Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package net.minecraft.server;
2
3import com.legacyminecraft.poseidon.PoseidonConfig;
4import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
5
6import java.util.List;
7
8public class TileEntityMobSpawner extends TileEntity {
9
10 public int spawnDelay = -1;
11 public String mobName = "Pig"; // CraftBukkit - private -> public
12 public double b;
13 public double c = 0.0D;
14
15 private static boolean poseidonAreaLimit = PoseidonConfig.getInstance().getConfigBoolean("world.settings.mob-spawner-area-limit.enable");
16 private static int poseidonAreaLimitRadius = PoseidonConfig.getInstance().getConfigInteger("world.settings.mob-spawner-area-limit.limit");
17 private static int poseidonChunkRadius = PoseidonConfig.getInstance().getConfigInteger("world.settings.mob-spawner-area-limit.chunk-radius");
18
19 public TileEntityMobSpawner() {
20 this.spawnDelay = 20;
21 }
22
23 public void a(String s) {
24 this.mobName = s;
25 }
26
27 public boolean a() {
28 return this.world.a((double) this.x + 0.5D, (double) this.y + 0.5D, (double) this.z + 0.5D, 16.0D) != null;
29 }
30
31 public void g_() {
32 this.c = this.b;
33 if (this.a()) {
34 double d0 = (double) ((float) this.x + this.world.random.nextFloat());
35 double d1 = (double) ((float) this.y + this.world.random.nextFloat());
36 double d2 = (double) ((float) this.z + this.world.random.nextFloat());
37
38 this.world.a("smoke", d0, d1, d2, 0.0D, 0.0D, 0.0D);
39 this.world.a("flame", d0, d1, d2, 0.0D, 0.0D, 0.0D);
40
41 for (this.b += (double) (1000.0F / ((float) this.spawnDelay + 200.0F)); this.b > 360.0D; this.c -= 360.0D) {
42 this.b -= 360.0D;
43 }
44
45 if (!this.world.isStatic) {
46 if (this.spawnDelay == -1) {
47 this.c();
48 }
49
50 if (this.spawnDelay > 0) {
51 --this.spawnDelay;
52 return;
53 }
54
55 byte b0 = 4;
56
57 for (int i = 0; i < b0; ++i) {
58 EntityLiving entityliving = (EntityLiving) ((EntityLiving) EntityTypes.a(this.mobName, this.world));
59
60 if (entityliving == null) {
61 return;
62 }
63
64 // CraftBukkit start - The world we're spawning in accepts this creature
65 boolean isAnimal = entityliving instanceof EntityAnimal || entityliving instanceof EntityWaterAnimal;
66 if ((isAnimal && !this.world.allowAnimals) || (!isAnimal && !this.world.allowMonsters)) {
67 return;
68 }
69 // CraftBukkit end
70
71
72 // Check mob cap within the spawning radius
73 int j = this.world.a(entityliving.getClass(), AxisAlignedBB.b((double) this.x, (double) this.y, (double) this.z, (double) (this.x + 1), (double) (this.y + 1), (double) (this.z + 1)).b(8.0D, 4.0D, 8.0D)).size();
74
75 if (j >= 6) {
76 this.c();
77 return;
78 }
79
80 //Poseidon Start - Ensure the mob cound of the specific type of mob is under the defined limit within the area
81 if (poseidonAreaLimit) {
82 double chunkSize = 16.0D;
83 AxisAlignedBB searchArea = AxisAlignedBB.b(this.x - poseidonChunkRadius * chunkSize, 0.0D, this.z - poseidonChunkRadius * chunkSize, this.x + poseidonChunkRadius * chunkSize, 128, this.z + poseidonChunkRadius * chunkSize);
84 List<Entity> existingEntities = this.world.a(entityliving.getClass(), searchArea);
85 if (existingEntities.size() >= poseidonAreaLimitRadius) {
86 this.c();
87 return;
88 }
89 }
90 //Poseidon End
91
92 if (entityliving != null) {
93 double d3 = (double) this.x + (this.world.random.nextDouble() - this.world.random.nextDouble()) * 4.0D;
94 double d4 = (double) (this.y + this.world.random.nextInt(3) - 1);
95 double d5 = (double) this.z + (this.world.random.nextDouble() - this.world.random.nextDouble()) * 4.0D;
96
97 entityliving.setPositionRotation(d3, d4, d5, this.world.random.nextFloat() * 360.0F, 0.0F);
98 if (entityliving.d()) {
99 // CraftBukkit - added a reason for spawning this creature
100 this.world.addEntity(entityliving, SpawnReason.SPAWNER);
101
102 for (int k = 0; k < 20; ++k) {
103 d0 = (double) this.x + 0.5D + ((double) this.world.random.nextFloat() - 0.5D) * 2.0D;
104 d1 = (double) this.y + 0.5D + ((double) this.world.random.nextFloat() - 0.5D) * 2.0D;
105 d2 = (double) this.z + 0.5D + ((double) this.world.random.nextFloat() - 0.5D) * 2.0D;
106 this.world.a("smoke", d0, d1, d2, 0.0D, 0.0D, 0.0D);
107 this.world.a("flame", d0, d1, d2, 0.0D, 0.0D, 0.0D);
108 }
109
110 entityliving.S();
111 this.c();
112 }
113 }
114 }
115 }
116
117 super.g_();
118 }
119 }
120
121 private void c() {
122 this.spawnDelay = 200 + this.world.random.nextInt(600);
123 }
124
125 public void a(NBTTagCompound nbttagcompound) {
126 super.a(nbttagcompound);
127 this.mobName = nbttagcompound.getString("EntityId");
128 this.spawnDelay = nbttagcompound.d("Delay");
129 }
130
131 public void b(NBTTagCompound nbttagcompound) {
132 super.b(nbttagcompound);
133 nbttagcompound.setString("EntityId", this.mobName);
134 nbttagcompound.a("Delay", (short) this.spawnDelay);
135 }
136}