papermc/Spigot-Server-Patches/0054-Configurable-TNT-cannon-fix.patch

350 lines
18 KiB
Diff

From 9731a3cad42fe83dbe25013238a3fbca97bf2ad6 Mon Sep 17 00:00:00 2001
From: Iceee <andrew@opticgaming.tv>
Date: Thu, 4 Jun 2015 13:55:02 -0700
Subject: [PATCH] Configurable TNT cannon fix
diff --git a/src/main/java/net/minecraft/server/BlockDiodeAbstract.java b/src/main/java/net/minecraft/server/BlockDiodeAbstract.java
index ee49839..eaf9154 100644
--- a/src/main/java/net/minecraft/server/BlockDiodeAbstract.java
+++ b/src/main/java/net/minecraft/server/BlockDiodeAbstract.java
@@ -72,6 +72,17 @@ public abstract class BlockDiodeAbstract extends BlockDirectional {
} else {
this.b(world, blockposition, iblockdata, 0);
world.setAir(blockposition);
+ // PaperSpigot start - Fix cannons
+ if (world.paperSpigotConfig.fixCannons) {
+ world.applyPhysics(blockposition.shift(EnumDirection.EAST), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.WEST), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.SOUTH), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.NORTH), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.DOWN), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.UP), this);
+ return;
+ }
+ // PaperSpigot end
EnumDirection[] aenumdirection = EnumDirection.values();
int i = aenumdirection.length;
@@ -169,6 +180,17 @@ public abstract class BlockDiodeAbstract extends BlockDirectional {
public void postBreak(World world, BlockPosition blockposition, IBlockData iblockdata) {
if (this.N) {
+ // PaperSpigot start - Fix cannons
+ if (world.paperSpigotConfig.fixCannons) {
+ world.applyPhysics(blockposition.shift(EnumDirection.EAST), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.WEST), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.NORTH), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.SOUTH), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.DOWN), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.UP), this);
+ return;
+ }
+ // PaperSpigot end
EnumDirection[] aenumdirection = EnumDirection.values();
int i = aenumdirection.length;
diff --git a/src/main/java/net/minecraft/server/BlockRedstoneTorch.java b/src/main/java/net/minecraft/server/BlockRedstoneTorch.java
index 6a7e7b3..78c6d19 100644
--- a/src/main/java/net/minecraft/server/BlockRedstoneTorch.java
+++ b/src/main/java/net/minecraft/server/BlockRedstoneTorch.java
@@ -52,6 +52,17 @@ public class BlockRedstoneTorch extends BlockTorch {
public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) {
if (this.isOn) {
+ // PaperSpigot start - Fix cannons
+ if (world.paperSpigotConfig.fixCannons) {
+ world.applyPhysics(blockposition.shift(EnumDirection.DOWN), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.UP), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.WEST), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.EAST), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.SOUTH), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.NORTH), this);
+ return;
+ }
+ // PaperSpigot end
EnumDirection[] aenumdirection = EnumDirection.values();
int i = aenumdirection.length;
@@ -66,6 +77,17 @@ public class BlockRedstoneTorch extends BlockTorch {
public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {
if (this.isOn) {
+ // PaperSpigot start - Fix cannons
+ if (world.paperSpigotConfig.fixCannons) {
+ world.applyPhysics(blockposition.shift(EnumDirection.DOWN), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.UP), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.WEST), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.EAST), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.SOUTH), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.NORTH), this);
+ return;
+ }
+ // PaperSpigot end
EnumDirection[] aenumdirection = EnumDirection.values();
int i = aenumdirection.length;
diff --git a/src/main/java/net/minecraft/server/BlockRedstoneWire.java b/src/main/java/net/minecraft/server/BlockRedstoneWire.java
index ea87aa5..3e3848e 100644
--- a/src/main/java/net/minecraft/server/BlockRedstoneWire.java
+++ b/src/main/java/net/minecraft/server/BlockRedstoneWire.java
@@ -142,6 +142,17 @@ public class BlockRedstoneWire extends Block {
}
this.R.add(blockposition);
+ // PaperSpigot start - Fix cannons
+ if (world.paperSpigotConfig.fixCannons) {
+ this.R.add(blockposition.shift(EnumDirection.WEST));
+ this.R.add(blockposition.shift(EnumDirection.EAST));
+ this.R.add(blockposition.shift(EnumDirection.DOWN));
+ this.R.add(blockposition.shift(EnumDirection.UP));
+ this.R.add(blockposition.shift(EnumDirection.NORTH));
+ this.R.add(blockposition.shift(EnumDirection.SOUTH));
+ return iblockdata;
+ }
+ // PaperSpigot end
EnumDirection[] aenumdirection = EnumDirection.values();
int i1 = aenumdirection.length;
@@ -158,6 +169,17 @@ public class BlockRedstoneWire extends Block {
private void e(World world, BlockPosition blockposition) {
if (world.getType(blockposition).getBlock() == this) {
world.applyPhysics(blockposition, this);
+ // PaperSpigot start - Fix cannons
+ if (world.paperSpigotConfig.fixCannons) {
+ world.applyPhysics(blockposition.shift(EnumDirection.WEST), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.EAST), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.NORTH), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.SOUTH), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.DOWN), this);
+ world.applyPhysics(blockposition.shift(EnumDirection.UP), this);
+ return;
+ }
+ // PaperSpigot end
EnumDirection[] aenumdirection = EnumDirection.values();
int i = aenumdirection.length;
diff --git a/src/main/java/net/minecraft/server/BlockTNT.java b/src/main/java/net/minecraft/server/BlockTNT.java
index 3a0bc4b..a901742 100644
--- a/src/main/java/net/minecraft/server/BlockTNT.java
+++ b/src/main/java/net/minecraft/server/BlockTNT.java
@@ -30,7 +30,11 @@ public class BlockTNT extends Block {
public void wasExploded(World world, BlockPosition blockposition, Explosion explosion) {
if (!world.isClientSide) {
org.bukkit.Location loc = explosion.source instanceof EntityTNTPrimed ? ((EntityTNTPrimed) explosion.source).sourceLoc : new org.bukkit.Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); // PaperSpigot
- EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(loc, world, (double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.5F), (double) ((float) blockposition.getZ() + 0.5F), explosion.c()); // PaperSpigot - add loc
+ // PaperSpigot start - Fix cannons
+ double y = blockposition.getY();
+ if (!world.paperSpigotConfig.fixCannons) y += 0.5;
+ EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(loc, world, (double) ((float) blockposition.getX() + 0.5F), y, (double) ((float) blockposition.getZ() + 0.5F), explosion.c()); // PaperSpigot - add loc
+ // PaperSpigot end
entitytntprimed.fuseTicks = world.random.nextInt(entitytntprimed.fuseTicks / 4) + entitytntprimed.fuseTicks / 8;
world.addEntity(entitytntprimed);
@@ -45,7 +49,11 @@ public class BlockTNT extends Block {
if (!world.isClientSide) {
if (((Boolean) iblockdata.get(BlockTNT.EXPLODE)).booleanValue()) {
org.bukkit.Location loc = new org.bukkit.Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); // PaperSpigot
- EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(loc, world, (double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.5F), (double) ((float) blockposition.getZ() + 0.5F), entityliving); // PaperSpigot - add loc
+ // PaperSpigot start - Fix cannons
+ double y = blockposition.getY();
+ if (!world.paperSpigotConfig.fixCannons) y += 0.5;
+ EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(loc, world, (double) ((float) blockposition.getX() + 0.5F), y, (double) ((float) blockposition.getZ() + 0.5F), entityliving); // PaperSpigot - add loc
+ // PaperSpigot end
world.addEntity(entitytntprimed);
world.makeSound(entitytntprimed, "game.tnt.primed", 1.0F, 1.0F);
diff --git a/src/main/java/net/minecraft/server/DispenserRegistry.java b/src/main/java/net/minecraft/server/DispenserRegistry.java
index f3858d1..d8e1609 100644
--- a/src/main/java/net/minecraft/server/DispenserRegistry.java
+++ b/src/main/java/net/minecraft/server/DispenserRegistry.java
@@ -519,7 +519,11 @@ public class DispenserRegistry {
org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ());
CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1);
- BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX() + 0.5, blockposition.getY() + 0.5, blockposition.getZ() + 0.5));
+ // PaperSpigot start - Fix cannons
+ double y = blockposition.getY();
+ if (!world.paperSpigotConfig.fixCannons) y += 0.5;
+ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX() + 0.5, y, blockposition.getZ() + 0.5));
+ // PaperSpigot end
if (!BlockDispenser.eventFired) {
world.getServer().getPluginManager().callEvent(event);
}
diff --git a/src/main/java/net/minecraft/server/EntityFallingBlock.java b/src/main/java/net/minecraft/server/EntityFallingBlock.java
index a0452ac..8a3fd44 100644
--- a/src/main/java/net/minecraft/server/EntityFallingBlock.java
+++ b/src/main/java/net/minecraft/server/EntityFallingBlock.java
@@ -291,4 +291,22 @@ public class EntityFallingBlock extends Entity {
public IBlockData getBlock() {
return this.block;
}
+
+ // PaperSpigot start - Fix cannons
+ @Override
+ public double f(double d0, double d1, double d2) {
+ if (!world.paperSpigotConfig.fixCannons) return super.f(d0, d1, d2);
+
+ double d3 = this.locX - d0;
+ double d4 = this.locY + this.getHeadHeight() - d1;
+ double d5 = this.locZ - d2;
+
+ return (double) MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
+ }
+
+ @Override
+ public float getHeadHeight() {
+ return world.paperSpigotConfig.fixCannons ? this.length / 2 : super.getHeadHeight();
+ }
+ // PaperSpigot end
}
diff --git a/src/main/java/net/minecraft/server/EntityTNTPrimed.java b/src/main/java/net/minecraft/server/EntityTNTPrimed.java
index db33c98..5290767 100644
--- a/src/main/java/net/minecraft/server/EntityTNTPrimed.java
+++ b/src/main/java/net/minecraft/server/EntityTNTPrimed.java
@@ -36,6 +36,7 @@ public class EntityTNTPrimed extends Entity {
this.lastY = d1;
this.lastZ = d2;
this.source = entityliving;
+ if (world.paperSpigotConfig.fixCannons) this.motX = this.motZ = 0.0F; // PaperSpigot - Fix cannons
}
protected void h() {}
@@ -156,7 +157,64 @@ public class EntityTNTPrimed extends Entity {
return this.source;
}
+ // PaperSpigot start - Fix cannons
+ @Override
+ public double f(double d0, double d1, double d2) {
+ if (!world.paperSpigotConfig.fixCannons) return super.f(d0, d1, d2);
+
+ double d3 = this.locX - d0;
+ double d4 = this.locY + this.getHeadHeight() - d1;
+ double d5 = this.locZ - d2;
+
+ return (double) MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
+ }
+
+ @Override
+ public boolean aL() {
+ return !world.paperSpigotConfig.fixCannons && super.aL();
+ }
+
+ @Override
public float getHeadHeight() {
- return 0.0F;
+ return world.paperSpigotConfig.fixCannons ? this.length / 2 : 0.0F;
}
+
+ /**
+ * Author: Jedediah Smith <jedediah@silencegreys.com>
+ */
+ @Override
+ public boolean W() {
+ if (!world.paperSpigotConfig.fixCannons) return super.W();
+
+ // Preserve velocity while calling the super method
+ double oldMotX = this.motX;
+ double oldMotY = this.motY;
+ double oldMotZ = this.motZ;
+
+ super.W();
+
+ this.motX = oldMotX;
+ this.motY = oldMotY;
+ this.motZ = oldMotZ;
+
+ if (this.inWater) {
+ // Send position and velocity updates to nearby players on every tick while the TNT is in water.
+ // This does pretty well at keeping their clients in sync with the server.
+ EntityTrackerEntry ete = ((WorldServer) this.getWorld()).getTracker().trackedEntities.get(this.getId());
+ if (ete != null) {
+ PacketPlayOutEntityVelocity velocityPacket = new PacketPlayOutEntityVelocity(this);
+ PacketPlayOutEntityTeleport positionPacket = new PacketPlayOutEntityTeleport(this);
+
+ for (EntityPlayer viewer : ete.trackedPlayers) {
+ if ((viewer.locX - this.locX) * (viewer.locY - this.locY) * (viewer.locZ - this.locZ) < 16 * 16) {
+ viewer.playerConnection.sendPacket(velocityPacket);
+ viewer.playerConnection.sendPacket(positionPacket);
+ }
+ }
+ }
+ }
+
+ return this.inWater;
+ }
+ // PaperSpigot end
}
diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java
index fdf886a..a3df604 100644
--- a/src/main/java/net/minecraft/server/Explosion.java
+++ b/src/main/java/net/minecraft/server/Explosion.java
@@ -142,9 +142,16 @@ public class Explosion {
// CraftBukkit end
double d14 = EnchantmentProtection.a(entity, d13);
+ // PaperSpigot start - Fix cannons
+ /*
entity.motX += d8 * d14;
entity.motY += d9 * d14;
entity.motZ += d10 * d14;
+ */
+ // This impulse method sets the dirty flag, so clients will get an immediate velocity update
+ entity.g(d8 * d14, d9 * d14, d10 * d14);
+ // PaperSpigot end
+
if (entity instanceof EntityHuman && !((EntityHuman) entity).abilities.isInvulnerable) {
this.k.put((EntityHuman) entity, new Vec3D(d8 * d13, d9 * d13, d10 * d13));
}
diff --git a/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java b/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java
index 8338cc6..3edd322 100644
--- a/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java
+++ b/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java
@@ -299,4 +299,43 @@ public class PaperSpigotWorldConfig
generateVillage = getBoolean( "generator-settings.village", true );
generateFlatBedrock = getBoolean( "generator-settings.flat-bedrock", false );
}
+
+ public boolean fixCannons;
+ private void fixCannons()
+ {
+ // TODO: Remove migrations after most users have upgraded.
+ if ( PaperSpigotConfig.version < 9 )
+ {
+ // Migrate default value
+
+ boolean value = config.getBoolean( "world-settings.default.fix-cannons", false );
+ if ( !value ) value = config.getBoolean( "world-settings.default.tnt-gameplay.fix-directional-bias", false );
+ if ( !value ) value = !config.getBoolean( "world-settings.default.tnt-gameplay.moves-in-water", true );
+ if ( !value ) value = config.getBoolean( "world-settings.default.tnt-gameplay.legacy-explosion-height", false );
+ if ( value ) config.set( "world-settings.default.fix-cannons", true );
+
+ if ( config.contains( "world-settings.default.tnt-gameplay" ) )
+ {
+ config.getDefaults().set( "world-settings.default.tnt-gameplay", null);
+ config.set( "world-settings.default.tnt-gameplay", null );
+ }
+
+ // Migrate world setting
+
+ value = config.getBoolean( "world-settings." + worldName + ".fix-cannons", false );
+ if ( !value ) value = config.getBoolean( "world-settings." + worldName + ".tnt-gameplay.fix-directional-bias", false );
+ if ( !value ) value = !config.getBoolean( "world-settings." + worldName + ".tnt-gameplay.moves-in-water", true );
+ if ( !value ) value = config.getBoolean( "world-settings." + worldName + ".tnt-gameplay.legacy-explosion-height", false );
+ if ( value ) config.set( "world-settings." + worldName + ".fix-cannons", true );
+
+ if ( config.contains( "world-settings." + worldName + ".tnt-gameplay" ) )
+ {
+ config.getDefaults().set( "world-settings." + worldName + ".tnt-gameplay", null);
+ config.set( "world-settings." + worldName + ".tnt-gameplay", null );
+ }
+ }
+
+ fixCannons = getBoolean( "fix-cannons", false );
+ log( "Fix TNT cannons: " + fixCannons );
+ }
}
--
1.9.5.msysgit.1