mirror of
https://github.com/PaperMC/Paper.git
synced 2025-03-20 14:08:57 +01:00
Get skull data before destroying block. Fixes BUKKIT-2723
Skull blocks store their type in a tile entity and use their block data as rotation. When breaking a block the block data is used for determining what item to drop. Simply changing this to use the skull method for getting their drop data is not enough because their tile entity is already gone. Therefore we have to special case skulls to get the correct data _and_ get that data before breaking the block.
This commit is contained in:
parent
14f4bd9024
commit
216cddb2ab
4 changed files with 30 additions and 8 deletions
|
@ -264,8 +264,14 @@ public class Explosion {
|
||||||
|
|
||||||
// CraftBukkit - stop explosions from putting out fire
|
// CraftBukkit - stop explosions from putting out fire
|
||||||
if (l > 0 && l != Block.FIRE.id) {
|
if (l > 0 && l != Block.FIRE.id) {
|
||||||
// CraftBukkit
|
// CraftBukkit start - special case skulls, add yield
|
||||||
Block.byId[l].dropNaturally(this.world, i, j, k, this.world.getData(i, j, k), event.getYield(), 0);
|
int data = this.world.getData(i, j, k);
|
||||||
|
if (l == Block.SKULL.id) {
|
||||||
|
data = Block.SKULL.getDropData(this.world, i, j, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
Block.byId[l].dropNaturally(this.world, i, j, k, data, event.getYield(), 0);
|
||||||
|
// CraftBukkit end
|
||||||
if (this.world.setRawTypeIdAndData(i, j, k, 0, 0, this.world.isStatic)) {
|
if (this.world.setRawTypeIdAndData(i, j, k, 0, 0, this.world.isStatic)) {
|
||||||
this.world.applyPhysics(i, j, k, 0);
|
this.world.applyPhysics(i, j, k, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -291,6 +291,11 @@ public class ItemInWorldManager {
|
||||||
int l = this.world.getTypeId(i, j, k);
|
int l = this.world.getTypeId(i, j, k);
|
||||||
if (Block.byId[l] == null) return false; // CraftBukkit - a plugin set block to air without cancelling
|
if (Block.byId[l] == null) return false; // CraftBukkit - a plugin set block to air without cancelling
|
||||||
int i1 = this.world.getData(i, j, k);
|
int i1 = this.world.getData(i, j, k);
|
||||||
|
// CraftBukkit start - special case skulls, their item data comes from a tile entity
|
||||||
|
if (l == Block.SKULL.id) {
|
||||||
|
i1 = Block.SKULL.getDropData(world, i, j, k);
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
|
|
||||||
this.world.a(this.player, 2001, i, j, k, l + (this.world.getData(i, j, k) << 12));
|
this.world.a(this.player, 2001, i, j, k, l + (this.world.getData(i, j, k) << 12));
|
||||||
boolean flag = this.d(i, j, k);
|
boolean flag = this.d(i, j, k);
|
||||||
|
|
|
@ -1083,7 +1083,11 @@ public class CraftWorld implements World {
|
||||||
int blockY = block.getY();
|
int blockY = block.getY();
|
||||||
int blockZ = block.getZ();
|
int blockZ = block.getZ();
|
||||||
// following code is lifted from Explosion.a(boolean), and modified
|
// following code is lifted from Explosion.a(boolean), and modified
|
||||||
net.minecraft.server.Block.byId[blockId].dropNaturally(this.world, blockX, blockY, blockZ, block.getData(), yield, 0);
|
int data = block.getData();
|
||||||
|
if (blockId == net.minecraft.server.Block.SKULL.id) {
|
||||||
|
data = net.minecraft.server.Block.SKULL.getDropData(this.world, blockX, blockY, blockZ);
|
||||||
|
}
|
||||||
|
net.minecraft.server.Block.byId[blockId].dropNaturally(this.world, blockX, blockY, blockZ, data, yield, 0);
|
||||||
block.setType(org.bukkit.Material.AIR);
|
block.setType(org.bukkit.Material.AIR);
|
||||||
// not sure what this does, seems to have something to do with the 'base' material of a block.
|
// not sure what this does, seems to have something to do with the 'base' material of a block.
|
||||||
// For example, WOODEN_STAIRS does something with WOOD in this method
|
// For example, WOODEN_STAIRS does something with WOOD in this method
|
||||||
|
|
|
@ -342,15 +342,22 @@ public class CraftBlock implements Block {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean breakNaturally() {
|
public boolean breakNaturally() {
|
||||||
|
// Order matters here, need to drop before setting to air so skulls can get their data
|
||||||
net.minecraft.server.Block block = net.minecraft.server.Block.byId[this.getTypeId()];
|
net.minecraft.server.Block block = net.minecraft.server.Block.byId[this.getTypeId()];
|
||||||
byte data = getData();
|
byte data = getData();
|
||||||
|
boolean result = false;
|
||||||
|
|
||||||
|
if (block != null) {
|
||||||
|
if (block.id == net.minecraft.server.Block.SKULL.id) {
|
||||||
|
data = (byte) block.getDropData(chunk.getHandle().world, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
block.dropNaturally(chunk.getHandle().world, x, y, z, data, 1.0F, 0);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
setTypeId(Material.AIR.getId());
|
setTypeId(Material.AIR.getId());
|
||||||
if (block != null) {
|
return result;
|
||||||
block.dropNaturally(chunk.getHandle().world, x, y, z, data, 1.0F, 0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean breakNaturally(ItemStack item) {
|
public boolean breakNaturally(ItemStack item) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue