diff --git a/src/main/java/ovh/glitchlabs/masterwild/Block/ModBlocks.java b/src/main/java/ovh/glitchlabs/masterwild/Block/ModBlocks.java new file mode 100644 index 0000000..da9bb5f --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/Block/ModBlocks.java @@ -0,0 +1,34 @@ +package ovh.glitchlabs.masterwild.Block; + +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredBlock; +import net.neoforged.neoforge.registries.DeferredRegister; +import ovh.glitchlabs.masterwild.Item.ModItems; +import ovh.glitchlabs.masterwild.Masterwild; + +import java.util.function.Supplier; + +public class ModBlocks { + public static final DeferredRegister.Blocks BLOCKS = + DeferredRegister.createBlocks(Masterwild.MODID); + + + + + private static DeferredBlock registerBlock(String name, Supplier block) { + DeferredBlock toReturn = BLOCKS.register(name, block); + registerBlockItem(name, toReturn); + return toReturn; + } + + private static void registerBlockItem(String name, DeferredBlock block) { + ModItems.ITEMS.register(name, () -> new BlockItem(block.get(), new Item.Properties())); + } + + public static void register(IEventBus eventBus) { + BLOCKS.register(eventBus); + } +} diff --git a/src/main/java/ovh/glitchlabs/masterwild/Item/ModItems.java b/src/main/java/ovh/glitchlabs/masterwild/Item/ModItems.java new file mode 100644 index 0000000..f6f84fe --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/Item/ModItems.java @@ -0,0 +1,30 @@ +package ovh.glitchlabs.masterwild.Item; + +import net.minecraft.world.item.Item; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.common.DeferredSpawnEggItem; +import net.neoforged.neoforge.registries.DeferredItem; +import net.neoforged.neoforge.registries.DeferredRegister; +import ovh.glitchlabs.masterwild.Masterwild; +import ovh.glitchlabs.masterwild.entity.ModEntities; + +public class ModItems { + public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(Masterwild.MODID); + + + + //SpawnEggs + public static final DeferredItem PINGUIN_SPAWN_EGG = ITEMS.register("pinguin_spawn_egg", + () -> new DeferredSpawnEggItem(ModEntities.PINGUIN, 0x31afaf, 0xffac00, + new Item.Properties())); + public static final DeferredItem FIREFLY_SPAWN_EGG = ITEMS.register("firefly_spawn_egg", + () -> new DeferredSpawnEggItem(ModEntities.FIREFLY, 0x31afaf, 0xffac00, + new Item.Properties())); + public static final DeferredItem ROOSTER_SPAWN_EGG = ITEMS.register("rooster_spawn_egg", + () -> new DeferredSpawnEggItem(ModEntities.ROOSTER, 0x31afaf, 0xffac00, + new Item.Properties())); + + public static void register(IEventBus eventBus) { + ITEMS.register(eventBus); + } +} diff --git a/src/main/java/ovh/glitchlabs/masterwild/Masterwild.java b/src/main/java/ovh/glitchlabs/masterwild/Masterwild.java index 2f4be95..2fc1865 100644 --- a/src/main/java/ovh/glitchlabs/masterwild/Masterwild.java +++ b/src/main/java/ovh/glitchlabs/masterwild/Masterwild.java @@ -1,19 +1,7 @@ package ovh.glitchlabs.masterwild; import com.mojang.logging.LogUtils; -import net.minecraft.client.Minecraft; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.chat.Component; -import net.minecraft.world.food.FoodProperties; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.CreativeModeTabs; -import net.minecraft.world.item.Item; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.material.MapColor; +import net.minecraft.client.renderer.entity.EntityRenderers; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.SubscribeEvent; @@ -24,40 +12,22 @@ import net.neoforged.fml.config.ModConfig; import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; import net.neoforged.neoforge.event.server.ServerStartingEvent; -import net.neoforged.neoforge.registries.DeferredBlock; -import net.neoforged.neoforge.registries.DeferredHolder; -import net.neoforged.neoforge.registries.DeferredItem; -import net.neoforged.neoforge.registries.DeferredRegister; import org.slf4j.Logger; +import ovh.glitchlabs.masterwild.Block.ModBlocks; +import ovh.glitchlabs.masterwild.Item.ModItems; +import ovh.glitchlabs.masterwild.Sounds.ModSounds; +import ovh.glitchlabs.masterwild.entity.ModEntities; +import ovh.glitchlabs.masterwild.entity.client.Pinguin.PinguinRenderer; +import ovh.glitchlabs.masterwild.entity.client.Rooster.RoosterRenderer; +import ovh.glitchlabs.masterwild.entity.client.firefly.FireflyRenderer; // The value here should match an entry in the META-INF/neoforge.mods.toml file @Mod(Masterwild.MODID) public class Masterwild { // Define mod id in a common place for everything to reference public static final String MODID = "masterwild"; - // Directly reference a slf4j logger private static final Logger LOGGER = LogUtils.getLogger(); - // Create a Deferred Register to hold Blocks which will all be registered under the "masterwild" namespace - public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(MODID); - // Create a Deferred Register to hold Items which will all be registered under the "masterwild" namespace - public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MODID); - // Create a Deferred Register to hold CreativeModeTabs which will all be registered under the "masterwild" namespace - public static final DeferredRegister CREATIVE_MODE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, MODID); - - // Creates a new Block with the id "masterwild:example_block", combining the namespace and path - public static final DeferredBlock EXAMPLE_BLOCK = BLOCKS.registerSimpleBlock("example_block", BlockBehaviour.Properties.of().mapColor(MapColor.STONE)); - // Creates a new BlockItem with the id "masterwild:example_block", combining the namespace and path - public static final DeferredItem EXAMPLE_BLOCK_ITEM = ITEMS.registerSimpleBlockItem("example_block", EXAMPLE_BLOCK); - - // Creates a new food item with the id "masterwild:example_id", nutrition 1 and saturation 2 - public static final DeferredItem EXAMPLE_ITEM = ITEMS.registerSimpleItem("example_item", new Item.Properties().food(new FoodProperties.Builder().alwaysEdible().nutrition(1).saturationModifier(2f).build())); - - // Creates a creative tab with the id "masterwild:example_tab" for the example item, that is placed after the combat tab - public static final DeferredHolder EXAMPLE_TAB = CREATIVE_MODE_TABS.register("example_tab", () -> CreativeModeTab.builder().title(Component.translatable("itemGroup.masterwild")).withTabsBefore(CreativeModeTabs.COMBAT).icon(() -> EXAMPLE_ITEM.get().getDefaultInstance()).displayItems((parameters, output) -> { - output.accept(EXAMPLE_ITEM.get()); // Add the example item to the tab. For your own tabs, this method is preferred over the event - }).build()); // The constructor for the mod class is the first code that is run when your mod is loaded. // FML will recognize some parameter types like IEventBus or ModContainer and pass them in automatically. @@ -65,46 +35,30 @@ public class Masterwild { // Register the commonSetup method for modloading modEventBus.addListener(this::commonSetup); - // Register the Deferred Register to the mod event bus so blocks get registered - BLOCKS.register(modEventBus); - // Register the Deferred Register to the mod event bus so items get registered - ITEMS.register(modEventBus); - // Register the Deferred Register to the mod event bus so tabs get registered - CREATIVE_MODE_TABS.register(modEventBus); + ModItems.register(modEventBus); + ModBlocks.register(modEventBus); + + ModEntities.register(modEventBus); + ModSounds.register(modEventBus); // Register ourselves for server and other game events we are interested in. // Note that this is necessary if and only if we want *this* class (Masterwild) to respond directly to events. // Do not add this line if there are no @SubscribeEvent-annotated functions in this class, like onServerStarting() below. NeoForge.EVENT_BUS.register(this); - // Register the item to a creative tab - modEventBus.addListener(this::addCreative); - // Register our mod's ModConfigSpec so that FML can create and load the config file for us modContainer.registerConfig(ModConfig.Type.COMMON, Config.SPEC); } private void commonSetup(final FMLCommonSetupEvent event) { // Some common setup code - LOGGER.info("HELLO FROM COMMON SETUP"); - if (Config.logDirtBlock) LOGGER.info("DIRT BLOCK >> {}", BuiltInRegistries.BLOCK.getKey(Blocks.DIRT)); - - LOGGER.info(Config.magicNumberIntroduction + Config.magicNumber); - - Config.items.forEach((item) -> LOGGER.info("ITEM >> {}", item.toString())); - } - - // Add the example block item to the building blocks tab - private void addCreative(BuildCreativeModeTabContentsEvent event) { - if (event.getTabKey() == CreativeModeTabs.BUILDING_BLOCKS) event.accept(EXAMPLE_BLOCK_ITEM); } // You can use SubscribeEvent and let the Event Bus discover methods to call @SubscribeEvent public void onServerStarting(ServerStartingEvent event) { - // Do something when the server starts - LOGGER.info("HELLO from server starting"); + LOGGER.info("yipi you installed MasterWild :3"); } // You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent @@ -112,9 +66,11 @@ public class Masterwild { public static class ClientModEvents { @SubscribeEvent public static void onClientSetup(FMLClientSetupEvent event) { - // Some client setup code - LOGGER.info("HELLO FROM CLIENT SETUP"); - LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName()); + LOGGER.info("yipi you installed MasterWild :3"); + + EntityRenderers.register(ModEntities.PINGUIN.get(), PinguinRenderer::new); + EntityRenderers.register(ModEntities.FIREFLY.get(), FireflyRenderer::new); + EntityRenderers.register(ModEntities.ROOSTER.get(), RoosterRenderer::new); } } } diff --git a/src/main/java/ovh/glitchlabs/masterwild/Sounds/ModSounds.java b/src/main/java/ovh/glitchlabs/masterwild/Sounds/ModSounds.java new file mode 100644 index 0000000..0af5fe3 --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/Sounds/ModSounds.java @@ -0,0 +1,26 @@ +package ovh.glitchlabs.masterwild.Sounds; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvent; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredRegister; +import ovh.glitchlabs.masterwild.Masterwild; + +import java.util.function.Supplier; + +public class ModSounds { + public static final DeferredRegister SOUND_EVENTS = + DeferredRegister.create(BuiltInRegistries.SOUND_EVENT, Masterwild.MODID); + + public static final Supplier ROOSTER_CROW = registerSound("rooster_crow"); + + private static Supplier registerSound(String name) { + ResourceLocation id = ResourceLocation.fromNamespaceAndPath(Masterwild.MODID, name); + return SOUND_EVENTS.register(name, () -> SoundEvent.createVariableRangeEvent(id)); + } + + public static void register(IEventBus eventBus) { + SOUND_EVENTS.register(eventBus); + } +} \ No newline at end of file diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/ModEntities.java b/src/main/java/ovh/glitchlabs/masterwild/entity/ModEntities.java new file mode 100644 index 0000000..45819de --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/ModEntities.java @@ -0,0 +1,35 @@ +package ovh.glitchlabs.masterwild.entity; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredRegister; +import ovh.glitchlabs.masterwild.Masterwild; +import ovh.glitchlabs.masterwild.entity.custom.FireflyEntity; +import ovh.glitchlabs.masterwild.entity.custom.PinguinEntity; +import ovh.glitchlabs.masterwild.entity.custom.RoosterEntity; + +import java.util.function.Supplier; + +public class ModEntities { + public static final DeferredRegister> ENTITY_TYPES = + DeferredRegister.create(BuiltInRegistries.ENTITY_TYPE, Masterwild.MODID); + + public static final Supplier> PINGUIN = + ENTITY_TYPES.register("pinguin", () -> EntityType.Builder.of(PinguinEntity::new, MobCategory.CREATURE) + .sized(0.75f, 0.5f).build("pinguin")); + + public static final Supplier> FIREFLY = + ENTITY_TYPES.register("firefly", () -> EntityType.Builder.of(FireflyEntity::new, MobCategory.CREATURE) + .sized(0.35f, 0.5f).build("firefly")); + + public static final Supplier> ROOSTER = + ENTITY_TYPES.register("rooster", () -> EntityType.Builder.of(RoosterEntity::new, MobCategory.CREATURE) + .sized(0.5f, 0.75f).build("rooster")); + + + public static void register(IEventBus eventBus) { + ENTITY_TYPES.register(eventBus); + } +} \ No newline at end of file diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/PinguinVariants.java b/src/main/java/ovh/glitchlabs/masterwild/entity/PinguinVariants.java new file mode 100644 index 0000000..f75d1c8 --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/PinguinVariants.java @@ -0,0 +1,26 @@ +package ovh.glitchlabs.masterwild.entity; + +import java.util.Arrays; +import java.util.Comparator; + +public enum PinguinVariants { + NORMAL(0), + RARE(1); + + + private static final PinguinVariants[] BY_ID = Arrays.stream(values()).sorted( + Comparator.comparingInt(PinguinVariants::getId)).toArray(PinguinVariants[]::new); + private final int id; + + PinguinVariants(int id) { + this.id = id; + } + + public int getId() { + return id; + } + + public static PinguinVariants byId(int id) { + return BY_ID[id % BY_ID.length]; + } +} diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/client/Pinguin/PinguinAnimation.java b/src/main/java/ovh/glitchlabs/masterwild/entity/client/Pinguin/PinguinAnimation.java new file mode 100755 index 0000000..eb65e56 --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/client/Pinguin/PinguinAnimation.java @@ -0,0 +1,59 @@ +package ovh.glitchlabs.masterwild.entity.client.Pinguin; + +import net.minecraft.client.animation.AnimationChannel; +import net.minecraft.client.animation.AnimationDefinition; +import net.minecraft.client.animation.Keyframe; +import net.minecraft.client.animation.KeyframeAnimations; + +/** + * Made with Blockbench 5.2.0 + * Exported for Minecraft version 1.19 or later with Mojang mappings + * @author Author + */ +public class PinguinAnimation { + public static final AnimationDefinition PINGUIN_Iidle = AnimationDefinition.Builder.withLength(0.25F).looping() + .addAnimation("wings_L", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.125F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -22.5F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.25F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR) + )) + .addAnimation("wings_R", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.125F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 22.5F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.25F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR) + )) + .addAnimation("wings_R", new AnimationChannel(AnimationChannel.Targets.POSITION, + new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.125F, KeyframeAnimations.posVec(0.0F, -0.25F, 0.0F), AnimationChannel.Interpolations.LINEAR) + )) + .build(); + + public static final AnimationDefinition PINGUIN_walking = AnimationDefinition.Builder.withLength(0.25F).looping() + .addAnimation("Foot_R", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.0833F, KeyframeAnimations.degreeVec(-22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.1667F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.25F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR) + )) + .addAnimation("Foot_L", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.0833F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.1667F, KeyframeAnimations.degreeVec(-22.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.25F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR) + )) + .addAnimation("wings_L", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.125F, KeyframeAnimations.degreeVec(0.0F, 0.0F, -22.5F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.25F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR) + )) + .addAnimation("wings_R", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.125F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 22.5F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.25F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR) + )) + .addAnimation("wings_R", new AnimationChannel(AnimationChannel.Targets.POSITION, + new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR), + new Keyframe(0.125F, KeyframeAnimations.posVec(0.0F, -0.25F, 0.0F), AnimationChannel.Interpolations.LINEAR) + )) + .build(); +} \ No newline at end of file diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/client/Pinguin/PinguinModel.java b/src/main/java/ovh/glitchlabs/masterwild/entity/client/Pinguin/PinguinModel.java new file mode 100755 index 0000000..50aaece --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/client/Pinguin/PinguinModel.java @@ -0,0 +1,260 @@ +package ovh.glitchlabs.masterwild.entity.client.Pinguin;// Made with Blockbench 5.2.0 +// Exported for Minecraft version 1.17 or later with Mojang mappings +// Paste this class into your mod and generate all required imports + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.HierarchicalModel; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.*; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import ovh.glitchlabs.masterwild.Masterwild; +import ovh.glitchlabs.masterwild.entity.custom.PinguinEntity; + +public class PinguinModel extends HierarchicalModel { + // This layer location should be baked with EntityRendererProvider.Context in the entity renderer and passed into this model's constructor + public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(ResourceLocation.fromNamespaceAndPath(Masterwild.MODID, "pinguin"), "main"); + private final ModelPart Pinguin; + private final ModelPart Head; + private final ModelPart fins_up; + private final ModelPart fins_back2; + private final ModelPart fins_L2; + private final ModelPart fins_R; + private final ModelPart body; + private final ModelPart Foot_R; + private final ModelPart Foot_L; + private final ModelPart wings_L; + private final ModelPart wings_R; + private final ModelPart fins_L; + private final ModelPart fins_back; + + public PinguinModel(ModelPart root) { + this.Pinguin = root.getChild("Pinguin"); + this.Head = this.Pinguin.getChild("Head"); + this.fins_up = this.Head.getChild("fins_up"); + this.fins_back2 = this.Head.getChild("fins_back2"); + this.fins_L2 = this.Head.getChild("fins_L2"); + this.fins_R = this.Head.getChild("fins_R"); + this.body = this.Pinguin.getChild("body"); + this.Foot_R = this.body.getChild("Foot_R"); + this.Foot_L = this.body.getChild("Foot_L"); + this.wings_L = this.body.getChild("wings_L"); + this.wings_R = this.body.getChild("wings_R"); + this.fins_L = this.body.getChild("fins_L"); + this.fins_back = this.body.getChild("fins_back"); + } + + public static LayerDefinition createBodyLayer() { + MeshDefinition meshdefinition = new MeshDefinition(); + PartDefinition partdefinition = meshdefinition.getRoot(); + + PartDefinition Pinguin = partdefinition.addOrReplaceChild("Pinguin", CubeListBuilder.create(), PartPose.offset(0.0F, 24.0F, 0.0F)); + + PartDefinition Head = Pinguin.addOrReplaceChild("Head", CubeListBuilder.create().texOffs(0, 13).addBox(-4.0F, -13.5F, -3.0F, 8.0F, 5.0F, 5.0F, new CubeDeformation(0.0F)) + .texOffs(26, 3).addBox(-1.0F, -10.5F, -4.5F, 2.0F, 2.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 0.0F, 0.0F)); + + PartDefinition fins_up = Head.addOrReplaceChild("fins_up", CubeListBuilder.create(), PartPose.offset(2.5F, -12.0F, 3.25F)); + + PartDefinition cube_r1 = fins_up.addOrReplaceChild("cube_r1", CubeListBuilder.create().texOffs(24, 28).addBox(-1.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(26, 14).addBox(1.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(24, 26).addBox(3.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(26, 19).addBox(5.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.0F, 0.0F, -1.0F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition cube_r2 = fins_up.addOrReplaceChild("cube_r2", CubeListBuilder.create().texOffs(20, 28).addBox(-1.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(20, 26).addBox(1.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(26, 22).addBox(3.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(26, 17).addBox(5.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.0F, 0.0F, -2.0F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition cube_r3 = fins_up.addOrReplaceChild("cube_r3", CubeListBuilder.create().texOffs(24, 27).addBox(-1.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(26, 18).addBox(1.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(26, 21).addBox(3.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(26, 15).addBox(5.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.0F, 0.0F, -3.0F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition cube_r4 = fins_up.addOrReplaceChild("cube_r4", CubeListBuilder.create().texOffs(20, 27).addBox(-1.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(26, 16).addBox(1.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(26, 20).addBox(3.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(26, 13).addBox(5.0F, -2.0F, -1.0F, 1.0F, 0.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.0F, 0.0F, -4.0F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition fins_back2 = Head.addOrReplaceChild("fins_back2", CubeListBuilder.create(), PartPose.offset(0.0F, 0.0F, 0.0F)); + + PartDefinition cube_r5 = fins_back2.addOrReplaceChild("cube_r5", CubeListBuilder.create().texOffs(14, 35).addBox(-1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(16, 35).addBox(1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(6, 35).addBox(3.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(2, 35).addBox(5.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-2.5F, -12.0F, 3.25F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition cube_r6 = fins_back2.addOrReplaceChild("cube_r6", CubeListBuilder.create().texOffs(24, 35).addBox(-1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(22, 35).addBox(1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(12, 35).addBox(3.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(10, 35).addBox(5.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-2.5F, -11.0F, 3.25F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition cube_r7 = fins_back2.addOrReplaceChild("cube_r7", CubeListBuilder.create().texOffs(32, 35).addBox(-1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(34, 35).addBox(1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(18, 35).addBox(3.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(20, 35).addBox(5.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-2.5F, -10.0F, 3.25F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition cube_r8 = fins_back2.addOrReplaceChild("cube_r8", CubeListBuilder.create().texOffs(36, 2).addBox(-1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(2, 36).addBox(1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(30, 35).addBox(3.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(26, 35).addBox(5.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-2.5F, -9.0F, 3.25F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition fins_L2 = Head.addOrReplaceChild("fins_L2", CubeListBuilder.create(), PartPose.offset(0.0F, 0.0F, 0.0F)); + + PartDefinition cube_r9 = fins_L2.addOrReplaceChild("cube_r9", CubeListBuilder.create().texOffs(32, 15).addBox(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(32, 13).addBox(-1.0F, -1.0F, 0.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(5.25F, -12.0F, 0.0F, 0.0F, 0.0F, -0.3927F)); + + PartDefinition cube_r10 = fins_L2.addOrReplaceChild("cube_r10", CubeListBuilder.create().texOffs(32, 11).addBox(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(32, 9).addBox(-1.0F, -1.0F, -2.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(5.25F, -11.0F, 1.5F, 0.0F, 0.0F, -0.3927F)); + + PartDefinition cube_r11 = fins_L2.addOrReplaceChild("cube_r11", CubeListBuilder.create().texOffs(26, 29).addBox(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(24, 29).addBox(-1.0F, -1.0F, -2.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(5.25F, -9.0F, 1.5F, 0.0F, 0.0F, -0.3927F)); + + PartDefinition cube_r12 = fins_L2.addOrReplaceChild("cube_r12", CubeListBuilder.create().texOffs(20, 29).addBox(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(5.25F, -10.0F, 1.5F, 0.0F, 0.0F, -0.3927F)); + + PartDefinition fins_R = Head.addOrReplaceChild("fins_R", CubeListBuilder.create(), PartPose.offset(0.0F, 0.0F, 0.0F)); + + PartDefinition cube_r13 = fins_R.addOrReplaceChild("cube_r13", CubeListBuilder.create().texOffs(18, 33).addBox(1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(16, 33).addBox(1.0F, -1.0F, 0.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.25F, -12.0F, 0.0F, 0.0F, 0.0F, 0.3927F)); + + PartDefinition cube_r14 = fins_R.addOrReplaceChild("cube_r14", CubeListBuilder.create().texOffs(14, 33).addBox(1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(12, 33).addBox(1.0F, -1.0F, -2.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.25F, -11.0F, 1.5F, 0.0F, 0.0F, 0.3927F)); + + PartDefinition cube_r15 = fins_R.addOrReplaceChild("cube_r15", CubeListBuilder.create().texOffs(8, 33).addBox(1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(6, 33).addBox(1.0F, -1.0F, -2.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.25F, -9.0F, 1.5F, 0.0F, 0.0F, 0.3927F)); + + PartDefinition cube_r16 = fins_R.addOrReplaceChild("cube_r16", CubeListBuilder.create().texOffs(2, 33).addBox(1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.25F, -10.0F, 1.5F, 0.0F, 0.0F, 0.3927F)); + + PartDefinition body = Pinguin.addOrReplaceChild("body", CubeListBuilder.create().texOffs(0, 0).addBox(-4.0F, -8.5F, -3.0F, 8.0F, 8.0F, 5.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 0.0F, 0.0F)); + + PartDefinition Foot_R = body.addOrReplaceChild("Foot_R", CubeListBuilder.create().texOffs(26, 7).addBox(-3.0F, -2.0F, -1.0F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(26, 0).addBox(-4.0F, 0.0F, -3.0F, 2.0F, 0.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 0.0F, 0.0F)); + + PartDefinition Foot_L = body.addOrReplaceChild("Foot_L", CubeListBuilder.create().texOffs(26, 10).addBox(2.0F, -2.0F, -1.0F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(20, 23).addBox(2.0F, 0.0F, -3.0F, 2.0F, 0.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 0.0F, 0.0F)); + + PartDefinition wings_L = body.addOrReplaceChild("wings_L", CubeListBuilder.create().texOffs(0, 23).addBox(-1.0F, -1.5F, -3.0F, 1.0F, 6.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offset(5.0F, -7.0F, 0.5F)); + + PartDefinition wings_R = body.addOrReplaceChild("wings_R", CubeListBuilder.create().texOffs(10, 23).addBox(-1.0F, -1.0F, -2.0F, 1.0F, 6.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offset(-4.0F, -7.5F, -0.5F)); + + PartDefinition fins_L = body.addOrReplaceChild("fins_L", CubeListBuilder.create(), PartPose.offset(0.0F, 0.0F, 0.0F)); + + PartDefinition cube_r17 = fins_L.addOrReplaceChild("cube_r17", CubeListBuilder.create().texOffs(0, 35).addBox(1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.25F, -4.0F, 1.5F, 0.0F, 0.0F, 0.3927F)); + + PartDefinition cube_r18 = fins_L.addOrReplaceChild("cube_r18", CubeListBuilder.create().texOffs(34, 29).addBox(1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.25F, -3.0F, 1.5F, 0.0F, 0.0F, 0.3927F)); + + PartDefinition cube_r19 = fins_L.addOrReplaceChild("cube_r19", CubeListBuilder.create().texOffs(34, 23).addBox(1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(34, 21).addBox(1.0F, -1.0F, 0.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.25F, -5.0F, 0.0F, 0.0F, 0.0F, 0.3927F)); + + PartDefinition cube_r20 = fins_L.addOrReplaceChild("cube_r20", CubeListBuilder.create().texOffs(34, 19).addBox(1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(34, 17).addBox(1.0F, -1.0F, -2.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.25F, -6.0F, 1.5F, 0.0F, 0.0F, 0.3927F)); + + PartDefinition cube_r21 = fins_L.addOrReplaceChild("cube_r21", CubeListBuilder.create().texOffs(34, 13).addBox(1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(34, 11).addBox(1.0F, -1.0F, 0.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(34, 9).addBox(1.0F, -1.0F, 2.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.25F, -7.0F, -1.5F, 0.0F, 0.0F, 0.3927F)); + + PartDefinition cube_r22 = fins_L.addOrReplaceChild("cube_r22", CubeListBuilder.create().texOffs(34, 7).addBox(1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(34, 5).addBox(1.0F, -1.0F, 0.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(34, 3).addBox(1.0F, -1.0F, 2.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.25F, -8.0F, -1.5F, 0.0F, 0.0F, 0.3927F)); + + PartDefinition cube_r23 = fins_L.addOrReplaceChild("cube_r23", CubeListBuilder.create().texOffs(30, 33).addBox(1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(26, 33).addBox(1.0F, -1.0F, 0.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.25F, -1.0F, 0.0F, 0.0F, 0.0F, 0.3927F)); + + PartDefinition cube_r24 = fins_L.addOrReplaceChild("cube_r24", CubeListBuilder.create().texOffs(24, 33).addBox(1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(22, 33).addBox(1.0F, -1.0F, -2.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.25F, -2.0F, 1.5F, 0.0F, 0.0F, 0.3927F)); + + PartDefinition cube_r25 = fins_L.addOrReplaceChild("cube_r25", CubeListBuilder.create().texOffs(30, 31).addBox(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(5.25F, -4.0F, 1.5F, 0.0F, 0.0F, -0.3927F)); + + PartDefinition cube_r26 = fins_L.addOrReplaceChild("cube_r26", CubeListBuilder.create().texOffs(22, 31).addBox(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(5.25F, -3.0F, 1.5F, 0.0F, 0.0F, -0.3927F)); + + PartDefinition cube_r27 = fins_L.addOrReplaceChild("cube_r27", CubeListBuilder.create().texOffs(30, 27).addBox(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(30, 25).addBox(-1.0F, -1.0F, 0.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(5.25F, -5.0F, 0.0F, 0.0F, 0.0F, -0.3927F)); + + PartDefinition cube_r28 = fins_L.addOrReplaceChild("cube_r28", CubeListBuilder.create().texOffs(30, 23).addBox(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(30, 21).addBox(-1.0F, -1.0F, -2.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(5.25F, -6.0F, 1.5F, 0.0F, 0.0F, -0.3927F)); + + PartDefinition cube_r29 = fins_L.addOrReplaceChild("cube_r29", CubeListBuilder.create().texOffs(30, 17).addBox(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(30, 15).addBox(-1.0F, -1.0F, 0.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(30, 13).addBox(-1.0F, -1.0F, 2.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(5.25F, -7.0F, -1.5F, 0.0F, 0.0F, -0.3927F)); + + PartDefinition cube_r30 = fins_L.addOrReplaceChild("cube_r30", CubeListBuilder.create().texOffs(30, 11).addBox(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(30, 9).addBox(-1.0F, -1.0F, 0.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(30, 7).addBox(-1.0F, -1.0F, 2.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(5.25F, -8.0F, -1.5F, 0.0F, 0.0F, -0.3927F)); + + PartDefinition cube_r31 = fins_L.addOrReplaceChild("cube_r31", CubeListBuilder.create().texOffs(32, 27).addBox(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(32, 25).addBox(-1.0F, -1.0F, 0.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(5.25F, -1.0F, 0.0F, 0.0F, 0.0F, -0.3927F)); + + PartDefinition cube_r32 = fins_L.addOrReplaceChild("cube_r32", CubeListBuilder.create().texOffs(32, 23).addBox(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(32, 21).addBox(-1.0F, -1.0F, -2.5F, 0.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(5.25F, -2.0F, 1.5F, 0.0F, 0.0F, -0.3927F)); + + PartDefinition fins_back = body.addOrReplaceChild("fins_back", CubeListBuilder.create(), PartPose.offset(2.5F, -12.0F, 3.25F)); + + PartDefinition cube_r33 = fins_back.addOrReplaceChild("cube_r33", CubeListBuilder.create().texOffs(36, 4).addBox(-1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 5).addBox(1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 0).addBox(3.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 1).addBox(5.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.0F, 4.0F, 0.0F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition cube_r34 = fins_back.addOrReplaceChild("cube_r34", CubeListBuilder.create().texOffs(8, 36).addBox(-1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 7).addBox(1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(4, 36).addBox(3.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 3).addBox(5.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.0F, 5.0F, 0.0F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition cube_r35 = fins_back.addOrReplaceChild("cube_r35", CubeListBuilder.create().texOffs(10, 36).addBox(-1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 10).addBox(1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(6, 36).addBox(3.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 6).addBox(5.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.0F, 6.0F, 0.0F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition cube_r36 = fins_back.addOrReplaceChild("cube_r36", CubeListBuilder.create().texOffs(36, 13).addBox(-1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 12).addBox(1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 9).addBox(3.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 8).addBox(5.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.0F, 7.0F, 0.0F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition cube_r37 = fins_back.addOrReplaceChild("cube_r37", CubeListBuilder.create().texOffs(36, 15).addBox(-1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(16, 36).addBox(1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 11).addBox(3.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(12, 36).addBox(5.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.0F, 8.0F, 0.0F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition cube_r38 = fins_back.addOrReplaceChild("cube_r38", CubeListBuilder.create().texOffs(36, 18).addBox(-1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(18, 36).addBox(1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 14).addBox(3.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(14, 36).addBox(5.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.0F, 9.0F, 0.0F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition cube_r39 = fins_back.addOrReplaceChild("cube_r39", CubeListBuilder.create().texOffs(36, 20).addBox(-1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 21).addBox(1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 16).addBox(3.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 17).addBox(5.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.0F, 10.0F, 0.0F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition cube_r40 = fins_back.addOrReplaceChild("cube_r40", CubeListBuilder.create().texOffs(8, 35).addBox(-1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(4, 35).addBox(1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(20, 36).addBox(3.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(36, 19).addBox(5.0F, -1.0F, -1.0F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-5.0F, 11.0F, 0.0F, 0.3927F, 0.0F, 0.0F)); + + return LayerDefinition.create(meshdefinition, 64, 64); + } + + @Override + public void setupAnim(PinguinEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { + this.root().getAllParts().forEach(ModelPart::resetPose); + this.applyHeadRotation(netHeadYaw, headPitch); + + this.animateWalk(PinguinAnimation.PINGUIN_walking, limbSwing, limbSwingAmount, 2f, 2.5f); + this.animate(entity.idleAnimationState, PinguinAnimation.PINGUIN_Iidle, ageInTicks, 1f); + } + + private void applyHeadRotation(float headYaw, float headPitch) { + headYaw = Mth.clamp(headYaw, -30f, 30f); + + this.Head.yRot = headYaw * ((float)Math.PI / 180f); + } + + @Override + public void renderToBuffer(PoseStack poseStack, VertexConsumer vertexConsumer, int packedLight, int packedOverlay, int color) { + Pinguin.render(poseStack, vertexConsumer, packedLight, packedOverlay, color); + } + + @Override + public ModelPart root() { + return Pinguin; + } +} \ No newline at end of file diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/client/Pinguin/PinguinRenderer.java b/src/main/java/ovh/glitchlabs/masterwild/entity/client/Pinguin/PinguinRenderer.java new file mode 100644 index 0000000..cf9b361 --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/client/Pinguin/PinguinRenderer.java @@ -0,0 +1,45 @@ +package ovh.glitchlabs.masterwild.entity.client.Pinguin; + +import com.google.common.collect.Maps; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.Util; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.resources.ResourceLocation; +import ovh.glitchlabs.masterwild.Masterwild; +import ovh.glitchlabs.masterwild.entity.PinguinVariants; +import ovh.glitchlabs.masterwild.entity.custom.PinguinEntity; + +import java.util.Map; + +public class PinguinRenderer extends MobRenderer> { + + public static final Map LOCATION_BY_VARIANT = + Util.make(Maps.newEnumMap(PinguinVariants.class), map -> { + map.put(PinguinVariants.NORMAL, + ResourceLocation.fromNamespaceAndPath(Masterwild.MODID, "textures/entity/pinguin.png")); + map.put(PinguinVariants.RARE, + ResourceLocation.fromNamespaceAndPath(Masterwild.MODID, "textures/entity/pinguin_rare.png")); + }); + + public PinguinRenderer(EntityRendererProvider.Context context) { + super(context, new PinguinModel<>(context.bakeLayer(PinguinModel.LAYER_LOCATION)), 0.25f); + } + + @Override + public ResourceLocation getTextureLocation(PinguinEntity entity) { + return ResourceLocation.fromNamespaceAndPath(Masterwild.MODID, "textures/entity/pinguin.png"); + } + + @Override + public void render(PinguinEntity entity, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource buffer, int packedLight) { + if(entity.isBaby()) { + poseStack.scale(0.45f, 0.45f, 0.45f); + } else { + poseStack.scale(1f, 1f, 1f); + } + + super.render(entity, entityYaw, partialTicks, poseStack, buffer, packedLight); + } +} diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/client/Rooster/RoosterModel.java b/src/main/java/ovh/glitchlabs/masterwild/entity/client/Rooster/RoosterModel.java new file mode 100755 index 0000000..f804c43 --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/client/Rooster/RoosterModel.java @@ -0,0 +1,99 @@ +package ovh.glitchlabs.masterwild.entity.client.Rooster;// Made with Blockbench 5.2.0 +// Exported for Minecraft version 1.17 or later with Mojang mappings +// Paste this class into your mod and generate all required imports + + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.model.HierarchicalModel; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.*; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import ovh.glitchlabs.masterwild.Masterwild; +import ovh.glitchlabs.masterwild.entity.custom.RoosterEntity; + +public class RoosterModel extends HierarchicalModel { + // This layer location should be baked with EntityRendererProvider.Context in the entity renderer and passed into this model's constructor + public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(ResourceLocation.fromNamespaceAndPath(Masterwild.MODID, "rooster"), "main"); + private final ModelPart Rooster; + private final ModelPart head; + private final ModelPart body; + private final ModelPart Foot_L; + private final ModelPart Foot_R; + private final ModelPart flaps; + + public RoosterModel(ModelPart root) { + this.Rooster = root.getChild("Rooster"); + this.head = this.Rooster.getChild("head"); + this.body = this.Rooster.getChild("body"); + this.Foot_L = this.body.getChild("Foot_L"); + this.Foot_R = this.body.getChild("Foot_R"); + this.flaps = this.body.getChild("flaps"); + } + + public static LayerDefinition createBodyLayer() { + MeshDefinition meshdefinition = new MeshDefinition(); + PartDefinition partdefinition = meshdefinition.getRoot(); + + PartDefinition Rooster = partdefinition.addOrReplaceChild("Rooster", CubeListBuilder.create(), PartPose.offset(-0.5F, 24.0F, 0.0F)); + + PartDefinition head = Rooster.addOrReplaceChild("head", CubeListBuilder.create().texOffs(12, 21).addBox(-1.5F, -2.6981F, -1.6444F, 3.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)) + .texOffs(20, 27).addBox(-0.5F, -1.6981F, -2.6444F, 1.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(0, 29).addBox(-0.5F, -0.6981F, -2.1444F, 1.0F, 1.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offset(0.5F, -8.3019F, -4.3556F)); + + PartDefinition cube_r1 = head.addOrReplaceChild("cube_r1", CubeListBuilder.create().texOffs(26, 10).addBox(-1.0F, -3.0F, -1.0F, 0.0F, 3.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(1.0F, -1.6981F, -1.6444F, 0.2618F, 0.0F, 0.0F)); + + PartDefinition body = Rooster.addOrReplaceChild("body", CubeListBuilder.create().texOffs(0, 0).addBox(-2.5F, -6.75F, -3.25F, 5.0F, 5.0F, 7.0F, new CubeDeformation(0.0F)), PartPose.offset(0.5F, 0.0F, 0.0F)); + + PartDefinition cube_r2 = body.addOrReplaceChild("cube_r2", CubeListBuilder.create().texOffs(24, 21).addBox(1.0F, -4.0F, -1.0F, 0.0F, 4.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-1.25F, -6.0F, 3.5F, 0.0F, -0.2182F, 0.0F)); + + PartDefinition cube_r3 = body.addOrReplaceChild("cube_r3", CubeListBuilder.create().texOffs(24, 2).addBox(1.0F, -4.0F, -1.0F, 0.0F, 4.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-0.75F, -6.0F, 4.0F, 0.0F, 0.2182F, 0.0F)); + + PartDefinition cube_r4 = body.addOrReplaceChild("cube_r4", CubeListBuilder.create().texOffs(26, 17).addBox(-1.0F, -2.0F, -1.0F, 3.0F, 2.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-0.5F, -6.75F, -4.0F, 0.1309F, 0.0F, 0.0F)); + + PartDefinition cube_r5 = body.addOrReplaceChild("cube_r5", CubeListBuilder.create().texOffs(0, 12).addBox(-2.0F, -5.0F, -1.0F, 4.0F, 5.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, -2.25F, -2.5F, 0.3927F, 0.0F, 0.0F)); + + PartDefinition Foot_L = body.addOrReplaceChild("Foot_L", CubeListBuilder.create().texOffs(25, 0).addBox(1.0F, 0.0F, -1.0F, 2.0F, 0.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offset(-1.5F, 0.0F, 0.0F)); + + PartDefinition cube_r6 = Foot_L.addOrReplaceChild("cube_r6", CubeListBuilder.create().texOffs(16, 27).addBox(-1.0F, -2.0F, 0.0F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(3.0F, 0.0F, 0.0F, -0.1309F, 0.0F, 0.0F)); + + PartDefinition Foot_R = body.addOrReplaceChild("Foot_R", CubeListBuilder.create().texOffs(24, 0).addBox(-1.0F, 0.0F, -1.0F, 2.0F, 0.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offset(-0.5F, 0.0F, 0.0F)); + + PartDefinition cube_r7 = Foot_R.addOrReplaceChild("cube_r7", CubeListBuilder.create().texOffs(12, 27).addBox(-1.0F, -2.0F, 0.0F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, 0.0F, 0.0F, -0.1309F, 0.0F, 0.0F)); + + PartDefinition flaps = body.addOrReplaceChild("flaps", CubeListBuilder.create().texOffs(14, 12).addBox(-1.0F, -4.0F, -2.0F, 1.0F, 4.0F, 5.0F, new CubeDeformation(0.0F)) + .texOffs(0, 20).addBox(-7.0F, -4.0F, -2.0F, 1.0F, 4.0F, 5.0F, new CubeDeformation(0.0F)), PartPose.offset(3.5F, -2.75F, 0.0F)); + + return LayerDefinition.create(meshdefinition, 64, 64); + } + + @Override + public void setupAnim(RoosterEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { + this.root().getAllParts().forEach(ModelPart::resetPose); + this.applyHeadRotation(netHeadYaw, headPitch); + + //this.animateWalk(RoosterAnimations.ANIM_GECKO_WALK, limbSwing, limbSwingAmount, 2f, 2.5f); + } + + private void applyHeadRotation(float headYaw, float headPitch) { + headYaw = Mth.clamp(headYaw, -30f, 30f); + headPitch = Mth.clamp(headPitch, -25f, 45); + + this.head.yRot = headYaw * ((float)Math.PI / 180f); + this.head.xRot = headPitch * ((float)Math.PI / 180f); + } + + @Override + public void renderToBuffer(PoseStack poseStack, VertexConsumer vertexConsumer, int packedLight, int packedOverlay, int color) { + Rooster.render(poseStack, vertexConsumer, packedLight, packedOverlay, color); + } + + @Override + public ModelPart root() { + return Rooster; + } +} \ No newline at end of file diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/client/Rooster/RoosterRenderer.java b/src/main/java/ovh/glitchlabs/masterwild/entity/client/Rooster/RoosterRenderer.java new file mode 100644 index 0000000..c199ce3 --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/client/Rooster/RoosterRenderer.java @@ -0,0 +1,32 @@ +package ovh.glitchlabs.masterwild.entity.client.Rooster; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.resources.ResourceLocation; +import ovh.glitchlabs.masterwild.Masterwild; +import ovh.glitchlabs.masterwild.entity.custom.RoosterEntity; + +public class RoosterRenderer extends MobRenderer> { + + public RoosterRenderer(EntityRendererProvider.Context context) { + super(context, new RoosterModel<>(context.bakeLayer(RoosterModel.LAYER_LOCATION)), 0.25f); + } + + @Override + public ResourceLocation getTextureLocation(RoosterEntity entity) { + return ResourceLocation.fromNamespaceAndPath(Masterwild.MODID, "textures/entity/rooster.png"); + } + + @Override + public void render(RoosterEntity entity, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource buffer, int packedLight) { + if(entity.isBaby()) { + poseStack.scale(0.45f, 0.45f, 0.45f); + } else { + poseStack.scale(1.5f, 1.5f, 1.5f); + } + + super.render(entity, entityYaw, partialTicks, poseStack, buffer, packedLight); + } +} diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyAnimation.java b/src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyAnimation.java new file mode 100755 index 0000000..932a780 --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyAnimation.java @@ -0,0 +1,94 @@ +package ovh.glitchlabs.masterwild.entity.client.firefly;// Save this class in your mod and generate all required imports + +import net.minecraft.client.animation.AnimationChannel; +import net.minecraft.client.animation.AnimationDefinition; +import net.minecraft.client.animation.Keyframe; +import net.minecraft.client.animation.KeyframeAnimations; +/** + * Made with Blockbench 5.2.0 + * Exported for Minecraft version 1.19 or later with Mojang mappings + * @author Author + */ +public class FireflyAnimation { + public static final AnimationDefinition firefly_idle = AnimationDefinition.Builder.withLength(0.5F).looping() + .addAnimation("firefly", new AnimationChannel(AnimationChannel.Targets.POSITION, + new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.1667F, KeyframeAnimations.posVec(0.0F, -0.5F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.375F, KeyframeAnimations.posVec(0.0F, 0.63F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.5F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("head", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.1667F, KeyframeAnimations.degreeVec(2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.375F, KeyframeAnimations.degreeVec(-2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.5F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("head", new AnimationChannel(AnimationChannel.Targets.POSITION, + new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.5F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("head", new AnimationChannel(AnimationChannel.Targets.SCALE, + new Keyframe(0.0F, KeyframeAnimations.scaleVec(1.0F, 1.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.5F, KeyframeAnimations.scaleVec(1.0F, 1.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("body", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.125F, KeyframeAnimations.degreeVec(-2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.5F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("body", new AnimationChannel(AnimationChannel.Targets.POSITION, + new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.5F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("body", new AnimationChannel(AnimationChannel.Targets.SCALE, + new Keyframe(0.0F, KeyframeAnimations.scaleVec(1.0F, 1.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.5F, KeyframeAnimations.scaleVec(1.0F, 1.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("L", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.0417F, KeyframeAnimations.degreeVec(3.4049F, -6.3763F, -19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.0833F, KeyframeAnimations.degreeVec(1.7F, 20.37F, 19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.125F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.1667F, KeyframeAnimations.degreeVec(3.4049F, -6.3763F, -19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.2083F, KeyframeAnimations.degreeVec(1.13F, 20.37F, 19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.25F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.2917F, KeyframeAnimations.degreeVec(3.4049F, -6.3763F, -19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.3333F, KeyframeAnimations.degreeVec(1.7F, 20.37F, 19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.375F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.4167F, KeyframeAnimations.degreeVec(3.4049F, -6.3763F, -19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.4583F, KeyframeAnimations.degreeVec(1.7F, 20.37F, -19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.5F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("L", new AnimationChannel(AnimationChannel.Targets.POSITION, + new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.5F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("L", new AnimationChannel(AnimationChannel.Targets.SCALE, + new Keyframe(0.0F, KeyframeAnimations.scaleVec(1.0F, 1.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.5F, KeyframeAnimations.scaleVec(1.0F, 1.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("R", new AnimationChannel(AnimationChannel.Targets.ROTATION, + new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.0417F, KeyframeAnimations.degreeVec(3.4049F, 6.3763F, -19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.0833F, KeyframeAnimations.degreeVec(1.13F, -20.37F, -19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.125F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.1667F, KeyframeAnimations.degreeVec(3.4049F, 6.3763F, 19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.2083F, KeyframeAnimations.degreeVec(1.13F, -20.37F, -19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.25F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.2917F, KeyframeAnimations.degreeVec(3.4049F, 6.3763F, 19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.3333F, KeyframeAnimations.degreeVec(1.13F, -20.37F, -19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.375F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.4167F, KeyframeAnimations.degreeVec(3.4049F, 6.3763F, -19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.4583F, KeyframeAnimations.degreeVec(1.13F, -20.37F, -19.0788F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.5F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("R", new AnimationChannel(AnimationChannel.Targets.POSITION, + new Keyframe(0.0F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.5F, KeyframeAnimations.posVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .addAnimation("R", new AnimationChannel(AnimationChannel.Targets.SCALE, + new Keyframe(0.0F, KeyframeAnimations.scaleVec(1.0F, 1.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM), + new Keyframe(0.5F, KeyframeAnimations.scaleVec(1.0F, 1.0F, 1.0F), AnimationChannel.Interpolations.CATMULLROM) + )) + .build(); +} \ No newline at end of file diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyGlowLayer.java b/src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyGlowLayer.java new file mode 100644 index 0000000..2c22888 --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyGlowLayer.java @@ -0,0 +1,22 @@ +package ovh.glitchlabs.masterwild.entity.client.firefly; + +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.RenderLayerParent; +import net.minecraft.client.renderer.entity.layers.EyesLayer; +import net.minecraft.resources.ResourceLocation; +import ovh.glitchlabs.masterwild.Masterwild; +import ovh.glitchlabs.masterwild.entity.custom.FireflyEntity; + +public class FireflyGlowLayer extends EyesLayer> { + private static final RenderType GLOW = RenderType.eyes( + ResourceLocation.fromNamespaceAndPath(Masterwild.MODID, "textures/entity/firefly_glow.png")); + + public FireflyGlowLayer(RenderLayerParent> parent) { + super(parent); + } + + @Override + public RenderType renderType() { + return GLOW; + } +} \ No newline at end of file diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyModel.java b/src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyModel.java new file mode 100755 index 0000000..41e822a --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyModel.java @@ -0,0 +1,98 @@ +package ovh.glitchlabs.masterwild.entity.client.firefly;// Made with Blockbench 5.2.0 +// Exported for Minecraft version 1.17 or later with Mojang mappings +// Paste this class into your mod and generate all required imports + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.model.HierarchicalModel; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.*; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import ovh.glitchlabs.masterwild.Masterwild; +import ovh.glitchlabs.masterwild.entity.client.firefly.FireflyAnimation; +import ovh.glitchlabs.masterwild.entity.custom.FireflyEntity; + + +public class FireflyModel extends HierarchicalModel { + // This layer location should be baked with EntityRendererProvider.Context in the entity renderer and passed into this model's constructor + public static final ModelLayerLocation LAYER_LOCATION = + new ModelLayerLocation(ResourceLocation.fromNamespaceAndPath(Masterwild.MODID, "firefly"), "main"); + private final ModelPart root; + private final ModelPart firefly; + private final ModelPart head; + private final ModelPart eyes; + private final ModelPart body; + private final ModelPart wings; + private final ModelPart L; + private final ModelPart R; + private final ModelPart legs; + + public FireflyModel(ModelPart root) { + this.root = root; + this.firefly = root.getChild("firefly"); + this.head = this.firefly.getChild("head"); + this.eyes = this.head.getChild("eyes"); + this.body = this.firefly.getChild("body"); + this.wings = this.body.getChild("wings"); + this.L = this.wings.getChild("L"); + this.R = this.wings.getChild("R"); + this.legs = this.body.getChild("legs"); + } + + public static LayerDefinition createBodyLayer() { + MeshDefinition meshdefinition = new MeshDefinition(); + PartDefinition partdefinition = meshdefinition.getRoot(); + + PartDefinition firefly = partdefinition.addOrReplaceChild("firefly", CubeListBuilder.create(), PartPose.offset(0.4167F, 19.2048F, -4.693F)); + + PartDefinition head = firefly.addOrReplaceChild("head", CubeListBuilder.create().texOffs(0, 13).addBox(-2.0F, -3.0F, 3.0F, 3.0F, 3.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0833F, -0.2048F, -1.307F)); + + PartDefinition cube_r1 = head.addOrReplaceChild("cube_r1", CubeListBuilder.create().texOffs(16, 17).addBox(-1.0F, -2.0F, 0.0F, 0.0F, 3.0F, 2.0F, new CubeDeformation(0.0F)) + .texOffs(12, 17).addBox(-3.0F, -2.0F, 0.0F, 0.0F, 3.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(1.5F, -2.0F, 3.0F, 0.6109F, 0.0F, 0.0F)); + + PartDefinition eyes = head.addOrReplaceChild("eyes", CubeListBuilder.create().texOffs(14, 12).addBox(-2.0F, -2.5F, 2.9F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)) + .texOffs(16, 12).addBox(0.0F, -2.5F, 2.9F, 1.0F, 1.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 0.0F, 0.0F)); + + PartDefinition body = firefly.addOrReplaceChild("body", CubeListBuilder.create(), PartPose.offset(-0.3333F, -1.2952F, 3.807F)); + + PartDefinition cube_r2 = body.addOrReplaceChild("cube_r2", CubeListBuilder.create().texOffs(0, 0).addBox(-1.0F, -1.2396F, 0.0976F, 2.0F, 2.0F, 7.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-0.0833F, 0.319F, -0.2719F, -0.6545F, 0.0F, 0.0F)); + + PartDefinition wings = body.addOrReplaceChild("wings", CubeListBuilder.create(), PartPose.offset(0.4167F, 1.0905F, -5.114F)); + + PartDefinition L = wings.addOrReplaceChild("L", CubeListBuilder.create(), PartPose.offset(-0.5391F, -0.1086F, 7.0995F)); + + PartDefinition cube_r3 = L.addOrReplaceChild("cube_r3", CubeListBuilder.create().texOffs(12, 13).addBox(-0.985F, -1.0F, 0.0361F, 3.0F, 0.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, 1.6086F, 0.1505F, -1.1082F, 0.8227F, -0.9733F)); + + PartDefinition R = wings.addOrReplaceChild("R", CubeListBuilder.create(), PartPose.offset(-0.5391F, -0.1086F, 7.0995F)); + + PartDefinition cube_r4 = R.addOrReplaceChild("cube_r4", CubeListBuilder.create().texOffs(0, 9).addBox(-0.97F, 0.1846F, 0.3843F, 3.0F, 0.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, 0.0F, 0.0F, -1.1082F, -0.8227F, 0.9733F)); + + PartDefinition legs = body.addOrReplaceChild("legs", CubeListBuilder.create().texOffs(14, 9).addBox(-1.25F, 0.0F, 5.0F, 0.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(18, 0).addBox(-1.25F, 2.0F, 8.0F, 0.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(16, 9).addBox(0.25F, 2.0F, 8.0F, 0.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)) + .texOffs(18, 3).addBox(0.25F, 0.0F, 5.0F, 0.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offset(0.4167F, 1.0905F, -5.114F)); + + return LayerDefinition.create(meshdefinition, 32, 32); + } + + @Override + public void setupAnim(FireflyEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { + this.root().getAllParts().forEach(ModelPart::resetPose); + + this.animate(entity.idleAnimationState, FireflyAnimation.firefly_idle, ageInTicks, 1f); + } + + @Override + public void renderToBuffer(PoseStack poseStack, VertexConsumer vertexConsumer, int packedLight, int packedOverlay, int color) { + root.render(poseStack, vertexConsumer, packedLight, packedOverlay, color); + } + + @Override + public ModelPart root() { + return root; + } +} \ No newline at end of file diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyRenderer.java b/src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyRenderer.java new file mode 100644 index 0000000..6ab4e92 --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyRenderer.java @@ -0,0 +1,28 @@ +package ovh.glitchlabs.masterwild.entity.client.firefly; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.resources.ResourceLocation; +import ovh.glitchlabs.masterwild.Masterwild; +import ovh.glitchlabs.masterwild.entity.custom.FireflyEntity; + +public class FireflyRenderer extends MobRenderer> { + public FireflyRenderer(EntityRendererProvider.Context context) { + super(context, new FireflyModel<>(context.bakeLayer(FireflyModel.LAYER_LOCATION)), 0.50f); + this.addLayer(new FireflyGlowLayer(this)); + } + + @Override + public ResourceLocation getTextureLocation(FireflyEntity entity) { + return ResourceLocation.fromNamespaceAndPath(Masterwild.MODID, "textures/entity/firefly.png"); + } + + @Override + public void render(FireflyEntity entity, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource buffer, int packedLight) { + poseStack.scale(1f, 1f, 1f); + + super.render(entity, entityYaw, partialTicks, poseStack, buffer, packedLight); + } +} diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/custom/FireflyEntity.java b/src/main/java/ovh/glitchlabs/masterwild/entity/custom/FireflyEntity.java new file mode 100644 index 0000000..60d9aa1 --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/custom/FireflyEntity.java @@ -0,0 +1,146 @@ +package ovh.glitchlabs.masterwild.entity.custom; + +import net.minecraft.Util; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.DifficultyInstance; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.control.FlyingMoveControl; +import net.minecraft.world.entity.ai.goal.*; +import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation; +import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.entity.animal.Animal; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; +import ovh.glitchlabs.masterwild.entity.PinguinVariants; + +public class FireflyEntity extends Animal { + public static final AnimationState idleAnimationState = new AnimationState(); + private BlockPos targetPosition; + + public FireflyEntity(EntityType entityType, Level level) { + super(entityType, level); + xpReward = 0; + setNoAi(false); + } + + @Override + protected void customServerAiStep() { + super.customServerAiStep(); + + if (this.targetPosition != null && (!this.level().isEmptyBlock(this.targetPosition) + || this.targetPosition.getY() <= this.level().getMinBuildHeight())) { + this.targetPosition = null; + } + + if (this.targetPosition == null || this.random.nextInt(30) == 0 + || this.targetPosition.closerToCenterThan(this.position(), 2.0)) { + this.targetPosition = BlockPos.containing( + this.getX() + this.random.nextInt(7) - this.random.nextInt(7), + this.getY() + this.random.nextInt(6) - 2.0, + this.getZ() + this.random.nextInt(7) - this.random.nextInt(7)); + } + + double dx = this.targetPosition.getX() + 0.5 - this.getX(); + double dy = this.targetPosition.getY() + 0.1 - this.getY(); + double dz = this.targetPosition.getZ() + 0.5 - this.getZ(); + + Vec3 motion = this.getDeltaMovement(); + Vec3 newMotion = motion.add( + (Math.signum(dx) * 0.25 - motion.x) * 0.1, + (Math.signum(dy) * 0.35 - motion.y) * 0.1, + (Math.signum(dz) * 0.25 - motion.z) * 0.1); + this.setDeltaMovement(newMotion); + + float targetYaw = (float) (Mth.atan2(newMotion.z, newMotion.x) * 180.0 / Math.PI) - 90.0F; + float yawDiff = Mth.wrapDegrees(targetYaw - this.getYRot()); + this.zza = 0.5F; + this.setYRot(this.getYRot() + yawDiff); + } + + @Override + protected SoundEvent getHurtSound(DamageSource damageSource) { + return SoundEvents.BAT_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return SoundEvents.BAT_DEATH; + } + + @Override + public boolean isPushable() { + return false; + } + + @Override + protected PathNavigation createNavigation(Level world) { + return new FlyingPathNavigation(this, world); + } + + @Override + public boolean isFood(ItemStack itemStack) { + return false; + } + + @Override + public @Nullable AgeableMob getBreedOffspring(ServerLevel serverLevel, AgeableMob ageableMob) { + return null; + } + + @Override + public void aiStep() { + super.aiStep(); + this.setNoGravity(true); + } + + @Override + public void setNoGravity(boolean ignored) { + super.setNoGravity(true); + } + + @Override + public boolean causeFallDamage(float l, float d, DamageSource source) { + return false; + } + + @Override + protected void checkFallDamage(double y, boolean onGroundIn, BlockState state, BlockPos pos) { + } + + public static AttributeSupplier.Builder createAttributes() { + AttributeSupplier.Builder builder = Mob.createMobAttributes(); + builder = builder.add(Attributes.MOVEMENT_SPEED, 0.4); + builder = builder.add(Attributes.MAX_HEALTH, 4); + builder = builder.add(Attributes.ARMOR, 0); + builder = builder.add(Attributes.ATTACK_DAMAGE, 0); + builder = builder.add(Attributes.FOLLOW_RANGE, 4); + builder = builder.add(Attributes.STEP_HEIGHT, 0.6); + builder = builder.add(Attributes.FLYING_SPEED, 0.3); + return builder; + } + + private void setupAnimationStates() { + this.idleAnimationState.startIfStopped(this.tickCount); + } + + @Override + public void tick() { + super.tick(); + + if(this.level().isClientSide()) { + this.setupAnimationStates(); + } + } +} diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/custom/PinguinEntity.java b/src/main/java/ovh/glitchlabs/masterwild/entity/custom/PinguinEntity.java new file mode 100644 index 0000000..87579d6 --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/custom/PinguinEntity.java @@ -0,0 +1,144 @@ +package ovh.glitchlabs.masterwild.entity.custom; + +import net.minecraft.Util; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.DifficultyInstance; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.goal.*; +import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; +import net.minecraft.world.entity.animal.Animal; +import net.minecraft.world.entity.animal.Cod; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.ServerLevelAccessor; +import ovh.glitchlabs.masterwild.entity.ModEntities; +import ovh.glitchlabs.masterwild.entity.PinguinVariants; + +import javax.annotation.Nullable; + +public class PinguinEntity extends Animal { + public static final AnimationState idleAnimationState = new AnimationState(); + private int idleAnimationTimeout = 0; + + private static final EntityDataAccessor VARIANT = + SynchedEntityData.defineId(PinguinEntity.class, EntityDataSerializers.INT); + + public PinguinEntity(EntityType entityType, Level level) { + super(entityType, level); + xpReward = 0; + setNoAi(false); + } + + public static AttributeSupplier.Builder createAttributes() { + AttributeSupplier.Builder builder = Mob.createMobAttributes(); + builder = builder.add(Attributes.MOVEMENT_SPEED, 0.3); + builder = builder.add(Attributes.MAX_HEALTH, 6); + builder = builder.add(Attributes.ARMOR, 0); + builder = builder.add(Attributes.ATTACK_DAMAGE, 3); + builder = builder.add(Attributes.FOLLOW_RANGE, 4); + builder = builder.add(Attributes.STEP_HEIGHT, 0.6); + return builder; + } + + @Override + public boolean isFood(ItemStack stack) { + return Ingredient.of(new ItemStack(Items.COD)).test(stack); + } + + @Override + protected void registerGoals() { + super.registerGoals(); + this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1, false) { + @Override + protected boolean canPerformAttack(LivingEntity entity) { + return this.isTimeToAttack() && this.mob.distanceToSqr(entity) < (this.mob.getBbWidth() * this.mob.getBbWidth() + entity.getBbWidth()) && this.mob.getSensing().hasLineOfSight(entity); + } + }); + this.targetSelector.addGoal(2, new NearestAttackableTargetGoal(this, Cod.class, true, true)); + this.goalSelector.addGoal(3, new WaterAvoidingRandomStrollGoal(this, 0.8)); + this.goalSelector.addGoal(4, new PanicGoal(this, 1)); + this.goalSelector.addGoal(5, new FollowParentGoal(this, 0.8)); + this.goalSelector.addGoal(6, new BreedGoal(this, 1)); + this.goalSelector.addGoal(7, new RandomLookAroundGoal(this)); + this.goalSelector.addGoal(8, new FloatGoal(this)); + this.goalSelector.addGoal(10, new TemptGoal(this, 1, (Ingredient.of(Items.COD, Items.SALMON)), false)); + } + + protected void dropCustomDeathLoot(ServerLevel serverLevel, DamageSource source, boolean recentlyHitIn) { + super.dropCustomDeathLoot(serverLevel, source, recentlyHitIn); + this.spawnAtLocation(new ItemStack(Items.COD)); + } + + @Override + public AgeableMob getBreedOffspring(ServerLevel serverWorld, AgeableMob ageable) { + PinguinEntity retval = ModEntities.PINGUIN.get().create(serverWorld); + retval.finalizeSpawn(serverWorld, serverWorld.getCurrentDifficultyAt(retval.blockPosition()), MobSpawnType.BREEDING, null); + return retval; + } + + private void setupAnimationStates() { + if(this.idleAnimationTimeout <= 0) { + this.idleAnimationTimeout = 5; + this.idleAnimationState.start(this.tickCount); + } else { + --this.idleAnimationTimeout; + } + } + + @Override + public void tick() { + super.tick(); + + if(this.level().isClientSide()) { + this.setupAnimationStates(); + } + } + + @Override + protected void defineSynchedData(SynchedEntityData.Builder builder) { + super.defineSynchedData(builder); + builder.define(VARIANT, 0); + } + + private int getTypeVariant() { + return this.entityData.get(VARIANT); + } + + public PinguinVariants getVariant() { + return PinguinVariants.byId(this.getTypeVariant() & 255); + } + + private void setVariant(PinguinVariants variant) { + this.entityData.set(VARIANT, variant.getId() & 255); + } + + @Override + public void addAdditionalSaveData(CompoundTag compound) { + super.addAdditionalSaveData(compound); + compound.putInt("Variant", this.getTypeVariant()); + } + + @Override + public void readAdditionalSaveData(CompoundTag compound) { + super.readAdditionalSaveData(compound); + this.entityData.set(VARIANT, compound.getInt("Variant")); + } + + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, + MobSpawnType spawnType, @Nullable SpawnGroupData spawnGroupData) { + PinguinVariants variants = Util.getRandom(PinguinVariants.values(), this.random); + this.setVariant(variants); + return super.finalizeSpawn(level, difficulty, spawnType, spawnGroupData); + } + +} diff --git a/src/main/java/ovh/glitchlabs/masterwild/entity/custom/RoosterEntity.java b/src/main/java/ovh/glitchlabs/masterwild/entity/custom/RoosterEntity.java new file mode 100644 index 0000000..5f48088 --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/entity/custom/RoosterEntity.java @@ -0,0 +1,120 @@ +package ovh.glitchlabs.masterwild.entity.custom; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.AgeableMob; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.goal.*; +import net.minecraft.world.entity.animal.Animal; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.pathfinder.PathType; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.event.EventHooks; +import org.jetbrains.annotations.Nullable; +import ovh.glitchlabs.masterwild.Sounds.ModSounds; + +public class RoosterEntity extends Animal { + + boolean newDay = false; + private long lastDay; + + public RoosterEntity(EntityType entityType, Level level) { + super(entityType, level); + xpReward = 10; + setNoAi(false); + this.setPathfindingMalus(PathType.WATER, 0.0F); + } + + public static AttributeSupplier.Builder createAttributes() { + AttributeSupplier.Builder builder = Mob.createMobAttributes(); + builder = builder.add(Attributes.MOVEMENT_SPEED, 0.3); + builder = builder.add(Attributes.MAX_HEALTH, 5); + builder = builder.add(Attributes.ARMOR, 0); + builder = builder.add(Attributes.ATTACK_DAMAGE, 0); + builder = builder.add(Attributes.FOLLOW_RANGE, 16); + builder = builder.add(Attributes.STEP_HEIGHT, 0.6); + return builder; + } + + @Override + protected void registerGoals() { + this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(1, new PanicGoal(this, 1.4)); + this.goalSelector.addGoal(2, new BreedGoal(this, 1.0)); + this.goalSelector.addGoal(3, new TemptGoal(this, 1.0, p_335679_ -> p_335679_.is(ItemTags.CHICKEN_FOOD), false)); + this.goalSelector.addGoal(4, new FollowParentGoal(this, 1.1)); + this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 1.0)); + this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F)); + this.goalSelector.addGoal(7, new RandomLookAroundGoal(this)); + } + + @Override + protected SoundEvent getAmbientSound() { + return SoundEvents.CHICKEN_AMBIENT; + } + + @Override + protected SoundEvent getHurtSound(DamageSource damageSource) { + return SoundEvents.CHICKEN_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return SoundEvents.CHICKEN_DEATH; + } + + @Override + protected void playStepSound(BlockPos blockPos, BlockState blockState) { + this.playSound(SoundEvents.CHICKEN_STEP, 0.15F, 1.0F); + } + + @Override + public boolean isFood(ItemStack stack) { + return Ingredient.of(new ItemStack(Items.WHEAT_SEEDS)).test(stack); + } + + + @Override + public @Nullable AgeableMob getBreedOffspring(ServerLevel serverLevel, AgeableMob ageableMob) { + return null; + } + + protected void dropCustomDeathLoot(ServerLevel serverLevel, DamageSource source, boolean recentlyHitIn) { + super.dropCustomDeathLoot(serverLevel, source, recentlyHitIn); + this.spawnAtLocation(new ItemStack(Items.CHICKEN)); + } + + @Override + public void tick() { + super.tick(); + if (!this.level().isClientSide() && !level().isRaining() && !level().isThundering()) { + long day = this.level().getDayTime() / 24000L; + long lastDay = -1; + if (this.lastDay != -1 && day != this.lastDay) { + this.onNewDay(); + } + this.lastDay = day; + } + + } + + private void onNewDay() { + this.playSound(ModSounds.ROOSTER_CROW.get(), 2.0f, 0.8f + this.random.nextFloat() * 0.4f); + } + + +} diff --git a/src/main/java/ovh/glitchlabs/masterwild/event/ModEventBusEvents.java b/src/main/java/ovh/glitchlabs/masterwild/event/ModEventBusEvents.java new file mode 100644 index 0000000..b291dad --- /dev/null +++ b/src/main/java/ovh/glitchlabs/masterwild/event/ModEventBusEvents.java @@ -0,0 +1,31 @@ +package ovh.glitchlabs.masterwild.event; + +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.EntityRenderersEvent; +import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent; +import ovh.glitchlabs.masterwild.Masterwild; +import ovh.glitchlabs.masterwild.entity.ModEntities; +import ovh.glitchlabs.masterwild.entity.client.Pinguin.PinguinModel; +import ovh.glitchlabs.masterwild.entity.client.Rooster.RoosterModel; +import ovh.glitchlabs.masterwild.entity.client.firefly.FireflyModel; +import ovh.glitchlabs.masterwild.entity.custom.FireflyEntity; +import ovh.glitchlabs.masterwild.entity.custom.PinguinEntity; +import ovh.glitchlabs.masterwild.entity.custom.RoosterEntity; + +@EventBusSubscriber(modid = Masterwild.MODID, bus = EventBusSubscriber.Bus.MOD) +public class ModEventBusEvents { + @SubscribeEvent + public static void registerLayers(EntityRenderersEvent.RegisterLayerDefinitions event) { + event.registerLayerDefinition(PinguinModel.LAYER_LOCATION, PinguinModel::createBodyLayer); + event.registerLayerDefinition(FireflyModel.LAYER_LOCATION, FireflyModel::createBodyLayer); + event.registerLayerDefinition(RoosterModel.LAYER_LOCATION, RoosterModel::createBodyLayer); + } + + @SubscribeEvent + public static void registerAttributes(EntityAttributeCreationEvent event) { + event.put(ModEntities.PINGUIN.get(), PinguinEntity.createAttributes().build()); + event.put(ModEntities.FIREFLY.get(), FireflyEntity.createAttributes().build()); + event.put(ModEntities.ROOSTER.get(), RoosterEntity.createAttributes().build()); + } +} diff --git a/src/main/resources/assets/masterwild/sounds.json b/src/main/resources/assets/masterwild/sounds.json new file mode 100644 index 0000000..9310ba8 --- /dev/null +++ b/src/main/resources/assets/masterwild/sounds.json @@ -0,0 +1,6 @@ +{ + "rooster_crow": { + "subtitle": "subtitles.masterwild.rooster_crow", + "sounds": ["masterwild:rooster_crow"] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/masterwild/sounds/rooster_crow.ogg b/src/main/resources/assets/masterwild/sounds/rooster_crow.ogg new file mode 100755 index 0000000..59c42c8 Binary files /dev/null and b/src/main/resources/assets/masterwild/sounds/rooster_crow.ogg differ diff --git a/src/main/resources/assets/masterwild/textures/entity/firefly.png b/src/main/resources/assets/masterwild/textures/entity/firefly.png new file mode 100755 index 0000000..7ff0e66 Binary files /dev/null and b/src/main/resources/assets/masterwild/textures/entity/firefly.png differ diff --git a/src/main/resources/assets/masterwild/textures/entity/firefly_glow.png b/src/main/resources/assets/masterwild/textures/entity/firefly_glow.png new file mode 100755 index 0000000..3766076 Binary files /dev/null and b/src/main/resources/assets/masterwild/textures/entity/firefly_glow.png differ diff --git a/src/main/resources/assets/masterwild/textures/entity/pinguin.png b/src/main/resources/assets/masterwild/textures/entity/pinguin.png new file mode 100755 index 0000000..a248a26 Binary files /dev/null and b/src/main/resources/assets/masterwild/textures/entity/pinguin.png differ diff --git a/src/main/resources/assets/masterwild/textures/entity/pinguin_rare.png b/src/main/resources/assets/masterwild/textures/entity/pinguin_rare.png new file mode 100755 index 0000000..f27ad7b Binary files /dev/null and b/src/main/resources/assets/masterwild/textures/entity/pinguin_rare.png differ diff --git a/src/main/resources/assets/masterwild/textures/entity/rooster.png b/src/main/resources/assets/masterwild/textures/entity/rooster.png new file mode 100755 index 0000000..8d476d8 Binary files /dev/null and b/src/main/resources/assets/masterwild/textures/entity/rooster.png differ diff --git a/src/main/templates/META-INF/neoforge.mods.toml b/src/main/templates/META-INF/neoforge.mods.toml index b2648cd..8df9d4a 100644 --- a/src/main/templates/META-INF/neoforge.mods.toml +++ b/src/main/templates/META-INF/neoforge.mods.toml @@ -23,7 +23,7 @@ displayName = "${mod_name}" #mandatory # A URL to query for updates for this mod. See the JSON update specification https://docs.neoforge.net/docs/misc/updatechecker/ #updateJSONURL="https://change.me.example.invalid/updates.json" #optional # A URL for the "homepage" for this mod, displayed in the mod UI -displayURL = "www.glitchlabs.ovh" #optional +displayURL = "glitchlabs.ovh" #optional # A file name (in the root of the mod JAR) containing a logo for display #logoFile="masterwild.png" #optional # A text field displayed in the mod UI