From 1ba07217ec4e877f1a2afa9572316ebdced79f8a Mon Sep 17 00:00:00 2001 From: Boblet Date: Mon, 23 Oct 2023 16:55:38 +0200 Subject: [PATCH] flying rats --- .../java/com/hbm/entity/EntityMappings.java | 2 +- .../java/com/hbm/entity/mob/EntityPigeon.java | 50 ++++++++++++++-- .../com/hbm/entity/mob/IFlyingCreature.java | 10 ++++ .../ai/EntityAIFlutterAroundAimlessly.java | 44 ++++++++++++++ .../mob/ai/EntityAIPanicConditional.java | 56 ++++++++++++++++++ .../entity/mob/ai/EntityAIStartFlying.java | 28 +++++++++ .../hbm/entity/mob/ai/EntityAIStopFlying.java | 27 +++++++++ .../mob/ai/EntityAISwimmingConditional.java | 36 ++++++++++++ .../mob/ai/EntityAIWanderConditional.java | 58 +++++++++++++++++++ .../hbm/render/entity/mob/RenderPigeon.java | 4 +- 10 files changed, 308 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/hbm/entity/mob/IFlyingCreature.java create mode 100644 src/main/java/com/hbm/entity/mob/ai/EntityAIFlutterAroundAimlessly.java create mode 100644 src/main/java/com/hbm/entity/mob/ai/EntityAIPanicConditional.java create mode 100644 src/main/java/com/hbm/entity/mob/ai/EntityAIStartFlying.java create mode 100644 src/main/java/com/hbm/entity/mob/ai/EntityAIStopFlying.java create mode 100644 src/main/java/com/hbm/entity/mob/ai/EntityAISwimmingConditional.java create mode 100644 src/main/java/com/hbm/entity/mob/ai/EntityAIWanderConditional.java diff --git a/src/main/java/com/hbm/entity/EntityMappings.java b/src/main/java/com/hbm/entity/EntityMappings.java index 4c69f8102..0b88e2b9b 100644 --- a/src/main/java/com/hbm/entity/EntityMappings.java +++ b/src/main/java/com/hbm/entity/EntityMappings.java @@ -239,7 +239,7 @@ public class EntityMappings { addMob(EntityMaskMan.class, "entity_mob_mask_man", 0x818572, 0xC7C1B7); addMob(EntityDuck.class, "entity_fucc_a_ducc", 0xd0d0d0, 0xFFBF00); addMob(EntityQuackos.class, "entity_elder_one", 0xd0d0d0, 0xFFBF00); - //addMob(EntityPigeon.class, "entity_pigeon", 0xd0d0d0, 0xFFBF00); + addMob(EntityPigeon.class, "entity_pigeon", 0xd0d0d0, 0xFFBF00); addMob(EntityFBI.class, "entity_ntm_fbi", 0x008000, 0x404040); addMob(EntityFBIDrone.class, "entity_ntm_fbi_drone", 0x008000, 0x404040); addMob(EntityRADBeast.class, "entity_ntm_radiation_blaze", 0x303030, 0x008000); diff --git a/src/main/java/com/hbm/entity/mob/EntityPigeon.java b/src/main/java/com/hbm/entity/mob/EntityPigeon.java index af1ac41e0..0c6253e02 100644 --- a/src/main/java/com/hbm/entity/mob/EntityPigeon.java +++ b/src/main/java/com/hbm/entity/mob/EntityPigeon.java @@ -1,14 +1,56 @@ package com.hbm.entity.mob; -import net.minecraft.entity.passive.EntityChicken; +import java.util.function.Predicate; + +import com.hbm.entity.mob.ai.EntityAIFlutterAroundAimlessly; +import com.hbm.entity.mob.ai.EntityAIStartFlying; +import com.hbm.entity.mob.ai.EntityAIStopFlying; +import com.hbm.entity.mob.ai.EntityAISwimmingConditional; +import com.hbm.entity.mob.ai.EntityAIWanderConditional; + +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.ai.EntityAILookIdle; +import net.minecraft.entity.ai.EntityAIWatchClosest; +import net.minecraft.entity.passive.IAnimals; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; -public class EntityPigeon extends EntityChicken { +public class EntityPigeon extends EntityCreature implements IFlyingCreature, IAnimals { - public EntityPigeon(World p_i1682_1_) { - super(p_i1682_1_); + public EntityPigeon(World world) { + super(world); + Predicate noFlyCondition = x -> { return ((EntityPigeon) x).getFlyingState() == IFlyingCreature.STATE_WALKING; }; + this.tasks.addTask(0, new EntityAIStartFlying(this, this)); + this.tasks.addTask(0, new EntityAIStopFlying(this, this)); + this.tasks.addTask(1, new EntityAISwimmingConditional(this, noFlyCondition)); + this.tasks.addTask(2, new EntityAIFlutterAroundAimlessly(this, this)); + //this.tasks.addTask(2, new EntityAIPanicConditional(this, 1.4D, noFlyCondition)); + this.tasks.addTask(5, new EntityAIWanderConditional(this, 1.0D, noFlyCondition)); + this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); + this.tasks.addTask(7, new EntityAILookIdle(this)); + } + + @Override + public boolean isAIEnabled() { + return true; } + @Override + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(12, Byte.valueOf((byte) 0)); + } + + @Override + public int getFlyingState() { + return this.dataWatcher.getWatchableObjectByte(12); + } + + @Override + public void setFlyingState(int state) { + this.dataWatcher.updateObject(12, (byte) state); + } + protected String getLivingSound() { return null; } diff --git a/src/main/java/com/hbm/entity/mob/IFlyingCreature.java b/src/main/java/com/hbm/entity/mob/IFlyingCreature.java new file mode 100644 index 000000000..68bd8c36c --- /dev/null +++ b/src/main/java/com/hbm/entity/mob/IFlyingCreature.java @@ -0,0 +1,10 @@ +package com.hbm.entity.mob; + +public interface IFlyingCreature { + + public static final int STATE_WALKING = 0; + public static final int STATE_FLYING = 1; + + public int getFlyingState(); + public void setFlyingState(int state); +} diff --git a/src/main/java/com/hbm/entity/mob/ai/EntityAIFlutterAroundAimlessly.java b/src/main/java/com/hbm/entity/mob/ai/EntityAIFlutterAroundAimlessly.java new file mode 100644 index 000000000..98556f3aa --- /dev/null +++ b/src/main/java/com/hbm/entity/mob/ai/EntityAIFlutterAroundAimlessly.java @@ -0,0 +1,44 @@ +package com.hbm.entity.mob.ai; + +import com.hbm.entity.mob.IFlyingCreature; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.ai.EntityAIBase; + +public class EntityAIFlutterAroundAimlessly extends EntityAIBase { + + private EntityLivingBase living; + private IFlyingCreature flying; + + public EntityAIFlutterAroundAimlessly(EntityLivingBase living, IFlyingCreature flying) { + this.living = living; + this.flying = flying; + } + + @Override + public boolean shouldExecute() { + return this.flying.getFlyingState() == this.flying.STATE_FLYING; + } + + @Override + public boolean continueExecuting() { + return shouldExecute(); + } + + @Override + public void startExecuting() { + + /*this.living.motionX = this.living.getRNG().nextGaussian() * 0.1; + this.living.motionY = this.living.getRNG().nextGaussian() * 0.1; + this.living.motionZ = this.living.getRNG().nextGaussian() * 0.1;*/ + + this.living.motionX = 0; + this.living.motionY = this.living.getRNG().nextGaussian() * 0.1; + this.living.motionZ = 0; + + if(living.onGround) this.living.motionY = Math.abs(this.living.motionY) + 0.1D; + + this.living.moveForward = 0.5F; + this.living.rotationYaw += this.living.getRNG().nextGaussian() * 0.1; + } +} diff --git a/src/main/java/com/hbm/entity/mob/ai/EntityAIPanicConditional.java b/src/main/java/com/hbm/entity/mob/ai/EntityAIPanicConditional.java new file mode 100644 index 000000000..71fa26e4d --- /dev/null +++ b/src/main/java/com/hbm/entity/mob/ai/EntityAIPanicConditional.java @@ -0,0 +1,56 @@ +package com.hbm.entity.mob.ai; + +import java.util.function.Predicate; + +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.ai.RandomPositionGenerator; +import net.minecraft.util.Vec3; + +public class EntityAIPanicConditional extends EntityAIBase { + + private EntityCreature creature; + private double speed; + private Predicate condition; + private double randPosX; + private double randPosY; + private double randPosZ; + + public EntityAIPanicConditional(EntityCreature creature, double speed, Predicate condition) { + this.creature = creature; + this.speed = speed; + this.condition = condition; + this.setMutexBits(1); + } + + @Override + public boolean shouldExecute() { + + if(!condition.test(creature)) return false; + + if(this.creature.getAITarget() == null && !this.creature.isBurning()) { + return false; + } else { + Vec3 vec3 = RandomPositionGenerator.findRandomTarget(this.creature, 5, 4); + + if(vec3 == null) { + return false; + } else { + this.randPosX = vec3.xCoord; + this.randPosY = vec3.yCoord; + this.randPosZ = vec3.zCoord; + return true; + } + } + } + + @Override + public void startExecuting() { + this.creature.getNavigator().tryMoveToXYZ(this.randPosX, this.randPosY, this.randPosZ, this.speed); + } + + @Override + public boolean continueExecuting() { + return !this.creature.getNavigator().noPath() && condition.test(creature); + } +} diff --git a/src/main/java/com/hbm/entity/mob/ai/EntityAIStartFlying.java b/src/main/java/com/hbm/entity/mob/ai/EntityAIStartFlying.java new file mode 100644 index 000000000..2f8ffa66c --- /dev/null +++ b/src/main/java/com/hbm/entity/mob/ai/EntityAIStartFlying.java @@ -0,0 +1,28 @@ +package com.hbm.entity.mob.ai; + +import com.hbm.entity.mob.IFlyingCreature; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.ai.EntityAIBase; + +public class EntityAIStartFlying extends EntityAIBase { + + private EntityLivingBase living; + private IFlyingCreature flying; + + public EntityAIStartFlying(EntityLivingBase living, IFlyingCreature flying) { + this.living = living; + this.flying = flying; + } + + @Override + public boolean shouldExecute() { + //take off if attacked, on fire or at random (avg 30s) + return this.flying.getFlyingState() == this.flying.STATE_WALKING && (this.living.getAITarget() != null || this.living.isBurning() || this.living.getRNG().nextInt(600) == 0); + } + + @Override + public void startExecuting() { + this.flying.setFlyingState(this.flying.STATE_FLYING); + } +} diff --git a/src/main/java/com/hbm/entity/mob/ai/EntityAIStopFlying.java b/src/main/java/com/hbm/entity/mob/ai/EntityAIStopFlying.java new file mode 100644 index 000000000..6f8dadee5 --- /dev/null +++ b/src/main/java/com/hbm/entity/mob/ai/EntityAIStopFlying.java @@ -0,0 +1,27 @@ +package com.hbm.entity.mob.ai; + +import com.hbm.entity.mob.IFlyingCreature; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.ai.EntityAIBase; + +public class EntityAIStopFlying extends EntityAIBase { + + private EntityLivingBase living; + private IFlyingCreature flying; + + public EntityAIStopFlying(EntityLivingBase living, IFlyingCreature flying) { + this.living = living; + this.flying = flying; + } + + @Override + public boolean shouldExecute() { + return this.flying.getFlyingState() == this.flying.STATE_FLYING && this.living.getRNG().nextInt(200) == 0; + } + + @Override + public void startExecuting() { + this.flying.setFlyingState(this.flying.STATE_WALKING); + } +} diff --git a/src/main/java/com/hbm/entity/mob/ai/EntityAISwimmingConditional.java b/src/main/java/com/hbm/entity/mob/ai/EntityAISwimmingConditional.java new file mode 100644 index 000000000..1f2e3c18a --- /dev/null +++ b/src/main/java/com/hbm/entity/mob/ai/EntityAISwimmingConditional.java @@ -0,0 +1,36 @@ +package com.hbm.entity.mob.ai; + +import java.util.function.Predicate; + +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.ai.EntityAIBase; + +/** + * Identical to EntityAISwimming, but with an added conditional lambda for maximum reusability. + * + * @author hbm + */ +public class EntityAISwimmingConditional extends EntityAIBase { + + private EntityLiving living; + private Predicate condition; + + public EntityAISwimmingConditional(EntityLiving living, Predicate condition) { + this.living = living; + this.condition = condition; + this.setMutexBits(4); + living.getNavigator().setCanSwim(true); + } + + @Override + public boolean shouldExecute() { + return (this.living.isInWater() || this.living.handleLavaMovement()) && condition.test(living); + } + + @Override + public void updateTask() { + if(this.living.getRNG().nextFloat() < 0.8F) { + this.living.getJumpHelper().setJumping(); + } + } +} diff --git a/src/main/java/com/hbm/entity/mob/ai/EntityAIWanderConditional.java b/src/main/java/com/hbm/entity/mob/ai/EntityAIWanderConditional.java new file mode 100644 index 000000000..6132468eb --- /dev/null +++ b/src/main/java/com/hbm/entity/mob/ai/EntityAIWanderConditional.java @@ -0,0 +1,58 @@ +package com.hbm.entity.mob.ai; + +import java.util.function.Predicate; + +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.ai.RandomPositionGenerator; +import net.minecraft.util.Vec3; + +public class EntityAIWanderConditional extends EntityAIBase { + + private EntityCreature creature; + private double speed; + private Predicate condition; + private double xPosition; + private double yPosition; + private double zPosition; + + public EntityAIWanderConditional(EntityCreature creature, double speed, Predicate condition) { + this.creature = creature; + this.speed = speed; + this.condition = condition; + this.setMutexBits(1); + } + + @Override + public boolean shouldExecute() { + + if(!condition.test(creature)) return false; + + if(this.creature.getAge() >= 100) { + return false; + } else if(this.creature.getRNG().nextInt(120) != 0) { + return false; + } else { + Vec3 vec3 = RandomPositionGenerator.findRandomTarget(this.creature, 10, 7); + + if(vec3 == null) { + return false; + } else { + this.xPosition = vec3.xCoord; + this.yPosition = vec3.yCoord; + this.zPosition = vec3.zCoord; + return true; + } + } + } + + @Override + public boolean continueExecuting() { + return !this.creature.getNavigator().noPath() && condition.test(creature); + } + + @Override + public void startExecuting() { + this.creature.getNavigator().tryMoveToXYZ(this.xPosition, this.yPosition, this.zPosition, this.speed); + } +} diff --git a/src/main/java/com/hbm/render/entity/mob/RenderPigeon.java b/src/main/java/com/hbm/render/entity/mob/RenderPigeon.java index a825a0b3b..0c92d178d 100644 --- a/src/main/java/com/hbm/render/entity/mob/RenderPigeon.java +++ b/src/main/java/com/hbm/render/entity/mob/RenderPigeon.java @@ -4,11 +4,11 @@ import com.hbm.entity.mob.EntityPigeon; import com.hbm.lib.RefStrings; import net.minecraft.client.model.ModelBase; -import net.minecraft.client.renderer.entity.RenderChicken; +import net.minecraft.client.renderer.entity.RenderLiving; import net.minecraft.entity.Entity; import net.minecraft.util.ResourceLocation; -public class RenderPigeon extends RenderChicken { +public class RenderPigeon extends RenderLiving { public static final ResourceLocation texture = new ResourceLocation(RefStrings.MODID, "textures/entity/pigeon.png");