Add configurable fix for TNT cannnons.

This attempts to revert cannoning mechanics to pre-1.8 behavior. A huge
thanks to TheIceAP who championed almost every fix in this patch.

Another shoutout to Jebediah Smith from SportBukkit for the velocity
update patch which mostly fixes the client issue of TNT moving in water.
This commit is contained in:
Byteflux 2015-06-04 14:25:07 -07:00
parent d75469a33d
commit e82e438855
2 changed files with 354 additions and 4 deletions

View File

@ -1,4 +1,4 @@
From 617b628170e99f7bb483692f80d881180a5d953c Mon Sep 17 00:00:00 2001
From 469624f4ab003a9eda57e265454a13dea46e7b02 Mon Sep 17 00:00:00 2001
From: Zach Brown <zach.brown@destroystokyo.com>
Date: Thu, 28 May 2015 00:08:15 -0500
Subject: [PATCH] PaperSpigot config files
@ -88,7 +88,7 @@ index 337aa29..c936219 100644
diff --git a/src/main/java/org/github/paperspigot/PaperSpigotConfig.java b/src/main/java/org/github/paperspigot/PaperSpigotConfig.java
new file mode 100644
index 0000000..18513a5
index 0000000..a2fabf5
--- /dev/null
+++ b/src/main/java/org/github/paperspigot/PaperSpigotConfig.java
@@ -0,0 +1,141 @@
@ -147,8 +147,8 @@ index 0000000..18513a5
+
+ commands = new HashMap<String, Command>();
+
+ version = getInt( "config-version", 8 );
+ set( "config-version", 8 );
+ version = getInt( "config-version", 9 );
+ set( "config-version", 9 );
+ readConfig( PaperSpigotConfig.class, null );
+ }
+

View File

@ -0,0 +1,350 @@
From 0f429d02717e024c12d5648f37da385520aef72c 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..793f043 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