9
0
mirror of https://github.com/HibiscusMC/HMCCosmetics.git synced 2026-01-03 06:12:20 +00:00

refactor: make itemdisplay metadata configurable

This commit is contained in:
Boy
2024-08-01 12:29:20 +02:00
parent 0041f29ed7
commit ed4803f36b
6 changed files with 196 additions and 33 deletions

View File

@@ -2,16 +2,23 @@ package com.hibiscusmc.hmccosmetics.cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.misc.ItemDisplayMetadata;
import lombok.Getter;
import lombok.Setter;
import me.lojosho.hibiscuscommons.config.serializer.ItemSerializer;
import me.lojosho.shaded.configurate.ConfigurationNode;
import me.lojosho.shaded.configurate.serialize.SerializationException;
import org.bukkit.Material;
import org.bukkit.entity.Display;
import org.bukkit.entity.ItemDisplay;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
public abstract class Cosmetic {
@@ -76,4 +83,56 @@ public abstract class Cosmetic {
throw new RuntimeException(e);
}
}
protected ItemDisplayMetadata generateItemDisplayMetadata(ConfigurationNode config) {
ItemDisplayMetadata metadata = new ItemDisplayMetadata();
ConfigurationNode translationNode = config.node("translation");
ConfigurationNode scaleNode = config.node("scale");
ConfigurationNode rotationLeftNode = config.node("rotation-left");
ConfigurationNode rotationRightNode = config.node("rotation-right");
ConfigurationNode billboardNode = config.node("billboard");
ConfigurationNode blockLightNode = config.node("block-light");
ConfigurationNode skyLightNode = config.node("sky-light");
ConfigurationNode viewRangeNode = config.node("viewrange");
ConfigurationNode widthNode = config.node("width");
ConfigurationNode heightNode = config.node("height");
ConfigurationNode displayTransformNode = config.node("display-transform");
ConfigurationNode itemstackNode = config.node("item");
if (!translationNode.virtual()) metadata.translation = stringToVector(translationNode.getString("0,0,0"));
if (!scaleNode.virtual()) metadata.scale = stringToVector(scaleNode.getString("1,1,1"));
if (!rotationLeftNode.virtual()) metadata.rotationLeft = stringToQuaternion(rotationLeftNode.getString("0,0,0,1"));
if (!rotationRightNode.virtual()) metadata.rotationRight = stringToQuaternion(rotationRightNode.getString("0,0,0,1"));
if (!billboardNode.virtual()) try {
metadata.billboard = Display.Billboard.valueOf(billboardNode.getString("VERTICAL"));
} catch (Exception ignored) {}
if (!blockLightNode.virtual()) metadata.blockLight = blockLightNode.getInt(0);
if (!skyLightNode.virtual()) metadata.skyLight = skyLightNode.getInt(15);
if (!viewRangeNode.virtual()) metadata.viewRange = viewRangeNode.getFloat(1);
if (!widthNode.virtual()) metadata.width = widthNode.getFloat(0);
if (!heightNode.virtual()) metadata.height = heightNode.getFloat(0);
if (!displayTransformNode.virtual()) try {
metadata.displayTransform = ItemDisplay.ItemDisplayTransform.valueOf(displayTransformNode.getString());
} catch (Exception ignored) {}
if (!itemstackNode.virtual()) try {
metadata.itemStack = ItemSerializer.INSTANCE.deserialize(ItemStack.class, itemstackNode);
} catch (Exception ignored) {}
return metadata;
}
protected Vector3f stringToVector(String string) {
List<String> vector = Arrays.stream(string.replace(" ", "").split(",", 3)).toList();
while (vector.size() < 3) vector.add("0");
float x = Float.parseFloat(vector.get(0)), y = Float.parseFloat(vector.get(1)), z = Float.parseFloat(vector.get(2));
return new Vector3f(x, y, z);
}
protected Quaternionf stringToQuaternion(String string) {
List<String> vector = Arrays.stream(string.replace(" ", "").split(",", 4)).toList();
while (vector.size() < 3) vector.add("0");
if (vector.size() < 4) vector.add("1");
float x = Float.parseFloat(vector.get(0)), y = Float.parseFloat(vector.get(1)), z = Float.parseFloat(vector.get(2)), w = Float.parseFloat(vector.get(3));
return new Quaternionf(x, y, z, w);
}
}

View File

@@ -5,16 +5,16 @@ import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.manager.UserBackpackManager;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.misc.ItemDisplayMetadata;
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import lombok.Getter;
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
import lombok.Setter;
import me.lojosho.shaded.configurate.ConfigurationNode;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
@@ -30,6 +30,8 @@ public class CosmeticBackpackType extends Cosmetic {
@Getter
private int height = -1;
private ItemStack firstPersonBackpack;
@Getter @Setter
private ItemDisplayMetadata metadata;
public CosmeticBackpackType(String id, ConfigurationNode config) {
super(id, config);
@@ -40,6 +42,10 @@ public class CosmeticBackpackType extends Cosmetic {
this.firstPersonBackpack = generateItemStack(config.node("firstperson-item"));
this.height = config.node("height").getInt(5);
}
if (!config.node("metadata").virtual()) {
this.metadata = generateItemDisplayMetadata(config.node("metadata"));
} else this.metadata = new ItemDisplayMetadata();
}
@Override
@@ -58,15 +64,16 @@ public class CosmeticBackpackType extends Cosmetic {
List<Player> outsideViewers = user.getUserBackpackManager().getEntityManager().refreshViewers(loc);
UserBackpackManager backpackManager = user.getUserBackpackManager();
backpackManager.getEntityManager().setRotation((int) loc.getYaw(), isFirstPersonCompadible());
//backpackManager.getEntityManager().setRotation((int) loc.getYaw(), isFirstPersonCompadible());
HMCCPacketManager.sendEntitySpawnPacket(user.getEntity().getLocation(), backpackManager.getFirstItemDisplayId(), EntityType.ITEM_DISPLAY, UUID.randomUUID(), outsideViewers);
HMCCPacketManager.sendItemDisplayMetadata(backpackManager.getFirstItemDisplayId(), user.getUserCosmeticItem(this, getItem()), outsideViewers);
//metadata.rotationLeft.rotateY((float) Math.toRadians(loc.getYaw()));
HMCCPacketManager.sendItemDisplayMetadata(backpackManager.getFirstItemDisplayId(), metadata, user.getUserCosmeticItem(this, getItem()), outsideViewers);
// If true, it will send the riding packet to all players. If false, it will send the riding packet only to new players
if (Settings.isBackpackForceRidingEnabled()) HMCCPacketManager.sendRidingPacket(entity.getEntityId(), backpackManager.getFirstItemDisplayId(), backpackManager.getEntityManager().getViewers());
else HMCCPacketManager.sendRidingPacket(entity.getEntityId(), user.getUserBackpackManager().getFirstItemDisplayId(), outsideViewers);
if (!user.isInWardrobe() && isFirstPersonCompadible() && user.getPlayer() != null) {
if (!user.isInWardrobe() && isFirstPersonCompatible() && user.getPlayer() != null) {
List<Player> owner = List.of(user.getPlayer());
ArrayList<Integer> particleCloud = backpackManager.getAreaEffectEntityId();
@@ -79,9 +86,7 @@ public class CosmeticBackpackType extends Cosmetic {
}
HMCCPacketManager.sendRidingPacket(particleCloud.get(particleCloud.size() - 1), backpackManager.getFirstItemDisplayId(), owner);
if (!user.isHidden()) {
//if (loc.getPitch() < -70) NMSHandlers.getHandler().equipmentSlotUpdate(user.getUserBackpackManager().getFirstArmorStandId(), EquipmentSlot.HEAD, new ItemStack(Material.AIR), owner);
//else NMSHandlers.getHandler().equipmentSlotUpdate(user.getUserBackpackManager().getFirstArmorStandId(), EquipmentSlot.HEAD, firstPersonBackpack, owner);
HMCCPacketManager.sendItemDisplayMetadata(backpackManager.getFirstItemDisplayId(), user.getUserCosmeticItem(this, firstPersonBackpack), owner);
HMCCPacketManager.sendItemDisplayMetadata(backpackManager.getFirstItemDisplayId(), metadata, user.getUserCosmeticItem(this, firstPersonBackpack), owner);
}
MessagesUtil.sendDebugMessages("First Person Backpack Update[owner=" + user.getUniqueId() + ",player_location=" + loc + "]!", Level.INFO);
}
@@ -90,7 +95,7 @@ public class CosmeticBackpackType extends Cosmetic {
backpackManager.showBackpack();
}
public boolean isFirstPersonCompadible() {
public boolean isFirstPersonCompatible() {
return firstPersonBackpack != null;
}

View File

@@ -1,30 +1,28 @@
package com.hibiscusmc.hmccosmetics.user.manager;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.misc.ItemDisplayMetadata;
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import com.ticxo.modelengine.api.ModelEngineAPI;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import lombok.Getter;
import lombok.Setter;
import me.lojosho.hibiscuscommons.hooks.Hooks;
import me.lojosho.hibiscuscommons.util.ServerUtils;
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.logging.Level;
@@ -62,10 +60,12 @@ public class UserBackpackManager {
}
private void spawn(CosmeticBackpackType cosmeticBackpackType) {
Location entityLoc = user.getEntity().getLocation();
entityLoc.setPitch(0f);
getEntityManager().setIds(List.of(itemDisplayId));
getEntityManager().teleport(user.getEntity().getLocation());
getEntityManager().teleport(entityLoc);
List<Player> outsideViewers = getEntityManager().getViewers();
HMCCPacketManager.sendEntitySpawnPacket(user.getEntity().getLocation(), getFirstItemDisplayId(), EntityType.ITEM_DISPLAY, UUID.randomUUID(), getEntityManager().getViewers());
HMCCPacketManager.sendEntitySpawnPacket(entityLoc, getFirstItemDisplayId(), EntityType.ITEM_DISPLAY, UUID.randomUUID(), getEntityManager().getViewers());
Entity entity = user.getEntity();
@@ -80,7 +80,7 @@ public class UserBackpackManager {
ArrayList<Player> owner = new ArrayList<>();
if (user.getPlayer() != null) owner.add(user.getPlayer());
if (cosmeticBackpackType.isFirstPersonCompadible()) {
if (cosmeticBackpackType.isFirstPersonCompatible()) {
for (int i = particleCloud.size(); i < cosmeticBackpackType.getHeight(); i++) {
int entityId = ServerUtils.getNextEntityId();
HMCCPacketManager.sendEntitySpawnPacket(user.getEntity().getLocation(), entityId, EntityType.AREA_EFFECT_CLOUD, UUID.randomUUID());
@@ -92,10 +92,11 @@ public class UserBackpackManager {
if (i == 0) HMCCPacketManager.sendRidingPacket(entity.getEntityId(), particleCloud.get(i), owner);
else HMCCPacketManager.sendRidingPacket(particleCloud.get(i - 1), particleCloud.get(i) , owner);
}
HMCCPacketManager.sendRidingPacket(particleCloud.get(particleCloud.size() - 1), user.getUserBackpackManager().getFirstItemDisplayId(), owner);
if (!user.isHidden()) HMCCPacketManager.sendItemDisplayMetadata(getFirstItemDisplayId(), user.getUserCosmeticItem(cosmeticBackpackType, cosmeticBackpackType.getFirstPersonBackpack()), outsideViewers);
HMCCPacketManager.sendRidingPacket(particleCloud.get(particleCloud.size() - 1),getFirstItemDisplayId(), owner);
if (!user.isHidden()) HMCCPacketManager.sendItemDisplayMetadata(getFirstItemDisplayId(), cosmeticBackpackType.getMetadata(), user.getUserCosmeticItem(cosmeticBackpackType, cosmeticBackpackType.getFirstPersonBackpack()), outsideViewers);
}
HMCCPacketManager.sendItemDisplayMetadata(getFirstItemDisplayId(), user.getUserCosmeticItem(cosmeticBackpackType), outsideViewers);
HMCCPacketManager.sendItemDisplayMetadata(getFirstItemDisplayId(), cosmeticBackpackType.getMetadata(), user.getUserCosmeticItem(cosmeticBackpackType), outsideViewers);
HMCCPacketManager.sendRidingPacket(entity.getEntityId(), passengerIDs, outsideViewers);
// No one should be using ME because it barely works but some still use it, so it's here
@@ -148,8 +149,8 @@ public class UserBackpackManager {
}
public void setItem(ItemStack item) {
//PacketManager.equipmentSlotUpdate(getFirstItemDisplayId(), EquipmentSlot.HEAD, item, getEntityManager().getViewers());
HMCCPacketManager.sendItemDisplayMetadata(getFirstItemDisplayId(), item, getEntityManager().getViewers());
ItemDisplayMetadata metadata = Optional.ofNullable((CosmeticBackpackType) user.getCosmetic(CosmeticSlot.BACKPACK)).map(CosmeticBackpackType::getMetadata).orElse(new ItemDisplayMetadata());
HMCCPacketManager.sendItemDisplayMetadata(getFirstItemDisplayId(), metadata, item, getEntityManager().getViewers());
}
public void clearItems() {

View File

@@ -6,6 +6,7 @@ import com.hibiscusmc.hmccosmetics.config.WardrobeLocation;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus;
@@ -13,6 +14,7 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
import com.hibiscusmc.hmccosmetics.util.misc.ItemDisplayMetadata;
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import lombok.Getter;
import lombok.Setter;
@@ -139,12 +141,13 @@ public class UserWardrobeManager {
// Misc
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
// Maybe null as backpack maybe despawned before entering
if (user.getUserBackpackManager() == null) user.respawnBackpack();
UserBackpackManager userBackpackManager = user.getUserBackpackManager();
if (userBackpackManager == null) user.respawnBackpack();
if (user.isBackpackSpawned()) {
user.getUserBackpackManager().getEntityManager().teleport(npcLocation.clone().add(0, 2, 0));
//PacketManager.equipmentSlotUpdate(user.getUserBackpackManager().getFirstItemDisplayId(), EquipmentSlot.HEAD, user.getUserCosmeticItem(user.getCosmetic(CosmeticSlot.BACKPACK)), viewer);
HMCCPacketManager.sendItemDisplayMetadata(ITEM_DISPLAY_ID, user.getUserCosmeticItem(user.getCosmetic(CosmeticSlot.BACKPACK)), viewer);
HMCCPacketManager.ridingMountPacket(NPC_ID, user.getUserBackpackManager().getFirstItemDisplayId(), viewer);
userBackpackManager.getEntityManager().teleport(npcLocation.clone());
CosmeticBackpackType backpackCosmetic = (CosmeticBackpackType) user.getCosmetic(CosmeticSlot.BACKPACK);
HMCCPacketManager.sendItemDisplayMetadata(ITEM_DISPLAY_ID, backpackCosmetic.getMetadata(), user.getUserCosmeticItem(backpackCosmetic), viewer);
HMCCPacketManager.ridingMountPacket(NPC_ID, userBackpackManager.getFirstItemDisplayId(), viewer);
}
}

View File

@@ -0,0 +1,87 @@
package com.hibiscusmc.hmccosmetics.util.misc;
import org.bukkit.Material;
import org.bukkit.entity.Display;
import org.bukkit.entity.ItemDisplay;
import org.bukkit.inventory.ItemStack;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import java.util.HashMap;
import java.util.Map;
public class ItemDisplayMetadata {
public static final Map<Integer, ItemDisplayMetadata> metadataCache = new HashMap<>();
public Vector3f translation;
public Vector3f scale;
public Quaternionf rotationLeft;
public Quaternionf rotationRight;
public Display.Billboard billboard;
public int blockLight;
public int skyLight;
public float viewRange;
public float width;
public float height;
public ItemDisplay.ItemDisplayTransform displayTransform;
public ItemStack itemStack;
public ItemDisplayMetadata() {
this.translation = new Vector3f();
this.scale = new Vector3f(1.0f, 1.0f, 1.0f);
this.rotationLeft = new Quaternionf();
this.rotationRight = new Quaternionf();
this.billboard = Display.Billboard.FIXED;
this.blockLight = 0;
this.skyLight = 0;
this.viewRange = 1.0f;
this.width = 0.0f;
this.height = 0.0f;
this.displayTransform = ItemDisplay.ItemDisplayTransform.NONE;
this.itemStack = new ItemStack(Material.AIR);
}
public ItemDisplayMetadata(ItemDisplayMetadata metadata) {
this.translation = metadata.translation;
this.scale = metadata.scale;
this.rotationLeft = metadata.rotationLeft;
this.rotationRight = metadata.rotationRight;
this.billboard = metadata.billboard;
this.blockLight = metadata.blockLight;
this.skyLight = metadata.skyLight;
this.viewRange = metadata.viewRange;
this.width = metadata.width;
this.height = metadata.height;
this.displayTransform = metadata.displayTransform;
this.itemStack = metadata.itemStack;
}
public ItemDisplayMetadata(
Vector3f translation,
Vector3f scale,
Quaternionf rotationLeft,
Quaternionf rotationRight,
Display.Billboard billboard,
int blockLight,
int skyLight,
float viewRange,
float width,
float height,
ItemDisplay.ItemDisplayTransform displayTransform,
ItemStack itemStack
) {
this.translation = translation;
this.scale = scale;
this.rotationLeft = rotationLeft;
this.rotationRight = rotationRight;
this.billboard = billboard;
this.blockLight = blockLight;
this.skyLight = skyLight;
this.viewRange = viewRange;
this.width = width;
this.height = height;
this.displayTransform = displayTransform;
this.itemStack = itemStack;
}
}

View File

@@ -12,6 +12,7 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
import com.hibiscusmc.hmccosmetics.util.misc.ItemDisplayMetadata;
import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerNamedEntitySpawn;
import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerPlayerInfo;
import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerRelEntityMove;
@@ -91,12 +92,19 @@ public class HMCCPacketManager extends PacketManager {
equipmentSlotUpdate(entityId, HMCCInventoryUtils.getEquipmentSlot(cosmeticSlot), user.getUserCosmeticItem(cosmeticSlot), sendTo);
}
public static void sendItemDisplayMetadata(
int entityId,
ItemStack itemStack,
List<Player> sendTo
) {
PacketManager.sendItemDisplayMetadataPacket(entityId, new Vector3f(0.0f, -3.2f, -0.5f), new Vector3f(1f,1f,1f), new Quaternionf(0f,0f,0f,1f), new Quaternionf(0f,0f,0f,1f), Display.Billboard.VERTICAL, 0, 15, 32, 1f, 1f, ItemDisplay.ItemDisplayTransform.NONE, itemStack, sendTo);
public static void sendItemDisplayMetadata(int entityId, ItemStack itemStack, List<Player> sendTo) {
ItemDisplayMetadata metadata = new ItemDisplayMetadata();
metadata.itemStack = itemStack;
PacketManager.sendItemDisplayMetadataPacket(entityId, metadata.translation, metadata.scale, metadata.rotationLeft, metadata.rotationRight, metadata.billboard, metadata.blockLight, metadata.skyLight, metadata.viewRange, metadata.width, metadata.height, metadata.displayTransform, itemStack, sendTo);
}
public static void sendItemDisplayMetadata(int entityId, ItemDisplayMetadata metadata, List<Player> sendTo) {
ItemDisplayMetadata.metadataCache.put(entityId, metadata);
PacketManager.sendItemDisplayMetadataPacket(entityId, metadata.translation, metadata.scale, metadata.rotationLeft, metadata.rotationRight, metadata.billboard, metadata.blockLight, metadata.skyLight, metadata.viewRange, metadata.width, metadata.height, metadata.displayTransform, metadata.itemStack, sendTo);
}
public static void sendItemDisplayMetadata(int entityId, ItemDisplayMetadata metadata, ItemStack itemStack, List<Player> sendTo) {
PacketManager.sendItemDisplayMetadataPacket(entityId, metadata.translation, metadata.scale, metadata.rotationLeft, metadata.rotationRight, metadata.billboard, metadata.blockLight, metadata.skyLight, metadata.viewRange, metadata.width, metadata.height, metadata.displayTransform, itemStack, sendTo);
}
public static void sendInvisibilityPacket(