mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-12-19 14:59:27 +00:00
Only store GeyserItemStacks for equipment in LivingEntity
This commit is contained in:
@@ -35,7 +35,6 @@ import org.cloudburstmc.protocol.bedrock.data.AttributeData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MobArmorEquipmentPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MobEquipmentPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
|
||||
@@ -46,9 +45,10 @@ import org.geysermc.geyser.entity.vehicle.ClientVehicle;
|
||||
import org.geysermc.geyser.entity.vehicle.HappyGhastVehicleComponent;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.scoreboard.Team;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.translator.item.ItemTranslator;
|
||||
import org.geysermc.geyser.util.AttributeUtils;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
@@ -82,15 +82,6 @@ import java.util.UUID;
|
||||
public class LivingEntity extends Entity {
|
||||
protected EnumMap<EquipmentSlot, GeyserItemStack> equipment = new EnumMap<>(EquipmentSlot.class);
|
||||
|
||||
protected ItemData helmet = ItemData.AIR;
|
||||
protected ItemData chestplate = ItemData.AIR;
|
||||
protected ItemData leggings = ItemData.AIR;
|
||||
protected ItemData boots = ItemData.AIR;
|
||||
protected ItemData body = ItemData.AIR;
|
||||
protected ItemData saddle = ItemData.AIR;
|
||||
protected ItemData hand = ItemData.AIR;
|
||||
protected ItemData offhand = ItemData.AIR;
|
||||
|
||||
@Getter(value = AccessLevel.NONE)
|
||||
protected float health = 1f; // The default value in Java Edition before any entity metadata is sent
|
||||
@Getter(value = AccessLevel.NONE)
|
||||
@@ -116,40 +107,50 @@ public class LivingEntity extends Entity {
|
||||
|
||||
public LivingEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
||||
for (EquipmentSlot slot : EquipmentSlot.values()) {
|
||||
equipment.put(slot, GeyserItemStack.EMPTY);
|
||||
public GeyserItemStack getItemInSlot(EquipmentSlot slot) {
|
||||
GeyserItemStack stack = equipment.get(slot);
|
||||
if (stack == null) {
|
||||
return GeyserItemStack.EMPTY;
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
public GeyserItemStack getMainHandItem() {
|
||||
return getItemInSlot(EquipmentSlot.MAIN_HAND);
|
||||
}
|
||||
|
||||
public GeyserItemStack getOffHandItem() {
|
||||
return getItemInSlot(EquipmentSlot.OFF_HAND);
|
||||
}
|
||||
|
||||
public boolean isHolding(Item item) {
|
||||
return getMainHandItem().is(item) || getOffHandItem().is(item);
|
||||
}
|
||||
|
||||
public void setHelmet(GeyserItemStack stack) {
|
||||
this.equipment.put(EquipmentSlot.HELMET, stack);
|
||||
this.helmet = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setChestplate(GeyserItemStack stack) {
|
||||
this.equipment.put(EquipmentSlot.CHESTPLATE, stack);
|
||||
this.chestplate = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setLeggings(GeyserItemStack stack) {
|
||||
this.equipment.put(EquipmentSlot.LEGGINGS, stack);
|
||||
this.leggings = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setBoots(GeyserItemStack stack) {
|
||||
this.equipment.put(EquipmentSlot.BOOTS, stack);
|
||||
this.boots = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setBody(GeyserItemStack stack) {
|
||||
this.equipment.put(EquipmentSlot.BODY, stack);
|
||||
this.body = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setSaddle(GeyserItemStack stack) {
|
||||
this.equipment.put(EquipmentSlot.SADDLE, stack);
|
||||
this.saddle = ItemTranslator.translateToBedrock(session, stack);
|
||||
|
||||
boolean saddled = false;
|
||||
if (!stack.isEmpty()) {
|
||||
@@ -162,12 +163,10 @@ public class LivingEntity extends Entity {
|
||||
|
||||
public void setHand(GeyserItemStack stack) {
|
||||
this.equipment.put(EquipmentSlot.MAIN_HAND, stack);
|
||||
this.hand = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setOffhand(GeyserItemStack stack) {
|
||||
this.equipment.put(EquipmentSlot.OFF_HAND, stack);
|
||||
this.offhand = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
protected void updateSaddled(boolean saddled) {
|
||||
@@ -182,13 +181,9 @@ public class LivingEntity extends Entity {
|
||||
}
|
||||
|
||||
public void switchHands() {
|
||||
GeyserItemStack javaOffhand = this.equipment.get(EquipmentSlot.OFF_HAND);
|
||||
GeyserItemStack offhand = this.equipment.get(EquipmentSlot.OFF_HAND);
|
||||
this.equipment.put(EquipmentSlot.OFF_HAND, this.equipment.get(EquipmentSlot.MAIN_HAND));
|
||||
this.equipment.put(EquipmentSlot.MAIN_HAND, javaOffhand);
|
||||
|
||||
ItemData bedrockOffhand = this.offhand;
|
||||
this.offhand = this.hand;
|
||||
this.hand = bedrockOffhand;
|
||||
this.equipment.put(EquipmentSlot.MAIN_HAND, offhand);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -283,11 +278,10 @@ public class LivingEntity extends Entity {
|
||||
}
|
||||
|
||||
protected boolean hasShield(boolean offhand) {
|
||||
ItemMapping shieldMapping = session.getItemMappings().getStoredItems().shield();
|
||||
if (offhand) {
|
||||
return this.offhand.getDefinition().equals(shieldMapping.getBedrockDefinition());
|
||||
return getOffHandItem().is(Items.SHIELD);
|
||||
} else {
|
||||
return hand.getDefinition().equals(shieldMapping.getBedrockDefinition());
|
||||
return getMainHandItem().is(Items.SHIELD);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,39 +392,38 @@ public class LivingEntity extends Entity {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
public void updateArmor(GeyserSession session) {
|
||||
public void updateArmor() {
|
||||
if (!valid) return;
|
||||
|
||||
ItemData helmet = this.helmet;
|
||||
ItemData chestplate = this.chestplate;
|
||||
GeyserItemStack helmet = getItemInSlot(EquipmentSlot.HELMET);
|
||||
GeyserItemStack chestplate = getItemInSlot(EquipmentSlot.CHESTPLATE);
|
||||
// If an entity has a banner on them, it will be in the helmet slot in Java but the chestplate spot in Bedrock
|
||||
// But don't overwrite the chestplate if it isn't empty
|
||||
ItemMapping banner = session.getItemMappings().getStoredItems().banner();
|
||||
if (ItemData.AIR.equals(chestplate) && helmet.getDefinition().equals(banner.getBedrockDefinition())) {
|
||||
chestplate = this.helmet;
|
||||
helmet = ItemData.AIR;
|
||||
} else if (chestplate.getDefinition().equals(banner.getBedrockDefinition())) {
|
||||
if (chestplate.isEmpty() && helmet.is(session, ItemTag.BANNERS)) {
|
||||
chestplate = helmet;
|
||||
helmet = GeyserItemStack.EMPTY;
|
||||
} else if (chestplate.is(session, ItemTag.BANNERS)) {
|
||||
// Prevent chestplate banners from showing erroneously
|
||||
chestplate = ItemData.AIR;
|
||||
chestplate = GeyserItemStack.EMPTY;
|
||||
}
|
||||
|
||||
MobArmorEquipmentPacket armorEquipmentPacket = new MobArmorEquipmentPacket();
|
||||
armorEquipmentPacket.setRuntimeEntityId(geyserId);
|
||||
armorEquipmentPacket.setHelmet(helmet);
|
||||
armorEquipmentPacket.setChestplate(chestplate);
|
||||
armorEquipmentPacket.setLeggings(leggings);
|
||||
armorEquipmentPacket.setBoots(boots);
|
||||
armorEquipmentPacket.setBody(body);
|
||||
armorEquipmentPacket.setHelmet(ItemTranslator.translateToBedrock(session, helmet));
|
||||
armorEquipmentPacket.setChestplate(ItemTranslator.translateToBedrock(session, chestplate));
|
||||
armorEquipmentPacket.setLeggings(ItemTranslator.translateToBedrock(session, getItemInSlot(EquipmentSlot.LEGGINGS)));
|
||||
armorEquipmentPacket.setBoots(ItemTranslator.translateToBedrock(session, getItemInSlot(EquipmentSlot.BOOTS)));
|
||||
armorEquipmentPacket.setBody(ItemTranslator.translateToBedrock(session, getItemInSlot(EquipmentSlot.BODY)));
|
||||
|
||||
session.sendUpstreamPacket(armorEquipmentPacket);
|
||||
}
|
||||
|
||||
public void updateMainHand(GeyserSession session) {
|
||||
public void updateMainHand() {
|
||||
if (!valid) return;
|
||||
|
||||
MobEquipmentPacket handPacket = new MobEquipmentPacket();
|
||||
handPacket.setRuntimeEntityId(geyserId);
|
||||
handPacket.setItem(hand);
|
||||
handPacket.setItem(ItemTranslator.translateToBedrock(session, getMainHandItem()));
|
||||
handPacket.setHotbarSlot(-1);
|
||||
handPacket.setInventorySlot(0);
|
||||
handPacket.setContainerId(ContainerId.INVENTORY);
|
||||
@@ -438,12 +431,12 @@ public class LivingEntity extends Entity {
|
||||
session.sendUpstreamPacket(handPacket);
|
||||
}
|
||||
|
||||
public void updateOffHand(GeyserSession session) {
|
||||
public void updateOffHand() {
|
||||
if (!valid) return;
|
||||
|
||||
MobEquipmentPacket offHandPacket = new MobEquipmentPacket();
|
||||
offHandPacket.setRuntimeEntityId(geyserId);
|
||||
offHandPacket.setItem(offhand);
|
||||
offHandPacket.setItem(ItemTranslator.translateToBedrock(session, getOffHandItem()));
|
||||
offHandPacket.setHotbarSlot(-1);
|
||||
offHandPacket.setInventorySlot(0);
|
||||
offHandPacket.setContainerId(ContainerId.OFFHAND);
|
||||
|
||||
@@ -60,9 +60,9 @@ public class AllayEntity extends MobEntity {
|
||||
if (this.canDuplicate && getFlag(EntityFlag.DANCING) && isDuplicationItem(itemInHand)) {
|
||||
// Maybe better as another tag?
|
||||
return InteractiveTag.GIVE_ITEM_TO_ALLAY;
|
||||
} else if (!this.hand.isValid() && !itemInHand.isEmpty()) {
|
||||
} else if (getMainHandItem().isEmpty() && !itemInHand.isEmpty()) {
|
||||
return InteractiveTag.GIVE_ITEM_TO_ALLAY;
|
||||
} else if (this.hand.isValid() && hand == Hand.MAIN_HAND && itemInHand.isEmpty()) {
|
||||
} else if (!getMainHandItem().isEmpty() && hand == Hand.MAIN_HAND && itemInHand.isEmpty()) {
|
||||
// Seems like there isn't a good tag for this yet
|
||||
return InteractiveTag.GIVE_ITEM_TO_ALLAY;
|
||||
} else {
|
||||
@@ -76,10 +76,10 @@ public class AllayEntity extends MobEntity {
|
||||
if (this.canDuplicate && getFlag(EntityFlag.DANCING) && isDuplicationItem(itemInHand)) {
|
||||
//TOCHECK sound
|
||||
return InteractionResult.SUCCESS;
|
||||
} else if (!this.hand.isValid() && !itemInHand.isEmpty()) {
|
||||
} else if (getMainHandItem().isEmpty() && !itemInHand.isEmpty()) {
|
||||
//TODO play sound?
|
||||
return InteractionResult.SUCCESS;
|
||||
} else if (this.hand.isValid() && hand == Hand.MAIN_HAND && itemInHand.isEmpty()) {
|
||||
} else if (!getMainHandItem().isEmpty() && hand == Hand.MAIN_HAND && itemInHand.isEmpty()) {
|
||||
//TOCHECK also play sound here?
|
||||
return InteractionResult.SUCCESS;
|
||||
} else {
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.type.LivingEntity;
|
||||
@@ -42,6 +41,7 @@ import org.geysermc.geyser.scoreboard.Team;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
@@ -332,8 +332,7 @@ public class ArmorStandEntity extends LivingEntity {
|
||||
return;
|
||||
}
|
||||
boolean isNametagEmpty = nametag.isEmpty();
|
||||
if (!isNametagEmpty && (!helmet.equals(ItemData.AIR) || !chestplate.equals(ItemData.AIR) || !leggings.equals(ItemData.AIR)
|
||||
|| !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offhand.equals(ItemData.AIR))) {
|
||||
if (!isNametagEmpty && hasAnyEquipment()) {
|
||||
// Reset scale of the proper armor stand
|
||||
setScale(getScale());
|
||||
// Set the proper armor stand to invisible to show armor
|
||||
@@ -396,6 +395,12 @@ public class ArmorStandEntity extends LivingEntity {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasAnyEquipment() {
|
||||
return (!getItemInSlot(EquipmentSlot.HELMET).isEmpty() || !getItemInSlot(EquipmentSlot.CHESTPLATE).isEmpty()
|
||||
|| !getItemInSlot(EquipmentSlot.LEGGINGS).isEmpty() || !getItemInSlot(EquipmentSlot.BOOTS).isEmpty()
|
||||
|| !getMainHandItem().isEmpty() || !getOffHandItem().isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getBoundingBoxWidth() {
|
||||
// For consistency with getBoundingBoxHeight()
|
||||
|
||||
@@ -64,7 +64,7 @@ public class PandaEntity extends AnimalEntity {
|
||||
packet.setRuntimeEntityId(geyserId);
|
||||
packet.setType(EntityEventType.EATING_ITEM);
|
||||
// As of 1.20.5 - pandas can eat cake
|
||||
packet.setData(this.hand.getDefinition().getRuntimeId() << 16);
|
||||
packet.setData(session.getItemMappings().getMapping(getMainHandItem()).getBedrockDefinition().getRuntimeId() << 16);
|
||||
session.sendUpstreamPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector2f;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
@@ -157,8 +156,7 @@ public class StriderEntity extends AnimalEntity implements Tickable, ClientVehic
|
||||
vehicleComponent.tickBoost();
|
||||
}
|
||||
} else { // getHand() for session player seems to always return air
|
||||
ItemDefinition itemDefinition = session.getItemMappings().getStoredItems().warpedFungusOnAStick().getBedrockDefinition();
|
||||
if (player.getHand().getDefinition() == itemDefinition || player.getOffhand().getDefinition() == itemDefinition) {
|
||||
if (player.isHolding(Items.WARPED_FUNGUS_ON_A_STICK)) {
|
||||
vehicleComponent.tickBoost();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector2f;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.Tickable;
|
||||
@@ -116,8 +115,7 @@ public class PigEntity extends TemperatureVariantAnimal implements Tickable, Cli
|
||||
vehicleComponent.tickBoost();
|
||||
}
|
||||
} else { // getHand() for session player seems to always return air
|
||||
ItemDefinition itemDefinition = session.getItemMappings().getStoredItems().carrotOnAStick().getBedrockDefinition();
|
||||
if (player.getHand().getDefinition() == itemDefinition || player.getOffhand().getDefinition() == itemDefinition) {
|
||||
if (player.isHolding(Items.CARROT_ON_A_STICK)) {
|
||||
vehicleComponent.tickBoost();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.geysermc.geyser.session.cache.tags.Tag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.geyser.util.ItemUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
||||
@@ -159,17 +160,16 @@ public class WolfEntity extends TameableEntity implements VariantIntHolder {
|
||||
return super.testMobInteraction(hand, itemInHand);
|
||||
}
|
||||
}
|
||||
if (itemInHand.asItem() == Items.WOLF_ARMOR && !this.body.isValid() && !getFlag(EntityFlag.BABY)) {
|
||||
if (itemInHand.asItem() == Items.WOLF_ARMOR && !getItemInSlot(EquipmentSlot.BODY).isEmpty() && !getFlag(EntityFlag.BABY)) {
|
||||
return InteractiveTag.EQUIP_WOLF_ARMOR;
|
||||
}
|
||||
if (itemInHand.asItem() == Items.SHEARS && this.body.isValid()
|
||||
if (itemInHand.asItem() == Items.SHEARS && !getItemInSlot(EquipmentSlot.BODY).isEmpty()
|
||||
&& (!isCurseOfBinding || session.getGameMode().equals(GameMode.CREATIVE))) {
|
||||
return InteractiveTag.REMOVE_WOLF_ARMOR;
|
||||
}
|
||||
if (getFlag(EntityFlag.SITTING) &&
|
||||
session.getTagCache().isItem(repairableItems, itemInHand.asItem()) &&
|
||||
this.body.isValid() && this.body.getTag() != null &&
|
||||
this.body.getTag().getInt("Damage") > 0) {
|
||||
!getItemInSlot(EquipmentSlot.BODY).isEmpty() && getItemInSlot(EquipmentSlot.BODY).isDamaged()) {
|
||||
return InteractiveTag.REPAIR_WOLF_ARMOR;
|
||||
}
|
||||
// Tamed and owned by player - can sit/stand
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
package org.geysermc.geyser.entity.type.living.monster;
|
||||
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
|
||||
@@ -49,8 +49,7 @@ public class AbstractSkeletonEntity extends MonsterEntity {
|
||||
dirtyMetadata.put(EntityDataTypes.TARGET_EID, ((xd & 4) == 4) ? geyserId : 0);
|
||||
|
||||
if ((xd & 4) == 4) {
|
||||
ItemDefinition bow = session.getItemMappings().getStoredItems().bow().getBedrockDefinition();
|
||||
setFlag(EntityFlag.FACING_TARGET_TO_RANGE_ATTACK, this.hand.getDefinition() == bow || this.offhand.getDefinition() == bow);
|
||||
setFlag(EntityFlag.FACING_TARGET_TO_RANGE_ATTACK, isHolding(Items.BOW));
|
||||
} else {
|
||||
setFlag(EntityFlag.FACING_TARGET_TO_RANGE_ATTACK, false);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -74,14 +75,14 @@ public class PiglinEntity extends BasePiglinEntity {
|
||||
ItemMapping crossbow = session.getItemMappings().getStoredItems().crossbow();
|
||||
boolean toCrossbow = stack != null && stack.asItem() == crossbow.getJavaItem();
|
||||
|
||||
if (toCrossbow ^ this.hand.getDefinition() == crossbow.getBedrockDefinition()) { // If switching to/from crossbow
|
||||
if (toCrossbow ^ getMainHandItem().is(Items.CROSSBOW)) { // If switching to/from crossbow
|
||||
dirtyMetadata.put(EntityDataTypes.BLOCK, session.getBlockMappings().getDefinition(toCrossbow ? 0 : 1));
|
||||
dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, (byte) 0);
|
||||
setFlag(EntityFlag.CHARGED, false);
|
||||
setFlag(EntityFlag.USING_ITEM, false);
|
||||
updateBedrockMetadata();
|
||||
|
||||
if (this.hand.isValid()) {
|
||||
if (!getMainHandItem().isEmpty()) {
|
||||
MobEquipmentPacket mobEquipmentPacket = new MobEquipmentPacket();
|
||||
mobEquipmentPacket.setRuntimeEntityId(geyserId);
|
||||
mobEquipmentPacket.setContainerId(ContainerId.INVENTORY);
|
||||
@@ -96,11 +97,11 @@ public class PiglinEntity extends BasePiglinEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMainHand(GeyserSession session) {
|
||||
super.updateMainHand(session);
|
||||
public void updateMainHand() {
|
||||
super.updateMainHand();
|
||||
|
||||
if (this.hand.getDefinition() == session.getItemMappings().getStoredItems().crossbow().getBedrockDefinition()) {
|
||||
if (this.hand.getTag() != null && this.hand.getTag().containsKey("chargedItem")) {
|
||||
if (getMainHandItem().is(Items.CROSSBOW)) {
|
||||
if (getMainHandItem().getComponent(DataComponentTypes.CHARGED_PROJECTILES) != null) {
|
||||
dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, Byte.MAX_VALUE);
|
||||
setFlag(EntityFlag.CHARGING, false);
|
||||
setFlag(EntityFlag.CHARGED, true);
|
||||
@@ -116,12 +117,12 @@ public class PiglinEntity extends BasePiglinEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateOffHand(GeyserSession session) {
|
||||
public void updateOffHand() {
|
||||
// Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates
|
||||
setFlag(EntityFlag.ADMIRING, session.getTagCache().is(ItemTag.PIGLIN_LOVED, session.getItemMappings().getMapping(this.offhand).getJavaItem()));
|
||||
setFlag(EntityFlag.ADMIRING, getOffHandItem().is(session, ItemTag.PIGLIN_LOVED));
|
||||
super.updateBedrockMetadata();
|
||||
|
||||
super.updateOffHand(session);
|
||||
super.updateOffHand();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
||||
@@ -28,11 +28,12 @@ package org.geysermc.geyser.entity.type.living.monster.raid;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -49,33 +50,32 @@ public class PillagerEntity extends AbstractIllagerEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMainHand(GeyserSession session) {
|
||||
public void updateMainHand() {
|
||||
updateCrossbow();
|
||||
|
||||
super.updateMainHand(session);
|
||||
super.updateMainHand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateOffHand(GeyserSession session) {
|
||||
public void updateOffHand() {
|
||||
updateCrossbow();
|
||||
|
||||
super.updateOffHand(session);
|
||||
super.updateOffHand();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for a crossbow in either the mainhand or offhand. If one exists, indicate that the pillager should be posing
|
||||
*/
|
||||
protected void updateCrossbow() {
|
||||
ItemMapping crossbow = session.getItemMappings().getStoredItems().crossbow();
|
||||
ItemData activeCrossbow = null;
|
||||
if (this.hand.getDefinition() == crossbow.getBedrockDefinition()) {
|
||||
activeCrossbow = this.hand;
|
||||
} else if (this.offhand.getDefinition() == crossbow.getBedrockDefinition()) {
|
||||
activeCrossbow = this.offhand;
|
||||
GeyserItemStack activeCrossbow = null;
|
||||
if (getMainHandItem().is(Items.CROSSBOW)) {
|
||||
activeCrossbow = getMainHandItem();
|
||||
} else if (getOffHandItem().is(Items.CROSSBOW)) {
|
||||
activeCrossbow = getOffHandItem();
|
||||
}
|
||||
|
||||
if (activeCrossbow != null) {
|
||||
if (activeCrossbow.getTag() != null && activeCrossbow.getTag().containsKey("chargedItem")) {
|
||||
if (activeCrossbow.getComponent(DataComponentTypes.CHARGED_PROJECTILES) != null) {
|
||||
dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, Byte.MAX_VALUE);
|
||||
setFlag(EntityFlag.CHARGING, false);
|
||||
setFlag(EntityFlag.CHARGED, true);
|
||||
|
||||
@@ -39,7 +39,6 @@ import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.AddPlayerPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket;
|
||||
@@ -52,6 +51,7 @@ import org.geysermc.geyser.entity.type.LivingEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.tameable.ParrotEntity;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.ItemTranslator;
|
||||
import org.geysermc.geyser.util.ChunkUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
@@ -135,7 +135,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
|
||||
addPlayerPacket.setPosition(position.sub(0, definition.offset(), 0));
|
||||
addPlayerPacket.setRotation(getBedrockRotation());
|
||||
addPlayerPacket.setMotion(motion);
|
||||
addPlayerPacket.setHand(hand);
|
||||
addPlayerPacket.setHand(ItemTranslator.translateToBedrock(session, getMainHandItem()));
|
||||
addPlayerPacket.getAdventureSettings().setCommandPermission(CommandPermission.ANY);
|
||||
addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER);
|
||||
addPlayerPacket.setDeviceId("");
|
||||
@@ -164,12 +164,6 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
|
||||
this.nametag = username;
|
||||
|
||||
this.equipment.clear();
|
||||
this.hand = ItemData.AIR;
|
||||
this.offhand = ItemData.AIR;
|
||||
this.boots = ItemData.AIR;
|
||||
this.leggings = ItemData.AIR;
|
||||
this.chestplate = ItemData.AIR;
|
||||
this.helmet = ItemData.AIR;
|
||||
}
|
||||
|
||||
public void resetMetadata() {
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.geysermc.geyser.level.physics.Direction;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.SkullCache;
|
||||
import org.geysermc.geyser.skin.SkullSkinManager;
|
||||
import org.geysermc.geyser.translator.item.ItemTranslator;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
@@ -86,7 +87,7 @@ public class SkullPlayerEntity extends PlayerEntity {
|
||||
addPlayerPacket.setPosition(position.sub(0, definition.offset(), 0));
|
||||
addPlayerPacket.setRotation(getBedrockRotation());
|
||||
addPlayerPacket.setMotion(motion);
|
||||
addPlayerPacket.setHand(hand);
|
||||
addPlayerPacket.setHand(ItemTranslator.translateToBedrock(session, getMainHandItem()));
|
||||
addPlayerPacket.getAdventureSettings().setCommandPermission(CommandPermission.ANY);
|
||||
addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER);
|
||||
addPlayerPacket.setDeviceId("");
|
||||
|
||||
@@ -275,6 +275,10 @@ public class GeyserItemStack {
|
||||
return getComponent(DataComponentTypes.MAX_DAMAGE) != null && getComponent(DataComponentTypes.UNBREAKABLE) == null && getComponent(DataComponentTypes.DAMAGE) != null;
|
||||
}
|
||||
|
||||
public boolean isDamaged() {
|
||||
return isDamageable() && getDamage() > 0;
|
||||
}
|
||||
|
||||
public Item asItem() {
|
||||
if (isEmpty()) {
|
||||
return Items.AIR;
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.common.DefinitionRegistry;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.block.custom.CustomBlockData;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.item.StoredItemMappings;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
@@ -75,11 +76,21 @@ public class ItemMappings implements DefinitionRegistry<ItemDefinition> {
|
||||
|
||||
Object2ObjectMap<CustomBlockData, ItemDefinition> customBlockItemDefinitions;
|
||||
|
||||
/**
|
||||
* Gets an {@link ItemMapping} from the given {@link GeyserItemStack}.
|
||||
*
|
||||
* @param itemStack the itemstack
|
||||
* @return an item entry from the given item stack
|
||||
*/
|
||||
public ItemMapping getMapping(@NonNull GeyserItemStack itemStack) {
|
||||
return this.getMapping(itemStack.getJavaId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an {@link ItemMapping} from the given {@link ItemStack}.
|
||||
*
|
||||
* @param itemStack the itemstack
|
||||
* @return an item entry from the given java edition identifier
|
||||
* @return an item entry from the given java edition item stack
|
||||
*/
|
||||
@NonNull
|
||||
public ItemMapping getMapping(@NonNull ItemStack itemStack) {
|
||||
|
||||
@@ -259,8 +259,8 @@ public class JavaEntityEventTranslator extends PacketTranslator<ClientboundEntit
|
||||
if (entity instanceof LivingEntity livingEntity) {
|
||||
livingEntity.switchHands();
|
||||
|
||||
livingEntity.updateMainHand(session);
|
||||
livingEntity.updateOffHand(session);
|
||||
livingEntity.updateMainHand();
|
||||
livingEntity.updateOffHand();
|
||||
} else {
|
||||
session.getGeyser().getLogger().debug("Got status message to swap hands for a non-living entity.");
|
||||
}
|
||||
|
||||
@@ -104,13 +104,13 @@ public class JavaSetEquipmentTranslator extends PacketTranslator<ClientboundSetE
|
||||
}
|
||||
|
||||
if (armorUpdated) {
|
||||
livingEntity.updateArmor(session);
|
||||
livingEntity.updateArmor();
|
||||
}
|
||||
if (mainHandUpdated) {
|
||||
livingEntity.updateMainHand(session);
|
||||
livingEntity.updateMainHand();
|
||||
}
|
||||
if (offHandUpdated) {
|
||||
livingEntity.updateOffHand(session);
|
||||
livingEntity.updateOffHand();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user