This commit is contained in:
LOOHP
2021-04-06 21:14:05 +08:00
parent 05cfdb73a9
commit 6d14314bd9
126 changed files with 191394 additions and 0 deletions
@@ -0,0 +1,135 @@
package com.loohp.limbo.entity;
import java.util.UUID;
import com.loohp.limbo.Limbo;
import com.loohp.limbo.entity.DataWatcher.WatchableField;
import com.loohp.limbo.entity.DataWatcher.WatchableObjectType;
import com.loohp.limbo.location.Location;
import com.loohp.limbo.utils.Rotation3f;
import com.loohp.limbo.world.World;
public class ArmorStand extends LivingEntity {
@WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01)
protected boolean small = false;
@WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04)
protected boolean arms = false;
@WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x08)
protected boolean noBasePlate = false;
@WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x10)
protected boolean marker = false;
@WatchableField(MetadataIndex = 15, WatchableObjectType = WatchableObjectType.ROTATION)
protected Rotation3f headRotation = new Rotation3f(0.0, 0.0, 0.0);
@WatchableField(MetadataIndex = 16, WatchableObjectType = WatchableObjectType.ROTATION)
protected Rotation3f bodyRotation = new Rotation3f(0.0, 0.0, 0.0);
@WatchableField(MetadataIndex = 17, WatchableObjectType = WatchableObjectType.ROTATION)
protected Rotation3f leftArmRotation = new Rotation3f(-10.0, 0.0, -10.0);
@WatchableField(MetadataIndex = 18, WatchableObjectType = WatchableObjectType.ROTATION)
protected Rotation3f rightArmRotation = new Rotation3f(-15.0, 0.0, 10.0);
@WatchableField(MetadataIndex = 19, WatchableObjectType = WatchableObjectType.ROTATION)
protected Rotation3f leftLegRotation = new Rotation3f(-1.0, 0.0, -1.0);
@WatchableField(MetadataIndex = 20, WatchableObjectType = WatchableObjectType.ROTATION)
protected Rotation3f rightLegRotation = new Rotation3f(1.0, 0.0, 1.0);
public ArmorStand(int entityId, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) {
super(EntityType.ARMOR_STAND, entityId, uuid, world, x, y, z, yaw, pitch);
}
public ArmorStand(UUID uuid, World world, double x, double y, double z, float yaw, float pitch) {
this(Limbo.getInstance().getNextEntityId(), uuid, world, x, y, z, yaw, pitch);
}
public ArmorStand(World world, double x, double y, double z, float yaw, float pitch) {
this(Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), world, x, y, z, yaw, pitch);
}
public ArmorStand(UUID uuid, Location location) {
this(Limbo.getInstance().getNextEntityId(), uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
}
public ArmorStand(Location location) {
this(Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
}
public boolean isSmall() {
return small;
}
public void setSmall(boolean small) {
this.small = small;
}
public boolean showArms() {
return arms;
}
public void setArms(boolean arms) {
this.arms = arms;
}
public boolean hasNoBasePlate() {
return noBasePlate;
}
public void setNoBasePlate(boolean noBasePlate) {
this.noBasePlate = noBasePlate;
}
public boolean isMarker() {
return marker;
}
public void setMarker(boolean marker) {
this.marker = marker;
}
public Rotation3f getHeadRotation() {
return headRotation;
}
public void setHeadRotation(Rotation3f headRotation) {
this.headRotation = headRotation;
}
public Rotation3f getBodyRotation() {
return bodyRotation;
}
public void setBodyRotation(Rotation3f bodyRotation) {
this.bodyRotation = bodyRotation;
}
public Rotation3f getLeftArmRotation() {
return leftArmRotation;
}
public void setLeftArmRotation(Rotation3f leftArmRotation) {
this.leftArmRotation = leftArmRotation;
}
public Rotation3f getRightArmRotation() {
return rightArmRotation;
}
public void setRightArmRotation(Rotation3f rightArmRotation) {
this.rightArmRotation = rightArmRotation;
}
public Rotation3f getLeftLegRotation() {
return leftLegRotation;
}
public void setLeftLegRotation(Rotation3f leftLegRotation) {
this.leftLegRotation = leftLegRotation;
}
public Rotation3f getRightLegRotation() {
return rightLegRotation;
}
public void setRightLegRotation(Rotation3f rightLegRotation) {
this.rightLegRotation = rightLegRotation;
}
}
@@ -0,0 +1,178 @@
package com.loohp.limbo.entity;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class DataWatcher {
private Entity entity;
private Map<Field, WatchableObject> values;
public DataWatcher(Entity entity) {
this.entity = entity;
this.values = new HashMap<>();
Class<?> clazz = entity.getClass();
while (clazz != null) {
for (Field field : clazz.getDeclaredFields()) {
WatchableField a = field.getAnnotation(WatchableField.class);
if (a != null) {
field.setAccessible(true);
try {
values.put(field, new WatchableObject(field.get(entity), a.MetadataIndex(), a.WatchableObjectType(), a.IsOptional(), a.IsBitmask(), a.Bitmask()));
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
clazz = clazz.getSuperclass();
}
}
public Entity getEntity() {
return entity;
}
public boolean isValid() {
return entity.isValid();
}
public synchronized Map<Field, WatchableObject> update() throws IllegalArgumentException, IllegalAccessException {
if (!isValid()) {
return null;
}
Map<Field, WatchableObject> updated = new HashMap<>();
for (Entry<Field, WatchableObject> entry : values.entrySet()) {
Field field = entry.getKey();
WatchableObject watchableObj = entry.getValue();
field.setAccessible(true);
Object newValue = field.get(entity);
if ((newValue == null && watchableObj.getValue() != null) || (newValue != null && watchableObj.getValue() == null) || (newValue != null && watchableObj.getValue() != null && !newValue.equals(watchableObj.getValue()))) {
watchableObj.setValue(newValue);
updated.put(field, watchableObj);
}
}
return updated;
}
public Map<Field, WatchableObject> getWatchableObjects() {
return Collections.unmodifiableMap(values);
}
public static class WatchableObject {
private int index;
private WatchableObjectType type;
private boolean optional;
private boolean isBitmask;
private int bitmask;
private Object value;
public WatchableObject(Object value, int index, WatchableObjectType type, boolean optional, boolean isBitmask, int bitmask) {
this.index = index;
this.type = type;
this.optional = optional;
this.isBitmask = isBitmask;
this.bitmask = bitmask;
this.value = value;
}
public WatchableObject(Object value, int index, WatchableObjectType type, boolean isBitmask, int bitmask) {
this(value, index, type, false, isBitmask, bitmask);
}
public WatchableObject(Object value, int index, WatchableObjectType type, boolean optional) {
this(value, index, type, optional, false, 0x00);
}
public WatchableObject(Object value, int index, WatchableObjectType type) {
this(value, index, type, false, false, 0x00);
}
public Object getValue() {
return value;
}
public void setValue(Object newValue) {
this.value = newValue;
}
public int getIndex() {
return index;
}
public WatchableObjectType getType() {
return type;
}
public boolean isOptional() {
return optional;
}
public boolean isBitmask() {
return isBitmask;
}
public int getBitmask() {
return bitmask;
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public static @interface WatchableField {
int MetadataIndex();
WatchableObjectType WatchableObjectType();
boolean IsOptional() default false;
boolean IsBitmask() default false;
int Bitmask() default 0x00;
}
public static enum WatchableObjectType {
BYTE(0),
VARINT(1, 17),
FLOAT(2),
STRING(3),
CHAT(4, 5),
SLOT(6),
BOOLEAN(7),
ROTATION(8),
POSITION(9, 10),
DIRECTION(11),
UUID(-1, 12),
BLOCKID(-1, 13),
NBT(14),
PARTICLE(15),
VILLAGER_DATA(16),
POSE(18);
int typeId;
int optionalTypeId;
WatchableObjectType(int typeId, int optionalTypeId) {
this.typeId = typeId;
this.optionalTypeId = optionalTypeId;
}
WatchableObjectType(int typeId) {
this(typeId, -1);
}
public int getTypeId() {
return typeId;
}
public int getOptionalTypeId() {
return optionalTypeId;
}
}
}
@@ -0,0 +1,283 @@
package com.loohp.limbo.entity;
import java.util.UUID;
import com.loohp.limbo.Limbo;
import com.loohp.limbo.entity.DataWatcher.WatchableField;
import com.loohp.limbo.entity.DataWatcher.WatchableObjectType;
import com.loohp.limbo.location.Location;
import com.loohp.limbo.world.World;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
public abstract class Entity {
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01)
protected boolean onFire = false;
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x02)
protected boolean crouching = false;
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04)
protected boolean unused = false;
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x08)
protected boolean sprinting = false;
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x10)
protected boolean swimming = false;
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x20)
protected boolean invisible = false;
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x40)
protected boolean glowing = false;
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x80)
protected boolean elytraFlying = false;
@WatchableField(MetadataIndex = 1, WatchableObjectType = WatchableObjectType.VARINT)
protected int air = 300;
@WatchableField(MetadataIndex = 2, WatchableObjectType = WatchableObjectType.CHAT, IsOptional = true)
protected BaseComponent[] customName = null;
@WatchableField(MetadataIndex = 3, WatchableObjectType = WatchableObjectType.BOOLEAN)
protected boolean customNameVisible = false;
@WatchableField(MetadataIndex = 4, WatchableObjectType = WatchableObjectType.BOOLEAN)
protected boolean silent = false;
@WatchableField(MetadataIndex = 5, WatchableObjectType = WatchableObjectType.BOOLEAN)
protected boolean noGravity = false;
@WatchableField(MetadataIndex = 6, WatchableObjectType = WatchableObjectType.POSE)
protected Pose pose = Pose.STANDING;
protected final EntityType type;
protected int entityId;
protected UUID uuid;
protected World world;
protected double x;
protected double y;
protected double z;
protected float yaw;
protected float pitch;
public Entity(EntityType type, int entityId, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) {
this.type = type;
this.entityId = entityId;
this.uuid = uuid;
this.world = world;
this.x = x;
this.y = y;
this.z = z;
this.yaw = yaw;
this.pitch = pitch;
}
public Entity(EntityType type, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) {
this(type, Limbo.getInstance().getNextEntityId(), uuid, world, x, y, z, yaw, pitch);
}
public Entity(EntityType type, World world, double x, double y, double z, float yaw, float pitch) {
this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), world, x, y, z, yaw, pitch);
}
public Entity(EntityType type, UUID uuid, Location location) {
this(type, Limbo.getInstance().getNextEntityId(), uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
}
public Entity(EntityType type, Location location) {
this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
}
public EntityType getType() {
return type;
}
public Location getLocation() {
return new Location(world, x, y, z, yaw, pitch);
}
public void teleport(Location location) {
this.world = location.getWorld();
this.x = location.getX();
this.y = location.getY();
this.z = location.getZ();
this.yaw = location.getYaw();
this.pitch = location.getPitch();
}
public BaseComponent[] getCustomName() {
return customName;
}
public void setCustomName(String name) {
this.customName = name == null ? null : new BaseComponent[] {new TextComponent(name)};
}
public void setCustomName(BaseComponent component) {
this.customName = component == null ? null : new BaseComponent[] {component};
}
public void setCustomName(BaseComponent[] components) {
this.customName = components;
}
public boolean isOnFire() {
return onFire;
}
public void setOnFire(boolean onFire) {
this.onFire = onFire;
}
public boolean isCrouching() {
return crouching;
}
public void setCrouching(boolean crouching) {
this.crouching = crouching;
}
public boolean isSprinting() {
return sprinting;
}
public void setSprinting(boolean sprinting) {
this.sprinting = sprinting;
}
public boolean isSwimming() {
return swimming;
}
public void setSwimming(boolean swimming) {
this.swimming = swimming;
}
public boolean isInvisible() {
return invisible;
}
public void setInvisible(boolean invisible) {
this.invisible = invisible;
}
public boolean isGlowing() {
return glowing;
}
public void setGlowing(boolean glowing) {
this.glowing = glowing;
}
public boolean isElytraFlying() {
return elytraFlying;
}
public void setElytraFlying(boolean elytraFlying) {
this.elytraFlying = elytraFlying;
}
public int getAir() {
return air;
}
public void setAir(int air) {
this.air = air;
}
public boolean isCustomNameVisible() {
return customNameVisible;
}
public void setCustomNameVisible(boolean customNameVisible) {
this.customNameVisible = customNameVisible;
}
public boolean isSilent() {
return silent;
}
public void setSilent(boolean silent) {
this.silent = silent;
}
public boolean hasGravity() {
return !noGravity;
}
public void setGravity(boolean gravity) {
this.noGravity = !gravity;
}
public Pose getPose() {
return pose;
}
public void setPose(Pose pose) {
this.pose = pose;
}
public World getWorld() {
return world;
}
public void setWorld(World world) {
this.world = world;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public double getZ() {
return z;
}
public void setZ(double z) {
this.z = z;
}
public float getYaw() {
return yaw;
}
public void setYaw(float yaw) {
this.yaw = yaw;
}
public float getPitch() {
return pitch;
}
public void setPitch(float pitch) {
this.pitch = pitch;
}
public int getEntityId() {
return entityId;
}
public UUID getUniqueId() {
return uuid;
}
public boolean isValid() {
return world.getEntities().contains(this);
}
@SuppressWarnings("deprecation")
public void remove() {
Limbo.getInstance().getUnsafe().removeEntity(world, this);
}
@SuppressWarnings("deprecation")
public DataWatcher getDataWatcher() {
return Limbo.getInstance().getUnsafe().getDataWatcher(world, this);
}
}
@@ -0,0 +1,397 @@
package com.loohp.limbo.entity;
import java.util.HashMap;
import java.util.Map;
import com.loohp.limbo.location.Location;
import com.loohp.limbo.player.Player;
import com.loohp.limbo.utils.NamespacedKey;
import com.loohp.limbo.world.World;
public enum EntityType {
// These strings MUST match the strings in nms.EntityTypes and are case sensitive.
/**
* An item resting on the ground.
* <p>
* Spawn with {@link World#dropItem(Location, ItemStack)} or {@link
* World#dropItemNaturally(Location, ItemStack)}
*/
//DROPPED_ITEM("item", Item.class, 1, false),
/**
* An experience orb.
*/
//EXPERIENCE_ORB("experience_orb", ExperienceOrb.class, 2),
/**
* @see AreaEffectCloud
*/
//AREA_EFFECT_CLOUD("area_effect_cloud", AreaEffectCloud.class, 3),
/**
* @see ElderGuardian
*/
//ELDER_GUARDIAN("elder_guardian", ElderGuardian.class, 4),
/**
* @see WitherSkeleton
*/
//WITHER_SKELETON("wither_skeleton", WitherSkeleton.class, 5),
/**
* @see Stray
*/
//STRAY("stray", Stray.class, 6),
/**
* A flying chicken egg.
*/
//EGG("egg", Egg.class, 7),
/**
* A leash attached to a fencepost.
*/
//LEASH_HITCH("leash_knot", LeashHitch.class, 8),
/**
* A painting on a wall.
*/
//PAINTING("painting", Painting.class, 9),
/**
* An arrow projectile; may get stuck in the ground.
*/
//ARROW("arrow", Arrow.class, 10),
/**
* A flying snowball.
*/
//SNOWBALL("snowball", Snowball.class, 11),
/**
* A flying large fireball, as thrown by a Ghast for example.
*/
//FIREBALL("fireball", LargeFireball.class, 12),
/**
* A flying small fireball, such as thrown by a Blaze or player.
*/
//SMALL_FIREBALL("small_fireball", SmallFireball.class, 13),
/**
* A flying ender pearl.
*/
//ENDER_PEARL("ender_pearl", EnderPearl.class, 14),
/**
* An ender eye signal.
*/
//ENDER_SIGNAL("eye_of_ender", EnderSignal.class, 15),
/**
* A flying splash potion.
*/
//SPLASH_POTION("potion", ThrownPotion.class, 16, false),
/**
* A flying experience bottle.
*/
//THROWN_EXP_BOTTLE("experience_bottle", ThrownExpBottle.class, 17),
/**
* An item frame on a wall.
*/
//ITEM_FRAME("item_frame", ItemFrame.class, 18),
/**
* A flying wither skull projectile.
*/
//WITHER_SKULL("wither_skull", WitherSkull.class, 19),
/**
* Primed TNT that is about to explode.
*/
//PRIMED_TNT("tnt", TNTPrimed.class, 20),
/**
* A block that is going to or is about to fall.
*/
//FALLING_BLOCK("falling_block", FallingBlock.class, 21, false),
/**
* Internal representation of a Firework once it has been launched.
*/
//FIREWORK("firework_rocket", Firework.class, 22, false),
/**
* @see Husk
*/
//HUSK("husk", Husk.class, 23),
/**
* Like {@link #ARROW} but causes the {@link PotionEffectType#GLOWING} effect on all team members.
*/
//SPECTRAL_ARROW("spectral_arrow", SpectralArrow.class, 24),
/**
* Bullet fired by {@link #SHULKER}.
*/
//SHULKER_BULLET("shulker_bullet", ShulkerBullet.class, 25),
/**
* Like {@link #FIREBALL} but with added effects.
*/
//DRAGON_FIREBALL("dragon_fireball", DragonFireball.class, 26),
/**
* @see ZombieVillager
*/
//ZOMBIE_VILLAGER("zombie_villager", ZombieVillager.class, 27),
/**
* @see SkeletonHorse
*/
//SKELETON_HORSE("skeleton_horse", SkeletonHorse.class, 28),
/**
* @see ZombieHorse
*/
//ZOMBIE_HORSE("zombie_horse", ZombieHorse.class, 29),
/**
* Mechanical entity with an inventory for placing weapons / armor into.
*/
ARMOR_STAND("armor_stand", ArmorStand.class, 1),
/**
* @see Donkey
*/
//DONKEY("donkey", Donkey.class, 31),
/**
* @see Mule
*/
//MULE("mule", Mule.class, 32),
/**
* @see EvokerFangs
*/
//EVOKER_FANGS("evoker_fangs", EvokerFangs.class, 33),
/**
* @see Evoker
*/
//EVOKER("evoker", Evoker.class, 34),
/**
* @see Vex
*/
//VEX("vex", Vex.class, 35),
/**
* @see Vindicator
*/
//VINDICATOR("vindicator", Vindicator.class, 36),
/**
* @see Illusioner
*/
//ILLUSIONER("illusioner", Illusioner.class, 37),
/**
* @see CommandMinecart
*/
//MINECART_COMMAND("command_block_minecart", CommandMinecart.class, 40),
/**
* A placed boat.
*/
//BOAT("boat", Boat.class, 41),
/**
* @see RideableMinecart
*/
//MINECART("minecart", RideableMinecart.class, 42),
/**
* @see StorageMinecart
*/
//MINECART_CHEST("chest_minecart", StorageMinecart.class, 43),
/**
* @see PoweredMinecart
*/
//MINECART_FURNACE("furnace_minecart", PoweredMinecart.class, 44),
/**
* @see ExplosiveMinecart
*/
//MINECART_TNT("tnt_minecart", ExplosiveMinecart.class, 45),
/**
* @see HopperMinecart
*/
//MINECART_HOPPER("hopper_minecart", HopperMinecart.class, 46),
/**
* @see SpawnerMinecart
*/
//MINECART_MOB_SPAWNER("spawner_minecart", SpawnerMinecart.class, 47),
//CREEPER("creeper", Creeper.class, 50),
//SKELETON("skeleton", Skeleton.class, 51),
//SPIDER("spider", Spider.class, 52),
//GIANT("giant", Giant.class, 53),
//ZOMBIE("zombie", Zombie.class, 54),
//SLIME("slime", Slime.class, 55),
//GHAST("ghast", Ghast.class, 56),
//ZOMBIFIED_PIGLIN("zombified_piglin", PigZombie.class, 57),
//ENDERMAN("enderman", Enderman.class, 58),
//CAVE_SPIDER("cave_spider", CaveSpider.class, 59),
//SILVERFISH("silverfish", Silverfish.class, 60),
//BLAZE("blaze", Blaze.class, 61),
//MAGMA_CUBE("magma_cube", MagmaCube.class, 62),
//ENDER_DRAGON("ender_dragon", EnderDragon.class, 63),
//WITHER("wither", Wither.class, 64),
//BAT("bat", Bat.class, 65),
//WITCH("witch", Witch.class, 66),
//ENDERMITE("endermite", Endermite.class, 67),
//GUARDIAN("guardian", Guardian.class, 68),
//SHULKER("shulker", Shulker.class, 69),
//PIG("pig", Pig.class, 90),
//SHEEP("sheep", Sheep.class, 91),
//COW("cow", Cow.class, 92),
//CHICKEN("chicken", Chicken.class, 93),
//SQUID("squid", Squid.class, 94),
//WOLF("wolf", Wolf.class, 95),
//MUSHROOM_COW("mooshroom", MushroomCow.class, 96),
//SNOWMAN("snow_golem", Snowman.class, 97),
//OCELOT("ocelot", Ocelot.class, 98),
//IRON_GOLEM("iron_golem", IronGolem.class, 99),
//HORSE("horse", Horse.class, 100),
//RABBIT("rabbit", Rabbit.class, 101),
//POLAR_BEAR("polar_bear", PolarBear.class, 102),
//LLAMA("llama", Llama.class, 103),
//LLAMA_SPIT("llama_spit", LlamaSpit.class, 104),
//PARROT("parrot", Parrot.class, 105),
//VILLAGER("villager", Villager.class, 120),
//ENDER_CRYSTAL("end_crystal", EnderCrystal.class, 200),
//TURTLE("turtle", Turtle.class, -1),
//PHANTOM("phantom", Phantom.class, -1),
//TRIDENT("trident", Trident.class, -1),
//COD("cod", Cod.class, -1),
//SALMON("salmon", Salmon.class, -1),
//PUFFERFISH("pufferfish", PufferFish.class, -1),
//TROPICAL_FISH("tropical_fish", TropicalFish.class, -1),
//DROWNED("drowned", Drowned.class, -1),
//DOLPHIN("dolphin", Dolphin.class, -1),
//CAT("cat", Cat.class, -1),
//PANDA("panda", Panda.class, -1),
//PILLAGER("pillager", Pillager.class, -1),
//RAVAGER("ravager", Ravager.class, -1),
//TRADER_LLAMA("trader_llama", TraderLlama.class, -1),
//WANDERING_TRADER("wandering_trader", WanderingTrader.class, -1),
//FOX("fox", Fox.class, -1),
//BEE("bee", Bee.class, -1),
//HOGLIN("hoglin", Hoglin.class, -1),
//PIGLIN("piglin", Piglin.class, -1),
//STRIDER("strider", Strider.class, -1),
//ZOGLIN("zoglin", Zoglin.class, -1),
//PIGLIN_BRUTE("piglin_brute", PiglinBrute.class, -1),
/**
* A fishing line and bobber.
*/
//FISHING_HOOK("fishing_bobber", FishHook.class, -1, false),
/**
* A bolt of lightning.
* <p>
* Spawn with {@link World#strikeLightning(Location)}.
*/
//LIGHTNING("lightning_bolt", LightningStrike.class, -1, false),
PLAYER("player", Player.class, 106, false),
/**
* An unknown entity without an Entity Class
*/
UNKNOWN(null, null, -1, false);
private final String name;
private final Class<? extends Entity> clazz;
private final short typeId;
private final boolean independent;
private final boolean living;
private final NamespacedKey key;
private static final Map<String, EntityType> NAME_MAP = new HashMap<>();
private static final Map<Short, EntityType> ID_MAP = new HashMap<>();
static {
for (EntityType type : values()) {
if (type.name != null) {
NAME_MAP.put(type.name.toLowerCase(java.util.Locale.ENGLISH), type);
}
if (type.typeId > 0) {
ID_MAP.put(type.typeId, type);
}
}
// Add legacy names
/*
NAME_MAP.put("xp_orb", EXPERIENCE_ORB);
NAME_MAP.put("eye_of_ender_signal", ENDER_SIGNAL);
NAME_MAP.put("xp_bottle", THROWN_EXP_BOTTLE);
NAME_MAP.put("fireworks_rocket", FIREWORK);
NAME_MAP.put("evocation_fangs", EVOKER_FANGS);
NAME_MAP.put("evocation_illager", EVOKER);
NAME_MAP.put("vindication_illager", VINDICATOR);
NAME_MAP.put("illusion_illager", ILLUSIONER);
NAME_MAP.put("commandblock_minecart", MINECART_COMMAND);
NAME_MAP.put("snowman", SNOWMAN);
NAME_MAP.put("villager_golem", IRON_GOLEM);
NAME_MAP.put("ender_crystal", ENDER_CRYSTAL);
NAME_MAP.put("zombie_pigman", ZOMBIFIED_PIGLIN);
*/
}
private EntityType(String name, Class<? extends Entity> clazz, int typeId) {
this(name, clazz, typeId, true);
}
private EntityType(String name, Class<? extends Entity> clazz, int typeId, boolean independent) {
this.name = name;
this.clazz = clazz;
this.typeId = (short) typeId;
this.independent = independent;
this.living = clazz != null && LivingEntity.class.isAssignableFrom(clazz);
this.key = (name == null) ? null : NamespacedKey.minecraft(name);
}
/**
* Gets the entity type name.
*
* @return the entity type's name
* @deprecated Magic value
*/
@Deprecated
public String getName() {
return name;
}
public NamespacedKey getKey() {
return key;
}
public Class<? extends Entity> getEntityClass() {
return clazz;
}
/**
* Gets the entity network type id.
*
* @return the network type id
*/
public short getTypeId() {
return typeId;
}
/**
* Gets an entity type from its name.
*
* @param name the entity type's name
* @return the matching entity type or null
* @deprecated Magic value
*/
@Deprecated
public static EntityType fromName(String name) {
if (name == null) {
return null;
}
return NAME_MAP.get(name.toLowerCase(java.util.Locale.ENGLISH));
}
/**
* Gets an entity from its id.
*
* @param id the raw type id
* @return the matching entity type or null
* @deprecated Magic value
*/
@Deprecated
public static EntityType fromId(int id) {
if (id > Short.MAX_VALUE) {
return null;
}
return ID_MAP.get((short) id);
}
/**
* Some entities cannot be spawned using {@link
* World#spawnEntity(Location, EntityType)} or {@link
* World#spawn(Location, Class)}, usually because they require additional
* information in order to spawn.
*
* @return False if the entity type cannot be spawned
*/
public boolean isSpawnable() {
return independent;
}
public boolean isAlive() {
return living;
}
}
@@ -0,0 +1,132 @@
package com.loohp.limbo.entity;
import java.util.UUID;
import com.loohp.limbo.Limbo;
import com.loohp.limbo.entity.DataWatcher.WatchableField;
import com.loohp.limbo.entity.DataWatcher.WatchableObjectType;
import com.loohp.limbo.inventory.EquipmentSlot;
import com.loohp.limbo.location.Location;
import com.loohp.limbo.world.BlockPosition;
import com.loohp.limbo.world.World;
public abstract class LivingEntity extends Entity {
@WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01)
protected boolean handActive = false;
@WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x02)
protected boolean activeHand = false; //false = main hand, true = off hand
@WatchableField(MetadataIndex = 7, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x04)
protected boolean inRiptideSpinAttack = false;
@WatchableField(MetadataIndex = 8, WatchableObjectType = WatchableObjectType.FLOAT)
protected float health = 1.0F;
@WatchableField(MetadataIndex = 9, WatchableObjectType = WatchableObjectType.VARINT)
protected int potionEffectColor = 0;
@WatchableField(MetadataIndex = 10, WatchableObjectType = WatchableObjectType.BOOLEAN)
protected boolean potionEffectAmbient = false;
@WatchableField(MetadataIndex = 11, WatchableObjectType = WatchableObjectType.VARINT)
protected int arrowsInEntity = 0;
@WatchableField(MetadataIndex = 12, WatchableObjectType = WatchableObjectType.VARINT)
protected int absorption = 0;
@WatchableField(MetadataIndex = 13, WatchableObjectType = WatchableObjectType.POSITION, IsOptional = true)
protected BlockPosition sleepingLocation = null;
public LivingEntity(EntityType type, int entityId, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) {
super(type, entityId, uuid, world, x, y, z, yaw, pitch);
}
public LivingEntity(EntityType type, UUID uuid, World world, double x, double y, double z, float yaw, float pitch) {
this(type, Limbo.getInstance().getNextEntityId(), uuid, world, x, y, z, yaw, pitch);
}
public LivingEntity(EntityType type, World world, double x, double y, double z, float yaw, float pitch) {
this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), world, x, y, z, yaw, pitch);
}
public LivingEntity(EntityType type, UUID uuid, Location location) {
this(type, Limbo.getInstance().getNextEntityId(), uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
}
public LivingEntity(EntityType type, Location location) {
this(type, Limbo.getInstance().getNextEntityId(), UUID.randomUUID(), location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
}
public boolean isHandActive() {
return handActive;
}
public void setHandActive(boolean handActive) {
this.handActive = handActive;
}
public EquipmentSlot getActiveHand() {
return activeHand ? EquipmentSlot.OFFHAND : EquipmentSlot.MAINHAND;
}
public void setActiveHand(EquipmentSlot activeHand) {
if (activeHand.equals(EquipmentSlot.MAINHAND)) {
this.activeHand = false;
} else if (activeHand.equals(EquipmentSlot.OFFHAND)) {
this.activeHand = true;
} else {
throw new IllegalArgumentException("Invalid EquipmentSlot " + activeHand.toString());
}
}
public boolean isInRiptideSpinAttack() {
return inRiptideSpinAttack;
}
public void setInRiptideSpinAttack(boolean inRiptideSpinAttack) {
this.inRiptideSpinAttack = inRiptideSpinAttack;
}
public float getHealth() {
return health;
}
public void setHealth(float health) {
this.health = health;
}
public int getPotionEffectColor() {
return potionEffectColor;
}
public void setPotionEffectColor(int potionEffectColor) {
this.potionEffectColor = potionEffectColor;
}
public boolean isPotionEffectAmbient() {
return potionEffectAmbient;
}
public void setPotionEffectAmbient(boolean potionEffectAmbient) {
this.potionEffectAmbient = potionEffectAmbient;
}
public int getArrowsInEntity() {
return arrowsInEntity;
}
public void setArrowsInEntity(int arrowsInEntity) {
this.arrowsInEntity = arrowsInEntity;
}
public int getAbsorption() {
return absorption;
}
public void setAbsorption(int absorption) {
this.absorption = absorption;
}
public BlockPosition getSleepingLocation() {
return sleepingLocation;
}
public void setSleepingLocation(BlockPosition sleepingLocation) {
this.sleepingLocation = sleepingLocation;
}
}
@@ -0,0 +1,34 @@
package com.loohp.limbo.entity;
public enum Pose {
STANDING(0),
FALL_FLYING(1),
SLEEPING(2),
SWIMMING(3),
SPIN_ATTACK(4),
SNEAKING(5),
DYING(6);
private static final Pose[] VALUES = values();
private int id;
Pose(int id) {
this.id = id;
}
public int getId() {
return id;
}
public static Pose fromId(int id) {
for (Pose pose : VALUES) {
if (id == pose.id) {
return pose;
}
}
return null;
}
}