001 package net.minecraft.src; 002 003 import cpw.mods.fml.common.Side; 004 import cpw.mods.fml.common.asm.SideOnly; 005 import java.util.Iterator; 006 007 public class TileEntityMobSpawner extends TileEntity 008 { 009 /** The stored delay before a new spawn. */ 010 public int delay = -1; 011 012 /** 013 * The string ID of the mobs being spawned from this spawner. Defaults to pig, apparently. 014 */ 015 private String mobID = "Pig"; 016 017 /** The extra NBT data to add to spawned entities */ 018 private NBTTagCompound spawnerTags = null; 019 public double yaw; 020 public double yaw2 = 0.0D; 021 private int minSpawnDelay = 200; 022 private int maxSpawnDelay = 800; 023 private int spawnCount = 4; 024 @SideOnly(Side.CLIENT) 025 private Entity spawnedMob; 026 027 public TileEntityMobSpawner() 028 { 029 this.delay = 20; 030 } 031 032 @SideOnly(Side.CLIENT) 033 public String getMobID() 034 { 035 return this.mobID; 036 } 037 038 public void setMobID(String par1Str) 039 { 040 this.mobID = par1Str; 041 } 042 043 /** 044 * Returns true if there is a player in range (using World.getClosestPlayer) 045 */ 046 public boolean anyPlayerInRange() 047 { 048 return this.worldObj.getClosestPlayer((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D, 16.0D) != null; 049 } 050 051 /** 052 * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count 053 * ticks and creates a new spawn inside its implementation. 054 */ 055 public void updateEntity() 056 { 057 if (this.anyPlayerInRange()) 058 { 059 if (this.worldObj.isRemote) 060 { 061 double var1 = (double)((float)this.xCoord + this.worldObj.rand.nextFloat()); 062 double var3 = (double)((float)this.yCoord + this.worldObj.rand.nextFloat()); 063 double var5 = (double)((float)this.zCoord + this.worldObj.rand.nextFloat()); 064 this.worldObj.spawnParticle("smoke", var1, var3, var5, 0.0D, 0.0D, 0.0D); 065 this.worldObj.spawnParticle("flame", var1, var3, var5, 0.0D, 0.0D, 0.0D); 066 this.yaw2 = this.yaw % 360.0D; 067 this.yaw += 4.545454502105713D; 068 } 069 else 070 { 071 if (this.delay == -1) 072 { 073 this.updateDelay(); 074 } 075 076 if (this.delay > 0) 077 { 078 --this.delay; 079 return; 080 } 081 082 for (int var11 = 0; var11 < this.spawnCount; ++var11) 083 { 084 Entity var2 = EntityList.createEntityByName(this.mobID, this.worldObj); 085 086 if (var2 == null) 087 { 088 return; 089 } 090 091 int var12 = this.worldObj.getEntitiesWithinAABB(var2.getClass(), AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)this.xCoord, (double)this.yCoord, (double)this.zCoord, (double)(this.xCoord + 1), (double)(this.yCoord + 1), (double)(this.zCoord + 1)).expand(8.0D, 4.0D, 8.0D)).size(); 092 093 if (var12 >= 6) 094 { 095 this.updateDelay(); 096 return; 097 } 098 099 if (var2 != null) 100 { 101 double var4 = (double)this.xCoord + (this.worldObj.rand.nextDouble() - this.worldObj.rand.nextDouble()) * 4.0D; 102 double var6 = (double)(this.yCoord + this.worldObj.rand.nextInt(3) - 1); 103 double var8 = (double)this.zCoord + (this.worldObj.rand.nextDouble() - this.worldObj.rand.nextDouble()) * 4.0D; 104 EntityLiving var10 = var2 instanceof EntityLiving ? (EntityLiving)var2 : null; 105 var2.setLocationAndAngles(var4, var6, var8, this.worldObj.rand.nextFloat() * 360.0F, 0.0F); 106 107 if (var10 == null || var10.getCanSpawnHere()) 108 { 109 this.writeNBTTagsTo(var2); 110 this.worldObj.spawnEntityInWorld(var2); 111 this.worldObj.playAuxSFX(2004, this.xCoord, this.yCoord, this.zCoord, 0); 112 113 if (var10 != null) 114 { 115 var10.spawnExplosionParticle(); 116 } 117 118 this.updateDelay(); 119 } 120 } 121 } 122 } 123 124 super.updateEntity(); 125 } 126 } 127 128 public void writeNBTTagsTo(Entity par1Entity) 129 { 130 if (this.spawnerTags != null) 131 { 132 NBTTagCompound var2 = new NBTTagCompound(); 133 par1Entity.addEntityID(var2); 134 Iterator var3 = this.spawnerTags.getTags().iterator(); 135 136 while (var3.hasNext()) 137 { 138 NBTBase var4 = (NBTBase)var3.next(); 139 var2.setTag(var4.getName(), var4.copy()); 140 } 141 142 par1Entity.readFromNBT(var2); 143 } 144 } 145 146 /** 147 * Sets the delay before a new spawn (base delay of 200 + random number up to 600). 148 */ 149 private void updateDelay() 150 { 151 this.delay = this.minSpawnDelay + this.worldObj.rand.nextInt(this.maxSpawnDelay - this.minSpawnDelay); 152 } 153 154 /** 155 * Reads a tile entity from NBT. 156 */ 157 public void readFromNBT(NBTTagCompound par1NBTTagCompound) 158 { 159 super.readFromNBT(par1NBTTagCompound); 160 this.mobID = par1NBTTagCompound.getString("EntityId"); 161 this.delay = par1NBTTagCompound.getShort("Delay"); 162 163 if (par1NBTTagCompound.hasKey("SpawnData")) 164 { 165 this.spawnerTags = par1NBTTagCompound.getCompoundTag("SpawnData"); 166 } 167 else 168 { 169 this.spawnerTags = null; 170 } 171 172 if (par1NBTTagCompound.hasKey("MinSpawnDelay")) 173 { 174 this.minSpawnDelay = par1NBTTagCompound.getShort("MinSpawnDelay"); 175 this.maxSpawnDelay = par1NBTTagCompound.getShort("MaxSpawnDelay"); 176 this.spawnCount = par1NBTTagCompound.getShort("SpawnCount"); 177 } 178 } 179 180 /** 181 * Writes a tile entity to NBT. 182 */ 183 public void writeToNBT(NBTTagCompound par1NBTTagCompound) 184 { 185 super.writeToNBT(par1NBTTagCompound); 186 par1NBTTagCompound.setString("EntityId", this.mobID); 187 par1NBTTagCompound.setShort("Delay", (short)this.delay); 188 par1NBTTagCompound.setShort("MinSpawnDelay", (short)this.minSpawnDelay); 189 par1NBTTagCompound.setShort("MaxSpawnDelay", (short)this.maxSpawnDelay); 190 par1NBTTagCompound.setShort("SpawnCount", (short)this.spawnCount); 191 192 if (this.spawnerTags != null) 193 { 194 par1NBTTagCompound.setCompoundTag("SpawnData", this.spawnerTags); 195 } 196 } 197 198 @SideOnly(Side.CLIENT) 199 200 /** 201 * will create the entity from the internalID the first time it is accessed 202 */ 203 public Entity getMobEntity() 204 { 205 if (this.spawnedMob == null) 206 { 207 Entity var1 = EntityList.createEntityByName(this.getMobID(), (World)null); 208 this.writeNBTTagsTo(var1); 209 this.spawnedMob = var1; 210 } 211 212 return this.spawnedMob; 213 } 214 215 /** 216 * Overriden in a sign to provide the text. 217 */ 218 public Packet getDescriptionPacket() 219 { 220 NBTTagCompound var1 = new NBTTagCompound(); 221 this.writeToNBT(var1); 222 return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 1, var1); 223 } 224 }