From 7873b7818026886aa1e1828ee9c654ccfeb14774 Mon Sep 17 00:00:00 2001 From: Eli Gibbs Date: Sun, 7 Jun 2026 14:20:19 -0400 Subject: [PATCH] Added variable size Added variable and dynamic hitbox Added dynamic growth times Added name tag skin handling Added Frozen Bone item Added Permafrost block and frozen bone drop, with spawn rules Changed Stone Fossil and Deepslate Fossil to have random texture --- .../cmr/jurassicrevived/block/ModBlocks.java | 2 + .../datagen/ModBlockLootTableProvider.java | 5 +- .../datagen/ModBlockStateProvider.java | 22 ++- .../datagen/ModBlockTagProvider.java | 4 +- .../datagen/ModItemModelProvider.java | 1 + .../datagen/ModWorldgenProvider.java | 47 ++++- .../entity/client/AlbertosaurusRenderer.java | 21 +-- .../entity/client/AllosaurusModel.java | 9 +- .../entity/client/AllosaurusRenderer.java | 9 +- .../entity/client/AlvarezsaurusRenderer.java | 21 +-- .../entity/client/AnkylosaurusModel.java | 15 +- .../entity/client/AnkylosaurusRenderer.java | 21 +-- .../entity/client/ApatosaurusRenderer.java | 21 +-- .../entity/client/ArambourgianiaRenderer.java | 21 +-- .../entity/client/BaryonyxRenderer.java | 21 +-- .../entity/client/BrachiosaurusRenderer.java | 21 +-- .../client/CarcharodontosaurusRenderer.java | 9 +- .../entity/client/CarnotaurusRenderer.java | 9 +- .../entity/client/CearadactylusRenderer.java | 21 +-- .../entity/client/CeratosaurusRenderer.java | 21 +-- .../entity/client/ChasmosaurusRenderer.java | 21 +-- .../entity/client/ChickenosaurusRenderer.java | 21 +-- .../entity/client/ChilesaurusRenderer.java | 21 +-- .../entity/client/CoelophysisRenderer.java | 21 +-- .../entity/client/CoelurusRenderer.java | 21 +-- .../entity/client/CompsognathusRenderer.java | 9 +- .../entity/client/ConcavenatorRenderer.java | 21 +-- .../entity/client/CorythosaurusRenderer.java | 21 +-- .../entity/client/DeinonychusRenderer.java | 21 +-- .../entity/client/DilophosaurusModel.java | 7 + .../entity/client/DilophosaurusRenderer.java | 21 +-- .../entity/client/DimorphodonRenderer.java | 21 +-- .../entity/client/DiplodocusRenderer.java | 21 +-- .../entity/client/DistortusRexRenderer.java | 9 +- .../entity/client/DryosaurusRenderer.java | 21 +-- .../entity/client/EdmontosaurusRenderer.java | 21 +-- .../entity/client/FDuckRenderer.java | 21 +-- .../entity/client/GallimimusRenderer.java | 21 +-- .../entity/client/GeosternbergiaRenderer.java | 21 +-- .../entity/client/GiganotosaurusRenderer.java | 9 +- .../entity/client/GuanlongRenderer.java | 21 +-- .../entity/client/GuidracoRenderer.java | 21 +-- .../entity/client/HadrosaurusRenderer.java | 21 +-- .../entity/client/HerrerasaurusRenderer.java | 21 +-- .../entity/client/HypsilophodonRenderer.java | 21 +-- .../entity/client/IndominusRexRenderer.java | 21 +-- .../entity/client/IndoraptorRenderer.java | 21 +-- .../entity/client/InostranceviaRenderer.java | 21 +-- .../entity/client/LambeosaurusRenderer.java | 21 +-- .../entity/client/LudodactylusModel.java | 7 + .../entity/client/LudodactylusRenderer.java | 21 +-- .../entity/client/MajungasaurusRenderer.java | 21 +-- .../entity/client/MamenchisaurusRenderer.java | 21 +-- .../client/MetriacanthosaurusRenderer.java | 9 +- .../entity/client/MoganopterusRenderer.java | 9 +- .../entity/client/MussasaurusRenderer.java | 9 +- .../entity/client/NyctosaurusRenderer.java | 9 +- .../entity/client/OrnitholestesRenderer.java | 21 +-- .../entity/client/OrnithomimusRenderer.java | 9 +- .../entity/client/OuranosaurusRenderer.java | 9 +- .../entity/client/OviraptorRenderer.java | 21 +-- .../client/PachycephalosaurusRenderer.java | 21 +-- .../client/ParasaurolophusRenderer.java | 21 +-- .../client/ProceratosaurusRenderer.java | 21 +-- .../client/ProcompsognathusRenderer.java | 9 +- .../entity/client/ProtoceratopsRenderer.java | 21 +-- .../entity/client/PteranodonRenderer.java | 21 +-- .../entity/client/PterodaustroRenderer.java | 21 +-- .../entity/client/QuetzalcoatlusRenderer.java | 9 +- .../entity/client/RajasaurusRenderer.java | 9 +- .../entity/client/RugopsRenderer.java | 9 +- .../entity/client/SegisaurusRenderer.java | 9 +- .../client/ShantungosaurusRenderer.java | 9 +- .../entity/client/SpinosaurusRenderer.java | 9 +- .../entity/client/StegosaurusRenderer.java | 21 +-- .../entity/client/StyracosaurusRenderer.java | 21 +-- .../entity/client/SuchomimusRenderer.java | 9 +- .../entity/client/TapejaraRenderer.java | 21 +-- .../client/TherizinosaurusRenderer.java | 21 +-- .../entity/client/ThescelosaurusRenderer.java | 9 +- .../entity/client/TitanosaurusRenderer.java | 11 +- .../entity/client/TriceratopsRenderer.java | 21 +-- .../entity/client/TroodonRenderer.java | 9 +- .../entity/client/TropeognathusRenderer.java | 21 +-- .../entity/client/TupuxuaraRenderer.java | 9 +- .../entity/client/TyrannosaurusRexModel.java | 16 +- .../client/TyrannosaurusRexRenderer.java | 9 +- .../entity/client/UtahraptorRenderer.java | 21 +-- .../entity/client/VelociraptorModel.java | 25 +++ .../entity/client/VelociraptorRenderer.java | 21 +-- .../client/ZhenyuanopterusRenderer.java | 9 +- .../entity/custom/AchillobatorEntity.java | 6 +- .../entity/custom/AlbertosaurusEntity.java | 69 +++++++- .../entity/custom/AllosaurusEntity.java | 153 ++++++++++++----- .../entity/custom/AlvarezsaurusEntity.java | 161 ++++++++++++------ .../entity/custom/AnkylosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/ApatosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/ArambourgianiaEntity.java | 69 +++++++- .../entity/custom/BaryonyxEntity.java | 161 ++++++++++++------ .../entity/custom/BrachiosaurusEntity.java | 161 ++++++++++++------ .../custom/CarcharodontosaurusEntity.java | 74 +++++++- .../entity/custom/CarnotaurusEntity.java | 115 ++++++++++--- .../entity/custom/CearadactylusEntity.java | 139 ++++++++++----- .../entity/custom/CeratosaurusEntity.java | 153 ++++++++++++----- .../entity/custom/ChasmosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/ChickenosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/ChilesaurusEntity.java | 161 ++++++++++++------ .../entity/custom/CoelophysisEntity.java | 161 ++++++++++++------ .../entity/custom/CoelurusEntity.java | 161 ++++++++++++------ .../entity/custom/CompsognathusEntity.java | 121 +++++++++---- .../entity/custom/ConcavenatorEntity.java | 153 ++++++++++++----- .../entity/custom/CorythosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/DeinonychusEntity.java | 161 ++++++++++++------ .../entity/custom/DilophosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/DimorphodonEntity.java | 139 ++++++++++----- .../entity/custom/DiplodocusEntity.java | 161 ++++++++++++------ .../entity/custom/DistortusRexEntity.java | 74 +++++++- .../entity/custom/DryosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/EdmontosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/FDuckEntity.java | 161 ++++++++++++------ .../entity/custom/GallimimusEntity.java | 161 ++++++++++++------ .../entity/custom/GeosternbergiaEntity.java | 139 ++++++++++----- .../entity/custom/GiganotosaurusEntity.java | 74 +++++++- .../entity/custom/GuanlongEntity.java | 161 ++++++++++++------ .../entity/custom/GuidracoEntity.java | 139 ++++++++++----- .../entity/custom/HadrosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/HerrerasaurusEntity.java | 161 ++++++++++++------ .../entity/custom/HypsilophodonEntity.java | 161 ++++++++++++------ .../entity/custom/IndominusRexEntity.java | 161 ++++++++++++------ .../entity/custom/IndoraptorEntity.java | 161 ++++++++++++------ .../entity/custom/InostranceviaEntity.java | 161 ++++++++++++------ .../entity/custom/LambeosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/LudodactylusEntity.java | 139 ++++++++++----- .../entity/custom/MajungasaurusEntity.java | 161 ++++++++++++------ .../entity/custom/MamenchisaurusEntity.java | 161 ++++++++++++------ .../custom/MetriacanthosaurusEntity.java | 72 +++++++- .../entity/custom/MoganopterusEntity.java | 86 ++++++++-- .../entity/custom/MussasaurusEntity.java | 80 +++++++-- .../entity/custom/NyctosaurusEntity.java | 82 +++++++-- .../entity/custom/OrnitholestesEntity.java | 161 ++++++++++++------ .../entity/custom/OrnithomimusEntity.java | 161 ++++++++++++------ .../entity/custom/OuranosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/OviraptorEntity.java | 161 ++++++++++++------ .../custom/PachycephalosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/ParasaurolophusEntity.java | 161 ++++++++++++------ .../entity/custom/ProceratosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/ProcompsognathusEntity.java | 161 ++++++++++++------ .../entity/custom/ProtoceratopsEntity.java | 161 ++++++++++++------ .../entity/custom/PteranodonEntity.java | 139 ++++++++++----- .../entity/custom/PterodaustroEntity.java | 139 ++++++++++----- .../entity/custom/QuetzalcoatlusEntity.java | 86 ++++++++-- .../entity/custom/RajasaurusEntity.java | 88 ++++++++-- .../entity/custom/RugopsEntity.java | 88 ++++++++-- .../entity/custom/SegisaurusEntity.java | 86 ++++++++-- .../entity/custom/ShantungosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/SpinosaurusEntity.java | 88 ++++++++-- .../entity/custom/StegosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/StyracosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/SuchomimusEntity.java | 80 +++++++-- .../entity/custom/TapejaraEntity.java | 121 +++++++++---- .../entity/custom/TherizinosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/ThescelosaurusEntity.java | 161 ++++++++++++------ .../entity/custom/TitanosaurusEntity.java | 120 +++++++++---- .../entity/custom/TriceratopsEntity.java | 161 ++++++++++++------ .../entity/custom/TroodonEntity.java | 161 ++++++++++++------ .../entity/custom/TropeognathusEntity.java | 139 ++++++++++----- .../entity/custom/TupuxuaraEntity.java | 88 ++++++++-- .../entity/custom/TyrannosaurusRexEntity.java | 72 +++++++- .../entity/custom/UtahraptorEntity.java | 161 ++++++++++++------ .../entity/custom/VelociraptorEntity.java | 161 ++++++++++++------ .../entity/custom/ZhenyuanopterusEntity.java | 88 ++++++++-- .../jurassicrevived/item/ModCreativeTabs.java | 2 + .../cmr/jurassicrevived/item/ModItems.java | 1 + .../worldgen/ModWorldgenDefinitions.java | 38 ++++- .../textures/block/deepslate_fossil.png | Bin 649 -> 0 bytes .../textures/block/deepslate_fossil_egg.png | Bin 0 -> 673 bytes .../textures/block/deepslate_fossil_rib.png | Bin 0 -> 716 bytes .../textures/block/deepslate_fossil_skull.png | Bin 0 -> 646 bytes .../textures/block/permafrost_bottom.png | Bin 0 -> 410 bytes .../textures/block/permafrost_side.png | Bin 0 -> 706 bytes .../textures/block/permafrost_top.png | Bin 0 -> 310 bytes .../textures/block/stone_fossil.png | Bin 522 -> 0 bytes .../textures/block/stone_fossil_egg.png | Bin 0 -> 599 bytes .../textures/block/stone_fossil_rib.png | Bin 0 -> 572 bytes .../textures/block/stone_fossil_skull.png | Bin 0 -> 614 bytes .../textures/entity/allosaurus_al.png | Bin 0 -> 57938 bytes .../textures/entity/ankylosaurus_bumpy.png | Bin 0 -> 83155 bytes .../textures/entity/dilophosaurus_inferno.png | Bin 0 -> 119759 bytes .../textures/entity/ludodactylus_pinwin.png | Bin 0 -> 65481 bytes .../entity/tyrannosaurus_rex_drgray.png | Bin 0 -> 138148 bytes .../entity/tyrannosaurus_rex_ember.png | Bin 0 -> 147186 bytes .../textures/entity/velociraptor_blue.png | Bin 0 -> 28443 bytes .../textures/entity/velociraptor_charlie.png | Bin 0 -> 28013 bytes .../textures/entity/velociraptor_delta.png | Bin 0 -> 33041 bytes .../textures/entity/velociraptor_echo.png | Bin 0 -> 41806 bytes .../textures/item/frozen_bone.png | Bin 0 -> 648 bytes .../java/net/cmr/jurassicrevived/JRMod.java | 12 ++ .../datagen/FabricBlockLootTableProvider.java | 16 ++ .../datagen/FabricModModelProvider.java | 51 ++++++ gradle.properties | 2 +- message.txt | 92 ++++++++++ .../datagen/ForgeBlockLootTableProvider.java | 16 ++ .../datagen/ForgeBlockStateProvider.java | 31 ++++ .../NeoForgeBlockLootTableProvider.java | 16 ++ .../datagen/NeoForgeBlockStateProvider.java | 31 ++++ 205 files changed, 8742 insertions(+), 3979 deletions(-) delete mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/deepslate_fossil.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/deepslate_fossil_egg.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/deepslate_fossil_rib.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/deepslate_fossil_skull.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/permafrost_bottom.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/permafrost_side.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/permafrost_top.png delete mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/stone_fossil.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/stone_fossil_egg.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/stone_fossil_rib.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/block/stone_fossil_skull.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/entity/allosaurus_al.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/entity/ankylosaurus_bumpy.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/entity/dilophosaurus_inferno.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/entity/ludodactylus_pinwin.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/entity/tyrannosaurus_rex_drgray.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/entity/tyrannosaurus_rex_ember.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/entity/velociraptor_blue.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/entity/velociraptor_charlie.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/entity/velociraptor_delta.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/entity/velociraptor_echo.png create mode 100644 common/src/main/resources/assets/jurassicrevived/textures/item/frozen_bone.png create mode 100644 message.txt diff --git a/common/src/main/java/net/cmr/jurassicrevived/block/ModBlocks.java b/common/src/main/java/net/cmr/jurassicrevived/block/ModBlocks.java index c5ca39c..f4a06e1 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/block/ModBlocks.java +++ b/common/src/main/java/net/cmr/jurassicrevived/block/ModBlocks.java @@ -207,6 +207,8 @@ public class ModBlocks { () -> new Block(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops())); public static final RegistrySupplier DEEPSLATE_ICE_SHARD_ORE = registerBlock("deepslate_ice_shard_ore", () -> new Block(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops())); + public static final RegistrySupplier PERMAFROST = registerBlock("permafrost", + () -> new Block(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops())); public static final RegistrySupplier REINFORCED_STONE = registerBlock("reinforced_stone", () -> new Block(BlockBehaviour.Properties.of().strength(4f).requiresCorrectToolForDrops())); diff --git a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockLootTableProvider.java b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockLootTableProvider.java index 08ce2b1..6e3794e 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockLootTableProvider.java +++ b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockLootTableProvider.java @@ -20,7 +20,8 @@ public class ModBlockLootTableProvider { void dropSelf(Block block); void add(Block block, LootTable.Builder builder); LootTable.Builder createMultipleOreDrops(Block block, Item item, float minDrops, float maxDrops); - LootTable.Builder createPotFlowerItemTable(Block block); + LootTable.Builder createRandomOreDrops(Block block, Item silkTouchDrop, Item firstDrop, Item secondDrop, float minRolls, float maxRolls, double firstDropChance); + LootTable.Builder createPotFlowerItemTable(Block block); } public static void registerBlockLootTables(BlockLootHelper helper) { @@ -53,6 +54,8 @@ public class ModBlockLootTableProvider { helper.createMultipleOreDrops(ModBlocks.AMBER_ORE.get(), ModItems.MOSQUITO_IN_AMBER.get(),1, 1)); helper.add(ModBlocks.DEEPSLATE_ICE_SHARD_ORE.get(), helper.createMultipleOreDrops(ModBlocks.DEEPSLATE_ICE_SHARD_ORE.get(), ModItems.FROZEN_LEECH.get(),1, 1)); + helper.add(ModBlocks.PERMAFROST.get(), + helper.createMultipleOreDrops(ModBlocks.PERMAFROST.get(), ModItems.FROZEN_BONE.get(),1, 1)); helper.dropSelf(ModBlocks.REINFORCED_STONE.get()); helper.dropSelf(ModBlocks.REINFORCED_STONE_BRICKS.get()); diff --git a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockStateProvider.java b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockStateProvider.java index ea8bfc9..cf8cc97 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockStateProvider.java +++ b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockStateProvider.java @@ -12,6 +12,8 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BooleanProperty; import net.minecraft.world.level.block.state.properties.EnumProperty; +import java.util.List; + public class ModBlockStateProvider { public interface BlockStateHelper { @@ -25,7 +27,9 @@ public class ModBlockStateProvider { void pottedPlantBlock(Block block, ResourceLocation plantTexture); void blockWithItem(Block block); - void horizontalFacingWithItem(Block block); + void blockWithItem(Block block, ResourceLocation sideTexture, ResourceLocation bottomTexture, ResourceLocation topTexture); + void randomTextureBlockWithItem(Block block, List textures); + void horizontalFacingWithItem(Block block); void horizontalFacingLitWithItem(Block block); void horizontalFacingLitNoBlockstateWithItem(Block block); void eggLike(Block block); @@ -68,10 +72,22 @@ public class ModBlockStateProvider { helper.blockWithItem(ModBlocks.SMOOTH_GYPSUM_STONE.get()); helper.blockWithItem(ModBlocks.CHISELED_GYPSUM_STONE.get()); - helper.blockWithItem(ModBlocks.STONE_FOSSIL.get()); - helper.blockWithItem(ModBlocks.DEEPSLATE_FOSSIL.get()); + helper.randomTextureBlockWithItem(ModBlocks.STONE_FOSSIL.get(), List.of( + Constants.rl("block/stone_fossil_egg"), + Constants.rl("block/stone_fossil_rib"), + Constants.rl("block/stone_fossil_skull") + )); + helper.randomTextureBlockWithItem(ModBlocks.DEEPSLATE_FOSSIL.get(), List.of( + Constants.rl("block/deepslate_fossil_egg"), + Constants.rl("block/deepslate_fossil_rib"), + Constants.rl("block/deepslate_fossil_skull") + )); helper.blockWithItem(ModBlocks.AMBER_ORE.get()); helper.blockWithItem(ModBlocks.DEEPSLATE_ICE_SHARD_ORE.get()); + helper.blockWithItem(ModBlocks.PERMAFROST.get(), + Constants.rl("block/permafrost_side"), + Constants.rl("block/permafrost_bottom"), + Constants.rl("block/permafrost_top")); helper.blockWithItem(ModBlocks.REINFORCED_STONE.get()); helper.blockWithItem(ModBlocks.REINFORCED_STONE_BRICKS.get()); diff --git a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockTagProvider.java b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockTagProvider.java index f82a661..143ef8e 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockTagProvider.java +++ b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModBlockTagProvider.java @@ -148,7 +148,9 @@ public class ModBlockTagProvider { ModBlocks.INCUBATED_CHILESAURUS_EGG.get() ); - helper.tag(BlockTags.MINEABLE_WITH_SHOVEL); + helper.tag(BlockTags.MINEABLE_WITH_SHOVEL, + ModBlocks.PERMAFROST.get() + ); helper.tag(BlockTags.NEEDS_STONE_TOOL, ModBlocks.STONE_FOSSIL.get(), diff --git a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModItemModelProvider.java b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModItemModelProvider.java index a7cca04..f472228 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModItemModelProvider.java +++ b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModItemModelProvider.java @@ -109,6 +109,7 @@ public class ModItemModelProvider { helper.basicItemModel(ModItems.CRUSHED_FOSSIL.get()); helper.basicItemModel(ModItems.MOSQUITO_IN_AMBER.get()); helper.basicItemModel(ModItems.FROZEN_LEECH.get()); + helper.basicItemModel(ModItems.FROZEN_BONE.get()); helper.basicItemModel(ModItems.CABLE.get()); helper.basicItemModel(ModItems.SCREEN.get()); helper.basicItemModel(ModItems.PROCESSOR.get()); diff --git a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModWorldgenProvider.java b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModWorldgenProvider.java index 64faa90..ccd8faa 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/datagen/ModWorldgenProvider.java +++ b/common/src/main/java/net/cmr/jurassicrevived/datagen/ModWorldgenProvider.java @@ -42,18 +42,22 @@ public class ModWorldgenProvider implements DataProvider { )) .toArray(CompletableFuture[]::new); - return CompletableFuture.allOf( + CompletableFuture allGenerators = CompletableFuture.allOf( java.util.stream.Stream.concat( java.util.Arrays.stream(oreFutures), java.util.Arrays.stream(spawnFutures) ).toArray(CompletableFuture[]::new) ); + + return CompletableFuture.allOf(allGenerators, saveIsSnowyFallbackTag(cachedOutput)); + } private CompletableFuture saveForgeAddFeatureBiomeModifier(CachedOutput cachedOutput, ModWorldgenDefinitions.OreDefinition ore) { JsonObject root = new JsonObject(); root.addProperty("type", "forge:add_features"); - root.addProperty("biomes", "#minecraft:is_overworld"); + // Dynamically grab the biome tag + root.addProperty("biomes", "#" + ore.biomeTag().location().toString()); root.addProperty("features", Constants.rl(ore.name() + "_placed").toString()); root.addProperty("step", "underground_ores"); @@ -66,7 +70,8 @@ public class ModWorldgenProvider implements DataProvider { private CompletableFuture saveNeoForgeAddFeatureBiomeModifier(CachedOutput cachedOutput, ModWorldgenDefinitions.OreDefinition ore) { JsonObject root = new JsonObject(); root.addProperty("type", "neoforge:add_features"); - root.addProperty("biomes", "#minecraft:is_overworld"); + // Dynamically grab the biome tag + root.addProperty("biomes", "#" + ore.biomeTag().location().toString()); root.addProperty("features", Constants.rl(ore.name() + "_placed").toString()); root.addProperty("step", "underground_ores"); @@ -192,6 +197,42 @@ public class ModWorldgenProvider implements DataProvider { return DataProvider.saveStable(cachedOutput, root, path); } + private CompletableFuture saveIsSnowyFallbackTag(CachedOutput cachedOutput) { + JsonObject root = new JsonObject(); + root.addProperty("replace", false); + + JsonArray values = new JsonArray(); + + // Optional Forge Tag + JsonObject forgeTag = new JsonObject(); + forgeTag.addProperty("id", "#forge:is_snowy"); + forgeTag.addProperty("required", false); + values.add(forgeTag); + + // Optional Fabric Tag + JsonObject fabricTag = new JsonObject(); + fabricTag.addProperty("id", "#c:snowy"); + fabricTag.addProperty("required", false); + values.add(fabricTag); + + // Vanilla Fallbacks + values.add("minecraft:snowy_plains"); + values.add("minecraft:ice_spikes"); + values.add("minecraft:snowy_taiga"); + values.add("minecraft:snowy_beach"); + values.add("minecraft:grove"); + values.add("minecraft:snowy_slopes"); + values.add("minecraft:jagged_peaks"); + values.add("minecraft:frozen_peaks"); + + root.add("values", values); + + Path path = output.getOutputFolder() + .resolve("data/" + Constants.MOD_ID + "/tags/worldgen/biome/is_snowy.json"); + + return DataProvider.saveStable(cachedOutput, root, path); + } + @Override public String getName() { return "Jurassic Revived Worldgen"; diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/AlbertosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/AlbertosaurusRenderer.java index a2ce820..ba159fe 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/AlbertosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/AlbertosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class AlbertosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.7F; - public AlbertosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new AlbertosaurusModel()); - } + public AlbertosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new AlbertosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, AlbertosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, AlbertosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/AllosaurusModel.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/AllosaurusModel.java index 54ab2fb..99ef85b 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/AllosaurusModel.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/AllosaurusModel.java @@ -25,6 +25,9 @@ public class AllosaurusModel extends GeoModel { map.put(AllosaurusVariant.FEMALE, Constants.rl("textures/entity/allosaurus_female.png")); }); + private static final ResourceLocation AL_LOCATION = + Constants.rl("textures/entity/allosaurus_al.png"); + // Model-local "currently applied" offsets; cleared before each entity render private float[] appliedYaw = null; private float[] appliedRoll = null; @@ -36,7 +39,11 @@ public class AllosaurusModel extends GeoModel { @Override public ResourceLocation getTextureResource(AllosaurusEntity animatable) { - return LOCATION_BY_VARIANT.get(animatable.getVariant()); + if (animatable.hasCustomName() && "al".equalsIgnoreCase(animatable.getName().getString())) { + return AL_LOCATION; + } + + return LOCATION_BY_VARIANT.get(animatable.getVariant()); } @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/AllosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/AllosaurusRenderer.java index 64d4ef8..a6e660c 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/AllosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/AllosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class AllosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.9F; public AllosaurusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new AllosaurusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, AllosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/AlvarezsaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/AlvarezsaurusRenderer.java index cd35a32..f4c26a6 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/AlvarezsaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/AlvarezsaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class AlvarezsaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.8F; - public AlvarezsaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new AlvarezsaurusModel()); - } + public AlvarezsaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new AlvarezsaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, AlvarezsaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, AlvarezsaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/AnkylosaurusModel.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/AnkylosaurusModel.java index c34302a..261c6db 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/AnkylosaurusModel.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/AnkylosaurusModel.java @@ -25,6 +25,9 @@ public class AnkylosaurusModel extends GeoModel { map.put(AnkylosaurusVariant.FEMALE, Constants.rl("textures/entity/ankylosaurus_female.png")); }); + private static final ResourceLocation BUMPY_LOCATION = + Constants.rl("textures/entity/ankylosaurus_bumpy.png"); + // Model-local "currently applied" offsets; cleared before each entity render private float[] appliedYaw = null; private float[] appliedRoll = null; @@ -34,10 +37,14 @@ public class AnkylosaurusModel extends GeoModel { return Constants.rl("geo/ankylosaurus.geo.json"); } - @Override - public ResourceLocation getTextureResource(AnkylosaurusEntity animatable) { - return LOCATION_BY_VARIANT.get(animatable.getVariant()); - } + @Override + public ResourceLocation getTextureResource(AnkylosaurusEntity animatable) { + if (animatable.hasCustomName() && "bumpy".equalsIgnoreCase(animatable.getName().getString())) { + return BUMPY_LOCATION; + } + + return LOCATION_BY_VARIANT.get(animatable.getVariant()); + } @Override public ResourceLocation getAnimationResource(AnkylosaurusEntity animatable) { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/AnkylosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/AnkylosaurusRenderer.java index bac1d77..0c11aec 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/AnkylosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/AnkylosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class AnkylosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 2.4F; - public AnkylosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new AnkylosaurusModel()); - } + public AnkylosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new AnkylosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, AnkylosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, AnkylosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ApatosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ApatosaurusRenderer.java index 0516cd7..dd9f382 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ApatosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ApatosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class ApatosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.9F; - public ApatosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new ApatosaurusModel()); - } + public ApatosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new ApatosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ApatosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ApatosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ArambourgianiaRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ArambourgianiaRenderer.java index 79939bb..c64a667 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ArambourgianiaRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ArambourgianiaRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class ArambourgianiaRenderer extends GeoEntityRenderer { - private final float animalScale = 1.9F; - public ArambourgianiaRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new ArambourgianiaModel()); - } + public ArambourgianiaRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new ArambourgianiaModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ArambourgianiaEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ArambourgianiaEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/BaryonyxRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/BaryonyxRenderer.java index 5c70a01..7ba1a49 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/BaryonyxRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/BaryonyxRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class BaryonyxRenderer extends GeoEntityRenderer { - private final float animalScale = 1.3F; - public BaryonyxRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new BaryonyxModel()); - } + public BaryonyxRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new BaryonyxModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, BaryonyxEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, BaryonyxEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/BrachiosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/BrachiosaurusRenderer.java index 635296c..02b3e52 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/BrachiosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/BrachiosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class BrachiosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 2.0F; - public BrachiosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new BrachiosaurusModel()); - } + public BrachiosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new BrachiosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, BrachiosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, BrachiosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CarcharodontosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CarcharodontosaurusRenderer.java index 2450fd3..7a31cae 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CarcharodontosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CarcharodontosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class CarcharodontosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 2.0F; public CarcharodontosaurusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new CarcharodontosaurusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, CarcharodontosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CarnotaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CarnotaurusRenderer.java index 83c730c..7186e2f 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CarnotaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CarnotaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class CarnotaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.5F; public CarnotaurusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new CarnotaurusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, CarnotaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CearadactylusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CearadactylusRenderer.java index 1f40e5f..b004bd8 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CearadactylusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CearadactylusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class CearadactylusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.9F; - public CearadactylusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new CearadactylusModel()); - } + public CearadactylusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new CearadactylusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, CearadactylusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, CearadactylusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CeratosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CeratosaurusRenderer.java index 68614a5..e83ec3e 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CeratosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CeratosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class CeratosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 2.1F; - public CeratosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new CeratosaurusModel()); - } + public CeratosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new CeratosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, CeratosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, CeratosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ChasmosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ChasmosaurusRenderer.java index ab6069b..7f3322c 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ChasmosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ChasmosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class ChasmosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.3F; - public ChasmosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new ChasmosaurusModel()); - } + public ChasmosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new ChasmosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ChasmosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ChasmosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ChickenosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ChickenosaurusRenderer.java index 42599b1..245df3e 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ChickenosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ChickenosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class ChickenosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.9F; - public ChickenosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new ChickenosaurusModel()); - } + public ChickenosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new ChickenosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ChickenosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ChickenosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ChilesaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ChilesaurusRenderer.java index b64de2d..053b1de 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ChilesaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ChilesaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class ChilesaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.6F; - public ChilesaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new ChilesaurusModel()); - } + public ChilesaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new ChilesaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ChilesaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ChilesaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CoelophysisRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CoelophysisRenderer.java index 8458714..6991f71 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CoelophysisRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CoelophysisRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class CoelophysisRenderer extends GeoEntityRenderer { - private final float animalScale = 0.7F; - public CoelophysisRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new CoelophysisModel()); - } + public CoelophysisRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new CoelophysisModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, CoelophysisEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, CoelophysisEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CoelurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CoelurusRenderer.java index c84fd88..db36c22 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CoelurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CoelurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class CoelurusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.5F; - public CoelurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new CoelurusModel()); - } + public CoelurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new CoelurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, CoelurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, CoelurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CompsognathusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CompsognathusRenderer.java index 0c9ccd8..7183115 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CompsognathusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CompsognathusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class CompsognathusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.4F; public CompsognathusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new CompsognathusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, CompsognathusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ConcavenatorRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ConcavenatorRenderer.java index 99b73a8..39c886e 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ConcavenatorRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ConcavenatorRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class ConcavenatorRenderer extends GeoEntityRenderer { - private final float animalScale = 0.9F; - public ConcavenatorRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new ConcavenatorModel()); - } + public ConcavenatorRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new ConcavenatorModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ConcavenatorEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ConcavenatorEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CorythosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CorythosaurusRenderer.java index c6cd69d..d769ff8 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/CorythosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/CorythosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class CorythosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.7F; - public CorythosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new CorythosaurusModel()); - } + public CorythosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new CorythosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, CorythosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, CorythosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/DeinonychusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/DeinonychusRenderer.java index 68fe9a5..21463d5 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/DeinonychusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/DeinonychusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class DeinonychusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.9F; - public DeinonychusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new DeinonychusModel()); - } + public DeinonychusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new DeinonychusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, DeinonychusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, DeinonychusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/DilophosaurusModel.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/DilophosaurusModel.java index e84a928..6fc2c51 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/DilophosaurusModel.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/DilophosaurusModel.java @@ -25,6 +25,9 @@ public class DilophosaurusModel extends GeoModel { map.put(DilophosaurusVariant.FEMALE, Constants.rl("textures/entity/dilophosaurus_female.png")); }); + private static final ResourceLocation INFERNO_LOCATION = + Constants.rl("textures/entity/dilophosaurus_inferno.png"); + // Model-local "currently applied" offsets; cleared before each entity render private float[] appliedYaw = null; private float[] appliedRoll = null; @@ -36,6 +39,10 @@ public class DilophosaurusModel extends GeoModel { @Override public ResourceLocation getTextureResource(DilophosaurusEntity animatable) { + if (animatable.hasCustomName() && "inferno".equalsIgnoreCase(animatable.getName().getString())) { + return INFERNO_LOCATION; + } + return LOCATION_BY_VARIANT.get(animatable.getVariant()); } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/DilophosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/DilophosaurusRenderer.java index ed6bd97..fc60ba9 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/DilophosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/DilophosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class DilophosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.2F; - public DilophosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new DilophosaurusModel()); - } + public DilophosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new DilophosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, DilophosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, DilophosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/DimorphodonRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/DimorphodonRenderer.java index dfa3305..237b4b1 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/DimorphodonRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/DimorphodonRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class DimorphodonRenderer extends GeoEntityRenderer { - private final float animalScale = 0.7F; - public DimorphodonRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new DimorphodonModel()); - } + public DimorphodonRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new DimorphodonModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, DimorphodonEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, DimorphodonEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/DiplodocusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/DiplodocusRenderer.java index 6006d5f..c070d11 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/DiplodocusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/DiplodocusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class DiplodocusRenderer extends GeoEntityRenderer { - private final float animalScale = 2.8F; - public DiplodocusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new DiplodocusModel()); - } + public DiplodocusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new DiplodocusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, DiplodocusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, DiplodocusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/DistortusRexRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/DistortusRexRenderer.java index 3f9161b..927c826 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/DistortusRexRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/DistortusRexRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class DistortusRexRenderer extends GeoEntityRenderer { - private final float animalScale = 3.4F; public DistortusRexRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new DistortusRexModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, DistortusRexEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/DryosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/DryosaurusRenderer.java index 9216297..e5b090f 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/DryosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/DryosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class DryosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.45F; - public DryosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new DryosaurusModel()); - } + public DryosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new DryosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, DryosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, DryosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/EdmontosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/EdmontosaurusRenderer.java index 926c7c5..577c23c 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/EdmontosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/EdmontosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class EdmontosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.8F; - public EdmontosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new EdmontosaurusModel()); - } + public EdmontosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new EdmontosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, EdmontosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, EdmontosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/FDuckRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/FDuckRenderer.java index b60b857..e856f1d 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/FDuckRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/FDuckRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class FDuckRenderer extends GeoEntityRenderer { - private final float animalScale = 1.4F; - public FDuckRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new FDuckModel()); - } + public FDuckRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new FDuckModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, FDuckEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, FDuckEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/GallimimusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/GallimimusRenderer.java index 341f7e9..bbcfb27 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/GallimimusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/GallimimusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class GallimimusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.0F; - public GallimimusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new GallimimusModel()); - } + public GallimimusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new GallimimusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, GallimimusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, GallimimusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/GeosternbergiaRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/GeosternbergiaRenderer.java index 1d4a250..3f8700b 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/GeosternbergiaRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/GeosternbergiaRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class GeosternbergiaRenderer extends GeoEntityRenderer { - private final float animalScale = 1.4F; - public GeosternbergiaRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new GeosternbergiaModel()); - } + public GeosternbergiaRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new GeosternbergiaModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, GeosternbergiaEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, GeosternbergiaEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/GiganotosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/GiganotosaurusRenderer.java index 23e5601..11e4f24 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/GiganotosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/GiganotosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class GiganotosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 2.2F; public GiganotosaurusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new GiganotosaurusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, GiganotosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/GuanlongRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/GuanlongRenderer.java index 9cecb7b..2b75b65 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/GuanlongRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/GuanlongRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class GuanlongRenderer extends GeoEntityRenderer { - private final float animalScale = 0.6F; - public GuanlongRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new GuanlongModel()); - } + public GuanlongRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new GuanlongModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, GuanlongEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, GuanlongEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/GuidracoRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/GuidracoRenderer.java index 317e892..df83cbd 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/GuidracoRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/GuidracoRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class GuidracoRenderer extends GeoEntityRenderer { - private final float animalScale = 0.8F; - public GuidracoRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new GuidracoModel()); - } + public GuidracoRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new GuidracoModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, GuidracoEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, GuidracoEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/HadrosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/HadrosaurusRenderer.java index 580abcd..f636457 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/HadrosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/HadrosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class HadrosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.5F; - public HadrosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new HadrosaurusModel()); - } + public HadrosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new HadrosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, HadrosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, HadrosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/HerrerasaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/HerrerasaurusRenderer.java index 7ec746c..0424349 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/HerrerasaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/HerrerasaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class HerrerasaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.3F; - public HerrerasaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new HerrerasaurusModel()); - } + public HerrerasaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new HerrerasaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, HerrerasaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, HerrerasaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/HypsilophodonRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/HypsilophodonRenderer.java index 45e0d5a..277cad1 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/HypsilophodonRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/HypsilophodonRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class HypsilophodonRenderer extends GeoEntityRenderer { - private final float animalScale = 0.5F; - public HypsilophodonRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new HypsilophodonModel()); - } + public HypsilophodonRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new HypsilophodonModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, HypsilophodonEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, HypsilophodonEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/IndominusRexRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/IndominusRexRenderer.java index 0b4f3db..9f466d6 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/IndominusRexRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/IndominusRexRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class IndominusRexRenderer extends GeoEntityRenderer { - private final float animalScale = 3.0F; - public IndominusRexRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new IndominusRexModel()); - } + public IndominusRexRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new IndominusRexModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, IndominusRexEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, IndominusRexEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/IndoraptorRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/IndoraptorRenderer.java index 92aeaa5..547936c 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/IndoraptorRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/IndoraptorRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class IndoraptorRenderer extends GeoEntityRenderer { - private final float animalScale = 1.8F; - public IndoraptorRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new IndoraptorModel()); - } + public IndoraptorRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new IndoraptorModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, IndoraptorEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, IndoraptorEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/InostranceviaRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/InostranceviaRenderer.java index 6b24848..08326d4 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/InostranceviaRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/InostranceviaRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class InostranceviaRenderer extends GeoEntityRenderer { - private final float animalScale = 1.1F; - public InostranceviaRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new InostranceviaModel()); - } + public InostranceviaRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new InostranceviaModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, InostranceviaEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, InostranceviaEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/LambeosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/LambeosaurusRenderer.java index d69b200..f0ea410 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/LambeosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/LambeosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class LambeosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.8F; - public LambeosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new LambeosaurusModel()); - } + public LambeosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new LambeosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, LambeosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, LambeosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/LudodactylusModel.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/LudodactylusModel.java index 5a29272..2d5796a 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/LudodactylusModel.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/LudodactylusModel.java @@ -25,6 +25,9 @@ public class LudodactylusModel extends GeoModel { map.put(LudodactylusVariant.FEMALE, Constants.rl("textures/entity/ludodactylus_female.png")); }); + private static final ResourceLocation PINWIN_LOCATION = + Constants.rl("textures/entity/ludodactylus_pinwin.png"); + // Model-local "currently applied" offsets; cleared before each entity render private float[] appliedYaw = null; private float[] appliedRoll = null; @@ -36,6 +39,10 @@ public class LudodactylusModel extends GeoModel { @Override public ResourceLocation getTextureResource(LudodactylusEntity animatable) { + if (animatable.hasCustomName() && "pinwin".equalsIgnoreCase(animatable.getName().getString())) { + return PINWIN_LOCATION; + } + return LOCATION_BY_VARIANT.get(animatable.getVariant()); } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/LudodactylusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/LudodactylusRenderer.java index d024549..3f6a82b 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/LudodactylusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/LudodactylusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class LudodactylusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.5F; - public LudodactylusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new LudodactylusModel()); - } + public LudodactylusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new LudodactylusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, LudodactylusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, LudodactylusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/MajungasaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/MajungasaurusRenderer.java index 6ee34f7..83deb3f 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/MajungasaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/MajungasaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class MajungasaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.4F; - public MajungasaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new MajungasaurusModel()); - } + public MajungasaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new MajungasaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, MajungasaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, MajungasaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/MamenchisaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/MamenchisaurusRenderer.java index 1a15817..4fd5f8f 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/MamenchisaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/MamenchisaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class MamenchisaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.7F; - public MamenchisaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new MamenchisaurusModel()); - } + public MamenchisaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new MamenchisaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, MamenchisaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, MamenchisaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/MetriacanthosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/MetriacanthosaurusRenderer.java index a5a3926..747f061 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/MetriacanthosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/MetriacanthosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class MetriacanthosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.5F; public MetriacanthosaurusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new MetriacanthosaurusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, MetriacanthosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/MoganopterusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/MoganopterusRenderer.java index 95d79c8..39eb47b 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/MoganopterusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/MoganopterusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class MoganopterusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.8F; public MoganopterusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new MoganopterusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, MoganopterusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/MussasaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/MussasaurusRenderer.java index 77f40f1..fc595b0 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/MussasaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/MussasaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class MussasaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.7F; public MussasaurusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new MussasaurusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, MussasaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/NyctosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/NyctosaurusRenderer.java index db81d30..3c4704d 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/NyctosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/NyctosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class NyctosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.3F; public NyctosaurusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new NyctosaurusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, NyctosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/OrnitholestesRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/OrnitholestesRenderer.java index 1a84e1e..5cb6116 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/OrnitholestesRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/OrnitholestesRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class OrnitholestesRenderer extends GeoEntityRenderer { - private final float animalScale = 0.6F; - public OrnitholestesRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new OrnitholestesModel()); - } + public OrnitholestesRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new OrnitholestesModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, OrnitholestesEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, OrnitholestesEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/OrnithomimusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/OrnithomimusRenderer.java index 1a16fa1..168fb14 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/OrnithomimusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/OrnithomimusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class OrnithomimusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.8F; public OrnithomimusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new OrnithomimusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, OrnithomimusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/OuranosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/OuranosaurusRenderer.java index eef76b8..5890dd2 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/OuranosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/OuranosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class OuranosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.2F; public OuranosaurusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new OuranosaurusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, OuranosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/OviraptorRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/OviraptorRenderer.java index 80f6e38..cdf51af 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/OviraptorRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/OviraptorRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class OviraptorRenderer extends GeoEntityRenderer { - private final float animalScale = 0.55F; - public OviraptorRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new OviraptorModel()); - } + public OviraptorRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new OviraptorModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, OviraptorEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, OviraptorEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/PachycephalosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/PachycephalosaurusRenderer.java index 8f683d9..5c820c1 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/PachycephalosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/PachycephalosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class PachycephalosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.8F; - public PachycephalosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new PachycephalosaurusModel()); - } + public PachycephalosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new PachycephalosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, PachycephalosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, PachycephalosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ParasaurolophusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ParasaurolophusRenderer.java index 1e67593..dc3aa20 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ParasaurolophusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ParasaurolophusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class ParasaurolophusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.7F; - public ParasaurolophusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new ParasaurolophusModel()); - } + public ParasaurolophusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new ParasaurolophusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ParasaurolophusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ParasaurolophusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ProceratosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ProceratosaurusRenderer.java index 41f34cb..fc80d6a 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ProceratosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ProceratosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class ProceratosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.6F; - public ProceratosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new ProceratosaurusModel()); - } + public ProceratosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new ProceratosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ProceratosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ProceratosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ProcompsognathusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ProcompsognathusRenderer.java index 6e949d3..2552ead 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ProcompsognathusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ProcompsognathusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class ProcompsognathusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.2F; public ProcompsognathusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new ProcompsognathusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ProcompsognathusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ProtoceratopsRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ProtoceratopsRenderer.java index 58c70e6..2f20c61 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ProtoceratopsRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ProtoceratopsRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class ProtoceratopsRenderer extends GeoEntityRenderer { - private final float animalScale = 1.2F; - public ProtoceratopsRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new ProtoceratopsModel()); - } + public ProtoceratopsRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new ProtoceratopsModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ProtoceratopsEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ProtoceratopsEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/PteranodonRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/PteranodonRenderer.java index e482136..7b668ce 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/PteranodonRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/PteranodonRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class PteranodonRenderer extends GeoEntityRenderer { - private final float animalScale = 1.5F; - public PteranodonRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new PteranodonModel()); - } + public PteranodonRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new PteranodonModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, PteranodonEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, PteranodonEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/PterodaustroRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/PterodaustroRenderer.java index b7048ec..503b511 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/PterodaustroRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/PterodaustroRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class PterodaustroRenderer extends GeoEntityRenderer { - private final float animalScale = 0.7F; - public PterodaustroRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new PterodaustroModel()); - } + public PterodaustroRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new PterodaustroModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, PterodaustroEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, PterodaustroEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/QuetzalcoatlusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/QuetzalcoatlusRenderer.java index d4f3b37..b368c16 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/QuetzalcoatlusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/QuetzalcoatlusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class QuetzalcoatlusRenderer extends GeoEntityRenderer { - private final float animalScale = 2.0F; public QuetzalcoatlusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new QuetzalcoatlusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, QuetzalcoatlusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/RajasaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/RajasaurusRenderer.java index 8c08a95..9d90916 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/RajasaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/RajasaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class RajasaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.5F; public RajasaurusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new RajasaurusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, RajasaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/RugopsRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/RugopsRenderer.java index cc92bb7..fb74c29 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/RugopsRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/RugopsRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class RugopsRenderer extends GeoEntityRenderer { - private final float animalScale = 0.9F; public RugopsRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new RugopsModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, RugopsEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/SegisaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/SegisaurusRenderer.java index 9515d15..d501b5a 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/SegisaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/SegisaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class SegisaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.62F; public SegisaurusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new SegisaurusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, SegisaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ShantungosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ShantungosaurusRenderer.java index b17f2cb..8bf54b2 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ShantungosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ShantungosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class ShantungosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.8F; public ShantungosaurusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new ShantungosaurusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ShantungosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/SpinosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/SpinosaurusRenderer.java index 1dd7013..c2b0f0b 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/SpinosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/SpinosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class SpinosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 2.2F; public SpinosaurusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new SpinosaurusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, SpinosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/StegosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/StegosaurusRenderer.java index 56f28a4..e1cc2e0 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/StegosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/StegosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class StegosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.8F; - public StegosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new StegosaurusModel()); - } + public StegosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new StegosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, StegosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, StegosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/StyracosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/StyracosaurusRenderer.java index ff0cf36..903dfbb 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/StyracosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/StyracosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class StyracosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.7F; - public StyracosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new StyracosaurusModel()); - } + public StyracosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new StyracosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, StyracosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, StyracosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/SuchomimusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/SuchomimusRenderer.java index 935985b..9c6a4e8 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/SuchomimusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/SuchomimusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class SuchomimusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.5F; public SuchomimusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new SuchomimusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, SuchomimusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TapejaraRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TapejaraRenderer.java index b86b50b..97f9943 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TapejaraRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TapejaraRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class TapejaraRenderer extends GeoEntityRenderer { - private final float animalScale = 0.6F; - public TapejaraRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new TapejaraModel()); - } + public TapejaraRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new TapejaraModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, TapejaraEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, TapejaraEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TherizinosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TherizinosaurusRenderer.java index bbca7f9..85424b6 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TherizinosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TherizinosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class TherizinosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.9F; - public TherizinosaurusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new TherizinosaurusModel()); - } + public TherizinosaurusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new TherizinosaurusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, TherizinosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, TherizinosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ThescelosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ThescelosaurusRenderer.java index 032f631..41f7fe7 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ThescelosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ThescelosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class ThescelosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 0.7F; public ThescelosaurusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new ThescelosaurusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ThescelosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TitanosaurusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TitanosaurusRenderer.java index 1495129..3e7fa0b 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TitanosaurusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TitanosaurusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class TitanosaurusRenderer extends GeoEntityRenderer { - private final float animalScale = 2.3F; public TitanosaurusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new TitanosaurusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, TitanosaurusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TriceratopsRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TriceratopsRenderer.java index f589f07..0e99753 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TriceratopsRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TriceratopsRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class TriceratopsRenderer extends GeoEntityRenderer { - private final float animalScale = 1.5F; - public TriceratopsRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new TriceratopsModel()); - } + public TriceratopsRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new TriceratopsModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, TriceratopsEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, TriceratopsEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TroodonRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TroodonRenderer.java index 3d09201..7ceca2c 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TroodonRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TroodonRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class TroodonRenderer extends GeoEntityRenderer { - private final float animalScale = 0.3F; public TroodonRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new TroodonModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, TroodonEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TropeognathusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TropeognathusRenderer.java index f2c1c5e..ea02419 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TropeognathusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TropeognathusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class TropeognathusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.4F; - public TropeognathusRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new TropeognathusModel()); - } + public TropeognathusRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new TropeognathusModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, TropeognathusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, TropeognathusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TupuxuaraRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TupuxuaraRenderer.java index 1e31bda..d0fec54 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TupuxuaraRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TupuxuaraRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class TupuxuaraRenderer extends GeoEntityRenderer { - private final float animalScale = 1.0F; public TupuxuaraRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new TupuxuaraModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, TupuxuaraEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TyrannosaurusRexModel.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TyrannosaurusRexModel.java index 6fdca42..54f9ed8 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TyrannosaurusRexModel.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TyrannosaurusRexModel.java @@ -25,6 +25,12 @@ public class TyrannosaurusRexModel extends GeoModel { map.put(TyrannosaurusRexVariant.FEMALE, Constants.rl("textures/entity/tyrannosaurus_rex_female.png")); }); + private static final ResourceLocation DRGRAY_LOCATION = + Constants.rl("textures/entity/tyrannosaurus_rex_drgray.png"); + + private static final ResourceLocation EMBER_LOCATION = + Constants.rl("textures/entity/tyrannosaurus_rex_ember.png"); + // Model-local "currently applied" offsets; cleared before each entity render private float[] appliedYaw = null; private float[] appliedRoll = null; @@ -36,7 +42,15 @@ public class TyrannosaurusRexModel extends GeoModel { @Override public ResourceLocation getTextureResource(TyrannosaurusRexEntity animatable) { - return LOCATION_BY_VARIANT.get(animatable.getVariant()); + if (animatable.hasCustomName() && "drgray".equalsIgnoreCase(animatable.getName().getString())) { + return DRGRAY_LOCATION; + } + + if (animatable.hasCustomName() && "ember".equalsIgnoreCase(animatable.getName().getString())) { + return EMBER_LOCATION; + } + + return LOCATION_BY_VARIANT.get(animatable.getVariant()); } @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TyrannosaurusRexRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TyrannosaurusRexRenderer.java index 57041aa..c3d2765 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/TyrannosaurusRexRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/TyrannosaurusRexRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class TyrannosaurusRexRenderer extends GeoEntityRenderer { - private final float animalScale = 2.5F; public TyrannosaurusRexRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new TyrannosaurusRexModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, TyrannosaurusRexEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/UtahraptorRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/UtahraptorRenderer.java index 530242d..efc4063 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/UtahraptorRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/UtahraptorRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class UtahraptorRenderer extends GeoEntityRenderer { - private final float animalScale = 1.0F; - public UtahraptorRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new UtahraptorModel()); - } + public UtahraptorRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new UtahraptorModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, UtahraptorEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, UtahraptorEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/VelociraptorModel.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/VelociraptorModel.java index 16d8559..d14cf79 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/VelociraptorModel.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/VelociraptorModel.java @@ -25,6 +25,18 @@ public class VelociraptorModel extends GeoModel { map.put(VelociraptorVariant.FEMALE, Constants.rl("textures/entity/velociraptor_female.png")); }); + private static final ResourceLocation BLUE_LOCATION = + Constants.rl("textures/entity/velociraptor_blue.png"); + + private static final ResourceLocation CHARLIE_LOCATION = + Constants.rl("textures/entity/velociraptor_charlie.png"); + + private static final ResourceLocation DELTA_LOCATION = + Constants.rl("textures/entity/velociraptor_delta.png"); + + private static final ResourceLocation ECHO_LOCATION = + Constants.rl("textures/entity/velociraptor_echo.png"); + // Model-local "currently applied" offsets; cleared before each entity render private float[] appliedYaw = null; private float[] appliedRoll = null; @@ -36,6 +48,19 @@ public class VelociraptorModel extends GeoModel { @Override public ResourceLocation getTextureResource(VelociraptorEntity animatable) { + if (animatable.hasCustomName() && "blue".equalsIgnoreCase(animatable.getName().getString())) { + return BLUE_LOCATION; + } + if (animatable.hasCustomName() && "charlie".equalsIgnoreCase(animatable.getName().getString())) { + return CHARLIE_LOCATION; + } + if (animatable.hasCustomName() && "delta".equalsIgnoreCase(animatable.getName().getString())) { + return DELTA_LOCATION; + } + if (animatable.hasCustomName() && "echo".equalsIgnoreCase(animatable.getName().getString())) { + return ECHO_LOCATION; + } + return LOCATION_BY_VARIANT.get(animatable.getVariant()); } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/VelociraptorRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/VelociraptorRenderer.java index 06216da..36ee698 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/VelociraptorRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/VelociraptorRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class VelociraptorRenderer extends GeoEntityRenderer { - private final float animalScale = 1.0F; - public VelociraptorRenderer(EntityRendererProvider.Context renderManager) { - super(renderManager, new VelociraptorModel()); - } + public VelociraptorRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new VelociraptorModel()); + } - @Override - public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, VelociraptorEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } - } + @Override + public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, VelociraptorEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); + } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ZhenyuanopterusRenderer.java b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ZhenyuanopterusRenderer.java index bb12bbf..2a54a88 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/client/ZhenyuanopterusRenderer.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/client/ZhenyuanopterusRenderer.java @@ -9,18 +9,13 @@ import software.bernie.geckolib.renderer.GeoEntityRenderer; public class ZhenyuanopterusRenderer extends GeoEntityRenderer { - private final float animalScale = 1.1F; public ZhenyuanopterusRenderer(EntityRendererProvider.Context renderManager) { super(renderManager, new ZhenyuanopterusModel()); } @Override public void scaleModelForRender(float widthScale, float heightScale, PoseStack poseStack, ZhenyuanopterusEntity animatable, BakedGeoModel model, boolean isReRender, float partialTick, int packedLight, int packedOverlay) { - poseStack.scale(animalScale, animalScale, animalScale); - if(animatable.isBaby()) { - float growthProgress = Mth.clamp((24000.0F + animatable.getSyncedAge()) / 24000.0F, 0.0F, 1.0F); - float scale = Mth.lerp(growthProgress, 0.2F, 1.0F); - poseStack.scale(scale, scale, scale); - } + float scale = animatable.getTotalModelScale(); + poseStack.scale(scale, scale, scale); } } diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AchillobatorEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AchillobatorEntity.java index 8fd1706..e98dca8 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AchillobatorEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AchillobatorEntity.java @@ -46,9 +46,9 @@ import software.bernie.geckolib.animation.*; public class AchillobatorEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - public static final int BABY_TO_ADULT_AGE_TICKS = 240; - private static final float MIN_ANIMAL_SCALE = 0.92F; - private static final float MAX_ANIMAL_SCALE = 1.08F; + public static final int BABY_TO_ADULT_AGE_TICKS = 28800; + private static final float MIN_ANIMAL_SCALE = 0.8F; + private static final float MAX_ANIMAL_SCALE = 1.2F; private float lastDimensionsScale = 1.0F; diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AlbertosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AlbertosaurusEntity.java index f5c6eaa..62d6ad5 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AlbertosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AlbertosaurusEntity.java @@ -47,10 +47,18 @@ import software.bernie.geckolib.animation.*; public class AlbertosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 67200; + private static final float MIN_ANIMAL_SCALE = 1.5F; + private static final float MAX_ANIMAL_SCALE = 1.9F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(AlbertosaurusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(AlbertosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(AlbertosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -103,6 +111,10 @@ public class AlbertosaurusEntity extends DinoEntityBase implements GeoEntity { return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); } + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } + public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() .add(Attributes.MAX_HEALTH, 55D) @@ -121,6 +133,7 @@ public class AlbertosaurusEntity extends DinoEntityBase implements GeoEntity { if (child instanceof AlbertosaurusEntity baby) { AlbertosaurusVariant randomVariant = Util.getRandom(AlbertosaurusVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -179,6 +192,8 @@ public class AlbertosaurusEntity extends DinoEntityBase implements GeoEntity { } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -244,6 +259,7 @@ public class AlbertosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -251,6 +267,7 @@ public class AlbertosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ @@ -258,6 +275,48 @@ public class AlbertosaurusEntity extends DinoEntityBase implements GeoEntity { return this.entityData.get(DATA_SYNCED_AGE); } + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ + public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -280,12 +339,16 @@ public class AlbertosaurusEntity extends DinoEntityBase implements GeoEntity { public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } /*? if <=1.20.1 {*/ @@ -293,15 +356,13 @@ public class AlbertosaurusEntity extends DinoEntityBase implements GeoEntity { public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { AlbertosaurusVariant variant = Util.getRandom(AlbertosaurusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - AlbertosaurusVariant variant = Util.getRandom(AlbertosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + AlbertosaurusVariant variant = Util.getRandom(AlbertosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AllosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AllosaurusEntity.java index 9cab7ee..ca60d34 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AllosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AllosaurusEntity.java @@ -50,10 +50,18 @@ import software.bernie.geckolib.animation.*; public class AllosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(AllosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(AllosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 52800; + private static final float MIN_ANIMAL_SCALE = 1.7F; + private static final float MAX_ANIMAL_SCALE = 2.1F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(AllosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(AllosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(AllosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,6 +114,10 @@ public class AllosaurusEntity extends DinoEntityBase implements GeoEntity { return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); } + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } + public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() .add(Attributes.MAX_HEALTH, 65D) @@ -117,16 +129,17 @@ public class AllosaurusEntity extends DinoEntityBase implements GeoEntity { .add(Attributes.ATTACK_DAMAGE, 18D); } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.ALLOSAURUS.get().create(pLevel); - if (child instanceof AllosaurusEntity baby) { - AllosaurusVariant randomVariant = Util.getRandom(AllosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.ALLOSAURUS.get().create(pLevel); + if (child instanceof AllosaurusEntity baby) { + AllosaurusVariant randomVariant = Util.getRandom(AllosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -178,11 +191,13 @@ public class AllosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -247,6 +262,7 @@ public class AllosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -254,12 +270,55 @@ public class AllosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -278,33 +337,35 @@ public class AllosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof AllosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - AllosaurusVariant variant = Util.getRandom(AllosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - AllosaurusVariant variant = Util.getRandom(AllosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + AllosaurusVariant variant = Util.getRandom(AllosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + AllosaurusVariant variant = Util.getRandom(AllosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AlvarezsaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AlvarezsaurusEntity.java index 2b109cc..b45517d 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AlvarezsaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AlvarezsaurusEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class AlvarezsaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(AlvarezsaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(AlvarezsaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 19200; + private static final float MIN_ANIMAL_SCALE = 0.6F; + private static final float MAX_ANIMAL_SCALE = 1.0F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(AlvarezsaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(AlvarezsaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(AlvarezsaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class AlvarezsaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_ALVAREZSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class AlvarezsaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.ALVAREZSAURUS.get().create(pLevel); - if (child instanceof AlvarezsaurusEntity baby) { - AlvarezsaurusVariant randomVariant = Util.getRandom(AlvarezsaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.ALVAREZSAURUS.get().create(pLevel); + if (child instanceof AlvarezsaurusEntity baby) { + AlvarezsaurusVariant randomVariant = Util.getRandom(AlvarezsaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -182,11 +195,13 @@ public class AlvarezsaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -251,6 +266,7 @@ public class AlvarezsaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -258,12 +274,55 @@ public class AlvarezsaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -282,33 +341,35 @@ public class AlvarezsaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof AlvarezsaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - AlvarezsaurusVariant variant = Util.getRandom(AlvarezsaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - AlvarezsaurusVariant variant = Util.getRandom(AlvarezsaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + AlvarezsaurusVariant variant = Util.getRandom(AlvarezsaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + AlvarezsaurusVariant variant = Util.getRandom(AlvarezsaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AnkylosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AnkylosaurusEntity.java index 6159dcd..6963e2e 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AnkylosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/AnkylosaurusEntity.java @@ -53,10 +53,18 @@ import software.bernie.geckolib.animation.*; public class AnkylosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(AnkylosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(AnkylosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 86400; + private static final float MIN_ANIMAL_SCALE = 2.2F; + private static final float MAX_ANIMAL_SCALE = 2.6F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(AnkylosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(AnkylosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(AnkylosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -105,10 +113,14 @@ public class AnkylosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_ANKYLOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -122,16 +134,17 @@ public class AnkylosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.ANKYLOSAURUS.get().create(pLevel); - if (child instanceof AnkylosaurusEntity baby) { - AnkylosaurusVariant randomVariant = Util.getRandom(AnkylosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.ANKYLOSAURUS.get().create(pLevel); + if (child instanceof AnkylosaurusEntity baby) { + AnkylosaurusVariant randomVariant = Util.getRandom(AnkylosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -181,11 +194,13 @@ public class AnkylosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -250,6 +265,7 @@ public class AnkylosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -257,12 +273,55 @@ public class AnkylosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -281,33 +340,35 @@ public class AnkylosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof AnkylosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - AnkylosaurusVariant variant = Util.getRandom(AnkylosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - AnkylosaurusVariant variant = Util.getRandom(AnkylosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + AnkylosaurusVariant variant = Util.getRandom(AnkylosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + AnkylosaurusVariant variant = Util.getRandom(AnkylosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ApatosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ApatosaurusEntity.java index 31101b3..4d8a7d7 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ApatosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ApatosaurusEntity.java @@ -55,10 +55,18 @@ import software.bernie.geckolib.animation.*; public class ApatosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(ApatosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(ApatosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 110400; + private static final float MIN_ANIMAL_SCALE = 1.7F; + private static final float MAX_ANIMAL_SCALE = 2.1F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(ApatosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(ApatosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(ApatosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -107,10 +115,14 @@ public class ApatosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_APATOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -124,16 +136,17 @@ public class ApatosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.APATOSAURUS.get().create(pLevel); - if (child instanceof ApatosaurusEntity baby) { - ApatosaurusVariant randomVariant = Util.getRandom(ApatosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.APATOSAURUS.get().create(pLevel); + if (child instanceof ApatosaurusEntity baby) { + ApatosaurusVariant randomVariant = Util.getRandom(ApatosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -185,11 +198,13 @@ public class ApatosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -254,6 +269,7 @@ public class ApatosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -261,12 +277,55 @@ public class ApatosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -285,33 +344,35 @@ public class ApatosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof ApatosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - ApatosaurusVariant variant = Util.getRandom(ApatosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - ApatosaurusVariant variant = Util.getRandom(ApatosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + ApatosaurusVariant variant = Util.getRandom(ApatosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + ApatosaurusVariant variant = Util.getRandom(ApatosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ArambourgianiaEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ArambourgianiaEntity.java index 5ec9da3..8fb6206 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ArambourgianiaEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ArambourgianiaEntity.java @@ -63,10 +63,18 @@ import software.bernie.geckolib.animation.*; public class ArambourgianiaEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 43200; + private static final float MIN_ANIMAL_SCALE = 1.7F; + private static final float MAX_ANIMAL_SCALE = 2.1F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(ArambourgianiaEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(ArambourgianiaEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(ArambourgianiaEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -121,6 +129,10 @@ public class ArambourgianiaEntity extends DinoEntityBase implements GeoEntity, F return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); } + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } + public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() .add(Attributes.MAX_HEALTH, 100D) @@ -164,6 +176,7 @@ public class ArambourgianiaEntity extends DinoEntityBase implements GeoEntity, F if (child instanceof ArambourgianiaEntity baby) { ArambourgianiaVariant randomVariant = Util.getRandom(ArambourgianiaVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -225,6 +238,8 @@ public class ArambourgianiaEntity extends DinoEntityBase implements GeoEntity, F } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -290,6 +305,7 @@ public class ArambourgianiaEntity extends DinoEntityBase implements GeoEntity, F super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -297,6 +313,7 @@ public class ArambourgianiaEntity extends DinoEntityBase implements GeoEntity, F super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ @@ -304,6 +321,48 @@ public class ArambourgianiaEntity extends DinoEntityBase implements GeoEntity, F return this.entityData.get(DATA_SYNCED_AGE); } + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ + public ArambourgianiaVariant getVariant() { return ArambourgianiaVariant.byId(this.getTypeVariant() & 255); } @@ -327,27 +386,29 @@ public class ArambourgianiaEntity extends DinoEntityBase implements GeoEntity, F public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { ArambourgianiaVariant variant = Util.getRandom(ArambourgianiaVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - ArambourgianiaVariant variant = Util.getRandom(ArambourgianiaVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + ArambourgianiaVariant variant = Util.getRandom(ArambourgianiaVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } @Override public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/BaryonyxEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/BaryonyxEntity.java index 9afef59..6d47a0b 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/BaryonyxEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/BaryonyxEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class BaryonyxEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(BaryonyxEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(BaryonyxEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 52800; + private static final float MIN_ANIMAL_SCALE = 1.1F; + private static final float MAX_ANIMAL_SCALE = 1.5F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(BaryonyxEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(BaryonyxEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(BaryonyxEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class BaryonyxEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_BARYONYX_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class BaryonyxEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.BARYONYX.get().create(pLevel); - if (child instanceof BaryonyxEntity baby) { - BaryonyxVariant randomVariant = Util.getRandom(BaryonyxVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.BARYONYX.get().create(pLevel); + if (child instanceof BaryonyxEntity baby) { + BaryonyxVariant randomVariant = Util.getRandom(BaryonyxVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -184,11 +197,13 @@ public class BaryonyxEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -253,6 +268,7 @@ public class BaryonyxEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -260,12 +276,55 @@ public class BaryonyxEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -284,33 +343,35 @@ public class BaryonyxEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof BaryonyxEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - BaryonyxVariant variant = Util.getRandom(BaryonyxVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - BaryonyxVariant variant = Util.getRandom(BaryonyxVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + BaryonyxVariant variant = Util.getRandom(BaryonyxVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + BaryonyxVariant variant = Util.getRandom(BaryonyxVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/BrachiosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/BrachiosaurusEntity.java index ae4081c..63bbdd4 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/BrachiosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/BrachiosaurusEntity.java @@ -55,10 +55,18 @@ import software.bernie.geckolib.animation.*; public class BrachiosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(BrachiosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(BrachiosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 134400; + private static final float MIN_ANIMAL_SCALE = 1.8F; + private static final float MAX_ANIMAL_SCALE = 2.2F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(BrachiosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(BrachiosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(BrachiosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -107,10 +115,14 @@ public class BrachiosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_BRACHIOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -124,16 +136,17 @@ public class BrachiosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.BRACHIOSAURUS.get().create(pLevel); - if (child instanceof BrachiosaurusEntity baby) { - BrachiosaurusVariant randomVariant = Util.getRandom(BrachiosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.BRACHIOSAURUS.get().create(pLevel); + if (child instanceof BrachiosaurusEntity baby) { + BrachiosaurusVariant randomVariant = Util.getRandom(BrachiosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -185,11 +198,13 @@ public class BrachiosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -254,6 +269,7 @@ public class BrachiosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -261,12 +277,55 @@ public class BrachiosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -285,33 +344,35 @@ public class BrachiosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof BrachiosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - BrachiosaurusVariant variant = Util.getRandom(BrachiosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - BrachiosaurusVariant variant = Util.getRandom(BrachiosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + BrachiosaurusVariant variant = Util.getRandom(BrachiosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + BrachiosaurusVariant variant = Util.getRandom(BrachiosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CarcharodontosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CarcharodontosaurusEntity.java index 8cef66b..83ba415 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CarcharodontosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CarcharodontosaurusEntity.java @@ -57,10 +57,18 @@ import software.bernie.geckolib.animation.*; public class CarcharodontosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 72000; + private static final float MIN_ANIMAL_SCALE = 1.8F; + private static final float MAX_ANIMAL_SCALE = 2.2F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(CarcharodontosaurusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(CarcharodontosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(CarcharodontosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -114,6 +122,10 @@ public class CarcharodontosaurusEntity extends DinoEntityBase implements GeoEnti return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); } + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } + public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() .add(Attributes.MAX_HEALTH, 80D) @@ -133,6 +145,7 @@ public class CarcharodontosaurusEntity extends DinoEntityBase implements GeoEnti if (child instanceof CarcharodontosaurusEntity baby) { CarcharodontosaurusVariant randomVariant = Util.getRandom(CarcharodontosaurusVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -186,10 +199,12 @@ public class CarcharodontosaurusEntity extends DinoEntityBase implements GeoEnti double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } + } } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -255,19 +270,58 @@ public class CarcharodontosaurusEntity extends DinoEntityBase implements GeoEnti super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ public int getSyncedAge() { return this.entityData.get(DATA_SYNCED_AGE); } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -290,12 +344,16 @@ public class CarcharodontosaurusEntity extends DinoEntityBase implements GeoEnti public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } /*? if <=1.20.1 {*/ @@ -303,15 +361,13 @@ public class CarcharodontosaurusEntity extends DinoEntityBase implements GeoEnti public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { CarcharodontosaurusVariant variant = Util.getRandom(CarcharodontosaurusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - CarcharodontosaurusVariant variant = Util.getRandom(CarcharodontosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + CarcharodontosaurusVariant variant = Util.getRandom(CarcharodontosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CarnotaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CarnotaurusEntity.java index 1a21e01..59e4715 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CarnotaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CarnotaurusEntity.java @@ -51,10 +51,18 @@ import software.bernie.geckolib.animation.*; public class CarnotaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(CarnotaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(CarnotaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 43200; + private static final float MIN_ANIMAL_SCALE = 1.3F; + private static final float MAX_ANIMAL_SCALE = 1.7F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(CarnotaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(CarnotaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(CarnotaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -104,8 +112,12 @@ public class CarnotaurusEntity extends DinoEntityBase implements GeoEntity { } @Override - public DinoEntityBase.DinoAIConfig getAIConfig() { - return new DinoEntityBase.DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); } public static AttributeSupplier.Builder createAttributes() { @@ -126,6 +138,7 @@ public class CarnotaurusEntity extends DinoEntityBase implements GeoEntity { if (child instanceof CarnotaurusEntity baby) { CarnotaurusVariant randomVariant = Util.getRandom(CarnotaurusVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -179,11 +192,13 @@ public class CarnotaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -248,6 +263,7 @@ public class CarnotaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -255,12 +271,55 @@ public class CarnotaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -279,32 +338,34 @@ public class CarnotaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof CarnotaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } /*? if <=1.20.1 {*/ @Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { CarnotaurusVariant variant = Util.getRandom(CarnotaurusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - CarnotaurusVariant variant = Util.getRandom(CarnotaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + CarnotaurusVariant variant = Util.getRandom(CarnotaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CearadactylusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CearadactylusEntity.java index 7c36c94..b2f06e5 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CearadactylusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CearadactylusEntity.java @@ -63,10 +63,18 @@ import software.bernie.geckolib.animation.*; public class CearadactylusEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(CearadactylusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(CearadactylusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 28800; + private static final float MIN_ANIMAL_SCALE = 0.7F; + private static final float MAX_ANIMAL_SCALE = 1.1F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(CearadactylusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(CearadactylusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(CearadactylusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -116,10 +124,14 @@ public class CearadactylusEntity extends DinoEntityBase implements GeoEntity, Fl return ModBlocks.INCUBATED_CEARADACTYLUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -157,16 +169,17 @@ public class CearadactylusEntity extends DinoEntityBase implements GeoEntity, Fl } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.CEARADACTYLUS.get().create(pLevel); - if (child instanceof CearadactylusEntity baby) { - CearadactylusVariant randomVariant = Util.getRandom(CearadactylusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.CEARADACTYLUS.get().create(pLevel); + if (child instanceof CearadactylusEntity baby) { + CearadactylusVariant randomVariant = Util.getRandom(CearadactylusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -221,11 +234,13 @@ public class CearadactylusEntity extends DinoEntityBase implements GeoEntity, Fl double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -290,6 +305,7 @@ public class CearadactylusEntity extends DinoEntityBase implements GeoEntity, Fl super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -297,12 +313,55 @@ public class CearadactylusEntity extends DinoEntityBase implements GeoEntity, Fl super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public CearadactylusVariant getVariant() { return CearadactylusVariant.byId(this.getTypeVariant() & 255); @@ -327,28 +386,30 @@ public class CearadactylusEntity extends DinoEntityBase implements GeoEntity, Fl public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { CearadactylusVariant variant = Util.getRandom(CearadactylusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - CearadactylusVariant variant = Util.getRandom(CearadactylusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + CearadactylusVariant variant = Util.getRandom(CearadactylusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CeratosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CeratosaurusEntity.java index 3b9d6ef..40600f4 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CeratosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CeratosaurusEntity.java @@ -50,10 +50,18 @@ import software.bernie.geckolib.animation.*; public class CeratosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(CeratosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(CeratosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 38400; + private static final float MIN_ANIMAL_SCALE = 1.9F; + private static final float MAX_ANIMAL_SCALE = 2.3F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(CeratosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(CeratosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(CeratosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -107,6 +115,10 @@ public class CeratosaurusEntity extends DinoEntityBase implements GeoEntity { return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); } + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } + public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() .add(Attributes.MAX_HEALTH, 55D) @@ -118,16 +130,17 @@ public class CeratosaurusEntity extends DinoEntityBase implements GeoEntity { .add(Attributes.ATTACK_DAMAGE, 16D ); } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.CERATOSAURUS.get().create(pLevel); - if (child instanceof CeratosaurusEntity baby) { - CeratosaurusVariant randomVariant = Util.getRandom(CeratosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.CERATOSAURUS.get().create(pLevel); + if (child instanceof CeratosaurusEntity baby) { + CeratosaurusVariant randomVariant = Util.getRandom(CeratosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -178,11 +191,13 @@ public class CeratosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -247,6 +262,7 @@ public class CeratosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -254,12 +270,55 @@ public class CeratosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); @@ -279,33 +338,35 @@ public class CeratosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof CeratosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - CeratosaurusVariant variant = Util.getRandom(CeratosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - CeratosaurusVariant variant = Util.getRandom(CeratosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + CeratosaurusVariant variant = Util.getRandom(CeratosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + CeratosaurusVariant variant = Util.getRandom(CeratosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ChasmosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ChasmosaurusEntity.java index a43248d..903f13d 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ChasmosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ChasmosaurusEntity.java @@ -53,10 +53,18 @@ import software.bernie.geckolib.animation.*; public class ChasmosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(ChasmosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(ChasmosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 67200; + private static final float MIN_ANIMAL_SCALE = 1.1F; + private static final float MAX_ANIMAL_SCALE = 1.5F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(ChasmosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(ChasmosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(ChasmosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -105,10 +113,14 @@ public class ChasmosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_CHASMOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -122,16 +134,17 @@ public class ChasmosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.CHASMOSAURUS.get().create(pLevel); - if (child instanceof ChasmosaurusEntity baby) { - ChasmosaurusVariant randomVariant = Util.getRandom(ChasmosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.CHASMOSAURUS.get().create(pLevel); + if (child instanceof ChasmosaurusEntity baby) { + ChasmosaurusVariant randomVariant = Util.getRandom(ChasmosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -181,11 +194,13 @@ public class ChasmosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -250,6 +265,7 @@ public class ChasmosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -257,12 +273,55 @@ public class ChasmosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -281,33 +340,35 @@ public class ChasmosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof ChasmosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - ChasmosaurusVariant variant = Util.getRandom(ChasmosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - ChasmosaurusVariant variant = Util.getRandom(ChasmosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + ChasmosaurusVariant variant = Util.getRandom(ChasmosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + ChasmosaurusVariant variant = Util.getRandom(ChasmosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ChickenosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ChickenosaurusEntity.java index 0f75e02..bd0fdf5 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ChickenosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ChickenosaurusEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class ChickenosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(ChickenosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(ChickenosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 28800; + private static final float MIN_ANIMAL_SCALE = 0.7F; + private static final float MAX_ANIMAL_SCALE = 1.1F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(ChickenosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(ChickenosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(ChickenosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class ChickenosaurusEntity extends DinoEntityBase implements GeoEntity { return null; } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class ChickenosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.CHICKENOSAURUS.get().create(pLevel); - if (child instanceof ChickenosaurusEntity baby) { - ChickenosaurusVariant randomVariant = Util.getRandom(ChickenosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.CHICKENOSAURUS.get().create(pLevel); + if (child instanceof ChickenosaurusEntity baby) { + ChickenosaurusVariant randomVariant = Util.getRandom(ChickenosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -182,11 +195,13 @@ public class ChickenosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -251,6 +266,7 @@ public class ChickenosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -258,12 +274,55 @@ public class ChickenosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -282,33 +341,35 @@ public class ChickenosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof ChickenosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - ChickenosaurusVariant variant = Util.getRandom(ChickenosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - ChickenosaurusVariant variant = Util.getRandom(ChickenosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + ChickenosaurusVariant variant = Util.getRandom(ChickenosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + ChickenosaurusVariant variant = Util.getRandom(ChickenosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ChilesaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ChilesaurusEntity.java index f317c91..55d1146 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ChilesaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ChilesaurusEntity.java @@ -46,10 +46,18 @@ import software.bernie.geckolib.animation.*; public class ChilesaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(ChilesaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(ChilesaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 38400; + private static final float MIN_ANIMAL_SCALE = 0.4F; + private static final float MAX_ANIMAL_SCALE = 0.8F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(ChilesaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(ChilesaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(ChilesaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -98,10 +106,14 @@ public class ChilesaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_CHILESAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -115,16 +127,17 @@ public class ChilesaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.CHILESAURUS.get().create(pLevel); - if (child instanceof ChilesaurusEntity baby) { - ChilesaurusVariant randomVariant = Util.getRandom(ChilesaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.CHILESAURUS.get().create(pLevel); + if (child instanceof ChilesaurusEntity baby) { + ChilesaurusVariant randomVariant = Util.getRandom(ChilesaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -171,11 +184,13 @@ public class ChilesaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -239,6 +254,7 @@ public class ChilesaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -246,12 +262,55 @@ public class ChilesaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -270,33 +329,35 @@ public class ChilesaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof ChilesaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - ChilesaurusVariant variant = Util.getRandom(ChilesaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - ChilesaurusVariant variant = Util.getRandom(ChilesaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + ChilesaurusVariant variant = Util.getRandom(ChilesaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + ChilesaurusVariant variant = Util.getRandom(ChilesaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CoelophysisEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CoelophysisEntity.java index f41b0de..5bfdf47 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CoelophysisEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CoelophysisEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class CoelophysisEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(CoelophysisEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(CoelophysisEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 19200; + private static final float MIN_ANIMAL_SCALE = 0.5F; + private static final float MAX_ANIMAL_SCALE = 0.9F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(CoelophysisEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(CoelophysisEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(CoelophysisEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class CoelophysisEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_COELOPHYSIS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class CoelophysisEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.COELOPHYSIS.get().create(pLevel); - if (child instanceof CoelophysisEntity baby) { - CoelophysisVariant randomVariant = Util.getRandom(CoelophysisVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.COELOPHYSIS.get().create(pLevel); + if (child instanceof CoelophysisEntity baby) { + CoelophysisVariant randomVariant = Util.getRandom(CoelophysisVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -182,11 +195,13 @@ public class CoelophysisEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -251,6 +266,7 @@ public class CoelophysisEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -258,12 +274,55 @@ public class CoelophysisEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -282,33 +341,35 @@ public class CoelophysisEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof CoelophysisEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - CoelophysisVariant variant = Util.getRandom(CoelophysisVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - CoelophysisVariant variant = Util.getRandom(CoelophysisVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + CoelophysisVariant variant = Util.getRandom(CoelophysisVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + CoelophysisVariant variant = Util.getRandom(CoelophysisVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CoelurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CoelurusEntity.java index 941662a..e79638e 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CoelurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CoelurusEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class CoelurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(CoelurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(CoelurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 24000; + private static final float MIN_ANIMAL_SCALE = 0.3F; + private static final float MAX_ANIMAL_SCALE = 0.7F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(CoelurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(CoelurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(CoelurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class CoelurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_COELURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class CoelurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.COELURUS.get().create(pLevel); - if (child instanceof CoelurusEntity baby) { - CoelurusVariant randomVariant = Util.getRandom(CoelurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.COELURUS.get().create(pLevel); + if (child instanceof CoelurusEntity baby) { + CoelurusVariant randomVariant = Util.getRandom(CoelurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -182,11 +195,13 @@ public class CoelurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -251,6 +266,7 @@ public class CoelurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -258,12 +274,55 @@ public class CoelurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -282,33 +341,35 @@ public class CoelurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof CoelurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - CoelurusVariant variant = Util.getRandom(CoelurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - CoelurusVariant variant = Util.getRandom(CoelurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + CoelurusVariant variant = Util.getRandom(CoelurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + CoelurusVariant variant = Util.getRandom(CoelurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CompsognathusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CompsognathusEntity.java index b08cf71..ce0a398 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CompsognathusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CompsognathusEntity.java @@ -9,6 +9,8 @@ import net.cmr.jurassicrevived.entity.ai.SprintingMeleeAttackGoal; import net.cmr.jurassicrevived.entity.ai.SprintingPanicGoal; import net.cmr.jurassicrevived.entity.client.CompsognathusVariant; import net.cmr.jurassicrevived.entity.client.CompsognathusVariant; +import net.cmr.jurassicrevived.entity.client.CompsognathusVariant; +import net.cmr.jurassicrevived.entity.client.CompsognathusVariant; import net.cmr.jurassicrevived.item.ModItems; import net.cmr.jurassicrevived.sound.ModSounds; import net.minecraft.Util; @@ -53,10 +55,18 @@ import software.bernie.geckolib.animation.*; public class CompsognathusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 14400; + private static final float MIN_ANIMAL_SCALE = 0.2F; + private static final float MAX_ANIMAL_SCALE = 0.6F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(CompsognathusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(CompsognathusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(CompsognathusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -110,6 +120,10 @@ public class CompsognathusEntity extends DinoEntityBase implements GeoEntity { return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); } + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } + public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() .add(Attributes.MAX_HEALTH, 5D) @@ -122,16 +136,17 @@ public class CompsognathusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.COMPSOGNATHUS.get().create(pLevel); - if (child instanceof CompsognathusEntity baby) { - CompsognathusVariant randomVariant = Util.getRandom(CompsognathusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.COMPSOGNATHUS.get().create(pLevel); + if (child instanceof CompsognathusEntity baby) { + CompsognathusVariant randomVariant = Util.getRandom(CompsognathusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -185,6 +200,8 @@ public class CompsognathusEntity extends DinoEntityBase implements GeoEntity { } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -250,19 +267,59 @@ public class CompsognathusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ public int getSyncedAge() { return this.entityData.get(DATA_SYNCED_AGE); } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ + public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -281,32 +338,34 @@ public class CompsognathusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof CompsognathusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } /*? if <=1.20.1 {*/ @Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { CompsognathusVariant variant = Util.getRandom(CompsognathusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - CompsognathusVariant variant = Util.getRandom(CompsognathusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + CompsognathusVariant variant = Util.getRandom(CompsognathusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ConcavenatorEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ConcavenatorEntity.java index 78e547e..74cd05d 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ConcavenatorEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ConcavenatorEntity.java @@ -50,10 +50,18 @@ import software.bernie.geckolib.animation.*; public class ConcavenatorEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(ConcavenatorEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(ConcavenatorEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 43200; + private static final float MIN_ANIMAL_SCALE = 0.7F; + private static final float MAX_ANIMAL_SCALE = 1.1F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(ConcavenatorEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(ConcavenatorEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(ConcavenatorEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -107,6 +115,10 @@ public class ConcavenatorEntity extends DinoEntityBase implements GeoEntity { return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); } + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } + public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() .add(Attributes.MAX_HEALTH, 45D) @@ -118,16 +130,17 @@ public class ConcavenatorEntity extends DinoEntityBase implements GeoEntity { .add(Attributes.ATTACK_KNOCKBACK, 0D); } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.CONCAVENATOR.get().create(pLevel); - if (child instanceof ConcavenatorEntity baby) { - ConcavenatorVariant randomVariant = Util.getRandom(ConcavenatorVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.CONCAVENATOR.get().create(pLevel); + if (child instanceof ConcavenatorEntity baby) { + ConcavenatorVariant randomVariant = Util.getRandom(ConcavenatorVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -178,11 +191,13 @@ public class ConcavenatorEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -247,6 +262,7 @@ public class ConcavenatorEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -254,12 +270,55 @@ public class ConcavenatorEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -278,33 +337,35 @@ public class ConcavenatorEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof ConcavenatorEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - ConcavenatorVariant variant = Util.getRandom(ConcavenatorVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - ConcavenatorVariant variant = Util.getRandom(ConcavenatorVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + ConcavenatorVariant variant = Util.getRandom(ConcavenatorVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + ConcavenatorVariant variant = Util.getRandom(ConcavenatorVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CorythosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CorythosaurusEntity.java index 757165f..cec01bd 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CorythosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/CorythosaurusEntity.java @@ -51,10 +51,18 @@ import software.bernie.geckolib.animation.*; public class CorythosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(CorythosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(CorythosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 52800; + private static final float MIN_ANIMAL_SCALE = 1.5F; + private static final float MAX_ANIMAL_SCALE = 1.9F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(CorythosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(CorythosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(CorythosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -103,10 +111,14 @@ public class CorythosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_CORYTHOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -120,16 +132,17 @@ public class CorythosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.CORYTHOSAURUS.get().create(pLevel); - if (child instanceof CorythosaurusEntity baby) { - CorythosaurusVariant randomVariant = Util.getRandom(CorythosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.CORYTHOSAURUS.get().create(pLevel); + if (child instanceof CorythosaurusEntity baby) { + CorythosaurusVariant randomVariant = Util.getRandom(CorythosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -179,11 +192,13 @@ public class CorythosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -248,6 +263,7 @@ public class CorythosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -255,12 +271,55 @@ public class CorythosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -279,33 +338,35 @@ public class CorythosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof CorythosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - CorythosaurusVariant variant = Util.getRandom(CorythosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - CorythosaurusVariant variant = Util.getRandom(CorythosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + CorythosaurusVariant variant = Util.getRandom(CorythosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + CorythosaurusVariant variant = Util.getRandom(CorythosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DeinonychusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DeinonychusEntity.java index 976c1f4..a18cb26 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DeinonychusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DeinonychusEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class DeinonychusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(DeinonychusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(DeinonychusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 33600; + private static final float MIN_ANIMAL_SCALE = 0.7F; + private static final float MAX_ANIMAL_SCALE = 1.1F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(DeinonychusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(DeinonychusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(DeinonychusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class DeinonychusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_DEINONYCHUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class DeinonychusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.DEINONYCHUS.get().create(pLevel); - if (child instanceof DeinonychusEntity baby) { - DeinonychusVariant randomVariant = Util.getRandom(DeinonychusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.DEINONYCHUS.get().create(pLevel); + if (child instanceof DeinonychusEntity baby) { + DeinonychusVariant randomVariant = Util.getRandom(DeinonychusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -182,11 +195,13 @@ public class DeinonychusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -251,6 +266,7 @@ public class DeinonychusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -258,12 +274,55 @@ public class DeinonychusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -282,33 +341,35 @@ public class DeinonychusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof DeinonychusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - DeinonychusVariant variant = Util.getRandom(DeinonychusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - DeinonychusVariant variant = Util.getRandom(DeinonychusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + DeinonychusVariant variant = Util.getRandom(DeinonychusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + DeinonychusVariant variant = Util.getRandom(DeinonychusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DilophosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DilophosaurusEntity.java index e3d3ff5..fd616e5 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DilophosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DilophosaurusEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class DilophosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(DilophosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(DilophosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 33600; + private static final float MIN_ANIMAL_SCALE = 1.0F; + private static final float MAX_ANIMAL_SCALE = 1.4F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(DilophosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(DilophosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(DilophosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class DilophosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_DILOPHOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class DilophosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.DILOPHOSAURUS.get().create(pLevel); - if (child instanceof DilophosaurusEntity baby) { - DilophosaurusVariant randomVariant = Util.getRandom(DilophosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.DILOPHOSAURUS.get().create(pLevel); + if (child instanceof DilophosaurusEntity baby) { + DilophosaurusVariant randomVariant = Util.getRandom(DilophosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -187,11 +200,13 @@ public class DilophosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -256,6 +271,7 @@ public class DilophosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -263,12 +279,55 @@ public class DilophosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -287,33 +346,35 @@ public class DilophosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof DilophosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - DilophosaurusVariant variant = Util.getRandom(DilophosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - DilophosaurusVariant variant = Util.getRandom(DilophosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + DilophosaurusVariant variant = Util.getRandom(DilophosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + DilophosaurusVariant variant = Util.getRandom(DilophosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DimorphodonEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DimorphodonEntity.java index f6211dc..c709200 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DimorphodonEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DimorphodonEntity.java @@ -63,10 +63,18 @@ import software.bernie.geckolib.animation.*; public class DimorphodonEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(DimorphodonEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(DimorphodonEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 19200; + private static final float MIN_ANIMAL_SCALE = 0.5F; + private static final float MAX_ANIMAL_SCALE = 0.9F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(DimorphodonEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(DimorphodonEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(DimorphodonEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -116,10 +124,14 @@ public class DimorphodonEntity extends DinoEntityBase implements GeoEntity, Flyi return ModBlocks.INCUBATED_DIMORPHODON_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -157,16 +169,17 @@ public class DimorphodonEntity extends DinoEntityBase implements GeoEntity, Flyi } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.DIMORPHODON.get().create(pLevel); - if (child instanceof DimorphodonEntity baby) { - DimorphodonVariant randomVariant = Util.getRandom(DimorphodonVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.DIMORPHODON.get().create(pLevel); + if (child instanceof DimorphodonEntity baby) { + DimorphodonVariant randomVariant = Util.getRandom(DimorphodonVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -221,11 +234,13 @@ public class DimorphodonEntity extends DinoEntityBase implements GeoEntity, Flyi double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -290,6 +305,7 @@ public class DimorphodonEntity extends DinoEntityBase implements GeoEntity, Flyi super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -297,12 +313,55 @@ public class DimorphodonEntity extends DinoEntityBase implements GeoEntity, Flyi super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public DimorphodonVariant getVariant() { return DimorphodonVariant.byId(this.getTypeVariant() & 255); @@ -327,28 +386,30 @@ public class DimorphodonEntity extends DinoEntityBase implements GeoEntity, Flyi public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { DimorphodonVariant variant = Util.getRandom(DimorphodonVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - DimorphodonVariant variant = Util.getRandom(DimorphodonVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + DimorphodonVariant variant = Util.getRandom(DimorphodonVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DiplodocusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DiplodocusEntity.java index e371841..7e956cd 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DiplodocusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DiplodocusEntity.java @@ -55,10 +55,18 @@ import software.bernie.geckolib.animation.*; public class DiplodocusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(DiplodocusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(DiplodocusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 110400; + private static final float MIN_ANIMAL_SCALE = 2.6F; + private static final float MAX_ANIMAL_SCALE = 3.0F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(DiplodocusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(DiplodocusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(DiplodocusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -107,10 +115,14 @@ public class DiplodocusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_DIPLODOCUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -124,16 +136,17 @@ public class DiplodocusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.DIPLODOCUS.get().create(pLevel); - if (child instanceof DiplodocusEntity baby) { - DiplodocusVariant randomVariant = Util.getRandom(DiplodocusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.DIPLODOCUS.get().create(pLevel); + if (child instanceof DiplodocusEntity baby) { + DiplodocusVariant randomVariant = Util.getRandom(DiplodocusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -184,11 +197,13 @@ public class DiplodocusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -253,6 +268,7 @@ public class DiplodocusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -260,12 +276,55 @@ public class DiplodocusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -284,33 +343,35 @@ public class DiplodocusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof DiplodocusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - DiplodocusVariant variant = Util.getRandom(DiplodocusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - DiplodocusVariant variant = Util.getRandom(DiplodocusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + DiplodocusVariant variant = Util.getRandom(DiplodocusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + DiplodocusVariant variant = Util.getRandom(DiplodocusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DistortusRexEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DistortusRexEntity.java index a613396..3f48053 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DistortusRexEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DistortusRexEntity.java @@ -57,10 +57,18 @@ import software.bernie.geckolib.animation.*; public class DistortusRexEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 62400; + private static final float MIN_ANIMAL_SCALE = 3.2F; + private static final float MAX_ANIMAL_SCALE = 3.6F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(DistortusRexEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(DistortusRexEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(DistortusRexEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -114,6 +122,10 @@ public class DistortusRexEntity extends DinoEntityBase implements GeoEntity { return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); } + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } + public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() .add(Attributes.MAX_HEALTH, 120D) @@ -133,6 +145,7 @@ public class DistortusRexEntity extends DinoEntityBase implements GeoEntity { if (child instanceof DistortusRexEntity baby) { DistortusRexVariant randomVariant = Util.getRandom(DistortusRexVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -186,10 +199,12 @@ public class DistortusRexEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } + } } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -255,19 +270,58 @@ public class DistortusRexEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ public int getSyncedAge() { return this.entityData.get(DATA_SYNCED_AGE); } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -290,12 +344,16 @@ public class DistortusRexEntity extends DinoEntityBase implements GeoEntity { public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } /*? if <=1.20.1 {*/ @@ -303,15 +361,13 @@ public class DistortusRexEntity extends DinoEntityBase implements GeoEntity { public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { DistortusRexVariant variant = Util.getRandom(DistortusRexVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - DistortusRexVariant variant = Util.getRandom(DistortusRexVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + DistortusRexVariant variant = Util.getRandom(DistortusRexVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DryosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DryosaurusEntity.java index 1460306..73a3ee6 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DryosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/DryosaurusEntity.java @@ -51,10 +51,18 @@ import software.bernie.geckolib.animation.*; public class DryosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(DryosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(DryosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 28800; + private static final float MIN_ANIMAL_SCALE = 0.25F; + private static final float MAX_ANIMAL_SCALE = 0.65F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(DryosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(DryosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(DryosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -103,10 +111,14 @@ public class DryosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_DRYOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -120,16 +132,17 @@ public class DryosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.DRYOSAURUS.get().create(pLevel); - if (child instanceof DryosaurusEntity baby) { - DryosaurusVariant randomVariant = Util.getRandom(DryosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.DRYOSAURUS.get().create(pLevel); + if (child instanceof DryosaurusEntity baby) { + DryosaurusVariant randomVariant = Util.getRandom(DryosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -179,11 +192,13 @@ public class DryosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -248,6 +263,7 @@ public class DryosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -255,12 +271,55 @@ public class DryosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -279,33 +338,35 @@ public class DryosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof DryosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - DryosaurusVariant variant = Util.getRandom(DryosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - DryosaurusVariant variant = Util.getRandom(DryosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + DryosaurusVariant variant = Util.getRandom(DryosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + DryosaurusVariant variant = Util.getRandom(DryosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/EdmontosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/EdmontosaurusEntity.java index 9d748ee..ae30537 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/EdmontosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/EdmontosaurusEntity.java @@ -51,10 +51,18 @@ import software.bernie.geckolib.animation.*; public class EdmontosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(EdmontosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(EdmontosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 67200; + private static final float MIN_ANIMAL_SCALE = 1.6F; + private static final float MAX_ANIMAL_SCALE = 2.0F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(EdmontosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(EdmontosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(EdmontosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -103,10 +111,14 @@ public class EdmontosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_EDMONTOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -120,16 +132,17 @@ public class EdmontosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.EDMONTOSAURUS.get().create(pLevel); - if (child instanceof EdmontosaurusEntity baby) { - EdmontosaurusVariant randomVariant = Util.getRandom(EdmontosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.EDMONTOSAURUS.get().create(pLevel); + if (child instanceof EdmontosaurusEntity baby) { + EdmontosaurusVariant randomVariant = Util.getRandom(EdmontosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -179,11 +192,13 @@ public class EdmontosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -248,6 +263,7 @@ public class EdmontosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -255,12 +271,55 @@ public class EdmontosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -279,33 +338,35 @@ public class EdmontosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof EdmontosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - EdmontosaurusVariant variant = Util.getRandom(EdmontosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - EdmontosaurusVariant variant = Util.getRandom(EdmontosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + EdmontosaurusVariant variant = Util.getRandom(EdmontosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + EdmontosaurusVariant variant = Util.getRandom(EdmontosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/FDuckEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/FDuckEntity.java index caae834..e39e9a4 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/FDuckEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/FDuckEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class FDuckEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(FDuckEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(FDuckEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 28800; + private static final float MIN_ANIMAL_SCALE = 1.2F; + private static final float MAX_ANIMAL_SCALE = 1.6F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(FDuckEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(FDuckEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(FDuckEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class FDuckEntity extends DinoEntityBase implements GeoEntity { return null; } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class FDuckEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.FDUCK.get().create(pLevel); - if (child instanceof FDuckEntity baby) { - FDuckVariant randomVariant = Util.getRandom(FDuckVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.FDUCK.get().create(pLevel); + if (child instanceof FDuckEntity baby) { + FDuckVariant randomVariant = Util.getRandom(FDuckVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -182,11 +195,13 @@ public class FDuckEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -251,6 +266,7 @@ public class FDuckEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -258,12 +274,55 @@ public class FDuckEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -282,33 +341,35 @@ public class FDuckEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof FDuckEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - FDuckVariant variant = Util.getRandom(FDuckVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - FDuckVariant variant = Util.getRandom(FDuckVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + FDuckVariant variant = Util.getRandom(FDuckVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + FDuckVariant variant = Util.getRandom(FDuckVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GallimimusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GallimimusEntity.java index 29c194a..f2b8ec1 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GallimimusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GallimimusEntity.java @@ -51,10 +51,18 @@ import software.bernie.geckolib.animation.*; public class GallimimusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(GallimimusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(GallimimusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 33600; + private static final float MIN_ANIMAL_SCALE = 0.8F; + private static final float MAX_ANIMAL_SCALE = 1.2F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(GallimimusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(GallimimusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(GallimimusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -103,10 +111,14 @@ public class GallimimusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_GALLIMIMUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -120,16 +132,17 @@ public class GallimimusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.GALLIMIMUS.get().create(pLevel); - if (child instanceof GallimimusEntity baby) { - GallimimusVariant randomVariant = Util.getRandom(GallimimusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.GALLIMIMUS.get().create(pLevel); + if (child instanceof GallimimusEntity baby) { + GallimimusVariant randomVariant = Util.getRandom(GallimimusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -179,11 +192,13 @@ public class GallimimusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -248,6 +263,7 @@ public class GallimimusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -255,12 +271,55 @@ public class GallimimusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -279,33 +338,35 @@ public class GallimimusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof GallimimusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - GallimimusVariant variant = Util.getRandom(GallimimusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - GallimimusVariant variant = Util.getRandom(GallimimusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + GallimimusVariant variant = Util.getRandom(GallimimusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + GallimimusVariant variant = Util.getRandom(GallimimusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GeosternbergiaEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GeosternbergiaEntity.java index 5f42265..5ee10aa 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GeosternbergiaEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GeosternbergiaEntity.java @@ -63,10 +63,18 @@ import software.bernie.geckolib.animation.*; public class GeosternbergiaEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(GeosternbergiaEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(GeosternbergiaEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 28800; + private static final float MIN_ANIMAL_SCALE = 1.2F; + private static final float MAX_ANIMAL_SCALE = 1.6F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(GeosternbergiaEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(GeosternbergiaEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(GeosternbergiaEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -116,10 +124,14 @@ public class GeosternbergiaEntity extends DinoEntityBase implements GeoEntity, F return ModBlocks.INCUBATED_GEOSTERNBERGIA_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -157,16 +169,17 @@ public class GeosternbergiaEntity extends DinoEntityBase implements GeoEntity, F } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.GEOSTERNBERGIA.get().create(pLevel); - if (child instanceof GeosternbergiaEntity baby) { - GeosternbergiaVariant randomVariant = Util.getRandom(GeosternbergiaVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.GEOSTERNBERGIA.get().create(pLevel); + if (child instanceof GeosternbergiaEntity baby) { + GeosternbergiaVariant randomVariant = Util.getRandom(GeosternbergiaVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -221,11 +234,13 @@ public class GeosternbergiaEntity extends DinoEntityBase implements GeoEntity, F double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -290,6 +305,7 @@ public class GeosternbergiaEntity extends DinoEntityBase implements GeoEntity, F super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -297,12 +313,55 @@ public class GeosternbergiaEntity extends DinoEntityBase implements GeoEntity, F super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public GeosternbergiaVariant getVariant() { return GeosternbergiaVariant.byId(this.getTypeVariant() & 255); @@ -327,28 +386,30 @@ public class GeosternbergiaEntity extends DinoEntityBase implements GeoEntity, F public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { GeosternbergiaVariant variant = Util.getRandom(GeosternbergiaVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - GeosternbergiaVariant variant = Util.getRandom(GeosternbergiaVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + GeosternbergiaVariant variant = Util.getRandom(GeosternbergiaVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GiganotosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GiganotosaurusEntity.java index 5978afb..925c061 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GiganotosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GiganotosaurusEntity.java @@ -57,10 +57,18 @@ import software.bernie.geckolib.animation.*; public class GiganotosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 81600; + private static final float MIN_ANIMAL_SCALE = 2.0F; + private static final float MAX_ANIMAL_SCALE = 2.4F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(GiganotosaurusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(GiganotosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(GiganotosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -114,6 +122,10 @@ public class GiganotosaurusEntity extends DinoEntityBase implements GeoEntity { return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); } + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } + public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() .add(Attributes.MAX_HEALTH, 80D) @@ -133,6 +145,7 @@ public class GiganotosaurusEntity extends DinoEntityBase implements GeoEntity { if (child instanceof GiganotosaurusEntity baby) { GiganotosaurusVariant randomVariant = Util.getRandom(GiganotosaurusVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -186,10 +199,12 @@ public class GiganotosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } + } } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -255,19 +270,58 @@ public class GiganotosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ public int getSyncedAge() { return this.entityData.get(DATA_SYNCED_AGE); } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -290,12 +344,16 @@ public class GiganotosaurusEntity extends DinoEntityBase implements GeoEntity { public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } /*? if <=1.20.1 {*/ @@ -303,15 +361,13 @@ public class GiganotosaurusEntity extends DinoEntityBase implements GeoEntity { public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { GiganotosaurusVariant variant = Util.getRandom(GiganotosaurusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - GiganotosaurusVariant variant = Util.getRandom(GiganotosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + GiganotosaurusVariant variant = Util.getRandom(GiganotosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GuanlongEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GuanlongEntity.java index aa23a4d..d01cc6e 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GuanlongEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GuanlongEntity.java @@ -55,10 +55,18 @@ import software.bernie.geckolib.animation.*; public class GuanlongEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(GuanlongEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(GuanlongEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 33600; + private static final float MIN_ANIMAL_SCALE = 0.4F; + private static final float MAX_ANIMAL_SCALE = 0.8F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(GuanlongEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(GuanlongEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(GuanlongEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -107,10 +115,14 @@ public class GuanlongEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_GUANLONG_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -124,16 +136,17 @@ public class GuanlongEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.GUANLONG.get().create(pLevel); - if (child instanceof GuanlongEntity baby) { - GuanlongVariant randomVariant = Util.getRandom(GuanlongVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.GUANLONG.get().create(pLevel); + if (child instanceof GuanlongEntity baby) { + GuanlongVariant randomVariant = Util.getRandom(GuanlongVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -183,11 +196,13 @@ public class GuanlongEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -252,6 +267,7 @@ public class GuanlongEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -259,12 +275,55 @@ public class GuanlongEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -283,33 +342,35 @@ public class GuanlongEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof GuanlongEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - GuanlongVariant variant = Util.getRandom(GuanlongVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - GuanlongVariant variant = Util.getRandom(GuanlongVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + GuanlongVariant variant = Util.getRandom(GuanlongVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + GuanlongVariant variant = Util.getRandom(GuanlongVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GuidracoEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GuidracoEntity.java index 454361f..fc002c1 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GuidracoEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/GuidracoEntity.java @@ -63,10 +63,18 @@ import software.bernie.geckolib.animation.*; public class GuidracoEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(GuidracoEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(GuidracoEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 28800; + private static final float MIN_ANIMAL_SCALE = 0.6F; + private static final float MAX_ANIMAL_SCALE = 1.0F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(GuidracoEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(GuidracoEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(GuidracoEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -116,10 +124,14 @@ public class GuidracoEntity extends DinoEntityBase implements GeoEntity, FlyingA return ModBlocks.INCUBATED_GUIDRACO_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -157,16 +169,17 @@ public class GuidracoEntity extends DinoEntityBase implements GeoEntity, FlyingA } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.GUIDRACO.get().create(pLevel); - if (child instanceof GuidracoEntity baby) { - GuidracoVariant randomVariant = Util.getRandom(GuidracoVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.GUIDRACO.get().create(pLevel); + if (child instanceof GuidracoEntity baby) { + GuidracoVariant randomVariant = Util.getRandom(GuidracoVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -221,11 +234,13 @@ public class GuidracoEntity extends DinoEntityBase implements GeoEntity, FlyingA double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -290,6 +305,7 @@ public class GuidracoEntity extends DinoEntityBase implements GeoEntity, FlyingA super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -297,12 +313,55 @@ public class GuidracoEntity extends DinoEntityBase implements GeoEntity, FlyingA super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public GuidracoVariant getVariant() { return GuidracoVariant.byId(this.getTypeVariant() & 255); @@ -327,28 +386,30 @@ public class GuidracoEntity extends DinoEntityBase implements GeoEntity, FlyingA public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { GuidracoVariant variant = Util.getRandom(GuidracoVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - GuidracoVariant variant = Util.getRandom(GuidracoVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + GuidracoVariant variant = Util.getRandom(GuidracoVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/HadrosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/HadrosaurusEntity.java index 49fa211..981355d 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/HadrosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/HadrosaurusEntity.java @@ -51,10 +51,18 @@ import software.bernie.geckolib.animation.*; public class HadrosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(HadrosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(HadrosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 52800; + private static final float MIN_ANIMAL_SCALE = 1.3F; + private static final float MAX_ANIMAL_SCALE = 1.7F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(HadrosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(HadrosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(HadrosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -103,10 +111,14 @@ public class HadrosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_HADROSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -120,16 +132,17 @@ public class HadrosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.HADROSAURUS.get().create(pLevel); - if (child instanceof HadrosaurusEntity baby) { - HadrosaurusVariant randomVariant = Util.getRandom(HadrosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.HADROSAURUS.get().create(pLevel); + if (child instanceof HadrosaurusEntity baby) { + HadrosaurusVariant randomVariant = Util.getRandom(HadrosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -179,11 +192,13 @@ public class HadrosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -248,6 +263,7 @@ public class HadrosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -255,12 +271,55 @@ public class HadrosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -279,33 +338,35 @@ public class HadrosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof HadrosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - HadrosaurusVariant variant = Util.getRandom(HadrosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - HadrosaurusVariant variant = Util.getRandom(HadrosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + HadrosaurusVariant variant = Util.getRandom(HadrosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + HadrosaurusVariant variant = Util.getRandom(HadrosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/HerrerasaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/HerrerasaurusEntity.java index 8fd4609..28ee015 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/HerrerasaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/HerrerasaurusEntity.java @@ -55,10 +55,18 @@ import software.bernie.geckolib.animation.*; public class HerrerasaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(HerrerasaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(HerrerasaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 28800; + private static final float MIN_ANIMAL_SCALE = 1.1F; + private static final float MAX_ANIMAL_SCALE = 1.5F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(HerrerasaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(HerrerasaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(HerrerasaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -107,10 +115,14 @@ public class HerrerasaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_HERRERASAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -124,16 +136,17 @@ public class HerrerasaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.HERRERASAURUS.get().create(pLevel); - if (child instanceof HerrerasaurusEntity baby) { - HerrerasaurusVariant randomVariant = Util.getRandom(HerrerasaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.HERRERASAURUS.get().create(pLevel); + if (child instanceof HerrerasaurusEntity baby) { + HerrerasaurusVariant randomVariant = Util.getRandom(HerrerasaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -184,11 +197,13 @@ public class HerrerasaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -253,6 +268,7 @@ public class HerrerasaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -260,12 +276,55 @@ public class HerrerasaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -284,33 +343,35 @@ public class HerrerasaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof HerrerasaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - HerrerasaurusVariant variant = Util.getRandom(HerrerasaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - HerrerasaurusVariant variant = Util.getRandom(HerrerasaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + HerrerasaurusVariant variant = Util.getRandom(HerrerasaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + HerrerasaurusVariant variant = Util.getRandom(HerrerasaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/HypsilophodonEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/HypsilophodonEntity.java index e20c16c..04c7cb6 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/HypsilophodonEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/HypsilophodonEntity.java @@ -51,10 +51,18 @@ import software.bernie.geckolib.animation.*; public class HypsilophodonEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(HypsilophodonEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(HypsilophodonEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 24000; + private static final float MIN_ANIMAL_SCALE = 0.3F; + private static final float MAX_ANIMAL_SCALE = 0.7F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(HypsilophodonEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(HypsilophodonEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(HypsilophodonEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -103,10 +111,14 @@ public class HypsilophodonEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_HYPSILOPHODON_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -120,16 +132,17 @@ public class HypsilophodonEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.HYPSILOPHODON.get().create(pLevel); - if (child instanceof HypsilophodonEntity baby) { - HypsilophodonVariant randomVariant = Util.getRandom(HypsilophodonVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.HYPSILOPHODON.get().create(pLevel); + if (child instanceof HypsilophodonEntity baby) { + HypsilophodonVariant randomVariant = Util.getRandom(HypsilophodonVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -179,11 +192,13 @@ public class HypsilophodonEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -248,6 +263,7 @@ public class HypsilophodonEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -255,12 +271,55 @@ public class HypsilophodonEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -279,33 +338,35 @@ public class HypsilophodonEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof HypsilophodonEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - HypsilophodonVariant variant = Util.getRandom(HypsilophodonVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - HypsilophodonVariant variant = Util.getRandom(HypsilophodonVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + HypsilophodonVariant variant = Util.getRandom(HypsilophodonVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + HypsilophodonVariant variant = Util.getRandom(HypsilophodonVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/IndominusRexEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/IndominusRexEntity.java index 663fdd5..603a27a 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/IndominusRexEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/IndominusRexEntity.java @@ -56,10 +56,18 @@ import software.bernie.geckolib.animation.*; public class IndominusRexEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(IndominusRexEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(IndominusRexEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 50400; + private static final float MIN_ANIMAL_SCALE = 2.8F; + private static final float MAX_ANIMAL_SCALE = 3.2F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(IndominusRexEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(IndominusRexEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(IndominusRexEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -108,10 +116,14 @@ public class IndominusRexEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_INDOMINUS_REX_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -125,16 +137,17 @@ public class IndominusRexEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.INDOMINUS_REX.get().create(pLevel); - if (child instanceof IndominusRexEntity baby) { - IndominusRexVariant randomVariant = Util.getRandom(IndominusRexVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.INDOMINUS_REX.get().create(pLevel); + if (child instanceof IndominusRexEntity baby) { + IndominusRexVariant randomVariant = Util.getRandom(IndominusRexVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -185,11 +198,13 @@ public class IndominusRexEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -254,6 +269,7 @@ public class IndominusRexEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -261,12 +277,55 @@ public class IndominusRexEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -285,33 +344,35 @@ public class IndominusRexEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof IndominusRexEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - IndominusRexVariant variant = Util.getRandom(IndominusRexVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - IndominusRexVariant variant = Util.getRandom(IndominusRexVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + IndominusRexVariant variant = Util.getRandom(IndominusRexVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + IndominusRexVariant variant = Util.getRandom(IndominusRexVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/IndoraptorEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/IndoraptorEntity.java index b874a17..51e71d9 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/IndoraptorEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/IndoraptorEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class IndoraptorEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(IndoraptorEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(IndoraptorEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 24000; + private static final float MIN_ANIMAL_SCALE = 1.6F; + private static final float MAX_ANIMAL_SCALE = 2.0F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(IndoraptorEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(IndoraptorEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(IndoraptorEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class IndoraptorEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_INDORAPTOR_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class IndoraptorEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.INDORAPTOR.get().create(pLevel); - if (child instanceof IndoraptorEntity baby) { - IndoraptorVariant randomVariant = Util.getRandom(IndoraptorVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.INDORAPTOR.get().create(pLevel); + if (child instanceof IndoraptorEntity baby) { + IndoraptorVariant randomVariant = Util.getRandom(IndoraptorVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -183,11 +196,13 @@ public class IndoraptorEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -252,6 +267,7 @@ public class IndoraptorEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -259,12 +275,55 @@ public class IndoraptorEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -283,33 +342,35 @@ public class IndoraptorEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof IndoraptorEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - IndoraptorVariant variant = Util.getRandom(IndoraptorVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - IndoraptorVariant variant = Util.getRandom(IndoraptorVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + IndoraptorVariant variant = Util.getRandom(IndoraptorVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + IndoraptorVariant variant = Util.getRandom(IndoraptorVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/InostranceviaEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/InostranceviaEntity.java index 95f740f..33c42f6 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/InostranceviaEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/InostranceviaEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class InostranceviaEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(InostranceviaEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(InostranceviaEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 33600; + private static final float MIN_ANIMAL_SCALE = 0.9F; + private static final float MAX_ANIMAL_SCALE = 1.3F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(InostranceviaEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(InostranceviaEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(InostranceviaEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class InostranceviaEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_INOSTRANCEVIA_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class InostranceviaEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.INOSTRANCEVIA.get().create(pLevel); - if (child instanceof InostranceviaEntity baby) { - InostranceviaVariant randomVariant = Util.getRandom(InostranceviaVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.INOSTRANCEVIA.get().create(pLevel); + if (child instanceof InostranceviaEntity baby) { + InostranceviaVariant randomVariant = Util.getRandom(InostranceviaVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -183,11 +196,13 @@ public class InostranceviaEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -252,6 +267,7 @@ public class InostranceviaEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -259,12 +275,55 @@ public class InostranceviaEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -283,33 +342,35 @@ public class InostranceviaEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof InostranceviaEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - InostranceviaVariant variant = Util.getRandom(InostranceviaVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - InostranceviaVariant variant = Util.getRandom(InostranceviaVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + InostranceviaVariant variant = Util.getRandom(InostranceviaVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + InostranceviaVariant variant = Util.getRandom(InostranceviaVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/LambeosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/LambeosaurusEntity.java index 231c3ad..399038c 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/LambeosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/LambeosaurusEntity.java @@ -51,10 +51,18 @@ import software.bernie.geckolib.animation.*; public class LambeosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(LambeosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(LambeosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 52800; + private static final float MIN_ANIMAL_SCALE = 1.6F; + private static final float MAX_ANIMAL_SCALE = 2.0F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(LambeosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(LambeosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(LambeosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -103,10 +111,14 @@ public class LambeosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_LAMBEOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -120,16 +132,17 @@ public class LambeosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.LAMBEOSAURUS.get().create(pLevel); - if (child instanceof LambeosaurusEntity baby) { - LambeosaurusVariant randomVariant = Util.getRandom(LambeosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.LAMBEOSAURUS.get().create(pLevel); + if (child instanceof LambeosaurusEntity baby) { + LambeosaurusVariant randomVariant = Util.getRandom(LambeosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -179,11 +192,13 @@ public class LambeosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -248,6 +263,7 @@ public class LambeosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -255,12 +271,55 @@ public class LambeosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -279,33 +338,35 @@ public class LambeosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof LambeosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - LambeosaurusVariant variant = Util.getRandom(LambeosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - LambeosaurusVariant variant = Util.getRandom(LambeosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + LambeosaurusVariant variant = Util.getRandom(LambeosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + LambeosaurusVariant variant = Util.getRandom(LambeosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/LudodactylusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/LudodactylusEntity.java index 2e6c312..f6b90a5 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/LudodactylusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/LudodactylusEntity.java @@ -63,10 +63,18 @@ import software.bernie.geckolib.animation.*; public class LudodactylusEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(LudodactylusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(LudodactylusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 24000; + private static final float MIN_ANIMAL_SCALE = 1.3F; + private static final float MAX_ANIMAL_SCALE = 1.7F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(LudodactylusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(LudodactylusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(LudodactylusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -116,10 +124,14 @@ public class LudodactylusEntity extends DinoEntityBase implements GeoEntity, Fly return ModBlocks.INCUBATED_LUDODACTYLUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -157,16 +169,17 @@ public class LudodactylusEntity extends DinoEntityBase implements GeoEntity, Fly } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.LUDODACTYLUS.get().create(pLevel); - if (child instanceof LudodactylusEntity baby) { - LudodactylusVariant randomVariant = Util.getRandom(LudodactylusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.LUDODACTYLUS.get().create(pLevel); + if (child instanceof LudodactylusEntity baby) { + LudodactylusVariant randomVariant = Util.getRandom(LudodactylusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -221,11 +234,13 @@ public class LudodactylusEntity extends DinoEntityBase implements GeoEntity, Fly double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -290,6 +305,7 @@ public class LudodactylusEntity extends DinoEntityBase implements GeoEntity, Fly super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -297,12 +313,55 @@ public class LudodactylusEntity extends DinoEntityBase implements GeoEntity, Fly super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public LudodactylusVariant getVariant() { return LudodactylusVariant.byId(this.getTypeVariant() & 255); @@ -327,28 +386,30 @@ public class LudodactylusEntity extends DinoEntityBase implements GeoEntity, Fly public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { LudodactylusVariant variant = Util.getRandom(LudodactylusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - LudodactylusVariant variant = Util.getRandom(LudodactylusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + LudodactylusVariant variant = Util.getRandom(LudodactylusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MajungasaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MajungasaurusEntity.java index 1710f0a..a4bf11e 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MajungasaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MajungasaurusEntity.java @@ -55,10 +55,18 @@ import software.bernie.geckolib.animation.*; public class MajungasaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(MajungasaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(MajungasaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 43200; + private static final float MIN_ANIMAL_SCALE = 1.2F; + private static final float MAX_ANIMAL_SCALE = 1.6F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(MajungasaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(MajungasaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(MajungasaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -107,10 +115,14 @@ public class MajungasaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_MAJUNGASAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -124,16 +136,17 @@ public class MajungasaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.MAJUNGASAURUS.get().create(pLevel); - if (child instanceof MajungasaurusEntity baby) { - MajungasaurusVariant randomVariant = Util.getRandom(MajungasaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.MAJUNGASAURUS.get().create(pLevel); + if (child instanceof MajungasaurusEntity baby) { + MajungasaurusVariant randomVariant = Util.getRandom(MajungasaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -184,11 +197,13 @@ public class MajungasaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -253,6 +268,7 @@ public class MajungasaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -260,12 +276,55 @@ public class MajungasaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -284,33 +343,35 @@ public class MajungasaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof MajungasaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - MajungasaurusVariant variant = Util.getRandom(MajungasaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - MajungasaurusVariant variant = Util.getRandom(MajungasaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + MajungasaurusVariant variant = Util.getRandom(MajungasaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + MajungasaurusVariant variant = Util.getRandom(MajungasaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MamenchisaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MamenchisaurusEntity.java index 07e6f6e..2b00936 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MamenchisaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MamenchisaurusEntity.java @@ -55,10 +55,18 @@ import software.bernie.geckolib.animation.*; public class MamenchisaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(MamenchisaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(MamenchisaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 134400; + private static final float MIN_ANIMAL_SCALE = 1.5F; + private static final float MAX_ANIMAL_SCALE = 1.9F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(MamenchisaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(MamenchisaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(MamenchisaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -107,10 +115,14 @@ public class MamenchisaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_MAMENCHISAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -124,16 +136,17 @@ public class MamenchisaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.MAMENCHISAURUS.get().create(pLevel); - if (child instanceof MamenchisaurusEntity baby) { - MamenchisaurusVariant randomVariant = Util.getRandom(MamenchisaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.MAMENCHISAURUS.get().create(pLevel); + if (child instanceof MamenchisaurusEntity baby) { + MamenchisaurusVariant randomVariant = Util.getRandom(MamenchisaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -185,11 +198,13 @@ public class MamenchisaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -254,6 +269,7 @@ public class MamenchisaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -261,12 +277,55 @@ public class MamenchisaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -285,33 +344,35 @@ public class MamenchisaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof MamenchisaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - MamenchisaurusVariant variant = Util.getRandom(MamenchisaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - MamenchisaurusVariant variant = Util.getRandom(MamenchisaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + MamenchisaurusVariant variant = Util.getRandom(MamenchisaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + MamenchisaurusVariant variant = Util.getRandom(MamenchisaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MetriacanthosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MetriacanthosaurusEntity.java index e203ddb..e56b2f7 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MetriacanthosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MetriacanthosaurusEntity.java @@ -50,10 +50,18 @@ import software.bernie.geckolib.animation.*; public class MetriacanthosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 52800; + private static final float MIN_ANIMAL_SCALE = 1.3F; + private static final float MAX_ANIMAL_SCALE = 1.7F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(MetriacanthosaurusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(MetriacanthosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(MetriacanthosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -107,6 +115,10 @@ public class MetriacanthosaurusEntity extends DinoEntityBase implements GeoEntit return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); } + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } + public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() .add(Attributes.MAX_HEALTH, 45D) @@ -125,6 +137,7 @@ public class MetriacanthosaurusEntity extends DinoEntityBase implements GeoEntit if (child instanceof MetriacanthosaurusEntity baby) { MetriacanthosaurusVariant randomVariant = Util.getRandom(MetriacanthosaurusVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -182,6 +195,8 @@ public class MetriacanthosaurusEntity extends DinoEntityBase implements GeoEntit } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -247,20 +262,59 @@ public class MetriacanthosaurusEntity extends DinoEntityBase implements GeoEntit super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ public int getSyncedAge() { return this.entityData.get(DATA_SYNCED_AGE); } + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ + public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -283,12 +337,16 @@ public class MetriacanthosaurusEntity extends DinoEntityBase implements GeoEntit public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } /*? if <=1.20.1 {*/ @@ -296,15 +354,13 @@ public class MetriacanthosaurusEntity extends DinoEntityBase implements GeoEntit public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { MetriacanthosaurusVariant variant = Util.getRandom(MetriacanthosaurusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - MetriacanthosaurusVariant variant = Util.getRandom(MetriacanthosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + MetriacanthosaurusVariant variant = Util.getRandom(MetriacanthosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MoganopterusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MoganopterusEntity.java index bbb680a..a06202f 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MoganopterusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MoganopterusEntity.java @@ -63,10 +63,18 @@ import software.bernie.geckolib.animation.*; public class MoganopterusEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 33600; + private static final float MIN_ANIMAL_SCALE = 0.6F; + private static final float MAX_ANIMAL_SCALE = 1.0F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(MoganopterusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(MoganopterusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(MoganopterusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -116,10 +124,14 @@ public class MoganopterusEntity extends DinoEntityBase implements GeoEntity, Fly return ModBlocks.INCUBATED_MOGANOPTERUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -164,6 +176,7 @@ public class MoganopterusEntity extends DinoEntityBase implements GeoEntity, Fly if (child instanceof MoganopterusEntity baby) { MoganopterusVariant randomVariant = Util.getRandom(MoganopterusVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -225,6 +238,8 @@ public class MoganopterusEntity extends DinoEntityBase implements GeoEntity, Fly } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -290,19 +305,58 @@ public class MoganopterusEntity extends DinoEntityBase implements GeoEntity, Fly super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ public MoganopterusVariant getVariant() { return MoganopterusVariant.byId(this.getTypeVariant() & 255); @@ -327,27 +381,29 @@ public class MoganopterusEntity extends DinoEntityBase implements GeoEntity, Fly public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { MoganopterusVariant variant = Util.getRandom(MoganopterusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - MoganopterusVariant variant = Util.getRandom(MoganopterusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + MoganopterusVariant variant = Util.getRandom(MoganopterusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } @Override public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MussasaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MussasaurusEntity.java index ebd3832..b4c719a 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MussasaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/MussasaurusEntity.java @@ -46,10 +46,18 @@ import software.bernie.geckolib.animation.*; public class MussasaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 62400; + private static final float MIN_ANIMAL_SCALE = 0.5F; + private static final float MAX_ANIMAL_SCALE = 0.9F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(MussasaurusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(MussasaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(MussasaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -98,10 +106,14 @@ public class MussasaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_MUSSASAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -122,6 +134,7 @@ public class MussasaurusEntity extends DinoEntityBase implements GeoEntity { if (child instanceof MussasaurusEntity baby) { MussasaurusVariant randomVariant = Util.getRandom(MussasaurusVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -178,6 +191,8 @@ public class MussasaurusEntity extends DinoEntityBase implements GeoEntity { } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -243,19 +258,58 @@ public class MussasaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ public int getSyncedAge() { return this.entityData.get(DATA_SYNCED_AGE); } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -278,12 +332,16 @@ public class MussasaurusEntity extends DinoEntityBase implements GeoEntity { public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } /*? if <=1.20.1 {*/ @@ -291,15 +349,13 @@ public class MussasaurusEntity extends DinoEntityBase implements GeoEntity { public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { MussasaurusVariant variant = Util.getRandom(MussasaurusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - MussasaurusVariant variant = Util.getRandom(MussasaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + MussasaurusVariant variant = Util.getRandom(MussasaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/NyctosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/NyctosaurusEntity.java index 449b5d0..9aeffd0 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/NyctosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/NyctosaurusEntity.java @@ -63,10 +63,18 @@ import software.bernie.geckolib.animation.*; public class NyctosaurusEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 24000; + private static final float MIN_ANIMAL_SCALE = 0.1F; + private static final float MAX_ANIMAL_SCALE = 0.5F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(NyctosaurusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(NyctosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(NyctosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -116,10 +124,14 @@ public class NyctosaurusEntity extends DinoEntityBase implements GeoEntity, Flyi return ModBlocks.INCUBATED_NYCTOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -164,6 +176,7 @@ public class NyctosaurusEntity extends DinoEntityBase implements GeoEntity, Flyi if (child instanceof NyctosaurusEntity baby) { NyctosaurusVariant randomVariant = Util.getRandom(NyctosaurusVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -221,10 +234,12 @@ public class NyctosaurusEntity extends DinoEntityBase implements GeoEntity, Flyi double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } + } } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -290,20 +305,59 @@ public class NyctosaurusEntity extends DinoEntityBase implements GeoEntity, Flyi super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ public int getSyncedAge() { return this.entityData.get(DATA_SYNCED_AGE); } + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ + public NyctosaurusVariant getVariant() { return NyctosaurusVariant.byId(this.getTypeVariant() & 255); } @@ -327,27 +381,29 @@ public class NyctosaurusEntity extends DinoEntityBase implements GeoEntity, Flyi public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { NyctosaurusVariant variant = Util.getRandom(NyctosaurusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - NyctosaurusVariant variant = Util.getRandom(NyctosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + NyctosaurusVariant variant = Util.getRandom(NyctosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } @Override public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OrnitholestesEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OrnitholestesEntity.java index da35134..d7af625 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OrnitholestesEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OrnitholestesEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class OrnitholestesEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(OrnitholestesEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(OrnitholestesEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 24000; + private static final float MIN_ANIMAL_SCALE = 0.4F; + private static final float MAX_ANIMAL_SCALE = 0.8F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(OrnitholestesEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(OrnitholestesEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(OrnitholestesEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class OrnitholestesEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_ORNITHOLESTES_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class OrnitholestesEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.ORNITHOLESTES.get().create(pLevel); - if (child instanceof OrnitholestesEntity baby) { - OrnitholestesVariant randomVariant = Util.getRandom(OrnitholestesVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.ORNITHOLESTES.get().create(pLevel); + if (child instanceof OrnitholestesEntity baby) { + OrnitholestesVariant randomVariant = Util.getRandom(OrnitholestesVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -182,11 +195,13 @@ public class OrnitholestesEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -251,6 +266,7 @@ public class OrnitholestesEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -258,12 +274,55 @@ public class OrnitholestesEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -282,33 +341,35 @@ public class OrnitholestesEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof OrnitholestesEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - OrnitholestesVariant variant = Util.getRandom(OrnitholestesVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - OrnitholestesVariant variant = Util.getRandom(OrnitholestesVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + OrnitholestesVariant variant = Util.getRandom(OrnitholestesVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + OrnitholestesVariant variant = Util.getRandom(OrnitholestesVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OrnithomimusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OrnithomimusEntity.java index 3a8d50c..1417e0e 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OrnithomimusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OrnithomimusEntity.java @@ -51,10 +51,18 @@ import software.bernie.geckolib.animation.*; public class OrnithomimusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(OrnithomimusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(OrnithomimusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 33600; + private static final float MIN_ANIMAL_SCALE = 0.8F; + private static final float MAX_ANIMAL_SCALE = 1.2F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(OrnithomimusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(OrnithomimusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(OrnithomimusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -103,10 +111,14 @@ public class OrnithomimusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_ORNITHOMIMUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -120,16 +132,17 @@ public class OrnithomimusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.ORNITHOMIMUS.get().create(pLevel); - if (child instanceof OrnithomimusEntity baby) { - OrnithomimusVariant randomVariant = Util.getRandom(OrnithomimusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.ORNITHOMIMUS.get().create(pLevel); + if (child instanceof OrnithomimusEntity baby) { + OrnithomimusVariant randomVariant = Util.getRandom(OrnithomimusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -179,11 +192,13 @@ public class OrnithomimusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -248,6 +263,7 @@ public class OrnithomimusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -255,12 +271,55 @@ public class OrnithomimusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -279,33 +338,35 @@ public class OrnithomimusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof OrnithomimusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - OrnithomimusVariant variant = Util.getRandom(OrnithomimusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - OrnithomimusVariant variant = Util.getRandom(OrnithomimusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + OrnithomimusVariant variant = Util.getRandom(OrnithomimusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + OrnithomimusVariant variant = Util.getRandom(OrnithomimusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OuranosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OuranosaurusEntity.java index 4af5662..80ddaea 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OuranosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OuranosaurusEntity.java @@ -51,10 +51,18 @@ import software.bernie.geckolib.animation.*; public class OuranosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(OuranosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(OuranosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 52800; + private static final float MIN_ANIMAL_SCALE = 1.2F; + private static final float MAX_ANIMAL_SCALE = 1.6F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(OuranosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(OuranosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(OuranosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -103,10 +111,14 @@ public class OuranosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_OURANOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -120,16 +132,17 @@ public class OuranosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.OURANOSAURUS.get().create(pLevel); - if (child instanceof OuranosaurusEntity baby) { - OuranosaurusVariant randomVariant = Util.getRandom(OuranosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.OURANOSAURUS.get().create(pLevel); + if (child instanceof OuranosaurusEntity baby) { + OuranosaurusVariant randomVariant = Util.getRandom(OuranosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -179,11 +192,13 @@ public class OuranosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -248,6 +263,7 @@ public class OuranosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -255,12 +271,55 @@ public class OuranosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -279,33 +338,35 @@ public class OuranosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof OuranosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - OuranosaurusVariant variant = Util.getRandom(OuranosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - OuranosaurusVariant variant = Util.getRandom(OuranosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + OuranosaurusVariant variant = Util.getRandom(OuranosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + OuranosaurusVariant variant = Util.getRandom(OuranosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OviraptorEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OviraptorEntity.java index 1df5cd2..b27f265 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OviraptorEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/OviraptorEntity.java @@ -53,10 +53,18 @@ import software.bernie.geckolib.animation.*; public class OviraptorEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(OviraptorEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(OviraptorEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 28800; + private static final float MIN_ANIMAL_SCALE = 0.35F; + private static final float MAX_ANIMAL_SCALE = 0.75F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(OviraptorEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(OviraptorEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(OviraptorEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -105,10 +113,14 @@ public class OviraptorEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_OVIRAPTOR_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -122,16 +134,17 @@ public class OviraptorEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.OVIRAPTOR.get().create(pLevel); - if (child instanceof OviraptorEntity baby) { - OviraptorVariant randomVariant = Util.getRandom(OviraptorVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.OVIRAPTOR.get().create(pLevel); + if (child instanceof OviraptorEntity baby) { + OviraptorVariant randomVariant = Util.getRandom(OviraptorVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -181,11 +194,13 @@ public class OviraptorEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -250,6 +265,7 @@ public class OviraptorEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -257,12 +273,55 @@ public class OviraptorEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -281,33 +340,35 @@ public class OviraptorEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof OviraptorEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - OviraptorVariant variant = Util.getRandom(OviraptorVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - OviraptorVariant variant = Util.getRandom(OviraptorVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + OviraptorVariant variant = Util.getRandom(OviraptorVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + OviraptorVariant variant = Util.getRandom(OviraptorVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/PachycephalosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/PachycephalosaurusEntity.java index d191908..e8c6797 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/PachycephalosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/PachycephalosaurusEntity.java @@ -53,10 +53,18 @@ import software.bernie.geckolib.animation.*; public class PachycephalosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(PachycephalosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(PachycephalosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 52800; + private static final float MIN_ANIMAL_SCALE = 0.6F; + private static final float MAX_ANIMAL_SCALE = 1.0F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(PachycephalosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(PachycephalosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(PachycephalosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -105,10 +113,14 @@ public class PachycephalosaurusEntity extends DinoEntityBase implements GeoEntit return ModBlocks.INCUBATED_PACHYCEPHALOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -122,16 +134,17 @@ public class PachycephalosaurusEntity extends DinoEntityBase implements GeoEntit } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.PACHYCEPHALOSAURUS.get().create(pLevel); - if (child instanceof PachycephalosaurusEntity baby) { - PachycephalosaurusVariant randomVariant = Util.getRandom(PachycephalosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.PACHYCEPHALOSAURUS.get().create(pLevel); + if (child instanceof PachycephalosaurusEntity baby) { + PachycephalosaurusVariant randomVariant = Util.getRandom(PachycephalosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -181,11 +194,13 @@ public class PachycephalosaurusEntity extends DinoEntityBase implements GeoEntit double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -250,6 +265,7 @@ public class PachycephalosaurusEntity extends DinoEntityBase implements GeoEntit super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -257,12 +273,55 @@ public class PachycephalosaurusEntity extends DinoEntityBase implements GeoEntit super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -281,33 +340,35 @@ public class PachycephalosaurusEntity extends DinoEntityBase implements GeoEntit if (!(other instanceof PachycephalosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - PachycephalosaurusVariant variant = Util.getRandom(PachycephalosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - PachycephalosaurusVariant variant = Util.getRandom(PachycephalosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + PachycephalosaurusVariant variant = Util.getRandom(PachycephalosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + PachycephalosaurusVariant variant = Util.getRandom(PachycephalosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ParasaurolophusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ParasaurolophusEntity.java index a09c039..27f0527 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ParasaurolophusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ParasaurolophusEntity.java @@ -51,10 +51,18 @@ import software.bernie.geckolib.animation.*; public class ParasaurolophusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(ParasaurolophusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(ParasaurolophusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 57600; + private static final float MIN_ANIMAL_SCALE = 1.5F; + private static final float MAX_ANIMAL_SCALE = 1.9F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(ParasaurolophusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(ParasaurolophusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(ParasaurolophusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -103,10 +111,14 @@ public class ParasaurolophusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_PARASAUROLOPHUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -120,16 +132,17 @@ public class ParasaurolophusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.PARASAUROLOPHUS.get().create(pLevel); - if (child instanceof ParasaurolophusEntity baby) { - ParasaurolophusVariant randomVariant = Util.getRandom(ParasaurolophusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.PARASAUROLOPHUS.get().create(pLevel); + if (child instanceof ParasaurolophusEntity baby) { + ParasaurolophusVariant randomVariant = Util.getRandom(ParasaurolophusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -179,11 +192,13 @@ public class ParasaurolophusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -248,6 +263,7 @@ public class ParasaurolophusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -255,12 +271,55 @@ public class ParasaurolophusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -279,33 +338,35 @@ public class ParasaurolophusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof ParasaurolophusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - ParasaurolophusVariant variant = Util.getRandom(ParasaurolophusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - ParasaurolophusVariant variant = Util.getRandom(ParasaurolophusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + ParasaurolophusVariant variant = Util.getRandom(ParasaurolophusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + ParasaurolophusVariant variant = Util.getRandom(ParasaurolophusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ProceratosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ProceratosaurusEntity.java index 4d8c999..3e24d86 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ProceratosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ProceratosaurusEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class ProceratosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(ProceratosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(ProceratosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 33600; + private static final float MIN_ANIMAL_SCALE = 0.4F; + private static final float MAX_ANIMAL_SCALE = 0.8F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(ProceratosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(ProceratosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(ProceratosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class ProceratosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_PROCERATOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class ProceratosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.PROCERATOSAURUS.get().create(pLevel); - if (child instanceof ProceratosaurusEntity baby) { - ProceratosaurusVariant randomVariant = Util.getRandom(ProceratosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.PROCERATOSAURUS.get().create(pLevel); + if (child instanceof ProceratosaurusEntity baby) { + ProceratosaurusVariant randomVariant = Util.getRandom(ProceratosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -182,11 +195,13 @@ public class ProceratosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -251,6 +266,7 @@ public class ProceratosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -258,12 +274,55 @@ public class ProceratosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -282,33 +341,35 @@ public class ProceratosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof ProceratosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - ProceratosaurusVariant variant = Util.getRandom(ProceratosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - ProceratosaurusVariant variant = Util.getRandom(ProceratosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + ProceratosaurusVariant variant = Util.getRandom(ProceratosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + ProceratosaurusVariant variant = Util.getRandom(ProceratosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ProcompsognathusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ProcompsognathusEntity.java index 657bb2f..e0ab0e4 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ProcompsognathusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ProcompsognathusEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class ProcompsognathusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(ProcompsognathusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(ProcompsognathusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 14400; + private static final float MIN_ANIMAL_SCALE = 0.0F; + private static final float MAX_ANIMAL_SCALE = 0.4F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(ProcompsognathusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(ProcompsognathusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(ProcompsognathusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class ProcompsognathusEntity extends DinoEntityBase implements GeoEntity return ModBlocks.INCUBATED_PROCOMPSOGNATHUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class ProcompsognathusEntity extends DinoEntityBase implements GeoEntity } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.PROCOMPSOGNATHUS.get().create(pLevel); - if (child instanceof ProcompsognathusEntity baby) { - ProcompsognathusVariant randomVariant = Util.getRandom(ProcompsognathusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.PROCOMPSOGNATHUS.get().create(pLevel); + if (child instanceof ProcompsognathusEntity baby) { + ProcompsognathusVariant randomVariant = Util.getRandom(ProcompsognathusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -182,11 +195,13 @@ public class ProcompsognathusEntity extends DinoEntityBase implements GeoEntity double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -251,6 +266,7 @@ public class ProcompsognathusEntity extends DinoEntityBase implements GeoEntity super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -258,12 +274,55 @@ public class ProcompsognathusEntity extends DinoEntityBase implements GeoEntity super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -282,33 +341,35 @@ public class ProcompsognathusEntity extends DinoEntityBase implements GeoEntity if (!(other instanceof ProcompsognathusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - ProcompsognathusVariant variant = Util.getRandom(ProcompsognathusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - ProcompsognathusVariant variant = Util.getRandom(ProcompsognathusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + ProcompsognathusVariant variant = Util.getRandom(ProcompsognathusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + ProcompsognathusVariant variant = Util.getRandom(ProcompsognathusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ProtoceratopsEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ProtoceratopsEntity.java index fd59906..9a639cf 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ProtoceratopsEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ProtoceratopsEntity.java @@ -53,10 +53,18 @@ import software.bernie.geckolib.animation.*; public class ProtoceratopsEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(ProtoceratopsEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(ProtoceratopsEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 43200; + private static final float MIN_ANIMAL_SCALE = 1.0F; + private static final float MAX_ANIMAL_SCALE = 1.4F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(ProtoceratopsEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(ProtoceratopsEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(ProtoceratopsEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -105,10 +113,14 @@ public class ProtoceratopsEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_PROTOCERATOPS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -122,16 +134,17 @@ public class ProtoceratopsEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.PROTOCERATOPS.get().create(pLevel); - if (child instanceof ProtoceratopsEntity baby) { - ProtoceratopsVariant randomVariant = Util.getRandom(ProtoceratopsVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.PROTOCERATOPS.get().create(pLevel); + if (child instanceof ProtoceratopsEntity baby) { + ProtoceratopsVariant randomVariant = Util.getRandom(ProtoceratopsVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -181,11 +194,13 @@ public class ProtoceratopsEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -250,6 +265,7 @@ public class ProtoceratopsEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -257,12 +273,55 @@ public class ProtoceratopsEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -281,33 +340,35 @@ public class ProtoceratopsEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof ProtoceratopsEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - ProtoceratopsVariant variant = Util.getRandom(ProtoceratopsVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - ProtoceratopsVariant variant = Util.getRandom(ProtoceratopsVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + ProtoceratopsVariant variant = Util.getRandom(ProtoceratopsVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + ProtoceratopsVariant variant = Util.getRandom(ProtoceratopsVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/PteranodonEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/PteranodonEntity.java index c37b43d..d5109b7 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/PteranodonEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/PteranodonEntity.java @@ -63,10 +63,18 @@ import software.bernie.geckolib.animation.*; public class PteranodonEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(PteranodonEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(PteranodonEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 28800; + private static final float MIN_ANIMAL_SCALE = 1.3F; + private static final float MAX_ANIMAL_SCALE = 1.7F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(PteranodonEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(PteranodonEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(PteranodonEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -116,10 +124,14 @@ public class PteranodonEntity extends DinoEntityBase implements GeoEntity, Flyin return ModBlocks.INCUBATED_PTERANODON_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -157,16 +169,17 @@ public class PteranodonEntity extends DinoEntityBase implements GeoEntity, Flyin } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.PTERANODON.get().create(pLevel); - if (child instanceof PteranodonEntity baby) { - PteranodonVariant randomVariant = Util.getRandom(PteranodonVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.PTERANODON.get().create(pLevel); + if (child instanceof PteranodonEntity baby) { + PteranodonVariant randomVariant = Util.getRandom(PteranodonVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -221,11 +234,13 @@ public class PteranodonEntity extends DinoEntityBase implements GeoEntity, Flyin double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -290,6 +305,7 @@ public class PteranodonEntity extends DinoEntityBase implements GeoEntity, Flyin super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -297,12 +313,55 @@ public class PteranodonEntity extends DinoEntityBase implements GeoEntity, Flyin super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public PteranodonVariant getVariant() { return PteranodonVariant.byId(this.getTypeVariant() & 255); @@ -327,28 +386,30 @@ public class PteranodonEntity extends DinoEntityBase implements GeoEntity, Flyin public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { PteranodonVariant variant = Util.getRandom(PteranodonVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - PteranodonVariant variant = Util.getRandom(PteranodonVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + PteranodonVariant variant = Util.getRandom(PteranodonVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/PterodaustroEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/PterodaustroEntity.java index 57d1e34..fea51ba 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/PterodaustroEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/PterodaustroEntity.java @@ -63,10 +63,18 @@ import software.bernie.geckolib.animation.*; public class PterodaustroEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(PterodaustroEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(PterodaustroEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 19200; + private static final float MIN_ANIMAL_SCALE = 0.5F; + private static final float MAX_ANIMAL_SCALE = 0.9F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(PterodaustroEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(PterodaustroEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(PterodaustroEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -116,10 +124,14 @@ public class PterodaustroEntity extends DinoEntityBase implements GeoEntity, Fly return ModBlocks.INCUBATED_PTERODAUSTRO_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -157,16 +169,17 @@ public class PterodaustroEntity extends DinoEntityBase implements GeoEntity, Fly } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.PTERODAUSTRO.get().create(pLevel); - if (child instanceof PterodaustroEntity baby) { - PterodaustroVariant randomVariant = Util.getRandom(PterodaustroVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.PTERODAUSTRO.get().create(pLevel); + if (child instanceof PterodaustroEntity baby) { + PterodaustroVariant randomVariant = Util.getRandom(PterodaustroVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -221,11 +234,13 @@ public class PterodaustroEntity extends DinoEntityBase implements GeoEntity, Fly double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -290,6 +305,7 @@ public class PterodaustroEntity extends DinoEntityBase implements GeoEntity, Fly super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -297,12 +313,55 @@ public class PterodaustroEntity extends DinoEntityBase implements GeoEntity, Fly super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public PterodaustroVariant getVariant() { return PterodaustroVariant.byId(this.getTypeVariant() & 255); @@ -327,28 +386,30 @@ public class PterodaustroEntity extends DinoEntityBase implements GeoEntity, Fly public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { PterodaustroVariant variant = Util.getRandom(PterodaustroVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - PterodaustroVariant variant = Util.getRandom(PterodaustroVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + PterodaustroVariant variant = Util.getRandom(PterodaustroVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/QuetzalcoatlusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/QuetzalcoatlusEntity.java index 4ac8eca..b6951f2 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/QuetzalcoatlusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/QuetzalcoatlusEntity.java @@ -63,10 +63,18 @@ import software.bernie.geckolib.animation.*; public class QuetzalcoatlusEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 43200; + private static final float MIN_ANIMAL_SCALE = 2.3F; + private static final float MAX_ANIMAL_SCALE = 2.7F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(QuetzalcoatlusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(QuetzalcoatlusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(QuetzalcoatlusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -116,10 +124,14 @@ public class QuetzalcoatlusEntity extends DinoEntityBase implements GeoEntity, F return ModBlocks.INCUBATED_QUETZALCOATLUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -164,6 +176,7 @@ public class QuetzalcoatlusEntity extends DinoEntityBase implements GeoEntity, F if (child instanceof QuetzalcoatlusEntity baby) { QuetzalcoatlusVariant randomVariant = Util.getRandom(QuetzalcoatlusVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -225,6 +238,8 @@ public class QuetzalcoatlusEntity extends DinoEntityBase implements GeoEntity, F } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -290,19 +305,58 @@ public class QuetzalcoatlusEntity extends DinoEntityBase implements GeoEntity, F super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ public QuetzalcoatlusVariant getVariant() { return QuetzalcoatlusVariant.byId(this.getTypeVariant() & 255); @@ -327,27 +381,29 @@ public class QuetzalcoatlusEntity extends DinoEntityBase implements GeoEntity, F public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { QuetzalcoatlusVariant variant = Util.getRandom(QuetzalcoatlusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - QuetzalcoatlusVariant variant = Util.getRandom(QuetzalcoatlusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + QuetzalcoatlusVariant variant = Util.getRandom(QuetzalcoatlusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } @Override public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/RajasaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/RajasaurusEntity.java index ad4933d..45cd798 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/RajasaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/RajasaurusEntity.java @@ -55,10 +55,18 @@ import software.bernie.geckolib.animation.*; public class RajasaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 43200; + private static final float MIN_ANIMAL_SCALE = 1.0F; + private static final float MAX_ANIMAL_SCALE = 1.4F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(RajasaurusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(RajasaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(RajasaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -107,10 +115,14 @@ public class RajasaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_RAJASAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -131,6 +143,7 @@ public class RajasaurusEntity extends DinoEntityBase implements GeoEntity { if (child instanceof RajasaurusEntity baby) { RajasaurusVariant randomVariant = Util.getRandom(RajasaurusVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -184,10 +197,12 @@ public class RajasaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } + } } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -253,19 +268,58 @@ public class RajasaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -288,12 +342,16 @@ public class RajasaurusEntity extends DinoEntityBase implements GeoEntity { public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } /*? if <=1.20.1 {*/ @@ -301,15 +359,13 @@ public class RajasaurusEntity extends DinoEntityBase implements GeoEntity { public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { RajasaurusVariant variant = Util.getRandom(RajasaurusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - RajasaurusVariant variant = Util.getRandom(RajasaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + RajasaurusVariant variant = Util.getRandom(RajasaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/RugopsEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/RugopsEntity.java index 584c6f5..ce3905d 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/RugopsEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/RugopsEntity.java @@ -55,10 +55,18 @@ import software.bernie.geckolib.animation.*; public class RugopsEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 38400; + private static final float MIN_ANIMAL_SCALE = 0.7F; + private static final float MAX_ANIMAL_SCALE = 1.1F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(RugopsEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(RugopsEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(RugopsEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -107,10 +115,14 @@ public class RugopsEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_RUGOPS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -131,6 +143,7 @@ public class RugopsEntity extends DinoEntityBase implements GeoEntity { if (child instanceof RugopsEntity baby) { RugopsVariant randomVariant = Util.getRandom(RugopsVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -184,10 +197,12 @@ public class RugopsEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } + } } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -253,19 +268,58 @@ public class RugopsEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -288,12 +342,16 @@ public class RugopsEntity extends DinoEntityBase implements GeoEntity { public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } /*? if <=1.20.1 {*/ @@ -301,15 +359,13 @@ public class RugopsEntity extends DinoEntityBase implements GeoEntity { public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { RugopsVariant variant = Util.getRandom(RugopsVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - RugopsVariant variant = Util.getRandom(RugopsVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + RugopsVariant variant = Util.getRandom(RugopsVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/SegisaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/SegisaurusEntity.java index 42f2738..0b494ba 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/SegisaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/SegisaurusEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class SegisaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 19200; + private static final float MIN_ANIMAL_SCALE = 0.2F; + private static final float MAX_ANIMAL_SCALE = 0.6F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(SegisaurusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(SegisaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(SegisaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class SegisaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_SEGISAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -130,6 +142,7 @@ public class SegisaurusEntity extends DinoEntityBase implements GeoEntity { if (child instanceof SegisaurusEntity baby) { SegisaurusVariant randomVariant = Util.getRandom(SegisaurusVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -186,6 +199,8 @@ public class SegisaurusEntity extends DinoEntityBase implements GeoEntity { } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -251,19 +266,58 @@ public class SegisaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -286,12 +340,16 @@ public class SegisaurusEntity extends DinoEntityBase implements GeoEntity { public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } /*? if <=1.20.1 {*/ @@ -299,15 +357,13 @@ public class SegisaurusEntity extends DinoEntityBase implements GeoEntity { public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { SegisaurusVariant variant = Util.getRandom(SegisaurusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - SegisaurusVariant variant = Util.getRandom(SegisaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + SegisaurusVariant variant = Util.getRandom(SegisaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ShantungosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ShantungosaurusEntity.java index 43bdd81..bdb0807 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ShantungosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ShantungosaurusEntity.java @@ -51,10 +51,18 @@ import software.bernie.geckolib.animation.*; public class ShantungosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(ShantungosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(ShantungosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 81600; + private static final float MIN_ANIMAL_SCALE = 1.6F; + private static final float MAX_ANIMAL_SCALE = 2.0F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(ShantungosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(ShantungosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(ShantungosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -103,10 +111,14 @@ public class ShantungosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_SHANTUNGOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -120,16 +132,17 @@ public class ShantungosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.SHANTUNGOSAURUS.get().create(pLevel); - if (child instanceof ShantungosaurusEntity baby) { - ShantungosaurusVariant randomVariant = Util.getRandom(ShantungosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.SHANTUNGOSAURUS.get().create(pLevel); + if (child instanceof ShantungosaurusEntity baby) { + ShantungosaurusVariant randomVariant = Util.getRandom(ShantungosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -179,11 +192,13 @@ public class ShantungosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -248,6 +263,7 @@ public class ShantungosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -255,12 +271,55 @@ public class ShantungosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -279,33 +338,35 @@ public class ShantungosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof ShantungosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - ShantungosaurusVariant variant = Util.getRandom(ShantungosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - ShantungosaurusVariant variant = Util.getRandom(ShantungosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + ShantungosaurusVariant variant = Util.getRandom(ShantungosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + ShantungosaurusVariant variant = Util.getRandom(ShantungosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/SpinosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/SpinosaurusEntity.java index 0154c00..fc8063a 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/SpinosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/SpinosaurusEntity.java @@ -56,10 +56,18 @@ import software.bernie.geckolib.animation.*; public class SpinosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 86400; + private static final float MIN_ANIMAL_SCALE = 2.2F; + private static final float MAX_ANIMAL_SCALE = 2.6F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(SpinosaurusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(SpinosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(SpinosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -108,10 +116,14 @@ public class SpinosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_SPINOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -132,6 +144,7 @@ public class SpinosaurusEntity extends DinoEntityBase implements GeoEntity { if (child instanceof SpinosaurusEntity baby) { SpinosaurusVariant randomVariant = Util.getRandom(SpinosaurusVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -185,10 +198,12 @@ public class SpinosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } + } } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -254,19 +269,58 @@ public class SpinosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -289,12 +343,16 @@ public class SpinosaurusEntity extends DinoEntityBase implements GeoEntity { public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } /*? if <=1.20.1 {*/ @@ -302,15 +360,13 @@ public class SpinosaurusEntity extends DinoEntityBase implements GeoEntity { public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { SpinosaurusVariant variant = Util.getRandom(SpinosaurusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - SpinosaurusVariant variant = Util.getRandom(SpinosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + SpinosaurusVariant variant = Util.getRandom(SpinosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/StegosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/StegosaurusEntity.java index dd2b18e..d5e88c2 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/StegosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/StegosaurusEntity.java @@ -53,10 +53,18 @@ import software.bernie.geckolib.animation.*; public class StegosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(StegosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(StegosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 52800; + private static final float MIN_ANIMAL_SCALE = 1.6F; + private static final float MAX_ANIMAL_SCALE = 2.0F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(StegosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(StegosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(StegosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -105,10 +113,14 @@ public class StegosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_STEGOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -122,16 +134,17 @@ public class StegosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.STEGOSAURUS.get().create(pLevel); - if (child instanceof StegosaurusEntity baby) { - StegosaurusVariant randomVariant = Util.getRandom(StegosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.STEGOSAURUS.get().create(pLevel); + if (child instanceof StegosaurusEntity baby) { + StegosaurusVariant randomVariant = Util.getRandom(StegosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -182,11 +195,13 @@ public class StegosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -251,6 +266,7 @@ public class StegosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -258,12 +274,55 @@ public class StegosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -282,33 +341,35 @@ public class StegosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof StegosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - StegosaurusVariant variant = Util.getRandom(StegosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - StegosaurusVariant variant = Util.getRandom(StegosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + StegosaurusVariant variant = Util.getRandom(StegosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + StegosaurusVariant variant = Util.getRandom(StegosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/StyracosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/StyracosaurusEntity.java index 5eea24b..1b541a8 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/StyracosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/StyracosaurusEntity.java @@ -53,10 +53,18 @@ import software.bernie.geckolib.animation.*; public class StyracosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(StyracosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(StyracosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 67200; + private static final float MIN_ANIMAL_SCALE = 0.5F; + private static final float MAX_ANIMAL_SCALE = 0.9F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(StyracosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(StyracosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(StyracosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -105,10 +113,14 @@ public class StyracosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_STYRACOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -122,16 +134,17 @@ public class StyracosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.STYRACOSAURUS.get().create(pLevel); - if (child instanceof StyracosaurusEntity baby) { - StyracosaurusVariant randomVariant = Util.getRandom(StyracosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.STYRACOSAURUS.get().create(pLevel); + if (child instanceof StyracosaurusEntity baby) { + StyracosaurusVariant randomVariant = Util.getRandom(StyracosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -181,11 +194,13 @@ public class StyracosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -250,6 +265,7 @@ public class StyracosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -257,12 +273,55 @@ public class StyracosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -281,33 +340,35 @@ public class StyracosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof StyracosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - StyracosaurusVariant variant = Util.getRandom(StyracosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - StyracosaurusVariant variant = Util.getRandom(StyracosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + StyracosaurusVariant variant = Util.getRandom(StyracosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + StyracosaurusVariant variant = Util.getRandom(StyracosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/SuchomimusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/SuchomimusEntity.java index ac8b98d..938f1bd 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/SuchomimusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/SuchomimusEntity.java @@ -46,10 +46,18 @@ import software.bernie.geckolib.animation.*; public class SuchomimusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 72000; + private static final float MIN_ANIMAL_SCALE = 1.7F; + private static final float MAX_ANIMAL_SCALE = 2.1F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(SuchomimusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(SuchomimusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(SuchomimusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -103,6 +111,10 @@ public class SuchomimusEntity extends DinoEntityBase implements GeoEntity { return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); } + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } + public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() .add(Attributes.MAX_HEALTH, 55D) @@ -122,6 +134,7 @@ public class SuchomimusEntity extends DinoEntityBase implements GeoEntity { if (child instanceof SuchomimusEntity baby) { SuchomimusVariant randomVariant = Util.getRandom(SuchomimusVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -176,10 +189,12 @@ public class SuchomimusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } + } } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -245,19 +260,58 @@ public class SuchomimusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -280,12 +334,16 @@ public class SuchomimusEntity extends DinoEntityBase implements GeoEntity { public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } /*? if <=1.20.1 {*/ @@ -293,15 +351,13 @@ public class SuchomimusEntity extends DinoEntityBase implements GeoEntity { public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { SuchomimusVariant variant = Util.getRandom(SuchomimusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - SuchomimusVariant variant = Util.getRandom(SuchomimusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + SuchomimusVariant variant = Util.getRandom(SuchomimusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TapejaraEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TapejaraEntity.java index fa660c5..8e89f81 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TapejaraEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TapejaraEntity.java @@ -61,12 +61,20 @@ import software.bernie.geckolib.animation.*; *//*?}*/ public class TapejaraEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { - private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(TapejaraEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(TapejaraEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 24000; + private static final float MIN_ANIMAL_SCALE = 0.4F; + private static final float MAX_ANIMAL_SCALE = 0.8F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(TapejaraEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(TapejaraEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(TapejaraEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -116,10 +124,14 @@ public class TapejaraEntity extends DinoEntityBase implements GeoEntity, FlyingA return ModBlocks.INCUBATED_TAPEJARA_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -157,16 +169,17 @@ public class TapejaraEntity extends DinoEntityBase implements GeoEntity, FlyingA } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.TAPEJARA.get().create(pLevel); - if (child instanceof TapejaraEntity baby) { - TapejaraVariant randomVariant = Util.getRandom(TapejaraVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.TAPEJARA.get().create(pLevel); + if (child instanceof TapejaraEntity baby) { + TapejaraVariant randomVariant = Util.getRandom(TapejaraVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -221,11 +234,13 @@ public class TapejaraEntity extends DinoEntityBase implements GeoEntity, FlyingA double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -290,6 +305,7 @@ public class TapejaraEntity extends DinoEntityBase implements GeoEntity, FlyingA super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -297,12 +313,55 @@ public class TapejaraEntity extends DinoEntityBase implements GeoEntity, FlyingA super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public TapejaraVariant getVariant() { return TapejaraVariant.byId(this.getTypeVariant() & 255); @@ -327,27 +386,29 @@ public class TapejaraEntity extends DinoEntityBase implements GeoEntity, FlyingA public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { TapejaraVariant variant = Util.getRandom(TapejaraVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - TapejaraVariant variant = Util.getRandom(TapejaraVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + TapejaraVariant variant = Util.getRandom(TapejaraVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } @Override public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TherizinosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TherizinosaurusEntity.java index 952b364..ff66172 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TherizinosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TherizinosaurusEntity.java @@ -53,10 +53,18 @@ import software.bernie.geckolib.animation.*; public class TherizinosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(TherizinosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(TherizinosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 76800; + private static final float MIN_ANIMAL_SCALE = 1.7F; + private static final float MAX_ANIMAL_SCALE = 2.1F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(TherizinosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(TherizinosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(TherizinosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -105,10 +113,14 @@ public class TherizinosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_THERIZINOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -122,16 +134,17 @@ public class TherizinosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.THERIZINOSAURUS.get().create(pLevel); - if (child instanceof TherizinosaurusEntity baby) { - TherizinosaurusVariant randomVariant = Util.getRandom(TherizinosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.THERIZINOSAURUS.get().create(pLevel); + if (child instanceof TherizinosaurusEntity baby) { + TherizinosaurusVariant randomVariant = Util.getRandom(TherizinosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -182,11 +195,13 @@ public class TherizinosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -251,6 +266,7 @@ public class TherizinosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -258,12 +274,55 @@ public class TherizinosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -282,33 +341,35 @@ public class TherizinosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof TherizinosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - TherizinosaurusVariant variant = Util.getRandom(TherizinosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - TherizinosaurusVariant variant = Util.getRandom(TherizinosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + TherizinosaurusVariant variant = Util.getRandom(TherizinosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + TherizinosaurusVariant variant = Util.getRandom(TherizinosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ThescelosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ThescelosaurusEntity.java index dcbe934..da08782 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ThescelosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ThescelosaurusEntity.java @@ -46,10 +46,18 @@ import software.bernie.geckolib.animation.*; public class ThescelosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(ThescelosaurusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(ThescelosaurusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 43200; + private static final float MIN_ANIMAL_SCALE = 0.5F; + private static final float MAX_ANIMAL_SCALE = 0.9F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(ThescelosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(ThescelosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(ThescelosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -98,10 +106,14 @@ public class ThescelosaurusEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_THESCELOSAURUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -115,16 +127,17 @@ public class ThescelosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.THESCELOSAURUS.get().create(pLevel); - if (child instanceof ThescelosaurusEntity baby) { - ThescelosaurusVariant randomVariant = Util.getRandom(ThescelosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.THESCELOSAURUS.get().create(pLevel); + if (child instanceof ThescelosaurusEntity baby) { + ThescelosaurusVariant randomVariant = Util.getRandom(ThescelosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -171,11 +184,13 @@ public class ThescelosaurusEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -239,6 +254,7 @@ public class ThescelosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -246,12 +262,55 @@ public class ThescelosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -270,33 +329,35 @@ public class ThescelosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof ThescelosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - ThescelosaurusVariant variant = Util.getRandom(ThescelosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - ThescelosaurusVariant variant = Util.getRandom(ThescelosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + ThescelosaurusVariant variant = Util.getRandom(ThescelosaurusVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + ThescelosaurusVariant variant = Util.getRandom(ThescelosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TitanosaurusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TitanosaurusEntity.java index e85778e..d1cbb5b 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TitanosaurusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TitanosaurusEntity.java @@ -55,10 +55,18 @@ import software.bernie.geckolib.animation.*; public class TitanosaurusEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 129600; + private static final float MIN_ANIMAL_SCALE = 2.1F; + private static final float MAX_ANIMAL_SCALE = 2.5F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(TitanosaurusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(TitanosaurusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(TitanosaurusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -112,6 +120,10 @@ public class TitanosaurusEntity extends DinoEntityBase implements GeoEntity { return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); } + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } + public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() .add(Attributes.MAX_HEALTH, 250D) @@ -124,16 +136,17 @@ public class TitanosaurusEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.TITANOSAURUS.get().create(pLevel); - if (child instanceof TitanosaurusEntity baby) { - TitanosaurusVariant randomVariant = Util.getRandom(TitanosaurusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.TITANOSAURUS.get().create(pLevel); + if (child instanceof TitanosaurusEntity baby) { + TitanosaurusVariant randomVariant = Util.getRandom(TitanosaurusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -189,6 +202,8 @@ public class TitanosaurusEntity extends DinoEntityBase implements GeoEntity { } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -254,19 +269,59 @@ public class TitanosaurusEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ public int getSyncedAge() { return this.entityData.get(DATA_SYNCED_AGE); } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ + public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -285,32 +340,35 @@ public class TitanosaurusEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof TitanosaurusEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } /*? if <=1.20.1 {*/ @Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { TitanosaurusVariant variant = Util.getRandom(TitanosaurusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - TitanosaurusVariant variant = Util.getRandom(TitanosaurusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + TitanosaurusVariant variant = Util.getRandom(TitanosaurusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TriceratopsEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TriceratopsEntity.java index 527af15..df0f811 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TriceratopsEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TriceratopsEntity.java @@ -53,10 +53,18 @@ import software.bernie.geckolib.animation.*; public class TriceratopsEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(TriceratopsEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(TriceratopsEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 91200; + private static final float MIN_ANIMAL_SCALE = 1.3F; + private static final float MAX_ANIMAL_SCALE = 1.7F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(TriceratopsEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(TriceratopsEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(TriceratopsEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -105,10 +113,14 @@ public class TriceratopsEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_TRICERATOPS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -122,16 +134,17 @@ public class TriceratopsEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.TRICERATOPS.get().create(pLevel); - if (child instanceof TriceratopsEntity baby) { - TriceratopsVariant randomVariant = Util.getRandom(TriceratopsVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.TRICERATOPS.get().create(pLevel); + if (child instanceof TriceratopsEntity baby) { + TriceratopsVariant randomVariant = Util.getRandom(TriceratopsVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -181,11 +194,13 @@ public class TriceratopsEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -250,6 +265,7 @@ public class TriceratopsEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -257,12 +273,55 @@ public class TriceratopsEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -281,33 +340,35 @@ public class TriceratopsEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof TriceratopsEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - TriceratopsVariant variant = Util.getRandom(TriceratopsVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - TriceratopsVariant variant = Util.getRandom(TriceratopsVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + TriceratopsVariant variant = Util.getRandom(TriceratopsVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + TriceratopsVariant variant = Util.getRandom(TriceratopsVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TroodonEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TroodonEntity.java index 22be976..eddd632 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TroodonEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TroodonEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class TroodonEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(TroodonEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(TroodonEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 24000; + private static final float MIN_ANIMAL_SCALE = 0.1F; + private static final float MAX_ANIMAL_SCALE = 0.5F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(TroodonEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(TroodonEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(TroodonEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class TroodonEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_TROODON_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class TroodonEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.TROODON.get().create(pLevel); - if (child instanceof TroodonEntity baby) { - TroodonVariant randomVariant = Util.getRandom(TroodonVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.TROODON.get().create(pLevel); + if (child instanceof TroodonEntity baby) { + TroodonVariant randomVariant = Util.getRandom(TroodonVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -182,11 +195,13 @@ public class TroodonEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -251,6 +266,7 @@ public class TroodonEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -258,12 +274,55 @@ public class TroodonEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -282,33 +341,35 @@ public class TroodonEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof TroodonEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - TroodonVariant variant = Util.getRandom(TroodonVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - TroodonVariant variant = Util.getRandom(TroodonVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + TroodonVariant variant = Util.getRandom(TroodonVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + TroodonVariant variant = Util.getRandom(TroodonVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TropeognathusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TropeognathusEntity.java index cd4fc30..5c366a4 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TropeognathusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TropeognathusEntity.java @@ -63,10 +63,18 @@ import software.bernie.geckolib.animation.*; public class TropeognathusEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(TropeognathusEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(TropeognathusEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 28800; + private static final float MIN_ANIMAL_SCALE = 1.2F; + private static final float MAX_ANIMAL_SCALE = 1.6F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(TropeognathusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(TropeognathusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(TropeognathusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -116,10 +124,14 @@ public class TropeognathusEntity extends DinoEntityBase implements GeoEntity, Fl return ModBlocks.INCUBATED_TROPEOGNATHUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -157,16 +169,17 @@ public class TropeognathusEntity extends DinoEntityBase implements GeoEntity, Fl } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.TROPEOGNATHUS.get().create(pLevel); - if (child instanceof TropeognathusEntity baby) { - TropeognathusVariant randomVariant = Util.getRandom(TropeognathusVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.TROPEOGNATHUS.get().create(pLevel); + if (child instanceof TropeognathusEntity baby) { + TropeognathusVariant randomVariant = Util.getRandom(TropeognathusVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -221,11 +234,13 @@ public class TropeognathusEntity extends DinoEntityBase implements GeoEntity, Fl double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -290,6 +305,7 @@ public class TropeognathusEntity extends DinoEntityBase implements GeoEntity, Fl super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -297,12 +313,55 @@ public class TropeognathusEntity extends DinoEntityBase implements GeoEntity, Fl super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public TropeognathusVariant getVariant() { return TropeognathusVariant.byId(this.getTypeVariant() & 255); @@ -327,28 +386,30 @@ public class TropeognathusEntity extends DinoEntityBase implements GeoEntity, Fl public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { TropeognathusVariant variant = Util.getRandom(TropeognathusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - TropeognathusVariant variant = Util.getRandom(TropeognathusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + TropeognathusVariant variant = Util.getRandom(TropeognathusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TupuxuaraEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TupuxuaraEntity.java index b8d692d..fed3314 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TupuxuaraEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TupuxuaraEntity.java @@ -63,10 +63,18 @@ import software.bernie.geckolib.animation.*; public class TupuxuaraEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 28800; + private static final float MIN_ANIMAL_SCALE = 0.8F; + private static final float MAX_ANIMAL_SCALE = 1.2F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(TupuxuaraEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(TupuxuaraEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(TupuxuaraEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -116,10 +124,14 @@ public class TupuxuaraEntity extends DinoEntityBase implements GeoEntity, Flying return ModBlocks.INCUBATED_TUPUXUARA_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -164,6 +176,7 @@ public class TupuxuaraEntity extends DinoEntityBase implements GeoEntity, Flying if (child instanceof TupuxuaraEntity baby) { TupuxuaraVariant randomVariant = Util.getRandom(TupuxuaraVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -221,10 +234,12 @@ public class TupuxuaraEntity extends DinoEntityBase implements GeoEntity, Flying double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } + } } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -290,19 +305,58 @@ public class TupuxuaraEntity extends DinoEntityBase implements GeoEntity, Flying super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ public TupuxuaraVariant getVariant() { return TupuxuaraVariant.byId(this.getTypeVariant() & 255); @@ -327,27 +381,29 @@ public class TupuxuaraEntity extends DinoEntityBase implements GeoEntity, Flying public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { TupuxuaraVariant variant = Util.getRandom(TupuxuaraVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - TupuxuaraVariant variant = Util.getRandom(TupuxuaraVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + TupuxuaraVariant variant = Util.getRandom(TupuxuaraVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } @Override public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TyrannosaurusRexEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TyrannosaurusRexEntity.java index 6883af0..bcf018f 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TyrannosaurusRexEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/TyrannosaurusRexEntity.java @@ -57,10 +57,18 @@ import software.bernie.geckolib.animation.*; public class TyrannosaurusRexEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 91200; + private static final float MIN_ANIMAL_SCALE = 2.3F; + private static final float MAX_ANIMAL_SCALE = 2.7F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(TyrannosaurusRexEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(TyrannosaurusRexEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(TyrannosaurusRexEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -114,6 +122,10 @@ public class TyrannosaurusRexEntity extends DinoEntityBase implements GeoEntity return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); } + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } + public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() .add(Attributes.MAX_HEALTH, 80D) @@ -133,6 +145,7 @@ public class TyrannosaurusRexEntity extends DinoEntityBase implements GeoEntity if (child instanceof TyrannosaurusRexEntity baby) { TyrannosaurusRexVariant randomVariant = Util.getRandom(TyrannosaurusRexVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -190,6 +203,8 @@ public class TyrannosaurusRexEntity extends DinoEntityBase implements GeoEntity } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -255,19 +270,58 @@ public class TyrannosaurusRexEntity extends DinoEntityBase implements GeoEntity super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ public int getSyncedAge() { return this.entityData.get(DATA_SYNCED_AGE); } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -290,12 +344,16 @@ public class TyrannosaurusRexEntity extends DinoEntityBase implements GeoEntity public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } /*? if <=1.20.1 {*/ @@ -303,15 +361,13 @@ public class TyrannosaurusRexEntity extends DinoEntityBase implements GeoEntity public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { TyrannosaurusRexVariant variant = Util.getRandom(TyrannosaurusRexVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - TyrannosaurusRexVariant variant = Util.getRandom(TyrannosaurusRexVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + TyrannosaurusRexVariant variant = Util.getRandom(TyrannosaurusRexVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/UtahraptorEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/UtahraptorEntity.java index c34d302..1f30a9c 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/UtahraptorEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/UtahraptorEntity.java @@ -53,10 +53,18 @@ import software.bernie.geckolib.animation.*; public class UtahraptorEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(UtahraptorEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(UtahraptorEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 43200; + private static final float MIN_ANIMAL_SCALE = 0.8F; + private static final float MAX_ANIMAL_SCALE = 1.2F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(UtahraptorEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(UtahraptorEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(UtahraptorEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -105,10 +113,14 @@ public class UtahraptorEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_UTAHRAPTOR_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -122,16 +134,17 @@ public class UtahraptorEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.UTAHRAPTOR.get().create(pLevel); - if (child instanceof UtahraptorEntity baby) { - UtahraptorVariant randomVariant = Util.getRandom(UtahraptorVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.UTAHRAPTOR.get().create(pLevel); + if (child instanceof UtahraptorEntity baby) { + UtahraptorVariant randomVariant = Util.getRandom(UtahraptorVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -181,11 +194,13 @@ public class UtahraptorEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -250,6 +265,7 @@ public class UtahraptorEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -257,12 +273,55 @@ public class UtahraptorEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -281,33 +340,35 @@ public class UtahraptorEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof UtahraptorEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - UtahraptorVariant variant = Util.getRandom(UtahraptorVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - UtahraptorVariant variant = Util.getRandom(UtahraptorVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + UtahraptorVariant variant = Util.getRandom(UtahraptorVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + UtahraptorVariant variant = Util.getRandom(UtahraptorVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/VelociraptorEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/VelociraptorEntity.java index 7de1746..5fda18e 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/VelociraptorEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/VelociraptorEntity.java @@ -54,10 +54,18 @@ import software.bernie.geckolib.animation.*; public class VelociraptorEntity extends DinoEntityBase implements GeoEntity { private AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); - private static final EntityDataAccessor VARIANT = - SynchedEntityData.defineId(VelociraptorEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_SYNCED_AGE = - SynchedEntityData.defineId(VelociraptorEntity.class, EntityDataSerializers.INT); + public static final int BABY_TO_ADULT_AGE_TICKS = 28800; + private static final float MIN_ANIMAL_SCALE = 0.8F; + private static final float MAX_ANIMAL_SCALE = 1.2F; + + private float lastDimensionsScale = 1.0F; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(VelociraptorEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_SYNCED_AGE = + SynchedEntityData.defineId(VelociraptorEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(VelociraptorEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -106,10 +114,14 @@ public class VelociraptorEntity extends DinoEntityBase implements GeoEntity { return ModBlocks.INCUBATED_VELOCIRAPTOR_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -123,16 +135,17 @@ public class VelociraptorEntity extends DinoEntityBase implements GeoEntity { } - @Nullable - @Override - public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { - AgeableMob child = ModEntities.VELOCIRAPTOR.get().create(pLevel); - if (child instanceof VelociraptorEntity baby) { - VelociraptorVariant randomVariant = Util.getRandom(VelociraptorVariant.values(), this.random); - baby.setVariant(randomVariant); - } - return child; - } + @Nullable + @Override + public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) { + AgeableMob child = ModEntities.VELOCIRAPTOR.get().create(pLevel); + if (child instanceof VelociraptorEntity baby) { + VelociraptorVariant randomVariant = Util.getRandom(VelociraptorVariant.values(), this.random); + baby.setVariant(randomVariant); + baby.setBaby(true); + } + return child; + } @Override public boolean doHurtTarget(Entity target) { @@ -183,11 +196,13 @@ public class VelociraptorEntity extends DinoEntityBase implements GeoEntity { double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } - } - } + } + } + } - if (!level().isClientSide) { + updateDynamicDimensions(); + + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; } else { @@ -252,6 +267,7 @@ public class VelociraptorEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override @@ -259,12 +275,55 @@ public class VelociraptorEntity extends DinoEntityBase implements GeoEntity { super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); + pBuilder.define(DATA_ANIMAL_SCALE, 1.0F); } *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + *//*?}*/ public int getTypeVariant() { return this.entityData.get(VARIANT); } @@ -283,33 +342,35 @@ public class VelociraptorEntity extends DinoEntityBase implements GeoEntity { if (!(other instanceof VelociraptorEntity that)) return false; return this.getVariant() != that.getVariant(); } - @Override - public void addAdditionalSaveData(CompoundTag pCompound) { - super.addAdditionalSaveData(pCompound); - pCompound.putInt("Variant", this.getTypeVariant()); - } + @Override + public void addAdditionalSaveData(CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); + } - @Override - public void readAdditionalSaveData(CompoundTag pCompound) { - super.readAdditionalSaveData(pCompound); - this.entityData.set(VARIANT, pCompound.getInt("Variant")); - } + @Override + public void readAdditionalSaveData(CompoundTag pCompound) { + super.readAdditionalSaveData(pCompound); + this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } + } - /*? if <=1.20.1 {*/ - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { - VelociraptorVariant variant = Util.getRandom(VelociraptorVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); - } - /*?} else {*/ - /*@Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - VelociraptorVariant variant = Util.getRandom(VelociraptorVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } - *//*?}*/ + /*? if <=1.20.1 {*/ + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { + VelociraptorVariant variant = Util.getRandom(VelociraptorVariant.values(), this.random); + this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); + return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); + } + /*?} else {*/ + /*@Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + VelociraptorVariant variant = Util.getRandom(VelociraptorVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} + *//*?}*/ @Override public AnimatableInstanceCache getAnimatableInstanceCache() { diff --git a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ZhenyuanopterusEntity.java b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ZhenyuanopterusEntity.java index 24f2fd4..beb14fa 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ZhenyuanopterusEntity.java +++ b/common/src/main/java/net/cmr/jurassicrevived/entity/custom/ZhenyuanopterusEntity.java @@ -63,10 +63,18 @@ import software.bernie.geckolib.animation.*; public class ZhenyuanopterusEntity extends DinoEntityBase implements GeoEntity, FlyingAnimal { private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + public static final int BABY_TO_ADULT_AGE_TICKS = 28800; + private static final float MIN_ANIMAL_SCALE = 0.9F; + private static final float MAX_ANIMAL_SCALE = 1.3F; + + private float lastDimensionsScale = 1.0F; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(ZhenyuanopterusEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_SYNCED_AGE = SynchedEntityData.defineId(ZhenyuanopterusEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_ANIMAL_SCALE = + SynchedEntityData.defineId(ZhenyuanopterusEntity.class, EntityDataSerializers.FLOAT); // Procedural tail sway state (client-side use for rendering) private float tailSwayOffset; // Smoothed offset in range roughly [-1, 1] @@ -116,10 +124,14 @@ public class ZhenyuanopterusEntity extends DinoEntityBase implements GeoEntity, return ModBlocks.INCUBATED_ZHENYUANOPTERUS_EGG.get(); } - @Override - public DinoAIConfig getAIConfig() { - return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); - } + @Override + public DinoAIConfig getAIConfig() { + return new DinoAIConfig(0.3D, 1.1D, 1.5D, 100, 100, 0.05f, 0.1f, 20); + } + + public void setBaby(boolean baby) { + this.setAge(baby ? -BABY_TO_ADULT_AGE_TICKS : 0); + } public static AttributeSupplier.Builder createAttributes() { return Animal.createLivingAttributes() @@ -164,6 +176,7 @@ public class ZhenyuanopterusEntity extends DinoEntityBase implements GeoEntity, if (child instanceof ZhenyuanopterusEntity baby) { ZhenyuanopterusVariant randomVariant = Util.getRandom(ZhenyuanopterusVariant.values(), this.random); baby.setVariant(randomVariant); + baby.setBaby(true); } return child; } @@ -221,10 +234,12 @@ public class ZhenyuanopterusEntity extends DinoEntityBase implements GeoEntity, double healthRatio = this.getHealth() / (float) oldMax; maxHealthAttr.setBaseValue(desired); this.setHealth((float) (desired * Mth.clamp(healthRatio, 0.0F, 1.0F))); - } + } } } + updateDynamicDimensions(); + if (!level().isClientSide) { if (mouthAnimCooldown > 0) { mouthAnimCooldown--; @@ -290,19 +305,58 @@ public class ZhenyuanopterusEntity extends DinoEntityBase implements GeoEntity, super.defineSynchedData(); this.entityData.define(VARIANT, 0); this.entityData.define(DATA_SYNCED_AGE, 0); + this.entityData.define(DATA_ANIMAL_SCALE, 1.0F); } /*?} else {*/ /*@Override protected void defineSynchedData(SynchedEntityData.Builder pBuilder) { - super.defineSynchedData(pBuilder); - pBuilder.define(VARIANT, 0); - pBuilder.define(DATA_SYNCED_AGE, 0); - } + super.defineSynchedData(pBuilder); pBuilder.define(VARIANT, 0); pBuilder.define(DATA_SYNCED_AGE, 0); pBuilder.define(DATA_ANIMAL_SCALE, 1.0F);} *//*?}*/ - public int getSyncedAge() { - return this.entityData.get(DATA_SYNCED_AGE); - } + public int getSyncedAge() { + return this.entityData.get(DATA_SYNCED_AGE); + } + + public float getAnimalScale() { + return this.entityData.get(DATA_ANIMAL_SCALE); + } + + private void setAnimalScale(float animalScale) { + this.entityData.set(DATA_ANIMAL_SCALE, animalScale); + } + + public float getGrowthScale() { + if (!this.isBaby()) { + return 1.0F; + } + + int age = this.level().isClientSide ? this.getSyncedAge() : this.getAge(); + float growthProgress = Mth.clamp((BABY_TO_ADULT_AGE_TICKS + age) / (float) BABY_TO_ADULT_AGE_TICKS, 0.0F, 1.0F); + return Mth.lerp(growthProgress, 0.2F, 1.0F); + } + + public float getTotalModelScale() { + return this.getAnimalScale() * this.getGrowthScale(); + } + + private void updateDynamicDimensions() { + float dimensionsScale = this.getTotalModelScale(); + if (Math.abs(dimensionsScale - this.lastDimensionsScale) > 0.01F) { + this.lastDimensionsScale = dimensionsScale; + this.refreshDimensions(); + } + } + + /*? if <=1.20.1 {*/ + @Override + public EntityDimensions getDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale()); + } + /*?} else {*/ + /*@Override + protected EntityDimensions getDefaultDimensions(Pose pose) { + return this.getType().getDimensions().scale(this.getTotalModelScale());} + *//*?}*/ public ZhenyuanopterusVariant getVariant() { return ZhenyuanopterusVariant.byId(this.getTypeVariant() & 255); @@ -327,27 +381,29 @@ public class ZhenyuanopterusEntity extends DinoEntityBase implements GeoEntity, public SpawnGroupData finalizeSpawn(ServerLevelAccessor pLevel, DifficultyInstance pDifficulty, MobSpawnType pReason, @Nullable SpawnGroupData pSpawnData, @Nullable CompoundTag pDataTag) { ZhenyuanopterusVariant variant = Util.getRandom(ZhenyuanopterusVariant.values(), this.random); this.setVariant(variant); + this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(pLevel, pDifficulty, pReason, pSpawnData, pDataTag); } /*?} else {*/ /*@Override public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { - ZhenyuanopterusVariant variant = Util.getRandom(ZhenyuanopterusVariant.values(), this.random); - this.setVariant(variant); - return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); - } + ZhenyuanopterusVariant variant = Util.getRandom(ZhenyuanopterusVariant.values(), this.random); this.setVariant(variant); this.setAnimalScale(Mth.nextFloat(this.random, MIN_ANIMAL_SCALE, MAX_ANIMAL_SCALE)); return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData);} *//*?}*/ @Override public void readAdditionalSaveData(CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); this.entityData.set(VARIANT, pCompound.getInt("Variant")); + if (pCompound.contains("AnimalScale")) { + this.setAnimalScale(pCompound.getFloat("AnimalScale")); + } } @Override public void addAdditionalSaveData(CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putInt("Variant", this.getTypeVariant()); + pCompound.putFloat("AnimalScale", this.getAnimalScale()); } @Override diff --git a/common/src/main/java/net/cmr/jurassicrevived/item/ModCreativeTabs.java b/common/src/main/java/net/cmr/jurassicrevived/item/ModCreativeTabs.java index f6ac50e..58c2c65 100755 --- a/common/src/main/java/net/cmr/jurassicrevived/item/ModCreativeTabs.java +++ b/common/src/main/java/net/cmr/jurassicrevived/item/ModCreativeTabs.java @@ -26,6 +26,7 @@ public class ModCreativeTabs { output.accept(ModItems.CRUSHED_FOSSIL.get()); output.accept(ModItems.MOSQUITO_IN_AMBER.get()); output.accept(ModItems.FROZEN_LEECH.get()); + output.accept(ModItems.FROZEN_BONE.get()); output.accept(ModItems.CABLE.get()); output.accept(ModItems.SCREEN.get()); output.accept(ModItems.PROCESSOR.get()); @@ -103,6 +104,7 @@ public class ModCreativeTabs { output.accept(ModBlocks.DEEPSLATE_FOSSIL.get()); output.accept(ModBlocks.AMBER_ORE.get()); output.accept(ModBlocks.DEEPSLATE_ICE_SHARD_ORE.get()); + output.accept(ModBlocks.PERMAFROST.get()); }); })); diff --git a/common/src/main/java/net/cmr/jurassicrevived/item/ModItems.java b/common/src/main/java/net/cmr/jurassicrevived/item/ModItems.java index 89805cc..80372af 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/item/ModItems.java +++ b/common/src/main/java/net/cmr/jurassicrevived/item/ModItems.java @@ -194,6 +194,7 @@ public class ModItems { public static final RegistrySupplier TEST_TUBE = ITEMS.register("test_tube", () -> new Item(new Item.Properties().stacksTo(16))); public static final RegistrySupplier SYRINGE = ITEMS.register("syringe", () -> new FrogSyringeItem(new Item.Properties().stacksTo(16))); public static final RegistrySupplier MOSQUITO_IN_AMBER = ITEMS.register("mosquito_in_amber", () -> new Item(new Item.Properties().stacksTo(16).rarity(Rarity.UNCOMMON))); + public static final RegistrySupplier FROZEN_BONE = ITEMS.register("frozen_bone", () -> new Item(new Item.Properties().stacksTo(16).rarity(Rarity.RARE))); public static final RegistrySupplier CRUSHED_FOSSIL = ITEMS.register("crushed_fossil", () -> new Item(new Item.Properties())); public static final RegistrySupplier FROZEN_LEECH = ITEMS.register("frozen_leech", () -> new Item(new Item.Properties().stacksTo(16).rarity(Rarity.RARE))); public static final RegistrySupplier CABLE = ITEMS.register("cable", () -> new Item(new Item.Properties().stacksTo(16))); diff --git a/common/src/main/java/net/cmr/jurassicrevived/worldgen/ModWorldgenDefinitions.java b/common/src/main/java/net/cmr/jurassicrevived/worldgen/ModWorldgenDefinitions.java index e8fe00c..7fb69fa 100644 --- a/common/src/main/java/net/cmr/jurassicrevived/worldgen/ModWorldgenDefinitions.java +++ b/common/src/main/java/net/cmr/jurassicrevived/worldgen/ModWorldgenDefinitions.java @@ -1,11 +1,16 @@ package net.cmr.jurassicrevived.worldgen; +import dev.architectury.registry.registries.RegistrySupplier; import net.cmr.jurassicrevived.Constants; import net.cmr.jurassicrevived.block.ModBlocks; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; +import net.minecraft.tags.BiomeTags; // <-- Add this import import net.minecraft.tags.BlockTags; import net.minecraft.tags.TagKey; +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.biome.Biome; // <-- Add this import import net.minecraft.world.level.block.Block; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; import net.minecraft.world.level.levelgen.placement.PlacedFeature; @@ -16,6 +21,8 @@ import java.util.function.Supplier; public final class ModWorldgenDefinitions { private ModWorldgenDefinitions() { } + public static final TagKey SNOWY_BIOMES = TagKey.create(Registries.BIOME, Constants.rl("is_snowy")); + public static final List ORES = List.of( new OreDefinition( @@ -25,7 +32,8 @@ public final class ModWorldgenDefinitions { 18, 20, 32, - 64 + 64, + BiomeTags.IS_OVERWORLD // <-- Add biome tag ), new OreDefinition( "stone_fossil", @@ -34,7 +42,8 @@ public final class ModWorldgenDefinitions { 8, 15, 0, - 64 + 64, + BiomeTags.IS_OVERWORLD ), new OreDefinition( "deepslate_fossil", @@ -43,7 +52,8 @@ public final class ModWorldgenDefinitions { 8, 15, -32, - 0 + 0, + BiomeTags.IS_OVERWORLD ), new OreDefinition( "amber_ore", @@ -52,7 +62,8 @@ public final class ModWorldgenDefinitions { 3, 4, 0, - 32 + 32, + BiomeTags.IS_OVERWORLD ), new OreDefinition( "deepslate_ice_shard_ore", @@ -61,7 +72,19 @@ public final class ModWorldgenDefinitions { 3, 6, -32, - 0 + 0, + BiomeTags.IS_OVERWORLD + ), + // Add your new Permafrost generation here! + new OreDefinition( + "permafrost", + ModBlocks.PERMAFROST, + BlockTags.DIRT, + 16, // Vein Size + 6, // Count + 60, // Min Y + 140,// Max Y + SNOWY_BIOMES ) ); @@ -72,7 +95,8 @@ public final class ModWorldgenDefinitions { int veinSize, int count, int minY, - int maxY + int maxY, + TagKey biomeTag // <-- Add this to the record ) { public ResourceKey> configuredFeatureKey() { return ResourceKey.create(Registries.CONFIGURED_FEATURE, Constants.rl(name)); @@ -82,4 +106,4 @@ public final class ModWorldgenDefinitions { return ResourceKey.create(Registries.PLACED_FEATURE, Constants.rl(name + "_placed")); } } -} +} \ No newline at end of file diff --git a/common/src/main/resources/assets/jurassicrevived/textures/block/deepslate_fossil.png b/common/src/main/resources/assets/jurassicrevived/textures/block/deepslate_fossil.png deleted file mode 100644 index 1557379b1caa3d2c0a9717a01d763b266ceff353..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 649 zcmV;40(Sk0P)|X|7lN3%%gave~5BW`m?`kX8;6 zZeXJyvnyk}wX3l1?1Q}N?(E$2ob&yj?>W!CB9%%dlgVfQJu53uBF3Iv0KtK)SPd5;z*>1I3l}hE&{JdpZ<#H7ondr>SLGjbay}YVE z3C>VwTni_Gn`h$QAKoA{=LxOgGei<5bQWCnZQ#(AY zAxGKi?5B;#s}OHz8+}~hXlaqySA`! zKNg$rERAj;5EvdAh5SX+*peNP>g(%eS6aaNb$m>~!W{x5l4>-5W;2;ZRh^DRUaYU< z*%&f7z99ObiADE*3i)@FlQ)%Mm|yEnHVc|Atl{%3fS|cYeIPNxSXg{^mOVVzHn%^A%-MT@}O715$Qm#ET;0P#Fvc?5kR< zsnK|{%mzxA))JQwtp?;xqfL9 zMUgVutVgfc^DZ1G*VortSzA*Q6umm{O=+~2F+ZhK<8)6t{l1n=ANu^eQGWI-^1 zL-5Rc1!+^wn~RuD%Zg96TGe#9EC(49wmHB$A)$K$Yj zjEg{7=Yl|4Q{{q!g=QmC$_`TLw6`CI&uwe?6e4c`_4W0)(xBx>g_ zPM8+znY1)poz=$1JNXcKOtfMmBBZPlK*#LjA|WT?y_}oV^6IL{&tCwUR_GnozRjF* zwXA1=GGx>j78cB$)4fdwLH`mV^GE+N;~nr&7+twi@jXYamV%(5rR5cS6QRz(|MdSq zOwQ2m)u<`vd>LD1qtLaSqJx$AIvpC9R@M>!dhG8PPvxC>$+ZY(=$IQ$PoJ3p@&9^m7C3W2~wI2_}coxLS~aIhB&;6fOXVxdq#U;i-5qw_kiV?tik>GSr;OW|$Bq@ieG}FAmy~RbzlNB2%@A~+-VwAzxa#>httS}5i zY19Rk&&A?*i8)lV;*2a7tH^7$E(;^dBdAuXRKTL+q{imX&Q941 zbFs}$(aV_IqNj0^jOE2vaumS^GErbm|?Zr*A6SZt(wjlSoK2!TGP)C!DO8RoX`EU>{AR4w`>q z0o2D?u;I>KPkXIeM+c^+#_%D%i;2lesdK1LntdWcpw*3U^Lo9Cg-iCXQsRTbAZoQ5 y_&qSkI(o|Z3jhHB|Bkq}Gynhq21!IgR09BAE{74Lr1^ya0000n& zv&v{Rk}BFJ!7-^)tD#&jW4qmAzuzLAwvb9D^&g2uLe3mjv30i1itEir96_@wf3`oFOfZ|zVHgHDu2M>>e{Q#Bbj3)LS@GC3 zc@?2(V?tuT+X;!I67;b;&x*5iJ{lR!3^CzRw@%Q{4(MYX?|*K8V|;%P#VqAYL*``% zxk3em>$)hGO7MMOL?oF7s85`XHpNzW;2snB9h2%;_h76!)CLC z;tr6oT84Q2YJ;^FlH&25sSC-pk;uwS#DaxF9+m1lh=^2|4$j9w65=~;BoLgPU2rc_ zmW4Nt^OS%(cz#i4XCRX>kOU$=XR~>DS`+8wM97SlO{5NX%7AGau&fMnxg6^Cx`5S4 z)=BW;1C(|f8S{62Hq)$07*qoM6N<$f+zth*Z=?k literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/block/permafrost_bottom.png b/common/src/main/resources/assets/jurassicrevived/textures/block/permafrost_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..dd79ad65dceeb6bcd8710f0a43656e4f4af66509 GIT binary patch literal 410 zcmV;L0cHM)P)l!Zz3k8?h7ul13zmAUVIuV1jqNn|t%- z?ac0S?fSlhn}=?TtGhJ?ZfD)&b0=1*^wx#}@%OA&9s2dt9gX8`5{r*meiEW|ta)L4 zAner9Xdr)j`RCr>8)(#6L7VkAPlCIYOg1ko5fyU+x5R3>8eR$l)u^_lQ7-7IODR8jhw(yg<6yH<|S(Ey0|BY@w&+S%moSz&LEnmjFgDm z0?gmSeu#}j88kBrQ7&>9mw-SO?AS@%y|E=)gXG_u zpJCoH0t&Thy!Zb_#4i8<0RR8VeYK+i000I_L_t&o01r*fYb$I;IRF3v07*qoM6N<$ Eg0Qo+UYoZp>e+MbnV5a81K(g7qe3uBRaK8u%v|JtX?(Lm}Z~Z`MN)^pJrM zhCKwDVrYUmXS(K=j<&YlZL}Y5^RCU?=T7L$;ltr`KIe1J`7%$SfY|kgqOlZkeLK3k z`Fm|Eiij(zn36dR{zM7{tFtEahP|k^leFxn zEa0j7SQY84MM@Mzu)d^(5CjhVfkK{`ghVZAAZrZVK|*6rYo?)&_9LZOyZ{zuvzarS z=;)XNXbZhBW{8LyYo2KBR{ z7A~^1I5mhI-mc4_i2*pC8XZIS8*-a#`2XH-N1dpxt*&hN!nGzkCs81(dx4~Ax~8j@ z`a3l=V;`6y5qq8jm*!`sTVwbD)ToZZ}=C6aE0Cty>;{cWCP$ zYjMe*Ag%q-?a;=W8i4v{7#-f6^Un-+SP3Mq#N7>@GRnoWt_Iqz9K)c`^Y5FT_d-f$ zXY(7{a1w?<*YS65z_NskMV>=H0;GP!#V)zEqZgTH`6D(4i@=8(%&q`@E%(LVqH o0RR8&SjcGr000I_L_t&o0BBw!0}yGTq5uE@07*qoM6N<$f)L11_5c6? literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/block/permafrost_top.png b/common/src/main/resources/assets/jurassicrevived/textures/block/permafrost_top.png new file mode 100644 index 0000000000000000000000000000000000000000..dce1e3755fa6cb30cdead68adfba6f426ed59e3a GIT binary patch literal 310 zcmV-60m=S}P)5y*w5QOhPQJ8|7M5QuXIR|E(c?FePQ!GjB;G2{cv6spvck_+6bSw)rF zM12^or3};5F{64+?b2RV+E`FahEW*R)~ZA$%@4}sm?47c4QOMgIFOZ>K2K}F zgdJVbQ05&3Kn-(T0_H#*yFUN`0RR8h62@Hs000I_L_t&o0GD$3XkLtrk^lez07*qo IM6N<$f{SB<6951J literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/block/stone_fossil.png b/common/src/main/resources/assets/jurassicrevived/textures/block/stone_fossil.png deleted file mode 100644 index b9fde77c05471c5ec49c942e946de4d013dc4c48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 522 zcmV+l0`>igP)9!mWio&!^KL7Z=|hZf}35 z>ECL#TB%g{Mx((mm&+{6ilUI@gU@EO+24ORnM_uzRg%0%yT1MnBaqPN%~k9es=$%#)MP1n2XgILfo&KNt+Q zvCz5K>+uBf(VEQ`HGS6W^-@83*Mev?^D~JtjOo{X!p~tfG9L=T86t0RR8|kmZ^H000I_L_t&o05dFS{fry%WB>pF M07*qoM6N<$f`6~|NdN!< diff --git a/common/src/main/resources/assets/jurassicrevived/textures/block/stone_fossil_egg.png b/common/src/main/resources/assets/jurassicrevived/textures/block/stone_fossil_egg.png new file mode 100644 index 0000000000000000000000000000000000000000..c9c209d25639fa6a06f31745d6610158a240090e GIT binary patch literal 599 zcmV-d0;v6oP)P=d5QNJQki(A*fdnKIqu5zMBpkk?cd1mj)(*=hr{8i3AwnK`043~=JVf%mzQT~*3=rHLWAS+s8Xq< zcDrpaQGWjQQy|=i0x%bgrK!`{aUnUKPL)olRjbv+I^V-nVRGZDFCCNdi7;-L?p^t*MH@S-oYqZ<#1kWbGL@G!C$c#yGsq|i}%|`pfL5d=a zS(SQt<^gM9*myiXjZZ-$kNG2@RDY<%H48Fgwn?$5Wkw))9Ly0JSZLF5F;g&-;g?wHV z^Slc~iy;=hk>LB|qYwnFu9@00006Nklk}@P)!MQB{ybl+PC;A2vdJsZ>f-0p^hjU;<@kj}p#l4|0fT zk2>{$WZZRKSLL%(z^x=1B@mHId$HIRDPq~St)^ij4o|1k=y`s$N6w52Zia}J%4+o? z$_qv3fLj20#&r5x3WYnNklA2H%sJR)KxQFbqF=xNtghS93?P$YW`h}tj`al~B4~{u z&q6i{NHP*>1H(AOEY2~G6$Q)%x6|UEiLgy3W0}uqI#Bg`U8j(_pb$dTq6}5+QDMOd z(|Y|W#bQZvxx5b5U@*|3qL@8|D1wMK6N!YHuO`AoA+nZBS12&;fF+X&cob)}xsU+V z7Dyrhj2E;-fHj*>`YMnb6IqF000030|CaxWZU6uP21!IgR09C4a(C@mZvYtp0000< KMNUMnLSTY1ZS}zb literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/block/stone_fossil_skull.png b/common/src/main/resources/assets/jurassicrevived/textures/block/stone_fossil_skull.png new file mode 100644 index 0000000000000000000000000000000000000000..e612527dcb84ce078819cb14f97f068acc7130d2 GIT binary patch literal 614 zcmV-s0-61ZP)$^xvg z!TX!!OCUM-n>%;ToSC^7uiNeJx_jt!I=gneZSd_@t7Uuq`1au~mrE@jX0w@n*Xy;y z;jlsOhyC>QSC5YqjYcDV9}Y!~JF>6m8>`hy^ZDEY@9utRAJ5PK1nTv=@`ZxN4-Xm) z1}0(&P$?FRLWzU~`?$IJs#>jPY9u{MCY3uqwLO)1EQv%yx3}Nmno=YbQYv+%YPG8A zWMY1QA=bCUu2qi(GK!o38#}8wMGX4>{b#11_xDzAI{jYb@z^S*9g=zU4H?D2y8t{J z6h0Dy)ys>OOpAasgc-igfHrUvOa`AYUn~SThrk(e?EC#bTY1rFREZ&} zmpVH;F+X;-Qn6qJn2(=~L|(`ZZ1ei6Y&NTliz^!@lg{TqYUu7fnM!Hl-T_3a@v9># ziEIWCdcB_AJt|xmGYTIL4-ge%GqwWHWx3G$*>m(^hY2Be~-@s+(OAzf%=Ji z3%OiQHbicM$H8NAaUuzU5P)x&+++J(E^Ft4;PCuC?h@kR!GUv2g?wJ0&d>Gb`dZ~u z$pDExvFYPui;F}evI@9MG93m2q8&>6;078D1{IIT4Y62E_?Q(W1o@K5V_`S|+Xo2& zB>q6CbLI>31#bWV0RR8p)!G&S000I_L_t&o0CzTQ?RTHh2LJ#707*qoM6N<$f>tFL AdjJ3c literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/entity/allosaurus_al.png b/common/src/main/resources/assets/jurassicrevived/textures/entity/allosaurus_al.png new file mode 100644 index 0000000000000000000000000000000000000000..5e8092bd196681da04533bb89dd0a5bf78f9345b GIT binary patch literal 57938 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 literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/entity/ankylosaurus_bumpy.png b/common/src/main/resources/assets/jurassicrevived/textures/entity/ankylosaurus_bumpy.png new file mode 100644 index 0000000000000000000000000000000000000000..76c9b3be6ee00c541499cadc0f9b489ea960f7cb GIT binary patch literal 83155 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 literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/entity/dilophosaurus_inferno.png b/common/src/main/resources/assets/jurassicrevived/textures/entity/dilophosaurus_inferno.png new file mode 100644 index 0000000000000000000000000000000000000000..3e434355e3700314dbe449f6d2f95597511088d2 GIT binary patch literal 119759 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 J$=}m{{XfSJAHx6u literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/entity/tyrannosaurus_rex_drgray.png b/common/src/main/resources/assets/jurassicrevived/textures/entity/tyrannosaurus_rex_drgray.png new file mode 100644 index 0000000000000000000000000000000000000000..c861a618bccf56ab58fd7b1546d36c972d25d1ac GIT binary patch literal 138148 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�z3B*MS+YFfUTQ$s5pGH};ClY3Oj zyx`5oiaY4H?f%p6x_XA~6K>QPNGI+nAC9t9mC>iLGdhRu?%Yjaml)SYc6M})oP3uT zyrY}D=$(;qRvu$)l3%jNF^xq-A)o%TWf0`SCW6v$;!LZ{*Qo07|4pk-{Wpwlt& zE(3owk}3mqkMCK(Jce7>-K|cQr623LK-%fA#(eX}910Mz-1O~yYn6%o?xf^yZ&TA( zwr>fMP*rmcaur;p3y8_PsKJ>&M_nriN0-<{$vt&W@9t|XStu5V%uoBZP%Qm}VvAmD zgvR1i#V}yu-6faQv6_JFfE99uGGxYq6a~skDp5 zYA7P|MsbVx-MV(H)oAxv@J;%3+U*0F?e_*)*gvsRtR80>A7VC#Az&kIwX-e4*33eg zt3GX<9mnM&Iz+CLOTf%qp{!Nw-CXr4yM}~Kjg2>PqombD{Vx@&jcN?;MVNu_&f4gj5#H_=kVR_ zO_K>4GALks`I{(n8Wg;e-+kkS`yV_0y7|kV^J8w5`mXfkx(HlKiorI*?lM}QH&n@f zTTMJw8=+4bMfvBKZ~RC^bE_LbEig#38@QEFo0<3Uy((=amdnD0DLO;-%M$QG`2?vn zzR%d1lYZX%cX_%B=;To)z-i2};~?8e(=0#_Rbab2Gm_anMSmQj;Vf~ZV8je`Beg9+ zf9# znxKGB)Tj}37nuXAh__|&8;G~n>l~0ix~n+}1Zp}2X8EM^9X7kBq!O^JJSV^Us}Hw0 zDstjRnHsPSL)eCiQ_;JTj19N-|M}yIVUiN-x$c2ai@klXTMeXUaeUn8%}Cj2je2lc z?fWIdnn591-Le6y|L?nEO3;AD6aDw#m&l zEM~~Cm{sGeAVz%l_`HH)?MBrL#&O6yNydR zIDUxo5S8)PAm3fr`sw#eApxEK4bAY;F+yr`a;HsI6^-wc-<-0Ib`o;hBK%7LrDfiW zmEA(D)x3R}qVXUhp{8Wd#}#r=Pv&>#?<3I1Q7juRzq_N3qoL&&i_$GKAR zO+6i*!@=mDYRD{?BS600RnX9Q*Sv)$nAS{<^R=3UOfEsGZBvJrn~Ub;SXFU;ze0NiR>qM#8$(R0 zv5Lkxu`EZ|((yG|8ApCq2l-WvZywzti(?M$@o+NKt&NS4 zAK$@EYDDSx_wMV7>()_z`?1tmM58)PNv;dS>do zd}ThQ<>)8ipQ#gBJ2pY1wfQD4vh;aF@R8T$lRr}^{M@I{*Apqoe!S^17x~in=fKNM zQ0YE+Hx&b>nTS%b_ujFMZQYI=g1Agmm2IUwPX{@|mxtku-%^1I(i4S8NW0Rjrj zX?X=(h_4|_6!Xe8AUSD6L^0X!j?Mu?S7+zFG#5A5!;~XTfm2G>Xq|T;5Ls4Mtx>YM z7YOdc%;_RMh)Byf5usX|0sRl1czJ*Cqe^!i223(`ZEQ~}9kWhq2)^)uk*TRE$9#al z4k#L&d!`S;HHqhP&pvenzO?7{4ajh5Swt!8Q+gXzGJ=MObqFna!Tt7r{GgGEs>nc% zof#*FdGdr<8+#ikLTO`*nKMyHGoX>a@#QXVf0#GSgUy_9%FWh%Q=cyw$$!V;R?^;3Kt6etp_H8eDSlPewUD2^3G${bi%9Qj06XCrZoSJC(61ma}LoxV6@3mc1D zxbntB6b)gfA9&PLwOa}BLt}u&-NJHXxz#ldAISL;t4>-YQW99<6~Wv<4}1yO zkasLRBmEYS{W#LbKvW_N)bk-=v{9>BD(5TdWZEeK$dyIDNVcaR%YeB?)Ek&XyAqIg zU1>4Ic%T*FpG z4w|e1&patVQ1E$!p+E2X)#x>p`8y7g?zsTaEg$ZJYU^R3%vb^Yz^H9K1VLeBJG+k4 zqz0`(D^iji&=#QP+2gkw6=2Km*!y*hP$oYJZ(oXXoJlbP+Ow7eU`Z_;iET)ZGP58; zicL6`(K|4MYDXzud#$D(pB^0=mHp0uY?tCIpqJ5nm>K0iRN1%=57@K{;&O@+W<;5v z4c}e6)i&~|yzk(JX7EDy!n5Ru0CvWxEK^nLII%0Dv4 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

`SZghaAK=9J4S1<@!TXK7{hl7uw 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 mo_nvV|8Efa|K1XtTvaKguUMy@>$2s3K?z!jQ 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%0ALrzB7w730C3 z_EnJiyh_k>x@EfZg|||FJNm{qxui6H;pj0-O&5c2m0U**H=Pn~Bv>$A!)(0(*SL0Tq|N&;EDs$2QQ}2Eg0MeL|i{mB-vOZ^pZtWMlnV$9g!}a2Ae2#HVTw>2| z@Y3hk^T~M@QGrtF*0befJf3~ud$2us)|VfbH#+%!|5vub*1}7Tb#2KlHsHX| zuiG+n#g+$C=Ws|NapWw{^xl(nvaW-kep~ikc7-(&6HU8K^0Bf(oX*CfZ`nq z6CDR!;r^(D<9o~6L9kjN6cTzZlv=%d?SB|G8grw~F9D6Uz6nmrU3*!4oOy*c4j8$< zwNtY^GB?TXZp7~PGR&BxGcW=Gi&^8K%H@GZg3(h+iQ-oWUw#NI{1m9Gk@)oP4f5AA z7#qp53dR5!J)#=L8hJu-qNVJM3**x$OiW|+`7F8*$Kf!%BI*n%Zrs_4)!!1$^{Va= zaAKd!U}S6ZJ=&9TG)LnIH$?Gz)=gjOVf5x~NijDkO$VtCiIzGCbBhiZmINr?6KkVc zgT3*Z$O9vwn!yD}v+_&e new FabricTransferHelper.InternalFluidStorage(((TankBlockEntity) be).getFluidHandler(side)), ModBlockEntities.TANK_BE.get() diff --git a/fabricmc/src/main/java/net/cmr/jurassicrevived/datagen/FabricBlockLootTableProvider.java b/fabricmc/src/main/java/net/cmr/jurassicrevived/datagen/FabricBlockLootTableProvider.java index b2bf542..271b767 100644 --- a/fabricmc/src/main/java/net/cmr/jurassicrevived/datagen/FabricBlockLootTableProvider.java +++ b/fabricmc/src/main/java/net/cmr/jurassicrevived/datagen/FabricBlockLootTableProvider.java @@ -9,9 +9,11 @@ import net.minecraft.world.item.enchantment.Enchantment; import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.entries.AlternativesEntry; import net.minecraft.world.level.storage.loot.entries.LootItem; import net.minecraft.world.level.storage.loot.functions.ApplyBonusCount; import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction; +import net.minecraft.world.level.storage.loot.predicates.LootItemRandomChanceCondition; import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; import java.util.concurrent.CompletableFuture; @@ -59,6 +61,20 @@ public class FabricBlockLootTableProvider extends net.fabricmc.fabric.api.datage //?} } + @Override + public LootTable.Builder createRandomOreDrops(Block block, Item silkTouchDrop, Item firstDrop, Item secondDrop, float minRolls, float maxRolls, double firstDropChance) { + return this.createSilkTouchDispatchTable(block, + AlternativesEntry.alternatives( + this.applyExplosionDecay(block, + LootItem.lootTableItem(firstDrop) + .when(LootItemRandomChanceCondition.randomChance((float) firstDropChance)) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(minRolls, maxRolls)))), + this.applyExplosionDecay(block, + LootItem.lootTableItem(secondDrop) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(minRolls, maxRolls)))) + )); + } + @Override public LootTable.Builder createPotFlowerItemTable(Block block) { return super.createPotFlowerItemTable(block); diff --git a/fabricmc/src/main/java/net/cmr/jurassicrevived/datagen/FabricModModelProvider.java b/fabricmc/src/main/java/net/cmr/jurassicrevived/datagen/FabricModModelProvider.java index d48c542..a4a1d0d 100755 --- a/fabricmc/src/main/java/net/cmr/jurassicrevived/datagen/FabricModModelProvider.java +++ b/fabricmc/src/main/java/net/cmr/jurassicrevived/datagen/FabricModModelProvider.java @@ -148,6 +148,57 @@ public class FabricModModelProvider extends FabricModelProvider implements ModBl } } + @Override + public void blockWithItem(Block block, ResourceLocation sideTexture, ResourceLocation bottomTexture, ResourceLocation topTexture) { + if (isGeneratingBlocks()) { + TextureMapping mapping = new TextureMapping() + .put(TextureSlot.SIDE, sideTexture) + .put(TextureSlot.BOTTOM, bottomTexture) + .put(TextureSlot.TOP, topTexture); + ResourceLocation modelLocation = ModelTemplates.CUBE_BOTTOM_TOP.create(block, mapping, blockStateGenerator.modelOutput); + blockStateGenerator.blockStateOutput.accept(BlockModelGenerators.createSimpleBlock(block, modelLocation)); + } + if (isGeneratingItems()) { + generateBlockItemModel(block); + } + } + + @Override + public void randomTextureBlockWithItem(Block block, List textures) { + if (textures.isEmpty()) { + throw new IllegalArgumentException("randomTextureBlockWithItem requires at least one texture"); + } + + ResourceLocation baseModel = null; + + if (isGeneratingBlocks()) { + Variant[] variants = new Variant[textures.size()]; + + for (int i = 0; i < textures.size(); i++) { + TextureMapping mapping = new TextureMapping().put(TextureSlot.ALL, textures.get(i)); + ResourceLocation model = ModelTemplates.CUBE_ALL.createWithSuffix(block, "_" + i, mapping, blockStateGenerator.modelOutput); + + if (i == 0) { + baseModel = model; + } + + variants[i] = Variant.variant() + .with(VariantProperties.MODEL, model); + } + + blockStateGenerator.blockStateOutput.accept(MultiVariantGenerator.multiVariant(block, variants)); + } + + if (isGeneratingItems()) { + ResourceLocation itemParent = baseModel != null ? baseModel : ModelLocationUtils.getModelLocation(block, "_0"); + itemModelGenerator.output.accept(ModelLocationUtils.getModelLocation(block.asItem()), () -> { + JsonObject json = new JsonObject(); + json.addProperty("parent", itemParent.toString()); + return json; + }); + } + } + private PropertyDispatch createRotatedHorizontalFacingDispatch() { return PropertyDispatch.property(BlockStateProperties.HORIZONTAL_FACING) .select(Direction.NORTH, Variant.variant().with(VariantProperties.Y_ROT, VariantProperties.Rotation.R180)) diff --git a/gradle.properties b/gradle.properties index b019620..293d22c 100755 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ fabric.loom.multiProjectOptimisation=true mod.name=Jurassic Revived mod.id=jurassicrevived mod.group=net.cmr.jurassicrevived -mod.version=0.218.0 +mod.version=0.222.0 mod.author=CMR Team, Eli Gibbs mod.description=A Minecraft mod that brings dinosaurs back to life using ancient DNA and modern technology\nBreed, study, and build your own prehistoric park with a wide variety of creatures... mod.license=CC-BY-ND-4.0 diff --git a/message.txt b/message.txt new file mode 100644 index 0000000..15b4659 --- /dev/null +++ b/message.txt @@ -0,0 +1,92 @@ +Achillobator – 28800 ticks + Albertosaurus – 67200 ticks + Alligator Gar – 33600 ticks + Allosaurus – 52800 ticks + Alvarezsaurus – 19200 ticks + Ankylosaurus – 86400 ticks + Apatosaurus – 110400 ticks + Arambourgiania – 43200 ticks + Argentavis – 48000 ticks + Baryonyx – 52800 ticks + Beelzebufo – 14400 ticks + Brachiosaurus – 134400 ticks + Carcharodontosaurus – 72000 ticks + Carnotaurus – 43200 ticks + Cearadactylus – 28800 ticks + Ceratosaurus – 38400 ticks + Chasmosaurus – 67200 ticks + Chilesaurus – 38400 ticks + Coelacanth – 38400 ticks + Coelophysis – 19200 ticks + Coelurus – 24000 ticks + Compsognathus – 14400 ticks + Concavenator – 43200 ticks + Corythosaurus – 52800 ticks + Crassigyrinus – 24000 ticks + Deinonychus – 33600 ticks + Dilophosaurus – 33600 ticks + Dimorphodon – 19200 ticks + Diplocaulus – 19200 ticks + Diplodocus – 110400 ticks + Distortus Rex – 62400 ticks + Dodo – 24000 ticks + Dryosaurus – 28800 ticks + Edmontosaurus – 67200 ticks + Gallimimus – 33600 ticks + Geosternbergia – 28800 ticks + Giant Moa – 57600 ticks + Giganotosuarus – 81600 ticks + Guanlong – 33600 ticks + Guidraco – 28800 ticks + Haast Eagle – 43200 ticks + Hadrosaurus – 52800 ticks + Herrerasaurus – 28800 ticks + Hypsilophodon – 24000 ticks + Ichthyornis – 19200 ticks + Indominus Rex – 50400 ticks + Indoraptor – 24000 ticks + Inostrancevia – 33600 ticks + Lambeosaurus – 52800 ticks + Ludodactylus – 24000 ticks + Majungasaurus – 43200 ticks + Mamenchisaurus – 134400 ticks + Mawsonia – 43200 ticks + Metriacanthosaurus – 52800 ticks + Moganopterus – 33600 ticks + Mussaurus – 62400 ticks + Nyctosaurus – 24000 ticks + Ornitholestes – 24000 ticks + Ornithomimus – 33600 ticks + Ouranosaurus – 52800 ticks + Oviraptor – 28800 ticks + Pachycephalosaurus – 52800 ticks + Parasaurolophus – 57600 ticks + Pelagornis – 33600 ticks + Proceratosaurus – 33600 ticks + Procompsognathus – 14400 ticks + Protoceratops – 43200 ticks + Pteranodon – 28800 ticks + Pterodaustro – 19200 ticks + Quetzalcoatlus – 43200 ticks + Rajasaurus – 43200 ticks + Rugops – 38400 ticks + Segisaurus – 19200 ticks + Shantungosaurus – 81600 ticks + Spinosaurus – 86400 ticks + Stegosaurus – 52800 ticks + Styracosaurus – 67200 ticks + Suchomimus – 72000 ticks + Tapejara – 24000 ticks + Theriznosarus – 76800 ticks + Thescelosaurus – 43200 ticks + Titanosaurus – 129600 ticks + Triceratops – 91200 ticks + Troodon – 24000 ticks + Tropeognathus – 28800 ticks + Tupuxuara – 28800 ticks + Tyrannosaurus Rex – 91200 ticks + Utahraptor – 43200 ticks + Velociraptor – 28800 ticks + Zhenyuanopterus – 28800 ticks + Fduck - 28800 ticks + Chickenosaurus - 28800 ticks \ No newline at end of file diff --git a/minecraftforge/src/main/java/net/cmr/jurassicrevived/datagen/ForgeBlockLootTableProvider.java b/minecraftforge/src/main/java/net/cmr/jurassicrevived/datagen/ForgeBlockLootTableProvider.java index 5ed93ea..1001b6a 100755 --- a/minecraftforge/src/main/java/net/cmr/jurassicrevived/datagen/ForgeBlockLootTableProvider.java +++ b/minecraftforge/src/main/java/net/cmr/jurassicrevived/datagen/ForgeBlockLootTableProvider.java @@ -8,9 +8,11 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.entries.AlternativesEntry; import net.minecraft.world.level.storage.loot.entries.LootItem; import net.minecraft.world.level.storage.loot.functions.ApplyBonusCount; import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction; +import net.minecraft.world.level.storage.loot.predicates.LootItemRandomChanceCondition; import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; import java.util.Set; @@ -44,6 +46,20 @@ public class ForgeBlockLootTableProvider extends BlockLootSubProvider implements .apply(ApplyBonusCount.addOreBonusCount(Enchantments.BLOCK_FORTUNE)))); } + @Override + public LootTable.Builder createRandomOreDrops(Block block, Item silkTouchDrop, Item firstDrop, Item secondDrop, float minRolls, float maxRolls, double firstDropChance) { + return this.createSilkTouchDispatchTable(block, + AlternativesEntry.alternatives( + this.applyExplosionDecay(block, + LootItem.lootTableItem(firstDrop) + .when(LootItemRandomChanceCondition.randomChance((float) firstDropChance)) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(minRolls, maxRolls)))), + this.applyExplosionDecay(block, + LootItem.lootTableItem(secondDrop) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(minRolls, maxRolls)))) + )); + } + @Override public LootTable.Builder createPotFlowerItemTable(Block block) { return super.createPotFlowerItemTable(block); diff --git a/minecraftforge/src/main/java/net/cmr/jurassicrevived/datagen/ForgeBlockStateProvider.java b/minecraftforge/src/main/java/net/cmr/jurassicrevived/datagen/ForgeBlockStateProvider.java index cc636a3..8cbd9c7 100755 --- a/minecraftforge/src/main/java/net/cmr/jurassicrevived/datagen/ForgeBlockStateProvider.java +++ b/minecraftforge/src/main/java/net/cmr/jurassicrevived/datagen/ForgeBlockStateProvider.java @@ -13,10 +13,13 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BooleanProperty; import net.minecraft.world.level.block.state.properties.EnumProperty; import net.minecraftforge.client.model.generators.BlockStateProvider; +import net.minecraftforge.client.model.generators.ConfiguredModel; import net.minecraftforge.client.model.generators.ModelFile; import net.minecraftforge.client.model.generators.MultiPartBlockStateBuilder; import net.minecraftforge.common.data.ExistingFileHelper; +import java.util.List; + public class ForgeBlockStateProvider extends BlockStateProvider implements ModBlockStateProvider.BlockStateHelper { public ForgeBlockStateProvider(PackOutput output, ExistingFileHelper exFileHelper) { @@ -65,6 +68,34 @@ public class ForgeBlockStateProvider extends BlockStateProvider implements ModBl super.simpleBlockWithItem(block, models().cubeAll(name(block), blockTexture(block))); } + @Override + public void blockWithItem(Block block, ResourceLocation sideTexture, ResourceLocation bottomTexture, ResourceLocation topTexture) { + super.simpleBlockWithItem(block, models().cubeBottomTop(name(block), sideTexture, bottomTexture, topTexture)); + } + + @Override + public void randomTextureBlockWithItem(Block block, List textures) { + if (textures.isEmpty()) { + throw new IllegalArgumentException("randomTextureBlockWithItem requires at least one texture"); + } + + ConfiguredModel[] configuredModels = new ConfiguredModel[textures.size()]; + + for (int i = 0; i < textures.size(); i++) { + ModelFile model = models().cubeAll(name(block) + "_" + i, textures.get(i)); + configuredModels[i] = ConfiguredModel.builder() + .modelFile(model) + .weight(1) + .buildLast(); + } + + getVariantBuilder(block) + .partialState() + .setModels(configuredModels); + + simpleBlockItem(block, models().cubeAll(name(block) + "_0", textures.get(0))); + } + @Override public void horizontalFacingWithItem(Block block) { ModelFile model = new ModelFile.UncheckedModelFile(modLoc("block/" + name(block))); diff --git a/neoforge/src/main/java/net/cmr/jurassicrevived/datagen/NeoForgeBlockLootTableProvider.java b/neoforge/src/main/java/net/cmr/jurassicrevived/datagen/NeoForgeBlockLootTableProvider.java index 9abf02e..1e953d4 100755 --- a/neoforge/src/main/java/net/cmr/jurassicrevived/datagen/NeoForgeBlockLootTableProvider.java +++ b/neoforge/src/main/java/net/cmr/jurassicrevived/datagen/NeoForgeBlockLootTableProvider.java @@ -10,9 +10,11 @@ import net.minecraft.world.item.enchantment.Enchantment; import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.entries.AlternativesEntry; import net.minecraft.world.level.storage.loot.entries.LootItem; import net.minecraft.world.level.storage.loot.functions.ApplyBonusCount; import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction; +import net.minecraft.world.level.storage.loot.predicates.LootItemRandomChanceCondition; import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; import java.util.Set; @@ -47,6 +49,20 @@ public class NeoForgeBlockLootTableProvider extends BlockLootSubProvider impleme .apply(ApplyBonusCount.addOreBonusCount(registrylookup.getOrThrow(Enchantments.FORTUNE))))); } + @Override + public LootTable.Builder createRandomOreDrops(Block block, Item silkTouchDrop, Item firstDrop, Item secondDrop, float minRolls, float maxRolls, double firstDropChance) { + return this.createSilkTouchDispatchTable(block, + AlternativesEntry.alternatives( + this.applyExplosionDecay(block, + LootItem.lootTableItem(firstDrop) + .when(LootItemRandomChanceCondition.randomChance((float) firstDropChance)) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(minRolls, maxRolls)))), + this.applyExplosionDecay(block, + LootItem.lootTableItem(secondDrop) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(minRolls, maxRolls)))) + )); + } + @Override public LootTable.Builder createPotFlowerItemTable(Block block) { return super.createPotFlowerItemTable(block); diff --git a/neoforge/src/main/java/net/cmr/jurassicrevived/datagen/NeoForgeBlockStateProvider.java b/neoforge/src/main/java/net/cmr/jurassicrevived/datagen/NeoForgeBlockStateProvider.java index bdf209d..23a1e7a 100755 --- a/neoforge/src/main/java/net/cmr/jurassicrevived/datagen/NeoForgeBlockStateProvider.java +++ b/neoforge/src/main/java/net/cmr/jurassicrevived/datagen/NeoForgeBlockStateProvider.java @@ -13,10 +13,13 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BooleanProperty; import net.minecraft.world.level.block.state.properties.EnumProperty; import net.neoforged.neoforge.client.model.generators.BlockStateProvider; +import net.neoforged.neoforge.client.model.generators.ConfiguredModel; import net.neoforged.neoforge.client.model.generators.ModelFile; import net.neoforged.neoforge.client.model.generators.MultiPartBlockStateBuilder; import net.neoforged.neoforge.common.data.ExistingFileHelper; +import java.util.List; + public class NeoForgeBlockStateProvider extends BlockStateProvider implements ModBlockStateProvider.BlockStateHelper { public NeoForgeBlockStateProvider(PackOutput output, ExistingFileHelper exFileHelper) { @@ -65,6 +68,34 @@ public class NeoForgeBlockStateProvider extends BlockStateProvider implements Mo super.simpleBlockWithItem(block, models().cubeAll(name(block), blockTexture(block))); } + @Override + public void blockWithItem(Block block, ResourceLocation sideTexture, ResourceLocation bottomTexture, ResourceLocation topTexture) { + super.simpleBlockWithItem(block, models().cubeBottomTop(name(block), sideTexture, bottomTexture, topTexture)); + } + + @Override + public void randomTextureBlockWithItem(Block block, List textures) { + if (textures.isEmpty()) { + throw new IllegalArgumentException("randomTextureBlockWithItem requires at least one texture"); + } + + ConfiguredModel[] configuredModels = new ConfiguredModel[textures.size()]; + + for (int i = 0; i < textures.size(); i++) { + ModelFile model = models().cubeAll(name(block) + "_" + i, textures.get(i)); + configuredModels[i] = ConfiguredModel.builder() + .modelFile(model) + .weight(1) + .buildLast(); + } + + getVariantBuilder(block) + .partialState() + .setModels(configuredModels); + + simpleBlockItem(block, models().cubeAll(name(block) + "_0", textures.get(0))); + } + @Override public void horizontalFacingWithItem(Block block) { ModelFile model = new ModelFile.UncheckedModelFile(modLoc("block/" + name(block)));

`CBlHf;SsEz6j2 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 literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/jurassicrevived/textures/entity/velociraptor_charlie.png b/common/src/main/resources/assets/jurassicrevived/textures/entity/velociraptor_charlie.png new file mode 100644 index 0000000000000000000000000000000000000000..b11e8680a3b6fd751d67d2bb026961c58c84a3e0 GIT binary patch literal 28013 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