Cats sitting on chests, initial commit
This commit is contained in:
parent
5b9778de03
commit
b9c4ecbbec
|
@ -0,0 +1,138 @@
|
|||
package cpw.mods.ironchest;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import net.minecraft.src.Block;
|
||||
import net.minecraft.src.BlockBed;
|
||||
import net.minecraft.src.EntityAIBase;
|
||||
import net.minecraft.src.EntityAIOcelotSit;
|
||||
import net.minecraft.src.EntityOcelot;
|
||||
import net.minecraft.src.TileEntityChest;
|
||||
import net.minecraft.src.World;
|
||||
|
||||
public class IronChestAIOcelotSit extends EntityAIBase {
|
||||
private EntityOcelot ocelot;
|
||||
private final float speed;
|
||||
private int ticksRun = 0;
|
||||
private int tryTicks = 0;
|
||||
private int maxTicks = 0;
|
||||
private int targetX = 0;
|
||||
private int targetY = 0;
|
||||
private int targetZ = 0;
|
||||
private EntityAIOcelotSit sitAI;
|
||||
private Method isTargetBlockMethod;
|
||||
private boolean grabbedMethod;
|
||||
|
||||
public IronChestAIOcelotSit(EntityOcelot par1EntityOcelot, float par2, EntityAIOcelotSit sitAI) {
|
||||
this.ocelot = par1EntityOcelot;
|
||||
this.speed = par2;
|
||||
this.sitAI = sitAI;
|
||||
this.setMutexBits(5);
|
||||
if (!grabbedMethod) {
|
||||
try {
|
||||
isTargetBlockMethod = EntityAIOcelotSit.class.getDeclaredMethod("a", World.class, int.class, int.class, int.class);
|
||||
} catch (Exception e) {
|
||||
// Can't find it
|
||||
try {
|
||||
isTargetBlockMethod = EntityAIOcelotSit.class.getDeclaredMethod("func_50078_a", World.class, int.class, int.class, int.class);
|
||||
} catch (Exception e1) {
|
||||
}
|
||||
}
|
||||
isTargetBlockMethod.setAccessible(true);
|
||||
grabbedMethod = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
return ocelot.isTamed() && !ocelot.isSitting() && ocelot.getRNG().nextDouble() <= 0.0065D && thereIsChestNearby();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return this.ticksRun <= this.maxTicks && this.tryTicks <= 60 && isBlockAChestBlock(ocelot.worldObj, this.targetX, this.targetY, this.targetZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.ocelot.getNavigator().tryMoveToXYZ((double) ((float) this.targetX) + 0.5D, (double) (this.targetY + 1), (double) ((float) this.targetZ) + 0.5D,
|
||||
this.speed);
|
||||
this.ticksRun = 0;
|
||||
this.tryTicks = 0;
|
||||
this.maxTicks = this.ocelot.getRNG().nextInt(this.ocelot.getRNG().nextInt(1200) + 1200) + 1200;
|
||||
this.ocelot.func_50008_ai().setIsSitting(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.ocelot.setSitting(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
++this.ticksRun;
|
||||
this.ocelot.func_50008_ai().setIsSitting(false);
|
||||
|
||||
if (this.ocelot.getDistanceSq((double) this.targetX, (double) (this.targetY + 1), (double) this.targetZ) > 1.0D)
|
||||
{
|
||||
this.ocelot.setSitting(false);
|
||||
this.ocelot.getNavigator().tryMoveToXYZ((double) ((float) this.targetX) + 0.5D, (double) (this.targetY + 1), (double) ((float) this.targetZ) + 0.5D,
|
||||
this.speed);
|
||||
++this.tryTicks;
|
||||
}
|
||||
else if (!this.ocelot.isSitting())
|
||||
{
|
||||
this.ocelot.setSitting(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
--this.tryTicks;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean thereIsChestNearby() {
|
||||
int searchY = (int) this.ocelot.posY;
|
||||
double closestChestDistance = Integer.MAX_VALUE;
|
||||
|
||||
for (int searchX = (int) this.ocelot.posX - 8; searchX < this.ocelot.posX + 8; searchX++) {
|
||||
for (int searchZ = (int) this.ocelot.posZ - 8; searchZ < this.ocelot.posZ + 8; searchZ++) {
|
||||
if (this.isBlockAChestBlock(this.ocelot.worldObj, searchX, searchY, searchZ) && this.ocelot.worldObj.isAirBlock(searchX, searchY + 1, searchZ)) {
|
||||
double chestDistance = this.ocelot.getDistanceSq((double) searchX, (double) searchY, (double) searchZ);
|
||||
|
||||
if (chestDistance < closestChestDistance) {
|
||||
this.targetX = searchX;
|
||||
this.targetY = searchY;
|
||||
this.targetZ = searchZ;
|
||||
closestChestDistance = chestDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closestChestDistance < Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
private boolean isBlockAChestBlock(World world, int x, int y, int z) {
|
||||
if (world.getBlockId(x, y, z)==mod_IronChest.ironChestBlock.blockID) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
return (Boolean) isTargetBlockMethod.invoke(sitAI, world, x, y, z);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package cpw.mods.ironchest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import cpw.mods.fml.common.ReflectionHelper;
|
||||
import net.minecraft.src.EntityAIBase;
|
||||
import net.minecraft.src.EntityAIOcelotSit;
|
||||
import net.minecraft.src.EntityAITasks;
|
||||
import net.minecraft.src.EntityLiving;
|
||||
import net.minecraft.src.EntityOcelot;
|
||||
import net.minecraft.src.World;
|
||||
import net.minecraft.src.forge.IEntityLivingHandler;
|
||||
import net.minecraft.src.forge.adaptors.EntityLivingHandlerAdaptor;
|
||||
|
||||
public class OcelotsSitOnChestsHandler extends EntityLivingHandlerAdaptor {
|
||||
private static EntityAIOcelotSit aiTask = new EntityAIOcelotSit(null, 0);
|
||||
@Override
|
||||
public boolean onEntityLivingUpdate(EntityLiving entity) {
|
||||
if (entity.ticksExisted<2 && entity instanceof EntityOcelot) {
|
||||
EntityOcelot ocelot = (EntityOcelot) entity;
|
||||
EntityAITasks ocelotTasks = ReflectionHelper.getPrivateValue(EntityLiving.class, ocelot, "tasks");
|
||||
List taskList = ReflectionHelper.getPrivateValue(EntityAITasks.class, ocelotTasks, "tasksToDo");
|
||||
taskList.remove(5);
|
||||
ocelotTasks.addTask(6, new IronChestAIOcelotSit(ocelot, 0.4F, aiTask));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@ import net.minecraft.src.SidedProxy;
|
|||
import net.minecraft.src.forge.Configuration;
|
||||
import net.minecraft.src.forge.MinecraftForge;
|
||||
import net.minecraft.src.forge.NetworkMod;
|
||||
import net.minecraft.src.forge.adaptors.EntityLivingHandlerAdaptor;
|
||||
|
||||
public class mod_IronChest extends NetworkMod {
|
||||
|
||||
|
@ -29,6 +30,7 @@ public class mod_IronChest extends NetworkMod {
|
|||
public static IProxy proxy;
|
||||
public static mod_IronChest instance;
|
||||
public static boolean CACHE_RENDER = true;
|
||||
public static boolean OCELOTS_SITONCHESTS = true;
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
|
@ -51,6 +53,7 @@ public class mod_IronChest extends NetworkMod {
|
|||
ironChestBlock = new BlockIronChest(bId);
|
||||
ChestChangerType.buildItems(cfg, 29501);
|
||||
CACHE_RENDER = cfg.getOrCreateBooleanProperty("cacheRenderingInformation", Configuration.CATEGORY_GENERAL, true).getBoolean(true);
|
||||
OCELOTS_SITONCHESTS = cfg.getOrCreateBooleanProperty("ocelotsSitOnChests", Configuration.CATEGORY_GENERAL, true).getBoolean(true);
|
||||
} catch (Exception e) {
|
||||
ModLoader.getLogger().severe("IronChest was unable to load it's configuration successfully");
|
||||
e.printStackTrace(System.err);
|
||||
|
@ -68,6 +71,7 @@ public class mod_IronChest extends NetworkMod {
|
|||
MinecraftForge.setGuiHandler(this, proxy);
|
||||
MinecraftForge.registerConnectionHandler(new PacketHandler());
|
||||
proxy.registerRenderInformation();
|
||||
MinecraftForge.registerEntityLivingHandler(new OcelotsSitOnChestsHandler());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue