From 5d8d160f9837501c250871481bf39f03800b6649 Mon Sep 17 00:00:00 2001 From: TheClashFruit Date: Mon, 18 Dec 2023 18:12:33 +0100 Subject: [PATCH] feat: add penguin --- .../java/me/theclashfruit/arctic/Arctic.java | 34 ++++++++ .../arctic/client/ArcticClient.java | 8 +- .../entity/penguin/BabyEmperorModel.java | 24 ++++++ .../entity/penguin/BabyEmperorRenderer.java | 20 +++++ .../arctic/entity/ModEntities.java | 22 +++++ .../entity/penguin/BabyEmperorEntity.java | 63 ++++++++++++++ .../penguin/baby_emperor.animation.json | 53 ++++++++++++ .../arctic/geo/penguin/baby_emperor.geo.json | 79 ++++++++++++++++++ .../models/item/baby_emperor_spawn_egg.json | 3 + .../textures/entity/penguin/baby_emperor.png | Bin 0 -> 4007 bytes 10 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 src/main/java/me/theclashfruit/arctic/client/entity/penguin/BabyEmperorModel.java create mode 100644 src/main/java/me/theclashfruit/arctic/client/entity/penguin/BabyEmperorRenderer.java create mode 100644 src/main/java/me/theclashfruit/arctic/entity/ModEntities.java create mode 100644 src/main/java/me/theclashfruit/arctic/entity/penguin/BabyEmperorEntity.java create mode 100644 src/main/resources/assets/arctic/animations/penguin/baby_emperor.animation.json create mode 100644 src/main/resources/assets/arctic/geo/penguin/baby_emperor.geo.json create mode 100644 src/main/resources/assets/arctic/models/item/baby_emperor_spawn_egg.json create mode 100644 src/main/resources/assets/arctic/textures/entity/penguin/baby_emperor.png diff --git a/src/main/java/me/theclashfruit/arctic/Arctic.java b/src/main/java/me/theclashfruit/arctic/Arctic.java index 28637c2..a27c6d1 100644 --- a/src/main/java/me/theclashfruit/arctic/Arctic.java +++ b/src/main/java/me/theclashfruit/arctic/Arctic.java @@ -1,7 +1,19 @@ package me.theclashfruit.arctic; +import me.theclashfruit.arctic.entity.ModEntities; +import me.theclashfruit.arctic.entity.penguin.BabyEmperorEntity; import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.item.v1.FabricItemSettings; +import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; +import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry; +import net.minecraft.item.Item; +import net.minecraft.item.ItemGroups; +import net.minecraft.item.Items; +import net.minecraft.item.SpawnEggItem; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,11 +23,33 @@ public class Arctic implements ModInitializer { public static final String MOD_ID = "arctic"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + /* Items */ + + public static final Item BABY_EMPEROR_SPAWN_EGG = new SpawnEggItem( + ModEntities.BABY_EMPEROR, + 0xB00B69, + 0xffffff, + new FabricItemSettings().maxCount(1) + ); + /** * Runs the mod initializer. */ @Override public void onInitialize() { + FabricDefaultAttributeRegistry.register( + ModEntities.BABY_EMPEROR, + BabyEmperorEntity.createBabyEmperorAttributes() + ); + + // ------------------------------ // + + Registry.register(Registries.ITEM, new Identifier(MOD_ID, "baby_emperor_spawn_egg"), BABY_EMPEROR_SPAWN_EGG); + + ItemGroupEvents.modifyEntriesEvent(ItemGroups.SPAWN_EGGS).register(content -> { + content.addAfter(Items.AXOLOTL_SPAWN_EGG, BABY_EMPEROR_SPAWN_EGG); + }); + GeckoLib.initialize(); } } \ No newline at end of file diff --git a/src/main/java/me/theclashfruit/arctic/client/ArcticClient.java b/src/main/java/me/theclashfruit/arctic/client/ArcticClient.java index ce2d303..9603f99 100644 --- a/src/main/java/me/theclashfruit/arctic/client/ArcticClient.java +++ b/src/main/java/me/theclashfruit/arctic/client/ArcticClient.java @@ -1,6 +1,9 @@ package me.theclashfruit.arctic.client; +import me.theclashfruit.arctic.client.entity.penguin.BabyEmperorRenderer; +import me.theclashfruit.arctic.entity.ModEntities; import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; public class ArcticClient implements ClientModInitializer { /** @@ -8,6 +11,9 @@ public class ArcticClient implements ClientModInitializer { */ @Override public void onInitializeClient() { - + EntityRendererRegistry.register( + ModEntities.BABY_EMPEROR, + BabyEmperorRenderer::new + ); } } \ No newline at end of file diff --git a/src/main/java/me/theclashfruit/arctic/client/entity/penguin/BabyEmperorModel.java b/src/main/java/me/theclashfruit/arctic/client/entity/penguin/BabyEmperorModel.java new file mode 100644 index 0000000..612ae1c --- /dev/null +++ b/src/main/java/me/theclashfruit/arctic/client/entity/penguin/BabyEmperorModel.java @@ -0,0 +1,24 @@ +package me.theclashfruit.arctic.client.entity.penguin; + +import me.theclashfruit.arctic.entity.penguin.BabyEmperorEntity; +import net.minecraft.util.Identifier; +import software.bernie.geckolib.model.GeoModel; + +import static me.theclashfruit.arctic.Arctic.MOD_ID; + +public class BabyEmperorModel extends GeoModel { + @Override + public Identifier getModelResource(BabyEmperorEntity animatable) { + return new Identifier(MOD_ID, "geo/penguin/baby_emperor.geo.json"); + } + + @Override + public Identifier getTextureResource(BabyEmperorEntity animatable) { + return new Identifier(MOD_ID, "textures/entity/penguin/baby_emperor.png"); + } + + @Override + public Identifier getAnimationResource(BabyEmperorEntity animatable) { + return new Identifier(MOD_ID, "animations/penguin/baby_emperor.animation.json"); + } +} diff --git a/src/main/java/me/theclashfruit/arctic/client/entity/penguin/BabyEmperorRenderer.java b/src/main/java/me/theclashfruit/arctic/client/entity/penguin/BabyEmperorRenderer.java new file mode 100644 index 0000000..1a7630d --- /dev/null +++ b/src/main/java/me/theclashfruit/arctic/client/entity/penguin/BabyEmperorRenderer.java @@ -0,0 +1,20 @@ +package me.theclashfruit.arctic.client.entity.penguin; + +import me.theclashfruit.arctic.entity.penguin.BabyEmperorEntity; +import net.minecraft.client.render.entity.EntityRendererFactory; +import net.minecraft.util.Identifier; +import software.bernie.geckolib.model.GeoModel; +import software.bernie.geckolib.renderer.GeoEntityRenderer; + +import static me.theclashfruit.arctic.Arctic.MOD_ID; + +public class BabyEmperorRenderer extends GeoEntityRenderer { + public BabyEmperorRenderer(EntityRendererFactory.Context ctx) { + super(ctx, new BabyEmperorModel()); + } + + @Override + public Identifier getTextureLocation(BabyEmperorEntity animatable) { + return new Identifier(MOD_ID, "textures/entity/penguin/baby_emperor.png"); + } +} diff --git a/src/main/java/me/theclashfruit/arctic/entity/ModEntities.java b/src/main/java/me/theclashfruit/arctic/entity/ModEntities.java new file mode 100644 index 0000000..5d1e93f --- /dev/null +++ b/src/main/java/me/theclashfruit/arctic/entity/ModEntities.java @@ -0,0 +1,22 @@ +package me.theclashfruit.arctic.entity; + +import me.theclashfruit.arctic.entity.penguin.BabyEmperorEntity; +import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder; +import net.minecraft.entity.EntityDimensions; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.SpawnGroup; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; + +import static me.theclashfruit.arctic.Arctic.MOD_ID; + +public class ModEntities { + public static final EntityType BABY_EMPEROR = Registry.register( + Registries.ENTITY_TYPE, + new Identifier(MOD_ID, "baby_emperor"), + FabricEntityTypeBuilder.create(SpawnGroup.CREATURE, BabyEmperorEntity::new) + .dimensions(EntityDimensions.fixed(0.8f, 1f)) + .build() + ); +} diff --git a/src/main/java/me/theclashfruit/arctic/entity/penguin/BabyEmperorEntity.java b/src/main/java/me/theclashfruit/arctic/entity/penguin/BabyEmperorEntity.java new file mode 100644 index 0000000..cf55fc8 --- /dev/null +++ b/src/main/java/me/theclashfruit/arctic/entity/penguin/BabyEmperorEntity.java @@ -0,0 +1,63 @@ +package me.theclashfruit.arctic.entity.penguin; + +import net.minecraft.entity.EntityType; +import net.minecraft.entity.ai.goal.SwimGoal; +import net.minecraft.entity.ai.goal.WanderAroundGoal; +import net.minecraft.entity.attribute.DefaultAttributeContainer; +import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.entity.passive.AnimalEntity; +import net.minecraft.entity.passive.PassiveEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; +import software.bernie.geckolib.animatable.GeoEntity; +import software.bernie.geckolib.core.animatable.GeoAnimatable; +import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; +import software.bernie.geckolib.core.animation.AnimatableManager; +import software.bernie.geckolib.core.animation.AnimationController; +import software.bernie.geckolib.core.animation.AnimationState; +import software.bernie.geckolib.core.animation.RawAnimation; +import software.bernie.geckolib.core.object.PlayState; +import software.bernie.geckolib.util.GeckoLibUtil; + +public class BabyEmperorEntity extends AnimalEntity implements GeoEntity { + private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this); + + public BabyEmperorEntity(EntityType entityType, World world) { + super(entityType, world); + } + + public static DefaultAttributeContainer.Builder createBabyEmperorAttributes() { + return AnimalEntity.createMobAttributes() + .add(EntityAttributes.GENERIC_MAX_HEALTH, 15.0D) + .add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.25D); + } + + @Nullable + @Override + public PassiveEntity createChild(ServerWorld world, PassiveEntity entity) { + return null; + } + + @Override + protected void initGoals() { + this.goalSelector.add(0, new SwimGoal(this)); + this.goalSelector.add(1, new WanderAroundGoal(this, 1.0D)); + } + + protected PlayState predicate(final AnimationState event) { + return event.setAndContinue( + RawAnimation.begin().thenLoop("animation.FM-Penguin.new") + ); + } + + @Override + public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { + controllers.add(new AnimationController<>(this, "controller", 0, this::predicate)); + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return this.geoCache; + } +} diff --git a/src/main/resources/assets/arctic/animations/penguin/baby_emperor.animation.json b/src/main/resources/assets/arctic/animations/penguin/baby_emperor.animation.json new file mode 100644 index 0000000..b231957 --- /dev/null +++ b/src/main/resources/assets/arctic/animations/penguin/baby_emperor.animation.json @@ -0,0 +1,53 @@ +{ + "format_version": "1.8.0", + "animations": { + "animation.FM-Penguin.new": { + "animation_length": 1.75, + "bones": { + "RightArm": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.5": { + "vector": [0, 0, 0], + "easing": "easeInBack" + }, + "1.0": { + "vector": [0, 0, -30], + "easing": "easeInBack" + }, + "1.5": { + "vector": [0, 0, 5], + "easing": "easeInBack" + }, + "1.75": { + "vector": [0, 0, 0], + "easing": "easeInBack" + } + } + }, + "LeftArm": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.5": { + "vector": [0, 0, 25], + "easing": "easeInBack" + }, + "1.0": { + "vector": [0, 0, -5], + "easing": "easeInBack" + }, + "1.25": { + "vector": [0, 0, 0], + "easing": "easeInBack" + } + } + } + } + } + }, + "geckolib_format_version": 2 +} \ No newline at end of file diff --git a/src/main/resources/assets/arctic/geo/penguin/baby_emperor.geo.json b/src/main/resources/assets/arctic/geo/penguin/baby_emperor.geo.json new file mode 100644 index 0000000..2551762 --- /dev/null +++ b/src/main/resources/assets/arctic/geo/penguin/baby_emperor.geo.json @@ -0,0 +1,79 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.Arctic-Penguin-BabyEmperor", + "texture_width": 64, + "texture_height": 64, + "visible_bounds_width": 2, + "visible_bounds_height": 2.5, + "visible_bounds_offset": [0, 0.75, 0] + }, + "bones": [ + { + "name": "bb_main", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [-4, 0.5, -3], "size": [8, 10, 6], "uv": [0, 0]}, + {"origin": [-3, 10.5, -2.75], "size": [6, 5, 5.5], "uv": [0, 16]} + ] + }, + { + "name": "Foots", + "pivot": [0, 0, 0] + }, + { + "name": "LeftFoot", + "parent": "Foots", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [0.5, 0, -3.75], "size": [3, 1, 6], "pivot": [0, 0, 0], "rotation": [2.5, -2.5, 0], "uv": [0, 28]} + ] + }, + { + "name": "RightFoot", + "parent": "Foots", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [-3.5, 0, -3.75], "size": [3, 1, 6], "pivot": [0, 0, 0], "rotation": [2.5, 2.5, 0], "uv": [28, 0]} + ] + }, + { + "name": "Tail", + "pivot": [0, 0.5, 2.5], + "cubes": [ + {"origin": [-1.5, 0.5, 2.5], "size": [3, 1, 2], "pivot": [0, 0.5, 2.5], "rotation": [-5, 0, 0], "uv": [22, 0]} + ] + }, + { + "name": "Beak", + "pivot": [0, 11.6, -2], + "cubes": [ + {"origin": [-1, 11.35, -4], "size": [2, 1, 2], "pivot": [0, 11.6, -2], "rotation": [7.5, 0, 0], "uv": [22, 3]} + ] + }, + { + "name": "Arms", + "pivot": [-4, 10.5, 0] + }, + { + "name": "RightArm", + "parent": "Arms", + "pivot": [4, 10.5, 0], + "cubes": [ + {"origin": [3.25, 2.2, -2.75], "size": [1, 8.25, 5.5], "pivot": [4, 10.5, 0], "rotation": [0, 0, -5], "uv": [24, 11]} + ] + }, + { + "name": "LeftArm", + "parent": "Arms", + "pivot": [-4, 10.5, 0], + "cubes": [ + {"origin": [-4.25, 2.2, -2.75], "size": [1, 8.25, 5.5], "pivot": [-4, 10.5, 0], "rotation": [0, 0, 5], "uv": [17, 21]} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/arctic/models/item/baby_emperor_spawn_egg.json b/src/main/resources/assets/arctic/models/item/baby_emperor_spawn_egg.json new file mode 100644 index 0000000..d1aaa9d --- /dev/null +++ b/src/main/resources/assets/arctic/models/item/baby_emperor_spawn_egg.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:item/template_spawn_egg" +} \ No newline at end of file diff --git a/src/main/resources/assets/arctic/textures/entity/penguin/baby_emperor.png b/src/main/resources/assets/arctic/textures/entity/penguin/baby_emperor.png new file mode 100644 index 0000000000000000000000000000000000000000..b13b97113f7bef55ce139fc35c164804e108ebb8 GIT binary patch literal 4007 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 wDz>GA