Implement shield blocking (#395)

* basic shield blocking

* Offhand works

* Add Shield as id in BlockTranslator

* Change Block Translator to Item Translator

* Fix formatting

Co-authored-by: DoctorMacc <toy.fighter1@gmail.com>
Co-authored-by: Redned <redned235@gmail.com>
This commit is contained in:
OnlyBMan 2020-04-24 23:11:28 -04:00 committed by GitHub
parent 298558078c
commit e82adf2cf9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 5 deletions

View file

@ -27,12 +27,15 @@ package org.geysermc.connector.entity;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
import com.github.steveice10.mc.protocol.data.message.TextMessage; import com.github.steveice10.mc.protocol.data.message.TextMessage;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerUseItemPacket;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.EntityData; import com.nukkitx.protocol.bedrock.data.*;
import com.nukkitx.protocol.bedrock.data.EntityDataMap;
import com.nukkitx.protocol.bedrock.data.EntityFlag;
import com.nukkitx.protocol.bedrock.data.EntityFlags;
import com.nukkitx.protocol.bedrock.packet.*; import com.nukkitx.protocol.bedrock.packet.*;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
@ -45,6 +48,7 @@ import org.geysermc.connector.entity.attribute.Attribute;
import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.attribute.AttributeType;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.utils.AttributeUtils; import org.geysermc.connector.utils.AttributeUtils;
import org.geysermc.connector.utils.MessageUtils; import org.geysermc.connector.utils.MessageUtils;
@ -199,6 +203,28 @@ public class Entity {
metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08); metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08);
metadata.getFlags().setFlag(EntityFlag.SWIMMING, (xd & 0x10) == 0x10); metadata.getFlags().setFlag(EntityFlag.SWIMMING, (xd & 0x10) == 0x10);
metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80); metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80);
// Shield code
if (session.getPlayerEntity().getEntityId() == entityId && metadata.getFlags().getFlag(EntityFlag.SNEAKING)) {
if ((session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() == ItemTranslator.SHIELD) ||
(session.getInventoryCache().getPlayerInventory().getItem(45) != null && session.getInventoryCache().getPlayerInventory().getItem(45).getId() == ItemTranslator.SHIELD)) {
ClientPlayerUseItemPacket useItemPacket;
metadata.getFlags().setFlag(EntityFlag.BLOCKING, true);
if (session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() == ItemTranslator.SHIELD) {
useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
}
// Else we just assume it's the offhand, to simplify logic and to assure the packet gets sent
else {
useItemPacket = new ClientPlayerUseItemPacket(Hand.OFF_HAND);
}
session.getDownstream().getSession().send(useItemPacket);
}
} else if (session.getPlayerEntity().getEntityId() == entityId && !metadata.getFlags().getFlag(EntityFlag.SNEAKING) && metadata.getFlags().getFlag(EntityFlag.BLOCKING)) {
metadata.getFlags().setFlag(EntityFlag.BLOCKING, false);
metadata.getFlags().setFlag(EntityFlag.DISABLE_BLOCKING, true);
ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, new Position(0,0,0), BlockFace.DOWN);
session.getDownstream().getSession().send(releaseItemPacket);
}
// metadata.getFlags().setFlag(EntityFlag.INVISIBLE, (xd & 0x20) == 0x20); // metadata.getFlags().setFlag(EntityFlag.INVISIBLE, (xd & 0x20) == 0x20);
if ((xd & 0x20) == 0x20) if ((xd & 0x20) == 0x20)
metadata.put(EntityData.SCALE, 0.0f); metadata.put(EntityData.SCALE, 0.0f);
@ -221,6 +247,12 @@ public class Entity {
case 5: // no gravity case 5: // no gravity
metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, !(boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, !(boolean) entityMetadata.getValue());
break; break;
case 7: // blocking
if (entityMetadata.getType() == MetadataType.BYTE) {
byte xd = (byte) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.BLOCKING, (xd & 0x01) == 0x01);
}
break;
} }
updateBedrockMetadata(session); updateBedrockMetadata(session);

View file

@ -34,6 +34,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction; import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket;
import com.nukkitx.protocol.bedrock.packet.InteractPacket; import com.nukkitx.protocol.bedrock.packet.InteractPacket;
import org.geysermc.connector.network.translators.item.ItemTranslator;
@Translator(packet = InteractPacket.class) @Translator(packet = InteractPacket.class)
public class BedrockInteractTranslator extends PacketTranslator<InteractPacket> { public class BedrockInteractTranslator extends PacketTranslator<InteractPacket> {
@ -46,6 +47,9 @@ public class BedrockInteractTranslator extends PacketTranslator<InteractPacket>
switch (packet.getAction()) { switch (packet.getAction()) {
case INTERACT: case INTERACT:
if (session.getInventory().getItem(session.getInventory().getHeldItemSlot() + 36).getId() == ItemTranslator.SHIELD) {
break;
}
ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(),
InteractAction.INTERACT, Hand.MAIN_HAND); InteractAction.INTERACT, Hand.MAIN_HAND);
session.getDownstream().getSession().send(interactPacket); session.getDownstream().getSession().send(interactPacket);

View file

@ -32,6 +32,7 @@ import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.utils.InventoryUtils; import org.geysermc.connector.utils.InventoryUtils;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
@ -75,6 +76,9 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
session.getDownstream().getSession().send(blockPacket); session.getDownstream().getSession().send(blockPacket);
break; break;
case 1: case 1:
if (session.getInventory().getItem(session.getInventory().getHeldItemSlot() + 36).getId() == ItemTranslator.SHIELD) {
break;
} // Handled in Entity.java
ClientPlayerUseItemPacket useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND); ClientPlayerUseItemPacket useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
session.getDownstream().getSession().send(useItemPacket); session.getDownstream().getSession().send(useItemPacket);
break; break;

View file

@ -45,6 +45,9 @@ public class ItemTranslator {
private Int2ObjectMap<ItemStackTranslator> itemTranslators = new Int2ObjectOpenHashMap(); private Int2ObjectMap<ItemStackTranslator> itemTranslators = new Int2ObjectOpenHashMap();
private List<NbtItemStackTranslator> nbtItemTranslators; private List<NbtItemStackTranslator> nbtItemTranslators;
private Map<String, ItemEntry> javaIdentifierMap = new HashMap<>(); private Map<String, ItemEntry> javaIdentifierMap = new HashMap<>();
// Shield ID, used in Entity.java
public static final int SHIELD = 829;
public void init() { public void init() {
Reflections ref = new Reflections("org.geysermc.connector.network.translators.item"); Reflections ref = new Reflections("org.geysermc.connector.network.translators.item");

@ -1 +1 @@
Subproject commit a6a790d944eb153c93d0c414813d8a0880fd5d26 Subproject commit efc9db6b7d51bdf145230933ac23b321ac1c132d