forked from GeyserMC/Geyser
Fix block breaking animations when in water (Closes #494)
This commit is contained in:
parent
99f69b3a7d
commit
0574feb87e
5 changed files with 56 additions and 17 deletions
|
@ -57,6 +57,7 @@ public class PlayerEntity extends LivingEntity {
|
|||
private String username;
|
||||
private long lastSkinUpdate = -1;
|
||||
private boolean playerList = true;
|
||||
private boolean onGround;
|
||||
private final EntityEffectCache effectCache;
|
||||
|
||||
private Entity leftParrot;
|
||||
|
@ -143,6 +144,8 @@ public class PlayerEntity extends LivingEntity {
|
|||
setPosition(position);
|
||||
setRotation(rotation);
|
||||
|
||||
this.onGround = isOnGround;
|
||||
|
||||
MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
|
||||
movePlayerPacket.setRuntimeEntityId(geyserId);
|
||||
movePlayerPacket.setPosition(this.position);
|
||||
|
@ -168,6 +171,8 @@ public class PlayerEntity extends LivingEntity {
|
|||
setRotation(rotation);
|
||||
this.position = Vector3f.from(position.getX() + relX, position.getY() + relY, position.getZ() + relZ);
|
||||
|
||||
this.onGround = isOnGround;
|
||||
|
||||
MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
|
||||
movePlayerPacket.setRuntimeEntityId(geyserId);
|
||||
movePlayerPacket.setPosition(position);
|
||||
|
|
|
@ -85,6 +85,7 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
|
|||
Vector3f rotation = Vector3f.from(packet.getRotation().getY(), packet.getRotation().getX(), packet.getRotation().getY());
|
||||
entity.setPosition(packet.getPosition().sub(0, EntityType.PLAYER.getOffset(), 0));
|
||||
entity.setRotation(rotation);
|
||||
entity.setOnGround(packet.isOnGround());
|
||||
|
||||
/*
|
||||
boolean colliding = false;
|
||||
|
|
|
@ -79,7 +79,7 @@ public class JavaPlayerActionAckTranslator extends PacketTranslator<ServerPlayer
|
|||
itemEntry = Translators.getItemTranslator().getItem(item);
|
||||
nbtData = item.getNbt();
|
||||
}
|
||||
double breakTime = Math.ceil(BlockUtils.getBreakTime(blockHardness, packet.getNewState().getId(), itemEntry, nbtData, session.getPlayerEntity()) * 20);
|
||||
double breakTime = Math.ceil(BlockUtils.getBreakTime(blockHardness, packet.getNewState().getId(), itemEntry, nbtData, session) * 20);
|
||||
levelEvent.setData((int) (65535 / breakTime));
|
||||
session.setBreakingBlock(packet.getNewState());
|
||||
session.sendUpstreamPacket(levelEvent);
|
||||
|
|
|
@ -26,8 +26,10 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.world;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
|
||||
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
||||
/**
|
||||
|
@ -39,6 +41,28 @@ import org.geysermc.connector.network.session.GeyserSession;
|
|||
*/
|
||||
public abstract class WorldManager {
|
||||
|
||||
/**
|
||||
* Gets the {@link BlockState} at the specified location
|
||||
*
|
||||
* @param session the session
|
||||
* @param position the position
|
||||
* @return the block state at the specified location
|
||||
*/
|
||||
public BlockState getBlockAt(GeyserSession session, Position position) {
|
||||
return this.getBlockAt(session, position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link BlockState} at the specified location
|
||||
*
|
||||
* @param session the session
|
||||
* @param vector the position
|
||||
* @return the block state at the specified location
|
||||
*/
|
||||
public BlockState getBlockAt(GeyserSession session, Vector3i vector) {
|
||||
return this.getBlockAt(session, vector.getX(), vector.getY(), vector.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link BlockState} at the specified location
|
||||
*
|
||||
|
|
|
@ -26,12 +26,15 @@
|
|||
package org.geysermc.connector.utils;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.Effect;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import org.geysermc.connector.entity.PlayerEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||
import org.geysermc.connector.network.translators.item.ItemEntry;
|
||||
import org.geysermc.connector.network.translators.item.ToolItemEntry;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class BlockUtils {
|
||||
|
||||
private static boolean correctTool(String blockToolType, String itemToolType) {
|
||||
|
@ -63,8 +66,8 @@ public class BlockUtils {
|
|||
|
||||
//http://minecraft.gamepedia.com/Breaking
|
||||
private static double calculateBreakTime(double blockHardness, String toolTier, boolean canHarvestWithHand, boolean correctTool,
|
||||
String toolType, boolean isWoolBlock, boolean isCobweb, int toolEfficiencyLevel, int hasteLevel, int miningFatigueLevel
|
||||
/*boolean insideOfWaterWithoutAquaAffinity, boolean outOfWaterButNotOnGround*/) {
|
||||
String toolType, boolean isWoolBlock, boolean isCobweb, int toolEfficiencyLevel, int hasteLevel, int miningFatigueLevel,
|
||||
boolean insideOfWaterWithoutAquaAffinity, boolean outOfWaterButNotOnGround, boolean insideWaterAndNotOnGround) {
|
||||
double baseTime = ((correctTool || canHarvestWithHand) ? 1.5 : 5.0) * blockHardness;
|
||||
double speed = 1.0 / baseTime;
|
||||
|
||||
|
@ -93,13 +96,13 @@ public class BlockUtils {
|
|||
break;
|
||||
}
|
||||
|
||||
//if (insideOfWaterWithoutAquaAffinity) speed *= 0.2;
|
||||
//if (outOfWaterButNotOnGround) speed *= 0.2;
|
||||
// else if insideWaterAndNotOnGround speed *= 0.2;
|
||||
if (insideOfWaterWithoutAquaAffinity) speed *= 0.2;
|
||||
if (outOfWaterButNotOnGround) speed *= 0.2;
|
||||
if (insideWaterAndNotOnGround) speed *= 0.2;
|
||||
return 1.0 / speed;
|
||||
}
|
||||
|
||||
public static double getBreakTime(double blockHardness, int blockId, ItemEntry item, CompoundTag nbtData, PlayerEntity player) {
|
||||
public static double getBreakTime(double blockHardness, int blockId, ItemEntry item, CompoundTag nbtData, GeyserSession session) {
|
||||
boolean isWoolBlock = BlockTranslator.JAVA_RUNTIME_WOOL_IDS.contains(blockId);
|
||||
boolean isCobweb = blockId == BlockTranslator.JAVA_RUNTIME_COBWEB_ID;
|
||||
String blockToolType = BlockTranslator.JAVA_RUNTIME_ID_TO_TOOL_TYPE.getOrDefault(blockId, "");
|
||||
|
@ -117,16 +120,22 @@ public class BlockUtils {
|
|||
int hasteLevel = 0;
|
||||
int miningFatigueLevel = 0;
|
||||
|
||||
if (player != null) {
|
||||
hasteLevel = player.getEffectCache().getEffectLevel(Effect.FASTER_DIG);
|
||||
miningFatigueLevel = player.getEffectCache().getEffectLevel(Effect.SLOWER_DIG);
|
||||
if (session == null) {
|
||||
return calculateBreakTime(blockHardness, toolTier, canHarvestWithHand, correctTool, toolType, isWoolBlock, isCobweb, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, false, false, false);
|
||||
}
|
||||
// TODO implement these checks and material check if possible
|
||||
//boolean insideOfWaterWithoutAquaAffinity = player.isInsideOfWater() &&
|
||||
// Optional.ofNullable(player.getInventory().getHelmet().getEnchantment(Enchantment.ID_WATER_WORKER))
|
||||
// .map(Enchantment::getLevel).map(l -> l >= 1).orElse(false);
|
||||
//boolean outOfWaterButNotOnGround = (!player.isInsideOfWater()) && (!player.isOnGround());
|
||||
return calculateBreakTime(blockHardness, toolTier, canHarvestWithHand, correctTool, toolType, isWoolBlock, isCobweb, toolEfficiencyLevel, hasteLevel, miningFatigueLevel);
|
||||
|
||||
hasteLevel = session.getPlayerEntity().getEffectCache().getEffectLevel(Effect.FASTER_DIG);
|
||||
miningFatigueLevel = session.getPlayerEntity().getEffectCache().getEffectLevel(Effect.SLOWER_DIG);
|
||||
|
||||
boolean isInWater = session.getConnector().getConfig().isCacheChunks()
|
||||
&& BlockTranslator.getBedrockBlockId(session.getConnector().getWorldManager().getBlockAt(session, session.getPlayerEntity().getPosition().toInt())) == BlockTranslator.BEDROCK_WATER_ID;
|
||||
|
||||
boolean insideOfWaterWithoutAquaAffinity = isInWater &&
|
||||
ItemUtils.getEnchantmentLevel(Optional.ofNullable(session.getInventory().getItem(5)).map(ItemStack::getNbt).orElse(null), "minecraft:aqua_affinity") < 1;
|
||||
|
||||
boolean outOfWaterButNotOnGround = (!isInWater) && (!session.getPlayerEntity().isOnGround());
|
||||
boolean insideWaterNotOnGround = isInWater && !session.getPlayerEntity().isOnGround();
|
||||
return calculateBreakTime(blockHardness, toolTier, canHarvestWithHand, correctTool, toolType, isWoolBlock, isCobweb, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity, outOfWaterButNotOnGround, insideWaterNotOnGround);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue