feat: add leash holding support to the entity api (#2026)

Co-authored-by: DeidaraMC <DeidaraMC>
This commit is contained in:
DeidaraMC 2024-03-19 12:48:52 -04:00 committed by GitHub
parent 32f96683ee
commit a31d239b51
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 51 additions and 0 deletions

View File

@ -163,6 +163,10 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
protected boolean removed;
private final Set<Entity> passengers = new CopyOnWriteArraySet<>();
private final Set<Entity> leashedEntities = new CopyOnWriteArraySet<>();
private Entity leashHolder;
protected EntityType entityType; // UNSAFE to change, modify at your own risk
// Network synchronization, send the absolute position of the entity each X milliseconds
@ -474,6 +478,15 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
}
player.sendPacket(getPassengersPacket());
}
// Leashes
if (leashHolder != null && (player.equals(leashHolder) || leashHolder.isViewer(player))) {
player.sendPacket(getAttachEntityPacket());
}
for (Entity entity : leashedEntities) {
if (entity.isViewer(player)) {
player.sendPacket(entity.getAttachEntityPacket());
}
};
// Head position
player.sendPacket(new EntityHeadLookPacket(getEntityId(), position.yaw()));
}
@ -492,6 +505,7 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
if (passenger != player) passenger.updateOldViewer(player);
}
}
leashedEntities.forEach(entity -> player.sendPacket(new AttachEntityPacket(entity, null)));
player.sendPacket(destroyPacketCache);
}
@ -1100,6 +1114,40 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
return new SetPassengersPacket(getEntityId(), passengers.stream().map(Entity::getEntityId).toList());
}
/**
* Gets the entities that this entity is leashing.
*
* @return an unmodifiable list containing all the leashed entities
*/
public @NotNull Set<Entity> getLeashedEntities() {
return Collections.unmodifiableSet(leashedEntities);
}
/**
* Gets the current leash holder.
*
* @return the entity leashing this entity, null if no leash holder
*/
public @Nullable Entity getLeashHolder() {
return leashHolder;
}
/**
* Sets the leash holder to this entity.
*
* @param entity the new leash holder
*/
public void setLeashHolder(@Nullable Entity entity) {
if (leashHolder != null) leashHolder.leashedEntities.remove(this);
if (entity != null) entity.leashedEntities.add(this);
this.leashHolder = entity;
sendPacketToViewersAndSelf(getAttachEntityPacket());
}
protected @NotNull AttachEntityPacket getAttachEntityPacket() {
return new AttachEntityPacket(this, leashHolder);
}
/**
* Entity statuses can be found <a href="https://wiki.vg/Entity_statuses">here</a>.
*
@ -1545,6 +1593,9 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
final Entity vehicle = this.vehicle;
if (vehicle != null) vehicle.removePassenger(this);
Set<Entity> leashedEntities = getLeashedEntities();
leashedEntities.forEach(entity -> entity.setLeashHolder(null));
MinecraftServer.process().dispatcher().removeElement(this);
this.removed = true;
if (permanent) {