001 package net.minecraft.src; 002 003 public class EntityAIOcelotSit extends EntityAIBase 004 { 005 private final EntityOcelot theOcelot; 006 private final float field_75404_b; 007 008 /** Tracks for how long the task has been executing */ 009 private int currentTick = 0; 010 private int field_75402_d = 0; 011 012 /** For how long the Ocelot should be sitting */ 013 private int maxSittingTicks = 0; 014 015 /** X Coordinate of a nearby sitable block */ 016 private int sitableBlockX = 0; 017 018 /** Y Coordinate of a nearby sitable block */ 019 private int sitableBlockY = 0; 020 021 /** Z Coordinate of a nearby sitable block */ 022 private int sitableBlockZ = 0; 023 024 public EntityAIOcelotSit(EntityOcelot par1EntityOcelot, float par2) 025 { 026 this.theOcelot = par1EntityOcelot; 027 this.field_75404_b = par2; 028 this.setMutexBits(5); 029 } 030 031 /** 032 * Returns whether the EntityAIBase should begin execution. 033 */ 034 public boolean shouldExecute() 035 { 036 return this.theOcelot.isTamed() && !this.theOcelot.isSitting() && this.theOcelot.getRNG().nextDouble() <= 0.006500000134110451D && this.getNearbySitableBlockDistance(); 037 } 038 039 /** 040 * Returns whether an in-progress EntityAIBase should continue executing 041 */ 042 public boolean continueExecuting() 043 { 044 return this.currentTick <= this.maxSittingTicks && this.field_75402_d <= 60 && this.isSittableBlock(this.theOcelot.worldObj, this.sitableBlockX, this.sitableBlockY, this.sitableBlockZ); 045 } 046 047 /** 048 * Execute a one shot task or start executing a continuous task 049 */ 050 public void startExecuting() 051 { 052 this.theOcelot.getNavigator().tryMoveToXYZ((double)((float)this.sitableBlockX) + 0.5D, (double)(this.sitableBlockY + 1), (double)((float)this.sitableBlockZ) + 0.5D, this.field_75404_b); 053 this.currentTick = 0; 054 this.field_75402_d = 0; 055 this.maxSittingTicks = this.theOcelot.getRNG().nextInt(this.theOcelot.getRNG().nextInt(1200) + 1200) + 1200; 056 this.theOcelot.func_70907_r().setSitting(false); 057 } 058 059 /** 060 * Resets the task 061 */ 062 public void resetTask() 063 { 064 this.theOcelot.setSitting(false); 065 } 066 067 /** 068 * Updates the task 069 */ 070 public void updateTask() 071 { 072 ++this.currentTick; 073 this.theOcelot.func_70907_r().setSitting(false); 074 075 if (this.theOcelot.getDistanceSq((double)this.sitableBlockX, (double)(this.sitableBlockY + 1), (double)this.sitableBlockZ) > 1.0D) 076 { 077 this.theOcelot.setSitting(false); 078 this.theOcelot.getNavigator().tryMoveToXYZ((double)((float)this.sitableBlockX) + 0.5D, (double)(this.sitableBlockY + 1), (double)((float)this.sitableBlockZ) + 0.5D, this.field_75404_b); 079 ++this.field_75402_d; 080 } 081 else if (!this.theOcelot.isSitting()) 082 { 083 this.theOcelot.setSitting(true); 084 } 085 else 086 { 087 --this.field_75402_d; 088 } 089 } 090 091 /** 092 * Searches for a block to sit on within a 8 block range, returns 0 if none found 093 */ 094 protected boolean getNearbySitableBlockDistance() 095 { 096 int var1 = (int)this.theOcelot.posY; 097 double var2 = 2.147483647E9D; 098 099 for (int var4 = (int)this.theOcelot.posX - 8; (double)var4 < this.theOcelot.posX + 8.0D; ++var4) 100 { 101 for (int var5 = (int)this.theOcelot.posZ - 8; (double)var5 < this.theOcelot.posZ + 8.0D; ++var5) 102 { 103 if (this.isSittableBlock(this.theOcelot.worldObj, var4, var1, var5) && this.theOcelot.worldObj.isAirBlock(var4, var1 + 1, var5)) 104 { 105 double var6 = this.theOcelot.getDistanceSq((double)var4, (double)var1, (double)var5); 106 107 if (var6 < var2) 108 { 109 this.sitableBlockX = var4; 110 this.sitableBlockY = var1; 111 this.sitableBlockZ = var5; 112 var2 = var6; 113 } 114 } 115 } 116 } 117 118 return var2 < 2.147483647E9D; 119 } 120 121 /** 122 * Determines wheter the Ocelot wants to sit on the block at given coordinate 123 */ 124 protected boolean isSittableBlock(World par1World, int par2, int par3, int par4) 125 { 126 int var5 = par1World.getBlockId(par2, par3, par4); 127 int var6 = par1World.getBlockMetadata(par2, par3, par4); 128 129 if (var5 == Block.chest.blockID) 130 { 131 TileEntityChest var7 = (TileEntityChest)par1World.getBlockTileEntity(par2, par3, par4); 132 133 if (var7.numUsingPlayers < 1) 134 { 135 return true; 136 } 137 } 138 else 139 { 140 if (var5 == Block.stoneOvenActive.blockID) 141 { 142 return true; 143 } 144 145 if (var5 == Block.bed.blockID && !BlockBed.isBlockHeadOfBed(var6)) 146 { 147 return true; 148 } 149 } 150 151 return false; 152 } 153 }