001package net.minecraft.tileentity; 002 003import cpw.mods.fml.relauncher.Side; 004import cpw.mods.fml.relauncher.SideOnly; 005import java.util.ArrayList; 006import java.util.Iterator; 007import java.util.List; 008import net.minecraft.entity.Entity; 009import net.minecraft.entity.EntityList; 010import net.minecraft.entity.EntityLiving; 011import net.minecraft.nbt.NBTBase; 012import net.minecraft.nbt.NBTTagCompound; 013import net.minecraft.nbt.NBTTagList; 014import net.minecraft.util.AxisAlignedBB; 015import net.minecraft.util.WeightedRandom; 016import net.minecraft.world.World; 017 018public abstract class MobSpawnerBaseLogic 019{ 020 /** The delay to spawn. */ 021 public int spawnDelay = 20; 022 private String mobID = "Pig"; 023 024 /** List of minecart to spawn. */ 025 private List minecartToSpawn = null; 026 private WeightedRandomMinecart randomMinecart = null; 027 public double field_98287_c; 028 public double field_98284_d = 0.0D; 029 private int minSpawnDelay = 200; 030 private int maxSpawnDelay = 800; 031 032 /** A counter for spawn tries. */ 033 private int spawnCount = 4; 034 private Entity field_98291_j; 035 private int maxNearbyEntities = 6; 036 037 /** The distance from which a player activates the spawner. */ 038 private int activatingRangeFromPlayer = 16; 039 040 /** The range coefficient for spawning entities around. */ 041 private int spawnRange = 4; 042 043 /** 044 * Gets the entity name that should be spawned. 045 */ 046 public String getEntityNameToSpawn() 047 { 048 if (this.getRandomMinecart() == null) 049 { 050 if (this.mobID.equals("Minecart")) 051 { 052 this.mobID = "MinecartRideable"; 053 } 054 055 return this.mobID; 056 } 057 else 058 { 059 return this.getRandomMinecart().minecartName; 060 } 061 } 062 063 public void setMobID(String par1Str) 064 { 065 this.mobID = par1Str; 066 } 067 068 /** 069 * Returns true if there's a player close enough to this mob spawner to activate it. 070 */ 071 public boolean canRun() 072 { 073 return this.getSpawnerWorld().getClosestPlayer((double)this.getSpawnerX() + 0.5D, (double)this.getSpawnerY() + 0.5D, (double)this.getSpawnerZ() + 0.5D, (double)this.activatingRangeFromPlayer) != null; 074 } 075 076 public void updateSpawner() 077 { 078 if (this.canRun()) 079 { 080 double d0; 081 082 if (this.getSpawnerWorld().isRemote) 083 { 084 double d1 = (double)((float)this.getSpawnerX() + this.getSpawnerWorld().rand.nextFloat()); 085 double d2 = (double)((float)this.getSpawnerY() + this.getSpawnerWorld().rand.nextFloat()); 086 d0 = (double)((float)this.getSpawnerZ() + this.getSpawnerWorld().rand.nextFloat()); 087 this.getSpawnerWorld().spawnParticle("smoke", d1, d2, d0, 0.0D, 0.0D, 0.0D); 088 this.getSpawnerWorld().spawnParticle("flame", d1, d2, d0, 0.0D, 0.0D, 0.0D); 089 090 if (this.spawnDelay > 0) 091 { 092 --this.spawnDelay; 093 } 094 095 this.field_98284_d = this.field_98287_c; 096 this.field_98287_c = (this.field_98287_c + (double)(1000.0F / ((float)this.spawnDelay + 200.0F))) % 360.0D; 097 } 098 else 099 { 100 if (this.spawnDelay == -1) 101 { 102 this.func_98273_j(); 103 } 104 105 if (this.spawnDelay > 0) 106 { 107 --this.spawnDelay; 108 return; 109 } 110 111 boolean flag = false; 112 113 for (int i = 0; i < this.spawnCount; ++i) 114 { 115 Entity entity = EntityList.createEntityByName(this.getEntityNameToSpawn(), this.getSpawnerWorld()); 116 117 if (entity == null) 118 { 119 return; 120 } 121 122 int j = this.getSpawnerWorld().getEntitiesWithinAABB(entity.getClass(), AxisAlignedBB.getAABBPool().getAABB((double)this.getSpawnerX(), (double)this.getSpawnerY(), (double)this.getSpawnerZ(), (double)(this.getSpawnerX() + 1), (double)(this.getSpawnerY() + 1), (double)(this.getSpawnerZ() + 1)).expand((double)(this.spawnRange * 2), 4.0D, (double)(this.spawnRange * 2))).size(); 123 124 if (j >= this.maxNearbyEntities) 125 { 126 this.func_98273_j(); 127 return; 128 } 129 130 d0 = (double)this.getSpawnerX() + (this.getSpawnerWorld().rand.nextDouble() - this.getSpawnerWorld().rand.nextDouble()) * (double)this.spawnRange; 131 double d3 = (double)(this.getSpawnerY() + this.getSpawnerWorld().rand.nextInt(3) - 1); 132 double d4 = (double)this.getSpawnerZ() + (this.getSpawnerWorld().rand.nextDouble() - this.getSpawnerWorld().rand.nextDouble()) * (double)this.spawnRange; 133 EntityLiving entityliving = entity instanceof EntityLiving ? (EntityLiving)entity : null; 134 entity.setLocationAndAngles(d0, d3, d4, this.getSpawnerWorld().rand.nextFloat() * 360.0F, 0.0F); 135 136 if (entityliving == null || entityliving.getCanSpawnHere()) 137 { 138 this.func_98265_a(entity); 139 this.getSpawnerWorld().playAuxSFX(2004, this.getSpawnerX(), this.getSpawnerY(), this.getSpawnerZ(), 0); 140 141 if (entityliving != null) 142 { 143 entityliving.spawnExplosionParticle(); 144 } 145 146 flag = true; 147 } 148 } 149 150 if (flag) 151 { 152 this.func_98273_j(); 153 } 154 } 155 } 156 } 157 158 public Entity func_98265_a(Entity par1Entity) 159 { 160 if (this.getRandomMinecart() != null) 161 { 162 NBTTagCompound nbttagcompound = new NBTTagCompound(); 163 par1Entity.addEntityID(nbttagcompound); 164 Iterator iterator = this.getRandomMinecart().field_98222_b.getTags().iterator(); 165 166 while (iterator.hasNext()) 167 { 168 NBTBase nbtbase = (NBTBase)iterator.next(); 169 nbttagcompound.setTag(nbtbase.getName(), nbtbase.copy()); 170 } 171 172 par1Entity.readFromNBT(nbttagcompound); 173 174 if (par1Entity.worldObj != null) 175 { 176 par1Entity.worldObj.spawnEntityInWorld(par1Entity); 177 } 178 179 NBTTagCompound nbttagcompound1; 180 181 for (Entity entity1 = par1Entity; nbttagcompound.hasKey("Riding"); nbttagcompound = nbttagcompound1) 182 { 183 nbttagcompound1 = nbttagcompound.getCompoundTag("Riding"); 184 Entity entity2 = EntityList.createEntityByName(nbttagcompound1.getString("id"), this.getSpawnerWorld()); 185 186 if (entity2 != null) 187 { 188 NBTTagCompound nbttagcompound2 = new NBTTagCompound(); 189 entity2.addEntityID(nbttagcompound2); 190 Iterator iterator1 = nbttagcompound1.getTags().iterator(); 191 192 while (iterator1.hasNext()) 193 { 194 NBTBase nbtbase1 = (NBTBase)iterator1.next(); 195 nbttagcompound2.setTag(nbtbase1.getName(), nbtbase1.copy()); 196 } 197 198 entity2.readFromNBT(nbttagcompound2); 199 entity2.setLocationAndAngles(entity1.posX, entity1.posY, entity1.posZ, entity1.rotationYaw, entity1.rotationPitch); 200 this.getSpawnerWorld().spawnEntityInWorld(entity2); 201 entity1.mountEntity(entity2); 202 } 203 204 entity1 = entity2; 205 } 206 } 207 else if (par1Entity instanceof EntityLiving && par1Entity.worldObj != null) 208 { 209 ((EntityLiving)par1Entity).initCreature(); 210 this.getSpawnerWorld().spawnEntityInWorld(par1Entity); 211 } 212 213 return par1Entity; 214 } 215 216 private void func_98273_j() 217 { 218 if (this.maxSpawnDelay <= this.minSpawnDelay) 219 { 220 this.spawnDelay = this.minSpawnDelay; 221 } 222 else 223 { 224 int i = this.maxSpawnDelay - this.minSpawnDelay; 225 this.spawnDelay = this.minSpawnDelay + this.getSpawnerWorld().rand.nextInt(i); 226 } 227 228 if (this.minecartToSpawn != null && this.minecartToSpawn.size() > 0) 229 { 230 this.setRandomMinecart((WeightedRandomMinecart)WeightedRandom.getRandomItem(this.getSpawnerWorld().rand, this.minecartToSpawn)); 231 } 232 233 this.func_98267_a(1); 234 } 235 236 public void readFromNBT(NBTTagCompound par1NBTTagCompound) 237 { 238 this.mobID = par1NBTTagCompound.getString("EntityId"); 239 this.spawnDelay = par1NBTTagCompound.getShort("Delay"); 240 241 if (par1NBTTagCompound.hasKey("SpawnPotentials")) 242 { 243 this.minecartToSpawn = new ArrayList(); 244 NBTTagList nbttaglist = par1NBTTagCompound.getTagList("SpawnPotentials"); 245 246 for (int i = 0; i < nbttaglist.tagCount(); ++i) 247 { 248 this.minecartToSpawn.add(new WeightedRandomMinecart(this, (NBTTagCompound)nbttaglist.tagAt(i))); 249 } 250 } 251 else 252 { 253 this.minecartToSpawn = null; 254 } 255 256 if (par1NBTTagCompound.hasKey("SpawnData")) 257 { 258 this.setRandomMinecart(new WeightedRandomMinecart(this, par1NBTTagCompound.getCompoundTag("SpawnData"), this.mobID)); 259 } 260 else 261 { 262 this.setRandomMinecart((WeightedRandomMinecart)null); 263 } 264 265 if (par1NBTTagCompound.hasKey("MinSpawnDelay")) 266 { 267 this.minSpawnDelay = par1NBTTagCompound.getShort("MinSpawnDelay"); 268 this.maxSpawnDelay = par1NBTTagCompound.getShort("MaxSpawnDelay"); 269 this.spawnCount = par1NBTTagCompound.getShort("SpawnCount"); 270 } 271 272 if (par1NBTTagCompound.hasKey("MaxNearbyEntities")) 273 { 274 this.maxNearbyEntities = par1NBTTagCompound.getShort("MaxNearbyEntities"); 275 this.activatingRangeFromPlayer = par1NBTTagCompound.getShort("RequiredPlayerRange"); 276 } 277 278 if (par1NBTTagCompound.hasKey("SpawnRange")) 279 { 280 this.spawnRange = par1NBTTagCompound.getShort("SpawnRange"); 281 } 282 283 if (this.getSpawnerWorld() != null && this.getSpawnerWorld().isRemote) 284 { 285 this.field_98291_j = null; 286 } 287 } 288 289 public void writeToNBT(NBTTagCompound par1NBTTagCompound) 290 { 291 par1NBTTagCompound.setString("EntityId", this.getEntityNameToSpawn()); 292 par1NBTTagCompound.setShort("Delay", (short)this.spawnDelay); 293 par1NBTTagCompound.setShort("MinSpawnDelay", (short)this.minSpawnDelay); 294 par1NBTTagCompound.setShort("MaxSpawnDelay", (short)this.maxSpawnDelay); 295 par1NBTTagCompound.setShort("SpawnCount", (short)this.spawnCount); 296 par1NBTTagCompound.setShort("MaxNearbyEntities", (short)this.maxNearbyEntities); 297 par1NBTTagCompound.setShort("RequiredPlayerRange", (short)this.activatingRangeFromPlayer); 298 par1NBTTagCompound.setShort("SpawnRange", (short)this.spawnRange); 299 300 if (this.getRandomMinecart() != null) 301 { 302 par1NBTTagCompound.setCompoundTag("SpawnData", (NBTTagCompound)this.getRandomMinecart().field_98222_b.copy()); 303 } 304 305 if (this.getRandomMinecart() != null || this.minecartToSpawn != null && this.minecartToSpawn.size() > 0) 306 { 307 NBTTagList nbttaglist = new NBTTagList(); 308 309 if (this.minecartToSpawn != null && this.minecartToSpawn.size() > 0) 310 { 311 Iterator iterator = this.minecartToSpawn.iterator(); 312 313 while (iterator.hasNext()) 314 { 315 WeightedRandomMinecart weightedrandomminecart = (WeightedRandomMinecart)iterator.next(); 316 nbttaglist.appendTag(weightedrandomminecart.func_98220_a()); 317 } 318 } 319 else 320 { 321 nbttaglist.appendTag(this.getRandomMinecart().func_98220_a()); 322 } 323 324 par1NBTTagCompound.setTag("SpawnPotentials", nbttaglist); 325 } 326 } 327 328 /** 329 * Sets the delay to minDelay if parameter given is 1, else return false. 330 */ 331 public boolean setDelayToMin(int par1) 332 { 333 if (par1 == 1 && this.getSpawnerWorld().isRemote) 334 { 335 this.spawnDelay = this.minSpawnDelay; 336 return true; 337 } 338 else 339 { 340 return false; 341 } 342 } 343 344 @SideOnly(Side.CLIENT) 345 public Entity func_98281_h() 346 { 347 if (this.field_98291_j == null) 348 { 349 Entity entity = EntityList.createEntityByName(this.getEntityNameToSpawn(), (World)null); 350 entity = this.func_98265_a(entity); 351 this.field_98291_j = entity; 352 } 353 354 return this.field_98291_j; 355 } 356 357 public WeightedRandomMinecart getRandomMinecart() 358 { 359 return this.randomMinecart; 360 } 361 362 public void setRandomMinecart(WeightedRandomMinecart par1WeightedRandomMinecart) 363 { 364 this.randomMinecart = par1WeightedRandomMinecart; 365 } 366 367 public abstract void func_98267_a(int i); 368 369 public abstract World getSpawnerWorld(); 370 371 public abstract int getSpawnerX(); 372 373 public abstract int getSpawnerY(); 374 375 public abstract int getSpawnerZ(); 376}