Compare commits

..
Author SHA1 Message Date
Sterrezo acb1ebda19 Finalized hoof sounds 2026-05-27 12:34:57 +02:00
Sterrezo 5dddc05626 Merge branch 'main' into steppy-steps 2026-05-27 00:16:42 +02:00
Sterrezo 99890671bd Added hoof footsteps for sand surfaces and updated other hoof sounds 2026-05-26 22:21:56 +02:00
Sterrezo 9451ac5f46 Merge branch 'main' into steppy-steps 2026-05-26 21:42:41 +02:00
Sterrezo a8e4e21ba1 Merge branch 'main' into steppy-steps 2026-05-19 14:15:48 +02:00
Sterrezo f555ba3703 Made Molang slightly less cursed with proper random functions 2026-05-16 14:24:18 +02:00
Sterrezo 37677b3730 Asset updates, added hoof on stone sounds 2026-05-16 12:17:24 +02:00
Sterrezo 2a298b2268 Merge branch 'main' into steppy-steps 2026-05-16 11:01:28 +02:00
Sterrezo ad3f94fb80 Added hoof grass medium and large sounds 2026-05-16 02:27:46 +02:00
Sterrezo 719660798e Started hoof sound implementation with Wyrdeer, asset and keyframe updates 2026-05-15 18:17:04 +02:00
Sterrezo 8d973a09e1 Tweaks to the footstep function logic to better account for depth
If depth is 2 outright, the function could pick a block below the actual block the entity is standing on if it was checked earlier in the function. Loop iterates twice, so now it plays footsteps even when standing on the edge of a block or running down slopes.
2026-05-15 11:48:50 +02:00
Sterrezo 3579a86cde Merge branch 'main' into steppy-steps 2026-05-15 11:08:00 +02:00
Sterrezo ba96a6a205 Added standard medium and large sand footsteps 2026-05-14 20:18:04 +02:00
Sterrezo f07d2a9a9a First implementation of footstep keyframes with Arcanine 2026-05-14 16:56:13 +02:00
Sterrezo 2469067fd4 Allow for silencing step sounds within the species file 2026-05-14 02:24:18 +02:00
1205 changed files with 9313 additions and 48529 deletions

No files matched your search

-1
View File
@@ -24,7 +24,6 @@ eclipse
run
runClient
runServer
utilityscripts/implementation/*.txt
# Files from Forge MDK
forge*changelog.txt
+27 -116
View File
@@ -56,7 +56,6 @@
- Pressing the inventory key now closes the Pokémon interact wheel GUI
- Pokémon cries now play when clicking Pokémon in the summary screen.
- Pressing the Summary key while either the starter selection or summary screen are open now closes those screens
- Ice type Pokémon are now immune to Packed Snow
### New rideable Pokémon
- Drampa
@@ -68,7 +67,6 @@
- Milotic
### Pokémon Added
#### Generation 3
- Wurmple
- Silcoon
- Beautifly
@@ -76,55 +74,59 @@
- Dustox
- Skitty
- Delcatty
- Seviper
- Zangoose
#### Generation 4
- Cherubi
- Cherrim
- Stunky
- Skuntank
#### Generation 5
- Audino
- Pawniard
- Bisharp
- Kingambit
#### Generation 6
- Pancham (+ Cosmetic with Black Glasses)
- Pangoro (+ Cosmetic with Black Glasses)
#### Generation 7
- Rockruff
- Lycanroc
#### Generation 8
- Rolycoly
- Carkol
- Coalossal
- Runerigus
- Snom
- Frosmoth
- Indeedee
- Duraludon
- Archaludon
- Applin
- Flapple
- Appletun
#### Generation 9
- Dipplin
- Hydrapple
- Nymble
- Lokix
- Kingambit
- Dipplin
- Archaludon
- Hydrapple
#### Regional Forms
- Sandshrew (Alolan Form)
- Sandslash (Alolan Form)
- Yamask (Galarian Form)
- Avalugg (Hisuian Form)
- Sandshrew (Alolan)
- Sandslash (Alolan)
- Avalugg (Hisuian)
### Model updates for the following Pokémon
- Goomy
- Sliggoo
- Goodra
- Porygon
- Porygon2
- Porygon-Z
- Zubat
- Golbat
- Crobat
### Model updates for the following Pokémon
@@ -134,12 +136,11 @@
- Zubat
- Golbat
- Crobat
- Ditto
- Porygon
- Porygon2
- Porygon-Z
- Skarmory
- Smoochum
- Jynx
- Popplio
- Brionne
@@ -147,22 +148,17 @@
- Fletchling
- Fletchinder
- Talonflame
- Sableye
- Mawile
- Goomy
- Sliggoo
- Goodra
- Nacli
- Naclstack
- Garganacl
- Bidoof
- Cranidos
- Chatot
- Yamask
- Cofagrigus
- Tyranitar
- Turtonator
- Arbok (New Patterns: Angry, Cartoon, Clown, Comedic, Crow, Grin, Ink, Modern, Rain, Scribble, Silence, Sloth, Suspicious, Will)
#### Model changes to the regional bias resource pack:
@@ -196,12 +192,6 @@
- Shedinja
- Skwovet
- Greedent
- Bidoof
- Cranidos
- Chatot
- Yamask
- Cofagrigus
- Luvdisc
#### Added sounds to the following moves
- Absorb
@@ -299,14 +289,6 @@
- Fixed Raichu (male) and Alolan Raichu (both genders) not displaying the correct Partner Cap when Pewter Crunchies are in the cosmetic slot.
- Regional Foods will now prioritize being eaten instead of used for healing Pokémon, shift clicking will use it as healing
- Resolved Z-Fighting on Pokédex Models
- Restored Ninjask's ability to do barrel rolls
- Fixed a crash caused by adding enchanted items to the Resurrection Machine
- Fixed a crash that could occur when starting a PvN battle with only fainted Pokémon.
- Fixed the Remember Riding Camera config not being respected when dismounting and resolved the incompatibility with the Auto Third Person mod
- Fixed Full Heal block not dropping Full Heals
- Fixed status cure items not returning an empty bottle when used
- Fixed Panpour consuming its held item when evolving with a Water Stone
- Fixed Smoked Tail Curry returning a Wooden Bowl when consumed despite it not being included in the recipe
### Fixes
- Fixed Croagunk's walkspeed
@@ -367,8 +349,6 @@
- Separated all the functions of MoLangFunctions.kt into their own files.
- Spawn buckets and their base weights are now provided by the spawner, with different base weights for world, fishing, snack, and habitat spawn buckets.
- Removed "SpawnBucket" class in favour of just storing maps of bucket names to weights.
- Fixed nicknames not being applied to Pokémon spawned from `spawn_pool_world` files.
- Added support for `profilePokedexScale`, `profilePokedexTranslation`, `profileSummaryScale`, and `profileSummaryTranslation` in poser files for finer control over profile displays.
### Molang & Datapacks
- Added `moveset_builders` datapack folder for different styles of movesets.
@@ -392,84 +372,15 @@
- Ride sounds no longer play when submerged unless specified with a new setting
- NPC Trainers can now call a `command` animation when issuing a command in battle.
- Added a q.failed function to move action effects.
- Herd spawned Pokémon have their levels controlled differently. The `levelRange` property now acts as a clamp instead of a filter, with a new `herdLevelRange` property to do the filter behaviour.
- `q.sound` now accepts three parameters (sound event, volume and pitch) instead of just the sound event and pitch.
- Herd spawned Pokémon have their levels controlled differently. The `levelRange` property now acts as a clamp instead of a filter, with a new `herdLevelRange` property to do the filter behaviour.
### Particles
#### New Move Animations
- Blizzard
- Disarming Voice
- Draco Meteor
- Dragon Breath
- Dragon Rage
- Drain Punch
- Fairy Wind
- Fire Fang
- Gust
- Horn Drill
- Hydro Pump
- Ice Fang
- Leafage
- Leaf Storm
- Light Screen
- Night Shade
- Play Rough
- Pyro Ball
- Reflect
- Rock Slide
- Sonic Boom
- Sucker Punch
- Supersonic
- Thunder Fang
#### Tweaks and Fixes (Moves)
- Confusion
- Dragon Claw
- Eruption
- Fire Punch
- Flame Burst
- Flame Charge
- Flamethrower
- Frost Breath
- Hypnosis
- Ice Punch
- Icy Wind
- Mud Sport
- Poison Fang
- Protect
- Psychic
- Quick Attack
- Rage Powder
- Razor Leaf
- Sand Attack
- Scratch
- Shadow Claw
- Sing
- Spore
- String Shot
- Tackle
- Tail Whip
- Thunder
- Thunder Punch
- Thunder Wave
- Water Gun
- Water Pulse
- Water Sport
#### Miscellaneous Particles
+ Added Wild Might particles for Alpha Pokémon
+ Updated stat increase and decrease particles
### Localization
- Updated translations for:
- Japanese
- German
- Spanish
- Ecuadorian Spanish
- Brazilian Portuguese
- Simplified Chinese
- Traditional Chinese
- Korean
@@ -1,111 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.mixin.accessor.SinglePoolElementAccessor;
import com.cobblemon.mod.common.world.structureprocessors.HeightRangeStructureProcessor;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.structure.Structure;
import net.minecraft.world.level.levelgen.structure.pools.*;
import net.minecraft.world.level.levelgen.structure.pools.alias.PoolAliasLookup;
import net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
@Mixin(JigsawPlacement.class)
public class JigsawPlacementMixin {
@Inject(
method = "addPieces(Lnet/minecraft/world/level/levelgen/structure/Structure$GenerationContext;Lnet/minecraft/core/Holder;Ljava/util/Optional;ILnet/minecraft/core/BlockPos;ZLjava/util/Optional;ILnet/minecraft/world/level/levelgen/structure/pools/alias/PoolAliasLookup;Lnet/minecraft/world/level/levelgen/structure/pools/DimensionPadding;Lnet/minecraft/world/level/levelgen/structure/templatesystem/LiquidSettings;)Ljava/util/Optional;",
at = @At("RETURN"),
cancellable = true
)
private static void onAddPieces(
Structure.GenerationContext context,
Holder<StructureTemplatePool> startPool,
Optional<ResourceLocation> startJigsawName,
int maxDepth,
BlockPos pos,
boolean useExpansionHack,
Optional<Heightmap.Types> projectStartToHeightmap,
int maxDistanceFromCenter,
PoolAliasLookup aliasLookup,
DimensionPadding dimensionPadding,
LiquidSettings liquidSettings,
CallbackInfoReturnable<Optional<Structure.GenerationStub>> cir
) {
Optional<Structure.GenerationStub> result = cir.getReturnValue();
if (result.isEmpty()) {
return;
}
BlockPos spawnPos = result.get().position();
boolean canPlace = cobblemon$canAnyStartElementPlace(context, startPool, spawnPos);
if (canPlace) {
return;
}
cir.setReturnValue(Optional.empty());
}
@Unique
private static boolean cobblemon$canAnyStartElementPlace(
Structure.GenerationContext generationContext,
Holder<StructureTemplatePool> startPool,
BlockPos startPos
) {
for (StructurePoolElement element : startPool.value().templates) {
Optional<HeightRangeStructureProcessor> heightRangeProcessor = cobblemon$getHeightRangeProcessor(element);
if (heightRangeProcessor.isEmpty()) {
return true;
}
HeightRangeStructureProcessor processor = heightRangeProcessor.get();
boolean valid = processor.isValidPlacement(
generationContext.chunkGenerator(),
generationContext.heightAccessor(),
generationContext.randomState(),
startPos
);
if (valid) {
return true;
}
}
return false;
}
@Unique
private static Optional<HeightRangeStructureProcessor> cobblemon$getHeightRangeProcessor(StructurePoolElement element) {
if (!(element instanceof SinglePoolElement)) {
return Optional.empty();
}
StructureProcessorList processorList = ((SinglePoolElementAccessor) element).getProcessors().value();
for (StructureProcessor processor : processorList.list()) {
if (processor instanceof HeightRangeStructureProcessor heightRangeStructureProcessor) {
return Optional.of(heightRangeStructureProcessor);
}
}
return Optional.empty();
}
}
@@ -1,22 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.accessor;
import net.minecraft.core.Holder;
import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(SinglePoolElement.class)
public interface SinglePoolElementAccessor {
@Accessor("processors")
Holder<StructureProcessorList> getProcessors();
}
@@ -10,13 +10,11 @@ package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.client.render.player.MountedPlayerRenderer;
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker;
import com.cobblemon.mod.common.duck.RidePassenger;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import net.minecraft.client.model.HumanoidModel;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import org.spongepowered.asm.mixin.Final;
@@ -98,26 +96,4 @@ public class HumanoidModelMixin {
MountedPlayerRenderer.INSTANCE.animate((HumanoidModel<AbstractClientPlayer>)(Object)this, pokemonEntity, player, netHeadYaw, headPitch, ageInTicks, limbSwing, limbSwingAmount);
}
}
// Pose the right arm forward while recalling so the held Poké Ball sits out in front.
@Inject(method = "setupAnim*", at = @At("TAIL"))
public void cobblemon$poseRecallArm(
LivingEntity entity,
float limbSwing,
float limbSwingAmount,
float ageInTicks,
float netHeadYaw,
float headPitch,
CallbackInfo ci
) {
if (!(entity instanceof AbstractClientPlayer player)) return;
// Skip while riding so we don't override the mounted-riding arm animation.
if (entity.getVehicle() instanceof PokemonEntity) return;
float raise = RecallArmAnimationTracker.INSTANCE.raiseFactor(player.getUUID());
if (raise <= 0f) return;
float armForwardXRot = (float) (-Math.PI / 2.0);
this.rightArm.xRot = Mth.lerp(raise, this.rightArm.xRot, armForwardXRot);
this.rightArm.yRot = Mth.lerp(raise, this.rightArm.yRot, 0f);
this.rightArm.zRot = Mth.lerp(raise, this.rightArm.zRot, 0f);
}
}
@@ -1,45 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.layers.ItemInHandLayer;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* Hides the player's right-hand item while recalling so it doesn't overlap the recall Poké Ball
* drawn by PlayerRecallBallRenderer.
*/
@Mixin(ItemInHandLayer.class)
public class ItemInHandLayerMixin {
@Inject(method = "renderArmWithItem", at = @At("HEAD"), cancellable = true)
private void cobblemon$hideRecallHandItem(
LivingEntity entity,
ItemStack itemStack,
ItemDisplayContext itemDisplayContext,
HumanoidArm humanoidArm,
PoseStack poseStack,
MultiBufferSource multiBufferSource,
int light,
CallbackInfo ci
) {
if (humanoidArm == HumanoidArm.RIGHT && RecallArmAnimationTracker.INSTANCE.isRecalling(entity.getUUID())) {
ci.cancel();
}
}
}
@@ -9,8 +9,6 @@
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.client.render.player.FirstPersonRecallBallRenderer;
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker;
import com.cobblemon.mod.common.item.PokedexItem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
@@ -33,12 +31,6 @@ public class ItemInHandRendererMixin {
if (abstractClientPlayer.isUsingItem() && abstractClientPlayer.getUseItem().getItem() instanceof PokedexItem) {
ci.cancel();
}
// While recalling, swap the main-hand item for the rising Poké Ball.
else if (interactionHand == InteractionHand.MAIN_HAND
&& RecallArmAnimationTracker.INSTANCE.isRecalling(abstractClientPlayer.getUUID())
&& FirstPersonRecallBallRenderer.INSTANCE.render(poseStack, multiBufferSource, j, f)) {
ci.cancel();
}
else if (abstractClientPlayer instanceof OrientationControllable controllable && controllable.getOrientationController().isActive()) {
}
@@ -308,9 +308,7 @@ object Cobblemon {
this.config.maxPokemonLevel,
this.config.maxPokemonFriendship,
this.config.maxDynamaxLevel,
this.config.unlockAllMoveDexMovesByDefault,
this.config.pokemonIntrinsicSizeMin,
this.config.pokemonIntrinsicSizeMax
this.config.unlockAllMoveDexMovesByDefault
).sendToPlayer(player)
}
@@ -405,7 +405,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val BIG_MALASADA = regionalFoodItem("big_malasada", 64, 7, 0.3f, false)
@JvmField
val SMOKED_TAIL_CURRY = regionalFoodItem("smoked_tail_curry", 64, 10, 0.6f, false)
val SMOKED_TAIL_CURRY = regionalFoodItem("smoked_tail_curry", 64, 10, 0.6f, false, ItemStack(Items.BOWL, 1))
@JvmField
val JUBILIFE_MUFFIN = regionalFoodItem("jubilife_muffin", 64, 7, 0.3f, false)
@JvmField
@@ -131,7 +131,6 @@ import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.ChangeP
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.RequestPCBoxWallpapersPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.SetPCBoxWallpapersPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.UnlockPCBoxWallpaperPacket
import com.cobblemon.mod.common.net.messages.client.tms.TechnicalMachineRegistrySyncPacket
import com.cobblemon.mod.common.net.messages.client.toast.ToastPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeAcceptanceChangedPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeCancelledPacket
@@ -440,7 +439,6 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(BehaviourSyncPacket.ID, BehaviourSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(MarkRegistrySyncPacket.ID, MarkRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(RideSettingsSyncPacket.ID, RideSettingsSyncPacket::decode, RideSettingsSyncHandler))
list.add(PacketRegisterInfo(TechnicalMachineRegistrySyncPacket.ID, TechnicalMachineRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
// Effects
list.add(PacketRegisterInfo(SpawnSnowstormParticlePacket.ID, SpawnSnowstormParticlePacket::decode, SpawnSnowstormParticleHandler))
@@ -69,7 +69,7 @@ class HabitatPool {
pool.spawns = spawns
return pool
} else {
return HabitatPools.habitatPoolsById[poolId] ?: default()
return HabitatPools.habitatPoolsById[poolId] ?: HabitatPool.default()
}
}
}
@@ -94,14 +94,6 @@ class HabitatPool {
return spawns.mapNotNull { it.createSpawnDetail(habitatBlockEntity) }
}
fun getPhaseCount(): Int {
return spawns
.flatMap { it.phases?.ranges?.flatten() ?: emptySet() }
.toSet()
.count()
.coerceAtLeast(1)
}
fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(id)
buffer.writeUtf(name)
@@ -17,6 +17,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
class HabitatSettingsDTO() {
var numberOfPhases = 1
var phaseOrder = HabitatPhaseOrder.SIMPLE
lateinit var levelRange: IntRange
var modifiers: String = ""
@@ -27,6 +28,7 @@ class HabitatSettingsDTO() {
var naturalSettings: NaturalHabitatSettingsDTO? = null
constructor(habitatBlockEntity: HabitatBlockEntity) : this() {
this.numberOfPhases = habitatBlockEntity.numberOfPhases
this.phaseOrder = habitatBlockEntity.phaseOrder
this.levelRange = habitatBlockEntity.levelRange
this.modifiers = habitatBlockEntity.modifiers.asString()
@@ -42,6 +44,7 @@ class HabitatSettingsDTO() {
}
fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeInt(numberOfPhases)
buffer.writeEnum(phaseOrder)
buffer.writeInt(levelRange.first)
buffer.writeInt(levelRange.last)
@@ -57,6 +60,7 @@ class HabitatSettingsDTO() {
}
fun decode(buffer: RegistryFriendlyByteBuf) {
this.numberOfPhases = buffer.readInt()
this.phaseOrder = buffer.readEnum(HabitatPhaseOrder::class.java)
val levelRangeStart = buffer.readInt()
val levelRangeEnd = buffer.readInt()
@@ -109,7 +109,7 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
DoubleValue(pokemon.species.nationalPokedexNumber.toDouble())
}
map["types"] = {
pokemon.form.types.map { it.showdownId }.asArrayValue(::StringValue)
pokemon.form.types.map { it.toString() }.asArrayValue(::StringValue)
}
map["gender_ratio"] = {
DoubleValue(pokemon.form.maleRatio.toDouble())
@@ -759,7 +759,6 @@ open class PokemonProperties {
shiny?.let { json.addProperty(DataKeys.POKEMON_SHINY, it) }
gender?.let { json.addProperty(DataKeys.POKEMON_GENDER, it.name) }
species?.let { json.addProperty(DataKeys.POKEMON_SPECIES_TEXT, it) }
nickname?.let { json.addProperty(DataKeys.POKEMON_NICKNAME, it.string) }
form?.let { json.addProperty(DataKeys.POKEMON_FORM_ID, it) }
friendship?.let { json.addProperty(DataKeys.POKEMON_FRIENDSHIP, it) }
fullness?.let { json.addProperty(DataKeys.POKEMON_FULLNESS, it) }
@@ -796,7 +795,6 @@ open class PokemonProperties {
shiny = json.get(DataKeys.POKEMON_SHINY)?.asBoolean
gender = json.get(DataKeys.POKEMON_GENDER)?.asString?.let { Gender.valueOf(it) }
species = json.get(DataKeys.POKEMON_SPECIES_TEXT)?.asString
nickname = json.get(DataKeys.POKEMON_NICKNAME)?.asString?.let(Component::literal)
form = json.get(DataKeys.POKEMON_FORM_ID)?.asString
friendship = json.get(DataKeys.POKEMON_FRIENDSHIP)?.asInt
fullness = json.get(DataKeys.POKEMON_FULLNESS)?.asInt
@@ -12,7 +12,6 @@ import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.moves.MoveTemplate
import com.cobblemon.mod.common.api.moves.adapters.MoveTemplateAdapter
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.net.messages.client.tms.TechnicalMachineRegistrySyncPacket
import com.cobblemon.mod.common.util.adapters.TMObtainMethodAdapter
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.cobblemonResource
@@ -71,7 +70,5 @@ object TechnicalMachines : JsonDataRegistry<TechnicalMachine> {
fun getByResourceLocation(resourceLocation: ResourceLocation) = tmMap[resourceLocation]
fun getAllResourceLocations() = tmMap.keys.toSet()
override fun sync(player: ServerPlayer) {
TechnicalMachineRegistrySyncPacket(tmMap.values.toList()).sendToPlayer(player)
}
override fun sync(player: ServerPlayer) {}
}
@@ -349,12 +349,11 @@ object BattleBuilder {
npcPartyStores.add(npcParty)
}
val playerAvailablePokemon = playerActor.pokemonList.count { it.health > 0 }
if (playerAvailablePokemon < battleFormat.battleType.slotsPerActor) {
if (playerActor.pokemonList.size < battleFormat.battleType.slotsPerActor) {
errors.participantErrors[playerActor] += BattleStartError.insufficientPokemon(
actorEntity = player,
requiredCount = battleFormat.battleType.slotsPerActor,
hadCount = playerAvailablePokemon
hadCount = playerActor.pokemonList.size
)
}
@@ -163,8 +163,7 @@ class TrackerActor(val uuid: UUID) {
//we assume that AI knows it all about our allies
trackerActor.party.addAll(actor.pokemonList.map { createAllied(it) })
actor.activePokemon.forEach {
val battlePokemon = it.battlePokemon ?: return@forEach
val active = trackerActor.party.first { trackMon -> trackMon.id == battlePokemon.uuid }
val active = trackerActor.party.first { trackMon -> trackMon.id == it.battlePokemon!!.uuid }
trackerActor.party.remove(active)
trackerActor.activePokemon.add(active)
}
@@ -177,8 +176,7 @@ class TrackerActor(val uuid: UUID) {
//only know basics of what we see right now
trackerActor.party.addAll(actor.pokemonList.map { createOpposing(it) })
actor.activePokemon.forEach {
val battlePokemon = it.battlePokemon ?: return@forEach
val active = trackerActor.party.first { trackMon -> trackMon.id == battlePokemon.uuid }
val active = trackerActor.party.first { trackMon -> trackMon.id == it.battlePokemon!!.uuid }
trackerActor.party.remove(active)
trackerActor.activePokemon.add(active)
}
@@ -16,20 +16,24 @@ import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.HolderLookup
import net.minecraft.core.NonNullList
import net.minecraft.core.component.DataComponents
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundSource
import net.minecraft.world.*
import net.minecraft.world.ContainerHelper
import net.minecraft.world.Containers
import net.minecraft.world.InteractionResult
import net.minecraft.world.ItemInteractionResult
import net.minecraft.world.WorldlyContainer
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.gameevent.GameEvent
import net.minecraft.world.phys.BlockHitResult
import java.util.*
import net.minecraft.world.level.gameevent.GameEvent
import java.util.OptionalInt
import kotlin.math.pow
class DiscShelfBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(CobblemonBlockEntities.DISC_SHELF, pos, state), WorldlyContainer {
@@ -130,7 +134,25 @@ class DiscShelfBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(Cobbl
return stack.item is TechnicalMachineItem
|| stack.item == CobblemonItems.UPGRADE
|| stack.item == CobblemonItems.DUBIOUS_DISC
|| stack.has(DataComponents.JUKEBOX_PLAYABLE)
|| stack.item == Items.MUSIC_DISC_13
|| stack.item == Items.MUSIC_DISC_CAT
|| stack.item == Items.MUSIC_DISC_BLOCKS
|| stack.item == Items.MUSIC_DISC_CHIRP
|| stack.item == Items.MUSIC_DISC_FAR
|| stack.item == Items.MUSIC_DISC_MALL
|| stack.item == Items.MUSIC_DISC_MELLOHI
|| stack.item == Items.MUSIC_DISC_STAL
|| stack.item == Items.MUSIC_DISC_STRAD
|| stack.item == Items.MUSIC_DISC_WARD
|| stack.item == Items.MUSIC_DISC_11
|| stack.item == Items.MUSIC_DISC_WAIT
|| stack.item == Items.MUSIC_DISC_OTHERSIDE
|| stack.item == Items.MUSIC_DISC_5
|| stack.item == Items.MUSIC_DISC_RELIC
|| stack.item == Items.MUSIC_DISC_PRECIPICE
|| stack.item == Items.MUSIC_DISC_CREATOR
|| stack.item == Items.MUSIC_DISC_CREATOR_MUSIC_BOX
|| stack.item == Items.MUSIC_DISC_PIGSTEP
}
fun onNoteBlockPulse(level: Level, noteBlockPos: BlockPos, soundEvent: SoundEvent) {
@@ -60,12 +60,10 @@ class HabitatBlockEntity(pos: BlockPos, state: BlockState) :
var spawningStyle: HabitatSpawningStyle = ActivatedHabitatSpawning(this)
var numberOfPhases: Int = 1
var phaseOrder = HabitatPhaseOrder.SIMPLE
var currentPhase = 1
val numberOfPhases: Int
get() = pool.getPhaseCount()
var levelRange: IntRange = 1..Cobblemon.config.maxPokemonLevel
var modifiers: PokemonProperties = PokemonProperties()
var pool: HabitatPool = HabitatPool.default()
@@ -141,6 +139,7 @@ class HabitatBlockEntity(pos: BlockPos, state: BlockState) :
val activatedSettings = habitatSettingsDTO.activatedSettings
val naturalSettings = habitatSettingsDTO.naturalSettings
val isActivated = habitatSettingsDTO.isActivatedSpawning
this.numberOfPhases = habitatSettingsDTO.numberOfPhases
this.phaseOrder = habitatSettingsDTO.phaseOrder
this.levelRange = habitatSettingsDTO.levelRange
this.modifiers = PokemonProperties.parse(habitatSettingsDTO.modifiers)
@@ -170,6 +169,7 @@ class HabitatBlockEntity(pos: BlockPos, state: BlockState) :
override fun saveAdditional(tag: CompoundTag, registryLookup: HolderLookup.Provider) {
super.saveAdditional(tag, registryLookup)
tag.putString(DataKeys.HABITAT_MIMIC, mimicId.toString())
tag.putInt(DataKeys.HABITAT_PHASE_COUNT, numberOfPhases)
tag.putString(DataKeys.HABITAT_PHASE_ORDER, phaseOrder.toString())
// Only save the level range when it's a non-trivial one
if (levelRange.first != 1 || levelRange.last != Cobblemon.config.maxPokemonLevel) {
@@ -201,6 +201,7 @@ class HabitatBlockEntity(pos: BlockPos, state: BlockState) :
return // Client doesn't need to try loading the rest
}
numberOfPhases = tag.getInt(DataKeys.HABITAT_PHASE_COUNT)
phaseOrder = HabitatPhaseOrder.valueOf(tag.getString(DataKeys.HABITAT_PHASE_ORDER))
levelRange = tag.getString(DataKeys.HABITAT_LEVEL_RANGE).takeIf { it.isNotBlank() }?.let(IntRangeAdapter::deserialize) ?: 1..Cobblemon.config.maxPokemonLevel
modifiers = tag.getString(DataKeys.HABITAT_MODIFIERS).takeIf { it.isNotBlank() }?.let(PokemonProperties::parse) ?: PokemonProperties()
@@ -630,8 +630,7 @@ class FossilMultiblockStructure (
result.putInt(DataKeys.ORGANIC_MATERIAL, organicMaterialInside)
val fossilInv = ListTag()
val ops = registryLookup.createSerializationContext(NbtOps.INSTANCE)
fossilInventory.forEach { fossilInv.add(ItemStack.CODEC.encodeStart(ops, it).getOrThrow()) }
fossilInventory.forEach { fossilInv.add(ItemStack.CODEC.encodeStart(NbtOps.INSTANCE, it).orThrow) }
result.put(DataKeys.FOSSIL_INVENTORY, fossilInv)
result.putString(DataKeys.CONNECTOR_DIRECTION, tankConnectorDirection?.toString())
@@ -670,10 +669,7 @@ class FossilMultiblockStructure (
val fossilInv = if (nbt.contains(DataKeys.FOSSIL_INVENTORY)) { (nbt.get(DataKeys.FOSSIL_INVENTORY) as ListTag) } else ListTag()
val actualFossilList = mutableListOf<ItemStack>()
val ops = registryLookup.createSerializationContext(NbtOps.INSTANCE)
fossilInv.forEach { ItemStack.CODEC.parse(ops, it).result().ifPresent(actualFossilList::add) }
fossilInv.forEach { ItemStack.parse(registryLookup, it).ifPresent(actualFossilList::add) }
result.fossilInventory = actualFossilList
result.tankConnectorDirection = Direction.byName(nbt.getString(DataKeys.CONNECTOR_DIRECTION))
@@ -44,7 +44,6 @@ import com.cobblemon.mod.common.client.render.entity.PokeBobberEntityRenderer
import com.cobblemon.mod.common.client.render.generic.GenericBedrockRenderer
import com.cobblemon.mod.common.client.render.item.CobblemonBuiltinItemRendererRegistry
import com.cobblemon.mod.common.client.render.item.PokemonItemRenderer
import com.cobblemon.mod.common.client.render.layer.PlayerRecallBallRenderer
import com.cobblemon.mod.common.client.render.layer.PokemonOnShoulderRenderer
import com.cobblemon.mod.common.client.render.models.blockbench.bedrock.animation.BedrockAnimationRepository
import com.cobblemon.mod.common.client.render.models.blockbench.repository.BerryModelRepository
@@ -406,10 +405,8 @@ object CobblemonClient {
var renderer: LivingEntityRenderer<Player, PlayerModel<Player>>? =
skinMap?.get(PlayerSkin.Model.WIDE) as LivingEntityRenderer<Player, PlayerModel<Player>>
renderer?.addLayer(PokemonOnShoulderRenderer(renderer))
renderer?.addLayer(PlayerRecallBallRenderer(renderer))
renderer = skinMap[PlayerSkin.Model.SLIM] as LivingEntityRenderer<Player, PlayerModel<Player>>?
renderer?.addLayer(PokemonOnShoulderRenderer(renderer))
renderer?.addLayer(PlayerRecallBallRenderer(renderer))
}
private fun registerMenuScreens() {
@@ -49,7 +49,7 @@ object MountedCameraTypeHandler {
return
}
val currentCameraType = mc.options.cameraType
if (Cobblemon.config.rememberRidingCamera && currentCameraType != unmountedCameraType) {
if (currentCameraType != unmountedCameraType) {
mc.options.cameraType = unmountedCameraType
}
val data = ClientPersistedData.ridingPerspectives
@@ -32,7 +32,6 @@ import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.animation.ActiveAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.PrimaryAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker
import com.cobblemon.mod.common.client.render.pokemon.PokemonRenderer.Companion.ease
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.net.messages.server.pokemon.update.ServerboundUpdateRidingStatePacket
@@ -321,13 +320,6 @@ class PokemonClientDelegate : PosableState(), PokemonSideDelegate {
ballOffset = 0f
ballRotOffset = 0f
sendOutPosition = null
// If a player is recalling, have them hold the matching Poké Ball out in their
// right hand for the duration of the beam (see ourRecallArmAnimationTracker class).
currentEntity.ownerUUID?.let { ownerId ->
if (currentEntity.level().getPlayerByUUID(ownerId) != null) {
RecallArmAnimationTracker.start(ownerId, currentEntity.exposedBall, emptySet())
}
}
afterOnClient(seconds = BEAM_EXTEND_TIME) {
activeSendoutScale = 1F
@@ -27,18 +27,10 @@ import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.Mth
import net.minecraft.world.phys.Vec3
import org.joml.Quaternionf
import org.joml.Vector3f
import kotlin.math.atan
enum class ProfileTransformType {
PROFILE,
NONE,
POKEDEX,
SUMMARY,
}
fun drawProfilePokemon(
renderablePokemon: RenderablePokemon,
matrixStack: PoseStack,
@@ -47,7 +39,7 @@ fun drawProfilePokemon(
state: PosableState,
partialTicks: Float,
scale: Float = 20F,
profileTransformType: ProfileTransformType = ProfileTransformType.PROFILE,
applyProfileTransform: Boolean = true,
applyBaseScale: Boolean = false,
r: Float = 1F,
g: Float = 1F,
@@ -64,7 +56,7 @@ fun drawProfilePokemon(
state = state.also { it.currentAspects = renderablePokemon.aspects },
partialTicks = partialTicks,
scale = scale,
profileTransformType = profileTransformType,
applyProfileTransform = applyProfileTransform,
applyBaseScale = applyBaseScale,
r = r,
g = g,
@@ -83,7 +75,7 @@ fun drawProfilePokemon(
state: PosableState,
partialTicks: Float,
scale: Float = 20F,
profileTransformType: ProfileTransformType = ProfileTransformType.PROFILE,
applyProfileTransform: Boolean = true,
applyBaseScale: Boolean = false,
doQuirks: Boolean = false,
r: Float = 1F,
@@ -122,38 +114,18 @@ fun drawProfilePokemon(
state.setPoseToFirstSuitable(poseType)
state.updatePartialTicks(partialTicks)
if (profileTransformType == ProfileTransformType.NONE) {
if (applyProfileTransform) {
matrixStack.translate(
model.profileTranslation.x,
model.profileTranslation.y + 1.5 * model.profileScale,
model.profileTranslation.z - 4.0
)
matrixStack.scale(model.profileScale, model.profileScale, 1 / model.profileScale)} else {
matrixStack.translate(0F, 0F, -4.0F)
if (applyBaseScale) {
matrixStack.scale(baseScale, baseScale, 1 / baseScale)
}
} else {
var profileScale: Float
var profileTranslation: Vec3
when (profileTransformType) {
ProfileTransformType.POKEDEX -> {
profileScale = model.profilePokedexScale ?: model.profileScale
profileTranslation = model.profilePokedexTranslation ?: model.profileTranslation
}
ProfileTransformType.SUMMARY -> {
profileScale = model.profileSummaryScale ?: model.profileScale
profileTranslation = model.profileSummaryTranslation ?: model.profileTranslation
}
else -> {
profileScale = model.profileScale
profileTranslation = model.profileTranslation
}
}
matrixStack.translate(
profileTranslation.x,
profileTranslation.y + 1.5 * profileScale,
profileTranslation.z - 4.0
)
matrixStack.scale(profileScale, profileScale, 1 / profileScale)
}
matrixStack.mulPose(rotation)
model.applyAnimations(null, state, 0F, 0F, 0F, headYaw, headPitch)
@@ -1,97 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.gui
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.mojang.blaze3d.platform.InputConstants
import net.minecraft.client.Minecraft
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.phys.Vec3
fun handleProfileDebugKeys(keyCode: Int, poserResourceLocation: ResourceLocation, state: FloatingState) {
if (!Cobblemon.config.enableDebugKeys) {
return
}
val model = VaryingModelRepository.getPoser(poserResourceLocation, state)
val delta = when (keyCode) {
InputConstants.KEY_UP -> Vec3(0.0, -0.01, 0.0)
InputConstants.KEY_DOWN -> Vec3(0.0, 0.01, 0.0)
InputConstants.KEY_LEFT -> Vec3(-0.01, 0.0, 0.0)
InputConstants.KEY_RIGHT -> Vec3(0.01, 0.0, 0.0)
else -> null
}
if (delta != null) {
model.profileTranslation = model.profileTranslation.add(delta)
model.profileSummaryTranslation = model.profileSummaryTranslation?.add(delta)
model.profilePokedexTranslation = model.profilePokedexTranslation?.add(delta)
}
val scaleDelta = when (keyCode) {
InputConstants.KEY_EQUALS -> 0.01F
InputConstants.KEY_MINUS -> -0.01F
else -> null
}
if (scaleDelta != null) {
model.profileScale += scaleDelta
model.profileSummaryScale = model.profileSummaryScale?.plus(scaleDelta)
model.profilePokedexScale = model.profilePokedexScale?.plus(scaleDelta)
}
}
fun logProfileTranslations(poserResourceLocation: ResourceLocation, state: FloatingState) {
if (!Cobblemon.config.enableDebugKeys) {
return
}
val model = VaryingModelRepository.getPoser(poserResourceLocation, state)
val player = Minecraft.getInstance().player
fun Double.f2() = "%.2f".format(this)
fun Float.f2() = "%.2f".format(this)
fun sendTranslation(name: String, translation: Vec3) {
player?.sendSystemMessage(Component.literal("$name Translation: (${translation.x.f2()}, ${translation.y.f2()}, ${translation.z.f2()})"))
}
fun sendScale(name: String, scale: Float) {
player?.sendSystemMessage(Component.literal("$name Scale: ${scale.f2()}"))
}
fun logTranslation(name: String, translation: Vec3) {
Cobblemon.LOGGER.info("override var ${name.replaceFirstChar(Char::lowercase)}Translation = Vec3(${translation.x.f2()}, ${translation.y.f2()}, ${translation.z.f2()})")
}
fun logScale(name: String, scale: Float) {
Cobblemon.LOGGER.info("override var ${name.replaceFirstChar(Char::lowercase)}Scale = ${scale.f2()}F")
}
sendTranslation("Profile", model.profileTranslation)
sendScale("Profile", model.profileScale)
model.profileSummaryTranslation?.let { sendTranslation("Summary Profile", it) }
model.profileSummaryScale?.let { sendScale("Summary Profile", it) }
model.profilePokedexTranslation?.let { sendTranslation("Pokedex Profile", it) }
model.profilePokedexScale?.let { sendScale("Pokedex Profile", it) }
logTranslation("Profile", model.profileTranslation)
logScale("Profile", model.profileScale)
model.profileSummaryTranslation?.let { logTranslation("ProfileSummary", it) }
model.profileSummaryScale?.let { logScale("ProfileSummary", it) }
model.profilePokedexTranslation?.let { logTranslation("ProfilePokedex", it) }
model.profilePokedexScale?.let { logScale("ProfilePokedex", it) }
}
@@ -115,19 +115,35 @@ class HabitatEditGUI(
addOptionWidget(mimicInput)
y += spacing
// Phase setting only visible if there's more than one phase
val phaseCount = habitatSettingsDTO.pool.toHabitatPool()?.getPhaseCount() ?: 1
if (phaseCount > 1) {
phaseOrderButton = addOptionWidget(
Button.builder(getPhaseOrderText()) {
val orders = HabitatPhaseOrder.entries
val currentIndex = orders.indexOf(habitatSettingsDTO.phaseOrder)
habitatSettingsDTO.phaseOrder = orders[(currentIndex + 1) % orders.size]
refresh()
}.bounds(10, y, buttonWidth, 20).build()
)
y += spacing
labels.add(lang("ui.edit.habitat.phase_number") to (10 to y))
y += 12
val phasesInput = EditBox(font, 10, y, buttonWidth, 20, "Phases".text())
phasesInput.value = habitatSettingsDTO.numberOfPhases.toString()
phasesInput.setResponder { value ->
val phases = value.toIntOrNull()
val valid = phases != null && phases > 0
if (valid) {
habitatSettingsDTO.numberOfPhases = phases
}
phasesInput.setTextColor(if (valid) validTextColor else invalidTextColor)
setFieldValidity("phases", valid, "ui.edit.habitat.validation.phases")
}
val initialPhases = phasesInput.value.toIntOrNull()
val initialPhasesValid = initialPhases != null && initialPhases > 0
phasesInput.setTextColor(if (initialPhasesValid) validTextColor else invalidTextColor)
setFieldValidity("phases", initialPhasesValid, "ui.edit.habitat.validation.phases")
addOptionWidget(phasesInput)
y += spacing
phaseOrderButton = addOptionWidget(
Button.builder(getPhaseOrderText()) {
val orders = HabitatPhaseOrder.entries
val currentIndex = orders.indexOf(habitatSettingsDTO.phaseOrder)
habitatSettingsDTO.phaseOrder = orders[(currentIndex + 1) % orders.size]
refresh()
}.bounds(10, y, buttonWidth, 20).build()
)
y += spacing
labels.add(lang("ui.edit.habitat.level_range") to (10 to y))
y += 12
@@ -374,10 +390,7 @@ class HabitatEditGUI(
}
fun refresh() {
val phaseCount = habitatSettingsDTO.pool.toHabitatPool()?.getPhaseCount() ?: 1
if (phaseCount > 1 && ::phaseOrderButton.isInitialized) {
phaseOrderButton.message = getPhaseOrderText()
}
phaseOrderButton.message = getPhaseOrderText()
spawnModeButton.message = getSpawnModeText()
poolSelectorButton.message = getPoolText()
viewPoolButton.message = getViewPoolText()
@@ -426,7 +439,6 @@ class HabitatEditGUI(
}
habitatSettingsDTO.pool = newCustomPool
}
rebuildWidgets()
return
}
@@ -439,7 +451,6 @@ class HabitatEditGUI(
}
habitatSettingsDTO.pool = selectedPool
rebuildWidgets()
}
private fun validateLevelRangeInputs() {
@@ -45,6 +45,7 @@ class HabitatSpawnEditorGUI(
private val actionButtonBottomMargin = 10
private val validTextColor = 0xFFFFFF
private val invalidTextColor = 0xFF5555
private val moonPhaseRange = 0..7
private lateinit var positionTypeButton: Button
private lateinit var bucketButton: Button
private lateinit var timeOfDayButton: Button
@@ -184,7 +185,7 @@ class HabitatSpawnEditorGUI(
phasesInput.setTextColor(validTextColor)
setFieldValidity("phases_list", true, "ui.edit.habitat.validation.phases_list")
} else {
val parsed = parsePhases(value)
val parsed = parseMoonPhases(value)
val valid = parsed != null
if (valid) {
spawn.phases = parsed
@@ -193,7 +194,7 @@ class HabitatSpawnEditorGUI(
setFieldValidity("phases_list", valid, "ui.edit.habitat.validation.phases_list")
}
}
val initialPhasesValid = phasesInput.value.isBlank() || parsePhases(phasesInput.value) != null
val initialPhasesValid = phasesInput.value.isBlank() || parseMoonPhases(phasesInput.value) != null
phasesInput.setTextColor(if (initialPhasesValid) validTextColor else invalidTextColor)
setFieldValidity("phases_list", initialPhasesValid, "ui.edit.habitat.validation.phases_list")
addOptionWidget(phasesInput)
@@ -331,7 +332,7 @@ class HabitatSpawnEditorGUI(
return runCatching { PokemonSpecies.getByName(lowered) }.getOrNull()
}
private fun parsePhases(raw: String): IntRanges? {
private fun parseMoonPhases(raw: String): IntRanges? {
val ranges = mutableListOf<IntRange>()
val tokens = raw.split(",").map(String::trim)
if (tokens.isEmpty() || tokens.any { it.isEmpty() }) {
@@ -343,12 +344,13 @@ class HabitatSpawnEditorGUI(
val range = when (parts.size) {
1 -> {
val value = parts[0].toIntOrNull() ?: return null
if (value !in moonPhaseRange) return null
value..value
}
2 -> {
val start = parts[0].toIntOrNull() ?: return null
val end = parts[1].toIntOrNull() ?: return null
if (start > end) {
if (start !in moonPhaseRange || end !in moonPhaseRange || start > end) {
return null
}
start..end
@@ -32,8 +32,6 @@ import com.cobblemon.mod.common.client.ClientMoLangFunctions.setupClient
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.CobblemonResources
import com.cobblemon.mod.common.client.gui.CobblemonRenderable
import com.cobblemon.mod.common.client.gui.handleProfileDebugKeys
import com.cobblemon.mod.common.client.gui.logProfileTranslations
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.BASE_HEIGHT
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.BASE_WIDTH
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_WIDTH
@@ -429,11 +427,6 @@ class PokedexGUI private constructor(
override fun onClose() {
if (blockPos != null) AdjustBlockEntityViewerCountPacket(blockPos, false).sendToServer()
playSound(CobblemonSounds.POKEDEX_CLOSE)
selectedEntry?.speciesId?.let { speciesId ->
logProfileTranslations(speciesId, pokemonInfoWidget.state)
}
super.onClose()
}
@@ -764,12 +757,6 @@ class PokedexGUI private constructor(
return true
}
if (!searchWidget.isFocused) {
selectedEntry?.speciesId?.let { speciesId ->
handleProfileDebugKeys(keyCode, speciesId, pokemonInfoWidget.state)
}
}
return super.keyPressed(keyCode, scanCode, modifiers)
}
@@ -22,7 +22,6 @@ import com.cobblemon.mod.common.api.types.ElementalType
import com.cobblemon.mod.common.client.ClientMoLangFunctions.setupClient
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.CobblemonResources
import com.cobblemon.mod.common.client.gui.ProfileTransformType
import com.cobblemon.mod.common.client.gui.TypeIcon
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_HEIGHT
@@ -387,8 +386,7 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
partialTicks = delta,
rotation = Quaternionf().fromEulerXYZDegrees(rotationVector),
state = state,
blockLight = 15,
profileTransformType = ProfileTransformType.POKEDEX,
blockLight = 15
)
matrices.popPose()
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.client.gui.pokedex.widgets
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.text.bold
import com.cobblemon.mod.common.client.CobblemonResources
import com.cobblemon.mod.common.client.gui.ProfileTransformType
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_WIDTH
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.POKEMON_DESCRIPTION_HEIGHT
@@ -91,7 +90,7 @@ class SizeWidget(val pX: Int, val pY: Int) : SoundlessWidget(
rotation = Quaternionf().fromEulerXYZDegrees(Vector3f(0F, 0F, 0F)),
state = FloatingState(),
scale = modelScale,
profileTransformType = ProfileTransformType.NONE,
applyProfileTransform = false,
applyBaseScale = true,
r = 0F,
g = 0F,
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.client.gui.summary
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.CobblemonNetwork.sendToServer
import com.cobblemon.mod.common.CobblemonSounds
@@ -20,8 +21,14 @@ import com.cobblemon.mod.common.api.text.bold
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.CobblemonResources
import com.cobblemon.mod.common.client.gui.*
import com.cobblemon.mod.common.client.gui.summary.widgets.*
import com.cobblemon.mod.common.client.gui.CobblemonRenderable
import com.cobblemon.mod.common.client.gui.ExitButton
import com.cobblemon.mod.common.client.gui.TypeIcon
import com.cobblemon.mod.common.client.gui.summary.widgets.EvolutionSelectScreen
import com.cobblemon.mod.common.client.gui.summary.widgets.MarkingsWidget
import com.cobblemon.mod.common.client.gui.summary.widgets.ModelWidget
import com.cobblemon.mod.common.client.gui.summary.widgets.NicknameEntryWidget
import com.cobblemon.mod.common.client.gui.summary.widgets.PartyWidget
import com.cobblemon.mod.common.client.gui.summary.widgets.screens.SummaryTab
import com.cobblemon.mod.common.client.gui.summary.widgets.screens.info.InfoWidget
import com.cobblemon.mod.common.client.gui.summary.widgets.screens.marks.MarksWidget
@@ -30,6 +37,7 @@ import com.cobblemon.mod.common.client.gui.summary.widgets.screens.moves.MovesWi
import com.cobblemon.mod.common.client.gui.summary.widgets.screens.stats.StatWidget
import com.cobblemon.mod.common.client.keybind.keybinds.SummaryBinding
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetItemHiddenPacket
import com.cobblemon.mod.common.net.messages.server.storage.party.MovePartyPokemonPacket
import com.cobblemon.mod.common.net.messages.server.storage.party.SwapPartyPokemonPacket
@@ -707,9 +715,27 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
) {
this.focused = null
}
handleProfileDebugKeys(keyCode, selectedPokemon.species.resourceIdentifier, modelWidget.state)
if (Cobblemon.config.enableDebugKeys) {
val model = VaryingModelRepository.getPoser(selectedPokemon.species.resourceIdentifier, modelWidget.state)
if (keyCode == InputConstants.KEY_UP) {
model.profileTranslation = model.profileTranslation.add(0.0, -0.01, 0.0)
}
if (keyCode == InputConstants.KEY_DOWN) {
model.profileTranslation = model.profileTranslation.add(0.0, 0.01, 0.0)
}
if (keyCode == InputConstants.KEY_LEFT) {
model.profileTranslation = model.profileTranslation.add(-0.01, 0.0, 0.0)
}
if (keyCode == InputConstants.KEY_RIGHT) {
model.profileTranslation = model.profileTranslation.add(0.01, 0.0, 0.0)
}
if (keyCode == InputConstants.KEY_EQUALS) {
model.profileScale += 0.01F
}
if (keyCode == InputConstants.KEY_MINUS) {
model.profileScale -= 0.01F
}
}
return super.keyPressed(keyCode, scanCode, modifiers)
}
@@ -718,8 +744,13 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
}
override fun onClose() {
logProfileTranslations(selectedPokemon.species.resourceIdentifier, modelWidget.state)
if (Cobblemon.config.enableDebugKeys) {
val model = VaryingModelRepository.getPoser(selectedPokemon.species.resourceIdentifier, modelWidget.state)
Minecraft.getInstance().player?.sendSystemMessage(Component.literal("Profile Translation: ${model.profileTranslation}"))
Minecraft.getInstance().player?.sendSystemMessage(Component.literal("Profile Scale: ${model.profileScale}"))
Cobblemon.LOGGER.info("override var profileTranslation = Vec3d(${model.profileTranslation.x}, ${model.profileTranslation.y}, ${model.profileTranslation.z})")
Cobblemon.LOGGER.info("override var profileScale = ${model.profileScale}F")
}
super.onClose()
}
}
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.client.gui.summary.widgets
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.client.gui.ProfileTransformType
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
import com.cobblemon.mod.common.client.gui.calculateHeadYawAndPitch
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState
@@ -117,8 +116,7 @@ class ModelWidget(
partialTicks = partialTicks,
headYaw = currentYawAndPitch.first,
headPitch = currentYawAndPitch.second,
blockLight = blockLight,
profileTransformType = ProfileTransformType.SUMMARY,
blockLight = blockLight
)
heldItemRenderer.renderOnModel(
@@ -22,8 +22,6 @@ object ServerSettingsPacketHandler : ClientNetworkPacketHandler<ServerSettingsPa
ServerSettings.maxPokemonFriendship = packet.maxPokemonFriendship
ServerSettings.maxDynamaxLevel = packet.maxDynamaxLevel
ServerSettings.unlockAllMoveDexMovesByDefault = packet.unlockAllMoveDexMovesByDefault
ServerSettings.pokemonIntrinsicSizeMin = packet.pokemonIntrinsicSizeMin
ServerSettings.pokemonIntrinsicSizeMax = packet.pokemonIntrinsicSizeMax
}
}
@@ -15,7 +15,6 @@ import com.cobblemon.mod.common.util.cobblemonResource
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.VertexConsumer
import com.mojang.math.Axis
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.LevelRenderer
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderType
@@ -40,13 +39,13 @@ class DiscShelfBlockEntityRenderer(ctx: BlockEntityRendererProvider.Context) :
private val leftMargin = 1f
private val rightMargin = 1f
private val topMargin = 1f
private val bottomMargin = 1f
private val interRowSpacing = 0f
private val tmOverlayDepthOffset = -0.0002f
private val slotBrightnessMultiplier = 0.65f
private val tmBaseTexture = cobblemonResource("textures/block/disc_shelf/technical_machine_base.png")
private val tmOverlayTexture = cobblemonResource("textures/block/disc_shelf/technical_machine_overlay.png")
private val musicDiscUnknownTexture = cobblemonResource("textures/block/disc_shelf/music_disc_unknown.png")
override fun render(
entity: DiscShelfBlockEntity,
@@ -78,6 +77,7 @@ class DiscShelfBlockEntityRenderer(ctx: BlockEntityRendererProvider.Context) :
val slotWidth = slotWidthPixels / textureSize
val slotHeight = slotHeightPixels / textureSize
val verticalSpacing = (slotHeightPixels + interRowSpacing) / textureSize
val totalHeight = slotHeight * 7 + interRowSpacing * 6 / textureSize
val startY = topMargin / textureSize
for ((index, item) in entity.items.withIndex()) {
@@ -188,13 +188,6 @@ class DiscShelfBlockEntityRenderer(ctx: BlockEntityRendererProvider.Context) :
private fun getItemTexture(itemStack: ItemStack): ResourceLocation {
val id = BuiltInRegistries.ITEM.getKey(itemStack.item)
val resource = cobblemonResource("textures/block/disc_shelf/${id.path}.png")
val resourceManager = Minecraft.getInstance().resourceManager
if (resourceManager.getResource(resource).isEmpty) {
return musicDiscUnknownTexture
}
return resource
return cobblemonResource("textures/block/disc_shelf/${id.path}.png")
}
}
@@ -1,127 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.layer
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import net.minecraft.client.Minecraft
import net.minecraft.client.model.PlayerModel
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.entity.ItemRenderer
import net.minecraft.client.renderer.entity.RenderLayerParent
import net.minecraft.client.renderer.entity.layers.RenderLayer
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.world.entity.HumanoidArm
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec3
import org.joml.Vector3f
/**
* Draws the matching Poké Ball in a recalling player's right hand and records where the recall beam
* should start. Driven by [RecallArmAnimationTracker]; the right arm is posed forward in
* HumanoidModelMixin so [PlayerModel.translateToHand] lands on the extended hand.
*
* The local player in first person is handled by FirstPersonRecallBallRenderer instead, so it's
* skipped here.
*/
class PlayerRecallBallRenderer<T : Player>(
renderLayerParent: RenderLayerParent<T, PlayerModel<T>>
) : RenderLayer<T, PlayerModel<T>>(renderLayerParent) {
companion object {
private const val BALL_SCALE = 0.5F
private const val HAND_X = 0.0625
private const val HAND_Y = 0.125
private const val HAND_Z = -0.625
private const val BALL_YAW_SPIN = 180F
private const val BALL_INFLATE = 1.08F
private const val BEAM_X_OFFSET = 0F
private const val BEAM_Y_OFFSET = 0.18F
private const val BEAM_Z_OFFSET = -0.30F
}
private val ballContext = RenderContext().also {
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.WORLD)
}
override fun render(
matrixStack: PoseStack,
buffer: MultiBufferSource,
packedLight: Int,
player: T,
limbSwing: Float,
limbSwingAmount: Float,
partialTicks: Float,
ageInTicks: Float,
netHeadYaw: Float,
headPitch: Float
) {
val anim = RecallArmAnimationTracker.get(player.uuid) ?: return
val mc = Minecraft.getInstance()
if (player === mc.player && mc.options.cameraType.isFirstPerson) return
matrixStack.pushPose()
getParentModel().translateToHand(HumanoidArm.RIGHT, matrixStack)
matrixStack.mulPose(Axis.XP.rotationDegrees(-90F))
matrixStack.mulPose(Axis.YP.rotationDegrees(180F))
matrixStack.translate(HAND_X, HAND_Y, HAND_Z)
renderBall(anim, matrixStack, buffer, packedLight, partialTicks)
matrixStack.popPose()
}
private fun renderBall(
anim: RecallArmAnimationTracker.RecallAnim,
matrixStack: PoseStack,
buffer: MultiBufferSource,
packedLight: Int,
partialTicks: Float
) {
val state = anim.ballState
val ball = anim.ball
matrixStack.pushPose()
matrixStack.scale(BALL_INFLATE, BALL_INFLATE, BALL_INFLATE)
matrixStack.translate(0.0, (-8.0 / 16.0) * BALL_SCALE, 0.0)
matrixStack.scale(BALL_SCALE, -BALL_SCALE, -BALL_SCALE)
matrixStack.mulPose(Axis.YP.rotationDegrees(BALL_YAW_SPIN))
val model = VaryingModelRepository.getPoser(ball.name, state)
val texture = VaryingModelRepository.getTexture(ball.name, state)
state.updatePartialTicks(partialTicks)
model.context = ballContext
ballContext.put(RenderContext.ASPECTS, state.aspects)
ballContext.put(RenderContext.POSABLE_STATE, state)
model.applyAnimations(null, state, 0F, 0F, 0F, 0F, 0F)
state.locatorStates["beam"]?.let { beamLocator ->
matrixStack.pushPose()
matrixStack.mulPose(beamLocator.matrix)
val camRelative = matrixStack.last().pose().transformPosition(Vector3f(BEAM_X_OFFSET, BEAM_Y_OFFSET, BEAM_Z_OFFSET))
matrixStack.popPose()
val camera = Minecraft.getInstance().gameRenderer.mainCamera.position
anim.beamOrigin = Vec3(camera.x + camRelative.x, camera.y + camRelative.y, camera.z + camRelative.z)
}
val consumer = ItemRenderer.getFoilBufferDirect(buffer, RenderType.entityCutout(texture), false, false)
model.render(ballContext, matrixStack, consumer, packedLight, OverlayTexture.NO_OVERLAY, -0x1)
model.red = 1F
model.green = 1F
model.blue = 1F
model.resetLayerContext()
matrixStack.popPose()
}
}
@@ -134,11 +134,6 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
*/
open var profileTranslation = Vec3(0.0, 0.0, 0.0)
open var profilePokedexScale: Float? = null
open var profilePokedexTranslation: Vec3? = null
open var profileSummaryScale: Float? = null
open var profileSummaryTranslation: Vec3? = null
var red = 1F
var green = 1F
var blue = 1F
@@ -0,0 +1,121 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.animation.WaveAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.WaveSegment
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.sineFunction
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class ArbokModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("arbok")
override val head = getPart("head_ai")
override var portraitScale = 1.5F
override var portraitTranslation = Vec3(-0.4, 1.0, 0.0)
override var profileScale = 0.67F
override var profileTranslation = Vec3(0.0, 0.7, 0.0)
lateinit var sleep: Pose
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var summary: Pose
val tail = getPart("tail")
val tail2 = getPart("tail2")
val tail3 = getPart("tail3")
val tail4 = getPart("tail4")
val tail5 = getPart("tail5")
val tailWaveSegment = WaveSegment(modelPart = tail, length = 11F)
val tail2WaveSegment = WaveSegment(modelPart = tail2, length = 11F)
val tail3WaveSegment = WaveSegment(modelPart = tail3, length = 11F)
val tail4WaveSegment = WaveSegment(modelPart = tail4, length = 11F)
val tail5WaveSegment = WaveSegment(modelPart = tail5, length = 11F)
override val cryAnimation = CryProvider { bedrockStateful("arbok", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("arbok", "blink") }
// TODO tongue_flick
val wave = WaveAnimation(
waveFunction = sineFunction(
period = 10F,
amplitude = 0.5F
),
basedOnLimbSwing = true,
oscillationsScalar = 8F,
head = tail,
rotationAxis = ModelPartTransformation.Y_AXIS,
motionAxis = ModelPartTransformation.X_AXIS,
headLength = 0.1F,
segments = arrayOf(
tailWaveSegment,
tail2WaveSegment,
tail3WaveSegment,
tail4WaveSegment,
tail5WaveSegment
)
)
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("arbok", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("arbok", "summary_idle"),
wave
)
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("arbok", "ground_walk"),
wave
)
)
summary = registerPose(
poseName = "summary",
poseTypes = UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("arbok", "summary_idle")
)
)
}
override fun getFaintAnimation(state: PosableState) = if (state.isPosedIn(standing, walk, sleep)) bedrockStateful("arbok", "faint") else null
}
@@ -0,0 +1,74 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class DittoModel(root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("ditto")
override var portraitScale = 3.2F
override var portraitTranslation = Vec3(0.0, -2.2, 0.0)
override var profileScale = 1.4F
override var profileTranslation = Vec3(0.0, -0.34, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var sleep: Pose
override val cryAnimation = CryProvider { bedrockStateful("ditto", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("ditto", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
// singleBoneLook()
bedrock("ditto", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
// singleBoneLook()
bedrock("ditto", "ground_walk")
)
)
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
// singleBoneLook()
bedrock("ditto", "sleep")
)
)
}
override fun getFaintAnimation(state: PosableState) = bedrockStateful("ditto", "faint")
}
@@ -0,0 +1,103 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class OmanyteModel(root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("omanyte")
override var portraitScale = 3.15F
override var portraitTranslation = Vec3(-0.06, -3.18, 0.0)
override var profileScale = 1.13F
override var profileTranslation = Vec3(0.0, -0.02, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
lateinit var float: CobblemonPose
lateinit var swim: CobblemonPose
lateinit var sleep: CobblemonPose
lateinit var battleidle: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("omanyte", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("omanyte", "blink") }
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("omanyte", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STANDING_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
transformTicks = 10,
condition = { !it.isBattling},
animations = arrayOf(
bedrock("omanyte", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES - PoseType.SWIM,
quirks = arrayOf(blink),
transformTicks = 10,
animations = arrayOf(
bedrock("omanyte", "ground_walk")
)
)
float = registerPose(
poseName = "float",
poseTypes = setOf(PoseType.FLOAT, PoseType.HOVER),
quirks = arrayOf(blink),
transformTicks = 10,
animations = arrayOf(
bedrock("omanyte", "water_idle")
)
)
swim = registerPose(
poseName = "swim",
poseTypes = setOf(PoseType.SWIM, PoseType.FLY),
quirks = arrayOf(blink),
transformTicks = 10,
animations = arrayOf(
bedrock("omanyte", "water_swim")
)
)
battleidle = registerPose(
poseName = "battle-standing",
poseTypes = PoseType.STATIONARY_POSES,
quirks = arrayOf(blink),
transformTicks = 10,
condition = { it.isBattling},
animations = arrayOf(
bedrock("omanyte", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("omanyte", "faint") else null
}
@@ -0,0 +1,102 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class OmastarModel(root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("omastar")
override var portraitTranslation = Vec3(0.02, -2.20, 0.0)
override var portraitScale = 2.4F
override var profileTranslation = Vec3(0.0, 0.066, 0.0)
override var profileScale = 1.1F
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
lateinit var float: CobblemonPose
lateinit var swim: CobblemonPose
lateinit var sleep: CobblemonPose
lateinit var battleidle: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("omastar", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("omastar", "blink") }
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("omastar", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STANDING_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
transformTicks = 10,
condition = { !it.isBattling},
animations = arrayOf(
bedrock("omastar", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES - PoseType.SWIM,
quirks = arrayOf(blink),
transformTicks = 10,
animations = arrayOf(
bedrock("omastar", "ground_walk")
)
)
float = registerPose(
poseName = "float",
poseTypes = setOf(PoseType.FLOAT, PoseType.HOVER),
quirks = arrayOf(blink),
transformTicks = 10,
animations = arrayOf(
bedrock("omastar", "water_idle")
)
)
swim = registerPose(
poseName = "swim",
poseTypes = setOf(PoseType.SWIM, PoseType.FLY),
quirks = arrayOf(blink),
transformTicks = 10,
animations = arrayOf(
bedrock("omastar", "water_swim")
)
)
battleidle = registerPose(
poseName = "battle-standing",
poseTypes = PoseType.STATIONARY_POSES,
quirks = arrayOf(blink),
transformTicks = 10,
condition = { it.isBattling},
animations = arrayOf(
bedrock("omastar", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("omastar", "faint") else null
}
@@ -0,0 +1,155 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen2
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import com.cobblemon.mod.common.util.isUnderWater
import com.cobblemon.mod.common.util.isInWater
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class FeraligatrModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame {
override val rootPart = root.registerChildWithAllChildren("feraligatr")
override val head = getPart("head_ai")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override var portraitScale = 1.3F
override var portraitTranslation = Vec3(-0.7, 1.1, 0.0)
override var profileScale = 0.6F
override var profileTranslation = Vec3(0.0, 0.8, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var floating: Pose
lateinit var swimming: Pose
lateinit var sleep: Pose
lateinit var watersleep: Pose
lateinit var battleidle: Pose
lateinit var water_surface_idle: Pose
lateinit var water_surface_swim: Pose
val wateroffset = -10
override val cryAnimation = CryProvider { bedrockStateful("feraligatr", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("feraligatr", "blink")}
sleep = registerPose(
poseName = "sleeping",
poseType = PoseType.SLEEP,
condition = { !it.isInWater },
animations = arrayOf(bedrock("feraligatr", "sleep"))
)
watersleep = registerPose(
poseName = "water_sleeping",
poseType = PoseType.SLEEP,
condition = { it.isInWater },
animations = arrayOf(bedrock("feraligatr", "water_sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.UI_POSES + PoseType.STAND,
transformTicks = 10,
condition = { !it.isBattling && !it.isInWater && !it.isUnderWater },
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("feraligatr", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
transformTicks = 10,
poseType = PoseType.WALK,
condition = { !it.isInWater && !it.isUnderWater },
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("feraligatr", "ground_walk")
)
)
floating = registerPose(
poseName = "floating",
transformTicks = 10,
poseType = PoseType.FLOAT,
condition = { it.isUnderWater },
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("feraligatr", "water_idle")
)
)
swimming = registerPose(
poseName = "swimming",
transformTicks = 10,
condition = { it.isUnderWater },
poseType = PoseType.SWIM,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("feraligatr", "water_swim"),
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling && !it.isInWater },
animations = arrayOf(
singleBoneLook(),
bedrock("feraligatr", "battle_idle")
)
)
water_surface_idle = registerPose(
poseName = "surface_idle",
poseTypes = PoseType.STATIONARY_POSES,
quirks = arrayOf(blink),
condition = { !it.isUnderWater && it.isInWater },
animations = arrayOf(
singleBoneLook(),
bedrock("feraligatr", "watersurface_idle"),
),
transformedParts = arrayOf(rootPart.createTransformation().addPosition(ModelPartTransformation.Y_AXIS, wateroffset))
)
water_surface_swim = registerPose(
poseName = "surface_swim",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
condition = { !it.isUnderWater && it.isInWater },
animations = arrayOf(
singleBoneLook(),
bedrock("feraligatr", "watersurface_swim"),
),
transformedParts = arrayOf(rootPart.createTransformation().addPosition(ModelPartTransformation.Y_AXIS, wateroffset))
)
}
override fun getFaintAnimation(state: PosableState) = if (state.isPosedIn(standing, walk, battleidle, sleep)) bedrockStateful("feraligatr", "faint") else if (state.isPosedIn(water_surface_idle, water_surface_swim, watersleep )) bedrockStateful("feraligatr", "faint") else null
}
@@ -0,0 +1,91 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen2
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class SmoochumModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("smoochum")
override val head = getPart("head")
override var portraitScale = 2.3F
override var portraitTranslation = Vec3(-0.14, -1.0, 0.0)
override var profileScale = 0.8F
override var profileTranslation = Vec3(0.0, 0.55, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var shoulderLeft: Pose
lateinit var shoulderRight: Pose
val shoulderOffset = 1
override fun registerPoses() {
// val blink = quirk { bedrockStateful("smoochum", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
// quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("smoochum", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
// quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("smoochum", "ground_idle")
)
)
shoulderLeft = registerPose(
poseType = PoseType.SHOULDER_LEFT,
//quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("smoochum", "ground_idle")
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, shoulderOffset)
)
)
shoulderRight = registerPose(
poseType = PoseType.SHOULDER_RIGHT,
//quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("smoochum", "ground_idle")
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, -shoulderOffset)
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("smoochum", "faint") else null
}
@@ -19,7 +19,7 @@ import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class TyphlosionHisuianModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("typhlosion")
override val rootPart = root.registerChildWithAllChildren("typhlosion_hisui")
override val head = getPart("head")
override var portraitScale = 1.4F
@@ -0,0 +1,67 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen2
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BimanualSwingAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class TyranitarModel(root: ModelPart) : PokemonPosableModel(root), BipedFrame, BimanualFrame, HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("tyranitar")
override val head = getPart("head")
override val leftArm = getPart("arm_left")
override val rightArm = getPart("arm_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override var portraitScale = 1.21F
override var portraitTranslation = Vec3(-0.43, 3.73, 0.0)
override var profileScale = 0.33F
override var profileTranslation = Vec3(0.02, 1.31, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("tyranitar", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("tyranitar", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(pitchMultiplier = 0.2F, yawMultiplier = 0.4F),
bedrock("tyranitar", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(pitchMultiplier = 0.2F, yawMultiplier = 0.4F),
bedrock("tyranitar", "ground_idle"),
BipedWalkAnimation(this, periodMultiplier = 0.6F, amplitudeMultiplier = 0.9F),
BimanualSwingAnimation(this, swingPeriodMultiplier = 0.6F, amplitudeMultiplier = 0.9F)
)
)
}
}
@@ -23,7 +23,7 @@ import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class WooperPaldeanModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("wooper")
override val rootPart = root.registerChildWithAllChildren("wooper_paldean")
override val head = getPart("head")
override var portraitScale = 2.0F
@@ -0,0 +1,78 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class LuvdiscModel (root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("luvdisc")
override var portraitScale = 6.0F
override var portraitTranslation = Vec3(0.15, -6.5, 0.0)
override var profileScale = 2.0F
override var profileTranslation = Vec3(0.0, -1.3, 0.0)
lateinit var standing: Pose
lateinit var sleep: Pose
lateinit var walk: Pose
lateinit var float: Pose
lateinit var swim: Pose
override fun registerPoses() {
val blink = quirk { bedrockStateful("luvdisc", "blink")}
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("luvdisc", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseType = PoseType.STAND,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("luvdisc", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseType = PoseType.WALK,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("luvdisc", "ground_walk")
)
)
float = registerPose(
poseName = "float",
poseTypes = PoseType.UI_POSES + PoseType.FLOAT,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("luvdisc", "water_idle")
)
)
swim = registerPose(
poseName = "swim",
poseType = PoseType.SWIM,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("luvdisc", "water_swim")
)
)
}
override fun getFaintAnimation(state: PosableState) = if (state.isPosedIn(standing, walk, sleep)) bedrockStateful("luvdisc", "ground_faint") else null
}
@@ -0,0 +1,170 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen4
import com.cobblemon.mod.common.client.render.models.blockbench.animation.WingFlapIdleAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BiWingedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.parabolaFunction
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.sineFunction
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.FLYING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.SHOULDER_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import com.cobblemon.mod.common.util.math.geometry.toRadians
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class ChatotModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BiWingedFrame{
override val rootPart = root.registerChildWithAllChildren("chatot")
override val leftWing = getPart("wing_left")
override val rightWing = getPart("wing_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override val head = getPart("head")
private val tail = getPart("tail")
override var portraitScale = 3.5F
override var portraitTranslation = Vec3(-0.1, -2.1, 0.0)
override var profileScale = 1.2F
override var profileTranslation = Vec3(0.0, -0.01, 0.0)
lateinit var sleep: Pose
lateinit var stand: Pose
lateinit var walk: Pose
lateinit var fly: Pose
override val cryAnimation = CryProvider { bedrockStateful("chatot", "cry") }
override fun registerPoses() {
// no sleep anim yet
// sleep = registerPose(
// poseType = PoseType.SLEEP,
// animations = arrayOf(bedrock("chatot", "sleep"))
// )
val blink = quirk { bedrockStateful("chatot", "blink") }
stand = registerPose(
poseName = "standing",
poseTypes = SHOULDER_POSES + UI_POSES + PoseType.STAND,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("chatot", "ground_idle")
)
)
fly = registerPose(
poseName = "hover",
poseTypes = FLYING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("chatot", "air_idle"),
WingFlapIdleAnimation(this,
flapFunction = sineFunction(verticalShift = -10F.toRadians(), period = 0.9F, amplitude = 0.6F),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Z_AXIS
)
)
)
walk = registerPose(
poseName = "walking",
poseType = PoseType.WALK,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("chatot", "ground_idle"),
rootPart.translation(
function = parabolaFunction(
peak = -4F,
period = 0.4F
),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Y_AXIS
),
head.translation(
function = sineFunction(
amplitude = (-20F).toRadians(),
period = 1F,
verticalShift = (-10F).toRadians()
),
axis = ModelPartTransformation.X_AXIS,
timeVariable = { state, _, _ -> state.animationSeconds }
),
leftLeg.rotation(
function = parabolaFunction(
tightness = -20F,
phaseShift = 0F,
verticalShift = (30F).toRadians()
),
axis = ModelPartTransformation.X_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
rightLeg.rotation(
function = parabolaFunction(
tightness = -20F,
phaseShift = 0F,
verticalShift = (30F).toRadians()
),
axis = ModelPartTransformation.X_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
tail.rotation(
function = sineFunction(
amplitude = (-5F).toRadians(),
period = 1F
),
axis = ModelPartTransformation.X_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
wingFlap(
flapFunction = sineFunction(
amplitude = (-5F).toRadians(),
period = 0.4F,
phaseShift = 0.00F,
verticalShift = (-20F).toRadians()
),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Z_AXIS
),
rightWing.translation(
function = parabolaFunction(
tightness = -10F,
phaseShift = 30F,
verticalShift = (25F).toRadians()
),
axis = ModelPartTransformation.Y_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
leftWing.translation(
function = parabolaFunction(
tightness = -10F,
phaseShift = 30F,
verticalShift = (25F).toRadians()
),
axis = ModelPartTransformation.Y_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
)
)
}
}
@@ -0,0 +1,86 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen7
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BimanualSwingAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class TurtonatorModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
override val rootPart = root.registerChildWithAllChildren("turtonator")
override val head = getPart("head")
override val leftArm = getPart("arm_left")
override val rightArm = getPart("arm_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override var portraitScale = 1.62F
override var portraitTranslation = Vec3(-1.14, 1.92, 0.0)
override var profileScale = 0.54F
override var profileTranslation = Vec3(-0.08, 0.87, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
lateinit var battleidle: CobblemonPose
override fun registerPoses() {
val blink = quirk { bedrockStateful("turtonator", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
condition = { !it.isBattling },
animations = arrayOf(
singleBoneLook(),
bedrock("turtonator", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("turtonator", "ground_idle"),
BipedWalkAnimation(this, periodMultiplier = 0.6F, amplitudeMultiplier = 0.9F),
BimanualSwingAnimation(this, swingPeriodMultiplier = 0.6F, amplitudeMultiplier = 0.9F)
//bedrock("turtonator", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
singleBoneLook(),
bedrock("turtonator", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("turtonator", "faint") else null
}
@@ -248,8 +248,10 @@ object VaryingModelRepository {
inbuilt("machop", ::MachopModel)
inbuilt("machoke", ::MachokeModel)
inbuilt("machamp", ::MachampModel)
inbuilt("arbok", ::ArbokModel)
inbuilt("chansey", ::ChanseyModel)
inbuilt("cubone", ::CuboneModel)
inbuilt("ditto", ::DittoModel)
inbuilt("dodrio", ::DodrioModel)
inbuilt("doduo", ::DoduoModel)
inbuilt("electabuzz", ::ElectabuzzModel)
@@ -276,6 +278,8 @@ object VaryingModelRepository {
inbuilt("nidoranm", ::NidoranmModel)
inbuilt("nidorina", ::NidorinaModel)
inbuilt("nidorino", ::NidorinoModel)
inbuilt("omanyte", ::OmanyteModel)
inbuilt("omastar", ::OmastarModel)
inbuilt("persian", ::PersianModel)
inbuilt("pinsir", ::PinsirModel)
inbuilt("poliwag", ::PoliwagModel)
@@ -289,6 +293,7 @@ object VaryingModelRepository {
inbuilt("venomoth", ::VenomothModel)
inbuilt("venonat", ::VenonatModel)
inbuilt("elekid", ::ElekidModel)
inbuilt("smoochum", ::SmoochumModel)
inbuilt("hitmontop", ::HitmontopModel)
inbuilt("electivire", ::ElectivireModel)
inbuilt("tangrowth", ::TangrowthModel)
@@ -350,6 +355,7 @@ object VaryingModelRepository {
inbuilt("whismur", :: WhismurModel)
inbuilt("loudred", :: LoudredModel)
inbuilt("exploud", :: ExploudModel)
inbuilt("luvdisc", :: LuvdiscModel)
inbuilt("cryogonal", :: CryogonalModel)
inbuilt("pumpkaboo", :: PumpkabooModel)
inbuilt("gourgeist", :: GourgeistModel)
@@ -391,6 +397,7 @@ object VaryingModelRepository {
inbuilt("tandemaus", ::TandemausModel)
inbuilt("fidough", ::FidoughModel)
inbuilt("dachsbun", ::DachsbunModel)
inbuilt("chatot", ::ChatotModel)
inbuilt("gligar", ::GligarModel)
inbuilt("gliscor", ::GliscorModel)
inbuilt("poochyena", ::PoochyenaModel)
@@ -480,6 +487,7 @@ object VaryingModelRepository {
inbuilt("phantump", ::PhantumpModel)
inbuilt("totodile", ::TotodileModel)
inbuilt("croconaw", ::CroconawModel)
inbuilt("feraligatr", ::FeraligatrModel)
inbuilt("cyndaquil", ::CyndaquilModel)
inbuilt("quilava", ::QuilavaModel)
inbuilt("typhlosion", ::TyphlosionModel)
@@ -536,6 +544,7 @@ object VaryingModelRepository {
inbuilt("petilil_hisui_bias", ::PetililHisuiBiasModel)
inbuilt("lilligant_hisuian", ::LilligantHisuianModel)
inbuilt("darumaka", ::DarumakaModel)
inbuilt("turtonator", ::TurtonatorModel)
inbuilt("cufant", ::CufantModel)
inbuilt("copperajah", ::CopperajahModel)
inbuilt("budew", ::BudewModel)
@@ -565,6 +574,7 @@ object VaryingModelRepository {
inbuilt("vibrava", ::VibravaModel)
inbuilt("larvitar", ::LarvitarModel)
inbuilt("pupitar", ::PupitarModel)
inbuilt("tyranitar", ::TyranitarModel)
inbuilt("impidimp", ::ImpidimpModel)
inbuilt("morgrem", ::MorgremModel)
inbuilt("grimmsnarl", ::GrimmsnarlModel)
@@ -1,76 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.player
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.entity.ItemRenderer
import net.minecraft.client.renderer.texture.OverlayTexture
/**
* Draws the recalling player's Poké Ball in first person, rising into view from the bottom of the
* screen in place of their held item. The world-space beam still starts near the hand (the eye/look
* fallback in PokemonRenderer), so this is cosmetic only.
*
* Called from ItemInHandRendererMixin, which cancels the vanilla main-hand item while recalling.
*/
object FirstPersonRecallBallRenderer {
/** Resting position of the ball in view space (right, up, forward). */
private const val REST_X = 0.45
private const val REST_Y = -0.55
private const val REST_Z = -.6
/** How far below REST_Y the ball starts before rising into view. */
private const val RISE_DISTANCE = 0.6
private const val BALL_SCALE = 0.45F
private val ballContext = RenderContext().also {
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.WORLD)
}
/**
* @return true if a recall ball was rendered (so the caller should cancel the vanilla item).
*/
fun render(poseStack: PoseStack, buffer: MultiBufferSource, packedLight: Int, partialTicks: Float): Boolean {
val player = Minecraft.getInstance().player ?: return false
val anim = RecallArmAnimationTracker.get(player.uuid) ?: return false
val rise = RecallArmAnimationTracker.raiseFactor(player.uuid)
poseStack.pushPose()
poseStack.translate(REST_X, REST_Y - RISE_DISTANCE * (1.0 - rise), REST_Z)
poseStack.scale(BALL_SCALE, -BALL_SCALE, -BALL_SCALE)
poseStack.mulPose(Axis.YP.rotationDegrees(180F))
poseStack.mulPose(Axis.XP.rotationDegrees(15F))
val state = anim.ballState
val ball = anim.ball
val model = VaryingModelRepository.getPoser(ball.name, state)
val texture = VaryingModelRepository.getTexture(ball.name, state)
state.updatePartialTicks(partialTicks)
model.context = ballContext
ballContext.put(RenderContext.ASPECTS, state.aspects)
ballContext.put(RenderContext.POSABLE_STATE, state)
model.applyAnimations(null, state, 0F, 0F, 0F, 0F, 0F)
val consumer = ItemRenderer.getFoilBufferDirect(buffer, RenderType.entityCutout(texture), false, false)
model.render(ballContext, poseStack, consumer, packedLight, OverlayTexture.NO_OVERLAY, -0x1)
model.red = 1F
model.green = 1F
model.blue = 1F
model.resetLayerContext()
poseStack.popPose()
return true
}
}
@@ -1,73 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.player
import com.cobblemon.mod.common.client.battle.ClientBallDisplay
import com.cobblemon.mod.common.pokeball.PokeBall
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap
import net.minecraft.util.Mth
import net.minecraft.world.phys.Vec3
/**
* Tracks which players are recalling a Pokémon so we can pose their arm, draw the Poké Ball in their
* hand, and start the recall beam from it.
*
* Keyed by player UUID. Entries time out on their own once the beam is done, and a new recall resets
* the timer, so nothing has to clear them.
*
* Written by PokemonClientDelegate on recall (beamMode 3); read by HumanoidModelMixin, the ball
* renderers, and PokemonRenderer.
*/
object RecallArmAnimationTracker {
// How long the arm stays raised, in seconds.
const val ARM_HOLD_SECONDS = 0.8
// Fraction of the hold spent easing the arm up at the start and down at the end.
private const val EASE_SECONDS = 0.15
class RecallAnim(
val ball: PokeBall,
val aspects: Set<String>,
val startTimeMs: Long
) {
val ballState = ClientBallDisplay(ball, aspects)
var beamOrigin: Vec3? = null
}
private val activeRecalls = ConcurrentHashMap<UUID, RecallAnim>()
fun start(playerUuid: UUID, ball: PokeBall, aspects: Set<String>) {
activeRecalls[playerUuid] = RecallAnim(ball, aspects, System.currentTimeMillis())
}
/** Returns the active recall for the player, or null if there is none or if it has expired. */
fun get(playerUuid: UUID): RecallAnim? {
val anim = activeRecalls[playerUuid] ?: return null
if (secondsSince(anim) > ARM_HOLD_SECONDS) {
activeRecalls.remove(playerUuid)
return null
}
return anim
}
fun isRecalling(playerUuid: UUID): Boolean = get(playerUuid) != null
private fun secondsSince(anim: RecallAnim) = (System.currentTimeMillis() - anim.startTimeMs) / 1000.0
/** 0..1 ramp: eases in at the start, holds at 1, eases out at the end. 0 when not recalling. */
fun raiseFactor(playerUuid: UUID): Float {
val anim = get(playerUuid) ?: return 0F
val elapsed = secondsSince(anim)
val riseIn = Mth.clamp((elapsed / EASE_SECONDS).toFloat(), 0F, 1F)
val fallOut = Mth.clamp(((ARM_HOLD_SECONDS - elapsed) / EASE_SECONDS).toFloat(), 0F, 1F)
return minOf(riseIn, fallOut)
}
}
@@ -26,7 +26,6 @@ import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PosableP
import com.cobblemon.mod.common.client.render.models.blockbench.repository.MiscModelRepository
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker
import com.cobblemon.mod.common.client.render.pokeball.PokeBallPosableState
import com.cobblemon.mod.common.client.render.renderBeaconBeam
import com.cobblemon.mod.common.client.settings.ServerSettings
@@ -61,7 +60,6 @@ import net.minecraft.network.chat.Style
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.Mth
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec3
import org.joml.*
import kotlin.math.*
@@ -71,9 +69,6 @@ class PokemonRenderer(
) : MobRenderer<PokemonEntity, PosablePokemonEntityModel>(context, PosablePokemonEntityModel(), 0.5f) {
companion object {
val recallBeamColour = Vector4f(1F, 0.1F, 0.1F, 1F)
private const val CAPTURE_BEAM_X_OFFSET = 0.0
private const val CAPTURE_BEAM_Y_OFFSET = 0.2
private const val CAPTURE_BEAM_Z_OFFSET = 0.45
fun ease(x: Double): Double {
return 1 - (1 - x).pow(3)
}
@@ -147,6 +142,8 @@ class PokemonRenderer(
}
modelNow.setLayerContext(buffer, clientDelegate, VaryingModelRepository.getLayers(entity.pokemon.species.resourceIdentifier, clientDelegate))
if (entity.passengers.isNotEmpty()) {
renderRiding(entity, entityYaw, partialTicks, poseMatrix, buffer, packedLight)
} else {
@@ -319,15 +316,8 @@ class PokemonRenderer(
fun renderBeam(matrixStack: PoseStack, partialTicks: Float, entity: PokemonEntity, beamTarget: Entity, buffer: MultiBufferSource, offset: Vec3) {
val clientDelegate = entity.delegate as PokemonClientDelegate
val pokemonPosition = entity.position().add(0.0, entity.bbHeight / 2.0 * clientDelegate.activeSendoutScale.toDouble(), 0.0)
// If a player is recalling, start the beam from the Poké Ball held in their hand
val recallBallOrigin = (beamTarget as? Player)?.let { RecallArmAnimationTracker.get(it.uuid)?.beamOrigin }
var beamSourcePosition = if (recallBallOrigin != null) {
recallBallOrigin
} else if (beamTarget is EmptyPokeBallEntity) {
(beamTarget.delegate as PokeBallPosableState).locatorStates["beam"]
?.transformPosition(Vec3(CAPTURE_BEAM_X_OFFSET, CAPTURE_BEAM_Y_OFFSET, CAPTURE_BEAM_Z_OFFSET))
?: beamTarget.position()
var beamSourcePosition = if (beamTarget is EmptyPokeBallEntity) {
(beamTarget.delegate as PokeBallPosableState).locatorStates["beam"]?.getOrigin() ?: beamTarget.position()
} else {
if (beamTarget.uuid == Minecraft.getInstance().player?.uuid) {
val lookVec = beamTarget.lookAngle.yRot((PI / 2).toFloat()).multiply(1.0, 0.0, 1.0).normalize()
@@ -28,7 +28,5 @@ object ServerSettings {
var maxPokemonFriendship = Cobblemon.config.maxPokemonFriendship
var maxDynamaxLevel = Cobblemon.config.maxDynamaxLevel
var unlockAllMoveDexMovesByDefault = Cobblemon.config.unlockAllMoveDexMovesByDefault
var pokemonIntrinsicSizeMin = Cobblemon.config.pokemonIntrinsicSizeMin
var pokemonIntrinsicSizeMax = Cobblemon.config.pokemonIntrinsicSizeMax
}
@@ -243,6 +243,18 @@ class CobblemonConfig {
@CobblemonConfigField(Category.Pokemon, lang = "pokemon_intrinsic_size_max", SERVER)
var pokemonIntrinsicSizeMax = 1.05F
@CobblemonConfigField(Category.Pokemon, lang = "alpha_pokemon_size_small_multiplier", SERVER)
var alphaPokemonSizeSmallMultiplier = 1.70F
@CobblemonConfigField(Category.Pokemon, lang = "alpha_pokemon_size_medium_multiplier", SERVER)
var alphaPokemonSizeMediumMultiplier = 1.55F
@CobblemonConfigField(Category.Pokemon, lang = "alpha_pokemon_size_large_multiplier", SERVER)
var alphaPokemonSizeLargeMultiplier = 1.40F
@CobblemonConfigField(Category.Pokemon, lang = "alpha_pokemon_size_extra_large_multiplier", SERVER)
var alphaPokemonSizeExtraLargeMultiplier = 1.25F
@CobblemonConfigField(Category.Pokemon, lang = "baby_pokemon_level_duration", SERVER)
var babyPokemonLevelDuration = 9
@@ -335,6 +347,9 @@ class CobblemonConfig {
// @CobblemonConfigField(Category.Riding, lang = "third_person_view_bobbing", CLIENT)
var thirdPersonViewBobbing = true
@CobblemonConfigField(Category.Riding, lang = "invert_roll", CLIENT)
var invertRoll = false
@CobblemonConfigField(Category.Riding, lang = "invert_pitch", CLIENT)
var invertPitch = false
@@ -350,6 +365,9 @@ class CobblemonConfig {
@CobblemonConfigField(Category.Riding, lang = "swap_x_and_y_axes", CLIENT)
var swapXAndYAxes = false
@CobblemonConfigField(Category.Riding, lang = "automatic_righting_delay", CLIENT)
var rightingDelay = -1.0
@CobblemonConfigField(Category.Riding, lang = "disable_roll", CLIENT)
var disableRoll = false
@@ -798,13 +798,6 @@ open class PokemonEntity(
return pokemon.isFireImmune()
}
/**
* Prevents ice type Pokémon from freezing (from powered snow)
*/
override fun canFreeze(): Boolean {
return !pokemon.isFreezeImmune() && super.canFreeze()
}
/**
* Prevents flying type Pokémon from taking fall damage.
*/
@@ -2729,4 +2722,9 @@ open class PokemonEntity(
}
fun hasRider() = this.passengers.any { it is LivingEntity }
override fun playStepSound(pos: BlockPos, state: BlockState) {
if (this.pokemon.species.silenceStepSounds) return
super.playStepSound(pos, state)
}
}
@@ -36,7 +36,7 @@ import net.minecraft.world.level.block.Block
class StatusCureItem(val itemName: String, vararg val status: Status, block: Block) : ItemNameBlockItem(block, Properties()), PokemonSelectingItem {
override val bagItem = object : BagItem {
override val itemName = this@StatusCureItem.itemName
override val returnItem = Items.GLASS_BOTTLE
override val returnItem = Items.AIR
override fun canUse(stack: ItemStack, battle: PokemonBattle, target: BattlePokemon) = canUseOnPokemon(stack, target.effectedPokemon)
override fun getShowdownInput(actor: BattleActor, battlePokemon: BattlePokemon, data: String?) = "cure_status${status.takeIf { it.isNotEmpty() }?.let { " ${it.joinToString(separator = " ") { it.showdownName } }" } ?: "" }"
}
@@ -26,9 +26,7 @@ class ServerSettingsPacket internal constructor(
val maxPokemonLevel: Int,
val maxPokemonFriendship: Int,
val maxDynamaxLevel: Int,
val unlockAllMoveDexMovesByDefault: Boolean,
val pokemonIntrinsicSizeMin: Float,
val pokemonIntrinsicSizeMax: Float
val unlockAllMoveDexMovesByDefault: Boolean
) : NetworkPacket<ServerSettingsPacket> {
override val id = ID
override fun encode(buffer: RegistryFriendlyByteBuf) {
@@ -39,14 +37,9 @@ class ServerSettingsPacket internal constructor(
buffer.writeInt(Cobblemon.config.maxPokemonFriendship)
buffer.writeInt(Cobblemon.config.maxDynamaxLevel)
buffer.writeBoolean(Cobblemon.config.unlockAllMoveDexMovesByDefault)
buffer.writeFloat(Cobblemon.config.pokemonIntrinsicSizeMin)
buffer.writeFloat(Cobblemon.config.pokemonIntrinsicSizeMax)
}
companion object {
val ID = cobblemonResource("server_settings")
fun decode(buffer: RegistryFriendlyByteBuf) = ServerSettingsPacket(buffer.readBoolean(),
buffer.readBoolean(), buffer.readBoolean(),
buffer.readInt(), buffer.readInt(), buffer.readInt(),
buffer.readBoolean(), buffer.readFloat(), buffer.readFloat())
fun decode(buffer: RegistryFriendlyByteBuf) = ServerSettingsPacket(buffer.readBoolean(), buffer.readBoolean(), buffer.readBoolean(), buffer.readInt(), buffer.readInt(), buffer.readInt(), buffer.readBoolean())
}
}
@@ -1037,10 +1037,6 @@ open class Pokemon : ShowdownIdentifiable {
return ElementalTypes.FIRE in types || form.behaviour.moving.swim.canSwimInLava || form.behaviour.fireImmune
}
fun isFreezeImmune(): Boolean {
return ElementalTypes.ICE in types || form.behaviour.freezeImmune
}
fun dampensVibrations(): Boolean = form.behaviour.dampensVibrations
// function to return the max hunger for the pokemon
@@ -8,7 +8,7 @@
package com.cobblemon.mod.common.pokemon
import com.cobblemon.mod.common.client.settings.ServerSettings
import com.cobblemon.mod.common.Cobblemon
enum class PokemonSizeCategory {
XS,
@@ -21,7 +21,7 @@ enum class PokemonSizeCategory {
// Find which size category corresponds to the given scale modifier.
// The scale modifier should be between the intrinsic min and max size.
fun fromScale(scaleModifier: Float): PokemonSizeCategory {
val config = ServerSettings //Don't use cobblemon config here as it will be used by server AND client
val config = Cobblemon.config
val minScale = config.pokemonIntrinsicSizeMin
val maxScale = config.pokemonIntrinsicSizeMax
val range = (maxScale - minScale).coerceAtLeast(0.0001F)
@@ -173,6 +173,7 @@ class Species : ShowdownIdentifiable {
.addStandardFunctions()
.addSpeciesFunctions(this)
var silenceStepSounds = false
fun initialize() {
Cobblemon.statProvider.provide(this)
@@ -256,6 +257,7 @@ class Species : ShowdownIdentifiable {
}
this.riding.encode(buffer)
buffer.writeBoolean(this.silenceStepSounds)
}
fun decode(buffer: RegistryFriendlyByteBuf) {
@@ -299,6 +301,7 @@ class Species : ShowdownIdentifiable {
}
}
this.riding = RidingProperties.decode(buffer)
this.silenceStepSounds = buffer.readBoolean()
this.initialize()
}
@@ -35,9 +35,6 @@ class FormPokemonBehaviour {
@SerializedName("fireImmune")
private val _fireImmune: Boolean? = null
@SerializedName("freezeImmune")
private val _freezeImmune: Boolean? = null
@SerializedName("dampensVibrations")
private val _dampensVibrations: Boolean? = null
@@ -75,9 +72,6 @@ class FormPokemonBehaviour {
val fireImmune: Boolean
get() = _fireImmune ?: parent.fireImmune
val freezeImmune: Boolean
get() = _freezeImmune ?: parent.freezeImmune
val entityInteract: EntityBehaviour
get() = _entityInteract ?: parent.entityInteract
@@ -318,7 +318,7 @@ class OmniPathNodeMaker : NodeEvaluator() {
// Hitbox thing looks confusing but if the hitbox volume is more than like, 5, it starts getting pretty
// fucking slow to use the findAcceptedNodeWalk function
val strictlyWalkPathing = !canFly() && !mob.isInWater
val strictlyWalkPathing = !canFly() && !mob.isInWater && mob.boundingBox.size < MAX_HITBOX_SIZE_FOR_WALKING
val doVerticalNeighbourChecks = (canFly() || mob.isInWater) && mob.boundingBox.size < MAX_HITBOX_FOR_VERTICAL_NEIGHBOURS
// Non-diagonal surroundings in 3d space
@@ -623,11 +623,9 @@ class OmniPathNodeMaker : NodeEvaluator() {
override fun getPathTypeOfMob(pfContext: PathfindingContext, x: Int, y: Int, z: Int, mob: Mob): PathType {
val set = EnumSet.noneOf(PathType::class.java)
// Capping the observed size of hitboxes here to put an upper limit on the cost of larger hitbox mobs
// Mobs larger than these caps will inevitably become stuck on obstacles as their pathing will be flawed
val sizeX = ((mob.boundingBox.maxX - mob.boundingBox.minX).toInt() + 1).coerceAtMost(2)
val sizeY = ((mob.boundingBox.maxY - mob.boundingBox.minY).toInt() + 1).coerceAtMost(3)
val sizeZ = ((mob.boundingBox.maxZ - mob.boundingBox.minZ).toInt() + 1).coerceAtMost(2)
val sizeX = (mob.boundingBox.maxX - mob.boundingBox.minX).toInt() + 1
val sizeY = (mob.boundingBox.maxY - mob.boundingBox.minY).toInt() + 1
val sizeZ = (mob.boundingBox.maxZ - mob.boundingBox.minZ).toInt() + 1
// TODO -- This is experimental code to see if this is meaningful. We should clean this up later when time permits.
val returnedEarlyPathType = mutableListOf<PathType>()
@@ -31,7 +31,6 @@ open class PokemonBehaviour(
val herd: HerdBehaviour = HerdBehaviour(),
val characteristicRainbow: Boolean = false,
val itemInteract: ItemBehavior = ItemBehavior(),
val freezeImmune: Boolean = false,
) {
@Transient
val struct = ObjectValue<PokemonBehaviour>(this).also {
@@ -274,9 +274,11 @@ object DataKeys {
// Habitat Blocks
const val HABITAT_SPAWNING_STYLE = "SpawningStyle"
const val HABITAT_MIMIC = "MimicId"
const val HABITAT_PHASE_COUNT = "PhaseCount"
const val HABITAT_PHASE_ORDER = "PhaseOrder"
const val HABITAT_LEVEL_RANGE = "LevelRange"
const val HABITAT_MODIFIERS = "Modifiers"
const val HABITAT_POOL = "Pool"
// --- Pools
const val HABITAT_POOL_ID = "PoolId"
@@ -13,10 +13,7 @@ import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.core.BlockPos
import net.minecraft.world.level.LevelReader
import net.minecraft.world.level.LevelHeightAccessor
import net.minecraft.world.level.chunk.ChunkGenerator
import net.minecraft.world.level.levelgen.Heightmap
import net.minecraft.world.level.levelgen.RandomState
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate
@@ -27,25 +24,6 @@ class HeightRangeStructureProcessor(
val reference: HeightReference = HeightReference.SEA_LEVEL
) : StructureProcessor() {
fun isValidPlacement(world: LevelReader, pos: BlockPos): Boolean {
val referenceY = reference.getY(world, pos)
val minY = referenceY + minOffset
val maxY = referenceY + maxOffset
return pos.y in minY..maxY
}
fun isValidPlacement(
chunkGenerator: ChunkGenerator,
heightAccessor: LevelHeightAccessor,
randomState: RandomState,
pos: BlockPos
): Boolean {
val referenceY = reference.getY(chunkGenerator, heightAccessor, randomState, pos)
val minY = referenceY + minOffset
val maxY = referenceY + maxOffset
return pos.y in minY..maxY
}
override fun processBlock(
world: LevelReader,
pos: BlockPos,
@@ -54,7 +32,11 @@ class HeightRangeStructureProcessor(
currentBlockInfo: StructureTemplate.StructureBlockInfo,
data: StructurePlaceSettings
): StructureTemplate.StructureBlockInfo? {
return if (isValidPlacement(world, pos)) {
val referenceY = reference.getY(world, pos)
val minY = referenceY + minOffset
val maxY = referenceY + maxOffset
return if (pos.y in minY..maxY) {
currentBlockInfo
} else {
null
@@ -83,19 +65,6 @@ class HeightRangeStructureProcessor(
}
}
fun getY(
chunkGenerator: ChunkGenerator,
heightAccessor: LevelHeightAccessor,
randomState: RandomState,
pos: BlockPos
): Int {
return if (this == SEA_LEVEL) {
chunkGenerator.seaLevel
} else {
chunkGenerator.getBaseHeight(pos.x, pos.z, type ?: Heightmap.Types.WORLD_SURFACE_WG, heightAccessor, randomState)
}
}
companion object {
val CODEC: Codec<HeightReference> = Codec.STRING.xmap(
{ serialized -> entries.firstOrNull { it.id == serialized } ?: SEA_LEVEL },
@@ -1,39 +0,0 @@
{
"format_version": "1.8.0",
"animations": {
"animation.playrough.actor": {
"animation_length": 3,
"bones": {
"root_part": {
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, 0, -3],
"0.0833": [0, 0, -6],
"0.125": [0, 0, -16],
"0.2917": [0, 0, -26],
"1.2083": [0, 0, -10],
"1.2917": [0, 0, -4],
"1.4167": [0, 0, 0]
},
"scale": {
"0.0": [1, 1, 1],
"0.0417": [1, 1, 1.05],
"0.0833": [1, 1, 1.2],
"0.125": {"pre": [0.9841, 0.9841, 1.6], "post": [0, 0, 0]},
"1.2083": {"pre": [0, 0, 0], "post": [1, 1, 1]}
}
}
},
"particle_effects": {
"0.0": {
"effect": "closecombat_actor",
"locator": "middle"
},
"0.0417": {
"effect": "closecombat_dashlines",
"locator": "middle"
}
}
}
}
}
@@ -1,72 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:blizzard_actor",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/impact/impact_ice"
}
},
"curves": {
"variable.bsizing": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 0.69, 0.96, 1, 1, 1, 1, 1, 1, 0.96, 0.82, 0]
}
},
"components": {
"minecraft:emitter_rate_steady": {
"spawn_rate": 900,
"max_particles": 10000
},
"minecraft:emitter_lifetime_once": {
"active_time": 1.1
},
"minecraft:emitter_shape_box": {
"offset": [0, 4, 2],
"half_dimensions": [10, 4, 10],
"direction": ["(v.particle_random_1-0.5)*0.5", "(v.target_deltay/v.target_distance)+((v.particle_random_2-0.5)*0.5)", -1]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(0.9,1.4)*1.1"
},
"minecraft:particle_initial_speed": "(v.particle_random_4+1)*16",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": ["math.sin(v.particle_age*((v.particle_random_2-0.5)*(360+(v.particle_random_2*180))))*1.5", "math.cos(v.particle_age*((v.particle_random_4-0.5)*(360+(v.particle_random_2*180))))*2", "math.sin(v.particle_age*((v.particle_random_1-0.5)*(360+(v.particle_random_2*180))))*1.5"],
"linear_drag_coefficient": 1.5
},
"minecraft:particle_appearance_billboard": {
"size": ["0.1*v.bsizing", "0.1*v.bsizing"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 8,
"texture_height": 56,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [8, 8],
"step_UV": [0, 8],
"frames_per_second": 10,
"max_frame": 7,
"loop": true
}
}
},
"minecraft:particle_motion_collision": {
"collision_drag": 0.2,
"coefficient_of_restitution": 0.05,
"collision_radius": 0.1
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFFFFF",
"1.0": "#FFAAD4FF"
}
}
}
}
}
}
@@ -1,73 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:blizzard_target",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/impact/impact_ice"
}
},
"curves": {
"variable.dfd": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 0.69, 0.96, 1, 1, 1, 0.96, 0.82, 0]
}
},
"components": {
"minecraft:emitter_initialization": {
"creation_expression": "v.entity_height=1;"
},
"minecraft:emitter_rate_steady": {
"spawn_rate": 1000,
"max_particles": 10000
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.1
},
"minecraft:emitter_shape_point": {
"direction": ["(v.particle_random_1-0.5)*3", "(v.particle_random_2-0.5)*3", "(v.particle_random_3-0.5)*3"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "0.6+(v.particle_random_4*0.4)"
},
"minecraft:particle_initial_speed": "math.random(1.25,4.75)*7",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": ["(v.particle_random_3-0.5)*16", "(v.particle_random_4-0.5)*16", "(v.particle_random_2-0.5)*16"],
"linear_drag_coefficient": 4
},
"minecraft:particle_appearance_billboard": {
"size": ["0.1*v.dfd", "0.1*v.dfd"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 8,
"texture_height": 56,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [8, 8],
"step_UV": [0, 8],
"frames_per_second": 10,
"max_frame": 7,
"stretch_to_lifetime": true
}
}
},
"minecraft:particle_motion_collision": {
"collision_drag": 0.2,
"coefficient_of_restitution": 0.6,
"collision_radius": 0.1
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFFFFF",
"1.0": "#FFAAD4FF"
}
}
}
}
}
}
@@ -1,64 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:blizzard_targetswirl",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/impact/impact_ice"
}
},
"curves": {
"variable.dfd": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 0.69, 0.96, 1, 1, 1, 0.96, 0.82, 0]
}
},
"components": {
"minecraft:emitter_initialization": {
"creation_expression": "v.entity_height=1;"
},
"minecraft:emitter_rate_steady": {
"spawn_rate": 200,
"max_particles": 10000
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.7
},
"minecraft:emitter_shape_point": {},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "0.6+(v.particle_random_4*0.4)"
},
"minecraft:particle_motion_parametric": {
"relative_position": ["(math.sin((v.particle_age*420)+(v.particle_random_1*360))*(math.clamp(v.entity_radius*1.04,0.65,4)+(v.particle_age*1.7)))", "(math.cos((v.particle_age*410)+(v.particle_random_1*360))*0.25)+((((v.particle_random_2-0.5)*2)*(v.entity_height*0.65))+((v.particle_age+v.particle_age)*(v.particle_random_4-0.5)))", "(math.cos((v.particle_age*410)+(v.particle_random_1*360))*(math.clamp(v.entity_radius*1.04,0.65,4)+(v.particle_age*1.7)))"]
},
"minecraft:particle_appearance_billboard": {
"size": ["0.1*v.dfd", "0.1*v.dfd"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 8,
"texture_height": 56,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [8, 8],
"step_UV": [0, 8],
"frames_per_second": 10,
"max_frame": 7,
"loop": true
}
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFFFFF",
"1.0": "#FFAAD4FF"
}
}
}
}
}
}
@@ -37,7 +37,7 @@
"minecraft:particle_motion_dynamic": {},
"minecraft:particle_appearance_billboard": {
"size": ["0.35+(v.particle_age*0.175)", "0.35+(v.particle_age*0.175)"],
"facing_camera_mode": "emitter_transform_xy",
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 117,
"texture_height": 13,
@@ -48,7 +48,7 @@
0.55,
0.55
],
"facing_camera_mode": "emitter_transform_xy",
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 68,
"texture_height": 17,
@@ -1,60 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:disarmingvoice_actor1",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/generic/ring/largering"
}
},
"components": {
"minecraft:emitter_initialization": {
"creation_expression": "v.target_deltaz=5;"
},
"minecraft:emitter_rate_steady": {
"spawn_rate": 8,
"max_particles": 7
},
"minecraft:emitter_lifetime_once": {
"active_time": 1.1
},
"minecraft:emitter_shape_point": {
"offset": ["v.target_deltax*(v.emitter_age/v.emitter_lifetime)", "v.target_deltay*(v.emitter_age/v.emitter_lifetime)", "-(v.target_deltaz*(v.emitter_age/v.emitter_lifetime))"],
"direction": [0, "(v.target_deltay/v.target_distance)", -1]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.43
},
"minecraft:particle_initial_speed": "math.clamp(v.target_deltaz,1,12)",
"minecraft:particle_motion_dynamic": {
"linear_drag_coefficient": "math.clamp(v.target_deltaz*1.5,3,10)"
},
"minecraft:particle_appearance_billboard": {
"size": [0.75, 0.75],
"facing_camera_mode": "emitter_transform_xy",
"uv": {
"texture_width": 160,
"texture_height": 20,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [20, 20],
"step_UV": [20, 0],
"frames_per_second": 20,
"max_frame": 8
}
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFECFE",
"0.47": "#FFFF89E8",
"1.0": "#FFE600BA"
}
}
}
}
}
}
@@ -1,60 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:disarmingvoice_actor2",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/generic/ring/mediumring"
}
},
"components": {
"minecraft:emitter_initialization": {
"creation_expression": "v.target_deltaz=5;"
},
"minecraft:emitter_rate_steady": {
"spawn_rate": 8,
"max_particles": 7
},
"minecraft:emitter_lifetime_once": {
"active_time": 1.1
},
"minecraft:emitter_shape_point": {
"offset": ["v.target_deltax*(v.emitter_age/v.emitter_lifetime)", "v.target_deltay*(v.emitter_age/v.emitter_lifetime)", "-(v.target_deltaz*(v.emitter_age/v.emitter_lifetime))"],
"direction": [0, "(v.target_deltay/v.target_distance)", -1]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.3
},
"minecraft:particle_initial_speed": "math.clamp(v.target_deltaz,1,12)",
"minecraft:particle_motion_dynamic": {
"linear_drag_coefficient": "math.clamp(v.target_deltaz*1.5,3,10)"
},
"minecraft:particle_appearance_billboard": {
"size": [0.55, 0.55],
"facing_camera_mode": "emitter_transform_xy",
"uv": {
"texture_width": 90,
"texture_height": 15,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [15, 15],
"step_UV": [15, 0],
"frames_per_second": 20,
"max_frame": 6
}
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFECFE",
"0.47": "#FFFF89E8",
"1.0": "#FFE600BA"
}
}
}
}
}
}
@@ -1,63 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:disarmingvoice_actorhearts",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/status/infatuation_heart"
}
},
"curves": {
"variable.d": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 0.93, 1, 1, 1, 0.93, 0.61, 0]
}
},
"components": {
"minecraft:emitter_initialization": {
"creation_expression": "v.target_deltaz=5;"
},
"minecraft:emitter_rate_steady": {
"spawn_rate": 25,
"max_particles": 2000
},
"minecraft:emitter_lifetime_once": {
"active_time": 1.1
},
"minecraft:emitter_shape_point": {
"offset": ["(v.target_deltax*(v.emitter_age/v.emitter_lifetime))+math.sin(v.emitter_age*360*7.5)*0.7", "(v.target_deltay*(v.emitter_age/v.emitter_lifetime))+math.cos(v.emitter_age*360*7.5)*0.7", "-(v.target_deltaz*(v.emitter_age/v.emitter_lifetime))"],
"direction": [0, "(v.target_deltay/v.target_distance)", -1]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.45
},
"minecraft:particle_initial_speed": "v.target_deltaz*0.5",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": ["(v.particle_random_1-0.5)", "(v.particle_random_2-0.5)", "(v.particle_random_3-0.5)"],
"linear_drag_coefficient": 4
},
"minecraft:particle_appearance_billboard": {
"size": ["(0.1-(v.particle_random_4*0.04))*v.d", "(0.1-(v.particle_random_4*0.04))*v.d"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 90,
"texture_height": 9,
"uv": [3, 3],
"uv_size": [3, 3]
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFF89E8",
"1.0": "#FFE600BA"
}
}
}
}
}
}
@@ -1,70 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:disarmingvoice_target",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/generic/ring/xlring"
}
},
"curves": {
"variable.s": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0.24, 0.69, 0.9, 0.98, 1, 1, 1, 1, 1, 1, 1, 1, 1]
}
},
"events": {
"event": {
"particle_effect": {
"effect": "cobblemon:disarmingvoice_targetsparks",
"type": "emitter"
}
}
},
"components": {
"minecraft:emitter_rate_instant": {
"num_particles": 1
},
"minecraft:emitter_lifetime_once": {
"active_time": 1.1
},
"minecraft:emitter_lifetime_events": {
"creation_event": "event"
},
"minecraft:emitter_shape_point": {},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.43
},
"minecraft:particle_initial_speed": 0,
"minecraft:particle_motion_dynamic": {},
"minecraft:particle_appearance_billboard": {
"size": ["1*v.s", "1*v.s"],
"facing_camera_mode": "emitter_transform_xy",
"uv": {
"texture_width": 160,
"texture_height": 20,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [20, 20],
"step_UV": [20, 0],
"frames_per_second": 20,
"max_frame": 8
}
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFECFE",
"0.47": "#FFFF89E8",
"1.0": "#FFE600BA"
}
}
}
}
}
}
@@ -1,64 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:disarmingvoice_targetsparks",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/orb/scaling"
}
},
"curves": {
"variable.size": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 1, 0.98, 0.86, 0.6, 0]
}
},
"components": {
"minecraft:emitter_rate_instant": {
"num_particles": 10
},
"minecraft:emitter_lifetime_once": {
"active_time": 1
},
"minecraft:emitter_shape_point": {
"direction": ["math.random(-0.91,0.91)", "math.random(-0.81, 1.01)", "math.random(-0.91,0.91)"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(0.45, 0.6)"
},
"minecraft:particle_initial_speed": "(0.8+(v.particle_random_4*0.6))*10",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": ["(v.particle_random_1-0.5)*7", "(v.particle_random_2-0.5)*7", "(v.particle_random_3-0.5)*7"],
"linear_drag_coefficient": 5
},
"minecraft:particle_appearance_billboard": {
"size": ["0.11*v.size", "0.11*v.size"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 8,
"texture_height": 32,
"flipbook": {
"base_UV": [0, 16],
"size_UV": [8, 8],
"step_UV": [0, -8],
"frames_per_second": 12,
"max_frame": 3,
"stretch_to_lifetime": true
}
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFECFE",
"0.93": "#FFE600BA"
}
}
}
}
}
}
@@ -1,77 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:dragonbreath_actor",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/fire/cloudyfire_white"
}
},
"curves": {
"variable.fun": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [1, 1, 1, 1, 0.99, 0.97, 0.91, 0.77, 0.54, -0.1]
}
},
"components": {
"minecraft:emitter_initialization": {
"creation_expression": "v.target_deltaz=5;v.target_deltax=0;v.target_deltay=0;"
},
"minecraft:emitter_rate_steady": {
"spawn_rate": "30*(math.clamp(v.target_deltaz,1,4))",
"max_particles": 1000
},
"minecraft:emitter_lifetime_once": {
"active_time": 1
},
"minecraft:emitter_shape_point": {
"direction": ["(-v.target_deltax+((v.particle_random_1-0.5)*1.05))+(math.sin(v.emitter_age*360)*0.25)", "(v.target_deltay+((v.particle_random_2-0.5)*1.05))+(math.sin(v.emitter_age*540)*0.2)", "-v.target_deltaz*1.05"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(0.75,1.0)*1.4"
},
"minecraft:particle_initial_spin": {
"rotation": "math.round(v.particle_random_4*3)*90"
},
"minecraft:particle_initial_speed": "(v.target_deltaz*((v.particle_random_4+0.75)*1.15))*(math.clamp(v.target_deltaz,3,24)/1.7)",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": ["(v.particle_random_3-0.5)*4", "3+(v.particle_random_1-0.5)*2", "(v.particle_random_2-0.5)*1"],
"linear_drag_coefficient": "math.clamp(v.target_deltaz,1,20)*(0.5+(math.clamp(v.target_deltaz,1,5)*0.05))"
},
"minecraft:particle_appearance_billboard": {
"size": ["(0.5-(v.particle_random_4*0.15))*v.fun", "(0.5-(v.particle_random_4*0.15))*v.fun"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 160,
"texture_height": 16,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [16, 16],
"step_UV": [16, 0],
"frames_per_second": 12,
"max_frame": 10
}
}
},
"minecraft:particle_motion_collision": {
"collision_drag": 10,
"collision_radius": 0.01
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "(v.particle_age / v.particle_lifetime) * (v.particle_random_4+0.75)",
"gradient": {
"0.0": "#FFFFE6A1",
"0.05": "#FFFFE6A1",
"0.2": "#FFFF3B8F",
"0.6": "#FFA300FF",
"1.0": "#FF3E00C7"
}
}
}
}
}
}
@@ -1,71 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:dragonbreath_target",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/generic/fire/cloudyfire_white"
}
},
"curves": {
"variable.dorasize": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0.42, 0.77, 0.91, 0.98, 1, 1, 1, 1, 1, 0.86, 0.55, 0]
}
},
"components": {
"minecraft:emitter_rate_steady": {
"spawn_rate": 250,
"max_particles": 150
},
"minecraft:emitter_lifetime_looping": {
"active_time": 0.3
},
"minecraft:emitter_shape_point": {
"offset": [0, 0, "math.random(0.15,-0.05)"],
"direction": ["math.random(-2,2)*1.1", "math.random(-2,2)*1.1", "math.random(-2,2)*0.45"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(0.65,1.0)*1.4"
},
"minecraft:particle_initial_speed": "math.random(1.25,4.75)*1.25",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": [0, "math.random(1.5,3.5)", 0],
"linear_drag_coefficient": "math.random(1.25,1.5)*2"
},
"minecraft:particle_appearance_billboard": {
"size": ["(0.5-(v.particle_random_4*0.15))*v.dorasize", "(0.5-(v.particle_random_4*0.15))*v.dorasize"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 160,
"texture_height": 16,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [16, 16],
"step_UV": [16, 0],
"frames_per_second": 12,
"max_frame": 10
}
}
},
"minecraft:particle_motion_collision": {
"coefficient_of_restitution": 0.1,
"collision_radius": 0.1
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFE6A1",
"0.35": "#FFFF3B8F",
"0.7": "#FFA300FF",
"1.0": "#FF3E00C7"
}
}
}
}
}
}
@@ -1,74 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:dragonrage_actor",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/fire/cloudyfire_white"
}
},
"curves": {
"variable.fun": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [1, 1, 1, 0.99, 0.95, 0.8, 0.5, 0.05]
}
},
"components": {
"minecraft:emitter_initialization": {
"creation_expression": "v.target_deltaz=5;"
},
"minecraft:emitter_rate_steady": {
"spawn_rate": 60,
"max_particles": 300
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.65
},
"minecraft:emitter_shape_point": {
"offset": ["-v.target_deltax*(v.emitter_age/v.emitter_lifetime)", "v.target_deltay*(v.emitter_age/v.emitter_lifetime)", "-v.target_deltaz*(v.emitter_age/v.emitter_lifetime)"],
"direction": ["math.random(-0.45,0.45)", "math.random(-0.45,0.45)-(v.target_deltay/v.target_deltaz)", "math.random(-2.05,-0.55)"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.7
},
"minecraft:particle_initial_spin": {
"rotation": "math.round(v.particle_random_4*3)*90"
},
"minecraft:particle_initial_speed": "math.random(2.75,3.25)*(v.target_deltaz*0.5)",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": ["(v.particle_random_1-0.5)*4", "1.5+(v.particle_random_1-0.5)*3", "(v.particle_random_1-0.5)*3"],
"linear_drag_coefficient": 4
},
"minecraft:particle_appearance_billboard": {
"size": ["0.45*v.fun", "0.45*v.fun"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 160,
"texture_height": 16,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [16, 16],
"step_UV": [16, 0],
"frames_per_second": 20,
"max_frame": 10
}
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFA1A1",
"0.05": "#FFFFA1A1",
"0.2": "#FFFF3BF2",
"0.6": "#FF7C00FF",
"1.0": "#FF3E00C7"
}
}
}
}
}
}
@@ -1,85 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:dragonrage_actorburst",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/fire/cloudyfire_white"
}
},
"curves": {
"variable.fun": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [1, 1, 1, 1, 0.97, 0.87, 0.54, 0]
}
},
"events": {
"ring": {
"particle_effect": {
"effect": "cobblemon:dragonrage_actorring",
"type": "emitter"
}
}
},
"components": {
"minecraft:emitter_rate_steady": {
"spawn_rate": 200,
"max_particles": 1000
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.1
},
"minecraft:emitter_lifetime_events": {
"creation_event": "ring"
},
"minecraft:emitter_shape_point": {
"direction": ["math.random(-1.05,1.05)*1.25", "math.random(-1.05,1.05)*1.25", "math.random(-1.25,-0.05)"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(0.4,0.8)"
},
"minecraft:particle_initial_spin": {
"rotation": "math.round(v.particle_random_4*3)*90"
},
"minecraft:particle_initial_speed": "math.random(2.5,7.5)*2",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": ["(v.particle_random_1-0.5)*4", "3+(v.particle_random_1-0.5)*3", "(v.particle_random_1-0.5)*1"],
"linear_drag_coefficient": 4
},
"minecraft:particle_appearance_billboard": {
"size": ["(0.5-(v.particle_random_4*0.15))*v.fun", "(0.5-(v.particle_random_4*0.15))*v.fun"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 160,
"texture_height": 16,
"flipbook": {
"base_UV": [16, 0],
"size_UV": [16, 16],
"step_UV": [16, 0],
"frames_per_second": 20,
"max_frame": 9
}
}
},
"minecraft:particle_motion_collision": {
"collision_drag": 10,
"collision_radius": 0.01
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFA1A1",
"0.05": "#FFFFA1A1",
"0.2": "#FFFF3BF2",
"0.6": "#FF7C00FF",
"1.0": "#FF3E00C7"
}
}
}
}
}
}
@@ -1,63 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:dragonrage_actorring",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/generic/ring/xlring"
}
},
"curves": {
"variable.s": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 0.57, 0.84, 0.96, 1, 1, 1, 1, 1, 1, 1]
}
},
"components": {
"minecraft:emitter_rate_instant": {
"num_particles": 1
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.05
},
"minecraft:emitter_shape_point": {
"offset": [0, 0, -0.1]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.45
},
"minecraft:particle_initial_speed": 0,
"minecraft:particle_motion_dynamic": {},
"minecraft:particle_appearance_billboard": {
"size": ["1.2*v.s", "1.2*v.s"],
"facing_camera_mode": "emitter_transform_xy",
"uv": {
"texture_width": 200,
"texture_height": 25,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [25, 25],
"step_UV": [25, 0],
"frames_per_second": 20,
"max_frame": 8
}
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFA1A1",
"0.05": "#FFFFA1A1",
"0.2": "#FFFF3BF2",
"0.78": "#FF6600C7",
"1.0": "#003E00C7"
}
}
}
}
}
}
@@ -1,84 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:dragonrage_target",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/fire/cloudyfire_white"
}
},
"curves": {
"variable.fun": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [1, 1, 1, 1, 1, 1, 0.96, 0.85, 0.6, -0.05]
}
},
"events": {
"cover": {
"particle_effect": {
"effect": "cobblemon:dragonrage_targetcover",
"type": "emitter_bound"
}
}
},
"components": {
"minecraft:emitter_rate_instant": {
"num_particles": "30*math.clamp(v.entity_height,1,2)"
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.05
},
"minecraft:emitter_lifetime_events": {
"creation_event": "cover"
},
"minecraft:emitter_shape_point": {
"direction": ["math.random(-1.55,1.55)", "math.random(-1.55,1.55)", "math.random(-1.55,1.55)"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(0.35,0.95)"
},
"minecraft:particle_initial_spin": {
"rotation": "math.round(v.particle_random_4*3)*90"
},
"minecraft:particle_initial_speed": "math.random(3,8.5)*math.clamp(v.entity_height,1,1.5)",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": ["(v.particle_random_1-0.5)*5", "4+(v.particle_random_2-0.5)*3", "(v.particle_random_3-0.5)*5"],
"linear_drag_coefficient": 3
},
"minecraft:particle_appearance_billboard": {
"size": ["(0.5-(v.particle_random_4*0.15))*v.fun", "(0.5-(v.particle_random_4*0.15))*v.fun"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 160,
"texture_height": 16,
"flipbook": {
"base_UV": [16, 0],
"size_UV": [16, 16],
"step_UV": [16, 0],
"frames_per_second": 20,
"max_frame": 9
}
}
},
"minecraft:particle_motion_collision": {
"collision_drag": 10,
"collision_radius": 0.01
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFA1A1",
"0.05": "#FFFFA1A1",
"0.2": "#FFFF3BF2",
"0.6": "#FF7C00FF",
"1.0": "#FF3E00C7"
}
}
}
}
}
}
@@ -1,78 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:dragonrage_targetcover",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/fire/cloudyfire_white"
}
},
"curves": {
"variable.burstarc": {
"type": "linear",
"input": "v.emitter_age",
"horizontal_range": "v.emitter_lifetime",
"nodes": [0.06, 0.5, 0.78, 0.91, 0.97, 0.99, 0.96, 0.83, 0.55, 0.06]
},
"variable.fun": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [1, 1, 1, 1, 1, 1, 0.96, 0.85, 0.6, -0.05]
}
},
"components": {
"minecraft:emitter_rate_steady": {
"spawn_rate": "25*math.clamp(v.entity_height,1,2)",
"max_particles": 1000
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.75
},
"minecraft:emitter_shape_sphere": {
"radius": "(v.entity_height*(0.7-(v.particle_random_4*0.15)))*math.clamp(v.entity_scale,0.5,1))",
"surface_only": true,
"direction": ["math.random(-0.45,0.45)", "math.random(-0.15,0.35)", "math.random(-0.45,0.45)"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(0.45,0.75)"
},
"minecraft:particle_initial_spin": {
"rotation": "math.round(v.particle_random_4*3)*90"
},
"minecraft:particle_initial_speed": 1,
"minecraft:particle_motion_dynamic": {
"linear_acceleration": ["(v.particle_random_1-0.5)*4", "3+(v.particle_random_1-0.5)*2", "(v.particle_random_1-0.5)*4"],
"linear_drag_coefficient": 2
},
"minecraft:particle_appearance_billboard": {
"size": ["0.4*v.fun", "0.4*v.fun"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 160,
"texture_height": 16,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [16, 16],
"step_UV": [16, 0],
"frames_per_second": 20,
"max_frame": 10
}
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFA1A1",
"0.05": "#FFFFA1A1",
"0.2": "#FFFF3BF2",
"0.6": "#FF7C00FF",
"1.0": "#FF3E00C7"
}
}
}
}
}
}
@@ -1,78 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:drainpunch_actor",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/generic/orb/xsfadeorblite"
}
},
"curves": {
"variable.drainopen": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0.35, 0.8, 0.98, 1, 1, 1, 1, 0.98, 0.9, 0.65, 0.01]
}
},
"events": {
"sparkle": {
"particle_effect": {
"effect": "cobblemon:megadrain_actortrail",
"type": "particle"
}
}
},
"components": {
"minecraft:emitter_rate_steady": {
"spawn_rate": 15,
"max_particles": 32
},
"minecraft:emitter_lifetime_looping": {
"active_time": 1.3
},
"minecraft:emitter_shape_point": {},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.7
},
"minecraft:particle_lifetime_events": {
"timeline": {
"0.05": "sparkle",
"0.15": "sparkle",
"0.33": "sparkle",
"0.45": "sparkle"
}
},
"minecraft:particle_motion_parametric": {
"relative_position": ["(math.sin((v.particle_age*65)+(v.emitter_age*1523))*(0.75-(v.particle_age*(v.particle_age*1.7)))*v.drainopen)-(v.target_deltax*0.9)+((v.target_deltax * (v.particle_age / v.particle_lifetime))*0.95)", "(math.cos((v.particle_age*65)+(v.emitter_age*1523))*(0.75-(v.particle_age*(v.particle_age*1.7)))*v.drainopen)+(v.target_deltay*0.9)-((v.target_deltay * (v.particle_age / v.particle_lifetime))*0.95)", "-(v.target_deltaz*0.9)+((v.target_deltaz*(v.particle_age / v.particle_lifetime))*0.95)"]
},
"minecraft:particle_appearance_billboard": {
"size": [0.135, 0.135],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 45,
"texture_height": 5,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [5, 5],
"step_UV": [5, 0],
"frames_per_second": 12,
"max_frame": 9
}
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#8FC48F00",
"0.25": "#DFFFE74E",
"0.85": "#DFBDF700",
"1.0": "#4F65D000"
}
}
}
}
}
}
@@ -1,81 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:drainpunch_target",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/generic/bigfist"
}
},
"curves": {
"variable.punch": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0.54, 0.27, 0, 0.06, 0.1, 0.13, 0.15, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16]
}
},
"events": {
"burst": {
"particle_effect": {
"effect": "cobblemon:drainpunch_targetburst",
"type": "emitter"
}
},
"ring": {
"particle_effect": {
"effect": "cobblemon:drainpunch_targetring",
"type": "emitter"
}
}
},
"components": {
"minecraft:emitter_rate_instant": {
"num_particles": 1
},
"minecraft:emitter_lifetime_looping": {
"active_time": 1
},
"minecraft:emitter_lifetime_events": {
"timeline": {
"0.05": ["burst", "ring"]
}
},
"minecraft:emitter_shape_point": {},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.65
},
"minecraft:particle_initial_speed": 0,
"minecraft:particle_motion_dynamic": {},
"minecraft:particle_appearance_billboard": {
"size": ["0.6+v.punch", "0.6+v.punch"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 270,
"texture_height": 30,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [30, 30],
"step_UV": [30, 0],
"frames_per_second": 14,
"max_frame": 9
}
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFF7A00",
"0.2": "#FFFFA700",
"0.25": "#FFFFF390",
"0.43": "#FFFF7A00",
"0.65": "#FFB84100",
"1.0": "#005F1D00"
}
}
}
}
}
}
@@ -1,73 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:drainpunch_targetburst",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/orb/xsfadeorblite"
}
},
"curves": {
"variable.scale": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 1, 0.97, 0.94, 0.89, 0.83, 0.68, 0.52, 0.26, 0]
}
},
"components": {
"minecraft:emitter_rate_steady": {
"spawn_rate": 300,
"max_particles": 10000
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.05
},
"minecraft:emitter_shape_point": {
"direction": ["(v.particle_random_1-0.5)*6", "(v.particle_random_2-0.5)*6", "(v.particle_random_3-0.5)*4"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(0.5,0.8)"
},
"minecraft:particle_initial_spin": {
"rotation": "math.round(v.particle_random_2*3)*90"
},
"minecraft:particle_initial_speed": "(3+(v.particle_random_4*5))*3.5",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": ["(v.particle_random_1-0.5)*12", "(v.particle_random_2-0.5)*12", "(v.particle_random_3-0.5)*12"],
"linear_drag_coefficient": 8
},
"minecraft:particle_appearance_billboard": {
"size": ["(0.1-(v.particle_random_4*0.06))*variable.scale", "(0.1-(v.particle_random_4*0.06))*variable.scale"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 45,
"texture_height": 5,
"flipbook": {
"base_UV": [10, 0],
"size_UV": [5, 5],
"step_UV": [5, 0],
"frames_per_second": 16,
"max_frame": 7
}
}
},
"minecraft:particle_motion_collision": {
"collision_drag": 1,
"collision_radius": 0.01,
"expire_on_contact": true
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age/v.particle_lifetime",
"gradient": {
"0.0": "#FFFF7A00",
"0.2": "#FFFFF390",
"1.0": "#FFFF7A00"
}
}
}
}
}
}
@@ -1,59 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:drainpunch_targetring",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/generic/ring/xlring"
}
},
"curves": {
"variable.s": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 0.56, 0.88, 0.98, 1, 1, 1, 1, 1]
}
},
"components": {
"minecraft:emitter_rate_instant": {
"num_particles": 1
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.5
},
"minecraft:emitter_shape_point": {},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.4
},
"minecraft:particle_initial_speed": 0,
"minecraft:particle_motion_dynamic": {},
"minecraft:particle_appearance_billboard": {
"size": ["1.05*v.s", "1.05*v.s"],
"facing_camera_mode": "emitter_transform_xy",
"uv": {
"texture_width": 200,
"texture_height": 25,
"flipbook": {
"base_UV": [50, 0],
"size_UV": [25, 25],
"step_UV": [25, 0],
"frames_per_second": 16,
"max_frame": 6
}
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFF390",
"0.79": "#FFFF7A00",
"1.0": "#FFBA3800"
}
}
}
}
}
}
@@ -5,7 +5,7 @@
"identifier": "cobblemon:eruption_target",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/burning_rock"
"texture": "textures/particles/vanilla/lava"
}
},
"curves": {
@@ -19,7 +19,7 @@
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [-0.04, 0.46, 0.8, 0.96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
"nodes": [1, 1, 0.99, 0.97, 0.93, 0.83, 0.54, 0]
}
},
"events": {
@@ -47,7 +47,7 @@
"creation_expression": "v.target_deltaz=10;"
},
"minecraft:emitter_rate_steady": {
"spawn_rate": 10,
"spawn_rate": 25,
"max_particles": 1000
},
"minecraft:emitter_lifetime_once": {
@@ -55,7 +55,7 @@
},
"minecraft:emitter_shape_disc": {
"offset": [0, 9, "-v.target_deltaz*0.33"],
"radius": "math.clamp(v.entity_width,2,10)",
"radius": "math.clamp(v.entity_width,1.5,10)",
"direction": ["(v.particle_random_1-0.5)*0.3", "(-v.particle_random_2-0.55)*0.9", "(v.target_deltaz*0.05)+(v.particle_random_3-0.5)*0.3"]
},
"minecraft:particle_lifetime_expression": {
@@ -87,18 +87,18 @@
"linear_drag_coefficient": 1
},
"minecraft:particle_appearance_billboard": {
"size": ["((0.8-(v.particle_random_4*0.125))*v.quiver)*v.shrink", "((0.8-(v.particle_random_4*0.125))*v.quiver)*v.shrink"],
"size": ["((0.3-(v.particle_random_4*0.125))*v.quiver)*v.shrink", "((0.3-(v.particle_random_4*0.125))*v.quiver)*v.shrink"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 32,
"texture_height": 192,
"uv": [0, "math.round(v.particle_random_4*5)*32"],
"uv_size": [32, 32]
"texture_width": 8,
"texture_height": 8,
"uv": [0, 0],
"uv_size": [8, 8]
}
},
"minecraft:particle_motion_collision": {
"collision_drag": 20,
"collision_radius": 0.2
"collision_radius": 0.1
},
"minecraft:particle_appearance_tinting": {
"color": {
@@ -38,7 +38,7 @@
},
"components": {
"minecraft:emitter_rate_steady": {
"spawn_rate": 600,
"spawn_rate": 400,
"max_particles": 10000
},
"minecraft:emitter_lifetime_once": {
@@ -18,13 +18,13 @@
},
"components": {
"minecraft:emitter_rate_instant": {
"num_particles": 2
"num_particles": 1
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.4
},
"minecraft:emitter_shape_point": {
"offset": [0, -0.5, 0.25],
"offset": [0, 0, 0],
"direction": ["math.random(-1.55,1.55)*0.7", "math.random(-1.55,-0.55)", "math.random(-1.55,1.55)*0.7"]
},
"minecraft:particle_lifetime_expression": {
@@ -1,84 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:fairywind_actor",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/vanilla/generic"
}
},
"curves": {
"variable.debrissize": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 1, 1, 0.89, 0.59, 0]
}
},
"events": {
"sparkle": {
"particle_effect": {
"effect": "cobblemon:fairywind_actorspark",
"type": "particle"
}
}
},
"components": {
"minecraft:emitter_initialization": {
"creation_expression": "v.target_deltaz=5;"
},
"minecraft:emitter_rate_steady": {
"spawn_rate": 30,
"max_particles": 1000
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.4
},
"minecraft:emitter_shape_sphere": {
"offset": ["-((v.target_deltax*0.8)*(v.emitter_age/v.emitter_lifetime))", "((v.target_deltay*0.8)*(v.emitter_age/v.emitter_lifetime))", "-((v.target_deltaz*0.8)*(v.emitter_age/v.emitter_lifetime))"],
"radius": "0.1+(v.emitter_age*2)",
"surface_only": true,
"direction": ["(math.random(-0.4,0.4))/((v.emitter_age+0.25)*5)", "(math.random(-0.3,0.3))+((v.target_deltay/v.target_deltaz)*1.1)", "math.random(-1.15, -0.95)"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(0.6,0.7)*1.2"
},
"minecraft:particle_lifetime_events": {
"timeline": {
"0.07": "sparkle"
}
},
"minecraft:particle_initial_spin": {
"rotation": "math.random_integer(0,3)*90"
},
"minecraft:particle_initial_speed": "4-(v.emitter_age*4)",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": [0, 2, 0],
"linear_drag_coefficient": 3
},
"minecraft:particle_appearance_billboard": {
"size": ["0.15*v.debrissize", "0.15*v.debrissize"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 64,
"texture_height": 8,
"flipbook": {
"base_UV": [56, 0],
"size_UV": [8, 8],
"step_UV": [-8, 0],
"frames_per_second": 12,
"max_frame": 8
}
}
},
"minecraft:particle_motion_collision": {
"collision_radius": 0.01,
"expire_on_contact": true
},
"minecraft:particle_appearance_tinting": {
"color": [1, 0.75686, 0.97647, 0.62745]
}
}
}
}
@@ -1,65 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:fairywind_actorspark",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/impact/impact_fairy"
}
},
"curves": {
"variable.scale": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 0.73, 1, 0.96, 0.87, 0.61, 0]
}
},
"components": {
"minecraft:emitter_rate_instant": {
"num_particles": 1
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.5
},
"minecraft:emitter_shape_sphere": {
"radius": 0.2,
"surface_only": true,
"direction": ["math.random(-0.4,0.4)", "(math.random(-0.2,0.2))+((v.target_deltay/v.target_deltaz)*1.1)", "math.random(-1.15, -0.95)"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "0.5-(v.particle_random_4*0.1)"
},
"minecraft:particle_initial_speed": "math.clamp(v.target_deltaz*4,0,4)",
"minecraft:particle_motion_dynamic": {
"linear_drag_coefficient": 5
},
"minecraft:particle_appearance_billboard": {
"size": ["(0.125*v.scale)-(v.particle_random_4*0.075)", "(0.125*v.scale)-(v.particle_random_4*0.075)"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 8,
"texture_height": 56,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [8, 8],
"step_UV": [0, 8],
"frames_per_second": 16,
"max_frame": 7
}
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFFFFF",
"0.33": "#ffffffff",
"1.0": "#FFFF80E7"
}
}
}
}
}
}
@@ -1,68 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:fairywind_target",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/vanilla/generic"
}
},
"curves": {
"variable.debrissize": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 1, 0.69, 0.35, 0]
}
},
"components": {
"minecraft:emitter_rate_steady": {
"spawn_rate": 200,
"max_particles": 100
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.1
},
"minecraft:emitter_shape_sphere": {
"offset": [0, 0, "-0.4/math.clamp(q.entity_scale*1.1-0.1,1,9)"],
"radius": 0.1,
"surface_only": true,
"direction": "outwards"
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(0.6,0.7)"
},
"minecraft:particle_initial_spin": {
"rotation": "math.random_integer(0,3)*90"
},
"minecraft:particle_initial_speed": "math.random(1.5,2.75)*2.85",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": [0, 3, 0],
"linear_drag_coefficient": 4
},
"minecraft:particle_appearance_billboard": {
"size": ["0.2*v.debrissize", "0.2*v.debrissize"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 64,
"texture_height": 8,
"flipbook": {
"base_UV": [56, 0],
"size_UV": [8, 8],
"step_UV": [-8, 0],
"frames_per_second": 12,
"max_frame": 8
}
}
},
"minecraft:particle_motion_collision": {
"collision_radius": 0.01,
"expire_on_contact": true
},
"minecraft:particle_appearance_tinting": {
"color": [1, 0.75686, 0.97647, 0.62745]
}
}
}
}
@@ -1,67 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:fairywind_targethit",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/impact/impact_fairy"
}
},
"curves": {
"variable.scale": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 0.73, 1, 0.96, 0.87, 0.61, 0]
}
},
"components": {
"minecraft:emitter_rate_steady": {
"spawn_rate": 20,
"max_particles": 8
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.7
},
"minecraft:emitter_shape_sphere": {
"radius": 0.8,
"surface_only": true,
"direction": "outwards"
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "0.5-(v.particle_random_4*0.1)"
},
"minecraft:particle_initial_speed": 0,
"minecraft:particle_motion_dynamic": {
"linear_acceleration": [0, 2, 0],
"linear_drag_coefficient": 5
},
"minecraft:particle_appearance_billboard": {
"size": ["(0.125*v.scale)-(v.particle_random_4*0.075)", "(0.125*v.scale)-(v.particle_random_4*0.075)"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 8,
"texture_height": 56,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [8, 8],
"step_UV": [0, 8],
"frames_per_second": 16,
"max_frame": 7
}
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFFFFFF",
"0.33": "#ffffffff",
"1.0": "#FFFF80E7"
}
}
}
}
}
}
@@ -1,67 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:firefang_target",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/generic/bite"
}
},
"events": {
"event_sound": {
"sound_effect": {
"event_name": "cobblemon:move.bite.target"
}
}
},
"components": {
"minecraft:emitter_rate_instant": {
"num_particles": 1
},
"minecraft:emitter_lifetime_once": {
"active_time": 1
},
"minecraft:emitter_lifetime_events": {
"creation_event": "event_sound"
},
"minecraft:emitter_shape_point": {
"offset": [0, 0, -0.25]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.55
},
"minecraft:particle_initial_speed": 0,
"minecraft:particle_motion_dynamic": {},
"minecraft:particle_appearance_billboard": {
"size": [0.9, 0.9],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 32,
"texture_height": 320,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [32, 32],
"step_UV": [0, 32],
"frames_per_second": 18,
"max_frame": 10
}
}
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#00570000",
"0.12": "#FFFF3A00",
"0.38": "#FFFF3A00",
"0.44": "#FFFFD600",
"0.63": "#FFFF7400",
"0.82": "#E0C30000",
"1.0": "#003E0C00"
}
}
}
}
}
}
@@ -1,76 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:firefang_targetburst",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/fire/cloudyfire_white"
}
},
"curves": {
"variable.fun": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [1, 1, 1, 1, 1, 0.96, 0.85, 0.6, -0.05]
}
},
"components": {
"minecraft:emitter_rate_steady": {
"spawn_rate": 150,
"max_particles": 10000
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.1
},
"minecraft:emitter_shape_point": {
"direction": ["math.random(-1.75,1.75)", "math.random(-1.15,0.85)", "math.random(-0.65,0.65)*1.15"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(0.65,0.95)"
},
"minecraft:particle_initial_spin": {
"rotation": "math.round(v.particle_random_4*3)*90"
},
"minecraft:particle_initial_speed": "(math.random(2,5.25)*math.clamp(v.entity_height,1,1.5))*1.85",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": ["(v.particle_random_1-0.5)*5", "4+(v.particle_random_2-0.5)*3", "(v.particle_random_3-0.5)*5"],
"linear_drag_coefficient": 4
},
"minecraft:particle_appearance_billboard": {
"size": ["(0.5-(v.particle_random_4*0.15))*v.fun", "(0.5-(v.particle_random_4*0.15))*v.fun"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 160,
"texture_height": 16,
"flipbook": {
"base_UV": [16, 0],
"size_UV": [16, 16],
"step_UV": [16, 0],
"frames_per_second": 20,
"max_frame": 9
}
}
},
"minecraft:particle_motion_collision": {
"collision_drag": 10,
"collision_radius": 0.01
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#ffffffff",
"0.2": "#FFFFE872",
"0.4": "#FFFFCC00",
"0.55": "#FFFF9400",
"0.75": "#FFFF4700",
"0.9": "#FFFF4700",
"1.0": "#FF531C0E"
}
}
}
}
}
}
@@ -1,67 +0,0 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:firefang_targetspark",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/vanilla/critical_hit"
}
},
"curves": {
"variable.bitespark": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 0.87, 1, 0.5, 0]
}
},
"components": {
"minecraft:emitter_rate_instant": {
"num_particles": 10
},
"minecraft:emitter_lifetime_looping": {
"active_time": 1
},
"minecraft:emitter_shape_sphere": {
"offset": [0, 0, -0.25],
"radius": 0.025,
"surface_only": true,
"direction": "outwards"
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.35
},
"minecraft:particle_initial_speed": "math.random(1.75,4.55)*3",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": [0, -5, 0],
"linear_drag_coefficient": 4
},
"minecraft:particle_appearance_billboard": {
"size": ["0.1*v.bitespark", "0.1*v.bitespark"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 8,
"texture_height": 8,
"uv": [0, 0],
"uv_size": [7, 7]
}
},
"minecraft:particle_motion_collision": {
"collision_radius": 0.01,
"expire_on_contact": true
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFFF3A00",
"0.23": "#FFFFAD00",
"0.6": "#FFFF3A00",
"1.0": "#FF9D2300"
}
}
}
}
}
}
@@ -25,7 +25,7 @@
"active_time": 0.9
},
"minecraft:emitter_shape_point": {
"offset": ["v.target_deltax*(v.emitter_age/v.emitter_lifetime)", "v.target_deltay*(v.emitter_age/v.emitter_lifetime)+(v.burstarc*0.7)", "-v.target_deltaz*(v.emitter_age/v.emitter_lifetime)"],
"offset": ["-v.target_deltax*(v.emitter_age/v.emitter_lifetime)", "v.target_deltay*(v.emitter_age/v.emitter_lifetime)+(v.burstarc*0.7)", "-v.target_deltaz*(v.emitter_age/v.emitter_lifetime)"],
"direction": ["math.random(-0.45,0.45)", "(v.burstarc/math.clamp(v.target_deltaz*0.5,1,4))+math.random(-0.45,0.45)-(v.target_deltay/v.target_deltaz)", "math.random(-2.05,-0.55)"]
},
"minecraft:particle_lifetime_expression": {
@@ -28,8 +28,7 @@
"active_time": 1
},
"minecraft:emitter_shape_point": {
"offset": [0, 0, 0],
"direction": ["(-v.target_deltax+((v.particle_random_1-0.5)*1.15))+(math.sin(v.emitter_age*360)*0.35)", "(v.target_deltay+((v.particle_random_2-0.5)*1.05))+(math.sin(v.emitter_age*540)*0.3)", "-v.target_deltaz"]
"direction": ["(-v.target_deltax+((v.particle_random_1-0.5)*1.05))+(math.sin(v.emitter_age*360)*0.25)", "(v.target_deltay+((v.particle_random_2-0.5)*0.95))+(math.sin(v.emitter_age*540)*0.2)", "-v.target_deltaz*1.05"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(0.65,1.0)*1.4"
@@ -37,9 +36,9 @@
"minecraft:particle_initial_spin": {
"rotation": "math.round(v.particle_random_4*3)*90"
},
"minecraft:particle_initial_speed": "(v.target_deltaz*((v.particle_random_4+0.75)*1.25))*(math.clamp(v.target_deltaz,3,24)/2)",
"minecraft:particle_initial_speed": "(v.target_deltaz*math.random(0.65,2.05))*(math.clamp(v.target_deltaz,3,24)/2)",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": ["(v.particle_random_3-0.5)*4", "3+(v.particle_random_4-0.5)*2", "(v.particle_random_2-0.5)*1"],
"linear_acceleration": ["(v.particle_random_1-0.5)*4", "3+(v.particle_random_2-0.5)*2", "(v.particle_random_3-0.5)*1"],
"linear_drag_coefficient": "math.clamp(v.target_deltaz,1,20)*(0.5+(math.clamp(v.target_deltaz,1,5)*0.05))"
},
"minecraft:particle_appearance_billboard": {
@@ -63,15 +62,15 @@
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "(v.particle_age / v.particle_lifetime) * (v.particle_random_4+0.75)",
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FFB3F6FF",
"0.05": "#FFFFFFFF",
"0.15": "#FFFFE872",
"0.3": "#FFFFCC00",
"0.5": "#FFFF8700",
"0.0": "#ffffffff",
"0.2": "#FFFFE872",
"0.4": "#FFFFCC00",
"0.55": "#FFFF9400",
"0.75": "#FFFF4700",
"1.0": "#FFA31F00"
"0.9": "#FFFF4700",
"1.0": "#FF531C0E"
}
}
}
@@ -60,6 +60,7 @@
"minecraft:particle_motion_collision": {
"collision_radius": 0.1
},
"minecraft:particle_appearance_lighting": {},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
Loaded 100 of 1205 files, more files were not shown because too many files have changed in this diff. Show more