459 lines
14 KiB
Java
459 lines
14 KiB
Java
/*
|
|
* This file is part of SpongeAPI, licensed under the MIT License (MIT).
|
|
*
|
|
* Copyright (c) SpongePowered <https://www.spongepowered.org>
|
|
* Copyright (c) contributors
|
|
*
|
|
* 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.
|
|
*/
|
|
package org.spongepowered.api.entity;
|
|
|
|
import net.kyori.adventure.text.Component;
|
|
import net.kyori.adventure.text.event.HoverEvent;
|
|
import net.kyori.adventure.text.event.HoverEventSource;
|
|
import org.spongepowered.api.data.Keys;
|
|
import org.spongepowered.api.data.SerializableDataHolder;
|
|
import org.spongepowered.api.data.value.ListValue;
|
|
import org.spongepowered.api.data.value.Value;
|
|
import org.spongepowered.api.event.cause.entity.damage.source.DamageSource;
|
|
import org.spongepowered.api.projectile.source.EntityProjectileSource;
|
|
import org.spongepowered.api.util.AABB;
|
|
import org.spongepowered.api.util.Identifiable;
|
|
import org.spongepowered.api.util.RandomProvider;
|
|
import org.spongepowered.api.util.RelativePositions;
|
|
import org.spongepowered.api.util.Ticks;
|
|
import org.spongepowered.api.util.Transform;
|
|
import org.spongepowered.api.util.annotation.DoNotStore;
|
|
import org.spongepowered.api.world.Locatable;
|
|
import org.spongepowered.api.world.World;
|
|
import org.spongepowered.api.world.schematic.Schematic;
|
|
import org.spongepowered.api.world.server.ServerLocation;
|
|
import org.spongepowered.api.world.server.ServerWorld;
|
|
import org.spongepowered.math.imaginary.Quaterniond;
|
|
import org.spongepowered.math.vector.Vector3d;
|
|
|
|
import java.util.Collection;
|
|
import java.util.EnumSet;
|
|
import java.util.Objects;
|
|
import java.util.Optional;
|
|
import java.util.UUID;
|
|
import java.util.function.Predicate;
|
|
import java.util.function.Supplier;
|
|
import java.util.function.UnaryOperator;
|
|
|
|
/**
|
|
* An entity is a Minecraft entity.
|
|
*
|
|
* <p>Examples of entities include:</p>
|
|
*
|
|
* <ul>
|
|
* <li>Zombies</li>
|
|
* <li>Sheep</li>
|
|
* <li>Players</li>
|
|
* <li>Dropped items</li>
|
|
* <li>Dropped experience points</li>
|
|
* <li>etc.</li>
|
|
* </ul>
|
|
*
|
|
* <p>Blocks and items (when they are in inventories) are not entities.</p>
|
|
*/
|
|
@DoNotStore
|
|
public interface Entity extends Identifiable, HoverEventSource<HoverEvent.ShowEntity>, Locatable, EntityProjectileSource,
|
|
SerializableDataHolder.Mutable, RandomProvider {
|
|
|
|
/**
|
|
* Gets the {@link EntityType}.
|
|
*
|
|
* @return The type
|
|
*/
|
|
EntityType<?> type();
|
|
|
|
/**
|
|
* Creates an {@link EntitySnapshot}.
|
|
*
|
|
* @return The snapshot
|
|
*/
|
|
EntitySnapshot createSnapshot();
|
|
|
|
@Override
|
|
Entity copy();
|
|
|
|
/**
|
|
* Creates an {@link EntityArchetype} for use with {@link Schematic}s.
|
|
*
|
|
* @return The archetype
|
|
*/
|
|
EntityArchetype createArchetype();
|
|
|
|
/**
|
|
* Gets the position of this entity
|
|
*
|
|
* @return The position of this entity
|
|
*/
|
|
Vector3d position();
|
|
|
|
/**
|
|
* Sets the position of this entity.
|
|
*
|
|
* @param position The position to set
|
|
* @return True if set, false if not
|
|
*/
|
|
boolean setPosition(Vector3d position);
|
|
|
|
/**
|
|
* Sets the location of this entity.
|
|
*
|
|
* @param location The location to set
|
|
* @return True if location was set successfully, false otherwise
|
|
*/
|
|
boolean setLocation(ServerLocation location);
|
|
|
|
/**
|
|
* Gets the rotation.
|
|
*
|
|
* <p>The format of the rotation is represented by:</p>
|
|
*
|
|
* <p>{@code x -> pitch}, {@code y -> yaw}, {@code z -> roll}</p>
|
|
*
|
|
* @return The rotation
|
|
*/
|
|
Vector3d rotation();
|
|
|
|
/**
|
|
* Sets the rotation of this entity.
|
|
*
|
|
* <p>The format of the rotation is represented by:</p>
|
|
*
|
|
* <p>{@code x -> pitch}, {@code y -> yaw}, {@code z -> roll}</p>
|
|
*
|
|
* @param rotation The rotation to set the entity to
|
|
*/
|
|
void setRotation(Vector3d rotation);
|
|
|
|
/**
|
|
* Gets the unit vector representing the direction of this entity.
|
|
*
|
|
* @return The direction
|
|
*/
|
|
default Vector3d direction() {
|
|
final Vector3d rotation = this.rotation();
|
|
return Quaterniond.fromAxesAnglesDeg(rotation.getX(), -rotation.getY(), rotation.getZ()).getDirection();
|
|
}
|
|
|
|
/**
|
|
* Moves the entity to the specified location and sets the rotation.
|
|
*
|
|
* <p>The format of the rotation is represented by:</p>
|
|
*
|
|
* <p>{@code x -> pitch}, {@code y -> yaw}, {@code z -> roll}</p>
|
|
*
|
|
* @param location The location to set
|
|
* @param rotation The rotation to set
|
|
* @return True if location was set successfully, false otherwise
|
|
*/
|
|
boolean setLocationAndRotation(ServerLocation location, Vector3d rotation);
|
|
|
|
/**
|
|
* Moves the entity to the specified location and sets the rotation.
|
|
* {@link RelativePositions} listed inside the EnumSet are considered
|
|
* relative.
|
|
*
|
|
* <p>The format of the rotation is represented by:</p>
|
|
*
|
|
* <p>{@code x -> pitch}, {@code y -> yaw}, {@code z -> roll}</p>
|
|
*
|
|
* @param location The location to set
|
|
* @param rotation The rotation to set
|
|
* @param relativePositions The coordinates to set relatively
|
|
* @return True if location was set successfully, false otherwise
|
|
*/
|
|
boolean setLocationAndRotation(ServerLocation location, Vector3d rotation, EnumSet<RelativePositions> relativePositions);
|
|
|
|
/**
|
|
* Gets the scale.
|
|
*
|
|
* @return The entity scale
|
|
*/
|
|
Vector3d scale();
|
|
|
|
/**
|
|
* Sets the scale.
|
|
*
|
|
* @param scale The scale
|
|
*/
|
|
void setScale(Vector3d scale);
|
|
|
|
/**
|
|
* Gets the {@link Transform}.
|
|
*
|
|
* @return The transform
|
|
*/
|
|
Transform transform();
|
|
|
|
/**
|
|
* Sets the {@link Transform}.
|
|
*
|
|
* @param transform The transform to set
|
|
* @return True if the transform was set successfully, false if the transform couldn't be set
|
|
*/
|
|
boolean setTransform(Transform transform);
|
|
|
|
/**
|
|
* Sets the {@link ServerLocation} of this entity to the {@link ServerWorld}'s spawn
|
|
* point.
|
|
*
|
|
* @param world The world to transfer to
|
|
* @return Whether the transfer was successful, returns false if the action
|
|
* is cancelled or not possible (eg. because the entity has been
|
|
* removed)
|
|
*/
|
|
default boolean transferToWorld(final ServerWorld world) {
|
|
Objects.requireNonNull(world, "World cannot be null");
|
|
return this.transferToWorld(world, world.properties().spawnPosition().toDouble());
|
|
}
|
|
|
|
/**
|
|
* Sets the {@link ServerLocation} of this entity to a new position in a world.
|
|
*
|
|
* @param world The world to transfer to
|
|
* @param position The position in the target world
|
|
* @return Whether the transfer was successful, returns false if the action
|
|
* is cancelled or not possible (eg. because the entity has been
|
|
* removed)
|
|
*/
|
|
boolean transferToWorld(ServerWorld world, Vector3d position);
|
|
|
|
/**
|
|
* Gets the entity's bounding box, usually for collisions and interaction.
|
|
* The box has an offset matching the entity's positions. That is to say, it
|
|
* is absolutely positioned and not relative to the entity.
|
|
*
|
|
* @return The axis aligned bounding box
|
|
*/
|
|
Optional<AABB> boundingBox();
|
|
|
|
/**
|
|
* Returns whether this entity has been removed.
|
|
*
|
|
* @return True if this entity has been removed
|
|
*/
|
|
boolean isRemoved();
|
|
|
|
/**
|
|
* Returns whether this entity is still loaded in a world/chunk.
|
|
*
|
|
* @return True if this entity is still loaded
|
|
*/
|
|
boolean isLoaded();
|
|
|
|
/**
|
|
* Mark this entity for removal in the very near future, preferably
|
|
* within one game tick.
|
|
*/
|
|
void remove();
|
|
|
|
/**
|
|
* Damages this {@link Entity} with the given {@link DamageSource}.
|
|
*
|
|
* @param damage The damage to deal
|
|
* @param damageSource The cause of the damage
|
|
* @return True if damaging the entity was successful
|
|
*/
|
|
default boolean damage(final double damage, final Supplier<? extends DamageSource> damageSource) {
|
|
return this.damage(damage, damageSource.get());
|
|
}
|
|
|
|
/**
|
|
* Damages this {@link Entity} with the given {@link DamageSource}.
|
|
*
|
|
* @param damage The damage to deal
|
|
* @param damageSource The cause of the damage
|
|
* @return True if damaging the entity was successful
|
|
*/
|
|
boolean damage(double damage, DamageSource damageSource);
|
|
|
|
/**
|
|
* Gets the nearby entities within the desired distance.
|
|
*
|
|
* @see World#nearbyEntities(Vector3d, double)
|
|
* @param distance The distance
|
|
* @return The collection of nearby entities
|
|
*/
|
|
default Collection<? extends Entity> nearbyEntities(final double distance) {
|
|
if (distance <= 0) {
|
|
throw new IllegalArgumentException("Distance must be greater than 0!");
|
|
}
|
|
return this.world().nearbyEntities(this.location().position(), distance);
|
|
}
|
|
|
|
/**
|
|
* Gets the nearby entities that satisfy the desired predicate.
|
|
*
|
|
* @see World#entities(AABB, Predicate)
|
|
* @param distance The distance
|
|
* @param predicate The predicate to use
|
|
* @return The collection of entities
|
|
*/
|
|
default Collection<? extends Entity> nearbyEntities(final double distance, final Predicate<? super Entity> predicate) {
|
|
Objects.requireNonNull(predicate, "Predicate cannot be null");
|
|
return this.world().entities(this.boundingBox().get().expand(distance, distance, distance), predicate);
|
|
}
|
|
|
|
/**
|
|
* Returns whether this entity can see the provided {@link Entity}.
|
|
*
|
|
* @param entity The entity to check visibility for
|
|
* @return {@code true} if this entity can see the provided entity
|
|
*/
|
|
default boolean canSee(final Entity entity) {
|
|
Objects.requireNonNull(entity, "Entity cannot be null");
|
|
final Optional<Boolean> optional = entity.get(Keys.VANISH);
|
|
return !optional.isPresent() || !optional.get();
|
|
}
|
|
|
|
/**
|
|
* {@link Keys#DISPLAY_NAME}
|
|
*
|
|
* @return The display name of this entity
|
|
*/
|
|
default Value.Mutable<Component> displayName() {
|
|
return this.requireValue(Keys.DISPLAY_NAME).asMutable();
|
|
}
|
|
|
|
/**
|
|
* {@link Keys#FALL_DISTANCE}
|
|
*
|
|
* @return The fall distance
|
|
*/
|
|
default Value.Mutable<Double> fallDistance() {
|
|
return this.requireValue(Keys.FALL_DISTANCE).asMutable();
|
|
}
|
|
|
|
/**
|
|
* {@link Keys#PASSENGERS}
|
|
*
|
|
* @return The list of passengers that may be riding this entity
|
|
*/
|
|
default ListValue.Mutable<Entity> passengers() {
|
|
return this.requireValue(Keys.PASSENGERS).asMutable();
|
|
}
|
|
|
|
/**
|
|
* {@link Keys#VEHICLE}
|
|
*
|
|
* @return The vehicle this entity may be riding
|
|
*/
|
|
default Optional<Value.Mutable<Entity>> vehicle() {
|
|
return this.getValue(Keys.VEHICLE).map(Value::asMutable);
|
|
}
|
|
|
|
/**
|
|
* {@link Keys#BASE_VEHICLE}
|
|
*
|
|
* @return The "base vehicle" of the entity vehicle riding chain
|
|
*/
|
|
default Optional<Value.Mutable<Entity>> baseVehicle() {
|
|
return this.getValue(Keys.BASE_VEHICLE).map(Value::asMutable);
|
|
}
|
|
|
|
/**
|
|
* {@link Keys#ON_GROUND}
|
|
*
|
|
* @return Whether this entity is on the ground
|
|
*/
|
|
default Value.Mutable<Boolean> onGround() {
|
|
return this.requireValue(Keys.ON_GROUND).asMutable();
|
|
}
|
|
|
|
/**
|
|
* {@link Keys#VELOCITY}
|
|
*
|
|
* @return The velocity of this entity
|
|
*/
|
|
default Value.Mutable<Vector3d> velocity() {
|
|
return this.requireValue(Keys.VELOCITY).asMutable();
|
|
}
|
|
|
|
/**
|
|
* {@link Keys#IS_GRAVITY_AFFECTED}
|
|
*
|
|
* @return Whether this entity is affected by gravity
|
|
*/
|
|
default Value.Mutable<Boolean> gravityAffected() {
|
|
return this.requireValue(Keys.IS_GRAVITY_AFFECTED).asMutable();
|
|
}
|
|
|
|
/**
|
|
* {@link Keys#IS_SILENT}
|
|
*
|
|
* @return Whether this entity is silent
|
|
*/
|
|
default Value.Mutable<Boolean> silent() {
|
|
return this.requireValue(Keys.IS_SILENT).asMutable();
|
|
}
|
|
|
|
/**
|
|
* {@link Keys#CREATOR}
|
|
*
|
|
* @return The unique id of the creator of this entity
|
|
*/
|
|
default Optional<Value.Mutable<UUID>> creator() {
|
|
return this.getValue(Keys.CREATOR).map(Value::asMutable);
|
|
}
|
|
|
|
/**
|
|
* {@link Keys#NOTIFIER}
|
|
*
|
|
* @return The unique id of the notifier of this entity
|
|
*/
|
|
default Optional<Value.Mutable<UUID>> notifier() {
|
|
return this.getValue(Keys.NOTIFIER).map(Value::asMutable);
|
|
}
|
|
|
|
/**
|
|
* {@link Keys#FIRE_TICKS}
|
|
*
|
|
* @return The amount of time in ticks an Entity is will continue burn for.
|
|
*/
|
|
default Optional<Value.Mutable<Ticks>> fireTicks() {
|
|
return this.getValue(Keys.FIRE_TICKS).map(Value::asMutable);
|
|
}
|
|
|
|
/**
|
|
* {@link Keys#FIRE_DAMAGE_DELAY}
|
|
*
|
|
* @return The amount of time to delay in ticks before an Entity will be burned by fire.
|
|
*/
|
|
default Optional<Value.Mutable<Ticks>> fireImmuneTicks() {
|
|
return this.getValue(Keys.FIRE_DAMAGE_DELAY).map(Value::asMutable);
|
|
}
|
|
|
|
/**
|
|
* {@link Keys#TRANSIENT}
|
|
*
|
|
* @return The transient state
|
|
*/
|
|
default Optional<Value.Mutable<Boolean>> isTransient() {
|
|
return this.getValue(Keys.TRANSIENT).map(Value::asMutable);
|
|
}
|
|
|
|
@Override
|
|
HoverEvent<HoverEvent.ShowEntity> asHoverEvent(final UnaryOperator<HoverEvent.ShowEntity> op);
|
|
}
|