From 9f7f87634334bbe1f82e9e0f790f371401f51ff6 Mon Sep 17 00:00:00 2001 From: ian1337 Date: Thu, 24 Sep 2026 16:51:27 +0200 Subject: [PATCH] [add] Rooster - [add] Rooster sounds - [add] Rooster newday craw [add] firefly - [fix] firefly ai similar to bat ai [add] pinguin --- .../masterwild/Block/ModBlocks.java | 34 +++ .../glitchlabs/masterwild/Item/ModItems.java | 30 ++ .../ovh/glitchlabs/masterwild/Masterwild.java | 82 ++---- .../masterwild/Sounds/ModSounds.java | 26 ++ .../masterwild/entity/ModEntities.java | 35 +++ .../masterwild/entity/PinguinVariants.java | 26 ++ .../client/Pinguin/PinguinAnimation.java | 59 ++++ .../entity/client/Pinguin/PinguinModel.java | 260 ++++++++++++++++++ .../client/Pinguin/PinguinRenderer.java | 45 +++ .../entity/client/Rooster/RoosterModel.java | 99 +++++++ .../client/Rooster/RoosterRenderer.java | 32 +++ .../client/firefly/FireflyAnimation.java | 94 +++++++ .../client/firefly/FireflyGlowLayer.java | 22 ++ .../entity/client/firefly/FireflyModel.java | 98 +++++++ .../client/firefly/FireflyRenderer.java | 28 ++ .../entity/custom/FireflyEntity.java | 146 ++++++++++ .../entity/custom/PinguinEntity.java | 144 ++++++++++ .../entity/custom/RoosterEntity.java | 120 ++++++++ .../masterwild/event/ModEventBusEvents.java | 31 +++ .../resources/assets/masterwild/sounds.json | 6 + .../assets/masterwild/sounds/rooster_crow.ogg | Bin 0 -> 43934 bytes .../masterwild/textures/entity/firefly.png | Bin 0 -> 771 bytes .../textures/entity/firefly_glow.png | Bin 0 -> 258 bytes .../masterwild/textures/entity/pinguin.png | Bin 0 -> 2703 bytes .../textures/entity/pinguin_rare.png | Bin 0 -> 3293 bytes .../masterwild/textures/entity/rooster.png | Bin 0 -> 1477 bytes .../templates/META-INF/neoforge.mods.toml | 2 +- 27 files changed, 1355 insertions(+), 64 deletions(-) create mode 100644 src/main/java/ovh/glitchlabs/masterwild/Block/ModBlocks.java create mode 100644 src/main/java/ovh/glitchlabs/masterwild/Item/ModItems.java create mode 100644 src/main/java/ovh/glitchlabs/masterwild/Sounds/ModSounds.java create mode 100644 src/main/java/ovh/glitchlabs/masterwild/entity/ModEntities.java create mode 100644 src/main/java/ovh/glitchlabs/masterwild/entity/PinguinVariants.java create mode 100755 src/main/java/ovh/glitchlabs/masterwild/entity/client/Pinguin/PinguinAnimation.java create mode 100755 src/main/java/ovh/glitchlabs/masterwild/entity/client/Pinguin/PinguinModel.java create mode 100644 src/main/java/ovh/glitchlabs/masterwild/entity/client/Pinguin/PinguinRenderer.java create mode 100755 src/main/java/ovh/glitchlabs/masterwild/entity/client/Rooster/RoosterModel.java create mode 100644 src/main/java/ovh/glitchlabs/masterwild/entity/client/Rooster/RoosterRenderer.java create mode 100755 src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyAnimation.java create mode 100644 src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyGlowLayer.java create mode 100755 src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyModel.java create mode 100644 src/main/java/ovh/glitchlabs/masterwild/entity/client/firefly/FireflyRenderer.java create mode 100644 src/main/java/ovh/glitchlabs/masterwild/entity/custom/FireflyEntity.java create mode 100644 src/main/java/ovh/glitchlabs/masterwild/entity/custom/PinguinEntity.java create mode 100644 src/main/java/ovh/glitchlabs/masterwild/entity/custom/RoosterEntity.java create mode 100644 src/main/java/ovh/glitchlabs/masterwild/event/ModEventBusEvents.java create mode 100644 src/main/resources/assets/masterwild/sounds.json create mode 100755 src/main/resources/assets/masterwild/sounds/rooster_crow.ogg create mode 100755 src/main/resources/assets/masterwild/textures/entity/firefly.png create mode 100755 src/main/resources/assets/masterwild/textures/entity/firefly_glow.png create mode 100755 src/main/resources/assets/masterwild/textures/entity/pinguin.png create mode 100755 src/main/resources/assets/masterwild/textures/entity/pinguin_rare.png create mode 100755 src/main/resources/assets/masterwild/textures/entity/rooster.png 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 0000000000000000000000000000000000000000..59c42c85aa403ae1fdd755dd77a2f0afd7e3733c GIT binary patch literal 43934 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 nPc!j>w$(xn%JykCs7(W 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a248a2607be4681a090b53b65ffd6f401ec7ac34 GIT binary patch literal 2703 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 bK~w_(VK^wv&<}4B00000NkvXXu0mjfEoeV; literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..8d476d820d3a099588f2eb9c4eaeb8b3f1817707 GIT binary patch literal 1477 zcmV;$1v>hPP)9M35X~N!M?1v4QR!@iBHytf)7PRUj(fPf-h1P zDFmg9T4`)RYPCj+PonLEwoNdlO^9{l+L+B|cgOkWGI93i?(N;(_U`TO4f*alGw00Q zbIzQdGxuIjE`O(X^$HV5pXw8j4&A>BE>o-$O@7ob(0S!(zYsrJyq!Ys7hD4XBT|KC zx|oj<=z?fMS5@fjscQIjAM6?cIBnjsjpfZ|MSRcBNrr)-Y@5Z~Ddc{^H2~&{g9rRF z%&+^n1^_Frodys1Wtd<0aSZ^Rhtq&x2Kjv-*8uc3EzugDD?%j(4kfmzoxhT?H+l>= z%bcBey7}vEDY8S4Lz&dPrf`0qZYNNu`D)$A?K{0T=wG2WYu#L-rTX3KVC{DsZ6o@z6sMl0TeY9d!t60DdUbMh6zw z6yg2FPC`GZDMQ<-A3C}pIwor1Q(3p2T=4Nkey;4-`oAR=(sey7)8N5{Z|EzEF zUhTrB=T$c-dPM<1>b^1?Cjk5t^J~dOwML)ZevcTxYlGZfteKKqHspTXx^cm3)#j?s z0UsppR*$$ap}U(C0RG{~6205;Hy!VqQ8;Bh9z$LZzIte*INu(j<(>#35OBPO^ZdD7 zJ~j40-%>eqRikSkt1=)a_iqTIg$!jf)&hY?pO%5I1|5-R%H{=4cgAQglcmeKTnk_0x0@W%R%ihvqAGXHlwUMod_Q}{TqAX+q10qy)lX( zK1tEh@0&i~w(Cydtp^jW_WAv4s{pLy)^k3bMh0jKBeV>>7o_FE3PGDKL`ZLnntB=U zw~h*czG*reQ!Ijz<#ENAd&$U?pbkP-1_Ob>96C!5y)i^@zW5luz5hwtcXf0HS`J-5 z!3RIP$N*itkAM9;JJ7MH9(d3PnG@WM{HG9=$Khtm$N=Odpo=V+%ttAe=G5BCs3k5) zwdE@}$ZLh74A4g49iZk*Q3S^w5XfW65J>UjV`#(%7{54~l4~O-4zV5X|;L}%# z+IOTGFtBHq#Wx)+aymJBrl@VrRNE{6aPxXGw|h`offZAX%SC_F>wkWdX&&G9z@yJ) zXdp#=