    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    }