Skip to content

Commit

Permalink
item.armor_pose and entity.armor_pose rework
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Oct 24, 2021
1 parent c91ccb1 commit 36f3ed3
Show file tree
Hide file tree
Showing 4 changed files with 272 additions and 53 deletions.
Expand Up @@ -133,6 +133,7 @@ public static void registerMainProperties() {
PropertyParser.registerProperty(InventoryUniquifier.class, InventoryTag.class);

// register core ItemTag properties
PropertyParser.registerProperty(ItemArmorPose.class, ItemTag.class);
PropertyParser.registerProperty(ItemAttributeModifiers.class, ItemTag.class);
PropertyParser.registerProperty(ItemAttributeNBT.class, ItemTag.class);
PropertyParser.registerProperty(ItemBaseColor.class, ItemTag.class);
Expand Down
Expand Up @@ -5,14 +5,18 @@
import com.denizenscript.denizencore.objects.Mechanism;
import com.denizenscript.denizencore.objects.core.ListTag;
import com.denizenscript.denizencore.objects.ObjectTag;
import com.denizenscript.denizencore.objects.core.MapTag;
import com.denizenscript.denizencore.objects.properties.Property;
import com.denizenscript.denizencore.tags.Attribute;
import com.denizenscript.denizencore.objects.properties.PropertyParser;
import com.denizenscript.denizencore.utilities.CoreUtilities;
import com.denizenscript.denizencore.utilities.Deprecations;
import com.denizenscript.denizencore.utilities.text.StringHolder;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EntityType;
import org.bukkit.util.EulerAngle;

import java.util.Iterator;
import java.util.Map;

public class EntityArmorPose implements Property {

Expand All @@ -30,10 +34,6 @@ public static EntityArmorPose getFrom(ObjectTag entity) {
}
}

public static final String[] handledTags = new String[] {
"armor_pose_list", "armor_pose"
};

public static final String[] handledMechs = new String[] {
"armor_pose"
};
Expand All @@ -46,7 +46,7 @@ private EntityArmorPose(EntityTag ent) {

@Override
public String getPropertyString() {
return getPoseList().identify();
return getPoseMap().identify();
}

@Override
Expand All @@ -64,52 +64,51 @@ private ListTag getPoseList() {
return list;
}

@Override
public ObjectTag getObjectAttribute(Attribute attribute) {

if (attribute == null) {
return null;
public MapTag getPoseMap() {
ArmorStand armorStand = (ArmorStand) entity.getBukkitEntity();
MapTag map = new MapTag();
for (PosePart posePart : PosePart.values()) {
map.putObject(CoreUtilities.toLowerCase(posePart.name()), fromEulerAngle(posePart.getAngle(armorStand)));
}
return map;
}

// <--[tag]
// @attribute <EntityTag.armor_pose_list>
// @returns ListTag
// @mechanism EntityTag.armor_pose
// @group attributes
// @description
// Returns a list of all poses and angles for the armor stand in the
// format: PART|ANGLE|...
// For example, head|4.5,3,4.5|body|5.4,3.2,1
// Angles are in radians!
// -->
if (attribute.startsWith("armor_pose_list")) {
return getPoseList().getObjectAttribute(attribute.fulfill(1));
}
public static void registerTags() {

// <--[tag]
// @attribute <EntityTag.armor_pose[<part>]>
// @returns LocationTag
// @attribute <EntityTag.armor_pose_map>
// @returns MapTag
// @mechanism EntityTag.armor_pose
// @group attributes
// @description
// Returns the current angle pose for the specified part.
// Valid parts: HEAD, BODY, LEFT_ARM, RIGHT_ARM, LEFT_LEG, RIGHT_LEG
// Returns a map of all poses and angles for the armor stand.
// For example, head=4.5,3,4.5;body=5.4,3.2,1
// Angles are in radians!
// -->
else if (attribute.startsWith("armor_pose") && attribute.hasContext(1)) {
PropertyParser.<EntityArmorPose, MapTag>registerTag(MapTag.class, "armor_pose_map", (attribute, entity) -> {
return entity.getPoseMap();
});

PropertyParser.<EntityArmorPose, ListTag>registerTag(ListTag.class, "armor_pose_list", (attribute, entity) -> {
Deprecations.entityArmorPose.warn(attribute.context);
return entity.getPoseList();
});

PropertyParser.<EntityArmorPose, LocationTag>registerTag(LocationTag.class, "armor_pose", (attribute, entity) -> {
Deprecations.entityArmorPose.warn(attribute.context);
if (!attribute.hasContext(1)) {
return null;
}
String name = attribute.getContext(1);
PosePart posePart = PosePart.fromName(name);
if (posePart == null) {
attribute.echoError("Invalid pose part specified: " + name);
return null;
}
else {
return fromEulerAngle(posePart.getAngle((ArmorStand) entity.getBukkitEntity()))
.getObjectAttribute(attribute.fulfill(1));
return fromEulerAngle(posePart.getAngle((ArmorStand) entity.entity.getBukkitEntity()));
}
}

return null;
});
}

@Override
Expand All @@ -118,31 +117,43 @@ public void adjust(Mechanism mechanism) {
// <--[mechanism]
// @object EntityTag
// @name armor_pose
// @input ListTag
// @input MapTag
// @description
// Sets the angle for various parts of the armor stand in the
// format: PART|ANGLE|...
// For example, head|4.5,3,4.5|body|5.4,3.2,1
// Sets the angle for various parts of the armor stand.
// For example, head=4.5,3,4.5;body=5.4,3.2,1
// Valid parts: HEAD, BODY, LEFT_ARM, RIGHT_ARM, LEFT_LEG, RIGHT_LEG
// Angles are in radians!
// Here's a website to help you figure out the correct values: <@link url https://bgielinor.github.io/Minecraft-ArmorStand/>.
// @tags
// <EntityTag.armor_pose_list>
// <EntityTag.armor_pose[<part>]>
// <EntityTag.armor_pose_map>
// -->
if (mechanism.matches("armor_pose")) {
ArmorStand armorStand = (ArmorStand) entity.getBukkitEntity();
ListTag list = mechanism.valueAsType(ListTag.class);
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String name = iterator.next();
String angle = iterator.next();
PosePart posePart = PosePart.fromName(name);
if (posePart == null) {
mechanism.echoError("Invalid pose part specified: " + name + "; ignoring next: " + angle);
if (mechanism.getValue().asString().contains("=")) {
MapTag map = mechanism.valueAsType(MapTag.class);
for (Map.Entry<StringHolder, ObjectTag> entry : map.map.entrySet()) {
PosePart posePart = PosePart.fromName(entry.getKey().str);
if (posePart == null) {
mechanism.echoError("Invalid pose part specified: " + entry.getKey().str);
}
else {
posePart.setAngle(armorStand, toEulerAngle(entry.getValue().asType(LocationTag.class, mechanism.context)));
}
}
else {
posePart.setAngle(armorStand, toEulerAngle(LocationTag.valueOf(angle, mechanism.context)));
}
else {
ListTag list = mechanism.valueAsType(ListTag.class);
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String name = iterator.next();
String angle = iterator.next();
PosePart posePart = PosePart.fromName(name);
if (posePart == null) {
mechanism.echoError("Invalid pose part specified: " + name + "; ignoring next: " + angle);
}
else {
posePart.setAngle(armorStand, toEulerAngle(LocationTag.valueOf(angle, mechanism.context)));
}
}
}
}
Expand Down
@@ -0,0 +1,194 @@
package com.denizenscript.denizen.objects.properties.item;

import com.denizenscript.denizen.nms.NMSHandler;
import com.denizenscript.denizen.nms.util.jnbt.*;
import com.denizenscript.denizen.objects.ItemTag;
import com.denizenscript.denizencore.objects.Mechanism;
import com.denizenscript.denizencore.objects.ObjectTag;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.objects.core.MapTag;
import com.denizenscript.denizencore.objects.properties.Property;
import com.denizenscript.denizencore.objects.properties.PropertyParser;
import com.denizenscript.denizencore.utilities.CoreUtilities;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;

import java.util.ArrayList;
import java.util.List;

public class ItemArmorPose implements Property {

public static boolean describes(ObjectTag item) {
return item instanceof ItemTag
&& ((ItemTag) item).getBukkitMaterial() == Material.ARMOR_STAND;
}

public static ItemArmorPose getFrom(ObjectTag item) {
if (!describes(item)) {
return null;
}
else {
return new ItemArmorPose((ItemTag) item);
}
}

public static final String[] handledMechs = new String[] {
"armor_pose"
};

private ItemArmorPose(ItemTag item) {
this.item = item;
}

public static void procPart(CompoundTag pose, String nmsName, String denizenName, MapTag result) {
List<Tag> list = pose.getList(nmsName);
if (list == null || list.size() != 3) {
return;
}
Tag x = list.get(0), y = list.get(1), z = list.get(2);
if (!(x instanceof FloatTag) || !(y instanceof FloatTag) || !(z instanceof FloatTag)) {
return;
}
String combined = x.getValue() + "," + y.getValue() + "," + z.getValue();
result.putObject(denizenName, new ElementTag(combined));
}

public MapTag getPoseMap() {
CompoundTag compoundTag = NMSHandler.getItemHelper().getNbtData(item.getItemStack());
if (compoundTag == null) {
return null;
}
Tag entPart = compoundTag.getValue().get("EntityTag");
if (!(entPart instanceof CompoundTag)) {
return null;
}
Tag posePart = ((CompoundTag) entPart).getValue().get("Pose");
if (!(posePart instanceof CompoundTag)) {
return null;
}
CompoundTag pose = (CompoundTag) posePart;
MapTag result = new MapTag();
procPart(pose, "Head", "head", result);
procPart(pose, "Body", "body", result);
procPart(pose, "LeftArm", "left_arm", result);
procPart(pose, "RightArm", "right_arm", result);
procPart(pose, "LeftLeg", "left_leg", result);
procPart(pose, "RightLeg", "right_leg", result);
return result;
}

ItemTag item;

public static void registerTags() {

// <--[tag]
// @attribute <ItemTag.armor_pose>
// @returns MapTag
// @group properties
// @mechanism ItemTag.armor_pose
// @description
// Returns the pose of this armor stand item, if any.
// Map has keys: head, body, left_arm, right_arm, left_leg, right_leg
// -->
PropertyParser.<ItemArmorPose, MapTag>registerTag(MapTag.class, "armor_stand_data", (attribute, item) -> {
return item.getPoseMap();
});
}

@Override
public String getPropertyString() {
MapTag result = getPoseMap();
if (result == null) {
return null;
}
return result.toString();
}

@Override
public String getPropertyId() {
return "armor_pose";
}

public static void procMechKey(Mechanism mech, CompoundTagBuilder pose, String nmsName, String denizenName, MapTag input) {
ObjectTag value = input.getObject(denizenName);
if (value == null) {
return;
}
List<String> raw = CoreUtilities.split(value.toString(), ',');
if (raw.size() != 3) {
mech.echoError("Invalid pose piece '" + value + "'");
return;
}
List<FloatTag> rawList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
rawList.add(new FloatTag(Float.valueOf(raw.get(i))));
}
JNBTListTag list = new JNBTListTag(FloatTag.class, rawList);
pose.put(nmsName, list);
}

@Override
public void adjust(Mechanism mechanism) {

// <--[mechanism]
// @object ItemTag
// @name armor_pose
// @input MapTag
// @description
// Sets the pose of this armor stand item.
// Allowed keys: head, body, left_arm, right_arm, left_leg, right_leg
// @tags
// <ItemTag.armor_pose>
// -->
if (mechanism.matches("armor_pose")) {
CompoundTag compoundTag = NMSHandler.getItemHelper().getNbtData(item.getItemStack());
Tag entPart, posePart;
if (mechanism.hasValue() && mechanism.requireObject(MapTag.class)) {
if (compoundTag == null) {
compoundTag = new CompoundTagBuilder().build();
}
entPart = compoundTag.getValue().get("EntityTag");
if (!(entPart instanceof CompoundTag)) {
entPart = new CompoundTagBuilder().build();
}
CompoundTagBuilder poseBuilder = new CompoundTagBuilder();
MapTag input = mechanism.valueAsType(MapTag.class);
procMechKey(mechanism, poseBuilder, "Head", "head", input);
procMechKey(mechanism, poseBuilder, "Body", "body", input);
procMechKey(mechanism, poseBuilder, "LeftArm", "left_arm", input);
procMechKey(mechanism, poseBuilder, "RightArm", "right_arm", input);
procMechKey(mechanism, poseBuilder, "LeftLeg", "left_leg", input);
procMechKey(mechanism, poseBuilder, "RightLeg", "right_leg", input);
CompoundTag pose = poseBuilder.build();
if (pose.getValue().isEmpty()) {
entPart = ((CompoundTag) entPart).createBuilder().remove("Pose").build();
}
else {
entPart = ((CompoundTag) entPart).createBuilder().put("Pose", pose).build();
}
}
else {
if (compoundTag == null) {
return;
}
entPart = compoundTag.getValue().get("EntityTag");
if (!(entPart instanceof CompoundTag)) {
return;
}
posePart = ((CompoundTag) entPart).getValue().get("Pose");
if (!(posePart instanceof CompoundTag)) {
return;
}
entPart = ((CompoundTag) entPart).createBuilder().remove("Pose").build();
}
if (((CompoundTag) entPart).getValue().isEmpty()) {
compoundTag = compoundTag.createBuilder().remove("EntityTag").build();
}
else {
compoundTag = compoundTag.createBuilder().put("EntityTag", entPart).build();
}
ItemStack result = NMSHandler.getItemHelper().setNbtData(item.getItemStack(), compoundTag);
item.setItemStack(result);
}
}
}

0 comments on commit 36f3ed3

Please sign in to comment.