From 3b637ca60017860980e2318bf53e2f2b3ad85e1e Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 2 Aug 2017 19:56:48 +0100 Subject: [PATCH] Implement client side shop morphs --- .../mineplex/core/gadget/GadgetManager.java | 6 + .../gamemodifiers/GameCosmeticManager.java | 31 +++ .../gamemodifiers/moba/ShopMorphType.java | 99 ++++++++++ .../moba/shopmorph/ShopMorphGadget.java | 37 ++++ .../arcade/game/games/moba/shop/MobaShop.java | 184 +++++++++--------- .../games/moba/shop/MobaShopCategoryMenu.java | 2 +- .../game/games/moba/shop/MobaShopNPC.java | 107 ++++++++++ 7 files changed, 374 insertions(+), 92 deletions(-) create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/moba/ShopMorphType.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/moba/shopmorph/ShopMorphGadget.java create mode 100644 Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/shop/MobaShopNPC.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java index 1dcc6e303..8411680eb 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java @@ -104,6 +104,8 @@ import mineplex.core.gadget.gadgets.gamemodifiers.GameCosmeticType; import mineplex.core.gadget.gadgets.gamemodifiers.minestrike.GameModifierMineStrikeSkin; import mineplex.core.gadget.gadgets.gamemodifiers.minestrike.MineStrikeSkin; import mineplex.core.gadget.gadgets.gamemodifiers.moba.HeroSkinGadget; +import mineplex.core.gadget.gadgets.gamemodifiers.moba.ShopMorphType; +import mineplex.core.gadget.gadgets.gamemodifiers.moba.shopmorph.ShopMorphGadget; import mineplex.core.gadget.gadgets.hat.HatItem; import mineplex.core.gadget.gadgets.hat.HatType; import mineplex.core.gadget.gadgets.item.ItemBatGun; @@ -768,6 +770,10 @@ public class GadgetManager extends MiniPlugin @Override public void addGadgets() { + for (ShopMorphType type : ShopMorphType.values()) + { + addGameGadget(new ShopMorphGadget(getManager(), this, type)); + } } }; } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/GameCosmeticManager.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/GameCosmeticManager.java index 57e9da73c..e4ec0598c 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/GameCosmeticManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/GameCosmeticManager.java @@ -8,9 +8,13 @@ import java.util.Map.Entry; import java.util.function.Predicate; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; import mineplex.core.MiniPlugin; import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.gadget.event.GadgetChangeEvent; +import mineplex.core.gadget.event.GadgetChangeEvent.GadgetState; +import mineplex.core.gadget.types.Gadget; import mineplex.core.gadget.types.GameModifierGadget; import mineplex.core.game.GameDisplay; @@ -32,6 +36,33 @@ public class GameCosmeticManager extends MiniPlugin _cosmetics.put(type, cosmetics); } + @EventHandler + public void gadgetEquip(GadgetChangeEvent event) + { + if (event.getGadgetState() != GadgetState.ENABLED) + { + return; + } + + Gadget gadget = event.getGadget(); + + if (gadget instanceof GameModifierGadget) + { + GameCosmeticCategory category = ((GameModifierGadget) gadget).getCategory(); + + if (category.isAllowingMultiple()) + { + return; + } + + // Disable all other gadgets if not allowing multiple. + category.getGadgets().stream() + .filter(gadget1 -> !gadget.equals(gadget1)) + .forEach(gadget1 -> gadget.disable(event.getPlayer())); + } + + } + public GameModifierGadget getActiveCosmetic(Player player, GameDisplay gameType, String categoryName) { return getActiveCosmetic(player, gameType, categoryName, null); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/moba/ShopMorphType.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/moba/ShopMorphType.java new file mode 100644 index 000000000..342a71e85 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/moba/ShopMorphType.java @@ -0,0 +1,99 @@ +package mineplex.core.gadget.gadgets.gamemodifiers.moba; + +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; + +import mineplex.core.common.skin.SkinData; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.disguise.disguises.DisguiseCow; +import mineplex.core.disguise.disguises.DisguiseLiving; +import mineplex.core.disguise.disguises.DisguiseMooshroom; +import mineplex.core.disguise.disguises.DisguisePlayer; +import mineplex.core.disguise.disguises.DisguiseSheep; + +public enum ShopMorphType +{ + + SHEEP("Sheep", Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.SHEEP), DisguiseSheep.class), + COW("Cow", Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.COW), DisguiseCow.class), + MOOSHROOM("Mooshroom", Material.MONSTER_EGG, UtilEnt.getEntityEggData(EntityType.MUSHROOM_COW), DisguiseMooshroom.class), + BOB_ROSS("Bob Ross", Material.PAINTING, SkinData.BOB_ROSS) + + ; + + private final String _name; + private final Material _material; + private final byte _materialData; + private final Class _clazz; + private final SkinData _skinData; + + ShopMorphType(String name, Material material, Class clazz) + { + this(name, material, (byte) 0, clazz); + } + + ShopMorphType(String name, Material material, byte materialData, Class clazz) + { + this(name, material, materialData, clazz, null); + } + + ShopMorphType(String name, Material material, SkinData skinData) + { + this(name, material, (byte) 0, DisguisePlayer.class, skinData); + } + + ShopMorphType(String name, Material material, byte materialData, SkinData skinData) + { + this(name, material, materialData, DisguisePlayer.class, skinData); + } + + ShopMorphType(String name, Material material, byte materialData, Class clazz, SkinData skinData) + { + _name = name; + _material = material; + _materialData = materialData; + _clazz = clazz; + _skinData = skinData; + } + + public DisguiseLiving createInstance(LivingEntity entity) + { + try + { + return _clazz.getConstructor(Entity.class).newInstance(entity); + } + catch (Exception e) + { + e.printStackTrace(); + } + + return null; + } + + public String getName() + { + return _name; + } + + public Material getMaterial() + { + return _material; + } + + public byte getMaterialData() + { + return _materialData; + } + + public Class getClazz() + { + return _clazz; + } + + public SkinData getSkinData() + { + return _skinData; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/moba/shopmorph/ShopMorphGadget.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/moba/shopmorph/ShopMorphGadget.java new file mode 100644 index 000000000..de511ef71 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/gamemodifiers/moba/shopmorph/ShopMorphGadget.java @@ -0,0 +1,37 @@ +package mineplex.core.gadget.gadgets.gamemodifiers.moba.shopmorph; + +import org.bukkit.Material; + +import mineplex.core.common.util.C; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.gadgets.gamemodifiers.GameCosmeticCategory; +import mineplex.core.gadget.gadgets.gamemodifiers.moba.ShopMorphType; +import mineplex.core.gadget.types.GameModifierGadget; +import mineplex.core.itemstack.ItemStackFactory; + +public class ShopMorphGadget extends GameModifierGadget +{ + + private final ShopMorphType _type; + + public ShopMorphGadget(GadgetManager manager, GameCosmeticCategory category, ShopMorphType type) + { + this(manager, category, type, -2); + } + + public ShopMorphGadget(GadgetManager manager, GameCosmeticCategory category, ShopMorphType type, int cost) + { + super(manager, category, type.getName(), new String[] { + C.cGray + "Changes the Gold Upgrades NPC", + C.cGray + "to " + (type.getSkinData() == null ? "a " + type.getName() : type.getName()) + ".", + }, cost, Material.GLASS, (byte) 0); + + _type = type; + setDisplayItem(type.getSkinData() == null ? ItemStackFactory.Instance.CreateStack(type.getMaterial(), type.getMaterialData()) : type.getSkinData().getSkull()); + } + + public ShopMorphType getType() + { + return _type; + } +} diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/shop/MobaShop.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/shop/MobaShop.java index 224ee61bc..5fa7f9a98 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/shop/MobaShop.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/shop/MobaShop.java @@ -1,19 +1,44 @@ package nautilus.game.arcade.game.games.moba.shop; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.minecraft.server.v1_8_R3.PacketPlayInUseEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerInteractEvent; + import mineplex.core.common.util.C; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilEnt; import mineplex.core.common.util.UtilPlayer; +import mineplex.core.gadget.gadgets.gamemodifiers.moba.shopmorph.ShopMorphGadget; +import mineplex.core.game.GameDisplay; +import mineplex.core.packethandler.PacketHandler.ListenerPriority; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.minecraft.game.core.combat.CombatComponent; import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; import mineplex.minecraft.game.core.condition.events.ConditionApplyEvent; import mineplex.minecraft.game.core.damage.CustomDamageEvent; + import nautilus.game.arcade.events.GameStateChangeEvent; import nautilus.game.arcade.events.PlayerGameRespawnEvent; import nautilus.game.arcade.game.Game.GameState; +import nautilus.game.arcade.game.GameTeam; import nautilus.game.arcade.game.games.moba.Moba; import nautilus.game.arcade.game.games.moba.MobaPlayer; import nautilus.game.arcade.game.games.moba.MobaRole; @@ -26,34 +51,18 @@ import nautilus.game.arcade.game.games.moba.shop.hunter.MobaHunterShop; import nautilus.game.arcade.game.games.moba.shop.mage.MobaMageShop; import nautilus.game.arcade.game.games.moba.shop.warrior.MobaWarriorShop; import nautilus.game.arcade.game.games.moba.util.MobaConstants; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.entity.Villager; -import org.bukkit.entity.Villager.Profession; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.player.PlayerInteractAtEntityEvent; -import org.bukkit.event.player.PlayerInteractEvent; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; public class MobaShop implements Listener { + private static final String NPC_NAME = C.cGoldB + "GOLD UPGRADES"; + static String getNPCName() + { + return NPC_NAME; + } + private final Moba _host; - private final Map _entities; + private final Map _entities; private final Map _roleMenus; private final Map> _upgrades; @@ -71,7 +80,7 @@ public class MobaShop implements Listener _roleMenus.put(MobaRole.MAGE, new MobaMageShop(host, this)); } - @EventHandler + @EventHandler(priority = EventPriority.HIGHEST) public void spawnNpc(GameStateChangeEvent event) { if (event.GetState() != GameState.Prepare) @@ -79,90 +88,93 @@ public class MobaShop implements Listener return; } - List locations = _host.WorldData.GetDataLocs(MobaConstants.SHOP); + ArrayList locations = _host.WorldData.GetDataLocs(MobaConstants.SHOP); _host.CreatureAllowOverride = true; - for (Location location : locations) + for (GameTeam team : _host.GetTeamList()) { - Villager villager = location.getWorld().spawn(location, Villager.class); + Location location = UtilAlg.findClosest(team.GetSpawn(), locations); - villager.setProfession(Profession.LIBRARIAN); - villager.setAgeLock(true); - villager.setRemoveWhenFarAway(false); - villager.setCustomName(C.cGoldB + "GOLD UPGRADES"); - villager.setCustomNameVisible(true); - UtilEnt.vegetate(villager); - UtilEnt.silence(villager, true); - UtilEnt.ghost(villager, true, false); - UtilEnt.CreatureForceLook(villager, 0, UtilAlg.GetYaw(UtilAlg.getTrajectory(villager.getLocation(), _host.GetSpectatorLocation()))); - ((CraftLivingEntity) villager).getHandle().k = false; + for (Player player : team.GetPlayers(true)) + { + ArmorStand stand = location.getWorld().spawn(location, ArmorStand.class); - _entities.put(villager, location); + stand.setRemoveWhenFarAway(false); + stand.setCustomName(getNPCName()); + stand.setCustomNameVisible(true); + UtilEnt.vegetate(stand); + UtilEnt.silence(stand, true); + UtilEnt.ghost(stand, true, false); + UtilEnt.CreatureForceLook(stand, 0, UtilAlg.GetYaw(UtilAlg.getTrajectory(stand.getLocation(), _host.GetSpectatorLocation()))); + + ShopMorphGadget gadget = (ShopMorphGadget) _host.getArcadeManager().getCosmeticManager().getGadgetManager().getGameCosmeticManager().getActiveCosmetic( + player, + GameDisplay.MOBA, + "Shop Morph" + ); + + MobaShopNPC npc = new MobaShopNPC(this, player, stand, gadget); + + _host.getArcadeManager().getPacketHandler().addPacketHandler(npc, ListenerPriority.NORMAL, false, PacketPlayInUseEntity.class, PacketPlayOutSpawnEntityLiving.class); + _entities.put(player, npc); + } } _host.CreatureAllowOverride = false; } - public void openShop(MobaPlayer player) + @EventHandler + public void cleanup(GameStateChangeEvent event) + { + if (event.GetState() != GameState.End && event.GetState() != GameState.Dead) + { + return; + } + + _entities.forEach((player, npc) -> + { + _host.getArcadeManager().getPacketHandler().removePacketHandler(npc); + }); + } + + public void openShop(Player player) { if (_host.GetState() != GameState.Live) { return; } - MobaShopMenu menu = _roleMenus.get(player.getRole()); + MobaPlayer mobaPlayer = _host.getMobaData(player); + + if (mobaPlayer == null) + { + return; + } + + MobaShopMenu menu = _roleMenus.get(mobaPlayer.getRole()); if (menu == null) { - player.getPlayer().sendMessage(F.main("Game", "There isn't an upgrade shop for that kit yet.")); + player.sendMessage(F.main("Game", "There isn't an upgrade shop for that kit yet.")); return; } - menu.open(player.getPlayer()); - } - - @EventHandler - public void npcMove(UpdateEvent event) - { - if (event.getType() != UpdateType.FASTEST) - { - return; - } - - for (Entry entry : _entities.entrySet()) - { - LivingEntity entity = entry.getKey(); - Location location = entry.getValue(); - - ((CraftEntity) entity).getHandle().setPosition(location.getX(), location.getY(), location.getZ()); - } + menu.open(player); } @EventHandler public void npcDamage(CustomDamageEvent event) { - for (LivingEntity entity : _entities.keySet()) + for (MobaShopNPC npc : _entities.values()) { - if (entity.equals(event.GetDamageeEntity())) + if (npc.getStand().equals(event.GetDamageeEntity())) { - entity.setFireTicks(0); + npc.getStand().setFireTicks(0); event.SetCancelled("Shop NPC"); return; } } } - @EventHandler - public void entityDamage(EntityDamageByEntityEvent event) - { - npcInteract(event.getEntity(), event.getDamager()); - } - - @EventHandler - public void entityInteract(PlayerInteractAtEntityEvent event) - { - npcInteract(event.getRightClicked(), event.getPlayer()); - } - private void npcInteract(Entity clicked, Entity clicker) { if (!(clicker instanceof Player) || UtilPlayer.isSpectator(clicker)) @@ -176,15 +188,7 @@ public class MobaShop implements Listener { if (clicked.equals(shop)) { - MobaPlayer data = _host.getMobaData(player); - - if (data == null) - { - player.sendMessage(F.main("Game", "You don't appear to have any data?")); - return; - } - - openShop(data); + openShop(player); return; } } @@ -298,14 +302,7 @@ public class MobaShop implements Listener return; } - MobaPlayer mobaPlayer = _host.getMobaData(event.getPlayer()); - - if (mobaPlayer == null) - { - return; - } - - openShop(mobaPlayer); + openShop(event.getPlayer()); } /* @@ -571,4 +568,9 @@ public class MobaShop implements Listener } } } + + public Moba getHost() + { + return _host; + } } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/shop/MobaShopCategoryMenu.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/shop/MobaShopCategoryMenu.java index 66c061c14..f2a8b27aa 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/shop/MobaShopCategoryMenu.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/shop/MobaShopCategoryMenu.java @@ -125,7 +125,7 @@ public class MobaShopCategoryMenu extends Menu @Override public void onClick(Player player, ClickType clickType) { - _shop.openShop(_host.getMobaData(player)); + _shop.openShop(player); } } } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/shop/MobaShopNPC.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/shop/MobaShopNPC.java new file mode 100644 index 000000000..2fc7b3880 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/shop/MobaShopNPC.java @@ -0,0 +1,107 @@ +package nautilus.game.arcade.game.games.moba.shop; + +import java.util.UUID; + +import net.minecraft.server.v1_8_R3.PacketPlayInUseEntity; +import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving; + +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; + +import com.mojang.authlib.GameProfile; + +import mineplex.core.common.skin.SkinData; +import mineplex.core.disguise.disguises.DisguiseInsentient; +import mineplex.core.disguise.disguises.DisguiseLiving; +import mineplex.core.disguise.disguises.DisguisePlayer; +import mineplex.core.disguise.disguises.DisguiseVillager; +import mineplex.core.gadget.gadgets.gamemodifiers.moba.shopmorph.ShopMorphGadget; +import mineplex.core.packethandler.IPacketHandler; +import mineplex.core.packethandler.PacketInfo; + +public class MobaShopNPC implements IPacketHandler +{ + + private final MobaShop _shop; + private final Player _player; + private final ArmorStand _stand; + private final ShopMorphGadget _gadget; + + public MobaShopNPC(MobaShop shop, Player player, ArmorStand stand, ShopMorphGadget gadget) + { + _shop = shop; + _player = player; + _stand = stand; + _gadget = gadget; + + disguise(); + } + + private void disguise() + { + DisguiseLiving disguise; + + if (_gadget == null) + { + DisguiseVillager villager = new DisguiseVillager(_stand); + villager.setName(MobaShop.getNPCName()); + villager.setCustomNameVisible(true); + disguise = villager; + } + else if (_gadget.getType().getSkinData() != null) + { + GameProfile profile = new GameProfile(UUID.randomUUID(), SkinData.getUnusedSkullName()); + profile.getProperties().clear(); + profile.getProperties().put("textures", _gadget.getType().getSkinData().getProperty()); + + DisguisePlayer player = new DisguisePlayer(_stand, profile); + player.setReplaceOriginalName(false, 0); + disguise = player; + } + else + { + DisguiseInsentient insentient = (DisguiseInsentient) _gadget.getType().createInstance(_stand); + + if (insentient == null) + { + return; + } + + insentient.setName(MobaShop.getNPCName()); + insentient.setCustomNameVisible(true); + disguise = insentient; + } + + _shop.getHost().getArcadeManager().GetDisguise().disguise(disguise); + } + + @Override + public void handle(PacketInfo packetInfo) + { + Player player = packetInfo.getPlayer(); + + if (packetInfo.getPacket() instanceof PacketPlayOutSpawnEntityLiving && !player.equals(_player)) + { + PacketPlayOutSpawnEntityLiving packet = (PacketPlayOutSpawnEntityLiving) packetInfo.getPacket(); + + if (packet.a == _stand.getEntityId()) + { + packetInfo.setCancelled(true); + } + } + else if (packetInfo.getPacket() instanceof PacketPlayInUseEntity) + { + PacketPlayInUseEntity packet = (PacketPlayInUseEntity) packetInfo.getPacket(); + + if (packet.a == _stand.getEntityId()) + { + _shop.openShop(packetInfo.getPlayer()); + } + } + } + + public ArmorStand getStand() + { + return _stand; + } +}