mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-19 06:32:03 +01:00
Fix position issue when cancelling the breaking of a block just below the player
This commit is contained in:
parent
e6764ce6f7
commit
ce81c3a85d
@ -212,8 +212,12 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
|||||||
Check.stateCondition(instance == null, "You need to use Entity#setInstance before teleporting an entity!");
|
Check.stateCondition(instance == null, "You need to use Entity#setInstance before teleporting an entity!");
|
||||||
|
|
||||||
final Runnable runnable = () -> {
|
final Runnable runnable = () -> {
|
||||||
refreshPosition(position.getX(), position.getY(), position.getZ());
|
if (!this.position.isSimilar(position)) {
|
||||||
refreshView(position.getYaw(), position.getPitch());
|
refreshPosition(position.getX(), position.getY(), position.getZ());
|
||||||
|
}
|
||||||
|
if (!this.position.hasSimilarView(position)) {
|
||||||
|
refreshView(position.getYaw(), position.getPitch());
|
||||||
|
}
|
||||||
sendSynchronization();
|
sendSynchronization();
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
callback.run();
|
callback.run();
|
||||||
|
@ -310,8 +310,8 @@ public class InstanceContainer extends Instance {
|
|||||||
|
|
||||||
PlayerBlockBreakEvent blockBreakEvent = new PlayerBlockBreakEvent(player, blockPosition, blockStateId, customBlock, (short) 0, (short) 0);
|
PlayerBlockBreakEvent blockBreakEvent = new PlayerBlockBreakEvent(player, blockPosition, blockStateId, customBlock, (short) 0, (short) 0);
|
||||||
player.callEvent(PlayerBlockBreakEvent.class, blockBreakEvent);
|
player.callEvent(PlayerBlockBreakEvent.class, blockBreakEvent);
|
||||||
final boolean result = !blockBreakEvent.isCancelled();
|
final boolean allowed = !blockBreakEvent.isCancelled();
|
||||||
if (result) {
|
if (allowed) {
|
||||||
// Break or change the broken block based on event result
|
// Break or change the broken block based on event result
|
||||||
setSeparateBlocks(x, y, z, blockBreakEvent.getResultBlockStateId(), blockBreakEvent.getResultCustomBlockId());
|
setSeparateBlocks(x, y, z, blockBreakEvent.getResultBlockStateId(), blockBreakEvent.getResultCustomBlockId());
|
||||||
|
|
||||||
@ -330,11 +330,19 @@ public class InstanceContainer extends Instance {
|
|||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Cancelled so we need to refresh player chunk section
|
|
||||||
final int section = ChunkUtils.getSectionAt(blockPosition.getY());
|
final boolean solid = Block.fromStateId(blockStateId).isSolid();
|
||||||
chunk.sendChunkSectionUpdate(section, player);
|
if (solid) {
|
||||||
|
final BlockPosition playerBlockPosition = player.getPosition().toBlockPosition();
|
||||||
|
|
||||||
|
// Teleport the player back if he broke a solid block just below him
|
||||||
|
if (playerBlockPosition.subtract(0, 1, 0).equals(blockPosition)) {
|
||||||
|
player.teleport(player.getPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
|
return allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -40,7 +40,7 @@ public class PlayerDiggingListener {
|
|||||||
Block.fromStateId(blockStateId).breaksInstantaneously();
|
Block.fromStateId(blockStateId).breaksInstantaneously();
|
||||||
|
|
||||||
if (instantBreak) {
|
if (instantBreak) {
|
||||||
breakBlock(instance, player, blockPosition);
|
breakBlock(instance, player, blockPosition, blockStateId);
|
||||||
} else {
|
} else {
|
||||||
final CustomBlock customBlock = instance.getCustomBlock(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ());
|
final CustomBlock customBlock = instance.getCustomBlock(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ());
|
||||||
if (customBlock != null) {
|
if (customBlock != null) {
|
||||||
@ -76,7 +76,7 @@ public class PlayerDiggingListener {
|
|||||||
ClientPlayerDiggingPacket.Status.CANCELLED_DIGGING, true);
|
ClientPlayerDiggingPacket.Status.CANCELLED_DIGGING, true);
|
||||||
break;
|
break;
|
||||||
case FINISHED_DIGGING:
|
case FINISHED_DIGGING:
|
||||||
breakBlock(instance, player, blockPosition);
|
breakBlock(instance, player, blockPosition, blockStateId);
|
||||||
break;
|
break;
|
||||||
case DROP_ITEM_STACK:
|
case DROP_ITEM_STACK:
|
||||||
final ItemStack droppedItemStack = player.getInventory().getItemInMainHand().clone();
|
final ItemStack droppedItemStack = player.getInventory().getItemInMainHand().clone();
|
||||||
@ -117,16 +117,21 @@ public class PlayerDiggingListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void breakBlock(Instance instance, Player player, BlockPosition blockPosition) {
|
private static void breakBlock(Instance instance, Player player, BlockPosition blockPosition, int blockStateId) {
|
||||||
// Finished digging, remove effect if any
|
// Finished digging, remove effect if any
|
||||||
player.resetTargetBlock();
|
player.resetTargetBlock();
|
||||||
|
|
||||||
// Unverified block break, client is fully responsive
|
// Unverified block break, client is fully responsive
|
||||||
instance.breakBlock(player, blockPosition);
|
final boolean result = instance.breakBlock(player, blockPosition);
|
||||||
|
|
||||||
// Send acknowledge packet to confirm the digging process
|
final int updatedBlockId = result ? 0 : blockStateId;
|
||||||
sendAcknowledgePacket(player, blockPosition, 0,
|
final ClientPlayerDiggingPacket.Status status = result ?
|
||||||
ClientPlayerDiggingPacket.Status.FINISHED_DIGGING, true);
|
ClientPlayerDiggingPacket.Status.FINISHED_DIGGING :
|
||||||
|
ClientPlayerDiggingPacket.Status.CANCELLED_DIGGING;
|
||||||
|
|
||||||
|
// Send acknowledge packet to allow or cancel the digging process
|
||||||
|
sendAcknowledgePacket(player, blockPosition, updatedBlockId,
|
||||||
|
status, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void dropItem(Player player, ItemStack droppedItem, ItemStack handItem) {
|
private static void dropItem(Player player, ItemStack droppedItem, ItemStack handItem) {
|
||||||
|
@ -196,7 +196,20 @@ public class Position {
|
|||||||
* @return true if the two positions are similar
|
* @return true if the two positions are similar
|
||||||
*/
|
*/
|
||||||
public boolean isSimilar(Position position) {
|
public boolean isSimilar(Position position) {
|
||||||
return position.x == x && position.y == y && position.z == z;
|
return Float.compare(position.x, x) == 0 &&
|
||||||
|
Float.compare(position.y, y) == 0 &&
|
||||||
|
Float.compare(position.z, z) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if two positions have a similar view (yaw/pitch)
|
||||||
|
*
|
||||||
|
* @param position the position to compare
|
||||||
|
* @return true if the two positions have the same view
|
||||||
|
*/
|
||||||
|
public boolean hasSimilarView(Position position) {
|
||||||
|
return Float.compare(position.yaw, yaw) == 0 &&
|
||||||
|
Float.compare(position.pitch, pitch) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user