Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package net.minecraft.server;
2
3import org.bukkit.block.BlockFace;
4import org.bukkit.event.block.BlockFromToEvent;
5
6import java.util.Random;
7
8// CraftBukkit start
9// CraftBukkit end
10
11public class BlockFlowing extends BlockFluids {
12
13 int a = 0;
14 boolean[] b = new boolean[4];
15 int[] c = new int[4];
16
17 protected BlockFlowing(int i, Material material) {
18 super(i, material);
19 }
20
21 private void i(World world, int i, int j, int k) {
22 int l = world.getData(i, j, k);
23
24 world.setRawTypeIdAndData(i, j, k, this.id + 1, l);
25 world.b(i, j, k, i, j, k);
26 world.notify(i, j, k);
27 }
28
29 public void a(World world, int i, int j, int k, Random random) {
30 // CraftBukkit start
31 org.bukkit.World bworld = world.getWorld();
32 org.bukkit.Server server = world.getServer();
33 org.bukkit.block.Block source = bworld == null ? null : bworld.getBlockAt(i, j, k);
34 // CraftBukkit end
35
36 int l = this.g(world, i, j, k);
37 byte b0 = 1;
38
39 if (this.material == Material.LAVA && !world.worldProvider.d) {
40 b0 = 2;
41 }
42
43 boolean flag = true;
44 int i1;
45
46 if (l > 0) {
47 byte b1 = -100;
48
49 this.a = 0;
50 int j1 = this.f(world, i - 1, j, k, b1);
51
52 j1 = this.f(world, i + 1, j, k, j1);
53 j1 = this.f(world, i, j, k - 1, j1);
54 j1 = this.f(world, i, j, k + 1, j1);
55 i1 = j1 + b0;
56 if (i1 >= 8 || j1 < 0) {
57 i1 = -1;
58 }
59
60 if (this.g(world, i, j + 1, k) >= 0) {
61 int k1 = this.g(world, i, j + 1, k);
62
63 if (k1 >= 8) {
64 i1 = k1;
65 } else {
66 i1 = k1 + 8;
67 }
68 }
69
70 if (this.a >= 2 && this.material == Material.WATER) {
71 if (world.getMaterial(i, j - 1, k).isBuildable()) {
72 i1 = 0;
73 } else if (world.getMaterial(i, j - 1, k) == this.material && world.getData(i, j, k) == 0) {
74 i1 = 0;
75 }
76 }
77
78 if (this.material == Material.LAVA && l < 8 && i1 < 8 && i1 > l && random.nextInt(4) != 0) {
79 i1 = l;
80 flag = false;
81 }
82
83 if (i1 != l) {
84 l = i1;
85 if (i1 < 0) {
86 world.setTypeId(i, j, k, 0);
87 } else {
88 world.setData(i, j, k, i1);
89 world.c(i, j, k, this.id, this.c());
90 world.applyPhysics(i, j, k, this.id);
91 }
92 } else if (flag) {
93 this.i(world, i, j, k);
94 }
95 } else {
96 this.i(world, i, j, k);
97 }
98
99 if (this.l(world, i, j - 1, k)) {
100 // CraftBukkit start - send "down" to the server
101 BlockFromToEvent event = new BlockFromToEvent(source, BlockFace.DOWN);
102 if (server != null) {
103 server.getPluginManager().callEvent(event);
104 }
105
106 if (!event.isCancelled()) {
107 if (l >= 8) {
108 world.setTypeIdAndData(i, j - 1, k, this.id, l);
109 } else {
110 world.setTypeIdAndData(i, j - 1, k, this.id, l + 8);
111 }
112 }
113 // CraftBukkit end
114 } else if (l >= 0 && (l == 0 || this.k(world, i, j - 1, k))) {
115 boolean[] aboolean = this.j(world, i, j, k);
116
117 i1 = l + b0;
118 if (l >= 8) {
119 i1 = 1;
120 }
121
122 if (i1 >= 8) {
123 return;
124 }
125
126 // CraftBukkit start - all four cardinal directions. Do not change the order!
127 BlockFace[] faces = new BlockFace[] { BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST };
128 int index = 0;
129
130 for (BlockFace currentFace : faces) {
131 if (aboolean[index]) {
132 BlockFromToEvent event = new BlockFromToEvent(source, currentFace);
133
134 if (server != null) {
135 server.getPluginManager().callEvent(event);
136 }
137
138 if (!event.isCancelled()) {
139 this.flow(world, i + currentFace.getModX(), j, k + currentFace.getModZ(), i1);
140 }
141 }
142 index++;
143 }
144 // CraftBukkit end
145 }
146 }
147
148 private void flow(World world, int i, int j, int k, int l) {
149 if (this.l(world, i, j, k)) {
150 int i1 = world.getTypeId(i, j, k);
151
152 if (i1 > 0) {
153 if (this.material == Material.LAVA) {
154 this.h(world, i, j, k);
155 } else {
156 Block.byId[i1].g(world, i, j, k, world.getData(i, j, k));
157 }
158 }
159
160 world.setTypeIdAndData(i, j, k, this.id, l);
161 }
162 }
163
164 private int b(World world, int i, int j, int k, int l, int i1) {
165 int j1 = 1000;
166
167 for (int k1 = 0; k1 < 4; ++k1) {
168 if ((k1 != 0 || i1 != 1) && (k1 != 1 || i1 != 0) && (k1 != 2 || i1 != 3) && (k1 != 3 || i1 != 2)) {
169 int l1 = i;
170 int i2 = k;
171
172 if (k1 == 0) {
173 l1 = i - 1;
174 }
175
176 if (k1 == 1) {
177 ++l1;
178 }
179
180 if (k1 == 2) {
181 i2 = k - 1;
182 }
183
184 if (k1 == 3) {
185 ++i2;
186 }
187
188 if (!this.k(world, l1, j, i2) && (world.getMaterial(l1, j, i2) != this.material || world.getData(l1, j, i2) != 0)) {
189 if (!this.k(world, l1, j - 1, i2)) {
190 return l;
191 }
192
193 if (l < 4) {
194 int j2 = this.b(world, l1, j, i2, l + 1, k1);
195
196 if (j2 < j1) {
197 j1 = j2;
198 }
199 }
200 }
201 }
202 }
203
204 return j1;
205 }
206
207 private boolean[] j(World world, int i, int j, int k) {
208 int l;
209 int i1;
210
211 for (l = 0; l < 4; ++l) {
212 this.c[l] = 1000;
213 i1 = i;
214 int j1 = k;
215
216 if (l == 0) {
217 i1 = i - 1;
218 }
219
220 if (l == 1) {
221 ++i1;
222 }
223
224 if (l == 2) {
225 j1 = k - 1;
226 }
227
228 if (l == 3) {
229 ++j1;
230 }
231
232 if (!this.k(world, i1, j, j1) && (world.getMaterial(i1, j, j1) != this.material || world.getData(i1, j, j1) != 0)) {
233 if (!this.k(world, i1, j - 1, j1)) {
234 this.c[l] = 0;
235 } else {
236 this.c[l] = this.b(world, i1, j, j1, 1, l);
237 }
238 }
239 }
240
241 l = this.c[0];
242
243 for (i1 = 1; i1 < 4; ++i1) {
244 if (this.c[i1] < l) {
245 l = this.c[i1];
246 }
247 }
248
249 for (i1 = 0; i1 < 4; ++i1) {
250 this.b[i1] = this.c[i1] == l;
251 }
252
253 return this.b;
254 }
255
256 private boolean k(World world, int i, int j, int k) {
257 int l = world.getTypeId(i, j, k);
258
259 if (l != Block.WOODEN_DOOR.id && l != Block.IRON_DOOR_BLOCK.id && l != Block.SIGN_POST.id && l != Block.LADDER.id && l != Block.SUGAR_CANE_BLOCK.id) {
260 if (l == 0) {
261 return false;
262 } else {
263 Material material = Block.byId[l].material;
264
265 return material.isSolid();
266 }
267 } else {
268 return true;
269 }
270 }
271
272 protected int f(World world, int i, int j, int k, int l) {
273 int i1 = this.g(world, i, j, k);
274
275 if (i1 < 0) {
276 return l;
277 } else {
278 if (i1 == 0) {
279 ++this.a;
280 }
281
282 if (i1 >= 8) {
283 i1 = 0;
284 }
285
286 return l >= 0 && i1 >= l ? l : i1;
287 }
288 }
289
290 private boolean l(World world, int i, int j, int k) {
291 Material material = world.getMaterial(i, j, k);
292
293 return material == this.material ? false : (material == Material.LAVA ? false : !this.k(world, i, j, k));
294 }
295
296 public void c(World world, int i, int j, int k) {
297 super.c(world, i, j, k);
298 if (world.getTypeId(i, j, k) == this.id) {
299 world.c(i, j, k, this.id, this.c());
300 }
301 }
302}