Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-03 14:50:19 +01:00
Block breaking animations
Dieser Commit ist enthalten in:
Commit
4a8aeda677
@ -48,6 +48,24 @@
|
||||
<version>8.1.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.nukkitx.fastutil</groupId>
|
||||
<artifactId>fastutil-int-double-maps</artifactId>
|
||||
<version>8.3.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.nukkitx.fastutil</groupId>
|
||||
<artifactId>fastutil-int-boolean-maps</artifactId>
|
||||
<version>8.3.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.nukkitx.fastutil</groupId>
|
||||
<artifactId>fastutil-object-int-maps</artifactId>
|
||||
<version>8.3.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.nukkitx.fastutil</groupId>
|
||||
<artifactId>fastutil-object-byte-maps</artifactId>
|
||||
|
@ -39,6 +39,7 @@ import lombok.Setter;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.session.cache.EntityEffectCache;
|
||||
import org.geysermc.connector.utils.SkinUtils;
|
||||
|
||||
import java.util.UUID;
|
||||
@ -50,6 +51,7 @@ public class PlayerEntity extends LivingEntity {
|
||||
private String username;
|
||||
private long lastSkinUpdate = -1;
|
||||
private boolean playerList = true;
|
||||
private final EntityEffectCache effectCache;
|
||||
|
||||
public PlayerEntity(GameProfile gameProfile, long entityId, long geyserId, Vector3f position, Vector3f motion, Vector3f rotation) {
|
||||
super(entityId, geyserId, EntityType.PLAYER, position, motion, rotation);
|
||||
@ -57,6 +59,7 @@ public class PlayerEntity extends LivingEntity {
|
||||
profile = gameProfile;
|
||||
uuid = gameProfile.getId();
|
||||
username = gameProfile.getName();
|
||||
effectCache = new EntityEffectCache();
|
||||
if (geyserId == 1) valid = true;
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,6 @@ public class PlayerInventory extends Inventory {
|
||||
}
|
||||
|
||||
public ItemStack getItemInHand() {
|
||||
return items[heldItemSlot];
|
||||
return items[36 + heldItemSlot];
|
||||
}
|
||||
}
|
||||
|
54
connector/src/main/java/org/geysermc/connector/network/session/cache/EntityEffectCache.java
vendored
Normale Datei
54
connector/src/main/java/org/geysermc/connector/network/session/cache/EntityEffectCache.java
vendored
Normale Datei
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.connector.network.session.cache;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.Effect;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import lombok.Getter;
|
||||
|
||||
public class EntityEffectCache {
|
||||
|
||||
@Getter
|
||||
private final Object2IntMap<Effect> entityEffects = new Object2IntOpenHashMap<>();
|
||||
|
||||
public void addEffect(Effect effect, int effectAmplifier) {
|
||||
if (effect != null) {
|
||||
entityEffects.putIfAbsent(effect, effectAmplifier + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeEffect(Effect effect) {
|
||||
if (entityEffects.containsKey(effect)) {
|
||||
int effectLevel = entityEffects.getInt(effect);
|
||||
entityEffects.remove(effect, effectLevel);
|
||||
}
|
||||
}
|
||||
|
||||
public int getEffectLevel(Effect effect) {
|
||||
return entityEffects.getOrDefault(effect, 0);
|
||||
}
|
||||
}
|
@ -47,12 +47,15 @@ public class Registry<T> {
|
||||
BEDROCK.MAP.put(clazz, translator);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <P extends T> boolean translate(Class<? extends P> clazz, P packet, GeyserSession session) {
|
||||
if (!session.getUpstream().isClosed() && !session.isClosed()) {
|
||||
try {
|
||||
if (MAP.containsKey(clazz)) {
|
||||
((PacketTranslator<P>) MAP.get(clazz)).translate(packet, session);
|
||||
return true;
|
||||
} else {
|
||||
GeyserConnector.getInstance().getLogger().debug("Could not find packet for " + (packet.toString().length() > 25 ? packet.getClass().getSimpleName() : packet));
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
GeyserConnector.getInstance().getLogger().error("Could not translate packet " + packet.getClass().getSimpleName(), ex);
|
||||
|
@ -54,6 +54,13 @@ public class BlockTranslator {
|
||||
private static final Object2ByteOpenHashMap<BlockState> BED_COLORS = new Object2ByteOpenHashMap<>();
|
||||
|
||||
private static final Map<BlockState, String> JAVA_ID_TO_BLOCK_ENTITY_MAP = new HashMap<>();
|
||||
public static final Int2DoubleMap JAVA_RUNTIME_ID_TO_HARDNESS = new Int2DoubleOpenHashMap();
|
||||
public static final Int2BooleanMap JAVA_RUNTIME_ID_TO_CAN_HARVEST_WITH_HAND = new Int2BooleanOpenHashMap();
|
||||
public static final Int2ObjectMap<String> JAVA_RUNTIME_ID_TO_TOOL_TYPE = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
// For block breaking animation math
|
||||
public static final List<Integer> JAVA_RUNTIME_WOOL_IDS = new ArrayList<>();
|
||||
public static final int JAVA_RUNTIME_COBWEB_ID;
|
||||
|
||||
private static final int BLOCK_STATE_VERSION = 17760256;
|
||||
|
||||
@ -89,6 +96,7 @@ public class BlockTranslator {
|
||||
int waterRuntimeId = -1;
|
||||
int javaRuntimeId = -1;
|
||||
int bedrockRuntimeId = 0;
|
||||
int cobwebRuntimeId = -1;
|
||||
Iterator<Map.Entry<String, JsonNode>> blocksIterator = blocks.fields();
|
||||
while (blocksIterator.hasNext()) {
|
||||
javaRuntimeId++;
|
||||
@ -97,6 +105,27 @@ public class BlockTranslator {
|
||||
BlockState javaBlockState = new BlockState(javaRuntimeId);
|
||||
CompoundTag blockTag = buildBedrockState(entry.getValue());
|
||||
|
||||
// TODO fix this, (no block should have a null hardness)
|
||||
JsonNode hardnessNode = entry.getValue().get("block_hardness");
|
||||
if (hardnessNode != null) {
|
||||
JAVA_RUNTIME_ID_TO_HARDNESS.put(javaRuntimeId, hardnessNode.doubleValue());
|
||||
}
|
||||
|
||||
JAVA_RUNTIME_ID_TO_CAN_HARVEST_WITH_HAND.put(javaRuntimeId, entry.getValue().get("can_break_with_hand").booleanValue());
|
||||
|
||||
JsonNode toolTypeNode = entry.getValue().get("tool_type");
|
||||
if (toolTypeNode != null) {
|
||||
JAVA_RUNTIME_ID_TO_TOOL_TYPE.put(javaRuntimeId, toolTypeNode.textValue());
|
||||
}
|
||||
|
||||
if (javaId.contains("wool")) {
|
||||
JAVA_RUNTIME_WOOL_IDS.add(javaRuntimeId);
|
||||
}
|
||||
|
||||
if (javaId.contains("cobweb")) {
|
||||
cobwebRuntimeId = javaRuntimeId;
|
||||
}
|
||||
|
||||
JAVA_ID_BLOCK_MAP.put(javaId, javaBlockState);
|
||||
|
||||
if (javaId.contains("sign[")) {
|
||||
@ -142,6 +171,11 @@ public class BlockTranslator {
|
||||
bedrockRuntimeId++;
|
||||
}
|
||||
|
||||
if (cobwebRuntimeId == -1) {
|
||||
throw new AssertionError("Unable to find cobwebs in palette");
|
||||
}
|
||||
JAVA_RUNTIME_COBWEB_ID = cobwebRuntimeId;
|
||||
|
||||
if (waterRuntimeId == -1) {
|
||||
throw new AssertionError("Unable to find water in palette");
|
||||
}
|
||||
|
@ -34,11 +34,11 @@ public class ItemEntry {
|
||||
|
||||
public static ItemEntry AIR = new ItemEntry("minecraft:air", 0, 0, 0);
|
||||
|
||||
private String javaIdentifier;
|
||||
private int javaId;
|
||||
private final String javaIdentifier;
|
||||
private final int javaId;
|
||||
|
||||
private int bedrockId;
|
||||
private int bedrockData;
|
||||
private final int bedrockId;
|
||||
private final int bedrockData;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
@ -0,0 +1,15 @@
|
||||
package org.geysermc.connector.network.translators.item;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class ToolItemEntry extends ItemEntry {
|
||||
private final String toolType;
|
||||
private final String toolTier;
|
||||
|
||||
public ToolItemEntry(String javaIdentifier, int javaId, int bedrockId, int bedrockData, String toolType, String toolTier) {
|
||||
super(javaIdentifier, javaId, bedrockId, bedrockData);
|
||||
this.toolType = toolType;
|
||||
this.toolTier = toolTier;
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ package org.geysermc.connector.network.translators.java.entity;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityEffectPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.MobEffectPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.entity.PlayerEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.utils.EntityUtils;
|
||||
@ -39,6 +40,7 @@ public class JavaEntityEffectTranslator extends PacketTranslator<ServerEntityEff
|
||||
Entity entity = session.getEntityCache().getEntityByJavaId(packet.getEntityId());
|
||||
if (packet.getEntityId() == session.getPlayerEntity().getEntityId()) {
|
||||
entity = session.getPlayerEntity();
|
||||
((PlayerEntity) entity).getEffectCache().addEffect(packet.getEffect(), packet.getAmplifier());
|
||||
}
|
||||
if (entity == null)
|
||||
return;
|
||||
|
@ -28,6 +28,7 @@ package org.geysermc.connector.network.translators.java.entity;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityRemoveEffectPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.MobEffectPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.entity.PlayerEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.utils.EntityUtils;
|
||||
@ -39,6 +40,7 @@ public class JavaEntityRemoveEffectTranslator extends PacketTranslator<ServerEnt
|
||||
Entity entity = session.getEntityCache().getEntityByJavaId(packet.getEntityId());
|
||||
if (packet.getEntityId() == session.getPlayerEntity().getEntityId()) {
|
||||
entity = session.getPlayerEntity();
|
||||
((PlayerEntity) entity).getEffectCache().removeEffect(packet.getEffect());
|
||||
}
|
||||
if (entity == null)
|
||||
return;
|
||||
|
@ -25,19 +25,64 @@
|
||||
|
||||
package org.geysermc.connector.network.translators.java.entity.player;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerActionAckPacket;
|
||||
import com.github.steveice10.opennbt.tag.builtin.*;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
||||
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
|
||||
import org.geysermc.connector.inventory.PlayerInventory;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.TranslatorsInit;
|
||||
import org.geysermc.connector.network.translators.block.BlockTranslator;
|
||||
import org.geysermc.connector.network.translators.item.ItemEntry;
|
||||
import org.geysermc.connector.utils.BlockUtils;
|
||||
import org.geysermc.connector.utils.ChunkUtils;
|
||||
|
||||
public class JavaPlayerActionAckTranslator extends PacketTranslator<ServerPlayerActionAckPacket> {
|
||||
|
||||
@Override
|
||||
public void translate(ServerPlayerActionAckPacket packet, GeyserSession session) {
|
||||
LevelEventPacket levelEvent = new LevelEventPacket();
|
||||
switch (packet.getAction()) {
|
||||
case FINISH_DIGGING:
|
||||
ChunkUtils.updateBlock(session, packet.getNewState(), packet.getPosition());
|
||||
break;
|
||||
|
||||
case START_DIGGING:
|
||||
levelEvent.setType(LevelEventType.BLOCK_START_BREAK);
|
||||
levelEvent.setPosition(Vector3f.from(
|
||||
packet.getPosition().getX(),
|
||||
packet.getPosition().getY(),
|
||||
packet.getPosition().getZ()
|
||||
));
|
||||
double blockHardness = BlockTranslator.JAVA_RUNTIME_ID_TO_HARDNESS.get(packet.getNewState().getId());
|
||||
PlayerInventory inventory = session.getInventory();
|
||||
ItemStack item = inventory.getItemInHand();
|
||||
ItemEntry itemEntry = null;
|
||||
CompoundTag nbtData = new CompoundTag("");
|
||||
if (item != null) {
|
||||
itemEntry = TranslatorsInit.getItemTranslator().getItem(item);
|
||||
nbtData = item.getNbt();
|
||||
}
|
||||
double breakTime = Math.ceil(BlockUtils.getBreakTime(blockHardness, packet.getNewState().getId(), itemEntry, nbtData, session.getPlayerEntity()) * 20);
|
||||
levelEvent.setData((int) (65535 / breakTime));
|
||||
session.getUpstream().sendPacket(levelEvent);
|
||||
break;
|
||||
|
||||
case CANCEL_DIGGING:
|
||||
levelEvent.setType(LevelEventType.BLOCK_STOP_BREAK);
|
||||
levelEvent.setPosition(Vector3f.from(
|
||||
packet.getPosition().getX(),
|
||||
packet.getPosition().getY(),
|
||||
packet.getPosition().getZ()
|
||||
));
|
||||
levelEvent.setData(0);
|
||||
session.getUpstream().sendPacket(levelEvent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
128
connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java
Normale Datei
128
connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java
Normale Datei
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.connector.utils;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.Effect;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import org.geysermc.connector.entity.PlayerEntity;
|
||||
import org.geysermc.connector.network.translators.block.BlockTranslator;
|
||||
import org.geysermc.connector.network.translators.item.ItemEntry;
|
||||
import org.geysermc.connector.network.translators.item.ToolItemEntry;
|
||||
|
||||
public class BlockUtils {
|
||||
|
||||
private static boolean correctTool(String blockToolType, String itemToolType) {
|
||||
return (blockToolType.equals("sword") && itemToolType.equals("sword")) ||
|
||||
(blockToolType.equals("shovel") && itemToolType.equals("shovel")) ||
|
||||
(blockToolType.equals("pickaxe") && itemToolType.equals("pickaxe")) ||
|
||||
(blockToolType.equals("axe") && itemToolType.equals("axe")) ||
|
||||
(blockToolType.equals("shears") && itemToolType.equals("shears"));
|
||||
}
|
||||
|
||||
private static double toolBreakTimeBonus(String toolType, String toolTier, boolean isWoolBlock) {
|
||||
if (toolType.equals("shears")) return isWoolBlock ? 5.0 : 15.0;
|
||||
if (toolType.equals("")) return 1.0;
|
||||
switch (toolTier) {
|
||||
case "wooden":
|
||||
return 2.0;
|
||||
case "stone":
|
||||
return 4.0;
|
||||
case "iron":
|
||||
return 6.0;
|
||||
case "diamond":
|
||||
return 8.0;
|
||||
case "golden":
|
||||
return 12.0;
|
||||
default:
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
//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*/) {
|
||||
double baseTime = ((correctTool || canHarvestWithHand) ? 1.5 : 5.0) * blockHardness;
|
||||
double speed = 1.0 / baseTime;
|
||||
|
||||
if (correctTool) {
|
||||
speed *= toolBreakTimeBonus(toolType, toolTier, isWoolBlock);
|
||||
speed += toolEfficiencyLevel == 0 ? 0 : toolEfficiencyLevel * toolEfficiencyLevel + 1;
|
||||
} else if (toolType.equals("sword")) {
|
||||
speed*= (isCobweb ? 15.0 : 1.5);
|
||||
}
|
||||
speed *= 1.0 + (0.2 * hasteLevel);
|
||||
|
||||
switch (miningFatigueLevel) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
speed -= (speed * 0.7);
|
||||
break;
|
||||
case 2:
|
||||
speed -= (speed * 0.91);
|
||||
break;
|
||||
case 3:
|
||||
speed -= (speed * 0.9973);
|
||||
break;
|
||||
default:
|
||||
speed -= (speed * 0.99919);
|
||||
break;
|
||||
}
|
||||
|
||||
//if (insideOfWaterWithoutAquaAffinity) speed *= 0.2;
|
||||
//if (outOfWaterButNotOnGround) speed *= 0.2;
|
||||
// else if insideWaterAndNotOnGround speed *= 0.2;
|
||||
return 1.0 / speed;
|
||||
}
|
||||
|
||||
public static double getBreakTime(double blockHardness, int blockId, ItemEntry item, CompoundTag nbtData, PlayerEntity player) {
|
||||
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, "");
|
||||
boolean canHarvestWithHand = BlockTranslator.JAVA_RUNTIME_ID_TO_CAN_HARVEST_WITH_HAND.get(blockId);
|
||||
String toolType = "";
|
||||
String toolTier = "";
|
||||
boolean correctTool = false;
|
||||
if (item instanceof ToolItemEntry) {
|
||||
ToolItemEntry toolItem = (ToolItemEntry) item;
|
||||
toolType = toolItem.getToolType();
|
||||
toolTier = toolItem.getToolTier();
|
||||
correctTool = correctTool(blockToolType, toolType);
|
||||
}
|
||||
int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(nbtData, "minecraft:efficiency");
|
||||
int hasteLevel = player.getEffectCache().getEffectLevel(Effect.FASTER_DIG);
|
||||
int miningFatigueLevel = player.getEffectCache().getEffectLevel(Effect.SLOWER_DIG);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
}
|
47
connector/src/main/java/org/geysermc/connector/utils/ItemUtils.java
Normale Datei
47
connector/src/main/java/org/geysermc/connector/utils/ItemUtils.java
Normale Datei
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.connector.utils;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.*;
|
||||
|
||||
public class ItemUtils {
|
||||
|
||||
public static int getEnchantmentLevel(CompoundTag itemNBTData, String enchantmentId) {
|
||||
ListTag enchantments = (itemNBTData == null ? null : itemNBTData.get("Enchantments"));
|
||||
if (enchantments != null) {
|
||||
int enchantmentLevel = 0;
|
||||
for (Tag tag : enchantments) {
|
||||
CompoundTag enchantment = (CompoundTag) tag;
|
||||
StringTag enchantId = enchantment.get("id");
|
||||
if (enchantId.getValue().equals(enchantmentId)) {
|
||||
enchantmentLevel = (int) ((ShortTag) enchantment.get("lvl")).getValue();
|
||||
}
|
||||
}
|
||||
return enchantmentLevel;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -40,6 +40,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.network.translators.item.ItemEntry;
|
||||
import org.geysermc.connector.network.translators.item.ToolItemEntry;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
@ -103,8 +104,28 @@ public class Toolbox {
|
||||
Iterator<Map.Entry<String, JsonNode>> iterator = items.fields();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, JsonNode> entry = iterator.next();
|
||||
ITEM_ENTRIES.put(itemIndex, new ItemEntry(entry.getKey(), itemIndex,
|
||||
entry.getValue().get("bedrock_id").intValue(), entry.getValue().get("bedrock_data").intValue()));
|
||||
if (entry.getValue().has("tool_type")) {
|
||||
if (entry.getValue().has("tool_tier")) {
|
||||
ITEM_ENTRIES.put(itemIndex, new ToolItemEntry(
|
||||
entry.getKey(), itemIndex,
|
||||
entry.getValue().get("bedrock_id").intValue(),
|
||||
entry.getValue().get("bedrock_data").intValue(),
|
||||
entry.getValue().get("tool_type").textValue(),
|
||||
entry.getValue().get("tool_tier").textValue()));
|
||||
} else {
|
||||
ITEM_ENTRIES.put(itemIndex, new ToolItemEntry(
|
||||
entry.getKey(), itemIndex,
|
||||
entry.getValue().get("bedrock_id").intValue(),
|
||||
entry.getValue().get("bedrock_data").intValue(),
|
||||
entry.getValue().get("tool_type").textValue(),
|
||||
""));
|
||||
}
|
||||
} else {
|
||||
ITEM_ENTRIES.put(itemIndex, new ItemEntry(
|
||||
entry.getKey(), itemIndex,
|
||||
entry.getValue().get("bedrock_id").intValue(),
|
||||
entry.getValue().get("bedrock_data").intValue()));
|
||||
}
|
||||
itemIndex++;
|
||||
}
|
||||
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren