mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Boats are leashable
This commit is contained in:
parent
65fd409a00
commit
8ad10f8a9e
17 changed files with 120 additions and 38 deletions
|
@ -41,7 +41,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class BoatEntity extends Entity implements Tickable {
|
public class BoatEntity extends Entity implements Leashable, Tickable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Required when IS_BUOYANT is sent in order for boats to work in the water. <br>
|
* Required when IS_BUOYANT is sent in order for boats to work in the water. <br>
|
||||||
|
@ -65,6 +65,8 @@ public class BoatEntity extends Entity implements Tickable {
|
||||||
@Getter
|
@Getter
|
||||||
private int variant;
|
private int variant;
|
||||||
|
|
||||||
|
private long leashHolderBedrockId = -1;
|
||||||
|
|
||||||
// Looks too fast and too choppy with 0.1f, which is how I believe the Microsoftian client handles it
|
// Looks too fast and too choppy with 0.1f, which is how I believe the Microsoftian client handles it
|
||||||
private final float ROWING_SPEED = 0.1f;
|
private final float ROWING_SPEED = 0.1f;
|
||||||
|
|
||||||
|
@ -147,8 +149,18 @@ public class BoatEntity extends Entity implements Tickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLeashHolderBedrockId(long bedrockId) {
|
||||||
|
this.leashHolderBedrockId = bedrockId;
|
||||||
|
dirtyMetadata.put(EntityDataTypes.LEASH_HOLDER, bedrockId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InteractiveTag testInteraction(Hand hand) {
|
protected InteractiveTag testInteraction(Hand hand) {
|
||||||
|
InteractiveTag tag = super.testInteraction(hand);
|
||||||
|
if (tag != InteractiveTag.NONE) {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
if (session.isSneaking()) {
|
if (session.isSneaking()) {
|
||||||
return InteractiveTag.NONE;
|
return InteractiveTag.NONE;
|
||||||
} else if (passengers.size() < 2) {
|
} else if (passengers.size() < 2) {
|
||||||
|
@ -160,6 +172,10 @@ public class BoatEntity extends Entity implements Tickable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InteractionResult interact(Hand hand) {
|
public InteractionResult interact(Hand hand) {
|
||||||
|
InteractionResult result = super.interact(hand);
|
||||||
|
if (result != InteractionResult.PASS) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
if (session.isSneaking()) {
|
if (session.isSneaking()) {
|
||||||
return InteractionResult.PASS;
|
return InteractionResult.PASS;
|
||||||
} else {
|
} else {
|
||||||
|
@ -191,6 +207,11 @@ public class BoatEntity extends Entity implements Tickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long leashHolderBedrockId() {
|
||||||
|
return leashHolderBedrockId;
|
||||||
|
}
|
||||||
|
|
||||||
private void sendAnimationPacket(GeyserSession session, Entity rower, AnimatePacket.Action action, float rowTime) {
|
private void sendAnimationPacket(GeyserSession session, Entity rower, AnimatePacket.Action action, float rowTime) {
|
||||||
AnimatePacket packet = new AnimatePacket();
|
AnimatePacket packet = new AnimatePacket();
|
||||||
packet.setRuntimeEntityId(rower.getGeyserId());
|
packet.setRuntimeEntityId(rower.getGeyserId());
|
||||||
|
|
|
@ -40,6 +40,7 @@ import org.geysermc.geyser.api.entity.type.GeyserEntity;
|
||||||
import org.geysermc.geyser.entity.EntityDefinition;
|
import org.geysermc.geyser.entity.EntityDefinition;
|
||||||
import org.geysermc.geyser.entity.GeyserDirtyMetadata;
|
import org.geysermc.geyser.entity.GeyserDirtyMetadata;
|
||||||
import org.geysermc.geyser.entity.properties.GeyserEntityPropertyManager;
|
import org.geysermc.geyser.entity.properties.GeyserEntityPropertyManager;
|
||||||
|
import org.geysermc.geyser.item.Items;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||||
import org.geysermc.geyser.util.EntityUtils;
|
import org.geysermc.geyser.util.EntityUtils;
|
||||||
|
@ -557,6 +558,17 @@ public class Entity implements GeyserEntity {
|
||||||
* Should usually mirror {@link #interact(Hand)} without any side effects.
|
* Should usually mirror {@link #interact(Hand)} without any side effects.
|
||||||
*/
|
*/
|
||||||
protected InteractiveTag testInteraction(Hand hand) {
|
protected InteractiveTag testInteraction(Hand hand) {
|
||||||
|
if (isAlive() && this instanceof Leashable leashable) {
|
||||||
|
if (leashable.leashHolderBedrockId() == session.getPlayerEntity().getGeyserId()) {
|
||||||
|
// Note this might be client side. Has yet to be an issue though, as of Java 1.21.
|
||||||
|
return InteractiveTag.REMOVE_LEASH;
|
||||||
|
}
|
||||||
|
if (session.getPlayerInventory().getItemInHand(hand).asItem() == Items.LEAD && leashable.canBeLeashed()) {
|
||||||
|
// We shall leash
|
||||||
|
return InteractiveTag.LEASH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return InteractiveTag.NONE;
|
return InteractiveTag.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,6 +577,18 @@ public class Entity implements GeyserEntity {
|
||||||
* to ensure packet parity as well as functionality parity (such as sound effect responses).
|
* to ensure packet parity as well as functionality parity (such as sound effect responses).
|
||||||
*/
|
*/
|
||||||
public InteractionResult interact(Hand hand) {
|
public InteractionResult interact(Hand hand) {
|
||||||
|
if (isAlive() && this instanceof Leashable leashable) {
|
||||||
|
if (leashable.leashHolderBedrockId() == session.getPlayerEntity().getGeyserId()) {
|
||||||
|
// Note this might also update client side (a theoretical Geyser/client desync and Java parity issue).
|
||||||
|
// Has yet to be an issue though, as of Java 1.21.
|
||||||
|
return InteractionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
if (session.getPlayerInventory().getItemInHand(hand).asItem() == Items.LEAD && leashable.canBeLeashed()) {
|
||||||
|
// We shall leash
|
||||||
|
return InteractionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return InteractionResult.PASS;
|
return InteractionResult.PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 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.geyser.entity.type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* I can haz lead
|
||||||
|
* (The item, not the mineral)
|
||||||
|
*/
|
||||||
|
public interface Leashable {
|
||||||
|
void setLeashHolderBedrockId(long bedrockId);
|
||||||
|
|
||||||
|
long leashHolderBedrockId();
|
||||||
|
|
||||||
|
default boolean canBeLeashed() {
|
||||||
|
return isNotLeashed();
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isNotLeashed() {
|
||||||
|
return leashHolderBedrockId() == -1L;
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,7 +38,7 @@ public class AmbientEntity extends MobEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBeLeashed() {
|
public boolean canBeLeashed() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class DolphinEntity extends WaterEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBeLeashed() {
|
public boolean canBeLeashed() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,12 +25,12 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.entity.type.living;
|
package org.geysermc.geyser.entity.type.living;
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.cloudburstmc.math.vector.Vector3f;
|
import org.cloudburstmc.math.vector.Vector3f;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.geyser.entity.EntityDefinition;
|
import org.geysermc.geyser.entity.EntityDefinition;
|
||||||
|
import org.geysermc.geyser.entity.type.Leashable;
|
||||||
import org.geysermc.geyser.entity.type.LivingEntity;
|
import org.geysermc.geyser.entity.type.LivingEntity;
|
||||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||||
import org.geysermc.geyser.item.Items;
|
import org.geysermc.geyser.item.Items;
|
||||||
|
@ -43,11 +43,10 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class MobEntity extends LivingEntity {
|
public class MobEntity extends LivingEntity implements Leashable {
|
||||||
/**
|
/**
|
||||||
* If another mob is holding this mob by a leash, this variable tracks their Bedrock entity ID.
|
* If another mob is holding this mob by a leash, this variable tracks their Bedrock entity ID.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private long leashHolderBedrockId;
|
private long leashHolderBedrockId;
|
||||||
|
|
||||||
public MobEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
public MobEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||||
|
@ -65,6 +64,7 @@ public class MobEntity extends LivingEntity {
|
||||||
setFlag(EntityFlag.NO_AI, (xd & 0x01) == 0x01);
|
setFlag(EntityFlag.NO_AI, (xd & 0x01) == 0x01);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setLeashHolderBedrockId(long bedrockId) {
|
public void setLeashHolderBedrockId(long bedrockId) {
|
||||||
this.leashHolderBedrockId = bedrockId;
|
this.leashHolderBedrockId = bedrockId;
|
||||||
dirtyMetadata.put(EntityDataTypes.LEASH_HOLDER, bedrockId);
|
dirtyMetadata.put(EntityDataTypes.LEASH_HOLDER, bedrockId);
|
||||||
|
@ -79,10 +79,7 @@ public class MobEntity extends LivingEntity {
|
||||||
return InteractiveTag.REMOVE_LEASH;
|
return InteractiveTag.REMOVE_LEASH;
|
||||||
} else {
|
} else {
|
||||||
GeyserItemStack itemStack = session.getPlayerInventory().getItemInHand(hand);
|
GeyserItemStack itemStack = session.getPlayerInventory().getItemInHand(hand);
|
||||||
if (itemStack.asItem() == Items.LEAD && canBeLeashed()) {
|
if (itemStack.asItem() == Items.NAME_TAG) {
|
||||||
// We shall leash
|
|
||||||
return InteractiveTag.LEASH;
|
|
||||||
} else if (itemStack.asItem() == Items.NAME_TAG) {
|
|
||||||
InteractionResult result = checkInteractWithNameTag(itemStack);
|
InteractionResult result = checkInteractWithNameTag(itemStack);
|
||||||
if (result.consumesAction()) {
|
if (result.consumesAction()) {
|
||||||
return InteractiveTag.NAME;
|
return InteractiveTag.NAME;
|
||||||
|
@ -99,9 +96,6 @@ public class MobEntity extends LivingEntity {
|
||||||
if (!isAlive()) {
|
if (!isAlive()) {
|
||||||
// dead lol
|
// dead lol
|
||||||
return InteractionResult.PASS;
|
return InteractionResult.PASS;
|
||||||
} else if (leashHolderBedrockId == session.getPlayerEntity().getGeyserId()) {
|
|
||||||
// TODO looks like the client assumes it will go through and removes the attachment itself?
|
|
||||||
return InteractionResult.SUCCESS;
|
|
||||||
} else {
|
} else {
|
||||||
GeyserItemStack itemInHand = session.getPlayerInventory().getItemInHand(hand);
|
GeyserItemStack itemInHand = session.getPlayerInventory().getItemInHand(hand);
|
||||||
InteractionResult result = checkPriorityInteractions(itemInHand);
|
InteractionResult result = checkPriorityInteractions(itemInHand);
|
||||||
|
@ -115,10 +109,7 @@ public class MobEntity extends LivingEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private InteractionResult checkPriorityInteractions(GeyserItemStack itemInHand) {
|
private InteractionResult checkPriorityInteractions(GeyserItemStack itemInHand) {
|
||||||
if (itemInHand.asItem() == Items.LEAD && canBeLeashed()) {
|
if (itemInHand.asItem() == Items.NAME_TAG) {
|
||||||
// We shall leash
|
|
||||||
return InteractionResult.SUCCESS;
|
|
||||||
} else if (itemInHand.asItem() == Items.NAME_TAG) {
|
|
||||||
InteractionResult result = checkInteractWithNameTag(itemInHand);
|
InteractionResult result = checkInteractWithNameTag(itemInHand);
|
||||||
if (result.consumesAction()) {
|
if (result.consumesAction()) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -143,12 +134,14 @@ public class MobEntity extends LivingEntity {
|
||||||
return InteractionResult.PASS;
|
return InteractionResult.PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean canBeLeashed() {
|
@Override
|
||||||
|
public boolean canBeLeashed() {
|
||||||
return isNotLeashed() && !isEnemy();
|
return isNotLeashed() && !isEnemy();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final boolean isNotLeashed() {
|
@Override
|
||||||
return leashHolderBedrockId == -1L;
|
public long leashHolderBedrockId() {
|
||||||
|
return leashHolderBedrockId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -122,7 +122,7 @@ public class SquidEntity extends WaterEntity implements Tickable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBeLeashed() {
|
public boolean canBeLeashed() {
|
||||||
return isNotLeashed();
|
return isNotLeashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class WaterEntity extends CreatureEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBeLeashed() {
|
public boolean canBeLeashed() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class AxolotlEntity extends AnimalEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBeLeashed() {
|
public boolean canBeLeashed() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ public class HoglinEntity extends AnimalEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBeLeashed() {
|
public boolean canBeLeashed() {
|
||||||
return isNotLeashed();
|
return isNotLeashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ public class PandaEntity extends AnimalEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBeLeashed() {
|
public boolean canBeLeashed() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class TurtleEntity extends AnimalEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBeLeashed() {
|
public boolean canBeLeashed() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ public abstract class TameableEntity extends AnimalEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBeLeashed() {
|
public boolean canBeLeashed() {
|
||||||
return isNotLeashed();
|
return isNotLeashed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ public class WolfEntity extends TameableEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBeLeashed() {
|
public boolean canBeLeashed() {
|
||||||
return !getFlag(EntityFlag.ANGRY) && super.canBeLeashed();
|
return !getFlag(EntityFlag.ANGRY) && super.canBeLeashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class AbstractMerchantEntity extends AgeableEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBeLeashed() {
|
public boolean canBeLeashed() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class ZoglinEntity extends MonsterEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canBeLeashed() {
|
public boolean canBeLeashed() {
|
||||||
return isNotLeashed();
|
return isNotLeashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,15 +25,15 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.java.entity;
|
package org.geysermc.geyser.translator.protocol.java.entity;
|
||||||
|
|
||||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityLinkPacket;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
||||||
import org.geysermc.geyser.entity.type.Entity;
|
import org.geysermc.geyser.entity.type.Entity;
|
||||||
import org.geysermc.geyser.entity.type.living.MobEntity;
|
import org.geysermc.geyser.entity.type.Leashable;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityLinkPacket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a leash is attached, removed or updated from an entity
|
* Called when a leash is attached, removed or updated from an entity
|
||||||
|
@ -44,16 +44,16 @@ public class JavaSetEntityLinkTranslator extends PacketTranslator<ClientboundSet
|
||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, ClientboundSetEntityLinkPacket packet) {
|
public void translate(GeyserSession session, ClientboundSetEntityLinkPacket packet) {
|
||||||
Entity holderId = session.getEntityCache().getEntityByJavaId(packet.getEntityId());
|
Entity holderId = session.getEntityCache().getEntityByJavaId(packet.getEntityId());
|
||||||
if (!(holderId instanceof MobEntity mobEntity)) {
|
if (!(holderId instanceof Leashable asLeashable)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity attachedToId = session.getEntityCache().getEntityByJavaId(packet.getAttachedToId());
|
Entity attachedToId = session.getEntityCache().getEntityByJavaId(packet.getAttachedToId());
|
||||||
if (attachedToId == null || packet.getAttachedToId() == 0) {
|
if (attachedToId == null || packet.getAttachedToId() == 0) {
|
||||||
// Is not being leashed
|
// Is not being leashed
|
||||||
mobEntity.setFlag(EntityFlag.LEASHED, false);
|
holderId.setFlag(EntityFlag.LEASHED, false);
|
||||||
mobEntity.setLeashHolderBedrockId(-1L);
|
asLeashable.setLeashHolderBedrockId(-1L);
|
||||||
mobEntity.updateBedrockMetadata();
|
holderId.updateBedrockMetadata();
|
||||||
EntityEventPacket eventPacket = new EntityEventPacket();
|
EntityEventPacket eventPacket = new EntityEventPacket();
|
||||||
eventPacket.setRuntimeEntityId(holderId.getGeyserId());
|
eventPacket.setRuntimeEntityId(holderId.getGeyserId());
|
||||||
eventPacket.setType(EntityEventType.REMOVE_LEASH);
|
eventPacket.setType(EntityEventType.REMOVE_LEASH);
|
||||||
|
@ -62,8 +62,8 @@ public class JavaSetEntityLinkTranslator extends PacketTranslator<ClientboundSet
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mobEntity.setFlag(EntityFlag.LEASHED, true);
|
holderId.setFlag(EntityFlag.LEASHED, true);
|
||||||
mobEntity.setLeashHolderBedrockId(attachedToId.getGeyserId());
|
asLeashable.setLeashHolderBedrockId(attachedToId.getGeyserId());
|
||||||
holderId.updateBedrockMetadata();
|
holderId.updateBedrockMetadata();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue