bread monster entity wip

This commit is contained in:
YuRaNnNzZZ 2025-02-27 22:01:35 +03:00
parent d362c135d7
commit 7ba2e020b7
Signed by: YuRaNnNzZZ
GPG Key ID: 5F71738C85A6006D
9 changed files with 233 additions and 49 deletions

View File

@ -0,0 +1,77 @@
package ru.dbotthepony.mc.otm.client.animation;
import net.minecraft.client.animation.AnimationChannel;
import net.minecraft.client.animation.AnimationDefinition;
import net.minecraft.client.animation.Keyframe;
import net.minecraft.client.animation.KeyframeAnimations;
public class BreadMonsterAnimation {
public static final AnimationDefinition IDLE = AnimationDefinition.Builder.withLength(1.44F).looping()
.addAnimation("Body", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, -2.5F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.72F, KeyframeAnimations.degreeVec(0.0F, 3.33F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(1.44F, KeyframeAnimations.degreeVec(0.0F, -2.5F, 0.0F), AnimationChannel.Interpolations.LINEAR)
))
.addAnimation("Ljaw", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.72F, KeyframeAnimations.degreeVec(5.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(1.44F, KeyframeAnimations.degreeVec(2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR)
))
.addAnimation("UJaw", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(-2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.72F, KeyframeAnimations.degreeVec(-5.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(1.44F, KeyframeAnimations.degreeVec(-2.5F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR)
))
.addAnimation("tail", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 5.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.72F, KeyframeAnimations.degreeVec(0.0F, -7.5F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(1.44F, KeyframeAnimations.degreeVec(0.0F, 5.0F, 0.0F), AnimationChannel.Interpolations.LINEAR)
))
.build();
public static final AnimationDefinition MOVE = AnimationDefinition.Builder.withLength(1.44F).looping()
.addAnimation("root", new AnimationChannel(AnimationChannel.Targets.POSITION,
new Keyframe(0.0F, KeyframeAnimations.posVec(1.0F, 0.0F, 2.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.12F, KeyframeAnimations.posVec(0.0F, 5.0F, -1.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.24F, KeyframeAnimations.posVec(-1.0F, 0.0F, -1.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.72F, KeyframeAnimations.posVec(-2.0F, 0.0F, 2.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.84F, KeyframeAnimations.posVec(0.0F, 5.0F, -1.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.96F, KeyframeAnimations.posVec(1.0F, 0.0F, -1.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(1.44F, KeyframeAnimations.posVec(1.0F, 0.0F, 2.0F), AnimationChannel.Interpolations.LINEAR)
))
.addAnimation("Body", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.12F, KeyframeAnimations.degreeVec(7.5283F, 4.9571F, 0.6543F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.2F, KeyframeAnimations.degreeVec(12.5094F, 1.6524F, 0.2181F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.24F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.72F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.84F, KeyframeAnimations.degreeVec(7.5283F, -4.9571F, -0.6543F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.92F, KeyframeAnimations.degreeVec(15.0189F, -3.3047F, -0.4362F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.96F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR)
))
.addAnimation("Ljaw", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.12F, KeyframeAnimations.degreeVec(25.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.32F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.72F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.84F, KeyframeAnimations.degreeVec(25.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(1.04F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR)
))
.addAnimation("UJaw", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.12F, KeyframeAnimations.degreeVec(-25.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.32F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.72F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.84F, KeyframeAnimations.degreeVec(-30.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(1.04F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR)
))
.addAnimation("tail", new AnimationChannel(AnimationChannel.Targets.ROTATION,
new Keyframe(0.0F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.12F, KeyframeAnimations.degreeVec(-10.0374F, -4.9238F, 0.8704F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.24F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.72F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.84F, KeyframeAnimations.degreeVec(-12.5462F, 4.8812F, -1.0848F), AnimationChannel.Interpolations.LINEAR),
new Keyframe(0.96F, KeyframeAnimations.degreeVec(0.0F, 0.0F, 0.0F), AnimationChannel.Interpolations.LINEAR)
))
.build();
}

View File

@ -0,0 +1,73 @@
package ru.dbotthepony.mc.otm.client.model.entity;
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.CubeDeformation;
import net.minecraft.client.model.geom.builders.CubeListBuilder;
import net.minecraft.client.model.geom.builders.LayerDefinition;
import net.minecraft.client.model.geom.builders.MeshDefinition;
import net.minecraft.client.model.geom.builders.PartDefinition;
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
import org.jetbrains.annotations.NotNull;
import ru.dbotthepony.mc.otm.client.animation.BreadMonsterAnimation;
import ru.dbotthepony.mc.otm.entity.BreadMonster;
import ru.dbotthepony.mc.otm.registry.MNames;
import static ru.dbotthepony.mc.otm.OverdriveThatMatters.loc;
public class BreadMonsterModel {
public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(loc(MNames.BREAD_MONSTER), "main");
private static HierarchicalModel<BreadMonster> model;
private static LayerDefinition def;
public static HierarchicalModel<BreadMonster> getModel() {
if (model == null) {
return model = new BreadMonsterHierarchicalModel<>(def.bakeRoot());
}
return model;
}
public static LayerDefinition createBodyLayer() {
MeshDefinition meshdefinition = new MeshDefinition();
PartDefinition partdefinition = meshdefinition.getRoot();
PartDefinition root = partdefinition.addOrReplaceChild("root", CubeListBuilder.create(), PartPose.offset(0.0F, 24.0F, 0.0F));
PartDefinition Body = root.addOrReplaceChild("Body", CubeListBuilder.create().texOffs(0, 0).addBox(-4.0F, -3.0F, -5.0F, 8.0F, 6.0F, 6.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, -3.0F, 0.0F));
PartDefinition Ljaw = Body.addOrReplaceChild("Ljaw", CubeListBuilder.create().texOffs(26, 24).addBox(-4.0F, -2.0F, -4.0F, 8.0F, 3.0F, 4.0F, new CubeDeformation(0.1F)), PartPose.offset(0.0F, 2.0F, -3.0F));
PartDefinition UJaw = Body.addOrReplaceChild("UJaw", CubeListBuilder.create().texOffs(0, 24).addBox(-4.0F, -2.0F, -4.0F, 8.0F, 3.0F, 5.0F, new CubeDeformation(0.1F)), PartPose.offset(0.0F, -1.0F, -3.0F));
PartDefinition tail = Body.addOrReplaceChild("tail", CubeListBuilder.create().texOffs(0, 12).addBox(-4.0F, -3.0F, -0.1F, 8.0F, 6.0F, 6.0F, new CubeDeformation(-0.1F)), PartPose.offset(0.0F, 0.0F, 1.0F));
model = null;
return def = LayerDefinition.create(meshdefinition, 64, 32);
}
private static class BreadMonsterHierarchicalModel<T extends BreadMonster> extends HierarchicalModel<T> {
private final ModelPart root;
public BreadMonsterHierarchicalModel(ModelPart root) {
this.root = root.getChild("root");
}
@Override
public void setupAnim(@NotNull T entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {
this.root().getAllParts().forEach(ModelPart::resetPose);
// this.applyStatic(BreadMonsterAnimation.IDLE);
this.animate(entity.getIdleState(), BreadMonsterAnimation.IDLE, ageInTicks, 1.0F);
this.animateWalk(BreadMonsterAnimation.MOVE, limbSwing, limbSwingAmount, 1.0F, 2.5F);
}
@Override
public @NotNull ModelPart root() {
return this.root;
}
}
public static void register(EntityRenderersEvent.RegisterLayerDefinitions event) {
event.registerLayerDefinition(LAYER_LOCATION, BreadMonsterModel::createBodyLayer);
}
}

View File

@ -24,6 +24,7 @@ import ru.dbotthepony.mc.otm.client.createCursors
import ru.dbotthepony.mc.otm.client.model.ExosuitModel
import ru.dbotthepony.mc.otm.client.model.GravitationStabilizerModel
import ru.dbotthepony.mc.otm.client.model.TritaniumArmorModel
import ru.dbotthepony.mc.otm.client.model.entity.BreadMonsterModel
import ru.dbotthepony.mc.otm.client.onMovementInputUpdate
import ru.dbotthepony.mc.otm.client.onScreenOpen
import ru.dbotthepony.mc.otm.client.onPostScreenInit
@ -92,6 +93,7 @@ import thedarkcolour.kotlinforforge.neoforge.forge.DIST
import thedarkcolour.kotlinforforge.neoforge.forge.FORGE_BUS
import thedarkcolour.kotlinforforge.neoforge.forge.LOADING_CONTEXT
import thedarkcolour.kotlinforforge.neoforge.forge.MOD_BUS
import top.theillusivec4.curios.client.ClientEventHandler
@Mod(OverdriveThatMatters.MOD_ID)
object OverdriveThatMatters {
@ -150,6 +152,7 @@ object OverdriveThatMatters {
MOD_BUS.addListener(EventPriority.NORMAL, AndroidAbilityKeyMapping::register)
MOD_BUS.addListener(EventPriority.NORMAL, TritaniumArmorModel::register)
MOD_BUS.addListener(EventPriority.NORMAL, GravitationStabilizerModel::register)
MOD_BUS.addListener(EventPriority.NORMAL, BreadMonsterModel::register)
MOD_BUS.addListener(EventPriority.NORMAL, MCreativeTabs::register)
MOD_BUS.addListener(EventPriority.NORMAL, BatteryBankRenderer.Companion::onRegisterAdditionalModels)

View File

@ -0,0 +1,18 @@
package ru.dbotthepony.mc.otm.client.render.entity
import net.minecraft.client.model.HierarchicalModel
import net.minecraft.client.renderer.entity.EntityRendererProvider
import net.minecraft.client.renderer.entity.MobRenderer
import net.minecraft.resources.ResourceLocation
import ru.dbotthepony.mc.otm.OverdriveThatMatters.loc
import ru.dbotthepony.mc.otm.client.model.entity.BreadMonsterModel
import ru.dbotthepony.mc.otm.entity.BreadMonster
class BreadMonsterRenderer(context: EntityRendererProvider.Context)
: MobRenderer<BreadMonster, HierarchicalModel<BreadMonster>>(context, BreadMonsterModel.getModel(), 0.9f) {
override fun getTextureLocation(entity: BreadMonster): ResourceLocation = TEXTURE_LOCATION
companion object {
private val TEXTURE_LOCATION = loc("textures/entity/bread_monster.png")
}
}

View File

@ -0,0 +1,43 @@
package ru.dbotthepony.mc.otm.entity
import net.minecraft.world.entity.AnimationState
import net.minecraft.world.entity.EntityType
import net.minecraft.world.entity.ai.attributes.AttributeSupplier
import net.minecraft.world.entity.ai.attributes.Attributes
import net.minecraft.world.entity.ai.goal.LeapAtTargetGoal
import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal
import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation
import net.minecraft.world.entity.ai.navigation.PathNavigation
import net.minecraft.world.entity.monster.Monster
import net.minecraft.world.entity.player.Player
import net.minecraft.world.level.Level
class BreadMonster(type: EntityType<BreadMonster>, level: Level) : Monster(type, level) {
val idleState = AnimationState()
init {
idleState.start(tickCount)
}
override fun registerGoals() {
goalSelector.addGoal(1, LeapAtTargetGoal(this, 0.4f))
goalSelector.addGoal(2, WaterAvoidingRandomStrollGoal(this, 0.8))
goalSelector.addGoal(3, LookAtPlayerGoal(this, Player::class.java, 8f))
goalSelector.addGoal(4, RandomLookAroundGoal(this))
targetSelector.addGoal(1, HurtByTargetGoal(this))
}
override fun createNavigation(level: Level): PathNavigation = GroundPathNavigation(this, level)
companion object {
fun createAttributes() : AttributeSupplier.Builder {
return createMonsterAttributes()
.add(Attributes.MAX_HEALTH, 16.0)
.add(Attributes.MOVEMENT_SPEED, 0.3)
}
}
}

View File

@ -306,6 +306,7 @@ object MNames {
// entities
const val PLASMA = "plasma_projectile"
const val RIDEABLE_DUMMY = "rideable_dummy"
const val BREAD_MONSTER = "bread_monster"
const val PHANTOM_ATTRACTOR = "phantom_attractor"
const val JUMP_BOOST = "jump_boost"

View File

@ -12,7 +12,10 @@ import net.minecraft.world.entity.MobCategory
import net.minecraft.world.item.DyeColor
import net.neoforged.bus.api.IEventBus
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent
import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent
import ru.dbotthepony.mc.otm.client.render.entity.BreadMonsterRenderer
import ru.dbotthepony.mc.otm.client.render.entity.PlasmaProjectileRenderer
import ru.dbotthepony.mc.otm.entity.BreadMonster
import ru.dbotthepony.mc.otm.entity.MinecartCargoCrate
import ru.dbotthepony.mc.otm.entity.PlasmaProjectile
import ru.dbotthepony.mc.otm.entity.RideableDummy
@ -38,11 +41,25 @@ object MEntityTypes {
.build(MNames.RIDEABLE_DUMMY)
}
val BREAD_MONSTER: EntityType<BreadMonster> by registry.register(MNames.BREAD_MONSTER) {
EntityType.Builder.of(::BreadMonster, MobCategory.MONSTER)
.sized(0.9f, 0.375f)
.eyeHeight(0.1875f)
.passengerAttachments(0.375f)
.clientTrackingRange(8)
.build(MNames.BREAD_MONSTER)
}
fun register(bus: IEventBus) {
registry.register(bus)
bus.addListener(this::registerAttributes)
bus.addListener(this::registerClient)
}
private fun registerAttributes(event: EntityAttributeCreationEvent) {
event.put(BREAD_MONSTER, BreadMonster.createAttributes().build())
}
@Suppress("unchecked_cast")
private fun registerClient(event: FMLClientSetupEvent) {
event.enqueueWork {
@ -53,6 +70,7 @@ object MEntityTypes {
}
EntityRenderers.register(RIDEABLE_DUMMY, ::NoopRenderer)
EntityRenderers.register(BREAD_MONSTER, ::BreadMonsterRenderer)
}
}
}

View File

@ -1,49 +0,0 @@
// Made with Blockbench 4.12.3
// Exported for Minecraft version 1.17 or later with Mojang mappings
// Paste this class into your mod and generate all required imports
public class bread_monster<T extends Entity> extends EntityModel<T> {
// 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(new ResourceLocation("modid", "bread_monster"), "main");
private final ModelPart root;
private final ModelPart Body;
private final ModelPart Ljaw;
private final ModelPart UJaw;
private final ModelPart tail;
public bread_monster(ModelPart root) {
this.root = root.getChild("root");
this.Body = this.root.getChild("Body");
this.Ljaw = this.Body.getChild("Ljaw");
this.UJaw = this.Body.getChild("UJaw");
this.tail = this.Body.getChild("tail");
}
public static LayerDefinition createBodyLayer() {
MeshDefinition meshdefinition = new MeshDefinition();
PartDefinition partdefinition = meshdefinition.getRoot();
PartDefinition root = partdefinition.addOrReplaceChild("root", CubeListBuilder.create(), PartPose.offset(0.0F, 24.0F, 0.0F));
PartDefinition Body = root.addOrReplaceChild("Body", CubeListBuilder.create().texOffs(0, 0).addBox(-4.0F, -3.0F, -5.0F, 8.0F, 6.0F, 6.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, -3.0F, 0.0F));
PartDefinition Ljaw = Body.addOrReplaceChild("Ljaw", CubeListBuilder.create().texOffs(26, 24).addBox(-4.0F, -2.0F, -4.0F, 8.0F, 3.0F, 4.0F, new CubeDeformation(0.1F)), PartPose.offset(0.0F, 2.0F, -3.0F));
PartDefinition UJaw = Body.addOrReplaceChild("UJaw", CubeListBuilder.create().texOffs(0, 24).addBox(-4.0F, -2.0F, -4.0F, 8.0F, 3.0F, 5.0F, new CubeDeformation(0.1F)), PartPose.offset(0.0F, -1.0F, -3.0F));
PartDefinition tail = Body.addOrReplaceChild("tail", CubeListBuilder.create().texOffs(0, 12).addBox(-4.0F, -3.0F, -0.1F, 8.0F, 6.0F, 6.0F, new CubeDeformation(-0.1F)), PartPose.offset(0.0F, 0.0F, 1.0F));
return LayerDefinition.create(meshdefinition, 64, 32);
}
@Override
public void setupAnim(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {
}
@Override
public void renderToBuffer(PoseStack poseStack, VertexConsumer vertexConsumer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) {
root.render(poseStack, vertexConsumer, packedLight, packedOverlay, red, green, blue, alpha);
}
}