Skip to content

Commit

Permalink
More work on the block breaking of AOE Tools: Really fast tools now b…
Browse files Browse the repository at this point in the history
…reak in AOE correctly. Changed behaviour to emulate the correct behaviour, but don't call the recursive block breaks. Furthermore, send packets causing updates for each AOE block broken. This should prevent clientside ghost blocks because the client is breaking blocks that it can't break yet on the server.

#1072
  • Loading branch information
bonii-xx committed Oct 14, 2014
1 parent eb874d8 commit fc35996
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 55 deletions.
1 change: 1 addition & 0 deletions resources/META-INF/TConstruct_at.cfg
Expand Up @@ -38,4 +38,5 @@ public net.minecraft.client.multiplayer.PlayerControllerMP func_85182_a(III)Z #s
public net.minecraft.server.management.ItemInWorldManager field_73086_f
public net.minecraft.server.management.ItemInWorldManager field_73087_g
public net.minecraft.server.management.ItemInWorldManager field_73099_h
public net.minecraft.server.management.ItemInWorldManager func_73079_d(III)Z #removeBlock
# needs to have a space at the end of every line or SS will derp
84 changes: 33 additions & 51 deletions src/main/java/tconstruct/library/tools/AOEHarvestTool.java
Expand Up @@ -32,60 +32,42 @@ public boolean onBlockStartBreak(ItemStack stack, int x, int y, int z, EntityPla
if(block == null || !isEffective(block, meta))
return super.onBlockStartBreak(stack, x,y,z, player);

boolean originalBlock = true;
// check if we're breaking the block we hit, or if this call belongs to one of the surrounding blocks broken by the AOE
if(player.worldObj.isRemote)
{
originalBlock = Minecraft.getMinecraft().playerController.sameToolAndBlock(x,y,z);
}
// same check serverside
else {
ItemInWorldManager iiiwm = ((EntityPlayerMP) player).theItemInWorldManager;

if(x != iiiwm.partiallyDestroyedBlockX || y != iiiwm.partiallyDestroyedBlockY || z != iiiwm.partiallyDestroyedBlockZ)
originalBlock = false;
}

// the code below initiates block breaks, which again call this function. But we don't want to do the aoe-break-stuff again. This is to prevent recursive, infinite-range aoe blockbreaking.
if(originalBlock || player.capabilities.isCreativeMode) {
MovingObjectPosition mop = AbilityHelper.raytraceFromEntity(player.worldObj, player, false, 4.5d);
if(mop == null)
return super.onBlockStartBreak(stack, x,y,z, player);
int sideHit = mop.sideHit;
//int sideHit = Minecraft.getMinecraft().objectMouseOver.sideHit;

// we successfully destroyed a block. time to do AOE!
int xRange = breakRadius;
int yRange = breakRadius;
int zRange = breakDepth;
switch (sideHit) {
case 0:
case 1:
yRange = breakDepth;
zRange = breakRadius;
break;
case 2:
case 3:
xRange = breakRadius;
zRange = breakDepth;
break;
case 4:
case 5:
xRange = breakDepth;
zRange = breakRadius;
break;
}
MovingObjectPosition mop = AbilityHelper.raytraceFromEntity(player.worldObj, player, false, 4.5d);
if(mop == null)
return super.onBlockStartBreak(stack, x,y,z, player);
int sideHit = mop.sideHit;
//int sideHit = Minecraft.getMinecraft().objectMouseOver.sideHit;

for (int xPos = x - xRange; xPos <= x + xRange; xPos++)
for (int yPos = y - yRange; yPos <= y + yRange; yPos++)
for (int zPos = z - zRange; zPos <= z + zRange; zPos++) {
// don't break the originally already broken block, duh
if (xPos == x && yPos == y && zPos == z)
continue;
breakExtraBlock(player.worldObj, xPos, yPos, zPos, sideHit, player, x,y,z);
}
// we successfully destroyed a block. time to do AOE!
int xRange = breakRadius;
int yRange = breakRadius;
int zRange = breakDepth;
switch (sideHit) {
case 0:
case 1:
yRange = breakDepth;
zRange = breakRadius;
break;
case 2:
case 3:
xRange = breakRadius;
zRange = breakDepth;
break;
case 4:
case 5:
xRange = breakDepth;
zRange = breakRadius;
break;
}

for (int xPos = x - xRange; xPos <= x + xRange; xPos++)
for (int yPos = y - yRange; yPos <= y + yRange; yPos++)
for (int zPos = z - zRange; zPos <= z + zRange; zPos++) {
// don't break the originally already broken block, duh
if (xPos == x && yPos == y && zPos == z)
continue;
breakExtraBlock(player.worldObj, xPos, yPos, zPos, sideHit, player, x,y,z);
}


return super.onBlockStartBreak(stack, x, y, z, player);
Expand Down
31 changes: 27 additions & 4 deletions src/main/java/tconstruct/library/tools/HarvestTool.java
@@ -1,5 +1,7 @@
package tconstruct.library.tools;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.Minecraft;
Expand All @@ -10,10 +12,12 @@
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.play.client.C07PacketPlayerDigging;
import net.minecraft.network.play.server.S23PacketBlockChange;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeHooks;
import tconstruct.TConstruct;
import tconstruct.util.config.PHConstruct;

/* Base class for tools that should be harvesting blocks */

Expand Down Expand Up @@ -256,19 +260,38 @@ protected void breakExtraBlock(World world, int x, int y, int z, int sidehit, En
}
// server sided handling
if (!world.isRemote) {
// serverside we
EntityPlayerMP mpPlayer = (EntityPlayerMP) player;
// serverside we reproduce ItemInWorldManager.tryHarvestBlock

// ItemInWorldManager.removeBlock
block.onBlockHarvested(world, x,y,z, meta, player);

if(block.removedByPlayer(world, player, x,y,z, true)) // boolean is if block can be harvested, checked above
{
block.onBlockDestroyedByPlayer( world, x,y,z, meta);
block.harvestBlock(world, player, x,y,z, meta);
}

mpPlayer.theItemInWorldManager.tryHarvestBlock(x, y, z);
// send block update to client
// always send block update to client
EntityPlayerMP mpPlayer = (EntityPlayerMP) player;
mpPlayer.playerNetServerHandler.sendPacket(new S23PacketBlockChange(x, y, z, world));
}
// client sided handling
else {
PlayerControllerMP pcmp = Minecraft.getMinecraft().playerController;
// clientside we do a "this clock has been clicked on long enough to be broken" call. This should not send any new packets
// the code above, executed on the server, sends a block-updates that give us the correct state of the block we destroy.

// following code can be found in PlayerControllerMP.onPlayerDestroyBlock
world.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(block) + (meta << 12));
if(block.removedByPlayer(world, player, x,y,z))
{
block.onBlockDestroyedByPlayer(world, x,y,z, meta);
}
pcmp.onPlayerDestroyBlock(x, y, z, sidehit);

// send an update to the server, so we get an update back
if(PHConstruct.extraBlockUpdates)
Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C07PacketPlayerDigging(2, x,y,z, Minecraft.getMinecraft().objectMouseOver.sideHit));
}
}
}
2 changes: 2 additions & 0 deletions src/main/java/tconstruct/util/config/PHConstruct.java
Expand Up @@ -186,6 +186,7 @@ public static void initProps (File location)
newSmeltery = config.get("Experimental", "Use new adaptive Smeltery code", false, "Warning: Very buggy").getBoolean(false);
meltableHorses = config.get("Experimental", "Allow horses to be melted down for glue", true).getBoolean(true);
minimalTextures = config.get("Experimental", "Minimal Textures", false).getBoolean(false);
extraBlockUpdates = config.get("Experimental", "Send additional block updates when using AOE tools", true,"This fixes very fast tools sometimes resulting in ghost blocks, but causes a bit more network traffic. Should be fine in theory.").getBoolean(true);

/* Save the configuration file only if it has changed */
if (config.hasChanged())
Expand Down Expand Up @@ -355,5 +356,6 @@ public static void initProps (File location)
public static boolean newSmeltery;
public static boolean meltableHorses;
public static boolean minimalTextures;
public static boolean extraBlockUpdates;

}

0 comments on commit fc35996

Please sign in to comment.