Commit 91d7096d authored by Ash's avatar Ash
Browse files

Added `Renderer: DISPLAY` option to backpacks to make them render using display entities

parent ea8e4aa7
......@@ -4,24 +4,35 @@ import io.lumine.cosmetics.api.cosmetics.ColorableCosmetic;
import io.lumine.cosmetics.api.cosmetics.EquippedCosmetic;
import io.lumine.cosmetics.api.cosmetics.ItemCosmetic;
import io.lumine.cosmetics.api.players.CosmeticProfile;
import io.lumine.cosmetics.config.Scope;
import io.lumine.cosmetics.constants.CosmeticType;
import io.lumine.cosmetics.types.AbstractCosmetic;
import io.lumine.mythic.api.packs.Pack;
import io.lumine.mythic.bukkit.utils.config.properties.Property;
import io.lumine.mythic.bukkit.utils.config.properties.types.StringProp;
import io.lumine.mythic.bukkit.utils.items.ItemFactory;
import io.lumine.mythic.bukkit.utils.menu.Icon;
import lombok.Getter;
import org.bukkit.inventory.ItemStack;
import java.io.File;
public class BackAccessory extends AbstractCosmetic implements ColorableCosmetic,ItemCosmetic {
public BackAccessory(BackManager manager, File file, String key) {
this(manager, null, file, key);
}
private static final StringProp TYPE = Property.String(Scope.NONE, "Renderer", "ARMOR_STAND");
@Getter
private BackRendererType rendererType;
public BackAccessory(BackManager manager, Pack pack, File file, String key) {
super(manager, pack, file, CosmeticType.type(BackAccessory.class), key);
this.rendererType = switch(TYPE.fget(file, key).toUpperCase()) {
case "ARMORSTAND", "ARMOR_sTAND" -> BackRendererType.ARMOR_STAND;
case "DISPLAY", "DISPLAY_ENTITY" -> BackRendererType.DISPLAY_ENTITY;
default -> BackRendererType.ARMOR_STAND;
};
}
@Override
......
......@@ -3,25 +3,46 @@ package io.lumine.cosmetics.types.back;
import io.lumine.cosmetics.MCCosmeticsPlugin;
import io.lumine.cosmetics.api.cosmetics.Cosmetic;
import io.lumine.cosmetics.api.cosmetics.EquippedCosmetic;
import io.lumine.cosmetics.api.cosmetics.ItemCosmetic;
import io.lumine.cosmetics.api.cosmetics.manager.HideableCosmetic;
import io.lumine.cosmetics.api.players.CosmeticProfile;
import io.lumine.cosmetics.api.players.wardrobe.Mannequin;
import io.lumine.cosmetics.logging.MCLogger;
import io.lumine.cosmetics.types.MCCosmeticsManager;
import io.lumine.cosmetics.types.gestures.Gesture;
import io.lumine.cosmetics.nms.cosmetic.VolatileAppliedCosmeticHelper;
import io.lumine.mythic.api.adapters.AbstractVector;
import io.lumine.mythic.api.packs.Pack;
import io.lumine.mythic.api.volatilecode.virtual.PacketArmorStand;
import io.lumine.mythic.api.volatilecode.virtual.PacketEntity;
import io.lumine.mythic.api.volatilecode.virtual.PacketEntityRenderer;
import io.lumine.mythic.api.volatilecode.virtual.PacketItemDisplay;
import io.lumine.mythic.bukkit.BukkitAdapter;
import io.lumine.mythic.bukkit.MythicBukkit;
import io.lumine.mythic.bukkit.utils.Events;
import io.lumine.mythic.bukkit.utils.Schedulers;
import java.io.File;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import io.lumine.mythic.bukkit.utils.logging.Log;
import io.papermc.paper.event.player.PlayerTrackEntityEvent;
import lombok.Data;
import org.bukkit.GameMode;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.util.EulerAngle;
public class BackManager extends MCCosmeticsManager<BackAccessory> implements HideableCosmetic {
private final Map<Player, PacketItemDisplay> renderedBacks = new ConcurrentHashMap<>();
public BackManager(MCCosmeticsPlugin plugin) {
super(plugin, BackAccessory.class);
......@@ -80,6 +101,16 @@ public class BackManager extends MCCosmeticsManager<BackAccessory> implements Hi
}
})
.bindWith(this);
Schedulers.async().runRepeating(this::handleUpdate, 1, 1).bindWith(this);
//Events.subscribe(PlayerMoveEvent.class)
// .handler(this::handlePlayerMove)
// .bindWith(this);
Events.subscribe(PlayerTrackEntityEvent.class)
.handler(this::handlePlayerTrack)
.bindWith(this);
}
@Override
......@@ -89,12 +120,137 @@ public class BackManager extends MCCosmeticsManager<BackAccessory> implements Hi
@Override
public void equip(CosmeticProfile profile) {
getHelper().apply(profile);
var maybeEquipped = profile.getEquipped(BackAccessory.class);
if(maybeEquipped.isEmpty()) {
return;
}
var equipped = maybeEquipped.get();
var cosmetic = equipped.getCosmetic();
if (!(cosmetic instanceof BackAccessory back)) {
return;
}
final var itemStack = back.getCosmetic(equipped);
final var aPlayer = BukkitAdapter.adapt(profile.getPlayer());
if(back.getRendererType() == BackRendererType.DISPLAY_ENTITY) {
final var packetDisplay = PacketItemDisplay.create()
.item(itemStack)
.interpolationDelay(0)
.interpolationDuration(1)
.yOffset(1.26F)
.height(0F)
.width(0F)
.scale(new AbstractVector(0.5, 0.5, 0.5))
.build(aPlayer.getLocation());
packetDisplay.getRenderer().spawn(() -> {
final var list = MythicBukkit.inst().getVolatileCodeHandler().getEntityHandler().getTrackedPlayers(aPlayer);
list.add(aPlayer);
return list;
});
packetDisplay.getRenderer().mountEntity(aPlayer);
Schedulers.async().runLater(() -> {
packetDisplay.setTranslationTransformation(0, 1.26F, 0);
}, 20);;
renderedBacks.put(profile.getPlayer(), packetDisplay);
} else {
getHelper().apply(profile);
/*
Log.info("Spawn ARMOR STAND Backpack");
final var packetDisplay = PacketArmorStand.create()
.headItem(itemStack)
.build(aPlayer.getLocation());
packetDisplay.getRenderer().spawn(() -> {
final var list = MythicBukkit.inst().getVolatileCodeHandler().getEntityHandler().getTrackedPlayers(aPlayer);
list.add(aPlayer);
return list;
});
packetDisplay.getRenderer().mountEntity(aPlayer);
renderedBacks.put(profile.getPlayer(), packetDisplay);
/*
packetDisplay.getRenderer().spawnWithMount(() -> {
final var list = MythicBukkit.inst().getVolatileCodeHandler().getEntityHandler().getTrackedPlayers(aPlayer);
list.add(aPlayer);
return list;
}, aPlayer);
*/
}
}
@Override
public void unequip(CosmeticProfile profile) {
getHelper().unapply(profile);
final var removed = renderedBacks.remove(profile.getPlayer());
if(removed != null) {
removed.destroy();
} else {
getHelper().unapply(profile);
}
}
private void handleUpdate() {
renderedBacks.entrySet().forEach(entry -> {
final var player = entry.getKey();
final var backpack = entry.getValue();
float bodyYaw = player.getBodyYaw();
float locationYaw = player.getLocation().getYaw();
bodyYaw = (bodyYaw + 360) % 360;
if (bodyYaw > 180) bodyYaw -= 360;
locationYaw = (locationYaw + 360) % 360;
if (locationYaw > 180) locationYaw -= 360;
float diff = Math.abs(bodyYaw - locationYaw);
if (diff > 180) {
if (bodyYaw > locationYaw) {
locationYaw += 360;
} else {
bodyYaw += 360;
}
}
float yaw = (bodyYaw + locationYaw) / 2;
yaw = (yaw + 360) % 360;
if (yaw > 180) yaw -= 360;
backpack.setInterpolationDuration(1);
backpack.setRotation(yaw + 180, 0);
backpack.update();
});
}
private void handlePlayerMove(PlayerMoveEvent event) {
final var player = event.getPlayer();
final var backpack = renderedBacks.get(player);
if(backpack != null && backpack instanceof PacketItemDisplay<?> itemDisplay) {
final var yaw = event.getTo().getYaw();
MCLogger.log("yaw {0}", yaw);
itemDisplay.setRotation(yaw, 0);
itemDisplay.update();
}
}
private void handlePlayerTrack(PlayerTrackEntityEvent event) {
if(!(event.getEntity() instanceof Player player)) {
return;
}
final var backpack = renderedBacks.get(player);
if(backpack != null) {
backpack.getRenderer().updateRenderedPlayers();
}
}
@Override
......@@ -109,16 +265,20 @@ public class BackManager extends MCCosmeticsManager<BackAccessory> implements Hi
@Override
public void hide(CosmeticProfile profile, Cosmetic request) {
if(!(request instanceof Gesture))
if(!(request instanceof Gesture)) {
return;
}
profile.setHidden(getCosmeticClass(), true);
getHelper().unapply(profile);
}
@Override
public void show(CosmeticProfile profile) {
if(profile.getPlayer().isDead())
if(profile.getPlayer().isDead()) {
return;
}
profile.setHidden(getCosmeticClass(), false);
getHelper().apply(profile);
}
......
package io.lumine.cosmetics.types.back;
public enum BackRendererType {
ARMOR_STAND,
DISPLAY_ENTITY
}
......@@ -193,7 +193,7 @@ public class VolatileBackImpl implements VolatileAppliedCosmeticHelper {
return handleMove(profile, moveEntityPacket);
}
}else if(packet instanceof ClientboundTeleportEntityPacket teleportEntityPacket) {
int id = teleportEntityPacket.getId();
int id = teleportEntityPacket.getI d();
if(playerTracker.containsKey(id)) {
final var spawnedPlayer = playerTracker.get(id);
final var profile = MCCosmeticsPlugin.inst().getProfiles().getProfile(spawnedPlayer);
......@@ -222,6 +222,7 @@ public class VolatileBackImpl implements VolatileAppliedCosmeticHelper {
if(!hasBack(profile)) {
return null;
}
final var wearer = profile.getPlayer();
final var stand = activeProfile.get(wearer);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment