flying rats

This commit is contained in:
Boblet 2023-10-23 16:55:38 +02:00
parent 42d7882637
commit 1ba07217ec
10 changed files with 308 additions and 7 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}
}

View File

@ -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");