diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/Mount.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/Mount.java index 41d66c896..eb248c71e 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/Mount.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/Mount.java @@ -1,5 +1,7 @@ package mineplex.game.clans.clans.mounts; +import java.util.function.Consumer; + import org.bukkit.Material; import org.bukkit.craftbukkit.v1_8_R3.entity.CraftHorse; import org.bukkit.entity.EntityType; @@ -12,25 +14,68 @@ import org.bukkit.inventory.ItemStack; import mineplex.core.common.TriConsumer; import mineplex.core.common.util.C; import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; import net.minecraft.server.v1_8_R3.GenericAttributes; public class Mount { + private static final long HIT_REGEN_COOLDOWN = 30000; + private Player _owner; private CraftHorse _entity; + private SkinType _skin; + private final int _strength; + private long _lastHit; + private int _hits; - public Mount(Player owner, CraftHorse entity) + public Mount(Player owner, CraftHorse entity, SkinType skin, int strength) { _owner = owner; _entity = entity; + _skin = skin; + _strength = strength; + _lastHit = System.currentTimeMillis(); + _hits = 0; } - public void despawn() + public Player getOwner() { - UtilServer.CallEvent(new MountDespawnEvent(this)); + return _owner; + } + + public CraftHorse getEntity() + { + return _entity; + } + + public void update() + { + if (_skin != null) + { + _skin.onUpdate(_entity); + } + if (UtilTime.elapsed(_lastHit, HIT_REGEN_COOLDOWN) && _hits > 0) + { + _hits--; + _lastHit = System.currentTimeMillis(); + } + } + + public void despawn(boolean forced) + { + UtilServer.CallEvent(new MountDespawnEvent(this, forced)); _entity.remove(); } + public void handleHit() + { + _hits++; + if (_hits == _strength) + { + despawn(true); + } + } + public static enum SkinType { ; @@ -41,8 +86,9 @@ public class Mount private final Color _color; private final Variant _variant; private final Style _style; + private final Consumer _onUpdate; - private SkinType(int id, String packageName, String displayName, Color color, Variant variant, Style style) + private SkinType(int id, String packageName, String displayName, Color color, Variant variant, Style style, Consumer onUpdate) { _id = id; _packageName = packageName; @@ -50,6 +96,7 @@ public class Mount _color = color; _variant = variant; _style = style; + _onUpdate = onUpdate; } public int getId() @@ -82,6 +129,11 @@ public class Mount return _style; } + public void onUpdate(CraftHorse horse) + { + _onUpdate.accept(horse); + } + public static SkinType getFromId(int id) { for (SkinType type : SkinType.values()) @@ -98,55 +150,63 @@ public class Mount public static enum MountType { - HORSE(1, C.cGold + "Horse", (owner, skin, stats) -> + HORSE(1, C.cWhite + "Horse", Material.IRON_BARDING, (owner, skin, stats) -> { CraftHorse horse = (CraftHorse) owner.getWorld().spawnEntity(owner.getLocation(), EntityType.HORSE); horse.setAdult(); horse.setAgeLock(true); horse.setBreed(false); - horse.setVariant(skin.getVariant()); - horse.setColor(skin.getColor()); - horse.setStyle(skin.getStyle()); + if (skin != null) + { + horse.setVariant(skin.getVariant()); + horse.setColor(skin.getColor()); + horse.setStyle(skin.getStyle()); + } horse.setTamed(true); horse.getInventory().setSaddle(new ItemStack(Material.SADDLE)); horse.setOwner(owner); - horse.setJumpStrength(stats.JumpStrength); - horse.getHandle().getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(stats.Speed); + horse.setJumpStrength(MountManager.getJump(stats.JumpStars)); + horse.getHandle().getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(MountManager.getSpeed(stats.SpeedStars)); horse.setCustomNameVisible(true); - horse.setCustomName(owner.getName() + "'s " + skin.getDisplayName()); - horse.setPassenger(owner); - Mount mount = new Mount(owner, horse); + horse.setCustomName(owner.getName() + "'s " + (skin == null ? "Horse" : skin.getDisplayName())); + //horse.setPassenger(owner); + Mount mount = new Mount(owner, horse, skin, MountManager.getStrength(stats.StrengthStars)); UtilServer.CallEvent(new MountSpawnEvent(mount)); }), - STORAGE(2, C.cGold + "Storage", (owner, skin, stats) -> + DONKEY(2, C.cWhite + "Donkey", Material.GOLD_BARDING, (owner, skin, stats) -> { CraftHorse horse = (CraftHorse) owner.getWorld().spawnEntity(owner.getLocation(), EntityType.HORSE); horse.setAdult(); horse.setAgeLock(true); horse.setBreed(false); - horse.setVariant(skin.getVariant()); + if (skin != null) + { + horse.setVariant(skin.getVariant()); + } horse.setTamed(true); horse.getInventory().setSaddle(new ItemStack(Material.SADDLE)); horse.setOwner(owner); - horse.setJumpStrength(stats.JumpStrength); - horse.getHandle().getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(stats.Speed); + horse.setJumpStrength(MountManager.getJump(stats.JumpStars)); + horse.getHandle().getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(MountManager.getSpeed(stats.SpeedStars)); horse.setCustomNameVisible(true); - horse.setCustomName(owner.getName() + "'s " + skin.getDisplayName()); + horse.setCustomName(owner.getName() + "'s " + (skin == null ? "Donkey" : skin.getDisplayName())); horse.setCarryingChest(true); - horse.setPassenger(owner); - Mount mount = new Mount(owner, horse); + //horse.setPassenger(owner); + Mount mount = new Mount(owner, horse, skin, MountManager.getStrength(stats.StrengthStars)); UtilServer.CallEvent(new MountSpawnEvent(mount)); }) ; private final int _id; private final String _displayName; + private final Material _displayType; private final TriConsumer _spawnHandler; - private MountType(int id, String displayName, TriConsumer spawnHandler) + private MountType(int id, String displayName, Material displayType, TriConsumer spawnHandler) { _id = id; _displayName = displayName; + _displayType = displayType; _spawnHandler = spawnHandler; } @@ -160,6 +220,11 @@ public class Mount return _displayName; } + public Material getDisplayType() + { + return _displayType; + } + public void spawn(Player owner, SkinType skinType, MountStatToken statToken) { _spawnHandler.accept(owner, skinType, statToken); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountClaimToken.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountClaimToken.java new file mode 100644 index 000000000..63c0b11d6 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountClaimToken.java @@ -0,0 +1,103 @@ +package mineplex.game.clans.clans.mounts; + +import org.bukkit.ChatColor; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.game.clans.clans.mounts.Mount.MountType; + +public class MountClaimToken +{ + private final String STAR = "✩"; + + public final int JumpStars; + public final int SpeedStars; + public final int StrengthStars; + public final MountType Type; + + public MountClaimToken(int jumpStars, int speedStars, int strengthStars, MountType type) + { + JumpStars = jumpStars; + SpeedStars = speedStars; + StrengthStars = strengthStars; + Type = type; + } + + public ItemStack toItem() + { + ItemBuilder builder = new ItemBuilder(Type.getDisplayType()); + builder.setTitle(Type.getDisplayName() + " Mount Token"); + String strength = C.cYellow; + for (int i = 0; i < StrengthStars; i++) + { + strength += STAR; + } + builder.addLore(C.cPurple + "Strength: " + strength); + String speed = C.cYellow; + for (int i = 0; i < SpeedStars; i++) + { + speed += STAR; + } + builder.addLore(C.cPurple + "Speed: " + speed); + String jump = C.cYellow; + for (int i = 0; i < JumpStars; i++) + { + jump += STAR; + } + builder.addLore(C.cPurple + "Jump: " + jump); + builder.addLore(C.cRed); + builder.addLore(C.cDGreen + "Right-Click While Holding to Consume"); + + return builder.build(); + } + + public static MountClaimToken fromItem(ItemStack item) + { + if (!item.hasItemMeta() || !item.getItemMeta().hasLore()) + { + return null; + } + + MountType type = null; + for (MountType check : MountType.values()) + { + if (check.getDisplayType() == item.getType()) + { + type = check; + break; + } + } + if (type == null) + { + return null; + } + + int strength = -1; + int speed = -1; + int jump = -1; + + for (String lore : item.getItemMeta().getLore()) + { + if (ChatColor.stripColor(lore).startsWith("Strength: ")) + { + strength = ChatColor.stripColor(lore).replace("Strength: ", "").length(); + } + if (ChatColor.stripColor(lore).startsWith("Speed: ")) + { + speed = ChatColor.stripColor(lore).replace("Speed: ", "").length(); + } + if (ChatColor.stripColor(lore).startsWith("Jump: ")) + { + jump = ChatColor.stripColor(lore).replace("Jump: ", "").length(); + } + } + + if (strength <= 0 || speed <= 0 || jump <= 0) + { + return null; + } + + return new MountClaimToken(strength, speed, jump, type); + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountDespawnEvent.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountDespawnEvent.java index 2641dcb56..9d4745116 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountDespawnEvent.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountDespawnEvent.java @@ -11,10 +11,12 @@ public class MountDespawnEvent extends Event private static final HandlerList handlers = new HandlerList(); private final Mount _mount; + private final boolean _forced; - public MountDespawnEvent(Mount mount) + public MountDespawnEvent(Mount mount, boolean forced) { _mount = mount; + _forced = forced; } public Mount getMount() @@ -22,6 +24,11 @@ public class MountDespawnEvent extends Event return _mount; } + public boolean isForced() + { + return _forced; + } + public HandlerList getHandlers() { return handlers; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountManager.java index 5202606c2..74db30a98 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountManager.java @@ -2,36 +2,380 @@ package mineplex.game.clans.clans.mounts; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; import java.util.UUID; +import java.util.WeakHashMap; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftHorse; +import org.bukkit.entity.Horse; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.inventory.HorseInventory; import org.bukkit.plugin.java.JavaPlugin; import mineplex.core.MiniDbClientPlugin; import mineplex.core.account.CoreClientManager; +import mineplex.core.command.CommandBase; import mineplex.core.common.Pair; +import mineplex.core.common.Rank; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.donation.DonationManager; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; import mineplex.game.clans.clans.mounts.Mount.MountType; import mineplex.game.clans.clans.mounts.Mount.SkinType; +import mineplex.game.clans.clans.mounts.gui.MountShop; +import mineplex.game.clans.spawn.Spawn; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; import mineplex.serverdata.Utility; public class MountManager extends MiniDbClientPlugin { - private static final double[] JUMP_BOUNDS = {0.5, 2}; - private static final double[] SPEED_BOUNDS = {0.1125, 0.3375}; - private static final int[] STRENGTH_BOUNDS = {1, 3}; + private static final double[] JUMP_STARS = {1, 1.5, 2}; + private static final double[] SPEED_STARS = {0.2, 0.27, 0.33}; + private static final int[] STRENGTH_STARS = {1, 2, 3}; - private MountRepository _repository; + private static final long SUMMON_WARMUP = 5000; + private static final long FORCED_COOLDOWN = 120 * 1000; + private static final long MAX_TIME_DISMOUNTED = 30000; - public MountManager(JavaPlugin plugin, CoreClientManager clientManager) + private static final int MAX_PER_TYPE = 3; + + private final MountRepository _repository; + private final DonationManager _donationManager; + private final MountShop _shop; + + private final Map _spawnedMounts = new HashMap<>(); + private final Map> _summoning = new WeakHashMap<>(); + + public MountManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager) { super("Clans Mount Manager", plugin, clientManager); + + _repository = new MountRepository(plugin, this); + _donationManager = donationManager; + + _shop = new MountShop(this); + + addCommand(new CommandBase(this, Rank.ALL, "mounts", "mount") + { + @Override + public void Execute(Player caller, String[] args) + { + _shop.attemptShopOpen(caller); + } + }); + + addCommand(new CommandBase(this, Rank.ADMIN, "givemount") + { + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 4) + { + UtilPlayer.message(caller, F.main(getName(), "Usage: /" + _aliasUsed + " , , , ")); + return; + } + + Integer speed = 0; + Integer jump = 0; + Integer strength = 0; + MountType type = null; + + try + { + speed = Integer.parseInt(args[0]); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(getName(), "Invalid speed!")); + return; + } + + try + { + jump = Integer.parseInt(args[1]); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(getName(), "Invalid jump!")); + return; + } + + try + { + strength = Integer.parseInt(args[2]); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(getName(), "Invalid strength!")); + return; + } + + try + { + type = MountType.valueOf(args[3]); + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main(getName(), "Invalid type!")); + return; + } + + caller.getInventory().addItem(new MountClaimToken(jump, speed, strength, type).toItem()); + } + }); + } + + public DonationManager getDonationManager() + { + return _donationManager; + } + + public MountRepository getRepository() + { + return _repository; + } + + public boolean summonMount(Player player, MountToken token) + { + if (_summoning.containsKey(player)) + { + return false; + } + if (Spawn.getInstance().isSafe(player.getLocation())) + { + return false; + } + if (!Recharge.Instance.usable(player, "Mount Spawn Delay")) + { + return false; + } + _spawnedMounts.values().stream().filter(mount -> mount.getOwner().getEntityId() == player.getEntityId()).findFirst().ifPresent(mount -> mount.despawn(false)); + _summoning.put(player, Pair.create(System.currentTimeMillis(), token)); + UtilPlayer.message(player, F.main(getName(), "You are now summoning your mount! Please remain still for 5 seconds!")); + return true; } public void giveMount(Player player, MountType type) { - Pair tokens = Get(player).grantMount(type, SPEED_BOUNDS, JUMP_BOUNDS, STRENGTH_BOUNDS); + Pair tokens = Get(player).grantMount(type); _repository.saveMount(ClientManager.getAccountId(player), tokens.getLeft(), tokens.getRight()); } + + public void giveMount(Player player, MountClaimToken token) + { + Pair tokens = Get(player).grantMount(token.Type, token.SpeedStars, token.JumpStars, token.StrengthStars); + _repository.saveMount(ClientManager.getAccountId(player), tokens.getLeft(), tokens.getRight()); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() == UpdateType.TICK) + { + Iterator> mountIterator = _spawnedMounts.entrySet().iterator(); + while (mountIterator.hasNext()) + { + Entry entry = mountIterator.next(); + if (entry.getKey().isDead() || !entry.getKey().isValid()) + { + mountIterator.remove(); + entry.getValue().despawn(false); + continue; + } + if (Spawn.getInstance().isSafe(entry.getKey().getLocation())) + { + mountIterator.remove(); + entry.getValue().despawn(false); + continue; + } + if (entry.getKey().getPassenger() == null) + { + if (UtilEnt.GetMetadata(entry.getKey(), "DISMOUNT_TIME") != null) + { + Long dismount = (Long) UtilEnt.GetMetadata(entry.getKey(), "DISMOUNT_TIME"); + if (UtilTime.elapsed(dismount.longValue(), MAX_TIME_DISMOUNTED)) + { + mountIterator.remove(); + entry.getValue().despawn(false); + continue; + } + } + else + { + UtilEnt.SetMetadata(entry.getKey(), "DISMOUNT_TIME", System.currentTimeMillis()); + } + } + else + { + UtilEnt.removeMetadata(entry.getKey(), "DISMOUNT_TIME"); + } + entry.getValue().update(); + } + + Iterator>> summoningIterator = _summoning.entrySet().iterator(); + while (summoningIterator.hasNext()) + { + Entry> entry = summoningIterator.next(); + if (UtilTime.elapsed(entry.getValue().getLeft(), SUMMON_WARMUP)) + { + summoningIterator.remove(); + entry.getValue().getRight().Type.spawn(entry.getKey(), entry.getValue().getRight().Skin, Get(entry.getKey()).getStatToken(entry.getValue().getRight())); + continue; + } + if (UtilEnt.hasFlag(entry.getKey(), "MOVED_WHILE_SUMMONING_MOUNT")) + { + summoningIterator.remove(); + UtilEnt.removeFlag(entry.getKey(), "MOVED_WHILE_SUMMONING_MOUNT"); + continue; + } + } + } + } + + @EventHandler + public void onMove(PlayerMoveEvent event) + { + if (_summoning.containsKey(event.getPlayer()) && !UtilEnt.hasFlag(event.getPlayer(), "MOVED_WHILE_SUMMONING_MOUNT")) + { + Block from = event.getFrom().getBlock(); + Block to = event.getTo().getBlock(); + + if (from.getX() == to.getX() && from.getY() == to.getY() && from.getZ() == to.getZ()) + { + return; + } + UtilEnt.addFlag(event.getPlayer(), "MOVED_WHILE_SUMMONING_MOUNT"); + } + } + + @EventHandler + public void onSummon(MountSpawnEvent event) + { + _spawnedMounts.put(event.getMount().getEntity(), event.getMount()); + UtilPlayer.message(event.getMount().getOwner(), F.main(getName(), "Your mount has spawned!")); + } + + @EventHandler + public void onDespawn(MountDespawnEvent event) + { + _spawnedMounts.remove(event.getMount().getEntity()); + event.getMount().getEntity().eject(); + event.getMount().getEntity().remove(); + UtilPlayer.message(event.getMount().getOwner(), F.main(getName(), "Your mount has despawned!")); + if (event.isForced()) + { + Recharge.Instance.use(event.getMount().getOwner(), "Mount Spawn Delay", FORCED_COOLDOWN, false, false); + } + } + + @EventHandler + public void onUseToken(PlayerInteractEvent event) + { + if (!UtilEvent.isAction(event, ActionType.R)) + { + return; + } + if (event.getItem() == null) + { + return; + } + MountClaimToken token = MountClaimToken.fromItem(event.getItem()); + if (token == null) + { + return; + } + + event.setCancelled(true); + + if (Get(event.getPlayer()).getAmountOwned(token.Type) >= MAX_PER_TYPE) + { + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You have reached the maximum amount of that type of mount!")); + return; + } + + giveMount(event.getPlayer(), token); + UtilPlayer.message(event.getPlayer(), F.main(getName(), "You have redeemed your mount!")); + event.getPlayer().getInventory().setItemInHand(null); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void handleHits(CustomDamageEvent event) + { + if (event.GetDamageeEntity() == null) + { + return; + } + Mount[] spawned = _spawnedMounts.values().toArray(new Mount[_spawnedMounts.size()]); + for (Mount mount : spawned) + { + if (mount.getEntity().getEntityId() == event.GetDamageeEntity().getEntityId()) + { + if (event.GetDamagerPlayer(true) != null && event.GetDamagerPlayer(true).getEntityId() == mount.getOwner().getEntityId()) + { + event.SetCancelled("Damaging own mount"); + return; + } + event.setDamagee(mount.getOwner()); + mount.handleHit(); + return; + } + if (mount.getOwner().getEntityId() == event.GetDamageeEntity().getEntityId()) + { + mount.handleHit(); + return; + } + } + } + + @EventHandler + public void onEditHorseInventory(InventoryClickEvent event) + { + if (!(event.getClickedInventory() instanceof HorseInventory)) + { + return; + } + + event.setCancelled(true); + } + + @EventHandler + public void mountInteract(PlayerInteractEntityEvent event) + { + if (!(event.getRightClicked() instanceof Horse)) + { + return; + } + Optional opt = _spawnedMounts.entrySet().stream().filter(entry -> entry.getKey().getEntityId() == event.getRightClicked().getEntityId()).map(Entry::getValue).findAny(); + if (!opt.isPresent()) + { + return; + } + if (opt.get().getOwner().getEntityId() == event.getPlayer().getEntityId()) + { + return; + } + + UtilPlayer.message(event.getPlayer(), F.main(getName(), "This is not your Mount!")); + event.setCancelled(true); + } @Override public String getQuery(int accountId, String uuid, String name) @@ -60,4 +404,22 @@ public class MountManager extends MiniDbClientPlugin { return new MountOwnerData(); } + + public static double getSpeed(int stars) + { + stars = Math.min(Math.max(1, stars), 3); + return SPEED_STARS[stars - 1]; + } + + public static double getJump(int stars) + { + stars = Math.min(Math.max(1, stars), 3); + return JUMP_STARS[stars - 1]; + } + + public static int getStrength(int stars) + { + stars = Math.min(Math.max(1, stars), 3); + return STRENGTH_STARS[stars - 1]; + } } \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountOwnerData.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountOwnerData.java index 4cc8408ff..f962de9a7 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountOwnerData.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountOwnerData.java @@ -18,9 +18,24 @@ public class MountOwnerData return _mounts.entrySet().stream().filter(entry -> onlyInitialized ? entry.getKey().Id != -1 : true).map(entry -> Pair.create(entry.getKey(), entry.getValue())).collect(Collectors.toList()); } + public List> getOwnedMounts(boolean onlyInitialized, MountType type) + { + return _mounts.entrySet().stream().filter(entry -> (onlyInitialized ? entry.getKey().Id != -1 : true) && type == entry.getKey().Type).map(entry -> Pair.create(entry.getKey(), entry.getValue())).collect(Collectors.toList()); + } + + public MountStatToken getStatToken(MountToken mountToken) + { + return _mounts.get(mountToken); + } + public boolean ownsMount(MountType type) { - return _mounts.keySet().stream().anyMatch(token->token.Type == type); + return getAmountOwned(type) > 0; + } + + public long getAmountOwned(MountType type) + { + return _mounts.keySet().stream().filter(token -> token.Type == type).count(); } public void acceptLoad(MountToken token, MountStatToken statToken) @@ -28,33 +43,38 @@ public class MountOwnerData _mounts.put(token, statToken); } - public Pair grantMount(MountType type, double[] speedRange, double[] jumpRange, int[] strengthRange) + public Pair grantMount(MountType type, int speed, int jump, int strength) { - double speed = UtilMath.random(speedRange[0], speedRange[1]); - double jump = UtilMath.random(jumpRange[0], jumpRange[1]); - int strength = UtilMath.rRange(strengthRange[0], strengthRange[1]); - MountToken token = new MountToken(); token.Type = type; MountStatToken statToken = new MountStatToken(); - statToken.JumpStrength = jump; - statToken.Speed = speed; - statToken.Strength = strength; + statToken.JumpStars = jump; + statToken.SpeedStars = speed; + statToken.StrengthStars = strength; _mounts.put(token, statToken); return Pair.create(token, statToken); } - public int[] revokeMount(MountType type) + public Pair grantMount(MountType type) + { + int speed = UtilMath.rRange(1, 3); + int jump = UtilMath.rRange(1, 3); + int strength = UtilMath.rRange(1, 3); + + return grantMount(type, speed, jump, strength); + } + + public Integer[] removeMounts(MountType type) { Integer[] array = _mounts.keySet().stream().filter(token->token.Type == type).map(token->token.Id).toArray(size->new Integer[size]); _mounts.keySet().removeIf(token->token.Type == type); - int[] returnArray = new int[array.length]; - for (int i = 0; i < returnArray.length; i++) - { - returnArray[i] = array[i]; - } - return returnArray; + return array; + } + + public void removeMount(int id) + { + _mounts.keySet().removeIf(token->token.Id == id); } } \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountRepository.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountRepository.java index 03894e819..821c887d2 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountRepository.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountRepository.java @@ -3,6 +3,7 @@ package mineplex.game.clans.clans.mounts; import java.sql.Connection; import java.sql.SQLException; import java.util.List; +import java.util.function.Consumer; import org.bukkit.plugin.java.JavaPlugin; @@ -22,16 +23,16 @@ public class MountRepository extends RepositoryBase + "accountId INT NOT NULL," + "mountTypeId INT NOT NULL," + "mountSkinId INT NOT NULL," - + "UNIQUE INDEX typeIndex (accountId, mountTypeId)," + + "INDEX typeIndex (mountTypeId)," + "INDEX skinIndex (mountSkinId)," + "PRIMARY KEY (id));"; private static final String CREATE_MOUNT_STATS_TABLE = "CREATE TABLE IF NOT EXISTS clansMountStats (mountId INT NOT NULL," - + "accountId INT NOT NULL," + "statToken VARCHAR(20) NOT NULL," + "PRIMARY KEY (mountId));"; - private static final String SAVE_MOUNT = "INSERT INTO accountClansMounts (accountId, mountTypeId, mountSkinId) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE mountSkinId=VALUES(mountSkinId);"; + private static final String INSERT_MOUNT = "INSERT INTO accountClansMounts (accountId, mountTypeId, mountSkinId) VALUES (?, ?, ?);"; + private static final String SAVE_MOUNT = "UPDATE accountClansMounts SET mountSkinId=? WHERE id=?;"; private static final String SAVE_MOUNT_STATS = "INSERT INTO clansMountStats (mountId, statToken) VALUES (?, ?) ON DUPLICATE KEY UPDATE statToken=VALUES(statToken);"; private static final String DELETE_MOUNT = "DELETE FROM accountClansMounts WHERE id=?;"; private static final String DELETE_MOUNT_STATS = "DELETE FROM clansMountStats WHERE mountId=?;"; @@ -58,17 +59,17 @@ public class MountRepository extends RepositoryBase { if (token.Id == -1) { - executeInsert(connection, SAVE_MOUNT, idResult -> + executeInsert(connection, INSERT_MOUNT, idResult -> { if (idResult.next()) { token.Id = idResult.getInt(1); } - }, null, new ColumnInt("accountId", accountId), new ColumnInt("mountTypeId", token.Type.getId()), new ColumnInt("mountSkinId", token.Skin.getId())); + }, null, new ColumnInt("accountId", accountId), new ColumnInt("mountTypeId", token.Type.getId()), new ColumnInt("mountSkinId", token.Skin == null ? -1 : token.Skin.getId())); } else { - executeUpdate(connection, SAVE_MOUNT, null, new ColumnInt("accountId", accountId), new ColumnInt("mountTypeId", token.Type.getId()), new ColumnInt("mountSkinId", token.Skin.getId())); + executeUpdate(connection, SAVE_MOUNT, null, new ColumnInt("mountSkinId", token.Skin == null ? -1 : token.Skin.getId()), new ColumnInt("id", token.Id)); } if (token.Id == -1) { @@ -101,23 +102,23 @@ public class MountRepository extends RepositoryBase if (token.Id == -1) { - executeInsert(connection, SAVE_MOUNT, idResult -> + executeInsert(connection, INSERT_MOUNT, idResult -> { if (idResult.next()) { token.Id = idResult.getInt(1); } - }, null, new ColumnInt("accountId", accountId), new ColumnInt("mountTypeId", token.Type.getId()), new ColumnInt("mountSkinId", token.Skin.getId())); + }, null, new ColumnInt("accountId", accountId), new ColumnInt("mountTypeId", token.Type.getId()), new ColumnInt("mountSkinId", token.Skin == null ? -1 : token.Skin.getId())); } else { - executeUpdate(connection, SAVE_MOUNT, null, new ColumnInt("accountId", accountId), new ColumnInt("mountTypeId", token.Type.getId()), new ColumnInt("mountSkinId", token.Skin.getId())); + executeUpdate(connection, SAVE_MOUNT, null, new ColumnInt("mountSkinId", token.Skin == null ? -1 : token.Skin.getId()), new ColumnInt("id", token.Id)); } if (token.Id == -1) { continue; } - executeUpdate(connection, SAVE_MOUNT_STATS, null, new ColumnInt("mountId", token.Id), new ColumnVarChar("statToken", 20, Utility.serialize(statToken))); + executeUpdate(connection, SAVE_MOUNT_STATS, null, new ColumnInt("mountId", token.Id), new ColumnVarChar("statToken", 100, Utility.serialize(statToken))); } } catch (SQLException e) @@ -131,7 +132,7 @@ public class MountRepository extends RepositoryBase * Deletes a mount from the database * @param token The mount to delete */ - public void deleteMount(final MountToken token) + public void deleteMount(final MountToken token, final Consumer after) { if (token.Id == -1) { @@ -141,6 +142,13 @@ public class MountRepository extends RepositoryBase { executeUpdate(DELETE_MOUNT, new ColumnInt("id", token.Id)); executeUpdate(DELETE_MOUNT_STATS, new ColumnInt("mountId", token.Id)); + if (after != null) + { + _mountManager.runSync(() -> + { + after.accept(token.Id); + }); + } }); } @@ -148,7 +156,7 @@ public class MountRepository extends RepositoryBase * Deletes an array from the database * @param ids The mount ids to delete */ - public void deleteMounts(final int[] ids) + public void deleteMounts(final int[] ids, final Runnable after) { if (ids.length <= 0) { @@ -163,6 +171,10 @@ public class MountRepository extends RepositoryBase } executeUpdate(DELETE_MOUNT.replace("id=?;", "id IN (" + idList + ");")); executeUpdate(DELETE_MOUNT_STATS.replace("mountId=?;", "mountId IN (" + idList + ");")); + if (after != null) + { + _mountManager.runSync(after); + } }); } } \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountStatToken.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountStatToken.java index 63f41c590..42517042e 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountStatToken.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/MountStatToken.java @@ -2,7 +2,7 @@ package mineplex.game.clans.clans.mounts; public class MountStatToken { - public double JumpStrength = 0.7; - public double Speed = .2250; - public int Strength = 1; + public int JumpStars = 1; + public int SpeedStars = 1; + public int StrengthStars = 1; } \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountOverviewPage.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountOverviewPage.java new file mode 100644 index 000000000..9dfddf0c0 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountOverviewPage.java @@ -0,0 +1,157 @@ +package mineplex.game.clans.clans.mounts.gui; + +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.Pair; +import mineplex.core.common.util.C; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.shop.confirmation.ConfirmationCallback; +import mineplex.core.shop.confirmation.ConfirmationPage; +import mineplex.core.shop.confirmation.ConfirmationProcessor; +import mineplex.core.shop.item.IButton; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.mounts.Mount.MountType; +import mineplex.game.clans.clans.mounts.MountManager; +import mineplex.game.clans.clans.mounts.MountStatToken; +import mineplex.game.clans.clans.mounts.MountToken; + +public class MountOverviewPage extends ShopPageBase +{ + private final String STAR = "✩"; + + public MountOverviewPage(MountManager plugin, MountShop shop, String name, Player player) + { + super(plugin, shop, plugin.getClientManager(), plugin.getDonationManager(), name, player, 27); + + buildPage(); + } + + private ItemStack toItem(MountToken mountToken, MountStatToken statToken, boolean overview) + { + ItemBuilder builder = new ItemBuilder(mountToken.Type.getDisplayType()); + builder.setTitle(mountToken.Type.getDisplayName() + " Mount"); + String strength = C.cYellow; + for (int i = 0; i < statToken.StrengthStars; i++) + { + strength += STAR; + } + builder.addLore(C.cPurple + "Strength: " + strength); + String speed = C.cYellow; + for (int i = 0; i < statToken.SpeedStars; i++) + { + speed += STAR; + } + builder.addLore(C.cPurple + "Speed: " + speed); + String jump = C.cYellow; + for (int i = 0; i < statToken.JumpStars; i++) + { + jump += STAR; + } + builder.addLore(C.cPurple + "Jump: " + jump); + if (overview) + { + builder.addLore(C.cRed); + builder.addLore(C.cDGreen + "Left-Click to Summon"); + builder.addLore(C.cDGreen + "Right-Click to Manage Skin"); + builder.addLore(C.cDRed + "Shift Right-Click to Destroy"); + } + + return builder.build(); + } + + @Override + protected void buildPage() + { + int[] horseSlots = {10, 11, 12}; + List> horses = getPlugin().Get(getPlayer()).getOwnedMounts(true, MountType.HORSE); + int[] donkeySlots = {14, 15, 16}; + List> donkeys = getPlugin().Get(getPlayer()).getOwnedMounts(true, MountType.DONKEY); + + for (int i = 0; i < horseSlots.length; i++) + { + int slot = horseSlots[i]; + ItemStack item = new ItemBuilder(Material.INK_SACK).setData((short)8).setTitle(C.cRed).build(); + IButton button = null; + if (horses.size() > i) + { + Pair tokens = horses.get(i); + item = toItem(tokens.getLeft(), tokens.getRight(), true); + button = new IButton() + { + @Override + public void onClick(Player player, ClickType clickType) + { + if (clickType == ClickType.LEFT) + { + if (!getPlugin().summonMount(player, tokens.getLeft())) + { + playDenySound(player); + } + } + else if (clickType == ClickType.RIGHT) + { + playDenySound(player); + //getShop().openPageForPlayer(player, page); + } + else if (clickType == ClickType.SHIFT_RIGHT) + { + getShop().openPageForPlayer(player, new ConfirmationPage(player, MountOverviewPage.this, new ConfirmationProcessor() + { + @Override + public void init(Inventory inventory) {} + + @Override + public void process(ConfirmationCallback callback) + { + getPlugin().getRepository().deleteMount(tokens.getLeft(), id -> + { + getPlugin().Get(getPlayer()).removeMount(id.intValue()); + callback.resolve("Mount successfully deleted!"); + }); + } + }, toItem(tokens.getLeft(), tokens.getRight(), false))); + } + } + }; + } + addButton(slot, item, button); + } + for (int i = 0; i < donkeySlots.length; i++) + { + int slot = donkeySlots[i]; + ItemStack item = new ItemBuilder(Material.INK_SACK).setData((short)8).setTitle(C.cRed).build(); + IButton button = null; + if (donkeys.size() > i) + { + Pair tokens = donkeys.get(i); + item = toItem(tokens.getLeft(), tokens.getRight(), true); + button = new IButton() + { + @Override + public void onClick(Player player, ClickType clickType) + { + if (clickType == ClickType.LEFT) + { + + } + else if (clickType == ClickType.RIGHT) + { + + } + else if (clickType == ClickType.SHIFT_RIGHT) + { + + } + } + }; + } + addButton(slot, item, button); + } + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountShop.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountShop.java new file mode 100644 index 000000000..d6dd454d5 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/mounts/gui/MountShop.java @@ -0,0 +1,21 @@ +package mineplex.game.clans.clans.mounts.gui; + +import org.bukkit.entity.Player; + +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.game.clans.clans.mounts.MountManager; + +public class MountShop extends ShopBase +{ + public MountShop(MountManager plugin) + { + super(plugin, plugin.getClientManager(), plugin.getDonationManager(), "Manage Mounts"); + } + + @Override + protected ShopPageBase> buildPagesFor(Player player) + { + return new MountOverviewPage(getPlugin(), this, "Manage Mounts", player); + } +} \ No newline at end of file