added all (i guess)) horse properties

This commit is contained in:
D3v1s0m 2023-08-23 02:57:18 +05:30
parent 467eac5972
commit b79b41b26d
No known key found for this signature in database
GPG Key ID: FA1F770C7B1D40C1
12 changed files with 223 additions and 9 deletions

@ -0,0 +1,8 @@
package lol.pyr.znpcsplus.util;
public enum HorseArmor {
NONE,
IRON,
GOLD,
DIAMOND
}

@ -0,0 +1,11 @@
package lol.pyr.znpcsplus.util;
public enum HorseColor {
WHITE,
CREAMY,
CHESTNUT,
BROWN,
BLACK,
GRAY,
DARK_BROWN
}

@ -0,0 +1,9 @@
package lol.pyr.znpcsplus.util;
public enum HorseStyle {
NONE,
WHITE,
WHITEFIELD,
WHITE_DOTS,
BLACK_DOTS
}

@ -0,0 +1,9 @@
package lol.pyr.znpcsplus.util;
public enum HorseType {
HORSE,
DONKEY,
MULE,
ZOMBIE,
SKELETON
}

@ -253,6 +253,7 @@ public class ZNpcsPlus extends JavaPlugin {
manager.registerParser(Color.class, new ColorParser(incorrectUsageMessage));
manager.registerParser(Vector3f.class, new Vector3fParser(incorrectUsageMessage));
// TODO: Need to find a better way to do this
registerEnumParser(manager, NpcPose.class, incorrectUsageMessage);
registerEnumParser(manager, DyeColor.class, incorrectUsageMessage);
registerEnumParser(manager, CatVariant.class, incorrectUsageMessage);
@ -265,6 +266,10 @@ public class ZNpcsPlus extends JavaPlugin {
registerEnumParser(manager, VillagerProfession.class, incorrectUsageMessage);
registerEnumParser(manager, VillagerLevel.class, incorrectUsageMessage);
registerEnumParser(manager, AxolotlVariant.class, incorrectUsageMessage);
registerEnumParser(manager, HorseType.class, incorrectUsageMessage);
registerEnumParser(manager, HorseStyle.class, incorrectUsageMessage);
registerEnumParser(manager, HorseColor.class, incorrectUsageMessage);
registerEnumParser(manager, HorseArmor.class, incorrectUsageMessage);
manager.registerCommand("npc", new MultiCommand(loadHelpMessage("root"))
.addSubcommand("create", new CreateCommand(npcRegistry, typeRegistry))

@ -59,6 +59,11 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
registerEnumSerializer(VillagerProfession.class);
registerEnumSerializer(VillagerLevel.class);
registerEnumSerializer(AxolotlVariant.class);
registerEnumSerializer(HorseType.class);
registerEnumSerializer(HorseColor.class);
registerEnumSerializer(HorseStyle.class);
registerEnumSerializer(HorseArmor.class);
/*
registerType("using_item", false); // TODO: fix it for 1.8 and add new property to use offhand item and riptide animation
@ -97,11 +102,6 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
// Sniffer
registerType("sniffer_state", null); // TODO: Nothing on wiki.vg, look in mc source
// Horse
registerType("horse_style", 0); // TODO: Figure this out
registerType("horse_chest", false); // TODO
registerType("horse_saddle", false); // TODO
// LLama
registerType("carpet_color", DyeColor.class); // TODO
registerType("llama_variant", 0); // TODO
@ -294,6 +294,56 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
register(new EncodedIntegerProperty<>("creeper_state", CreeperState.IDLE, creeperIndex++, CreeperState::getState));
register(new BooleanProperty("creeper_charged", creeperIndex, false, legacyBooleans));
// Abstract Horse
int horseIndex;
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) horseIndex = 17;
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) horseIndex = 16;
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) horseIndex = 15;
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) horseIndex = 13;
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) horseIndex = 12;
else horseIndex = 16;
int horseEating = ver.isNewerThanOrEquals(ServerVersion.V_1_12) ? 0x10 : 0x20;
boolean v1_8 = ver.isOlderThan(ServerVersion.V_1_9);
register(new BitsetProperty("is_tame", horseIndex, 0x02, false, v1_8));
register(new BitsetProperty("is_saddled", horseIndex, 0x04, false, v1_8));
register(new BitsetProperty("is_eating", horseIndex, horseEating, false, v1_8));
register(new BitsetProperty("is_rearing", horseIndex, horseEating << 1, false, v1_8));
register(new BitsetProperty("has_mouth_open", horseIndex, horseEating << 2, false, v1_8));
// Horse
if (ver.isNewerThanOrEquals(ServerVersion.V_1_8) && ver.isOlderThan(ServerVersion.V_1_9)) {
register(new EncodedByteProperty<>("horse_type", HorseType.HORSE, 19, obj -> (byte) obj.ordinal()));
} else if (ver.isOlderThan(ServerVersion.V_1_11)) {
int horseTypeIndex = 14;
if (ver.isOlderThan(ServerVersion.V_1_10)) horseTypeIndex = 13;
register(new EncodedIntegerProperty<>("horse_type", HorseType.HORSE, horseTypeIndex, Enum::ordinal));
}
int horseVariantIndex;
if (ver.isNewerThanOrEquals(ServerVersion.V_1_18)) horseVariantIndex = 18;
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) horseVariantIndex = 19;
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) horseVariantIndex = 18;
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) horseVariantIndex = 17;
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) horseVariantIndex = 15;
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) horseVariantIndex = 14;
else horseVariantIndex = 20;
register(new HorseStyleProperty(horseVariantIndex));
register(new HorseColorProperty(horseVariantIndex));
linkProperties("horse_style", "horse_color");
// Use chesteplate property for 1.14 and above
if (ver.isOlderThan(ServerVersion.V_1_14)) {
register(new EncodedIntegerProperty<>("horse_armor", HorseArmor.NONE, horseVariantIndex + 2, Enum::ordinal));
}
// Chested Horse
if (ver.isOlderThan(ServerVersion.V_1_11)) {
register(new BitsetProperty("has_chest", horseIndex, 0x08, false, v1_8));
linkProperties("is_saddled", "has_chest", "is_eating", "is_rearing", "has_mouth_open");
} else {
register(new BooleanProperty("has_chest", horseVariantIndex, false, legacyBooleans));
linkProperties("is_saddled", "is_eating", "is_rearing", "has_mouth_open");
}
if (!ver.isNewerThanOrEquals(ServerVersion.V_1_14)) return;
// Pose
register(new NpcPoseProperty());

@ -12,6 +12,12 @@ public class BitsetProperty extends EntityPropertyImpl<Boolean> {
private final int index;
private final int bitmask;
private final boolean inverted;
private boolean integer = false;
public BitsetProperty(String name, int index, int bitmask, boolean inverted, boolean integer) {
this(name, index, bitmask, inverted);
this.integer = integer;
}
public BitsetProperty(String name, int index, int bitmask, boolean inverted) {
super(name, inverted, Boolean.class);
@ -27,9 +33,11 @@ public class BitsetProperty extends EntityPropertyImpl<Boolean> {
@Override
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
EntityData oldData = properties.get(index);
byte oldValue = oldData == null ? 0 : (byte) oldData.getValue();
boolean enabled = entity.getProperty(this);
if (inverted) enabled = !enabled;
properties.put(index, newEntityData(index, EntityDataTypes.BYTE, (byte) (oldValue | (enabled ? bitmask : 0))));
properties.put(index,
integer ? newEntityData(index, EntityDataTypes.INT, (oldData == null ? 0 : (int) oldData.getValue()) | (enabled ? bitmask : 0)) :
newEntityData(index, EntityDataTypes.BYTE, (byte) ((oldData == null ? 0 : (byte) oldData.getValue()) | (enabled ? bitmask : 0))));
}
}

@ -0,0 +1,48 @@
package lol.pyr.znpcsplus.entity.properties;
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataType;
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 EncodedByteProperty<T> extends EntityPropertyImpl<T> {
private final EntityDataType<Byte> type;
private final ByteDecoder<T> decoder;
private final int index;
protected EncodedByteProperty(String name, T defaultValue, Class<T> clazz, int index, ByteDecoder<T> decoder, EntityDataType<Byte> type) {
super(name, defaultValue, clazz);
this.decoder = decoder;
this.index = index;
this.type = type;
}
@SuppressWarnings("unchecked")
public EncodedByteProperty(String name, T defaultValue, int index, ByteDecoder<T> decoder) {
this(name, defaultValue, (Class<T>) defaultValue.getClass(), index, decoder, EntityDataTypes.BYTE);
}
@SuppressWarnings("unchecked")
public EncodedByteProperty(String name, T defaultValue, int index, ByteDecoder<T> decoder, EntityDataType<Byte> type) {
this(name, defaultValue, (Class<T>) defaultValue.getClass(), index, decoder, type);
}
public EncodedByteProperty(String name, Class<T> clazz, int index, ByteDecoder<T> decoder) {
this(name, null, clazz, index, decoder, EntityDataTypes.BYTE);
}
@Override
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
T value = entity.getProperty(this);
if (value == null) return;
properties.put(index, newEntityData(index, type, decoder.decode(value)));
}
public interface ByteDecoder<T> {
byte decode(T obj);
}
}

@ -0,0 +1,26 @@
package lol.pyr.znpcsplus.entity.properties;
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 lol.pyr.znpcsplus.util.HorseColor;
import org.bukkit.entity.Player;
import java.util.Map;
public class HorseColorProperty extends EntityPropertyImpl<HorseColor> {
private final int index;
public HorseColorProperty(int index) {
super("horse_color", HorseColor.WHITE, HorseColor.class);
this.index = index;
}
@Override
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
EntityData oldData = properties.get(index);
HorseColor value = entity.getProperty(this);
properties.put(index, newEntityData(index, EntityDataTypes.INT, value.ordinal() | (oldData == null ? 0 : ((int) oldData.getValue() & 0xFF00))));
}
}

@ -0,0 +1,26 @@
package lol.pyr.znpcsplus.entity.properties;
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 lol.pyr.znpcsplus.util.HorseStyle;
import org.bukkit.entity.Player;
import java.util.Map;
public class HorseStyleProperty extends EntityPropertyImpl<HorseStyle> {
private final int index;
public HorseStyleProperty(int index) {
super("horse_style", HorseStyle.NONE, HorseStyle.class);
this.index = index;
}
@Override
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
EntityData oldData = properties.get(index);
HorseStyle value = entity.getProperty(this);
properties.put(index, newEntityData(index, EntityDataTypes.INT, (oldData == null ? 0 : ((int) oldData.getValue() & 0x00FF)) | (value.ordinal() << 8)));
}
}

@ -91,11 +91,24 @@ public class NpcTypeImpl implements NpcType {
addProperties("fire", "invisible", "silent", "look",
"using_item", "potion_color", "potion_ambient", "dinnerbone");
if (version.isNewerThanOrEquals(ServerVersion.V_1_9)) addProperties("glow");
if (version.isNewerThanOrEquals(ServerVersion.V_1_14)) addProperties("pose");
if (version.isNewerThanOrEquals(ServerVersion.V_1_14)) {
addProperties("pose");
if (EntityTypes.isTypeInstanceOf(type, EntityTypes.HORSE)) {
addProperties("chestplate");
}
}
if (version.isNewerThanOrEquals(ServerVersion.V_1_17)) addProperties("shaking");
if (EntityTypes.isTypeInstanceOf(type, EntityTypes.ABSTRACT_AGEABLE)) {
addProperties("baby");
}
if (EntityTypes.isTypeInstanceOf(type, EntityTypes.ABSTRACT_HORSE)) {
addProperties("is_saddled", "is_eating", "is_rearing", "has_mouth_open");
}
if (EntityTypes.isTypeInstanceOf(type, EntityTypes.CHESTED_HORSE)) {
addProperties("has_chest");
} else if (version.isOlderThan(ServerVersion.V_1_11) && type.equals(EntityTypes.HORSE)) {
addProperties("has_chest");
}
return new NpcTypeImpl(name, type, hologramOffset, new HashSet<>(allowedProperties));
}
}

@ -88,7 +88,8 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
.setHologramOffset(-1.125));
register(builder(p, "horse", EntityTypes.HORSE)
.setHologramOffset(-0.375));
.setHologramOffset(-0.375)
.addProperties("horse_type", "horse_style", "horse_color", "horse_armor"));
register(builder(p, "iron_golem", EntityTypes.IRON_GOLEM)
.setHologramOffset(0.725));