Commit 03fd7353 authored by Ashijin's avatar Ashijin
Browse files

Added first version of wardrobe feature (1.19.2 only at the moment)

No related merge requests found
package io.lumine.cosmetics.api.cosmetics.manager;
import io.lumine.cosmetics.api.cosmetics.EquippedCosmetic;
import io.lumine.cosmetics.api.players.CosmeticProfile;
import io.lumine.cosmetics.api.players.wardrobe.Mannequin;
public interface CosmeticManager {
void equip(CosmeticProfile profile);
void unequip(CosmeticProfile profile);
void equipMannequin(Mannequin mannequin, EquippedCosmetic cosmetic);
void unequipMannequin(Mannequin mannequin);
}
package io.lumine.cosmetics.api.players.wardrobe;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import io.lumine.cosmetics.api.cosmetics.Cosmetic;
public interface Mannequin {
public int getEntityId();
public UUID getUniqueId();
public Player getPlayer();
public Location getLocation();
public float getRotation();
public WardrobeTracker getTracker();
public void despawn();
default public void setCleanupWhenDone(Class<? extends Cosmetic> type) {
getTracker().setCleanupWhenDone(type);
}
public void addExtraEntity(Class<? extends Cosmetic> type, int id);
public void removeExtraEntity(Class<? extends Cosmetic> type);
}
package io.lumine.cosmetics.api.players.wardrobe;
import org.bukkit.entity.Player;
public interface WardrobeManager {
public void openWardrobe(Player player);
public void closeWardrobe(Player player);
public boolean isInWardrobe(Player player);
public Mannequin getMannequin(Player player);
}
package io.lumine.cosmetics.api.players.wardrobe;
import org.bukkit.entity.Player;
import io.lumine.cosmetics.api.cosmetics.Cosmetic;
public interface WardrobeTracker {
public WardrobeManager getManager();
public Player getPlayer();
public Mannequin getMannequin();
public void setCleanupWhenDone(Class<? extends Cosmetic> type);
}
......@@ -163,7 +163,7 @@
<dependency>
<groupId>io.lumine</groupId>
<artifactId>MCCosmetics-API</artifactId>
<version>0.6.0-SNAPSHOT</version>
<version>0.8.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
......
......@@ -24,6 +24,7 @@ import io.lumine.cosmetics.metrics.bStats;
import io.lumine.cosmetics.nms.VolatileCodeDisabled;
import io.lumine.cosmetics.nms.VolatileCodeHandler;
import io.lumine.cosmetics.players.ProfileManager;
import io.lumine.cosmetics.players.wardrobe.WardrobeExecutor;
import io.lumine.utils.chat.ColorString;
import io.lumine.utils.logging.ConsoleColor;
import io.lumine.utils.logging.Log;
......@@ -54,6 +55,7 @@ public class MCCosmeticsPlugin extends LuminePlugin {
@Getter private OffhandManager offhandManager;
@Getter private MEGManager megManager;
@Getter private GestureManager gestureManager;
@Getter private WardrobeExecutor wardrobeManager;
private VolatileCodeHandler volatileCodeHandler;
......@@ -129,6 +131,7 @@ public class MCCosmeticsPlugin extends LuminePlugin {
profiles = new ProfileManager(this);
menuManager = new MenuManager(this);
wardrobeManager = new WardrobeExecutor(this);
/*
* Events
......
......@@ -14,7 +14,11 @@ public class BaseCommand extends Command<MCCosmeticsPlugin> {
public BaseCommand(MCCosmeticsPlugin plugin) {
super(plugin);
this.addSubCommands(new DyeCommand(this), new EquipCommand(this), new UnequipCommand(this));
this.addSubCommands(
new DyeCommand(this),
new EquipCommand(this),
new UnequipCommand(this),
new WardrobeCommand(this));
}
@Override
......
package io.lumine.cosmetics.commands;
import io.lumine.cosmetics.MCCosmeticsPlugin;
import io.lumine.cosmetics.api.cosmetics.ColorableCosmetic;
import io.lumine.cosmetics.api.cosmetics.Cosmetic;
import io.lumine.cosmetics.api.cosmetics.EquippedCosmetic;
import io.lumine.cosmetics.constants.CosmeticType;
import io.lumine.cosmetics.constants.Permissions;
import io.lumine.utils.commands.Command;
import io.lumine.utils.serialize.Chroma;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
public class WardrobeCommand extends Command<MCCosmeticsPlugin> {
public WardrobeCommand(Command command) {
super(command);
}
@Override
public boolean onCommand(CommandSender sender, String[] args) {
final var player = (Player) sender;
getPlugin().getWardrobeManager().openWardrobe(player);
CommandHelper.sendSuccess(sender, "Spawned wardrobe");
return true;
}
@Override
public List<String> onTabComplete(CommandSender sender, String[] args) {
return Collections.emptyList();
}
@Override
public String getPermissionNode() {
return Permissions.COMMAND_BASE;
}
@Override
public boolean isConsoleFriendly() {
return false;
}
@Override
public String getName() {
return "wardrobe";
}
}
......@@ -3,8 +3,10 @@ package io.lumine.cosmetics.managers;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.lumine.cosmetics.MCCosmeticsPlugin;
import io.lumine.cosmetics.api.cosmetics.Cosmetic;
import io.lumine.cosmetics.api.cosmetics.CosmeticVariant;
import io.lumine.cosmetics.api.cosmetics.EquippedCosmetic;
import io.lumine.cosmetics.api.players.CosmeticProfile;
import io.lumine.cosmetics.commands.CommandHelper;
import io.lumine.cosmetics.config.Scope;
......@@ -33,13 +35,15 @@ public abstract class AbstractCosmetic extends Cosmetic {
protected static final IntProp MODEL = Property.Int(Scope.NONE, "Model");
protected static final LangProp DISPLAY = Property.Lang(Scope.NONE, "Display");
protected static final LangListProp DESCRIPTION = Property.LangList(Scope.NONE, "Description");
protected static final StringProp COLOR = Property.String(Scope.NONE, "Color");
protected static final StringProp TEXTURE = Property.String(Scope.NONE, "SkullTexture");
protected static final StringProp COLOR = Property.String(Scope.NONE, "Color");
protected static final BooleanProp COLORABLE = Property.Boolean(Scope.NONE, "Colorable", false);
protected static final NodeListProp VARIANTS = Property.NodeList(Scope.NONE, "Variants");
private final MCCosmeticsManager manager;
protected final File file;
@Getter protected final String id;
@Getter protected final String key;
......@@ -61,7 +65,7 @@ public abstract class AbstractCosmetic extends Cosmetic {
public AbstractCosmetic(MCCosmeticsManager manager, File file, String type, String key) {
super(manager, type, key);
this.manager = manager;
this.file = file;
this.key = key;
this.namespace = NAMESPACE.fget(file,this);
......@@ -130,14 +134,29 @@ public abstract class AbstractCosmetic extends Cosmetic {
.click((prof,player) -> {
if(prof.getPlayer().isOp() || prof.has(this)) {
CosmeticMenu.playMenuClick(player);
prof.equip(this);
CommandHelper.sendSuccess(player, "Set your " + type + " to " + getDisplay());
if(manager.getWardrobeManager().isInWardrobe(player)) {
var mannequin = manager.getWardrobeManager().getMannequin(player);
manager.equipMannequin(mannequin, new EquippedCosmetic(this));
CommandHelper.sendSuccess(player, "Set wardrobe " + type + " to " + getDisplay());
} else {
prof.equip(this);
CommandHelper.sendSuccess(player, "Set your " + type + " to " + getDisplay());
}
player.closeInventory();
} else {
CommandHelper.sendError(player, Property.String(Scope.CONFIG,
"Configuration.Language.Cosmetic-Not-Unlocked","You haven't unlocked that cosmetic!").get());
}
}).build();
})
.rightClick((prof,player) -> {
if(prof.getPlayer().isOp() || prof.has(this)) {
} else {
CommandHelper.sendError(player, Property.String(Scope.CONFIG,
"Configuration.Language.Cosmetic-Not-Unlocked","You haven't unlocked that cosmetic!").get());
}
}).build();
}
public boolean hasVariants() {
......
......@@ -4,14 +4,17 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
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.manager.CosmeticManager;
import io.lumine.cosmetics.api.players.CosmeticProfile;
import io.lumine.cosmetics.api.players.wardrobe.Mannequin;
import io.lumine.cosmetics.config.Scope;
import io.lumine.cosmetics.constants.CosmeticType;
import io.lumine.cosmetics.menus.SelectionMenu;
import io.lumine.cosmetics.nms.VolatileCodeHandler;
import io.lumine.cosmetics.nms.cosmetic.VolatileCosmeticHelper;
import io.lumine.cosmetics.players.ProfileManager;
import io.lumine.cosmetics.players.wardrobe.WardrobeExecutor;
import io.lumine.utils.config.properties.Property;
import io.lumine.utils.config.properties.types.NodeListProp;
import io.lumine.utils.files.Files;
......@@ -100,6 +103,16 @@ public abstract class MCCosmeticsManager<T extends Cosmetic> extends ReloadableM
public abstract void equip(CosmeticProfile profile);
@Override
public void equipMannequin(Mannequin mannequin, EquippedCosmetic cosmetic) {
}
@Override
public void unequipMannequin(Mannequin mannequin) {
}
protected ProfileManager getProfiles() {
return plugin.getProfiles();
}
......@@ -111,5 +124,9 @@ public abstract class MCCosmeticsManager<T extends Cosmetic> extends ReloadableM
protected VolatileCosmeticHelper getNMSHelper() {
return getNMS().getCosmeticHelper(cosmeticClass);
}
protected WardrobeExecutor getWardrobeManager() {
return plugin.getWardrobeManager();
}
}
......@@ -2,8 +2,10 @@ package io.lumine.cosmetics.managers.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.manager.HideableCosmetic;
import io.lumine.cosmetics.api.players.CosmeticProfile;
import io.lumine.cosmetics.api.players.wardrobe.Mannequin;
import io.lumine.cosmetics.managers.MCCosmeticsManager;
import io.lumine.cosmetics.managers.gestures.Gesture;
import io.lumine.cosmetics.managers.modelengine.MEGAccessory;
......@@ -78,6 +80,16 @@ public class BackManager extends MCCosmeticsManager<BackAccessory> implements Hi
public void unequip(CosmeticProfile profile) {
getHelper().unapply(profile);
}
@Override
public void equipMannequin(Mannequin mannequin, EquippedCosmetic cosmetic) {
getHelper().equipMannequin(mannequin, cosmetic);
}
@Override
public void unequipMannequin(Mannequin mannequin) {
getHelper().unequipMannequin(mannequin);
}
@Override
public void hide(CosmeticProfile profile, Cosmetic request) {
......
......@@ -2,19 +2,18 @@ package io.lumine.cosmetics.managers.hats;
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.manager.HideableCosmetic;
import io.lumine.cosmetics.api.players.CosmeticProfile;
import io.lumine.cosmetics.constants.CosmeticType;
import io.lumine.cosmetics.managers.MCCosmeticsManager;
import io.lumine.cosmetics.managers.gestures.Gesture;
import io.lumine.cosmetics.managers.offhand.Offhand;
import io.lumine.cosmetics.nms.cosmetic.VolatileEquipmentHelper;
import io.lumine.cosmetics.players.Profile;
import io.lumine.utils.Events;
import io.lumine.utils.events.extra.ArmorEquipEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import io.lumine.cosmetics.api.players.wardrobe.Mannequin;
import java.io.File;
......@@ -66,6 +65,16 @@ public class HatManager extends MCCosmeticsManager<Hat> implements HideableCosme
public void unequip(CosmeticProfile profile) {
getHelper().unapply(profile);
}
@Override
public void equipMannequin(Mannequin mannequin, EquippedCosmetic cosmetic) {
getHelper().equipMannequin(mannequin, cosmetic);
}
@Override
public void unequipMannequin(Mannequin mannequin) {
getHelper().unequipMannequin(mannequin);
}
@Override
public void hide(CosmeticProfile profile, Cosmetic request) {
......
......@@ -6,8 +6,11 @@ import com.ticxo.modelengine.api.animation.blueprint.LoopMode;
import com.ticxo.modelengine.api.model.ModeledEntity;
import com.ticxo.modelengine.api.nms.entity.wrapper.RangeManager;
import io.lumine.cosmetics.MCCosmeticsPlugin;
import io.lumine.cosmetics.api.cosmetics.EquippedCosmetic;
import io.lumine.cosmetics.api.players.CosmeticProfile;
import io.lumine.cosmetics.api.players.wardrobe.Mannequin;
import io.lumine.cosmetics.managers.MCCosmeticsManager;
import io.lumine.cosmetics.players.wardrobe.WardrobeMegDummy;
import io.lumine.utils.Events;
import io.lumine.utils.Schedulers;
import org.bukkit.entity.Player;
......@@ -147,5 +150,53 @@ public class MEGManager extends MCCosmeticsManager<MEGAccessory> {
final var player = profile.getPlayer();
ModelEngineAPI.removeModeledEntity(player.getUniqueId());
}
@Override
public void equipMannequin(Mannequin mannequin, EquippedCosmetic cosmetic) {
var opt = cosmetic.getCosmetic();
if(!(opt instanceof MEGAccessory meg)) {
return;
}
final var blueprint = ModelEngineAPI.getBlueprint(meg.getModelId());
if(blueprint == null)
return;
final var animation = blueprint.getAnimations().get(meg.getState());
if(animation == null)
return;
mannequin.setCleanupWhenDone(MEGAccessory.class);
final var activeModel = ModelEngineAPI.createActiveModel(blueprint);
final var property = new AnimationProperty(animation, 1, 0, 1);
property.setForceLoopMode(LoopMode.LOOP);
property.setForceOverride(true);
activeModel.getAnimationHandler().playAnimation(property, true);
activeModel.setCanHurt(false);
var dummy = new WardrobeMegDummy(mannequin, meg.getOffset(), meg.getAnchor());
ModeledEntity modeledEntity = ModelEngineAPI.getModeledEntity(mannequin.getUniqueId());
if(modeledEntity == null) {
modeledEntity = ModelEngineAPI.createModeledEntity(dummy);
modeledEntity.setBaseEntityVisible(true);
if(modeledEntity.getRangeManager() instanceof RangeManager.Disguise disguise) {
disguise.setIncludeSelf(true);
}
modeledEntity.getRangeManager().forceSpawn(mannequin.getPlayer());
}
modeledEntity.destroy();
modeledEntity.addModel(activeModel, false);
}
@Override
public void unequipMannequin(Mannequin mannequin) {
ModelEngineAPI.removeModeledEntity(mannequin.getUniqueId());
}
}
......@@ -2,8 +2,10 @@ package io.lumine.cosmetics.managers.offhand;
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.manager.HideableCosmetic;
import io.lumine.cosmetics.api.players.CosmeticProfile;
import io.lumine.cosmetics.api.players.wardrobe.Mannequin;
import io.lumine.cosmetics.managers.MCCosmeticsManager;
import io.lumine.cosmetics.managers.gestures.Gesture;
import io.lumine.cosmetics.nms.cosmetic.VolatileEquipmentHelper;
......@@ -70,6 +72,16 @@ public class OffhandManager extends MCCosmeticsManager<Offhand> implements Hidea
public void unequip(CosmeticProfile profile) {
getHelper().unapply(profile);
}
@Override
public void equipMannequin(Mannequin mannequin, EquippedCosmetic cosmetic) {
getHelper().equipMannequin(mannequin, cosmetic);
}
@Override
public void unequipMannequin(Mannequin mannequin) {
getHelper().unequipMannequin(mannequin);
}
@Override
public void hide(CosmeticProfile profile, Cosmetic request) {
......
package io.lumine.cosmetics.nms;
import io.lumine.cosmetics.api.cosmetics.Cosmetic;
import io.lumine.cosmetics.api.players.wardrobe.Mannequin;
import io.lumine.cosmetics.api.players.wardrobe.WardrobeTracker;
import io.lumine.cosmetics.nms.cosmetic.VolatileCosmeticHelper;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
......@@ -17,10 +21,12 @@ public interface VolatileCodeHandler {
void removePlayer(Player player);
default Mannequin createMannequin(WardrobeTracker tracker, Player player, Location location) { return null; }
void removeFakeEntity(int id);
void setBodyYaw(LivingEntity entity, double yaw);
float getBodyYaw(LivingEntity entity);
}
package io.lumine.cosmetics.nms.cosmetic;
import io.lumine.cosmetics.api.cosmetics.EquippedCosmetic;
import io.lumine.cosmetics.api.players.CosmeticProfile;
import io.lumine.cosmetics.api.players.wardrobe.Mannequin;
public interface VolatileEquipmentHelper extends VolatileCosmeticHelper {
void apply(CosmeticProfile profile);
void unapply(CosmeticProfile profile);
default void equipMannequin(Mannequin mannequin, EquippedCosmetic cosmetic) {
}
default void unequipMannequin(Mannequin mannequin) {
}
static byte toByte(float val) {
return (byte)((int)(val * 256.0F / 360.0F));
......
package io.lumine.cosmetics.players.wardrobe;
import java.util.Map;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerQuitEvent;
import com.google.common.collect.Maps;
import io.lumine.cosmetics.MCCosmeticsPlugin;
import io.lumine.cosmetics.api.players.wardrobe.Mannequin;
import io.lumine.cosmetics.api.players.wardrobe.WardrobeManager;
import io.lumine.utils.Events;
import io.lumine.utils.plugin.ReloadableModule;
public class WardrobeExecutor extends ReloadableModule<MCCosmeticsPlugin> implements WardrobeManager {
private Map<Player,WardrobeTrackerImpl> usingWardrobe = Maps.newConcurrentMap();
public WardrobeExecutor(MCCosmeticsPlugin plugin) {
super(plugin, false);
}
@Override
public void load(MCCosmeticsPlugin plugin) {
}
@Override
public void unload() {
}
public WardrobeTrackerImpl createTracker(Player player) {
return new WardrobeTrackerImpl(this, player);
}
public void openWardrobe(Player player) {
closeWardrobe(player);
var tracker = createTracker(player);
usingWardrobe.put(player,tracker);
}
public void closeWardrobe(Player player) {
var tracker = usingWardrobe.remove(player);
if(tracker != null) {
tracker.terminate();
}
}
public boolean isInWardrobe(Player player) {
return usingWardrobe.containsKey(player);
}
public Mannequin getMannequin(Player player) {
return usingWardrobe.get(player).getMannequin();
}
}
package io.lumine.cosmetics.players.wardrobe;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import com.ticxo.modelengine.api.entity.Dummy;
import com.ticxo.modelengine.api.nms.entity.wrapper.BodyRotationController;
import com.ticxo.modelengine.api.utils.math.Offset;
import io.lumine.cosmetics.api.players.wardrobe.Mannequin;
import io.lumine.cosmetics.managers.modelengine.ModelAnchor;
import io.lumine.utils.serialize.Orient;
public class WardrobeMegDummy extends Dummy {
private final Mannequin mannequin;
private final Vector offset;
private final double yaw;
private final double pitch;
private final ModelAnchor anchor;
private BodyRotationController controller;
public WardrobeMegDummy(Mannequin mannequin, Orient orient, ModelAnchor anchor) {
super(mannequin.getEntityId(), mannequin.getUniqueId());
this.mannequin = mannequin;
offset = orient.getLocus().toVector();
yaw = Math.toRadians(orient.getDirection().getYaw());
pitch = Math.toRadians(orient.getDirection().getPitch());
this.anchor = anchor;
this.setYBodyRot(mannequin.getRotation());
this.setYHeadRot(mannequin.getRotation());
}
@Override
public BodyRotationController wrapBodyRotationControl() {
controller = super.wrapBodyRotationControl();
controller.setMaxHeadAngle(45);
controller.setMaxBodyAngle(45);
controller.setStableAngle(5);
return controller;
}
@Override
public Location getLocation() {
Location location = mannequin.getLocation().clone();
Vector offset;
if (anchor == ModelAnchor.HEAD) {
double pYaw = Math.toRadians(location.getYaw());
double pPitch = Math.toRadians(location.getPitch());
offset = Offset.rotateYaw(Offset.rotatePitch(this.offset.clone(), pitch + pPitch), yaw + pYaw);
}else {
double pYaw = Math.toRadians(getYBodyRot());
offset = Offset.rotateYaw(this.offset.clone(), yaw + pYaw);
}
return location.add(offset);
}
}
package io.lumine.cosmetics.players.wardrobe;
import java.util.Collection;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerQuitEvent;
import com.google.common.collect.Sets;
import io.lumine.cosmetics.MCCosmeticsPlugin;
import io.lumine.cosmetics.api.cosmetics.Cosmetic;
import io.lumine.cosmetics.api.players.wardrobe.Mannequin;
import io.lumine.cosmetics.api.players.wardrobe.WardrobeManager;
import io.lumine.cosmetics.api.players.wardrobe.WardrobeTracker;
import io.lumine.cosmetics.constants.CosmeticType;
import io.lumine.utils.Events;
import io.lumine.utils.Players;
import io.lumine.utils.Schedulers;
import io.lumine.utils.particles.Particle;
import io.lumine.utils.plugin.PluginComponent;
import lombok.Getter;
public class WardrobeTrackerImpl extends PluginComponent<MCCosmeticsPlugin> implements WardrobeTracker,Runnable {
private static final int DESPAWN_RADIUS = 8*8;
@Getter private final WardrobeManager manager;
@Getter private final Player player;
private final Location location;
@Getter private Mannequin mannequin;
private Collection<Class<? extends Cosmetic>> cleanup = Sets.newConcurrentHashSet();
public WardrobeTrackerImpl(WardrobeExecutor manager, Player player) {
super(manager.getPlugin());
this.manager = manager;
this.player = player;
this.location = player.getLocation();
location.setPitch(0);
location.add(location.getDirection().normalize().multiply(4));
Events.subscribe(PlayerQuitEvent.class)
.filter(event -> event.getPlayer().equals(player))
.handler(event -> this.terminate())
.bindWith(this);
Schedulers.async().runRepeating(this, 20, 20).bindWith(this);
this.mannequin = manager.getPlugin().getVolatileCodeHandler().createMannequin(this, player, location);
Players.playSound(player, location, Sound.ENTITY_CHICKEN_EGG);
Particle.CLOUD.create()
.at(location.clone().add(0,1,0))
.amount(50)
.offset(0.5F, 1F, 0.5F)
.speed(0.1F)
.send(player);
}
public void setCleanupWhenDone(Class<? extends Cosmetic> type) {
cleanup.add(type);
}
@Override
public void run() {
if(player.getLocation().distanceSquared(location) > DESPAWN_RADIUS) {
this.terminate();
}
}
@Override
public boolean terminate() {
if(this.mannequin != null) {
for(var clazz : cleanup) {
var type = CosmeticType.get(clazz).type();
getPlugin().getCosmetics().getManager(type).ifPresent(manager -> {
manager.unequipMannequin(mannequin);
});
}
this.mannequin.despawn();
this.mannequin = null;
manager.closeWardrobe(player);
Players.playSound(player, location, Sound.BLOCK_CONDUIT_DEACTIVATE);
Particle.ENCHANTMENT_TABLE.create()
.at(location.clone().add(0,1,0))
.amount(50)
.offset(0.5F, 1F, 0.5F)
.speed(0.1F)
.send(player);
}
return super.terminate();
}
}
......@@ -86,10 +86,14 @@
<id>lumine-snapshots</id>
<url>https://mvn.lumine.io/repository/maven-snapshots/</url>
</repository>
<repository>
<repository>
<id>lumine-test</id>
<url>https://mvn.lumine.io/repository/maven-test/</url>
</repository>
<repository>
<id>paper-repo</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
<repository>
<id>minecraft-libraries</id>
<name>Minecraft Libraries</name>
......@@ -141,6 +145,12 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>authlib</artifactId>
<version>3.11.50</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>datafixerupper</artifactId>
......
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