upstream #1
9 changed files with 139 additions and 0 deletions
|
@ -11,6 +11,7 @@ import lol.pyr.director.adventure.command.CommandHandler;
|
||||||
import lol.pyr.director.common.command.CommandExecutionException;
|
import lol.pyr.director.common.command.CommandExecutionException;
|
||||||
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
|
import lol.pyr.znpcsplus.entity.properties.attributes.AttributeProperty;
|
||||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcImpl;
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
|
@ -124,6 +125,15 @@ public class PropertySetCommand implements CommandHandler {
|
||||||
value = context.parse(type);
|
value = context.parse(type);
|
||||||
valueName = value == null ? "NONE" : ((Vector3i) value).toPrettyString();
|
valueName = value == null ? "NONE" : ((Vector3i) value).toPrettyString();
|
||||||
}
|
}
|
||||||
|
else if (property instanceof AttributeProperty) {
|
||||||
|
value = context.parse(type);
|
||||||
|
if ((double) value < ((AttributeProperty) property).getMinValue() || (double) value > ((AttributeProperty) property).getMaxValue()) {
|
||||||
|
double sanitizedValue = ((AttributeProperty) property).sanitizeValue((double) value);
|
||||||
|
context.send(Component.text("WARNING: Value " + value + " is out of range for property " + property.getName() + ", setting to " + sanitizedValue, NamedTextColor.YELLOW));
|
||||||
|
value = sanitizedValue;
|
||||||
|
}
|
||||||
|
valueName = String.valueOf(value);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
value = context.parse(type);
|
value = context.parse(type);
|
||||||
|
|
|
@ -2,6 +2,7 @@ package lol.pyr.znpcsplus.entity;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.PacketEvents;
|
import com.github.retrooper.packetevents.PacketEvents;
|
||||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||||
|
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
||||||
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
|
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
|
||||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||||
|
@ -15,6 +16,7 @@ import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry;
|
||||||
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
|
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
|
||||||
import lol.pyr.znpcsplus.config.ConfigManager;
|
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||||
import lol.pyr.znpcsplus.entity.properties.*;
|
import lol.pyr.znpcsplus.entity.properties.*;
|
||||||
|
import lol.pyr.znpcsplus.entity.properties.attributes.AttributeProperty;
|
||||||
import lol.pyr.znpcsplus.entity.properties.villager.VillagerLevelProperty;
|
import lol.pyr.znpcsplus.entity.properties.villager.VillagerLevelProperty;
|
||||||
import lol.pyr.znpcsplus.entity.properties.villager.VillagerProfessionProperty;
|
import lol.pyr.znpcsplus.entity.properties.villager.VillagerProfessionProperty;
|
||||||
import lol.pyr.znpcsplus.entity.properties.villager.VillagerTypeProperty;
|
import lol.pyr.znpcsplus.entity.properties.villager.VillagerTypeProperty;
|
||||||
|
@ -154,6 +156,16 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
|
||||||
linkProperties("glow", "fire", "invisible");
|
linkProperties("glow", "fire", "invisible");
|
||||||
register(new BooleanProperty("silent", 4, false, legacyBooleans));
|
register(new BooleanProperty("silent", 4, false, legacyBooleans));
|
||||||
|
|
||||||
|
// Attribute Max Health
|
||||||
|
register(new AttributeProperty(packetFactory, "attribute_max_health", Attributes.MAX_HEALTH));
|
||||||
|
|
||||||
|
// Health - LivingEntity
|
||||||
|
int healthIndex = 6;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) healthIndex = 9;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) healthIndex = 8;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) healthIndex = 7;
|
||||||
|
register(new HealthProperty(healthIndex));
|
||||||
|
|
||||||
final int tameableIndex;
|
final int tameableIndex;
|
||||||
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) tameableIndex = 17;
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) tameableIndex = 17;
|
||||||
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) tameableIndex = 16;
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) tameableIndex = 16;
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package lol.pyr.znpcsplus.entity.properties;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
||||||
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class HealthProperty extends EntityPropertyImpl<Float> {
|
||||||
|
private final int index;
|
||||||
|
|
||||||
|
public HealthProperty(int index) {
|
||||||
|
super("health", 20f, Float.class);
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
float health = entity.getProperty(this);
|
||||||
|
health = (float) Attributes.MAX_HEALTH.sanitizeValue(health);
|
||||||
|
properties.put(index, new EntityData(index, EntityDataTypes.FLOAT, health));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package lol.pyr.znpcsplus.entity.properties.attributes;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.attribute.Attribute;
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
|
||||||
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AttributeProperty extends EntityPropertyImpl<Double> {
|
||||||
|
private final PacketFactory packetFactory;
|
||||||
|
private final Attribute attribute;
|
||||||
|
|
||||||
|
public AttributeProperty(PacketFactory packetFactory, String name, Attribute attribute) {
|
||||||
|
super(name, attribute.getDefaultValue(), Double.class);
|
||||||
|
this.packetFactory = packetFactory;
|
||||||
|
this.attribute = attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMinValue() {
|
||||||
|
return attribute.getMinValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMaxValue() {
|
||||||
|
return attribute.getMaxValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double sanitizeValue(double value) {
|
||||||
|
return attribute.sanitizeValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EntityData> applyStandalone(Player player, PacketEntity packetEntity, boolean isSpawned) {
|
||||||
|
apply(player, packetEntity, isSpawned, Collections.emptyList());
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, List<WrapperPlayServerUpdateAttributes.Property> properties) {
|
||||||
|
Double value = entity.getProperty(this);
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
value = attribute.sanitizeValue(value);
|
||||||
|
if (isSpawned) {
|
||||||
|
packetFactory.sendAttribute(player, entity, new WrapperPlayServerUpdateAttributes.Property(attribute, value, Collections.emptyList()));
|
||||||
|
} else {
|
||||||
|
properties.add(new WrapperPlayServerUpdateAttributes.Property(attribute, value, Collections.emptyList()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Attribute getAttribute() {
|
||||||
|
return attribute;
|
||||||
|
}
|
||||||
|
}
|
|
@ -120,6 +120,9 @@ public class NpcTypeImpl implements NpcType {
|
||||||
"player_knockback_horizontal", "player_knockback_cooldown", "player_knockback_sound", "player_knockback_sound_name",
|
"player_knockback_horizontal", "player_knockback_cooldown", "player_knockback_sound", "player_knockback_sound_name",
|
||||||
"player_knockback_sound_volume", "player_knockback_sound_pitch");
|
"player_knockback_sound_volume", "player_knockback_sound_pitch");
|
||||||
if (!type.equals(EntityTypes.PLAYER)) addProperties("dinnerbone");
|
if (!type.equals(EntityTypes.PLAYER)) addProperties("dinnerbone");
|
||||||
|
if (EntityTypes.isTypeInstanceOf(type, EntityTypes.LIVINGENTITY)) {
|
||||||
|
addProperties("health", "attribute_max_health");
|
||||||
|
}
|
||||||
// TODO: make this look nicer after completing the rest of the properties
|
// TODO: make this look nicer after completing the rest of the properties
|
||||||
if (version.isNewerThanOrEquals(ServerVersion.V_1_9)) addProperties("glow");
|
if (version.isNewerThanOrEquals(ServerVersion.V_1_9)) addProperties("glow");
|
||||||
if (version.isNewerThanOrEquals(ServerVersion.V_1_14)) {
|
if (version.isNewerThanOrEquals(ServerVersion.V_1_14)) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package lol.pyr.znpcsplus.packets;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
import com.github.retrooper.packetevents.protocol.player.Equipment;
|
import com.github.retrooper.packetevents.protocol.player.Equipment;
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
import lol.pyr.znpcsplus.util.NamedColor;
|
import lol.pyr.znpcsplus.util.NamedColor;
|
||||||
|
@ -25,4 +26,6 @@ public interface PacketFactory {
|
||||||
void sendHeadRotation(Player player, PacketEntity entity, float yaw, float pitch);
|
void sendHeadRotation(Player player, PacketEntity entity, float yaw, float pitch);
|
||||||
void sendHandSwing(Player player, PacketEntity entity, boolean offHand);
|
void sendHandSwing(Player player, PacketEntity entity, boolean offHand);
|
||||||
void setPassengers(Player player, int vehicle, int... passengers);
|
void setPassengers(Player player, int vehicle, int... passengers);
|
||||||
|
void sendAllAttributes(Player player, PacketEntity entity, PropertyHolder properties);
|
||||||
|
void sendAttribute(Player player, PacketEntity entity, WrapperPlayServerUpdateAttributes.Property property);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package lol.pyr.znpcsplus.packets;
|
package lol.pyr.znpcsplus.packets;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.PacketEventsAPI;
|
import com.github.retrooper.packetevents.PacketEventsAPI;
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
import com.github.retrooper.packetevents.util.Vector3d;
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity;
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||||
|
@ -27,6 +28,7 @@ public class V1_17PacketFactory extends V1_8PacketFactory {
|
||||||
sendPacket(player, new WrapperPlayServerSpawnEntity(entity.getEntityId(), Optional.of(entity.getUuid()), entity.getType(),
|
sendPacket(player, new WrapperPlayServerSpawnEntity(entity.getEntityId(), Optional.of(entity.getUuid()), entity.getType(),
|
||||||
npcLocationToVector(location), location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.of(new Vector3d())));
|
npcLocationToVector(location), location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.of(new Vector3d())));
|
||||||
sendAllMetadata(player, entity, properties);
|
sendAllMetadata(player, entity, properties);
|
||||||
|
if (EntityTypes.isTypeInstanceOf(entity.getType(), EntityTypes.LIVINGENTITY)) sendAllAttributes(player, entity, properties);
|
||||||
createTeam(player, entity, properties.getProperty(propertyRegistry.getByName("glow", NamedColor.class)));
|
createTeam(player, entity, properties.getProperty(propertyRegistry.getByName("glow", NamedColor.class)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ public class V1_20_2PacketFactory extends V1_19_3PacketFactory {
|
||||||
npcLocationToVector(location), location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.of(new Vector3d())));
|
npcLocationToVector(location), location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.of(new Vector3d())));
|
||||||
sendPacket(player, new WrapperPlayServerEntityHeadLook(entity.getEntityId(), location.getYaw()));
|
sendPacket(player, new WrapperPlayServerEntityHeadLook(entity.getEntityId(), location.getYaw()));
|
||||||
sendAllMetadata(player, entity, properties);
|
sendAllMetadata(player, entity, properties);
|
||||||
|
sendAllAttributes(player, entity, properties);
|
||||||
scheduler.runLaterAsync(() -> removeTabPlayer(player, entity), configManager.getConfig().tabHideDelay());
|
scheduler.runLaterAsync(() -> removeTabPlayer(player, entity), configManager.getConfig().tabHideDelay());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import lol.pyr.znpcsplus.config.ConfigManager;
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
|
import lol.pyr.znpcsplus.entity.properties.attributes.AttributeProperty;
|
||||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||||
import lol.pyr.znpcsplus.skin.BaseSkinDescriptor;
|
import lol.pyr.znpcsplus.skin.BaseSkinDescriptor;
|
||||||
import lol.pyr.znpcsplus.util.NamedColor;
|
import lol.pyr.znpcsplus.util.NamedColor;
|
||||||
|
@ -55,6 +56,7 @@ public class V1_8PacketFactory implements PacketFactory {
|
||||||
entity.getUuid(), npcLocationToVector(location), location.getYaw(), location.getPitch(), Collections.emptyList()));
|
entity.getUuid(), npcLocationToVector(location), location.getYaw(), location.getPitch(), Collections.emptyList()));
|
||||||
sendPacket(player, new WrapperPlayServerEntityHeadLook(entity.getEntityId(), location.getYaw()));
|
sendPacket(player, new WrapperPlayServerEntityHeadLook(entity.getEntityId(), location.getYaw()));
|
||||||
sendAllMetadata(player, entity, properties);
|
sendAllMetadata(player, entity, properties);
|
||||||
|
sendAllAttributes(player, entity, properties);
|
||||||
scheduler.runLaterAsync(() -> removeTabPlayer(player, entity), configManager.getConfig().tabHideDelay());
|
scheduler.runLaterAsync(() -> removeTabPlayer(player, entity), configManager.getConfig().tabHideDelay());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -70,6 +72,7 @@ public class V1_8PacketFactory implements PacketFactory {
|
||||||
new WrapperPlayServerSpawnEntity(entity.getEntityId(), Optional.of(entity.getUuid()), entity.getType(), npcLocationToVector(location),
|
new WrapperPlayServerSpawnEntity(entity.getEntityId(), Optional.of(entity.getUuid()), entity.getType(), npcLocationToVector(location),
|
||||||
location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.empty()));
|
location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.empty()));
|
||||||
sendAllMetadata(player, entity, properties);
|
sendAllMetadata(player, entity, properties);
|
||||||
|
if (EntityTypes.isTypeInstanceOf(type, EntityTypes.LIVINGENTITY)) sendAllAttributes(player, entity, properties);
|
||||||
createTeam(player, entity, properties.getProperty(propertyRegistry.getByName("glow", NamedColor.class)));
|
createTeam(player, entity, properties.getProperty(propertyRegistry.getByName("glow", NamedColor.class)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,4 +190,19 @@ public class V1_8PacketFactory implements PacketFactory {
|
||||||
WrapperPlayServerEntityAnimation.EntityAnimationType.SWING_OFF_HAND :
|
WrapperPlayServerEntityAnimation.EntityAnimationType.SWING_OFF_HAND :
|
||||||
WrapperPlayServerEntityAnimation.EntityAnimationType.SWING_MAIN_ARM));
|
WrapperPlayServerEntityAnimation.EntityAnimationType.SWING_MAIN_ARM));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendAllAttributes(Player player, PacketEntity entity, PropertyHolder properties) {
|
||||||
|
List<WrapperPlayServerUpdateAttributes.Property> attributesList = new ArrayList<>();
|
||||||
|
properties.getAppliedProperties()
|
||||||
|
.stream()
|
||||||
|
.filter(property -> property instanceof AttributeProperty)
|
||||||
|
.forEach(property -> ((AttributeProperty) property).apply(player, entity, false, attributesList));
|
||||||
|
sendPacket(player, new WrapperPlayServerUpdateAttributes(entity.getEntityId(), attributesList));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendAttribute(Player player, PacketEntity entity, WrapperPlayServerUpdateAttributes.Property property) {
|
||||||
|
sendPacket(player, new WrapperPlayServerUpdateAttributes(entity.getEntityId(), Collections.singletonList(property)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue