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.Configuration;
|
||||||
import net.minecraft.src.forge.MinecraftForge;
|
import net.minecraft.src.forge.MinecraftForge;
|
||||||
import net.minecraft.src.forge.NetworkMod;
|
import net.minecraft.src.forge.NetworkMod;
|
||||||
|
import net.minecraft.src.forge.adaptors.EntityLivingHandlerAdaptor;
|
||||||
|
|
||||||
public class mod_IronChest extends NetworkMod {
|
public class mod_IronChest extends NetworkMod {
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ public class mod_IronChest extends NetworkMod {
|
||||||
public static IProxy proxy;
|
public static IProxy proxy;
|
||||||
public static mod_IronChest instance;
|
public static mod_IronChest instance;
|
||||||
public static boolean CACHE_RENDER = true;
|
public static boolean CACHE_RENDER = true;
|
||||||
|
public static boolean OCELOTS_SITONCHESTS = true;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getVersion() {
|
public String getVersion() {
|
||||||
|
@ -51,6 +53,7 @@ public class mod_IronChest extends NetworkMod {
|
||||||
ironChestBlock = new BlockIronChest(bId);
|
ironChestBlock = new BlockIronChest(bId);
|
||||||
ChestChangerType.buildItems(cfg, 29501);
|
ChestChangerType.buildItems(cfg, 29501);
|
||||||
CACHE_RENDER = cfg.getOrCreateBooleanProperty("cacheRenderingInformation", Configuration.CATEGORY_GENERAL, true).getBoolean(true);
|
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) {
|
} catch (Exception e) {
|
||||||
ModLoader.getLogger().severe("IronChest was unable to load it's configuration successfully");
|
ModLoader.getLogger().severe("IronChest was unable to load it's configuration successfully");
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
|
@ -68,6 +71,7 @@ public class mod_IronChest extends NetworkMod {
|
||||||
MinecraftForge.setGuiHandler(this, proxy);
|
MinecraftForge.setGuiHandler(this, proxy);
|
||||||
MinecraftForge.registerConnectionHandler(new PacketHandler());
|
MinecraftForge.registerConnectionHandler(new PacketHandler());
|
||||||
proxy.registerRenderInformation();
|
proxy.registerRenderInformation();
|
||||||
|
MinecraftForge.registerEntityLivingHandler(new OcelotsSitOnChestsHandler());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue