let the entities be aware of their world
This commit is contained in:
parent
522e31ef12
commit
3183a3140d
9 changed files with 280 additions and 53 deletions
|
@ -5,16 +5,15 @@
|
|||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="9d5d9b6f-43c8-41a4-bb42-a66ffc96c9b0" name="Changes" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/meta/CompatibilityIndex.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/APISettings.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/APIConfig.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/EntityLib.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/EntityLib.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/Platform.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/Platform.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/common/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java" beforeDir="false" afterPath="$PROJECT_DIR$/common/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/common/src/main/java/me/tofaa/entitylib/common/AbstractPlatform.java" beforeDir="false" afterPath="$PROJECT_DIR$/common/src/main/java/me/tofaa/entitylib/common/AbstractPlatform.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibAPI.java" beforeDir="false" afterPath="$PROJECT_DIR$/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibAPI.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibPlatform.java" beforeDir="false" afterPath="$PROJECT_DIR$/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibPlatform.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java" beforeDir="false" afterPath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/WorldWrapper.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/WorldWrapper.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/meta/UsedVersion.java" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/meta/VersionCompatCheck.java" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/tick/Tickable.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/tick/Tickable.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/ai/goals/RandomHeadMovementGoal.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/ai/goals/RandomHeadMovementGoal.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/common/src/main/java/me/tofaa/entitylib/common/AbstractWorldWrapper.java" beforeDir="false" afterPath="$PROJECT_DIR$/common/src/main/java/me/tofaa/entitylib/common/AbstractWorldWrapper.java" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
|
@ -256,7 +255,8 @@
|
|||
<workItem from="1706248178234" duration="17096000" />
|
||||
<workItem from="1706284605696" duration="11691000" />
|
||||
<workItem from="1706371324325" duration="1187000" />
|
||||
<workItem from="1706443875388" duration="3245000" />
|
||||
<workItem from="1706443875388" duration="4827000" />
|
||||
<workItem from="1706513591682" duration="2661000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
|||
import com.github.retrooper.packetevents.protocol.world.Dimension;
|
||||
import com.github.retrooper.packetevents.protocol.world.Location;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import me.tofaa.entitylib.tick.TickContainer;
|
||||
import me.tofaa.entitylib.wrapper.WrapperEntity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package me.tofaa.entitylib.meta;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataType;
|
||||
|
||||
public interface CompatibilityIndex {
|
||||
|
||||
byte getOffSet(byte latestOffset, EntityDataType<?> type);
|
||||
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package me.tofaa.entitylib.meta;
|
||||
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
|
||||
public @interface UsedVersion {
|
||||
|
||||
ServerVersion[] value();
|
||||
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package me.tofaa.entitylib.meta;
|
||||
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.manager.server.VersionComparison;
|
||||
import me.tofaa.entitylib.EntityLib;
|
||||
|
||||
public final class VersionCompatCheck {
|
||||
|
||||
private VersionCompatCheck() {}
|
||||
|
||||
static boolean isVersion(ServerVersion version) {
|
||||
return version.is(VersionComparison.EQUALS, EntityLib.getApi().getPacketEvents().getServerManager().getVersion());
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,21 @@ package me.tofaa.entitylib.tick;
|
|||
|
||||
public interface Tickable {
|
||||
|
||||
/**
|
||||
* @return if the entity is ticking.
|
||||
*/
|
||||
boolean isTicking();
|
||||
|
||||
/**
|
||||
* Sets the entities ticking status, incase you want to stop ticking for a moment then continue
|
||||
* @param ticking if the entity should tick.
|
||||
*/
|
||||
void setTicking(boolean ticking);
|
||||
|
||||
/**
|
||||
* Ticks this entity. This method will not be called if {@link #isTicking()} returns false.
|
||||
* @param time the current time in milliseconds.
|
||||
*/
|
||||
void tick(long time);
|
||||
|
||||
}
|
||||
|
|
|
@ -2,52 +2,106 @@ package me.tofaa.entitylib.wrapper;
|
|||
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.protocol.world.BoundingBox;
|
||||
import com.github.retrooper.packetevents.protocol.world.Location;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDestroyEntities;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityRotation;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityVelocity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.*;
|
||||
import me.tofaa.entitylib.EntityLib;
|
||||
import me.tofaa.entitylib.WorldWrapper;
|
||||
import me.tofaa.entitylib.meta.EntityMeta;
|
||||
import me.tofaa.entitylib.meta.types.ObjectData;
|
||||
import me.tofaa.entitylib.tick.Tickable;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.text.html.parser.Entity;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
public class WrapperEntity implements Tickable {
|
||||
|
||||
private final UUID uuid;
|
||||
private final int entityId;
|
||||
|
||||
private EntityType entityType;
|
||||
private EntityMeta entityMeta;
|
||||
private boolean ticking;
|
||||
private Location location;
|
||||
private Location preRidingLocation;
|
||||
private Set<UUID> viewers;
|
||||
private boolean onGround;
|
||||
private boolean spawned;
|
||||
private Vector3d velocity;
|
||||
|
||||
private int riding = -1;
|
||||
private Set<Integer> passengers = new HashSet<>();
|
||||
private WorldWrapper<?> world;
|
||||
|
||||
public WrapperEntity(int entityId, UUID uuid, EntityType entityType, EntityMeta entityMeta) {
|
||||
this.entityId = entityId;
|
||||
this.uuid = uuid;
|
||||
this.entityType = entityType;
|
||||
this.entityMeta = entityMeta;
|
||||
this.ticking = true;
|
||||
}
|
||||
|
||||
public void spawn() {}
|
||||
|
||||
public void despawn() {}
|
||||
|
||||
public void teleport(@NotNull Location location) {
|
||||
public boolean spawn(WorldWrapper<?> world, Location location) {
|
||||
if (spawned) return false;
|
||||
this.location = location;
|
||||
this.world = world;
|
||||
this.spawned = true;
|
||||
int data = 0;
|
||||
Optional<Vector3d> velocity;
|
||||
double veloX = 0, veloY = 0, veloZ = 0;
|
||||
if (entityMeta instanceof ObjectData) {
|
||||
ObjectData od = (ObjectData) entityMeta;
|
||||
data = od.getObjectData();
|
||||
if (od.requiresVelocityPacketAtSpawn()) {
|
||||
final WrapperPlayServerEntityVelocity veloPacket = getVelocityPacket();
|
||||
veloX = veloPacket.getVelocity().getX();
|
||||
veloY = veloPacket.getVelocity().getY();
|
||||
veloZ = veloPacket.getVelocity().getZ();
|
||||
}
|
||||
}
|
||||
if (veloX == 0 && veloY == 0 && veloZ == 0) {
|
||||
velocity = Optional.empty();
|
||||
} else {
|
||||
velocity = Optional.of(new Vector3d(veloX, veloY, veloZ));
|
||||
}
|
||||
sendPacketToViewers(
|
||||
new WrapperPlayServerSpawnEntity(
|
||||
entityId,
|
||||
Optional.of(this.uuid),
|
||||
entityType,
|
||||
location.getPosition(),
|
||||
location.getPitch(),
|
||||
location.getYaw(),
|
||||
location.getYaw(),
|
||||
data,
|
||||
velocity
|
||||
)
|
||||
);
|
||||
sendPacketToViewers(entityMeta.createPacket());
|
||||
return true;
|
||||
}
|
||||
|
||||
public void despawn() {
|
||||
if (!spawned) return;
|
||||
spawned = false;
|
||||
sendPacketToViewers(new WrapperPlayServerDestroyEntities(entityId));
|
||||
}
|
||||
|
||||
public void teleport(WorldWrapper<?> world, @NotNull Location location) {
|
||||
this.location = location;
|
||||
this.world = world;
|
||||
sendPacketToViewers(
|
||||
new WrapperPlayServerEntityTeleport(
|
||||
entityId,
|
||||
location.getPosition(),
|
||||
location.getYaw(),
|
||||
location.getPitch(),
|
||||
onGround
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public boolean addViewer(UUID uuid) {
|
||||
|
@ -131,12 +185,44 @@ public class WrapperEntity implements Tickable {
|
|||
return entityType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable set of the passengers of the entity.
|
||||
* @return the passengers of the entity
|
||||
*/
|
||||
public Set<Integer> getPassengers() {
|
||||
return Collections.unmodifiableSet(passengers);
|
||||
}
|
||||
|
||||
public WrapperEntity getRiding() {
|
||||
return world.getEntity(riding);
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected WrapperPlayServerSetPassengers createPassengerPacket() {
|
||||
return new WrapperPlayServerSetPassengers(entityId, passengers.stream().mapToInt(i -> i).toArray());
|
||||
}
|
||||
|
||||
|
||||
private WrapperPlayServerEntityVelocity getVelocityPacket() {
|
||||
Vector3d velocity = this.velocity.multiply(8000.0f / 20.0f);
|
||||
return new WrapperPlayServerEntityVelocity(entityId, velocity);
|
||||
}
|
||||
|
||||
public boolean isSpawned() {
|
||||
return spawned;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTicking() {
|
||||
return ticking;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTicking(boolean ticking) {
|
||||
this.ticking = ticking;
|
||||
}
|
||||
|
||||
public boolean hasVelocity() {
|
||||
if (isOnGround()) {
|
||||
// if the entity is on the ground and only "moves" downwards, it does not have a velocity.
|
||||
|
@ -189,6 +275,135 @@ public class WrapperEntity implements Tickable {
|
|||
refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a passenger to the entity. The passenger will be visible to all viewers of the entity.
|
||||
* @param passenger the entity id of the passenger
|
||||
*/
|
||||
public void addPassenger(int passenger) {
|
||||
if (passengers.contains(passenger)) {
|
||||
throw new IllegalArgumentException("Passenger already exists");
|
||||
}
|
||||
passengers.add(passenger);
|
||||
sendPacketToViewers(createPassengerPacket());
|
||||
WrapperEntity e = world.getEntity(passenger);
|
||||
if (e != null) {
|
||||
e.riding = this.entityId;
|
||||
e.preRidingLocation = e.location;
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable Location getPreRidingLocation() {
|
||||
return preRidingLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entity id of the entity that the entity is riding, -1 if the entity is not riding
|
||||
*/
|
||||
public int getRidingId() {
|
||||
return riding;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds multiple passengers to the entity. The passengers will be visible to all viewers of the entity.
|
||||
* @param passengers the entity ids of the passengers
|
||||
*/
|
||||
public void addPassengers(int... passengers) {
|
||||
for (int passenger : passengers) {
|
||||
addPassenger(passenger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a passenger to the entity. The passenger will be visible to all viewers of the entity.
|
||||
* @param passenger the wrapper entity passenger
|
||||
*/
|
||||
public void addPassenger(WrapperEntity passenger) {
|
||||
addPassenger(passenger.getEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds multiple passengers to the entity. The passengers will be visible to all viewers of the entity.
|
||||
* @param passengers the wrapper entity passengers
|
||||
*/
|
||||
public void addPassengers(WrapperEntity... passengers) {
|
||||
for (WrapperEntity passenger : passengers) {
|
||||
addPassenger(passenger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a passenger from the entity. The passenger will be removed from the view of all viewers of the entity.
|
||||
* @param passenger the entity id of the passenger
|
||||
*/
|
||||
public void removePassenger(int passenger) {
|
||||
if (!passengers.contains(passenger)) {
|
||||
throw new IllegalArgumentException("Passenger does not exist");
|
||||
}
|
||||
passengers.remove(passenger);
|
||||
sendPacketToViewers(createPassengerPacket());
|
||||
WrapperEntity e = world.getEntity(passenger);
|
||||
if (e != null) {
|
||||
e.riding = -1;
|
||||
e.teleport(world, e.preRidingLocation);
|
||||
}
|
||||
}
|
||||
|
||||
public WorldWrapper<?> getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param passenger the entity id of the passenger
|
||||
* @return true if the entity has the passenger, false otherwise
|
||||
*/
|
||||
public boolean hasPassenger(int passenger) {
|
||||
return passengers.contains(passenger);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param passenger the passenger wrapper entity
|
||||
* @return true if the entity has the passenger, false otherwise
|
||||
*/
|
||||
public boolean hasPassenger(WrapperEntity passenger) {
|
||||
return hasPassenger(passenger.getEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes multiple passengers from the entity. The passengers will be removed from the view of all viewers of the entity.
|
||||
* @param passengers the entity ids of the passengers
|
||||
*/
|
||||
public void removePassengers(int... passengers) {
|
||||
for (int passenger : passengers) {
|
||||
removePassenger(passenger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a passenger from the entity. The passenger will be removed from the view of all viewers of the entity.
|
||||
* @param passenger the wrapper entity passenger
|
||||
*/
|
||||
public void removePassenger(WrapperEntity passenger) {
|
||||
removePassenger(passenger.getEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes multiple passengers from the entity. The passengers will be removed from the view of all viewers of the entity.
|
||||
* @param passengers the wrapper entity passengers
|
||||
*/
|
||||
public void removePassengers(WrapperEntity... passengers) {
|
||||
for (WrapperEntity passenger : passengers) {
|
||||
removePassenger(passenger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the entity has passengers, false otherwise
|
||||
*/
|
||||
public boolean isRiding() {
|
||||
return riding != -1;
|
||||
}
|
||||
|
||||
public @NotNull Set<UUID> getViewers() {
|
||||
return Collections.unmodifiableSet(viewers);
|
||||
}
|
||||
|
@ -199,6 +414,18 @@ public class WrapperEntity implements Tickable {
|
|||
|
||||
@Override
|
||||
public void tick(long time) {
|
||||
|
||||
if (isRiding()) {
|
||||
WrapperEntity riding = getRiding();
|
||||
if (riding != null) {
|
||||
Location l = riding.getLocation();
|
||||
location = new Location(
|
||||
l.getX(),
|
||||
l.getY() + 1,
|
||||
l.getZ(),
|
||||
l.getYaw(),
|
||||
l.getPitch()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ public class RandomHeadMovementGoal extends GoalSelector {
|
|||
@Override
|
||||
public void tick(long time) {
|
||||
--lookTime;
|
||||
entity.teleport(CoordinateUtil.withDirection(entity.getLocation(), lookDirection));
|
||||
entity.teleport(entity.getWorld(), CoordinateUtil.withDirection(entity.getLocation(), lookDirection));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -37,8 +37,7 @@ public abstract class AbstractWorldWrapper<W> implements WorldWrapper<W> {
|
|||
|
||||
@Override
|
||||
public <T extends WrapperEntity> @NotNull T spawnEntity(@NotNull T entity, @NotNull Location location) {
|
||||
entity.teleport(location);
|
||||
entity.spawn();
|
||||
entity.spawn(this, location);
|
||||
entities.put(entity.getUuid(), entity);
|
||||
entitiesById.put(entity.getEntityId(), entity);
|
||||
return entity;
|
||||
|
|
Loading…
Reference in a new issue