Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package net.minecraft.server;
2
3import org.bukkit.Bukkit;
4import org.bukkit.craftbukkit.CraftServer;
5import org.bukkit.craftbukkit.event.CraftEventFactory;
6import org.bukkit.event.Event;
7import org.bukkit.event.block.Action;
8import org.bukkit.event.block.BlockBreakEvent;
9import org.bukkit.event.block.BlockDamageEvent;
10import org.bukkit.event.player.PlayerInteractEvent;
11
12// CraftBukkit start
13
14import com.legacyminecraft.poseidon.packets.ArtificialPacket53BlockChange;
15// CraftBukkit end
16
17import uk.betacraft.uberbukkit.packet.Packet62Sound;
18import uk.betacraft.uberbukkit.packet.Packet63Digging;
19
20public class ItemInWorldManager {
21
22 private WorldServer world;
23 public EntityHuman player;
24 private int c = 0;
25 private long lastDigTick;
26 public int e;
27 public int f;
28 public int g;
29 private long currentTick;
30 private boolean i;
31 private int j;
32 private int k;
33 private int l;
34 private long m;
35
36 public double damageDealt;
37 public float delaySound; // uberbukkit
38
39 public ItemInWorldManager(WorldServer worldserver) {
40 this.world = worldserver;
41 this.delaySound = 0.0F;
42 }
43
44 // ======= UBERBUKKIT PRE-b1.3 AREA =======
45
46 public void oldClick(int i, int j, int k, int l) { // UberBukkit add block face
47 int i1 = this.world.getTypeId(i, j, k);
48
49 // CraftBukkit start
50 PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, i, j, k, l, this.player.inventory.getItemInHand());
51
52 if (event.useInteractedBlock() == Event.Result.DENY) {
53 // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door.
54 if (i1 == Block.WOODEN_DOOR.id) {
55 // For some reason *BOTH* the bottom/top part have to be marked updated.
56 boolean bottom = (this.world.getData(i, j, k) & 8) == 0;
57 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world));
58 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j + (bottom ? 1 : -1), k, this.world));
59 } else if (i1 == Block.TRAP_DOOR.id) {
60 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world));
61 }
62 } else {
63 if (i1 > 0 && this.damageDealt == 0.0F) {
64 Block.byId[i1].b(this.world, i, j, k, this.player);
65 }
66 // Allow fire punching to be blocked
67 this.world.douseFire(player, i, j, k, l);
68 }
69 // CraftBukkit end
70
71 if (i1 > 0 && Block.byId[i1].getDamage(this.player) >= 1.0F) {
72 this.c(i, j, k);
73 }
74 }
75
76 public void oldHaltBreak() {
77 this.damageDealt = 0.0F;
78 this.c = 0;
79 }
80
81 public void oldDig(int i, int j, int k, int l) {
82 if (this.c > 0) {
83 --this.c;
84 } else {
85 if (i == this.e && j == this.f && k == this.g) {
86 int i1 = this.world.getTypeId(i, j, k);
87
88 if (i1 == 0) {
89 return;
90 }
91
92 Block block = Block.byId[i1];
93
94 this.damageDealt += block.getDamage(this.player);
95
96 // uberbukkit - play breaking sound for others
97 if (delaySound % 4.0F == 0.0F && block != null) {
98 this.world.makeSound((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, block.stepSound.getName(), (block.stepSound.getVolume1() + 1.0F) / 8.0F, block.stepSound.getVolume2() * 0.5F);
99 ((CraftServer) Bukkit.getServer()).getHandle().sendPacketNearby(player, i, j, k, 64D, player.dimension, new Packet63Digging(i, j, k, l, (float) this.damageDealt));
100 }
101
102 delaySound++;
103
104 if (this.damageDealt >= 1.0F) {
105 this.c(i, j, k);
106 this.damageDealt = 0.0F;
107 this.c = 5;
108 delaySound = 0.0F;
109 }
110 } else {
111 this.damageDealt = 0.0F;
112 this.e = i;
113 this.f = j;
114 this.g = k;
115 delaySound = 0.0F;
116 }
117 }
118 }
119
120 // ======= END =======
121
122 public void a() {
123 this.currentTick = System.currentTimeMillis(); // CraftBukkit
124 if (this.i) {
125 int i = (int) ((this.currentTick / 50) - (this.m / 50));
126 int j = this.world.getTypeId(this.j, this.k, this.l);
127
128 if (j != 0) {
129 Block block = Block.byId[j];
130 float f = block.getDamage(this.player) * (float) (i + 1);
131
132 if (f >= 1.0F) {
133 this.i = false;
134 this.c(this.j, this.k, this.l);
135 }
136 } else {
137 this.i = false;
138 }
139 }
140 }
141
142 // uberbukkit - make toolDamage from dig(...) accessible for getExpectedDigEnd()
143 public float toolDamage = 1.0F;
144
145 public void dig(int i, int j, int k, int l) {
146 // this.world.douseFire((EntityHuman) null, i, j, k, l); // CraftBukkit - moved down
147 this.lastDigTick = System.currentTimeMillis(); // CraftBukkit
148 int i1 = this.world.getTypeId(i, j, k);
149
150 // CraftBukkit start
151 // Swings at air do *NOT* exist.
152 if (i1 <= 0) {
153 return;
154 }
155
156 PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, i, j, k, l, this.player.inventory.getItemInHand());
157
158 if (event.useInteractedBlock() == Event.Result.DENY) {
159 // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door.
160 if (i1 == Block.WOODEN_DOOR.id) {
161 // For some reason *BOTH* the bottom/top part have to be marked updated.
162 boolean bottom = (this.world.getData(i, j, k) & 8) == 0;
163 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world));
164 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j + (bottom ? 1 : -1), k, this.world));
165 } else if (i1 == Block.TRAP_DOOR.id) {
166 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world));
167 }
168 } else {
169 Block.byId[i1].b(this.world, i, j, k, this.player);
170 // Allow fire punching to be blocked
171 this.world.douseFire((EntityHuman) null, i, j, k, l);
172 }
173
174 // Handle hitting a block
175 toolDamage = Block.byId[i1].getDamage(this.player);
176 if (event.useItemInHand() == Event.Result.DENY) {
177 // If we 'insta destroyed' then the client needs to be informed.
178 if (toolDamage > 1.0f) {
179 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world));
180 }
181 return;
182 }
183 BlockDamageEvent blockEvent = CraftEventFactory.callBlockDamageEvent(this.player, i, j, k, this.player.inventory.getItemInHand(), toolDamage >= 1.0f);
184
185 if (blockEvent.isCancelled()) {
186 return;
187 }
188
189 if (blockEvent.getInstaBreak()) {
190 toolDamage = 2.0f;
191 }
192
193 Block block = Block.byId[i1];
194
195 // uberbukkit - send digging sound
196 if (block != null) {
197 float vol1 = (block.stepSound.getVolume1() + 1.0F) / 8.0F;
198
199 ((CraftServer) Bukkit.getServer()).getHandle().sendPacketNearbyToScale(this.player, (double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, vol1, ((WorldServer) this.player.world).dimension, new Packet62Sound(block.stepSound.getName(), (double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, vol1, block.stepSound.getVolume2() * 0.5F));
200 }
201
202 if (toolDamage >= 1.0F) {
203 // CraftBukkit end
204 this.c(i, j, k);
205 } else {
206 this.e = i;
207 this.f = j;
208 this.g = k;
209 }
210 }
211
212 public void a(int i, int j, int k) {
213 if (i == this.e && j == this.f && k == this.g) {
214 this.currentTick = System.currentTimeMillis(); // CraftBukkit
215 int l = (int) ((this.currentTick / 50) - (this.lastDigTick / 50));
216 int i1 = this.world.getTypeId(i, j, k);
217
218 if (i1 != 0) {
219 Block block = Block.byId[i1];
220 float f = block.getDamage(this.player) * (float) (l + 1);
221
222 if (f >= 0.7F) {
223 this.c(i, j, k);
224 } else if (!this.i) {
225 this.i = true;
226 this.j = i;
227 this.k = j;
228 this.l = k;
229 this.m = this.lastDigTick;
230 }
231 }
232 // CraftBukkit start - force blockreset to client
233 } else {
234 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world));
235 // CraftBukkit end
236 }
237 }
238
239 public long getExpectedDigEnd() {
240 return (long) (1F / toolDamage / 0.0214285703109844D) + this.lastDigTick;
241 }
242
243 public int getCurrentMagic() {
244 return (int) ((System.currentTimeMillis() / 50) - (this.lastDigTick / 50));
245 }
246
247 public boolean b(int i, int j, int k) {
248 Block block = Block.byId[this.world.getTypeId(i, j, k)];
249 int l = this.world.getData(i, j, k);
250 boolean flag = this.world.setTypeId(i, j, k, 0);
251
252 if (block != null && flag) {
253 block.postBreak(this.world, i, j, k, l);
254 }
255
256 return flag;
257 }
258
259 public boolean c(int i, int j, int k) {
260 // CraftBukkit start
261 if (this.player instanceof EntityPlayer) {
262 org.bukkit.block.Block block = this.world.getWorld().getBlockAt(i, j, k);
263
264 //Project Poseidon Start - Craft Bukkit backport
265 // Tell client the block is gone immediately then process events
266 if (world.getTileEntity(i, j, k) == null) {
267 ((EntityPlayer) this.player).netServerHandler.sendPacket(new ArtificialPacket53BlockChange(i, j, k, 0, 0));
268 }
269 //Project Poseidon End
270 BlockBreakEvent event = new BlockBreakEvent(block, (org.bukkit.entity.Player) this.player.getBukkitEntity());
271 this.world.getServer().getPluginManager().callEvent(event);
272
273 if (event.isCancelled()) {
274 return false;
275 }
276 }
277 // CraftBukkit end
278
279 int l = this.world.getTypeId(i, j, k);
280 int i1 = this.world.getData(i, j, k);
281
282 this.world.a(this.player, 2001, i, j, k, l + this.world.getData(i, j, k) * 256);
283 boolean flag = this.b(i, j, k);
284 ItemStack itemstack = this.player.G();
285
286 if (flag && this.player.b(Block.byId[l])) {
287 Block.byId[l].a(this.world, this.player, i, j, k, i1);
288 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world));
289 }
290
291 if (itemstack != null) {
292 itemstack.a(l, i, j, k, this.player);
293 if (itemstack.count == 0) {
294 itemstack.a(this.player);
295 this.player.H();
296 }
297 }
298
299 return flag;
300 }
301
302 public boolean useItem(EntityHuman entityhuman, World world, ItemStack itemstack) {
303 int i = itemstack.count;
304 ItemStack itemstack1 = itemstack.a(world, entityhuman);
305
306 if (itemstack1 == itemstack && (itemstack1 == null || itemstack1.count == i)) {
307 return false;
308 } else {
309 entityhuman.inventory.items[entityhuman.inventory.itemInHandIndex] = itemstack1;
310 if (itemstack1.count == 0) {
311 entityhuman.inventory.items[entityhuman.inventory.itemInHandIndex] = null;
312 }
313
314 return true;
315 }
316 }
317
318 public boolean interact(EntityHuman entityhuman, World world, ItemStack itemstack, int i, int j, int k, int l) {
319 int i1 = world.getTypeId(i, j, k);
320
321 // CraftBukkit start - Interact
322 boolean result = false;
323 if (i1 > 0) {
324 PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(entityhuman, Action.RIGHT_CLICK_BLOCK, i, j, k, l, itemstack);
325 if (event.useInteractedBlock() == Event.Result.DENY) {
326 // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door.
327 if (i1 == Block.WOODEN_DOOR.id) {
328 boolean bottom = (world.getData(i, j, k) & 8) == 0;
329 ((EntityPlayer) entityhuman).netServerHandler.sendPacket(new Packet53BlockChange(i, j + (bottom ? 1 : -1), k, world));
330 }
331 result = (event.useItemInHand() != Event.Result.ALLOW);
332 } else {
333 result = Block.byId[i1].interact(world, i, j, k, entityhuman);
334 }
335
336 if (itemstack != null && !result) {
337 result = itemstack.placeItem(entityhuman, world, i, j, k, l);
338 }
339
340 // If we have 'true' and no explicit deny *or* an explicit allow -- run the item part of the hook
341 if (itemstack != null && ((!result && event.useItemInHand() != Event.Result.DENY) || event.useItemInHand() == Event.Result.ALLOW)) {
342 this.useItem(entityhuman, world, itemstack);
343 }
344 }
345 return result;
346 // CraftBukkit end
347 }
348}