Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package net.minecraft.server;
2
3import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
4
5import java.util.HashSet;
6import java.util.Iterator;
7import java.util.List;
8import java.util.Set;
9
10// CraftBukkit
11
12public final class SpawnerCreature {
13
14 private static Set b = new HashSet();
15 protected static final Class[] a = new Class[] { EntitySpider.class, EntityZombie.class, EntitySkeleton.class };
16
17 public SpawnerCreature() {
18 }
19
20 protected static ChunkPosition a(World world, int i, int j) {
21 int k = i + world.random.nextInt(16);
22 int l = world.random.nextInt(128);
23 int i1 = j + world.random.nextInt(16);
24
25 return new ChunkPosition(k, l, i1);
26 }
27
28 public static final int spawnEntities(World world, boolean flag, boolean flag1) {
29 if (!flag && !flag1) {
30 return 0;
31 } else {
32 b.clear();
33
34 int i;
35 int j;
36
37 for (i = 0; i < world.players.size(); ++i) {
38 EntityHuman entityhuman = (EntityHuman) world.players.get(i);
39 int k = MathHelper.floor(entityhuman.locX / 16.0D);
40
41 j = MathHelper.floor(entityhuman.locZ / 16.0D);
42 byte b0 = 8;
43
44 for (int l = -b0; l <= b0; ++l) {
45 for (int i1 = -b0; i1 <= b0; ++i1) {
46 b.add(new ChunkCoordIntPair(l + k, i1 + j));
47 }
48 }
49 }
50
51 i = 0;
52 ChunkCoordinates chunkcoordinates = world.getSpawn();
53 EnumCreatureType[] aenumcreaturetype = EnumCreatureType.values();
54
55 j = aenumcreaturetype.length;
56
57 for (int j1 = 0; j1 < j; ++j1) {
58 EnumCreatureType enumcreaturetype = aenumcreaturetype[j1];
59
60 if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && world.a(enumcreaturetype.a()) <= enumcreaturetype.b() * b.size() / 256) {
61 Iterator iterator = b.iterator();
62
63 label113:
64 while (iterator.hasNext()) {
65 ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next();
66 BiomeBase biomebase = world.getWorldChunkManager().a(chunkcoordintpair);
67 List list = biomebase.a(enumcreaturetype);
68
69 if (list != null && !list.isEmpty()) {
70 int k1 = 0;
71
72 BiomeMeta biomemeta;
73
74 for (Iterator iterator1 = list.iterator(); iterator1.hasNext(); k1 += biomemeta.b) {
75 biomemeta = (BiomeMeta) iterator1.next();
76 }
77
78 int l1 = world.random.nextInt(k1);
79
80 biomemeta = (BiomeMeta) list.get(0);
81 Iterator iterator2 = list.iterator();
82
83 while (iterator2.hasNext()) {
84 BiomeMeta biomemeta1 = (BiomeMeta) iterator2.next();
85
86 l1 -= biomemeta1.b;
87 if (l1 < 0) {
88 biomemeta = biomemeta1;
89 break;
90 }
91 }
92
93 ChunkPosition chunkposition = a(world, chunkcoordintpair.x * 16, chunkcoordintpair.z * 16);
94 int i2 = chunkposition.x;
95 int j2 = chunkposition.y;
96 int k2 = chunkposition.z;
97
98 if (!world.e(i2, j2, k2) && world.getMaterial(i2, j2, k2) == enumcreaturetype.c()) {
99 int l2 = 0;
100
101 for (int i3 = 0; i3 < 3; ++i3) {
102 int j3 = i2;
103 int k3 = j2;
104 int l3 = k2;
105 byte b1 = 6;
106
107 for (int i4 = 0; i4 < 4; ++i4) {
108 j3 += world.random.nextInt(b1) - world.random.nextInt(b1);
109 k3 += world.random.nextInt(1) - world.random.nextInt(1);
110 l3 += world.random.nextInt(b1) - world.random.nextInt(b1);
111 if (a(enumcreaturetype, world, j3, k3, l3)) {
112 float f = (float) j3 + 0.5F;
113 float f1 = (float) k3;
114 float f2 = (float) l3 + 0.5F;
115
116 if (world.a((double) f, (double) f1, (double) f2, 24.0D) == null) {
117 float f3 = f - (float) chunkcoordinates.x;
118 float f4 = f1 - (float) chunkcoordinates.y;
119 float f5 = f2 - (float) chunkcoordinates.z;
120 float f6 = f3 * f3 + f4 * f4 + f5 * f5;
121
122 if (f6 >= 576.0F) {
123 EntityLiving entityliving;
124
125 try {
126 entityliving = (EntityLiving) biomemeta.a.getConstructor(new Class[] { World.class }).newInstance(new Object[] { world });
127 } catch (Exception exception) {
128 exception.printStackTrace();
129 return i;
130 }
131
132 entityliving.setPositionRotation((double) f, (double) f1, (double) f2, world.random.nextFloat() * 360.0F, 0.0F);
133 if (entityliving.d()) {
134 ++l2;
135 // CraftBukkit - added a reason for spawning this creature
136 world.addEntity(entityliving, SpawnReason.NATURAL);
137 a(entityliving, world, f, f1, f2);
138 if (l2 >= entityliving.l()) {
139 continue label113;
140 }
141 }
142
143 i += l2;
144 }
145 }
146 }
147 }
148 }
149 }
150 }
151 }
152 }
153 }
154
155 return i;
156 }
157 }
158
159 private static boolean a(EnumCreatureType enumcreaturetype, World world, int i, int j, int k) {
160 return enumcreaturetype.c() == Material.WATER ? world.getMaterial(i, j, k).isLiquid() && !world.e(i, j + 1, k) : world.e(i, j - 1, k) && !world.e(i, j, k) && !world.getMaterial(i, j, k).isLiquid() && !world.e(i, j + 1, k);
161 }
162
163 private static void a(EntityLiving entityliving, World world, float f, float f1, float f2) {
164 if (entityliving instanceof EntitySpider && world.random.nextInt(100) == 0) {
165 EntitySkeleton entityskeleton = new EntitySkeleton(world);
166
167 entityskeleton.setPositionRotation((double) f, (double) f1, (double) f2, entityliving.yaw, 0.0F);
168 // CraftBukkit - added a reason for spawning this creature
169 world.addEntity(entityskeleton, SpawnReason.NATURAL);
170 entityskeleton.mount(entityliving);
171 } else if (entityliving instanceof EntitySheep) {
172 ((EntitySheep) entityliving).setColor(EntitySheep.a(world.random));
173 }
174 }
175
176 public static boolean a(World world, List list) {
177 boolean flag = false;
178 Pathfinder pathfinder = new Pathfinder(world);
179 Iterator iterator = list.iterator();
180
181 while (iterator.hasNext()) {
182 EntityHuman entityhuman = (EntityHuman) iterator.next();
183 Class[] aclass = a;
184
185 if (aclass != null && aclass.length != 0) {
186 boolean flag1 = false;
187
188 for (int i = 0; i < 20 && !flag1; ++i) {
189 int j = MathHelper.floor(entityhuman.locX) + world.random.nextInt(32) - world.random.nextInt(32);
190 int k = MathHelper.floor(entityhuman.locZ) + world.random.nextInt(32) - world.random.nextInt(32);
191 int l = MathHelper.floor(entityhuman.locY) + world.random.nextInt(16) - world.random.nextInt(16);
192
193 if (l < 1) {
194 l = 1;
195 } else if (l > 128) {
196 l = 128;
197 }
198
199 int i1 = world.random.nextInt(aclass.length);
200
201 int j1;
202
203 for (j1 = l; j1 > 2 && !world.e(j, j1 - 1, k); --j1) {
204 ;
205 }
206
207 while (!a(EnumCreatureType.MONSTER, world, j, j1, k) && j1 < l + 16 && j1 < 128) {
208 ++j1;
209 }
210
211 if (j1 < l + 16 && j1 < 128) {
212 float f = (float) j + 0.5F;
213 float f1 = (float) j1;
214 float f2 = (float) k + 0.5F;
215
216 EntityLiving entityliving;
217
218 try {
219 entityliving = (EntityLiving) aclass[i1].getConstructor(new Class[] { World.class }).newInstance(new Object[] { world });
220 } catch (Exception exception) {
221 exception.printStackTrace();
222 return flag;
223 }
224
225 entityliving.setPositionRotation((double) f, (double) f1, (double) f2, world.random.nextFloat() * 360.0F, 0.0F);
226 if (entityliving.d()) {
227 PathEntity pathentity = pathfinder.a(entityliving, entityhuman, 32.0F);
228
229 if (pathentity != null && pathentity.a > 1) {
230 PathPoint pathpoint = pathentity.c();
231
232 if (Math.abs((double) pathpoint.a - entityhuman.locX) < 1.5D && Math.abs((double) pathpoint.c - entityhuman.locZ) < 1.5D && Math.abs((double) pathpoint.b - entityhuman.locY) < 1.5D) {
233 ChunkCoordinates chunkcoordinates = BlockBed.f(world, MathHelper.floor(entityhuman.locX), MathHelper.floor(entityhuman.locY), MathHelper.floor(entityhuman.locZ), 1);
234
235 if (chunkcoordinates == null) {
236 chunkcoordinates = new ChunkCoordinates(j, j1 + 1, k);
237 }
238
239 entityliving.setPositionRotation((double) ((float) chunkcoordinates.x + 0.5F), (double) chunkcoordinates.y, (double) ((float) chunkcoordinates.z + 0.5F), 0.0F, 0.0F);
240 // CraftBukkit - added a reason for spawning this creature
241 world.addEntity(entityliving, SpawnReason.BED);
242 a(entityliving, world, (float) chunkcoordinates.x + 0.5F, (float) chunkcoordinates.y, (float) chunkcoordinates.z + 0.5F);
243 entityhuman.a(true, false, false);
244 entityliving.Q();
245 flag = true;
246 flag1 = true;
247 }
248 }
249 }
250 }
251 }
252 }
253 }
254
255 return flag;
256 }
257}