From 11fb02a5943144bec775db9abc1f8cf361833f64 Mon Sep 17 00:00:00 2001 From: fooify Date: Tue, 30 Jun 2015 09:03:43 -0700 Subject: [PATCH 001/377] add stained glass to list of blocks that can be broken in quiver --- .../src/nautilus/game/arcade/game/games/quiver/Quiver.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/quiver/Quiver.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/quiver/Quiver.java index bbd123b34..6a364cca3 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/quiver/Quiver.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/quiver/Quiver.java @@ -75,6 +75,8 @@ public class Quiver extends SoloGame this.SpawnDistanceRequirement = 16; this.BlockBreakAllow.add(102); this.BlockBreakAllow.add(20); + this.BlockBreakAllow.add(Material.STAINED_GLASS_PANE.getId()); + this.BlockBreakAllow.add(Material.STAINED_GLASS.getId()); _scoreObj = Scoreboard.GetScoreboard().registerNewObjective("Kills", "dummy"); _scoreObj.setDisplaySlot(DisplaySlot.BELOW_NAME); From d2cc8d507794a9175aaca77266f7b40faa1e70a2 Mon Sep 17 00:00:00 2001 From: fooify Date: Tue, 30 Jun 2015 09:19:21 -0700 Subject: [PATCH 002/377] fix grammar bug --- .../game/arcade/game/games/minestrike/MineStrike.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/MineStrike.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/MineStrike.java index b1900ffd7..3d38fad83 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/MineStrike.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/MineStrike.java @@ -1868,7 +1868,11 @@ public class MineStrike extends TeamGame ChatColor color = ChatColor.GRAY; if (winner != null) { - winnerLine= winner.GetColor() + C.Bold + winner.GetName() + " has won the round!"; + if(winner.GetName().contains("Bombers")) { + winnerLine= winner.GetColor() + C.Bold + winner.GetName() + " have won the round!"; + } else { + winnerLine= winner.GetColor() + C.Bold + winner.GetName() + " has won the round!"; + } addScore(winner); drawScoreboard(); color = winner.GetColor(); From c824a39058c98ce0f765d7fb1334bf0c2115bc8c Mon Sep 17 00:00:00 2001 From: fooify Date: Tue, 30 Jun 2015 13:33:41 -0700 Subject: [PATCH 003/377] ishh wanted it...k --- .../src/mineplex/core/message/MessageManager.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/message/MessageManager.java b/Plugins/Mineplex.Core/src/mineplex/core/message/MessageManager.java index b81e7fbb1..34956ecda 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/message/MessageManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/message/MessageManager.java @@ -224,6 +224,11 @@ public class MessageManager extends MiniClientPlugin UtilPlayer.message(from, C.cPurple + to.getName() + " is often AFK or minimized, due to plugin development."); UtilPlayer.message(from, C.cPurple + "Please be patient if he does not reply instantly."); } + + if(to.getName().equals("ishh")) + { + UtilPlayer.message(from, C.cPurple + "Hi, my name is ishh. If I don't respond to your message, please be patient and try again later!"); + } // Log // Logger().logChat("Private Message", from, to.getName(), message); From b9b9c5f80164c4b0e3f3608102bd97725700cd72 Mon Sep 17 00:00:00 2001 From: fooify Date: Tue, 30 Jun 2015 13:37:46 -0700 Subject: [PATCH 004/377] ishh also wanted this :P (let me know if I should remove it) --- .../src/mineplex/core/stats/command/GiveStatCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/stats/command/GiveStatCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/stats/command/GiveStatCommand.java index 35293a2b5..b718505d0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/stats/command/GiveStatCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/stats/command/GiveStatCommand.java @@ -13,7 +13,7 @@ public class GiveStatCommand extends CommandBase { public GiveStatCommand(StatsManager plugin) { - super(plugin, Rank.OWNER, "givestat"); + super(plugin, Rank.ADMIN, "givestat"); } @Override From 6d42be4d139e04c0db513ab15b58a5f1828357c9 Mon Sep 17 00:00:00 2001 From: fooify Date: Wed, 1 Jul 2015 07:17:41 -0700 Subject: [PATCH 005/377] fix spleef lava issue --- .../src/nautilus/game/arcade/game/games/spleef/Spleef.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/spleef/Spleef.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/spleef/Spleef.java index 6716ac290..dcfcfa9e1 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/spleef/Spleef.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/spleef/Spleef.java @@ -182,7 +182,7 @@ public class Spleef extends SoloGame public void BlockFade(Block block, Player player, boolean slowDamage) { - if (block.getTypeId() == 7) + if (block.getType() == Material.BEDROCK || block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA) return; //Prevent Super Hunger from Bow From 6dc7384c8215468af115632f8c137c3bba27d3d0 Mon Sep 17 00:00:00 2001 From: fooify Date: Wed, 1 Jul 2015 08:16:14 -0700 Subject: [PATCH 006/377] fix creeper smash exploding lava and bedrock --- .../arcade/kit/perks/PerkCreeperExplode.java | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java index 4e1c99624..9a7c2b172 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java @@ -1,40 +1,42 @@ package nautilus.game.arcade.kit.perks; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import org.bukkit.Location; -import org.bukkit.Sound; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.block.Action; -import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.util.Vector; - import mineplex.core.common.util.C; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilAction; import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilParticle; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; import mineplex.core.disguise.disguises.DisguiseBase; import mineplex.core.disguise.disguises.DisguiseCreeper; import mineplex.core.recharge.Recharge; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.minecraft.game.core.damage.CustomDamageEvent; -import nautilus.game.arcade.kit.Perk; import nautilus.game.arcade.kit.SmashPerk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.util.Vector; + public class PerkCreeperExplode extends SmashPerk { private HashMap _active = new HashMap(); @@ -144,7 +146,11 @@ public class PerkCreeperExplode extends SmashPerk player.getWorld().playSound(player.getLocation(), Sound.EXPLODE, (float)(2 + Math.random()*4), (float)(Math.random() + 0.2)); //Blocks - Manager.GetExplosion().BlockExplosion(UtilBlock.getInRadius(player.getLocation(), 12).keySet(), player.getLocation(), false); + Collection blocks = UtilBlock.getInRadius(player.getLocation(), 12).keySet(); + for(Block bl : blocks) + if(bl.getType() == Material.LAVA || bl.getType() == Material.BEDROCK) blocks.remove(bl); + + Manager.GetExplosion().BlockExplosion(blocks, player.getLocation(), false); //Remove Spawns Iterator spawnIterator = Manager.GetGame().GetTeam(player).GetSpawns().iterator(); From b7476cec5ed957e7ea0f1a746c2d408693fc3eab Mon Sep 17 00:00:00 2001 From: fooify Date: Wed, 1 Jul 2015 08:25:17 -0700 Subject: [PATCH 007/377] prevent STATIONARY_LAVA from breaking in creeper smash --- .../src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java index 9a7c2b172..0fe298495 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java @@ -148,7 +148,7 @@ public class PerkCreeperExplode extends SmashPerk //Blocks Collection blocks = UtilBlock.getInRadius(player.getLocation(), 12).keySet(); for(Block bl : blocks) - if(bl.getType() == Material.LAVA || bl.getType() == Material.BEDROCK) blocks.remove(bl); + if(bl.getType() == Material.STATIONARY_LAVA || bl.getType() == Material.LAVA || bl.getType() == Material.BEDROCK) blocks.remove(bl); Manager.GetExplosion().BlockExplosion(blocks, player.getLocation(), false); From 8574c0bdeb793cb9a5de7079341cf4598190bdf6 Mon Sep 17 00:00:00 2001 From: fooify Date: Wed, 1 Jul 2015 09:58:45 -0700 Subject: [PATCH 008/377] fix turfforts bug --- .../game/games/turfforts/TurfForts.java | 58 +++++++++++-------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/turfforts/TurfForts.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/turfforts/TurfForts.java index 87efca5ee..a250c4f7f 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/turfforts/TurfForts.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/turfforts/TurfForts.java @@ -4,30 +4,6 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Effect; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.craftbukkit.v1_7_R4.entity.CraftArrow; -import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; -import org.bukkit.entity.Arrow; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; -import org.bukkit.event.block.BlockEvent; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.bukkit.event.entity.EntityShootBowEvent; -import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.entity.ProjectileHitEvent; - -import net.minecraft.server.v1_7_R4.EntityArrow; -import net.minecraft.server.v1_7_R4.Item; import mineplex.core.common.util.C; import mineplex.core.common.util.F; import mineplex.core.common.util.MapUtil; @@ -54,6 +30,31 @@ import nautilus.game.arcade.kit.Kit; import nautilus.game.arcade.stats.BehindEnemyLinesStatTracker; import nautilus.game.arcade.stats.BlockShreadStatTracker; import nautilus.game.arcade.stats.TheComebackStatTracker; +import net.minecraft.server.v1_7_R4.EntityArrow; +import net.minecraft.server.v1_7_R4.Item; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftArrow; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.entity.ProjectileHitEvent; public class TurfForts extends TeamGame { @@ -281,6 +282,15 @@ public class TurfForts extends TeamGame } } + @EventHandler + public void BlockBreak(BlockBreakEvent event) + { + if (event.isCancelled()) // this statement might save just a small amount of time + return; + + if(getArcadeManager().isSpectator(event.getPlayer())) event.setCancelled(true); + } + @EventHandler public void BlockPlace(BlockPlaceEvent event) { From 4495468c7f905539979a18f852210686ba873dcd Mon Sep 17 00:00:00 2001 From: fooify Date: Wed, 1 Jul 2015 15:50:07 -0700 Subject: [PATCH 009/377] fix concurrentmodificationexception --- .../game/arcade/kit/perks/PerkCreeperExplode.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java index 0fe298495..6498ec8d8 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java @@ -147,9 +147,11 @@ public class PerkCreeperExplode extends SmashPerk //Blocks Collection blocks = UtilBlock.getInRadius(player.getLocation(), 12).keySet(); - for(Block bl : blocks) - if(bl.getType() == Material.STATIONARY_LAVA || bl.getType() == Material.LAVA || bl.getType() == Material.BEDROCK) blocks.remove(bl); - + synchronized(blocks) + { + for(Block bl : blocks) + if(bl.getType() == Material.STATIONARY_LAVA || bl.getType() == Material.LAVA || bl.getType() == Material.BEDROCK) blocks.remove(bl); + } Manager.GetExplosion().BlockExplosion(blocks, player.getLocation(), false); //Remove Spawns From 04c863c0eb521d0d9d000530c2ad9b3c4c86f826 Mon Sep 17 00:00:00 2001 From: fooify Date: Wed, 1 Jul 2015 16:10:41 -0700 Subject: [PATCH 010/377] FOOIFY IS A NOOB OKAY --- .../game/arcade/kit/perks/PerkCreeperExplode.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java index 6498ec8d8..40beca013 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java @@ -147,10 +147,12 @@ public class PerkCreeperExplode extends SmashPerk //Blocks Collection blocks = UtilBlock.getInRadius(player.getLocation(), 12).keySet(); - synchronized(blocks) - { - for(Block bl : blocks) - if(bl.getType() == Material.STATIONARY_LAVA || bl.getType() == Material.LAVA || bl.getType() == Material.BEDROCK) blocks.remove(bl); + Iterator iter = blocks.iterator(); + + while (iter.hasNext()) { + Block b = iter.next(); + + if(b.getType() == Material.STATIONARY_LAVA || b.getType() == Material.LAVA || b.getType() == Material.BEDROCK) blocks.remove(b); } Manager.GetExplosion().BlockExplosion(blocks, player.getLocation(), false); From d1e43066842895aa6f46d1e2b825d693f770a5e0 Mon Sep 17 00:00:00 2001 From: fooify Date: Wed, 1 Jul 2015 16:38:10 -0700 Subject: [PATCH 011/377] fix this agaaaaain --- .../src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java index 40beca013..318017f71 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkCreeperExplode.java @@ -152,7 +152,7 @@ public class PerkCreeperExplode extends SmashPerk while (iter.hasNext()) { Block b = iter.next(); - if(b.getType() == Material.STATIONARY_LAVA || b.getType() == Material.LAVA || b.getType() == Material.BEDROCK) blocks.remove(b); + if(b.getType() == Material.STATIONARY_LAVA || b.getType() == Material.LAVA || b.getType() == Material.BEDROCK) iter.remove();; } Manager.GetExplosion().BlockExplosion(blocks, player.getLocation(), false); From e7b51ac1c12521bbd6ca4054f308cfe5ac38552a Mon Sep 17 00:00:00 2001 From: fooify Date: Wed, 1 Jul 2015 16:40:15 -0700 Subject: [PATCH 012/377] add jnr_dev to updaterank --- .../src/mineplex/core/account/command/UpdateRank.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/command/UpdateRank.java b/Plugins/Mineplex.Core/src/mineplex/core/account/command/UpdateRank.java index 8a7efe8fe..b6a6a251b 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/account/command/UpdateRank.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/account/command/UpdateRank.java @@ -52,7 +52,7 @@ public class UpdateRank extends CommandBase final Rank rank = tempRank; - if (rank == Rank.ADMIN || rank == Rank.YOUTUBE || rank == Rank.TWITCH || rank == Rank.MODERATOR || rank == Rank.HELPER || rank == Rank.ALL || rank == Rank.MAPDEV || rank == Rank.SNR_MODERATOR) + if (rank == Rank.ADMIN || rank == Rank.YOUTUBE || rank == Rank.TWITCH || rank == Rank.MODERATOR || rank == Rank.JNR_DEV || rank == Rank.HELPER || rank == Rank.ALL || rank == Rank.MAPDEV || rank == Rank.SNR_MODERATOR) { if (rank == Rank.ADMIN && !Plugin.hasRank(caller, Rank.LT)) { From 70d351adaea275b3b9af5c33dc9e0e26a57feeb9 Mon Sep 17 00:00:00 2001 From: fooify Date: Wed, 1 Jul 2015 16:58:16 -0700 Subject: [PATCH 013/377] fix getting snowballs from bedrock --- .../src/nautilus/game/arcade/game/games/spleef/Spleef.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/spleef/Spleef.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/spleef/Spleef.java index dcfcfa9e1..a18493971 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/spleef/Spleef.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/spleef/Spleef.java @@ -175,7 +175,7 @@ public class Spleef extends SoloGame BlockFade(event.getBlock(), event.getPlayer(), false); //Snowball - if (GetKit(event.getPlayer()) instanceof KitSnowballer) + if (GetKit(event.getPlayer()) instanceof KitSnowballer && event.getBlock().getType() != Material.BEDROCK) if (!UtilInv.contains(event.getPlayer(), Material.SNOW_BALL, (byte)0, 16)) event.getPlayer().getInventory().addItem(ItemStackFactory.Instance.CreateStack(Material.SNOW_BALL)); } From 6008e58c12318fe26e389781d20d60fa465ea79c Mon Sep 17 00:00:00 2001 From: William Burns Date: Wed, 8 Jul 2015 09:49:41 +0100 Subject: [PATCH 014/377] Added map selection to MPS. --- .../privateServer/button/ChooseMapButton.java | 41 ++++++++++++++++++ .../gui/privateServer/page/ChooseMapPage.java | 43 +++++++++++++++++++ .../gui/privateServer/page/SetGamePage.java | 21 +++++++-- 3 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/button/ChooseMapButton.java create mode 100644 Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/ChooseMapPage.java diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/button/ChooseMapButton.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/button/ChooseMapButton.java new file mode 100644 index 000000000..1dbc380a9 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/button/ChooseMapButton.java @@ -0,0 +1,41 @@ +package nautilus.game.arcade.gui.privateServer.button; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import mineplex.core.shop.item.IButton; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.GameType; +import nautilus.game.arcade.gui.privateServer.PrivateServerShop; + +/** + * Created by WilliamTiger. + * All the code and any API's associated with it + * are not to be used anywhere else without written + * consent of William Burns. 2015. + * 08/07/2015 + */ +public class ChooseMapButton implements IButton +{ + private ArcadeManager _arcadeManager; + private PrivateServerShop _privateServerShop; + private GameType _gameType; + private String _map; + + public ChooseMapButton(ArcadeManager arcadeManager, PrivateServerShop privateServerShop, GameType gameType, String map) + { + _arcadeManager = arcadeManager; + _privateServerShop = privateServerShop; + _gameType = gameType; + _map = map; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + _arcadeManager.GetGameCreationManager().MapPref = _map; + _arcadeManager.GetGame().setGame(_gameType, player, true); + player.closeInventory(); + return; + } +} diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/ChooseMapPage.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/ChooseMapPage.java new file mode 100644 index 000000000..d1c062387 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/ChooseMapPage.java @@ -0,0 +1,43 @@ +package nautilus.game.arcade.gui.privateServer.page; + +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import mineplex.core.shop.item.ShopItem; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.GameType; +import nautilus.game.arcade.gui.privateServer.PrivateServerShop; +import nautilus.game.arcade.gui.privateServer.button.ChooseMapButton; + +/** + * Created by WilliamTiger. + * All the code and any API's associated with it + * are not to be used anywhere else without written + * consent of William Burns. 2015. + * 08/07/2015 + */ +public class ChooseMapPage extends BasePage +{ + private GameType _gameType; + + public ChooseMapPage(ArcadeManager plugin, PrivateServerShop shop, Player player, GameType gameType) + { + super(plugin, shop, "Choose Map", player); + _gameType = gameType; + + buildPage(); + } + + @Override + protected void buildPage() + { + addBackButton(4); + + int slot = 0; + for (String cur : getPlugin().LoadFiles(_gameType.GetName())){ + ChooseMapButton btn = new ChooseMapButton(getPlugin(), getShop(), _gameType, cur); + addButton(slot, new ShopItem(Material.MAP, "cur", new String[]{"§7Click to select map."}, 1, false), btn); + slot++; + } + } +} diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/SetGamePage.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/SetGamePage.java index b8ca9a28e..5f41f6a13 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/SetGamePage.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/SetGamePage.java @@ -62,15 +62,28 @@ public class SetGamePage extends BasePage private void addGameButton(int slot, final GameType type) { - String infoString = ChatColor.RESET + C.cGray + "Click to make this next Game Type"; - ShopItem shopItem = new ShopItem(type.GetMaterial(), type.GetMaterialData(), type.GetLobbyName(), new String[]{infoString}, 1, false, false); + String infoString = ChatColor.RESET + C.cGray + "Make this next Game Type"; + String space = ""; + String left = ChatColor.YELLOW + "Left-Click " + C.cGray + "for a §drandom map§7."; + String right = ChatColor.YELLOW + "Right-Click " + C.cGray + "to §6choose map§7."; + ShopItem shopItem = new ShopItem(type.GetMaterial(), type.GetMaterialData(), type.GetLobbyName(), new String[]{infoString, space, left, right}, 1, false, false); addButton(slot, shopItem, new IButton() { @Override public void onClick(Player player, ClickType clickType) { - getPlugin().GetGame().setGame(type, player, true); - player.closeInventory(); + if (clickType == ClickType.LEFT) + { + getPlugin().GetGame().setGame(type, player, true); + player.closeInventory(); + return; + } + else if (clickType == ClickType.RIGHT) + { + getShop().openPageForPlayer(player, new ChooseMapPage(getPlugin(), getShop(), player, type)); + return; + } + } }); } From 5d34716521dc4795b3fbfeb6d3447d7b579f3da6 Mon Sep 17 00:00:00 2001 From: fooify Date: Wed, 8 Jul 2015 06:20:40 -0700 Subject: [PATCH 015/377] squirrel! --- .../src/mineplex/core/achievement/AchievementManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java index 4fe166860..f0d47baed 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java @@ -212,6 +212,8 @@ public class AchievementManager extends MiniPlugin level = -level; else if (sender.getName().equalsIgnoreCase("B2_mp")) return 101; + else if (sender.getName().equalsIgnoreCase("fooify")) + level = 404; else if (rank.Has(Rank.OWNER)) level = Math.max(level, 50 + get(sender, Achievement.GLOBAL_GEM_HUNTER).getLevel()); else if (rank.Has(Rank.ADMIN)) From 3ba7ba259cc620a5f7968492bd72e13f44bf5cef Mon Sep 17 00:00:00 2001 From: William Burns Date: Wed, 8 Jul 2015 15:24:16 +0100 Subject: [PATCH 016/377] Added map selection to MPS. --- Plugins/.idea/artifacts/Nautilus_Game_Arcade_jar.xml | 2 ++ Plugins/.idea/codeStyleSettings.xml | 1 + .../game/arcade/gui/privateServer/page/ChooseMapPage.java | 4 ++-- .../game/arcade/gui/privateServer/page/SetGamePage.java | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Plugins/.idea/artifacts/Nautilus_Game_Arcade_jar.xml b/Plugins/.idea/artifacts/Nautilus_Game_Arcade_jar.xml index 3f5cae6e4..2fb39df09 100644 --- a/Plugins/.idea/artifacts/Nautilus_Game_Arcade_jar.xml +++ b/Plugins/.idea/artifacts/Nautilus_Game_Arcade_jar.xml @@ -18,6 +18,8 @@ + + \ No newline at end of file diff --git a/Plugins/.idea/codeStyleSettings.xml b/Plugins/.idea/codeStyleSettings.xml index 8e890f86b..44295e3d8 100644 --- a/Plugins/.idea/codeStyleSettings.xml +++ b/Plugins/.idea/codeStyleSettings.xml @@ -37,6 +37,7 @@ + + + - - + \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java index b5e12e2e3..7b92598b3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java @@ -1,9 +1,14 @@ package mineplex.core.votifier; +import java.util.UUID; + import mineplex.serverdata.commands.ServerCommand; public class RedisVotifierCommand extends ServerCommand { + private UUID _voterUUID; + + public RedisVotifierCommand() { diff --git a/Plugins/Mineplex.Votifier/plugin.yml b/Plugins/Mineplex.Votifier/plugin.yml index dca987662..75a40f893 100644 --- a/Plugins/Mineplex.Votifier/plugin.yml +++ b/Plugins/Mineplex.Votifier/plugin.yml @@ -1,3 +1,3 @@ -name: Hub +name: MineplexVotifier main: mineplex.votifier.Votifier version: 0.1 \ No newline at end of file diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java index 8ffdc12d8..5ebb77b02 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java @@ -3,6 +3,7 @@ package mineplex.votifier; import org.bukkit.plugin.java.JavaPlugin; import mineplex.core.account.CoreClientManager; +import mineplex.core.command.CommandCenter; import mineplex.core.donation.DonationManager; /** @@ -21,6 +22,7 @@ public class Votifier extends JavaPlugin String webServerAddress = getConfig().getString(WEB_CONFIG); + CommandCenter.Initialize(this); CoreClientManager clientManager = new CoreClientManager(this, webServerAddress); DonationManager donationManager = new DonationManager(this, clientManager, webServerAddress); diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index 977eab053..30646a1f5 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -8,6 +8,7 @@ import com.vexsoftware.votifier.model.VotifierEvent; import mineplex.core.MiniPlugin; import mineplex.core.account.CoreClientManager; import mineplex.core.donation.DonationManager; +import mineplex.core.votifier.RedisVotifierCommand; /** * Created by shaun on 15-08-05. @@ -26,6 +27,8 @@ public class VotifierManager extends MiniPlugin { Vote vote = event.getVote(); + RedisVotifierCommand command = new RedisVotifierCommand(); + System.out.println("New Vote: " + vote.getUsername()); } } \ No newline at end of file From ebbc13c0a4cd3abe3898027a3e5e255e9147fbfc Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Thu, 6 Aug 2015 17:07:52 +0200 Subject: [PATCH 251/377] lowered headshot damage --- .../nautilus/game/arcade/game/games/minestrike/MineStrike.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/MineStrike.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/MineStrike.java index 84ada67ea..eddcab047 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/MineStrike.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/MineStrike.java @@ -1284,7 +1284,7 @@ public class MineStrike extends TeamGame { Bukkit.getPluginManager().callEvent(new PlayerHeadshotEvent(bullet.Shooter, event.GetDamageePlayer())); - event.AddMod(bullet.Shooter.getName(), "Headshot", damage*2, true); + event.AddMod(bullet.Shooter.getName(), "Headshot", damage, true); //Wearing Helmet if (Armor.isArmor(event.GetDamageePlayer().getInventory().getHelmet()) || From d8041ba58247c12105561faec58619f86fccc86e Mon Sep 17 00:00:00 2001 From: Sarah Date: Thu, 6 Aug 2015 20:57:56 +0200 Subject: [PATCH 252/377] Fixing Players can disguise as disguised Players. --- .../hub/commands/DisguiseCommand.java | 33 ++++++++++++------- .../game/arcade/command/DisguiseCommand.java | 19 ++++++----- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java index 2f4adf9ec..9c7a5afb8 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java @@ -81,7 +81,10 @@ public class DisguiseCommand extends CommandBase implements Listener { for(Team team : other.getScoreboard().getTeams()) { - team.removePlayer(caller); + if(team.hasPlayer(caller)) + { + team.removePlayer(caller); + } } other.getScoreboard().getTeam(Plugin.GetClients().Get(caller).GetRank().Name).addPlayer(caller); } @@ -119,6 +122,11 @@ public class DisguiseCommand extends CommandBase implements Listener return; } } + if(_disguisedPlayersNames.containsValue(args[0])) + { + UtilPlayer.message(caller, C.cRed + C.Bold + "this name is already in use!"); + return; + } if(args[0].length() > 16) { UtilPlayer.message(caller, C.cRed + C.Bold + "Invalid Disguise Name: " + ChatColor.RESET + args[0]); @@ -129,19 +137,16 @@ public class DisguiseCommand extends CommandBase implements Listener { CoreClient client = Plugin.GetClients().Get(caller); UUID uuid = UUIDFetcher.getUUIDOf(args[0]); + GameProfile profile = null; try { - final GameProfile profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); - _disguisedPlayers.put(caller, profile); + profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); } catch (Exception e) { uuid = UUIDFetcher.getUUIDOf("Alex"); - final GameProfile profile = new ProfileLoader(uuid.toString(), "Steve").loadProfile(); - _disguisedPlayers.put(caller, profile); + profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); } - _disguisedPlayersNames.put(caller, caller.getName()); - Plugin.GetDisguise().undisguise(caller); Rank otherRank = Rank.ALL; try @@ -155,10 +160,10 @@ public class DisguiseCommand extends CommandBase implements Listener if(otherRank.Has(Rank.TWITCH)) { UtilPlayer.message(caller, C.cRed + C.Bold + "You can't disguise as staff!"); - _disguisedPlayers.remove(caller); - _disguisedPlayersNames.remove(caller); return; } + _disguisedPlayers.put(caller, profile); + _disguisedPlayersNames.put(caller, caller.getName()); client.setDisguisedRank(otherRank); client.setDisguised(true); @@ -195,11 +200,15 @@ public class DisguiseCommand extends CommandBase implements Listener { try { - if(other.getScoreboard().getTeam(Plugin.GetClients().Get(player).GetRank().Name).getPlayers().contains(player)) + for(Team team : other.getScoreboard().getTeams()) { - other.getScoreboard().getTeam(Plugin.GetClients().Get(player).GetRank().Name).removePlayer(player); - other.getScoreboard().getTeam(Plugin.GetClients().Get(player).getDisguisedRank().Name).addPlayer(player); + if(team.hasPlayer(player)) + { + team.removePlayer(player); + } } + other.getScoreboard().getTeam(Plugin.GetClients().Get(player).getDisguisedRank().Name).addPlayer(player); + } catch (NullPointerException exp) {} diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java index f8aeb8e80..ce33a87dc 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java @@ -120,6 +120,11 @@ public class DisguiseCommand extends CommandBase implements Liste return; } } + if(_disguisedPlayersNames.containsValue(args[0])) + { + UtilPlayer.message(caller, C.cRed + C.Bold + "this name is already in use!"); + return; + } if(args[0].length() > 16) { UtilPlayer.message(caller, C.cRed + C.Bold + "Invalid Disguise Name: " + ChatColor.RESET + args[0]); @@ -130,18 +135,16 @@ public class DisguiseCommand extends CommandBase implements Liste { CoreClient client = Plugin.GetClients().Get(caller); UUID uuid = UUIDFetcher.getUUIDOf(args[0]); + GameProfile profile = null; try { - final GameProfile profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); - _disguisedPlayers.put(caller, profile); + profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); } catch (Exception e) { uuid = UUIDFetcher.getUUIDOf("Alex"); - final GameProfile profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); - _disguisedPlayers.put(caller, profile); + profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); } - _disguisedPlayersNames.put(caller, caller.getName()); Rank otherRank = Rank.ALL; try @@ -151,14 +154,14 @@ public class DisguiseCommand extends CommandBase implements Liste otherRank = other.GetRank(); } catch (NullPointerException exception) - {} + {} if(otherRank.Has(Rank.TWITCH)) { UtilPlayer.message(caller, C.cRed + C.Bold + "You can't disguise as staff!"); - _disguisedPlayers.remove(caller); - _disguisedPlayersNames.remove(caller); return; } + _disguisedPlayers.put(caller, profile); + _disguisedPlayersNames.put(caller, caller.getName()); client.setDisguisedRank(otherRank); client.setDisguised(true); From 44e30a0903a4edcf17f1c5f86a2064db33a04156 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 6 Aug 2015 15:34:56 -0500 Subject: [PATCH 253/377] SimpleGui Improvements, Change daily timer to 20 hours, Add Carl Spin button, Starter code for Spin Gui --- .../src/mineplex/core/gui/SimpleGui.java | 155 +++++++++++------- .../src/mineplex/core/reward/Reward.java | 2 + .../core/reward/rewards/CoinReward.java | 13 +- .../core/reward/rewards/InventoryReward.java | 17 ++ .../core/reward/rewards/RankReward.java | 14 ++ .../reward/rewards/UnknownPackageReward.java | 6 + .../mineplex/hub/bonuses/BonusManager.java | 4 +- .../mineplex/hub/bonuses/gui/BonusGui.java | 9 +- .../src/mineplex/hub/bonuses/gui/SpinGui.java | 14 ++ .../bonuses/gui/buttons/CarlSpinButton.java | 44 +++++ .../bonuses/gui/buttons/DailyBonusButton.java | 45 +++-- .../hub/bonuses/gui/buttons/PollButton.java | 11 +- .../bonuses/gui/buttons/RankBonusButton.java | 23 ++- .../hub/bonuses/gui/buttons/RewardButton.java | 47 ++++++ 14 files changed, 294 insertions(+), 110 deletions(-) create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RewardButton.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGui.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGui.java index f6fef3357..0029d1864 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/SimpleGui.java @@ -1,5 +1,6 @@ package mineplex.core.gui; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -15,12 +16,16 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; public class SimpleGui implements ItemRefresher, Listener { - private Map _buttonMap = new HashMap(); +// private Map _buttonMap = new HashMap(); + private GuiItem[] _items; private Player _player; private Plugin _plugin; @@ -30,25 +35,20 @@ public class SimpleGui implements ItemRefresher, Listener public SimpleGui(Plugin plugin, Player player) { - this(plugin, player, null, 0, null); + this(plugin, player, null, 0); } public SimpleGui(Plugin plugin, Player player, int size) { - this(plugin, player, null, size, null); + this(plugin, player, null, size); } public SimpleGui(Plugin plugin, Player player, String title) { - this(plugin, player, title, 0, null); + this(plugin, player, title, 0); } public SimpleGui(Plugin plugin, Player player, String title, int size) - { - this(plugin, player, title, size, null); - } - - public SimpleGui(Plugin plugin, Player player, String title, int size, Map buttonMap) { Validate.notNull(plugin, "The plugin cannot be null!"); @@ -67,93 +67,139 @@ public class SimpleGui implements ItemRefresher, Listener else setTitle(title); - if (buttonMap == null) - this._buttonMap = new HashMap(); - else - this._buttonMap = buttonMap; + updateArray(); + + _inv = createInventory(); + refreshInventory(); + } + + private void updateArray() + { + _items = new GuiItem[_size]; + } + + public void setItem(int i, GuiItem item) + { + Validate.isTrue(i >= 0 && i < _size, "Tried to add a gui item outside of inventory range"); + + GuiItem oldItem = getItem(i); + if (oldItem != null) oldItem.close(); + + if (item != null) + { + _items[i] = item; + item.setup(); + } + + refreshItem(i); + } + + public GuiItem getItem(int i) + { + return _items[i]; } @Override public void openInventory() { - _inv = createInventory(); - + refreshInventory(); UtilPlayer.swapToInventory(_player, _inv); Bukkit.getPluginManager().registerEvents(this, _plugin); } public Inventory createInventory() { - for (GuiItem item : new HashSet(getButtonMap().values())) - { - item.setup(); - } - Inventory inv = Bukkit.createInventory(_player, getSize(), getTitle()); - - for (Entry entry : _buttonMap.entrySet()) - { - inv.setItem(entry.getKey(), entry.getValue().getObject()); - } return inv; } - - + + public void refreshInventory() + { + for (int i = 0; i < _size; i++) + { + refreshItem(i); + } + } + @EventHandler public void inventoryClick(InventoryClickEvent event) { - if (!event.getWhoClicked().equals(_player) || !event.getInventory().equals(_inv)) return; - - GuiItem item = _buttonMap.get(event.getSlot()); - System.out.println(item); - if (item == null) - return; - - event.setCancelled(true); - item.click(event.getClick()); + if (event.getSlot() >= 0 && event.getSlot() < _size) + { + GuiItem item = getItem(event.getSlot()); + if (item == null) + return; + + event.setCancelled(true); + + item.click(event.getClick()); + } + } + + @EventHandler + public void teleport(PlayerTeleportEvent event) + { + if (!event.getPlayer().equals(_player)) + return; + + close(); } @EventHandler public void inventoryClose(InventoryCloseEvent event) { - if (!event.getPlayer().equals(_player)) return; - _inv = null; + close(); + } + + @EventHandler + public void quit(PlayerQuitEvent event) + { + if (!event.getPlayer().equals(_player)) + return; + + close(); + } + + private void close() + { +// _inv = null; // TODO - do we really need to null the inventory? HandlerList.unregisterAll(this); - for (GuiItem item : new HashSet(getButtonMap().values())) + for (int i = 0; i < _size; i++) { - item.close(); + GuiItem item = getItem(i); + if (item != null) item.close(); } } - - @Override + @Deprecated public void refreshItem(GuiItem item) { if (_inv == null) return; - for (Entry entry : getButtonMap().entrySet()) + + for (int i = 0; i < _size; i++) { - if (entry.getValue().equals(item)) - _inv.setItem(entry.getKey(), entry.getValue().getObject()); + if (item.equals(getItem(i))) + refreshItem(i); } } public void refreshItem(int slot) { + GuiItem gi = getItem(slot); - GuiItem gi = getButtonMap().get(slot); - if (_inv == null || gi == null) - return; + ItemStack itemStack = null; + if (gi != null) itemStack = gi.getObject(); - _inv.setItem(slot, gi.getObject()); + _inv.setItem(slot, itemStack); } public int getSize() @@ -192,15 +238,4 @@ public class SimpleGui implements ItemRefresher, Listener Validate.isTrue(size % 9 == 0, "The size " + size + " is not divisible by 9"); this._size = size; } - - public Map getButtonMap() - { - return _buttonMap; - } - - public void setButtonMap(Map bottonMap) - { - this._buttonMap = bottonMap; - } - } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/Reward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/Reward.java index 67659dc64..3bd5e8202 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/Reward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/Reward.java @@ -27,6 +27,8 @@ public abstract class Reward protected abstract RewardData giveRewardCustom(Player player); + public abstract RewardData getFakeRewardData(Player player); + public abstract boolean canGiveReward(Player player); public RewardRarity getRarity() diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java index a0023e137..f6fbd063f 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java @@ -37,7 +37,7 @@ public class CoinReward extends Reward @Override public RewardData giveRewardCustom(Player player) { - int gemsToReward = _random.nextInt(_maxCoinCount - _minCoinCount) + _minCoinCount; + int coinsToReward = _random.nextInt(_maxCoinCount - _minCoinCount) + _minCoinCount; _donationManager.RewardCoins(new Callback() { @@ -46,9 +46,16 @@ public class CoinReward extends Reward { } - }, "Treasure Chest", player.getName(), _donationManager.getClientManager().Get(player).getAccountId(), gemsToReward); + }, "Treasure Chest", player.getName(), _donationManager.getClientManager().Get(player).getAccountId(), coinsToReward); - return new RewardData(getRarity().getColor() + gemsToReward + " Coins", new ItemStack(175)); + return new RewardData(getRarity().getColor() + coinsToReward + " Coins", new ItemStack(175)); + } + + @Override + public RewardData getFakeRewardData(Player player) + { + int coinsToReward = _random.nextInt(_maxCoinCount - _minCoinCount) + _minCoinCount; + return new RewardData(getRarity().getColor() + coinsToReward + " Coins", new ItemStack(175)); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java index 83c219e1c..68e01acf1 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java @@ -62,6 +62,23 @@ public class InventoryReward extends Reward return new RewardData(getRarity().getColor() + amountToGive + " " + _name, _itemStack); } + @Override + public RewardData getFakeRewardData(Player player) + { + int amountToGive; + + if (_minAmount != _maxAmount) + { + amountToGive = _random.nextInt(_maxAmount - _minAmount) + _minAmount; + } + else + { + amountToGive = _minAmount; + } + + return new RewardData(getRarity().getColor() + amountToGive + " " + _name, _itemStack); + } + @Override public boolean canGiveReward(Player player) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java index 815edb705..bbf22db1f 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java @@ -41,6 +41,20 @@ public class RankReward extends Reward return new RewardData(getRarity().getColor() + rank.Name + " Rank", new ItemStack(Material.NETHER_STAR)); } + @Override + public RewardData getFakeRewardData(Player player) + { + Rank rank = null; + if (_clientManager.Get(player).GetRank() == Rank.ALL) rank = Rank.ULTRA; + else if (_clientManager.Get(player).GetRank() == Rank.ULTRA) rank = Rank.HERO; + else if (_clientManager.Get(player).GetRank() == Rank.HERO) rank = Rank.LEGEND; + + if (rank == null) + return new RewardData(getRarity().getColor() + "Rank Upgrade Error", new ItemStack(Material.PAPER)); + + return new RewardData(getRarity().getColor() + rank.Name + " Rank", new ItemStack(Material.NETHER_STAR)); + } + @Override public boolean canGiveReward(Player player) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java index 6e041ee9b..364820d56 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java @@ -48,6 +48,12 @@ public class UnknownPackageReward extends Reward return !_donationManager.Get(player.getName()).OwnsUnknownPackage(_packageName); } + @Override + public RewardData getFakeRewardData(Player player) + { + return new RewardData(getRarity().getColor() + _name, _itemStack); + } + protected String getPackageName() { return _packageName; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index 8750d3bfb..5f2c1b0e9 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -121,8 +121,8 @@ public class BonusManager extends MiniClientPlugin implements I // DAILY BONUS - public static final long TIME_BETWEEN_BONUSES = 1000 * 60 * 60 * 16; - public static final long STREAK_RESET_TIME = 1000 * 60 * 60 * 8; + public static final long TIME_BETWEEN_BONUSES = 1000 * 60 * 60 * 20; + public static final long STREAK_RESET_TIME = 1000 * 60 * 60 * 12; public void attemptDailyBonus(final Player player, final BonusAmount amount, final Consumer result) { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java index 74dbe05c0..013873587 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java @@ -2,6 +2,7 @@ package mineplex.hub.bonuses.gui; import mineplex.core.gui.SimpleGui; import mineplex.hub.bonuses.BonusManager; +import mineplex.hub.bonuses.gui.buttons.CarlSpinButton; import mineplex.hub.bonuses.gui.buttons.DailyBonusButton; import mineplex.hub.bonuses.gui.buttons.RankBonusButton; import mineplex.hub.bonuses.gui.buttons.VoteButton; @@ -20,11 +21,13 @@ public class BonusGui extends SimpleGui this.manager = manager; - getButtonMap().put(11, new VoteButton(plugin, player, this, manager)); + setItem(11, new VoteButton(plugin, player, this, manager)); - getButtonMap().put(13, new RankBonusButton(getPlugin(), player, this, manager)); + setItem(13, new RankBonusButton(getPlugin(), player, this, manager)); - getButtonMap().put(15, new DailyBonusButton(getPlugin(), player, this, manager)); + setItem(15, new DailyBonusButton(getPlugin(), player, this, manager)); + + setItem(31, new CarlSpinButton()); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java new file mode 100644 index 000000000..c88bde558 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java @@ -0,0 +1,14 @@ +package mineplex.hub.bonuses.gui; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import mineplex.core.gui.SimpleGui; + +public class SpinGui extends SimpleGui +{ + public SpinGui(Plugin plugin, Player player) + { + super(plugin, player); + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java new file mode 100644 index 000000000..5262d6c3f --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java @@ -0,0 +1,44 @@ +package mineplex.hub.bonuses.gui.buttons; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.gui.GuiItem; +import mineplex.core.shop.item.ShopItem; + +public class CarlSpinButton implements GuiItem +{ + + public CarlSpinButton() + { + + } + + @Override + public void setup() + { + } + + @Override + public void close() + { + + } + + @Override + public void click(ClickType clickType) + { + + } + + @Override + public ItemStack getObject() + { + ShopItem item = new ShopItem(Material.SKULL_ITEM, (byte) 4, "Carl's Spinner", new String[] {ChatColor.RESET + "Try your Luck!" }, 1, false, false); + + + return item; + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java index 4ca85f532..2ba7a359a 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java @@ -33,13 +33,11 @@ import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; -public class DailyBonusButton implements GuiItem, Listener { - +public class DailyBonusButton implements GuiItem, Listener +{ private ItemStack _item; - private long bonusTime; - private Player _player; private Plugin _plugin; private ItemRefresher _gui; @@ -57,7 +55,6 @@ public class DailyBonusButton implements GuiItem, Listener { @Override public void setup() { - this.bonusTime = _bonusManager.nextDailyBonus(getPlayer()); Bukkit.getPluginManager().registerEvents(this, getPlugin()); setItem(); } @@ -68,7 +65,6 @@ public class DailyBonusButton implements GuiItem, Listener { HandlerList.unregisterAll(this); } - @Override public void click(ClickType clickType) { @@ -82,6 +78,9 @@ public class DailyBonusButton implements GuiItem, Listener { public void accept(Boolean t) { if (t) { + + setItem(); + if (getPlayer().getOpenInventory() != null) { new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, DyeColor.LIME.getData(), 1, ChatColor.GREEN + "Bonus collected!"), "Bonus collected!", 6*9, 20*3, getGui()).openInventory(); } else { @@ -101,7 +100,6 @@ public class DailyBonusButton implements GuiItem, Listener { } else getPlayer().playSound(getPlayer().getLocation(), Sound.ITEM_BREAK, 1, 10); return; - } @EventHandler @@ -109,20 +107,10 @@ public class DailyBonusButton implements GuiItem, Listener { { if (!event.getType().equals(UpdateType.SEC)) return; - setItem(); +// refreshItem(); // Todo Unnecessary? } - - @Override - public ItemStack getObject() - { - return _item; - } - - public void refreshItem() { - getGui().refreshItem(this); - } - - public void setItem() + + private void setItem() { ArrayList lore = new ArrayList(); Material material; @@ -172,14 +160,23 @@ public class DailyBonusButton implements GuiItem, Listener { lore.add(C.cYellow + "Streak: " + C.cWhite + "420"); - _item = new ShopItem(material, itemName, lore.toArray(new String[0]), 1, false, false); - - refreshItem(); + _item = new ShopItem(material, itemName, lore.toArray(new String[0]), 1, false, false); + } + + @Override + public ItemStack getObject() + { + return _item; + } + + public void refreshItem() + { + getGui().refreshItem(this); } public long timeLeft() { - long timeLeft = this.bonusTime - System.currentTimeMillis(); + long timeLeft = _bonusManager.nextDailyBonus(getPlayer()) - System.currentTimeMillis(); return timeLeft; } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java index ce0f3bbb8..9ae72899b 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java @@ -51,21 +51,20 @@ public class PollButton extends SimpleGui implements GuiItem { { this._poll = _pollManager.getNextPoll(_pollManager.Get(getPlayer()), _clientManager.Get(getPlayer()).GetRank()); - setButtonMap(new HashMap()); - if (_poll != null) { - - getButtonMap().putAll(hard); + + // Todo - Fix this! +// getButtonMap().putAll(hard); - getButtonMap().put(4, getQuestionItem(_poll.getQuestion())); + setItem(4, getQuestionItem(_poll.getQuestion())); int[] slots = even(9, _poll.getAnswers().length); for (int i = 0; i < slots.length; i++) { - getButtonMap().put(9 * 2 + slots[i], new AnswerItem(_poll, i)); + setItem(9 * 2 + slots[i], new AnswerItem(_poll, i)); } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java index ee2a9d9ba..e5007bd53 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java @@ -39,8 +39,6 @@ public class RankBonusButton implements GuiItem, Listener { private ItemStack _item; - private long bonusTime; - private Player _player; private Plugin _plugin; private ItemRefresher _gui; @@ -61,13 +59,13 @@ public class RankBonusButton implements GuiItem, Listener { if (_bonusManager.getRankBonusAmount(getPlayer()).isGreaterThanZero()) { this.hasRank = true; - this.bonusTime = _bonusManager.nextRankBonus(getPlayer()); Bukkit.getPluginManager().registerEvents(this, getPlugin()); } else { this.hasRank = false; } + setItem(); } @@ -91,6 +89,8 @@ public class RankBonusButton implements GuiItem, Listener { @Override public void accept(Boolean t) { + setItem(); + if (t) { if (getPlayer().getOpenInventory() != null) @@ -128,7 +128,7 @@ public class RankBonusButton implements GuiItem, Listener { { if (!event.getType().equals(UpdateType.SEC)) return; - setItem(); +// refreshItem(); // Todo Unnecessary? } @Override @@ -136,12 +136,8 @@ public class RankBonusButton implements GuiItem, Listener { { return _item; } - - public void refreshItem() { - getGui().refreshItem(this); - } - - public void setItem() + + private void setItem() { ArrayList lore = new ArrayList(); Material material; @@ -182,13 +178,16 @@ public class RankBonusButton implements GuiItem, Listener { } _item = new ShopItem(material, itemName, lore.toArray(new String[0]), 1, false, false); + } - refreshItem(); + public void refreshItem() + { + _gui.refreshItem(this); } public long timeLeft() { - return this.bonusTime - System.currentTimeMillis(); + return _bonusManager.nextRankBonus(getPlayer()) - System.currentTimeMillis(); } public boolean isAvailable() diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RewardButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RewardButton.java new file mode 100644 index 000000000..5f7b0050b --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RewardButton.java @@ -0,0 +1,47 @@ +package mineplex.hub.bonuses.gui.buttons; + +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import mineplex.core.gui.GuiItem; +import mineplex.core.reward.Reward; +import mineplex.core.reward.RewardData; + +public class RewardButton implements GuiItem +{ + private RewardData _data; + + public RewardButton(RewardData data) + { + _data = data; + } + + @Override + public void setup() + { + + } + + @Override + public void close() + { + + } + + @Override + public void click(ClickType clickType) + { + // Do nothing + } + + @Override + public ItemStack getObject() + { + ItemStack stack = _data.getDisplayItem(); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName(_data.getFriendlyName()); + stack.setItemMeta(meta); + return stack; + } +} From 1680b652db00895ce74b42145ec0f2545b25f604 Mon Sep 17 00:00:00 2001 From: Morten Date: Fri, 7 Aug 2015 03:10:17 +0200 Subject: [PATCH 254/377] Added Hat layer skin Added Sneak animation With love from Morten <3 --- .../disguise/disguises/DisguisePlayer.java | 230 ++++---- .../hub/commands/DisguiseCommand.java | 492 ++++++++-------- .../game/arcade/command/DisguiseCommand.java | 529 ++++++++++-------- 3 files changed, 654 insertions(+), 597 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguisePlayer.java b/Plugins/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguisePlayer.java index 33126f3d6..5fcff15ba 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguisePlayer.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/disguise/disguises/DisguisePlayer.java @@ -2,140 +2,152 @@ package mineplex.core.disguise.disguises; import java.util.UUID; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.block.BlockFace; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; import org.bukkit.entity.Player; +import org.spigotmc.ProtocolData; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; import net.minecraft.server.v1_7_R4.MathHelper; import net.minecraft.server.v1_7_R4.Packet; +import net.minecraft.server.v1_7_R4.PacketPlayInSettings; import net.minecraft.server.v1_7_R4.PacketPlayOutNamedEntitySpawn; import net.minecraft.server.v1_7_R4.PacketPlayOutPlayerInfo; import net.minecraft.util.com.mojang.authlib.GameProfile; public class DisguisePlayer extends DisguiseHuman { - private GameProfile _profile; - private boolean _sneaking; - private BlockFace _sleeping; + private GameProfile _profile; + private boolean _sneaking; + private BlockFace _sleeping; - public DisguisePlayer(org.bukkit.entity.Entity entity) + public DisguisePlayer(org.bukkit.entity.Entity entity) + { + super(entity); + } + + public DisguisePlayer(org.bukkit.entity.Entity entity, GameProfile profile) + { + this(entity); + + setProfile(profile); + } + + public void setProfile(GameProfile profile) + { + GameProfile newProfile = new GameProfile(UUID.randomUUID(), profile.getName()); + + newProfile.getProperties().putAll(profile.getProperties()); + + _profile = newProfile; + } + + public BlockFace getSleepingDirection() + { + return _sleeping; + } + + /** + * Don't use this if the disguise is already on as it will not work the way + * you want it to. Contact libraryaddict if you need that added. + */ + public void setSleeping(BlockFace sleeping) + { + _sleeping = sleeping; + } + + public void setSneaking(boolean sneaking) + { + _sneaking = sneaking; + } + + public boolean getSneaking() + { + return _sneaking; + } + + public Packet getOldInfoPacket(boolean add) + { + PacketPlayOutPlayerInfo playerInfo = new PacketPlayOutPlayerInfo(); + + if(Entity instanceof Player) { - super(entity); + playerInfo.username = Entity.getName(); + playerInfo.action = add ? 0 : 4; + playerInfo.ping = 90; + playerInfo.player = ((CraftPlayer) (Player) Entity).getProfile(); + playerInfo.gamemode = 0; } - public DisguisePlayer(org.bukkit.entity.Entity entity, GameProfile profile) - { - this(entity); + return playerInfo; + } - setProfile(profile); - } + public Packet getNewInfoPacket(boolean add) + { + PacketPlayOutPlayerInfo newDisguiseInfo = new PacketPlayOutPlayerInfo(); + newDisguiseInfo.username = _profile.getName(); + newDisguiseInfo.action = add ? 0 : 4; + newDisguiseInfo.ping = 90; + newDisguiseInfo.player = _profile; + newDisguiseInfo.gamemode = 0; - public void setProfile(GameProfile profile) - { - GameProfile newProfile = new GameProfile(UUID.randomUUID(), profile.getName()); + return newDisguiseInfo; + } - newProfile.getProperties().putAll(profile.getProperties()); + @SuppressWarnings("static-access") + @Override + public void UpdateDataWatcher() + { + super.UpdateDataWatcher(); - _profile = newProfile; - } + byte b0 = DataWatcher.getByte(0); + DataWatcher.watch(10, (Object)(byte)0x40); + + if(_sneaking) + DataWatcher.watch(0, Byte.valueOf((byte) (b0 | 1 << 1))); + else + DataWatcher.watch(0, Byte.valueOf((byte) (b0 & ~(1 << 1)))); + } - public BlockFace getSleepingDirection() - { - return _sleeping; - } + public PacketPlayOutNamedEntitySpawn spawnBeforePlayer(Location spawnLocation) + { + Location loc = spawnLocation.add(spawnLocation.getDirection().normalize().multiply(30)); + loc.setY(Math.max(loc.getY(), 0)); - /** - * Don't use this if the disguise is already on as it will not work the way you want it to. Contact libraryaddict if you need - * that added. - */ - public void setSleeping(BlockFace sleeping) - { - _sleeping = sleeping; - } + PacketPlayOutNamedEntitySpawn packet = new PacketPlayOutNamedEntitySpawn(); + packet.a = Entity.getId(); + packet.b = _profile; + packet.c = MathHelper.floor(loc.getX() * 32.0D); + packet.d = MathHelper.floor(loc.getY() * 32.0D); + packet.e = MathHelper.floor(loc.getZ() * 32.0D); + packet.f = (byte) ((int) (loc.getYaw() * 256.0F / 360.0F)); + packet.g = (byte) ((int) (loc.getPitch() * 256.0F / 360.0F)); + packet.i = DataWatcher; - public void setSneaking(boolean sneaking) - { - _sneaking = sneaking; - } + return packet; + } - public Packet getOldInfoPacket(boolean add) - { - PacketPlayOutPlayerInfo playerInfo = new PacketPlayOutPlayerInfo(); + @Override + public PacketPlayOutNamedEntitySpawn GetSpawnPacket() + { + PacketPlayOutNamedEntitySpawn packet = new PacketPlayOutNamedEntitySpawn(); + packet.a = Entity.getId(); + packet.b = _profile; + packet.c = MathHelper.floor(Entity.locX * 32.0D); + packet.d = MathHelper.floor(Entity.locY * 32.0D); + packet.e = MathHelper.floor(Entity.locZ * 32.0D); + packet.f = (byte) ((int) (Entity.yaw * 256.0F / 360.0F)); + packet.g = (byte) ((int) (Entity.pitch * 256.0F / 360.0F)); + packet.i = DataWatcher; - if (Entity instanceof Player) - { - playerInfo.username = Entity.getName(); - playerInfo.action = add ? 0 : 4; - playerInfo.ping = 90; - playerInfo.player = ((CraftPlayer) (Player) Entity).getProfile(); - playerInfo.gamemode = 0; - } + return packet; + } - return playerInfo; - } - - public Packet getNewInfoPacket(boolean add) - { - PacketPlayOutPlayerInfo newDisguiseInfo = new PacketPlayOutPlayerInfo(); - newDisguiseInfo.username = _profile.getName(); - newDisguiseInfo.action = add ? 0 : 4; - newDisguiseInfo.ping = 90; - newDisguiseInfo.player = _profile; - newDisguiseInfo.gamemode = 0; - - return newDisguiseInfo; - } - - @Override - public void UpdateDataWatcher() - { - super.UpdateDataWatcher(); - - byte b0 = DataWatcher.getByte(0); - - if (_sneaking) - DataWatcher.watch(0, Byte.valueOf((byte) (b0 | 1 << 1))); - else - DataWatcher.watch(0, Byte.valueOf((byte) (b0 & ~(1 << 1)))); - } - - public PacketPlayOutNamedEntitySpawn spawnBeforePlayer(Location spawnLocation) - { - Location loc = spawnLocation.add(spawnLocation.getDirection().normalize().multiply(30)); - loc.setY(Math.max(loc.getY(), 0)); - - PacketPlayOutNamedEntitySpawn packet = new PacketPlayOutNamedEntitySpawn(); - packet.a = Entity.getId(); - packet.b = _profile; - packet.c = MathHelper.floor(loc.getX() * 32.0D); - packet.d = MathHelper.floor(loc.getY() * 32.0D); - packet.e = MathHelper.floor(loc.getZ() * 32.0D); - packet.f = (byte) ((int) (loc.getYaw() * 256.0F / 360.0F)); - packet.g = (byte) ((int) (loc.getPitch() * 256.0F / 360.0F)); - packet.i = DataWatcher; - - return packet; - } - - @Override - public PacketPlayOutNamedEntitySpawn GetSpawnPacket() - { - PacketPlayOutNamedEntitySpawn packet = new PacketPlayOutNamedEntitySpawn(); - packet.a = Entity.getId(); - packet.b = _profile; - packet.c = MathHelper.floor(Entity.locX * 32.0D); - packet.d = MathHelper.floor(Entity.locY * 32.0D); - packet.e = MathHelper.floor(Entity.locZ * 32.0D); - packet.f = (byte) ((int) (Entity.yaw * 256.0F / 360.0F)); - packet.g = (byte) ((int) (Entity.pitch * 256.0F / 360.0F)); - packet.i = DataWatcher; - - return packet; - } - - public String getName() - { - return _profile.getName(); - } + public String getName() + { + return _profile.getName(); + } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java index 9c7a5afb8..e342650e7 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java @@ -35,6 +35,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerToggleSneakEvent; import org.bukkit.event.player.PlayerLoginEvent.Result; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.scoreboard.Team; @@ -43,263 +44,274 @@ import com.mysql.jdbc.BalanceStrategy; public class DisguiseCommand extends CommandBase implements Listener { - - private NautHashMap _disguisedPlayers = new NautHashMap<>(); - private NautHashMap _disguisedPlayersNames = new NautHashMap<>(); - - public DisguiseCommand(HubManager plugin) + + private NautHashMap _disguisedPlayers = new NautHashMap<>(); + private NautHashMap _disguisedPlayersNames = new NautHashMap<>(); + private NautHashMap _disguisedPlayerDisguises = new NautHashMap<>(); + + public DisguiseCommand(HubManager plugin) + { + super(plugin, Rank.JNR_DEV, new Rank[] + { Rank.YOUTUBE, Rank.TWITCH }, "disguise"); + plugin.getPluginManager().registerEvents(this, Plugin.getPlugin()); + new NCPDataManFix(); + } + + @Override + public void Execute(final Player caller, final String[] args) + { + if(args == null) { - super(plugin, Rank.JNR_DEV, new Rank[]{Rank.YOUTUBE, Rank.TWITCH}, "disguise"); - plugin.getPluginManager().registerEvents(this, Plugin.getPlugin()); - new NCPDataManFix(); + if(!Plugin.GetDisguise().isDisguised(caller)) + { + UtilPlayer.message(caller, C.cRed + C.Bold + "please use /disguise first"); + return; + } + try + { + _disguisedPlayers.remove(caller); + _disguisedPlayerDisguises.remove(caller); + Plugin.GetDisguise().undisguise(caller); + String playerName = _disguisedPlayersNames.get(caller); + + CoreClient client = Plugin.GetClients().Get(caller); + client.setDisguisedRank(null); + client.setDisguisedAs(null); + client.setDisguised(false); + + changeName(caller, playerName); + + for(Player other : UtilServer.getPlayers()) + { + for(Team team : other.getScoreboard().getTeams()) + { + if(team.hasPlayer(caller)) + { + team.removePlayer(caller); + } + } + other.getScoreboard().getTeam(Plugin.GetClients().Get(caller).GetRank().Name).addPlayer(caller); + } + + UtilPlayer.message(caller, C.cRed + C.Bold + "You are no longer disguised!"); + return; + } catch(Exception ex) + { + ex.printStackTrace(); + } + } + if(args != null && args.length > 1) + { + UtilPlayer.message(caller, C.cRed + C.Bold + "/disguise "); + return; } - @Override - public void Execute(final Player caller, final String[] args) - { - if (args == null) + Bukkit.getServer().getScheduler().runTaskAsynchronously(Plugin.getPlugin(), new Runnable() + { + @Override + public void run() + { + if(Plugin.GetDisguise().isDisguised(caller)) { - if(!Plugin.GetDisguise().isDisguised(caller)) - { - UtilPlayer.message(caller, C.cRed + C.Bold + "please use /disguise first"); - return; - } - try - { - _disguisedPlayers.remove(caller); - Plugin.GetDisguise().undisguise(caller); - String playerName = _disguisedPlayersNames.get(caller); - - CoreClient client = Plugin.GetClients().Get(caller); - client.setDisguisedRank(null); - client.setDisguisedAs(null); - client.setDisguised(false); - - changeName(caller, playerName); - - for(Player other : UtilServer.getPlayers()) - { - for(Team team : other.getScoreboard().getTeams()) - { - if(team.hasPlayer(caller)) - { - team.removePlayer(caller); - } - } - other.getScoreboard().getTeam(Plugin.GetClients().Get(caller).GetRank().Name).addPlayer(caller); - } - - - UtilPlayer.message(caller, C.cRed + C.Bold + "You are no longer disguised!"); - return; - } - catch (Exception ex) - { - ex.printStackTrace(); - } + UtilPlayer.message(caller, C.cRed + C.Bold + "please use /disguise first"); + return; } - if (args != null && args.length > 1) + for(Player other : UtilServer.getPlayers()) { - UtilPlayer.message(caller, C.cRed + C.Bold + "/disguise "); + if(other.getName().equalsIgnoreCase(args[0])) + { + UtilPlayer.message(caller, C.cRed + C.Bold + "this name is already in use!"); return; + } } - - Bukkit.getServer().getScheduler().runTaskAsynchronously(Plugin.getPlugin(), new Runnable() + if(_disguisedPlayersNames.containsValue(args[0])) { - @Override - public void run() - { - if(Plugin.GetDisguise().isDisguised(caller)) - { - UtilPlayer.message(caller, C.cRed + C.Bold + "please use /disguise first"); - return; - } - for(Player other : UtilServer.getPlayers()) - { - if(other.getName().equalsIgnoreCase(args[0])) - { - UtilPlayer.message(caller, C.cRed + C.Bold + "this name is already in use!"); - return; - } - } - if(_disguisedPlayersNames.containsValue(args[0])) - { - UtilPlayer.message(caller, C.cRed + C.Bold + "this name is already in use!"); - return; - } - if(args[0].length() > 16) - { - UtilPlayer.message(caller, C.cRed + C.Bold + "Invalid Disguise Name: " + ChatColor.RESET + args[0]); - return; - } - - try - { - CoreClient client = Plugin.GetClients().Get(caller); - UUID uuid = UUIDFetcher.getUUIDOf(args[0]); - GameProfile profile = null; - try - { - profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); - } - catch (Exception e) - { - uuid = UUIDFetcher.getUUIDOf("Alex"); - profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); - } - - Rank otherRank = Rank.ALL; - try - { - CoreClient other = new CoreClient(args[0]); - Plugin.GetClients().LoadClient(other, uuid, caller.getAddress().getAddress().getAddress().toString()); - otherRank = other.GetRank(); - } - catch (NullPointerException exception) - {} - if(otherRank.Has(Rank.TWITCH)) - { - UtilPlayer.message(caller, C.cRed + C.Bold + "You can't disguise as staff!"); - return; - } - _disguisedPlayers.put(caller, profile); - _disguisedPlayersNames.put(caller, caller.getName()); - client.setDisguisedRank(otherRank); - client.setDisguised(true); - - client.setDisguisedAs(args[0]); - - changeName(caller, args[0]); - - Plugin.GetGadget().RemoveItem(caller); - - UtilPlayer.message(caller, C.cGreen + C.Bold + "Disguise Active: " + ChatColor.RESET + args[0]); - } - catch (Exception e) - { - e.printStackTrace(); - UtilPlayer.message(caller, C.cRed + C.Bold + "Invalid Disguise Name: " + ChatColor.RESET + args[0]); - return; - } - }} - ); - } - - @EventHandler - public void updateDisguises(UpdateEvent event) - { - if(event.getType() != UpdateType.FASTEST) - return; - - for(final Player player : UtilServer.getPlayers()) + UtilPlayer.message(caller, C.cRed + C.Bold + "this name is already in use!"); + return; + } + if(args[0].length() > 16) { - if(!_disguisedPlayers.containsKey(player)) - continue; - - for(Player other : UtilServer.getPlayers()) - { - try - { - for(Team team : other.getScoreboard().getTeams()) - { - if(team.hasPlayer(player)) - { - team.removePlayer(player); - } - } - other.getScoreboard().getTeam(Plugin.GetClients().Get(player).getDisguisedRank().Name).addPlayer(player); - - } - catch (NullPointerException exp) - {} - } - - if(Plugin.GetDisguise().isDisguised(player)) - continue; + UtilPlayer.message(caller, C.cRed + C.Bold + "Invalid Disguise Name: " + ChatColor.RESET + args[0]); + return; + } - DisguisePlayer playerDisguise = new DisguisePlayer(player, _disguisedPlayers.get(player)); - Plugin.GetDisguise().disguise(playerDisguise); - } - } - - public void changeName(Player player , String changedName) - { try { - Field name = GameProfile.class.getDeclaredField("name"); - Field declaredProfile = EntityHuman.class.getDeclaredField("i"); - declaredProfile.setAccessible(true); - GameProfile gameProfile = (GameProfile) declaredProfile.get(((CraftHumanEntity)((CraftPlayer) player)).getHandle()); - - name.setAccessible(true); - name.set(gameProfile, changedName); - name.setAccessible(false); - } - catch (Exception ex) - { - ex.printStackTrace(); - } - } - - @EventHandler(priority=EventPriority.HIGHEST) - public void Quit(PlayerQuitEvent event) - { - Player player = event.getPlayer(); - - if(_disguisedPlayers.containsKey(player)) - { - try - { - _disguisedPlayers.remove(player); - Plugin.GetDisguise().undisguise(player); - String playerName = _disguisedPlayersNames.get(player); - - CoreClient client = Plugin.GetClients().Get(player); - client.setDisguisedRank(null); - client.setDisguisedAs(null); - client.setDisguised(false); - - changeName(player, playerName); - } - catch (Exception ex) - { - ex.printStackTrace(); - } - } - } - - @EventHandler(priority=EventPriority.HIGHEST) - public void Join(PlayerLoginEvent event) - { - for(Player player : _disguisedPlayers.keySet()) - { - if(player.getName().equalsIgnoreCase(event.getPlayer().getName())) - { - event.disallow(Result.KICK_OTHER, "There is already the same account playing. this probably happened because of /disguise"); - } - } - } - - @EventHandler - public void gadget(GadgetActivateEvent event) - { - if(!event.getGadget().GetName().equalsIgnoreCase("Coin Party Bomb") && event.getGadget().getGadgetType() != GadgetType.Morph) + CoreClient client = Plugin.GetClients().Get(caller); + UUID uuid = UUIDFetcher.getUUIDOf(args[0]); + GameProfile profile = null; + try + { + profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); + } catch(Exception e) + { + uuid = UUIDFetcher.getUUIDOf("Alex"); + profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); + } + + Rank otherRank = Rank.ALL; + try + { + CoreClient other = new CoreClient(args[0]); + Plugin.GetClients().LoadClient(other, uuid, caller.getAddress().getAddress().getAddress().toString()); + otherRank = other.GetRank(); + } catch(NullPointerException exception) + {} + if(otherRank.Has(Rank.TWITCH)) + { + UtilPlayer.message(caller, C.cRed + C.Bold + "You can't disguise as staff!"); return; - - if(_disguisedPlayers.containsKey(event.getPlayer())) + } + _disguisedPlayers.put(caller, profile); + _disguisedPlayersNames.put(caller, caller.getName()); + client.setDisguisedRank(otherRank); + client.setDisguised(true); + + client.setDisguisedAs(args[0]); + + changeName(caller, args[0]); + + Plugin.GetGadget().RemoveItem(caller); + + UtilPlayer.message(caller, C.cGreen + C.Bold + "Disguise Active: " + ChatColor.RESET + args[0]); + } catch(Exception e) { - event.setCancelled(true); + e.printStackTrace(); + UtilPlayer.message(caller, C.cRed + C.Bold + "Invalid Disguise Name: " + ChatColor.RESET + args[0]); + return; } - } - - @EventHandler - public void chest(TreasureStartEvent event) + } + }); + } + + @EventHandler + public void updateDisguises(UpdateEvent event) + { + if(event.getType() != UpdateType.FASTEST) + return; + + for(final Player player : UtilServer.getPlayers()) { - if(_disguisedPlayers.containsKey(event.getPlayer())) + if(!_disguisedPlayers.containsKey(player)) + continue; + + for(Player other : UtilServer.getPlayers()) + { + try { - UtilPlayer.message(event.getPlayer(), F.main("Disguise", "You cant open Treasure Chests while you are disguised!")); - event.setCancelled(true); - } + for(Team team : other.getScoreboard().getTeams()) + { + if(team.hasPlayer(player)) + { + team.removePlayer(player); + } + } + other.getScoreboard().getTeam(Plugin.GetClients().Get(player).getDisguisedRank().Name).addPlayer(player); + + } catch(NullPointerException exp) + {} + } + + if(Plugin.GetDisguise().isDisguised(player)) + continue; + + DisguisePlayer playerDisguise = new DisguisePlayer(player, _disguisedPlayers.get(player)); + _disguisedPlayerDisguises.put(player, playerDisguise); + Plugin.GetDisguise().disguise(playerDisguise); } - + } + + public void changeName(Player player, String changedName) + { + try + { + Field name = GameProfile.class.getDeclaredField("name"); + Field declaredProfile = EntityHuman.class.getDeclaredField("i"); + declaredProfile.setAccessible(true); + GameProfile gameProfile = (GameProfile) declaredProfile.get(((CraftHumanEntity) ((CraftPlayer) player)).getHandle()); + + name.setAccessible(true); + name.set(gameProfile, changedName); + name.setAccessible(false); + } catch(Exception ex) + { + ex.printStackTrace(); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void Quit(PlayerQuitEvent event) + { + Player player = event.getPlayer(); + + if(_disguisedPlayers.containsKey(player)) + { + try + { + _disguisedPlayers.remove(player); + _disguisedPlayerDisguises.remove(player); + _disguisedPlayersNames.remove(player); + Plugin.GetDisguise().undisguise(player); + String playerName = _disguisedPlayersNames.get(player); + + CoreClient client = Plugin.GetClients().Get(player); + client.setDisguisedRank(null); + client.setDisguisedAs(null); + client.setDisguised(false); + + changeName(player, playerName); + } catch(Exception ex) + { + ex.printStackTrace(); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void Join(PlayerLoginEvent event) + { + for(Player player : _disguisedPlayers.keySet()) + { + if(player.getName().equalsIgnoreCase(event.getPlayer().getName())) + { + event.disallow(Result.KICK_OTHER, "There is already the same account playing. this probably happened because of /disguise"); + } + } + } + + @EventHandler + public void gadget(GadgetActivateEvent event) + { + if(!event.getGadget().GetName().equalsIgnoreCase("Coin Party Bomb") && event.getGadget().getGadgetType() != GadgetType.Morph) + return; + + if(_disguisedPlayers.containsKey(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void chest(TreasureStartEvent event) + { + if(_disguisedPlayers.containsKey(event.getPlayer())) + { + UtilPlayer.message(event.getPlayer(), F.main("Disguise", "You cant open Treasure Chests while you are disguised!")); + event.setCancelled(true); + } + } + + @EventHandler + public void onPlayerSneak(PlayerToggleSneakEvent event) + { + Player player = event.getPlayer(); + + if(_disguisedPlayers.containsKey(player)) + { + DisguisePlayer dp = _disguisedPlayerDisguises.get(player); + + dp.setSneaking(!dp.getSneaking()); + } + } + } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java index ce33a87dc..b26139662 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java @@ -1,11 +1,7 @@ package nautilus.game.arcade.command; import java.lang.reflect.Field; -import java.net.URL; -import java.net.URLConnection; -import java.util.Scanner; import java.util.UUID; -import java.util.logging.Level; import mineplex.core.NCPDataManFix; import mineplex.core.account.CoreClient; @@ -25,282 +21,319 @@ import mineplex.core.treasure.event.TreasureStartEvent; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import nautilus.game.arcade.ArcadeManager; +import net.minecraft.server.v1_7_R4.EntityHuman; import net.minecraft.util.com.mojang.authlib.GameProfile; import org.bukkit.Bukkit; import org.bukkit.ChatColor; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftHumanEntity; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerLoginEvent; -import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerLoginEvent.Result; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerToggleSneakEvent; import org.bukkit.scoreboard.Team; -import org.jooq.tools.json.JSONArray; -import org.jooq.tools.json.JSONObject; -import org.jooq.tools.json.JSONParser; public class DisguiseCommand extends CommandBase implements Listener { - - private NautHashMap _disguisedPlayers = new NautHashMap<>(); - private NautHashMap _disguisedPlayersNames = new NautHashMap<>(); - - public DisguiseCommand(ArcadeManager plugin) + + private NautHashMap _disguisedPlayers = new NautHashMap<>(); + private NautHashMap _disguisedPlayersNames = new NautHashMap<>(); + private NautHashMap _disguisedPlayerDisguises = new NautHashMap<>(); + + public DisguiseCommand(ArcadeManager plugin) + { + super(plugin, Rank.JNR_DEV, new Rank[] + { Rank.YOUTUBE, Rank.TWITCH }, "disguise"); + plugin.getPluginManager().registerEvents(this, Plugin.getPlugin()); + new NCPDataManFix(); + } + + @Override + public void Execute(final Player caller, final String[] args) + { + if(args == null) { - super(plugin, Rank.JNR_DEV, new Rank[]{Rank.YOUTUBE, Rank.TWITCH}, "disguise"); - plugin.getPluginManager().registerEvents(this, Plugin.getPlugin()); - new NCPDataManFix(); + if(!Plugin.GetDisguise().isDisguised(caller)) + { + UtilPlayer.message(caller, C.cRed + C.Bold + "please use /disguise first"); + return; + } + try + { + _disguisedPlayers.remove(caller); + _disguisedPlayerDisguises.remove(caller); + Plugin.GetDisguise().undisguise(caller); + String playerName = _disguisedPlayersNames.get(caller); + + CoreClient client = Plugin.GetClients().Get(caller); + client.setDisguisedRank(null); + client.setDisguisedAs(null); + client.setDisguised(false); + + changeName(caller, playerName, true); + + for(Player other : UtilServer.getPlayers()) + { + for(Team team : other.getScoreboard().getTeams()) + { + team.removePlayer(caller); + } + other.getScoreboard().getTeam(Plugin.GetClients().Get(caller).GetRank().Name).addPlayer(caller); + } + + UtilPlayer.message(caller, C.cRed + C.Bold + "You are no longer disguised!"); + return; + } catch(Exception ex) + { + ex.printStackTrace(); + } + } + if(args != null && args.length > 1) + { + UtilPlayer.message(caller, C.cRed + C.Bold + "/disguise "); + return; } - @Override - public void Execute(final Player caller, final String[] args) - { - if (args == null) + Bukkit.getServer().getScheduler().runTaskAsynchronously(Plugin.getPlugin(), new Runnable() + { + @Override + public void run() + { + if(Plugin.GetDisguise().isDisguised(caller)) { - if(!Plugin.GetDisguise().isDisguised(caller)) - { - UtilPlayer.message(caller, C.cRed + C.Bold + "please use /disguise first"); - return; - } - try - { - _disguisedPlayers.remove(caller); - Plugin.GetDisguise().undisguise(caller); - String playerName = _disguisedPlayersNames.get(caller); - - CoreClient client = Plugin.GetClients().Get(caller); - client.setDisguisedRank(null); - client.setDisguisedAs(null); - client.setDisguised(false); - - changeName(caller, playerName, true); - - for(Player other : UtilServer.getPlayers()) - { - for(Team team : other.getScoreboard().getTeams()) - { - team.removePlayer(caller); - } - other.getScoreboard().getTeam(Plugin.GetClients().Get(caller).GetRank().Name).addPlayer(caller); - } - - - UtilPlayer.message(caller, C.cRed + C.Bold + "You are no longer disguised!"); - return; - } - catch (Exception ex) - { - ex.printStackTrace(); - } + UtilPlayer.message(caller, C.cRed + C.Bold + "please use /disguise first"); + return; } - if (args != null && args.length > 1) + for(Player other : UtilServer.getPlayers()) { - UtilPlayer.message(caller, C.cRed + C.Bold + "/disguise "); + if(other.getName().equalsIgnoreCase(args[0])) + { + UtilPlayer.message(caller, C.cRed + C.Bold + "this name is already in use!"); return; + } } - - Bukkit.getServer().getScheduler().runTaskAsynchronously(Plugin.getPlugin(), new Runnable() + if(_disguisedPlayersNames.containsValue(args[0])) { - @Override - public void run() - { - if(Plugin.GetDisguise().isDisguised(caller)) - { - UtilPlayer.message(caller, C.cRed + C.Bold + "please use /disguise first"); - return; - } - for(Player other : UtilServer.getPlayers()) - { - if(other.getName().equalsIgnoreCase(args[0])) - { - UtilPlayer.message(caller, C.cRed + C.Bold + "this name is already in use!"); - return; - } - } - if(_disguisedPlayersNames.containsValue(args[0])) - { - UtilPlayer.message(caller, C.cRed + C.Bold + "this name is already in use!"); - return; - } - if(args[0].length() > 16) - { - UtilPlayer.message(caller, C.cRed + C.Bold + "Invalid Disguise Name: " + ChatColor.RESET + args[0]); - return; - } - - try - { - CoreClient client = Plugin.GetClients().Get(caller); - UUID uuid = UUIDFetcher.getUUIDOf(args[0]); - GameProfile profile = null; - try - { - profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); - } - catch (Exception e) - { - uuid = UUIDFetcher.getUUIDOf("Alex"); - profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); - } - - Rank otherRank = Rank.ALL; - try - { - CoreClient other = new CoreClient(args[0]); - Plugin.GetClients().LoadClient(other, uuid, caller.getAddress().getAddress().getAddress().toString()); - otherRank = other.GetRank(); - } - catch (NullPointerException exception) - {} - if(otherRank.Has(Rank.TWITCH)) - { - UtilPlayer.message(caller, C.cRed + C.Bold + "You can't disguise as staff!"); - return; - } - _disguisedPlayers.put(caller, profile); - _disguisedPlayersNames.put(caller, caller.getName()); - client.setDisguisedRank(otherRank); - client.setDisguised(true); - - client.setDisguisedAs(args[0]); - - changeName(caller, args[0], true); - - Plugin.getCosmeticManager().getGadgetManager().RemoveItem(caller); - - UtilPlayer.message(caller, C.cGreen + C.Bold + "Disguise Active: " + ChatColor.RESET + args[0]); - } - catch (Exception e) - { - e.printStackTrace(); - UtilPlayer.message(caller, C.cRed + C.Bold + "Invalid Disguise Name: " + ChatColor.RESET + args[0]); - return; - } - }} - ); - } - - @EventHandler - public void updateDisguises(UpdateEvent event) - { - if(event.getType() != UpdateType.FASTEST) - return; - - for(final Player player : UtilServer.getPlayers()) + UtilPlayer.message(caller, C.cRed + C.Bold + "this name is already in use!"); + return; + } + if(args[0].length() > 16) { - if(!_disguisedPlayers.containsKey(player)) - continue; - - for(Player other : UtilServer.getPlayers()) - { - try - { - if(other.getScoreboard().getTeam(Plugin.GetClients().Get(player).GetRank().Name).getPlayers().contains(player)) - { - other.getScoreboard().getTeam(Plugin.GetClients().Get(player).GetRank().Name).removePlayer(player); - other.getScoreboard().getTeam(Plugin.GetClients().Get(player).getDisguisedRank().Name).addPlayer(player); - } - if(other.getScoreboard().getTeam(Plugin.GetClients().Get(player).GetRank().Name + Plugin.GetGame().GetTeam(player).GetName().toUpperCase()) != null) - { - if(other.getScoreboard().getTeam(Plugin.GetClients().Get(player).GetRank().Name + Plugin.GetGame().GetTeam(player).GetName().toUpperCase()).getPlayers().contains(player)) - { - other.getScoreboard().getTeam(Plugin.GetClients().Get(player).GetRank().Name + Plugin.GetGame().GetTeam(player).GetName().toUpperCase()).removePlayer(player); - other.getScoreboard().getTeam(Plugin.GetClients().Get(player).getDisguisedRank().Name + Plugin.GetGame().GetTeam(player).GetName().toUpperCase()).addPlayer(player); - } - } - } - catch (NullPointerException exp) - {} - } - - if(Plugin.GetDisguise().isDisguised(player)) - continue; + UtilPlayer.message(caller, C.cRed + C.Bold + "Invalid Disguise Name: " + ChatColor.RESET + args[0]); + return; + } - DisguisePlayer playerDisguise = new DisguisePlayer(player, _disguisedPlayers.get(player)); - Plugin.GetDisguise().disguise(playerDisguise); - } - } - - public void changeName(final Player player , String changedName, boolean skin) - { try - { - GameProfile gameProfile = ((CraftPlayer) player).getProfile(); - - Field name = GameProfile.class.getDeclaredField("name"); - name.setAccessible(true); - name.set(gameProfile, changedName); - name.setAccessible(false); - - } - catch (Exception ex) { - ex.printStackTrace(); - } - } - - @EventHandler(priority=EventPriority.HIGHEST) - public void Quit(PlayerQuitEvent event) - { - Player player = event.getPlayer(); - - if(_disguisedPlayers.containsKey(player)) - { - try - { - _disguisedPlayers.remove(player); - Plugin.GetDisguise().undisguise(player); - String playerName = _disguisedPlayersNames.get(player); - - CoreClient client = Plugin.GetClients().Get(player); - client.setDisguisedRank(null); - client.setDisguisedAs(null); - client.setDisguised(false); - - changeName(player, playerName, true); - } - catch (Exception ex) - { - ex.printStackTrace(); - } - } - } - - @EventHandler(priority=EventPriority.HIGHEST) - public void Join(PlayerLoginEvent event) - { - for(Player player : _disguisedPlayers.keySet()) - { - if(player.getName().equalsIgnoreCase(event.getPlayer().getName())) - { - event.disallow(Result.KICK_OTHER, "There is already the same account playing. this probably happened because of /disguise"); - } - } - } - - @EventHandler - public void gadget(GadgetActivateEvent event) - { - if(!event.getGadget().GetName().equalsIgnoreCase("Coin Party Bomb") && event.getGadget().getGadgetType() != GadgetType.Morph) + CoreClient client = Plugin.GetClients().Get(caller); + UUID uuid = UUIDFetcher.getUUIDOf(args[0]); + GameProfile profile = null; + try + { + profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); + } catch(Exception e) + { + uuid = UUIDFetcher.getUUIDOf("Alex"); + profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); + } + + Rank otherRank = Rank.ALL; + try + { + CoreClient other = new CoreClient(args[0]); + Plugin.GetClients().LoadClient(other, uuid, caller.getAddress().getAddress().getAddress().toString()); + otherRank = other.GetRank(); + } catch(NullPointerException exception) + {} + if(otherRank.Has(Rank.TWITCH)) + { + UtilPlayer.message(caller, C.cRed + C.Bold + "You can't disguise as staff!"); return; - - if(_disguisedPlayers.containsKey(event.getPlayer())) + } + _disguisedPlayers.put(caller, profile); + _disguisedPlayersNames.put(caller, caller.getName()); + client.setDisguisedRank(otherRank); + client.setDisguised(true); + + client.setDisguisedAs(args[0]); + + changeName(caller, args[0], true); + + Plugin.getCosmeticManager().getGadgetManager().RemoveItem(caller); + + UtilPlayer.message(caller, C.cGreen + C.Bold + "Disguise Active: " + ChatColor.RESET + args[0]); + } catch(Exception e) { - event.setCancelled(true); + e.printStackTrace(); + UtilPlayer.message(caller, C.cRed + C.Bold + "Invalid Disguise Name: " + ChatColor.RESET + args[0]); + return; } - } - - @EventHandler - public void chest(TreasureStartEvent event) + } + }); + } + + @EventHandler + public void updateDisguises(UpdateEvent event) + { + if(event.getType() != UpdateType.FASTEST) + return; + + for(final Player player : UtilServer.getPlayers()) { - if(_disguisedPlayers.containsKey(event.getPlayer())) + if(!_disguisedPlayers.containsKey(player)) + continue; + + for(Player other : UtilServer.getPlayers()) + { + try { - UtilPlayer.message(event.getPlayer(), F.main("Disguise", "You cant open Treasure Chests while you are disguised!")); - event.setCancelled(true); - } + if(other.getScoreboard().getTeam(Plugin.GetClients().Get(player).GetRank().Name).getPlayers().contains(player)) + { + other.getScoreboard().getTeam(Plugin.GetClients().Get(player).GetRank().Name).removePlayer(player); + other.getScoreboard().getTeam(Plugin.GetClients().Get(player).getDisguisedRank().Name).addPlayer(player); + } + if(other.getScoreboard().getTeam( + Plugin.GetClients().Get(player).GetRank().Name + Plugin.GetGame().GetTeam(player).GetName().toUpperCase()) != null) + { + if(other.getScoreboard() + .getTeam(Plugin.GetClients().Get(player).GetRank().Name + Plugin.GetGame().GetTeam(player).GetName().toUpperCase()) + .getPlayers().contains(player)) + { + other.getScoreboard() + .getTeam( + Plugin.GetClients().Get(player).GetRank().Name + Plugin.GetGame().GetTeam(player).GetName().toUpperCase()) + .removePlayer(player); + other.getScoreboard() + .getTeam( + Plugin.GetClients().Get(player).getDisguisedRank().Name + + Plugin.GetGame().GetTeam(player).GetName().toUpperCase()).addPlayer(player); + } + } + } catch(NullPointerException exp) + {} + } + + if(Plugin.GetDisguise().isDisguised(player)) + continue; + + DisguisePlayer playerDisguise = new DisguisePlayer(player, _disguisedPlayers.get(player)); + _disguisedPlayerDisguises.put(player, playerDisguise); + Plugin.GetDisguise().disguise(playerDisguise); } - + } + + public void changeName(final Player player, String changedName, boolean skin) + { + try + { + GameProfile gameProfile = ((CraftPlayer) player).getProfile(); + + Field name = GameProfile.class.getDeclaredField("name"); + name.setAccessible(true); + name.set(gameProfile, changedName); + name.setAccessible(false); + + } catch(Exception ex) + { + ex.printStackTrace(); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void Quit(PlayerQuitEvent event) + { + Player player = event.getPlayer(); + + if(_disguisedPlayers.containsKey(player)) + { + try + { + _disguisedPlayers.remove(player); + _disguisedPlayerDisguises.remove(player); + _disguisedPlayersNames.remove(player); + Plugin.GetDisguise().undisguise(player); + String playerName = _disguisedPlayersNames.get(player); + + CoreClient client = Plugin.GetClients().Get(player); + client.setDisguisedRank(null); + client.setDisguisedAs(null); + client.setDisguised(false); + + changeName(player, playerName, true); + } catch(Exception ex) + { + ex.printStackTrace(); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void Join(PlayerLoginEvent event) + { + for(Player player : _disguisedPlayers.keySet()) + { + if(player.getName().equalsIgnoreCase(event.getPlayer().getName())) + { + event.disallow(Result.KICK_OTHER, "There is already the same account playing. this probably happened because of /disguise"); + } + } + } + + @EventHandler + public void gadget(GadgetActivateEvent event) + { + if(!event.getGadget().GetName().equalsIgnoreCase("Coin Party Bomb") && event.getGadget().getGadgetType() != GadgetType.Morph) + return; + + if(_disguisedPlayers.containsKey(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void chest(TreasureStartEvent event) + { + if(_disguisedPlayers.containsKey(event.getPlayer())) + { + UtilPlayer.message(event.getPlayer(), F.main("Disguise", "You cant open Treasure Chests while you are disguised!")); + event.setCancelled(true); + } + } + + @EventHandler + public void onPlayerSneak(PlayerToggleSneakEvent event) + { + Player player = event.getPlayer(); + + if(_disguisedPlayers.containsKey(player)) + { + DisguisePlayer dp = _disguisedPlayerDisguises.get(player); + + dp.setSneaking(!dp.getSneaking()); + } + } + + @EventHandler + public void onPlayerLeftClick(PlayerInteractEvent event) + { + Player player = event.getPlayer(); + + if(event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) + { + if(_disguisedPlayers.containsKey(player)) + { + EntityHuman human = (((CraftHumanEntity)((CraftPlayer) player)).getHandle()); + human.world.broadcastEntityEffect(human, (byte) 0); + } + } + } + } From 6311ceaa0f81a07be1f53494a5347a48f946b8ce Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 6 Aug 2015 21:15:17 -0500 Subject: [PATCH 255/377] Reward work for new Game reward rarity and setup for carl, work on carl spinner --- .../src/mineplex/core/gui/DisplayItem.java | 40 +++++++ .../src/mineplex/core/reward/RewardData.java | 9 +- .../mineplex/core/reward/RewardManager.java | 12 ++ .../mineplex/core/reward/RewardRarity.java | 44 ++++++-- .../src/mineplex/core/reward/RewardType.java | 16 ++- .../core/reward/rewards/CoinReward.java | 5 +- .../core/reward/rewards/GemReward.java | 75 +++++++++++++ .../core/reward/rewards/InventoryReward.java | 15 +-- .../core/reward/rewards/RankReward.java | 8 +- .../reward/rewards/UnknownPackageReward.java | 4 +- .../core/treasure/TreasureManager.java | 9 +- .../src/mineplex/hub/HubManager.java | 13 ++- .../mineplex/hub/bonuses/BonusManager.java | 12 +- .../hub/bonuses/commands/GuiCommand.java | 3 +- .../mineplex/hub/bonuses/gui/BonusGui.java | 5 +- .../src/mineplex/hub/bonuses/gui/SpinGui.java | 104 +++++++++++++++++- .../bonuses/gui/buttons/CarlSpinButton.java | 17 ++- 17 files changed, 335 insertions(+), 56 deletions(-) create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gui/DisplayItem.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/GemReward.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gui/DisplayItem.java b/Plugins/Mineplex.Core/src/mineplex/core/gui/DisplayItem.java new file mode 100644 index 000000000..87e844b1c --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gui/DisplayItem.java @@ -0,0 +1,40 @@ +package mineplex.core.gui; + +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.gui.GuiItem; + +public class DisplayItem implements GuiItem +{ + private ItemStack _item; + + public DisplayItem(ItemStack item) + { + _item = item; + } + + @Override + public void setup() + { + + } + + @Override + public void close() + { + + } + + @Override + public void click(ClickType clickType) + { + + } + + @Override + public ItemStack getObject() + { + return _item; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardData.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardData.java index 77f8b91e3..0a20e5ccf 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardData.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardData.java @@ -9,11 +9,13 @@ public class RewardData { private final String _friendlyName; private final ItemStack _displayItem; + private final RewardRarity _rarity; - public RewardData(String friendlyName, ItemStack displayItem) + public RewardData(String friendlyName, ItemStack displayItem, RewardRarity rarity) { _friendlyName = friendlyName; _displayItem = displayItem; + _rarity = rarity; } public String getFriendlyName() @@ -26,4 +28,9 @@ public class RewardData return _displayItem; } + public RewardRarity getRarity() + { + return _rarity; + } + } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index 775ab3cd5..b3d467ddc 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -18,6 +18,7 @@ import mineplex.core.donation.DonationManager; import mineplex.core.inventory.InventoryManager; import mineplex.core.pet.PetManager; import mineplex.core.reward.rewards.CoinReward; +import mineplex.core.reward.rewards.GemReward; import mineplex.core.reward.rewards.InventoryReward; import mineplex.core.reward.rewards.PetReward; import mineplex.core.reward.rewards.RankReward; @@ -53,12 +54,18 @@ public class RewardManager _doubleGadgetValue = doubleGadgetValue; + addGame(donationManager, inventoryManager, petManager); addCommon(donationManager, inventoryManager, petManager, commonValueMin, commonValueMax); addUncommon(donationManager, inventoryManager, petManager, uncommonValueMin, uncommonValueMax); addRare(donationManager, inventoryManager, petManager, rareValueMin, rareValueMax); addLegendary(donationManager, inventoryManager, petManager, legendValueMin, legendValueMax); } + public void addGame(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager) + { + addReward(new GemReward(donationManager, 100, 500, 1, RewardRarity.GAME)); + } + public void addCommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.COMMON; @@ -393,6 +400,11 @@ public class RewardManager } } + System.out.println("null"); + System.out.println("type: " + type.toString()); + System.out.println("rarity: " + rarity); + System.out.println("total weight: " + totalWeight); + return null; } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java index fc186ed03..1f56de46a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java @@ -1,5 +1,9 @@ package mineplex.core.reward; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + import mineplex.core.common.util.C; import static mineplex.core.common.util.C.*; @@ -14,20 +18,31 @@ public enum RewardRarity * (Fireworks, sounds, etc) */ - OTHER("Other", cWhite), - COMMON("Common", cWhite), - UNCOMMON("Uncommon", cAqua), - RARE("Rare", cPurple), - LEGENDARY("Legendary", cGreen), - MYTHICAL("Mythical", cRed); + OTHER("Other", cWhite, Material.STAINED_GLASS_PANE, (byte) 0), + COMMON("Common", cWhite, Material.STAINED_GLASS_PANE, (byte) 0), + GAME("Game", cYellow, Material.STAINED_GLASS_PANE, (byte) 4), + UNCOMMON("Uncommon", cAqua, Material.STAINED_GLASS_PANE, (byte) 3), + RARE("Rare", cPurple, Material.STAINED_GLASS_PANE, (byte) 10), + LEGENDARY("Legendary", cGreen, Material.STAINED_GLASS_PANE, (byte) 5), + MYTHICAL("Mythical", cRed, Material.STAINED_GLASS_PANE, (byte) 14); private String _name; private String _color; + private Material _material; + private byte _data; + private ItemStack _stack; - RewardRarity(String name, String color) + RewardRarity(String name, String color, Material material, byte data) { _name = name; _color = color; + _material = material; + _data = data; + + _stack = new ItemStack(getMaterial(), 1, (short) 0, getData()); + ItemMeta meta = _stack.getItemMeta(); + meta.setDisplayName(_color + _name); + _stack.setItemMeta(meta); } public String getColor() @@ -40,4 +55,19 @@ public enum RewardRarity return _name; } + public Material getMaterial() + { + return _material; + } + + public byte getData() + { + return _data; + } + + public ItemStack getItemStack() + { + return _stack; + } + } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java index 556c7f5e0..febaec152 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java @@ -3,22 +3,25 @@ package mineplex.core.reward; public enum RewardType { //% Chances Mythic Legend Rare Uncommon - GameLoot( 0.000001, 0.00001, 0.0001, 3), - OldChest( 0, 0.05, 0.4, 5), - AncientChest( 0, 1, 4, 25), - MythicalChest( 0.5, 3, 12, 75); + GameLoot( 0.000001, 0.00001, 0.0001, 3, 10), + Spinner( 0.000001, 0.2, 0.8, 10, 10), + OldChest( 0, 0.05, 0.4, 5, 0), + AncientChest( 0, 1, 4, 25, 0), + MythicalChest( 0.5, 3, 12, 75, 0); private double _mythicalChance; private double _legendaryChance; private double _rareChance; private double _uncommonChance; - - RewardType(double mythical, double legend, double rare, double uncommon) + private double _gameChance; + + RewardType(double mythical, double legend, double rare, double uncommon, double game) { _mythicalChance = (mythical / 100d); _legendaryChance = _mythicalChance + (legend / 100d); //Add previous chance to prep for generateRarity random values. _rareChance = _legendaryChance + (rare / 100d); _uncommonChance = _rareChance + (uncommon / 100d); + _gameChance = _uncommonChance + (game / 100d); } public RewardRarity generateRarity(boolean requiresUncommon) @@ -31,6 +34,7 @@ public enum RewardType else if (rand <= _legendaryChance) rarity = RewardRarity.LEGENDARY; else if (rand <= _rareChance) rarity = RewardRarity.RARE; else if (rand <= _uncommonChance || requiresUncommon) rarity = RewardRarity.UNCOMMON; + else if (rand <= _gameChance) rarity = RewardRarity.GAME; return rarity; } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java index f6fbd063f..1bf59afb9 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/CoinReward.java @@ -48,14 +48,13 @@ public class CoinReward extends Reward } }, "Treasure Chest", player.getName(), _donationManager.getClientManager().Get(player).getAccountId(), coinsToReward); - return new RewardData(getRarity().getColor() + coinsToReward + " Coins", new ItemStack(175)); + return new RewardData(getRarity().getColor() + coinsToReward + " Coins", new ItemStack(175), getRarity()); } @Override public RewardData getFakeRewardData(Player player) { - int coinsToReward = _random.nextInt(_maxCoinCount - _minCoinCount) + _minCoinCount; - return new RewardData(getRarity().getColor() + coinsToReward + " Coins", new ItemStack(175)); + return new RewardData(getRarity().getColor() + "Coins", new ItemStack(175), getRarity()); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/GemReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/GemReward.java new file mode 100644 index 000000000..26e695abb --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/GemReward.java @@ -0,0 +1,75 @@ +package mineplex.core.reward.rewards; + +import java.util.Random; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.Callback; +import mineplex.core.donation.DonationManager; +import mineplex.core.reward.Reward; +import mineplex.core.reward.RewardData; +import mineplex.core.reward.RewardManager; +import mineplex.core.reward.RewardRarity; + +public class GemReward extends Reward +{ + private DonationManager _donationManager; + private Random _random; + private int _minGemCount; + private int _maxGemCount; + + public GemReward(DonationManager donationManager, int minGemCount, int maxGemCount, int weight, RewardRarity rarity) + { + this(donationManager, minGemCount, maxGemCount, weight, rarity, RANDOM); + } + + public GemReward(DonationManager donationManager, int minGemCount, int maxGemCount, int weight, RewardRarity rarity, Random random) + { + super(rarity, weight); + _donationManager = donationManager; + _minGemCount = minGemCount; + _maxGemCount = maxGemCount; + + _random = random; + } + + @Override + public RewardData giveRewardCustom(Player player) + { + int GemsToReward = _random.nextInt(_maxGemCount - _minGemCount) + _minGemCount; + + _donationManager.RewardGems(new Callback() + { + @Override + public void run(Boolean data) + { + + } + }, "Treasure Chest", player.getName(), player.getUniqueId(), GemsToReward); + + return new RewardData(getRarity().getColor() + GemsToReward + " Gems", new ItemStack(Material.EMERALD), getRarity()); + } + + @Override + public RewardData getFakeRewardData(Player player) + { + return new RewardData(getRarity().getColor() + "Gems", new ItemStack(Material.EMERALD), getRarity()); + } + + @Override + public boolean canGiveReward(Player player) + { + return true; + } + + @Override + public boolean equals(Object obj) + { + if (obj instanceof GemReward) + return true; + + return false; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java index 68e01acf1..0eb1504e0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/InventoryReward.java @@ -59,24 +59,13 @@ public class InventoryReward extends Reward _inventoryManager.addItemToInventory(player, "Item", _packageName, amountToGive); - return new RewardData(getRarity().getColor() + amountToGive + " " + _name, _itemStack); + return new RewardData(getRarity().getColor() + amountToGive + " " + _name, _itemStack, getRarity()); } @Override public RewardData getFakeRewardData(Player player) { - int amountToGive; - - if (_minAmount != _maxAmount) - { - amountToGive = _random.nextInt(_maxAmount - _minAmount) + _minAmount; - } - else - { - amountToGive = _minAmount; - } - - return new RewardData(getRarity().getColor() + amountToGive + " " + _name, _itemStack); + return new RewardData(getRarity().getColor() + _name, _itemStack, getRarity()); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java index bbf22db1f..6c3ce1a6a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/RankReward.java @@ -33,12 +33,12 @@ public class RankReward extends Reward else if (_clientManager.Get(player).GetRank() == Rank.HERO) rank = Rank.LEGEND; if (rank == null) - return new RewardData(getRarity().getColor() + "Rank Upgrade Error", new ItemStack(Material.PAPER)); + return new RewardData(getRarity().getColor() + "Rank Upgrade Error", new ItemStack(Material.PAPER), getRarity()); _clientManager.Get(player).SetRank(rank); _clientManager.getRepository().saveRank(null, player.getName(), player.getUniqueId(), rank, true); - return new RewardData(getRarity().getColor() + rank.Name + " Rank", new ItemStack(Material.NETHER_STAR)); + return new RewardData(getRarity().getColor() + rank.Name + " Rank", new ItemStack(Material.NETHER_STAR), getRarity()); } @Override @@ -50,9 +50,9 @@ public class RankReward extends Reward else if (_clientManager.Get(player).GetRank() == Rank.HERO) rank = Rank.LEGEND; if (rank == null) - return new RewardData(getRarity().getColor() + "Rank Upgrade Error", new ItemStack(Material.PAPER)); + return new RewardData(getRarity().getColor() + "Rank Upgrade Error", new ItemStack(Material.PAPER), getRarity()); - return new RewardData(getRarity().getColor() + rank.Name + " Rank", new ItemStack(Material.NETHER_STAR)); + return new RewardData(getRarity().getColor() + rank.Name + " Rank", new ItemStack(Material.NETHER_STAR), getRarity()); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java index 364820d56..af27a817e 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/UnknownPackageReward.java @@ -33,7 +33,7 @@ public class UnknownPackageReward extends Reward { _donationManager.PurchaseUnknownSalesPackage(null, player.getName(), _donationManager.getClientManager().Get(player).getAccountId(), _packageName, true, 0, true); - return new RewardData(getRarity().getColor() + _name, _itemStack); + return new RewardData(getRarity().getColor() + _name, _itemStack, getRarity()); } @Override @@ -51,7 +51,7 @@ public class UnknownPackageReward extends Reward @Override public RewardData getFakeRewardData(Player player) { - return new RewardData(getRarity().getColor() + _name, _itemStack); + return new RewardData(getRarity().getColor() + _name, _itemStack, getRarity()); } protected String getPackageName() diff --git a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java index 39de66bf0..5746bc978 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java @@ -32,19 +32,14 @@ public class TreasureManager extends MiniPlugin private HologramManager _hologramManager; private List _treasureLocations; - public TreasureManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, BlockRestore blockRestore, HologramManager hologramManager) + public TreasureManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, BlockRestore blockRestore, HologramManager hologramManager, RewardManager rewardManager) { super("Treasure", plugin); _inventoryManager = inventoryManager; _blockRestore = blockRestore; _hologramManager = hologramManager; - _rewardManager = new RewardManager(clientManager, donationManager, inventoryManager, petManager, - 100, 250, - 500, 1000, - 4000, 6000, - 12000, 32000, - true); + _rewardManager = rewardManager; World world = Bukkit.getWorlds().get(0); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index b87554309..2b5188a30 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -78,6 +78,7 @@ import mineplex.core.pet.PetManager; import mineplex.core.portal.Portal; import mineplex.core.preferences.PreferencesManager; import mineplex.core.projectile.ProjectileManager; +import mineplex.core.reward.RewardManager; import mineplex.core.stats.StatsManager; import mineplex.core.task.TaskManager; import mineplex.core.treasure.TreasureManager; @@ -177,7 +178,15 @@ public class HubManager extends MiniClientPlugin _inventoryManager = new InventoryManager(plugin, clientManager); new BenefitManager(plugin, clientManager, _inventoryManager); _gadgetManager = new GadgetManager(_plugin, clientManager, donationManager, _inventoryManager, _mountManager, petManager, preferences, disguiseManager, blockRestore, new ProjectileManager(plugin)); - _treasureManager = new TreasureManager(_plugin, clientManager, donationManager, _inventoryManager, petManager, _blockRestore, hologramManager); + + RewardManager rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, + 100, 250, + 500, 1000, + 4000, 6000, + 12000, 32000, + true); + + _treasureManager = new TreasureManager(_plugin, clientManager, donationManager, _inventoryManager, petManager, _blockRestore, hologramManager, rewardManager); new CosmeticManager(_plugin, clientManager, donationManager, _inventoryManager, _gadgetManager, _mountManager, petManager, _treasureManager); _petManager = petManager; @@ -198,7 +207,7 @@ public class HubManager extends MiniClientPlugin ((CraftWorld)Bukkit.getWorlds().get(0)).getHandle().pvpMode = true; - new BonusManager(plugin, clientManager, donationManager, npcManager, hologramManager); + new BonusManager(plugin, clientManager, donationManager, npcManager, hologramManager, rewardManager); // NotificationManager notificationManager = new NotificationManager(plugin, clientManager, donationManager); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index 5f2c1b0e9..f5b67a4a5 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -21,6 +21,7 @@ import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; import mineplex.core.npc.Npc; import mineplex.core.npc.NpcManager; +import mineplex.core.reward.RewardManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.hub.bonuses.commands.GuiCommand; @@ -84,9 +85,10 @@ public class BonusManager extends MiniClientPlugin implements I private DonationManager _donationManager; private NpcManager _npcManager; private HologramManager _hologramManager; + private RewardManager _rewardManager; private Npc _carlNpc; - public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, NpcManager npcManager, HologramManager hologramManager) + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, NpcManager npcManager, HologramManager hologramManager, RewardManager rewardManager) { super("Bonus", plugin); _repository = new BonusRepository(plugin, this, donationManager); @@ -94,6 +96,7 @@ public class BonusManager extends MiniClientPlugin implements I _donationManager = donationManager; _npcManager = npcManager; _hologramManager = hologramManager; + _rewardManager = rewardManager; // Hope to god this works! _carlNpc = _npcManager.getNpcByName("Carl the Creeper"); @@ -402,7 +405,7 @@ public class BonusManager extends MiniClientPlugin implements I if (entity instanceof LivingEntity && entity.getType().equals(EntityType.CREEPER) && ((LivingEntity) entity).getCustomName().contains("Carl the Creeper")) { updateDailyStreak(event.getPlayer()); - new BonusGui(_plugin, event.getPlayer(), this).openInventory(); + new BonusGui(_plugin, event.getPlayer(), this, _rewardManager).openInventory(); } } @@ -535,6 +538,11 @@ public class BonusManager extends MiniClientPlugin implements I return _clientManager; } + public RewardManager getRewardManager() + { + return _rewardManager; + } + @Override @EventHandler public void UnloadPlayer(final ClientUnloadEvent event) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java index 79247514a..655a94199 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java @@ -4,6 +4,7 @@ import org.bukkit.entity.Player; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; +import mineplex.core.reward.RewardManager; import mineplex.hub.bonuses.BonusManager; import mineplex.hub.bonuses.gui.BonusGui; @@ -17,7 +18,7 @@ public class GuiCommand extends CommandBase{ @Override public void Execute(Player caller, String[] args) { - new BonusGui(Plugin.getPlugin(), caller, Plugin).openInventory(); + new BonusGui(Plugin.getPlugin(), caller, Plugin, Plugin.getRewardManager()).openInventory(); } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java index 013873587..083288461 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java @@ -1,6 +1,7 @@ package mineplex.hub.bonuses.gui; import mineplex.core.gui.SimpleGui; +import mineplex.core.reward.RewardManager; import mineplex.hub.bonuses.BonusManager; import mineplex.hub.bonuses.gui.buttons.CarlSpinButton; import mineplex.hub.bonuses.gui.buttons.DailyBonusButton; @@ -15,7 +16,7 @@ public class BonusGui extends SimpleGui private BonusManager manager; - public BonusGui(Plugin plugin, Player player, BonusManager manager) + public BonusGui(Plugin plugin, Player player, BonusManager manager, RewardManager rewardManager) { super(plugin, player, player.getName() + "'s Bonuses", 5 * 9); @@ -27,7 +28,7 @@ public class BonusGui extends SimpleGui setItem(15, new DailyBonusButton(getPlugin(), player, this, manager)); - setItem(31, new CarlSpinButton()); + setItem(31, new CarlSpinButton(getPlugin(), player, rewardManager)); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java index c88bde558..8701b3618 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java @@ -1,14 +1,114 @@ package mineplex.hub.bonuses.gui; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; +import mineplex.core.gui.DisplayItem; import mineplex.core.gui.SimpleGui; +import mineplex.core.reward.Reward; +import mineplex.core.reward.RewardData; +import mineplex.core.reward.RewardManager; +import mineplex.core.reward.RewardType; +import mineplex.core.shop.item.ShopItem; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.bonuses.gui.buttons.RewardButton; public class SpinGui extends SimpleGui { - public SpinGui(Plugin plugin, Player player) + private static final int SELECT_OFFSET = 4; + private static final int REWARDS_TO_GENERATE = 1000; + private static final int HOPPER_SLOT = 22; + private static final int CARL_SLOT = 40; + private static final int[] LINE_NUMS = { -27, -18, -9, 9, 18 }; + + private int _tickCount; + private int _currentRewardIndex; + private int _ticksThisSwap; + private int _ticksPerSwap; + private int _swapCount; + private Reward[] _rewards; + + public SpinGui(Plugin plugin, Player player, RewardManager rewardManager) { - super(plugin, player); + super(plugin, player, "Carl's Spinner", 54); + + ShopItem carlItem = new ShopItem(Material.SKULL_ITEM, (byte) 4, "Carl's Spinner", new String[] {ChatColor.RESET + "Good Luck!" }, 1, false, false); + + setItem(HOPPER_SLOT, new DisplayItem(new ItemStack(Material.HOPPER))); + setItem(CARL_SLOT, new DisplayItem(carlItem)); + + _rewards = new Reward[REWARDS_TO_GENERATE]; + + for (int i = 0; i < REWARDS_TO_GENERATE; i++) + { + _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.Spinner, true); + } + + _ticksPerSwap = 3; } + + private void tick() + { + _ticksThisSwap++; + + // Swap + if (_ticksThisSwap >= _ticksPerSwap) + { + _ticksThisSwap = 0; + _swapCount++; + + updateGui(); + float pitch = Math.max(-2, 2 - (_swapCount / 50f)); +// Bukkit.broadcastMessage(pitch + ""); + getPlayer().playSound(getPlayer().getEyeLocation(), Sound.NOTE_PLING, 1, pitch); + + _currentRewardIndex++; + + // Slow + if (_swapCount % 10 == 0) + _ticksPerSwap++; + } + + _tickCount++; + } + + public void updateGui() + { + for (int i = 0; i < 9; i++) + { + int index = _currentRewardIndex + i; + index = index % REWARDS_TO_GENERATE; + + int slot = 27 + i; + RewardData data = _rewards[index].getFakeRewardData(getPlayer()); + setItem(slot, new RewardButton(data)); + + // Glass Panes + for (int j = 0; j < LINE_NUMS.length; j++) + { + int paneSlot = slot + LINE_NUMS[j]; + if (paneSlot == HOPPER_SLOT || paneSlot == CARL_SLOT) + continue; + + setItem(paneSlot, new DisplayItem(data.getRarity().getItemStack())); + } + } + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + tick(); + } + } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java index 5262d6c3f..e91626a23 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java @@ -2,18 +2,28 @@ package mineplex.hub.bonuses.gui.buttons; import org.bukkit.ChatColor; import org.bukkit.Material; +import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; import mineplex.core.gui.GuiItem; +import mineplex.core.reward.RewardManager; import mineplex.core.shop.item.ShopItem; +import mineplex.hub.bonuses.gui.SpinGui; public class CarlSpinButton implements GuiItem { - public CarlSpinButton() - { + private Plugin _plugin; + private Player _player; + private RewardManager _rewardManager; + public CarlSpinButton(Plugin plugin, Player player, RewardManager rewardManager) + { + _plugin = plugin; + _player = player; + _rewardManager = rewardManager; } @Override @@ -30,7 +40,7 @@ public class CarlSpinButton implements GuiItem @Override public void click(ClickType clickType) { - + new SpinGui(_plugin, _player, _rewardManager).openInventory(); } @Override @@ -38,7 +48,6 @@ public class CarlSpinButton implements GuiItem { ShopItem item = new ShopItem(Material.SKULL_ITEM, (byte) 4, "Carl's Spinner", new String[] {ChatColor.RESET + "Try your Luck!" }, 1, false, false); - return item; } } From be18dc1bf58971e363fc708d60af7e64dc0c8114 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 6 Aug 2015 21:41:56 -0500 Subject: [PATCH 256/377] Add experience rewards to reward manager --- .../mineplex/core/reward/RewardManager.java | 15 +++--- .../core/reward/rewards/ExperienceReward.java | 52 +++++++++++++++++++ .../src/mineplex/hub/HubManager.java | 2 +- .../game/arcade/managers/GameLootManager.java | 2 +- 4 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index b3d467ddc..53bc45205 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -18,11 +18,13 @@ import mineplex.core.donation.DonationManager; import mineplex.core.inventory.InventoryManager; import mineplex.core.pet.PetManager; import mineplex.core.reward.rewards.CoinReward; +import mineplex.core.reward.rewards.ExperienceReward; import mineplex.core.reward.rewards.GemReward; import mineplex.core.reward.rewards.InventoryReward; import mineplex.core.reward.rewards.PetReward; import mineplex.core.reward.rewards.RankReward; import mineplex.core.reward.rewards.UnknownPackageReward; +import mineplex.core.stats.StatsManager; public class RewardManager { @@ -31,10 +33,10 @@ public class RewardManager private Random _random; private CoreClientManager _clientManager; - + private boolean _doubleGadgetValue; - public RewardManager(CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, + public RewardManager(CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, int commonValueMin, int commonValueMax, int uncommonValueMin, int uncommonValueMax, int rareValueMin, int rareValueMax, @@ -51,19 +53,20 @@ public class RewardManager } _clientManager = clientManager; - + _doubleGadgetValue = doubleGadgetValue; - addGame(donationManager, inventoryManager, petManager); + addGame(donationManager, inventoryManager, petManager, statsManager); addCommon(donationManager, inventoryManager, petManager, commonValueMin, commonValueMax); addUncommon(donationManager, inventoryManager, petManager, uncommonValueMin, uncommonValueMax); addRare(donationManager, inventoryManager, petManager, rareValueMin, rareValueMax); addLegendary(donationManager, inventoryManager, petManager, legendValueMin, legendValueMax); } - public void addGame(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager) + public void addGame(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager) { - addReward(new GemReward(donationManager, 100, 500, 1, RewardRarity.GAME)); + addReward(new GemReward(donationManager, 100, 500, 100, RewardRarity.GAME)); + addReward(new ExperienceReward(statsManager, 100, 5000, 100, RewardRarity.GAME)); } public void addCommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java new file mode 100644 index 000000000..a96245c6f --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java @@ -0,0 +1,52 @@ +package mineplex.core.reward.rewards; + +import java.util.Random; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.reward.Reward; +import mineplex.core.reward.RewardData; +import mineplex.core.reward.RewardRarity; +import mineplex.core.stats.StatsManager; + +public class ExperienceReward extends Reward +{ + private StatsManager _statsManager; + private Random _random; + private int _minExperience; + private int _maxExperience; + + public ExperienceReward(StatsManager statsManager, int minExperience, int maxExperience, int weight, RewardRarity rarity) + { + super(rarity, weight); + + _statsManager = statsManager; + _random = new Random(); + _minExperience = minExperience; + _maxExperience = maxExperience; + } + + @Override + protected RewardData giveRewardCustom(Player player) + { + int experience = _random.nextInt(_maxExperience - _minExperience) + _minExperience; + + _statsManager.incrementStat(player, "Global.ExpEarned", experience); + + return new RewardData(getRarity().getColor() + experience + " Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.GAME); + } + + @Override + public RewardData getFakeRewardData(Player player) + { + return new RewardData(getRarity().getColor() + "Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.GAME); + } + + @Override + public boolean canGiveReward(Player player) + { + return true; + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index 2b5188a30..4a4fbdd2b 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -179,7 +179,7 @@ public class HubManager extends MiniClientPlugin new BenefitManager(plugin, clientManager, _inventoryManager); _gadgetManager = new GadgetManager(_plugin, clientManager, donationManager, _inventoryManager, _mountManager, petManager, preferences, disguiseManager, blockRestore, new ProjectileManager(plugin)); - RewardManager rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, + RewardManager rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, statsManager, 100, 250, 500, 1000, 4000, 6000, diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java index 08fc48275..91e3ae9ec 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java @@ -50,7 +50,7 @@ public class GameLootManager implements Listener Manager.getPluginManager().registerEvents(this, Manager.getPlugin()); - _rewardManager = new RewardManager(Manager.GetClients(), Manager.GetDonation(), Manager.getInventoryManager(), petManager, + _rewardManager = new RewardManager(Manager.GetClients(), Manager.GetDonation(), Manager.getInventoryManager(), petManager, Manager.GetStatsManager(), 100, 250, 500, 1000, 1500, 2500, From 5f435a079ee8213ff99493cef8e2665b467c794e Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 6 Aug 2015 21:59:21 -0500 Subject: [PATCH 257/377] Update vote button --- .../mineplex/hub/bonuses/BonusManager.java | 9 + .../hub/bonuses/gui/buttons/VoteButton.java | 182 ++++++------------ 2 files changed, 73 insertions(+), 118 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index f5b67a4a5..5acba755a 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -268,6 +268,15 @@ public class BonusManager extends MiniClientPlugin implements I return amount; } + public BonusAmount getVoteBonusAmount(Player player) + { + BonusAmount amount = new BonusAmount(); + amount.setTickets(1); + amount.setBonusCoins(100); + amount.setBonusExperience(100); + return amount; + } + public BonusAmount getRankBonusAmount(Player player) { Rank rank = _clientManager.Get(player).GetRank(); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java index 963e8506e..164c55936 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java @@ -1,13 +1,21 @@ package mineplex.hub.bonuses.gui.buttons; +import java.util.ArrayList; + +import mineplex.core.common.jsonchat.ClickEvent; +import mineplex.core.common.jsonchat.JsonMessage; +import mineplex.core.common.util.C; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime.TimeUnit; import mineplex.core.gui.GuiItem; import mineplex.core.gui.ItemRefresher; import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.shop.item.ShopItem; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.bonuses.BonusAmount; +import mineplex.hub.bonuses.BonusClientData; import mineplex.hub.bonuses.BonusManager; import net.minecraft.server.v1_7_R4.ChatSerializer; import net.minecraft.server.v1_7_R4.IChatBaseComponent; @@ -29,8 +37,6 @@ public class VoteButton implements GuiItem, Listener { private ItemStack _item; - private long bonusTime; - private String _url; private Player _player; @@ -51,14 +57,9 @@ public class VoteButton implements GuiItem, Listener { public void setup() { //TODO get url from db - _url = "http://minecraftservers.org/server/121070"; + _url = "http://minecraftservers.org/vote/121070"; - this.bonusTime = _bonusManager.nextVoteTime(getPlayer()); - - //if (_url != null) Bukkit.getPluginManager().registerEvents(this, getPlugin()); - - setItem(); } @Override @@ -77,22 +78,14 @@ public class VoteButton implements GuiItem, Listener { getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); - // TODO This probably needs to be redone, I just looked stuff up and - // pasted it together - - UtilPlayer.message(getPlayer(), "============================================="); + UtilPlayer.message(getPlayer(), C.cRed + "------------------------------------------------"); UtilPlayer.message(getPlayer(), ""); - IChatBaseComponent comp = ChatSerializer.a("{\"text\":\"" + " " + "\",\"extra\":[{\"text\":\"" + ChatColor.GREEN - - + "---==Click to vote==---\",\"hoverEvent\":{\"action\":\"show_text\",\"value\":\"" + ChatColor.GREEN - - + _url.replace("http://", "").replace("https://", "") + "\"},\"clickEvent\":{\"action\":\"open_url\",\"value\":\"" + _url - - + "\"}}]}"); - - UtilPlayer.sendPacket(_player, new PacketPlayOutChat(comp, true)); + + new JsonMessage("Click to Open in Web Browser").click(ClickEvent.OPEN_URL, _url).sendToPlayer(getPlayer()); + new JsonMessage(C.cGreen + _url).click(ClickEvent.OPEN_URL, _url).sendToPlayer(getPlayer()); + UtilPlayer.message(getPlayer(), ""); - UtilPlayer.message(getPlayer(), "============================================="); + UtilPlayer.message(getPlayer(), C.cRed + "------------------------------------------------"); @@ -105,37 +98,67 @@ public class VoteButton implements GuiItem, Listener { } } - @EventHandler - public void onUpdate(UpdateEvent event) - { - if (!event.getType().equals(UpdateType.SEC)) - return; - setItem(); - } - @Override public ItemStack getObject() { return _item; } - public void refreshItem() { - getGui().refreshItem(this); - } - - public void setItem() + private void setItem() { - if (isAvailable()) { - _item = ItemStackFactory.Instance.CreateStack(Material.JUKEBOX, (byte) 0, 1, ChatColor.GREEN + "Click to vote!"); - } else { - _item = ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + "Next link in:", new String[] {ChatColor.WHITE + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) }); + ArrayList lore = new ArrayList(); + Material material; + String itemName; + byte data = 0; + + if (isAvailable()) + { + material = Material.CHEST; + itemName = C.cGreen + C.Bold + "Vote Bonus"; + + lore.add(" "); + lore.add(ChatColor.RESET + "Click to Vote!"); } - refreshItem(); + else + { + material = Material.REDSTONE_BLOCK; + itemName = C.cRed + C.Bold + "Vote Bonus"; + + lore.add(" "); + lore.add(ChatColor.RESET + "Next vote in " + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) + "!"); + } + + lore.add(" "); + + BonusClientData client = _bonusManager.Get(_player); + + BonusAmount bonusAmount = _bonusManager.getVoteBonusAmount(_player); + bonusAmount.addLore(lore); + + lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getVoteStreak()); + lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxVoteStreak()); + + if (client.getVoteTime() != null) + { + long lastBonus = _bonusManager.getLocalTime(client.getVoteTime().getTime()); + long timeLeft = _bonusManager.getStreakTimeRemaining(lastBonus, BonusManager.STREAK_RESET_TIME); + + if (timeLeft > 0) + { + lore.add(C.cYellow + "Streak Reset: " + C.cWhite + UtilTime.convertString(timeLeft, 1, TimeUnit.FIT)); + } + } + + lore.add(" "); + lore.add(C.cYellow + "Record Holder: " + C.cWhite + "Phinary"); + lore.add(C.cYellow + "Streak: " + C.cWhite + "420"); + + _item = new ShopItem(material, itemName, lore.toArray(new String[0]), 1, false, false); } public long timeLeft() { - return this.bonusTime - System.currentTimeMillis(); + return _bonusManager.nextVoteTime(getPlayer()) - System.currentTimeMillis(); } public boolean isAvailable() @@ -160,80 +183,3 @@ public class VoteButton implements GuiItem, Listener { return _gui; } } - - - - - - - - - -/*implements GuiItem { - - private ItemStack _item; - private String _url; - private Player _player; - - public VoteButton(Player player) - { - this._player = player; - - //TODO get url from somewhere - _url = "http://minecraftservers.org/server/121070"; - - //TODO check if claimed - boolean claimed = false; - - if (_url == null) - _item = ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + "Nothing to vote for!"); - else if (claimed) { - _item = ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + "You have already voted!"); - _url = null; - } else - _item = ItemStackFactory.Instance.CreateStack(Material.JUKEBOX, (byte) 0, 1, ChatColor.GREEN + "Click to vote!"); - } - - @Override - public void setup() - { - - } - - @Override - public void close() - { - - } - - @Override - public void click(ClickType clickType) - { - if (_url == null) { - getPlayer().playSound(getPlayer().getLocation(), Sound.ITEM_BREAK, 1, 10); - return; - } - getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); - // TODO This probably needs to be redone, I just looked stuff up and - // pasted it together - IChatBaseComponent comp = ChatSerializer.a("{\"text\":\"" + ChatColor.BLUE + "Vote> \",\"extra\":[{\"text\":\"" + ChatColor.GREEN - + "Click to vote!\",\"hoverEvent\":{\"action\":\"show_text\",\"value\":\"" + ChatColor.GREEN - + _url.replace("http://", "").replace("https://", "") + "\"},\"clickEvent\":{\"action\":\"open_url\",\"value\":\"" + _url - + "\"}}]}"); - - UtilPlayer.sendPacket(_player, new PacketPlayOutChat(comp, true)); - getPlayer().closeInventory(); - } - - @Override - public ItemStack getObject() - { - return _item; - } - - public Player getPlayer() - { - return _player; - } -} -*/ From 608e8bf693784ad04ccc9912a5edcd4709888de0 Mon Sep 17 00:00:00 2001 From: Morten Date: Fri, 7 Aug 2015 05:40:16 +0200 Subject: [PATCH 258/377] For Sarah <3 --- .../src/mineplex/core/account/CoreClient.java | 4 ++ .../hub/commands/DisguiseCommand.java | 1 - .../game/arcade/command/DisguiseCommand.java | 37 ++++++++++++++++++- .../game/arcade/managers/GameChatManager.java | 18 +++++++-- 4 files changed, 54 insertions(+), 6 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java index fb00a3c54..df6717c6a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClient.java @@ -76,6 +76,10 @@ public class CoreClient this._disguisedAs = originalName; } + /** + * Only use this method if the client is actually disguised! + * @return + */ public Rank getDisguisedRank() { return _disguisedRank; } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java index e342650e7..904fd21ef 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java @@ -313,5 +313,4 @@ public class DisguiseCommand extends CommandBase implements Listener dp.setSneaking(!dp.getSneaking()); } } - } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java index b26139662..26ac74dec 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java @@ -22,6 +22,7 @@ import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import nautilus.game.arcade.ArcadeManager; import net.minecraft.server.v1_7_R4.EntityHuman; +import net.minecraft.server.v1_7_R4.PacketPlayOutAnimation; import net.minecraft.util.com.mojang.authlib.GameProfile; import org.bukkit.Bukkit; @@ -33,6 +34,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; +import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerLoginEvent.Result; @@ -168,6 +170,7 @@ public class DisguiseCommand extends CommandBase implements Liste Plugin.getCosmeticManager().getGadgetManager().RemoveItem(caller); + Bukkit.broadcastMessage(ChatColor.DARK_GRAY + "Quit> " + ChatColor.GRAY + _disguisedPlayersNames.get(caller)); UtilPlayer.message(caller, C.cGreen + C.Bold + "Disguise Active: " + ChatColor.RESET + args[0]); } catch(Exception e) { @@ -330,10 +333,42 @@ public class DisguiseCommand extends CommandBase implements Liste { if(_disguisedPlayers.containsKey(player)) { - EntityHuman human = (((CraftHumanEntity)((CraftPlayer) player)).getHandle()); + EntityHuman human = (((CraftHumanEntity) ((CraftPlayer) player)).getHandle()); human.world.broadcastEntityEffect(human, (byte) 0); } } } + @EventHandler(priority = EventPriority.LOWEST) + public void onDPlayerChat(AsyncPlayerChatEvent event) + { + if(_disguisedPlayers.containsKey(event.getPlayer())) + { + event.setFormat(" *" + event.getMessage()); + } + } + + @EventHandler + public void on(PlayerInteractEvent event) + { + if(event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) + { + if(_disguisedPlayers.containsKey(event.getPlayer())) + { + + Player player = event.getPlayer(); + + PacketPlayOutAnimation packet = new PacketPlayOutAnimation(); + packet.a = player.getEntityId(); + + for(Player p : Bukkit.getOnlinePlayers()) + { + if(p != player) + { + Plugin.getPacketHandler().getPacketVerifier((Player) p).bypassProcess(packet); + } + } + } + } + } } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameChatManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameChatManager.java index aadc5715f..4aed91a8a 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameChatManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameChatManager.java @@ -2,6 +2,7 @@ package nautilus.game.arcade.managers; import java.util.Iterator; +import mineplex.core.account.CoreClient; import mineplex.core.common.Rank; import mineplex.core.common.util.C; import mineplex.core.common.util.F; @@ -55,8 +56,17 @@ public class GameChatManager implements Listener dead = C.cGray + "Dead "; Rank rank = Manager.GetClients().Get(sender).GetRank(); + String disguiseTag = ""; if(Manager.GetClients().Get(sender).isDisguised()) - rank = Manager.GetClients().Get(sender).getDisguisedRank(); + { + CoreClient cc = Manager.GetClients().Get(sender); + rank = cc.getDisguisedRank(); + + if(!cc.GetRank().Has(Rank.JNR_DEV)) + { + disguiseTag = ChatColor.BLACK + " "; + } + } boolean ownsUltra = false; @@ -112,7 +122,7 @@ public class GameChatManager implements Listener } //Base Format - event.setFormat(dead + levelStr + rankStr + Manager.GetColor(sender) + senderName + " " + ChatColor.WHITE + "%2$s"); + event.setFormat(disguiseTag + dead + levelStr + rankStr + Manager.GetColor(sender) + senderName + " " + ChatColor.WHITE + "%2$s"); //Public/Private (Not If Player Dead) if (Manager.GetGame() != null && Manager.GetGame().GetState() == GameState.Live) @@ -128,13 +138,13 @@ public class GameChatManager implements Listener if (event.getMessage().charAt(0) == '@') { event.setMessage(event.getMessage().substring(1, event.getMessage().length())); - event.setFormat(C.cWhite + C.Bold + "Team" + " " + dead + levelStr + rankStr + team.GetColor() + senderName + " " + C.cWhite + "%2$s"); + event.setFormat(disguiseTag + C.cWhite + C.Bold + "Team" + " " + dead + levelStr + rankStr + team.GetColor() + senderName + " " + C.cWhite + "%2$s"); } //All Chat else { globalMessage = true; - event.setFormat(dead + levelStr + rankStr + team.GetColor() + senderName + " " + C.cWhite + "%2$s"); + event.setFormat(disguiseTag + dead + levelStr + rankStr + team.GetColor() + senderName + " " + C.cWhite + "%2$s"); } } From f37e25e9d7dd8860e0d77dc0b710bf13a546b286 Mon Sep 17 00:00:00 2001 From: Morten Date: Fri, 7 Aug 2015 07:03:15 +0200 Subject: [PATCH 259/377] Finish push for today <3 --- .../core/disguise/DisguiseManager.java | 10 +++-- .../Mineplex.Hub/src/mineplex/hub/Hub.java | 2 +- .../src/mineplex/hub/HubManager.java | 10 ++++- .../hub/commands/DisguiseCommand.java | 38 +++++++++++++++++++ 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java b/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java index 521812057..92f499ab2 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java @@ -1143,10 +1143,14 @@ public class DisguiseManager extends MiniPlugin implements IPacketHandler EntityPlayer disguisedPlayer = (EntityPlayer) disguise.GetEntity(); - if (Bukkit.getPlayerExact(disguisedPlayer.getName()) == null || !disguisedPlayer.isAlive() || !disguisedPlayer.valid) - disguiseIterator.remove(); - else + try { + if (Bukkit.getPlayerExact(disguisedPlayer.getName()) == null || !disguisedPlayer.isAlive() || !disguisedPlayer.valid) + disguiseIterator.remove(); + } + catch(NullPointerException e) + { + for (Iterator playerIterator = _disguisePlayerMap.get(disguise).iterator(); playerIterator.hasNext();) { Player player = playerIterator.next(); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java index 0873db91b..0bddd8b20 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java @@ -122,7 +122,7 @@ public class Hub extends JavaPlugin implements IRelation PartyManager partyManager = new PartyManager(this, portal, clientManager, preferenceManager); - HubManager hubManager = new HubManager(this, blockRestore, clientManager, donationManager, new ConditionManager(this), disguiseManager, new TaskManager(this, clientManager, webServerAddress), portal, partyManager, preferenceManager, petManager, pollManager, statsManager, achievementManager, new HologramManager(this)); + HubManager hubManager = new HubManager(this, blockRestore, clientManager, donationManager, new ConditionManager(this), disguiseManager, new TaskManager(this, clientManager, webServerAddress), portal, partyManager, preferenceManager, petManager, pollManager, statsManager, achievementManager, new HologramManager(this), packetHandler); QueueManager queueManager = new QueueManager(this, clientManager, donationManager, new EloManager(this, clientManager), partyManager); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index c4696b7da..102f706e3 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -35,6 +35,7 @@ import mineplex.core.message.PrivateMessageEvent; import mineplex.core.mount.MountManager; import mineplex.core.mount.event.MountActivateEvent; import mineplex.core.notifier.NotificationManager; +import mineplex.core.packethandler.PacketHandler; import mineplex.core.party.Party; import mineplex.core.party.PartyManager; import mineplex.core.pet.PetManager; @@ -127,6 +128,7 @@ public class HubManager extends MiniClientPlugin private AchievementManager _achievementManager; private TreasureManager _treasureManager; private PetManager _petManager; + private PacketHandler _packetHandler; private Location _spawn; private int _scoreboardTick = 0; @@ -147,7 +149,7 @@ public class HubManager extends MiniClientPlugin //Admin private boolean _gadgetsEnabled = true; - public HubManager(JavaPlugin plugin, BlockRestore blockRestore, CoreClientManager clientManager, DonationManager donationManager, ConditionManager conditionManager, DisguiseManager disguiseManager, TaskManager taskManager, Portal portal, PartyManager partyManager, PreferencesManager preferences, PetManager petManager, PollManager pollManager, StatsManager statsManager, AchievementManager achievementManager, HologramManager hologramManager) + public HubManager(JavaPlugin plugin, BlockRestore blockRestore, CoreClientManager clientManager, DonationManager donationManager, ConditionManager conditionManager, DisguiseManager disguiseManager, TaskManager taskManager, Portal portal, PartyManager partyManager, PreferencesManager preferences, PetManager petManager, PollManager pollManager, StatsManager statsManager, AchievementManager achievementManager, HologramManager hologramManager, PacketHandler packetHandler) { super("Hub Manager", plugin); @@ -191,6 +193,7 @@ public class HubManager extends MiniClientPlugin _statsManager = statsManager; _achievementManager = achievementManager; _achievementManager.setGiveInterfaceItem(true); + _packetHandler = packetHandler; new NotificationManager(getPlugin(), clientManager); @@ -1082,4 +1085,9 @@ public class HubManager extends MiniClientPlugin UtilPlayer.message(player, F.main("Game Mode", event.getPlayer().getName() + " left the game. Creative Mode: " + F.tf(false))); } } + + public PacketHandler getPacketHandler() + { + return _packetHandler; + } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java index 904fd21ef..9812d610c 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java @@ -24,6 +24,7 @@ import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.hub.HubManager; import net.minecraft.server.v1_7_R4.EntityHuman; +import net.minecraft.server.v1_7_R4.PacketPlayOutAnimation; import net.minecraft.util.com.mojang.authlib.GameProfile; import org.bukkit.Bukkit; @@ -34,6 +35,9 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerToggleSneakEvent; import org.bukkit.event.player.PlayerLoginEvent.Result; @@ -313,4 +317,38 @@ public class DisguiseCommand extends CommandBase implements Listener dp.setSneaking(!dp.getSneaking()); } } + + @EventHandler(priority = EventPriority.LOWEST) + public void onDPlayerChat(AsyncPlayerChatEvent event) + { + if(_disguisedPlayers.containsKey(event.getPlayer())) + { + event.setFormat(" *" + event.getMessage()); + } + } + + @EventHandler + public void on(PlayerInteractEvent event) + { + if(event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) + { + if(_disguisedPlayers.containsKey(event.getPlayer())) + { + + Player player = event.getPlayer(); + + PacketPlayOutAnimation packet = new PacketPlayOutAnimation(); + packet.a = player.getEntityId(); + + for(Player p : Bukkit.getOnlinePlayers()) + { + if(p != player) + { + Plugin.getPacketHandler().getPacketVerifier((Player) p).bypassProcess(packet); + } + } + } + } + } + } From 181b778a9c30c9584d3137563798a780e6832c3e Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 7 Aug 2015 07:39:40 +0200 Subject: [PATCH 260/377] Fixing some bugs and disallow MPS while disguised. --- .../src/mineplex/core/disguise/DisguiseManager.java | 12 +++++------- .../core/personalServer/HostEventServerCommand.java | 7 +++++++ .../core/personalServer/HostServerCommand.java | 7 +++++++ .../core/personalServer/PersonalServerManager.java | 5 +++++ .../src/mineplex/hub/commands/DisguiseCommand.java | 9 +++++---- .../game/arcade/command/DisguiseCommand.java | 2 +- 6 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java b/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java index 92f499ab2..86a78df78 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/disguise/DisguiseManager.java @@ -1143,22 +1143,20 @@ public class DisguiseManager extends MiniPlugin implements IPacketHandler EntityPlayer disguisedPlayer = (EntityPlayer) disguise.GetEntity(); - try - { - if (Bukkit.getPlayerExact(disguisedPlayer.getName()) == null || !disguisedPlayer.isAlive() || !disguisedPlayer.valid) + + if (Bukkit.getPlayerExact(disguisedPlayer.getName()) == null || !disguisedPlayer.isAlive() || !disguisedPlayer.valid) disguiseIterator.remove(); - } - catch(NullPointerException e) - { + try{ for (Iterator playerIterator = _disguisePlayerMap.get(disguise).iterator(); playerIterator.hasNext();) { Player player = playerIterator.next(); - + if (!player.isOnline() || !player.isValid()) playerIterator.remove(); } } + catch (Exception exception) {} } } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostEventServerCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostEventServerCommand.java index 566c95a04..65d95c26a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostEventServerCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostEventServerCommand.java @@ -4,6 +4,8 @@ import org.bukkit.entity.Player; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; import mineplex.core.recharge.Recharge; public class HostEventServerCommand extends CommandBase @@ -19,6 +21,11 @@ public class HostEventServerCommand extends CommandBase if (!Recharge.Instance.use(caller, "Host Event", 30000, false, false)) return; + if(Plugin.getClients().Get(caller).isDisguised()) + { + UtilPlayer.message(caller, F.main("Disguise", "You cant host Servers while you are disguised!")); + return; + } Plugin.hostServer(caller, caller.getName(), true); } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostServerCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostServerCommand.java index b09c4cc54..dbf091299 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostServerCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostServerCommand.java @@ -4,6 +4,8 @@ import org.bukkit.entity.Player; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; import mineplex.core.recharge.Recharge; public class HostServerCommand extends CommandBase @@ -19,6 +21,11 @@ public class HostServerCommand extends CommandBase if (!Recharge.Instance.use(caller, "Host Server", 30000, false, false)) return; + if(Plugin.getClients().Get(caller).isDisguised()) + { + UtilPlayer.message(caller, F.main("Disguise", "You cant host Servers while you are disguised!")); + return; + } Plugin.hostServer(caller, caller.getName(), false); } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/personalServer/PersonalServerManager.java b/Plugins/Mineplex.Core/src/mineplex/core/personalServer/PersonalServerManager.java index 466a26d50..2030044e5 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/personalServer/PersonalServerManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/personalServer/PersonalServerManager.java @@ -177,4 +177,9 @@ public class PersonalServerManager extends MiniPlugin } }); } + + public CoreClientManager getClients() + { + return _clientManager; + } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java index 9812d610c..0402366e7 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java @@ -56,9 +56,10 @@ public class DisguiseCommand extends CommandBase implements Listener public DisguiseCommand(HubManager plugin) { super(plugin, Rank.JNR_DEV, new Rank[] - { Rank.YOUTUBE, Rank.TWITCH }, "disguise"); - plugin.getPluginManager().registerEvents(this, Plugin.getPlugin()); - new NCPDataManFix(); + { + Rank.YOUTUBE, Rank.TWITCH }, "disguise"); + plugin.getPluginManager().registerEvents(this, Plugin.getPlugin()); + new NCPDataManFix(); } @Override @@ -254,9 +255,9 @@ public class DisguiseCommand extends CommandBase implements Listener { _disguisedPlayers.remove(player); _disguisedPlayerDisguises.remove(player); - _disguisedPlayersNames.remove(player); Plugin.GetDisguise().undisguise(player); String playerName = _disguisedPlayersNames.get(player); + _disguisedPlayersNames.remove(player); CoreClient client = Plugin.GetClients().Get(player); client.setDisguisedRank(null); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java index 26ac74dec..7c32ed36a 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/command/DisguiseCommand.java @@ -260,9 +260,9 @@ public class DisguiseCommand extends CommandBase implements Liste { _disguisedPlayers.remove(player); _disguisedPlayerDisguises.remove(player); - _disguisedPlayersNames.remove(player); Plugin.GetDisguise().undisguise(player); String playerName = _disguisedPlayersNames.get(player); + _disguisedPlayersNames.remove(player); CoreClient client = Plugin.GetClients().Get(player); client.setDisguisedRank(null); From e8c60e6e8406ed4a0dedea9122302176d13b7ce8 Mon Sep 17 00:00:00 2001 From: Jonathan Williams Date: Fri, 7 Aug 2015 02:22:13 -0500 Subject: [PATCH 261/377] Added storage of pets in mysql. Going to have live while backend process is copying data over. Updated ServerTypePage to resolve clicking issues with solo/team pages. --- .../core/cosmetic/ui/page/PetTagPage.java | 5 +++ .../src/mineplex/core/pet/PetManager.java | 2 +- .../core/pet/repository/PetRepository.java | 32 +++++++++++++++++-- .../pet/repository/token/PetChangeToken.java | 2 ++ .../hub/server/ui/ServerTypePage.java | 7 ++-- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/PetTagPage.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/PetTagPage.java index a9fd03414..9bdcadd54 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/PetTagPage.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/PetTagPage.java @@ -82,8 +82,13 @@ public class PetTagPage extends ShopPageBase public void run() { PetChangeToken token = new PetChangeToken(); + + if (getClientManager().Get(getPlayer()) != null) + token.AccountId = getClientManager().Get(getPlayer()).getAccountId(); + token.Name = getPlayer().getName(); token.PetType = _pet.GetPetType().toString(); + token.PetId = _pet.GetPetType().ordinal(); token.PetName = _tagName; PetToken petToken = new PetToken(); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/pet/PetManager.java b/Plugins/Mineplex.Core/src/mineplex/core/pet/PetManager.java index 747fed442..b50fc27b4 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/pet/PetManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/pet/PetManager.java @@ -77,7 +77,7 @@ public class PetManager extends MiniClientPlugin _creatureModule = creatureModule; _disguiseManager = disguiseManager; - _repository = new PetRepository(webAddress); + _repository = new PetRepository(plugin, webAddress); _petFactory = new PetFactory(_repository); _blockRestore = restore; _donationManager = donationManager; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/pet/repository/PetRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/pet/repository/PetRepository.java index a206881ff..2ed20694b 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/pet/repository/PetRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/pet/repository/PetRepository.java @@ -3,19 +3,26 @@ package mineplex.core.pet.repository; import java.util.List; import org.bukkit.craftbukkit.libs.com.google.gson.reflect.TypeToken; +import org.bukkit.plugin.java.JavaPlugin; +import mineplex.core.database.DBPool; +import mineplex.core.database.RepositoryBase; +import mineplex.core.database.column.ColumnInt; +import mineplex.core.database.column.ColumnVarChar; import mineplex.core.pet.repository.token.PetChangeToken; import mineplex.core.pet.repository.token.PetExtraToken; import mineplex.core.pet.repository.token.PetSalesToken; import mineplex.core.server.remotecall.AsyncJsonWebCall; import mineplex.core.server.remotecall.JsonWebCall; -public class PetRepository +public class PetRepository extends RepositoryBase { private String _webAddress; - public PetRepository(String webAddress) + public PetRepository(JavaPlugin plugin, String webAddress) { + super(plugin, DBPool.ACCOUNT); + _webAddress = webAddress; } @@ -37,5 +44,26 @@ public class PetRepository public void UpdatePet(PetChangeToken token) { new AsyncJsonWebCall(_webAddress + "Pets/UpdatePet").Execute(token); + + int rowsChanged = executeUpdate("UPDATE accountPets SET petName = ? WHERE petId = ? AND accountId = ?;", new ColumnVarChar("petName", 32, token.PetName) + , new ColumnInt("petId", token.PetId) + , new ColumnInt("accountId", token.AccountId)); + + if (rowsChanged < 1) + { + executeInsert("INSERT INTO accountPets(petName, petId, accountId) VALUES (?, ?, ?);", null, new ColumnVarChar("petName", 32, token.PetName) + , new ColumnInt("petId", token.PetId) + , new ColumnInt("accountId", token.AccountId)); + } + } + + @Override + protected void initialize() + { + } + + @Override + protected void update() + { } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/pet/repository/token/PetChangeToken.java b/Plugins/Mineplex.Core/src/mineplex/core/pet/repository/token/PetChangeToken.java index e42a5e61e..4bd7a5236 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/pet/repository/token/PetChangeToken.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/pet/repository/token/PetChangeToken.java @@ -2,6 +2,8 @@ package mineplex.core.pet.repository.token; public class PetChangeToken { + public int AccountId; + public int PetId; public String Name; public String PetName; public String PetType; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerTypePage.java b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerTypePage.java index c8975ab8e..3c909f545 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerTypePage.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerTypePage.java @@ -80,14 +80,11 @@ public class ServerTypePage extends ShopPageBase { if (team) { - //getPlugin().selectServer(player, _serverGroup.getTeamServerKey()); // TODO: Grab the team-key instead of regular game key - //getPlugin().getServerNPCShopByName(_serverGroup.getServerNpcName() + " 2").attemptShopOpen(player); - getShop().openPageForPlayer(player, new ServerNpcPage(getPlugin(), getShop(), getClientManager(), getDonationManager(), _serverGroup.getServerNpcName(), player, _serverGroup.getTeamServerKey())); + getShop().openPageForPlayer(player, new ServerNpcPage(getPlugin(), getShop(), getClientManager(), getDonationManager(), _serverGroup.getServerNpcName() + " Teams", player, _serverGroup.getTeamServerKey())); } else { - //getPlugin().selectServer(player, _serverGroup.getPrefix()); - getShop().openPageForPlayer(player, new ServerNpcPage(getPlugin(), getShop(), getClientManager(), getDonationManager(), _serverGroup.getServerNpcName(), player, _serverGroup.getPrefix())); + getShop().openPageForPlayer(player, new ServerNpcPage(getPlugin(), getShop(), getClientManager(), getDonationManager(), _serverGroup.getServerNpcName() + " Solo", player, _serverGroup.getPrefix())); } } } From 320a3efe5ba4953028bab9861b6c7df3b7e194b3 Mon Sep 17 00:00:00 2001 From: Jonathan Williams Date: Fri, 7 Aug 2015 02:22:58 -0500 Subject: [PATCH 262/377] Remove some debug code. --- .../src/mineplex/hub/server/ServerManager.java | 1 - .../src/mineplex/hub/server/ui/ServerNpcPage.java | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java index 9accebcc0..9cfa24d21 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java @@ -346,7 +346,6 @@ public class ServerManager extends MiniPlugin public Collection getServerList(String serverNpcName) { - System.out.println("contains?" + _serverKeyInfoMap.containsKey(serverNpcName)); return _serverKeyInfoMap.get(serverNpcName); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerNpcPage.java b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerNpcPage.java index 6e498d3eb..bdd807710 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerNpcPage.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerNpcPage.java @@ -52,8 +52,6 @@ public class ServerNpcPage extends ShopPageBase im @Override protected void buildPage() { - System.out.println(_serverGroupName); - System.out.println("getPlugin() null?" + (getPlugin() == null)); List serverList = new ArrayList(getPlugin().getServerList(_serverGroupName)); int slotsNeeded = 1; @@ -277,7 +275,9 @@ public class ServerNpcPage extends ShopPageBase im if (serverInfo.MOTD.contains("Open in")) setItem(slot, shopItem); else + { addButton(slot, shopItem, new JoinServerButton(this, serverInfo)); + } if (full) fullCount++; @@ -410,7 +410,8 @@ public class ServerNpcPage extends ShopPageBase im } public void SelectServer(Player player, ServerInfo serverInfo) - { + { + System.out.println("Selecting server :" + serverInfo.Name); int slots = getPlugin().getRequiredSlots(player, serverInfo.ServerType); if (serverInfo.getAvailableSlots() < slots && !(getDonationManager().Get(getPlayer().getName()).OwnsUnknownPackage(serverInfo.ServerType + " ULTRA") || getClient().GetRank().Has(Rank.ULTRA))) From 5f8e80a55f30980fd8bd08159ce8b1b916bf032b Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Fri, 7 Aug 2015 11:10:50 +0200 Subject: [PATCH 263/377] art --- Art/Carl.png | Bin 0 -> 352908 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Art/Carl.png diff --git a/Art/Carl.png b/Art/Carl.png new file mode 100644 index 0000000000000000000000000000000000000000..5d4fe6d3651d5897860b212e72fde071c521c501 GIT binary patch literal 352908 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%0DYK9e4 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%0D>nmim~Z3j0zA74T`9d zsBvrh^4eKQ;IB1*B(HLK%&eA*53iC+G@U5+H3T%_fJj4=w4Q;WvG1Ia&vW9=bG5V> zz0HhYKNlC}0}CXB{UuVCm!k8^W{LwUcsF)R%)jy;9Ee6AJ@IK#v9v~A9IHt`#p1BYK zo_f>s?>9iR^KLq8nxgmNYu{a|(R6cmYu^jY`*~}+N*KAi&m3{hM}r#`&*ZfcdI@YX zyB2vOaYSkpsUPFd*p~nP_t<>#J7!8~$@IPiGoy^DD%_1NSMJ=oJ$d$6-8eJ<)#2KH z?Z!Z=I4!d8m(|%W$@30v7KgDLYD@|*M$y!fwLxmOi(%}tAWR&w4oG2B^HV7Urv%6- z=TGLmd4vCW34L#sVS8?a!&o0&^#WHyIu*|^;Naj}>8qss2yn>2TBPTpH%w^)5oC@X zA%qRNt_v`O3SuvlisS`%B4A=b15MTezTT|qxed5srJmr!><%uK6t(^cnN$ZeNn$u9 zFfyXjvJAXOi<#`wTNn_0qjFBVQnpw4FMqVW@l3u_Y>}iOR>@=@uXyGuBXxoOf%syo zaN;?QtABUScp$CYqLVA=&~ua!9oTl)lwH_dG6x0B3ZOrU1FfPmiqu`6%LXt*zxfd) zTf|imS0YKlc~T;&n@us+; zCeP;TgMIEOMAki^e(OJYOE2j(KyKOLOA-F>uhW{+h0WT<9qhSs*u{^#TZ_$^Cy&84 zqRwj1qIJHF(nASoANFxm@rAew`9^{j++z$O9jWl|S*KE}gkUXk_fA_==LeM?-K;g$ zleSMCrrws@8atcJtDpZtNv^$0z{f21#@12Cw2p%8@$67=p(Ra#WVm4sUk(B|< z@vPDz$g5Cx6W`=I3NsigYkgZpyP94Vg-B<@CurEVPy84L0UDt5<29egjQ7Z2qhgfr zi2nCBxuL#DZIRU+G5GLFfxY<4OgZpe!=OV z?bXdLau6jM>DmU1v0(g@&5r;}ApwE;D_i6w7$ou!4ODuijV3Ta!<`GJmZt<$z)pK> zmuJ0f`>M#m_+`2nFA3E5m&k(=k5Y3kJ_O1=B7;j1aCLb<*T@<9soO`Pb86H7l$w^9TK8*Z*8CeHR6St*OZTp@ zqFSoc#L}y=PH7PGCgmF+5H*hJUkS(%CN>nAdd#JCE{$g410@X`f zxv&^sraHU#-n~nXj%0y(al~LNeRC7a^83s)LRlNyabgqiQN1`~wgzIrE#fi&?B}Ww>q|hmWp5?qw$Ow77d~*$^PiZ9 zL98ujp71OHoI=7FZ6FV)qt6rKgUZ)J&keYGZ~S;YTd8$iKJ|;{hgJdoHk}2u%c;3M*`L= zrYRlZ6%Z@%XU2HJV$!su%SVjf`x1exe|?(eU-*m=XCE}KJNaJOM6f&+#1hE!fk(+u za@4{nI4TME3PY|V0RaU+<1>Ep3)(x?{pZOv6VI>4S2Nu;iu?a<_1RsA$Up$8@aL3? zsa6@V4r9&AV(iEMs#;bn*gU^i4xppO0E+pw8~|Wg&eQ@n^T|yF*_yftJ!SPbDl;|) zIgiWr&E47h?Hl{a?+$m4!}sR^Uh| z3Y+xiwaRgZ#*(8z_O@)orUqxPYsX|D<{fA>u@^|S5n<4%0XqP3yL$z`{i03`W)@Wa z;Jz%*q6+qKVD{z1|K6O7y?Aa+399SIY-_EV zL;tQ?{O{wt0A(}N{9i8M`KD?{{_*vM`0CnuygBF}QfW+a%W1t|@X(6FEwRc?7kr5hi84x93Jx=HNvATm{YP%^Kn6JK(x%;c@TzK0}HU1O3e(~jYae1q& zTA|vYf5Mz;-(Ggte zVlG6?f1fApI$#XaNX}eiGxXw?*S_Qbhl9B~FW!v*1u#yl)=3RjBT51?3h*BsQzZRSxKQlk zv;nIlE760dU$olPi;RJks38U@eJU;NTm~4n`hGaO+duV>ulDl7a<{9MRoi_xjU3lA z3Xy{Ukx%oIu zAUd)(#$6)#lHl_)UlyICwqnFgm}eFd@SjMYt9hrv8n&iO*?vKE@8|)x0Nsy==A58W zY)J^ZVYD(LEdns%kF+GU+~<0meXBN;G4qm^E#y0IEZl6M4X2bLTF;-*E>{mf1AWu+ zShr}%9`W*R!jCjHfd<-{pCwGc`&gTUtOPR%thH8UO{0k0S*rZ(8DRhINB>qxS$)iS z>g(72C;p8h62u;QBlSwc!}l!Kc7_m_&O8}Kqx%yVyi5Jbt?P|q&Un$xpiFto-u=oN z-db_Br?o1G`c(v|>2lj1-#QYA1SZ;~5&mvJGWIiucg?KGV_V}lbnzQk17HAZw5IsY zfVrFpjW#&0AKlWS&$1YQf%hc7BKXISR#D{9@qI)5jzi$pfC3^kAS2+edM+j@z??QY zOV(UjkRizV6SSk>3`Zo>0)qagLCp7qJjsdO;%~WTjbG&j+}}=?|0pD2^WEQ2B!uKS zst}aa`0*6`^#+VtwHV3ST^yDbB<*j7FRcN4(4oU)3AN(TO+V@C(aTqVAHEEl!fizN zBm%9FpWs8vW;Cb#V7DtHu~@A8aUf(AZ@GyC-q;y~jm#H-!6Sgl&K=jjd$}WyYzN9% zNqm%p0KDv(p47_gTu?^CoBCg80ogtXkSzAD&r@{P__c1vXi5m<0Nq=Jxd)i$PH{C-#<2P5W%k zD+O>clg9aWDa~x_2i-BRFY6JsIgfu)Id4T)Pmdzh=c3AulqC|@$D^X=WbWC_Bn_wk zdHH%Y%lgRT(&qzji!|SK7x8BwRPx(AmuJ%%5E?C7D3DOkgIohR$7Z4EsJZ5-8Lph9 z7m(B{F~ECbD~3qd5m$-3$KHdGtwd9T1FZ>0746#|^=HG8wSIfAjZgh<)*l9Ej9pxg zhU31=-nwcpWO?e_Y+gHz*!{w)JXH*S0m=zFl-f|c7$HQ-ju!ljaP}uHOPX`BAq9%t zJoTI)-Oc3e_i3+n78+-_yfZLCyR_FSYFhL3FEHcOjpR+_=!x%tcA3+dqaf5a&Fd6C z8!!<&Gd=MDC8)zFWKdM%QW1FP%)$aYU5kn44N@XLbQ!w5KCTv!ag=EZtQ--I6=Z+v zo8eE)H+EEt<~*RpR{8>pFJ2cE@cY4w4E}9Me@5yA@M7Ug@d*06431P7YK2?EK5-Ro zUUj*@mm>EK>Hh3gsgJ_RIH?yvi(;FG!9Ntp3jr(Sf-cZr^1idOr&u#JfjvN`6iKg` zft2hR$pyyM{k+v#qMO9*ni%V6+~RVn$k5+#>Mk3c2(hPth^&_o-OkQ(J^@x2F)?R1 z!WG?{AN{%89fL|hv$NPYw)bk0>g!ce^L2NMF)aW?Qitg#q32HwTr8zsS*w6MViyrm zG4m;lzu${7^ZV!u$_J8^4L|#yQMIXTop$`yDcj)3MCt){k*i*%wb&DM_ZfYZ>q~MQ zxt&D{++{q%Wo=`sKamp@rjBpu2J>GNfa2 zORbrmcx<1ziyuw9NXXyf@%^fHpkW*jj#eAPw!)@}0AmVDV5I6FU zeJN(+9H8(Fw^p`LZvOSaU2eRyvn`7Q9xw%s^?G{A9oy^E# zcj*8>U7O$jtA{W4pZQVk9ul*brjqG4cV)It3!x%x-CopO^|h>qh$kPQ_2DY9IVqc6O$uLc*3IPZK*w9BT)4-O0`acg|%EUyrYB%?$ zAF8kY@PUvKCa@vxOmByE`43S0Z3`JJoH3K3$A>WWR0Eoc@OA< zrH~LxX`_n|6P`PGFJym>z)kagK;_dW;EJ)lg$*L#1>NAwD)+glPbrx z*r(^RC|*cjZ!9>MP9Y|K>TqqLsEtB!dWZri;FcX2T@=!l|@4(p!&@pBN^^`x)iBWYp)XUpl_s9&) zh)3h#!q-G(1EJpeJC*=#0Z3&7bwnuSIp*`Q_m-!XejOqMZ%0*9{}ONrRH{U-xb#V+ z-f_v5);s-92iu7sPzbH@d<_Tv*no~jOn-lao2J(ztNj*quGP>DdU&_!giM1%XCCk0 zcR^KZskI@yg(#w*-q-R=Ay=rA=^Gih>?=HU*Rj0+`a^PNvE7(hUao>-2#o!tV3tZn zu=z=HCl{e=etP$bl}uJK707~X~ORjjdD~R@H$03vc@oCo9$*8p+t?7 z+AdvRqmX_C#A0UpzPb_A(ZGh4P6SHT4mLz08|W?vK1j6qs`JT}_&xAB5KqGLA0v!= z+K01Maz<+ioYv}z2K_GqhMlAK;@PmsL?qwWe>)pB0+q2AKzFTr-dLC+o z{rxZEnpCkXK z*eqvn>Nh3g$?bRswn+U`fWWPl7BR}W5wB3e%xMKjez zR3|>+{o%w$FEK9RpD!hg4Eq0#U*lG}*$lsBK80LiLz4sBezGm%)3%+9(!E$VL8#~= zWDQ2??`l~ECA^QRVrYHd@;s9XQ|S?V##m?)e`oZKY_AZz=P7?7PO5dcGv;z9MK`vN zD6(n2unp>)g+$-Q41y|*0g>D(pU#@V$H1J!0h6yO2B;h$-`1dWy0BkddeAEneL$x7N3V8=JqJV)H=ILnqz?6kejQp({}U_A&2uj^`6C!lly&t4ciI;1nmBXEieDa2^OIatLbS5#!RtNTnc2=~Gn%)03sg>3zDZ5~?rtGdqWQHw``0rB%9NKGmN^~`EV#PGb>R6A{+smH+Rpjt}lhJDS?>_;@jkMRL7l<~^K( zXCm}k4`{x|VAB#~EGVEK!zs`VgDhrDEvqacCrn`YeOs})XlzWSV_Qw(zzqZ%_=~#m zjH@ui02X1~%)KS)6Po&9w@J3L9!1t;x!4#t@!%(H!E5@wusb8zqjV@kq$y_pEV!me zM%l2ko(SRts%E1ysi~^_rCXRmqg(#(xugr4Bkho;TiP;Elc*Z--wRI#@j+ro2+g>I zp3CC7%0-D6Oc>2j{N0h$%zLYgIUTm5ls~=m9?)twR4TID8#{d@tDj*?F4?Jh53(65 zrd4~xyDVr`t-AoQVpED9r#=sg%=p-0t^3=p*BdG( zMxyn*6(}=EFiiVP1&B(3D`Met5k>^&`Z^GPwi#8>1aSr_A?~^mA8( zqDzeWD31L4+Q|7I>M8#WSKYuLd%x!`?^qskR$!^IdKRSnDJrbUij<<~9_3x6tX0GBuN@uxL)uv-!zAtTN&v(jULNByxwNY-eS-$oqcl_{x zJBQP8@u?xZGD|=@Im$B+S(jutt&0RxOsz^MTkru~uFWCo^7XZJJ@#C_EEV<#fIhj2 z1T|LJXggDZ>n4J(ot;0q&JSa0QKIxdPabHsr>On=+sIY5@wqsCnHFDop|TO<`s?v5 zYDV4Pk7HlW88+FPGK~Mt2AMSrT<4cu-52v>9;QBr@f#wo9MJ3wEK(wuwoA$1%{^Vn zo0ct-*6udhE_VKfVp}_ZNI2wP&q)_SPK}=4N5iH*F@otE#6f@owv!RfRjsc3ZruY| zPRgO(SR-8`UP$?zh>Lo_S2MU(pLijB^2efPmtO{kLMD$~e_j7IsL>be*N$JiL9q|| zU;I~P7SVq!;YD^WDc}7u)W!blJoly#l+#0te)~p2b6*|3!APl5y@=vyWgxL znjGn0Bj@p3{^VLSe3o+AutMN4>`&UD7&b<8jb-;IAa;hrn=y&ChN*F@b{?eV7AZa2 z8X$QVFCu~#qsq&H6S|2pzbzNK(4KU7O{j=* zm{>Vv0VLB*ZgWxev(>8uIgf4`loCVl;Fbd)y8dYw(as0%W~CC^sL#HjU&i5RE^q+| zLRt!8OiObyGZt=)G6!Vwrtu)%fY1U}aAgyw-e112ae9hXUSB%4SPgzTaEA`YRM>}eb)=lhqWM2JU+uY0?aFM1` z7klMBD7ydH@hXeakxz2u>Bxgv;JpBrGZ9sQIv=6Zi@+tyC#b;wEZ`|N*KpIF#n?{m zk&ewNv5DOM*4tW4QG1Eu7+Y4P=ER3&vHOI4*t2IC`^Q@Eq@VhN)VYhf{`%s%g=#Eh zx(K>dL#-j;JCM~OC7l7syZzwhg0>VF#O!@(BNXIz>l+xlsyoF<8&_|vA1SCgO__?s z-q)z&gz1fe?VrH;D<-|T#ftsD%>5@~BEou+3bs?1zhqk^tHyPZ7YEK=ms==55@sI9 zYi_qN5DM1%J$&(2)axoZVqbV6>^)zw+*G+KBduMbc~b!G-a>my*FXAybGyqc0sp3F zh4xLp?=2^5lbn94BYZ39{s5ETddv&dApy^BO26KJMZsaOmsv>U-wvo|e+~O*&$~E9NO%U=QD&;Vrdh z1i$h&25gAZr=ZFvM#fi*!o%>2ZLc;BvPZ8)_XL^~X^+4trG&kqJ^Nn|rj zmXE1tL%+9w*I}VekG5b%%Q8Y+QsvAvZIm!f_xqU+*4ru2c*M}Fub;`gDA0sYt8=%h zC>Ka5)5!?dHRuTeeHml%m+%=`^KcPL@C}hBW<;g7x(JweyWE*!)2d>ex7AsWprEIqmH+QjTvd{n*%$ zuX1-D|DolMKOkF^a_I}==m=p2T)G>#e>LjvBK|3*%0kQ(JIp6TKQWyKn`!Ppz&*Ix zQXOYbZ_QAz$RN7!1}A@Z75Uae_X}(kPNJL&pfmI^ia;nUhlKnwS;35Swcv@U-!R;*3*c{dDv^c`*|$)-~7Ir%btC?6;z}Gop?fVy}Pn~N3%2S3Z5!u zsB32{4Pr%EX6KD!q@|RIk6F+Q!nOldM1a|?b#jNiVde~wGNn>Y>+e}ZK%MxD#dlsqhl;m z+>~rF)NoU-e>)lK2H%Xf3@YBZG8xwRs2V@`Ko3l2o>VMkzgN>Gj&vFH3AYIzxVo=- z=~KRqimAcf51^EH0^hPK@R-UgG=t%(rDi z_|bsi(+xF12%b(Z#-A-Ia2>;kSDt2la=tz`ChY!~E z9Uq0ZUa@_`H6k+VMxYMEMqrNC7cGKtGU1eWCWcuZPe7*50xizJGsr9}mL|P{v#wyxjH{W*IQ3DTdG6f*Enjv z7T+mlN;3SSkz)d863r5`CT2~j_Q5?4NSMYrsxAOWtZc# z`iSJNGddN0zzD-fi4B^UC_ZB%0;k}kN_BR4r^yauGwV&L$>jt>S+POhnPS4m^6QD#t4W zXkZRA+3oiA9>%6&6rb>c=vf{~_X_Q^U`oB(Gu%0lOT^*xW`)ULp7AHbG%kz7EK zI>WgecJn7BO@NB+d`~P3;52~bgpKZu+Tx^LgA9sw zyoG;%SkE+q7Jg$SMvm|qjhcK3snBLM_KF1KiP>cs0x*g34l1-Cz`k7%Y>XBmh2iLQ z-jyE9k_3~!0wScWc}&$l^AfvnC)6<)mrw!b^VdGJr2+H}Q5S zk%@t6GdB@i0I2N8r4A&UCf&)LnAZesN7`dpkPC85G0N0_2AsW~st33M=15EO$uh}N zuAgm1iS4_kp}vF-Ls9&m@vaEjdoEuO7Ek1L@cEsuKuJq1v1Be=YnG}E-}!=98YXsw z&6fpPWkShQw;eEc1|l&p$TcPtB%dohH}6y?KdwgVRKaxX+Z`&tgyP0cQ$15s5fVkWT_t-M*Og+)U}v2spOf_V+Y`?#)5@?JX^cUP5rhSxXslj)G6oQe0?<7+9n0o)url0 z?}db$ieSa(kJ((gooW8O{rA~D71aKhYMt0pV-T_SgL4>@(wqh|DFmLkDR~HU`9B9T z;s@nH;Wxh+0KS_T*0OOb;AyOk#%s9D>XiO9#IH8>p`~2TtZ-UPB93g@DbJ#4l1Sx$ z;ZE5owIeyeX`h!w*nMTJZ|UfE5ZC)w;g#^6VKIQPQ{6;iC+#Lvd8_x`!2%K*UalfRUF9ml1=9-9?(oQR4Y7G(BGET9czJ0YtgVe|ciG zA(YpO*3#O(Us@D)=Ev!!Wl^pp(psnC%k=(C21y;;dGVD>F}pxj*d_G)bZvH!xCdn| zux#-BnWdkrXIrIAYP2LJV|KI1G_cqd?)g>G>tys-NI>q3y`Lu+;A>|9Y=BH=OZ^WJ z_!GnxsmM#i(Q&uV73>v;mV|(17I>jX%L`ca>&%W);Zx#h8V;W>%;kd+Y@f^J(xFUx z!&y!|x68G(vltp>mRT=yCFK!lvJYo1FQ0YwZaBOPp{LZZw zbtd|N+$NXs>s*g`nmQK!`#L{OA9)ClbWZ0F$uTYW@4alf_;qWuvm>!MW2)>${zgH= z+RqBz+!rU<_j<0!9HS{&X(7GkASRCCOWt7bORE>T@Ha9ky}tcs36gN1FtkU#uS}%7D;W$t&*8PG^wNHNh($SW-RFy-Mw=xyuMZNi+ zmK4LA5%7qjlc~zONV(ou?~v*Z+v)G|mbp~_jjE%*Oq)ra`6#Age5g*;^P4||;l|GXD9Eowi?ga+Lq zUo$@E*MyVbiUd$E?3uu4>$+`OXXfp(_6zMChSFLM@6&@zFB> zdl~YKWmy%uX5U>DX-PK29aOG2oGDOB2=sHvcZs-c@DJ-G? zfb=%5eFri3)R+l(eP*aW3@Pk$#YsU^>;f1F3)JOucj=g-D(jzer@IZ$NG8o!DN%V8 zneFD>HP<3{Q>vfeq;SOx+d<)v&k_TY84=puKdgD z^@^RgO&%l4^}f2=AeFsI0WJ%G_GRky!o@l)(}QRla9{t?-2HcWje%fPH21Js^}yik zuK%jqd)nYXKhB-B%B=aK-Uk@lKA3%-=yUc`VS^?vH!rXEUHSfjx`8XUL?AoLn+91p z;J#!UGc4O$j!|~H3wH!;WM>{SBMCt)h0a1f2XYU8ZF2t&x>~uX85zdg&J+NukgARG zjrwZ$CZDD%^k!N9MgF?ah2aa)5Cf|t$&|!!q`dd;o!E<&!s9(Nou#^jiy@r@f0e7v zfyKf5u`jeci3^`VB47Wh8-2d!#Elg%IfnlC0KKF^JuNI{^(Ym&>}9`O8kH#2K2qK@ zKDRAWW%Ig;Qv1ILi4ldddVePU1E2c6sTtnic#(>CxBLXHU(w`)eopPzsC&Ot>j!B( zYlAl_WGEO9u1Ky{uS?kmhlRmhtAQnZqqxJ5jj6Gsk|{pzO5vZc0;h|l``;n=cjPf* zm1BW(3aG~@MhnAQk<(Siy8<0KUHnY&{>3{UH#crt10HE$)e=fkt`6KfPWVxG3DCdT zlU1!yt#IMEht-ZfZoH^hW&2^jcN~%*)49Wx07^jQ9^z~r*3~J8;X#`Mb0gQqhERYLMFMeJ)@**By5Khirv;x7x z045Bc(Ln_FW}LykSNuys#A@)?7SDW^%I22POy5%TN^65A8dQekd@>nDiC^e{GUk6_ ziiI)oWO9{z!HFLzw*{5hJ>Smc5C1eWTzLB_{8#!ACC zR&nF{gt#aC$NkEQhG)MdXU;=(W#pI;(?|}f$L7-Y#Ip zoV4XJW}Z(6E;k%bdp@YfrBHmr0wa|bP<2yi3@)rh?(Gw+r<^XF4$wzzK#=YTfYq{2 z-?J{Bgfgj%d)&n3XXr@exg0(yN(4w5p+iX_1vaiW!8h!54`rUtaozxcS^kV)pB-o^ zM7nz4rmxB|Q~KBx)48f`U)%pj<{drsR9Sa-UGl-q+tg1KGi%hA@*DENLuF2bQqRG+ zO3k}5HF&eP9)4A9>)QJ!^)A5(9v8+iosTe!VC zgor#}3420lrz((&85`I=`#X1OG3K0&+D9MXa8&mg+`if9F_P2K8r(bZMNnk!T*2>L za<(&w^XlyLRjkJ3d8KfMSxK_@iqxOa5}#pjGMM`^-BV|lRVh#oWr96Ks{U6gcgdjF zlT@CA-rk3s-Utm!XMd8x+IyX*i>@)o!c&Db?7w=hk;sIx7rVdmlfP_UH*+2bL_g@` z<-bwzH=q!gg7?dNFDru3PO9m_(L+G>(E5wU584@6T&AvXVu5ta4_;KNI+N`aYfhVc z%adIHy(3w5AFoL9jfVsutCzapRrSL9f3DK2f}&R5Rpb1%Q~n^B%eFA=nQHMSiod5# z@3KCLkzL4(o!p=WLhWSswbL+5PVl@-*|%BK)!<{St|z)Q33ZmOt8BG_DuPkrx~D)3I9dDMk!at5S+{%o9%TjMXNxt_}6JK98ExV zHmrP-{I=@TT5Z*EzO2sV2gyeLZb!tn@C3ZUjeiWDU)+c zVqLRD5$1*%@8U-l#IQO!_JL$Xn{A57kOn}i`OSSzZIbd) zLmHZaQVDEHwo1^lJNk?mvcYwd^w`w)XWg9wSaKFsO^XH={%lR}2pXWE-sXT^W@Sg1c)>}%ZG;gyq zvfAIhn_@pX*8WK2hCznwkM~iLk$<`3n&Tk6$KE>eCkM7UukX;lZp4SXNiW)z$jAI3 zK~`gZv3b}2|KFW65>cRVcrFptYdgGl#uK@!t`5}}xu_`cVl(D#2=+-0Lg*(VAHXMf zO3+WQwF_}p@{3H^y#7o+3ER{+O|~Y6?RW5-mCKgZ$m%xcHDI6G?x@~~RAH@`0s`{n zOt#*(WB4wwUw5;ycp6pXs399&2)zxyCIL!3OGY@kZ6-RE1fUkU!B`0anU0!N%&Lar7n=-%(n^q% z<)uC+#TP?lc79nQ(dn0ta2bLG8**R-CI$W3GA3!>L)iQ)mytmASJIqCFrA^nPswHY z@V0`6C48N&q1LS%b_R|4c%xjyHYS7d-bCt-U8gs*kY<9cj__q&{(qk)rcGA0_|rRz z9*w0ZFl~MHV@97FM5=eP<@RM!R?t@g-c~+fu4gkSPW6Ik#xmtLmBESC<9JhbY*m32 zlFm7T7Vor0B9nnYC3%|1B_fT7LVPv`tiE<16jvBaS9vm&@Lz{g=h&u8+xmtbtC&$_ zs!f2U3UhQHD!Rh1o{YK*1fy;A?Eq*T4ADL727m&E%xcG_hQ*B{gNhPu?CGpH0YGJ& zuOCzmn^|CtbeN)_T3xPp!;zvGf~?CJ0bb=3Yx~!Mi!}Hzbf_F#A0;fjg3v$>WF#^` z?MnCMH8SP-6)Q#C#^uyn=?OORe{U6WR#bBu6mJ$_MQ6D63zXSmofw9jdI4 zj>Kpo-a^J5#{5r91-uXRg`rxgWkeEqfWWdBO^B_Yhi@DMVi4XBv{~jwY?P;o6 z$R`NBx@p0{sr9|Qv6-7s`AMP*5?l_JNT4`cPh!>YRq(O8j*|mtx}O~_?p$abmtLLx z#T)N@*|{88*-$mF3u503+X2Rkt17N}N)WT@6qO{!cZ&NHj;X?(NpLN0Y&g+%;$0`J z(@UG~m%p^)1f^KbiHd&Zyq_lcijcQslsYJzHWrnkG9AY+0@#zK$1be7Hucb+)aEHJ z;E)4_3A+%6Nm_7+mfrzd!t?D^Kh;A{h&3U}%Ddt^kUS1-Pu2peq<)C+!F<>~BZdhT zwux#w+2z88^s-^_-l67!T_Er1MXkgZkLxho6IxWyTc+~B6s}~u68*PmhkG6fbIO(I zjQ4Zt%d0`hOwmHEDVGCVBImD2?fup6T-kXYcehT5s>XlK)!-1 zSCGh8`haegBK_OVwZ4h z{6f{pI*+w|X_tQ$@45*17XWZ>7W{ZyZ+ERn+_&}W6`0~S#IVG2(Zp+8a3jC!LJON< z7{h>{B;7GQ`xceRI?;&_>{CmH~yQHlif z-p1Vq8xvK;4#eJ1LR_%EEp7cZS)8bF!n{2QVZk5KQkSR_uCr7?B5nQH=$hN%QU9~K zPL@`MM0o-y`QHfLtJY$RWJ`Zey9Tzz@} zn0JZc<3gu=|4d(8&hSzj0t~T}(*_H>Kz~h}`4Zh{#WE0J!u&ednu5T2RO!Bw!aKe9 zL`Jq#JB#1BxQ|#Tx45ZVxV`-r5qZj)a>&$md@5AZ)s?#zBK|(|n_IH=z?6za%%4$g zLmZevK%Ru0n(40IliLR34EpOdr>gu~Y}sC>eY=z)^)W+K?=<2mY)49aBAh>;)Zf`y z*gqa}zRJ3(MK+i!S_YpF;;$MpGY6`+#lPZnGfSC z#tDF4o`4sX!ZEGmDLj zRvwgZ#DX*CN8Y-&L%3sM|L(1boms(zu1yHt>x345Xsm`;bLA;`omieiWfE5gAg|U5 zvI>58ZGF_*vW5aiC+G7Fx7?=>rp8Cr&wJS!G=2sW&D?#lZ_m3$Cx<3TT9Xfv?aZ5^+WP;JE3tfST?A zTUYar8Rnt-f_$@Z(&cb+LahsM&;vWhl1#{fAF!v?%4g{!A@k?q zI_+vc+9wpAev`UK6y!}eza`Ir`fnZmXzN|yqOtX>pcGLv;(B)gXDHPcY&Uz?t-6p9 za6WOo{J$?@zRuOkXwe-gnf62Xg$O&89_c>MmPFA?DBlcO?w9KFcg_~1G6AUWs<6Ek zK-ok4L^|}AYkxb~$48-_97*n53_1f(J{B}UT2vIw0IO=_m}%g7)Pj_8r^ki-bGc0!KpHcVFV5!&8QN$@f_9cyqGlIhAb{`n`xu_7m{r z5&N^vdHOnt%h7i0-p|(nU0j{ob6LD>ACSi=#q!Ovd3S61aLvB-EG=m|k5DKA@%tvKz)G?sNPZTr z0L7XYceetz3#L{h4=H2K*dY0jK{1)2A(4qU@X4~#PN6t$v_}w6k97v3G5Ax+!=!Mc z(QyqX5fj1DsM?T-(N4iU75r~shL!?^4g;y=50{vdC_rS$q?sc!=(QA;^*MM&$SnC# zfek4#EF|q{8j_?7uDvp6M~VBcUHDDdi)sNs(dc(3gX=tS88=es&1izS(aR;(AR&8k zGd+>5>SMW#Fjj}EL2w5J{@z`@ya@@~4YQEC6MjE#VPEOG49)(#Hp;S%`m$A>;2T^4 z^ErR(ocVRsE~o#?5+|j^=m}}XW%=xRU7z}^Ms$+z_@-C*97@qt{0RJhZxFVf9gr$D zH)Jd)V`xsOW|_rvzteW5tHpv&J;5=eJZ0i1ObZ>!F`=x_(}arJW&SqTl-# z?yj;-2{f3Ty67SyfHiTg zCh89VS!qD`q^d-PddwC95xIR4rg?fPUJ{4UJ!7f+9Fs#m8sIXK>Jj^<=RhSZO=mRY zo>C?60wXYapIENbxyn(?<`y+kA#Aii_z|5s8_csqF?HuVR=N%Se$AZ^m56d{@~h#4No&g2|J9= zzq1mlV9(4jF@pbK&*2yRWJqN`z;K1~L~k}_jeD>6|jqngiek}HOR zKxcN=-mMun?uS*zUwcfd)Fio15L1R}@WA7MJ6Z5As$*Bvf@zP*fjP|z(w{vi%_R?R z+PTN*7SN%azb7|#xF14Bd_)SRH^f?UKmzb(7@@fNaYNuyCIM%YZ17l@g^@t(?o(qi zFV?8Y?C0&ufZO=Ezsv7V-7^g-lsF`#ibt!-2D{rLBU}>bLP>0Qqm-HZ)9107>gJ<% zEi*V0RphH>4xY6y*9GrKBx6{b1+m0x)~669ePrL*GkyucdM~5Eo$G0_3PQ) z$uuS7N@w8g?s-u@p!5~p)jj6>wGefU#W#i__ulR>Z%g2^`sEq({NsN>h4XLEa-xt< zOgb{=(B=25Z#2AYjGyP{EIK-%o9`daZCa1HzpJCg=Y9Jz=Hg=A(tOj+#wV(YvWsKl zG&t-2_ft;bK1KpiGNmB^y9NXta%GOjaf?zix;A(w$*^+GB~=X5`-lTeYdk$G*>F$0 zhS5D04?_)#fM#7x9c!0R2U4c@C{%3wfSm$g29s{4deZ7PRDgZ;QtG8F6Z^zS2kaJ< z=KL};gnBO6#qBWpjndFmE9H_S9Gx!xg%1_o^M(qUd`o|d%6?M4Oxx*lT2OarNeaz~ zN{tiMmmG_Uz8)LKoGMdsi~boM(u|+^gOT@!5fDpfO!f}DJM~<~T&bI#lTcuA;LnMb z`NWuB$DoV=IPOo|X)&qx-{$YGA&Wcm8+BM8(V~7b=YOqPE?2nv7g^Jyrf&@q9toi- z102RR@ptIomfY%XRizF(BA5VQA!W_;ODdtOKzg%;mK5%VxdFtM(9*$?*$p$Ng?qcJ z6zx-J<&(YN{rC#{oUJ_OfrMW>=h<@RpA2N$r|zW>KVBUBz)4jz|8(22@@c4DB zJVEkiU0O-J92aGb;d{^)O{@@07TLQJS4ke8dsVsm&wHLq^1&XonCgC8Z3r|gN(Y3R zG*7f7ZatErNwwN6;G6*7Djh5jT*EmvB@np|q#~ZZvX}y>e zSp5$XdEaf)tG<7d;RMkRQ9c!Ddzv)B+jvCLXjxp5S{k2N*1?ifGMY7`Km}nBNXT6@ zsl#3l({sb)w*S-gNnxFyNg<^Nzeka`PvVM`NBQ_6Ax8|&)X+{YI#lY+6ZBhF2)L6I zMahE-(1kALB}tCJSJwZYC1RRSLp~?s5^JQfFn;+5rgvDdUD8w#!Csy}7|J9mU8~*# z`_ns)Wrq%$*GJ!m3e`KyPpo?=VHUWYZxs)hH;-U;3`TM#GcHI4@cHCS=f(`U3!XQ#vz=k%- zB$hHX$G$ebU+AByi`by?6Kg>Gb}I4}1U(&A5UZ`v0EZSc~MHC?;vYvV_ zPD>7JE2NuikV*&q2<@(6L~jWH_>xyB9kffBYuTFvmIDBgDUyFQz9XAkhXwLEAytmH z$@y~o)hq2I(u!>j`8v6H|a^S9&1-X48-}dMmKG3V@b_hT1s}Ba;q-} zut`hj4`#*b5;57yc4@ZY1w?vHR$Hli8X|{uxxpnIuH2u(`}drAuIJg1TtxtE>06PY z{*vQZQQyUn#8B${ zw-esO@Z_VDad(jlc!WgrwVeBjI%OCWJIRl?>=Fx|<9*I=pA7szm)pj|WqLcau-nLZ z#VXKtHPwjFy9kF`Oy#o@sL*(n0TPG2q5WfBBw|T3T#l=xaz^b_LC)qcA^V3JzyDNC zeWn8YnFbw6mMBw)6^P{>(zvd^?lPYU?7~^9~yGo!G1~gfo0;vpA=mXDC zfhmfH_R~QoH+R{)bmtT(Dknh&Khy0)49(n6-i8daiaHqSU}rNQCbpQnK+K#XJ>%?t z-%A3sxYKV|$DpDIt{-;Q&@pkS^wTr(SrD2i-XkP_53ar?3>c1pae%2vEx6F%fr$tjilszi{nY~#5 zhtj`U6m;AAzk!MYu|sLO;X5gMBlk&c2T8kgUC;9^%+l_W#P(vwM&!9DFsvxKSd%Te zIsrbNYa(6eJ2&Ugj~SdV*3{Gql{Gr`w(!<7EvhFNk1j^<&W;RAJWmM-SZ~d$n z9MSadxvG=s=0EbavRtkBp&X%Q&WKCa_cS%Gm0P0kdJ`En?iE!Gy45Q&%b)Mk7ZwSc z@&=vxh3Z_Tfoy=*^K)9@$b9W5fNDYmr4c0`Wrqc>&GHq&FAuN}Z(t8;0DJ}asuyCgl2KD;Y>byy`)U`O6S<>7~E{9sDYA@!)&U-BY> z6|!+qmF4sjZ!|<|3(*KJP^o3r)OdAULAtzS^~ISFr!OFZ-X&&#+jI>lQURpN_pqeX zlA@IXV;YpT{;Y*WW3rX+hG9(kP!Wu#n7}_~lJdMo)yjORU^GeNg1ER2K(}Y#?7XC< zDT`^lzd*!((FI1dVbVofc;O(!Q@26V%^$?vvW#R3wEKv`&_^b92D{B>&qS%|YFb*l z7T=G^+L3i**-}*mDjaStL&=8(a7hFl1Zymej2$MYSmbM})+2B~Z*LcU;>~Srn>y~f zij&Q>`^i4$N5KJ4wJl5sywWNdN(0FooW=#Yuwx4kSP%chO}br!2@c=d?oC)4L1tcRVC z^OqO4dgp{?Ss?+^!Bq!fwpFHLTg?NcpG zr3ee8)aG2Ld#q~Qoy(tjCQ||MdxY@8XA0#%6W(1N>v>%r}(7(6nI3V$ZL1 zUJ}*v!Mye1Wg$ZQ)4T81_|08MY$AUwd@^tM5H34}!(rZ4iXeVA17sDz0@EJNw1#x% zv;hHS;5h9NE!*`2yhT+KoB5UB`TKQwLu_8#0TpdW1BIFTohZYV3CFL+t@$k>`SSnH z-PiJS@9de|)89$9@0D>^IqZEDC1hJ<+WKGAA|9IYSjU*3iZ~XLbO_UeL^vBl-G!hs z{{vj!O**_?U8|-GpF>Ka_5*&v3)Y|LlL6NWkV(-GgO-Au)G`y(vIf%blj)DStCWQv z4Swd%3P(fZ0N-fE(mDVxoj-()txtQwAEiG7-}L=JYi}Dw`8cnu)G!{%(eGiZ*VaPsBrvHkAV3;5p;I0^sO;?l4}E`m74EPdgWRSm*3X@=0c#%N~q%A1K95D zgmOZW3K{T8``}f@Z~2-9%pwM6@oK$Dyl!ppbi)hKh+ibCI#i8kcjE~`Q}V{b>Xoi0 ze?JftpGjq+9e@C?ZHTpJq5n~kzG>|^8-#zr=3eQiV%8=Pl3zBd*Il7^41_Eby7INL zKU4h{kkA|~RISpURRGZCQ(<}&_<5d2+4~@Za)q+u-}B*3>db(<`l)jC zpt^5eRand&DNLoa=K0*>nk}0UARUy+ejoZXc^mRbz>y6s;%X|{Ps|#)OO6uvVwN7p zS2s~X)=qQWQ)k)B>woD2@ZcN`#ZFE~<#tx`M;kmQ$vEUJhQ)k;el$v9A`*V}?fvbKz-27!5F^jeDfKeG zUW>RKb?h=2_ZZ2lvEC4^OJM1N$(yvGlQAylw_R1ze3AbYAcyKvrf8WhaAL2%`MXgWt0|h`YAuI|R1O86-A-&RII(|0$12S{@*XF#`fc+kgMwcjV>~f@ zMZhKJ8^4dnVxQ}dw{X?Fn9QZW!XkNqjQ;TX6Q7|FFJ83fk3^%?G8*J8vG+o{ z*#^MmQdv*2LAY5Ut$KvGXIczep?YJM|7Cr z5P1kLZbX7%&F3ecwXlvKsGd_jt{o_#* ziqv$ssUGsj;J_oF&_}nQou$_#TWn!=ZNoelZR2qOrE|x% zTR=I2rL*>Vb%LTBwr9r<8%$Z{%Yd`^+gX9GAjU}pdJ6oDA669T{@>(|$b)}YdYG@) zRp`D}J;ZwvgjAC{6MWKj*m%OGH3u)Qk0_H%QVCxJ<=C-5{T-$+9~{D9AejB4`i9(j zqbsbjFWEk$imo=krq1dKZ!N8%zQ;f7{Y#S6En+$ioqHjeqs1N}A+-&?3`yAiq^k%` ztP80qNUE0Lt`eHM41Smbm;wT-T{cQ9c;M*kxLT6M^Ukfq%-keks@~c^CdhT zol1Ht&4!>>p(jA(du{2#R6rd~J%lAt!8=`hQ-(0dRM%#EPdjT^AGNR-I9d)*! zOqDLUZx(j(?rja`5AOAZYhyIQ$tlhO{b*scr8TpN;q_Z7hbzv)%LmRSbRM72h6;~i zdsA{d=Lka{H5J;Z-QSqAj!^BPB2w0+l$}36gnzOhEFDj2L_QywPz$jb86t$y_e!ii zZ}52h`^oR@bH`-s0+_DJRT=PJpp5L{X}%FCRv6jj$9T6JjM8Cuj1r=1;;%NWSX9S>hrOOVi1_AUHpSWsZt z-DE>qZ5d~6!3lORsbM9R)_Rz6CE#569??kV7|rzgLX|acEiGq!9H2(u_I(u4VK836 z-3WT}wNFB-u*4`#B^|5&`yC_txwp{$KG>+3L(I*{u$qy)wlf(v|G3;ldO6C*@CN=F z&o4DpPd{#X*xaO$nk28?wo^ zQ=Ik#@=wUkGbIFB*Z?523nxlFT~~Tal+#{+;v*ff;I=Kx)tkB0r>tnpI6O*UfJq2c z(IFLp9EiQH%pAtXC!t->j~rfGnjhsHGP}0}*YYQ!l;|J6HDpkzv-5<=ZybOJI2F`@>sIDL?r%eg&$65@0FfHY>wzqxO=jv#PRv|F87=tUF#U69?7s>Qg0ZO#~3G!Tfp_K|1u*(D< z&s@!CZ4caf<(NW99}AK<2>>~?Dz1Nd24mJNcUnc$Z(RqmK_030yY0j7>9b^TqwO_j1rn)#&7W`^JmC`Ga@ITE)Q`%uTmRpl-V z!XWgMDaZBjuz^Kr&P+JX`~;w8n4IZGBeCAOa@TQ`G+yqwqkF5rNUR_(pY1-TMu;#J z8J6xflAIpZWsaM!6&86>ns=EhJO%6bF7W~@)2Z$S+UufA2uB$97|z_W08z1?cd>iJu8{b{}WE{@+vMm~ff z(oEB_-@-xWyNi~)VPyNcyPn?6<8K`g9XU+(;WHw1R0kj^)w?4|y@8MV$>9`D>popa zQnDN=ps76zPoakNKbwq_h6EJBvs9r!tzD-Uu1KQ$o z!!xi2Cw??4iKnyV*le53elwS-52*+gvw3eJ{ddw$K0;60uo?w?Q7?p2etGulTGNUg zK!Xx%Qs)iiXquoUEWXV4r*ND*k@_kK zez7r{&^I$wDDOG%K#`uNrVq0m7`5HTKil-vbDs4An5v$o*HBEG)C;5+6`J$m+t(sh zYo7|75dV&--2*80f0O&>hztgKz@oi`!4bNl9STG2Fy@=4BZm8f`LiT5%`hYWIL*;2Vqlv8O zE>%|;sJ%>1?@y@iNHQjls20{{BQkt=xAgVpHUunCL4&Gz6U)^6Cyk9fLln;T=$MHPy_p6(a==^Xs zAB68GD0l4vgPW%V%ig03!TUVFPdgHarf6;blsF>vYd;dLKi{(TiaI6L$56Z5+yj~1 z^S2__Sq&T#Du9BQjR7L=orT8wAHNU5tI>3hOrOsM^m)-7T>{}dyy=e721OUi zLVHy1g5D#Rk$-Ll1Z*ViKJ6~3HxUgR6L>2EZDuYwTattxH3;;bX1`cW`;aKOn zA#e5HfaFgYIVO&`Y0UC<*p|)%H|GjZ2E$J>0jAhX8$e5)lOEymg7z^wh%5=#;7bX> zPOrovYYOTkaI`M)#np^O=|!r=!o&GAWgve!A%36+f5n5nJW9Ay^{O%8q z--=o!SZQOZ-(MXbdQDDh)1k=#o1V7WGe-O@UD8|o?_!^|06`xG3gD`@tGh1NGBqyq zh{6agEx|)aX>8%5hhd^QhkE~9(|ycRiNxzaIZmHc{8b%~;P1SGcF~mW&CatJfc`Wu z|K;syFW1z`kZz;vn*D_}iH=l@eH-J|D#hPfs;#2;4^AwWcX_LG8c@OFA@-IL%jR*$ zw{$t9yP+-`9rw%y_A~BP-CQVn*QQR*>jxl+QjO5;8aEg4sks5@O2OFAAscRrD~T}> zz#g;R`i9gg(@7xbQ-N2!OzvlZ&quLSmmZ!}f3 zY!g{EuZGA!jdY0*DtdiBKT(@M-z8hPJhwNOhF=`;e_P8QSX?2Ve|i4p;-%BPP)qEZ z=FuU~LK?7U|GI3ZbCG%g#=H;yVK2*Fv7Ouys@c4y)`C5=e z>q?(%Q?t~>$bt_>@VG`ji*MuMdtCZYML-Jg_a3*31bUg`5ZYj%U^rtPhtkTQ`?8IY zdk#1*r~pIORQ-xP#JZ&tmh{%xsB6bq#pM2CI7M_9>y*>==g)>Yoo7J0AcQ%>p0P`J z_J`_f{3)+Jt37Y6RJEE;AL8nswO zNCsPQSOE+uq-vIR^VV*0`>Sp7JvO;P^$>*xXj?|>tQ>5s*c4%IC3~H& z47Pa-cwdqkaO(A{@7KCEBDQ|TT~VLplMrne;#1Jz=Ig0lb~5c@X#UQ=i^kmca9xD9 z?zW&jh=lNzWQc$Y6Bd%Y5F~y2)ay7Lt-`py=3N_M_UnUDVSjDJzn5k|%Yvnu_e*}s zO^yQ7*m8+Jorarl3@2fZJrA(<)hIrcK!hIj@xpaU!~BD7IjTBYF>Cr{a<8yqT*^^5 zkU9mNR9%}8WfT+D=z4C^J#v=jTfiq(+-29FY<%7-hrpdN=%_^jkbN` zWcW}u+M5$XyTvcLalz8nmGN|@C@jvr(u5P(fp`6C#rnBvyfy_Z4ZbAtBZqzyKdG?a zcv!V^lNz{bT0Vn%(9Zoa_HQpUeb#uB?-7%@Q3VXlz|*MI5&$FhL-7~=hd@>WzFQ-? zU$QimJO<=Pe3yfXTOf`rw~EW;I-~jdJ0&F z>{jS*HH%J&b@&Y9<{v142y0jOr_vnUurY2kI;n_8{;;4Yn=4CU0J5I3?c5 z98L@%hdRS}Z@_8ZXZK*D>S^^kw(u4Mva7VMX3QtMJOOJKZGD~ZtNglbi z(v^EIu(_UDnwDq_fVLNPPs|jf~H|4 zdT7-GlgnlKg0jh>%oDpyrch!wlt6hz6i$AaLhU->he|lxy6P`@ ztIA^N+@Ycs4R<{|Bzs)jj}seIp`s8Xa~rD*IZaLHD*bGB7xw%udB&02 zrm1u6!yg#aZJ&<}vfLU~-1qoyuYn2vZy&|q8WkeG7`Ko1N%evIA z483HlQ8M&B$O66F>6(8Ot>MNTEyRn#}YT-_I>_& zQM}9TkHQb`?RLq}C_hLk_|IwCfm9^KxYO_Br)L>#gRI3c?T?EE>%Rz#5TYa$YwIyD ztJklUH+~-k_WK6~mEw|jmAt@G|B+UrRF&d|1miWLz#CA*-{WVSpL6xMyb*d&w!NY| zSkoSRV-IJrR3aM}tmve8+H1r8{{J#W{LbJ-l^3OtJKq-cbyLpC2L`D|qU7=vWmXrO zTd9!M<5Ck`&+jC`EUSY^t@h<|>!Ugq{A~rqh3{Jh7EH?{L^f#fyaSIEu6iSDI#l(; z8JoO@_9|MAzgTFVos_Uc)SRz&*%q!&IpgI)XUla9#%9DH!?E^; zO(0nFjfDoMC!6=T@K%4LrX|<|*WY>KsNg=Bi*#HQATnEp8C75_&Qduk@L|B%M#0b; z@B#G*tyLWSF(!T&t?K&2Q}gFi#ktf-K8 z(Hz?YUs=$}HYA&wkLf*#AV0UmW?gWVyD*0Yi7KB0DYSn?4|!>EUq3PIT<8|KIf>TB zhg-fDESf1+q-earmvPq0Hxxh4`S_4iUnTL{P|=E>ND3^*M}s-{9}#xK zl{i^tIH+{37#m^W{b?fnAvDd475#y3!>U4TdmAF>2OLsyyRE=7^1WsLcs~b)XsT_@ zv^~~04Y9vqA3zw{`&F+(8^)?#$DA&g4f<6L@lh)Z3cT$l$eV4HVc;^jIln5=iK43w zUkYhc_p|ciZO~Fx(H~`$VsP;PKZ?#foXxk7;3+O*bQ151E(atRKAdg;eHA+J{ zth6=lYa7jimH z^<<|N6`)9vy?CbUD5H!v9E8pwwSK#*czw+(v z8Qr^~fAn@kyCdJI@@bsU4itX~uF&Va?FcUchQ*&lace@WwwA2V&5jg+|1;-EAXNVOLf$@EXElyOSlU@kZ@^GvE79ZQmI+E+){%5kXDq>b zJ5p2ZEuRvP%OB3l4I9E;|zyob`?2eHqAH}(kp@G#-8RWR{1IeL1g z=p%`f+~Wei#UjR)!>7bQ)8oE2K+s1rqy^E*cP+wxLGzl{YWeS70v3>z;{r2`LH)w6G8bIM`}e;D5{nF zC7&3Pg0W+n04#A^%;FhI z39(7<7HFCdGwrY>({t{OlyM{hN;3fPm6+PhexKNqAyDzC=m3>Oz-Z>4-ev-nHOODB z*(9Ijx!Jd+VA^=M(8h=;rXWmOY-2Rxyx`sGt>vufSF6$xYCsFu?S+2Ln+5`gbH8W~ zODq$<2>+Dg(R(x|d5vB&jgkg@wt~AntJL6L@6?(R?ic0|3ZYh&xcbTwh57*tp;spf zR+hKUT@I&zW)}QThlpBFb4_1g9&r)w%94QlY6*8)&o5^z&JAjilqeg-b&~8bq9jpS2Av7nqK0+=&_8^s>^s!-#N+w`O)A%_4Zmw{LJb_aIJ)2#_4Rx<#s`hqqw zcSqVeX8c{yE>)SO%nyk~8>$ffDMd3ME>WP%N@VJjv{e3UyeM&TOeXG!t2$su#8w-h?Jx+5k8q zc`rlQt_Xy*n+%8*kRUsav(+mbtHKRw9>{oSs9G}a`Dd_Cor+nNOS>Bv4sl zRkUOYI$$-eX*|wP)T}+odi+z~PIFuzujE4wKBiLt=~!p66`=a5H@{N!Wjrv}Jk#3L_oN_1OfI zjY?XeXG1NT;-^s`#n|EfX@kz}gjuH|a0gMCTr8fUN%2@dYRNdt;mM=qQyuKb%x89t z361%TQc=t9qbl+Qfmw$AQ=h*9gSVf@K<(WnEes4Od;-SDT3?Ztud-;( z4Wz%jmCoLSj*gzrHrcVYwkp*e`&Gu6YKkU6KO1{JJ)1s!CfPNWH~nf#Ca7~hr?1C~ zfUQM|_5&R|f{bM}KpT2jX@B&!SeF#Z3kidPzQ7O8tkR^r@kfk}tG$Ff(QPccE3r?uU$H%y~W~(b-9{y~9ygu z7;t>|*+|Tj+64(#U{PTyPcqcnx+^OzYy8R23n)FiQXt%2mrI-vrbIQ%e@%$+*pzh* z{c*Bug31Xbw6#`>7qSf~7MJ9Pqkp%;&_AI^f5QJjcV=^5pSJPK`BLO}=~-0~erwT>E-4QfR`AvfrlPnezaXAJNy#o6b8$8 zyOvWeb0_iyhEM%SthfjvE$0eWL;X2myX@r;K9!^SX}d$2s|?pX0auNhh_wS>0@$~ua zw-59H>$jJ2=xeB7cc>%u_T$c64_8!WkjB)ZD)Bro0c6G)VN_#GP;lp9~l7%Y7L3IsZFtpuNBw-BfS`|Zu9_q=;M^G*X3LwV?t81FrUX}ekKZ7=(jC3yy#}m z2oT}RXiD+U;?P+6Jax=gOI$-|3DJG|;88;6G>meZChtY_Rfe=7}ZCTWQC8%@<+4Y!)8CH$!!{f-=q4 z4HD-s?&+I2XnOJe2JwLg{UZJUK5N1@tdK532+g*KiSr(KBcDN?=@&{dZ|{H-(8`5t zQr;@R8G|zXtOZfZ1!zbUIEX~v#=7Ss$aUf-Bp4`X62hYQ%Z*-S zuc-~m@{**pzaiFMiiQokKAb%?aAf|a*cT@=*GlPpj8vUb3})s#TSr z$(}CRbR0bld=8Hz6pN|5e6JR|CpxxJLv@JUc|f&0LY7o&b?9tH$DTeKcBB+lZ|=2V zP}7udma8z`2m_UlPcA&?Ahd$BT7*7{R54d6Msg@8U%beS8W{FHTk9YxgTynt=a{%n-gK$?jZ1g#pXSGft`E9NVZma8%X;N z{QZ<{&zxG_q5JA|^?-0bOi0jie&Sv7BC`XURUrx9v@|0pU(-lz$%xc{pmP3x>}09W zd^UvG#L04TKBab^ReD^6gzGy#YIs?d%cuwL|Y7Tl@c7C{(!qs%mo|YbU23akLru`T(Ov zh=^K<)7%w}JZq_Ea^E_{+uLEN7chq7yzYLIk$SJE>m$4lH!*2evK4E&F%I2(bVJ>n z2bY+~Y>!<;7DZqG7{@&_sOQ={yHaoxj09B>2B7{V{#zpBi^&51+r5O=Cz6+i8CAvj|{CqlK%ZE1MTX>E#U!kFb&v8i>>n+OOmuFhSGE9#X_7qj-YwN4L*Dk zrZj5ypw`?fnqC}TsP(6s>{;tE)AQWo=kJ5-l$&)C6xNw4o^2$(i9n`C0*=&K=oRks z{sq*jDx6qKEjaA!_f~2Gx@V?wb?4g(-2XiU!M09lX%(m&b{hmRGD!*N^Q)S#n`(Zv zKNYv|Wp)04xP!2jFw3|$yzv6 zzHB3ICbqg%F8?0iSNu3e=d>r+mQd^e^R_`{ARd~du%2K{9kGAF=Ty}dx z$r68?%|}_>ZXW9xe*)o~I(>jV<(8$4`|>&+{^iR%LR->Ij?aK4BC5^t3WPObLo(dJ z6$wIlFCgoEB$iE1N}0A@iC)g#mGyRUthe|zdj@1TV278O^gV8dis{_Wvdz_@J&%6> zeKmY2TxY;FA<|l03tba*=4R~OB__0DP3BU7h>#i-Cutn>?5_ML`+)DmAR`Dv2}Y=y zA--9Nv4&^*Nag^|i1tb1+i%eR8D&kNst|*9L>@CwB}zpX{m%-kP$n2(5u&cvC)UFA z_g8~XLe2AhpmXkCoecu$Did`MZe{N6)W6Hv>^W+2*X*w(Uln5N>u#qJCNC!>;Rbj! z5zk`}fjkwf?cJNtpB#RSF^#G|A~?!4?2D}aVW2(|=SS$E;%3*i&?vlNUR^4o9+4MM`XxsRGaC3ZY%jrj_;DnT^Gy?PMDM8UA#^OIg2?l} zxA~n{^5ngNife0+wwM1+zT7gdv}R63{7G49D>UNACPY76jWINjvw%DZdcIoZeg-Xo0@*W(E^AX$yosh%DN#$JRY)uR!W-quE|Q`B(;~B}Y1`HPF3x*qU^nUZgTVeEEAxjNHs2L^$5Ly{Y}x=*LYb*Brfu(WhN1Ty8GUq z3fNu$V=}ynWbGJ-Xz%LC*-9|1@j!ptG5f7!3D!C;z8(OZu-eU*;cUz~IT(GU8_s$) z76_Q<_GO^uCgSV(DMKSsr_S&N zfRZ2-daqlLy>C=J-}c}t8wbU^yu)u*h0K?2DqhbqKfH1Z#r<> zp2%t5hFPY;J4opCBcfCy_43VWO0W+rfM&R4Lo^aK-aD~rXU7!7FAE~R&BVss8-CHv zSsr}#LJ5qQy3)sehLnlQM^(?PU zu2XHpMk<2Q6EOY!C{$m_ZQy+DB`8=Ae)Ih;-Rcy|tM%m1-L9LPh_%Y0ZZ`L@z(jnD z?%ie)})hrjmAV}Kpi%wgTimgqP6UhgiiY1O0 zCL~`R(YHBty$k#6y~0n`R(m^)1MpuYOCPT3+tQ^M-by48H!lq#HOe!6giRi|#G)NC zIM2oG!;f~^hV8_cCc>OW?=21FZOkF{`8_EN5HOcv83PjJV*JV-V8EK+ZnO($CtQ{Q zx`sr8gbBvSl$!y>pRfckW)%_yKYf_ysnY>;slt&3?Z$TQ%1Fx6TvDe!zP_EtZ+S8A zWuLQfzS;jHXbu84)^ygEds40)2#7Ptb5|N3i}|}DQs2f$^vb+4D{;aTUkzklTLg$L zX`O)Fm7pih7j_EE3C@jZ>jGEMy47z zN5=;hS2SL^tV33pRsvYR-P|?;Rq6h=R=C)i2d=KJ_gpZezzh9SMizLP0zalp2abMJ zNLiCQ9^JX!Ir!ZH@sDxS(AcwM5?g1_oa1B+nOH)amJDI%-BBK2=o30f<_qD#|*RTbPyJ7dj+cY)q z1H#>m<*{Gi_CpV*c|iC$rP?WmrseD1j9<_hm8%Vcz0QtI0qadZ+d-sV{fFme$#*AO zHB^)@f5lxFaz!Wd6eUbb0qmf-S8GD|L;jtYfE@E9*{!+^O)Iqe^iB#y#95Qdccg~F z3a)2!O`e$O`C}Wg3iJ6bgB)m;`D`W_cH}-6POq>fOWbs=9^uh4_c~YuRELodg%{*5 zyxahdZCW9z5Og*JJydkkJBN(v4yunEU*X4?S%W$q@Hz;u#ys2dV0DZL&ZY!EzN=LL`IpC5+mb)Zf z^~u57h?HwKwH~?gfz1YyCKl%>t8wODRLvPDxrC;L0`30C=l>H~H&px$1G1;7)cA$Zvcr|iLymzBr%TNyylKpUuq*?31)y$$l^=uh`-Uzd; zLTSLOPz$s#<2QEC@?=Pypc1|BcNhHs_J!HBM{#7?cm6<|a^H%oUo9W*1OC3e=Aeh{ zq3-ogt*!dv($;1MFEAUa;$Rr~nNp$sAZzX}iOuXls@MYA;yx4Bi1pGtW*q4<-bcf*6F0 zwGclpW99X$pB8;IDBGnFm|xeZFNa89*IuuZ^Ux`&ePFbw!x9(#%+ng2{U z&$w&}+xVCO?=A>Z$1Gm%D%<@#c-FHGbf1rPW23>Pr}^ETIDFf~uV0IOR&fiMKk{Xa zj{S#fza>0B3R^x{PFO{dt?F71Np{~P0k#ExeH?GMy%zP=b!(JQtqsXL1Ose6o@^W`nuC=FLMff) zlw(M=TWp`!<-C0dIp8iUZltIds{MDzT@-k*-Ps<7He7`$u*Hb8<@T;W! zODm^rNnQ@?gqcgntT@TihT4Q`yv3W^vRoK++NxrxkHlR8CR#dhd|NE_Rdv?05CdEI z0iv8Qde4mkm!!ZRxfLGA&n3oNY2rStU##5+_YKn)sAil$449#PT5dOB9P`v=iVJjC zj`X8O33QIR&Iij-lin?Y*s4c`dsFbs&SPYMih3a)DfSnCpg*KIq--$p8VuiZmyGjT z@D}D|NG#ou0nqPau11Y$zlb%%=x?$ee}RJhx~kZw>q9KTW&G{NEuN%(BY1WoC+245f z(mG8H%RZ{QkbKR6z&0sfZO9Ys(sD*Ln^tlbM1`s^(AI9(nwM-`baY2$TEr;#TF5)= zzy2==?05?AR+%|Xbn8~_x#p=~JVvd7w=rQ!On%9_pC_jsqf|o%k$5CpD(NIhlCJ75aN~Cvr!dlm*CT1TGTW2 z=q#!GX2dP;-z6f5Y#w_G*ol)@n0SrXm`_E!X!BykecvvfGkiBx#j2gK{tTZOfu;#R zc-XqZKsJhhYnm6J53T3rb6O0&kdi8NOz=BwLX zoo{&Z+0A`=212|$on+a?DowG~mk|K@Y3oogyIRqoJzSYkeqB$hIMYJrVf5t7kO9)V zcwEhtXAX#W^lr^Q9J~EXDgoSk^sI4y#J0ol{1=H$S0I^v=QW5m_hupf)HmjegIhT| z(SwQw=7Yy68luf05xJ6?tDf`3)AJ~8#27#!jCedC)>0wh`lLQ>_Wa2@?nTC7)Sl;hHR9DICFDbq2*pXmHRz|M-CYEt|Tk5;Y$aQsTjd8 zx73F#hySDu3Y8vGKBCk7uHhmlcbThEeR@%wT0n)|DHJdX+XilAkb3w8E6wC#7d(M6 za2$&iCk#F$aO%YoLM8y`Q#{C|Oe>^N+nV=5^HX}Uhl>w6YN#c}Ui&7v2yHrS{0Edw zyH=EjOjLWYg;wz>Lf~(4`86IcIM!xCQWP=bzi9P4j7SLD(t5UC8e_L8kB5KW_3S-N zRjk5xND*QxwF=g6TCA^ikG3j{c}>>IlevXN7|PNUya!}TU7wL07cY<;Wf}DSYMzw7 zoqBL=&98PIZz3FYtwML3pr0qhJ^$S^_C6#)*iwJFmJmnh8vH76am;pQmIzUKc+xW> z?lyioP)mh+>g#}d9%W~_4KSHl2ng~LKZ4!F?81tfhH`N6q)+J_gWaym%3`^`5L zUzR|n#tCRW1c=g83wZJAG*1@lx~EXGaMJDd^^obC{m=G$E2nhDPMH7Xo_%~&vOJUQ zF{8+)c5|L^ZOa3kfp6$;p8I3!mdHnQIE+hmXc*DOl;KVrVzFf>>uTpKMJ(=5#^4yK zvfU@7TbD15rbv&A)2X#w$(`M(y#KR$rq)j@+3cv~FF@$#tqxnsG47vVJ+W#tuj6g` zG0*?U{~rr!aYXE^&Hv|6>>XNtz1NfC5%2)GxpfB^Zzbib?sYPG86SdlZnfF-+iUdc zwe~v-(~r|1eX_p%nl|ilf!5fG+g;?ISW~@H!eW4Jv}5Rk3zL9)iZKaZ|Dyv(ud3s8 z%?Qf}d@8vm)qZO2+TTQ;@tukPa1#E(EWT@Ap1~#{5|CRTEBI7!Vk?yc zRom3A!NJ}Ps`W&Wp=y6O?c=t}gX5qaVhS+kQBTriUB>6SVWY@tc;i0ceeaCs8t=Yj zxV^ByJ=v$2FOIn&sT?cT^}XPQ%R_1=sq|*56J$>CCGqNLoh$l6J8Xk5&&3_GKV;+P zfs|HgR<_}>!i2q}&4-o|A`Yx2Z*5Zq9G13}BS=%H>XL<}|J9EP+Q_WGNL!%@Ms>m# z-a7=@E;5J<&1kH$%!v=Pq)EogJ&&ELd+?o+%=nj1P?4lw`tY!wsLDvFX#Do|ixTj% zNkErW!1TDVx|})KOPbAp+xp!}rg@t=(_LNCXCcY_+K|pWKm+PMR2+*pbBh%-N?Wr@ z3Fe~E4p&#AYJS;!8Yeuh^cXx=TMi+Ek4yBW$_5f6Wg9Gwl=l0HkLTwI5syJyX(uJ{ z<~_El%XpA+2Z|jGsY=zM!j$037=&jY^8`$fCa%Y&9FJe_jek>Pzo}%?P_3VE($R=t zZ+s`HE8{HrAGg5vrsju<94S9*C9yVTn*93u{?mM~hPB^{-d$)0xTIwNk3d-|KNnVF zmeD_E&QZlm`sk1DYM-moALuKI5tB;z)ZSXq&y5gts%6zlEVQLklpiMUfoeXdYJ742 zyC(PUuA4l7#n%d=6(0&})a%%P2ygDMB>|se*|FTL*rM}rR)d%py3H=NKL8pUcD;*) zogzz52lnmBZHg^lUtgyfXukHb*BuRr7MEPU+EVn1j3HQK$#{zVbJJa4s*{=c`7Pc2 z^2Ms|`N7Q^t~0`Ysf7Q1r5?@l#eagg2j41_3myUHviEXZWmR%(9ZaYK;{^)`Oa?1c zqwKrrzb}cYi{fH6Cf^y<84gkI{m~v)c9Cm(Y5i7ga>k3PRd)TOtk*`sf6Q0d1FSi< zVg#Mm_!29Y0Y#^ofa~wUQMJ^C5Njjg*F8E2)V+iyVEW;T!ic+oc0nH$H+pHx^lY6FPp*dFf z(b+b+F+)R=t2ED> zA_F>o8ep&upI2S569O^cz@fJ9NS;{$Lnwln^X?@?Fl!?oX!$+%B83zi|ICiEx9Ryl z6T#Gk#3RNx(trP2I3zP6tKYk5+{5p--oa=3eB$N#@Mi8e;1C-Hd963IrSAfAIwjEl zHBH~~l(}ET?%VT`Px?l!_&fd2-woog9vXi_R!!9vx;>WUK>AEIZScO{arbJ9GcCDh z!)DH?&S#N`vtCX{>0h2`?|=KycrpB{pgo+~UOA?&`}qIrZVSQIK@$R;h+EZuVJCvXZ9w&w%fb5^pb`wJP_%vGN##l|D}Kt67-)%sdM zE%Xnb-NjM&->Sb4qA+gp6^QeGLDr0@oYrjwJwYi#ffk9(H`cwi>K39c0}Q+d?SJfI zSPZRs?@`K+Cy8{vaBn4%fTM{s8w=?{M!Ij66{P)^j zGWJsWytKZi5^?}vLfJxRg8l95X6|9txZz5L(#akC^ZmNj{Hn} z`~%`(?fqKKUH?;kiwJ7Iv;obqJt~%RNOXiBB=VpV&>np{fux(hZadf2>KV*r<*IIa zpkq``Eeuu@stFNEUHK*_b!yc?P@^_^Fu;HDi?K?i}r^<<+F}3I_}tcz^{#|X_s`jDyI|9J??}7 zpHslW%Hu!AYgK&gy&)Zk-nNw4Ah(C7sgV?Dp8A%aAMsC579sua+EoW1$lR zj`8yy-O-u4-AjWXmiI=sxFQem!OGe6=>DA-N`}#$Z>`mA22r7#MsTYWqx!7pKW(1; zU87rGP$THe`nz^bcAI5+IOis8(^U3P=3WR#U*&`ouMTbz#1RjJu66tf67tlw&X;U3 z5sjTDcbKHfyFa6^GvCGdF6j@KBF8-;G2M!9@a(Wd&)!{jh}N(SM4XVMU7OWMH(!NS zYUP-VS{io3N;t#Xwy%K*y^144rh-X!z0%(UT-?*nV`@2|dUtPnDEqqk^KhdcOs{t2 zVn;OV{z5AMaQnXo=AxDl`VwRa<Yaz?6!CkPsucDj*F~aM+2NyBaarCm}yC?WW*6 zv(15aZFj2?N6kr3iyoe`1^#_0DsNf~Pgl?L?57=ncALK8)x~1+Nw3(Nrl|im5Be3a zMV%p^f?KeBb>x@lUgWNAu4H% z`{9o5w$H1ANC&jauBvN@ItbWlIpF|{v4$5*(nTz&lJlGhQC8vrwf=?Xd_+$57}A$A zt~RtJWcc@rC+1&7-0Ann_D*x{!R>$Hdd;p?42ukMNhTUikUl@ zvkVN8h5`Yv>aD!6phxZAUWrf+kqZ*BNoQN2P{4$NS(jB^;Q59$iE(WpZ4{TuZ-cV5 zmc{yOHFiRIpLn)s#j;N*r^hl=xl&;_*@u5xs|b=f-SmtS^G@xbfG2KE*>{8#qm zIlH&%`U9 z_Yv;${mwxNr^8evU@G4RUiqGR=A8aAEO_lV57)!!v-H2s5j%Hq$a*<4J*$AkKLDJ40xlo;4N)?ko6HLG7a?3=n)|Zu~G-mT9x#;?m z-;OO`I`64L0d?b1j(U@8Av0<*NaNLl7w3v0kv!y5|lW$Q!X!BB! zKeO_EZ7m;GuyX(o$TEhPFa0_wNq&1jJ%UtX_xts!RRd=T5zezu7=5Q`A0Naa)TY{5 zQ=gcFIgp=;fv=|i9hj&j_86?AzmOIy07qWu2iu5%NxDW}``{_V*_y)V}U<(>31`@`Q&5 zyd+-x)CD+Tih%P)^HjmCmTH0qIXF9B!T+xw-s3{yY@PSoZdlqD4Lrwfa91a4Ke0_I&TQ#WsOFM1|I1@)t{w4o!6jJ9M&PQ)JUcYRqn57YpwA`l7`$(h zQVrf+WR=y>{OC1jQmK0ZoX|vhH>km(3vty`;o2o$g@++y@C`?q()00HXiSMOwu4n? zv@q>+uEbVf!*cZP^)eaKzAG%@LKFmqT<8IVEZS7}(VuBX{S6{_K1qj$FP7e-M*Snc z1bmD_fBGcRYzpR933F1vcyUknmOXwy`sisxHsN?t9L6RP?#xtG#K`sg5eiI09Jokd z@^Xl9ev*y7`C#X~6!$5dUI-DIBd=dlmTKt;eYnsDGf-*>cO|JwG+?Hx>54tckaQ1r zMYM_e-Tw%L^aY`qpU=~$!P*e2(LvKPr)_*uRG` zpUd;%+sag<5g+l^nzFvq6HGJgq=14+!-S`scMJ$^N)U{E@cQEKjYhQB#Wn*PKl zeVIMg+p_92UQWok`J z;p~{rK~f=C1bJ@EsTlp*!#K?1zm0fJ(2=ah)f4W2;Y8ykjVzuN^SZB3uZR{e zR~aOtqc|sV=~|^_6q=o?FH4CJ{MY8quPQap??y*19-J;IdCxX6ljwc?SPXwd z@xfF5da$QM;Utw@;2z<(~o4#=PlSC z-V5Iqm@od4Rf;#@UHCyn2vRe~j%>ZZ1|2KnD4SbAQlEUU zn8})-2!yQ%@WoG)0vcSG|5y3$c${rXR17ALWL}TflaZp232DRjJ8e2E1uZ;VH7$am zLe>7De4wv%=R<{mvQKh$%O*L5%V;Wzxf{z>ZvC^ucVYk^w&Zv6rZy$PJamVvyB0)& zkCM*~=Ceew99}*;NU8<7rdUNZ#aU5S4j(5Coc^6+X#b9br;7&w-jBeX^Ygdlnl9V zugu)L!>(A;K=qoFb+*QpPGoOt&EIjQf&f+L``vXC@^`Gd3sgIHa}pu-VsV#tUu2FJ zH#a>$QSW7y5!|$(U6#Eo2)D34;rw0%v%skMX_-1Ff=TPL>A7ukuojMs1683XI{OSN z$$fw5*v!M}L26Q@KA~|*#9gx;V>81e`LR-Z^Qw8Olv>OlO9IxIZ7xs}apeMPU1$Ox+`tNkiJ`S)av=Xrl}@qLZbJn~^E6G@GW_O!$R)-!|) zX>Z1}1bRHMa?QsU(W?eh6I_!#9gN2?HeCM(s-n9Yhj{jewuavNpMEp836EyCuq*ny zDfu8goTX#jS7RfbdHtI5n#YSc%-+=5AYLqIa(J^>#ZF()AP$pUM+J6lM{~c#7JhA2cnNQgxBC4T4pF!)H!oK?kkjZOt6bij zOd%_Hfx!_u;wUvDC?7|wRGNdSki}km*8%1W^yF5C+`m@qTl_Yb9&$!CkwLD|Py3%0 z)yFVO^n2TM7hN;*0fOz#qW|u1aq4?=l+tShbSEg6z5$85PD5IwI~VWDG?WUXvugms zXItLH;4QyPCEqh{8TxMv$J&P>*YDbAUYBtwGkVB1BT4xDM(RAivmbzcIFvVB zhA#FR={Ud-;t_AG`$AfKaBvg6Cc>f|SE&bI_|1Tfw{!%4i{5-QB;2x58#_hlg)W!3 zjN)%0k@#8JXyo~FNs=wjg5|w0*xdT!j=qp0Dh{`4tneYMc2T8wg!)gS zS~LtsM~2osWE<|{#fSq@?BuS&X1QN}`(w;>#lj%huW%1S8dH;VIvS$8^Y(cp=tU=5 zr9ZJ_+l{^KT_tNl9zx`v177XD@kG`fEnWN_=dT@4KdUeB(2yX3*)h01Slha7`R8Qi z!OEPh-%vx$6Ze>Z7eci^+er|Y#~NRYRIqtb?1u(Ty6Bw9hDFXeW-Fg;tOhUMJ5$O_ zu-(r>lB3zKv5|ed$x!iSe)^Xjy~H*X6@y=v?$YSY%niq2G^UTGoyzjJ-b2*kHcunN z&)<|97)$<6hWmEyYz8@}lh2CpYgK;~og{hr@y6 zdJYDZ0|ngZo`Leiu&NDB=~CQw_4jzqol2C3R}GTZU5n5d`63%_GpZzY50g3G`<_v@ z@qGOe!7kINvOH;L2y*JiQgW(J{Ou>%R6cvmXpDuu_s8M8?|5HPJAcb($eCx+{5!?| z2la&QIs`e`qq2*%>qi@A9=3Tj!fqLRj@EIfKaxnS+cK`vk<`U-=Vx}*%Ru)y z9gA&VqWD>^R}PK{%z+BYfkMbCf9_3_IBs^UCB9JOny#tUKve(udAU()S|R|9l2PY) zeeGJM@#u(H4mG=;3*St~@81N3jbwbQW|DGF9;7h5I!Z#F8Ycba|92iZlm%cBw1%=i z2bGH)$_~b$p!RO%R6%Y3Hz~k(U~<;f3CBrMd4-f||47(yc?}zI(wJ z!TkhKWHV3P-n}q5^67%54IN^3NkVP3dkbd@m=06o#90f<^KZDZEd1_ERR~xyhiQ3+ zJv!-Tt3cNLI{w7z*LHa@@P_e3h#))&R+Q&qnb#ypev-;`Dg@76)ugP=BTJZ^gPc1m zd%G85N}iYA4U4CKqYJD%V_ z41!O!U|iT`FcYp`ayw{0Y2LPj*Ye9VtZLXb`|U|R_rgib?LUrF3>}R2F!M1BAmx64 zOHJVR?Nd$de-H8LtM{GV#t$8!3fFgRqCPX*Jb_^A$?of(9H*RDfW|4~=Wu@{U@pt< z9~!4oGn0L_N~Fy!4%Y**AY*GWzWX}O(JO~!Vl9T^(|o{A{E+X?tB6?59GHNa0E_!| zFRm-|todMju-3dS2XA%3$h#G3YM}<%8@$Ig6_9U}dHe%M6q*B!uv_H_xi8d$-dynm zx~>ir#@|vrEd2tS43yZqTJldP7?6TAP^eD%1j)NcUbDY0r_~)}rI|6CrKzdyzBcdHmu-3sQ%!Mf9K3*J7P2 z_c(kc28)z9{Qs@07DR+|vKAHgZ?L-g;W47E*VA%~&`Ilh0eib?&bAJ+IZC&KtHy&P zuE+W>sgNNtViQ{^sh5uGUeS%uh4SQ@-6ubyVM&k&+^i<~HemPr|2;r4zgNWc(0s={ zs+7{dUe~`+EZnnp_NBY{ZeAfhKwawFE=yJZYD z3>+vH*RwEn;FjG%-e~W|tcYjS+Mu{7S~QDyvw})-TXd*>a<~z?+MhT%+<8NN=&g|U zC4Y>+I5xK#Lbdn6TVIpNLIYoiHTXxJ!X9dd-JY#$P{%ariQZW=u=v;9Ub(Bzt2^3O z+9KVRC+BbB!Hndd0$cwA|5>k~tZfKazv?+oXa ziFigoWiTgO#lQqyzkei(M}syEDCeDWB~~%M-P8NGG56dr5;iXjmHw!CFtB5k+{0Zu zYXBc4Vq`w5iPm{3?^@~Wws%c!b*HM8U@dQxFCY^qeV_sBSEmu`H*Jwi)a%s}h)-+_ zabpKr{m4Dr+$(KN9(-dT-{Q#NZ#UT><3<*j3}ic)-Zb z#N$!1J#*9!yyxHsPQYFTQou5o%-D>7CH26J< z{!Asj-=AKCf~asN*5cy6P08_J73!xyXCC|Sf7f4(3gilX5W2i*v@W6ih-<6KADMmY z8T8)U|E}ftPtGfQpXKaXSMx2$Hy9v;ugwqC=RLRMg> zsRru2j`vQnGFj0b0^==ol|OfeCWJb$NYkhb7n$SMX6NVc9kxnIP7PE3zvEqHX}zT@ zaVXJDX4$=_(pSr1(Q+#i^uUokw?29L!$AX*-}P+Hh1jHV2t8x@v7nuB>CC<-cCCL$ zA2C9!^!4=}rNsi)MMeLmx(1Z7SGbq>l->@GhzeDdLe}oGm*e({FQ98JrDM3`C9K^+ zh>&&f{SLZ84@qfot>gQ+5snfh?I-Q%7q_Ov6>5ZNc%RDQW+juHx&ja?51+iTA+&u1 ztjYL!LQZ^nTPh);wa%-KwNF3CIgoH-WT6-~fY!4yRbmRv=dS;YGWF(QK2{safYo#(??QtBMaw>B%>Ip0rK8W#+Hy zHm7`K{oca#UtlTaWi0eFh9?kqng$ln?tWz3XlMEXB^vwu-B>Mw@HonH0}?~poDTA6 zi~mU~zChQSme*mDpI-&>L2)zru$K8>x4VVH#nRs$Wq8=W@_$p z^(uCy!65Aw$~A@$Q`22c!#cWt+0PHA#gnR~fT8nk-VxbLd-?Rf?_O0*O^oOY?c1!)X^;vncn= zuiICF4ZC|HI~^?~LfpF+*ru4%K|F?XUb3q#fy{n+FzQLnE#CT*DIJ~Dzoe4kY<}L+ z3`LXm=dkGjkXMwNTcQ~Jcu~Y+b6mtZYDFaX+D?)$gc<2=o&ER7rY+PzeNm9-cB|3S zKUfeQb8ru^x|ZdkSW+8lUZtH*f)Ql@N0qWB+nygZNYJl+Byt3OMJL$XrhVPPD zpqSQ{)mO>=vj9rP0G-lMi-U`@Cr!xlOOUJRG{%V5@*2_7S}^aeN~-{9!-q!x3K2X4 zvz(gfbA`-+DuB!y)qQ_jVxT65Y#ERGx61Em|0Z(^DdQ`m^vsag+w(s=U3*Hxc) zi@h7ZnAkMhd)|n@&}JdVzk(jdyoNRjxXTHss$xI*s!Yg8mcp5dAtD$)2>dxo%Usgi z0A4o}p`!iz2%gwkH8{^4dX2ed7bs`~RvXzErD*FmB{+Tg0y5pw<72~l$>bb>jz*== z5V)D7Z(i4n0Hu9tW?$Jwco_I}nm(ZM1Y=aB%PeI?iC}%gjv>~377G}SvefpZSgZG& zE>D}qTt2sGn>LV5=2fRQxoq54(S&Cd^gaK;nX8Veh`E!k2#0;Ff8_?IxzeP=rt?h5 zp9WPmfc9VJ6KX$d;y)bY3=tybq(e!Bk@18IwLb@o&gRlJ$&SgukE!; zbLUe&aiC%YXp{_u?dJK1N~h20zti+cOy~sQqUlD>XLiC#5W4fr=aP;lK_knucz!gx zJ#7xzj7Yx>y{-vGEB`pcB}Y{i3nyJZjWmXSEK)yHGS5~g+A411cR~FpZ5v54{CiJJ z>Rw1SiwYbfN8-U1I%P+%^(MUB6e#Bx$Q;s-dvYiUB-g8EZsnJEqmBpM40M|opG_>7 z_HvtBJBP)HJL=^v7TqsJO0*t!`+uhlKd}{*S+b(T?AwyJ3tOn(-rJl%*&z{&f^-#HDwwtBNP1`q&(V36qsgWmDg{T}_e~k$ z%80muBEn%Ozv}sIM5GU8Mq|-a+jiSoc4onL^fHUq@kJT4bCpZ5g z9LEixq(_$A`u6-ObMm}$P1|pA0EmLS*P%=qQLPn~NMD0zp;qBRl&#j)1K(xCd`__H ztn#fq^g;%eQ3Jl6Vt*ce?#<)kz?Crn)8{jIW(~O2+SyIA9!GN4)JO-N0a=ky-M$}2 zj7i%Fwe56u!{9}=cz1>Ln8E4?&WQ^JT-~I)MIYv(}U2NLk2Tl`iU z@K(hEFT>|G4K#)U!)%T=O-7Q10n0Lk{7kM3cZG8mZ+VR2Zq`>ps$sOMGWHEo z&c4P50b{tTilKvfIxCfd4aad@i_sAB=CLn@=aG9$boc@xDzHD#gWP4QH20n>rXOFF zr1LRfc8oq1!vgB})JHmyl*+LZT2QC^iJH6XY#We%<<#!&p{@C27;u5y>Oru563N+nVwXvs@AOD5Ex~ zd-_>S(2K{j>|{s-`a-0ZtFcpA-m@wr4=eHjLV+CJJ_h@}w0yVYll6`LAWxUBu-el8 zlV~BS%dpvVQ<=K(UIEZz{W}YURp2zYHSy>d(6iPAs)^S|90|C;A{sc})XwRJn4PoX zb_u;wh11{K58E8<0(M7V7WhPH-|rJ^QXKpKt~HwxA;O4=ofmg@MTbk0Ebzbvy2S%m z&(^P-&en2bPfkotnQAjul)ADTZAjhs*7|^_3nMNp6jp z!P?{*3im{(A~Dx3zhe8|h+evkI#Xbbpl}lB?HE~CuNz-$!?2eNG!GXe(-S+FjE9tb zHc!U$YqyT&Im6qDUN3X@{Tfu5sEy##NZz^bef(m2=)a{-l8(z8_%*}be-qJzb)0F9 zWKfSb<5&?vR*xC!NI1PDfB7fvL0 zeO(4jH^UCfKrTs`vUeR@9V*vFESX_-(b>84&9U>%7IdtFu2zx-*QC=@%n%x0$mUBz zGW%md@N-=q!R&}o^C>)w5LLeal|KEdUZhD5{ZU1~+hdn%3jrPujJL!RB8+YxA%YBM-yC94u|zf(EU`Q&Sr-)ael9VTwmds7RlaHG!= zG_J~&V2*}ViUy2=h*t$Sv|*{G+*Mn_m|?=YC4iyx`k?ii>qh*JD6~Nb<*ua@l34g0 zG1FB&Qa=+-(KYu7nrqH8bYYKvxEpE{zBd&ftlamO;nB2EGDViJ$xw3OBMz5w_xyg* z2}gJ74Oq5n*7lPADn7jXA+#ozwDWBMfQ2N?F({wYHs>und3PA`w&)2l`QxGVWW^L9 z_4e`N_1Z(}R}Wmq6Y<;msSX&T`nwn@GaxSMt^Y_1fyK%lY zeAy=&nJw&ie(_1H--h&FsP(?V9J&9Lsdj8??mNE3u2#qbXXRWgDSJ9JUVoU~p|8vn zxIo}YrmCq1%3B#~uVPmJ;#rVS%d`lSSJvcYm*>vn2a@ zJtFVi`n=7*F0;c@3O)iZ&7JMzZvEWeU}tPw^xrJ#ze_WU-dFb_4P+3%$D|WC|2Z?b zZR6J^un5{8r!~i7KFgN`t~5}!9K`18#bV&{C3y--lCZhrb59^G{cX*`&#yZ4P`C12c; ze{pAfe=iJ2r39`-WM4uoN^*oHDju6H(@?&92$^2yK0}8)2Eq1SU ziUAu9vTvjVRCN;|mvzGu>hsbnnLRD5&RXY_m^C$-l%wh=psg};G?59#-=~+yIj@ti zl_29`*!qlS8at&kX;D$>lnc7^;A_b?}*G2?wk?F&H@UN9WZU=hYsVIOMi?18z97S5Q5z`u(S) zBb7hXP@wrVKK#p!=JFeJMq+Cmp^WX)mhxM3tG4wBt_5l-(uueEX5V2RM(2^A#dBWB zn%@7Zl);~E0v60JQPN4XHF*iG6H82|Xh>C_@a-iEbF&2Y>ThV@GUmns(YXN@gt;L? zC(xMPm^H#QuI&6rVRazTf$vL(>Vx0`1tZ6EBv7{nJA7 zd7&tYAn)5*=#%{!LHEcOLJ}L#?(a1xzozpqC4w#;HIjZWrPGUQ8S9oPGIidZq+DnJ zZ|4gcoUO68?X6F^|54$;_I4y4KVZJqjj5by7JtLln*4KX&mpx4_-XFb3(DMn0~dE~ zR~a6PSZqi164v&LJ?%66&MUXFJ0Z<@yTe;w$F9>iCNrP<@LgB)f?_2Suh8j++L7+c zb>rmW??CbCizGa_VuuKXh|WzNZJXEN79boeq)MMo+t5=5U(Hjygxl|L^HY6I9sst!CTk@RA~FenH0?8Iv=VMO|G$$Vm?3v zIqtBF20@8U?Hg}W z#5D0{j)6+PaFqTgNt9R+K0v9}lk;5dc&A^F9;j=}Rol`WMMy0Kf(RHPA52!?4~g3@ z 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 Date: Fri, 7 Aug 2015 04:13:09 -0500 Subject: [PATCH 264/377] Push fixes --- .../src/mineplex/hub/bonuses/BonusManager.java | 4 ++++ .../src/mineplex/hub/bonuses/gui/buttons/VoteButton.java | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index 5acba755a..d02890ff0 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -141,6 +141,7 @@ public class BonusManager extends MiniClientPlugin implements I { incrementDailyStreak(player); awardBonus(player, amount); + updateCreeperVisual(player); } result.accept(r); @@ -177,7 +178,10 @@ public class BonusManager extends MiniClientPlugin implements I public void accept(Boolean aBoolean) { if (aBoolean) + { awardBonus(player, getRankBonusAmount(player)); + updateCreeperVisual(player); + } result.accept(aBoolean); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java index 164c55936..0552203d7 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java @@ -58,7 +58,8 @@ public class VoteButton implements GuiItem, Listener { { //TODO get url from db _url = "http://minecraftservers.org/vote/121070"; - + + setItem(); Bukkit.getPluginManager().registerEvents(this, getPlugin()); } @@ -68,7 +69,6 @@ public class VoteButton implements GuiItem, Listener { HandlerList.unregisterAll(this); } - @Override public void click(ClickType clickType) { @@ -113,7 +113,7 @@ public class VoteButton implements GuiItem, Listener { if (isAvailable()) { - material = Material.CHEST; + material = Material.JUKEBOX; itemName = C.cGreen + C.Bold + "Vote Bonus"; lore.add(" "); @@ -165,6 +165,8 @@ public class VoteButton implements GuiItem, Listener { { if (_url == null) return false; + System.out.println(timeLeft()); + return (timeLeft() <= 0); } From f76d9b0d37f021374ed3880fa117cb47597888c2 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Fri, 7 Aug 2015 04:20:54 -0500 Subject: [PATCH 265/377] Replace Consumers with Callbacks --- .../mineplex/hub/bonuses/BonusManager.java | 25 +++++++------ .../mineplex/hub/bonuses/BonusRepository.java | 35 +++++++++---------- .../bonuses/gui/buttons/DailyBonusButton.java | 7 ++-- .../bonuses/gui/buttons/RankBonusButton.java | 8 ++--- 4 files changed, 34 insertions(+), 41 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index d02890ff0..bfd1bca5a 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -4,7 +4,6 @@ import java.sql.Date; import java.sql.Timestamp; import java.util.Calendar; import java.util.TimeZone; -import java.util.function.Consumer; import mineplex.core.MiniClientPlugin; import mineplex.core.account.CoreClient; @@ -127,15 +126,15 @@ public class BonusManager extends MiniClientPlugin implements I public static final long TIME_BETWEEN_BONUSES = 1000 * 60 * 60 * 20; public static final long STREAK_RESET_TIME = 1000 * 60 * 60 * 12; - public void attemptDailyBonus(final Player player, final BonusAmount amount, final Consumer result) + public void attemptDailyBonus(final Player player, final BonusAmount amount, final Callback result) { if (timeTillDailyBonus(player) > 0) - result.accept(false); + result.run(false); - getRepository().attemptDailyBonus(player, new Consumer() + getRepository().attemptDailyBonus(player, new Callback() { @Override - public void accept(Boolean r) + public void run(Boolean r) { if (r) { @@ -144,7 +143,7 @@ public class BonusManager extends MiniClientPlugin implements I updateCreeperVisual(player); } - result.accept(r); + result.run(r); } }); } @@ -168,14 +167,14 @@ public class BonusManager extends MiniClientPlugin implements I } // RANK BONUS - public void attemptRankBonus(final Player player, final Consumer result) + public void attemptRankBonus(final Player player, final Callback result) { if (timeTillRankBonus(player) > 0) - result.accept(false); - getRepository().attemptRankBonus(player, new Consumer() + result.run(false); + getRepository().attemptRankBonus(player, new Callback() { @Override - public void accept(Boolean aBoolean) + public void run(Boolean aBoolean) { if (aBoolean) { @@ -183,7 +182,7 @@ public class BonusManager extends MiniClientPlugin implements I updateCreeperVisual(player); } - result.accept(aBoolean); + result.run(aBoolean); } }); } @@ -305,10 +304,10 @@ public class BonusManager extends MiniClientPlugin implements I //VOTE - public void atteptVoteBonus(final Player player, final Consumer result) + public void atteptVoteBonus(final Player player, final Callback result) { if (timeTillRankBonus(player) > 0) - result.accept(false); + result.run(false); getRepository().attemptRankBonus(player, result); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java index 0ee538f8b..070e4aec0 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java @@ -6,11 +6,8 @@ import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; -import java.util.function.Consumer; import mineplex.core.common.util.Callback; -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilPlayer; import mineplex.core.database.DBPool; import mineplex.core.database.RepositoryBase; import mineplex.core.database.ResultSetCallable; @@ -60,10 +57,10 @@ public class BonusRepository extends RepositoryBase return record; } - public void attemptDailyBonus(final Player player, final Consumer result) + public void attemptDailyBonus(final Player player, final Callback result) { if (!Recharge.Instance.usable(player, "AttemptDailyBonus")) { - result.accept(false); + result.run(false); return; } final int accountId = _manager.getClientManager().Get(player).getAccountId(); @@ -105,13 +102,13 @@ public class BonusRepository extends RepositoryBase if (pass) { _manager.Get(player).setDailyTime(new Timestamp(BonusManager.getSqlTime())); - result.accept(true); + result.run(true); } else { Recharge.Instance.use(player, "AttemptDailyBonus", 1000 * 10, false, false); _manager.Get(player).setDailyTime(timeStamp); - result.accept(false); + result.run(false); } } }); @@ -120,23 +117,23 @@ public class BonusRepository extends RepositoryBase { Recharge.Instance.use(player, "AttemptDailyBonus", 1000 * 30, false, false); e.printStackTrace(); - result.accept(false); + result.run(false); } } }); } - public void attemptRankBonus(final Player player, final Consumer result) + public void attemptRankBonus(final Player player, final Callback result) { if (!Recharge.Instance.usable(player, "AttemptRankBonus")) { - result.accept(false); + result.run(false); return; } final int accountId = _manager.getClientManager().Get(player).getAccountId(); final int coins = _manager.getRankBonusAmount(player).getCoins(); if (coins == 0/* && gems == 0 */) { - result.accept(false); + result.run(false); return; } @@ -171,29 +168,29 @@ public class BonusRepository extends RepositoryBase if (pass) { - result.accept(true); + result.run(true); } else { Recharge.Instance.use(player, "AttemptRankBonus", 1000 * 10, false, false); - result.accept(false); + result.run(false); } } }); } catch (Exception e) { Recharge.Instance.use(player, "AttemptRankBonus", 1000 * 30, false, false); e.printStackTrace(); - result.accept(false); + result.run(false); } } }); } - public void voteBonus(final Player player, final Consumer result) + public void voteBonus(final Player player, final Callback result) { if (!Recharge.Instance.usable(player, "AttemptVoteBonus")) { - result.accept(false); + result.run(false); return; } final int accountId = _manager.getClientManager().Get(player).getAccountId(); @@ -202,7 +199,7 @@ public class BonusRepository extends RepositoryBase final int gems = 0; if (coins == 0/* && gems == 0 */) { - result.accept(false); + result.run(false); return; } @@ -237,13 +234,13 @@ public class BonusRepository extends RepositoryBase _donationManager.RewardCoins(null, "Vote bonus", player.getName(), accountId, coins); _donationManager.RewardGems(null, "Vote bonus", player.getName(), player.getUniqueId(), gems); - result.accept(true); + result.run(true); } }); } catch (Exception e) { e.printStackTrace(); - result.accept(false); + result.run(false); } } }); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java index 2ba7a359a..4554c8a58 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java @@ -1,9 +1,9 @@ package mineplex.hub.bonuses.gui.buttons; import java.util.ArrayList; -import java.util.function.Consumer; import mineplex.core.common.util.C; +import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilTime; @@ -72,10 +72,9 @@ public class DailyBonusButton implements GuiItem, Listener _item = ItemStackFactory.Instance.CreateStack(Material.LAPIS_BLOCK, (byte)0, 1, ChatColor.BLUE + "Processing..."); refreshItem(); new LoadingWindow(getPlugin(), getPlayer(), 6*9); - _bonusManager.attemptDailyBonus(getPlayer(), _bonusManager.getDailyBonusAmount(_player), new Consumer() { - @SuppressWarnings("deprecation") + _bonusManager.attemptDailyBonus(getPlayer(), _bonusManager.getDailyBonusAmount(_player), new Callback() { @Override - public void accept(Boolean t) + public void run(Boolean t) { if (t) { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java index e5007bd53..3189ec5d5 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java @@ -1,9 +1,9 @@ package mineplex.hub.bonuses.gui.buttons; import java.util.ArrayList; -import java.util.function.Consumer; import mineplex.core.common.util.C; +import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilTime; @@ -17,7 +17,6 @@ import mineplex.core.shop.item.ShopItem; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.hub.bonuses.BonusAmount; -import mineplex.hub.bonuses.BonusClientData; import mineplex.hub.bonuses.BonusManager; import org.bukkit.Bukkit; @@ -83,11 +82,10 @@ public class RankBonusButton implements GuiItem, Listener { _item = ItemStackFactory.Instance.CreateStack(Material.LAPIS_BLOCK, (byte)0, 1, ChatColor.BLUE + "Processing..."); refreshItem(); new LoadingWindow(getPlugin(), getPlayer(), 6*9); - _bonusManager.attemptRankBonus(getPlayer(), new Consumer() + _bonusManager.attemptRankBonus(getPlayer(), new Callback() { - @SuppressWarnings("deprecation") @Override - public void accept(Boolean t) + public void run(Boolean t) { setItem(); From b22706e649f38036544b7130e327ab3f658759b5 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Fri, 7 Aug 2015 21:45:38 +0200 Subject: [PATCH 266/377] hub update part 1 --- .../mineplex/core/common/util/UtilAlg.java | 2 +- .../core/blockrestore/BlockRestoreData.java | 2 + .../mineplex/core/gadget/GadgetManager.java | 38 +- .../core/gadget/gadgets/ItemPaintbrush.java | 179 +++++++ .../core/gadget/gadgets/MorphSlime.java | 103 ++++ .../core/gadget/gadgets/OutfitRaveSuit.java | 10 +- .../core/gadget/gadgets/OutfitSpaceSuit.java | 3 +- .../core/gadget/gadgets/OutfitTeam.java | 144 ++++++ .../Mineplex.Hub/src/mineplex/hub/Hub.java | 1 + .../src/mineplex/hub/HubManager.java | 6 +- .../mineplex/hub/modules/ParkourManager.java | 11 - .../mineplex/hub/modules/SoccerManager.java | 472 ++++++++++++++++++ .../mineplex/hub/modules/WorldManager.java | 5 +- .../src/mineplex/mapparser/MapParser.java | 9 + .../src/nautilus/game/arcade/Arcade.java | 2 +- 15 files changed, 958 insertions(+), 29 deletions(-) create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/MorphSlime.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java index d686faa2d..56a9b917e 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java @@ -26,7 +26,7 @@ public class UtilAlg public static Location getMidpoint(Location a, Location b) { - return a.add(b.subtract(a).multiply(0.5)); + return a.clone().add(b.clone().subtract(a.clone()).multiply(0.5)); } public static Vector getTrajectory(Entity from, Entity to) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreData.java b/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreData.java index 1fa27e84d..fda3caaef 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreData.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/blockrestore/BlockRestoreData.java @@ -96,6 +96,8 @@ public class BlockRestoreData if (_toID == 78) _toData = (byte)Math.min(7, _toData + addData); else _toData = addData; } + else + _toData = addData; _toID = toID; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java index bc7f2ac7d..a5af05afb 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java @@ -18,6 +18,7 @@ import org.bukkit.plugin.java.JavaPlugin; import mineplex.core.MiniPlugin; import mineplex.core.account.CoreClientManager; +import mineplex.core.achievement.AchievementManager; import mineplex.core.blockrestore.BlockRestore; import mineplex.core.common.Rank; import mineplex.core.common.util.NautHashMap; @@ -52,6 +53,7 @@ public class GadgetManager extends MiniPlugin private DisguiseManager _disguiseManager; private BlockRestore _blockRestore; private ProjectileManager _projectileManager; + private AchievementManager _achievementManager; private NautHashMap> _gadgets; @@ -63,7 +65,7 @@ public class GadgetManager extends MiniPlugin public GadgetManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, MountManager mountManager, PetManager petManager, PreferencesManager preferencesManager, - DisguiseManager disguiseManager, BlockRestore blockRestore, ProjectileManager projectileManager) + DisguiseManager disguiseManager, BlockRestore blockRestore, ProjectileManager projectileManager, AchievementManager achievementManager) { super("Gadget Manager", plugin); @@ -75,26 +77,25 @@ public class GadgetManager extends MiniPlugin _disguiseManager = disguiseManager; _blockRestore = blockRestore; _projectileManager = projectileManager; - + _achievementManager = achievementManager; + CreateGadgets(); } private void CreateGadgets() { _gadgets = new NautHashMap>(); - + // Items addGadget(new ItemEtherealPearl(this)); addGadget(new ItemFirework(this)); addGadget(new ItemTNT(this)); addGadget(new ItemMelonLauncher(this)); addGadget(new ItemFleshHook(this)); - addGadget(new ItemPaintballGun(this)); + //addGadget(new ItemPaintballGun(this)); addGadget(new ItemBatGun(this)); addGadget(new ItemCoinBomb(this)); - //addGadget(new ItemGemBomb(this)); - //addGadget(new ItemFootball(this)); - //addGadget(new ItemDuelingSword(this)); + addGadget(new ItemPaintbrush(this)); // Costume addGadget(new OutfitRaveSuit(this, "Rave Hat", -2, ArmorSlot.Helmet, Material.LEATHER_HELMET, (byte)0)); @@ -107,6 +108,11 @@ public class GadgetManager extends MiniPlugin addGadget(new OutfitSpaceSuit(this, "Space Pants", -2, ArmorSlot.Legs, Material.GOLD_LEGGINGS, (byte)0)); addGadget(new OutfitSpaceSuit(this, "Space Boots", -2, ArmorSlot.Boots, Material.GOLD_BOOTS, (byte)0)); + addGadget(new OutfitTeam(this, "Team Helmet", -1, ArmorSlot.Helmet, Material.LEATHER_HELMET, (byte)0)); + addGadget(new OutfitTeam(this, "Team Shirt", -1, ArmorSlot.Chest, Material.LEATHER_CHESTPLATE, (byte)0)); + addGadget(new OutfitTeam(this, "Team Pants", -1, ArmorSlot.Legs, Material.LEATHER_LEGGINGS, (byte)0)); + addGadget(new OutfitTeam(this, "Team Boots", -1, ArmorSlot.Boots, Material.LEATHER_BOOTS, (byte)0)); + // Morphs addGadget(new MorphVillager(this)); addGadget(new MorphCow(this)); @@ -114,14 +120,13 @@ public class GadgetManager extends MiniPlugin addGadget(new MorphBlock(this)); addGadget(new MorphEnderman(this)); addGadget(new MorphBat(this)); - //addGadget(new MorphNotch(this)); addGadget(new MorphPumpkinKing(this)); addGadget(new MorphPig(this)); addGadget(new MorphCreeper(this)); addGadget(new MorphBlaze(this)); - //addGadget(new MorphGeno(this)); addGadget(new MorphWither(this)); addGadget(new MorphBunny(this)); + addGadget(new MorphSlime(this, _achievementManager)); // Particles addGadget(new ParticleFoot(this)); @@ -146,7 +151,6 @@ public class GadgetManager extends MiniPlugin addGadget(new MusicGadget(this, "Stal Disc", new String[] {""}, -2, 2263, 150000)); addGadget(new MusicGadget(this, "Strad Disc", new String[] {""}, -2, 2264, 188000)); addGadget(new MusicGadget(this, "Ward Disc", new String[] {""}, -2, 2265, 251000)); - //addGadget(new MusicGadget(this, "11 Disc", new String[] {""}, -2, 2266, 71000)); addGadget(new MusicGadget(this, "Wait Disc", new String[] {""}, -2, 2267, 238000)); } @@ -274,6 +278,20 @@ public class GadgetManager extends MiniPlugin } } } + + public void DisableAll(Player player, List dontDisable) + { + for (GadgetType gadgetType : _gadgets.keySet()) + { + for (Gadget gadget : _gadgets.get(gadgetType)) + { + if (dontDisable.contains(gadget.GetName())) + continue; + + gadget.Disable(player); + } + } + } public PetManager getPetManager() { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java new file mode 100644 index 000000000..92c03c83c --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java @@ -0,0 +1,179 @@ +package mineplex.core.gadget.gadgets; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractEvent; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilGear; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.types.ItemGadget; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + +public class ItemPaintbrush extends ItemGadget +{ + private NautHashMap _brushColor = new NautHashMap(); + private NautHashMap _brushPrevious = new NautHashMap(); + + public ItemPaintbrush(GadgetManager manager) + { + super(manager, "Paintbrush", new String[] + { + C.cWhite + "Unleash your inner creativity!", + }, + -2, + Material.WOOD_SWORD, (byte)0, + 200, new Ammo("Paint", "100 Pixels", Material.INK_SACK, (byte)0, new String[] { C.cWhite + "100 Pixels worth of Paint!" }, 500, 100)); + } + + @Override + public void ApplyItem(Player player, boolean inform) + { + Manager.RemoveItem(player); + + _active.add(player); + + List itemLore = new ArrayList(); + itemLore.addAll(Arrays.asList(GetDescription())); + + player.getInventory().setItem(Manager.getActiveItemSlot(), ItemStackFactory.Instance.CreateStack(GetDisplayMaterial(), GetDisplayData(), 1, GetName())); + + if (inform) + UtilPlayer.message(player, F.main("Gadget", "You equipped " + F.elem(GetName()) + ".")); + } + + @Override + @EventHandler + public void Activate(PlayerInteractEvent event) + { + + } + + @Override + public void ActivateCustom(Player player) + { + + } + + @Override + public void EnableCustom(Player player) + { + ApplyItem(player, true); + + _brushColor.put(player.getName(), (byte)15); + } + + + @Override + public void DisableCustom(Player player) + { + _brushColor.remove(player.getName()); + _brushPrevious.remove(player.getName()); + + RemoveItem(player); + } + + @EventHandler + public void colorSelect(PlayerInteractEvent event) + { + if (!IsActive(event.getPlayer())) + return; + + if (!UtilEvent.isAction(event, ActionType.L)) + return; + + Player player = event.getPlayer(); + + Block block = player.getTargetBlock(null, 100); + if (block == null || block.getType() != Material.STAINED_CLAY) + return; + + _brushColor.put(player.getName(), block.getData()); + + player.playSound(player.getLocation(), Sound.ORB_PICKUP, 2f, 1f); + } + + @EventHandler + public void paint(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + for (Player player : GetActive()) + { + if (!UtilGear.isMat(player.getItemInHand(), Material.WOOD_SWORD)) + continue; + + if (!player.isBlocking()) + { + _brushPrevious.remove(player.getName()); + continue; + } + + Block block = player.getTargetBlock(null, 100); + if (block == null || block.getType() != Material.WOOL) + continue; + + //Color + Manager.getBlockRestore().Add(block, 35, _brushColor.get(player.getName()), 30000); + + //Join Dots + if (_brushPrevious.containsKey(player.getName())) + { + while (UtilMath.offset(_brushPrevious.get(player.getName()), block.getLocation().add(0.5, 0.5, 0.5)) > 0.5) + { + _brushPrevious.get(player.getName()).add(UtilAlg.getTrajectory(_brushPrevious.get(player.getName()), block.getLocation().add(0.5, 0.5, 0.5)).multiply(0.5)); + + Block fixBlock = _brushPrevious.get(player.getName()).getBlock(); + + if (fixBlock.getType() != Material.WOOL) + continue; + + Manager.getBlockRestore().Add(fixBlock, 35, _brushColor.get(player.getName()), 30000); + } + } + + player.getWorld().playSound(player.getLocation(), Sound.FIZZ, 0.25f, 2f); + + + _brushPrevious.put(player.getName(), block.getLocation().add(0.5, 0.5, 0.5)); + } + } + + //XXX TODO ENABLE + + @EventHandler + public void enableInteract(PlayerInteractEvent event) + { + if (IsActive(event.getPlayer())) + return; + + if (!UtilEvent.isAction(event, ActionType.L)) + return; + + Player player = event.getPlayer(); + + Block block = player.getTargetBlock(null, 100); + if (block == null || block.getType() != Material.STAINED_CLAY) + return; + + Enable(event.getPlayer()); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/MorphSlime.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/MorphSlime.java new file mode 100644 index 000000000..12f9a3eca --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/MorphSlime.java @@ -0,0 +1,103 @@ +package mineplex.core.gadget.gadgets; + +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.*; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.achievement.AchievementManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.core.disguise.disguises.DisguiseSlime; +import mineplex.core.recharge.Recharge; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.types.MorphGadget; + +public class MorphSlime extends MorphGadget +{ + private CoreClientManager _clientManager; + private AchievementManager _achievementManager; + + public MorphSlime(GadgetManager manager, AchievementManager achievements) + { + super(manager, "Big Larry Morph", new String[] + { + C.cWhite + "Become a slime like Big Larry!", + " ", + C.cYellow + "Left Click" + C.cGray + " to use " + C.cGreen + "Bounce", + " ", + C.cWhite + "+1 Slime Size for every 10 Mineplex Levels", + }, + 80000, + Material.SLIME_BALL, (byte)0); + + _achievementManager = achievements; + _clientManager = manager.getClientManager(); + } + + @Override + public void EnableCustom(final Player player) + { + this.ApplyArmor(player); + + DisguiseSlime disguise = new DisguiseSlime(player); + disguise.setName(player.getName(), Manager.getClientManager().Get(player).GetRank()); + disguise.setCustomNameVisible(true); + + int size = 1 + (_achievementManager.getMineplexLevelNumber(player, _clientManager.Get(player).GetRank())) / 8; + + if (size < 1) + size = 1; + + if (size > 12) + size = 12; + + disguise.SetSize(size); + + Manager.getDisguiseManager().disguise(disguise); + } + + @Override + public void DisableCustom(Player player) + { + this.RemoveArmor(player); + Manager.getDisguiseManager().undisguise(player); + } + + @EventHandler + public void skill(PlayerInteractEvent event) + { + Player player = event.getPlayer(); + + if (!IsActive(player)) + return; + + if (!UtilEvent.isAction(event, ActionType.L)) + return; + + if (!UtilEnt.isGrounded(player)) + return; + + if (!Recharge.Instance.use(player, GetName(), 1000, false, false)) + return; + + player.getWorld().playSound(player.getLocation(), Sound.SLIME_ATTACK, 1f, 1f); + + //Size + int size = 1 + (_achievementManager.getMineplexLevelNumber(player, _clientManager.Get(player).GetRank())) / 8; + + if (size < 1) + size = 1; + + if (size > 12) + size = 12; + + //Vel + UtilAction.velocity(player, 1 + (size * 0.2), 0, 10, true); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitRaveSuit.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitRaveSuit.java index 265ad7952..2834498a4 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitRaveSuit.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitRaveSuit.java @@ -2,11 +2,13 @@ package mineplex.core.gadget.gadgets; import java.util.HashMap; +import org.bukkit.ChatColor; import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.LeatherArmorMeta; @@ -25,7 +27,7 @@ public class OutfitRaveSuit extends OutfitGadget public OutfitRaveSuit(GadgetManager manager, String name, int cost, ArmorSlot slot, Material mat, byte data) { - super(manager, name, new String[] {"Wear the complete set for","awesome bonus effects!", "Bonus coming soon..."}, cost, slot, mat, data); + super(manager, name, new String[] {ChatColor.RESET + "Wear the complete set for",ChatColor.RESET + "awesome bonus effects!", ChatColor.RESET + "Bonus coming soon..."}, cost, slot, mat, data); } @Override @@ -147,4 +149,10 @@ public class OutfitRaveSuit extends OutfitGadget stack.setItemMeta(meta); } } + + @EventHandler + public void playerQuit(PlayerQuitEvent event) + { + _colorPhase.remove(event.getPlayer().getName()); + } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitSpaceSuit.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitSpaceSuit.java index f69ccf7eb..fe25b7843 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitSpaceSuit.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitSpaceSuit.java @@ -1,5 +1,6 @@ package mineplex.core.gadget.gadgets; +import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -11,7 +12,7 @@ public class OutfitSpaceSuit extends OutfitGadget public OutfitSpaceSuit(GadgetManager manager, String name, int cost, ArmorSlot slot, Material mat, byte data) { - super(manager, name, new String[] {"Wear the complete set for","awesome bonus effects!", "Bonus coming soon..."}, cost, slot, mat, data); + super(manager, name, new String[] {ChatColor.RESET + "Wear the complete set for",ChatColor.RESET + "awesome bonus effects!", ChatColor.RESET + "Bonus coming soon..."}, cost, slot, mat, data); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java new file mode 100644 index 000000000..10102b0e9 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java @@ -0,0 +1,144 @@ +package mineplex.core.gadget.gadgets; + +import java.util.HashMap; + +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.LeatherArmorMeta; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilGear; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.types.OutfitGadget; + +public class OutfitTeam extends OutfitGadget +{ + private HashMap _colorSetting = new HashMap(); + + public OutfitTeam(GadgetManager manager, String name, + int cost, ArmorSlot slot, Material mat, byte data) + { + super(manager, name, new String[] {ChatColor.RESET + "Team up with other players!", ChatColor.RESET + "Equip by typing;", ChatColor.RESET + C.cGreen + "/team "}, cost, slot, mat, data); + } + + @Override + public void EnableCustom(Player player) + { + ApplyArmor(player); + colorArmor(player); + } + + @Override + public void DisableCustom(Player player) + { + RemoveArmor(player); + } + + @EventHandler(priority=EventPriority.LOWEST) + public void updateColor(PlayerCommandPreprocessEvent event) + { + Player player = event.getPlayer(); + + if (!event.getMessage().toLowerCase().startsWith("/team ")) + return; + + event.setCancelled(true); + + String[] args = event.getMessage().toLowerCase().split(" "); + + if (args.length < 2) + return; + + //Color + if (args[1].equals("red")) + _colorSetting.put(player.getName(), Color.RED); + else if (args[1].equals("yellow")) + _colorSetting.put(player.getName(), Color.YELLOW); + else if (args[1].equals("green")) + _colorSetting.put(player.getName(), Color.GREEN); + else if (args[1].equals("blue")) + _colorSetting.put(player.getName(), Color.AQUA); + + colorArmor(player); + + Enable(player); + } + + private void colorArmor(Player player) + { + if (!_colorSetting.containsKey(player.getName())) + return; + + //Get Item + ItemStack stack; + + if (GetSlot() == ArmorSlot.Helmet) + { + stack = player.getInventory().getHelmet(); + + if (!UtilGear.isMat(stack, GetDisplayMaterial())) + { + Disable(player); + return; + } + } + else if (GetSlot() == ArmorSlot.Chest) + { + stack = player.getInventory().getChestplate(); + + if (!UtilGear.isMat(stack, GetDisplayMaterial())) + { + Disable(player); + return; + } + } + else if (GetSlot() == ArmorSlot.Legs) + { + stack = player.getInventory().getLeggings(); + + if (!UtilGear.isMat(stack, GetDisplayMaterial())) + { + Disable(player); + return; + } + } + else if (GetSlot() == ArmorSlot.Boots) + { + stack = player.getInventory().getBoots(); + + if (!UtilGear.isMat(stack, GetDisplayMaterial())) + { + Disable(player); + return; + } + } + else + { + return; + } + + + //Set! + LeatherArmorMeta meta = (LeatherArmorMeta)stack.getItemMeta(); + meta.setColor(_colorSetting.get(player.getName())); + stack.setItemMeta(meta); + } + + @EventHandler + public void playerQuit(PlayerQuitEvent event) + { + _colorSetting.remove(event.getPlayer().getName()); + } + + public Color getTeamColor(Player player) + { + return _colorSetting.get(player.getName()); + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java index 0873db91b..60dcb8d55 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java @@ -159,6 +159,7 @@ public class Hub extends JavaPlugin implements IRelation ItemFactory itemFactory = new ItemFactory(this, blockRestore, conditionManager, damage, energy, fire, throwManager, webServerAddress); SkillFactory skillManager = new SkillFactory(this, damage, this, combatManager, conditionManager, throwManager, disguiseManager, blockRestore, fire, new Movement(this), teleport, energy, webServerAddress); ClassManager classManager = new ClassManager(this, clientManager, donationManager, skillManager, itemFactory, webServerAddress); + classManager.setEnabled(false); ClassShopManager shopManager = new ClassShopManager(this, classManager, skillManager, itemFactory, achievementManager, clientManager); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index 2cf2e5b53..9c3042ee5 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -91,6 +91,7 @@ import mineplex.hub.modules.HubVisibilityManager; import mineplex.hub.modules.JumpManager; import mineplex.hub.modules.NewsManager; import mineplex.hub.modules.ParkourManager; +import mineplex.hub.modules.SoccerManager; import mineplex.hub.modules.TextManager; import mineplex.hub.modules.WorldManager; import mineplex.hub.poll.PollManager; @@ -168,16 +169,19 @@ public class HubManager extends MiniClientPlugin new WorldManager(this); new JumpManager(this); //new TournamentInviter(this); + _news = new NewsManager(this); _mountManager = new MountManager(_plugin, clientManager, donationManager, blockRestore, _disguiseManager); _inventoryManager = new InventoryManager(plugin, clientManager); new BenefitManager(plugin, clientManager, _inventoryManager); - _gadgetManager = new GadgetManager(_plugin, clientManager, donationManager, _inventoryManager, _mountManager, petManager, preferences, disguiseManager, blockRestore, new ProjectileManager(plugin)); + _gadgetManager = new GadgetManager(_plugin, clientManager, donationManager, _inventoryManager, _mountManager, petManager, preferences, disguiseManager, blockRestore, new ProjectileManager(plugin), achievementManager); _treasureManager = new TreasureManager(_plugin, clientManager, donationManager, _inventoryManager, petManager, _blockRestore, hologramManager); new CosmeticManager(_plugin, clientManager, donationManager, _inventoryManager, _gadgetManager, _mountManager, petManager, _treasureManager); + new SoccerManager(this, _gadgetManager); + _petManager = petManager; _partyManager = partyManager; _preferences = preferences; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/ParkourManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/ParkourManager.java index 8110f0cef..76c1b72d0 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/ParkourManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/ParkourManager.java @@ -470,15 +470,4 @@ public class ParkourManager extends MiniPlugin } } } - -// @EventHandler -// public void snakeUpdate(UpdateEvent event) -// { -// if (event.getType() != UpdateType.FASTER) -// return; -// -// for (ParkourData parkour : _parkour) -// if (parkour instanceof ParkourSnake) -// ((ParkourSnake)parkour).Update(); -// } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java new file mode 100644 index 000000000..9af84b8fa --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -0,0 +1,472 @@ +package mineplex.hub.modules; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.WeakHashMap; + +import org.bukkit.Bukkit; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Bat; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.entity.Slime; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.inventory.InventoryOpenEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilTime; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.event.GadgetActivateEvent; +import mineplex.core.gadget.gadgets.OutfitTeam; +import mineplex.core.gadget.types.Gadget; +import mineplex.core.gadget.types.GadgetType; +import mineplex.core.gadget.types.MusicGadget; +import mineplex.core.mount.event.MountActivateEvent; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.HubManager; + +public class SoccerManager extends MiniPlugin +{ + public HubManager Manager; + + private HashSet _active = new HashSet(); + + private ArrayList _teamArmor = new ArrayList(); + + private Location _cornerFieldPlayerA; + private Location _cornerFieldPlayerB; + + private Location _cornerGoalPlayerA; + private Location _cornerGoalPlayerB; + + private Location _cornerFieldA; + private Location _cornerFieldB; + + private Location _cornerRedGoalA; + private Location _cornerRedGoalB; + + private Location _cornerBlueGoalA; + private Location _cornerBlueGoalB; + + int _blueGoals = 0; + int _redGoals = 0; + + int _insideGoalTicks = 0; + + private Slime _ball; + private Vector _ballVel; + private long _ballDeadTime = -1; + + private String _lastKicker = ""; + + //Item Rebound + protected Vector _vel; + protected Location _lastLoc; + protected ArrayList _velHistory = new ArrayList(); + + public SoccerManager(HubManager manager, GadgetManager gadgets) + { + super("Football Manager", manager.getPlugin()); + + Manager = manager; + + _cornerFieldPlayerA = new Location(Manager.GetSpawn().getWorld(), 28.5,70,-27.5); + _cornerFieldPlayerB = new Location(Manager.GetSpawn().getWorld(), 49.5,100,-63.5); + + _cornerGoalPlayerA = new Location(Manager.GetSpawn().getWorld(), 35.5,70,-24.5); + _cornerGoalPlayerB = new Location(Manager.GetSpawn().getWorld(), 42.5,100,-66.5); + + _cornerFieldA = new Location(Manager.GetSpawn().getWorld(), 29.75,70,-28.75); + _cornerFieldB = new Location(Manager.GetSpawn().getWorld(), 48.25,100,-62.25); + + _cornerRedGoalA = new Location(Manager.GetSpawn().getWorld(), 36.75,70,-62.25); + _cornerRedGoalB = new Location(Manager.GetSpawn().getWorld(), 41.25,73.5,-65.25); + + _cornerBlueGoalA = new Location(Manager.GetSpawn().getWorld(), 36.75,70,-25.75); + _cornerBlueGoalB = new Location(Manager.GetSpawn().getWorld(), 41.25,73.5,-28.75); + + //Store Gadgets + for (Gadget gadget : gadgets.getGadgets(GadgetType.Costume)) + { + if (gadget instanceof OutfitTeam) + { + _teamArmor.add((OutfitTeam)gadget); + } + } + } + + @EventHandler + public void ballUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + if (_active.size() <= 0) + { + _blueGoals = 0; + _redGoals = 0; + + if (_ball != null) + _ball.remove();; + + return; + } + + //New Ball Needed + if (_ballDeadTime == -1 && (_ball == null || !_ball.isValid())) + { + if (_ball != null) + _ball.remove(); + + _ballDeadTime = System.currentTimeMillis(); + } + + //Spawn Ball + if (_ballDeadTime > 0 && UtilTime.elapsed(_ballDeadTime, 4000)) + { + Location mid = UtilAlg.getMidpoint(_cornerFieldPlayerA, _cornerFieldPlayerB); + + if (!mid.getChunk().isLoaded()) + return; + + _ball = mid.getWorld().spawn(mid, Slime.class); + _ball.setSize(2); + + UtilEnt.Vegetate(_ball); + UtilEnt.ghost(_ball, true, false); + + _ballVel = new Vector(0,-0.1,0); + + UtilFirework.playFirework(mid, Type.BALL, Color.YELLOW, false, false); + + _ballDeadTime = -1; + + _vel = new Vector(0,-0.1,0); + _velHistory.add(_vel); + _lastLoc = _ball.getLocation(); + } + + if (_ball == null) + return; + + UtilParticle.PlayParticle(ParticleType.HAPPY_VILLAGER, _ball.getLocation().add(0, 0.5, 0), 0, 0, 0, 0, 1, ViewDist.NORMAL, UtilServer.getPlayers()); + + //Kick + for (Player player : _active) + { + if (UtilMath.offset(player, _ball) < 1.25 || + UtilMath.offset(player.getEyeLocation(), _ball.getLocation()) < 1) + { + if (Recharge.Instance.use(player, "Football Kick", 600, false, false)) + { + _ballVel = player.getLocation().getDirection(); + _ballVel.setY(_ballVel.getY() + 0.4); + + if (UtilEnt.isGrounded(_ball) && _ballVel.getY() <= 0) + _ballVel.setY(0); + + _ballVel.setY(Math.min(_ballVel.getY(), 0.8)); + + _ball.getWorld().playSound(_ball.getLocation(), Sound.ZOMBIE_WOOD, 0.5f, 1.5f); + + UtilParticle.PlayParticle(ParticleType.SLIME, + UtilAlg.getMidpoint(_ball.getLocation(), player.getLocation()), + 0, 0, 0, 0, 5, ViewDist.NORMAL, UtilServer.getPlayers()); + + UtilAction.zeroVelocity(player); + + if (getTeamColor(player) == null) + _lastKicker = player.getName(); + else if (getTeamColor(player) == Color.RED) + _lastKicker = C.cRed + player.getName(); + else if (getTeamColor(player) == Color.AQUA) + _lastKicker = C.cAqua + player.getName(); + } + } + } + + //Blue Goal + if (UtilAlg.inBoundingBox(_ball.getLocation(), _cornerRedGoalA, _cornerRedGoalB) && + !UtilAlg.inBoundingBox(_ball.getLocation(), _cornerFieldA, _cornerFieldB)) + { + + _insideGoalTicks++; + + if (_insideGoalTicks > 3) + { + UtilFirework.playFirework(_ball.getLocation(), Type.BALL, Color.AQUA, true, true); + + _blueGoals++; + + for (Player player : _active) + UtilTextMiddle.display("Goal! (" + C.cRed + _redGoals + C.cWhite + " : " + C.cBlue + _blueGoals + C.cWhite + ")", + _lastKicker + C.cWhite + " scored for " + C.cAqua + "Blue Team", 0, 70, 20, player); + + _ball.remove(); + _ball = null; + } + + + + return; + } + + //Red Goal + else if (UtilAlg.inBoundingBox(_ball.getLocation(), _cornerBlueGoalA, _cornerBlueGoalB) && + !UtilAlg.inBoundingBox(_ball.getLocation(), _cornerFieldA, _cornerFieldB)) + { + _insideGoalTicks++; + + if (_insideGoalTicks > 3) + { + UtilFirework.playFirework(_ball.getLocation(), Type.BALL, Color.RED, true, true); + + _redGoals++; + + for (Player player : _active) + UtilTextMiddle.display("Goal! (" + C.cRed + _redGoals + C.cWhite + " : " + C.cBlue + _blueGoals + C.cWhite + ")", + _lastKicker + C.cWhite + " scored for " + C.cRed + "Red Team", 0, 70, 20, player); + + _ball.remove(); + _ball = null; + } + + return; + } + else + { + _insideGoalTicks = 0; + } + + //Wind Drag + _ballVel = _ballVel.multiply(0.99); + + //Ground Drag + if (UtilEnt.isGrounded(_ball)) + _ballVel = _ballVel.multiply(0.98); + + //Rebound Y XXX + if (UtilEnt.isGrounded(_ball)) + { + if (_ballVel.getY() < -0.1) + { + _ballVel.setY(_ballVel.getY() * -0.65); + } + } + + //Gravity + if (!UtilEnt.isGrounded(_ball)) + _ballVel.setY(_ballVel.getY() - 0.04); + + //Rebound X + if ((_ballVel.getX() > 0 && _ball.getLocation().getX() > Math.max(_cornerFieldA.getX(), _cornerFieldB.getX())) || + (_ballVel.getX() < 0 && _ball.getLocation().getX() < Math.min(_cornerFieldA.getX(), _cornerFieldB.getX()))) + { + _ballVel.setX(_ballVel.getX() * -1); + + _ballVel = _ballVel.multiply(0.9); + + _ball.getWorld().playSound(_ball.getLocation(), Sound.ZOMBIE_WOOD, 0.5f, 1.5f); + UtilParticle.PlayParticle(ParticleType.LARGE_EXPLODE, _ball.getLocation(), 0, 0, 0, 0, 1, ViewDist.NORMAL, UtilServer.getPlayers()); + } + + //Rebound Z + if ((_ballVel.getZ() > 0 && _ball.getLocation().getZ() > Math.max(_cornerFieldA.getZ(), _cornerFieldB.getZ())) || + (_ballVel.getZ() < 0 && _ball.getLocation().getZ() < Math.min(_cornerFieldA.getZ(), _cornerFieldB.getZ()))) + { + _ballVel.setZ(_ballVel.getZ() * -1); + + _ballVel = _ballVel.multiply(0.9); + + _ball.getWorld().playSound(_ball.getLocation(), Sound.ZOMBIE_WOOD, 0.5f, 1.5f); + UtilParticle.PlayParticle(ParticleType.LARGE_EXPLODE, _ball.getLocation(), 0, 0, 0, 0, 1, ViewDist.NORMAL, UtilServer.getPlayers()); + } + + //Move Ball + _ball.setVelocity(_ballVel); + } + + public Color getTeamColor(Player player) + { + //All peices are always same color! + for (OutfitTeam outfit : _teamArmor) + { + return outfit.getTeamColor(player); + } + + return null; + } + + public boolean inPlayerArena(Entity entity) + { + return UtilAlg.inBoundingBox(entity.getLocation(), _cornerFieldPlayerA, _cornerFieldPlayerB) || + UtilAlg.inBoundingBox(entity.getLocation(), _cornerGoalPlayerA, _cornerGoalPlayerB); + } + + @EventHandler + public void clean(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + return; + + for (Entity ent : _cornerFieldA.getWorld().getEntitiesByClass(LivingEntity.class)) + { + if (ent instanceof Player) + continue; + + if (_ball != null && _ball.equals(ent)) + continue; + + if (inPlayerArena(ent)) + { + Location bounce = UtilAlg.getMidpoint(_cornerFieldPlayerA, _cornerFieldPlayerB); + bounce.setY(Math.min(_cornerFieldPlayerA.getY(), _cornerFieldPlayerB.getY())); + + Entity bottom = ent; + if (bottom.getVehicle() != null) + bottom = bottom.getVehicle(); + + UtilAction.velocity(bottom, UtilAlg.getTrajectory(bounce, ent.getLocation()), 1, false, 0, 0.4, 1, true); + + } + } + } + + @EventHandler + public void joinLeaveGame(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + for (Player player : UtilServer.getPlayers()) + { + if (_active.contains(player)) + { + if (!inPlayerArena(player)) + { + setSoccerMode(player, false, null); + continue; + } + + //Took armor off + Color color = getTeamColor(player); + if (color == null || (color != Color.RED && color != Color.AQUA)) + { + setSoccerMode(player, false, null); + } + } + else + { + if (inPlayerArena(player)) + { + Color color = getTeamColor(player); + + //Join + if (color != null && (color == Color.RED || color == Color.AQUA)) + { + setSoccerMode(player, true, color); + } + //Eject + else + { + Location bounce = UtilAlg.getMidpoint(_cornerFieldPlayerA, _cornerFieldPlayerB); + bounce.setY(Math.min(_cornerFieldPlayerA.getY(), _cornerFieldPlayerB.getY())); + + Entity bottom = player; + if (bottom.getVehicle() != null) + bottom = bottom.getVehicle(); + + UtilAction.velocity(bottom, UtilAlg.getTrajectory(bounce, player.getLocation()), 1, false, 0, 0.4, 1, true); + + if (Recharge.Instance.use(player, "Soccer Eject", 5000, false, false)) + { + UtilPlayer.message(player, F.main("Football", "You must be wearing Red/Blue Team Outfit.")); + UtilPlayer.message(player, F.main("Football", "Type " + F.elem("/team red") + " or " + F.elem("/team blue") + "!")); + } + } + } + } + } + } + + public void setSoccerMode(Player player, boolean enabled, Color color) + { + if (enabled) + { + _active.add(player); + + if (color == null) + UtilPlayer.message(player, F.main("Parkour", "You have entered " + F.elem("Football Mode") + ".")); + else if (color == Color.RED) + UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cRed + "Red Football Team") + ".")); + else if (color == Color.AQUA) + UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cAqua + "Blue Football Team") + ".")); + + ArrayList outfit = new ArrayList(); + outfit.add("Team Helmet"); + outfit.add("Team Shirt"); + outfit.add("Team Pants"); + outfit.add("Team Boots"); + + Manager.GetGadget().DisableAll(player, outfit); + } + else + { + _active.remove(player); + UtilPlayer.message(player, F.main("Parkour", "You have exited " + F.elem("Football Mode") + ".")); + } + } + + public boolean isSoccerMode(Player player) + { + return _active.contains(player); + } + + @EventHandler + public void disableGadgets(GadgetActivateEvent event) + { + if (isSoccerMode(event.getPlayer())) + event.setCancelled(true); + } + + @EventHandler + public void disableMounts(MountActivateEvent event) + { + if (isSoccerMode(event.getPlayer())) + event.setCancelled(true); + } + + @EventHandler + public void playerQuit(PlayerQuitEvent event) + { + _active.remove(event.getPlayer()); + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/WorldManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/WorldManager.java index c0f169c4e..1d2513e02 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/WorldManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/WorldManager.java @@ -103,9 +103,8 @@ public class WorldManager extends MiniPlugin Location loc = Manager.GetSpawn(); - if (r > 0.75) loc = new Location(Manager.GetSpawn().getWorld(), -9, 72, 42); - else if (r > 0.5) loc = new Location(Manager.GetSpawn().getWorld(), -36, 72, -28); - else if (r > 0.25) loc = new Location(Manager.GetSpawn().getWorld(), 31, 72, -34); + if (r > 0.66) loc = new Location(Manager.GetSpawn().getWorld(), -9, 72, 42); + else if (r > 0.33) loc = new Location(Manager.GetSpawn().getWorld(), -36, 72, -28); else loc = new Location(Manager.GetSpawn().getWorld(), 43, 72, 5); //Spawn diff --git a/Plugins/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java b/Plugins/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java index 9d1efd727..ed767a133 100644 --- a/Plugins/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java +++ b/Plugins/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java @@ -25,6 +25,8 @@ import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBurnEvent; import org.bukkit.event.block.BlockFadeEvent; import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; import org.bukkit.event.block.BlockSpreadEvent; import org.bukkit.event.block.LeavesDecayEvent; import org.bukkit.event.entity.EntitySpawnEvent; @@ -260,6 +262,13 @@ public class MapParser extends JavaPlugin implements Listener event.setCancelled(true); } + @EventHandler + public void DisableIgnite(BlockIgniteEvent event) + { + if (event.getCause() == IgniteCause.LAVA || event.getCause() == IgniteCause.SPREAD) + event.setCancelled(true); + } + @EventHandler public void DisableFire(BlockSpreadEvent event) { diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java index 772f894ed..3f063b9fb 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java @@ -134,7 +134,7 @@ public class Arcade extends JavaPlugin InventoryManager inventoryManager = new InventoryManager(this, _clientManager); PetManager petManager = new PetManager(this, _clientManager, _donationManager, disguiseManager, creature, blockRestore, webServerAddress); MountManager mountManager = new MountManager(this, _clientManager, _donationManager, blockRestore, disguiseManager); - GadgetManager gadgetManager = new GadgetManager(this, _clientManager, _donationManager, inventoryManager, mountManager, petManager, preferenceManager, disguiseManager, blockRestore, projectileManager); + GadgetManager gadgetManager = new GadgetManager(this, _clientManager, _donationManager, inventoryManager, mountManager, petManager, preferenceManager, disguiseManager, blockRestore, projectileManager, achievementManager); CosmeticManager cosmeticManager = new CosmeticManager(this, _clientManager, _donationManager, inventoryManager, gadgetManager, mountManager, petManager, null); cosmeticManager.setInterfaceSlot(7); From 33c96f51ae920397d5441913eea714b470cf8a1b Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Fri, 7 Aug 2015 22:59:50 +0200 Subject: [PATCH 267/377] fixed some stuff --- .../src/mineplex/core/NCPDataManFix.java | 2 +- .../core/gadget/gadgets/ItemPaintbrush.java | 26 +++++++++-------- .../core/gadget/gadgets/OutfitTeam.java | 21 ++++++++++++-- .../mineplex/hub/modules/SoccerManager.java | 28 +++++++++++++++---- .../src/mineplex/mapparser/MapParser.java | 13 +++++++++ 5 files changed, 68 insertions(+), 22 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/NCPDataManFix.java b/Plugins/Mineplex.Core/src/mineplex/core/NCPDataManFix.java index 3ddbb0f50..c531ad097 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/NCPDataManFix.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/NCPDataManFix.java @@ -5,6 +5,6 @@ import fr.neatmonster.nocheatplus.config.ConfigManager; public class NCPDataManFix { public NCPDataManFix() { - ConfigManager.getConfigFile().set("data.consistencychecks.suppresswarnings", true); + //ConfigManager.getConfigFile().set("data.consistencychecks.suppresswarnings", true); } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java index 92c03c83c..e48eba5f7 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java @@ -9,7 +9,10 @@ import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.entity.Villager; import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityInteractEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import mineplex.core.common.util.C; @@ -37,6 +40,8 @@ public class ItemPaintbrush extends ItemGadget super(manager, "Paintbrush", new String[] { C.cWhite + "Unleash your inner creativity!", + C.cWhite + "", + C.cWhite + "Click a Painter NPC to equip this.", }, -2, Material.WOOD_SWORD, (byte)0, @@ -157,23 +162,20 @@ public class ItemPaintbrush extends ItemGadget } } - //XXX TODO ENABLE - @EventHandler - public void enableInteract(PlayerInteractEvent event) + public void enableInteract(PlayerInteractEntityEvent event) { if (IsActive(event.getPlayer())) return; - - if (!UtilEvent.isAction(event, ActionType.L)) - return; - - Player player = event.getPlayer(); - - Block block = player.getTargetBlock(null, 100); - if (block == null || block.getType() != Material.STAINED_CLAY) + + if (!(event.getRightClicked() instanceof Villager)) return; - Enable(event.getPlayer()); + Villager villager = (Villager)event.getRightClicked(); + + if (villager.getCustomName() != null && villager.getCustomName().contains("Painter")) + { + Enable(event.getPlayer()); + } } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java index 10102b0e9..ce734cd57 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java @@ -14,7 +14,9 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.LeatherArmorMeta; import mineplex.core.common.util.C; +import mineplex.core.common.util.F; import mineplex.core.common.util.UtilGear; +import mineplex.core.common.util.UtilPlayer; import mineplex.core.gadget.GadgetManager; import mineplex.core.gadget.types.OutfitGadget; @@ -58,16 +60,29 @@ public class OutfitTeam extends OutfitGadget //Color if (args[1].equals("red")) + { _colorSetting.put(player.getName(), Color.RED); + + UtilPlayer.message(player, F.main("Gadget", "You equipped " + F.elem(C.cRed + "Red Team Outfit") + "!")); + } else if (args[1].equals("yellow")) + { _colorSetting.put(player.getName(), Color.YELLOW); + UtilPlayer.message(player, F.main("Gadget", "You equipped " + F.elem(C.cRed + "Yellow Team Outfit") + "!")); + } else if (args[1].equals("green")) - _colorSetting.put(player.getName(), Color.GREEN); + { + _colorSetting.put(player.getName(), Color.LIME); + UtilPlayer.message(player, F.main("Gadget", "You equipped " + F.elem(C.cGreen + "Green Team Outfit") + "!")); + } else if (args[1].equals("blue")) + { _colorSetting.put(player.getName(), Color.AQUA); + UtilPlayer.message(player, F.main("Gadget", "You equipped " + F.elem(C.cRed + "Blue Team Outfit") + "!")); + } colorArmor(player); - + Enable(player); } @@ -75,7 +90,7 @@ public class OutfitTeam extends OutfitGadget { if (!_colorSetting.containsKey(player.getName())) return; - + //Get Item ItemStack stack; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java index 9af84b8fa..8ab5599c1 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -22,6 +22,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; @@ -182,8 +183,8 @@ public class SoccerManager extends MiniPlugin //Kick for (Player player : _active) { - if (UtilMath.offset(player, _ball) < 1.25 || - UtilMath.offset(player.getEyeLocation(), _ball.getLocation()) < 1) + if (UtilMath.offset(player, _ball) < 1.5 || + UtilMath.offset(player.getEyeLocation(), _ball.getLocation()) < 1.25) { if (Recharge.Instance.use(player, "Football Kick", 600, false, false)) { @@ -388,9 +389,9 @@ public class SoccerManager extends MiniPlugin if (inPlayerArena(player)) { Color color = getTeamColor(player); - + //Join - if (color != null && (color == Color.RED || color == Color.AQUA)) + if (color != null && (color == Color.RED || color == Color.AQUA) && _active.size() < 8) { setSoccerMode(player, true, color); } @@ -408,8 +409,16 @@ public class SoccerManager extends MiniPlugin if (Recharge.Instance.use(player, "Soccer Eject", 5000, false, false)) { - UtilPlayer.message(player, F.main("Football", "You must be wearing Red/Blue Team Outfit.")); - UtilPlayer.message(player, F.main("Football", "Type " + F.elem("/team red") + " or " + F.elem("/team blue") + "!")); + if (_active.size() >= 8) + { + UtilPlayer.message(player, F.main("Football", "You must be wearing Red/Blue Team Outfit.")); + UtilPlayer.message(player, F.main("Football", "Type " + F.elem("/team red") + " or " + F.elem("/team blue") + "!")); + } + else + { + UtilPlayer.message(player, F.main("Football", "You must be wearing Red/Blue Team Outfit.")); + UtilPlayer.message(player, F.main("Football", "Type " + F.elem("/team red") + " or " + F.elem("/team blue") + "!")); + } } } } @@ -463,6 +472,13 @@ public class SoccerManager extends MiniPlugin if (isSoccerMode(event.getPlayer())) event.setCancelled(true); } + + @EventHandler(priority = EventPriority.LOWEST) + public void playerGrabSlime(PlayerInteractEntityEvent event) + { + if (_active.contains(event.getPlayer())) + event.setCancelled(true); + } @EventHandler public void playerQuit(PlayerQuitEvent event) diff --git a/Plugins/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java b/Plugins/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java index ed767a133..8e9b39b59 100644 --- a/Plugins/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java +++ b/Plugins/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java @@ -719,4 +719,17 @@ public class MapParser extends JavaPlugin implements Listener return blocks; } + + @EventHandler(priority = EventPriority.LOWEST) + public void leaptest(PlayerInteractEvent event) + { + + if (event.getPlayer().getItemInHand() == null) + return; + + if (event.getPlayer().getItemInHand().getType() != Material.FEATHER) + return; + + event.getPlayer().setVelocity(event.getPlayer().getLocation().getDirection().multiply(1.2)); + } } From 47cb98066dfc1dcb93847abae468b056ae2d46cf Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Sat, 8 Aug 2015 08:19:07 +0200 Subject: [PATCH 268/377] Hub fixes --- .../core/gadget/gadgets/OutfitTeam.java | 60 +++++++++++++++++-- .../core/gadget/types/OutfitGadget.java | 2 +- .../mineplex/hub/modules/SoccerManager.java | 36 +++++------ .../mineplex/hub/modules/WorldManager.java | 15 +++++ 4 files changed, 89 insertions(+), 24 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java index ce734cd57..ee053c618 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java @@ -2,6 +2,7 @@ package mineplex.core.gadget.gadgets; import java.util.HashMap; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Color; import org.bukkit.Material; @@ -18,7 +19,10 @@ import mineplex.core.common.util.F; import mineplex.core.common.util.UtilGear; import mineplex.core.common.util.UtilPlayer; import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.event.GadgetActivateEvent; import mineplex.core.gadget.types.OutfitGadget; +import mineplex.core.gadget.types.OutfitGadget.ArmorSlot; +import mineplex.core.itemstack.ItemStackFactory; public class OutfitTeam extends OutfitGadget { @@ -29,6 +33,43 @@ public class OutfitTeam extends OutfitGadget { super(manager, name, new String[] {ChatColor.RESET + "Team up with other players!", ChatColor.RESET + "Equip by typing;", ChatColor.RESET + C.cGreen + "/team "}, cost, slot, mat, data); } + + @Override + public void Enable(Player player) + { + GadgetActivateEvent gadgetEvent = new GadgetActivateEvent(player, this); + Bukkit.getServer().getPluginManager().callEvent(gadgetEvent); + + if (gadgetEvent.isCancelled()) + { + return; + } + + EnableCustom(player); + Manager.setActive(player, this); + } + + @Override + public void ApplyArmor(Player player) + { + Manager.RemoveMorph(player); + + Manager.RemoveOutfit(player, _slot); + + _active.add(player); + + if (_slot == ArmorSlot.Helmet) player.getInventory().setHelmet( + ItemStackFactory.Instance.CreateStack(GetDisplayMaterial().getId(), GetDisplayData(), 1, GetName())); + + else if (_slot == ArmorSlot.Chest) player.getInventory().setChestplate( + ItemStackFactory.Instance.CreateStack(GetDisplayMaterial().getId(), GetDisplayData(), 1, GetName())); + + else if (_slot == ArmorSlot.Legs) player.getInventory().setLeggings( + ItemStackFactory.Instance.CreateStack(GetDisplayMaterial().getId(), GetDisplayData(), 1, GetName())); + + else if (_slot == ArmorSlot.Boots) player.getInventory().setBoots( + ItemStackFactory.Instance.CreateStack(GetDisplayMaterial().getId(), GetDisplayData(), 1, GetName())); + } @Override public void EnableCustom(Player player) @@ -44,7 +85,7 @@ public class OutfitTeam extends OutfitGadget } @EventHandler(priority=EventPriority.LOWEST) - public void updateColor(PlayerCommandPreprocessEvent event) + public void setColor(PlayerCommandPreprocessEvent event) { Player player = event.getPlayer(); @@ -62,23 +103,30 @@ public class OutfitTeam extends OutfitGadget if (args[1].equals("red")) { _colorSetting.put(player.getName(), Color.RED); - - UtilPlayer.message(player, F.main("Gadget", "You equipped " + F.elem(C.cRed + "Red Team Outfit") + "!")); + + if (GetSlot() == ArmorSlot.Legs) //Only Display Once + UtilPlayer.message(player, F.main("Gadget", "You equipped " + F.elem(C.cRed + "Red Team Outfit") + "!")); } else if (args[1].equals("yellow")) { _colorSetting.put(player.getName(), Color.YELLOW); - UtilPlayer.message(player, F.main("Gadget", "You equipped " + F.elem(C.cRed + "Yellow Team Outfit") + "!")); + + if (GetSlot() == ArmorSlot.Legs) //Only Display Once + UtilPlayer.message(player, F.main("Gadget", "You equipped " + F.elem(C.cYellow + "Yellow Team Outfit") + "!")); } else if (args[1].equals("green")) { _colorSetting.put(player.getName(), Color.LIME); - UtilPlayer.message(player, F.main("Gadget", "You equipped " + F.elem(C.cGreen + "Green Team Outfit") + "!")); + + if (GetSlot() == ArmorSlot.Legs) //Only Display Once + UtilPlayer.message(player, F.main("Gadget", "You equipped " + F.elem(C.cGreen + "Green Team Outfit") + "!")); } else if (args[1].equals("blue")) { _colorSetting.put(player.getName(), Color.AQUA); - UtilPlayer.message(player, F.main("Gadget", "You equipped " + F.elem(C.cRed + "Blue Team Outfit") + "!")); + + if (GetSlot() == ArmorSlot.Legs) //Only Display Once + UtilPlayer.message(player, F.main("Gadget", "You equipped " + F.elem(C.cAqua + "Blue Team Outfit") + "!")); } colorArmor(player); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/OutfitGadget.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/OutfitGadget.java index 1ab3daa45..fabae966d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/OutfitGadget.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/types/OutfitGadget.java @@ -18,7 +18,7 @@ public abstract class OutfitGadget extends Gadget Boots } - private ArmorSlot _slot; + protected ArmorSlot _slot; public OutfitGadget(GadgetManager manager, String name, String[] desc, int cost, ArmorSlot slot, Material mat, byte data) { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java index 8ab5599c1..55fe110cf 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -2,32 +2,22 @@ package mineplex.hub.modules; import java.util.ArrayList; import java.util.HashSet; -import java.util.Iterator; -import java.util.WeakHashMap; -import org.bukkit.Bukkit; import org.bukkit.FireworkEffect.Type; import org.bukkit.Color; import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.Sound; -import org.bukkit.entity.Bat; import org.bukkit.entity.Entity; -import org.bukkit.entity.Item; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; -import org.bukkit.entity.Skeleton; import org.bukkit.entity.Slime; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; -import org.bukkit.event.inventory.InventoryOpenEvent; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; -import mineplex.core.MiniPlugin; +import mineplex.core.MiniPlugin; import mineplex.core.common.util.C; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilAction; @@ -47,7 +37,6 @@ import mineplex.core.gadget.event.GadgetActivateEvent; import mineplex.core.gadget.gadgets.OutfitTeam; import mineplex.core.gadget.types.Gadget; import mineplex.core.gadget.types.GadgetType; -import mineplex.core.gadget.types.MusicGadget; import mineplex.core.mount.event.MountActivateEvent; import mineplex.core.recharge.Recharge; import mineplex.core.updater.UpdateType; @@ -87,6 +76,7 @@ public class SoccerManager extends MiniPlugin private long _ballDeadTime = -1; private String _lastKicker = ""; + private Color _lastKick = null; //Item Rebound protected Vector _vel; @@ -178,7 +168,18 @@ public class SoccerManager extends MiniPlugin if (_ball == null) return; - UtilParticle.PlayParticle(ParticleType.HAPPY_VILLAGER, _ball.getLocation().add(0, 0.5, 0), 0, 0, 0, 0, 1, ViewDist.NORMAL, UtilServer.getPlayers()); + if (_lastKick == Color.AQUA) + { + for (int i = 0 ; i < 3 ; i++) + UtilParticle.PlayParticle(ParticleType.RED_DUST, _ball.getLocation().add(0.0, 0.5, 0.0), -1, 1, 1, 1, 0, + ViewDist.NORMAL, UtilServer.getPlayers()); + } + else + { + for (int i = 0 ; i < 3 ; i++) + UtilParticle.PlayParticle(ParticleType.RED_DUST, _ball.getLocation().add(0.0, 0.5, 0.0), 0, 0, 0, 0, 1, + ViewDist.NORMAL, UtilServer.getPlayers()); + } //Kick for (Player player : _active) @@ -204,11 +205,12 @@ public class SoccerManager extends MiniPlugin UtilAction.zeroVelocity(player); - if (getTeamColor(player) == null) + _lastKick = getTeamColor(player); + if (_lastKick == null) _lastKicker = player.getName(); - else if (getTeamColor(player) == Color.RED) + else if (_lastKick == Color.RED) _lastKicker = C.cRed + player.getName(); - else if (getTeamColor(player) == Color.AQUA) + else if (_lastKick == Color.AQUA) _lastKicker = C.cAqua + player.getName(); } } @@ -274,7 +276,7 @@ public class SoccerManager extends MiniPlugin if (UtilEnt.isGrounded(_ball)) _ballVel = _ballVel.multiply(0.98); - //Rebound Y XXX + //Rebound Y if (UtilEnt.isGrounded(_ball)) { if (_ballVel.getY() < -0.1) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/WorldManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/WorldManager.java index 1d2513e02..1506c0311 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/WorldManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/WorldManager.java @@ -37,7 +37,10 @@ import org.bukkit.entity.Snowman; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockSpreadEvent; import org.bukkit.event.block.LeavesDecayEvent; @@ -147,6 +150,18 @@ public class WorldManager extends MiniPlugin event.setCancelled(true); } + + @EventHandler + public void BlockBurn(BlockBurnEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void BlockIgnite(BlockIgniteEvent event) + { + event.setCancelled(true); + } @EventHandler(priority = EventPriority.LOWEST) public void Explosion(EntityExplodeEvent event) From eab7aa59f2d64dd8e58fd7260e1eb431029732db Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Sat, 8 Aug 2015 09:27:49 +0200 Subject: [PATCH 269/377] hub update! --- .../mineplex/core/gadget/gadgets/OutfitTeam.java | 4 ++++ .../src/mineplex/hub/modules/SoccerManager.java | 16 ++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java index ee053c618..34fd99802 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java @@ -23,6 +23,7 @@ import mineplex.core.gadget.event.GadgetActivateEvent; import mineplex.core.gadget.types.OutfitGadget; import mineplex.core.gadget.types.OutfitGadget.ArmorSlot; import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.recharge.Recharge; public class OutfitTeam extends OutfitGadget { @@ -98,6 +99,9 @@ public class OutfitTeam extends OutfitGadget if (args.length < 2) return; + + if (!Recharge.Instance.use(player, "Set Team Color", 20000, true, false)) + return; //Color if (args[1].equals("red")) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java index 55fe110cf..db273a153 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -90,19 +90,19 @@ public class SoccerManager extends MiniPlugin Manager = manager; _cornerFieldPlayerA = new Location(Manager.GetSpawn().getWorld(), 28.5,70,-27.5); - _cornerFieldPlayerB = new Location(Manager.GetSpawn().getWorld(), 49.5,100,-63.5); + _cornerFieldPlayerB = new Location(Manager.GetSpawn().getWorld(), 50.5,100,-65.5); _cornerGoalPlayerA = new Location(Manager.GetSpawn().getWorld(), 35.5,70,-24.5); - _cornerGoalPlayerB = new Location(Manager.GetSpawn().getWorld(), 42.5,100,-66.5); + _cornerGoalPlayerB = new Location(Manager.GetSpawn().getWorld(), 43.5,100,-68.5); _cornerFieldA = new Location(Manager.GetSpawn().getWorld(), 29.75,70,-28.75); - _cornerFieldB = new Location(Manager.GetSpawn().getWorld(), 48.25,100,-62.25); + _cornerFieldB = new Location(Manager.GetSpawn().getWorld(), 49.25,100,-64.25); - _cornerRedGoalA = new Location(Manager.GetSpawn().getWorld(), 36.75,70,-62.25); - _cornerRedGoalB = new Location(Manager.GetSpawn().getWorld(), 41.25,73.5,-65.25); + _cornerRedGoalA = new Location(Manager.GetSpawn().getWorld(), 36.75,70,-64.25); + _cornerRedGoalB = new Location(Manager.GetSpawn().getWorld(), 42.25,73.5,-67.25); _cornerBlueGoalA = new Location(Manager.GetSpawn().getWorld(), 36.75,70,-25.75); - _cornerBlueGoalB = new Location(Manager.GetSpawn().getWorld(), 41.25,73.5,-28.75); + _cornerBlueGoalB = new Location(Manager.GetSpawn().getWorld(), 42.25,73.5,-28.75); //Store Gadgets for (Gadget gadget : gadgets.getGadgets(GadgetType.Costume)) @@ -337,10 +337,10 @@ public class SoccerManager extends MiniPlugin @EventHandler public void clean(UpdateEvent event) { - if (event.getType() != UpdateType.FAST) + if (event.getType() != UpdateType.FASTER) return; - for (Entity ent : _cornerFieldA.getWorld().getEntitiesByClass(LivingEntity.class)) + for (Entity ent : _cornerFieldA.getWorld().getEntities()) { if (ent instanceof Player) continue; From 4f6dfdb856d9ab918e1aacd25532236fcbb3bc7d Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Sat, 8 Aug 2015 06:35:25 -0500 Subject: [PATCH 270/377] Update carl spin button to consume tickets, Updates to Votifier Plugin, Redis Vote Command, Various bug fixes --- .../core/votifier/RedisVotifierCommand.java | 17 --- .../core/votifier/VotifierCommand.java | 23 ++++ .../src/mineplex/hub/bonuses/BonusAmount.java | 1 - .../mineplex/hub/bonuses/BonusManager.java | 105 +++++++++++++++++- .../mineplex/hub/bonuses/BonusRepository.java | 65 +++++++++++ .../mineplex/hub/bonuses/StreakRecord.java | 23 ++++ .../src/mineplex/hub/bonuses/VoteHandler.java | 31 ++++++ .../mineplex/hub/bonuses/gui/BonusGui.java | 2 +- .../bonuses/gui/buttons/CarlSpinButton.java | 43 ++++++- .../bonuses/gui/buttons/DailyBonusButton.java | 12 +- .../hub/bonuses/gui/buttons/VoteButton.java | 13 ++- .../Mineplex.Votifier/Mineplex.Votifier.iml | 1 + .../mineplex/votifier/VotifierManager.java | 46 +++++++- 13 files changed, 342 insertions(+), 40 deletions(-) delete mode 100644 Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/StreakRecord.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/VoteHandler.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java deleted file mode 100644 index 7b92598b3..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/votifier/RedisVotifierCommand.java +++ /dev/null @@ -1,17 +0,0 @@ -package mineplex.core.votifier; - -import java.util.UUID; - -import mineplex.serverdata.commands.ServerCommand; - -public class RedisVotifierCommand extends ServerCommand -{ - private UUID _voterUUID; - - - public RedisVotifierCommand() - { - - } - -} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java new file mode 100644 index 000000000..a84087fb0 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java @@ -0,0 +1,23 @@ +package mineplex.core.votifier; + +import java.util.UUID; + +import mineplex.serverdata.commands.ServerCommand; + +public class VotifierCommand extends ServerCommand +{ + private String _playerName; + + public VotifierCommand(String playerName, String targetServer) + { + super(targetServer); + + _playerName = playerName; + } + + public String getPlayerName() + { + return _playerName; + } + +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java index 9c5343077..d596a846b 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java @@ -143,7 +143,6 @@ public class BonusAmount addLore(lore, getGems(), getBonusGems(), "Gems"); addLore(lore, getGold(), getBonusGold(), "Gold"); addLore(lore, getExperience(), getBonusExperience(), "Experience"); - lore.add(" "); } private void addLore(List lore, int amount, int bonus, String suffix) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index bfd1bca5a..b4bd57948 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -23,10 +23,14 @@ import mineplex.core.npc.NpcManager; import mineplex.core.reward.RewardManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; +import mineplex.core.votifier.VotifierCommand; import mineplex.hub.bonuses.commands.GuiCommand; import mineplex.hub.bonuses.gui.BonusGui; import mineplex.database.tables.records.BonusRecord; +import mineplex.hub.bonuses.gui.SpinGui; +import mineplex.serverdata.commands.ServerCommandManager; +import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; @@ -87,6 +91,10 @@ public class BonusManager extends MiniClientPlugin implements I private RewardManager _rewardManager; private Npc _carlNpc; + // Streak + private StreakRecord _dailyStreak; + private StreakRecord _voteStreak; + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, NpcManager npcManager, HologramManager hologramManager, RewardManager rewardManager) { super("Bonus", plugin); @@ -102,7 +110,11 @@ public class BonusManager extends MiniClientPlugin implements I clientManager.addStoredProcedureLoginProcessor(this); + ServerCommandManager.getInstance().registerCommandType("VotifierCommand", VotifierCommand.class, + new VoteHandler(this)); + updateOffSet(); + updateStreakRecord(); } @Override @@ -121,6 +133,51 @@ public class BonusManager extends MiniClientPlugin implements I updateOffSet(); } + @EventHandler + public void updateStreak(UpdateEvent event) + { + if (event.getType() != UpdateType.MIN_16) + return; + + updateStreakRecord(); + } + + private void updateStreakRecord() + { + _repository.getDailyStreakRecord(new Callback() + { + @Override + public void run(StreakRecord data) + { + _dailyStreak = data; + } + }); + + _repository.getVoteStreakRecord(new Callback() + { + @Override + public void run(StreakRecord data) + { + _voteStreak = data; + } + }); + } + + public StreakRecord getDailyStreak() + { + return _dailyStreak; + } + + public StreakRecord getVoteStreak() + { + return _voteStreak; + } + + public void handleVote(Player player) + { + Bukkit.broadcastMessage("Recieved Vote: " + player.getName()); + } + // DAILY BONUS public static final long TIME_BETWEEN_BONUSES = 1000 * 60 * 60 * 20; @@ -186,6 +243,41 @@ public class BonusManager extends MiniClientPlugin implements I } }); } + + public void attemptCarlSpin(final Player player) + { + final BonusClientData clientData = Get(player); + + if (clientData.getTickets() > 0) + { + clientData.setTickets(clientData.getTickets() - 1); + + runAsync(new Runnable() + { + @Override + public void run() + { + int modified = clientData.getRecord().store(); + + if (modified == 1) + { + runSync(new Runnable() + { + @Override + public void run() + { + new SpinGui(getPlugin(), player, _rewardManager).openInventory(); + } + }); + } + else + { + UtilPlayer.message(player, F.main("Carl", "There was an error processing your request")); + } + } + }); + } + } public long timeTillRankBonus(Player player) { @@ -275,8 +367,6 @@ public class BonusManager extends MiniClientPlugin implements I { BonusAmount amount = new BonusAmount(); amount.setTickets(1); - amount.setBonusCoins(100); - amount.setBonusExperience(100); return amount; } @@ -330,7 +420,7 @@ public class BonusManager extends MiniClientPlugin implements I public void awardBonus(final Player player, BonusAmount amount) { - BonusClientData bonusClient = Get(player); + final BonusClientData bonusClient = Get(player); CoreClient coreClient = _clientManager.Get(player); final int gems = amount.getTotalGems(); @@ -399,7 +489,14 @@ public class BonusManager extends MiniClientPlugin implements I if (tickets > 0) { bonusClient.setTickets(tickets + bonusClient.getTickets()); - // TODO database save + runAsync(new Runnable() + { + @Override + public void run() + { + bonusClient.getRecord().store(); + } + }); UtilPlayer.message(player, F.main("Bonus", "Rewarded " + F.elem(tickets + " Carl Spin Ticket"))); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java index 070e4aec0..8fcc95d6d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java @@ -16,6 +16,8 @@ import mineplex.core.recharge.Recharge; import mineplex.database.Tables; import mineplex.database.tables.records.BonusRecord; import org.jooq.DSLContext; +import org.jooq.Record2; +import org.jooq.TableField; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -57,6 +59,42 @@ public class BonusRepository extends RepositoryBase return record; } + public void getDailyStreakRecord(Callback callback) + { + getStreakRecord(Tables.bonus.maxDailyStreak, callback); + } + + public void getVoteStreakRecord(Callback callback) + { + getStreakRecord(Tables.bonus.maxVoteStreak, callback); + } + + private void getStreakRecord(final TableField field, final Callback callback) + { + Bukkit.getScheduler().runTaskAsynchronously(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + final Record2 record = jooq().select(Tables.accounts.name, field) + .from(Tables.bonus.join(Tables.accounts).on(Tables.bonus.accountId.eq(Tables.accounts.id))) + .orderBy(field.desc()).limit(1).fetchOne(); + + Bukkit.getScheduler().runTask(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + if (record.value1() != null && record.value2() != null) + { + callback.run(new StreakRecord(record.value1(), record.value2())); + } + } + }); + } + }); + } + public void attemptDailyBonus(final Player player, final Callback result) { if (!Recharge.Instance.usable(player, "AttemptDailyBonus")) { @@ -123,6 +161,33 @@ public class BonusRepository extends RepositoryBase }); } + @Deprecated + public void attemptPurchaseSpin(final Player player, final Callback result) + { + final int accountId = _manager.getClientManager().Get(player).getAccountId(); + + Bukkit.getScheduler().runTaskAsynchronously(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + final int newTickets = jooq().update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.sub(-1)). + where(Tables.bonus.accountId.eq(accountId)).returning(Tables.bonus.tickets).fetchOne().getTickets(); + + Bukkit.getScheduler().runTask(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + + + } + }); + + } + }); + } + public void attemptRankBonus(final Player player, final Callback result) { if (!Recharge.Instance.usable(player, "AttemptRankBonus")) { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/StreakRecord.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/StreakRecord.java new file mode 100644 index 000000000..901ef4ad6 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/StreakRecord.java @@ -0,0 +1,23 @@ +package mineplex.hub.bonuses; + +public class StreakRecord +{ + private String _playerName; + private int _streak; + + public StreakRecord(String playerName, int streak) + { + _playerName = playerName; + _streak = streak; + } + + public String getPlayerName() + { + return _playerName; + } + + public int getStreak() + { + return _streak; + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/VoteHandler.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/VoteHandler.java new file mode 100644 index 000000000..73e11305b --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/VoteHandler.java @@ -0,0 +1,31 @@ +package mineplex.hub.bonuses; + +import org.bukkit.entity.Player; + +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.votifier.VotifierCommand; +import mineplex.serverdata.commands.CommandCallback; +import mineplex.serverdata.commands.ServerCommand; + +public class VoteHandler implements CommandCallback +{ + private BonusManager _bonusManager; + + public VoteHandler(BonusManager bonusManager) + { + _bonusManager = bonusManager; + } + + @Override + public void run(ServerCommand command) + { + VotifierCommand v = ((VotifierCommand) command); + + Player player = UtilPlayer.searchExact(v.getPlayerName()); + + if (player != null) + { + _bonusManager.handleVote(player); + } + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java index 083288461..65aa961cf 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java @@ -28,7 +28,7 @@ public class BonusGui extends SimpleGui setItem(15, new DailyBonusButton(getPlugin(), player, this, manager)); - setItem(31, new CarlSpinButton(getPlugin(), player, rewardManager)); + setItem(31, new CarlSpinButton(getPlugin(), player, manager, rewardManager)); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java index e91626a23..c68f95814 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java @@ -1,5 +1,7 @@ package mineplex.hub.bonuses.gui.buttons; +import java.util.ArrayList; + import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -7,22 +9,25 @@ import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; +import mineplex.core.common.util.C; import mineplex.core.gui.GuiItem; import mineplex.core.reward.RewardManager; import mineplex.core.shop.item.ShopItem; -import mineplex.hub.bonuses.gui.SpinGui; +import mineplex.hub.bonuses.BonusClientData; +import mineplex.hub.bonuses.BonusManager; public class CarlSpinButton implements GuiItem { - private Plugin _plugin; private Player _player; + private BonusManager _bonusManager; private RewardManager _rewardManager; - public CarlSpinButton(Plugin plugin, Player player, RewardManager rewardManager) + public CarlSpinButton(Plugin plugin, Player player, BonusManager bonusManager, RewardManager rewardManager) { _plugin = plugin; _player = player; + _bonusManager = bonusManager; _rewardManager = rewardManager; } @@ -40,14 +45,40 @@ public class CarlSpinButton implements GuiItem @Override public void click(ClickType clickType) { - new SpinGui(_plugin, _player, _rewardManager).openInventory(); + BonusClientData client = _bonusManager.Get(_player); + int tickets = client.getTickets(); + + if (tickets > 0) + { + _bonusManager.attemptCarlSpin(_player); + } +// new SpinGui(_plugin, _player, _rewardManager).openInventory(); } @Override public ItemStack getObject() { - ShopItem item = new ShopItem(Material.SKULL_ITEM, (byte) 4, "Carl's Spinner", new String[] {ChatColor.RESET + "Try your Luck!" }, 1, false, false); + BonusClientData client = _bonusManager.Get(_player); + int tickets = client.getTickets(); - return item; + String name = (tickets > 0 ? C.cGreen : C.cRed) + C.Bold + "Carl's Spinner"; + ArrayList lore = new ArrayList(); + Material material = Material.SKULL_ITEM; + byte data = (byte) 4; + + lore.add(" "); + if (tickets > 0) + { + lore.add(ChatColor.RESET + "Click to Spin"); + } + else + { + lore.add(ChatColor.RESET + "You need a Carl Spin Ticket to Spin"); + } + + lore.add(" "); + lore.add(ChatColor.YELLOW + "Your Tickets: " + C.cWhite + tickets); + + return new ShopItem(material, data, name, lore.toArray(new String[0]), 1, false, false); } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java index 4554c8a58..f6534589d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java @@ -19,6 +19,7 @@ import mineplex.core.updater.event.UpdateEvent; import mineplex.hub.bonuses.BonusAmount; import mineplex.hub.bonuses.BonusClientData; import mineplex.hub.bonuses.BonusManager; +import mineplex.hub.bonuses.StreakRecord; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -139,6 +140,7 @@ public class DailyBonusButton implements GuiItem, Listener BonusAmount bonusAmount = _bonusManager.getDailyBonusAmount(_player); bonusAmount.addLore(lore); + lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getDailyStreak()); lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxDailyStreak()); @@ -154,9 +156,13 @@ public class DailyBonusButton implements GuiItem, Listener } } - lore.add(" "); - lore.add(C.cYellow + "Record Holder: " + C.cWhite + "Phinary"); - lore.add(C.cYellow + "Streak: " + C.cWhite + "420"); + StreakRecord streakRecord = _bonusManager.getDailyStreak(); + if (streakRecord != null) + { + lore.add(" "); + lore.add(C.cYellow + "Record: " + C.cWhite + streakRecord.getPlayerName()); + lore.add(C.cYellow + "Streak: " + C.cWhite + streakRecord.getStreak()); + } _item = new ShopItem(material, itemName, lore.toArray(new String[0]), 1, false, false); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java index 0552203d7..54021b6f2 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java @@ -17,6 +17,8 @@ import mineplex.core.updater.event.UpdateEvent; import mineplex.hub.bonuses.BonusAmount; import mineplex.hub.bonuses.BonusClientData; import mineplex.hub.bonuses.BonusManager; +import mineplex.hub.bonuses.StreakRecord; + import net.minecraft.server.v1_7_R4.ChatSerializer; import net.minecraft.server.v1_7_R4.IChatBaseComponent; import net.minecraft.server.v1_7_R4.PacketPlayOutChat; @@ -134,6 +136,7 @@ public class VoteButton implements GuiItem, Listener { BonusAmount bonusAmount = _bonusManager.getVoteBonusAmount(_player); bonusAmount.addLore(lore); + lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getVoteStreak()); lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxVoteStreak()); @@ -149,9 +152,13 @@ public class VoteButton implements GuiItem, Listener { } } - lore.add(" "); - lore.add(C.cYellow + "Record Holder: " + C.cWhite + "Phinary"); - lore.add(C.cYellow + "Streak: " + C.cWhite + "420"); + StreakRecord streakRecord = _bonusManager.getVoteStreak(); + if (streakRecord != null) + { + lore.add(" "); + lore.add(C.cYellow + "Record: " + C.cWhite + streakRecord.getPlayerName()); + lore.add(C.cYellow + "Streak: " + C.cWhite + streakRecord.getStreak()); + } _item = new ShopItem(material, itemName, lore.toArray(new String[0]), 1, false, false); } diff --git a/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml b/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml index 8d37a4051..b7d71d202 100644 --- a/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml +++ b/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml @@ -16,6 +16,7 @@ + diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index 30646a1f5..ecef96339 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -8,27 +8,63 @@ import com.vexsoftware.votifier.model.VotifierEvent; import mineplex.core.MiniPlugin; import mineplex.core.account.CoreClientManager; import mineplex.core.donation.DonationManager; -import mineplex.core.votifier.RedisVotifierCommand; +import mineplex.core.votifier.VotifierCommand; +import mineplex.serverdata.Region; +import mineplex.serverdata.commands.ServerCommandManager; +import mineplex.serverdata.data.PlayerStatus; +import mineplex.serverdata.redis.RedisDataRepository; +import mineplex.serverdata.servers.ServerManager; /** * Created by shaun on 15-08-05. */ public class VotifierManager extends MiniPlugin { + private RedisDataRepository _usPlayerRepo; + private RedisDataRepository _euPlayerRepo; + public VotifierManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager) { super("Votifier", plugin); + + _usPlayerRepo = new RedisDataRepository(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(), + Region.US, PlayerStatus.class, "playerStatus"); + _euPlayerRepo = new RedisDataRepository(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(), + Region.EU, PlayerStatus.class, "playerStatus"); + + ServerCommandManager.getInstance().registerCommandType("VotifierCommand", VotifierCommand.class); } - - @EventHandler public void handleVote(VotifierEvent event) { Vote vote = event.getVote(); - RedisVotifierCommand command = new RedisVotifierCommand(); - System.out.println("New Vote: " + vote.getUsername()); + + PlayerStatus usStatus = _usPlayerRepo.getElement(vote.getUsername()); +// VotifierCommand command = new VotifierCommand(vote.getUsername(), "PhiTest-1"); +// command.publish(); + + if (usStatus != null) + { + System.out.println("Found on US Server: " + usStatus.getServer()); + VotifierCommand command = new VotifierCommand(vote.getUsername(), usStatus.getServer()); + command.publish(); + } + else + { + System.out.println("Not found on US Server!"); + } + + PlayerStatus euStatus = _euPlayerRepo.getElement(vote.getUsername()); + if (euStatus != null) + { + System.out.println("Found on EU Server: " + euStatus.getServer()); + } + else + { + System.out.println("Not found on EU Server!"); + } } } \ No newline at end of file From 328c31de885a1be7b73bfcf5f52485a2235a0a53 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Sat, 8 Aug 2015 13:47:09 +0200 Subject: [PATCH 271/377] hub Update fixed bad gameid --- .../core/cosmetic/ui/page/GadgetPage.java | 8 + .../mineplex/core/gadget/GadgetManager.java | 1 + .../core/gadget/gadgets/ItemDuelingSword.java | 66 ++- .../core/gadget/gadgets/ItemKothSword.java | 5 + .../core/gadget/gadgets/ItemPaintbrush.java | 12 +- .../core/gadget/gadgets/MorphWither.java | 2 +- .../core/gadget/gadgets/OutfitTeam.java | 35 +- .../src/mineplex/core/game/GameDisplay.java | 4 +- .../src/mineplex/hub/HubManager.java | 18 +- .../src/mineplex/hub/modules/KothManager.java | 266 ++++++++++++ .../mineplex/hub/modules/SoccerManager.java | 2 +- .../hub/modules/koth/CapturePoint.java | 389 ++++++++++++++++++ 12 files changed, 745 insertions(+), 63 deletions(-) create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemKothSword.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/modules/koth/CapturePoint.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/GadgetPage.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/GadgetPage.java index af8b2e9f8..1189a4162 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/GadgetPage.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/ui/page/GadgetPage.java @@ -44,6 +44,9 @@ public class GadgetPage extends ShopPageBase for (Gadget gadget : getPlugin().getGadgetManager().getGadgets(GadgetType.Item)) { + if (gadget.GetCost(CurrencyType.Coins) == -3) + continue; + addGadget(gadget, slot); if (getPlugin().getInventoryManager().Get(getPlayer()).getItemCount(gadget.GetDisplayName()) > 0) @@ -88,6 +91,11 @@ public class GadgetPage extends ShopPageBase { itemLore.add(C.cGold + "Found in Treasure Chests."); } + else if (gadget.GetCost(CurrencyType.Coins) == -3) + { + + } + itemLore.add(C.cBlack); itemLore.addAll(Arrays.asList(gadget.GetDescription())); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java index a5af05afb..3c518f35a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java @@ -96,6 +96,7 @@ public class GadgetManager extends MiniPlugin addGadget(new ItemBatGun(this)); addGadget(new ItemCoinBomb(this)); addGadget(new ItemPaintbrush(this)); + addGadget(new ItemDuelingSword(this)); // Costume addGadget(new OutfitRaveSuit(this, "Rave Hat", -2, ArmorSlot.Helmet, Material.LEATHER_HELMET, (byte)0)); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemDuelingSword.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemDuelingSword.java index 7d56300dd..94d4bfea3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemDuelingSword.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemDuelingSword.java @@ -1,66 +1,48 @@ package mineplex.core.gadget.gadgets; -import java.util.HashSet; - import org.bukkit.Material; -import org.bukkit.entity.Bat; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.event.player.PlayerInteractEvent; import mineplex.core.common.util.C; -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilGear; -import mineplex.core.common.util.UtilPlayer; import mineplex.core.gadget.GadgetManager; import mineplex.core.gadget.types.ItemGadget; +import mineplex.core.itemstack.ItemStackFactory; public class ItemDuelingSword extends ItemGadget { public ItemDuelingSword(GadgetManager manager) { - super(manager, "Dueling Sword", new String[] + super(manager, "PvP Sword", new String[] { - C.cWhite + "While active, you are able to fight", - C.cWhite + "against other people who are also", - C.cWhite + "wielding a dueling sword.", + C.cGreen + "Activated in King of the Hill", }, - -1, - Material.WOOD_SWORD, (byte)3, + -3, + Material.GOLD_SWORD, (byte)0, 1000, new Ammo("Dueling Sword", "10 Swords", Material.WOOD_SWORD, (byte)0, new String[] { C.cWhite + "10 Swords to duel with" }, 1000, 10)); } + + @Override + public void ApplyItem(Player player, boolean inform) + { + Manager.RemoveItem(player); + + _active.add(player); + + player.getInventory().setItem(Manager.getActiveItemSlot(), ItemStackFactory.Instance.CreateStack(Material.GOLD_SWORD, (byte)0, 1, "PvP Sword")); + } + + @Override + @EventHandler + public void Activate(PlayerInteractEvent event) + { + + } @Override public void ActivateCustom(Player player) - { - ItemStack stack = new ItemStack(Material.GOLD_SWORD); - ItemMeta meta = stack.getItemMeta(); - meta.setDisplayName("Dueling Sword"); - stack.setItemMeta(meta); + { - player.getInventory().setItem(Manager.getActiveItemSlot(), stack); - - //Inform - UtilPlayer.message(player, F.main("Skill", "You used " + F.skill(GetName()) + ".")); - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void damage(EntityDamageByEntityEvent event) - { - if (!(event.getEntity() instanceof Player) || !(event.getDamager() instanceof Player)) - return; - - Player damager = (Player)event.getDamager(); - Player damagee = (Player)event.getEntity(); - - if (!UtilGear.isMat(damager.getItemInHand(), Material.GOLD_SWORD) || !UtilGear.isMat(damagee.getItemInHand(), Material.GOLD_SWORD)) - return; - - event.setCancelled(false); - - event.setDamage(4); } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemKothSword.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemKothSword.java new file mode 100644 index 000000000..6bb5d66a0 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemKothSword.java @@ -0,0 +1,5 @@ +package mineplex.core.gadget.gadgets; + +public class ItemKothSword { + +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java index e48eba5f7..80e91b5ad 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java @@ -41,9 +41,9 @@ public class ItemPaintbrush extends ItemGadget { C.cWhite + "Unleash your inner creativity!", C.cWhite + "", - C.cWhite + "Click a Painter NPC to equip this.", + C.cGreen + "Activated at a Painter NPC", }, - -2, + -3, Material.WOOD_SWORD, (byte)0, 200, new Ammo("Paint", "100 Pixels", Material.INK_SACK, (byte)0, new String[] { C.cWhite + "100 Pixels worth of Paint!" }, 500, 100)); } @@ -100,11 +100,11 @@ public class ItemPaintbrush extends ItemGadget { if (!IsActive(event.getPlayer())) return; - - if (!UtilEvent.isAction(event, ActionType.L)) - return; - + Player player = event.getPlayer(); + + if (!UtilGear.isMat(player.getItemInHand(), Material.WOOD_SWORD)) + return; Block block = player.getTargetBlock(null, 100); if (block == null || block.getType() != Material.STAINED_CLAY) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/MorphWither.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/MorphWither.java index a7ad7610a..da9d82ebd 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/MorphWither.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/MorphWither.java @@ -146,7 +146,7 @@ public class MorphWither extends MorphGadget { WitherSkull skull = skullIterator.next(); - if (!skull.isValid()) + if (!skull.isValid() || skull.getTicksLived() > 60) { skullIterator.remove(); skull.remove(); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java index 34fd99802..697f398c4 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java @@ -71,6 +71,18 @@ public class OutfitTeam extends OutfitGadget else if (_slot == ArmorSlot.Boots) player.getInventory().setBoots( ItemStackFactory.Instance.CreateStack(GetDisplayMaterial().getId(), GetDisplayData(), 1, GetName())); } + + @Override + public void RemoveArmor(Player player) + { + if (!_active.remove(player)) + return; + + if (_slot == ArmorSlot.Helmet) player.getInventory().setHelmet(null); + else if (_slot == ArmorSlot.Chest) player.getInventory().setChestplate(null); + else if (_slot == ArmorSlot.Legs) player.getInventory().setLeggings(null); + else if (_slot == ArmorSlot.Boots) player.getInventory().setBoots(null); + } @Override public void EnableCustom(Player player) @@ -90,7 +102,7 @@ public class OutfitTeam extends OutfitGadget { Player player = event.getPlayer(); - if (!event.getMessage().toLowerCase().startsWith("/team ")) + if (!event.getMessage().toLowerCase().startsWith("/team")) return; event.setCancelled(true); @@ -98,11 +110,24 @@ public class OutfitTeam extends OutfitGadget String[] args = event.getMessage().toLowerCase().split(" "); if (args.length < 2) + { + Disable(player); return; + } + + + //Will only display the message once + if (GetSlot() == ArmorSlot.Legs) + { + if (!Recharge.Instance.use(player, "Set Team Color", 20000, true, false)) + return; + } + else + { + if (!Recharge.Instance.use(player, "Set Team Color " + GetSlot(), 20000, false, false)) + return; + } - if (!Recharge.Instance.use(player, "Set Team Color", 20000, true, false)) - return; - //Color if (args[1].equals("red")) { @@ -132,6 +157,8 @@ public class OutfitTeam extends OutfitGadget if (GetSlot() == ArmorSlot.Legs) //Only Display Once UtilPlayer.message(player, F.main("Gadget", "You equipped " + F.elem(C.cAqua + "Blue Team Outfit") + "!")); } + else + return; colorArmor(player); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/game/GameDisplay.java b/Plugins/Mineplex.Core/src/mineplex/core/game/GameDisplay.java index d8fb8b9f9..37d826e6c 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/game/GameDisplay.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/game/GameDisplay.java @@ -27,7 +27,7 @@ public enum GameDisplay HideSeek("Block Hunt", Material.GRASS, (byte)0, GameCategory.CLASSICS, 20), HoleInTheWall("Hole in the Wall", Material.STAINED_GLASS, (byte) 2, GameCategory.ARCADE, 52), Horse("Horseback", Material.IRON_BARDING, (byte)0, GameCategory.ARCADE, 21), - Lobbers("Bomb Lobbers", Material.FIREBALL, (byte) 0, GameCategory.ARCADE, 53), + Micro("Micro Battle", Material.LAVA_BUCKET, (byte)0, GameCategory.ARCADE, 24), MilkCow("Milk the Cow", Material.MILK_BUCKET, (byte)0, GameCategory.ARCADE, 27), MineStrike("MineStrike", Material.TNT, (byte)0, GameCategory.CHAMPIONS, 25),// Temp set to CHAMPIONS to fix UI bug @@ -63,6 +63,8 @@ public enum GameDisplay Cards("Craft Against Humanity", Material.MAP, (byte)0, GameCategory.CLASSICS, 51), Skywars("Skywars", Material.FEATHER, (byte) 0, GameCategory.SURVIVAL, 52), SkywarsTeams("Skywars Teams", "Skywars", Material.FEATHER, (byte)0, GameCategory.TEAM_VARIANT, 53), + + Lobbers("Bomb Lobbers", Material.FIREBALL, (byte) 0, GameCategory.ARCADE, 54), Event("Mineplex Event", Material.CAKE, (byte)0, GameCategory.EVENT, 999); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index dc6b3fe59..65e2ae685 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -55,6 +55,7 @@ import mineplex.hub.commands.NewsCommand; import mineplex.hub.modules.ForcefieldManager; import mineplex.hub.modules.HubVisibilityManager; import mineplex.hub.modules.JumpManager; +import mineplex.hub.modules.KothManager; import mineplex.hub.modules.NewsManager; import mineplex.hub.modules.ParkourManager; import mineplex.hub.modules.SoccerManager; @@ -184,6 +185,7 @@ public class HubManager extends MiniClientPlugin new CosmeticManager(_plugin, clientManager, donationManager, _inventoryManager, _gadgetManager, _mountManager, petManager, _treasureManager); new SoccerManager(this, _gadgetManager); + new KothManager(this, _gadgetManager); _petManager = petManager; _partyManager = partyManager; @@ -600,14 +602,6 @@ public class HubManager extends MiniClientPlugin } } - - @EventHandler - public void PlayerDeath(PlayerDeathEvent event) - { - //XXX make this work > event.setKeepInventory(true); - event.getDrops().clear(); - } - @EventHandler public void PlayerQuit(PlayerQuitEvent event) { @@ -734,6 +728,14 @@ public class HubManager extends MiniClientPlugin event.setCancelled(true); } + @EventHandler(priority = EventPriority.LOWEST) + public void handleDeath(PlayerDeathEvent event) + { + event.setKeepInventory(true); + event.getDrops().clear(); + event.getEntity().setHealth(20); + event.getEntity().teleport(GetSpawn()); + } @EventHandler public void FoodHealthUpdate(UpdateEvent event) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java new file mode 100644 index 000000000..3e6440983 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java @@ -0,0 +1,266 @@ +package mineplex.hub.modules; + +import java.util.ArrayList; +import java.util.HashSet; + +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.event.GadgetActivateEvent; +import mineplex.core.gadget.gadgets.ItemDuelingSword; +import mineplex.core.gadget.gadgets.OutfitTeam; +import mineplex.core.gadget.types.Gadget; +import mineplex.core.gadget.types.GadgetType; +import mineplex.core.mount.event.MountActivateEvent; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.HubManager; +import mineplex.hub.modules.koth.CapturePoint; + +public class KothManager extends MiniPlugin +{ + public HubManager Manager; + + private HashSet _active = new HashSet(); + + private ArrayList _teamArmor = new ArrayList(); + private ItemDuelingSword _kothSword; + + private Location _cornerPlayerA; + private Location _cornerPlayerB; + + private Location _cornerHillA; + private Location _cornerHillB; + + private CapturePoint _cp; + + Color _hillOwner = null; + long _hillOwnTime = 0; + + public KothManager(HubManager manager, GadgetManager gadgets) + { + super("KOTH Manager", manager.getPlugin()); + + Manager = manager; + + _cornerPlayerA = new Location(Manager.GetSpawn().getWorld(), -52.5,0,-23.5); + _cornerPlayerB = new Location(Manager.GetSpawn().getWorld(), -133.5,200,80.5); + + _cornerHillA = new Location(Manager.GetSpawn().getWorld(), -88.5,60,47.5); + _cornerHillB = new Location(Manager.GetSpawn().getWorld(), -102.5,80,61.5); + + _cp = new CapturePoint(this, "Desert Pyramid", new Location(Manager.GetSpawn().getWorld(), -95.5,72,54.5)); + + //Store Gadgets + for (Gadget gadget : gadgets.getGadgets(GadgetType.Costume)) + { + if (gadget instanceof OutfitTeam) + { + _teamArmor.add((OutfitTeam)gadget); + } + } + + for (Gadget gadget : gadgets.getGadgets(GadgetType.Item)) + { + if (gadget instanceof ItemDuelingSword) + { + _kothSword = (ItemDuelingSword)gadget; + } + } + } + + @EventHandler + public void cpUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + return; + + _cp.captureUpdate(); + } + + public Color getTeamColor(Player player) + { + //All peices are always same color! + for (OutfitTeam outfit : _teamArmor) + { + return outfit.getTeamColor(player); + } + + return null; + } + + public boolean inPlayerArena(Entity entity) + { + return UtilAlg.inBoundingBox(entity.getLocation(), _cornerPlayerA, _cornerPlayerB); + } + + @EventHandler + public void joinLeaveGame(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + for (Player player : UtilServer.getPlayers()) + { + if (_active.contains(player)) + { + if (!inPlayerArena(player)) + { + setKOTHMode(player, false, null); + continue; + } + + //Took armor off + Color color = getTeamColor(player); + if (color == null) + { + setKOTHMode(player, false, null); + } + } + else + { + if (inPlayerArena(player)) + { + Color color = getTeamColor(player); + + //Join + if (color != null) + { + setKOTHMode(player, true, color); + continue; + } + //Eject + else if (UtilAlg.inBoundingBox(player.getLocation(), _cornerHillA, _cornerHillB)) + { + Location bounce = UtilAlg.getMidpoint(_cornerHillA, _cornerHillB); + bounce.setY(Math.min(_cornerHillA.getY(), _cornerHillB.getY())); + + Entity bottom = player; + if (bottom.getVehicle() != null) + bottom = bottom.getVehicle(); + + UtilAction.velocity(bottom, UtilAlg.getTrajectory(bounce, player.getLocation()), 1, false, 0, 0.4, 1, true); + + if (Recharge.Instance.use(player, "KOTH Eject", 5000, false, false)) + { + UtilPlayer.message(player, F.main("Football", "You must be wearing a Team Outfit.")); + UtilPlayer.message(player, F.main("Football", "Type " + F.elem("/team red|yellow|green|blue") + "!")); + } + } + } + } + } + } + + public void setKOTHMode(Player player, boolean enabled, Color color) + { + if (enabled) + { + _kothSword.Enable(player); + + _active.add(player); + + if (color == null) + UtilPlayer.message(player, F.main("Parkour", "You have entered " + F.elem("KOTH Mode") + ".")); + else if (color == Color.RED) + UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cRed + "Red KOTH Team") + ".")); + else if (color == Color.AQUA) + UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cAqua + "Blue KOTH Team") + ".")); + else if (color == Color.LIME) + UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cGreen + "Green KOTH Team") + ".")); + else if (color == Color.YELLOW) + UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cYellow + "Yellow KOTH Team") + ".")); + + ArrayList outfit = new ArrayList(); + outfit.add("Team Helmet"); + outfit.add("Team Shirt"); + outfit.add("Team Pants"); + outfit.add("Team Boots"); + outfit.add("PvP Sword"); + + Manager.GetGadget().DisableAll(player, outfit); + } + else + { + _kothSword.Disable(player); + _active.remove(player); + UtilPlayer.message(player, F.main("Parkour", "You have exited " + F.elem("KOTH Mode") + ".")); + } + } + + public boolean isKothMode(Player player) + { + return _active.contains(player); + } + + @EventHandler + public void disableGadgets(GadgetActivateEvent event) + { + if (isKothMode(event.getPlayer())) + event.setCancelled(true); + } + + @EventHandler + public void disableMounts(MountActivateEvent event) + { + if (isKothMode(event.getPlayer())) + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void disableStacker(PlayerInteractEntityEvent event) + { + if (_active.contains(event.getPlayer())) + event.setCancelled(true); + } + + @EventHandler + public void playerQuit(PlayerQuitEvent event) + { + _active.remove(event.getPlayer()); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void allowDamage(EntityDamageByEntityEvent event) + { + if (!(event.getEntity() instanceof Player) || !(event.getDamager() instanceof Player)) + return; + + Player damager = (Player)event.getDamager(); + Player damagee = (Player)event.getEntity(); + + if (!_active.contains(damager) || !_active.contains(damagee)) + return; + + if (getTeamColor(damager) == null || getTeamColor(damagee) == null) + return; + + if (getTeamColor(damager) == getTeamColor(damagee)) + return; + + event.setCancelled(false); + + event.setDamage(3.5); + } + + public HashSet getActive() + { + return _active; + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java index db273a153..4f8c51c8d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -195,7 +195,7 @@ public class SoccerManager extends MiniPlugin if (UtilEnt.isGrounded(_ball) && _ballVel.getY() <= 0) _ballVel.setY(0); - _ballVel.setY(Math.min(_ballVel.getY(), 0.8)); + _ballVel.setY(Math.min(_ballVel.getY(), 1)); _ball.getWorld().playSound(_ball.getLocation(), Sound.ZOMBIE_WOOD, 0.5f, 1.5f); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/koth/CapturePoint.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/koth/CapturePoint.java new file mode 100644 index 000000000..d9355fc44 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/koth/CapturePoint.java @@ -0,0 +1,389 @@ +package mineplex.hub.modules.koth; + +import java.util.ArrayList; +import java.util.Collection; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.hub.modules.KothManager; + +import org.bukkit.Color; +import org.bukkit.Effect; +import org.bukkit.FireworkEffect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; + +public class CapturePoint +{ + private KothManager Host; + + private String _name; + + //Locations + private ArrayList _floor = new ArrayList(); + private ArrayList _indicators = new ArrayList(); + private Location _loc; + + //Capture + private double _captureMax = 24; + private double _captureRate = 1; + private double _captureAmount = 0; + + private Color _owner = null; + private boolean _captured = false; + + private ArrayList _captureFloor = new ArrayList(); + private long _decayDelay = 0; + + private int _indicatorTick = 0; + + public CapturePoint(KothManager host, String name, Location loc) + { + Host = host; + + _name = name; + + for (int x=-3 ; x<= 3 ; x++) + { + for (int z=-3 ; z<= 3 ; z++) + { + //Indicators + if (Math.abs(x) == 3 && Math.abs(z) == 3) + { + Block ind = loc.getBlock().getRelative(x, 3, z); + ind.setType(Material.WOOL); + ind.setData((byte) 0); + _indicators.add(ind); + } + + //Floors + if (Math.abs(x) <= 2 && Math.abs(z) <= 2) + { + if (x != 0 || z != 0) + { + Block floor = loc.getBlock().getRelative(x, -2, z); + floor.setType(Material.WOOL); + _floor.add(floor); + } + else + { + Block block = loc.getBlock().getRelative(x, -2, z); + block.setType(Material.BEACON); + } + } + + //Glass + if (Math.abs(x) <= 2 && Math.abs(z) <= 2) + { + Block block = loc.getBlock().getRelative(x, -1, z); + block.setType(Material.STAINED_GLASS); + } + + //Iron + if (Math.abs(x) <= 1 && Math.abs(z) <= 1) + { + Block block = loc.getBlock().getRelative(x, -3, z); + block.setType(Material.IRON_BLOCK); + } + } + } + + //Firework + _loc = loc; + } + + public void captureUpdate() + { + //Who's on the CP? + ArrayList red = new ArrayList(); + ArrayList yellow = new ArrayList(); + ArrayList green = new ArrayList(); + ArrayList blue = new ArrayList(); + + ArrayList players = new ArrayList(); + + for (Player player : Host.getActive()) + { + Color team = Host.getTeamColor(player); + + if (team == null) + continue; + + if (Math.abs(_loc.getX() - player.getLocation().getX()) > 2.5) + continue; + + if (Math.abs(_loc.getY() - player.getLocation().getY()) > 2.5) + continue; + + if (Math.abs(_loc.getZ() - player.getLocation().getZ()) > 2.5) + continue; + + if (team == Color.RED) + { + red.add(player); + } + else if (team == Color.YELLOW) + { + yellow.add(player); + } + else if (team == Color.LIME) + { + green.add(player); + } + else if (team == Color.AQUA) + { + blue.add(player); + } + + players.add(player); + } + + //No one around (DEGENERATE CAPTURE) + if (players.isEmpty()) + { + if (_captureAmount > 0) + regenDegen(); + + return; + } + + //Capture + if (red.size() > players.size() - red.size()) + capture(Color.RED, red.size() - (players.size() - red.size()), red); + + else if (yellow.size() > players.size() - yellow.size()) + capture(Color.YELLOW, yellow.size() - (players.size() - yellow.size()), yellow); + + else if (green.size() > players.size() - green.size()) + capture(Color.LIME, green.size() - (players.size() - green.size()), green); + + else if (blue.size() > players.size() - blue.size()) + capture(Color.AQUA, blue.size() - (players.size() - blue.size()), blue); + } + + private void regenDegen() + { + if (!UtilTime.elapsed(_decayDelay, 1000)) + return; + + //Degen + if (!_captured || Host.getActive().isEmpty()) + { + _captureAmount = Math.max(0, (_captureAmount - (_captureRate*1))); + + //Floor Color + while ((double)_captureFloor.size()/((double)_captureFloor.size() + (double)_floor.size()) > _captureAmount/_captureMax) + { + Block block = _captureFloor.remove(UtilMath.r(_captureFloor.size())); + + _floor.add(block); + + setWoolColor(block, null, false); + } + + //Set Uncaptured + if (_captureAmount == 0) + { + _owner = null; + + _loc.getBlock().getRelative(BlockFace.DOWN).setData((byte)0); + + //Indicators + for (Block block : _indicators) + { + block.setData((byte)0); + } + } + + //Effect + for (Block block : _indicators) + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, 35); + } + //Regen + else if (_captureAmount < _captureMax) + { + _captureAmount = Math.min(_captureMax, (_captureAmount + (_captureRate*1))); + + //Floor Color + while ((double)_captureFloor.size()/((double)_captureFloor.size() + (double)_floor.size()) < _captureAmount/_captureMax) + { + Block block = _floor.remove(UtilMath.r(_floor.size())); + + _captureFloor.add(block); + + setWoolColor(block, _owner, false); + } + + //Effect + indicate(_owner); + } + } + + private void capture(Color team, int count, Collection capturers) + { + //Decay Delay + _decayDelay = System.currentTimeMillis(); + + //Count Up + if (_owner != null && _owner.equals(team)) + { + //Given if the other team hadnt actually captured it fully + int bonus = 0; + if (_captured) + bonus = 1; + + _captureAmount = Math.min(_captureMax, (_captureAmount + ((_captureRate*count)+bonus))); + + //Floor Color + while ((double)_captureFloor.size()/((double)_captureFloor.size() + (double)_floor.size()) < _captureAmount/_captureMax) + { + Block block = _floor.remove(UtilMath.r(_floor.size())); + + _captureFloor.add(block); + + setWoolColor(block, team, false); + } + + //Set Fully Captured + if (_captureAmount == _captureMax && !_captured) + { + _captured = true; + + //Firework + UtilFirework.playFirework(_loc, FireworkEffect.builder().flicker(true).withColor(team).with(Type.BALL_LARGE).trail(true).build()); + + //Indicators + indicate(team); + + for (Block block : _indicators) + { + if (team == Color.RED) + block.setData((byte) 14); + else if (team == Color.YELLOW) + block.setData((byte) 4); + else if (team == Color.LIME) + block.setData((byte) 5); + else if (team == Color.AQUA) + block.setData((byte) 3); + } + + //Center + setWoolColor(_loc.getBlock().getRelative(0, -2, 0), _owner, true); + + String teamName = C.cRed + "Red"; + if (team == Color.YELLOW) teamName = C.cYellow + "Yellow"; + if (team == Color.LIME) teamName = C.cGreen + "Green"; + if (team == Color.AQUA) teamName = C.cAqua + "Blue"; + + for (Player player : Host.getActive()) + UtilTextMiddle.display("KOTH", teamName + " Team captured the Hill!", 0, 60, 10, player); + } + } + //Count Down + else + { + //Given if the other team hadnt actually captured it fully + int bonus = 0; + if (!_captured) + bonus = 1; + + _captureAmount = Math.max(0, (_captureAmount - ((_captureRate*count)+bonus))); + + //Floor Color + while ((double)_captureFloor.size()/((double)_captureFloor.size() + (double)_floor.size()) > _captureAmount/_captureMax) + { + Block block = _captureFloor.remove(UtilMath.r(_captureFloor.size())); + + _floor.add(block); + + setWoolColor(block, null, false); + } + + //Set Uncaptured + if (_captureAmount == 0) + { + _captured = false; + _owner = team; + + //Center + setWoolColor(_loc.getBlock().getRelative(0, -2, 0), null, true); + + //Indicators + for (Block block : _indicators) + { + block.setData((byte)0); + } + } + } + + if (_captureAmount != _captureMax) + { + indicate(team); + } + + } + + private void setWoolColor(Block block, Color color, boolean glassOnly) + { + System.out.println(color == null ? "null" : color.toString()); + + if (color == null) + { + if (!glassOnly) + block.setData((byte)0); + + block.getRelative(BlockFace.UP).setTypeIdAndData(95, (byte)0, true); + } + else if (color == Color.RED) + { + if (!glassOnly) + block.setData((byte)14); + + block.getRelative(BlockFace.UP).setTypeIdAndData(95, (byte)14, true); + } + else if (color == Color.YELLOW) + { + if (!glassOnly) + block.setData((byte)4); + + block.getRelative(BlockFace.UP).setTypeIdAndData(95, (byte)4, true); + } + else if (color == Color.LIME) + { + if (!glassOnly) + block.setData((byte)5); + + block.getRelative(BlockFace.UP).setTypeIdAndData(95, (byte)5, true); + } + else if (color == Color.AQUA) + { + if (!glassOnly) + block.setData((byte)3); + + block.getRelative(BlockFace.UP).setTypeIdAndData(95, (byte)3, true); + } + } + + private void indicate(Color color) + { + //Effect + for (Block block : _indicators) + { + if (color == Color.RED) + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.REDSTONE_BLOCK); + else if (color == Color.YELLOW) + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.GOLD_BLOCK); + else if (color == Color.LIME) + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.EMERALD_BLOCK); + else if (color == Color.AQUA) + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.DIAMOND_BLOCK); + } + } +} From fa7f19bde58dc0e1cfa456a51a758cda45443dcf Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Sat, 8 Aug 2015 13:47:30 +0200 Subject: [PATCH 272/377] removed debug --- .../src/mineplex/hub/modules/koth/CapturePoint.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/koth/CapturePoint.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/koth/CapturePoint.java index d9355fc44..86008c18a 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/koth/CapturePoint.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/koth/CapturePoint.java @@ -332,8 +332,6 @@ public class CapturePoint private void setWoolColor(Block block, Color color, boolean glassOnly) { - System.out.println(color == null ? "null" : color.toString()); - if (color == null) { if (!glassOnly) From e030331565ff82a290c8352d67491914ad66edee Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Sat, 8 Aug 2015 13:51:37 +0200 Subject: [PATCH 273/377] fixed some bugs --- Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java | 3 ++- .../Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java index 3e6440983..bacb4156a 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java @@ -99,7 +99,8 @@ public class KothManager extends MiniPlugin //All peices are always same color! for (OutfitTeam outfit : _teamArmor) { - return outfit.getTeamColor(player); + if (outfit.IsActive(player)) + return outfit.getTeamColor(player); } return null; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java index 4f8c51c8d..d737d65d3 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -322,7 +322,8 @@ public class SoccerManager extends MiniPlugin //All peices are always same color! for (OutfitTeam outfit : _teamArmor) { - return outfit.getTeamColor(player); + if (outfit.IsActive(player)) + return outfit.getTeamColor(player); } return null; From cbb0cb96c8eab6e60a926bb54bcf7b629d035d07 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Sat, 8 Aug 2015 13:54:35 +0200 Subject: [PATCH 274/377] ensured white --- .../src/mineplex/hub/modules/koth/CapturePoint.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/koth/CapturePoint.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/koth/CapturePoint.java index 86008c18a..1a2177ce1 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/koth/CapturePoint.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/koth/CapturePoint.java @@ -70,6 +70,7 @@ public class CapturePoint { Block floor = loc.getBlock().getRelative(x, -2, z); floor.setType(Material.WOOL); + floor.setData((byte) 0); _floor.add(floor); } else @@ -84,6 +85,7 @@ public class CapturePoint { Block block = loc.getBlock().getRelative(x, -1, z); block.setType(Material.STAINED_GLASS); + block.setData((byte) 0); } //Iron From e6519206af6623cd0f16188a3b2c5cac3a39ef61 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Sat, 8 Aug 2015 16:29:03 -0500 Subject: [PATCH 275/377] Add event to be called when a player tries to buy a carl spin --- .../mineplex/hub/bonuses/BonusManager.java | 45 +++++++++------- .../hub/bonuses/event/CarlSpinnerEvent.java | 54 +++++++++++++++++++ 2 files changed, 80 insertions(+), 19 deletions(-) create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/event/CarlSpinnerEvent.java diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index b4bd57948..817db72db 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -25,6 +25,7 @@ import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.core.votifier.VotifierCommand; import mineplex.hub.bonuses.commands.GuiCommand; +import mineplex.hub.bonuses.event.CarlSpinnerEvent; import mineplex.hub.bonuses.gui.BonusGui; import mineplex.database.tables.records.BonusRecord; import mineplex.hub.bonuses.gui.SpinGui; @@ -250,32 +251,38 @@ public class BonusManager extends MiniClientPlugin implements I if (clientData.getTickets() > 0) { - clientData.setTickets(clientData.getTickets() - 1); + CarlSpinnerEvent event = new CarlSpinnerEvent(player); + Bukkit.getServer().getPluginManager().callEvent(event); - runAsync(new Runnable() + if (!event.isCancelled()) { - @Override - public void run() - { - int modified = clientData.getRecord().store(); + clientData.setTickets(clientData.getTickets() - 1); - if (modified == 1) + runAsync(new Runnable() + { + @Override + public void run() { - runSync(new Runnable() + int modified = clientData.getRecord().store(); + + if (modified == 1) { - @Override - public void run() + runSync(new Runnable() { - new SpinGui(getPlugin(), player, _rewardManager).openInventory(); - } - }); + @Override + public void run() + { + new SpinGui(getPlugin(), player, _rewardManager).openInventory(); + } + }); + } + else + { + UtilPlayer.message(player, F.main("Carl", "There was an error processing your request")); + } } - else - { - UtilPlayer.message(player, F.main("Carl", "There was an error processing your request")); - } - } - }); + }); + } } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/event/CarlSpinnerEvent.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/event/CarlSpinnerEvent.java new file mode 100644 index 000000000..fed71229b --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/event/CarlSpinnerEvent.java @@ -0,0 +1,54 @@ +package mineplex.hub.bonuses.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Called when a player attempts to purchase a spin through carl + */ +public class CarlSpinnerEvent extends Event implements Cancellable +{ + private static final HandlerList handlers = new HandlerList(); + + private Player _player; + private boolean _cancelled; + + public CarlSpinnerEvent(Player player) + { + _player = player; + } + + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + + public Player getPlayer() + { + return _player; + } + + public void setPlayer(Player player) + { + _player = player; + } + + @Override + public boolean isCancelled() + { + return _cancelled; + } + + @Override + public void setCancelled(boolean b) + { + _cancelled = b; + } +} From b974fcf838eeac435d9cc42bddde40bff7e7cae2 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Sun, 9 Aug 2015 00:09:26 +0200 Subject: [PATCH 276/377] map parser fixes --- .../src/mineplex/mapparser/GameType.java | 1 + .../src/mineplex/mapparser/MapParser.java | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Plugins/Mineplex.MapParser/src/mineplex/mapparser/GameType.java b/Plugins/Mineplex.MapParser/src/mineplex/mapparser/GameType.java index 7e627f491..7fe8dd6f8 100644 --- a/Plugins/Mineplex.MapParser/src/mineplex/mapparser/GameType.java +++ b/Plugins/Mineplex.MapParser/src/mineplex/mapparser/GameType.java @@ -30,6 +30,7 @@ public enum GameType Halloween("Halloween Horror"), HideSeek("Block Hunt"), Horse("Horseback"), + Lobbers("Bomb Lobbers"), SurvivalGames("Survival Games"), SurvivalGamesTeams("Survival Games Teams"), Micro("Micro Battle"), diff --git a/Plugins/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java b/Plugins/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java index 8e9b39b59..622e7516c 100644 --- a/Plugins/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java +++ b/Plugins/Mineplex.MapParser/src/mineplex/mapparser/MapParser.java @@ -38,6 +38,7 @@ import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; import mineplex.core.common.util.C; import mineplex.core.common.util.Callback; @@ -720,6 +721,7 @@ public class MapParser extends JavaPlugin implements Listener return blocks; } + long lastUse = 0; @EventHandler(priority = EventPriority.LOWEST) public void leaptest(PlayerInteractEvent event) { @@ -730,6 +732,18 @@ public class MapParser extends JavaPlugin implements Listener if (event.getPlayer().getItemInHand().getType() != Material.FEATHER) return; - event.getPlayer().setVelocity(event.getPlayer().getLocation().getDirection().multiply(1.2)); + if (System.currentTimeMillis() - lastUse < 800) + { + Bukkit.broadcastMessage("Cooldown"); + return; + } + + + lastUse = System.currentTimeMillis(); + + Vector vel = event.getPlayer().getLocation().getDirection().multiply(1.2); + vel.add(new Vector(0,0.6,0)); + + event.getPlayer().setVelocity(vel); } } From 85c8e42f53f3b6f2a75a3383a74683b3d9dabc6a Mon Sep 17 00:00:00 2001 From: Sarah Date: Sun, 9 Aug 2015 15:00:54 +0200 Subject: [PATCH 277/377] Finalizing and improving the Carl spinner and adding creeper explosion animations. --- .../core/treasure/animation/Animation.java | 12 ++ .../mineplex/hub/bonuses/BonusManager.java | 137 +++++++++++++- .../hub/bonuses/animations/AnimationCarl.java | 102 +++++++++++ .../bonuses/commands/AnimationCommand.java | 28 +++ .../src/mineplex/hub/bonuses/gui/SpinGui.java | 170 +++++++++++++++--- .../bonuses/gui/buttons/CarlSpinButton.java | 1 + .../bonuses/gui/buttons/RankBonusButton.java | 18 +- 7 files changed, 435 insertions(+), 33 deletions(-) create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/animations/AnimationCarl.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/AnimationCommand.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/treasure/animation/Animation.java b/Plugins/Mineplex.Core/src/mineplex/core/treasure/animation/Animation.java index c3fbe6e62..a6b986660 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/treasure/animation/Animation.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/treasure/animation/Animation.java @@ -16,6 +16,8 @@ public abstract class Animation _treasure = treasure; _running = true; } + + public Animation() {} public void run() { @@ -50,5 +52,15 @@ public abstract class Animation { return _treasure; } + + public void setRunning(boolean b) + { + _running = b; + } + + public void setTicks(int ticks) + { + _ticks = ticks; + } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index 817db72db..dbd6db81a 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -2,7 +2,9 @@ package mineplex.hub.bonuses; import java.sql.Date; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.Calendar; +import java.util.Iterator; import java.util.TimeZone; import mineplex.core.MiniClientPlugin; @@ -14,7 +16,16 @@ import mineplex.core.common.Rank; import mineplex.core.common.util.C; import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.disguise.disguises.DisguiseCreeper; import mineplex.core.donation.DonationManager; import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; @@ -24,6 +35,8 @@ import mineplex.core.reward.RewardManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.core.votifier.VotifierCommand; +import mineplex.hub.bonuses.animations.AnimationCarl; +import mineplex.hub.bonuses.commands.AnimationCommand; import mineplex.hub.bonuses.commands.GuiCommand; import mineplex.hub.bonuses.event.CarlSpinnerEvent; import mineplex.hub.bonuses.gui.BonusGui; @@ -32,15 +45,21 @@ import mineplex.hub.bonuses.gui.SpinGui; import mineplex.serverdata.commands.ServerCommandManager; import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; + import net.minecraft.server.v1_7_R4.DataWatcher; import net.minecraft.server.v1_7_R4.PacketPlayOutEntityMetadata; @@ -50,6 +69,11 @@ public class BonusManager extends MiniClientPlugin implements I public static final TimeZone TIMEZONE = TimeZone.getTimeZone("UTC"); private static long timeOffSet = 0; + + private ArrayList _pendingExplosions = new ArrayList<>(); + private ArrayList _pendingExplosionsPlayers = new ArrayList<>(); + private long _explode; + private boolean _canVote; public static long getSqlTime() { @@ -91,6 +115,7 @@ public class BonusManager extends MiniClientPlugin implements I private HologramManager _hologramManager; private RewardManager _rewardManager; private Npc _carlNpc; + private AnimationCarl _animation; // Streak private StreakRecord _dailyStreak; @@ -107,7 +132,10 @@ public class BonusManager extends MiniClientPlugin implements I _rewardManager = rewardManager; // Hope to god this works! + _canVote = true; _carlNpc = _npcManager.getNpcByName("Carl the Creeper"); + _animation = new AnimationCarl(_carlNpc.getEntity()); + _animation.setRunning(false); clientManager.addStoredProcedureLoginProcessor(this); @@ -122,6 +150,7 @@ public class BonusManager extends MiniClientPlugin implements I public void addCommands() { addCommand(new GuiCommand(this)); + addCommand(new AnimationCommand(this)); } // Just keeping things up-to-date @@ -176,7 +205,95 @@ public class BonusManager extends MiniClientPlugin implements I public void handleVote(Player player) { - Bukkit.broadcastMessage("Recieved Vote: " + player.getName()); + addPendingExplosion(player, player.getName()); + } + + @EventHandler + public void fireCreeper(UpdateEvent event) + { + if(event.getType() != UpdateType.SLOW) + return; + + if(_pendingExplosions.isEmpty()) + return; + + if(!_canVote) + return; + + if(_pendingExplosions.get(0) instanceof String) + { + String name = (String)_pendingExplosions.get(0); + Bukkit.broadcastMessage("Recieved Vote: " + name); + } + _explode = System.currentTimeMillis(); + _animation.setTicks(0); + _canVote = false; + } + + @EventHandler + public void creeperAnimation(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + if(_canVote) + return; + + Entity creeper = _carlNpc.getEntity(); + + double elapsed = (System.currentTimeMillis() - _explode)/1000d; + + //Not Detonated + if (elapsed < 1) + { + //Sound + creeper.getWorld().playSound(creeper.getLocation(), Sound.CREEPER_HISS, (float)(0.5 + elapsed), (float)(0.5 + elapsed)); + + IncreaseSize(creeper); + return; + } + + if(!_animation.isRunning()) + { + //Effect + UtilParticle.PlayParticle(ParticleType.HUGE_EXPLOSION, creeper.getLocation(), 0, 0, 0, 0, 1, ViewDist.MAX, UtilServer.getPlayers()); + creeper.getWorld().playSound(creeper.getLocation(), Sound.EXPLODE, 2f, 1f); + _animation.setType(_pendingExplosions.get(0)); + _animation.setPlayer(_pendingExplosionsPlayers.get(0)); + _animation.setTime(System.currentTimeMillis()); + _animation.setRunning(true); + } + + if(!_animation.isDone()) + return; + + DecreaseSize(creeper); + _pendingExplosions.remove(0); + _pendingExplosionsPlayers.remove(0); + _canVote = true; + } + + @EventHandler + public void updateAnimation(UpdateEvent event) + { + if(event.getType() != UpdateType.TICK) + return; + + if(!_animation.isRunning()) + return; + + _animation.run(); + } + + public void DecreaseSize(Entity player) + { + ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(16, -1); + ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(17, 1); + } + + public void IncreaseSize(Entity player) + { + ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(16, 1); } // DAILY BONUS @@ -253,6 +370,7 @@ public class BonusManager extends MiniClientPlugin implements I { CarlSpinnerEvent event = new CarlSpinnerEvent(player); Bukkit.getServer().getPluginManager().callEvent(event); + final BonusManager manager = this; if (!event.isCancelled()) { @@ -272,7 +390,7 @@ public class BonusManager extends MiniClientPlugin implements I @Override public void run() { - new SpinGui(getPlugin(), player, _rewardManager).openInventory(); + new SpinGui(getPlugin(), player, _rewardManager, manager).openInventory(); } }); } @@ -374,6 +492,7 @@ public class BonusManager extends MiniClientPlugin implements I { BonusAmount amount = new BonusAmount(); amount.setTickets(1); + amount.setGems(500); return amount; } @@ -383,15 +502,19 @@ public class BonusManager extends MiniClientPlugin implements I BonusAmount data = new BonusAmount(); + if (rank.Has(Rank.MODERATOR)) + { + data.setCoins(35000); + } if (rank.Has(Rank.LEGEND)) { data.setCoins(30000); } - else if (rank.Has(Rank.ULTRA)) + else if (rank.Has(Rank.HERO)) { data.setCoins(15000); } - else if (rank.Has(Rank.HERO)) + else if (rank.Has(Rank.ULTRA)) { data.setCoins(7500); } @@ -685,4 +808,10 @@ public class BonusManager extends MiniClientPlugin implements I BonusClientData clientData = new BonusClientData(record); Set(playerName, clientData); } + + public void addPendingExplosion(Player player, Object obj) + { + _pendingExplosions.add(obj); + _pendingExplosionsPlayers.add(player); + } } \ No newline at end of file diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/animations/AnimationCarl.java new file mode 100644 index 000000000..02783c89a --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/animations/AnimationCarl.java @@ -0,0 +1,102 @@ +package mineplex.hub.bonuses.animations; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilMath; +import mineplex.core.reward.Reward; +import mineplex.core.reward.RewardData; +import mineplex.core.treasure.animation.Animation; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +public class AnimationCarl extends Animation +{ + + private boolean _isDone; + private Block _creeper; + private long _startTime; + private Object _type; + private Player _player; + + public AnimationCarl(Entity creeper) + { + _creeper = creeper.getLocation().getBlock(); + } + + @Override + protected void tick() + { + if(_type instanceof String) + { + if (getTicks() < 40) + { + Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), new ItemStack(Material.EMERALD)); + + //Velocity + long passed = System.currentTimeMillis() - _startTime; + Vector vel = new Vector(Math.sin(passed/5d), 0, Math.cos(passed/5d)); + + UtilAction.velocity(gem, vel, Math.abs(Math.sin(passed/3000d)), false, 0, 0.2 + Math.abs(Math.cos(passed/3000d))*0.6, 1, false); + + gem.setTicksLived(1170); + } + else + { + finish(); + } + } + if(_type instanceof Reward) + { + RewardData rewardData = ((Reward)_type).getFakeRewardData(null); + ItemStack itemStack = rewardData.getDisplayItem(); + if(itemStack.getType() == Material.PAPER) + { + itemStack = new ItemStack(Material.NETHER_STAR); + } + Item item = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), itemStack); + + Vector vel = new Vector(_player.getLocation().getX() - _creeper.getLocation().getX(), 0, _player.getLocation().getZ() - _creeper.getLocation().getZ()); + + UtilAction.velocity(item, vel, 0.1, false, 0, 0.2 + 1*0.4, 1, false); + + item.setTicksLived(1170); + finish(); + } + } + + @Override + protected void onFinish() { + _isDone = true; + setTicks(0); + } + + public boolean isDone() + { + return _isDone; + } + + public void setDone(boolean b) + { + _isDone = b; + } + + public void setTime(long time) + { + _startTime = time; + } + + public void setType(Object type) + { + _type = type; + } + + public void setPlayer(Player player) + { + _player = player; + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/AnimationCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/AnimationCommand.java new file mode 100644 index 000000000..28e2f493a --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/AnimationCommand.java @@ -0,0 +1,28 @@ +package mineplex.hub.bonuses.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.Rank; +import mineplex.hub.bonuses.BonusManager; + +public class AnimationCommand extends CommandBase{ + + BonusManager _plugin; + + public AnimationCommand(BonusManager plugin) + { + super(plugin, Rank.DEVELOPER, "animation"); + _plugin = plugin; + } + + @Override + public void Execute(Player caller, String[] args) + { + _plugin.addPendingExplosion(caller, "Test"); + _plugin.addPendingExplosion(caller, "Chiss"); + _plugin.addPendingExplosion(caller, "Phinary"); + _plugin.addPendingExplosion(caller, "xXVevzZXx"); + } + +} \ No newline at end of file diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java index 8701b3618..fb3355211 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java @@ -1,16 +1,13 @@ package mineplex.hub.bonuses.gui; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.inventory.ItemStack; -import org.bukkit.plugin.Plugin; +import java.util.ArrayList; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; import mineplex.core.gui.DisplayItem; import mineplex.core.gui.SimpleGui; +import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.reward.Reward; import mineplex.core.reward.RewardData; import mineplex.core.reward.RewardManager; @@ -18,44 +15,97 @@ import mineplex.core.reward.RewardType; import mineplex.core.shop.item.ShopItem; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.bonuses.BonusManager; import mineplex.hub.bonuses.gui.buttons.RewardButton; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; + public class SpinGui extends SimpleGui { - private static final int SELECT_OFFSET = 4; private static final int REWARDS_TO_GENERATE = 1000; - private static final int HOPPER_SLOT = 22; - private static final int CARL_SLOT = 40; - private static final int[] LINE_NUMS = { -27, -18, -9, 9, 18 }; + private static final int HOPPER_SLOT = 4; + private static final int CARL_SLOT = 22; + private static final int[] LINE_NUMS = { /*-27, -18,*/ -9, 9/*, 18*/ }; + private static final int STOP_SPINNER_AT = 75; private int _tickCount; + private RewardData _rewardData; + private Reward _reward; + private BonusManager _manager; private int _currentRewardIndex; private int _ticksThisSwap; private int _ticksPerSwap; private int _swapCount; private Reward[] _rewards; + private boolean _stopped; + private boolean _rewarded; + private ArrayList _ticks; + private int _frame; + private float _pitch; + private int _stopSpinnerAt; - public SpinGui(Plugin plugin, Player player, RewardManager rewardManager) + public SpinGui(Plugin plugin, Player player, RewardManager rewardManager, BonusManager manager) { - super(plugin, player, "Carl's Spinner", 54); + super(plugin, player, "Carl's Spinner", 27); + + _manager = manager; ShopItem carlItem = new ShopItem(Material.SKULL_ITEM, (byte) 4, "Carl's Spinner", new String[] {ChatColor.RESET + "Good Luck!" }, 1, false, false); setItem(HOPPER_SLOT, new DisplayItem(new ItemStack(Material.HOPPER))); - setItem(CARL_SLOT, new DisplayItem(carlItem)); + //setItem(CARL_SLOT, new DisplayItem(carlItem)); _rewards = new Reward[REWARDS_TO_GENERATE]; + _ticks = new ArrayList<>(); + _frame = 0; + _pitch = 1; for (int i = 0; i < REWARDS_TO_GENERATE; i++) { _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.Spinner, true); } + + _ticksPerSwap = 1; + + _stopSpinnerAt = STOP_SPINNER_AT; + + for (int i=0 ; i<40 ; i++) + _ticks.add(1); + + for (int i=0 ; i<20 ; i++) + _ticks.add(2); - _ticksPerSwap = 3; + for (int i=0 ; i<10 ; i++) + _ticks.add(4); + + for (int i=0 ; i<5 ; i++) + _ticks.add(8); + + if (Math.random() > 0.5) + { + _ticks.add(12); + _stopSpinnerAt++; + } + + _reward = _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; + _rewardData = _reward.giveReward("Carls Spinner", getPlayer()); } private void tick() { + + if(_stopped) + return; + _ticksThisSwap++; // Swap @@ -65,15 +115,23 @@ public class SpinGui extends SimpleGui _swapCount++; updateGui(); - float pitch = Math.max(-2, 2 - (_swapCount / 50f)); -// Bukkit.broadcastMessage(pitch + ""); - getPlayer().playSound(getPlayer().getEyeLocation(), Sound.NOTE_PLING, 1, pitch); + if(_pitch == 1) + _pitch = (float) 1.5; + else if(_pitch == 1.5) + _pitch = 2; + else if(_pitch == 2) + _pitch = 1; + + getPlayer().playSound(getPlayer().getEyeLocation(), Sound.NOTE_PLING, 1, _pitch); _currentRewardIndex++; // Slow - if (_swapCount % 10 == 0) - _ticksPerSwap++; + _ticksPerSwap = _ticks.get(_currentRewardIndex - 1); + + if(_currentRewardIndex == _stopSpinnerAt) + _stopped = true; + } _tickCount++; @@ -86,7 +144,7 @@ public class SpinGui extends SimpleGui int index = _currentRewardIndex + i; index = index % REWARDS_TO_GENERATE; - int slot = 27 + i; + int slot = 9 + i; RewardData data = _rewards[index].getFakeRewardData(getPlayer()); setItem(slot, new RewardButton(data)); @@ -94,7 +152,7 @@ public class SpinGui extends SimpleGui for (int j = 0; j < LINE_NUMS.length; j++) { int paneSlot = slot + LINE_NUMS[j]; - if (paneSlot == HOPPER_SLOT || paneSlot == CARL_SLOT) + if (paneSlot == HOPPER_SLOT) continue; setItem(paneSlot, new DisplayItem(data.getRarity().getItemStack())); @@ -109,6 +167,72 @@ public class SpinGui extends SimpleGui return; tick(); + checkIfDone(); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void close(InventoryCloseEvent event) + { + if(_rewarded) + return; + + if(event.getPlayer() != getPlayer()) + return; + + _manager.addPendingExplosion(getPlayer(), _reward); + UtilPlayer.message(getPlayer(), F.main("Carl's Spinner", "You got " + _rewardData.getRarity().getColor() + _rewardData.getFriendlyName() + C.cGray + " From Carl's Spinner.")); + } + + @EventHandler + public void Glass(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + return; + + if(!_stopped) + return; + + if(!_rewarded) + return; + + if(_frame == 0) + { + setItem(CARL_SLOT, new DisplayItem(_rewardData.getRarity().getItemStack())); + setItem(HOPPER_SLOT, new DisplayItem(_rewardData.getRarity().getItemStack())); + _frame++; + } + else if(_frame < 5) + { + setItem(HOPPER_SLOT + _frame, new DisplayItem(_rewardData.getRarity().getItemStack())); + setItem(HOPPER_SLOT - _frame, new DisplayItem(_rewardData.getRarity().getItemStack())); + + setItem(CARL_SLOT + _frame, new DisplayItem(_rewardData.getRarity().getItemStack())); + setItem(CARL_SLOT - _frame, new DisplayItem(_rewardData.getRarity().getItemStack())); + + setItem(13 + _frame, new DisplayItem(_rewardData.getRarity().getItemStack())); + setItem(13 - _frame, new DisplayItem(_rewardData.getRarity().getItemStack())); + _frame++; + } + if(_frame == 6) + { + + } + } + + public void checkIfDone() + { + if(!_stopped) + return; + + if(_rewarded) + return; + + _manager.addPendingExplosion(getPlayer(), _reward); + ItemStack item = getInventory().getItem(13); + getInventory().setItem(13, ItemStackFactory.Instance.CreateStack(item.getType(), (byte) 0, 1, _rewardData.getFriendlyName())); + UtilPlayer.message(getPlayer(), F.main("Carl's Spinner", "You got " + _rewardData.getRarity().getColor() + _rewardData.getFriendlyName() + C.cGray + " From Carl's Spinner.")); + _rewarded = true; + } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java index c68f95814..4c295f5dd 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java @@ -52,6 +52,7 @@ public class CarlSpinButton implements GuiItem { _bonusManager.attemptCarlSpin(_player); } + // new SpinGui(_plugin, _player, _rewardManager).openInventory(); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java index 3189ec5d5..5cfb45207 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java @@ -145,17 +145,23 @@ public class RankBonusButton implements GuiItem, Listener { if (!hasRank) { material = Material.COAL_BLOCK; - itemName = C.cRed + ChatColor.BOLD + "Rank Bonus"; + itemName = C.cRed + ChatColor.BOLD + "Rank Monthly Bonus"; lore.add(" "); - lore.add(ChatColor.WHITE + "Players with a rank get monthly rewards!"); - lore.add(ChatColor.WHITE + "Purchase at mineplex.com/shop"); + lore.add(ChatColor.WHITE + "Players with a Rank get a Monthly Bonus!"); + lore.add(ChatColor.WHITE + ""); + lore.add(ChatColor.AQUA + "Ultra: 7500 Coins"); + lore.add(ChatColor.LIGHT_PURPLE + "Hero: 15000 Coins"); + lore.add(ChatColor.GREEN + "Legend: 30000 Coins"); + lore.add(ChatColor.WHITE + ""); + lore.add(ChatColor.WHITE + "Purchase a Rank at;"); + lore.add(ChatColor.WHITE + "www.mineplex.com/shop"); } else { if (isAvailable()) { material = Material.ENDER_CHEST; - itemName = C.cGreen + C.Bold + "Rank Bonus"; + itemName = C.cGreen + C.Bold + "Rank Monthly Bonus"; lore.add(" "); lore.add(ChatColor.RESET + "Click to Claim!"); @@ -163,7 +169,7 @@ public class RankBonusButton implements GuiItem, Listener { else { material = Material.REDSTONE_BLOCK; - itemName = C.cRed + C.Bold + "Rank Bonus"; + itemName = C.cRed + C.Bold + "Rank Monthly Bonus"; lore.add(" "); lore.add(ChatColor.RESET + "Next reward in " + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) + "!"); @@ -185,7 +191,7 @@ public class RankBonusButton implements GuiItem, Listener { public long timeLeft() { - return _bonusManager.nextRankBonus(getPlayer()) - System.currentTimeMillis(); + return _bonusManager.nextRankBonus(getPlayer()) - System.currentTimeMillis(); } public boolean isAvailable() From 941e746ca981a404b28c939b83a531a20b98fbd3 Mon Sep 17 00:00:00 2001 From: Sarah Date: Sun, 9 Aug 2015 16:47:03 +0200 Subject: [PATCH 278/377] Finalizing Poll GUI in Carl's GUI. --- .../src/mineplex/hub/HubManager.java | 4 ++- .../mineplex/hub/bonuses/BonusManager.java | 10 +++++- .../mineplex/hub/bonuses/gui/BonusGui.java | 10 ++++-- .../hub/bonuses/gui/buttons/PollButton.java | 36 +++++++++++++------ .../src/mineplex/hub/poll/PollManager.java | 4 +-- 5 files changed, 47 insertions(+), 17 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index 4a4fbdd2b..944e7d9b5 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -115,6 +115,7 @@ public class HubManager extends MiniClientPlugin private DisguiseManager _disguiseManager; private PartyManager _partyManager; private ForcefieldManager _forcefieldManager; + private PollManager _pollManager; private Portal _portal; private StatsManager _statsManager; private GadgetManager _gadgetManager; @@ -158,6 +159,7 @@ public class HubManager extends MiniClientPlugin _conditionManager = conditionManager; _donationManager = donationManager; _disguiseManager = disguiseManager; + _pollManager = pollManager; _portal = portal; @@ -207,7 +209,7 @@ public class HubManager extends MiniClientPlugin ((CraftWorld)Bukkit.getWorlds().get(0)).getHandle().pvpMode = true; - new BonusManager(plugin, clientManager, donationManager, npcManager, hologramManager, rewardManager); + new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, rewardManager); // NotificationManager notificationManager = new NotificationManager(plugin, clientManager, donationManager); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index dbd6db81a..6bd421b75 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -42,6 +42,7 @@ import mineplex.hub.bonuses.event.CarlSpinnerEvent; import mineplex.hub.bonuses.gui.BonusGui; import mineplex.database.tables.records.BonusRecord; import mineplex.hub.bonuses.gui.SpinGui; +import mineplex.hub.poll.PollManager; import mineplex.serverdata.commands.ServerCommandManager; import org.bukkit.Bukkit; @@ -111,6 +112,7 @@ public class BonusManager extends MiniClientPlugin implements I private BonusRepository _repository; private CoreClientManager _clientManager; private DonationManager _donationManager; + private PollManager _pollManager; private NpcManager _npcManager; private HologramManager _hologramManager; private RewardManager _rewardManager; @@ -121,7 +123,7 @@ public class BonusManager extends MiniClientPlugin implements I private StreakRecord _dailyStreak; private StreakRecord _voteStreak; - public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, NpcManager npcManager, HologramManager hologramManager, RewardManager rewardManager) + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, RewardManager rewardManager) { super("Bonus", plugin); _repository = new BonusRepository(plugin, this, donationManager); @@ -130,6 +132,7 @@ public class BonusManager extends MiniClientPlugin implements I _npcManager = npcManager; _hologramManager = hologramManager; _rewardManager = rewardManager; + _pollManager = pollManager; // Hope to god this works! _canVote = true; @@ -814,4 +817,9 @@ public class BonusManager extends MiniClientPlugin implements I _pendingExplosions.add(obj); _pendingExplosionsPlayers.add(player); } + + public PollManager getPollManager() + { + return _pollManager; + } } \ No newline at end of file diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java index 65aa961cf..ea7978621 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java @@ -5,11 +5,13 @@ import mineplex.core.reward.RewardManager; import mineplex.hub.bonuses.BonusManager; import mineplex.hub.bonuses.gui.buttons.CarlSpinButton; import mineplex.hub.bonuses.gui.buttons.DailyBonusButton; +import mineplex.hub.bonuses.gui.buttons.PollButton; import mineplex.hub.bonuses.gui.buttons.RankBonusButton; import mineplex.hub.bonuses.gui.buttons.VoteButton; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; +import org.omg.CORBA._PolicyStub; public class BonusGui extends SimpleGui { @@ -22,12 +24,14 @@ public class BonusGui extends SimpleGui this.manager = manager; - setItem(11, new VoteButton(plugin, player, this, manager)); + setItem(10, new VoteButton(plugin, player, this, manager)); - setItem(13, new RankBonusButton(getPlugin(), player, this, manager)); + setItem(12, new RankBonusButton(getPlugin(), player, this, manager)); - setItem(15, new DailyBonusButton(getPlugin(), player, this, manager)); + setItem(14, new DailyBonusButton(getPlugin(), player, this, manager)); + setItem(16, new PollButton(getPlugin(), player, manager.getPollManager(), manager.getClientManager(), this)); + setItem(31, new CarlSpinButton(getPlugin(), player, manager, rewardManager)); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java index 9ae72899b..5584e5b65 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java @@ -1,8 +1,10 @@ package mineplex.hub.bonuses.gui.buttons; +import java.util.ArrayList; import java.util.HashMap; import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; import mineplex.core.common.util.UtilText; import mineplex.core.gui.GuiInventory; import mineplex.core.gui.GuiItem; @@ -53,9 +55,6 @@ public class PollButton extends SimpleGui implements GuiItem { if (_poll != null) { - - // Todo - Fix this! -// getButtonMap().putAll(hard); setItem(4, getQuestionItem(_poll.getQuestion())); @@ -63,22 +62,38 @@ public class PollButton extends SimpleGui implements GuiItem { for (int i = 0; i < slots.length; i++) { - - setItem(9 * 2 + slots[i], new AnswerItem(_poll, i)); - + AnswerItem item = new AnswerItem(_poll, i); + setItem(9 * 2 + slots[i], item); } } } } - @Override public ItemStack getObject() { + ArrayList lore = new ArrayList<>(); if (_poll == null) - return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, "No polls!"); + { + lore.add(C.cRed + "You've already voted on all of the polls!"); + return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + C.Bold + "Vote on Poll", lore); + } else - return ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, ChatColor.GREEN + _poll.getQuestion()); + { + lore.add(C.cWhite + _poll.getQuestion()); + lore.add(""); + int i = 1; + for(String str : _poll.getAnswers()) + { + lore.add(C.cAqua + "" + i + ".) " + str); + i++; + } + lore.add(""); + lore.add(C.cYellow + C.Bold + "Reward: 500 Gems"); + lore.add(""); + lore.add(C.cGreen + "Click to go to the vote page!"); + return ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, C.cGreen + C.Bold + "Vote on Poll", lore); + } } @Override @@ -155,8 +170,9 @@ public class PollButton extends SimpleGui implements GuiItem { _pollManager.answerPoll(getPlayer(), _poll, num); getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); + new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.EMERALD_BLOCK, (byte) 0, 1, ChatColor.GREEN + "Your anwser:", wrap(getPoll().getAnswers()[num])), ChatColor.GREEN + "Moo", 6 * 9, 50, getMaster()).openInventory(); - + getPlayer().closeInventory(); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollManager.java index 8820efd46..7fb0e00fd 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollManager.java @@ -64,7 +64,7 @@ public class PollManager extends MiniDbClientPlugin pollData.setPollCooldown(5000); } - @EventHandler + /*@EventHandler public void update(UpdateEvent event) { if (event.getType() != UpdateType.SLOW) @@ -88,7 +88,7 @@ public class PollManager extends MiniDbClientPlugin pollData.updatePollCooldown(); } } - } + }*/ public Poll getNextPoll(PlayerPollData pollData, Rank playerRank) { From 0d70fb6b9606a90449b36dff0db0018ef9e4ed32 Mon Sep 17 00:00:00 2001 From: Sarah Date: Sun, 9 Aug 2015 16:55:10 +0200 Subject: [PATCH 279/377] removing deop of Admins and adding OP condition to setHost. --- .../src/nautilus/game/arcade/ArcadeManager.java | 2 -- .../src/nautilus/game/arcade/game/games/event/EventModule.java | 2 +- .../src/nautilus/game/arcade/managers/GameHostManager.java | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java index cc264d1e6..fd0f4fc6d 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java @@ -852,8 +852,6 @@ public class ArcadeManager extends MiniPlugin implements IRelation if (_clientManager.Get(event.getPlayer()).GetRank().Has(Rank.OWNER) || (testServer && (_clientManager.Get(event.getPlayer()).GetRank().Has(Rank.DEVELOPER) || _clientManager.Get(event.getPlayer()).GetRank() == Rank.JNR_DEV))) event.getPlayer().setOp(true); - else - event.getPlayer().setOp(false); } public boolean IsAlive(Player player) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/event/EventModule.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/event/EventModule.java index 6b77dd967..db6ce695e 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/event/EventModule.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/event/EventModule.java @@ -82,7 +82,7 @@ public class EventModule extends MiniPlugin if (!event.getMessage().toLowerCase().startsWith("/sethost ")) return; - if (!Manager.GetClients().Get(event.getPlayer()).GetRank().Has(event.getPlayer(), Rank.JNR_DEV, true)) + if (!Manager.GetClients().Get(event.getPlayer()).GetRank().Has(event.getPlayer(), Rank.JNR_DEV, true) && !event.getPlayer().isOp()) return; Manager.GetServerConfig().HostName = event.getMessage().split(" ")[1]; diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java index 2dfc1c151..aba7ea41b 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java @@ -374,7 +374,7 @@ public class GameHostManager implements Listener if (!isPrivateServer()) return; - if (!Manager.GetClients().Get(event.getPlayer()).GetRank().Has(event.getPlayer(), Rank.JNR_DEV, true)) + if (!Manager.GetClients().Get(event.getPlayer()).GetRank().Has(event.getPlayer(), Rank.JNR_DEV, true) && !event.getPlayer().isOp()) return; giveAdmin(event.getPlayer()); From 5a7de8ef3d26f881e21e35675616b0f804515712 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Sun, 9 Aug 2015 17:21:56 +0200 Subject: [PATCH 280/377] hub fixes --- .../src/mineplex/core/mount/MountManager.java | 8 + .../src/mineplex/core/pet/PetManager.java | 6 + .../mineplex/core/reward/RewardManager.java | 3 +- .../src/mineplex/hub/HubManager.java | 147 +----------------- .../src/mineplex/hub/modules/KothManager.java | 5 +- .../mineplex/hub/modules/SoccerManager.java | 5 +- 6 files changed, 32 insertions(+), 142 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/mount/MountManager.java b/Plugins/Mineplex.Core/src/mineplex/core/mount/MountManager.java index 00dcd9fdb..38152a878 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/mount/MountManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/mount/MountManager.java @@ -115,6 +115,12 @@ public class MountManager extends MiniPlugin mount.Disable(player); } + public void DisableAll(Player player) + { + for (Mount mount : _types) + mount.Disable(player); + } + @EventHandler public void quit(PlayerQuitEvent event) { @@ -161,4 +167,6 @@ public class MountManager extends MiniPlugin { return _disguiseManager; } + + } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/pet/PetManager.java b/Plugins/Mineplex.Core/src/mineplex/core/pet/PetManager.java index b50fc27b4..a95bcb150 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/pet/PetManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/pet/PetManager.java @@ -401,9 +401,15 @@ public class PetManager extends MiniClientPlugin for (Player player : UtilServer.getPlayers()) RemovePet(player, true); } + + public void DisableAll(Player player) + { + RemovePet(player, true); + } public Collection getPets() { return _activePetOwners.values(); } + } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index 775ab3cd5..539e9e124 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -22,6 +22,7 @@ import mineplex.core.reward.rewards.InventoryReward; import mineplex.core.reward.rewards.PetReward; import mineplex.core.reward.rewards.RankReward; import mineplex.core.reward.rewards.UnknownPackageReward; +import mineplex.core.timing.TimingManager; public class RewardManager { @@ -269,7 +270,7 @@ public class RewardManager new ItemStack(Material.INK_SACK, 1, (short) 0, (byte) 4), rarity, 13)); addReward(new UnknownPackageReward(donationManager, "Blood Helix Particles", "Blood Helix", new ItemStack(Material.REDSTONE), rarity, 10)); - addReward(new UnknownPackageReward(donationManager, "Emerald Twirl Particles", "Green Ring", + addReward(new UnknownPackageReward(donationManager, "Green Rings Particles", "Green Ring", new ItemStack(Material.EMERALD), rarity, 8)); addReward(new UnknownPackageReward(donationManager, "Flame Fairy Particles", "Flame Fairy", new ItemStack(Material.APPLE), rarity, 4)); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index 65e2ae685..e1cf08feb 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -65,6 +65,8 @@ import mineplex.hub.poll.PollManager; import mineplex.hub.tutorial.TutorialManager; import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; import mineplex.minecraft.game.classcombat.item.event.ItemTriggerEvent; +import mineplex.minecraft.game.core.combat.DeathMessageType; +import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; import mineplex.minecraft.game.core.condition.ConditionManager; import mineplex.minecraft.game.core.damage.CustomDamageEvent; @@ -137,11 +139,8 @@ public class HubManager extends MiniClientPlugin private HashMap _scoreboards = new HashMap(); - private String _pigStacker = "0 - Nobody"; private String _serverName = ""; - private ItemStack _ruleBook = null; - private boolean _shuttingDown; private HashMap _portalTime = new HashMap(); @@ -208,141 +207,8 @@ public class HubManager extends MiniClientPlugin // NotificationManager notificationManager = new NotificationManager(plugin, clientManager, donationManager); // new MailManager(_plugin, notificationManager); - _ruleBook = ItemStackFactory.Instance.CreateStack(Material.WRITTEN_BOOK, (byte)0, 1, ChatColor.GREEN + "Rule Book", new String[] { }); - BookMeta meta = (BookMeta)_ruleBook.getItemMeta(); _serverName = getPlugin().getConfig().getString("serverstatus.name"); _serverName = _serverName.substring(0, Math.min(16, _serverName.length())); - - meta.addPage("§m-------------------§r\n" - + "Welcome to §6§lMineplex§r\n" - + "§r§0§l§r§m§0§m-------------------§r§0\n" - + "\n" - + "§2Please §0take a moment to read through this book!\n" - + "\n" - + "\n" - + "Part 1 - Rules\n" - + "\n" - + "Part 2 - FAQ\n"); - - meta.addPage("§m-------------------\n" - + "§r §2§lRules§r§0\n" - + "§m-------------------\n" - + "§r\n" - + "§l1.§§§r §4No§r spamming.\n" - + "\n" - + "§0This is sending too many messages and/or repeating the same message in a short period of time.\n"); - - meta.addPage("§m-------------------\n" - + "§r §2§lRules§r§0\n" - + "§m-------------------\n" - + "§r\n" - + "§l2.§m§r §4No§0 use of excessive caps.\n" - + "\n" - + "This is sending messages with an excessive amount of capital letters.\n"); - - meta.addPage("§m-------------------\n" - + "§r §2§lRules§r§0\n" - + "§m-------------------\n" - + "§r\n" - + "§l3.§r §4No§0 hacking or use of any unapproved mods.\n" - + "\n" - + "This means we do not tolerate any sort of hacked client or any unapproved mods, such as fly hacks.\n"); - - meta.addPage("§m-------------------\n" - + "§r §2§lRules§r§0\n" - + "§m-------------------\n" - + "§r\n" - + "§l4.§r §4No§0 advertising non-Mineplex related links.\n" - + "\n" - + "This is when a link is sent in chat which directs others to non-Mineplex related content.\n"); - - meta.addPage("§m-------------------\n" - + "§r §2§lRules§r§0\n" - + "§m-------------------\n" - + "§r\n" - + "§l5.§r §4No§0 trolling or use of any exploits.\n" - + "\n" - + "This means that abuse of bugs/glitches is not tolerated. You also may not do things such as teamkilling and/or blocking spawns.\n"); - - meta.addPage("§m-------------------\n" - + "§r §2§lRules§r§0\n" - + "§m-------------------\n" - + "§r\n" - + "§l6.§r §2Be§0 respectful to others, yourself, and the environment around you.\n"); - - meta.addPage("§m-------------------\n" - + "§r §2§lRules§r§0\n" - + "§m-------------------\n" - + "§r\n" - + "§rPlease report any bugs, exploits, and/or rule breakers on our forums with evidence.\n" - + "§omineplex.com/forums\n"); - - meta.addPage("§m-------------------\n" - + "§r §2§lFAQ§r§0\n" - + "§m-------------------\n" - + "§r\n" - + "§lWhat is stacker and how do you play it?\n" - + "\n" - + "§rStacker is a hub game where you can stack & throw players/mobs.\n" - + "\n" - + "§9Right-Click: pick up\n" - + "Left-Click: throw\n"); - - meta.addPage("§m-------------------\n" - + "§r §2§lFAQ§r§0\n" - + "§m-------------------\n" - + "§r\n" - + "§lHow do I get §bUltra§l, §5Hero§l, or §aLegend§l?\n" - + "\n" - + "§r§0You are able to purchase these ranks through our shop on our website at:\n" - + "\n" - + "§owww.mineplex.com/shop\n"); - - meta.addPage("§m-------------------\n" - + "§r §2§lFAQ§r§0\n" - + "§m-------------------\n" - + "§r\n" - + "§lWhy hasn't my rank been applied yet?\n" - + "\n" - + "§m§rYour rank may take a while to be applied. If it has been over 24 hours please contact:\n" - + "\n" - + "§omineplex.com/support\n"); - - meta.addPage("§m-------------------\n" - + "§r §2§lFAQ§r§0\n" - + "§m-------------------\n" - + "§r\n" - + "§lWhat do I do if I was wrongfully punished?\n" - + "\n" - + "§0If you believe you were wrongfully punished, please submit an appeal at:\n" - + "\n" - + "§omineplex.com/appeals\n"); - - meta.addPage("§m-------------------\n" - + "§r §2§lFAQ§r§0\n" - + "§m-------------------\n" - + "§r\n" - + "§lHow do I apply for Trainee?\n" - + "\n" - + "§rYou may only apply for Trainee if you have §bUltra§0, §5Hero§0, or §aLegend§0.\n" - + "Apply at:\n" - + "§omineplex.com/application\n"); - - meta.addPage("§m-------------------\n" - + "§r §6§lThank you for \n" - + " reading!§r§0\n" - + "§m-------------------\n" - + "§r\n" - + "Remember to visit our website §2mineplex.com§0 for important news & updates!\n" - + "\n" - + "\n" - + "§c§lH§6§lA§a§lV§9§lE §c§lF§6§lU§a§lN§9§l!\n"); - - // These are needed or 1.8 clients will not show book correctly - meta.setTitle("Rule Book"); - meta.setAuthor("Mineplex"); - - _ruleBook.setItemMeta(meta); } @Override @@ -555,9 +421,6 @@ public class HubManager extends MiniClientPlugin //Health player.setHealth(20); - - //Rules - player.getInventory().setItem(2, _ruleBook); //Scoreboard Scoreboard board = Bukkit.getScoreboardManager().getNewScoreboard(); @@ -736,6 +599,12 @@ public class HubManager extends MiniClientPlugin event.getEntity().setHealth(20); event.getEntity().teleport(GetSpawn()); } + + @EventHandler + public void combatDeath(CombatDeathEvent event) + { + event.SetBroadcastType(DeathMessageType.None); + } @EventHandler public void FoodHealthUpdate(UpdateEvent event) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java index bacb4156a..cd465fce0 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java @@ -12,6 +12,7 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerVelocityEvent; import mineplex.core.MiniPlugin; import mineplex.core.common.util.C; @@ -196,6 +197,8 @@ public class KothManager extends MiniPlugin outfit.add("PvP Sword"); Manager.GetGadget().DisableAll(player, outfit); + Manager.GetMount().DisableAll(player); + Manager.getPetManager().DisableAll(player); } else { @@ -209,7 +212,7 @@ public class KothManager extends MiniPlugin { return _active.contains(player); } - + @EventHandler public void disableGadgets(GadgetActivateEvent event) { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java index d737d65d3..bafd2df86 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -15,6 +15,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerVelocityEvent; import org.bukkit.util.Vector; import mineplex.core.MiniPlugin; @@ -449,6 +450,8 @@ public class SoccerManager extends MiniPlugin outfit.add("Team Boots"); Manager.GetGadget().DisableAll(player, outfit); + Manager.GetMount().DisableAll(player); + Manager.getPetManager().DisableAll(player); } else { @@ -461,7 +464,7 @@ public class SoccerManager extends MiniPlugin { return _active.contains(player); } - + @EventHandler public void disableGadgets(GadgetActivateEvent event) { From ac5ff08fadb56cfe9a30b70c823445162f4cee01 Mon Sep 17 00:00:00 2001 From: Sarah Date: Sun, 9 Aug 2015 17:23:38 +0200 Subject: [PATCH 281/377] Git fix --- .../game/arcade/managers/GameHostManager.java | 97 ++++++++++--------- 1 file changed, 53 insertions(+), 44 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java index aba7ea41b..b247ee140 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java @@ -713,57 +713,66 @@ public class GameHostManager implements Listener if (!event.getMessage().toLowerCase().startsWith("/e set ") && !event.getMessage().toLowerCase().equals("/e set")) return; + Player caller = event.getPlayer(); String[] args = event.getMessage().split(" "); - //Parse Game - if (args.length >= 3) - { - ArrayList matches = new ArrayList(); - for (GameType type : GameType.values()) - { - if (type.toString().toLowerCase().equals(args[2])) - { - matches.clear(); - matches.add(type); - break; - } - - if (type.toString().toLowerCase().contains(args[2])) - { - matches.add(type); - } - } - - if (matches.size() == 0) - { - event.getPlayer().sendMessage("No results for: " + args[2]); - return; - } - - if (matches.size() > 1) - { - event.getPlayer().sendMessage("Matched multiple games;"); - for (GameType cur : matches) - event.getPlayer().sendMessage(cur.toString()); - return; - } - - GameType type = matches.get(0); - Manager.GetGame().setGame(type, event.getPlayer(), true); - } - else - { - Manager.GetGame().setGame(GameType.Event, event.getPlayer(), true); - } + String game = args[2].toLowerCase(); - - //Map Pref if (args.length >= 4) { - Manager.GetGameCreationManager().MapPref = args[3]; - UtilPlayer.message(event.getPlayer(), C.cAqua + C.Bold + "Map Preference: " + ChatColor.RESET + args[2]); + String map = ""; + String source = ""; + if(args.length == 5) + { + Manager.GetGameCreationManager().MapSource = args[2]; + Manager.GetGameCreationManager().MapPref = args[3]; + source = args[3]; + map = args[4]; + } + else + { + Manager.GetGameCreationManager().MapSource = args[0]; + Manager.GetGameCreationManager().MapPref = args[1]; + source = args[2]; + map = args[3]; + } + UtilPlayer.message(caller, C.cAqua + C.Bold + "Map Preference: " + ChatColor.RESET + source + ":" + map); } + //Parse Game + ArrayList matches = new ArrayList<>(); + for (GameType type : GameType.values()) + { + if (type.toString().toLowerCase().equals(game)) + { + matches.clear(); + matches.add(type); + break; + } + + if (type.toString().toLowerCase().contains(game)) + { + matches.add(type); + } + } + + if (matches.size() == 0) + { + caller.sendMessage("No results for: " + game); + return; + } + + if (matches.size() > 1) + { + caller.sendMessage("Matched multiple games;"); + for (GameType cur : matches) + caller.sendMessage(cur.toString()); + return; + } + + GameType type = matches.get(0); + Manager.GetGame().setGame(type, event.getPlayer(), true); + event.setCancelled(true); } From fdfc9ae99def48be8084444cba167303efb948f5 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Sun, 9 Aug 2015 18:17:29 +0200 Subject: [PATCH 282/377] longer games wont announce stay msgs --- .../src/nautilus/game/arcade/game/games/bridge/Bridge.java | 2 ++ .../game/arcade/game/games/minestrike/MineStrike.java | 2 ++ .../nautilus/game/arcade/game/games/skywars/Skywars.java | 2 ++ .../arcade/game/games/survivalgames/SurvivalGames.java | 2 ++ .../src/nautilus/game/arcade/game/games/uhc/UHC.java | 2 ++ .../src/nautilus/game/arcade/managers/GameFlagManager.java | 7 ++----- 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/bridge/Bridge.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/bridge/Bridge.java index e17db6abc..f839c7539 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/bridge/Bridge.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/bridge/Bridge.java @@ -177,6 +177,8 @@ public class Bridge extends TeamGame implements OreObsfucation ItemPickup = true; InventoryClick = true; + + AnnounceStay = false; PrivateBlocks = true; BlockBreak = true; diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/MineStrike.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/MineStrike.java index eddcab047..3908fbf20 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/MineStrike.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/MineStrike.java @@ -255,6 +255,8 @@ public class MineStrike extends TeamGame this.StrictAntiHack = true; + AnnounceStay = false; + this.HungerSet = 20; this.ItemDrop = true; diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skywars/Skywars.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skywars/Skywars.java index 00eb0798a..91a1f9c19 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skywars/Skywars.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/skywars/Skywars.java @@ -146,6 +146,8 @@ public abstract class Skywars extends Game PrepareFreeze = true; + AnnounceStay = false; + HideTeamSheep = true; CompassEnabled = true; diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/survivalgames/SurvivalGames.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/survivalgames/SurvivalGames.java index 0e984eb4c..a46a085de 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/survivalgames/SurvivalGames.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/survivalgames/SurvivalGames.java @@ -210,6 +210,8 @@ public abstract class SurvivalGames extends Game StrictAntiHack = true; + AnnounceStay = false; + HideTeamSheep = true; this.ReplaceTeamsWithKits = true; diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/uhc/UHC.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/uhc/UHC.java index c2b7ecd9f..9175d6350 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/uhc/UHC.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/uhc/UHC.java @@ -139,6 +139,8 @@ public class UHC extends TeamGame this.HideTeamSheep = true; this.StrictAntiHack = true; + + AnnounceStay = false; this.GameTimeout = 10800000; diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameFlagManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameFlagManager.java index 0f25e0656..46e4a9f65 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameFlagManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameFlagManager.java @@ -1110,16 +1110,13 @@ public class GameFlagManager implements Listener if (event.getType() != UpdateType.SEC) return; - - if (Manager.GetGame().GetType() == GameType.MineStrike) - return; - + for (Player player : UtilServer.getPlayers()) { if (Manager.IsAlive(player)) continue; - if (Recharge.Instance.use(player, "Dont Quit Message", 30000, false, false)) + if (Recharge.Instance.use(player, "Dont Quit Message", 300000, false, false)) { UtilPlayer.message(player, " "); UtilPlayer.message(player, C.cWhite + C.Bold + "You are out of the game, but " + C.cGold + C.Bold + "DON'T QUIT" + C.cWhite + C.Bold + "!"); From 8c66ef7f15883ec3c629a665af694572939fdb28 Mon Sep 17 00:00:00 2001 From: Sarah Date: Sun, 9 Aug 2015 18:33:44 +0200 Subject: [PATCH 283/377] changing Hub items and adding Profile GUI. --- .../core/achievement/AchievementManager.java | 28 +--------- .../personalServer/HostServerCommand.java | 2 +- .../personalServer/PersonalServerManager.java | 1 - .../core/preferences/PreferencesManager.java | 55 ++++++++++++------- .../Mineplex.Hub/src/mineplex/hub/Hub.java | 6 +- .../src/mineplex/hub/HubManager.java | 16 +++++- .../hub/bonuses/gui/buttons/PollButton.java | 35 +++++++++--- .../bonuses/gui/buttons/RankBonusButton.java | 14 ++++- .../hub/profile/buttons/ButtonMPS.java | 51 +++++++++++++++++ .../hub/profile/buttons/ButtonPrefs.java | 51 +++++++++++++++++ .../hub/profile/buttons/ButtonStats.java | 55 +++++++++++++++++++ .../mineplex/hub/profile/gui/GUIProfile.java | 48 ++++++++++++++++ 12 files changed, 301 insertions(+), 61 deletions(-) create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java index 485f5a124..76e58b6fb 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementManager.java @@ -137,15 +137,6 @@ public class AchievementManager extends MiniPlugin _log.remove(event.getPlayer().getName()); } - @EventHandler - public void playerJoin(PlayerJoinEvent event) - { - if (_giveInterfaceItem) - { - giveInterfaceItem(event.getPlayer()); - } - } - public void clearLog(Player player) { _log.remove(player.getName()); @@ -161,22 +152,7 @@ public class AchievementManager extends MiniPlugin _giveInterfaceItem = giveInterfaceItem; } - public void giveInterfaceItem(Player player) - { - if (!UtilGear.isMat(player.getInventory().getItem(_interfaceSlot), Material.SKULL_ITEM)) - { - ItemStack item = ItemStackFactory.Instance.CreateStack(Material.SKULL_ITEM, (byte) 3, 1, ChatColor.RESET + C.cGreen + "/stats"); - SkullMeta meta = ((SkullMeta) item.getItemMeta()); - meta.setOwner(player.getName()); - item.setItemMeta(meta); - - player.getInventory().setItem(_interfaceSlot, item); - - UtilInv.Update(player); - } - } - - @EventHandler + /*@EventHandler public void openShop(PlayerInteractEvent event) { if (!_shopEnabled) @@ -188,7 +164,7 @@ public class AchievementManager extends MiniPlugin openShop(event.getPlayer()); } - } + }*/ public boolean hasCategory(Player player, Achievement[] required) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostServerCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostServerCommand.java index b09c4cc54..a087fd3f6 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostServerCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/personalServer/HostServerCommand.java @@ -10,7 +10,7 @@ public class HostServerCommand extends CommandBase { public HostServerCommand(PersonalServerManager plugin) { - super(plugin, Rank.LEGEND, "hostserver"); + super(plugin, Rank.LEGEND, "hostserver", "mps"); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/personalServer/PersonalServerManager.java b/Plugins/Mineplex.Core/src/mineplex/core/personalServer/PersonalServerManager.java index 466a26d50..3438849f7 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/personalServer/PersonalServerManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/personalServer/PersonalServerManager.java @@ -59,7 +59,6 @@ public class PersonalServerManager extends MiniPlugin { if (_giveInterfaceItem) { - event.getPlayer().getInventory().setItem(_interfaceSlot, _interfaceItem); } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java b/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java index 6a96dcd16..c69ab7bed 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java @@ -4,6 +4,19 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map.Entry; +import mineplex.core.MiniDbClientPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.common.util.UtilGear; +import mineplex.core.common.util.UtilInv; +import mineplex.core.donation.DonationManager; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.preferences.command.PreferencesCommand; +import mineplex.core.preferences.ui.PreferencesShop; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; + import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -11,18 +24,10 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.plugin.java.JavaPlugin; -import mineplex.core.MiniDbClientPlugin; -import mineplex.core.account.CoreClientManager; -import mineplex.core.common.util.NautHashMap; -import mineplex.core.donation.DonationManager; -import mineplex.core.itemstack.ItemStackFactory; -import mineplex.core.preferences.command.PreferencesCommand; -import mineplex.core.preferences.ui.PreferencesShop; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; - public class PreferencesManager extends MiniDbClientPlugin { private PreferencesRepository _repository; @@ -53,6 +58,27 @@ public class PreferencesManager extends MiniDbClientPlugin _saveBuffer.put(caller.getUniqueId().toString(), Get(caller)); } + @EventHandler + public void givePlayerItem(PlayerJoinEvent event) + { + if (!GiveItem) + return; + + Player player = event.getPlayer(); + + if (!UtilGear.isMat(player.getInventory().getItem(8), Material.SKULL_ITEM)) + { + ItemStack item = ItemStackFactory.Instance.CreateStack(Material.SKULL_ITEM, (byte) 3, 1, ChatColor.RESET + C.cGreen + "My Profile"); + SkullMeta meta = ((SkullMeta) item.getItemMeta()); + meta.setOwner(player.getName()); + item.setItemMeta(meta); + + player.getInventory().setItem(8, item); + + UtilInv.Update(player); + } + } + @EventHandler public void storeBuffer(UpdateEvent event) { @@ -76,15 +102,6 @@ public class PreferencesManager extends MiniDbClientPlugin } }); } - - @EventHandler - public void givePlayerItem(PlayerJoinEvent event) - { - if (!GiveItem) - return; - - event.getPlayer().getInventory().setItem(8, ItemStackFactory.Instance.CreateStack(Material.REDSTONE_COMPARATOR.getId(), (byte)0, 1, ChatColor.GREEN + "/prefs")); - } @EventHandler(priority = EventPriority.LOWEST) public void playerInteract(PlayerInteractEvent event) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java index 3da68540b..c99d09044 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java @@ -122,7 +122,9 @@ public class Hub extends JavaPlugin implements IRelation PartyManager partyManager = new PartyManager(this, portal, clientManager, preferenceManager); - HubManager hubManager = new HubManager(this, blockRestore, clientManager, donationManager, new ConditionManager(this), disguiseManager, new TaskManager(this, clientManager, webServerAddress), portal, partyManager, preferenceManager, petManager, pollManager, statsManager, achievementManager, new HologramManager(this), npcManager); + PersonalServerManager personalServerManager = new PersonalServerManager(this, clientManager); + + HubManager hubManager = new HubManager(this, blockRestore, clientManager, donationManager, new ConditionManager(this), disguiseManager, new TaskManager(this, clientManager, webServerAddress), portal, partyManager, preferenceManager, petManager, pollManager, statsManager, achievementManager, new HologramManager(this), npcManager, personalServerManager); QueueManager queueManager = new QueueManager(this, clientManager, donationManager, new EloManager(this, clientManager), partyManager); @@ -141,7 +143,7 @@ public class Hub extends JavaPlugin implements IRelation } }); //new Replay(this, packetHandler); - new PersonalServerManager(this, clientManager); + AprilFoolsManager.Initialize(this, clientManager, disguiseManager); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index 944e7d9b5..03ffee480 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -25,6 +25,7 @@ import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerQuitEvent; @@ -74,6 +75,7 @@ import mineplex.core.notifier.NotificationManager; import mineplex.core.npc.NpcManager; import mineplex.core.party.Party; import mineplex.core.party.PartyManager; +import mineplex.core.personalServer.PersonalServerManager; import mineplex.core.pet.PetManager; import mineplex.core.portal.Portal; import mineplex.core.preferences.PreferencesManager; @@ -97,6 +99,7 @@ import mineplex.hub.modules.ParkourManager; import mineplex.hub.modules.TextManager; import mineplex.hub.modules.WorldManager; import mineplex.hub.poll.PollManager; +import mineplex.hub.profile.gui.GUIProfile; import mineplex.hub.tutorial.TutorialManager; import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; import mineplex.minecraft.game.classcombat.item.event.ItemTriggerEvent; @@ -130,6 +133,7 @@ public class HubManager extends MiniClientPlugin private AchievementManager _achievementManager; private TreasureManager _treasureManager; private PetManager _petManager; + private PersonalServerManager _personalServerManager; private Location _spawn; private int _scoreboardTick = 0; @@ -150,7 +154,7 @@ public class HubManager extends MiniClientPlugin //Admin private boolean _gadgetsEnabled = true; - public HubManager(JavaPlugin plugin, BlockRestore blockRestore, CoreClientManager clientManager, DonationManager donationManager, ConditionManager conditionManager, DisguiseManager disguiseManager, TaskManager taskManager, Portal portal, PartyManager partyManager, PreferencesManager preferences, PetManager petManager, PollManager pollManager, StatsManager statsManager, AchievementManager achievementManager, HologramManager hologramManager, NpcManager npcManager) + public HubManager(JavaPlugin plugin, BlockRestore blockRestore, CoreClientManager clientManager, DonationManager donationManager, ConditionManager conditionManager, DisguiseManager disguiseManager, TaskManager taskManager, Portal portal, PartyManager partyManager, PreferencesManager preferences, PetManager petManager, PollManager pollManager, StatsManager statsManager, AchievementManager achievementManager, HologramManager hologramManager, NpcManager npcManager, PersonalServerManager personalServerManager) { super("Hub Manager", plugin); @@ -160,6 +164,7 @@ public class HubManager extends MiniClientPlugin _donationManager = donationManager; _disguiseManager = disguiseManager; _pollManager = pollManager; + _personalServerManager = personalServerManager; _portal = portal; @@ -1094,4 +1099,13 @@ public class HubManager extends MiniClientPlugin UtilPlayer.message(player, F.main("Game Mode", event.getPlayer().getName() + " left the game. Creative Mode: " + F.tf(false))); } } + + @EventHandler + public void openProfile(PlayerInteractEvent event) + { + if(event.getItem().getType() != Material.SKULL_ITEM) + return; + + new GUIProfile(getPlugin(), event.getPlayer(), _preferences, _achievementManager, _personalServerManager).openInventory();; + } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java index 5584e5b65..b5fe9dca1 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java @@ -56,14 +56,14 @@ public class PollButton extends SimpleGui implements GuiItem { if (_poll != null) { - setItem(4, getQuestionItem(_poll.getQuestion())); + setItem(13, getQuestionItem(_poll.getQuestion())); int[] slots = even(9, _poll.getAnswers().length); for (int i = 0; i < slots.length; i++) { AnswerItem item = new AnswerItem(_poll, i); - setItem(9 * 2 + slots[i], item); + setItem(9 * 3 + slots[i], item); } } } @@ -80,16 +80,17 @@ public class PollButton extends SimpleGui implements GuiItem { } else { + lore.add(""); lore.add(C.cWhite + _poll.getQuestion()); lore.add(""); int i = 1; for(String str : _poll.getAnswers()) { - lore.add(C.cAqua + "" + i + ".) " + str); + lore.add(C.cAqua + "" + i + ".) " + C.cWhite + str); i++; } lore.add(""); - lore.add(C.cYellow + C.Bold + "Reward: 500 Gems"); + lore.add(C.cYellow + "Reward:" + C.cWhite + " 500 Gems"); lore.add(""); lore.add(C.cGreen + "Click to go to the vote page!"); return ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, C.cGreen + C.Bold + "Vote on Poll", lore); @@ -112,8 +113,24 @@ public class PollButton extends SimpleGui implements GuiItem { public GuiItem getQuestionItem(String question) { - return new SimpleGuiItem(ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, ChatColor.GREEN + "Question:", - wrap(question))); + + ArrayList lore = new ArrayList<>(); + lore.add(""); + lore.add(C.cWhite + wrap(question)); + lore.add(""); + int i = 1; + for(String str : _poll.getAnswers()) + { + lore.add(C.cAqua + "" + i + ".) " + C.cWhite + str); + i++; + } + lore.add(""); + lore.add(C.cYellow + "Reward:" + C.cWhite + " 500 Gems"); + lore.add(""); + lore.add(C.cGreen + "Click to go to the vote page!"); + + return new SimpleGuiItem(ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, ChatColor.GREEN + C.cGreen + C.Bold + "Vote on Poll", + lore)); } public static String[] wrap(String text) @@ -158,8 +175,10 @@ public class PollButton extends SimpleGui implements GuiItem { @Override public ItemStack getObject() { - return ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, ChatColor.GREEN + "" + (num + 1) + ":", wrap(getPoll() - .getAnswers()[num])); + ArrayList lore = new ArrayList<>(); + lore.add(""); + lore.add(getPoll().getAnswers()[num]); + return ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, ChatColor.GREEN + "Option " + (num + 1), lore); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java index 5cfb45207..14f43e9c6 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java @@ -149,9 +149,9 @@ public class RankBonusButton implements GuiItem, Listener { lore.add(" "); lore.add(ChatColor.WHITE + "Players with a Rank get a Monthly Bonus!"); lore.add(ChatColor.WHITE + ""); - lore.add(ChatColor.AQUA + "Ultra: 7500 Coins"); - lore.add(ChatColor.LIGHT_PURPLE + "Hero: 15000 Coins"); - lore.add(ChatColor.GREEN + "Legend: 30000 Coins"); + lore.add(ChatColor.AQUA + "Ultra receives 7500 Coins Monthly"); + lore.add(ChatColor.LIGHT_PURPLE + "Hero receives 15000 Coins Monthly"); + lore.add(ChatColor.GREEN + "Legend receives 30000 Coins Monthly"); lore.add(ChatColor.WHITE + ""); lore.add(ChatColor.WHITE + "Purchase a Rank at;"); lore.add(ChatColor.WHITE + "www.mineplex.com/shop"); @@ -197,7 +197,15 @@ public class RankBonusButton implements GuiItem, Listener { public boolean isAvailable() { if (!hasRank) + { + UtilPlayer.message(getPlayer(), "----------------------------------------"); + UtilPlayer.message(getPlayer(), ""); + UtilPlayer.message(getPlayer(), "Purchase a Rank at the Mineplex Shop:"); + UtilPlayer.message(getPlayer(), C.cGreen + "www.mineplex.com/shop"); + UtilPlayer.message(getPlayer(), ""); + UtilPlayer.message(getPlayer(), "----------------------------------------"); return false; + } return (timeLeft() <= 0); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java new file mode 100644 index 000000000..f4e3b506a --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java @@ -0,0 +1,51 @@ +package mineplex.hub.profile.buttons; + +import mineplex.core.common.util.C; +import mineplex.core.gui.GuiItem; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.hub.profile.gui.GUIProfile; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; + +public class ButtonMPS implements GuiItem +{ + + private GUIProfile _profile; + private Player _player; + + public ButtonMPS(GUIProfile profile, Player player) + { + _profile = profile; + _player = player; + } + + @Override + public void click(ClickType clickType) + { + _profile.getPersonalManager().showHostMessage(_player); + } + + @Override + public ItemStack getObject() + { + return ItemStackFactory.Instance.CreateStack(Material.SPECKLED_MELON, (byte)0, 1, C.cGreen + "/hostserver"); + } + + @Override + public void setup() + { + + } + + @Override + public void close() + { + + } + +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java new file mode 100644 index 000000000..8795cd2a5 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java @@ -0,0 +1,51 @@ +package mineplex.hub.profile.buttons; + +import mineplex.core.common.util.C; +import mineplex.core.gui.GuiItem; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.hub.profile.gui.GUIProfile; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; + +public class ButtonPrefs implements GuiItem +{ + + private GUIProfile _profile; + private Player _player; + + public ButtonPrefs(GUIProfile profile, Player player) + { + _profile = profile; + _player = player; + } + + @Override + public void click(ClickType clickType) + { + _profile.getPrefManager().openShop(_player); + } + + @Override + public ItemStack getObject() + { + return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_COMPARATOR.getId(), (byte)0, 1, ChatColor.GREEN + "/prefs"); + } + + @Override + public void setup() + { + + } + + @Override + public void close() + { + + } + +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java new file mode 100644 index 000000000..d5533a4ed --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java @@ -0,0 +1,55 @@ +package mineplex.hub.profile.buttons; + +import mineplex.core.common.util.C; +import mineplex.core.gui.GuiItem; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.hub.profile.gui.GUIProfile; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; + +public class ButtonStats implements GuiItem +{ + + private GUIProfile _profile; + private Player _player; + + public ButtonStats(GUIProfile profile, Player player) + { + _profile = profile; + _player = player; + } + + @Override + public void click(ClickType clickType) + { + _profile.getAchievementManager().openShop(_player); + } + + @Override + public ItemStack getObject() + { + ItemStack item = ItemStackFactory.Instance.CreateStack(Material.SKULL_ITEM, (byte) 3, 1, ChatColor.RESET + C.cGreen + "/stats"); + SkullMeta meta = ((SkullMeta) item.getItemMeta()); + meta.setOwner(_player.getName()); + item.setItemMeta(meta); + return item; + } + + @Override + public void setup() + { + + } + + @Override + public void close() + { + + } + +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java new file mode 100644 index 000000000..35c6ccf65 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java @@ -0,0 +1,48 @@ +package mineplex.hub.profile.gui; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import mineplex.core.achievement.AchievementManager; +import mineplex.core.gui.SimpleGui; +import mineplex.core.personalServer.PersonalServerManager; +import mineplex.core.preferences.PreferencesManager; +import mineplex.hub.profile.buttons.ButtonMPS; +import mineplex.hub.profile.buttons.ButtonPrefs; +import mineplex.hub.profile.buttons.ButtonStats; + +public class GUIProfile extends SimpleGui +{ + + private PreferencesManager _preferencesManager; + private AchievementManager _achievementManager; + private PersonalServerManager _personalServerManager; + + public GUIProfile(Plugin plugin, Player player, PreferencesManager preferencesManager, AchievementManager achievementManager, PersonalServerManager personalServerManager) + { + super(plugin, player, "My Profile", 9*3); + _preferencesManager = preferencesManager; + _achievementManager = achievementManager; + _personalServerManager = personalServerManager; + + setItem(11, new ButtonStats(this, player)); + setItem(13, new ButtonMPS(this, player)); + setItem(15, new ButtonPrefs(this, player)); + } + + public PreferencesManager getPrefManager() + { + return _preferencesManager; + } + + public AchievementManager getAchievementManager() + { + return _achievementManager; + } + + public PersonalServerManager getPersonalManager() + { + return _personalServerManager; + } + +} From ee65c72e8680287408518f345f3d581c5cda6121 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Sun, 9 Aug 2015 18:46:02 +0200 Subject: [PATCH 284/377] and wizards! --- .../src/nautilus/game/arcade/game/games/wizards/Wizards.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/wizards/Wizards.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/wizards/Wizards.java index f68614c57..01de44716 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/wizards/Wizards.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/wizards/Wizards.java @@ -155,6 +155,7 @@ public class Wizards extends SoloGame _wizard = new WizardSpellMenu("Wizard Spell Menu", getArcadeManager().getPlugin(), this); + AnnounceStay = false; BlockBreak = true; BlockPlace = true; ItemPickup = true; From 41dcc564c9a90b3a5f554b28e4b19d25e6fc642a Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Sun, 9 Aug 2015 19:02:07 +0200 Subject: [PATCH 285/377] polish polish polish MAKE IT SHINE! --- .../src/mineplex/hub/bonuses/gui/SpinGui.java | 23 ++++++++++++++++++- .../hub/profile/buttons/ButtonMPS.java | 11 ++++++++- .../hub/profile/buttons/ButtonPrefs.java | 12 +++++++++- .../hub/profile/buttons/ButtonStats.java | 18 +++++++++++---- .../mineplex/hub/profile/gui/GUIProfile.java | 4 ++-- 5 files changed, 59 insertions(+), 9 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java index fb3355211..7489d4dc3 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java @@ -11,8 +11,13 @@ import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.reward.Reward; import mineplex.core.reward.RewardData; import mineplex.core.reward.RewardManager; +import mineplex.core.reward.RewardRarity; import mineplex.core.reward.RewardType; import mineplex.core.shop.item.ShopItem; +import mineplex.core.treasure.animation.LootLegendaryAnimation; +import mineplex.core.treasure.animation.LootMythicalAnimation; +import mineplex.core.treasure.animation.LootRareAnimation; +import mineplex.core.treasure.animation.LootUncommonAnimation; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.hub.bonuses.BonusManager; @@ -180,7 +185,23 @@ public class SpinGui extends SimpleGui return; _manager.addPendingExplosion(getPlayer(), _reward); - UtilPlayer.message(getPlayer(), F.main("Carl's Spinner", "You got " + _rewardData.getRarity().getColor() + _rewardData.getFriendlyName() + C.cGray + " From Carl's Spinner.")); + + if (_reward.getRarity() == RewardRarity.RARE) + { + Bukkit.broadcastMessage(F.main("Treasure", F.name(event.getPlayer().getName()) + " won " + C.cPurple + "Rare " + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } + else if (_reward.getRarity() == RewardRarity.LEGENDARY) + { + Bukkit.broadcastMessage(F.main("Treasure", F.name(event.getPlayer().getName()) + " won " + C.cGreen + "Legendary " + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } + else if (_reward.getRarity() == RewardRarity.MYTHICAL) + { + Bukkit.broadcastMessage(F.main("Treasure", F.name(event.getPlayer().getName()) + " won " + C.cRed + "Mythical " + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } + else + { + UtilPlayer.message(getPlayer(), F.main("Carl's Spinner", "You won " + _rewardData.getRarity().getColor() + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } } @EventHandler diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java index f4e3b506a..00135e777 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonMPS.java @@ -33,7 +33,16 @@ public class ButtonMPS implements GuiItem @Override public ItemStack getObject() { - return ItemStackFactory.Instance.CreateStack(Material.SPECKLED_MELON, (byte)0, 1, C.cGreen + "/hostserver"); + return ItemStackFactory.Instance.CreateStack(Material.SPECKLED_MELON, (byte)0, 1, + ChatColor.RESET + C.cYellow + "Mineplex Player Server", + new String[] + { + "", + C.cWhite + "Create a server where you are the Host.", + C.cWhite + "You can choose the game, map and much more!", + "", + C.cWhite + "Type " + C.cGreen + "/mps" + C.cWhite + " to access this anywhere!" + }); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java index 8795cd2a5..38652a7c7 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonPrefs.java @@ -33,7 +33,17 @@ public class ButtonPrefs implements GuiItem @Override public ItemStack getObject() { - return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_COMPARATOR.getId(), (byte)0, 1, ChatColor.GREEN + "/prefs"); + return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_COMPARATOR.getId(), (byte)0, 1, + ChatColor.RESET + C.cYellow + "Preferences", + new String[] + { + "", + C.cWhite + "Set your preferences to your liking", + C.cWhite + "so you can enjoy the game more!", + + "", + C.cWhite + "Type " + C.cGreen + "/prefs" + C.cWhite + " to access this anywhere!" + }); } @Override diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java index d5533a4ed..3e36c712d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/buttons/ButtonStats.java @@ -17,7 +17,7 @@ public class ButtonStats implements GuiItem private GUIProfile _profile; private Player _player; - + public ButtonStats(GUIProfile profile, Player player) { _profile = profile; @@ -33,7 +33,17 @@ public class ButtonStats implements GuiItem @Override public ItemStack getObject() { - ItemStack item = ItemStackFactory.Instance.CreateStack(Material.SKULL_ITEM, (byte) 3, 1, ChatColor.RESET + C.cGreen + "/stats"); + ItemStack item = ItemStackFactory.Instance.CreateStack(Material.SKULL_ITEM, (byte) 3, 1, + ChatColor.RESET + C.cYellow + "Stats and Achievements", + new String[] + { + "", + C.cWhite + "View your Statistics and Achievements", + C.cWhite + "for all of the games on Mineplex!", + + "", + C.cWhite + "Type " + C.cGreen + "/stats" + C.cWhite + " to access this anywhere!" + }); SkullMeta meta = ((SkullMeta) item.getItemMeta()); meta.setOwner(_player.getName()); item.setItemMeta(meta); @@ -43,13 +53,13 @@ public class ButtonStats implements GuiItem @Override public void setup() { - + } @Override public void close() { - + } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java index 35c6ccf65..a7dca223b 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/profile/gui/GUIProfile.java @@ -26,8 +26,8 @@ public class GUIProfile extends SimpleGui _personalServerManager = personalServerManager; setItem(11, new ButtonStats(this, player)); - setItem(13, new ButtonMPS(this, player)); - setItem(15, new ButtonPrefs(this, player)); + setItem(13, new ButtonPrefs(this, player)); + setItem(15, new ButtonMPS(this, player)); } public PreferencesManager getPrefManager() From c2d066a576cd4089311743adcc0581f6e6f26734 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Sun, 9 Aug 2015 19:31:24 +0200 Subject: [PATCH 286/377] ui fixes --- .../src/mineplex/hub/bonuses/gui/SpinGui.java | 15 ++++++++------- .../hub/bonuses/gui/buttons/PollButton.java | 9 ++++----- .../hub/bonuses/gui/buttons/RankBonusButton.java | 2 ++ .../hub/bonuses/gui/buttons/VoteButton.java | 4 ++-- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java index 7489d4dc3..9e9bbefa9 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java @@ -40,7 +40,6 @@ public class SpinGui extends SimpleGui private static final int HOPPER_SLOT = 4; private static final int CARL_SLOT = 22; private static final int[] LINE_NUMS = { /*-27, -18,*/ -9, 9/*, 18*/ }; - private static final int STOP_SPINNER_AT = 75; private int _tickCount; private RewardData _rewardData; @@ -76,13 +75,11 @@ public class SpinGui extends SimpleGui for (int i = 0; i < REWARDS_TO_GENERATE; i++) { - _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.Spinner, true); + _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.MythicalChest, true); } _ticksPerSwap = 1; - - _stopSpinnerAt = STOP_SPINNER_AT; - + for (int i=0 ; i<40 ; i++) _ticks.add(1); @@ -92,15 +89,19 @@ public class SpinGui extends SimpleGui for (int i=0 ; i<10 ; i++) _ticks.add(4); - for (int i=0 ; i<5 ; i++) + for (int i=0 ; i<4 ; i++) + _ticks.add(6); + + for (int i=0 ; i<3 ; i++) _ticks.add(8); if (Math.random() > 0.5) { _ticks.add(12); - _stopSpinnerAt++; } + _stopSpinnerAt = _ticks.size(); + _reward = _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; _rewardData = _reward.giveReward("Carls Spinner", getPlayer()); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java index b5fe9dca1..008a024ce 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java @@ -75,7 +75,7 @@ public class PollButton extends SimpleGui implements GuiItem { ArrayList lore = new ArrayList<>(); if (_poll == null) { - lore.add(C.cRed + "You've already voted on all of the polls!"); + lore.add(C.cRed + "You've voted on all of the polls!"); return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + C.Bold + "Vote on Poll", lore); } else @@ -116,7 +116,8 @@ public class PollButton extends SimpleGui implements GuiItem { ArrayList lore = new ArrayList<>(); lore.add(""); - lore.add(C.cWhite + wrap(question)); + for (String string : wrap(question)) + lore.add(C.cWhite + string); lore.add(""); int i = 1; for(String str : _poll.getAnswers()) @@ -126,8 +127,6 @@ public class PollButton extends SimpleGui implements GuiItem { } lore.add(""); lore.add(C.cYellow + "Reward:" + C.cWhite + " 500 Gems"); - lore.add(""); - lore.add(C.cGreen + "Click to go to the vote page!"); return new SimpleGuiItem(ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, ChatColor.GREEN + C.cGreen + C.Bold + "Vote on Poll", lore)); @@ -177,7 +176,7 @@ public class PollButton extends SimpleGui implements GuiItem { { ArrayList lore = new ArrayList<>(); lore.add(""); - lore.add(getPoll().getAnswers()[num]); + lore.add(C.cWhite + getPoll().getAnswers()[num]); return ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, ChatColor.GREEN + "Option " + (num + 1), lore); } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java index 14f43e9c6..b394a398e 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java @@ -204,6 +204,8 @@ public class RankBonusButton implements GuiItem, Listener { UtilPlayer.message(getPlayer(), C.cGreen + "www.mineplex.com/shop"); UtilPlayer.message(getPlayer(), ""); UtilPlayer.message(getPlayer(), "----------------------------------------"); + + getPlayer().closeInventory(); return false; } return (timeLeft() <= 0); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java index 54021b6f2..f7fcb06a1 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java @@ -80,14 +80,14 @@ public class VoteButton implements GuiItem, Listener { getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); - UtilPlayer.message(getPlayer(), C.cRed + "------------------------------------------------"); + UtilPlayer.message(getPlayer(), "----------------------------------------"); UtilPlayer.message(getPlayer(), ""); new JsonMessage("Click to Open in Web Browser").click(ClickEvent.OPEN_URL, _url).sendToPlayer(getPlayer()); new JsonMessage(C.cGreen + _url).click(ClickEvent.OPEN_URL, _url).sendToPlayer(getPlayer()); UtilPlayer.message(getPlayer(), ""); - UtilPlayer.message(getPlayer(), C.cRed + "------------------------------------------------"); + UtilPlayer.message(getPlayer(), "----------------------------------------"); From f8a6a25b46b9336ae8a727e1f3478f3a7a394324 Mon Sep 17 00:00:00 2001 From: Mysticate Date: Sun, 9 Aug 2015 15:01:27 -0400 Subject: [PATCH 287/377] Various Fixes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Merged w/ master • Changed to William's method of Projectile limiting. - Prevented TNT hitting Teammates • Fixed gem count for Sniper • Added gems for direct hits + TNT Thrown • Removed assists counting for kills in 6 kill. --- .../core/achievement/Achievement.java | 2 +- .../core/projectile/ProjectileManager.java | 57 +++++++++++++++++- .../core/projectile/ProjectileUser.java | 58 ++++++++++++++++++- .../game/games/lobbers/BombLobbers.java | 27 +++++---- 4 files changed, 128 insertions(+), 16 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/Achievement.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/Achievement.java index 64d6215aa..f122d3034 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/Achievement.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/Achievement.java @@ -662,7 +662,7 @@ public enum Achievement new int[]{20}, AchievementCategory.BOMB_LOBBERS), - BOMB_LOBBERS_SNIPER("Sniper", 10000, + BOMB_LOBBERS_SNIPER("Sniper", 1000, new String[]{"Bomb Lobbers.Direct Hit"}, new String[]{"Get 50 direct hits"}, new int[]{50}, diff --git a/Plugins/Mineplex.Core/src/mineplex/core/projectile/ProjectileManager.java b/Plugins/Mineplex.Core/src/mineplex/core/projectile/ProjectileManager.java index 132500dc8..03f44665d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/projectile/ProjectileManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/projectile/ProjectileManager.java @@ -1,6 +1,7 @@ package mineplex.core.projectile; import java.util.Iterator; +import java.util.List; import java.util.Map.Entry; import java.util.WeakHashMap; @@ -13,6 +14,7 @@ import org.bukkit.Effect; import org.bukkit.Sound; 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.inventory.InventoryPickupItemEvent; @@ -75,10 +77,63 @@ public class ProjectileManager extends MiniPlugin long expireTime, boolean hitPlayer, boolean hitBlock, boolean idle, Sound sound, float soundVolume, float soundPitch, ParticleType particle, float pX, float pY, float pZ, float pS, int pC, UpdateType effectRate, float hitboxMult) { - _thrown.put(thrown, new ProjectileUser(this, thrown, thrower, callback, + _thrown.put(thrown, new ProjectileUser(this, thrown, thrower, callback, expireTime, hitPlayer, hitBlock, idle, false, sound, soundVolume, soundPitch, null, 0, effectRate, particle, pX, pY, pZ, pS, pC, hitboxMult)); } + + // WITH CAN HIT PLAYERS LIST: + public void AddThrow(Entity thrown, LivingEntity thrower, IThrown callback, + long expireTime, boolean hitPlayer, boolean hitBlock, boolean idle, float hitboxGrow, List canHit) + { + _thrown.put(thrown, new ProjectileUser(this, thrown, thrower, callback, + expireTime, hitPlayer, hitBlock, idle, false, + null, 1f, 1f, null, 0, null, null, 0F, 0F, 0F, 0F, 1, hitboxGrow, canHit)); + } + + public void AddThrow(Entity thrown, LivingEntity thrower, IThrown callback, + long expireTime, boolean hitPlayer, boolean hitBlock, boolean idle, boolean pickup, float hitboxGrow, List canHit) + { + _thrown.put(thrown, new ProjectileUser(this, thrown, thrower, callback, + expireTime, hitPlayer, hitBlock, idle, pickup, + null, 1f, 1f, null, 0, null, null, 0F, 0F, 0F, 0F, 1, hitboxGrow, canHit)); + } + + public void AddThrow(Entity thrown, LivingEntity thrower, IThrown callback, + long expireTime, boolean hitPlayer, boolean hitBlock, boolean idle, + Sound sound, float soundVolume, float soundPitch, Effect effect, int effectData, UpdateType effectRate , float hitboxGrow, List canHit) + { + _thrown.put(thrown, new ProjectileUser(this, thrown, thrower, callback, + expireTime, hitPlayer, hitBlock, idle, false, + sound, soundVolume, soundPitch, effect, effectData, effectRate, null, 0F, 0F, 0F, 0F, 1, hitboxGrow, canHit)); + } + + public void AddThrow(Entity thrown, LivingEntity thrower, IThrown callback, + long expireTime, boolean hitPlayer, boolean hitBlock, boolean idle, + Sound sound, float soundVolume, float soundPitch, ParticleType particle, Effect effect, int effectData, UpdateType effectRate, float hitboxGrow, List canHit) + { + _thrown.put(thrown, new ProjectileUser(this, thrown, thrower, callback, + expireTime, hitPlayer, hitBlock, idle, false, + sound, soundVolume, soundPitch, effect, effectData, effectRate, particle, 0F, 0F, 0F, 0F, 1, hitboxGrow, canHit)); + } + + public void AddThrow(Entity thrown, LivingEntity thrower, IThrown callback, + long expireTime, boolean hitPlayer, boolean hitBlock, boolean idle, + Sound sound, float soundVolume, float soundPitch, ParticleType particle, UpdateType effectRate, float hitboxMult, List canHit) + { + _thrown.put(thrown, new ProjectileUser(this, thrown, thrower, callback, + expireTime, hitPlayer, hitBlock, idle, false, + sound, soundVolume, soundPitch, null, 0, effectRate, particle, 0F, 0F, 0F, 0F, 1, hitboxMult, canHit)); + } + + public void AddThrow(Entity thrown, LivingEntity thrower, IThrown callback, + long expireTime, boolean hitPlayer, boolean hitBlock, boolean idle, + Sound sound, float soundVolume, float soundPitch, ParticleType particle, float pX, float pY, float pZ, float pS, int pC, UpdateType effectRate, float hitboxMult, List canHit) + { + _thrown.put(thrown, new ProjectileUser(this, thrown, thrower, callback, + expireTime, hitPlayer, hitBlock, idle, false, + sound, soundVolume, soundPitch, null, 0, effectRate, particle, pX, pY, pZ, pS, pC, hitboxMult, canHit)); + } @EventHandler public void Update(UpdateEvent event) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/projectile/ProjectileUser.java b/Plugins/Mineplex.Core/src/mineplex/core/projectile/ProjectileUser.java index 6c94d9e00..3d71c0831 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/projectile/ProjectileUser.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/projectile/ProjectileUser.java @@ -1,5 +1,7 @@ package mineplex.core.projectile; +import java.util.List; + import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilParticle.ParticleType; @@ -55,13 +57,51 @@ public class ProjectileUser private UpdateType _effectRate = UpdateType.TICK; private double _hitboxGrow; + + private List _canHit; + + public ProjectileUser(ProjectileManager throwInput, Entity thrown, LivingEntity thrower, IThrown callback, + long expireTime, boolean hitPlayer, boolean hitBlock, boolean idle, boolean pickup, + Sound sound, float soundVolume, float soundPitch, + Effect effect, int effectData, UpdateType effectRate, + ParticleType particle, float particleX, float particleY, + float particleZ, float particleS, int particleC, double hitboxMult) + { + Throw = throwInput; + + _thrown = thrown; + _thrower = thrower; + _callback = callback; + + _expireTime = expireTime; + _hitPlayer = hitPlayer; + _hitBlock = hitBlock; + _idle = idle; + _pickup = pickup; + + _sound = sound; + _soundVolume = soundVolume; + _soundPitch = soundPitch; + _particle = particle; + _particleX = particleX; + _particleY = particleY; + _particleZ = particleZ; + _particleS = particleS; + _particleC = particleC; + _effect = effect; + _effectData = effectData; + _effectRate = effectRate; + + _hitboxGrow = hitboxMult; + _canHit = null; + } public ProjectileUser(ProjectileManager throwInput, Entity thrown, LivingEntity thrower, IThrown callback, long expireTime, boolean hitPlayer, boolean hitBlock, boolean idle, boolean pickup, Sound sound, float soundVolume, float soundPitch, Effect effect, int effectData, UpdateType effectRate, ParticleType particle, float particleX, float particleY, - float particleZ, float particleS, int particleC, double hitboxMult) + float particleZ, float particleS, int particleC, double hitboxMult, List canHit) { Throw = throwInput; @@ -89,6 +129,7 @@ public class ProjectileUser _effectRate = effectRate; _hitboxGrow = hitboxMult; + _canHit = canHit; } public void Effect(UpdateEvent event) @@ -152,11 +193,22 @@ public class ProjectileUser if (ent.equals(_thrower)) continue; - //Creative or Spec + //Creative or Spec or No Hit if (ent instanceof Player) - if (((Player)ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent)) + { + if (((Player)ent).getGameMode() == GameMode.CREATIVE) continue; + if (UtilPlayer.isSpectator(ent)) + continue; + + if (_canHit != null) + { + if (!_canHit.contains(((Player)ent))) + continue; + } + } + //float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f); AxisAlignedBB axisalignedbb1 = ((CraftEntity)ent).getHandle().boundingBox.grow(1F, 1F, 1F); MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/lobbers/BombLobbers.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/lobbers/BombLobbers.java index e43c1adb1..5a7f6a0de 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/lobbers/BombLobbers.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/lobbers/BombLobbers.java @@ -130,11 +130,6 @@ public class BombLobbers extends TeamGame implements IThrown _kills.put(player, _kills.containsKey(player) ? _kills.get(player) + 1 : 1); } - public void addAssist(Player player) - { - _kills.put(player, _kills.containsKey(player) ? _kills.get(player) + .5 : .5); - } - public double getKills(Player player) { if (_kills.containsKey(player)) @@ -172,10 +167,6 @@ public class BombLobbers extends TeamGame implements IThrown { addKill(killer); } - else - { - addAssist(killer); - } } } } @@ -228,11 +219,23 @@ public class BombLobbers extends TeamGame implements IThrown tnt.setFuseTicks(60); UtilAction.velocity(tnt, player.getLocation().getDirection(), 2.0D, false, 0.0D, 0.1D, 10.0D, false); - Manager.GetProjectile().AddThrow(tnt, player, this, -1L, true, false, true, .2F); - + + ArrayList canHit = new ArrayList(); + for (Player pos : GetPlayers(true)) + { + if (GetTeam(player).HasPlayer(pos)) + continue; + + canHit.add(pos); + } + + Manager.GetProjectile().AddThrow(tnt, player, this, -1L, true, false, true, .2F, canHit); + Manager.getPlugin().getServer().getPluginManager().callEvent(new TNTThrowEvent(player, tnt)); _tnt.put(tnt, new BombToken(player)); + + AddGems(player, 0.5, "TNT Thrown", true, true); } public Player getThrower(TNTPrimed tnt) @@ -562,6 +565,8 @@ public class BombLobbers extends TeamGame implements IThrown UtilAction.velocity(target, UtilAlg.getTrajectory2d(data.GetThrown().getLocation(), target.getLocation()), .2, false, 0, 0.2, .4, true); Manager.GetDamage().NewDamageEvent(target, data.GetThrower(), null, DamageCause.PROJECTILE, 10.0, false, false, false, "Throwing TNT", "Throwing TNT Direct Hit"); + + AddGems((Player) data.GetThrower(), 4.0, "Direct Hit", true, true); } @Override From d20fe5401077a9a150fbdaf4a0067e7e651462d8 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Sun, 9 Aug 2015 16:36:48 -0500 Subject: [PATCH 288/377] Disable carl features when carl can't be found --- .../src/mineplex/core/npc/NpcManager.java | 2 +- .../mineplex/hub/bonuses/BonusManager.java | 55 +++++++++++++------ 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/npc/NpcManager.java b/Plugins/Mineplex.Core/src/mineplex/core/npc/NpcManager.java index f856cda99..d92a8690e 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/npc/NpcManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/npc/NpcManager.java @@ -165,7 +165,7 @@ public class NpcManager extends MiniPlugin { for (Npc npc : _npcs) { - if (npc.getDatabaseRecord().getName() != null && npc.getDatabaseRecord().getName().equalsIgnoreCase(name)) + if (npc.getDatabaseRecord().getName() != null && npc.getDatabaseRecord().getName().contains(name)) return npc; } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index 6bd421b75..08bf386c9 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -16,16 +16,11 @@ import mineplex.core.common.Rank; import mineplex.core.common.util.C; import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; -import mineplex.core.common.util.NautHashMap; -import mineplex.core.common.util.UtilAction; -import mineplex.core.common.util.UtilBlock; -import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilParticle.ViewDist; -import mineplex.core.disguise.disguises.DisguiseCreeper; import mineplex.core.donation.DonationManager; import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; @@ -46,7 +41,6 @@ import mineplex.hub.poll.PollManager; import mineplex.serverdata.commands.ServerCommandManager; import org.bukkit.Bukkit; -import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; import org.bukkit.entity.Entity; @@ -54,12 +48,10 @@ import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.util.Vector; import net.minecraft.server.v1_7_R4.DataWatcher; import net.minecraft.server.v1_7_R4.PacketPlayOutEntityMetadata; @@ -116,6 +108,7 @@ public class BonusManager extends MiniClientPlugin implements I private NpcManager _npcManager; private HologramManager _hologramManager; private RewardManager _rewardManager; + public boolean _enabled; private Npc _carlNpc; private AnimationCarl _animation; @@ -137,8 +130,18 @@ public class BonusManager extends MiniClientPlugin implements I // Hope to god this works! _canVote = true; _carlNpc = _npcManager.getNpcByName("Carl the Creeper"); - _animation = new AnimationCarl(_carlNpc.getEntity()); - _animation.setRunning(false); + if (_carlNpc == null) + { + _enabled = false; + } + else + { + _enabled = true; +// _carlNpc.getEntity().setCustomName(""); +// _carlNpc.getEntity().setCustomNameVisible(false); + _animation = new AnimationCarl(_carlNpc.getEntity()); + _animation.setRunning(false); + } clientManager.addStoredProcedureLoginProcessor(this); @@ -223,6 +226,9 @@ public class BonusManager extends MiniClientPlugin implements I if(!_canVote) return; + if (!_enabled) + return; + if(_pendingExplosions.get(0) instanceof String) { String name = (String)_pendingExplosions.get(0); @@ -241,6 +247,9 @@ public class BonusManager extends MiniClientPlugin implements I if(_canVote) return; + + if (!_enabled) + return; Entity creeper = _carlNpc.getEntity(); @@ -281,6 +290,9 @@ public class BonusManager extends MiniClientPlugin implements I { if(event.getType() != UpdateType.TICK) return; + + if (!_enabled) + return; if(!_animation.isRunning()) return; @@ -290,12 +302,18 @@ public class BonusManager extends MiniClientPlugin implements I public void DecreaseSize(Entity player) { + if (!_enabled) + return; + ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(16, -1); ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(17, 1); } public void IncreaseSize(Entity player) { + if (!_enabled) + return; + ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(16, 1); } @@ -643,8 +661,11 @@ public class BonusManager extends MiniClientPlugin implements I @EventHandler public void openGui(PlayerInteractEntityEvent event) { + if (!_enabled) + return; + Entity entity = event.getRightClicked(); - if (entity instanceof LivingEntity && entity.getType().equals(EntityType.CREEPER) && ((LivingEntity) entity).getCustomName().contains("Carl the Creeper")) + if (entity.equals(_carlNpc.getEntity())) { updateDailyStreak(event.getPlayer()); new BonusGui(_plugin, event.getPlayer(), this, _rewardManager).openInventory(); @@ -698,14 +719,11 @@ public class BonusManager extends MiniClientPlugin implements I }, 10); } - @EventHandler - public void join(PlayerInteractEvent event) - { - updateCreeperVisual(event.getPlayer()); - } - public void updateCreeperVisual(Player player) { + if (!_enabled) + return; + BonusClientData client = Get(player); int availableRewards = 0; @@ -719,7 +737,7 @@ public class BonusManager extends MiniClientPlugin implements I if (client.getHologram() == null) { - hologram = new Hologram(_hologramManager, _carlNpc.getLocation().clone().add(0, 2.75, 0), ""); + hologram = new Hologram(_hologramManager, _carlNpc.getLocation().clone().add(0, 2.75 - 0.285 - 0.285, 0), ""); hologram.setHologramTarget(Hologram.HologramTarget.WHITELIST); hologram.addPlayer(player); client.setHologram(hologram); @@ -732,6 +750,7 @@ public class BonusManager extends MiniClientPlugin implements I if (availableRewards > 0) { // Hologram +// String name = "Carl the Creeper"; String text = C.cAqua + availableRewards + " Reward" + (availableRewards > 1 ? "s" : "") + " to Claim"; hologram.setText(text); hologram.start(); From 28806aaf0a2a4b5b4fd4638017900d82a0de626c Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Mon, 10 Aug 2015 00:33:54 -0500 Subject: [PATCH 289/377] Update Bonus amounts, Attempting to fix Votifier plugin for EU/US --- .../src/mineplex/hub/bonuses/BonusAmount.java | 4 +- .../mineplex/hub/bonuses/BonusManager.java | 46 ++++++- .../mineplex/hub/bonuses/BonusRepository.java | 7 +- .../bonuses/gui/buttons/DailyBonusButton.java | 2 + .../hub/bonuses/gui/buttons/VoteButton.java | 2 + .../serverdata/servers/ServerManager.java | 11 +- .../Mineplex.Votifier/Mineplex.Votifier.iml | 4 + .../mineplex/votifier/VotifierManager.java | 130 +++++++++++++++--- 8 files changed, 170 insertions(+), 36 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java index d596a846b..17b12a1c7 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java @@ -150,7 +150,7 @@ public class BonusAmount if (amount > 0) lore.add(C.cYellow + "Reward: " + C.cWhite + amount + " " + suffix); - if (bonus > 0) - lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + bonus + " " + suffix); +// if (bonus > 0) +// lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + bonus + " " + suffix); } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index 08bf386c9..b91ff0527 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -211,6 +211,8 @@ public class BonusManager extends MiniClientPlugin implements I public void handleVote(Player player) { +// _repository.attemptDailyBonus(); + addPendingExplosion(player, player.getName()); } @@ -500,20 +502,54 @@ public class BonusManager extends MiniClientPlugin implements I return calendar.getTimeInMillis(); } + public int getDailyMultiplier(Player player) + { + BonusClientData client = Get(player); + int streak = client.getDailyStreak(); + + int multiplyer = Math.min(200, 5 * streak); + if (streak >= 40) multiplyer += (1 * (streak - 40)); + return multiplyer; + } + + public int getVoteMultiplyer(Player player) + { + BonusClientData client = Get(player); + int streak = client.getVoteStreak(); + + int multiplyer = Math.min(100, 5 * streak); + if (streak >= 20) multiplyer += (1 * (streak - 40)); + return multiplyer; + } + public BonusAmount getDailyBonusAmount(Player player) { + double mult = getDailyMultiplier(player) / 100.0; + BonusAmount amount = new BonusAmount(); - amount.setTickets(1); - amount.setBonusCoins(100); - amount.setBonusExperience(1000); + int coins = 100; + int gems = 100; + int experience = 250; + + amount.setCoins(coins); + amount.setGems(gems); + amount.setExperience(experience); + amount.setBonusCoins((int) (mult * coins)); + amount.setBonusGems((int) (mult * gems)); + amount.setBonusExperience((int) (mult * experience)); + return amount; } public BonusAmount getVoteBonusAmount(Player player) { + double mult = getVoteMultiplyer(player) / 100.0; + BonusAmount amount = new BonusAmount(); amount.setTickets(1); - amount.setGems(500); + amount.setGems(400); + amount.setBonusGems((int) (mult * 400)); + return amount; } @@ -545,7 +581,7 @@ public class BonusManager extends MiniClientPlugin implements I //VOTE - public void atteptVoteBonus(final Player player, final Callback result) + public void attemptVoteBonus(final Player player, final Callback result) { if (timeTillRankBonus(player) > 0) result.run(false); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java index 8fcc95d6d..bed58e3dd 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java @@ -251,13 +251,8 @@ public class BonusRepository extends RepositoryBase }); } - public void voteBonus(final Player player, final Callback result) + public void attemptVoteBonus(final Player player, final Callback result) { - if (!Recharge.Instance.usable(player, "AttemptVoteBonus")) - { - result.run(false); - return; - } final int accountId = _manager.getClientManager().Get(player).getAccountId(); final int coins = _manager.getRankBonusAmount(player).getCoins(); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java index f6534589d..8ee34647f 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java @@ -143,6 +143,8 @@ public class DailyBonusButton implements GuiItem, Listener lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getDailyStreak()); + lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + _bonusManager.getDailyMultiplier(_player) + "%"); + lore.add(" "); lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxDailyStreak()); if (client.getDailyTime() != null) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java index f7fcb06a1..969fc2f9d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java @@ -139,6 +139,8 @@ public class VoteButton implements GuiItem, Listener { lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getVoteStreak()); + lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + _bonusManager.getVoteMultiplyer(_player) + "%"); + lore.add(" "); lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxVoteStreak()); if (client.getVoteTime() != null) diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java index fbf5d563b..4ed251ae4 100644 --- a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java @@ -20,8 +20,9 @@ import mineplex.serverdata.servers.ConnectionData.ConnectionType; * */ public class ServerManager -{ +{ public static final String SERVER_STATUS_LABEL = "ServerStatus"; // Label differentiating ServerStatus related servers + private static final String DEFAULT_CONFIG = "redis-config.dat"; // Configuration determining connection information private static RedisConfig _config; @@ -74,7 +75,7 @@ public class ServerManager public static ConnectionData getConnection(boolean writeable, String name) { - return getConfig().getConnection(writeable, name); + return getConfig(DEFAULT_CONFIG).getConnection(writeable, name); } /** @@ -89,13 +90,13 @@ public class ServerManager /** * @return the {@link RedisConfig} associated with this manager, providing appropriate connections. */ - public static RedisConfig getConfig() + public static RedisConfig getConfig(String fileName) { if (_config == null) { try { - File configFile = new File("redis-config.dat"); + File configFile = new File(fileName); if (configFile.exists()) { @@ -113,7 +114,7 @@ public class ServerManager } else { - log("redis-config.dat not found at " + configFile.toPath().toString()); + log(fileName + " not found at " + configFile.toPath().toString()); _config = new RedisConfig(); } } diff --git a/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml b/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml index b7d71d202..c5e840788 100644 --- a/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml +++ b/Plugins/Mineplex.Votifier/Mineplex.Votifier.iml @@ -19,5 +19,9 @@ + + + + \ No newline at end of file diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index ecef96339..3ff5e1f0f 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -1,5 +1,7 @@ package mineplex.votifier; +import java.util.UUID; + import org.bukkit.event.EventHandler; import org.bukkit.plugin.java.JavaPlugin; @@ -7,64 +9,156 @@ import com.vexsoftware.votifier.model.Vote; import com.vexsoftware.votifier.model.VotifierEvent; import mineplex.core.MiniPlugin; import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.UUIDFetcher; +import mineplex.core.database.DBPool; import mineplex.core.donation.DonationManager; import mineplex.core.votifier.VotifierCommand; +import mineplex.database.Tables; import mineplex.serverdata.Region; +import mineplex.serverdata.Utility; +import mineplex.serverdata.commands.ServerCommand; import mineplex.serverdata.commands.ServerCommandManager; import mineplex.serverdata.data.PlayerStatus; +import mineplex.serverdata.redis.RedisConfig; import mineplex.serverdata.redis.RedisDataRepository; import mineplex.serverdata.servers.ServerManager; +import org.jooq.DSLContext; +import org.jooq.SQLDialect; +import org.jooq.impl.DSL; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.exceptions.JedisConnectionException; /** * Created by shaun on 15-08-05. */ public class VotifierManager extends MiniPlugin { + private CoreClientManager _clientManager; + private DonationManager _donationManager; + + private RedisConfig _usConfig; + private RedisConfig _euConfig; private RedisDataRepository _usPlayerRepo; private RedisDataRepository _euPlayerRepo; + private JedisPool _usWritePool; + private JedisPool _euWritePool; public VotifierManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager) { super("Votifier", plugin); - _usPlayerRepo = new RedisDataRepository(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(), - Region.US, PlayerStatus.class, "playerStatus"); - _euPlayerRepo = new RedisDataRepository(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(), - Region.EU, PlayerStatus.class, "playerStatus"); + _clientManager = clientManager; + _donationManager = donationManager; - ServerCommandManager.getInstance().registerCommandType("VotifierCommand", VotifierCommand.class); + _usConfig = ServerManager.getConfig("us-redis.dat"); + _euConfig = ServerManager.getConfig("eu-redis.dat"); + + _usPlayerRepo = new RedisDataRepository(_usConfig.getConnection(true, "DefaultConnection"), + _usConfig.getConnection(false, "DefaultConnection"), Region.US, PlayerStatus.class, "playerStatus"); + _euPlayerRepo = new RedisDataRepository(_euConfig.getConnection(true, "DefaultConnection"), + _euConfig.getConnection(false, "DefaultConnection"), Region.EU, PlayerStatus.class, "playerStatus"); + + _usWritePool = Utility.generatePool(_usConfig.getConnection(true, "DefaultConnection")); + _euWritePool = Utility.generatePool(_euConfig.getConnection(true, "DefaultConnection")); } @EventHandler public void handleVote(VotifierEvent event) { Vote vote = event.getVote(); + String playerName = "Phinary"; - System.out.println("New Vote: " + vote.getUsername()); + System.out.println("New Vote: " + playerName); - PlayerStatus usStatus = _usPlayerRepo.getElement(vote.getUsername()); -// VotifierCommand command = new VotifierCommand(vote.getUsername(), "PhiTest-1"); -// command.publish(); +// UUID uuid = UUIDFetcher.getUUIDOf(playerName); + UUID uuid = _clientManager.loadUUIDFromDB(playerName); + if (uuid != null) + { + System.out.println("Found UUID:" + uuid.toString()); +// if (playerName.equalsIgnoreCase("Phinary")) +// { +// System.out.println("award bonus"); +// awardBonus(uuid); +// } + } + else + { + System.out.println("Failed to load UUID for player: " + playerName); + } + notifyServer(playerName); + } + + private boolean notifyServer(String playerName) + { + JedisPool writePool = null; + String serverName = null; + + PlayerStatus usStatus = _usPlayerRepo.getElement(playerName); if (usStatus != null) { System.out.println("Found on US Server: " + usStatus.getServer()); - VotifierCommand command = new VotifierCommand(vote.getUsername(), usStatus.getServer()); - command.publish(); - } - else - { - System.out.println("Not found on US Server!"); + writePool = _usWritePool; + serverName = usStatus.getServer(); } - PlayerStatus euStatus = _euPlayerRepo.getElement(vote.getUsername()); + PlayerStatus euStatus = _euPlayerRepo.getElement(playerName); if (euStatus != null) { System.out.println("Found on EU Server: " + euStatus.getServer()); + writePool = _euWritePool; + serverName = euStatus.getServer(); } - else + + if (writePool != null && serverName != null) { - System.out.println("Not found on EU Server!"); + VotifierCommand command = new VotifierCommand(playerName, serverName); + System.out.println("Publishing Server Command!"); + publishCommand(command, writePool); + + return true; } + + return false; + } + + private void awardBonus(UUID uuid) + { + DSLContext create = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL); + int updated = create.update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.add(1)) + .where(Tables.bonus.accountId.eq(DSL.select(Tables.accounts.id).where(Tables.accounts.uuid.eq(uuid.toString())))).execute(); + System.out.println("Ran query with response: " + updated); + } + + private void publishCommand(final ServerCommand serverCommand, final JedisPool writePool) + { + new Thread(new Runnable() + { + public void run() + { + Jedis jedis = writePool.getResource(); + + try + { + String commandType = serverCommand.getClass().getSimpleName(); + String serializedCommand = Utility.serialize(serverCommand); + jedis.publish("commands.server" + ":" + commandType, serializedCommand); + } + catch (JedisConnectionException exception) + { + exception.printStackTrace(); + writePool.returnBrokenResource(jedis); + jedis = null; + } + finally + { + if (writePool != null) + { + writePool.returnResource(jedis); + } + } + } + }).start(); } } \ No newline at end of file From 511cc76befbb3ca1cb81f22501926f76dcd59fe5 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Mon, 10 Aug 2015 00:47:36 -0500 Subject: [PATCH 290/377] Allow servers to process votifier votes, redis command gets sent to all servers (Until I can figure out why EU playertracker isnt working) --- .../core/votifier/VotifierCommand.java | 2 +- .../mineplex/hub/bonuses/BonusManager.java | 22 +++++- .../mineplex/hub/bonuses/BonusRepository.java | 8 -- .../mineplex/votifier/VotifierManager.java | 74 +++++++++---------- 4 files changed, 53 insertions(+), 53 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java index a84087fb0..0d8454d2d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java @@ -8,7 +8,7 @@ public class VotifierCommand extends ServerCommand { private String _playerName; - public VotifierCommand(String playerName, String targetServer) + public VotifierCommand(String playerName, String... targetServer) { super(targetServer); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index b91ff0527..a63556c77 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -209,11 +209,25 @@ public class BonusManager extends MiniClientPlugin implements I return _voteStreak; } - public void handleVote(Player player) + public void handleVote(final Player player) { -// _repository.attemptDailyBonus(); - - addPendingExplosion(player, player.getName()); + _repository.attemptVoteBonus(player, new Callback() + { + @Override + public void run(Boolean data) + { + if (data) + { + addPendingExplosion(player, player.getName()); + awardBonus(player, getVoteBonusAmount(player)); + UtilPlayer.message(player, F.main("Vote", "Thanks for your vote!")); + } + else + { + UtilPlayer.message(player, F.main("Vote", "There was an error processing your vote. Please contact an admin!")); + } + } + }); } @EventHandler diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java index bed58e3dd..f34c71296 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java @@ -97,10 +97,6 @@ public class BonusRepository extends RepositoryBase public void attemptDailyBonus(final Player player, final Callback result) { - if (!Recharge.Instance.usable(player, "AttemptDailyBonus")) { - result.run(false); - return; - } final int accountId = _manager.getClientManager().Get(player).getAccountId(); final int coins = 0; final int gems = 0; @@ -290,10 +286,6 @@ public class BonusRepository extends RepositoryBase public void run() { _manager.Get(player).setVoteTime(date); - - _donationManager.RewardCoins(null, "Vote bonus", player.getName(), accountId, coins); - _donationManager.RewardGems(null, "Vote bonus", player.getName(), player.getUniqueId(), gems); - result.run(true); } diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index 3ff5e1f0f..420fb5adf 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -67,64 +67,58 @@ public class VotifierManager extends MiniPlugin public void handleVote(VotifierEvent event) { Vote vote = event.getVote(); - String playerName = "Phinary"; + String playerName = vote.getUsername(); System.out.println("New Vote: " + playerName); // UUID uuid = UUIDFetcher.getUUIDOf(playerName); - UUID uuid = _clientManager.loadUUIDFromDB(playerName); - if (uuid != null) - { - System.out.println("Found UUID:" + uuid.toString()); +// UUID uuid = _clientManager.loadUUIDFromDB(playerName); +// if (uuid != null) +// { +// System.out.println("Found UUID:" + uuid.toString()); // if (playerName.equalsIgnoreCase("Phinary")) // { // System.out.println("award bonus"); // awardBonus(uuid); // } - } - else - { - System.out.println("Failed to load UUID for player: " + playerName); - } +// } +// else +// { +// System.out.println("Failed to load UUID for player: " + playerName); +// } - notifyServer(playerName); +// PlayerStatus usStatus = _usPlayerRepo.getElement(playerName); +// if (usStatus != null) +// { +// System.out.println("Found on US Server: " + usStatus.getServer()); +// writePool = _usWritePool; +// serverName = usStatus.getServer(); +// } +// +// PlayerStatus euStatus = _euPlayerRepo.getElement(playerName); +// if (euStatus != null) +// { +// System.out.println("Found on EU Server: " + euStatus.getServer()); +// writePool = _euWritePool; +// serverName = euStatus.getServer(); +// } + + // Currently we just notify all servers, and the server with the player on it can deal with it + notifyServer(playerName, false); + notifyServer(playerName, true); } - private boolean notifyServer(String playerName) + private void notifyServer(String playerName, boolean eu) { - JedisPool writePool = null; - String serverName = null; + JedisPool writePool = eu ? _euWritePool : _usWritePool; - PlayerStatus usStatus = _usPlayerRepo.getElement(playerName); - if (usStatus != null) - { - System.out.println("Found on US Server: " + usStatus.getServer()); - writePool = _usWritePool; - serverName = usStatus.getServer(); - } - - PlayerStatus euStatus = _euPlayerRepo.getElement(playerName); - if (euStatus != null) - { - System.out.println("Found on EU Server: " + euStatus.getServer()); - writePool = _euWritePool; - serverName = euStatus.getServer(); - } - - if (writePool != null && serverName != null) - { - VotifierCommand command = new VotifierCommand(playerName, serverName); - System.out.println("Publishing Server Command!"); - publishCommand(command, writePool); - - return true; - } - - return false; + VotifierCommand command = new VotifierCommand(playerName); + publishCommand(command, writePool); } private void awardBonus(UUID uuid) { + // Don't use this right now! DSLContext create = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL); int updated = create.update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.add(1)) .where(Tables.bonus.accountId.eq(DSL.select(Tables.accounts.id).where(Tables.accounts.uuid.eq(uuid.toString())))).execute(); From a0be3fa96480a559d804a6d850c04dbab0d59ea8 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Mon, 10 Aug 2015 01:19:10 -0500 Subject: [PATCH 291/377] Use atomic mysql operations for modifying tickets --- .../mineplex/hub/bonuses/BonusManager.java | 42 ++++++++++++--- .../mineplex/hub/bonuses/BonusRepository.java | 4 +- .../hub/bonuses/commands/TicketCommand.java | 54 +++++++++++++++++++ 3 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/TicketCommand.java diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java index a63556c77..c997deaf8 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java @@ -21,6 +21,7 @@ import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.database.DBPool; import mineplex.core.donation.DonationManager; import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; @@ -30,15 +31,20 @@ import mineplex.core.reward.RewardManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.core.votifier.VotifierCommand; +import mineplex.database.Tables; import mineplex.hub.bonuses.animations.AnimationCarl; import mineplex.hub.bonuses.commands.AnimationCommand; import mineplex.hub.bonuses.commands.GuiCommand; +import mineplex.hub.bonuses.commands.TicketCommand; import mineplex.hub.bonuses.event.CarlSpinnerEvent; import mineplex.hub.bonuses.gui.BonusGui; import mineplex.database.tables.records.BonusRecord; import mineplex.hub.bonuses.gui.SpinGui; import mineplex.hub.poll.PollManager; import mineplex.serverdata.commands.ServerCommandManager; +import org.jooq.DSLContext; +import org.jooq.SQLDialect; +import org.jooq.impl.DSL; import org.bukkit.Bukkit; import org.bukkit.Sound; @@ -157,6 +163,7 @@ public class BonusManager extends MiniClientPlugin implements I { addCommand(new GuiCommand(this)); addCommand(new AnimationCommand(this)); + addCommand(new TicketCommand(this)); } // Just keeping things up-to-date @@ -411,27 +418,29 @@ public class BonusManager extends MiniClientPlugin implements I if (!event.isCancelled()) { - clientData.setTickets(clientData.getTickets() - 1); + final int accountId = _clientManager.Get(player).getAccountId(); runAsync(new Runnable() { @Override public void run() { - int modified = clientData.getRecord().store(); - - if (modified == 1) + try { + final int newTickets = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL).update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.sub(1)). + where(Tables.bonus.accountId.eq(accountId)).returning(Tables.bonus.tickets).fetchOne().getTickets(); + runSync(new Runnable() { @Override public void run() { + clientData.setTickets(newTickets); new SpinGui(getPlugin(), player, _rewardManager, manager).openInventory(); } }); } - else + catch (Exception e) { UtilPlayer.message(player, F.main("Carl", "There was an error processing your request")); } @@ -689,16 +698,33 @@ public class BonusManager extends MiniClientPlugin implements I if (tickets > 0) { - bonusClient.setTickets(tickets + bonusClient.getTickets()); + final int accountId = _clientManager.Get(player).getAccountId(); runAsync(new Runnable() { @Override public void run() { - bonusClient.getRecord().store(); + try + { + final int newTickets = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL).update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.add(tickets)). + where(Tables.bonus.accountId.eq(accountId)).returning(Tables.bonus.tickets).fetchOne().getTickets(); + runSync(new Runnable() + { + @Override + public void run() + { + bonusClient.setTickets(newTickets); + UtilPlayer.message(player, F.main("Bonus", "Rewarded " + F.elem(tickets + " Carl Spin Ticket"))); + } + }); + } + catch (Exception e) + { + System.out.println("Failed to award ticket to player: " + player); + e.printStackTrace(); + } } }); - UtilPlayer.message(player, F.main("Bonus", "Rewarded " + F.elem(tickets + " Carl Spin Ticket"))); } if (experience > 0) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java index f34c71296..2f53ae3ac 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java @@ -53,7 +53,7 @@ public class BonusRepository extends RepositoryBase record.setVoteStreak(0); record.setMaxVoteStreak(0); record.setTickets(0); -// record.store(); // Todo - is this necessary? + record.store(); // Todo - is this necessary? } System.out.println("Loaded record. Daily time: " + record.getDailytime()); return record; @@ -158,7 +158,7 @@ public class BonusRepository extends RepositoryBase } @Deprecated - public void attemptPurchaseSpin(final Player player, final Callback result) + public void giveTickets(final Player player, final Callback result) { final int accountId = _manager.getClientManager().Get(player).getAccountId(); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/TicketCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/TicketCommand.java new file mode 100644 index 000000000..14afed1e8 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/TicketCommand.java @@ -0,0 +1,54 @@ +package mineplex.hub.bonuses.commands; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.Rank; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.hub.bonuses.BonusManager; + +import org.bukkit.entity.Player; + +public class TicketCommand extends CommandBase +{ + public TicketCommand(BonusManager plugin) + { + super(plugin, Rank.DEVELOPER, "ticket"); + } + + @Override + public void Execute(final Player caller, String[] args) + { + if (args.length < 2) + { + UtilPlayer.message(caller, F.main("Carl", "Missing Args: " + F.elem("/ticket "))); + return; + } + + final String targetName = args[0]; + final String ticketString = args[1]; + Player target = UtilPlayer.searchExact(targetName); + + + rewardTickets(caller, target, target.getName(), ticketString); + } + + private void rewardTickets(final Player caller, final Player target, final String targetName, String ticketString) + { + try + { + int tickets = Integer.parseInt(ticketString); + Plugin.Get(target).setTickets(Plugin.Get(targetName).getTickets() + tickets); + + UtilPlayer.message(caller, F.main("Carl", "You gave " + F.elem(tickets + " Carl Tickets") + " to " + F.name(targetName) + ".")); + + if (target != null) + { + UtilPlayer.message(target, F.main("Carl", F.name(caller.getName()) + " gave you " + F.elem(tickets + " Carl Tickets") + ".")); + } + } + catch (Exception e) + { + UtilPlayer.message(caller, F.main("Carl", "Invalid Ticket Amount")); + } + } +} From 6f8d6f8a407c1f9b96297949d2d1559167e7a2e8 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Mon, 10 Aug 2015 01:55:50 -0500 Subject: [PATCH 292/377] Move Bonus and Poll to core --- .../mineplex/core}/bonuses/BonusAmount.java | 2 +- .../core}/bonuses/BonusClientData.java | 2 +- .../mineplex/core}/bonuses/BonusManager.java | 45 +++++++++---------- .../core}/bonuses/BonusRepository.java | 2 +- .../mineplex/core}/bonuses/StreakRecord.java | 2 +- .../mineplex/core}/bonuses/VoteHandler.java | 2 +- .../bonuses/animations/AnimationCarl.java | 3 +- .../bonuses/commands/AnimationCommand.java | 4 +- .../core}/bonuses/commands/GuiCommand.java | 7 ++- .../core}/bonuses/commands/TicketCommand.java | 4 +- .../core}/bonuses/event/CarlSpinnerEvent.java | 2 +- .../mineplex/core}/bonuses/gui/BonusGui.java | 15 +++---- .../mineplex/core}/bonuses/gui/SpinGui.java | 10 ++--- .../bonuses/gui/buttons/CarlSpinButton.java | 6 +-- .../bonuses/gui/buttons/DailyBonusButton.java | 10 ++--- .../core}/bonuses/gui/buttons/PollButton.java | 6 +-- .../bonuses/gui/buttons/RankBonusButton.java | 6 +-- .../bonuses/gui/buttons/RewardButton.java | 3 +- .../core}/bonuses/gui/buttons/VoteButton.java | 18 +++----- .../src/mineplex/core}/poll/DisplayType.java | 2 +- .../mineplex/core}/poll/PlayerPollData.java | 2 +- .../src/mineplex/core}/poll/Poll.java | 4 +- .../src/mineplex/core}/poll/PollManager.java | 6 +-- .../mineplex/core}/poll/PollRepository.java | 2 +- .../src/mineplex/core}/poll/PollStats.java | 2 +- .../core}/poll/command/PollCommand.java | 10 ++--- .../Mineplex.Hub/src/mineplex/hub/Hub.java | 3 +- .../src/mineplex/hub/HubManager.java | 6 +-- 28 files changed, 82 insertions(+), 104 deletions(-) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/BonusAmount.java (98%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/BonusClientData.java (98%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/BonusManager.java (94%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/BonusRepository.java (99%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/StreakRecord.java (90%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/VoteHandler.java (95%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/animations/AnimationCarl.java (96%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/commands/AnimationCommand.java (87%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/commands/GuiCommand.java (71%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/commands/TicketCommand.java (94%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/event/CarlSpinnerEvent.java (95%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/BonusGui.java (71%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/SpinGui.java (94%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/buttons/CarlSpinButton.java (93%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/buttons/DailyBonusButton.java (96%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/buttons/PollButton.java (97%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/buttons/RankBonusButton.java (97%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/buttons/RewardButton.java (90%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/bonuses/gui/buttons/VoteButton.java (89%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/poll/DisplayType.java (91%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/poll/PlayerPollData.java (97%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/poll/Poll.java (95%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/poll/PollManager.java (97%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/poll/PollRepository.java (99%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/poll/PollStats.java (97%) rename Plugins/{Mineplex.Hub/src/mineplex/hub => Mineplex.Core/src/mineplex/core}/poll/command/PollCommand.java (96%) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java similarity index 98% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java index 17b12a1c7..76e746f43 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusAmount.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses; +package mineplex.core.bonuses; import java.util.List; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusClientData.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusClientData.java similarity index 98% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusClientData.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusClientData.java index d145a7e35..08cccac7f 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusClientData.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusClientData.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses; +package mineplex.core.bonuses; import java.sql.Date; import java.sql.Timestamp; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java similarity index 94% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index c997deaf8..268664bdf 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -1,10 +1,9 @@ -package mineplex.hub.bonuses; +package mineplex.core.bonuses; import java.sql.Date; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Calendar; -import java.util.Iterator; import java.util.TimeZone; import mineplex.core.MiniClientPlugin; @@ -28,21 +27,21 @@ import mineplex.core.hologram.HologramManager; import mineplex.core.npc.Npc; import mineplex.core.npc.NpcManager; import mineplex.core.reward.RewardManager; +import mineplex.core.stats.StatsManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.core.votifier.VotifierCommand; import mineplex.database.Tables; -import mineplex.hub.bonuses.animations.AnimationCarl; -import mineplex.hub.bonuses.commands.AnimationCommand; -import mineplex.hub.bonuses.commands.GuiCommand; -import mineplex.hub.bonuses.commands.TicketCommand; -import mineplex.hub.bonuses.event.CarlSpinnerEvent; -import mineplex.hub.bonuses.gui.BonusGui; +import mineplex.core.bonuses.animations.AnimationCarl; +import mineplex.core.bonuses.commands.AnimationCommand; +import mineplex.core.bonuses.commands.GuiCommand; +import mineplex.core.bonuses.commands.TicketCommand; +import mineplex.core.bonuses.event.CarlSpinnerEvent; +import mineplex.core.bonuses.gui.BonusGui; import mineplex.database.tables.records.BonusRecord; -import mineplex.hub.bonuses.gui.SpinGui; -import mineplex.hub.poll.PollManager; +import mineplex.core.bonuses.gui.SpinGui; +import mineplex.core.poll.PollManager; import mineplex.serverdata.commands.ServerCommandManager; -import org.jooq.DSLContext; import org.jooq.SQLDialect; import org.jooq.impl.DSL; @@ -50,12 +49,9 @@ import org.bukkit.Bukkit; import org.bukkit.Sound; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.plugin.java.JavaPlugin; @@ -114,6 +110,7 @@ public class BonusManager extends MiniClientPlugin implements I private NpcManager _npcManager; private HologramManager _hologramManager; private RewardManager _rewardManager; + private StatsManager _statsManager; public boolean _enabled; private Npc _carlNpc; private AnimationCarl _animation; @@ -122,7 +119,7 @@ public class BonusManager extends MiniClientPlugin implements I private StreakRecord _dailyStreak; private StreakRecord _voteStreak; - public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, RewardManager rewardManager) + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, RewardManager rewardManager, StatsManager statsManager) { super("Bonus", plugin); _repository = new BonusRepository(plugin, this, donationManager); @@ -132,6 +129,7 @@ public class BonusManager extends MiniClientPlugin implements I _hologramManager = hologramManager; _rewardManager = rewardManager; _pollManager = pollManager; + _statsManager = statsManager; // Hope to god this works! _canVote = true; @@ -648,11 +646,11 @@ public class BonusManager extends MiniClientPlugin implements I { if (data) { - UtilPlayer.message(player, F.main("Bonus", "Rewarded " + F.elem(gems + " Gems"))); + UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(gems + " Gems"))); } else { - UtilPlayer.message(player, F.main("Bonus", "Failed to process Gems")); + UtilPlayer.message(player, F.main("Carl", "Failed to process Gems")); } } }, "BonusManager", player.getName(), player.getUniqueId(), gems, true); @@ -667,11 +665,11 @@ public class BonusManager extends MiniClientPlugin implements I { if (data) { - UtilPlayer.message(player, F.main("Bonus", "Rewarded " + F.elem(gold + " Gold"))); + UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(gold + " Gold"))); } else { - UtilPlayer.message(player, F.main("Bonus", "Failed to process Gold")); + UtilPlayer.message(player, F.main("Carl", "Failed to process Gold")); } } }, "BonusManager", player.getName(), coreClient.getAccountId(), gold, true); @@ -686,11 +684,11 @@ public class BonusManager extends MiniClientPlugin implements I { if (data) { - UtilPlayer.message(player, F.main("Bonus", "Rewarded " + F.elem(coins + " Coins"))); + UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(coins + " Coins"))); } else { - UtilPlayer.message(player, F.main("Bonus", "Failed to process Coins")); + UtilPlayer.message(player, F.main("Carl", "Failed to process Coins")); } } }, "BonusManager", player.getName(), coreClient.getAccountId(), coins, true); @@ -714,7 +712,7 @@ public class BonusManager extends MiniClientPlugin implements I public void run() { bonusClient.setTickets(newTickets); - UtilPlayer.message(player, F.main("Bonus", "Rewarded " + F.elem(tickets + " Carl Spin Ticket"))); + UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(tickets + " Carl Spin Ticket"))); } }); } @@ -729,7 +727,8 @@ public class BonusManager extends MiniClientPlugin implements I if (experience > 0) { - // TODO + _statsManager.incrementStat(player, "Global.ExpEarned", experience); + UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(experience + " Experience"))); } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java similarity index 99% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java index 2f53ae3ac..ea14f4141 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses; +package mineplex.core.bonuses; import java.sql.CallableStatement; import java.sql.Connection; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/StreakRecord.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/StreakRecord.java similarity index 90% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/StreakRecord.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/StreakRecord.java index 901ef4ad6..7757a2c8c 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/StreakRecord.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/StreakRecord.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses; +package mineplex.core.bonuses; public class StreakRecord { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/VoteHandler.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/VoteHandler.java similarity index 95% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/VoteHandler.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/VoteHandler.java index 73e11305b..4dec15845 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/VoteHandler.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/VoteHandler.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses; +package mineplex.core.bonuses; import org.bukkit.entity.Player; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java similarity index 96% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/animations/AnimationCarl.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index 02783c89a..89ec4d85d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -1,7 +1,6 @@ -package mineplex.hub.bonuses.animations; +package mineplex.core.bonuses.animations; import mineplex.core.common.util.UtilAction; -import mineplex.core.common.util.UtilMath; import mineplex.core.reward.Reward; import mineplex.core.reward.RewardData; import mineplex.core.treasure.animation.Animation; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/AnimationCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java similarity index 87% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/AnimationCommand.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java index 28e2f493a..0494fc2f0 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/AnimationCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java @@ -1,10 +1,10 @@ -package mineplex.hub.bonuses.commands; +package mineplex.core.bonuses.commands; import org.bukkit.entity.Player; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; -import mineplex.hub.bonuses.BonusManager; +import mineplex.core.bonuses.BonusManager; public class AnimationCommand extends CommandBase{ diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java similarity index 71% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java index 655a94199..c3ef35edd 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/GuiCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java @@ -1,12 +1,11 @@ -package mineplex.hub.bonuses.commands; +package mineplex.core.bonuses.commands; import org.bukkit.entity.Player; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; -import mineplex.core.reward.RewardManager; -import mineplex.hub.bonuses.BonusManager; -import mineplex.hub.bonuses.gui.BonusGui; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.bonuses.gui.BonusGui; public class GuiCommand extends CommandBase{ diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/TicketCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java similarity index 94% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/TicketCommand.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java index 14afed1e8..20aa7ad66 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/commands/TicketCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java @@ -1,10 +1,10 @@ -package mineplex.hub.bonuses.commands; +package mineplex.core.bonuses.commands; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; -import mineplex.hub.bonuses.BonusManager; +import mineplex.core.bonuses.BonusManager; import org.bukkit.entity.Player; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/event/CarlSpinnerEvent.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/event/CarlSpinnerEvent.java similarity index 95% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/event/CarlSpinnerEvent.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/event/CarlSpinnerEvent.java index fed71229b..a07e1770e 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/event/CarlSpinnerEvent.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/event/CarlSpinnerEvent.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses.event; +package mineplex.core.bonuses.event; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java similarity index 71% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java index ea7978621..48b2e0a6e 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java @@ -1,17 +1,16 @@ -package mineplex.hub.bonuses.gui; +package mineplex.core.bonuses.gui; import mineplex.core.gui.SimpleGui; import mineplex.core.reward.RewardManager; -import mineplex.hub.bonuses.BonusManager; -import mineplex.hub.bonuses.gui.buttons.CarlSpinButton; -import mineplex.hub.bonuses.gui.buttons.DailyBonusButton; -import mineplex.hub.bonuses.gui.buttons.PollButton; -import mineplex.hub.bonuses.gui.buttons.RankBonusButton; -import mineplex.hub.bonuses.gui.buttons.VoteButton; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.bonuses.gui.buttons.CarlSpinButton; +import mineplex.core.bonuses.gui.buttons.DailyBonusButton; +import mineplex.core.bonuses.gui.buttons.PollButton; +import mineplex.core.bonuses.gui.buttons.RankBonusButton; +import mineplex.core.bonuses.gui.buttons.VoteButton; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; -import org.omg.CORBA._PolicyStub; public class BonusGui extends SimpleGui { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java similarity index 94% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 9e9bbefa9..80268a046 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses.gui; +package mineplex.core.bonuses.gui; import java.util.ArrayList; @@ -14,14 +14,10 @@ import mineplex.core.reward.RewardManager; import mineplex.core.reward.RewardRarity; import mineplex.core.reward.RewardType; import mineplex.core.shop.item.ShopItem; -import mineplex.core.treasure.animation.LootLegendaryAnimation; -import mineplex.core.treasure.animation.LootMythicalAnimation; -import mineplex.core.treasure.animation.LootRareAnimation; -import mineplex.core.treasure.animation.LootUncommonAnimation; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.hub.bonuses.BonusManager; -import mineplex.hub.bonuses.gui.buttons.RewardButton; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.bonuses.gui.buttons.RewardButton; import org.bukkit.Bukkit; import org.bukkit.ChatColor; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/CarlSpinButton.java similarity index 93% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/CarlSpinButton.java index 4c295f5dd..006135c5d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/CarlSpinButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/CarlSpinButton.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses.gui.buttons; +package mineplex.core.bonuses.gui.buttons; import java.util.ArrayList; @@ -13,8 +13,8 @@ import mineplex.core.common.util.C; import mineplex.core.gui.GuiItem; import mineplex.core.reward.RewardManager; import mineplex.core.shop.item.ShopItem; -import mineplex.hub.bonuses.BonusClientData; -import mineplex.hub.bonuses.BonusManager; +import mineplex.core.bonuses.BonusClientData; +import mineplex.core.bonuses.BonusManager; public class CarlSpinButton implements GuiItem { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java similarity index 96% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java index 8ee34647f..897852d8d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses.gui.buttons; +package mineplex.core.bonuses.gui.buttons; import java.util.ArrayList; @@ -16,10 +16,10 @@ import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.shop.item.ShopItem; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.hub.bonuses.BonusAmount; -import mineplex.hub.bonuses.BonusClientData; -import mineplex.hub.bonuses.BonusManager; -import mineplex.hub.bonuses.StreakRecord; +import mineplex.core.bonuses.BonusAmount; +import mineplex.core.bonuses.BonusClientData; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.bonuses.StreakRecord; import org.bukkit.Bukkit; import org.bukkit.ChatColor; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java similarity index 97% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java index 008a024ce..e669f2ad3 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses.gui.buttons; +package mineplex.core.bonuses.gui.buttons; import java.util.ArrayList; import java.util.HashMap; @@ -13,8 +13,8 @@ import mineplex.core.gui.SimpleGuiItem; import mineplex.core.gui.botton.BackBotton; import mineplex.core.gui.pages.TimedMessageWindow; import mineplex.core.itemstack.ItemStackFactory; -import mineplex.hub.poll.Poll; -import mineplex.hub.poll.PollManager; +import mineplex.core.poll.Poll; +import mineplex.core.poll.PollManager; import org.bukkit.ChatColor; import org.bukkit.Material; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java similarity index 97% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java index b394a398e..21e6fd318 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses.gui.buttons; +package mineplex.core.bonuses.gui.buttons; import java.util.ArrayList; @@ -16,8 +16,8 @@ import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.shop.item.ShopItem; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.hub.bonuses.BonusAmount; -import mineplex.hub.bonuses.BonusManager; +import mineplex.core.bonuses.BonusAmount; +import mineplex.core.bonuses.BonusManager; import org.bukkit.Bukkit; import org.bukkit.ChatColor; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RewardButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RewardButton.java similarity index 90% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RewardButton.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RewardButton.java index 5f7b0050b..73ff6c9cc 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/RewardButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RewardButton.java @@ -1,11 +1,10 @@ -package mineplex.hub.bonuses.gui.buttons; +package mineplex.core.bonuses.gui.buttons; import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import mineplex.core.gui.GuiItem; -import mineplex.core.reward.Reward; import mineplex.core.reward.RewardData; public class RewardButton implements GuiItem diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java similarity index 89% rename from Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java index 969fc2f9d..da9360afc 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java @@ -1,4 +1,4 @@ -package mineplex.hub.bonuses.gui.buttons; +package mineplex.core.bonuses.gui.buttons; import java.util.ArrayList; @@ -10,25 +10,17 @@ import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime.TimeUnit; import mineplex.core.gui.GuiItem; import mineplex.core.gui.ItemRefresher; -import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.shop.item.ShopItem; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.hub.bonuses.BonusAmount; -import mineplex.hub.bonuses.BonusClientData; -import mineplex.hub.bonuses.BonusManager; -import mineplex.hub.bonuses.StreakRecord; - -import net.minecraft.server.v1_7_R4.ChatSerializer; -import net.minecraft.server.v1_7_R4.IChatBaseComponent; -import net.minecraft.server.v1_7_R4.PacketPlayOutChat; +import mineplex.core.bonuses.BonusAmount; +import mineplex.core.bonuses.BonusClientData; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.bonuses.StreakRecord; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.inventory.ClickType; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/DisplayType.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/DisplayType.java similarity index 91% rename from Plugins/Mineplex.Hub/src/mineplex/hub/poll/DisplayType.java rename to Plugins/Mineplex.Core/src/mineplex/core/poll/DisplayType.java index 3045f5277..c593307e9 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/DisplayType.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/DisplayType.java @@ -1,4 +1,4 @@ -package mineplex.hub.poll; +package mineplex.core.poll; import mineplex.core.common.Rank; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PlayerPollData.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/PlayerPollData.java similarity index 97% rename from Plugins/Mineplex.Hub/src/mineplex/hub/poll/PlayerPollData.java rename to Plugins/Mineplex.Core/src/mineplex/core/poll/PlayerPollData.java index e0de0ec32..3465fae3b 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PlayerPollData.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/PlayerPollData.java @@ -1,4 +1,4 @@ -package mineplex.hub.poll; +package mineplex.core.poll; import mineplex.core.common.util.NautHashMap; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/Poll.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/Poll.java similarity index 95% rename from Plugins/Mineplex.Hub/src/mineplex/hub/poll/Poll.java rename to Plugins/Mineplex.Core/src/mineplex/core/poll/Poll.java index 1998173ff..715b1f275 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/Poll.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/Poll.java @@ -1,6 +1,4 @@ -package mineplex.hub.poll; - -import mineplex.core.common.Rank; +package mineplex.core.poll; /** * Created by Shaun on 8/16/2014. diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollManager.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java similarity index 97% rename from Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollManager.java rename to Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java index 7fb0e00fd..5fa00cf3d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java @@ -1,4 +1,4 @@ -package mineplex.hub.poll; +package mineplex.core.poll; import java.sql.ResultSet; import java.sql.SQLException; @@ -23,9 +23,7 @@ import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; import mineplex.core.donation.DonationManager; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.hub.poll.command.PollCommand; +import mineplex.core.poll.command.PollCommand; public class PollManager extends MiniDbClientPlugin { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollRepository.java similarity index 99% rename from Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollRepository.java rename to Plugins/Mineplex.Core/src/mineplex/core/poll/PollRepository.java index e38e980ec..53884c66f 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollRepository.java @@ -1,4 +1,4 @@ -package mineplex.hub.poll; +package mineplex.core.poll; import java.sql.ResultSet; import java.sql.SQLException; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollStats.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollStats.java similarity index 97% rename from Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollStats.java rename to Plugins/Mineplex.Core/src/mineplex/core/poll/PollStats.java index 591302c01..5f3ecdb2a 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/PollStats.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollStats.java @@ -1,4 +1,4 @@ -package mineplex.hub.poll; +package mineplex.core.poll; /** * Created by Shaun on 8/26/2014. diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/command/PollCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/command/PollCommand.java similarity index 96% rename from Plugins/Mineplex.Hub/src/mineplex/hub/poll/command/PollCommand.java rename to Plugins/Mineplex.Core/src/mineplex/core/poll/command/PollCommand.java index fe5997c79..bafdb1dbe 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/poll/command/PollCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/command/PollCommand.java @@ -1,4 +1,4 @@ -package mineplex.hub.poll.command; +package mineplex.core.poll.command; import java.text.DecimalFormat; import java.util.List; @@ -13,10 +13,10 @@ import mineplex.core.common.jsonchat.JsonMessage; import mineplex.core.common.util.C; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; -import mineplex.hub.poll.PlayerPollData; -import mineplex.hub.poll.Poll; -import mineplex.hub.poll.PollManager; -import mineplex.hub.poll.PollStats; +import mineplex.core.poll.PlayerPollData; +import mineplex.core.poll.Poll; +import mineplex.core.poll.PollManager; +import mineplex.core.poll.PollStats; /** * Created by Shaun on 8/17/2014. diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java index c99d09044..f5a62d294 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java @@ -39,7 +39,6 @@ import mineplex.core.recharge.Recharge; import mineplex.core.resourcepack.ResUnloadCheck; import mineplex.core.resourcepack.ResPackManager; import mineplex.core.serverConfig.ServerConfiguration; -import mineplex.core.spawn.Spawn; import mineplex.core.stats.StatsManager; import mineplex.core.status.ServerStatusManager; import mineplex.core.task.TaskManager; @@ -49,7 +48,7 @@ import mineplex.core.updater.Updater; import mineplex.core.velocity.VelocityFix; import mineplex.core.visibility.VisibilityManager; import mineplex.hub.modules.StackerManager; -import mineplex.hub.poll.PollManager; +import mineplex.core.poll.PollManager; import mineplex.hub.queue.QueueManager; import mineplex.hub.server.ServerManager; import mineplex.minecraft.game.classcombat.Class.ClassManager; diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index 03ffee480..bfb01019f 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -86,7 +86,7 @@ import mineplex.core.task.TaskManager; import mineplex.core.treasure.TreasureManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.hub.bonuses.BonusManager; +import mineplex.core.bonuses.BonusManager; import mineplex.hub.commands.ForcefieldRadius; import mineplex.hub.commands.GadgetToggle; import mineplex.hub.commands.GameModeCommand; @@ -98,7 +98,7 @@ import mineplex.hub.modules.NewsManager; import mineplex.hub.modules.ParkourManager; import mineplex.hub.modules.TextManager; import mineplex.hub.modules.WorldManager; -import mineplex.hub.poll.PollManager; +import mineplex.core.poll.PollManager; import mineplex.hub.profile.gui.GUIProfile; import mineplex.hub.tutorial.TutorialManager; import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; @@ -214,7 +214,7 @@ public class HubManager extends MiniClientPlugin ((CraftWorld)Bukkit.getWorlds().get(0)).getHandle().pvpMode = true; - new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, rewardManager); + new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, rewardManager, statsManager); // NotificationManager notificationManager = new NotificationManager(plugin, clientManager, donationManager); From 87458841531babfba76a50505244d5697f53c6ef Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Mon, 10 Aug 2015 04:51:11 -0500 Subject: [PATCH 293/377] Various fixes --- .../src/mineplex/core/bonuses/BonusManager.java | 15 ++++++++++++++- .../Mineplex.Hub/src/mineplex/hub/HubManager.java | 14 ++++++++++---- .../src/mineplex/votifier/VotifierManager.java | 2 +- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 268664bdf..51af791c8 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -223,6 +223,7 @@ public class BonusManager extends MiniClientPlugin implements I { if (data) { + incrementVoteStreak(player); addPendingExplosion(player, player.getName()); awardBonus(player, getVoteBonusAmount(player)); UtilPlayer.message(player, F.main("Vote", "Thanks for your vote!")); @@ -493,6 +494,16 @@ public class BonusManager extends MiniClientPlugin implements I data.setMaxDailyStreak(data.getDailyStreak()); } + public void incrementVoteStreak(Player player) + { + BonusClientData data = Get(player); + + data.setVoteStreak(data.getVoteStreak() + 1); + + if (data.getVoteStreak() > data.getMaxVoteStreak()) + data.setMaxVoteStreak(data.getVoteStreak()); + } + public boolean continueStreak(long localLastBonus, long extendTime) { long maxTime = localLastBonus + TIME_BETWEEN_BONUSES + extendTime; @@ -884,7 +895,9 @@ public class BonusManager extends MiniClientPlugin implements I public void UnloadPlayer(final ClientUnloadEvent event) { final BonusClientData clientData = Get(event.GetName()); - clientData.getHologram().stop(); + + if (clientData.getHologram() != null) + clientData.getHologram().stop(); runAsync(new Runnable() { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index 0ab6560d3..f09e21e1f 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -25,6 +25,7 @@ import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerQuitEvent; @@ -66,12 +67,12 @@ import mineplex.core.gadget.event.GadgetActivateEvent; import mineplex.core.gadget.event.GadgetCollideEntityEvent; import mineplex.core.hologram.HologramManager; import mineplex.core.inventory.InventoryManager; -import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.message.PrivateMessageEvent; import mineplex.core.mount.MountManager; import mineplex.core.mount.event.MountActivateEvent; import mineplex.core.notifier.NotificationManager; import mineplex.core.npc.NpcManager; +import mineplex.core.packethandler.PacketHandler; import mineplex.core.party.Party; import mineplex.core.party.PartyManager; import mineplex.core.personalServer.PersonalServerManager; @@ -86,6 +87,7 @@ import mineplex.core.treasure.TreasureManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.core.bonuses.BonusManager; +import mineplex.hub.commands.DisguiseCommand; import mineplex.hub.commands.ForcefieldRadius; import mineplex.hub.commands.GadgetToggle; import mineplex.hub.commands.GameModeCommand; @@ -93,8 +95,10 @@ import mineplex.hub.commands.NewsCommand; import mineplex.hub.modules.ForcefieldManager; import mineplex.hub.modules.HubVisibilityManager; import mineplex.hub.modules.JumpManager; +import mineplex.hub.modules.KothManager; import mineplex.hub.modules.NewsManager; import mineplex.hub.modules.ParkourManager; +import mineplex.hub.modules.SoccerManager; import mineplex.hub.modules.TextManager; import mineplex.hub.modules.WorldManager; import mineplex.core.poll.PollManager; @@ -102,6 +106,8 @@ import mineplex.hub.profile.gui.GUIProfile; import mineplex.hub.tutorial.TutorialManager; import mineplex.minecraft.game.classcombat.Skill.event.SkillTriggerEvent; import mineplex.minecraft.game.classcombat.item.event.ItemTriggerEvent; +import mineplex.minecraft.game.core.combat.DeathMessageType; +import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; import mineplex.minecraft.game.core.condition.ConditionManager; import mineplex.minecraft.game.core.damage.CustomDamageEvent; @@ -151,7 +157,7 @@ public class HubManager extends MiniClientPlugin //Admin private boolean _gadgetsEnabled = true; - public HubManager(JavaPlugin plugin, BlockRestore blockRestore, CoreClientManager clientManager, DonationManager donationManager, ConditionManager conditionManager, DisguiseManager disguiseManager, TaskManager taskManager, Portal portal, PartyManager partyManager, PreferencesManager preferences, PetManager petManager, PollManager pollManager, StatsManager statsManager, AchievementManager achievementManager, HologramManager hologramManager, NpcManager npcManager, PersonalServerManager personalServerManager) + public HubManager(JavaPlugin plugin, BlockRestore blockRestore, CoreClientManager clientManager, DonationManager donationManager, ConditionManager conditionManager, DisguiseManager disguiseManager, TaskManager taskManager, Portal portal, PartyManager partyManager, PreferencesManager preferences, PetManager petManager, PollManager pollManager, StatsManager statsManager, AchievementManager achievementManager, HologramManager hologramManager, NpcManager npcManager, PersonalServerManager personalServerManager, PacketHandler packetHandler) { super("Hub Manager", plugin); @@ -182,7 +188,7 @@ public class HubManager extends MiniClientPlugin _mountManager = new MountManager(_plugin, clientManager, donationManager, blockRestore, _disguiseManager); _inventoryManager = new InventoryManager(plugin, clientManager); new BenefitManager(plugin, clientManager, _inventoryManager); - _gadgetManager = new GadgetManager(_plugin, clientManager, donationManager, _inventoryManager, _mountManager, petManager, preferences, disguiseManager, blockRestore, new ProjectileManager(plugin)); + _gadgetManager = new GadgetManager(_plugin, clientManager, donationManager, _inventoryManager, _mountManager, petManager, preferences, disguiseManager, blockRestore, new ProjectileManager(plugin), achievementManager); RewardManager rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, statsManager, 100, 250, @@ -984,7 +990,7 @@ public class HubManager extends MiniClientPlugin @EventHandler public void openProfile(PlayerInteractEvent event) { - if(event.getItem().getType() != Material.SKULL_ITEM) + if(event.getItem() == null || event.getItem().getType() != Material.SKULL_ITEM) return; new GUIProfile(getPlugin(), event.getPlayer(), _preferences, _achievementManager, _personalServerManager).openInventory();; diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index 420fb5adf..98f685a68 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -105,7 +105,7 @@ public class VotifierManager extends MiniPlugin // Currently we just notify all servers, and the server with the player on it can deal with it notifyServer(playerName, false); - notifyServer(playerName, true); +// notifyServer(playerName, true); } private void notifyServer(String playerName, boolean eu) From adb76b0681e07e1d742ab322ab8cdd9c4b42c362 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Mon, 10 Aug 2015 04:51:46 -0500 Subject: [PATCH 294/377] Fix giving out gold --- .../Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java index 76e746f43..d2cfef1f8 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java @@ -93,7 +93,7 @@ public class BonusAmount public int getTotalGold() { - return getGems() + getBonusGems(); + return getGold() + getBonusGold(); } public int getExperience() From aa13bcf5c6668e76976f5e12547a619358763126 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Mon, 10 Aug 2015 04:54:01 -0500 Subject: [PATCH 295/377] Bug fix! --- .../src/mineplex/core/bonuses/BonusManager.java | 7 ------- .../src/mineplex/core/bonuses/BonusRepository.java | 8 +------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 51af791c8..d309308bd 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -613,13 +613,6 @@ public class BonusManager extends MiniClientPlugin implements I //VOTE - public void attemptVoteBonus(final Player player, final Callback result) - { - if (timeTillRankBonus(player) > 0) - result.run(false); - getRepository().attemptRankBonus(player, result); - } - public long timeTillVoteBonus(Player player) { return nextVoteTime(player) - getLocalTime(); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java index ea14f4141..d97a76cc5 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java @@ -250,15 +250,9 @@ public class BonusRepository extends RepositoryBase public void attemptVoteBonus(final Player player, final Callback result) { final int accountId = _manager.getClientManager().Get(player).getAccountId(); - final int coins = _manager.getRankBonusAmount(player).getCoins(); - + final int coins = 0; final int gems = 0; - if (coins == 0/* && gems == 0 */) { - result.run(false); - return; - } - final JavaPlugin plug = _manager.getPlugin(); Bukkit.getScheduler().runTaskAsynchronously(plug, new Runnable() { From bd2c9aa5e6d133e569524b6ac6b19dbf7017f496 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Mon, 10 Aug 2015 14:00:02 +0200 Subject: [PATCH 296/377] hub stuff --- .../mineplex/hub/modules/SoccerManager.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java index bafd2df86..0eacb7d77 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -3,16 +3,20 @@ package mineplex.hub.modules; import java.util.ArrayList; import java.util.HashSet; +import org.bukkit.EntityEffect; import org.bukkit.FireworkEffect.Type; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.Sound; +import org.bukkit.entity.Bat; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Slime; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerVelocityEvent; @@ -349,6 +353,12 @@ public class SoccerManager extends MiniPlugin if (_ball != null && _ball.equals(ent)) continue; + + if (ent instanceof Bat) + { + ent.remove(); + continue; + } if (inPlayerArena(ent)) { @@ -491,4 +501,30 @@ public class SoccerManager extends MiniPlugin { _active.remove(event.getPlayer()); } + + @EventHandler(priority = EventPriority.HIGHEST) + public void allowDamage(EntityDamageByEntityEvent event) + { + if (!(event.getEntity() instanceof Player) || !(event.getDamager() instanceof Player)) + return; + + Player damager = (Player)event.getDamager(); + Player damagee = (Player)event.getEntity(); + + if (!_active.contains(damager) || !_active.contains(damagee)) + return; + + if (getTeamColor(damager) == null || getTeamColor(damagee) == null) + return; + + if (getTeamColor(damager) == getTeamColor(damagee)) + return; + + if (Recharge.Instance.use(damagee, "Football Damage", 800, false, false)) + { + UtilAction.velocity(damagee, UtilAlg.getTrajectory2d(damager, damagee), 0.6, false, 0, 0.3, 1, true); + + damagee.playEffect(EntityEffect.HURT); + } + } } From 5781009f4e3f405bd84756834aeed959d5cf939e Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 10 Aug 2015 14:00:40 +0200 Subject: [PATCH 297/377] Improving animations and some text. --- .../mineplex/core/bonuses/BonusManager.java | 5 +- .../bonuses/animations/AnimationCarl.java | 50 +++++++++++++------ .../bonuses/commands/AnimationCommand.java | 3 ++ .../mineplex/core/bonuses/gui/BonusGui.java | 2 +- .../bonuses/gui/buttons/DailyBonusButton.java | 5 +- .../core/bonuses/gui/buttons/PollButton.java | 9 +++- .../bonuses/gui/buttons/RankBonusButton.java | 3 +- .../core/bonuses/gui/buttons/VoteButton.java | 4 +- 8 files changed, 58 insertions(+), 23 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index d309308bd..2ad67f4b9 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -251,7 +251,10 @@ public class BonusManager extends MiniClientPlugin implements I if (!_enabled) return; - if(_pendingExplosions.get(0) instanceof String) + if(_pendingExplosions.get(0) instanceof String + && !((String)_pendingExplosions.get(0)).contentEquals("RANK") + && !((String)_pendingExplosions.get(0)).contentEquals("DAILY") + && !((String)_pendingExplosions.get(0)).contentEquals("VOTE")) { String name = (String)_pendingExplosions.get(0); Bukkit.broadcastMessage("Recieved Vote: " + name); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index 89ec4d85d..3f1d4a43c 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -1,6 +1,7 @@ package mineplex.core.bonuses.animations; import mineplex.core.common.util.UtilAction; +import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.reward.Reward; import mineplex.core.reward.RewardData; import mineplex.core.treasure.animation.Animation; @@ -32,22 +33,43 @@ public class AnimationCarl extends Animation { if(_type instanceof String) { - if (getTicks() < 40) - { - Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), new ItemStack(Material.EMERALD)); - - //Velocity - long passed = System.currentTimeMillis() - _startTime; - Vector vel = new Vector(Math.sin(passed/5d), 0, Math.cos(passed/5d)); - - UtilAction.velocity(gem, vel, Math.abs(Math.sin(passed/3000d)), false, 0, 0.2 + Math.abs(Math.cos(passed/3000d))*0.6, 1, false); - - gem.setTicksLived(1170); - } - else + if(((String) _type).contentEquals("DAILY")) { - finish(); + for (int i = 1; i < 60; i++) + { + Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, "" + i)); + Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, "" + i)); + Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); + UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 7/3000d))*0.6, 1, false); + UtilAction.velocity(coin, vel, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 8/3000d))*0.6, 1, false); + coin.setTicksLived(1160); + gem.setTicksLived(1160); + } } + if(((String) _type).contentEquals("RANK")) + { + for (int i = 1; i < 100; i++) + { + Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, "" + i)); + Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); + UtilAction.velocity(coin, vel, Math.abs(Math.sin(i * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 7/3000d))*0.6, 1, false); + coin.setTicksLived(1160); + } + } + if(!((String) _type).contentEquals("DAILY")&& !((String) _type).contentEquals("RANK")) + { + for (int i = 1; i < 60; i++) + { + Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, "" + i)); + Item paper = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, "" + i)); + Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); + UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 7/3000d))*0.6, 1, false); + UtilAction.velocity(paper, vel, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 8/3000d))*0.6, 1, false); + paper.setTicksLived(1160); + gem.setTicksLived(1160); + } + } + finish(); } if(_type instanceof Reward) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java index 0494fc2f0..262dbff1c 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java @@ -23,6 +23,9 @@ public class AnimationCommand extends CommandBase{ _plugin.addPendingExplosion(caller, "Chiss"); _plugin.addPendingExplosion(caller, "Phinary"); _plugin.addPendingExplosion(caller, "xXVevzZXx"); + + _plugin.addPendingExplosion(caller, "RANK"); + _plugin.addPendingExplosion(caller, "DAILY"); } } \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java index 48b2e0a6e..e54887dc8 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java @@ -29,7 +29,7 @@ public class BonusGui extends SimpleGui setItem(14, new DailyBonusButton(getPlugin(), player, this, manager)); - setItem(16, new PollButton(getPlugin(), player, manager.getPollManager(), manager.getClientManager(), this)); + setItem(16, new PollButton(getPlugin(), player, manager.getPollManager(), manager.getClientManager(), this, manager)); setItem(31, new CarlSpinButton(getPlugin(), player, manager, rewardManager)); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java index 897852d8d..8efb10fa5 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java @@ -86,6 +86,7 @@ public class DailyBonusButton implements GuiItem, Listener } else { UtilPlayer.message(getPlayer(), F.main("Bonus", "Bonus collected!")); } + _bonusManager.addPendingExplosion(getPlayer(), "DAILY"); getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); } else { if (getPlayer().getOpenInventory() != null) { @@ -120,7 +121,7 @@ public class DailyBonusButton implements GuiItem, Listener if (isAvailable()) { material = Material.CHEST; - itemName = C.cGreen + C.Bold + "Daily Bonus"; + itemName = C.cGreen + C.Bold + "Daily Reward"; lore.add(" "); lore.add(ChatColor.RESET + "Click to Claim!"); @@ -128,7 +129,7 @@ public class DailyBonusButton implements GuiItem, Listener else { material = Material.REDSTONE_BLOCK; - itemName = C.cRed + C.Bold + "Daily Bonus"; + itemName = C.cRed + C.Bold + "Daily Reward"; lore.add(" "); lore.add(ChatColor.RESET + "Next reward in " + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) + "!"); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java index e669f2ad3..417a6b556 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.HashMap; import mineplex.core.account.CoreClientManager; +import mineplex.core.bonuses.BonusManager; import mineplex.core.common.util.C; import mineplex.core.common.util.UtilText; import mineplex.core.gui.GuiInventory; @@ -29,6 +30,7 @@ public class PollButton extends SimpleGui implements GuiItem { protected boolean _create; private PollManager _pollManager; + private BonusManager _bonusManager; private CoreClientManager _clientManager; private GuiInventory _master; @@ -36,7 +38,7 @@ public class PollButton extends SimpleGui implements GuiItem { private Poll _poll; - public PollButton(Plugin plugin, Player player, PollManager pollManager, CoreClientManager clientManager, GuiInventory master) + public PollButton(Plugin plugin, Player player, PollManager pollManager, CoreClientManager clientManager, GuiInventory master, BonusManager bonusManager) { super(plugin, player, "Poll:", 6 * 9); this._create = true; @@ -44,6 +46,7 @@ public class PollButton extends SimpleGui implements GuiItem { this._clientManager = clientManager; this._pollManager = pollManager; hard.put(0, new BackBotton(master)); + _bonusManager = bonusManager; } @Override @@ -75,7 +78,8 @@ public class PollButton extends SimpleGui implements GuiItem { ArrayList lore = new ArrayList<>(); if (_poll == null) { - lore.add(C.cRed + "You've voted on all of the polls!"); + lore.add(""); + lore.add(C.cWhite + "You've voted on all of the polls!"); return ItemStackFactory.Instance.CreateStack(Material.REDSTONE_BLOCK, (byte) 0, 1, ChatColor.RED + C.Bold + "Vote on Poll", lore); } else @@ -190,6 +194,7 @@ public class PollButton extends SimpleGui implements GuiItem { getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.EMERALD_BLOCK, (byte) 0, 1, ChatColor.GREEN + "Your anwser:", wrap(getPoll().getAnswers()[num])), ChatColor.GREEN + "Moo", 6 * 9, 50, getMaster()).openInventory(); + _bonusManager.addPendingExplosion(getPlayer(), "VOTE"); getPlayer().closeInventory(); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java index 21e6fd318..501840411 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java @@ -99,6 +99,7 @@ public class RankBonusButton implements GuiItem, Listener { { UtilPlayer.message(getPlayer(), F.main("Bonus", "Bonus collected!")); } + _bonusManager.addPendingExplosion(getPlayer(), "RANK"); getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); } else @@ -144,7 +145,7 @@ public class RankBonusButton implements GuiItem, Listener { if (!hasRank) { - material = Material.COAL_BLOCK; + material = Material.REDSTONE_BLOCK; itemName = C.cRed + ChatColor.BOLD + "Rank Monthly Bonus"; lore.add(" "); lore.add(ChatColor.WHITE + "Players with a Rank get a Monthly Bonus!"); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java index da9360afc..b05c3dad0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java @@ -108,7 +108,7 @@ public class VoteButton implements GuiItem, Listener { if (isAvailable()) { material = Material.JUKEBOX; - itemName = C.cGreen + C.Bold + "Vote Bonus"; + itemName = C.cGreen + C.Bold + "Vote for Mineplex"; lore.add(" "); lore.add(ChatColor.RESET + "Click to Vote!"); @@ -116,7 +116,7 @@ public class VoteButton implements GuiItem, Listener { else { material = Material.REDSTONE_BLOCK; - itemName = C.cRed + C.Bold + "Vote Bonus"; + itemName = C.cRed + C.Bold + "Vote for Mineplex"; lore.add(" "); lore.add(ChatColor.RESET + "Next vote in " + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) + "!"); From 65b51a137c4211469322bb3ceb681c1cc4c8e049 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Mon, 10 Aug 2015 14:50:44 +0200 Subject: [PATCH 298/377] new party tute room --- .../hub/tutorial/types/PartyTutorial.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/PartyTutorial.java b/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/PartyTutorial.java index e8c7d1a8c..8b995220b 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/PartyTutorial.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/PartyTutorial.java @@ -17,8 +17,8 @@ public class PartyTutorial extends Tutorial double y = -manager.GetSpawn().getY(); _phases.add(new TutorialPhase( - manager.GetSpawn().add(84, y+69, 10), - manager.GetSpawn().add(81, y+68.5, 10), + manager.GetSpawn().add(0, 65 + y, 0), + manager.GetSpawn().add(4, 66.5 + y, 0), "Parties", new String[] { @@ -32,8 +32,8 @@ public class PartyTutorial extends Tutorial )); _phases.add(new TutorialPhase( - manager.GetSpawn().add(84, y+69, 9), - manager.GetSpawn().add(81, y+68.5, 9), + manager.GetSpawn().add(0, 65 + y, 0), + manager.GetSpawn().add(4, 66.5 + y, 0), "Creating a Party", new String[] { @@ -47,8 +47,8 @@ public class PartyTutorial extends Tutorial )); _phases.add(new TutorialPhase( - manager.GetSpawn().add(84, y+69, 9), - manager.GetSpawn().add(81, y+68.5, 9), + manager.GetSpawn().add(0, 65 + y, 0), + manager.GetSpawn().add(4, 66.5 + y, 0), "Inviting and Suggesting Players", new String[] { @@ -61,8 +61,8 @@ public class PartyTutorial extends Tutorial )); _phases.add(new TutorialPhase( - manager.GetSpawn().add(84, y+69, 9), - manager.GetSpawn().add(81, y+68.5, 9), + manager.GetSpawn().add(0, 65 + y, 0), + manager.GetSpawn().add(4, 66.5 + y, 0), "Leaving Parties", new String[] { @@ -73,8 +73,8 @@ public class PartyTutorial extends Tutorial )); _phases.add(new TutorialPhase( - manager.GetSpawn().add(84, y+69, 9), - manager.GetSpawn().add(81, y+68.5, 9), + manager.GetSpawn().add(0, 65 + y, 0), + manager.GetSpawn().add(4, 66.5 + y, 0), "Kicking Players from Party", new String[] { @@ -87,8 +87,8 @@ public class PartyTutorial extends Tutorial )); _phases.add(new TutorialPhase( - manager.GetSpawn().add(84, y+69, 9), - manager.GetSpawn().add(81, y+68.5, 9), + manager.GetSpawn().add(0, 65 + y, 0), + manager.GetSpawn().add(4, 66.5 + y, 0), "Joining Games Together", new String[] { @@ -103,8 +103,8 @@ public class PartyTutorial extends Tutorial )); _phases.add(new TutorialPhase( - manager.GetSpawn().add(84, y+69, 9), - manager.GetSpawn().add(81, y+68.5, 9), + manager.GetSpawn().add(0, 65 + y, 0), + manager.GetSpawn().add(4, 66.5 + y, 0), "Party Chat", new String[] { From 65fc81a2aaea6db76faa2c41c4f8b43318c03ccd Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 10 Aug 2015 15:33:00 +0200 Subject: [PATCH 299/377] improving animations again. --- .../mineplex/core/bonuses/BonusManager.java | 27 ++++++++++++- .../bonuses/animations/AnimationCarl.java | 38 +++++++++++-------- 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 2ad67f4b9..e1109137b 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -42,17 +42,20 @@ import mineplex.database.tables.records.BonusRecord; import mineplex.core.bonuses.gui.SpinGui; import mineplex.core.poll.PollManager; import mineplex.serverdata.commands.ServerCommandManager; + import org.jooq.SQLDialect; import org.jooq.impl.DSL; - import org.bukkit.Bukkit; import org.bukkit.Sound; +import org.bukkit.block.Dropper; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.java.JavaPlugin; import net.minecraft.server.v1_7_R4.DataWatcher; @@ -444,6 +447,7 @@ public class BonusManager extends MiniClientPlugin implements I } catch (Exception e) { + new SpinGui(getPlugin(), player, _rewardManager, manager).openInventory(); UtilPlayer.message(player, F.main("Carl", "There was an error processing your request")); } } @@ -925,4 +929,25 @@ public class BonusManager extends MiniClientPlugin implements I { return _pollManager; } + + @EventHandler + public void ItemDecay(UpdateEvent event) + { + if(event.getType() != UpdateType.TICK) + return; + + for(Entity entity : _carlNpc.getEntity().getNearbyEntities(3, -0.5, 3)) + { + if(!(entity instanceof Item)) + continue; + + if(!((Item) entity).getItemStack().hasItemMeta()) + continue; + + if(!((Item) entity).getItemStack().getItemMeta().getDisplayName().startsWith(" ")) + continue; + + entity.remove(); + } + } } \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index 3f1d4a43c..e994165c9 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -11,6 +11,7 @@ import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.Player; +import org.bukkit.event.Listener; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; @@ -35,22 +36,22 @@ public class AnimationCarl extends Animation { if(((String) _type).contentEquals("DAILY")) { - for (int i = 1; i < 60; i++) + for (int i = 1; i < 40; i++) { - Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, "" + i)); - Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, "" + i)); - Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); - UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 7/3000d))*0.6, 1, false); - UtilAction.velocity(coin, vel, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 8/3000d))*0.6, 1, false); + Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); + Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, " " + i)); + Vector vel = new Vector(Math.sin(i * 9/5d), 0, Math.cos(i * 9/5d)); + UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 9/3000d))*0.6, 1, false); + UtilAction.velocity(coin, vel, Math.abs(Math.sin(i * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 9/3000d))*0.6, 1, false); coin.setTicksLived(1160); gem.setTicksLived(1160); } } if(((String) _type).contentEquals("RANK")) { - for (int i = 1; i < 100; i++) + for (int i = 1; i < 50; i++) { - Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, "" + i)); + Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, " " + i)); Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); UtilAction.velocity(coin, vel, Math.abs(Math.sin(i * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 7/3000d))*0.6, 1, false); coin.setTicksLived(1160); @@ -58,13 +59,13 @@ public class AnimationCarl extends Animation } if(!((String) _type).contentEquals("DAILY")&& !((String) _type).contentEquals("RANK")) { - for (int i = 1; i < 60; i++) + for (int i = 1; i < 40; i++) { - Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, "" + i)); - Item paper = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, "" + i)); - Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); - UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 7/3000d))*0.6, 1, false); - UtilAction.velocity(paper, vel, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 8/3000d))*0.6, 1, false); + Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); + Item paper = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, " " + i)); + Vector vel = new Vector(Math.sin(i * 8/5d), 0, Math.cos(i * 8/5d)); + UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 8/3000d))*0.6, 1, false); + UtilAction.velocity(paper, vel, Math.abs(Math.sin(i * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 9/3000d))*0.6, 1, false); paper.setTicksLived(1160); gem.setTicksLived(1160); } @@ -79,13 +80,18 @@ public class AnimationCarl extends Animation { itemStack = new ItemStack(Material.NETHER_STAR); } - Item item = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 2, 0.5), itemStack); + Item item = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.7, 0.5), itemStack); Vector vel = new Vector(_player.getLocation().getX() - _creeper.getLocation().getX(), 0, _player.getLocation().getZ() - _creeper.getLocation().getZ()); UtilAction.velocity(item, vel, 0.1, false, 0, 0.2 + 1*0.4, 1, false); - item.setTicksLived(1170); + item.setTicksLived(1160); + + + + + finish(); } } From 18d11f7d68e23afa2fe2d0c35295d27382119a2d Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Mon, 10 Aug 2015 16:13:17 +0200 Subject: [PATCH 300/377] new enums --- .../src/mineplex/core/reward/RewardType.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java index b06cdcec6..90b201c08 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java @@ -3,11 +3,14 @@ package mineplex.core.reward; public enum RewardType { //% Chances Mythic Legend Rare Uncommon - GameLoot( 0.000001, 0.00001, 0.0001, 3, 10), - Spinner( 0.000001, 0.2, 0.8, 10, 10), + GameLoot( 0.000001, 0.00001, 0.0001, 3, 10), + OldChest( 0, 0.05, 0.4, 5, 0), AncientChest( 0, 1, 4, 25, 0), - MythicalChest( 0.4, 3, 12, 75, 0); + MythicalChest( 0.4, 3, 12, 75, 0), + + SpinnerFiller( 0.1, 1, 4, 20, 30), + SpinnerReal( 0.000001, 0.05, 0.4, 5, 10); private double _mythicalChance; private double _legendaryChance; From c6beb122e31c7119c86d111c0aab480a835551d8 Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 10 Aug 2015 16:42:43 +0200 Subject: [PATCH 301/377] Adding firework animations for spinner. --- .../bonuses/animations/AnimationCarl.java | 172 ++++++++++++++++-- .../bonuses/commands/AnimationCommand.java | 1 + 2 files changed, 157 insertions(+), 16 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index e994165c9..3090c9754 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -1,12 +1,23 @@ package mineplex.core.bonuses.animations; +import java.util.Random; + import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilParticle.ViewDist; import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.reward.Reward; import mineplex.core.reward.RewardData; +import mineplex.core.reward.RewardRarity; import mineplex.core.treasure.animation.Animation; +import org.bukkit.Color; +import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.FireworkEffect.Type; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.Item; @@ -23,6 +34,7 @@ public class AnimationCarl extends Animation private long _startTime; private Object _type; private Player _player; + private Random _random = new Random(); public AnimationCarl(Entity creeper) { @@ -74,25 +86,35 @@ public class AnimationCarl extends Animation } if(_type instanceof Reward) { - RewardData rewardData = ((Reward)_type).getFakeRewardData(null); - ItemStack itemStack = rewardData.getDisplayItem(); - if(itemStack.getType() == Material.PAPER) + if(getTicks() == 0) { - itemStack = new ItemStack(Material.NETHER_STAR); + RewardData rewardData = ((Reward)_type).getFakeRewardData(_player); + ItemStack itemStack = rewardData.getDisplayItem(); + Item item = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.7, 0.5), itemStack); + + Vector vel = new Vector(_player.getLocation().getX() - _creeper.getLocation().getX(), 0, _player.getLocation().getZ() - _creeper.getLocation().getZ()); + + UtilAction.velocity(item, vel, 0.1, false, 0, 0.2 + 1*0.4, 1, false); + + item.setTicksLived(1160); } - Item item = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.7, 0.5), itemStack); - Vector vel = new Vector(_player.getLocation().getX() - _creeper.getLocation().getX(), 0, _player.getLocation().getZ() - _creeper.getLocation().getZ()); - - UtilAction.velocity(item, vel, 0.1, false, 0, 0.2 + 1*0.4, 1, false); - - item.setTicksLived(1160); - - - - - - finish(); + if(((Reward)_type).getRarity() == RewardRarity.RARE) + { + RareAnimation(); + } + else if(((Reward)_type).getRarity() == RewardRarity.LEGENDARY) + { + LegendAnimation(); + } + else if(((Reward)_type).getRarity() == RewardRarity.MYTHICAL) + { + MythicalAnimation(); + } + else + { + finish(); + } } } @@ -126,4 +148,122 @@ public class AnimationCarl extends Animation { _player = player; } + + public void LegendAnimation() + { + if (getTicks() < 1) + { + UtilFirework.playFirework(_creeper.getLocation().add(0.5, 0.5, 0.5), Type.BALL_LARGE, Color.LIME, true, true); + } + + if (getTicks() == 1) + { + _creeper.getLocation().getWorld().playSound(_creeper.getLocation().add(0.5, 0.5, 0.5), Sound.ENDERDRAGON_DEATH, 10F, 2.0F); + } + else if (getTicks() < 35) + { + double radius = 2 - (getTicks() / 10D * 2); + int particleAmount = 20 - (getTicks() * 2); + Location _centerLocation = _creeper.getLocation().add(0.5, 0.1, 0.5); + for (int i = 0; i < particleAmount; i++) + { + double xDiff = Math.sin(i/(double)particleAmount * 2 * Math.PI) * radius; + double zDiff = Math.cos(i/(double)particleAmount * 2 * Math.PI) * radius; + for(double e = 0.1 ; e < 3 ; e += 0.6) + { + Location location = _centerLocation.clone().add(xDiff, e, zDiff); + UtilParticle.PlayParticle(UtilParticle.ParticleType.HAPPY_VILLAGER, location, 0, 0, 0, 0, 1, ViewDist.NORMAL, UtilServer.getPlayers()); + } + } + } + else + { + finish(); + } + } + + public void MythicalAnimation() + { + if (getTicks() < 30 && getTicks() % 3 == 0) + { + UtilFirework.playFirework(_creeper.getLocation().add(0.5, 0.5, 0.5), Type.BALL_LARGE, Color.RED, true, true); + } + + if (getTicks() == 1) + { + _creeper.getLocation().getWorld().playSound(_creeper.getLocation().add(0.5, 0.5, 0.5), Sound.PORTAL_TRAVEL, 10F, 2.0F); + _creeper.getLocation().getWorld().playSound(_creeper.getLocation().add(0.5, 0.5, 0.5), Sound.ZOMBIE_UNFECT, 10F, 0.1F); + } + else if (getTicks() < 60) + { + UtilFirework.launchFirework(_creeper.getLocation().add(0.5, 0.5, 0.5), Type.BALL_LARGE, Color.RED, true, true, + new Vector((Math.random()-0.5)*0.05, 0.1, (Math.random()-0.5)*0.05), 1); + + //Particle Spiral Up + double radius = getTicks() / 20D; + int particleAmount = getTicks() / 2; + for (int i = 0; i < particleAmount; i++) + { + double xDiff = Math.sin(i/(double)particleAmount * 2 * Math.PI) * radius; + double zDiff = Math.cos(i/(double)particleAmount * 2 * Math.PI) * radius; + + Location location = _creeper.getLocation().add(0.5, 0, 0.5).clone().add(xDiff, -1.3, zDiff); + UtilParticle.PlayParticle(UtilParticle.ParticleType.WITCH_MAGIC, location, 0, 0, 0, 0, 1, + ViewDist.NORMAL, UtilServer.getPlayers()); + } + } + else if (getTicks() < 60) + { + double radius = 2 - (getTicks() / 10D * 2); + int particleAmount = 20 - (getTicks() * 2); + Location _centerLocation = _creeper.getLocation().add(0.5, 0.1, 0.5); + for (int i = 0; i < particleAmount; i++) + { + double xDiff = Math.sin(i/(double)particleAmount * 2 * Math.PI) * radius; + double zDiff = Math.cos(i/(double)particleAmount * 2 * Math.PI) * radius; + for(double e = 0.1 ; e < 3 ; e += 0.5) + { + Location location = _centerLocation.clone().add(xDiff, e, zDiff); + UtilParticle.PlayParticle(UtilParticle.ParticleType.WITCH_MAGIC, location, 0, 0, 0, 0, 1, ViewDist.NORMAL, UtilServer.getPlayers()); + } + } + } + else + { + finish(); + } + } + + public void RareAnimation() + { + if (getTicks() == 1) + { + for(int i = 0; i < 3; i++) + { + UtilFirework.playFirework(_creeper.getLocation().add(0.5, i, 0.5), Type.BALL, Color.FUCHSIA, false, false); + } + _creeper.getWorld().playSound(_creeper.getLocation(), Sound.WITHER_SPAWN, 10F, 1.2F); + } + else if (getTicks() >= 60) + { + finish(); + } + + else if (getTicks() < 35) + { + double radius = 2 - (getTicks() / 10D * 2); + int particleAmount = 20 - (getTicks() * 2); + Location _centerLocation = _creeper.getLocation().add(0.5, 0.1, 0.5); + for (int i = 0; i < particleAmount; i++) + { + double xDiff = Math.sin(i/(double)particleAmount * 2 * Math.PI) * radius; + double zDiff = Math.cos(i/(double)particleAmount * 2 * Math.PI) * radius; + for(double e = 0.1 ; e < 3 ; e += 0.6) + { + Location location = _centerLocation.clone().add(xDiff, e, zDiff); + UtilParticle.PlayParticle(UtilParticle.ParticleType.WITCH_MAGIC, location, 0, 0, 0, 0, 1, ViewDist.NORMAL, UtilServer.getPlayers()); + } + } + } + } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java index 262dbff1c..4dbea71d2 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java @@ -26,6 +26,7 @@ public class AnimationCommand extends CommandBase{ _plugin.addPendingExplosion(caller, "RANK"); _plugin.addPendingExplosion(caller, "DAILY"); + } } \ No newline at end of file From ed7b8949bb0376762bace087f63fbfd2b6cb3dbf Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 10 Aug 2015 17:04:47 +0200 Subject: [PATCH 302/377] Adding SpinnerFiller and SpinnerRewards. --- .../src/mineplex/core/bonuses/gui/SpinGui.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 80268a046..e9d7221bb 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -46,6 +46,7 @@ public class SpinGui extends SimpleGui private int _ticksPerSwap; private int _swapCount; private Reward[] _rewards; + private Reward[] _fakeRewards; private boolean _stopped; private boolean _rewarded; private ArrayList _ticks; @@ -65,13 +66,18 @@ public class SpinGui extends SimpleGui //setItem(CARL_SLOT, new DisplayItem(carlItem)); _rewards = new Reward[REWARDS_TO_GENERATE]; + _fakeRewards = new Reward[REWARDS_TO_GENERATE]; _ticks = new ArrayList<>(); _frame = 0; _pitch = 1; for (int i = 0; i < REWARDS_TO_GENERATE; i++) { - _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.MythicalChest, true); + _fakeRewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); + } + for (int i = 0; i < REWARDS_TO_GENERATE; i++) + { + _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); } _ticksPerSwap = 1; @@ -98,7 +104,8 @@ public class SpinGui extends SimpleGui _stopSpinnerAt = _ticks.size(); - _reward = _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; + _fakeRewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3] = _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; + _reward = _fakeRewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; _rewardData = _reward.giveReward("Carls Spinner", getPlayer()); } @@ -147,7 +154,7 @@ public class SpinGui extends SimpleGui index = index % REWARDS_TO_GENERATE; int slot = 9 + i; - RewardData data = _rewards[index].getFakeRewardData(getPlayer()); + RewardData data = _fakeRewards[index].getFakeRewardData(getPlayer()); setItem(slot, new RewardButton(data)); // Glass Panes From 3be811e480bb6a6743f12655fa93e10c17314b90 Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 10 Aug 2015 17:08:03 +0200 Subject: [PATCH 303/377] Fixing Spinner announcements. --- .../src/mineplex/core/bonuses/gui/SpinGui.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index e9d7221bb..16c8fcba3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -253,9 +253,24 @@ public class SpinGui extends SimpleGui return; _manager.addPendingExplosion(getPlayer(), _reward); + if (_reward.getRarity() == RewardRarity.RARE) + { + Bukkit.broadcastMessage(F.main("Treasure", F.name(getPlayer().getName()) + " won " + C.cPurple + "Rare " + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } + else if (_reward.getRarity() == RewardRarity.LEGENDARY) + { + Bukkit.broadcastMessage(F.main("Treasure", F.name(getPlayer().getName()) + " won " + C.cGreen + "Legendary " + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } + else if (_reward.getRarity() == RewardRarity.MYTHICAL) + { + Bukkit.broadcastMessage(F.main("Treasure", F.name(getPlayer().getName()) + " won " + C.cRed + "Mythical " + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } + else + { + UtilPlayer.message(getPlayer(), F.main("Carl's Spinner", "You won " + _rewardData.getRarity().getColor() + _rewardData.getFriendlyName() + C.cGray + " from Carl's Spinner.")); + } ItemStack item = getInventory().getItem(13); getInventory().setItem(13, ItemStackFactory.Instance.CreateStack(item.getType(), (byte) 0, 1, _rewardData.getFriendlyName())); - UtilPlayer.message(getPlayer(), F.main("Carl's Spinner", "You got " + _rewardData.getRarity().getColor() + _rewardData.getFriendlyName() + C.cGray + " From Carl's Spinner.")); _rewarded = true; } From 186e3028c29556ddd0780ac81e5c95064ab1c3d1 Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 10 Aug 2015 17:15:56 +0200 Subject: [PATCH 304/377] removing temp fix "there was an error processing your request" for the Spinner. --- .../Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index e1109137b..9b4a4ee52 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -447,7 +447,6 @@ public class BonusManager extends MiniClientPlugin implements I } catch (Exception e) { - new SpinGui(getPlugin(), player, _rewardManager, manager).openInventory(); UtilPlayer.message(player, F.main("Carl", "There was an error processing your request")); } } From fef269b856a0b50d23fe894fb021d0bce4ac1db2 Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 10 Aug 2015 17:28:27 +0200 Subject: [PATCH 305/377] Fixing /e set. --- .../nautilus/game/arcade/managers/GameHostManager.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java index b247ee140..b6f91560c 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java @@ -724,15 +724,15 @@ public class GameHostManager implements Listener String source = ""; if(args.length == 5) { - Manager.GetGameCreationManager().MapSource = args[2]; - Manager.GetGameCreationManager().MapPref = args[3]; + Manager.GetGameCreationManager().MapSource = args[3]; + Manager.GetGameCreationManager().MapPref = args[4]; source = args[3]; map = args[4]; } else { - Manager.GetGameCreationManager().MapSource = args[0]; - Manager.GetGameCreationManager().MapPref = args[1]; + Manager.GetGameCreationManager().MapSource = args[2]; + Manager.GetGameCreationManager().MapPref = args[3]; source = args[2]; map = args[3]; } From 3bedc4ce841e637dec3d1ae81ed30a87aee383dc Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 05:37:58 +0200 Subject: [PATCH 306/377] Improving animation timing. --- .../bonuses/animations/AnimationCarl.java | 10 +++------- .../bonuses/commands/AnimationCommand.java | 19 ++++++++++++------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index 3090c9754..a98977521 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -184,7 +184,7 @@ public class AnimationCarl extends Animation public void MythicalAnimation() { - if (getTicks() < 30 && getTicks() % 3 == 0) + if (getTicks() < 30) { UtilFirework.playFirework(_creeper.getLocation().add(0.5, 0.5, 0.5), Type.BALL_LARGE, Color.RED, true, true); } @@ -194,7 +194,7 @@ public class AnimationCarl extends Animation _creeper.getLocation().getWorld().playSound(_creeper.getLocation().add(0.5, 0.5, 0.5), Sound.PORTAL_TRAVEL, 10F, 2.0F); _creeper.getLocation().getWorld().playSound(_creeper.getLocation().add(0.5, 0.5, 0.5), Sound.ZOMBIE_UNFECT, 10F, 0.1F); } - else if (getTicks() < 60) + else if (getTicks() < 40) { UtilFirework.launchFirework(_creeper.getLocation().add(0.5, 0.5, 0.5), Type.BALL_LARGE, Color.RED, true, true, new Vector((Math.random()-0.5)*0.05, 0.1, (Math.random()-0.5)*0.05), 1); @@ -211,11 +211,7 @@ public class AnimationCarl extends Animation UtilParticle.PlayParticle(UtilParticle.ParticleType.WITCH_MAGIC, location, 0, 0, 0, 0, 1, ViewDist.NORMAL, UtilServer.getPlayers()); } - } - else if (getTicks() < 60) - { - double radius = 2 - (getTicks() / 10D * 2); - int particleAmount = 20 - (getTicks() * 2); + Location _centerLocation = _creeper.getLocation().add(0.5, 0.1, 0.5); for (int i = 0; i < particleAmount; i++) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java index 4dbea71d2..c3356c9b7 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/AnimationCommand.java @@ -1,14 +1,16 @@ package mineplex.core.bonuses.commands; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; +import mineplex.core.reward.RewardType; import mineplex.core.bonuses.BonusManager; public class AnimationCommand extends CommandBase{ - BonusManager _plugin; + private BonusManager _plugin; public AnimationCommand(BonusManager plugin) { @@ -19,13 +21,16 @@ public class AnimationCommand extends CommandBase{ @Override public void Execute(Player caller, String[] args) { - _plugin.addPendingExplosion(caller, "Test"); - _plugin.addPendingExplosion(caller, "Chiss"); - _plugin.addPendingExplosion(caller, "Phinary"); - _plugin.addPendingExplosion(caller, "xXVevzZXx"); - _plugin.addPendingExplosion(caller, "RANK"); - _plugin.addPendingExplosion(caller, "DAILY"); + if(args != null) + { + caller = Bukkit.getPlayer(args[0]); + _plugin.addPendingExplosion(caller, _plugin.getRewardManager().nextReward(caller, null, false, RewardType.SpinnerFiller, true)); + } + if(args.length >= 2) + { + _plugin.addPendingExplosion(caller, args[1]); + } } From b4e8b4f1ac2c7cefbcdd45125e8b3620b48a85d0 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 08:24:28 +0200 Subject: [PATCH 307/377] cant go spinnin while its a countin! --- .../nautilus/game/arcade/managers/GameManager.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java index cfed7e11b..ab07870ab 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java @@ -3,6 +3,7 @@ package nautilus.game.arcade.managers; import java.util.ArrayList; import java.util.Iterator; +import mineplex.core.bonuses.event.CarlSpinnerEvent; import mineplex.core.common.util.C; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilFirework; @@ -130,7 +131,17 @@ public class GameManager implements Listener UtilTextBottom.displayProgress("Game Start", percentage, UtilTime.MakeStr(Math.max(0, game.PrepareTime - (System.currentTimeMillis() - game.GetStateTime()))), player); } - + + @EventHandler + public void cancelCarlSpinner(CarlSpinnerEvent event) + { + Game game = Manager.GetGame(); + if (game == null) return; + + if (game.GetCountdown() <= 0) + event.setCancelled(true); + } + @EventHandler public void StateUpdate(UpdateEvent event) { From 66f2a5df5e0b2233b49537aa198a3e490e509765 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 08:32:12 +0200 Subject: [PATCH 308/377] renamed GAME --- .../Mineplex.Core/src/mineplex/core/reward/RewardManager.java | 4 ++-- .../Mineplex.Core/src/mineplex/core/reward/RewardRarity.java | 2 +- .../Mineplex.Core/src/mineplex/core/reward/RewardType.java | 4 ++-- .../src/mineplex/core/reward/rewards/ExperienceReward.java | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index 386eba7ad..1b49623f7 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -66,8 +66,8 @@ public class RewardManager public void addGame(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager) { - addReward(new GemReward(donationManager, 100, 500, 100, RewardRarity.GAME)); - addReward(new ExperienceReward(statsManager, 100, 5000, 100, RewardRarity.GAME)); + addReward(new GemReward(donationManager, 100, 500, 100, RewardRarity.CARL_EXTRA)); + addReward(new ExperienceReward(statsManager, 100, 5000, 100, RewardRarity.CARL_EXTRA)); } public void addCommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java index 1f56de46a..971084562 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java @@ -20,7 +20,7 @@ public enum RewardRarity OTHER("Other", cWhite, Material.STAINED_GLASS_PANE, (byte) 0), COMMON("Common", cWhite, Material.STAINED_GLASS_PANE, (byte) 0), - GAME("Game", cYellow, Material.STAINED_GLASS_PANE, (byte) 4), + CARL_EXTRA("Game", cYellow, Material.STAINED_GLASS_PANE, (byte) 4), UNCOMMON("Uncommon", cAqua, Material.STAINED_GLASS_PANE, (byte) 3), RARE("Rare", cPurple, Material.STAINED_GLASS_PANE, (byte) 10), LEGENDARY("Legendary", cGreen, Material.STAINED_GLASS_PANE, (byte) 5), diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java index 90b201c08..6d9234391 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java @@ -3,7 +3,7 @@ package mineplex.core.reward; public enum RewardType { //% Chances Mythic Legend Rare Uncommon - GameLoot( 0.000001, 0.00001, 0.0001, 3, 10), + GameLoot( 0.000001, 0.00001, 0.0001, 3, 0), OldChest( 0, 0.05, 0.4, 5, 0), AncientChest( 0, 1, 4, 25, 0), @@ -37,7 +37,7 @@ public enum RewardType else if (rand <= _legendaryChance) rarity = RewardRarity.LEGENDARY; else if (rand <= _rareChance) rarity = RewardRarity.RARE; else if (rand <= _uncommonChance || requiresUncommon) rarity = RewardRarity.UNCOMMON; - else if (rand <= _gameChance) rarity = RewardRarity.GAME; + else if (rand <= _gameChance) rarity = RewardRarity.CARL_EXTRA; return rarity; } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java index a96245c6f..7c2811608 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java @@ -35,13 +35,13 @@ public class ExperienceReward extends Reward _statsManager.incrementStat(player, "Global.ExpEarned", experience); - return new RewardData(getRarity().getColor() + experience + " Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.GAME); + return new RewardData(getRarity().getColor() + experience + " Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.CARL_EXTRA); } @Override public RewardData getFakeRewardData(Player player) { - return new RewardData(getRarity().getColor() + "Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.GAME); + return new RewardData(getRarity().getColor() + "Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.CARL_EXTRA); } @Override From d833385df425197436eaf58f9a196b91d2d6a7aa Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 00:35:02 -0600 Subject: [PATCH 309/377] Fix carl spinner and ticket command, Fix polls not displaying in available count, Visual fixes --- Plugins/.idea/misc.xml | 2 +- Plugins/.idea/modules.xml | 1 - .../mineplex/core/bonuses/BonusAmount.java | 5 ++- .../mineplex/core/bonuses/BonusManager.java | 43 ++++++++----------- .../core/bonuses/BonusRepository.java | 42 ++++++++++++++++++ .../core/bonuses/commands/TicketCommand.java | 30 +++++++++---- .../bonuses/gui/buttons/DailyBonusButton.java | 6 +-- .../core/bonuses/gui/buttons/VoteButton.java | 10 ++--- 8 files changed, 94 insertions(+), 45 deletions(-) diff --git a/Plugins/.idea/misc.xml b/Plugins/.idea/misc.xml index 3a9b4c67e..aeea575e6 100644 --- a/Plugins/.idea/misc.xml +++ b/Plugins/.idea/misc.xml @@ -16,7 +16,7 @@ - + \ No newline at end of file diff --git a/Plugins/.idea/modules.xml b/Plugins/.idea/modules.xml index bcc0470f4..f7936ba2e 100644 --- a/Plugins/.idea/modules.xml +++ b/Plugins/.idea/modules.xml @@ -11,7 +11,6 @@ - diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java index d2cfef1f8..bb6d8c9f3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java @@ -2,6 +2,8 @@ package mineplex.core.bonuses; import java.util.List; +import org.bukkit.ChatColor; + import mineplex.core.common.util.C; public class BonusAmount @@ -138,6 +140,7 @@ public class BonusAmount public void addLore(List lore) { + lore.add(C.cYellow + "Rewards"); addLore(lore, getTickets(), 0, "Carl Spin Ticket" + (getTickets() > 1 ? "s" : "")); addLore(lore, getCoins(), getBonusCoins(), "Coins"); addLore(lore, getGems(), getBonusGems(), "Gems"); @@ -148,7 +151,7 @@ public class BonusAmount private void addLore(List lore, int amount, int bonus, String suffix) { if (amount > 0) - lore.add(C.cYellow + "Reward: " + C.cWhite + amount + " " + suffix); + lore.add(" " + C.cWhite + amount + " " + suffix); // if (bonus > 0) // lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + bonus + " " + suffix); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 9b4a4ee52..81121d59e 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -43,6 +43,7 @@ import mineplex.core.bonuses.gui.SpinGui; import mineplex.core.poll.PollManager; import mineplex.serverdata.commands.ServerCommandManager; +import org.jooq.DSLContext; import org.jooq.SQLDialect; import org.jooq.impl.DSL; import org.bukkit.Bukkit; @@ -419,35 +420,23 @@ public class BonusManager extends MiniClientPlugin implements I { CarlSpinnerEvent event = new CarlSpinnerEvent(player); Bukkit.getServer().getPluginManager().callEvent(event); - final BonusManager manager = this; if (!event.isCancelled()) { final int accountId = _clientManager.Get(player).getAccountId(); - runAsync(new Runnable() + _repository.attemptAddTickets(accountId, clientData, -1, new Callback() { @Override - public void run() + public void run(Boolean data) { - try + if (data) { - final int newTickets = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL).update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.sub(1)). - where(Tables.bonus.accountId.eq(accountId)).returning(Tables.bonus.tickets).fetchOne().getTickets(); - - runSync(new Runnable() - { - @Override - public void run() - { - clientData.setTickets(newTickets); - new SpinGui(getPlugin(), player, _rewardManager, manager).openInventory(); - } - }); + new SpinGui(_plugin, player, _rewardManager, BonusManager.this).openInventory(); } - catch (Exception e) + else { - UtilPlayer.message(player, F.main("Carl", "There was an error processing your request")); + UtilPlayer.message(player, F.main("Carl", "There waa an error processing your request. Try again later")); } } }); @@ -816,6 +805,7 @@ public class BonusManager extends MiniClientPlugin implements I if (canVote(player)) availableRewards++; if (canRank(player)) availableRewards++; if (canDaily(player)) availableRewards++; + if (getPollManager().getNextPoll(_pollManager.Get(player), _clientManager.Get(player).GetRank()) != null) availableRewards++; Hologram hologram; @@ -898,14 +888,15 @@ public class BonusManager extends MiniClientPlugin implements I if (clientData.getHologram() != null) clientData.getHologram().stop(); - runAsync(new Runnable() - { - @Override - public void run() - { - clientData.getRecord().store(); - } - }); + // This shouldnt be necessary anymore +// runAsync(new Runnable() +// { +// @Override +// public void run() +// { +// clientData.getRecord().store(); +// } +// }); super.UnloadPlayer(event); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java index d97a76cc5..2606705df 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java @@ -7,7 +7,11 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; +import com.sun.org.apache.xpath.internal.operations.Bool; +import mineplex.core.bonuses.gui.SpinGui; import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; import mineplex.core.database.DBPool; import mineplex.core.database.RepositoryBase; import mineplex.core.database.ResultSetCallable; @@ -17,7 +21,9 @@ import mineplex.database.Tables; import mineplex.database.tables.records.BonusRecord; import org.jooq.DSLContext; import org.jooq.Record2; +import org.jooq.SQLDialect; import org.jooq.TableField; +import org.jooq.impl.DSL; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -95,6 +101,42 @@ public class BonusRepository extends RepositoryBase }); } + public void attemptAddTickets(final int accountId, final BonusClientData client, final int tickets, final Callback callback) + { + if (client.getTickets() + tickets < 0) + callback.run(false); + + Bukkit.getScheduler().runTaskAsynchronously(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + try + { + DSLContext create = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL); + create.update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.add(tickets)). + where(Tables.bonus.accountId.eq(accountId)).execute(); + final int newTickets = create.select(Tables.bonus.tickets).from(Tables.bonus).where(Tables.bonus.accountId.eq(accountId)).fetchOne().value1(); + + Bukkit.getScheduler().runTask(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + client.setTickets(newTickets); + callback.run(true); + } + }); + } + catch (Exception e) + { + e.printStackTrace(); + callback.run(false); + } + } + }); + } + public void attemptDailyBonus(final Player player, final Callback result) { final int accountId = _manager.getClientManager().Get(player).getAccountId(); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java index 20aa7ad66..62cefef27 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java @@ -2,6 +2,7 @@ package mineplex.core.bonuses.commands; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; +import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; import mineplex.core.bonuses.BonusManager; @@ -36,15 +37,28 @@ public class TicketCommand extends CommandBase { try { - int tickets = Integer.parseInt(ticketString); - Plugin.Get(target).setTickets(Plugin.Get(targetName).getTickets() + tickets); - - UtilPlayer.message(caller, F.main("Carl", "You gave " + F.elem(tickets + " Carl Tickets") + " to " + F.name(targetName) + ".")); - - if (target != null) + final int tickets = Integer.parseInt(ticketString); + int accountId = Plugin.getClientManager().getAccountId(target); + Plugin.getRepository().attemptAddTickets(accountId, Plugin.Get(target), tickets, new Callback() { - UtilPlayer.message(target, F.main("Carl", F.name(caller.getName()) + " gave you " + F.elem(tickets + " Carl Tickets") + ".")); - } + @Override + public void run(Boolean data) + { + if (data) + { + UtilPlayer.message(caller, F.main("Carl", "You gave " + F.elem(tickets + " Carl Tickets") + " to " + F.name(targetName) + ".")); + + if (target != null && !target.equals(caller)) + { + UtilPlayer.message(target, F.main("Carl", F.name(caller.getName()) + " gave you " + F.elem(tickets + " Carl Tickets") + ".")); + } + } + else + { + UtilPlayer.message(caller, F.main("Carl", "Failed to give tickets. Try again later!")); + } + } + }); } catch (Exception e) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java index 8efb10fa5..2c09f41c4 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java @@ -144,9 +144,7 @@ public class DailyBonusButton implements GuiItem, Listener lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getDailyStreak()); - lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + _bonusManager.getDailyMultiplier(_player) + "%"); - lore.add(" "); - lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxDailyStreak()); + lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + "+" + _bonusManager.getDailyMultiplier(_player) + "%"); if (client.getDailyTime() != null) { @@ -159,6 +157,8 @@ public class DailyBonusButton implements GuiItem, Listener } } + lore.add(" "); + lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxDailyStreak()); StreakRecord streakRecord = _bonusManager.getDailyStreak(); if (streakRecord != null) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java index b05c3dad0..50ed5afee 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java @@ -131,10 +131,7 @@ public class VoteButton implements GuiItem, Listener { lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getVoteStreak()); - lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + _bonusManager.getVoteMultiplyer(_player) + "%"); - lore.add(" "); - lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxVoteStreak()); - + lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + "+" + _bonusManager.getVoteMultiplyer(_player) + "%"); if (client.getVoteTime() != null) { long lastBonus = _bonusManager.getLocalTime(client.getVoteTime().getTime()); @@ -146,6 +143,9 @@ public class VoteButton implements GuiItem, Listener { } } + lore.add(" "); + lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxVoteStreak()); + StreakRecord streakRecord = _bonusManager.getVoteStreak(); if (streakRecord != null) { @@ -185,4 +185,4 @@ public class VoteButton implements GuiItem, Listener { { return _gui; } -} +} \ No newline at end of file From d457e3a95570fa6e6fe0c73256075c46b828ed23 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 08:36:39 +0200 Subject: [PATCH 310/377] changing the setOP Event. --- .../src/nautilus/game/arcade/ArcadeManager.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java index fd0f4fc6d..bcda7f6ef 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java @@ -849,9 +849,15 @@ public class ArcadeManager extends MiniPlugin implements IRelation { // Give developers operator on their servers boolean testServer = _plugin.getConfig().getString("serverstatus.group").equalsIgnoreCase("Testing"); + boolean eventTestServer = _plugin.getConfig().getString("serverstatus.name").equalsIgnoreCase("SMTestServer-1"); - if (_clientManager.Get(event.getPlayer()).GetRank().Has(Rank.OWNER) || (testServer && (_clientManager.Get(event.getPlayer()).GetRank().Has(Rank.DEVELOPER) || _clientManager.Get(event.getPlayer()).GetRank() == Rank.JNR_DEV))) + if(eventTestServer) + return; + + if (_clientManager.Get(event.getPlayer()).GetRank().Has(Rank.OWNER) || (testServer && (_clientManager.Get(event.getPlayer()).GetRank().Has(Rank.JNR_DEV)))) event.getPlayer().setOp(true); + else + event.getPlayer().setOp(false); } public boolean IsAlive(Player player) From 5d3503b73306ef8be4ab45fd1fbb87a145f8678a Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 01:55:27 -0500 Subject: [PATCH 311/377] Carl rewards --- .../mineplex/core/bonuses/BonusManager.java | 13 ++++- .../mineplex/core/reward/RewardManager.java | 56 +++++++++++++------ .../mineplex/core/reward/RewardRarity.java | 2 +- .../src/mineplex/core/reward/RewardType.java | 2 +- .../core/reward/rewards/ExperienceReward.java | 4 +- .../core/treasure/TreasureManager.java | 10 +++- .../src/mineplex/hub/HubManager.java | 11 +--- .../game/arcade/managers/GameLootManager.java | 2 +- 8 files changed, 65 insertions(+), 35 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 81121d59e..eb98b5137 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -24,8 +24,10 @@ import mineplex.core.database.DBPool; import mineplex.core.donation.DonationManager; import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; +import mineplex.core.inventory.InventoryManager; import mineplex.core.npc.Npc; import mineplex.core.npc.NpcManager; +import mineplex.core.pet.PetManager; import mineplex.core.reward.RewardManager; import mineplex.core.stats.StatsManager; import mineplex.core.updater.UpdateType; @@ -123,7 +125,7 @@ public class BonusManager extends MiniClientPlugin implements I private StreakRecord _dailyStreak; private StreakRecord _voteStreak; - public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, RewardManager rewardManager, StatsManager statsManager) + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, StatsManager statsManager, InventoryManager inventoryManager, PetManager petManager) { super("Bonus", plugin); _repository = new BonusRepository(plugin, this, donationManager); @@ -131,7 +133,14 @@ public class BonusManager extends MiniClientPlugin implements I _donationManager = donationManager; _npcManager = npcManager; _hologramManager = hologramManager; - _rewardManager = rewardManager; + + _rewardManager = new RewardManager(clientManager, donationManager, inventoryManager, petManager, statsManager, + 100, 250, + 500, 1000, + 4000, 6000, + 12000, 32000, + true, true); + _pollManager = pollManager; _statsManager = statsManager; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index 1b49623f7..61db7e1eb 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -32,6 +32,7 @@ public class RewardManager private JavaPlugin _plugin; private HashMap> _treasureMap; private Random _random; + private boolean _carlSpinner; private CoreClientManager _clientManager; @@ -42,7 +43,7 @@ public class RewardManager int uncommonValueMin, int uncommonValueMax, int rareValueMin, int rareValueMax, int legendValueMin, int legendValueMax, - boolean doubleGadgetValue) + boolean doubleGadgetValue, boolean carlSpinner) { _plugin = donationManager.getPlugin(); _treasureMap = new HashMap>(); @@ -56,21 +57,15 @@ public class RewardManager _clientManager = clientManager; _doubleGadgetValue = doubleGadgetValue; + _carlSpinner = carlSpinner; - addGame(donationManager, inventoryManager, petManager, statsManager); - addCommon(donationManager, inventoryManager, petManager, commonValueMin, commonValueMax); - addUncommon(donationManager, inventoryManager, petManager, uncommonValueMin, uncommonValueMax); - addRare(donationManager, inventoryManager, petManager, rareValueMin, rareValueMax); - addLegendary(donationManager, inventoryManager, petManager, legendValueMin, legendValueMax); + addCommon(donationManager, inventoryManager, petManager, statsManager, commonValueMin, commonValueMax); + addUncommon(donationManager, inventoryManager, petManager, statsManager, uncommonValueMin, uncommonValueMax); + addRare(donationManager, inventoryManager, petManager, statsManager, rareValueMin, rareValueMax); + addLegendary(donationManager, inventoryManager, petManager, statsManager, legendValueMin, legendValueMax); } - public void addGame(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager) - { - addReward(new GemReward(donationManager, 100, 500, 100, RewardRarity.CARL_EXTRA)); - addReward(new ExperienceReward(statsManager, 100, 5000, 100, RewardRarity.CARL_EXTRA)); - } - - public void addCommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addCommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.COMMON; @@ -112,9 +107,16 @@ public class RewardManager addReward(new InventoryReward(inventoryManager, "TNT", "TNT", (int)(20*(minValue/500)), (int)(20*(maxValue/500)), new ItemStack(Material.TNT), rarity, 10)); + + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 25, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 25, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 25, rarity)); + } } - public void addUncommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addUncommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.UNCOMMON; @@ -198,9 +200,16 @@ public class RewardManager // new ItemStack(2266), rarity, 25)); addReward(new UnknownPackageReward(donationManager, "Wait Disc", "Wait Disc", new ItemStack(2267), rarity, 25)); + + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 1300, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 1300, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 1300, rarity)); + } } - public void addRare(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addRare(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.RARE; @@ -250,14 +259,20 @@ public class RewardManager addReward(new UnknownPackageReward(donationManager, "Space Boots", "Space Boots", new ItemStack(Material.GOLD_BOOTS), rarity, 50)); + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 390, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 390, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 390, rarity)); + } } - public void addLegendary(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addLegendary(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.LEGENDARY; // Coins - addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 25, RewardRarity.LEGENDARY)); + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 25, rarity)); // Mounts addReward(new UnknownPackageReward(donationManager, "Infernal Horror", "Infernal Horror", @@ -286,6 +301,13 @@ public class RewardManager new ItemStack(Material.APPLE), rarity, 4)); addReward(new UnknownPackageReward(donationManager, "Heart Particles", "I Heart You", new ItemStack(Material.BLAZE_POWDER), rarity, 2)); + + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 70, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 70, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 70, rarity)); + } } public void addReward(Reward reward) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java index 971084562..43072cbe4 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardRarity.java @@ -20,7 +20,7 @@ public enum RewardRarity OTHER("Other", cWhite, Material.STAINED_GLASS_PANE, (byte) 0), COMMON("Common", cWhite, Material.STAINED_GLASS_PANE, (byte) 0), - CARL_EXTRA("Game", cYellow, Material.STAINED_GLASS_PANE, (byte) 4), +// CARL_EXTRA("Game", cYellow, Material.STAINED_GLASS_PANE, (byte) 4), UNCOMMON("Uncommon", cAqua, Material.STAINED_GLASS_PANE, (byte) 3), RARE("Rare", cPurple, Material.STAINED_GLASS_PANE, (byte) 10), LEGENDARY("Legendary", cGreen, Material.STAINED_GLASS_PANE, (byte) 5), diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java index 6d9234391..4cbc5f6ec 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java @@ -37,7 +37,7 @@ public enum RewardType else if (rand <= _legendaryChance) rarity = RewardRarity.LEGENDARY; else if (rand <= _rareChance) rarity = RewardRarity.RARE; else if (rand <= _uncommonChance || requiresUncommon) rarity = RewardRarity.UNCOMMON; - else if (rand <= _gameChance) rarity = RewardRarity.CARL_EXTRA; +// else if (rand <= _gameChance) rarity = RewardRarity.CARL_EXTRA; return rarity; } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java index 7c2811608..ad1ad3b5b 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java @@ -35,13 +35,13 @@ public class ExperienceReward extends Reward _statsManager.incrementStat(player, "Global.ExpEarned", experience); - return new RewardData(getRarity().getColor() + experience + " Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.CARL_EXTRA); + return new RewardData(getRarity().getColor() + experience + " Experience", new ItemStack(Material.EXP_BOTTLE), getRarity()); } @Override public RewardData getFakeRewardData(Player player) { - return new RewardData(getRarity().getColor() + "Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.CARL_EXTRA); + return new RewardData(getRarity().getColor() + "Experience", new ItemStack(Material.EXP_BOTTLE), getRarity()); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java index 5746bc978..2afbb1ca3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java @@ -20,6 +20,7 @@ import mineplex.core.pet.PetManager; import mineplex.core.reward.Reward; import mineplex.core.reward.RewardManager; import mineplex.core.reward.RewardType; +import mineplex.core.stats.StatsManager; /** * Created by Shaun on 8/27/2014. @@ -32,14 +33,19 @@ public class TreasureManager extends MiniPlugin private HologramManager _hologramManager; private List _treasureLocations; - public TreasureManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, BlockRestore blockRestore, HologramManager hologramManager, RewardManager rewardManager) + public TreasureManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, BlockRestore blockRestore, HologramManager hologramManager, StatsManager statsManager) { super("Treasure", plugin); _inventoryManager = inventoryManager; _blockRestore = blockRestore; _hologramManager = hologramManager; - _rewardManager = rewardManager; + _rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, statsManager, + 100, 250, + 500, 1000, + 4000, 6000, + 12000, 32000, + true, false);; World world = Bukkit.getWorlds().get(0); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index f09e21e1f..8d58d26b1 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -190,14 +190,7 @@ public class HubManager extends MiniClientPlugin new BenefitManager(plugin, clientManager, _inventoryManager); _gadgetManager = new GadgetManager(_plugin, clientManager, donationManager, _inventoryManager, _mountManager, petManager, preferences, disguiseManager, blockRestore, new ProjectileManager(plugin), achievementManager); - RewardManager rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, statsManager, - 100, 250, - 500, 1000, - 4000, 6000, - 12000, 32000, - true); - - _treasureManager = new TreasureManager(_plugin, clientManager, donationManager, _inventoryManager, petManager, _blockRestore, hologramManager, rewardManager); + _treasureManager = new TreasureManager(_plugin, clientManager, donationManager, _inventoryManager, petManager, _blockRestore, hologramManager, statsManager); new CosmeticManager(_plugin, clientManager, donationManager, _inventoryManager, _gadgetManager, _mountManager, petManager, _treasureManager); new SoccerManager(this, _gadgetManager); @@ -222,7 +215,7 @@ public class HubManager extends MiniClientPlugin ((CraftWorld)Bukkit.getWorlds().get(0)).getHandle().pvpMode = true; - new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, rewardManager, statsManager); + new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, statsManager, _inventoryManager, petManager); // NotificationManager notificationManager = new NotificationManager(plugin, clientManager, donationManager); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java index 91e3ae9ec..e018a834d 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java @@ -55,7 +55,7 @@ public class GameLootManager implements Listener 500, 1000, 1500, 2500, 6000, 12000, - false); + false, false); //Chest _rewardManager.addReward(new InventoryReward(Manager.getInventoryManager(), "Old Chest", "Old Chest", 1, 1, From b99c52616918e2581bd4c115f134ccd9ec97b842 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 09:09:16 +0200 Subject: [PATCH 312/377] Implementing Carl message. --- .../mineplex/core/bonuses/BonusManager.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 9b4a4ee52..7c0f9b13d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -4,6 +4,7 @@ import java.sql.Date; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Calendar; +import java.util.HashMap; import java.util.TimeZone; import mineplex.core.MiniClientPlugin; @@ -26,6 +27,7 @@ import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; import mineplex.core.npc.Npc; import mineplex.core.npc.NpcManager; +import mineplex.core.recharge.Recharge; import mineplex.core.reward.RewardManager; import mineplex.core.stats.StatsManager; import mineplex.core.updater.UpdateType; @@ -70,6 +72,7 @@ public class BonusManager extends MiniClientPlugin implements I private ArrayList _pendingExplosions = new ArrayList<>(); private ArrayList _pendingExplosionsPlayers = new ArrayList<>(); + private HashMap _showCarl = new HashMap<>(); private long _explode; private boolean _canVote; @@ -949,4 +952,36 @@ public class BonusManager extends MiniClientPlugin implements I entity.remove(); } } + + @EventHandler + public void Join(final PlayerJoinEvent event) + { + runSyncLater(new Runnable() + { + @Override + public void run() + { + _showCarl.put(event.getPlayer().getName(), true); + } + }, 200); + } + + @EventHandler + public void carlUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + for (Player player : UtilServer.getPlayers()) + { + if (Recharge.Instance.use(player, "Carl Inform", 240000, false, false)) + { + if(_pollManager.Get(player).shouldPoll() || canVote(player) || canRank(player) || canDaily(player)) + { + if(_showCarl.containsKey(player.getName())) + UtilPlayer.message(player, C.cDGreen + C.Bold + "Carl the Creeper)" + C.cGreen + " Hey " + player.getName().replace("s", "sss") + "! I have sssome amazing rewardsss for you! Come sssee me!"); + } + } + } + } } \ No newline at end of file From 2c30d20cb1d6c6ed56781a510c918aa7e3dbf884 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 09:26:01 +0200 Subject: [PATCH 313/377] changing OP method, setHost permissions and /e command. --- .../src/nautilus/game/arcade/ArcadeManager.java | 7 +++---- .../game/arcade/game/games/event/EventModule.java | 10 ++++++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java index bcda7f6ef..5aeba4d0c 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java @@ -850,11 +850,10 @@ public class ArcadeManager extends MiniPlugin implements IRelation // Give developers operator on their servers boolean testServer = _plugin.getConfig().getString("serverstatus.group").equalsIgnoreCase("Testing"); boolean eventTestServer = _plugin.getConfig().getString("serverstatus.name").equalsIgnoreCase("SMTestServer-1"); - - if(eventTestServer) - return; - if (_clientManager.Get(event.getPlayer()).GetRank().Has(Rank.OWNER) || (testServer && (_clientManager.Get(event.getPlayer()).GetRank().Has(Rank.JNR_DEV)))) + if (_clientManager.Get(event.getPlayer()).GetRank().Has(Rank.OWNER) + || (testServer && (_clientManager.Get(event.getPlayer()).GetRank().Has(Rank.DEVELOPER) || _clientManager.Get(event.getPlayer()).GetRank() == Rank.JNR_DEV)) + || eventTestServer && _clientManager.Get(event.getPlayer()).GetRank().Has(Rank.JNR_DEV)) event.getPlayer().setOp(true); else event.getPlayer().setOp(false); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/event/EventModule.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/event/EventModule.java index db6ce695e..83c0c0801 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/event/EventModule.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/event/EventModule.java @@ -82,7 +82,11 @@ public class EventModule extends MiniPlugin if (!event.getMessage().toLowerCase().startsWith("/sethost ")) return; - if (!Manager.GetClients().Get(event.getPlayer()).GetRank().Has(event.getPlayer(), Rank.JNR_DEV, true) && !event.getPlayer().isOp()) + boolean eventTestServer = _plugin.getConfig().getString("serverstatus.name").equalsIgnoreCase("SMTestServer-1"); + + if (!Manager.GetClients().Get(event.getPlayer()).GetRank().Has(event.getPlayer(), Rank.JNR_DEV, true) + && !event.getPlayer().isOp() && + (!eventTestServer && !Manager.GetClients().Get(event.getPlayer()).GetRank().Has(event.getPlayer(), Rank.SNR_MODERATOR, true))) return; Manager.GetServerConfig().HostName = event.getMessage().split(" ")[1]; @@ -177,7 +181,9 @@ public class EventModule extends MiniPlugin if (!event.getMessage().toLowerCase().startsWith("/e ")) return; - if(!Manager.GetGameHostManager().isEventServer()) + boolean eventTestServer = _plugin.getConfig().getString("serverstatus.name").equalsIgnoreCase("SMTestServer-1"); + + if(!Manager.GetGameHostManager().isEventServer() && !eventTestServer) return; event.setCancelled(true); From c177307f70e510a138f56974977e13c070754c47 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 02:53:54 -0500 Subject: [PATCH 314/377] Votifier fixes --- .../mineplex/core/bonuses/BonusManager.java | 83 +++++++++++------- .../core/bonuses/gui/buttons/VoteButton.java | 2 +- .../src/mineplex/votifier/Votifier.java | 4 +- .../mineplex/votifier/VotifierManager.java | 87 +++++++++++++++++-- 4 files changed, 138 insertions(+), 38 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index eb98b5137..75233ccba 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -125,6 +125,21 @@ public class BonusManager extends MiniClientPlugin implements I private StreakRecord _dailyStreak; private StreakRecord _voteStreak; + /** + * THIS SHOULD ONLY BE USED FOR VOTIFIER! + */ + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager) + { + super("Bonus", plugin); + _enabled = false; + + _repository = new BonusRepository(plugin, this, donationManager); + _clientManager = clientManager; + _donationManager = donationManager; + + updateOffSet(); + } + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, StatsManager statsManager, InventoryManager inventoryManager, PetManager petManager) { super("Bonus", plugin); @@ -146,18 +161,26 @@ public class BonusManager extends MiniClientPlugin implements I // Hope to god this works! _canVote = true; - _carlNpc = _npcManager.getNpcByName("Carl the Creeper"); - if (_carlNpc == null) + + if (npcManager != null) { - _enabled = false; + _carlNpc = _npcManager.getNpcByName("Carl the Creeper"); + if (_carlNpc == null) + { + _enabled = false; + } + else + { + _enabled = true; +// _carlNpc.getEntity().setCustomName(""); +// _carlNpc.getEntity().setCustomNameVisible(false); + _animation = new AnimationCarl(_carlNpc.getEntity()); + _animation.setRunning(false); + } } else { - _enabled = true; -// _carlNpc.getEntity().setCustomName(""); -// _carlNpc.getEntity().setCustomNameVisible(false); - _animation = new AnimationCarl(_carlNpc.getEntity()); - _animation.setRunning(false); + _enabled = false; } clientManager.addStoredProcedureLoginProcessor(this); @@ -229,24 +252,24 @@ public class BonusManager extends MiniClientPlugin implements I public void handleVote(final Player player) { - _repository.attemptVoteBonus(player, new Callback() + runAsync(new Runnable() { @Override - public void run(Boolean data) + public void run() { - if (data) + Get(player).getRecord().refresh(); + runSync(new Runnable() { - incrementVoteStreak(player); - addPendingExplosion(player, player.getName()); - awardBonus(player, getVoteBonusAmount(player)); - UtilPlayer.message(player, F.main("Vote", "Thanks for your vote!")); - } - else - { - UtilPlayer.message(player, F.main("Vote", "There was an error processing your vote. Please contact an admin!")); - } + @Override + public void run() + { + addPendingExplosion(player, player.getName()); + UtilPlayer.message(player, F.main("Vote", "Thanks for your vote!")); + } + }); } }); + } @EventHandler @@ -498,14 +521,12 @@ public class BonusManager extends MiniClientPlugin implements I data.setMaxDailyStreak(data.getDailyStreak()); } - public void incrementVoteStreak(Player player) + public void incrementVoteStreak(BonusClientData client) { - BonusClientData data = Get(player); + client.setVoteStreak(client.getVoteStreak() + 1); - data.setVoteStreak(data.getVoteStreak() + 1); - - if (data.getVoteStreak() > data.getMaxVoteStreak()) - data.setMaxVoteStreak(data.getVoteStreak()); + if (client.getVoteStreak() > client.getMaxVoteStreak()) + client.setMaxVoteStreak(client.getVoteStreak()); } public boolean continueStreak(long localLastBonus, long extendTime) @@ -548,9 +569,8 @@ public class BonusManager extends MiniClientPlugin implements I return multiplyer; } - public int getVoteMultiplyer(Player player) + public int getVoteMultiplyer(BonusClientData client) { - BonusClientData client = Get(player); int streak = client.getVoteStreak(); int multiplyer = Math.min(100, 5 * streak); @@ -579,7 +599,12 @@ public class BonusManager extends MiniClientPlugin implements I public BonusAmount getVoteBonusAmount(Player player) { - double mult = getVoteMultiplyer(player) / 100.0; + return getVoteBonusAmount(Get(player)); + } + + public BonusAmount getVoteBonusAmount(BonusClientData client) + { + double mult = getVoteMultiplyer(client) / 100.0; BonusAmount amount = new BonusAmount(); amount.setTickets(1); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java index 50ed5afee..7b6118f70 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java @@ -131,7 +131,7 @@ public class VoteButton implements GuiItem, Listener { lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getVoteStreak()); - lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + "+" + _bonusManager.getVoteMultiplyer(_player) + "%"); + lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + "+" + _bonusManager.getVoteMultiplyer(client) + "%"); if (client.getVoteTime() != null) { long lastBonus = _bonusManager.getLocalTime(client.getVoteTime().getTime()); diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java index 5ebb77b02..f3fd02c9a 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java @@ -3,6 +3,7 @@ package mineplex.votifier; import org.bukkit.plugin.java.JavaPlugin; import mineplex.core.account.CoreClientManager; +import mineplex.core.bonuses.BonusManager; import mineplex.core.command.CommandCenter; import mineplex.core.donation.DonationManager; @@ -25,8 +26,9 @@ public class Votifier extends JavaPlugin CommandCenter.Initialize(this); CoreClientManager clientManager = new CoreClientManager(this, webServerAddress); DonationManager donationManager = new DonationManager(this, clientManager, webServerAddress); + BonusManager bonusManager = new BonusManager(this, clientManager, donationManager); - VotifierManager vote = new VotifierManager(this, clientManager, donationManager); + VotifierManager vote = new VotifierManager(this, clientManager, donationManager, bonusManager); } } diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index 98f685a68..4791202f9 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -1,5 +1,6 @@ package mineplex.votifier; +import java.sql.Date; import java.util.UUID; import org.bukkit.event.EventHandler; @@ -9,6 +10,10 @@ import com.vexsoftware.votifier.model.Vote; import com.vexsoftware.votifier.model.VotifierEvent; import mineplex.core.MiniPlugin; import mineplex.core.account.CoreClientManager; +import mineplex.core.bonuses.BonusAmount; +import mineplex.core.bonuses.BonusClientData; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.common.util.Callback; import mineplex.core.common.util.UUIDFetcher; import mineplex.core.database.DBPool; import mineplex.core.donation.DonationManager; @@ -23,6 +28,7 @@ import mineplex.serverdata.redis.RedisConfig; import mineplex.serverdata.redis.RedisDataRepository; import mineplex.serverdata.servers.ServerManager; import org.jooq.DSLContext; +import org.jooq.Record1; import org.jooq.SQLDialect; import org.jooq.impl.DSL; import redis.clients.jedis.Jedis; @@ -36,6 +42,7 @@ public class VotifierManager extends MiniPlugin { private CoreClientManager _clientManager; private DonationManager _donationManager; + private BonusManager _bonusManager; private RedisConfig _usConfig; private RedisConfig _euConfig; @@ -44,12 +51,13 @@ public class VotifierManager extends MiniPlugin private JedisPool _usWritePool; private JedisPool _euWritePool; - public VotifierManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager) + public VotifierManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, BonusManager bonusManager) { super("Votifier", plugin); _clientManager = clientManager; _donationManager = donationManager; + _bonusManager = bonusManager; _usConfig = ServerManager.getConfig("us-redis.dat"); _euConfig = ServerManager.getConfig("eu-redis.dat"); @@ -71,7 +79,24 @@ public class VotifierManager extends MiniPlugin System.out.println("New Vote: " + playerName); -// UUID uuid = UUIDFetcher.getUUIDOf(playerName); + UUID uuid = UUIDFetcher.getUUIDOf(playerName); + if (uuid == null) + { + System.out.println("Failed to load UUID of " + playerName + " from UUIDFetcher. Trying with database"); + uuid = _clientManager.loadUUIDFromDB(playerName); + + if (uuid == null) + { + System.out.println("Failed to load UUID from database. Giving up on " + playerName); + } + } + + System.out.println("Loaded " + playerName + " with uuid " + uuid); + System.out.println("Attempting to award bonus"); + awardBonus(playerName, uuid); + System.out.println(); + System.out.println(); + // UUID uuid = _clientManager.loadUUIDFromDB(playerName); // if (uuid != null) // { @@ -116,13 +141,61 @@ public class VotifierManager extends MiniPlugin publishCommand(command, writePool); } - private void awardBonus(UUID uuid) + private void awardBonus(final String playerName, UUID uuid) { - // Don't use this right now! DSLContext create = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL); - int updated = create.update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.add(1)) - .where(Tables.bonus.accountId.eq(DSL.select(Tables.accounts.id).where(Tables.accounts.uuid.eq(uuid.toString())))).execute(); - System.out.println("Ran query with response: " + updated); + + Record1 idRecord = create.select(Tables.accounts.id).from(Tables.accounts).where(Tables.accounts.uuid.eq(uuid.toString())).fetchOne(); + if (idRecord != null) + { + final int accountId = idRecord.value1(); + final BonusClientData client = new BonusClientData(_bonusManager.getRepository().loadRecord(playerName, accountId)); + + final BonusAmount amount = _bonusManager.getVoteBonusAmount(client); + + // Reward Amount + if (amount.getTickets() > 0) + client.setTickets(client.getTickets() + amount.getTickets()); + + if (amount.getGems() > 0) + { + _donationManager.RewardGems(new Callback() + { + @Override + public void run(Boolean data) + { + if (data) + System.out.println("Gave " + amount.getGems() + " gems to " + playerName); + else + System.out.println("Failed to give " + amount.getGems() + " gems to " + playerName); + } + }, "Votifier", playerName, uuid, amount.getGems()); + } + + if (amount.getCoins() > 0) + { + _donationManager.RewardCoins(new Callback() + { + @Override + public void run(Boolean data) + { + if (data) + System.out.println("Gave " + amount.getGems() + " coins to " + playerName); + else + System.out.println("Failed to give " + amount.getGems() + " coins to " + playerName); + } + }, "Votifier", playerName, accountId, amount.getCoins()); + } + + // Update time + client.getRecord().setVotetime(new Date(_bonusManager.getSqlTime())); + + // Update Streak + _bonusManager.incrementVoteStreak(client); + + client.getRecord().store(); + System.out.println("Awarded carl ticket to " + playerName); + } } private void publishCommand(final ServerCommand serverCommand, final JedisPool writePool) From 13e7e58986488050ee337df979490b208dbbde65 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 03:09:21 -0500 Subject: [PATCH 315/377] Creeper visual! --- .../mineplex/core/bonuses/BonusManager.java | 72 ++++++++++++------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 75233ccba..2edf3ef60 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -120,6 +120,7 @@ public class BonusManager extends MiniClientPlugin implements I public boolean _enabled; private Npc _carlNpc; private AnimationCarl _animation; + private int _visualTick; // Streak private StreakRecord _dailyStreak; @@ -397,7 +398,7 @@ public class BonusManager extends MiniClientPlugin implements I { incrementDailyStreak(player); awardBonus(player, amount); - updateCreeperVisual(player); + updateCreeperVisual(player, true, C.cAqua); } result.run(r); @@ -436,7 +437,7 @@ public class BonusManager extends MiniClientPlugin implements I if (aBoolean) { awardBonus(player, getRankBonusAmount(player)); - updateCreeperVisual(player); + updateCreeperVisual(player, true, C.cAqua); } result.run(aBoolean); @@ -822,12 +823,12 @@ public class BonusManager extends MiniClientPlugin implements I public void run() { if (event.getPlayer().isOnline()) - updateCreeperVisual(event.getPlayer()); + updateCreeperVisual(event.getPlayer(), true, C.cAqua); } }, 10); } - public void updateCreeperVisual(Player player) + public void updateCreeperVisual(Player player, boolean updateDataWatcher, String rewardPrefix) { if (!_enabled) return; @@ -846,10 +847,12 @@ public class BonusManager extends MiniClientPlugin implements I if (client.getHologram() == null) { - hologram = new Hologram(_hologramManager, _carlNpc.getLocation().clone().add(0, 2.75 - 0.285 - 0.285, 0), ""); + double yAdd = UtilPlayer.is1_8(player) ? 2.18 : 2.3; + hologram = new Hologram(_hologramManager, _carlNpc.getLocation().clone().add(0, yAdd, 0), ""); hologram.setHologramTarget(Hologram.HologramTarget.WHITELIST); hologram.addPlayer(player); client.setHologram(hologram); + hologram.start(); } else { @@ -860,34 +863,53 @@ public class BonusManager extends MiniClientPlugin implements I { // Hologram // String name = "Carl the Creeper"; - String text = C.cAqua + availableRewards + " Reward" + (availableRewards > 1 ? "s" : "") + " to Claim"; + String text = rewardPrefix + availableRewards + " Reward" + (availableRewards > 1 ? "s" : "") + " to Claim"; hologram.setText(text); - hologram.start(); - // Charged - DataWatcher watcher = new DataWatcher(null); - watcher.a(0, (byte) 0); - watcher.a(1, (short) 300); - watcher.a(17, (byte) 1); - PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(); - packet.a = _carlNpc.getEntity().getEntityId(); - packet.b = watcher.c(); + if (updateDataWatcher) + { + // Charged + DataWatcher watcher = new DataWatcher(null); + watcher.a(0, (byte) 0); + watcher.a(1, (short) 300); + watcher.a(17, (byte) 1); + PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(); + packet.a = _carlNpc.getEntity().getEntityId(); + packet.b = watcher.c(); - UtilPlayer.sendPacket(player, packet); + UtilPlayer.sendPacket(player, packet); + } } else { - // Hologram - hologram.stop(); + String text = C.cGray + "No Rewards"; + hologram.setText(text); - // Charged - DataWatcher watcher = new DataWatcher(null); - watcher.a(17, (byte) 0); - PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(); - packet.a = _carlNpc.getEntity().getEntityId(); - packet.b = watcher.c(); + if (updateDataWatcher) + { + // Charged + DataWatcher watcher = new DataWatcher(null); + watcher.a(17, (byte) 0); + PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(); + packet.a = _carlNpc.getEntity().getEntityId(); + packet.b = watcher.c(); - UtilPlayer.sendPacket(player, packet); + UtilPlayer.sendPacket(player, packet); + } + } + } + + @EventHandler + public void updateCreeper(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC || !_enabled) + return; + + for (Player player : UtilServer.getPlayers()) + { + String prefix = _visualTick % 2 == 0 ? C.cAqua : C.cDAqua; + updateCreeperVisual(player, false, prefix); + _visualTick++; } } From fe153bee11d9902547ac8887aa667de24f194b2c Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 03:19:27 -0500 Subject: [PATCH 316/377] Fix revert issues --- .../mineplex/core/bonuses/BonusManager.java | 2 + .../core/bonuses/BonusRepository.java | 48 +++++++++++++- .../mineplex/core/reward/RewardManager.java | 64 +++++++++++++------ .../core/treasure/TreasureManager.java | 10 ++- .../src/mineplex/hub/HubManager.java | 11 +--- .../game/arcade/managers/GameLootManager.java | 2 +- 6 files changed, 101 insertions(+), 36 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index bb95d2722..ecdd769fd 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -25,8 +25,10 @@ import mineplex.core.database.DBPool; import mineplex.core.donation.DonationManager; import mineplex.core.hologram.Hologram; import mineplex.core.hologram.HologramManager; +import mineplex.core.inventory.InventoryManager; import mineplex.core.npc.Npc; import mineplex.core.npc.NpcManager; +import mineplex.core.pet.PetManager; import mineplex.core.recharge.Recharge; import mineplex.core.reward.RewardManager; import mineplex.core.stats.StatsManager; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java index d97a76cc5..c33d49e19 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java @@ -7,7 +7,11 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; +import com.sun.org.apache.xpath.internal.operations.Bool; +import mineplex.core.bonuses.gui.SpinGui; import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; import mineplex.core.database.DBPool; import mineplex.core.database.RepositoryBase; import mineplex.core.database.ResultSetCallable; @@ -17,7 +21,9 @@ import mineplex.database.Tables; import mineplex.database.tables.records.BonusRecord; import org.jooq.DSLContext; import org.jooq.Record2; +import org.jooq.SQLDialect; import org.jooq.TableField; +import org.jooq.impl.DSL; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -95,6 +101,42 @@ public class BonusRepository extends RepositoryBase }); } + public void attemptAddTickets(final int accountId, final BonusClientData client, final int tickets, final Callback callback) + { + if (client.getTickets() + tickets < 0) + callback.run(false); + + Bukkit.getScheduler().runTaskAsynchronously(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + try + { + DSLContext create = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL); + create.update(Tables.bonus).set(Tables.bonus.tickets, Tables.bonus.tickets.add(tickets)). + where(Tables.bonus.accountId.eq(accountId)).execute(); + final int newTickets = create.select(Tables.bonus.tickets).from(Tables.bonus).where(Tables.bonus.accountId.eq(accountId)).fetchOne().value1(); + + Bukkit.getScheduler().runTask(_manager.getPlugin(), new Runnable() + { + @Override + public void run() + { + client.setTickets(newTickets); + callback.run(true); + } + }); + } + catch (Exception e) + { + e.printStackTrace(); + callback.run(false); + } + } + }); + } + public void attemptDailyBonus(final Player player, final Callback result) { final int accountId = _manager.getClientManager().Get(player).getAccountId(); @@ -207,7 +249,7 @@ public class BonusRepository extends RepositoryBase { try (Connection connection = getConnection(); - CallableStatement callableStatement = connection.prepareCall("{call check_rank(?, ?, ?, ?, ?)}")) { + CallableStatement callableStatement = connection.prepareCall("{call check_rank(?, ?, ?, ?, ?)}")) { callableStatement.setInt(1, accountId); callableStatement.setInt(2, coins); callableStatement.setInt(3, 0); @@ -262,7 +304,7 @@ public class BonusRepository extends RepositoryBase { try (Connection connection = getConnection(); - CallableStatement callableStatement = connection.prepareCall("{call check_vote(?, ?, ?, ?, ?)}")) { + CallableStatement callableStatement = connection.prepareCall("{call check_vote(?, ?, ?, ?, ?)}")) { callableStatement.setInt(1, accountId); callableStatement.setInt(2, coins); callableStatement.setInt(3, gems); @@ -281,7 +323,7 @@ public class BonusRepository extends RepositoryBase { _manager.Get(player).setVoteTime(date); result.run(true); - + } }); } catch (Exception e) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index 386eba7ad..056d5c901 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -32,17 +32,18 @@ public class RewardManager private JavaPlugin _plugin; private HashMap> _treasureMap; private Random _random; + private boolean _carlSpinner; private CoreClientManager _clientManager; private boolean _doubleGadgetValue; public RewardManager(CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, - int commonValueMin, int commonValueMax, - int uncommonValueMin, int uncommonValueMax, - int rareValueMin, int rareValueMax, - int legendValueMin, int legendValueMax, - boolean doubleGadgetValue) + int commonValueMin, int commonValueMax, + int uncommonValueMin, int uncommonValueMax, + int rareValueMin, int rareValueMax, + int legendValueMin, int legendValueMax, + boolean doubleGadgetValue, boolean carlSpinner) { _plugin = donationManager.getPlugin(); _treasureMap = new HashMap>(); @@ -56,21 +57,15 @@ public class RewardManager _clientManager = clientManager; _doubleGadgetValue = doubleGadgetValue; + _carlSpinner = carlSpinner; - addGame(donationManager, inventoryManager, petManager, statsManager); - addCommon(donationManager, inventoryManager, petManager, commonValueMin, commonValueMax); - addUncommon(donationManager, inventoryManager, petManager, uncommonValueMin, uncommonValueMax); - addRare(donationManager, inventoryManager, petManager, rareValueMin, rareValueMax); - addLegendary(donationManager, inventoryManager, petManager, legendValueMin, legendValueMax); + addCommon(donationManager, inventoryManager, petManager, statsManager, commonValueMin, commonValueMax); + addUncommon(donationManager, inventoryManager, petManager, statsManager, uncommonValueMin, uncommonValueMax); + addRare(donationManager, inventoryManager, petManager, statsManager, rareValueMin, rareValueMax); + addLegendary(donationManager, inventoryManager, petManager, statsManager, legendValueMin, legendValueMax); } - public void addGame(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager) - { - addReward(new GemReward(donationManager, 100, 500, 100, RewardRarity.GAME)); - addReward(new ExperienceReward(statsManager, 100, 5000, 100, RewardRarity.GAME)); - } - - public void addCommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addCommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.COMMON; @@ -112,9 +107,16 @@ public class RewardManager addReward(new InventoryReward(inventoryManager, "TNT", "TNT", (int)(20*(minValue/500)), (int)(20*(maxValue/500)), new ItemStack(Material.TNT), rarity, 10)); + + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 25, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 25, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 25, rarity)); + } } - public void addUncommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addUncommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.UNCOMMON; @@ -198,9 +200,16 @@ public class RewardManager // new ItemStack(2266), rarity, 25)); addReward(new UnknownPackageReward(donationManager, "Wait Disc", "Wait Disc", new ItemStack(2267), rarity, 25)); + + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 1300, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 1300, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 1300, rarity)); + } } - public void addRare(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addRare(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.RARE; @@ -250,14 +259,20 @@ public class RewardManager addReward(new UnknownPackageReward(donationManager, "Space Boots", "Space Boots", new ItemStack(Material.GOLD_BOOTS), rarity, 50)); + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 390, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 390, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 390, rarity)); + } } - public void addLegendary(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, double minValue, double maxValue) + public void addLegendary(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) { RewardRarity rarity = RewardRarity.LEGENDARY; // Coins - addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 25, RewardRarity.LEGENDARY)); + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 25, rarity)); // Mounts addReward(new UnknownPackageReward(donationManager, "Infernal Horror", "Infernal Horror", @@ -286,6 +301,13 @@ public class RewardManager new ItemStack(Material.APPLE), rarity, 4)); addReward(new UnknownPackageReward(donationManager, "Heart Particles", "I Heart You", new ItemStack(Material.BLAZE_POWDER), rarity, 2)); + + if (_carlSpinner) + { + addReward(new GemReward(donationManager, 0, 0, 70, rarity)); + addReward(new CoinReward(donationManager, 0, 0, 70, rarity)); + addReward(new ExperienceReward(statsManager, 0, 0, 70, rarity)); + } } public void addReward(Reward reward) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java index 5746bc978..fbd14ea54 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureManager.java @@ -20,6 +20,7 @@ import mineplex.core.pet.PetManager; import mineplex.core.reward.Reward; import mineplex.core.reward.RewardManager; import mineplex.core.reward.RewardType; +import mineplex.core.stats.StatsManager; /** * Created by Shaun on 8/27/2014. @@ -32,14 +33,19 @@ public class TreasureManager extends MiniPlugin private HologramManager _hologramManager; private List _treasureLocations; - public TreasureManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, BlockRestore blockRestore, HologramManager hologramManager, RewardManager rewardManager) + public TreasureManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, BlockRestore blockRestore, HologramManager hologramManager, StatsManager statsManager) { super("Treasure", plugin); _inventoryManager = inventoryManager; _blockRestore = blockRestore; _hologramManager = hologramManager; - _rewardManager = rewardManager; + _rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, statsManager, + 100, 250, + 500, 1000, + 4000, 6000, + 12000, 32000, + true, false); World world = Bukkit.getWorlds().get(0); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index f09e21e1f..8d58d26b1 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -190,14 +190,7 @@ public class HubManager extends MiniClientPlugin new BenefitManager(plugin, clientManager, _inventoryManager); _gadgetManager = new GadgetManager(_plugin, clientManager, donationManager, _inventoryManager, _mountManager, petManager, preferences, disguiseManager, blockRestore, new ProjectileManager(plugin), achievementManager); - RewardManager rewardManager = new RewardManager(clientManager, donationManager, _inventoryManager, petManager, statsManager, - 100, 250, - 500, 1000, - 4000, 6000, - 12000, 32000, - true); - - _treasureManager = new TreasureManager(_plugin, clientManager, donationManager, _inventoryManager, petManager, _blockRestore, hologramManager, rewardManager); + _treasureManager = new TreasureManager(_plugin, clientManager, donationManager, _inventoryManager, petManager, _blockRestore, hologramManager, statsManager); new CosmeticManager(_plugin, clientManager, donationManager, _inventoryManager, _gadgetManager, _mountManager, petManager, _treasureManager); new SoccerManager(this, _gadgetManager); @@ -222,7 +215,7 @@ public class HubManager extends MiniClientPlugin ((CraftWorld)Bukkit.getWorlds().get(0)).getHandle().pvpMode = true; - new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, rewardManager, statsManager); + new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, statsManager, _inventoryManager, petManager); // NotificationManager notificationManager = new NotificationManager(plugin, clientManager, donationManager); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java index 91e3ae9ec..e018a834d 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLootManager.java @@ -55,7 +55,7 @@ public class GameLootManager implements Listener 500, 1000, 1500, 2500, 6000, 12000, - false); + false, false); //Chest _rewardManager.addReward(new InventoryReward(Manager.getInventoryManager(), "Old Chest", "Old Chest", 1, 1, From 1c40478e6ee2f78f7716dc3ed1eae6a6f2e402b7 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 10:32:49 +0200 Subject: [PATCH 317/377] SPIN DOGGY SPIN --- .../mineplex/core/bonuses/gui/SpinGui.java | 6 +- .../mineplex/core/reward/RewardManager.java | 73 +++++++++++-------- 2 files changed, 44 insertions(+), 35 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 16c8fcba3..6739f1294 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -75,10 +75,6 @@ public class SpinGui extends SimpleGui { _fakeRewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); } - for (int i = 0; i < REWARDS_TO_GENERATE; i++) - { - _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); - } _ticksPerSwap = 1; @@ -104,7 +100,7 @@ public class SpinGui extends SimpleGui _stopSpinnerAt = _ticks.size(); - _fakeRewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3] = _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; + _fakeRewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); _reward = _fakeRewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; _rewardData = _reward.giveReward("Carls Spinner", getPlayer()); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index 056d5c901..8932c3658 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -70,7 +70,16 @@ public class RewardManager RewardRarity rarity = RewardRarity.COMMON; // Coins - addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 1, rarity)); + if (_carlSpinner) + { + addReward(new GemReward(donationManager, (int)minValue, (int)maxValue, 25, rarity)); + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 25, rarity)); + addReward(new ExperienceReward(statsManager, (int)minValue*5, (int)maxValue*5, 25, rarity)); + } + else + { + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 5, rarity)); + } //Increase Value if (_doubleGadgetValue) @@ -108,12 +117,7 @@ public class RewardManager (int)(20*(minValue/500)), (int)(20*(maxValue/500)), new ItemStack(Material.TNT), rarity, 10)); - if (_carlSpinner) - { - addReward(new GemReward(donationManager, 0, 0, 25, rarity)); - addReward(new CoinReward(donationManager, 0, 0, 25, rarity)); - addReward(new ExperienceReward(statsManager, 0, 0, 25, rarity)); - } + } public void addUncommon(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) @@ -121,7 +125,16 @@ public class RewardManager RewardRarity rarity = RewardRarity.UNCOMMON; // Coins - addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 250, RewardRarity.UNCOMMON)); + if (_carlSpinner) + { + addReward(new GemReward(donationManager, (int)minValue, (int)maxValue, 1200, rarity)); + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 1200, rarity)); + addReward(new ExperienceReward(statsManager, (int)minValue*5, (int)maxValue*5, 1200, rarity)); + } + else + { + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 250, RewardRarity.UNCOMMON)); + } //Increase Value if (_doubleGadgetValue) @@ -200,13 +213,6 @@ public class RewardManager // new ItemStack(2266), rarity, 25)); addReward(new UnknownPackageReward(donationManager, "Wait Disc", "Wait Disc", new ItemStack(2267), rarity, 25)); - - if (_carlSpinner) - { - addReward(new GemReward(donationManager, 0, 0, 1300, rarity)); - addReward(new CoinReward(donationManager, 0, 0, 1300, rarity)); - addReward(new ExperienceReward(statsManager, 0, 0, 1300, rarity)); - } } public void addRare(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) @@ -214,7 +220,17 @@ public class RewardManager RewardRarity rarity = RewardRarity.RARE; // Coins - addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 100, RewardRarity.RARE)); + if (_carlSpinner) + { + addReward(new GemReward(donationManager, (int)minValue, (int)maxValue, 150, rarity)); + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 150, rarity)); + addReward(new ExperienceReward(statsManager, (int)minValue*5, (int)maxValue*5, 150, rarity)); + } + else + { + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 100, RewardRarity.RARE)); + } + // Mounts addReward(new UnknownPackageReward(donationManager, "Mount Mule", "Mount Mule", @@ -258,13 +274,6 @@ public class RewardManager new ItemStack(Material.GOLD_LEGGINGS), rarity, 50)); addReward(new UnknownPackageReward(donationManager, "Space Boots", "Space Boots", new ItemStack(Material.GOLD_BOOTS), rarity, 50)); - - if (_carlSpinner) - { - addReward(new GemReward(donationManager, 0, 0, 390, rarity)); - addReward(new CoinReward(donationManager, 0, 0, 390, rarity)); - addReward(new ExperienceReward(statsManager, 0, 0, 390, rarity)); - } } public void addLegendary(DonationManager donationManager, InventoryManager inventoryManager, PetManager petManager, StatsManager statsManager, double minValue, double maxValue) @@ -272,7 +281,16 @@ public class RewardManager RewardRarity rarity = RewardRarity.LEGENDARY; // Coins - addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 25, rarity)); + if (_carlSpinner) + { + addReward(new GemReward(donationManager, (int)minValue, (int)maxValue, 10, rarity)); + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 10, rarity)); + addReward(new ExperienceReward(statsManager, (int)minValue*5, (int)maxValue*5, 10, rarity)); + } + else + { + addReward(new CoinReward(donationManager, (int)minValue, (int)maxValue, 25, rarity)); + } // Mounts addReward(new UnknownPackageReward(donationManager, "Infernal Horror", "Infernal Horror", @@ -302,12 +320,7 @@ public class RewardManager addReward(new UnknownPackageReward(donationManager, "Heart Particles", "I Heart You", new ItemStack(Material.BLAZE_POWDER), rarity, 2)); - if (_carlSpinner) - { - addReward(new GemReward(donationManager, 0, 0, 70, rarity)); - addReward(new CoinReward(donationManager, 0, 0, 70, rarity)); - addReward(new ExperienceReward(statsManager, 0, 0, 70, rarity)); - } + } public void addReward(Reward reward) From a1c10a7ec5ac39616723966b5c5b302152931dc6 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 10:33:44 +0200 Subject: [PATCH 318/377] clean up --- .../src/mineplex/core/bonuses/gui/SpinGui.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 6739f1294..fe989337a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -46,7 +46,6 @@ public class SpinGui extends SimpleGui private int _ticksPerSwap; private int _swapCount; private Reward[] _rewards; - private Reward[] _fakeRewards; private boolean _stopped; private boolean _rewarded; private ArrayList _ticks; @@ -66,14 +65,13 @@ public class SpinGui extends SimpleGui //setItem(CARL_SLOT, new DisplayItem(carlItem)); _rewards = new Reward[REWARDS_TO_GENERATE]; - _fakeRewards = new Reward[REWARDS_TO_GENERATE]; _ticks = new ArrayList<>(); _frame = 0; _pitch = 1; for (int i = 0; i < REWARDS_TO_GENERATE; i++) { - _fakeRewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); + _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); } _ticksPerSwap = 1; @@ -100,8 +98,8 @@ public class SpinGui extends SimpleGui _stopSpinnerAt = _ticks.size(); - _fakeRewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); - _reward = _fakeRewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; + _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); + _reward = _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; _rewardData = _reward.giveReward("Carls Spinner", getPlayer()); } @@ -150,7 +148,7 @@ public class SpinGui extends SimpleGui index = index % REWARDS_TO_GENERATE; int slot = 9 + i; - RewardData data = _fakeRewards[index].getFakeRewardData(getPlayer()); + RewardData data = _rewards[index].getFakeRewardData(getPlayer()); setItem(slot, new RewardButton(data)); // Glass Panes From f66a0439e8b5601a7b12b3bcaac66b1a642ff5d2 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 10:34:33 +0200 Subject: [PATCH 319/377] no need to gen so many --- .../Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index fe989337a..bea18f676 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -32,7 +32,7 @@ import org.bukkit.plugin.Plugin; public class SpinGui extends SimpleGui { - private static final int REWARDS_TO_GENERATE = 1000; + private static final int REWARDS_TO_GENERATE = 200; private static final int HOPPER_SLOT = 4; private static final int CARL_SLOT = 22; private static final int[] LINE_NUMS = { /*-27, -18,*/ -9, 9/*, 18*/ }; From 184feec875a7b7b5b05df01d069d5f51947f2e15 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 10:54:24 +0200 Subject: [PATCH 320/377] cleany and logic --- .../mineplex/core/bonuses/gui/SpinGui.java | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index bea18f676..1daab79ea 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -32,7 +32,6 @@ import org.bukkit.plugin.Plugin; public class SpinGui extends SimpleGui { - private static final int REWARDS_TO_GENERATE = 200; private static final int HOPPER_SLOT = 4; private static final int CARL_SLOT = 22; private static final int[] LINE_NUMS = { /*-27, -18,*/ -9, 9/*, 18*/ }; @@ -64,15 +63,12 @@ public class SpinGui extends SimpleGui setItem(HOPPER_SLOT, new DisplayItem(new ItemStack(Material.HOPPER))); //setItem(CARL_SLOT, new DisplayItem(carlItem)); - _rewards = new Reward[REWARDS_TO_GENERATE]; + _ticks = new ArrayList<>(); _frame = 0; _pitch = 1; - for (int i = 0; i < REWARDS_TO_GENERATE; i++) - { - _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); - } + _ticksPerSwap = 1; @@ -98,8 +94,19 @@ public class SpinGui extends SimpleGui _stopSpinnerAt = _ticks.size(); - _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); - _reward = _rewards[_stopSpinnerAt % REWARDS_TO_GENERATE + 3]; + //Create Fake Rewards + _rewards = new Reward[_stopSpinnerAt+5]; + for (int i = 0; i < _stopSpinnerAt+5 ; i++) + { + if (i != _stopSpinnerAt) + _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); + else + { + _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); + _reward = _rewards[i]; + } + } + _rewardData = _reward.giveReward("Carls Spinner", getPlayer()); } From 74b83d6851b59a94d3bcfdbc31ae30791f69cc5f Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 10:56:07 +0200 Subject: [PATCH 321/377] fixed! --- .../src/mineplex/core/bonuses/gui/SpinGui.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 1daab79ea..89f69a782 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -94,9 +94,9 @@ public class SpinGui extends SimpleGui _stopSpinnerAt = _ticks.size(); - //Create Fake Rewards - _rewards = new Reward[_stopSpinnerAt+5]; - for (int i = 0; i < _stopSpinnerAt+5 ; i++) + //Create Rewards + _rewards = new Reward[_stopSpinnerAt+10]; //Adding 10, so theres items to the right still. + for (int i = 0; i < _stopSpinnerAt+10 ; i++) { if (i != _stopSpinnerAt) _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); @@ -152,7 +152,6 @@ public class SpinGui extends SimpleGui for (int i = 0; i < 9; i++) { int index = _currentRewardIndex + i; - index = index % REWARDS_TO_GENERATE; int slot = 9 + i; RewardData data = _rewards[index].getFakeRewardData(getPlayer()); From 4c32f32ced5e6997a7735c33aae99c3eb0409dfa Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 11:17:20 +0200 Subject: [PATCH 322/377] removed game reward type --- .../src/mineplex/core/reward/RewardType.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java index 90b201c08..b226448c2 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardType.java @@ -3,28 +3,26 @@ package mineplex.core.reward; public enum RewardType { //% Chances Mythic Legend Rare Uncommon - GameLoot( 0.000001, 0.00001, 0.0001, 3, 10), + GameLoot( 0.000001, 0.00001, 0.0001, 3), - OldChest( 0, 0.05, 0.4, 5, 0), - AncientChest( 0, 1, 4, 25, 0), - MythicalChest( 0.4, 3, 12, 75, 0), + OldChest( 0, 0.05, 0.4, 5), + AncientChest( 0, 1, 4, 25), + MythicalChest( 0.4, 3, 12, 75), - SpinnerFiller( 0.1, 1, 4, 20, 30), - SpinnerReal( 0.000001, 0.05, 0.4, 5, 10); + SpinnerFiller( 0.1, 1, 4, 20), + SpinnerReal( 0.000001, 0.05, 0.4, 5); private double _mythicalChance; private double _legendaryChance; private double _rareChance; private double _uncommonChance; - private double _gameChance; - RewardType(double mythical, double legend, double rare, double uncommon, double game) + RewardType(double mythical, double legend, double rare, double uncommon) { _mythicalChance = (mythical / 100d); _legendaryChance = _mythicalChance + (legend / 100d); //Add previous chance to prep for generateRarity random values. _rareChance = _legendaryChance + (rare / 100d); _uncommonChance = _rareChance + (uncommon / 100d); - _gameChance = _uncommonChance + (game / 100d); } public RewardRarity generateRarity(boolean requiresUncommon) @@ -37,7 +35,6 @@ public enum RewardType else if (rand <= _legendaryChance) rarity = RewardRarity.LEGENDARY; else if (rand <= _rareChance) rarity = RewardRarity.RARE; else if (rand <= _uncommonChance || requiresUncommon) rarity = RewardRarity.UNCOMMON; - else if (rand <= _gameChance) rarity = RewardRarity.GAME; return rarity; } From 8abefaf856f333b0a985ad8b986a63e460ca0d19 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 11:31:51 +0200 Subject: [PATCH 323/377] The magical +3. --- .../Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 89f69a782..0dfee278a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -98,8 +98,10 @@ public class SpinGui extends SimpleGui _rewards = new Reward[_stopSpinnerAt+10]; //Adding 10, so theres items to the right still. for (int i = 0; i < _stopSpinnerAt+10 ; i++) { - if (i != _stopSpinnerAt) + if (i != _stopSpinnerAt + 3) + { _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); + } else { _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerReal, true); From 3eb7e91fbb9be7c5f2d64785a5895c9aacef4fb1 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 04:38:37 -0500 Subject: [PATCH 324/377] Removing the magical 3 --- Plugins/.idea/misc.xml | 2 +- .../Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Plugins/.idea/misc.xml b/Plugins/.idea/misc.xml index 3a9b4c67e..aeea575e6 100644 --- a/Plugins/.idea/misc.xml +++ b/Plugins/.idea/misc.xml @@ -16,7 +16,7 @@ - + \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 0dfee278a..18310ab5a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -98,7 +98,7 @@ public class SpinGui extends SimpleGui _rewards = new Reward[_stopSpinnerAt+10]; //Adding 10, so theres items to the right still. for (int i = 0; i < _stopSpinnerAt+10 ; i++) { - if (i != _stopSpinnerAt + 3) + if (i != _stopSpinnerAt + 4) { _rewards[i] = rewardManager.nextReward(player, null, false, RewardType.SpinnerFiller, true); } @@ -126,7 +126,6 @@ public class SpinGui extends SimpleGui _ticksThisSwap = 0; _swapCount++; - updateGui(); if(_pitch == 1) _pitch = (float) 1.5; else if(_pitch == 1.5) @@ -138,6 +137,8 @@ public class SpinGui extends SimpleGui _currentRewardIndex++; + updateGui(); + // Slow _ticksPerSwap = _ticks.get(_currentRewardIndex - 1); From 1c484367a136547616b5d21859eb7b88efa823fb Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 04:57:45 -0500 Subject: [PATCH 325/377] Add hasPoll --- .../src/mineplex/core/bonuses/BonusManager.java | 2 +- .../Mineplex.Core/src/mineplex/core/poll/PollManager.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index ecdd769fd..e262083a0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -1022,7 +1022,7 @@ public class BonusManager extends MiniClientPlugin implements I { if (Recharge.Instance.use(player, "Carl Inform", 240000, false, false)) { - if(_pollManager.Get(player).shouldPoll() || canVote(player) || canRank(player) || canDaily(player)) + if(_pollManager.hasPoll(player) || canVote(player) || canRank(player) || canDaily(player)) { if(_showCarl.containsKey(player.getName())) UtilPlayer.message(player, C.cDGreen + C.Bold + "Carl the Creeper)" + C.cGreen + " Hey " + player.getName().replace("s", "sss") + "! I have sssome amazing rewardsss for you! Come sssee me!"); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java index 5fa00cf3d..fa0b5daa0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java @@ -99,6 +99,11 @@ public class PollManager extends MiniDbClientPlugin return null; } + public boolean hasPoll(Player player) + { + return getNextPoll(Get(player), getClientManager().Get(player).GetRank()) != null; + } + public void displayPoll(Player player, Poll poll) { String[] answers = poll.getAnswers(); From c82152324032c812eb06e64a3f0b3c6061081ac6 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 12:04:54 +0200 Subject: [PATCH 326/377] removed vote broadcast. --- .../src/mineplex/core/bonuses/BonusManager.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index ecdd769fd..380a909e7 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -289,15 +289,7 @@ public class BonusManager extends MiniClientPlugin implements I if (!_enabled) return; - - if(_pendingExplosions.get(0) instanceof String - && !((String)_pendingExplosions.get(0)).contentEquals("RANK") - && !((String)_pendingExplosions.get(0)).contentEquals("DAILY") - && !((String)_pendingExplosions.get(0)).contentEquals("VOTE")) - { - String name = (String)_pendingExplosions.get(0); - Bukkit.broadcastMessage("Recieved Vote: " + name); - } + _explode = System.currentTimeMillis(); _animation.setTicks(0); _canVote = false; From 2d7d7f6ddecd123578116d7e2bb34897260578e9 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 13:01:20 +0200 Subject: [PATCH 327/377] Improving messages, animations and some Items. --- .../src/mineplex/core/bonuses/BonusManager.java | 15 ++++++++++++--- .../core/bonuses/animations/AnimationCarl.java | 6 +++--- .../core/bonuses/commands/GuiCommand.java | 2 +- .../bonuses/gui/buttons/DailyBonusButton.java | 1 + .../core/bonuses/gui/buttons/RankBonusButton.java | 3 ++- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 8fd3d6d54..a719ba172 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -59,6 +59,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.java.JavaPlugin; @@ -267,7 +268,8 @@ public class BonusManager extends MiniClientPlugin implements I public void run() { addPendingExplosion(player, player.getName()); - UtilPlayer.message(player, F.main("Vote", "Thanks for your vote!")); + UtilPlayer.message(player, F.main("Carl", "Thanks for voting for Mineplex!")); + UtilPlayer.message(player, F.main("Carl", "You received 500 Gems and 1 Carls Spinner Ticket!")); } }); } @@ -362,7 +364,6 @@ public class BonusManager extends MiniClientPlugin implements I return; ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(16, -1); - ((CraftEntity)_carlNpc.getEntity()).getHandle().getDataWatcher().watch(17, 1); } public void IncreaseSize(Entity player) @@ -758,6 +759,8 @@ public class BonusManager extends MiniClientPlugin implements I _statsManager.incrementStat(player, "Global.ExpEarned", experience); UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(experience + " Experience"))); } + + UtilPlayer.message(player, F.main("Carl", "Come back tomorrow for more!")); } @@ -1004,6 +1007,12 @@ public class BonusManager extends MiniClientPlugin implements I }, 200); } + @EventHandler + public void Quit(PlayerQuitEvent event) + { + _showCarl.remove(event.getPlayer().getName()); + } + @EventHandler public void carlUpdate(UpdateEvent event) { @@ -1017,7 +1026,7 @@ public class BonusManager extends MiniClientPlugin implements I if(_pollManager.hasPoll(player) || canVote(player) || canRank(player) || canDaily(player)) { if(_showCarl.containsKey(player.getName())) - UtilPlayer.message(player, C.cDGreen + C.Bold + "Carl the Creeper)" + C.cGreen + " Hey " + player.getName().replace("s", "sss") + "! I have sssome amazing rewardsss for you! Come sssee me!"); + UtilPlayer.message(player, C.cDGreen + C.Bold + "Carl the Creeper>" + C.cGreen + " Hey " + player.getName().replace("s", "sss") + "! I have sssome amazing rewardsss for you! Come sssee me!"); } } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index a98977521..0fc8fd838 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -48,7 +48,7 @@ public class AnimationCarl extends Animation { if(((String) _type).contentEquals("DAILY")) { - for (int i = 1; i < 40; i++) + for (int i = 1; i < 8; i++) { Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, " " + i)); @@ -61,7 +61,7 @@ public class AnimationCarl extends Animation } if(((String) _type).contentEquals("RANK")) { - for (int i = 1; i < 50; i++) + for (int i = 1; i < 8; i++) { Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, " " + i)); Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); @@ -71,7 +71,7 @@ public class AnimationCarl extends Animation } if(!((String) _type).contentEquals("DAILY")&& !((String) _type).contentEquals("RANK")) { - for (int i = 1; i < 40; i++) + for (int i = 1; i < 8; i++) { Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); Item paper = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, " " + i)); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java index c3ef35edd..ccc55a251 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/GuiCommand.java @@ -11,7 +11,7 @@ public class GuiCommand extends CommandBase{ public GuiCommand(BonusManager plugin) { - super(plugin, Rank.ALL, "bonus"); + super(plugin, Rank.DEVELOPER, "bonus"); } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java index 8efb10fa5..76d58c807 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java @@ -96,6 +96,7 @@ public class DailyBonusButton implements GuiItem, Listener } getPlayer().playSound(getPlayer().getLocation(), Sound.ENDERDRAGON_GROWL, 1, 10); } + getPlayer().closeInventory(); } }); } else diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java index 501840411..fe3e20322 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java @@ -114,6 +114,7 @@ public class RankBonusButton implements GuiItem, Listener { } getPlayer().playSound(getPlayer().getLocation(), Sound.ENDERDRAGON_GROWL, 1, 10); } + getPlayer().closeInventory(); } }); } else @@ -177,7 +178,7 @@ public class RankBonusButton implements GuiItem, Listener { } lore.add(" "); - + lore.add(C.cYellow + "Rank:" + C.cWhite + _bonusManager.getClientManager().Get(_player).GetRank().Name); BonusAmount bonusAmount = _bonusManager.getRankBonusAmount(_player); bonusAmount.addLore(lore); } From 49d54d4dd395bdd4fb231ae91d89357bab264a5f Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 13:22:58 +0200 Subject: [PATCH 328/377] doesnt count rank thingy as reward if no rank. yknow --- .../Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index a719ba172..3985cc1d3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -835,7 +835,7 @@ public class BonusManager extends MiniClientPlugin implements I int availableRewards = 0; if (canVote(player)) availableRewards++; - if (canRank(player)) availableRewards++; + if (canRank(player) && _clientManager.hasRank(player, Rank.ULTRA)) availableRewards++; if (canDaily(player)) availableRewards++; if (getPollManager().getNextPoll(_pollManager.Get(player), _clientManager.Get(player).GetRank()) != null) availableRewards++; From cfcfbbed3bc9d5fc979b5739df94f581e30c81a6 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 13:34:32 +0200 Subject: [PATCH 329/377] removed double gem --- .../src/nautilus/game/arcade/managers/GameGemManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameGemManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameGemManager.java index 07bb93f7a..53f8173c3 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameGemManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameGemManager.java @@ -36,7 +36,7 @@ public class GameGemManager implements Listener { ArcadeManager Manager; - boolean DoubleGem = true; + boolean DoubleGem = false; public GameGemManager(ArcadeManager manager) { From e25558fc91f88b77c7359a2d9002c980538573c3 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 13:49:06 +0200 Subject: [PATCH 330/377] Animation improvements. --- .../mineplex/core/bonuses/BonusManager.java | 4 +++ .../bonuses/animations/AnimationCarl.java | 31 ++++++++++--------- .../core/bonuses/gui/buttons/PollButton.java | 2 +- .../bonuses/gui/buttons/RankBonusButton.java | 2 +- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index a719ba172..af93fc985 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -50,6 +50,7 @@ import mineplex.serverdata.commands.ServerCommandManager; import org.jooq.SQLDialect; import org.jooq.impl.DSL; import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.block.Dropper; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; @@ -984,6 +985,9 @@ public class BonusManager extends MiniClientPlugin implements I if(!(entity instanceof Item)) continue; + if(((Item)entity).getItemStack().getType() == Material.MONSTER_EGG) + entity.remove(); + if(!((Item) entity).getItemStack().hasItemMeta()) continue; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index 0fc8fd838..160b2e14c 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -4,6 +4,7 @@ import java.util.Random; import mineplex.core.common.util.UtilAction; import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilParticle.ViewDist; @@ -46,39 +47,41 @@ public class AnimationCarl extends Animation { if(_type instanceof String) { - if(((String) _type).contentEquals("DAILY")) + if(((String) _type).contentEquals("DAILY") || ((String) _type).contentEquals("POLL")) { - for (int i = 1; i < 8; i++) + for (int i = 50; i < 60; i++) { Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, " " + i)); Vector vel = new Vector(Math.sin(i * 9/5d), 0, Math.cos(i * 9/5d)); - UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 9/3000d))*0.6, 1, false); - UtilAction.velocity(coin, vel, Math.abs(Math.sin(i * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 9/3000d))*0.6, 1, false); + UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 12/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 12/3000d))*0.6, 1, false); + UtilAction.velocity(coin, vel, Math.abs(Math.sin(UtilMath.r(i) * 30/3000d)), false, 0, 0.2 + Math.abs(Math.cos(UtilMath.r(i) * 30/3000d))*0.6, 1, false); coin.setTicksLived(1160); gem.setTicksLived(1160); } } if(((String) _type).contentEquals("RANK")) { - for (int i = 1; i < 8; i++) + for (int i = 50; i < 60; i++) { Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, " " + i)); - Vector vel = new Vector(Math.sin(i * 7/5d), 0, Math.cos(i * 7/5d)); - UtilAction.velocity(coin, vel, Math.abs(Math.sin(i * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 7/3000d))*0.6, 1, false); + Vector vel = new Vector(Math.sin(UtilMath.r(i) * 7/5d), 0, Math.cos(UtilMath.r(i) * 7/5d)); + UtilAction.velocity(coin, vel, Math.abs(Math.sin(UtilMath.r(i) * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(UtilMath.r(i) * 7/3000d))*0.6, 1, false); coin.setTicksLived(1160); } } - if(!((String) _type).contentEquals("DAILY")&& !((String) _type).contentEquals("RANK")) + if(!((String) _type).contentEquals("DAILY")&& !((String) _type).contentEquals("RANK")&& !((String) _type).contentEquals("POLL")) { - for (int i = 1; i < 8; i++) + + Item paper = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, " " + 64)); + Vector vel = new Vector(Math.sin(64 * 8/5d), 0, Math.cos(64 * 8/5d)); + UtilAction.velocity(paper, vel, Math.abs(Math.sin(64 * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(64 + 9/3000d))*0.6, 1, false); + paper.setTicksLived(1160); + for (int i = 50; i < 60; i++) { Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); - Item paper = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, " " + i)); - Vector vel = new Vector(Math.sin(i * 8/5d), 0, Math.cos(i * 8/5d)); - UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 8/3000d))*0.6, 1, false); - UtilAction.velocity(paper, vel, Math.abs(Math.sin(i * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 9/3000d))*0.6, 1, false); - paper.setTicksLived(1160); + Vector velo = new Vector(Math.sin(i * 8/5d), 0, Math.cos(i * 8/5d)); + UtilAction.velocity(gem, velo, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 8/3000d))*0.6, 1, false); gem.setTicksLived(1160); } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java index 417a6b556..8124e6292 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java @@ -194,7 +194,7 @@ public class PollButton extends SimpleGui implements GuiItem { getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); new TimedMessageWindow(getPlugin(), getPlayer(), ItemStackFactory.Instance.CreateStack(Material.EMERALD_BLOCK, (byte) 0, 1, ChatColor.GREEN + "Your anwser:", wrap(getPoll().getAnswers()[num])), ChatColor.GREEN + "Moo", 6 * 9, 50, getMaster()).openInventory(); - _bonusManager.addPendingExplosion(getPlayer(), "VOTE"); + _bonusManager.addPendingExplosion(getPlayer(), "POLL"); getPlayer().closeInventory(); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java index fe3e20322..489b257fd 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java @@ -178,7 +178,7 @@ public class RankBonusButton implements GuiItem, Listener { } lore.add(" "); - lore.add(C.cYellow + "Rank:" + C.cWhite + _bonusManager.getClientManager().Get(_player).GetRank().Name); + lore.add(C.cYellow + "Rank: " + C.cWhite + _bonusManager.getClientManager().Get(_player).GetRank().Name); BonusAmount bonusAmount = _bonusManager.getRankBonusAmount(_player); bonusAmount.addLore(lore); } From f7d94761911c46fb371b7da592f3e2765cda20f2 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Aug 2015 13:53:36 +0200 Subject: [PATCH 331/377] Hidden egg fix --- .../Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 176057ab7..fe37f5a42 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -985,7 +985,7 @@ public class BonusManager extends MiniClientPlugin implements I if(!(entity instanceof Item)) continue; - if(((Item)entity).getItemStack().getType() == Material.MONSTER_EGG) + if(((Item)entity).getItemStack().getType() == Material.MONSTER_EGG && ((Item)entity).getItemStack().hasItemMeta() && !((Item)entity).getItemStack().getItemMeta().getDisplayName().startsWith("Hidden")) entity.remove(); if(!((Item) entity).getItemStack().hasItemMeta()) From 89dab7ec8531ca4885e9f6725e0e8076abf2c60c Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 16:33:32 +0200 Subject: [PATCH 332/377] some little fixes --- .../mineplex/core/gadget/GadgetManager.java | 2 +- .../core/gadget/gadgets/ItemPaintballGun.java | 39 ------------------- .../gui/privateServer/page/MenuPage.java | 4 +- .../game/arcade/managers/GameChatManager.java | 4 +- .../game/arcade/managers/GameHostManager.java | 8 +++- 5 files changed, 11 insertions(+), 46 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java index 3c518f35a..54a3ea799 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/GadgetManager.java @@ -92,7 +92,7 @@ public class GadgetManager extends MiniPlugin addGadget(new ItemTNT(this)); addGadget(new ItemMelonLauncher(this)); addGadget(new ItemFleshHook(this)); - //addGadget(new ItemPaintballGun(this)); + addGadget(new ItemPaintballGun(this)); addGadget(new ItemBatGun(this)); addGadget(new ItemCoinBomb(this)); addGadget(new ItemPaintbrush(this)); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintballGun.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintballGun.java index 34d4ed557..e1b1b6c39 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintballGun.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintballGun.java @@ -61,45 +61,6 @@ public class ItemPaintballGun extends ItemGadget Location loc = event.getEntity().getLocation().add(event.getEntity().getVelocity()); loc.getWorld().playEffect(loc, Effect.STEP_SOUND, 49); - - byte color = 2; - double r = Math.random(); - if (r > 0.8) color = 4; - else if (r > 0.6) color = 5; - else if (r > 0.4) color = 9; - else if (r > 0.2) color = 14; - - for (Block block : UtilBlock.getInRadius(loc, 3d).keySet()) - { - if (block.getType() == Material.PORTAL) - return; - - if (block.getType() == Material.CACTUS) - return; - - if (block.getType() == Material.SUGAR_CANE_BLOCK) - return; - } - - List blocks = new ArrayList(); - blocks.addAll(UtilBlock.getInRadius(loc, 1.5d).keySet()); - - GadgetBlockEvent gadgetEvent = new GadgetBlockEvent(this, blocks); - Bukkit.getServer().getPluginManager().callEvent(gadgetEvent); - - if (gadgetEvent.isCancelled()) - return; - - for (Block block : gadgetEvent.getBlocks()) - { - if (!UtilBlock.solid(block)) - continue; - - if (block.getType() == Material.CARPET) - Manager.getBlockRestore().Add(block, 171, color, 4000); - else - Manager.getBlockRestore().Add(block, 35, color, 4000); - } } @EventHandler diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/MenuPage.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/MenuPage.java index c24a31d78..26adc68ba 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/MenuPage.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gui/privateServer/page/MenuPage.java @@ -89,10 +89,10 @@ public class MenuPage extends BasePage if (host) { GiveAdminButton giveAdminButton = new GiveAdminButton(getPlugin(), getShop()); - addButton(4 + 9, new ShopItem(Material.DIAMOND_SWORD, "Give Admin", new String[]{}, 1, false), giveAdminButton); + addButton(4 + 9, new ShopItem(Material.DIAMOND_SWORD, "Give Co-Host", new String[]{}, 1, false), giveAdminButton); RemoveAdminButton removeAdminButton = new RemoveAdminButton(getPlugin(), getShop()); - addButton(4 + 18, new ShopItem(Material.GOLD_SWORD, "Remove Admin", new String[]{}, 1, false), removeAdminButton); + addButton(4 + 18, new ShopItem(Material.GOLD_SWORD, "Remove Co-Host", new String[]{}, 1, false), removeAdminButton); KillButton killButton = new KillButton(getPlugin()); addButton(8 + 18, new ShopItem(Material.TNT, "Kill Private Server", diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameChatManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameChatManager.java index 4aed91a8a..5f949845c 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameChatManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameChatManager.java @@ -90,9 +90,9 @@ public class GameChatManager implements Listener else if (Manager.GetGameHostManager().isAdmin(event.getPlayer(), false)) { if (Manager.GetGameHostManager().isEventServer()) - rankStr = C.cDGreen + C.Bold + "Event Admin "; + rankStr = C.cDGreen + C.Bold + "Event Co-Host "; else - rankStr = C.cDGreen + C.Bold + "MPS Admin "; + rankStr = C.cDGreen + C.Bold + "MPS Co-Host "; } else { diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java index 2dfc1c151..20a10ed71 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java @@ -230,6 +230,10 @@ public class GameHostManager implements Listener _hostRank = Manager.GetClients().Get(_host).GetRank(); System.out.println("Game Host Joined."); + //Limit player count! + if (Manager.GetServerConfig().MaxPlayers > getMaxPlayerCap()) + Manager.GetServerConfig().MaxPlayers = getMaxPlayerCap(); + if (isEventServer()) worldeditPermissionSet(event.getPlayer(), true); } @@ -642,7 +646,7 @@ public class GameHostManager implements Listener { _adminList.add(player.getName()); _onlineAdmins.add(player); - UtilPlayer.message(player, F.main("Server", "You were given admin privileges.")); + UtilPlayer.message(player, F.main("Server", "You were given Co-Host privileges.")); if (isEventServer()) worldeditPermissionSet(player, true); @@ -660,7 +664,7 @@ public class GameHostManager implements Listener { player.closeInventory(); } - UtilPlayer.message(player, F.main("Server", "Your admin privileges were removed.")); + UtilPlayer.message(player, F.main("Server", "Your Co-Host privileges were removed.")); player.setGameMode(GameMode.SURVIVAL); From 83a010c2151bd0dcec7179ca69b957195abbdd81 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 17:05:41 +0200 Subject: [PATCH 333/377] enabled summer sale msg --- .../mineplex/core/notifier/NotificationManager.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/notifier/NotificationManager.java b/Plugins/Mineplex.Core/src/mineplex/core/notifier/NotificationManager.java index 342d7b840..a2214adb2 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/notifier/NotificationManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/notifier/NotificationManager.java @@ -42,8 +42,8 @@ public class NotificationManager extends MiniPlugin if (!_enabled) return; -// if (event.getType() == UpdateType.MIN_08) -// hugeSale(); + if (event.getType() == UpdateType.MIN_08) + hugeSale(); // if (event.getType() == UpdateType.MIN_16) // sale(); @@ -95,17 +95,17 @@ public class NotificationManager extends MiniPlugin if (rank == Rank.ALL) { UtilPlayer.message(player, C.cWhite + " " + player.getName() + ", you can get 75% Off " + C.cAqua + C.Bold + "All Lifetime Ranks" + C.cWhite + "!"); - UtilPlayer.message(player, C.cWhite + " This is our biggest sale ever, available " + C.cRed + C.Line + "this weekend only" + C.cWhite + "!"); + UtilPlayer.message(player, C.cWhite + " This is our biggest sale ever, " + C.cRed + C.Line + "ends Sunday 16th" + C.cWhite + "!"); } else if (rank == Rank.ULTRA) { UtilPlayer.message(player, C.cWhite + " Hello " + player.getName() + ", upgrade to " + C.cPurple + C.Bold + "HERO RANK" + C.cWhite + " for only $7.50!"); - UtilPlayer.message(player, C.cWhite + " This is our biggest sale ever, available " + C.cRed + C.Line + "this weekend only" + C.cWhite + "!"); + UtilPlayer.message(player, C.cWhite + " This is our biggest sale ever, " + C.cRed + C.Line + "ends Sunday 16th" + C.cWhite + "!"); } else if (rank == Rank.HERO) { UtilPlayer.message(player, C.cWhite + " Hello " + player.getName() + ", upgrade to " + C.cGreen + C.Bold + "LEGEND RANK" + C.cWhite + " for only $7.50!"); - UtilPlayer.message(player, C.cWhite + " This is our biggest sale ever, available " + C.cRed + C.Line + "this weekend only" + C.cWhite + "!"); + UtilPlayer.message(player, C.cWhite + " This is our biggest sale ever, " + C.cRed + C.Line + "ends Sunday 16th" + C.cWhite + "!"); } UtilPlayer.message(player, " "); From ddc663cc7577b80ef54a2ebc59b708c6840eca6b Mon Sep 17 00:00:00 2001 From: fooify Date: Tue, 11 Aug 2015 09:52:04 -0700 Subject: [PATCH 334/377] remove duplicate method --- .../game/arcade/game/games/turfforts/TurfForts.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/turfforts/TurfForts.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/turfforts/TurfForts.java index 4cead9888..3e4b5c774 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/turfforts/TurfForts.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/turfforts/TurfForts.java @@ -291,15 +291,6 @@ public class TurfForts extends TeamGame if(getArcadeManager().isSpectator(event.getPlayer())) event.setCancelled(true); } - @EventHandler - public void BlockBreak(BlockBreakEvent event) - { - if (event.isCancelled()) // this statement might save just a small amount of time - return; - - if(getArcadeManager().isSpectator(event.getPlayer())) event.setCancelled(true); - } - @EventHandler public void BlockPlace(BlockPlaceEvent event) { From 07bdbdde46e2a9e7b49f4e8606c9068a0534c18d Mon Sep 17 00:00:00 2001 From: fooify Date: Tue, 11 Aug 2015 09:55:10 -0700 Subject: [PATCH 335/377] minor grammar issue --- .../Mineplex.Hub/src/mineplex/hub/server/ui/ServerNpcPage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerNpcPage.java b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerNpcPage.java index bdd807710..64993b32e 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerNpcPage.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ui/ServerNpcPage.java @@ -74,7 +74,7 @@ public class ServerNpcPage extends ShopPageBase im if (_onMainPage) { - addButton(4, ItemStackFactory.Instance.CreateStack(Material.DIAMOND_BLOCK, (byte) 0, 1, C.cGreen + "Click to Join instantly!"), new IButton() { + addButton(4, ItemStackFactory.Instance.CreateStack(Material.DIAMOND_BLOCK, (byte) 0, 1, C.cGreen + "Click to join instantly!"), new IButton() { @Override public void onClick(Player player, ClickType clickType) { From 72adf21bff6a7987d9c577130951e1f565bba106 Mon Sep 17 00:00:00 2001 From: libraryaddict Date: Wed, 12 Aug 2015 06:23:13 +1200 Subject: [PATCH 336/377] Gadget Paintball: Add particles on impact, change block break effect to stone break sound. --- .../core/gadget/gadgets/ItemPaintballGun.java | 61 +++++++++++++------ 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintballGun.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintballGun.java index e1b1b6c39..68fba27a0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintballGun.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintballGun.java @@ -18,9 +18,15 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; +import org.bukkit.util.Vector; import mineplex.core.common.util.C; import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilServer; import mineplex.core.gadget.GadgetManager; import mineplex.core.gadget.event.GadgetBlockEvent; import mineplex.core.gadget.types.ItemGadget; @@ -30,16 +36,17 @@ import mineplex.core.updater.event.UpdateEvent; public class ItemPaintballGun extends ItemGadget { private HashSet _balls = new HashSet(); - - public ItemPaintballGun(GadgetManager manager) + + public ItemPaintballGun(GadgetManager manager) { - super(manager, "Paintball Gun", new String[] - { + super(manager, "Paintball Gun", new String[] + { C.cWhite + "PEW PEW PEW PEW!", - }, - -1, - Material.GOLD_BARDING, (byte)0, - 200, new Ammo("Paintball Gun", "100 Paintballs", Material.GOLD_BARDING, (byte)0, new String[] { C.cWhite + "100 Paintballs for you to shoot!" }, 500, 100)); + }, -1, Material.GOLD_BARDING, (byte) 0, 200, new Ammo("Paintball Gun", "100 Paintballs", Material.GOLD_BARDING, + (byte) 0, new String[] + { + C.cWhite + "100 Paintballs for you to shoot!" + }, 500, 100)); } @Override @@ -48,38 +55,56 @@ public class ItemPaintballGun extends ItemGadget Projectile proj = player.launchProjectile(EnderPearl.class); proj.setVelocity(proj.getVelocity().multiply(2)); _balls.add(proj); - - //Sound + + // Sound player.getWorld().playSound(player.getLocation(), Sound.CHICKEN_EGG_POP, 1.5f, 1.2f); } - + @EventHandler public void Paint(ProjectileHitEvent event) { if (!_balls.remove(event.getEntity())) return; - - Location loc = event.getEntity().getLocation().add(event.getEntity().getVelocity()); - loc.getWorld().playEffect(loc, Effect.STEP_SOUND, 49); + + Location loc = event.getEntity().getLocation(); + + Vector vec = event.getEntity().getVelocity().normalize().multiply(0.05); + + if (vec.length() > 0) + { + int i = 0; + + while (UtilBlock.airFoliage(loc.getBlock())) + { + loc.add(vec); + + if (i++ > 50) + break; + } + } + + loc.getWorld().playSound(loc, Sound.DIG_STONE, 1.3F, 1.3F); + + UtilParticle.PlayParticle(ParticleType.RED_DUST, loc, 0.2F, 0.2F, 0.2F, 1, 70, ViewDist.LONG, UtilServer.getPlayers()); } - + @EventHandler public void Teleport(PlayerTeleportEvent event) { if (event.getCause() == TeleportCause.ENDER_PEARL) event.setCancelled(true); } - + @EventHandler public void cleanupBalls(UpdateEvent event) { if (event.getType() != UpdateType.SLOW) return; - + for (Iterator ballIterator = _balls.iterator(); ballIterator.hasNext();) { Projectile ball = ballIterator.next(); - + if (ball.isDead() || !ball.isValid()) ballIterator.remove(); } From d41ab3432f8003d4a50cb775fafe20beee698253 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Tue, 11 Aug 2015 21:13:45 +0200 Subject: [PATCH 337/377] remove paintbrush when moved away --- .../core/gadget/gadgets/ItemPaintbrush.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java index 80e91b5ad..6b33334b1 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java @@ -23,6 +23,7 @@ import mineplex.core.common.util.UtilEvent; import mineplex.core.common.util.UtilGear; import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilEvent.ActionType; import mineplex.core.gadget.GadgetManager; import mineplex.core.gadget.types.ItemGadget; @@ -35,6 +36,8 @@ public class ItemPaintbrush extends ItemGadget private NautHashMap _brushColor = new NautHashMap(); private NautHashMap _brushPrevious = new NautHashMap(); + private NautHashMap _playerLocation = new NautHashMap(); + public ItemPaintbrush(GadgetManager manager) { super(manager, "Paintbrush", new String[] @@ -91,6 +94,7 @@ public class ItemPaintbrush extends ItemGadget { _brushColor.remove(player.getName()); _brushPrevious.remove(player.getName()); + _playerLocation.remove(player.getName()); RemoveItem(player); } @@ -115,6 +119,27 @@ public class ItemPaintbrush extends ItemGadget player.playSound(player.getLocation(), Sound.ORB_PICKUP, 2f, 1f); } + + @EventHandler + public void disableDistance(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + for (Player player : UtilServer.getPlayers()) + { + if (!GetActive().contains(player)) + continue; + + Location loc = _playerLocation.get(player.getName()); + + if (loc == null || UtilMath.offset(player.getLocation(), loc) > 12) + { + Disable(player); + } + } + } + @EventHandler public void paint(UpdateEvent event) { From 4549c810d40448440086e212535957d084771b29 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Tue, 11 Aug 2015 22:59:59 -0500 Subject: [PATCH 338/377] Fix for voting --- .../mineplex/core/bonuses/BonusManager.java | 11 ++---- .../core/bonuses/BonusRepository.java | 13 +++---- .../mineplex/core/bonuses/gui/BonusGui.java | 1 - .../mineplex/core/bonuses/gui/SpinGui.java | 1 - .../core/bonuses/gui/buttons/VoteButton.java | 1 - .../core/bonuses/{ => redis}/VoteHandler.java | 6 +-- .../redis}/VotifierCommand.java | 11 +++++- .../mineplex/votifier/VotifierManager.java | 38 +++++++++++++------ 8 files changed, 49 insertions(+), 33 deletions(-) rename Plugins/Mineplex.Core/src/mineplex/core/bonuses/{ => redis}/VoteHandler.java (80%) rename Plugins/Mineplex.Core/src/mineplex/core/{votifier => bonuses/redis}/VotifierCommand.java (53%) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index fe37f5a42..0a3f72ced 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -12,6 +12,8 @@ import mineplex.core.account.CoreClient; import mineplex.core.account.CoreClientManager; import mineplex.core.account.IQuerylessLoginProcessor; import mineplex.core.account.event.ClientUnloadEvent; +import mineplex.core.bonuses.redis.VoteHandler; +import mineplex.core.bonuses.redis.VotifierCommand; import mineplex.core.common.Rank; import mineplex.core.common.util.C; import mineplex.core.common.util.Callback; @@ -34,7 +36,6 @@ import mineplex.core.reward.RewardManager; import mineplex.core.stats.StatsManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.core.votifier.VotifierCommand; import mineplex.database.Tables; import mineplex.core.bonuses.animations.AnimationCarl; import mineplex.core.bonuses.commands.AnimationCommand; @@ -52,7 +53,6 @@ import org.jooq.impl.DSL; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Sound; -import org.bukkit.block.Dropper; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; import org.bukkit.entity.Entity; import org.bukkit.entity.Item; @@ -61,7 +61,6 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.java.JavaPlugin; import net.minecraft.server.v1_7_R4.DataWatcher; @@ -107,7 +106,6 @@ public class BonusManager extends MiniClientPlugin implements I @Override public void run(Long data) { - System.out.println("Sql time offset is: " + data); timeOffSet = data; } }); @@ -211,7 +209,6 @@ public class BonusManager extends MiniClientPlugin implements I { if (event.getType() != UpdateType.MIN_16) return; - System.err.println("Updating off set"); updateOffSet(); } @@ -255,7 +252,7 @@ public class BonusManager extends MiniClientPlugin implements I return _voteStreak; } - public void handleVote(final Player player) + public void handleVote(final Player player, final int gemsRecieved) { runAsync(new Runnable() { @@ -270,7 +267,7 @@ public class BonusManager extends MiniClientPlugin implements I { addPendingExplosion(player, player.getName()); UtilPlayer.message(player, F.main("Carl", "Thanks for voting for Mineplex!")); - UtilPlayer.message(player, F.main("Carl", "You received 500 Gems and 1 Carls Spinner Ticket!")); + UtilPlayer.message(player, F.main("Carl", "You received " + gemsRecieved + " Gems and 1 Carl Spinner Ticket!")); } }); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java index c33d49e19..dadb04d31 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java @@ -289,9 +289,8 @@ public class BonusRepository extends RepositoryBase }); } - public void attemptVoteBonus(final Player player, final Callback result) + public void attemptVoteBonus(final int accountId, final Callback result) { - final int accountId = _manager.getClientManager().Get(player).getAccountId(); final int coins = 0; final int gems = 0; @@ -312,23 +311,23 @@ public class BonusRepository extends RepositoryBase callableStatement.executeUpdate(); - //final boolean pass = callableStatement.getBoolean(4); + final boolean pass = callableStatement.getBoolean(4); - final Date date = callableStatement.getDate(4); + final Date date = callableStatement.getDate(5); Bukkit.getScheduler().runTask(plug, new Runnable() { @Override public void run() { - _manager.Get(player).setVoteTime(date); - result.run(true); +// _manager.Get(player).setVoteTime(date); + result.run(date); } }); } catch (Exception e) { e.printStackTrace(); - result.run(false); + result.run(null); } } }); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java index e54887dc8..8306c84d5 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java @@ -37,7 +37,6 @@ public class BonusGui extends SimpleGui @Override protected void finalize() throws Throwable { - System.err.println("Deleting the MailboxGui!"); super.finalize(); } } \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java index 18310ab5a..779c9e431 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/SpinGui.java @@ -144,7 +144,6 @@ public class SpinGui extends SimpleGui if(_currentRewardIndex == _stopSpinnerAt) _stopped = true; - } _tickCount++; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java index 7b6118f70..40950cd54 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java @@ -166,7 +166,6 @@ public class VoteButton implements GuiItem, Listener { { if (_url == null) return false; - System.out.println(timeLeft()); return (timeLeft() <= 0); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/VoteHandler.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VoteHandler.java similarity index 80% rename from Plugins/Mineplex.Core/src/mineplex/core/bonuses/VoteHandler.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VoteHandler.java index 4dec15845..7c4e6f37d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/VoteHandler.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VoteHandler.java @@ -1,9 +1,9 @@ -package mineplex.core.bonuses; +package mineplex.core.bonuses.redis; import org.bukkit.entity.Player; +import mineplex.core.bonuses.BonusManager; import mineplex.core.common.util.UtilPlayer; -import mineplex.core.votifier.VotifierCommand; import mineplex.serverdata.commands.CommandCallback; import mineplex.serverdata.commands.ServerCommand; @@ -25,7 +25,7 @@ public class VoteHandler implements CommandCallback if (player != null) { - _bonusManager.handleVote(player); + _bonusManager.handleVote(player, v.getGemsRecieved()); } } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VotifierCommand.java similarity index 53% rename from Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VotifierCommand.java index 0d8454d2d..d2574643e 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/votifier/VotifierCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VotifierCommand.java @@ -1,4 +1,4 @@ -package mineplex.core.votifier; +package mineplex.core.bonuses.redis; import java.util.UUID; @@ -7,12 +7,14 @@ import mineplex.serverdata.commands.ServerCommand; public class VotifierCommand extends ServerCommand { private String _playerName; + private int _gemsRecieved; - public VotifierCommand(String playerName, String... targetServer) + public VotifierCommand(String playerName, int gemsRecieved, String... targetServer) { super(targetServer); _playerName = playerName; + _gemsRecieved = gemsRecieved; } public String getPlayerName() @@ -20,4 +22,9 @@ public class VotifierCommand extends ServerCommand return _playerName; } + public int getGemsRecieved() + { + return _gemsRecieved; + } + } diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index 4791202f9..3d367e424 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -17,12 +17,11 @@ import mineplex.core.common.util.Callback; import mineplex.core.common.util.UUIDFetcher; import mineplex.core.database.DBPool; import mineplex.core.donation.DonationManager; -import mineplex.core.votifier.VotifierCommand; +import mineplex.core.bonuses.redis.VotifierCommand; import mineplex.database.Tables; import mineplex.serverdata.Region; import mineplex.serverdata.Utility; import mineplex.serverdata.commands.ServerCommand; -import mineplex.serverdata.commands.ServerCommandManager; import mineplex.serverdata.data.PlayerStatus; import mineplex.serverdata.redis.RedisConfig; import mineplex.serverdata.redis.RedisDataRepository; @@ -75,7 +74,7 @@ public class VotifierManager extends MiniPlugin public void handleVote(VotifierEvent event) { Vote vote = event.getVote(); - String playerName = vote.getUsername(); + final String playerName = vote.getUsername(); System.out.println("New Vote: " + playerName); @@ -93,7 +92,14 @@ public class VotifierManager extends MiniPlugin System.out.println("Loaded " + playerName + " with uuid " + uuid); System.out.println("Attempting to award bonus"); - awardBonus(playerName, uuid); + awardBonus(playerName, uuid, new Runnable() + { + @Override + public void run() + { + notifyServer(playerName, false); + } + }); System.out.println(); System.out.println(); @@ -129,7 +135,6 @@ public class VotifierManager extends MiniPlugin // } // Currently we just notify all servers, and the server with the player on it can deal with it - notifyServer(playerName, false); // notifyServer(playerName, true); } @@ -141,7 +146,7 @@ public class VotifierManager extends MiniPlugin publishCommand(command, writePool); } - private void awardBonus(final String playerName, UUID uuid) + private void awardBonus(final String playerName, UUID uuid, final Runnable onComplete) { DSLContext create = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL); @@ -188,13 +193,24 @@ public class VotifierManager extends MiniPlugin } // Update time - client.getRecord().setVotetime(new Date(_bonusManager.getSqlTime())); + _bonusManager.getRepository().attemptVoteBonus(accountId, new Callback() + { + @Override + public void run(Date data) + { + if (data != null) + { + client.getRecord().setVotetime(data); - // Update Streak - _bonusManager.incrementVoteStreak(client); + // Update Streak + _bonusManager.incrementVoteStreak(client); - client.getRecord().store(); - System.out.println("Awarded carl ticket to " + playerName); + client.getRecord().store(); + System.out.println("Awarded carl ticket to " + playerName); + onComplete.run(); + } + } + }); } } From 99a94251fd43eee81fd4a03a2e1ec5f2dcbb163d Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Wed, 12 Aug 2015 00:56:20 -0500 Subject: [PATCH 339/377] Fixes --- .../mineplex/core/bonuses/BonusAmount.java | 5 ++- .../mineplex/core/bonuses/BonusManager.java | 45 ++++++++++++++----- .../bonuses/gui/buttons/DailyBonusButton.java | 2 +- .../core/bonuses/gui/buttons/VoteButton.java | 2 +- .../core/bonuses/redis/VoteHandler.java | 2 +- .../core/bonuses/redis/VotifierCommand.java | 12 +++-- .../mineplex/votifier/VotifierManager.java | 25 ++++++----- 7 files changed, 59 insertions(+), 34 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java index d2cfef1f8..bb6d8c9f3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java @@ -2,6 +2,8 @@ package mineplex.core.bonuses; import java.util.List; +import org.bukkit.ChatColor; + import mineplex.core.common.util.C; public class BonusAmount @@ -138,6 +140,7 @@ public class BonusAmount public void addLore(List lore) { + lore.add(C.cYellow + "Rewards"); addLore(lore, getTickets(), 0, "Carl Spin Ticket" + (getTickets() > 1 ? "s" : "")); addLore(lore, getCoins(), getBonusCoins(), "Coins"); addLore(lore, getGems(), getBonusGems(), "Gems"); @@ -148,7 +151,7 @@ public class BonusAmount private void addLore(List lore, int amount, int bonus, String suffix) { if (amount > 0) - lore.add(C.cYellow + "Reward: " + C.cWhite + amount + " " + suffix); + lore.add(" " + C.cWhite + amount + " " + suffix); // if (bonus > 0) // lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + bonus + " " + suffix); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 0a3f72ced..e31bee5e0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -375,7 +375,8 @@ public class BonusManager extends MiniClientPlugin implements I // DAILY BONUS public static final long TIME_BETWEEN_BONUSES = 1000 * 60 * 60 * 20; - public static final long STREAK_RESET_TIME = 1000 * 60 * 60 * 12; + public static final long DAILY_STREAK_RESET_TIME = 1000 * 60 * 60 * 12; + public static final long VOTE_STREAK_RESET_TIME = 1000 * 60 * 60 * 24; public void attemptDailyBonus(final Player player, final BonusAmount amount, final Callback result) { @@ -496,7 +497,7 @@ public class BonusManager extends MiniClientPlugin implements I if (client.getDailyStreak() > 0 && client.getDailyTime() != null) { long lastBonus = getLocalTime(client.getDailyTime().getTime()); - long timeLeft = getStreakTimeRemaining(lastBonus, BonusManager.STREAK_RESET_TIME); + long timeLeft = getStreakTimeRemaining(lastBonus, BonusManager.DAILY_STREAK_RESET_TIME); if (timeLeft < 0) { @@ -505,6 +506,25 @@ public class BonusManager extends MiniClientPlugin implements I } } + public void updateVoteStreak(Player player) + { + updateVoteStreak(Get(player)); + } + + public void updateVoteStreak(BonusClientData client) + { + if (client.getVoteStreak() > 0 && client.getVoteTime() != null) + { + long lastBonus = getLocalTime(client.getDailyTime().getTime()); + long timeLeft = getStreakTimeRemaining(lastBonus, BonusManager.VOTE_STREAK_RESET_TIME); + + if (timeLeft < 0) + { + client.setVoteStreak(0); + } + } + } + public void incrementDailyStreak(Player player) { BonusClientData data = Get(player); @@ -666,6 +686,7 @@ public class BonusManager extends MiniClientPlugin implements I if (gems > 0) { + UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(gems + " Gems"))); _donationManager.RewardGems(new Callback() { @Override @@ -673,18 +694,18 @@ public class BonusManager extends MiniClientPlugin implements I { if (data) { - UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(gems + " Gems"))); } else { UtilPlayer.message(player, F.main("Carl", "Failed to process Gems")); } } - }, "BonusManager", player.getName(), player.getUniqueId(), gems, true); + }, "Earned", player.getName(), player.getUniqueId(), gems, true); } if (gold > 0) { + UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(gold + " Gold"))); _donationManager.RewardGold(new Callback() { @Override @@ -692,18 +713,18 @@ public class BonusManager extends MiniClientPlugin implements I { if (data) { - UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(gold + " Gold"))); } else { UtilPlayer.message(player, F.main("Carl", "Failed to process Gold")); } } - }, "BonusManager", player.getName(), coreClient.getAccountId(), gold, true); + }, "Earned", player.getName(), coreClient.getAccountId(), gold, true); } if (coins > 0) { + UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(coins + " Coins"))); _donationManager.RewardCoins(new Callback() { @Override @@ -711,18 +732,18 @@ public class BonusManager extends MiniClientPlugin implements I { if (data) { - UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(coins + " Coins"))); } else { UtilPlayer.message(player, F.main("Carl", "Failed to process Coins")); } } - }, "BonusManager", player.getName(), coreClient.getAccountId(), coins, true); + }, "Earned", player.getName(), coreClient.getAccountId(), coins, true); } if (tickets > 0) { + UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(tickets + " Carl Spin Ticket"))); final int accountId = _clientManager.Get(player).getAccountId(); runAsync(new Runnable() { @@ -739,7 +760,6 @@ public class BonusManager extends MiniClientPlugin implements I public void run() { bonusClient.setTickets(newTickets); - UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(tickets + " Carl Spin Ticket"))); } }); } @@ -757,7 +777,7 @@ public class BonusManager extends MiniClientPlugin implements I _statsManager.incrementStat(player, "Global.ExpEarned", experience); UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(experience + " Experience"))); } - + UtilPlayer.message(player, F.main("Carl", "Come back tomorrow for more!")); } @@ -897,15 +917,16 @@ public class BonusManager extends MiniClientPlugin implements I @EventHandler public void updateCreeper(UpdateEvent event) { - if (event.getType() != UpdateType.SEC || !_enabled) + if (event.getType() != UpdateType.FASTER || !_enabled) return; for (Player player : UtilServer.getPlayers()) { String prefix = _visualTick % 2 == 0 ? C.cAqua : C.cDAqua; updateCreeperVisual(player, false, prefix); - _visualTick++; } + + _visualTick++; } @Override diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java index 76d58c807..0c2ea37d2 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DailyBonusButton.java @@ -152,7 +152,7 @@ public class DailyBonusButton implements GuiItem, Listener if (client.getDailyTime() != null) { long lastBonus = _bonusManager.getLocalTime(client.getDailyTime().getTime()); - long timeLeft = _bonusManager.getStreakTimeRemaining(lastBonus, BonusManager.STREAK_RESET_TIME); + long timeLeft = _bonusManager.getStreakTimeRemaining(lastBonus, BonusManager.DAILY_STREAK_RESET_TIME); if (timeLeft > 0) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java index 40950cd54..9009fb7e0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java @@ -135,7 +135,7 @@ public class VoteButton implements GuiItem, Listener { if (client.getVoteTime() != null) { long lastBonus = _bonusManager.getLocalTime(client.getVoteTime().getTime()); - long timeLeft = _bonusManager.getStreakTimeRemaining(lastBonus, BonusManager.STREAK_RESET_TIME); + long timeLeft = _bonusManager.getStreakTimeRemaining(lastBonus, BonusManager.VOTE_STREAK_RESET_TIME); if (timeLeft > 0) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VoteHandler.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VoteHandler.java index 7c4e6f37d..54f2a820b 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VoteHandler.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VoteHandler.java @@ -25,7 +25,7 @@ public class VoteHandler implements CommandCallback if (player != null) { - _bonusManager.handleVote(player, v.getGemsRecieved()); + _bonusManager.handleVote(player, v.getGemsReceived()); } } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VotifierCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VotifierCommand.java index d2574643e..95dbb06a4 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VotifierCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VotifierCommand.java @@ -1,20 +1,18 @@ package mineplex.core.bonuses.redis; -import java.util.UUID; - import mineplex.serverdata.commands.ServerCommand; public class VotifierCommand extends ServerCommand { private String _playerName; - private int _gemsRecieved; + private int _gemsReceived; - public VotifierCommand(String playerName, int gemsRecieved, String... targetServer) + public VotifierCommand(String playerName, int gemsReceived, String... targetServer) { super(targetServer); _playerName = playerName; - _gemsRecieved = gemsRecieved; + _gemsReceived = gemsReceived; } public String getPlayerName() @@ -22,9 +20,9 @@ public class VotifierCommand extends ServerCommand return _playerName; } - public int getGemsRecieved() + public int getGemsReceived() { - return _gemsRecieved; + return _gemsReceived; } } diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index 3d367e424..ff124fa76 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -92,12 +92,12 @@ public class VotifierManager extends MiniPlugin System.out.println("Loaded " + playerName + " with uuid " + uuid); System.out.println("Attempting to award bonus"); - awardBonus(playerName, uuid, new Runnable() + awardBonus(playerName, uuid, new Callback() { @Override - public void run() + public void run(Integer gems) { - notifyServer(playerName, false); + notifyServer(playerName, gems, false); } }); System.out.println(); @@ -138,15 +138,15 @@ public class VotifierManager extends MiniPlugin // notifyServer(playerName, true); } - private void notifyServer(String playerName, boolean eu) + private void notifyServer(String playerName, int gems, boolean eu) { JedisPool writePool = eu ? _euWritePool : _usWritePool; - VotifierCommand command = new VotifierCommand(playerName); + VotifierCommand command = new VotifierCommand(playerName, gems); publishCommand(command, writePool); } - private void awardBonus(final String playerName, UUID uuid, final Runnable onComplete) + private void awardBonus(final String playerName, UUID uuid, final Callback onComplete) { DSLContext create = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL); @@ -162,7 +162,7 @@ public class VotifierManager extends MiniPlugin if (amount.getTickets() > 0) client.setTickets(client.getTickets() + amount.getTickets()); - if (amount.getGems() > 0) + if (amount.getTotalGems() > 0) { _donationManager.RewardGems(new Callback() { @@ -174,10 +174,10 @@ public class VotifierManager extends MiniPlugin else System.out.println("Failed to give " + amount.getGems() + " gems to " + playerName); } - }, "Votifier", playerName, uuid, amount.getGems()); + }, "Votifier", playerName, uuid, amount.getTotalGems()); } - if (amount.getCoins() > 0) + if (amount.getTotalCoins() > 0) { _donationManager.RewardCoins(new Callback() { @@ -189,9 +189,12 @@ public class VotifierManager extends MiniPlugin else System.out.println("Failed to give " + amount.getGems() + " coins to " + playerName); } - }, "Votifier", playerName, accountId, amount.getCoins()); + }, "Votifier", playerName, accountId, amount.getTotalCoins()); } + // Check if we need to reset vote streak + _bonusManager.updateVoteStreak(client); + // Update time _bonusManager.getRepository().attemptVoteBonus(accountId, new Callback() { @@ -207,7 +210,7 @@ public class VotifierManager extends MiniPlugin client.getRecord().store(); System.out.println("Awarded carl ticket to " + playerName); - onComplete.run(); + onComplete.run(amount.getTotalGems()); } } }); From e8963cc2af790269d240d85503bfab1f556aece8 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Wed, 12 Aug 2015 08:10:43 +0200 Subject: [PATCH 340/377] fixed paintbrush --- .../src/mineplex/core/gadget/gadgets/ItemPaintbrush.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java index 6b33334b1..894c1e4d1 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/ItemPaintbrush.java @@ -86,6 +86,7 @@ public class ItemPaintbrush extends ItemGadget ApplyItem(player, true); _brushColor.put(player.getName(), (byte)15); + _playerLocation.put(player.getName(), player.getLocation()); } From 7cda53cb28d25923b1b33066499e229a6d485568 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Wed, 12 Aug 2015 08:36:21 +0200 Subject: [PATCH 341/377] carl spinner in arcade/ tutorial fixes --- .../mineplex/hub/tutorial/types/PartyTutorial.java | 4 ++-- .../mineplex/hub/tutorial/types/WelcomeTutorial.java | 4 ++-- .../nautilus/game/arcade/managers/GameManager.java | 11 +++++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/PartyTutorial.java b/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/PartyTutorial.java index 8b995220b..c91ce9eca 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/PartyTutorial.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/PartyTutorial.java @@ -118,8 +118,8 @@ public class PartyTutorial extends Tutorial )); _phases.add(new TutorialPhase( - manager.GetSpawn().add(0, -2, 0), - manager.GetSpawn().add(0, -2.1, 5), + manager.GetSpawn().add(0, 0, 0), + manager.GetSpawn().add(0, 0.1, 5), "End", new String[] { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/WelcomeTutorial.java b/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/WelcomeTutorial.java index 5eb6b5ebb..17ddabbad 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/WelcomeTutorial.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/tutorial/types/WelcomeTutorial.java @@ -132,8 +132,8 @@ public class WelcomeTutorial extends Tutorial //END _phases.add(new TutorialPhase( - manager.GetSpawn().add(0, -2, 0), - manager.GetSpawn().add(0, -2.1, 5), + manager.GetSpawn().add(0, 0, 0), + manager.GetSpawn().add(0, 0.1, 5), "End", new String[] { diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java index cfed7e11b..4ff2caafe 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java @@ -3,6 +3,7 @@ package nautilus.game.arcade.managers; import java.util.ArrayList; import java.util.Iterator; +import mineplex.core.bonuses.event.CarlSpinnerEvent; import mineplex.core.common.util.C; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilFirework; @@ -692,4 +693,14 @@ public class GameManager implements Listener { event.GetGame().EndCheck(); } + + @EventHandler + public void carlSpinnerCancel(CarlSpinnerEvent event) + { + Game game = Manager.GetGame(); + if (game == null) return; + + if (game.GetCountdown() > 0) + event.setCancelled(true); + } } From af19754bcd477f3d1872ebdb6a0af0625d8c1225 Mon Sep 17 00:00:00 2001 From: Sarah Date: Wed, 12 Aug 2015 08:37:54 +0200 Subject: [PATCH 342/377] Implementing Carl to Arcade. --- .../src/mineplex/core/bonuses/BonusManager.java | 7 +++++-- .../src/nautilus/game/arcade/Arcade.java | 8 ++++++-- .../src/nautilus/game/arcade/ArcadeManager.java | 7 ++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index fe37f5a42..819f84273 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -985,7 +985,7 @@ public class BonusManager extends MiniClientPlugin implements I if(!(entity instanceof Item)) continue; - if(((Item)entity).getItemStack().getType() == Material.MONSTER_EGG && ((Item)entity).getItemStack().hasItemMeta() && !((Item)entity).getItemStack().getItemMeta().getDisplayName().startsWith("Hidden")) + if(((Item)entity).getItemStack().hasItemMeta() && !((Item)entity).getItemStack().getItemMeta().getDisplayName().startsWith("Hidden")) entity.remove(); if(!((Item) entity).getItemStack().hasItemMeta()) @@ -1030,7 +1030,10 @@ public class BonusManager extends MiniClientPlugin implements I if(_pollManager.hasPoll(player) || canVote(player) || canRank(player) || canDaily(player)) { if(_showCarl.containsKey(player.getName())) - UtilPlayer.message(player, C.cDGreen + C.Bold + "Carl the Creeper>" + C.cGreen + " Hey " + player.getName().replace("s", "sss") + "! I have sssome amazing rewardsss for you! Come sssee me!"); + { + if(_plugin.getConfig().getString("serverstatus.group").equalsIgnoreCase("Lobby")) + UtilPlayer.message(player, C.cDGreen + C.Bold + "Carl the Creeper>" + C.cGreen + " Hey " + player.getName().replace("s", "sss") + "! I have sssome amazing rewardsss for you! Come sssee me!"); + } } } } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java index 3f063b9fb..31b6bc189 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java @@ -4,6 +4,7 @@ import java.io.File; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; +import org.omg.CORBA._PolicyStub; import net.minecraft.server.v1_7_R4.BiomeBase; import net.minecraft.server.v1_7_R4.MinecraftServer; @@ -37,6 +38,7 @@ import mineplex.core.mount.MountManager; import mineplex.core.npc.NpcManager; import mineplex.core.packethandler.PacketHandler; import mineplex.core.pet.PetManager; +import mineplex.core.poll.PollManager; import mineplex.core.portal.Portal; import mineplex.core.preferences.PreferencesManager; import mineplex.core.projectile.ProjectileManager; @@ -112,7 +114,8 @@ public class Arcade extends JavaPlugin DisguiseManager disguiseManager = new DisguiseManager(this, packetHandler); - _damageManager = new DamageManager(this, new CombatManager(this), new NpcManager(this, creature), disguiseManager, null); + NpcManager npcmanager = new NpcManager(this, creature); + _damageManager = new DamageManager(this, new CombatManager(this), npcmanager, disguiseManager, null); Punish punish = new Punish(this, webServerAddress, _clientManager); AntiHack.Initialize(this, punish, portal, preferenceManager, _clientManager); @@ -139,7 +142,8 @@ public class Arcade extends JavaPlugin cosmeticManager.setInterfaceSlot(7); //Arcade Manager - _gameManager = new ArcadeManager(this, serverStatusManager, ReadServerConfig(), _clientManager, _donationManager, _damageManager, statsManager, achievementManager, disguiseManager, creature, teleport, new Blood(this), chat, portal, preferenceManager, inventoryManager, packetHandler, cosmeticManager, projectileManager, petManager, hologramManager, webServerAddress); + PollManager pollManager = new PollManager(this, _clientManager, _donationManager); + _gameManager = new ArcadeManager(this, serverStatusManager, ReadServerConfig(), _clientManager, _donationManager, _damageManager, statsManager, achievementManager, disguiseManager, creature, teleport, new Blood(this), chat, portal, preferenceManager, inventoryManager, packetHandler, cosmeticManager, projectileManager, petManager, hologramManager, webServerAddress, pollManager, npcmanager); new MemoryFix(this); new CustomTagFix(this, packetHandler); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java index cc264d1e6..66e647681 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java @@ -42,6 +42,7 @@ import mineplex.core.account.CoreClientManager; import mineplex.core.achievement.AchievementManager; import mineplex.core.blockrestore.BlockRestore; import mineplex.core.blood.Blood; +import mineplex.core.bonuses.BonusManager; import mineplex.core.chat.Chat; import mineplex.core.common.Rank; import mineplex.core.common.jsonchat.ClickEvent; @@ -67,6 +68,7 @@ import mineplex.core.inventory.InventoryManager; import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.movement.Movement; import mineplex.core.notifier.NotificationManager; +import mineplex.core.npc.NpcManager; import mineplex.core.packethandler.IPacketHandler; import mineplex.core.packethandler.PacketHandler; import mineplex.core.packethandler.PacketInfo; @@ -74,6 +76,7 @@ import mineplex.core.packethandler.PacketPlayResourcePackStatus; import mineplex.core.packethandler.PacketPlayResourcePackStatus.EnumResourcePackStatus; import mineplex.core.party.PartyManager; import mineplex.core.pet.PetManager; +import mineplex.core.poll.PollManager; import mineplex.core.portal.Portal; import mineplex.core.preferences.PreferencesManager; import mineplex.core.projectile.ProjectileManager; @@ -209,7 +212,7 @@ public class ArcadeManager extends MiniPlugin implements IRelation CoreClientManager clientManager, DonationManager donationManager, DamageManager damageManager, StatsManager statsManager, AchievementManager achievementManager, DisguiseManager disguiseManager, Creature creature, Teleport teleport, Blood blood, Chat chat, Portal portal, PreferencesManager preferences, InventoryManager inventoryManager, PacketHandler packetHandler, - CosmeticManager cosmeticManager, ProjectileManager projectileManager, PetManager petManager, HologramManager hologramManager, String webAddress) + CosmeticManager cosmeticManager, ProjectileManager projectileManager, PetManager petManager, HologramManager hologramManager, String webAddress, PollManager pollManager, NpcManager npcManager) { super("Game Manager", plugin); @@ -293,6 +296,8 @@ public class ArcadeManager extends MiniPlugin implements IRelation new NotificationManager(getPlugin(), clientManager); + new BonusManager(plugin, clientManager, donationManager, pollManager , npcManager, hologramManager, statsManager, _inventoryManager, petManager); + //Champions Modules _energy = new Energy(plugin); From e4eb28622502f872ca62bc00ff96b4b64eba2173 Mon Sep 17 00:00:00 2001 From: Sarah Date: Wed, 12 Aug 2015 08:56:20 +0200 Subject: [PATCH 343/377] Fixing despawning. --- .../Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index e31bee5e0..a20c7add1 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -1002,6 +1002,9 @@ public class BonusManager extends MiniClientPlugin implements I { if(!(entity instanceof Item)) continue; + + if(!((Item)entity).getItemStack().hasItemMeta()) + entity.remove(); if(((Item)entity).getItemStack().getType() == Material.MONSTER_EGG && ((Item)entity).getItemStack().hasItemMeta() && !((Item)entity).getItemStack().getItemMeta().getDisplayName().startsWith("Hidden")) entity.remove(); From d6f17c609b2bb9e62a3d608821837b23de3989c9 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Wed, 12 Aug 2015 08:58:46 +0200 Subject: [PATCH 344/377] carl --- .../src/nautilus/game/arcade/managers/GameManager.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java index 4ff2caafe..d3302b599 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameManager.java @@ -700,7 +700,11 @@ public class GameManager implements Listener Game game = Manager.GetGame(); if (game == null) return; - if (game.GetCountdown() > 0) + if (game.GetCountdown() > 0 || game.GetState() != GameState.Recruit) + { + UtilPlayer.message(event.getPlayer(), F.main("Carl", "You can't use my spinner at the moment!")); event.setCancelled(true); + } + } } From 2a40eee9e7812c4a5623ef11b95bd62a071e232b Mon Sep 17 00:00:00 2001 From: Sarah Date: Wed, 12 Aug 2015 09:00:13 +0200 Subject: [PATCH 345/377] Increasing radius of items despawning. --- .../Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index a20c7add1..f4a255d01 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -998,7 +998,7 @@ public class BonusManager extends MiniClientPlugin implements I if(event.getType() != UpdateType.TICK) return; - for(Entity entity : _carlNpc.getEntity().getNearbyEntities(3, -0.5, 3)) + for(Entity entity : _carlNpc.getEntity().getNearbyEntities(10, -0.5, 10)) { if(!(entity instanceof Item)) continue; From ade76791b37c93b5e491b8d95c7019a977a1b581 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Wed, 12 Aug 2015 09:12:49 +0200 Subject: [PATCH 346/377] optimized item cleaning --- .../mineplex/core/bonuses/BonusManager.java | 32 +++----------- .../bonuses/animations/AnimationCarl.java | 43 ++++++++++++++----- 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 57545689f..548d298f3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -5,6 +5,8 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; import java.util.TimeZone; import mineplex.core.MiniClientPlugin; @@ -301,6 +303,8 @@ public class BonusManager extends MiniClientPlugin implements I if (event.getType() != UpdateType.TICK) return; + _animation.itemClean(); + if(_canVote) return; @@ -328,7 +332,6 @@ public class BonusManager extends MiniClientPlugin implements I creeper.getWorld().playSound(creeper.getLocation(), Sound.EXPLODE, 2f, 1f); _animation.setType(_pendingExplosions.get(0)); _animation.setPlayer(_pendingExplosionsPlayers.get(0)); - _animation.setTime(System.currentTimeMillis()); _animation.setRunning(true); } @@ -992,32 +995,7 @@ public class BonusManager extends MiniClientPlugin implements I return _pollManager; } - @EventHandler - public void ItemDecay(UpdateEvent event) - { - if(event.getType() != UpdateType.TICK) - return; - - for(Entity entity : _carlNpc.getEntity().getNearbyEntities(10, -0.5, 10)) - { - if(!(entity instanceof Item)) - continue; - - if(!((Item)entity).getItemStack().hasItemMeta()) - entity.remove(); - - if(((Item)entity).getItemStack().hasItemMeta() && !((Item)entity).getItemStack().getItemMeta().getDisplayName().startsWith("Hidden")) - entity.remove(); - - if(!((Item) entity).getItemStack().hasItemMeta()) - continue; - - if(!((Item) entity).getItemStack().getItemMeta().getDisplayName().startsWith(" ")) - continue; - - entity.remove(); - } - } + @EventHandler public void Join(final PlayerJoinEvent event) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index 160b2e14c..47c731623 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -1,5 +1,7 @@ package mineplex.core.bonuses.animations; +import java.util.HashSet; +import java.util.Iterator; import java.util.Random; import mineplex.core.common.util.UtilAction; @@ -13,6 +15,8 @@ import mineplex.core.reward.Reward; import mineplex.core.reward.RewardData; import mineplex.core.reward.RewardRarity; import mineplex.core.treasure.animation.Animation; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; import org.bukkit.Color; import org.bukkit.Location; @@ -23,19 +27,19 @@ import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; public class AnimationCarl extends Animation { - private boolean _isDone; private Block _creeper; - private long _startTime; private Object _type; private Player _player; - private Random _random = new Random(); + + private HashSet _items = new HashSet(); public AnimationCarl(Entity creeper) { @@ -53,6 +57,9 @@ public class AnimationCarl extends Animation { Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, " " + i)); + _items.add(gem); + _items.add(coin); + Vector vel = new Vector(Math.sin(i * 9/5d), 0, Math.cos(i * 9/5d)); UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 12/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 12/3000d))*0.6, 1, false); UtilAction.velocity(coin, vel, Math.abs(Math.sin(UtilMath.r(i) * 30/3000d)), false, 0, 0.2 + Math.abs(Math.cos(UtilMath.r(i) * 30/3000d))*0.6, 1, false); @@ -65,6 +72,8 @@ public class AnimationCarl extends Animation for (int i = 50; i < 60; i++) { Item coin = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.DOUBLE_PLANT, (byte) 0, 1, " " + i)); + _items.add(coin); + Vector vel = new Vector(Math.sin(UtilMath.r(i) * 7/5d), 0, Math.cos(UtilMath.r(i) * 7/5d)); UtilAction.velocity(coin, vel, Math.abs(Math.sin(UtilMath.r(i) * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(UtilMath.r(i) * 7/3000d))*0.6, 1, false); coin.setTicksLived(1160); @@ -74,12 +83,16 @@ public class AnimationCarl extends Animation { Item paper = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, " " + 64)); + _items.add(paper); + Vector vel = new Vector(Math.sin(64 * 8/5d), 0, Math.cos(64 * 8/5d)); UtilAction.velocity(paper, vel, Math.abs(Math.sin(64 * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(64 + 9/3000d))*0.6, 1, false); paper.setTicksLived(1160); for (int i = 50; i < 60; i++) { Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); + _items.add(gem); + Vector velo = new Vector(Math.sin(i * 8/5d), 0, Math.cos(i * 8/5d)); UtilAction.velocity(gem, velo, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 8/3000d))*0.6, 1, false); gem.setTicksLived(1160); @@ -94,12 +107,11 @@ public class AnimationCarl extends Animation RewardData rewardData = ((Reward)_type).getFakeRewardData(_player); ItemStack itemStack = rewardData.getDisplayItem(); Item item = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.7, 0.5), itemStack); + _items.add(item); Vector vel = new Vector(_player.getLocation().getX() - _creeper.getLocation().getX(), 0, _player.getLocation().getZ() - _creeper.getLocation().getZ()); UtilAction.velocity(item, vel, 0.1, false, 0, 0.2 + 1*0.4, 1, false); - - item.setTicksLived(1160); } if(((Reward)_type).getRarity() == RewardRarity.RARE) @@ -137,11 +149,6 @@ public class AnimationCarl extends Animation _isDone = b; } - public void setTime(long time) - { - _startTime = time; - } - public void setType(Object type) { _type = type; @@ -265,4 +272,20 @@ public class AnimationCarl extends Animation } } } + + public void itemClean() + { + Iterator itemIterator = _items.iterator(); + + while (itemIterator.hasNext()) + { + Item item = itemIterator.next(); + + if (item.isOnGround() || !item.isValid() || item.getTicksLived() > 60) + { + item.remove(); + itemIterator.remove(); + } + } + } } From f19efb4a931cf7008c24cfad197662b4938acdf6 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Wed, 12 Aug 2015 09:23:00 +0200 Subject: [PATCH 347/377] renamed football to soccer --- .../src/mineplex/hub/modules/SoccerManager.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java index 0eacb7d77..462b0d7cf 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -425,13 +425,13 @@ public class SoccerManager extends MiniPlugin { if (_active.size() >= 8) { - UtilPlayer.message(player, F.main("Football", "You must be wearing Red/Blue Team Outfit.")); - UtilPlayer.message(player, F.main("Football", "Type " + F.elem("/team red") + " or " + F.elem("/team blue") + "!")); + UtilPlayer.message(player, F.main("Soccer", "You must be wearing Red/Blue Team Outfit.")); + UtilPlayer.message(player, F.main("Soccer", "Type " + F.elem("/team red") + " or " + F.elem("/team blue") + "!")); } else { - UtilPlayer.message(player, F.main("Football", "You must be wearing Red/Blue Team Outfit.")); - UtilPlayer.message(player, F.main("Football", "Type " + F.elem("/team red") + " or " + F.elem("/team blue") + "!")); + UtilPlayer.message(player, F.main("Soccer", "You must be wearing Red/Blue Team Outfit.")); + UtilPlayer.message(player, F.main("Soccer", "Type " + F.elem("/team red") + " or " + F.elem("/team blue") + "!")); } } } @@ -447,11 +447,11 @@ public class SoccerManager extends MiniPlugin _active.add(player); if (color == null) - UtilPlayer.message(player, F.main("Parkour", "You have entered " + F.elem("Football Mode") + ".")); + UtilPlayer.message(player, F.main("Parkour", "You have entered " + F.elem("Soccer Mode") + ".")); else if (color == Color.RED) - UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cRed + "Red Football Team") + ".")); + UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cRed + "Red Soccer Team") + ".")); else if (color == Color.AQUA) - UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cAqua + "Blue Football Team") + ".")); + UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cAqua + "Blue Soccer Team") + ".")); ArrayList outfit = new ArrayList(); outfit.add("Team Helmet"); @@ -466,7 +466,7 @@ public class SoccerManager extends MiniPlugin else { _active.remove(player); - UtilPlayer.message(player, F.main("Parkour", "You have exited " + F.elem("Football Mode") + ".")); + UtilPlayer.message(player, F.main("Parkour", "You have exited " + F.elem("Soccer Mode") + ".")); } } From 860127631cbb8584f148896036dc3e1b9b1def71 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Wed, 12 Aug 2015 09:27:05 +0200 Subject: [PATCH 348/377] fixed item insta-despawn --- .../mineplex/core/bonuses/animations/AnimationCarl.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java index 47c731623..4cc2ac529 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/animations/AnimationCarl.java @@ -63,8 +63,7 @@ public class AnimationCarl extends Animation Vector vel = new Vector(Math.sin(i * 9/5d), 0, Math.cos(i * 9/5d)); UtilAction.velocity(gem, vel, Math.abs(Math.sin(i * 12/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 12/3000d))*0.6, 1, false); UtilAction.velocity(coin, vel, Math.abs(Math.sin(UtilMath.r(i) * 30/3000d)), false, 0, 0.2 + Math.abs(Math.cos(UtilMath.r(i) * 30/3000d))*0.6, 1, false); - coin.setTicksLived(1160); - gem.setTicksLived(1160); + } } if(((String) _type).contentEquals("RANK")) @@ -76,7 +75,7 @@ public class AnimationCarl extends Animation Vector vel = new Vector(Math.sin(UtilMath.r(i) * 7/5d), 0, Math.cos(UtilMath.r(i) * 7/5d)); UtilAction.velocity(coin, vel, Math.abs(Math.sin(UtilMath.r(i) * 7/3000d)), false, 0, 0.2 + Math.abs(Math.cos(UtilMath.r(i) * 7/3000d))*0.6, 1, false); - coin.setTicksLived(1160); + } } if(!((String) _type).contentEquals("DAILY")&& !((String) _type).contentEquals("RANK")&& !((String) _type).contentEquals("POLL")) @@ -87,7 +86,7 @@ public class AnimationCarl extends Animation Vector vel = new Vector(Math.sin(64 * 8/5d), 0, Math.cos(64 * 8/5d)); UtilAction.velocity(paper, vel, Math.abs(Math.sin(64 * 9/3000d)), false, 0, 0.2 + Math.abs(Math.cos(64 + 9/3000d))*0.6, 1, false); - paper.setTicksLived(1160); + for (int i = 50; i < 60; i++) { Item gem = _creeper.getWorld().dropItem(_creeper.getLocation().add(0.5, 1.5, 0.5), ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, " " + i)); @@ -95,7 +94,7 @@ public class AnimationCarl extends Animation Vector velo = new Vector(Math.sin(i * 8/5d), 0, Math.cos(i * 8/5d)); UtilAction.velocity(gem, velo, Math.abs(Math.sin(i * 8/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i + 8/3000d))*0.6, 1, false); - gem.setTicksLived(1160); + } } finish(); From 30f20801c75129a60664dc0039fd426ae05bb888 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Wed, 12 Aug 2015 03:00:07 -0500 Subject: [PATCH 349/377] Lets hope everything works! --- .../mineplex/core/bonuses/BonusManager.java | 61 +++++++++- .../core/bonuses/BonusRepository.java | 12 +- .../core/bonuses/gui/buttons/PollButton.java | 12 +- .../bonuses/gui/buttons/RankBonusButton.java | 70 +++++++----- .../core/bonuses/gui/buttons/VoteButton.java | 2 +- .../src/mineplex/core/poll/PollManager.java | 26 +++-- .../serverdata/servers/ServerManager.java | 70 ++++++------ .../mineplex/votifier/VotifierManager.java | 106 +++++++++--------- 8 files changed, 227 insertions(+), 132 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index e31bee5e0..d14ad88dc 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -58,6 +58,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; @@ -128,6 +129,8 @@ public class BonusManager extends MiniClientPlugin implements I private StreakRecord _dailyStreak; private StreakRecord _voteStreak; + private ArrayList _voteList; + /** * THIS SHOULD ONLY BE USED FOR VOTIFIER! */ @@ -140,6 +143,10 @@ public class BonusManager extends MiniClientPlugin implements I _clientManager = clientManager; _donationManager = donationManager; + _voteList = new ArrayList(); + _voteList.add("http://vote1.mineplex.com"); + _voteList.add("http://vote2.mineplex.com"); + updateOffSet(); } @@ -162,7 +169,10 @@ public class BonusManager extends MiniClientPlugin implements I _pollManager = pollManager; _statsManager = statsManager; - // Hope to god this works! + _voteList = new ArrayList(); + _voteList.add("http://vote1.mineplex.com"); + _voteList.add("http://vote2.mineplex.com"); + _canVote = true; if (npcManager != null) @@ -515,7 +525,7 @@ public class BonusManager extends MiniClientPlugin implements I { if (client.getVoteStreak() > 0 && client.getVoteTime() != null) { - long lastBonus = getLocalTime(client.getDailyTime().getTime()); + long lastBonus = getLocalTime(client.getVoteTime().getTime()); long timeLeft = getStreakTimeRemaining(lastBonus, BonusManager.VOTE_STREAK_RESET_TIME); if (timeLeft < 0) @@ -795,6 +805,23 @@ public class BonusManager extends MiniClientPlugin implements I new BonusGui(_plugin, event.getPlayer(), this, _rewardManager).openInventory(); } } + + @EventHandler + public void openGui(EntityDamageByEntityEvent event) + { + if (!_enabled) + return; + + if (event.getDamager() instanceof Player) + { + Player player = (Player) event.getDamager(); + if (event.getEntity().equals(_carlNpc.getEntity())) + { + updateDailyStreak(player); + new BonusGui(_plugin, player, this, _rewardManager).openInventory(); + } + } + } public static long getNextVoteTime(long time) { @@ -853,7 +880,7 @@ public class BonusManager extends MiniClientPlugin implements I int availableRewards = 0; if (canVote(player)) availableRewards++; - if (canRank(player) && _clientManager.hasRank(player, Rank.ULTRA)) availableRewards++; + if (canRank(player) && _clientManager.hasRank(player, Rank.ULTRA) && isPastAugust()) availableRewards++; if (canDaily(player)) availableRewards++; if (getPollManager().getNextPoll(_pollManager.Get(player), _clientManager.Get(player).GetRank()) != null) availableRewards++; @@ -1045,7 +1072,7 @@ public class BonusManager extends MiniClientPlugin implements I { if (Recharge.Instance.use(player, "Carl Inform", 240000, false, false)) { - if(_pollManager.hasPoll(player) || canVote(player) || canRank(player) || canDaily(player)) + if(_pollManager.hasPoll(player) || canVote(player) || (canRank(player) && _clientManager.hasRank(player, Rank.ULTRA) && isPastAugust()) || canDaily(player)) { if(_showCarl.containsKey(player.getName())) UtilPlayer.message(player, C.cDGreen + C.Bold + "Carl the Creeper>" + C.cGreen + " Hey " + player.getName().replace("s", "sss") + "! I have sssome amazing rewardsss for you! Come sssee me!"); @@ -1053,4 +1080,30 @@ public class BonusManager extends MiniClientPlugin implements I } } } + + public String getVoteLink() + { + long sqlTime = getSqlTime(); + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(sqlTime); + int date = calendar.get(Calendar.DAY_OF_YEAR); + int index = date % _voteList.size(); + return _voteList.get(index); + } + + /** + * Used for disabling rank rewards during first month of release + * @return + */ + public boolean isPastAugust() + { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(TIMEZONE); + calendar.setTimeInMillis(getSqlTime()); + + if (calendar.get(Calendar.YEAR) == 2015 && calendar.get(Calendar.MONTH) == Calendar.AUGUST) + return false; + + return true; + } } \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java index dadb04d31..52a57e3ec 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java @@ -6,9 +6,12 @@ import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; +import java.sql.Types; +import java.util.Map; import com.sun.org.apache.xpath.internal.operations.Bool; import mineplex.core.bonuses.gui.SpinGui; +import mineplex.core.common.Pair; import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; @@ -289,7 +292,7 @@ public class BonusRepository extends RepositoryBase }); } - public void attemptVoteBonus(final int accountId, final Callback result) + public void attemptVoteBonus(final int accountId, final Callback> result) { final int coins = 0; final int gems = 0; @@ -307,12 +310,12 @@ public class BonusRepository extends RepositoryBase callableStatement.setInt(1, accountId); callableStatement.setInt(2, coins); callableStatement.setInt(3, gems); - callableStatement.registerOutParameter(4, java.sql.Types.DATE); + callableStatement.registerOutParameter(4, Types.BOOLEAN); + callableStatement.registerOutParameter(5, Types.DATE); callableStatement.executeUpdate(); final boolean pass = callableStatement.getBoolean(4); - final Date date = callableStatement.getDate(5); Bukkit.getScheduler().runTask(plug, new Runnable() { @@ -321,8 +324,7 @@ public class BonusRepository extends RepositoryBase public void run() { // _manager.Get(player).setVoteTime(date); - result.run(date); - + result.run(Pair.create(pass, date)); } }); } catch (Exception e) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java index 8124e6292..8e7a5889e 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.HashMap; import mineplex.core.account.CoreClientManager; +import mineplex.core.bonuses.BonusAmount; import mineplex.core.bonuses.BonusManager; import mineplex.core.common.util.C; import mineplex.core.common.util.UtilText; @@ -94,7 +95,11 @@ public class PollButton extends SimpleGui implements GuiItem { i++; } lore.add(""); - lore.add(C.cYellow + "Reward:" + C.cWhite + " 500 Gems"); + BonusAmount amount = new BonusAmount(); + amount.setCoins(_poll.getCoinReward()); + amount.setGems(_poll.getCoinReward()); + amount.addLore(lore); +// lore.add(C.cYellow + "Reward:" + C.cWhite + " 500 Gems"); lore.add(""); lore.add(C.cGreen + "Click to go to the vote page!"); return ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, C.cGreen + C.Bold + "Vote on Poll", lore); @@ -130,7 +135,10 @@ public class PollButton extends SimpleGui implements GuiItem { i++; } lore.add(""); - lore.add(C.cYellow + "Reward:" + C.cWhite + " 500 Gems"); + BonusAmount amount = new BonusAmount(); + amount.setCoins(_poll.getCoinReward()); + amount.setGems(_poll.getCoinReward()); + amount.addLore(lore); return new SimpleGuiItem(ItemStackFactory.Instance.CreateStack(Material.BOOK_AND_QUILL, (byte) 0, 1, ChatColor.GREEN + C.cGreen + C.Bold + "Vote on Poll", lore)); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java index 489b257fd..5fe0fc0f0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/RankBonusButton.java @@ -78,7 +78,7 @@ public class RankBonusButton implements GuiItem, Listener { @Override public void click(ClickType clickType) { - if (isAvailable()) { + if (isAvailable() && _bonusManager.isPastAugust()) { _item = ItemStackFactory.Instance.CreateStack(Material.LAPIS_BLOCK, (byte)0, 1, ChatColor.BLUE + "Processing..."); refreshItem(); new LoadingWindow(getPlugin(), getPlayer(), 6*9); @@ -144,44 +144,56 @@ public class RankBonusButton implements GuiItem, Listener { String itemName; byte data = 0; - if (!hasRank) + if (_bonusManager.isPastAugust()) { - material = Material.REDSTONE_BLOCK; - itemName = C.cRed + ChatColor.BOLD + "Rank Monthly Bonus"; - lore.add(" "); - lore.add(ChatColor.WHITE + "Players with a Rank get a Monthly Bonus!"); - lore.add(ChatColor.WHITE + ""); - lore.add(ChatColor.AQUA + "Ultra receives 7500 Coins Monthly"); - lore.add(ChatColor.LIGHT_PURPLE + "Hero receives 15000 Coins Monthly"); - lore.add(ChatColor.GREEN + "Legend receives 30000 Coins Monthly"); - lore.add(ChatColor.WHITE + ""); - lore.add(ChatColor.WHITE + "Purchase a Rank at;"); - lore.add(ChatColor.WHITE + "www.mineplex.com/shop"); - } - else - { - if (isAvailable()) + if (!hasRank) { - material = Material.ENDER_CHEST; - itemName = C.cGreen + C.Bold + "Rank Monthly Bonus"; - + material = Material.REDSTONE_BLOCK; + itemName = C.cRed + ChatColor.BOLD + "Rank Monthly Bonus"; lore.add(" "); - lore.add(ChatColor.RESET + "Click to Claim!"); + lore.add(ChatColor.WHITE + "Players with a Rank get a Monthly Bonus!"); + lore.add(ChatColor.WHITE + ""); + lore.add(ChatColor.AQUA + "Ultra receives 7500 Coins Monthly"); + lore.add(ChatColor.LIGHT_PURPLE + "Hero receives 15000 Coins Monthly"); + lore.add(ChatColor.GREEN + "Legend receives 30000 Coins Monthly"); + lore.add(ChatColor.WHITE + ""); + lore.add(ChatColor.WHITE + "Purchase a Rank at;"); + lore.add(ChatColor.WHITE + "www.mineplex.com/shop"); } else { - material = Material.REDSTONE_BLOCK; - itemName = C.cRed + C.Bold + "Rank Monthly Bonus"; + if (isAvailable()) + { + material = Material.ENDER_CHEST; + itemName = C.cGreen + C.Bold + "Rank Monthly Bonus"; + + lore.add(" "); + lore.add(ChatColor.RESET + "Click to Claim!"); + } + else + { + material = Material.REDSTONE_BLOCK; + itemName = C.cRed + C.Bold + "Rank Monthly Bonus"; + + lore.add(" "); + lore.add(ChatColor.RESET + "Next reward in " + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) + "!"); + } lore.add(" "); - lore.add(ChatColor.RESET + "Next reward in " + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) + "!"); + lore.add(C.cYellow + "Rank: " + C.cWhite + _bonusManager.getClientManager().Get(_player).GetRank().Name); + BonusAmount bonusAmount = _bonusManager.getRankBonusAmount(_player); + bonusAmount.addLore(lore); } - - lore.add(" "); - lore.add(C.cYellow + "Rank: " + C.cWhite + _bonusManager.getClientManager().Get(_player).GetRank().Name); - BonusAmount bonusAmount = _bonusManager.getRankBonusAmount(_player); - bonusAmount.addLore(lore); } + else + { + itemName = C.cRed + ChatColor.BOLD + "Rank Monthly Bonus"; + material = Material.REDSTONE_BLOCK; + lore.add(" "); + lore.add(ChatColor.RESET + "You can claim your Monthly Bonus"); + lore.add(ChatColor.RESET + "here, starting from September!"); + } + _item = new ShopItem(material, itemName, lore.toArray(new String[0]), 1, false, false); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java index 9009fb7e0..f277129b9 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java @@ -51,7 +51,7 @@ public class VoteButton implements GuiItem, Listener { public void setup() { //TODO get url from db - _url = "http://minecraftservers.org/vote/121070"; + _url = _bonusManager.getVoteLink(); setItem(); Bukkit.getPluginManager().registerEvents(this, getPlugin()); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java index fa0b5daa0..09f0e4ec3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/poll/PollManager.java @@ -149,6 +149,7 @@ public class PollManager extends MiniDbClientPlugin { final String name = player.getName(); final UUID uuid = player.getUniqueId(); + final int accountId = getClientManager().getAccountId(player); // First update answer locally so we know it was answered Get(player).addAnswer(poll.getId(), answer); @@ -169,17 +170,28 @@ public class PollManager extends MiniDbClientPlugin { if (completed) { - // Need to get out of Async code - _plugin.getServer().getScheduler().runTask(_plugin, new Runnable() + _donationManager.RewardCoins(new Callback() { @Override - public void run() + public void run(Boolean completed) { - UtilPlayer.message(player, F.main("Poll", "Thanks for your response!")); - player.playSound(player.getEyeLocation(), Sound.LEVEL_UP, 1F, 0); - UtilPlayer.message(player, F.main("Gem", "You received " + F.elem(poll.getCoinReward() + "") + " Gems!")); + if (completed) + { + // Need to get out of Async code + _plugin.getServer().getScheduler().runTask(_plugin, new Runnable() + { + @Override + public void run() + { + UtilPlayer.message(player, F.main("Carl", "Thanks for your response!")); + player.playSound(player.getEyeLocation(), Sound.LEVEL_UP, 1F, 0); + UtilPlayer.message(player, F.main("Carl", "You received " + F.elem(poll.getCoinReward() + "") + " Gems!")); + UtilPlayer.message(player, F.main("Carl", "You received " + F.elem(poll.getCoinReward() + "") + " Coins!")); + } + }); + } } - }); + }, "Poll", name, accountId, poll.getCoinReward()); } } }, "Poll", name, uuid, poll.getCoinReward()); diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java index 4ed251ae4..1c40dab73 100644 --- a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java @@ -93,41 +93,45 @@ public class ServerManager public static RedisConfig getConfig(String fileName) { if (_config == null) - { - try - { - File configFile = new File(fileName); - - if (configFile.exists()) - { - List connections = new ArrayList(); - List lines = Files.readAllLines(configFile.toPath(), Charset.defaultCharset()); - - for (String line : lines) - { - ConnectionData connection = deserializeConnection(line); - connections.add(connection); - - } - - _config = new RedisConfig(connections); - } - else - { - log(fileName + " not found at " + configFile.toPath().toString()); - _config = new RedisConfig(); - } - } - catch (Exception exception) - { - exception.printStackTrace(); - log("---Unable To Parse Redis Configuration File---"); - } - - } - + _config = loadConfig(fileName); + return _config; } + + public static RedisConfig loadConfig(String fileName) + { + try + { + File configFile = new File(fileName); + + if (configFile.exists()) + { + List connections = new ArrayList(); + List lines = Files.readAllLines(configFile.toPath(), Charset.defaultCharset()); + + for (String line : lines) + { + ConnectionData connection = deserializeConnection(line); + connections.add(connection); + + } + + return new RedisConfig(connections); + } + else + { + log(fileName + " not found at " + configFile.toPath().toString()); + return new RedisConfig(); + } + } + catch (Exception exception) + { + exception.printStackTrace(); + log("---Unable To Parse Redis Configuration File---"); + } + + return null; + } /** * @param line - the serialized line representing a valid {@link ConnectionData} object. diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index ff124fa76..de00742a1 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -13,6 +13,7 @@ import mineplex.core.account.CoreClientManager; import mineplex.core.bonuses.BonusAmount; import mineplex.core.bonuses.BonusClientData; import mineplex.core.bonuses.BonusManager; +import mineplex.core.common.Pair; import mineplex.core.common.util.Callback; import mineplex.core.common.util.UUIDFetcher; import mineplex.core.database.DBPool; @@ -45,8 +46,8 @@ public class VotifierManager extends MiniPlugin private RedisConfig _usConfig; private RedisConfig _euConfig; - private RedisDataRepository _usPlayerRepo; - private RedisDataRepository _euPlayerRepo; +// private RedisDataRepository _usPlayerRepo; +// private RedisDataRepository _euPlayerRepo; private JedisPool _usWritePool; private JedisPool _euWritePool; @@ -58,13 +59,13 @@ public class VotifierManager extends MiniPlugin _donationManager = donationManager; _bonusManager = bonusManager; - _usConfig = ServerManager.getConfig("us-redis.dat"); - _euConfig = ServerManager.getConfig("eu-redis.dat"); + _usConfig = ServerManager.loadConfig("us-redis.dat"); + _euConfig = ServerManager.loadConfig("eu-redis.dat"); - _usPlayerRepo = new RedisDataRepository(_usConfig.getConnection(true, "DefaultConnection"), - _usConfig.getConnection(false, "DefaultConnection"), Region.US, PlayerStatus.class, "playerStatus"); - _euPlayerRepo = new RedisDataRepository(_euConfig.getConnection(true, "DefaultConnection"), - _euConfig.getConnection(false, "DefaultConnection"), Region.EU, PlayerStatus.class, "playerStatus"); +// _usPlayerRepo = new RedisDataRepository(_usConfig.getConnection(true, "DefaultConnection"), +// _usConfig.getConnection(false, "DefaultConnection"), Region.US, PlayerStatus.class, "playerStatus"); +// _euPlayerRepo = new RedisDataRepository(_euConfig.getConnection(true, "DefaultConnection"), +// _euConfig.getConnection(false, "DefaultConnection"), Region.EU, PlayerStatus.class, "playerStatus"); _usWritePool = Utility.generatePool(_usConfig.getConnection(true, "DefaultConnection")); _euWritePool = Utility.generatePool(_euConfig.getConnection(true, "DefaultConnection")); @@ -98,6 +99,7 @@ public class VotifierManager extends MiniPlugin public void run(Integer gems) { notifyServer(playerName, gems, false); + notifyServer(playerName, gems, true); } }); System.out.println(); @@ -146,7 +148,7 @@ public class VotifierManager extends MiniPlugin publishCommand(command, writePool); } - private void awardBonus(final String playerName, UUID uuid, final Callback onComplete) + private void awardBonus(final String playerName, final UUID uuid, final Callback onComplete) { DSLContext create = DSL.using(DBPool.ACCOUNT, SQLDialect.MYSQL); @@ -158,52 +160,50 @@ public class VotifierManager extends MiniPlugin final BonusAmount amount = _bonusManager.getVoteBonusAmount(client); - // Reward Amount - if (amount.getTickets() > 0) - client.setTickets(client.getTickets() + amount.getTickets()); - - if (amount.getTotalGems() > 0) - { - _donationManager.RewardGems(new Callback() - { - @Override - public void run(Boolean data) - { - if (data) - System.out.println("Gave " + amount.getGems() + " gems to " + playerName); - else - System.out.println("Failed to give " + amount.getGems() + " gems to " + playerName); - } - }, "Votifier", playerName, uuid, amount.getTotalGems()); - } - - if (amount.getTotalCoins() > 0) - { - _donationManager.RewardCoins(new Callback() - { - @Override - public void run(Boolean data) - { - if (data) - System.out.println("Gave " + amount.getGems() + " coins to " + playerName); - else - System.out.println("Failed to give " + amount.getGems() + " coins to " + playerName); - } - }, "Votifier", playerName, accountId, amount.getTotalCoins()); - } - - // Check if we need to reset vote streak - _bonusManager.updateVoteStreak(client); - - // Update time - _bonusManager.getRepository().attemptVoteBonus(accountId, new Callback() + _bonusManager.getRepository().attemptVoteBonus(accountId, new Callback>() { @Override - public void run(Date data) + public void run(Pair pair) { - if (data != null) + if (pair.getLeft()) { - client.getRecord().setVotetime(data); + // Reward Amount + if (amount.getTickets() > 0) + client.setTickets(client.getTickets() + amount.getTickets()); + + if (amount.getTotalGems() > 0) + { + _donationManager.RewardGems(new Callback() + { + @Override + public void run(Boolean data) + { + if (data) + System.out.println("Gave " + amount.getGems() + " gems to " + playerName); + else + System.out.println("Failed to give " + amount.getGems() + " gems to " + playerName); + } + }, "Votifier", playerName, uuid, amount.getTotalGems()); + } + + if (amount.getTotalCoins() > 0) + { + _donationManager.RewardCoins(new Callback() + { + @Override + public void run(Boolean data) + { + if (data) + System.out.println("Gave " + amount.getGems() + " coins to " + playerName); + else + System.out.println("Failed to give " + amount.getGems() + " coins to " + playerName); + } + }, "Votifier", playerName, accountId, amount.getTotalCoins()); + } + + // Check if we need to reset vote streak + _bonusManager.updateVoteStreak(client); + client.getRecord().setVotetime(pair.getRight()); // Update Streak _bonusManager.incrementVoteStreak(client); @@ -212,6 +212,10 @@ public class VotifierManager extends MiniPlugin System.out.println("Awarded carl ticket to " + playerName); onComplete.run(amount.getTotalGems()); } + else + { + System.out.println(playerName + " attempted to vote, vote bonus returned false!"); + } } }); } From 37e5e97020bd8b67919d287853ab96a967a9e7df Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Wed, 12 Aug 2015 03:08:40 -0500 Subject: [PATCH 350/377] Fix experience reward displaying as game --- .../src/mineplex/core/reward/rewards/ExperienceReward.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java index a96245c6f..ad1ad3b5b 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/rewards/ExperienceReward.java @@ -35,13 +35,13 @@ public class ExperienceReward extends Reward _statsManager.incrementStat(player, "Global.ExpEarned", experience); - return new RewardData(getRarity().getColor() + experience + " Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.GAME); + return new RewardData(getRarity().getColor() + experience + " Experience", new ItemStack(Material.EXP_BOTTLE), getRarity()); } @Override public RewardData getFakeRewardData(Player player) { - return new RewardData(getRarity().getColor() + "Experience", new ItemStack(Material.EXP_BOTTLE), RewardRarity.GAME); + return new RewardData(getRarity().getColor() + "Experience", new ItemStack(Material.EXP_BOTTLE), getRarity()); } @Override From cd5c7e71101c9810d14c1a22e4fdede4339f1609 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Wed, 12 Aug 2015 11:23:19 +0200 Subject: [PATCH 351/377] fixed kb --- Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java | 2 +- .../Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java index cd465fce0..a44b61da0 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java @@ -157,7 +157,7 @@ public class KothManager extends MiniPlugin if (bottom.getVehicle() != null) bottom = bottom.getVehicle(); - UtilAction.velocity(bottom, UtilAlg.getTrajectory(bounce, player.getLocation()), 1, false, 0, 0.4, 1, true); + UtilAction.velocity(bottom, UtilAlg.getTrajectory2d(bounce, player.getLocation()), 1.2, false, 0, 0.6, 1, true); if (Recharge.Instance.use(player, "KOTH Eject", 5000, false, false)) { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java index 462b0d7cf..3e87b22d3 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -419,7 +419,7 @@ public class SoccerManager extends MiniPlugin if (bottom.getVehicle() != null) bottom = bottom.getVehicle(); - UtilAction.velocity(bottom, UtilAlg.getTrajectory(bounce, player.getLocation()), 1, false, 0, 0.4, 1, true); + UtilAction.velocity(bottom, UtilAlg.getTrajectory2d(bounce, player.getLocation()), 1, false, 0, 0.8, 1, true); if (Recharge.Instance.use(player, "Soccer Eject", 5000, false, false)) { From 5293e244693f628d4d667970296c88bfc5da7cd2 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Wed, 12 Aug 2015 11:58:40 +0200 Subject: [PATCH 352/377] fixed text --- .../Mineplex.Hub/src/mineplex/hub/modules/KothManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java index a44b61da0..373bb1e5d 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/KothManager.java @@ -161,8 +161,8 @@ public class KothManager extends MiniPlugin if (Recharge.Instance.use(player, "KOTH Eject", 5000, false, false)) { - UtilPlayer.message(player, F.main("Football", "You must be wearing a Team Outfit.")); - UtilPlayer.message(player, F.main("Football", "Type " + F.elem("/team red|yellow|green|blue") + "!")); + UtilPlayer.message(player, F.main("KOTH", "You must be wearing a Team Outfit.")); + UtilPlayer.message(player, F.main("KOTH", "Type " + F.elem("/team red|yellow|green|blue") + "!")); } } } From d1302e8dc37449074b9a3cfab7dbcbb15e53f56f Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Wed, 12 Aug 2015 12:42:59 +0200 Subject: [PATCH 353/377] fixed full msg --- .../Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java index 3e87b22d3..2b2c32564 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -423,15 +423,14 @@ public class SoccerManager extends MiniPlugin if (Recharge.Instance.use(player, "Soccer Eject", 5000, false, false)) { - if (_active.size() >= 8) + if (_active.size() < 8) { UtilPlayer.message(player, F.main("Soccer", "You must be wearing Red/Blue Team Outfit.")); UtilPlayer.message(player, F.main("Soccer", "Type " + F.elem("/team red") + " or " + F.elem("/team blue") + "!")); } else { - UtilPlayer.message(player, F.main("Soccer", "You must be wearing Red/Blue Team Outfit.")); - UtilPlayer.message(player, F.main("Soccer", "Type " + F.elem("/team red") + " or " + F.elem("/team blue") + "!")); + UtilPlayer.message(player, F.main("Soccer", "The game is currently full!")); } } } From fcfb2559b8a467b04caf205c1be76957292d73fd Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Wed, 12 Aug 2015 14:41:33 +0200 Subject: [PATCH 354/377] players cannot grab slime :O --- .../Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java index 2b2c32564..6383be7a3 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -493,6 +493,9 @@ public class SoccerManager extends MiniPlugin { if (_active.contains(event.getPlayer())) event.setCancelled(true); + + if (_ball != null && event.getRightClicked().equals(_ball)) + event.setCancelled(true); } @EventHandler From 4f163af909ca97b71b74d2b8c9c302a807a79ce2 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Wed, 12 Aug 2015 18:36:29 +0200 Subject: [PATCH 355/377] fixed a uid problem with maps --- .../src/mineplex/mapparser/command/MapCommand.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Plugins/Mineplex.MapParser/src/mineplex/mapparser/command/MapCommand.java b/Plugins/Mineplex.MapParser/src/mineplex/mapparser/command/MapCommand.java index 490f4b8cf..a229e5e07 100644 --- a/Plugins/Mineplex.MapParser/src/mineplex/mapparser/command/MapCommand.java +++ b/Plugins/Mineplex.MapParser/src/mineplex/mapparser/command/MapCommand.java @@ -1,5 +1,6 @@ package mineplex.mapparser.command; +import java.io.File; import java.util.List; import org.bukkit.Bukkit; @@ -77,6 +78,18 @@ public class MapCommand extends BaseCommand message(player, "That map is being backed up now. Try again soon"); return true; } + + //Delete UID + File file = new File(worldName + "/uid.dat"); + if (file.exists()) + { + System.out.println("Deleting uid.dat for " + worldName); + file.delete(); + } + else + { + System.out.println("Could not delete uid.dat for " + worldName); + } World world = getPlugin().GetMapWorld(worldName); if (world == null) From 05b1b91686598ce12065216304dcec75c8f53592 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 13 Aug 2015 03:32:31 -0500 Subject: [PATCH 356/377] Carl! --- .../bungee/playerTracker/PlayerTracker.java | 2 +- .../mineplex/core/bonuses/BonusManager.java | 99 +++++++++++++------ .../mineplex/core/bonuses/GiveDonorData.java | 50 ++++++++++ .../core/bonuses/gui/buttons/VoteButton.java | 11 +-- .../core/friend/data/FriendRepository.java | 4 +- .../serverdata/data/PlayerStatus.java | 2 +- .../mineplex/votifier/VotifierManager.java | 84 ++++++++++------ 7 files changed, 183 insertions(+), 69 deletions(-) create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/bonuses/GiveDonorData.java diff --git a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTracker.java b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTracker.java index 24e40892c..1b8117d04 100644 --- a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTracker.java +++ b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTracker.java @@ -56,7 +56,7 @@ public class PlayerTracker implements Listener { public void run() { - _repository.removeElement(event.getPlayer().getName()); + _repository.removeElement(event.getPlayer().getName().toLowerCase()); } }); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 2521d993c..8ed1721c4 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -7,6 +7,8 @@ import java.util.Calendar; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; +import java.util.Queue; import java.util.TimeZone; import mineplex.core.MiniClientPlugin; @@ -53,11 +55,9 @@ import mineplex.serverdata.commands.ServerCommandManager; import org.jooq.SQLDialect; import org.jooq.impl.DSL; import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; import org.bukkit.entity.Entity; -import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDamageByEntityEvent; @@ -133,6 +133,10 @@ public class BonusManager extends MiniClientPlugin implements I private ArrayList _voteList; + // Donor Queues + private Queue _coinQueue; + private Queue _gemQueue; + /** * THIS SHOULD ONLY BE USED FOR VOTIFIER! */ @@ -149,6 +153,9 @@ public class BonusManager extends MiniClientPlugin implements I _voteList.add("http://vote1.mineplex.com"); _voteList.add("http://vote2.mineplex.com"); + _coinQueue = new LinkedList(); + _gemQueue = new LinkedList(); + updateOffSet(); } @@ -176,6 +183,9 @@ public class BonusManager extends MiniClientPlugin implements I _voteList.add("http://vote2.mineplex.com"); _canVote = true; + _coinQueue = new LinkedList(); + _gemQueue = new LinkedList(); + if (npcManager != null) { @@ -279,7 +289,7 @@ public class BonusManager extends MiniClientPlugin implements I { addPendingExplosion(player, player.getName()); UtilPlayer.message(player, F.main("Carl", "Thanks for voting for Mineplex!")); - UtilPlayer.message(player, F.main("Carl", "You received " + gemsRecieved + " Gems and 1 Carl Spinner Ticket!")); + UtilPlayer.message(player, F.main("Carl", "You received " + F.elem(gemsRecieved + " Gems") + " and " + F.elem("1 Carl Spinner Ticket") + "!")); } }); } @@ -700,20 +710,7 @@ public class BonusManager extends MiniClientPlugin implements I if (gems > 0) { UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(gems + " Gems"))); - _donationManager.RewardGems(new Callback() - { - @Override - public void run(Boolean data) - { - if (data) - { - } - else - { - UtilPlayer.message(player, F.main("Carl", "Failed to process Gems")); - } - } - }, "Earned", player.getName(), player.getUniqueId(), gems, true); + _gemQueue.add(new GiveDonorData(player.getName(), coreClient.getAccountId(), player.getUniqueId(), gems)); } if (gold > 0) @@ -738,20 +735,7 @@ public class BonusManager extends MiniClientPlugin implements I if (coins > 0) { UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(coins + " Coins"))); - _donationManager.RewardCoins(new Callback() - { - @Override - public void run(Boolean data) - { - if (data) - { - } - else - { - UtilPlayer.message(player, F.main("Carl", "Failed to process Coins")); - } - } - }, "Earned", player.getName(), coreClient.getAccountId(), coins, true); + _coinQueue.add(new GiveDonorData(player.getName(), coreClient.getAccountId(), player.getUniqueId(), coins)); } if (tickets > 0) @@ -1065,6 +1049,59 @@ public class BonusManager extends MiniClientPlugin implements I } } + @EventHandler + public void processQueue(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTER) + return; + + // Gems + final GiveDonorData gemData = _gemQueue.poll(); + if (gemData != null && gemData.getAttempts() < 10) + { + _donationManager.RewardGems(new Callback() + { + @Override + public void run(Boolean data) + { + if (data) + { + System.out.println("Successfully processed " + gemData.getGiveAmount() + " gems for " + gemData.getPlayerName()); + } + else + { + gemData.incrementAttempts(); + System.out.println("Failed to process gems for " + gemData.getPlayerName() + " adding to back of queue. Attempts: " + gemData.getAttempts()); + _gemQueue.add(gemData); + } + } + }, "Earned", gemData.getPlayerName(), gemData.getUuid(), gemData.getGiveAmount()); + } + + // Coins + final GiveDonorData coinData = _coinQueue.poll(); + if (coinData != null && coinData.getAttempts() < 10) + { + _donationManager.RewardCoins(new Callback() + { + @Override + public void run(Boolean data) + { + if (data) + { + System.out.println("Successfully processed " + coinData.getGiveAmount() + " coins for " + coinData.getPlayerName()); + } + else + { + coinData.incrementAttempts(); + System.out.println("Failed to process coins for " + coinData.getPlayerName() + " adding to back of queue. Attempts: " + coinData.getAttempts()); + _coinQueue.add(coinData); + } + } + }, "Earned", coinData.getPlayerName(), coinData.getAccountId(), coinData.getGiveAmount()); + } + } + public String getVoteLink() { long sqlTime = getSqlTime(); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/GiveDonorData.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/GiveDonorData.java new file mode 100644 index 000000000..1aa07d0d5 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/GiveDonorData.java @@ -0,0 +1,50 @@ +package mineplex.core.bonuses; + +import java.util.UUID; + +public class GiveDonorData +{ + private String _playerName; + private int _accountId; + private UUID _uuid; + private int _giveAmount; + private int _attempts; + + public GiveDonorData(String playerName, int accountId, UUID uuid, int giveAmount) + { + _playerName = playerName; + _accountId = accountId; + _uuid = uuid; + _giveAmount = giveAmount; + } + + public String getPlayerName() + { + return _playerName; + } + + public int getAccountId() + { + return _accountId; + } + + public UUID getUuid() + { + return _uuid; + } + + public int getGiveAmount() + { + return _giveAmount; + } + + public int getAttempts() + { + return _attempts; + } + + public void incrementAttempts() + { + _attempts++; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java index f277129b9..6bd8f9638 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java @@ -72,17 +72,16 @@ public class VoteButton implements GuiItem, Listener { getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); - UtilPlayer.message(getPlayer(), "----------------------------------------"); + UtilPlayer.message(getPlayer(), "----------------------------------------------------"); UtilPlayer.message(getPlayer(), ""); new JsonMessage("Click to Open in Web Browser").click(ClickEvent.OPEN_URL, _url).sendToPlayer(getPlayer()); new JsonMessage(C.cGreen + _url).click(ClickEvent.OPEN_URL, _url).sendToPlayer(getPlayer()); - UtilPlayer.message(getPlayer(), ""); - UtilPlayer.message(getPlayer(), "----------------------------------------"); - - - + UtilPlayer.message(getPlayer(), "Please be patient, votes may take a few minutes to register."); + UtilPlayer.message(getPlayer(), ""); + UtilPlayer.message(getPlayer(), "----------------------------------------------------"); + getPlayer().closeInventory(); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/friend/data/FriendRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/friend/data/FriendRepository.java index 359220020..c7ab1ae90 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/friend/data/FriendRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/friend/data/FriendRepository.java @@ -159,7 +159,7 @@ public class FriendRepository extends RepositoryBase Set friendNames = new HashSet(); for(FriendStatus status : friendData.getFriends()) { - friendNames.add(status.Name); + friendNames.add(status.Name.toLowerCase()); } // Load PlayerStatus' for friends @@ -188,7 +188,7 @@ public class FriendRepository extends RepositoryBase */ public String fetchPlayerServer(String playerName) { - PlayerStatus status = _repository.getElement(playerName); + PlayerStatus status = _repository.getElement(playerName.toLowerCase()); return (status == null) ? null : status.getServer(); } diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/data/PlayerStatus.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/data/PlayerStatus.java index 509006ca0..605caa387 100644 --- a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/data/PlayerStatus.java +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/data/PlayerStatus.java @@ -28,6 +28,6 @@ public class PlayerStatus implements Data */ public String getDataId() { - return _name; + return _name.toLowerCase(); } } diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index de00742a1..c87ef4896 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -46,8 +46,8 @@ public class VotifierManager extends MiniPlugin private RedisConfig _usConfig; private RedisConfig _euConfig; -// private RedisDataRepository _usPlayerRepo; -// private RedisDataRepository _euPlayerRepo; + private RedisDataRepository _usPlayerRepo; + private RedisDataRepository _euPlayerRepo; private JedisPool _usWritePool; private JedisPool _euWritePool; @@ -62,10 +62,10 @@ public class VotifierManager extends MiniPlugin _usConfig = ServerManager.loadConfig("us-redis.dat"); _euConfig = ServerManager.loadConfig("eu-redis.dat"); -// _usPlayerRepo = new RedisDataRepository(_usConfig.getConnection(true, "DefaultConnection"), -// _usConfig.getConnection(false, "DefaultConnection"), Region.US, PlayerStatus.class, "playerStatus"); -// _euPlayerRepo = new RedisDataRepository(_euConfig.getConnection(true, "DefaultConnection"), -// _euConfig.getConnection(false, "DefaultConnection"), Region.EU, PlayerStatus.class, "playerStatus"); + _usPlayerRepo = new RedisDataRepository(_usConfig.getConnection(true, "DefaultConnection"), + _usConfig.getConnection(false, "DefaultConnection"), Region.US, PlayerStatus.class, "playerStatus"); + _euPlayerRepo = new RedisDataRepository(_euConfig.getConnection(true, "DefaultConnection"), + _euConfig.getConnection(false, "DefaultConnection"), Region.EU, PlayerStatus.class, "playerStatus"); _usWritePool = Utility.generatePool(_usConfig.getConnection(true, "DefaultConnection")); _euWritePool = Utility.generatePool(_euConfig.getConnection(true, "DefaultConnection")); @@ -74,32 +74,60 @@ public class VotifierManager extends MiniPlugin @EventHandler public void handleVote(VotifierEvent event) { - Vote vote = event.getVote(); + final Vote vote = event.getVote(); final String playerName = vote.getUsername(); System.out.println("New Vote: " + playerName); - UUID uuid = UUIDFetcher.getUUIDOf(playerName); - if (uuid == null) - { - System.out.println("Failed to load UUID of " + playerName + " from UUIDFetcher. Trying with database"); - uuid = _clientManager.loadUUIDFromDB(playerName); - - if (uuid == null) - { - System.out.println("Failed to load UUID from database. Giving up on " + playerName); - } - } - - System.out.println("Loaded " + playerName + " with uuid " + uuid); - System.out.println("Attempting to award bonus"); - awardBonus(playerName, uuid, new Callback() + runAsync(new Runnable() { @Override - public void run(Integer gems) + public void run() { - notifyServer(playerName, gems, false); - notifyServer(playerName, gems, true); + UUID uuid = UUIDFetcher.getUUIDOf(playerName); + if (uuid == null) + { + System.out.println("Failed to load UUID of " + playerName + " from UUIDFetcher. Trying with database"); + uuid = _clientManager.loadUUIDFromDB(playerName); + + if (uuid == null) + { + System.out.println("Failed to load UUID from database. Giving up on " + playerName); + } + } + + String lowerPlayerName = playerName.toLowerCase(); + final PlayerStatus usStatus = _usPlayerRepo.getElement(lowerPlayerName); + final PlayerStatus euStatus = _euPlayerRepo.getElement(lowerPlayerName); + + System.out.println("Loaded " + playerName + " with uuid " + uuid); + System.out.println("Attempting to award bonus"); + final UUID finalUuid = uuid; + awardBonus(playerName, finalUuid, new Callback() + { + @Override + public void run(final Integer gems) + { + runSync(new Runnable() + { + @Override + public void run() + { + if (usStatus != null) + { + System.out.println("Found " + playerName + " on US " + usStatus.getServer()); + notifyServer(playerName, gems, Region.US, usStatus.getServer()); + } + + if (euStatus != null) + { + System.out.println("Found " + playerName + " on EU " + euStatus.getServer()); + notifyServer(playerName, gems, Region.EU, euStatus.getServer()); + } + } + }); + } + }); } }); System.out.println(); @@ -140,11 +168,11 @@ public class VotifierManager extends MiniPlugin // notifyServer(playerName, true); } - private void notifyServer(String playerName, int gems, boolean eu) + private void notifyServer(String playerName, int gems, Region region, String targetServer) { - JedisPool writePool = eu ? _euWritePool : _usWritePool; + JedisPool writePool = region == Region.EU ? _euWritePool : _usWritePool; - VotifierCommand command = new VotifierCommand(playerName, gems); + VotifierCommand command = new VotifierCommand(playerName, gems, targetServer); publishCommand(command, writePool); } From 11a4805c3890a88431df5dae03b1966d5c224753 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 13 Aug 2015 03:54:23 -0500 Subject: [PATCH 357/377] Stat stuff! --- .../src/mineplex/core/achievement/AchievementCategory.java | 4 ++-- .../Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementCategory.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementCategory.java index 9c9491ad5..d19f0e93a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementCategory.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/AchievementCategory.java @@ -15,7 +15,7 @@ import mineplex.core.stats.StatsManager; public enum AchievementCategory { GLOBAL("Global", null, - new StatDisplay[] { StatDisplay.GEMS_EARNED, null, new StatDisplay("Games Played", "GamesPlayed"), StatDisplay.TIME_IN_GAME }, + new StatDisplay[] { StatDisplay.GEMS_EARNED, null, new StatDisplay("Games Played", "GamesPlayed"), StatDisplay.TIME_IN_GAME, null, new StatDisplay("Daily Rewards", "DailyReward"), new StatDisplay("Times Voted", "DailyVote") }, Material.EMERALD, 0, GameCategory.GLOBAL, "None"), BRIDGES("The Bridges", null, @@ -28,7 +28,7 @@ public enum AchievementCategory SKYWARS("Skywars",null, new StatDisplay[]{StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED}, - Material.FEATHER, 5, GameCategory.SURVIVAL, "Destructor Kit"), + Material.FEATHER, 0, GameCategory.SURVIVAL, "Destructor Kit"), UHC("Ultra Hardcore", null, new StatDisplay[] { StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.KILLS, StatDisplay.DEATHS, StatDisplay.GEMS_EARNED }, diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 8ed1721c4..72b110a18 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -287,6 +287,7 @@ public class BonusManager extends MiniClientPlugin implements I @Override public void run() { + _statsManager.incrementStat(player, "Global.DailyVote", 1); addPendingExplosion(player, player.getName()); UtilPlayer.message(player, F.main("Carl", "Thanks for voting for Mineplex!")); UtilPlayer.message(player, F.main("Carl", "You received " + F.elem(gemsRecieved + " Gems") + " and " + F.elem("1 Carl Spinner Ticket") + "!")); @@ -416,6 +417,8 @@ public class BonusManager extends MiniClientPlugin implements I incrementDailyStreak(player); awardBonus(player, amount); updateCreeperVisual(player, true, C.cAqua); + + _statsManager.incrementStat(player, "Global.DailyReward", 1); } result.run(r); From 0c68321e81a90889cd3d79a92245417abacfd62e Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 13 Aug 2015 03:58:05 -0500 Subject: [PATCH 358/377] Global button --- .../mineplex/core/achievement/ui/page/AchievementMainPage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementMainPage.java b/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementMainPage.java index 2ab5e498f..7867fab9a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementMainPage.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/achievement/ui/page/AchievementMainPage.java @@ -57,7 +57,7 @@ public class AchievementMainPage extends ShopPageBase lore = new ArrayList(); lore.add(" "); - category.addStats(getClientManager(), _statsManager, lore, category == AchievementCategory.GLOBAL ? 5 : 2, + category.addStats(getClientManager(), _statsManager, lore, category == AchievementCategory.GLOBAL ? 10 : 2, getPlayer(), _target); lore.add(" "); addAchievements(category, lore, 9); From 92c0e1452bfe3c5f2100fd51f50656a6eef5df63 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 13 Aug 2015 04:01:53 -0500 Subject: [PATCH 359/377] Add vote3 --- .../Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 72b110a18..29fd9899c 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -152,6 +152,7 @@ public class BonusManager extends MiniClientPlugin implements I _voteList = new ArrayList(); _voteList.add("http://vote1.mineplex.com"); _voteList.add("http://vote2.mineplex.com"); + _voteList.add("http://vote3.mineplex.com"); _coinQueue = new LinkedList(); _gemQueue = new LinkedList(); @@ -181,6 +182,7 @@ public class BonusManager extends MiniClientPlugin implements I _voteList = new ArrayList(); _voteList.add("http://vote1.mineplex.com"); _voteList.add("http://vote2.mineplex.com"); + _voteList.add("http://vote3.mineplex.com"); _canVote = true; _coinQueue = new LinkedList(); From 4d6e827739742b654f296b5d872644c615857132 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 13 Aug 2015 04:03:03 -0500 Subject: [PATCH 360/377] Remove vote3! --- .../Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 29fd9899c..72b110a18 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -152,7 +152,6 @@ public class BonusManager extends MiniClientPlugin implements I _voteList = new ArrayList(); _voteList.add("http://vote1.mineplex.com"); _voteList.add("http://vote2.mineplex.com"); - _voteList.add("http://vote3.mineplex.com"); _coinQueue = new LinkedList(); _gemQueue = new LinkedList(); @@ -182,7 +181,6 @@ public class BonusManager extends MiniClientPlugin implements I _voteList = new ArrayList(); _voteList.add("http://vote1.mineplex.com"); _voteList.add("http://vote2.mineplex.com"); - _voteList.add("http://vote3.mineplex.com"); _canVote = true; _coinQueue = new LinkedList(); From 94c00cdb726a82507f03a0b0f64a3435c31e7a11 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 13 Aug 2015 04:05:28 -0500 Subject: [PATCH 361/377] Adding some comments --- .../src/mineplex/serverdata/data/PlayerStatus.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/data/PlayerStatus.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/data/PlayerStatus.java index 605caa387..5cb4d9072 100644 --- a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/data/PlayerStatus.java +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/data/PlayerStatus.java @@ -25,6 +25,8 @@ public class PlayerStatus implements Data /** * Unique identifying String ID associated with this {@link PlayerStatus}. + * + * Use the lowercase name so we can have case-insensitive lookup */ public String getDataId() { From e1d04354fbfbe7b4e4f045d86704fb6871c1ecd7 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 13 Aug 2015 05:18:53 -0500 Subject: [PATCH 362/377] Use dummy record for AddPlayer --- .../Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 72b110a18..b708466c1 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -950,7 +950,8 @@ public class BonusManager extends MiniClientPlugin implements I protected BonusClientData AddPlayer(String player) { // Should never be called! - return null; + BonusRecord record = new BonusRecord(); + return new BonusClientData(record); } public BonusRepository getRepository() From f3b58fe9b6bc83193dc9f6fe0d3a145e5187d6f7 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Thu, 13 Aug 2015 12:51:57 +0200 Subject: [PATCH 363/377] disabled team armor command in games D: --- .../src/mineplex/core/gadget/gadgets/OutfitTeam.java | 10 ++++++++++ .../src/nautilus/game/arcade/ArcadeManager.java | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java index 697f398c4..9090eb81e 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/gadget/gadgets/OutfitTeam.java @@ -27,6 +27,8 @@ import mineplex.core.recharge.Recharge; public class OutfitTeam extends OutfitGadget { + private boolean _enabled = true; + private HashMap _colorSetting = new HashMap(); public OutfitTeam(GadgetManager manager, String name, @@ -100,6 +102,9 @@ public class OutfitTeam extends OutfitGadget @EventHandler(priority=EventPriority.LOWEST) public void setColor(PlayerCommandPreprocessEvent event) { + if (!_enabled) + return; + Player player = event.getPlayer(); if (!event.getMessage().toLowerCase().startsWith("/team")) @@ -235,4 +240,9 @@ public class OutfitTeam extends OutfitGadget { return _colorSetting.get(player.getName()); } + + public void setEnabled(boolean var) + { + _enabled = var; + } } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java index a45740b47..2ed9210ab 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java @@ -63,6 +63,9 @@ import mineplex.core.donation.DonationManager; import mineplex.core.elo.EloManager; import mineplex.core.energy.Energy; import mineplex.core.explosion.Explosion; +import mineplex.core.gadget.gadgets.OutfitTeam; +import mineplex.core.gadget.types.Gadget; +import mineplex.core.gadget.types.GadgetType; import mineplex.core.hologram.HologramManager; import mineplex.core.inventory.InventoryManager; import mineplex.core.itemstack.ItemStackFactory; @@ -1192,6 +1195,15 @@ public class ArcadeManager extends MiniPlugin implements IRelation } } } + + //Disable Team Armor + for (Gadget gadget : getCosmeticManager().getGadgetManager().getGadgets(GadgetType.Costume)) + { + if (gadget instanceof OutfitTeam) + { + ((OutfitTeam)gadget).setEnabled(event.GetState() == GameState.Recruit); + } + } } /*public void saveBasicStats(final Game game) From 1487692609e929ce64ee70ce8f9f3f23340720d8 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Thu, 13 Aug 2015 12:57:30 +0200 Subject: [PATCH 364/377] completely disabled team armor in arcade. avoids typing it just as game starts. --- .../mineplex/core/cosmetic/CosmeticManager.java | 16 ++++++++++++++++ .../src/nautilus/game/arcade/Arcade.java | 6 ++++++ .../src/nautilus/game/arcade/ArcadeManager.java | 9 --------- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/CosmeticManager.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/CosmeticManager.java index d41da36a3..08c1c410d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/CosmeticManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/CosmeticManager.java @@ -1,5 +1,7 @@ package mineplex.core.cosmetic; +import nautilus.game.arcade.game.Game.GameState; + import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -19,6 +21,9 @@ import mineplex.core.common.util.UtilServer; import mineplex.core.cosmetic.ui.CosmeticShop; import mineplex.core.donation.DonationManager; import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.gadgets.OutfitTeam; +import mineplex.core.gadget.types.Gadget; +import mineplex.core.gadget.types.GadgetType; import mineplex.core.inventory.InventoryManager; import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.mount.MountManager; @@ -191,4 +196,15 @@ public class CosmeticManager extends MiniPlugin { return _treasureManager; } + + public void disableTeamArmor() + { + for (Gadget gadget : getGadgetManager().getGadgets(GadgetType.Costume)) + { + if (gadget instanceof OutfitTeam) + { + ((OutfitTeam)gadget).setEnabled(false); + } + } + } } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java index 31b6bc189..d38023f34 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java @@ -25,6 +25,9 @@ import mineplex.core.disguise.DisguiseManager; import mineplex.core.donation.DonationManager; import mineplex.core.friend.FriendManager; import mineplex.core.gadget.GadgetManager; +import mineplex.core.gadget.gadgets.OutfitTeam; +import mineplex.core.gadget.types.Gadget; +import mineplex.core.gadget.types.GadgetType; import mineplex.core.give.Give; import mineplex.core.hologram.HologramManager; import mineplex.core.ignore.IgnoreManager; @@ -55,6 +58,7 @@ import mineplex.core.visibility.VisibilityManager; import mineplex.minecraft.game.core.combat.CombatManager; import mineplex.minecraft.game.core.damage.DamageManager; import nautilus.game.arcade.game.GameServerConfig; +import nautilus.game.arcade.game.Game.GameState; public class Arcade extends JavaPlugin { @@ -140,6 +144,8 @@ public class Arcade extends JavaPlugin GadgetManager gadgetManager = new GadgetManager(this, _clientManager, _donationManager, inventoryManager, mountManager, petManager, preferenceManager, disguiseManager, blockRestore, projectileManager, achievementManager); CosmeticManager cosmeticManager = new CosmeticManager(this, _clientManager, _donationManager, inventoryManager, gadgetManager, mountManager, petManager, null); cosmeticManager.setInterfaceSlot(7); + cosmeticManager.disableTeamArmor(); + //Arcade Manager PollManager pollManager = new PollManager(this, _clientManager, _donationManager); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java index 2ed9210ab..55e95d18d 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java @@ -1195,15 +1195,6 @@ public class ArcadeManager extends MiniPlugin implements IRelation } } } - - //Disable Team Armor - for (Gadget gadget : getCosmeticManager().getGadgetManager().getGadgets(GadgetType.Costume)) - { - if (gadget instanceof OutfitTeam) - { - ((OutfitTeam)gadget).setEnabled(event.GetState() == GameState.Recruit); - } - } } /*public void saveBasicStats(final Game game) From 878ac82ade54b7ebdc20b2cc50c3d989886e4e45 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Thu, 13 Aug 2015 13:01:41 +0200 Subject: [PATCH 365/377] fixed error! --- .../src/mineplex/core/cosmetic/CosmeticManager.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/CosmeticManager.java b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/CosmeticManager.java index 08c1c410d..48e7d35f2 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/CosmeticManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/cosmetic/CosmeticManager.java @@ -1,7 +1,5 @@ package mineplex.core.cosmetic; -import nautilus.game.arcade.game.Game.GameState; - import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; From af15476f19f280b979d332f25023100843deb27c Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 13 Aug 2015 06:12:11 -0500 Subject: [PATCH 366/377] Use login query to handle logins --- .../core/bonuses/BonusClientData.java | 54 +++++------ .../mineplex/core/bonuses/BonusManager.java | 90 +++++++++++-------- .../core/bonuses/BonusRepository.java | 63 ++++++++++++- .../core/bonuses/gui/buttons/VoteButton.java | 2 +- .../mineplex/votifier/VotifierManager.java | 9 +- 5 files changed, 150 insertions(+), 68 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusClientData.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusClientData.java index 08cccac7f..346f58b1c 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusClientData.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusClientData.java @@ -8,107 +8,111 @@ import mineplex.database.tables.records.BonusRecord; public class BonusClientData { - private BonusRecord _record; private Hologram _hologram; - public BonusClientData(BonusRecord record) - { - _record = record; - } + private int _accountId; + private Timestamp _dailyTime; + private Date _rankTime; + private Date _voteTime; + private int _dailyStreak; + private int _maxDailyStreak; + private int _voteStreak; + private int _maxVoteStreak; + private int _tickets; - public BonusRecord getRecord() + public BonusClientData() { - return _record; + _accountId = -1; } public void setAccountId(Integer value) { - _record.setAccountId(value); + _accountId = value; } public Integer getAccountId() { - return _record.getAccountId(); + return _accountId; } public void setDailyTime(Timestamp value) { - _record.setDailytime(value); + _dailyTime = value; } public Timestamp getDailyTime() { - return _record.getDailytime(); + return _dailyTime; } public void setRankTime(Date value) { - _record.setRanktime(value); + _rankTime = value; } public Date getRankTime() { - return _record.getRanktime(); + return _rankTime; } public void setVoteTime(Date value) { - _record.setVotetime(value); + _voteTime = value; } public Date getVoteTime() { - return _record.getVotetime(); + return _voteTime; } public void setDailyStreak(Integer value) { - _record.setDailyStreak(value); + _dailyStreak = value; } public Integer getDailyStreak() { - return _record.getDailyStreak(); + return _dailyStreak; } public void setMaxDailyStreak(Integer value) { - _record.setMaxDailyStreak(value); + _maxDailyStreak = value; } public Integer getMaxDailyStreak() { - return _record.getMaxDailyStreak(); + return _maxDailyStreak; } public void setVoteStreak(Integer value) { - _record.setVoteStreak(value); + _voteStreak = value; } public Integer getVoteStreak() { - return _record.getVoteStreak(); + return _voteStreak; } public void setMaxVoteStreak(Integer value) { - _record.setMaxVoteStreak(value); + _maxVoteStreak = value; } public Integer getMaxVoteStreak() { - return _record.getMaxVoteStreak(); + return _maxVoteStreak; } public void setTickets(Integer value) { - _record.setTickets(value); + _tickets = value; } public Integer getTickets() { - return _record.getTickets(); + return _tickets; } public Hologram getHologram() diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index b708466c1..0e0b52abf 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -1,6 +1,8 @@ package mineplex.core.bonuses; import java.sql.Date; +import java.sql.ResultSet; +import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Calendar; @@ -14,6 +16,7 @@ import java.util.TimeZone; import mineplex.core.MiniClientPlugin; import mineplex.core.account.CoreClient; import mineplex.core.account.CoreClientManager; +import mineplex.core.account.ILoginProcessor; import mineplex.core.account.IQuerylessLoginProcessor; import mineplex.core.account.event.ClientUnloadEvent; import mineplex.core.bonuses.redis.VoteHandler; @@ -52,6 +55,7 @@ import mineplex.core.bonuses.gui.SpinGui; import mineplex.core.poll.PollManager; import mineplex.serverdata.commands.ServerCommandManager; +import org.jooq.DSLContext; import org.jooq.SQLDialect; import org.jooq.impl.DSL; import org.bukkit.Bukkit; @@ -69,7 +73,7 @@ import org.bukkit.plugin.java.JavaPlugin; import net.minecraft.server.v1_7_R4.DataWatcher; import net.minecraft.server.v1_7_R4.PacketPlayOutEntityMetadata; -public class BonusManager extends MiniClientPlugin implements IQuerylessLoginProcessor +public class BonusManager extends MiniClientPlugin implements ILoginProcessor { public static final TimeZone TIMEZONE = TimeZone.getTimeZone("UTC"); @@ -276,21 +280,30 @@ public class BonusManager extends MiniClientPlugin implements I public void handleVote(final Player player, final int gemsRecieved) { + final int accountId = _clientManager.getAccountId(player); + runAsync(new Runnable() { @Override public void run() { - Get(player).getRecord().refresh(); - runSync(new Runnable() + _repository.getClientData(accountId, new Callback() { @Override - public void run() + public void run(final BonusClientData data) { - _statsManager.incrementStat(player, "Global.DailyVote", 1); - addPendingExplosion(player, player.getName()); - UtilPlayer.message(player, F.main("Carl", "Thanks for voting for Mineplex!")); - UtilPlayer.message(player, F.main("Carl", "You received " + F.elem(gemsRecieved + " Gems") + " and " + F.elem("1 Carl Spinner Ticket") + "!")); + runSync(new Runnable() + { + @Override + public void run() + { + Set(player, data); + _statsManager.incrementStat(player, "Global.DailyVote", 1); + addPendingExplosion(player, player.getName()); + UtilPlayer.message(player, F.main("Carl", "Thanks for voting for Mineplex!")); + UtilPlayer.message(player, F.main("Carl", "You received " + F.elem(gemsRecieved + " Gems") + " and " + F.elem("1 Carl Spinner Ticket") + "!")); + } + }); } }); } @@ -434,7 +447,7 @@ public class BonusManager extends MiniClientPlugin implements I // This calculates the the next daily bonus, IT HAS TO MATCH THE MYSQL STORED FUNCTION. public long nextDailyBonus(Player player) { - Timestamp timestamp = Get(player).getRecord().getDailytime(); + Timestamp timestamp = Get(player).getDailyTime(); if (timestamp == null) return 0; @@ -506,7 +519,7 @@ public class BonusManager extends MiniClientPlugin implements I // This calculates the the next rank bonus, IT HAS TO MATCH THE MYSQL STORED FUNCTION. public long nextRankBonus(Player player) { - Date date = Get(player).getRecord().getRanktime(); + Date date = Get(player).getRankTime(); if (date == null) return 0; @@ -532,16 +545,11 @@ public class BonusManager extends MiniClientPlugin implements I } } - public void updateVoteStreak(Player player) + public void updateVoteStreak(BonusRecord client) { - updateVoteStreak(Get(player)); - } - - public void updateVoteStreak(BonusClientData client) - { - if (client.getVoteStreak() > 0 && client.getVoteTime() != null) + if (client.getVoteStreak() > 0 && client.getVotetime() != null) { - long lastBonus = getLocalTime(client.getVoteTime().getTime()); + long lastBonus = getLocalTime(client.getVotetime().getTime()); long timeLeft = getStreakTimeRemaining(lastBonus, BonusManager.VOTE_STREAK_RESET_TIME); if (timeLeft < 0) @@ -561,7 +569,7 @@ public class BonusManager extends MiniClientPlugin implements I data.setMaxDailyStreak(data.getDailyStreak()); } - public void incrementVoteStreak(BonusClientData client) + public void incrementVoteStreak(BonusRecord client) { client.setVoteStreak(client.getVoteStreak() + 1); @@ -609,10 +617,8 @@ public class BonusManager extends MiniClientPlugin implements I return multiplyer; } - public int getVoteMultiplyer(BonusClientData client) + public int getVoteMultiplyer(int streak) { - int streak = client.getVoteStreak(); - int multiplyer = Math.min(100, 5 * streak); if (streak >= 20) multiplyer += (1 * (streak - 40)); return multiplyer; @@ -639,12 +645,12 @@ public class BonusManager extends MiniClientPlugin implements I public BonusAmount getVoteBonusAmount(Player player) { - return getVoteBonusAmount(Get(player)); + return getVoteBonusAmount(Get(player).getVoteStreak()); } - public BonusAmount getVoteBonusAmount(BonusClientData client) + public BonusAmount getVoteBonusAmount(int voteStreak) { - double mult = getVoteMultiplyer(client) / 100.0; + double mult = getVoteMultiplyer(voteStreak) / 100.0; BonusAmount amount = new BonusAmount(); amount.setTickets(1); @@ -949,9 +955,7 @@ public class BonusManager extends MiniClientPlugin implements I @Override protected BonusClientData AddPlayer(String player) { - // Should never be called! - BonusRecord record = new BonusRecord(); - return new BonusClientData(record); + return new BonusClientData(); } public BonusRepository getRepository() @@ -978,6 +982,16 @@ public class BonusManager extends MiniClientPlugin implements I if (clientData.getHologram() != null) clientData.getHologram().stop(); + // Save streaks + runAsync(new Runnable() + { + @Override + public void run() + { + _repository.saveStreak(clientData.getAccountId(), clientData); + } + }); + // This shouldnt be necessary anymore // runAsync(new Runnable() // { @@ -991,14 +1005,6 @@ public class BonusManager extends MiniClientPlugin implements I super.UnloadPlayer(event); } - @Override - public void processLogin(String playerName, int accountId) - { - BonusRecord record = _repository.loadRecord(playerName, accountId); - BonusClientData clientData = new BonusClientData(record); - Set(playerName, clientData); - } - public void addPendingExplosion(Player player, Object obj) { _pendingExplosions.add(obj); @@ -1131,4 +1137,16 @@ public class BonusManager extends MiniClientPlugin implements I return true; } + + @Override + public void processLoginResultSet(String playerName, int accountId, ResultSet resultSet) throws SQLException + { + Set(playerName, _repository.loadData(accountId, resultSet)); + } + + @Override + public String getQuery(int accountId, String uuid, String name) + { + return "SELECT * FROM bonus WHERE accountId = '" + accountId + "';"; + } } \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java index 52a57e3ec..ee21b56a0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java @@ -18,15 +18,18 @@ import mineplex.core.common.util.UtilPlayer; import mineplex.core.database.DBPool; import mineplex.core.database.RepositoryBase; import mineplex.core.database.ResultSetCallable; +import mineplex.core.database.column.ColumnInt; import mineplex.core.donation.DonationManager; import mineplex.core.recharge.Recharge; import mineplex.database.Tables; import mineplex.database.tables.records.BonusRecord; +import org.jooq.Configuration; import org.jooq.DSLContext; import org.jooq.Record2; import org.jooq.SQLDialect; import org.jooq.TableField; import org.jooq.impl.DSL; +import org.jooq.impl.DefaultConfiguration; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -68,6 +71,40 @@ public class BonusRepository extends RepositoryBase return record; } + public BonusClientData loadData(final int accountId, ResultSet resultSet) throws SQLException + { + BonusClientData clientData = new BonusClientData(); + clientData.setAccountId(accountId); + + boolean foundClient = false; + while (resultSet.next()) + { + foundClient = true; + clientData.setDailyTime(resultSet.getTimestamp(2)); + clientData.setRankTime(resultSet.getDate(3)); + clientData.setVoteTime(resultSet.getDate(4)); + clientData.setDailyStreak(resultSet.getInt(5)); + clientData.setMaxDailyStreak(resultSet.getInt(6)); + clientData.setVoteStreak(resultSet.getInt(7)); + clientData.setMaxVoteStreak(resultSet.getInt(8)); + clientData.setTickets(resultSet.getInt(9)); + } + + if (!foundClient) + { + _manager.runAsync(new Runnable() + { + @Override + public void run() + { + executeInsert("INSERT IGNORE INTO bonus (accountId) VALUES (" + accountId + ")", null); + } + }); + } + + return clientData; + } + public void getDailyStreakRecord(Callback callback) { getStreakRecord(Tables.bonus.maxDailyStreak, callback); @@ -170,8 +207,6 @@ public class BonusRepository extends RepositoryBase final Timestamp timeStamp = callableStatement.getTimestamp(5); - _manager.Get(player).getRecord().update(); - Bukkit.getScheduler().runTask(plug, new Runnable() { @Override @@ -373,6 +408,30 @@ public class BonusRepository extends RepositoryBase }); } + public void getClientData(final int accountId, final Callback callback) + { + String query = "SELECT * FROM bonus WHERE accountId = '" + accountId + "';"; + + executeQuery(query, new ResultSetCallable() + { + @Override + public void processResultSet(ResultSet resultSet) throws SQLException + { + BonusClientData clientData = loadData(accountId, resultSet); + callback.run(clientData); + } + }); + } + + public void saveStreak(int accountId, BonusClientData clientData) + { + jooq().update(Tables.bonus).set(Tables.bonus.dailyStreak, clientData.getDailyStreak()) + .set(Tables.bonus.maxDailyStreak, clientData.getMaxDailyStreak()) + .set(Tables.bonus.voteStreak, clientData.getVoteStreak()) + .set(Tables.bonus.maxVoteStreak, clientData.getMaxVoteStreak()) + .where(Tables.bonus.accountId.eq(accountId)).execute(); + } + @Override protected void initialize() { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java index 6bd8f9638..b2d46d294 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java @@ -130,7 +130,7 @@ public class VoteButton implements GuiItem, Listener { lore.add(" "); lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getVoteStreak()); - lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + "+" + _bonusManager.getVoteMultiplyer(client) + "%"); + lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + "+" + _bonusManager.getVoteMultiplyer(client.getVoteStreak()) + "%"); if (client.getVoteTime() != null) { long lastBonus = _bonusManager.getLocalTime(client.getVoteTime().getTime()); diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java index c87ef4896..19a3c37b3 100644 --- a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -20,6 +20,7 @@ import mineplex.core.database.DBPool; import mineplex.core.donation.DonationManager; import mineplex.core.bonuses.redis.VotifierCommand; import mineplex.database.Tables; +import mineplex.database.tables.records.BonusRecord; import mineplex.serverdata.Region; import mineplex.serverdata.Utility; import mineplex.serverdata.commands.ServerCommand; @@ -184,9 +185,9 @@ public class VotifierManager extends MiniPlugin if (idRecord != null) { final int accountId = idRecord.value1(); - final BonusClientData client = new BonusClientData(_bonusManager.getRepository().loadRecord(playerName, accountId)); + final BonusRecord client = _bonusManager.getRepository().loadRecord(playerName, accountId); - final BonusAmount amount = _bonusManager.getVoteBonusAmount(client); + final BonusAmount amount = _bonusManager.getVoteBonusAmount(client.getVoteStreak()); _bonusManager.getRepository().attemptVoteBonus(accountId, new Callback>() { @@ -231,12 +232,12 @@ public class VotifierManager extends MiniPlugin // Check if we need to reset vote streak _bonusManager.updateVoteStreak(client); - client.getRecord().setVotetime(pair.getRight()); + client.setVotetime(pair.getRight()); // Update Streak _bonusManager.incrementVoteStreak(client); - client.getRecord().store(); + client.store(); System.out.println("Awarded carl ticket to " + playerName); onComplete.run(amount.getTotalGems()); } From 534c91c706f04da49052d57d7fd114bff352c658 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Thu, 13 Aug 2015 13:24:55 +0200 Subject: [PATCH 367/377] remove items from inside soccer --- .../src/mineplex/hub/modules/SoccerManager.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java index 6383be7a3..630eb1e00 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -13,6 +13,8 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Slime; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.entity.WitherSkull; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDamageByEntityEvent; @@ -353,15 +355,15 @@ public class SoccerManager extends MiniPlugin if (_ball != null && _ball.equals(ent)) continue; - - if (ent instanceof Bat) - { - ent.remove(); - continue; - } if (inPlayerArena(ent)) { + if (ent instanceof Bat || ent instanceof WitherSkull || ent instanceof TNTPrimed) + { + ent.remove(); + continue; + } + Location bounce = UtilAlg.getMidpoint(_cornerFieldPlayerA, _cornerFieldPlayerB); bounce.setY(Math.min(_cornerFieldPlayerA.getY(), _cornerFieldPlayerB.getY())); @@ -370,7 +372,6 @@ public class SoccerManager extends MiniPlugin bottom = bottom.getVehicle(); UtilAction.velocity(bottom, UtilAlg.getTrajectory(bounce, ent.getLocation()), 1, false, 0, 0.4, 1, true); - } } } From 5fa9135b0887fa9fcf7ec997b4014421d1621cf5 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Thu, 13 Aug 2015 14:11:22 +0200 Subject: [PATCH 368/377] renamed soccer to slimeball :) --- .../src/mineplex/hub/modules/SoccerManager.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java index 630eb1e00..3fde170ec 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/SoccerManager.java @@ -426,12 +426,12 @@ public class SoccerManager extends MiniPlugin { if (_active.size() < 8) { - UtilPlayer.message(player, F.main("Soccer", "You must be wearing Red/Blue Team Outfit.")); - UtilPlayer.message(player, F.main("Soccer", "Type " + F.elem("/team red") + " or " + F.elem("/team blue") + "!")); + UtilPlayer.message(player, F.main("Slimeball", "You must be wearing Red/Blue Team Outfit.")); + UtilPlayer.message(player, F.main("Slimeball", "Type " + F.elem("/team red") + " or " + F.elem("/team blue") + "!")); } else { - UtilPlayer.message(player, F.main("Soccer", "The game is currently full!")); + UtilPlayer.message(player, F.main("Slimeball", "The game is currently full!")); } } } @@ -447,11 +447,11 @@ public class SoccerManager extends MiniPlugin _active.add(player); if (color == null) - UtilPlayer.message(player, F.main("Parkour", "You have entered " + F.elem("Soccer Mode") + ".")); + UtilPlayer.message(player, F.main("Parkour", "You have entered " + F.elem("Slimeball Mode") + ".")); else if (color == Color.RED) - UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cRed + "Red Soccer Team") + ".")); + UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cRed + "Red Slimeball Team") + ".")); else if (color == Color.AQUA) - UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cAqua + "Blue Soccer Team") + ".")); + UtilPlayer.message(player, F.main("Parkour", "You have joined " + F.elem(C.cAqua + "Blue Slimeball Team") + ".")); ArrayList outfit = new ArrayList(); outfit.add("Team Helmet"); @@ -466,7 +466,7 @@ public class SoccerManager extends MiniPlugin else { _active.remove(player); - UtilPlayer.message(player, F.main("Parkour", "You have exited " + F.elem("Soccer Mode") + ".")); + UtilPlayer.message(player, F.main("Parkour", "You have exited " + F.elem("Slimeball Mode") + ".")); } } From bd7317cf7be3dbd0cd82835261bd373140dc8db3 Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 13 Aug 2015 11:03:12 -0500 Subject: [PATCH 369/377] Fix ticket command rollback >:D --- .../core/bonuses/commands/TicketCommand.java | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java index 20aa7ad66..62cefef27 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java @@ -2,6 +2,7 @@ package mineplex.core.bonuses.commands; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; +import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilPlayer; import mineplex.core.bonuses.BonusManager; @@ -36,15 +37,28 @@ public class TicketCommand extends CommandBase { try { - int tickets = Integer.parseInt(ticketString); - Plugin.Get(target).setTickets(Plugin.Get(targetName).getTickets() + tickets); - - UtilPlayer.message(caller, F.main("Carl", "You gave " + F.elem(tickets + " Carl Tickets") + " to " + F.name(targetName) + ".")); - - if (target != null) + final int tickets = Integer.parseInt(ticketString); + int accountId = Plugin.getClientManager().getAccountId(target); + Plugin.getRepository().attemptAddTickets(accountId, Plugin.Get(target), tickets, new Callback() { - UtilPlayer.message(target, F.main("Carl", F.name(caller.getName()) + " gave you " + F.elem(tickets + " Carl Tickets") + ".")); - } + @Override + public void run(Boolean data) + { + if (data) + { + UtilPlayer.message(caller, F.main("Carl", "You gave " + F.elem(tickets + " Carl Tickets") + " to " + F.name(targetName) + ".")); + + if (target != null && !target.equals(caller)) + { + UtilPlayer.message(target, F.main("Carl", F.name(caller.getName()) + " gave you " + F.elem(tickets + " Carl Tickets") + ".")); + } + } + else + { + UtilPlayer.message(caller, F.main("Carl", "Failed to give tickets. Try again later!")); + } + } + }); } catch (Exception e) { From 0b4dbab8715b2c42c1b8d42e9118069e16ba8b9d Mon Sep 17 00:00:00 2001 From: Shaun Bennett Date: Thu, 13 Aug 2015 11:23:29 -0500 Subject: [PATCH 370/377] Change ticket command access to admin --- .../src/mineplex/core/bonuses/commands/TicketCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java index 62cefef27..307a57427 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/commands/TicketCommand.java @@ -13,7 +13,7 @@ public class TicketCommand extends CommandBase { public TicketCommand(BonusManager plugin) { - super(plugin, Rank.DEVELOPER, "ticket"); + super(plugin, Rank.ADMIN, "ticket"); } @Override From a1ba2cffacabf7c8f08c85358bec43ece971ea19 Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Thu, 13 Aug 2015 20:56:02 +0200 Subject: [PATCH 371/377] fixed needler not doing posion --- .../src/nautilus/game/arcade/kit/perks/PerkNeedler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkNeedler.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkNeedler.java index ce4603693..3844440ba 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkNeedler.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkNeedler.java @@ -131,7 +131,7 @@ public class PerkNeedler extends SmashPerk DamageCause.THORNS, 1.1, true, true, false, damager.getName(), GetName()); - if(Manager.GetGame().GetTeam(event.GetDamageePlayer()) != Manager.GetGame().GetTeam(damager)) + if(!Manager.GetGame().GetTeam(event.GetDamageePlayer()).equals(Manager.GetGame().GetTeam(damager))) { Manager.GetCondition().Factory().Poison(GetName(), event.GetDamageeEntity(), damager, 2, 0, false, false, false); } From 80588a308b0856ad58ef9da17d3aab007fe3969c Mon Sep 17 00:00:00 2001 From: Mini-Chiss Date: Thu, 13 Aug 2015 21:03:48 +0200 Subject: [PATCH 372/377] balanaced brawler --- .../src/nautilus/game/arcade/kit/perks/PerkMammoth.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkMammoth.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkMammoth.java index e91dc9742..23134ec56 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkMammoth.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/kit/perks/PerkMammoth.java @@ -14,7 +14,7 @@ public class PerkMammoth extends Perk { super("Mammoth", new String[] { - C.cGray + "Take 50% knockback and deal 150% knockback", + C.cGray + "Take 75% knockback and deal 125% knockback", }); } @@ -30,7 +30,7 @@ public class PerkMammoth extends Perk if (!Kit.HasKit(damager)) return; - event.AddKnockback(GetName(), 1.5d); + event.AddKnockback(GetName(), 1.25d); } @EventHandler(priority = EventPriority.HIGH) @@ -45,6 +45,6 @@ public class PerkMammoth extends Perk if (!Kit.HasKit(damagee)) return; - event.AddKnockback(GetName(), 0.5d); + event.AddKnockback(GetName(), 0.75d); } } From f5d934fe53de0c26cb00c10b22f747578f39a703 Mon Sep 17 00:00:00 2001 From: Jonathan Williams Date: Fri, 14 Aug 2015 00:37:43 -0500 Subject: [PATCH 373/377] Fixed sync db calls for pets. Make sure to add/remove pets in mysql. --- .../core/pet/repository/PetRepository.java | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/pet/repository/PetRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/pet/repository/PetRepository.java index 2ed20694b..85973eeb9 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/pet/repository/PetRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/pet/repository/PetRepository.java @@ -26,14 +26,34 @@ public class PetRepository extends RepositoryBase _webAddress = webAddress; } - public void AddPet(PetChangeToken token) + public void AddPet(final PetChangeToken token) { new AsyncJsonWebCall(_webAddress + "Pets/AddPet").Execute(token); + + Plugin.getServer().getScheduler().runTaskAsynchronously(Plugin, new Runnable() + { + public void run() + { + executeInsert("INSERT INTO accountPets(petName, petId, accountId) VALUES (?, ?, ?);", null, new ColumnVarChar("petName", 32, token.PetName) + , new ColumnInt("petId", token.PetId) + , new ColumnInt("accountId", token.AccountId)); + } + }); } - public void RemovePet(PetChangeToken token) + public void RemovePet(final PetChangeToken token) { new AsyncJsonWebCall(_webAddress + "Pets/RemovePet").Execute(token); + + Plugin.getServer().getScheduler().runTaskAsynchronously(Plugin, new Runnable() + { + public void run() + { + executeUpdate("DELETE FROM accountPets WHERE petId = ? AND accountId = ?;" + , new ColumnInt("petId", token.PetId) + , new ColumnInt("accountId", token.AccountId)); + } + }); } public List GetPetExtras(List petExtraTokens) @@ -41,20 +61,26 @@ public class PetRepository extends RepositoryBase return new JsonWebCall(_webAddress + "Pets/GetPetExtras").Execute(new TypeToken>(){}.getType(), petExtraTokens); } - public void UpdatePet(PetChangeToken token) + public void UpdatePet(final PetChangeToken token) { new AsyncJsonWebCall(_webAddress + "Pets/UpdatePet").Execute(token); - - int rowsChanged = executeUpdate("UPDATE accountPets SET petName = ? WHERE petId = ? AND accountId = ?;", new ColumnVarChar("petName", 32, token.PetName) + + Plugin.getServer().getScheduler().runTaskAsynchronously(Plugin, new Runnable() + { + public void run() + { + int rowsChanged = executeUpdate("UPDATE accountPets SET petName = ? WHERE petId = ? AND accountId = ?;", new ColumnVarChar("petName", 32, token.PetName) + , new ColumnInt("petId", token.PetId) + , new ColumnInt("accountId", token.AccountId)); + + if (rowsChanged < 1) + { + executeInsert("INSERT INTO accountPets(petName, petId, accountId) VALUES (?, ?, ?);", null, new ColumnVarChar("petName", 32, token.PetName) , new ColumnInt("petId", token.PetId) , new ColumnInt("accountId", token.AccountId)); - - if (rowsChanged < 1) - { - executeInsert("INSERT INTO accountPets(petName, petId, accountId) VALUES (?, ?, ?);", null, new ColumnVarChar("petName", 32, token.PetName) - , new ColumnInt("petId", token.PetId) - , new ColumnInt("accountId", token.AccountId)); - } + } + } + }); } @Override From 33a6e4cb13c5b6366eb1947f4b5e53e2702defa4 Mon Sep 17 00:00:00 2001 From: libraryaddict Date: Fri, 14 Aug 2015 19:12:05 +1200 Subject: [PATCH 374/377] UtilEnt: Add CreatureLook method --- .../mineplex/core/common/util/UtilEnt.java | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java index d87d16fa5..80358744b 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java @@ -4,21 +4,23 @@ import java.lang.reflect.Field; import java.util.HashMap; import java.util.LinkedList; import java.util.List; + import net.minecraft.server.v1_7_R4.EntityBat; import net.minecraft.server.v1_7_R4.EntityCreature; import net.minecraft.server.v1_7_R4.EntityEnderDragon; import net.minecraft.server.v1_7_R4.EntityHuman; import net.minecraft.server.v1_7_R4.EntityInsentient; -import net.minecraft.server.v1_7_R4.EntityLiving; +import net.minecraft.server.v1_7_R4.EntityTrackerEntry; import net.minecraft.server.v1_7_R4.Navigation; +import net.minecraft.server.v1_7_R4.PacketPlayOutEntityHeadRotation; import net.minecraft.server.v1_7_R4.PathfinderGoal; import net.minecraft.server.v1_7_R4.PathfinderGoalLookAtPlayer; import net.minecraft.server.v1_7_R4.PathfinderGoalMoveTowardsRestriction; import net.minecraft.server.v1_7_R4.PathfinderGoalRandomLookaround; import net.minecraft.server.v1_7_R4.PathfinderGoalSelector; +import net.minecraft.server.v1_7_R4.WorldServer; import org.bukkit.Bukkit; -import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Sound; @@ -32,6 +34,7 @@ import org.bukkit.entity.EntityType; import org.bukkit.entity.Giant; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import org.bukkit.util.Vector; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftCreature; import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; @@ -582,6 +585,36 @@ public class UtilEnt return false; } + public static boolean CreatureLook(Entity ent, Entity target) + { + return CreatureLook(ent, target instanceof LivingEntity ? ((LivingEntity) target).getEyeLocation() : target.getLocation()); + } + + public static boolean CreatureLook(Entity ent, Location target) + { + Vector vec = UtilAlg.getTrajectory(ent.getLocation(), target); + + return CreatureLook(ent, UtilAlg.GetPitch(vec), UtilAlg.GetYaw(vec)); + } + + public static boolean CreatureLook(Entity ent, float pitch, float yaw) + { + if (!(ent instanceof Creature)) + return false; + + EntityCreature ec = ((CraftCreature) ent).getHandle(); + Location loc = ent.getLocation(); + + ec.setPositionRotation(loc.getX(), loc.getY(), loc.getZ(), yaw, pitch); + ec.al = true; + + EntityTrackerEntry entry = (EntityTrackerEntry) ((WorldServer) ec.world).tracker.trackedEntities.get(ec.getId()); + + entry.broadcast(new PacketPlayOutEntityHeadRotation(ec, (byte) (ec.yaw * 256.0F / 360.0F))); + + return true; + } + public static void CreatureMove(Entity ent, Location target, float speed) { if (!(ent instanceof Creature)) From 7fb85f24d1925f569147dc53103952a1821343bd Mon Sep 17 00:00:00 2001 From: libraryaddict Date: Fri, 14 Aug 2015 19:15:35 +1200 Subject: [PATCH 375/377] UtilEnt: Change CreatureLook to support LivingEntity, not just Creature --- .../src/mineplex/core/common/util/UtilEnt.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java index 80358744b..8b489c952 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java @@ -10,6 +10,7 @@ import net.minecraft.server.v1_7_R4.EntityCreature; import net.minecraft.server.v1_7_R4.EntityEnderDragon; import net.minecraft.server.v1_7_R4.EntityHuman; import net.minecraft.server.v1_7_R4.EntityInsentient; +import net.minecraft.server.v1_7_R4.EntityLiving; import net.minecraft.server.v1_7_R4.EntityTrackerEntry; import net.minecraft.server.v1_7_R4.Navigation; import net.minecraft.server.v1_7_R4.PacketPlayOutEntityHeadRotation; @@ -599,10 +600,10 @@ public class UtilEnt public static boolean CreatureLook(Entity ent, float pitch, float yaw) { - if (!(ent instanceof Creature)) + if (!(ent instanceof LivingEntity)) return false; - EntityCreature ec = ((CraftCreature) ent).getHandle(); + EntityLiving ec = ((CraftLivingEntity) ent).getHandle(); Location loc = ent.getLocation(); ec.setPositionRotation(loc.getX(), loc.getY(), loc.getZ(), yaw, pitch); From 81f793d6932cb8daa46e3aaaec1b0bdd40a9a276 Mon Sep 17 00:00:00 2001 From: libraryaddict Date: Fri, 14 Aug 2015 20:49:17 +1200 Subject: [PATCH 376/377] Iron Wizard: Commit progress --- .../mineplex/core/common/util/UtilAlg.java | 36 ++ .../mineplex/core/common/util/UtilPlayer.java | 1 + .../game/clans/clans/ClansManager.java | 10 +- .../clans/worldevent/WorldEventType.java | 4 +- .../worldevent/creature/EventCreature.java | 5 + .../worldevent/event/golem/GolemBoss.java | 88 +++ .../worldevent/event/golem/GolemCreature.java | 382 ++++++++++++ .../event/golem/abilities/BlockHailBlock.java | 86 +++ .../event/golem/abilities/GolemAbility.java | 98 +++ .../event/golem/abilities/GolemBlockHail.java | 430 +++++++++++++ .../event/golem/abilities/GolemBlockShot.java | 412 +++++++++++++ .../event/golem/abilities/GolemCaveIn.java | 316 ++++++++++ .../golem/abilities/GolemEarthquake.java | 161 +++++ .../golem/abilities/GolemExplosiveBlock.java | 583 ++++++++++++++++++ .../golem/abilities/GolemMeleeAttack.java | 81 +++ .../event/golem/abilities/GolemRumble.java | 215 +++++++ .../golem/abilities/GolemWallExplode.java | 403 ++++++++++++ .../game/core/explosion/CustomExplosion.java | 6 +- 18 files changed, 3312 insertions(+), 5 deletions(-) create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemBoss.java create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemCreature.java create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/BlockHailBlock.java create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemAbility.java create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemBlockHail.java create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemBlockShot.java create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemCaveIn.java create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemEarthquake.java create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemExplosiveBlock.java create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemMeleeAttack.java create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemRumble.java create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemWallExplode.java diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java index 56a9b917e..8969368a4 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilAlg.java @@ -353,4 +353,40 @@ public class UtilAlg return bestLoc; } + + public static Vector calculateVelocity(Vector from, Vector to, int heightGain) + { + // Gravity of a potion + double gravity = 0.115; + // Block locations + int endGain = to.getBlockY() - from.getBlockY(); + + double dx1 = to.getBlockX() - from.getBlockX(); + double dz1 = to.getBlockZ() - from.getBlockZ(); + + double horizDist = Math.sqrt(dx1 * dx1 + dz1 * dz1); + // Height gain + int gain = heightGain; + double maxGain = gain > (endGain + gain) ? gain : (endGain + gain); + // Solve quadratic equation for velocity + double a = -horizDist * horizDist / (4 * maxGain); + double b = horizDist; + double c = -endGain; + double slope = -b / (2 * a) - Math.sqrt(b * b - 4 * a * c) / (2 * a); + // Vertical velocity + double vy = Math.sqrt(maxGain * gravity); + // Horizontal velocity + double vh = vy / slope; + // Calculate horizontal direction + int dx = to.getBlockX() - from.getBlockX(); + int dz = to.getBlockZ() - from.getBlockZ(); + double mag = Math.sqrt(dx * dx + dz * dz); + double dirx = dx / mag; + double dirz = dz / mag; + // Horizontal velocity components + double vx = vh * dirx; + double vz = vh * dirz; + return new Vector(vx, vy, vz); + } + } diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java index 494e12f30..7ae248bb1 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilPlayer.java @@ -12,6 +12,7 @@ import net.minecraft.server.v1_7_R4.Packet; import net.minecraft.server.v1_7_R4.PlayerConnection; import org.bukkit.ChatColor; +import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java index 2ee137ed8..16fd21055 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java @@ -30,6 +30,7 @@ import mineplex.core.creature.event.CreatureSpawnCustomEvent; import mineplex.core.disguise.DisguiseManager; import mineplex.core.donation.DonationManager; import mineplex.core.energy.Energy; +import mineplex.core.explosion.Explosion; import mineplex.core.movement.Movement; import mineplex.core.npc.NpcManager; import mineplex.core.packethandler.PacketHandler; @@ -102,6 +103,7 @@ public class ClansManager extends MiniClientPlugin implements IRelat private WorldEventManager _worldEvent; private Chat _chat; private ItemMapManager _itemMapManager; + private Explosion _explosion; private int _inviteExpire = 2; private int _nameMin = 3; @@ -151,6 +153,7 @@ public class ClansManager extends MiniClientPlugin implements IRelat _clanGame = new ClansGame(plugin, this); _clanUtility = new ClansUtility(this); _itemMapManager = new ItemMapManager(this, _worldEvent); + _explosion = new Explosion(plugin, blockRestore); Energy energy = new Energy(plugin); // TODO: Re-enable customtagfix with NCP update? @@ -217,6 +220,11 @@ public class ClansManager extends MiniClientPlugin implements IRelat return _itemMapManager; } + public Explosion getExplosion() + { + return _explosion; + } + public int getInviteExpire() { return _inviteExpire; @@ -609,7 +617,7 @@ public class ClansManager extends MiniClientPlugin implements IRelat _worldEvent.onDisable(); } - @EventHandler +// @EventHandler public void onJoin(PlayerLoginEvent event) { Rank rank = _clientManager.Get(event.getPlayer()).GetRank(); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventType.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventType.java index d2a50e064..34d174fee 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventType.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventType.java @@ -4,6 +4,7 @@ import org.bukkit.Location; import mineplex.game.clans.clans.worldevent.event.WorldEvent; import mineplex.game.clans.clans.worldevent.event.slimeking.SlimeBoss; +import mineplex.game.clans.clans.worldevent.event.golem.GolemBoss; import mineplex.game.clans.clans.worldevent.event.kinghill.KingHill; import mineplex.game.clans.clans.worldevent.event.undead.UndeadCamp; @@ -11,7 +12,8 @@ public enum WorldEventType { SLIME_KING("Slime King", SlimeBoss.class, 30), KING_OF_THE_HILL("King of The Hill", KingHill.class, 30), - UNDEAD_CAMP("Undead Camp", UndeadCamp.class, 30); + UNDEAD_CAMP("Undead Camp", UndeadCamp.class, 30), + Golem("Iron Wizard", GolemBoss.class, 30); private String _name; private Class _clazz; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/creature/EventCreature.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/creature/EventCreature.java index c69923152..a91ddd40d 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/creature/EventCreature.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/creature/EventCreature.java @@ -145,6 +145,11 @@ public abstract class EventCreature implements Listener _entityClass = clazz; } + public double getHealthPercent() + { + return getHealth() / getMaxHealth(); + } + public Location getSpawnLocation() { return _spawnLocation; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemBoss.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemBoss.java new file mode 100644 index 000000000..862e79a0d --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemBoss.java @@ -0,0 +1,88 @@ +package mineplex.game.clans.clans.worldevent.event.golem; + +import java.io.File; +import java.io.IOException; + +import mineplex.core.common.block.schematic.Schematic; +import mineplex.core.common.block.schematic.UtilSchematic; +import mineplex.game.clans.clans.worldevent.EventMap; +import mineplex.game.clans.clans.worldevent.WorldEventManager; +import mineplex.game.clans.clans.worldevent.creature.EventCreature; +import mineplex.game.clans.clans.worldevent.event.EventState; +import mineplex.game.clans.clans.worldevent.event.WorldEvent; +import mineplex.game.clans.clans.worldevent.event.slimeking.creature.SlimeCreature; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.util.Vector; + +public class GolemBoss extends WorldEvent +{ + + public GolemBoss(WorldEventManager eventManager, Location corner) + { + super(eventManager, "Iron Wizard", corner); + + Schematic schematic = null; + + try + { + schematic = UtilSchematic.loadSchematic(new File("schematic/Golem.schematic")); + } + catch (IOException e) + { + e.printStackTrace(); + setState(EventState.COMPLETE); + } + + EventMap map = new EventMap(schematic, corner, 15, 15, 15, 15, 15, 15); + setMap(map, new Runnable() + { + @Override + public void run() + { + System.out.println("Runnable on complete"); + } + }); + } + + @Override + protected void customStart() + { + Bukkit.broadcastMessage("Custom Start"); + spawnGolem(getCenterLocation()); + setState(EventState.LIVE); + announceStart(); + } + + /** + * Check if this slime boss has been defeated + */ + private void checkDeath() + { + if (getCreatures().size() == 0) + { + setState(EventState.COMPLETE); + Bukkit.broadcastMessage("FINISHED!"); + } + } + + @Override + public void removeCreature(EventCreature creature) + { + super.removeCreature(creature); + + if (creature instanceof GolemCreature) + { + checkDeath(); + } + } + + private GolemCreature spawnGolem(Location location) + { + GolemCreature slimeCreature = new GolemCreature(this, location, 1500); + registerCreature(slimeCreature); + return slimeCreature; + } + +} \ No newline at end of file diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemCreature.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemCreature.java new file mode 100644 index 000000000..e8256a5a5 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemCreature.java @@ -0,0 +1,382 @@ +package mineplex.game.clans.clans.worldevent.event.golem; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.creature.EventCreature; +import mineplex.game.clans.clans.worldevent.event.golem.abilities.*; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class GolemCreature extends EventCreature +{ + private GolemBoss _boss; + private GolemAbility _currentAbility; + private int _lastAbility; + private long _lastWalked; + private Location _standing; + private long _attackDelay = System.currentTimeMillis(); + private long _reverseWalk; + private HashMap _preferedCombos = new HashMap(); + private Class _lastAttack; + + public GolemCreature(GolemBoss boss, Location location, double maxHealth) + { + super(boss, location, "Iron Wizard", true, maxHealth, IronGolem.class); + _boss = boss; + + spawnEntity(); + + _preferedCombos.put(GolemEarthquake.class, new Class[] + { + GolemBlockHail.class, GolemRumble.class + }); + _preferedCombos.put(GolemMeleeAttack.class, new Class[] + { + GolemEarthquake.class, GolemRumble.class + }); + _preferedCombos.put(GolemCaveIn.class, new Class[] + { + GolemMeleeAttack.class + }); + _preferedCombos.put(GolemBlockShot.class, new Class[] + { + GolemEarthquake.class + }); + _preferedCombos.put(GolemRumble.class, new Class[] + { + GolemBlockShot.class + }); + } + + @Override + protected void spawnCustom() + { + UtilEnt.Vegetate(getEntity()); + // EntityInsentient creature = (EntityInsentient) ((CraftEntity) getEntity()).getHandle(); + + // creature.Vegetated = false; + + _standing = getEntity().getLocation(); + } + + @EventHandler + public void abilityTick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + if (!UtilTime.elapsed(_attackDelay, 5000)) + { + _standing = getEntity().getLocation(); + return; + } + + if (_currentAbility == null || _currentAbility.hasFinished()) + { + if (_currentAbility != null) + { + _lastAttack = _currentAbility.getClass(); + _currentAbility.setFinished(); + _lastAbility = 30;// _currentAbility.getCooldown(); + + HandlerList.unregisterAll(_currentAbility); + + System.out.print("Unregistered golem ability " + _currentAbility.getClass().getSimpleName()); + // Bukkit.broadcastMessage("Ability end"); + + _currentAbility = null; + } + + else if (_lastAbility-- <= 0 && UtilBlock.solid(getEntity().getLocation().getBlock().getRelative(BlockFace.DOWN))) + { + HashMap weight = new HashMap(); + HashMap dist = new HashMap(); + + for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50)) + { + if (player.hasLineOfSight(getEntity())) + { + dist.put(player, player.getLocation().distance(getEntity().getLocation())); + } + } + + if (!dist.isEmpty()) + { + + { // Melee + ArrayList players = getPlayers(dist, 3); + + if (!players.isEmpty()) + { + weight.put(GolemMeleeAttack.class, 3 + (players.size() * 5)); + } + } + + { // Earthquake + ArrayList players = getPlayers(dist, 6); + + if (!players.isEmpty()) + { + weight.put(GolemEarthquake.class, players.size() * 2); + } + } + + { // Wall explode + ArrayList players = getPlayers(dist, 12); + + for (Player player : players) + { + if (dist.get(player) > 4) + { + weight.put(GolemWallExplode.class, 4); + break; + } + } + } + + { // Rumble + ArrayList players = getPlayers(dist, 30); + + if (!players.isEmpty()) + { + weight.put(GolemRumble.class, (int) Math.min(5, dist.get(players.get(0)))); + } + } + + { // Cave in + ArrayList players = getPlayers(dist, 30); + + if (!players.isEmpty()) + { + weight.put(GolemCaveIn.class, (int) Math.min(players.size() * 2, 7)); + } + } + + {// Block Hail + ArrayList players = getPlayers(dist, 30); + + if (!players.isEmpty()) + { + weight.put(GolemBlockHail.class, (int) Math.min(5, dist.get(players.get(0)))); + } + } + + if (_lastAttack != null && _preferedCombos.containsKey(_lastAttack)) + { + weight.remove(_lastAttack); + + for (Class c : _preferedCombos.get(_lastAttack)) + { + if (weight.containsKey(c)) + { + weight.put(c, weight.get(c) + 5); + } + } + } + + if (!weight.isEmpty()) + { + int i = 0; + + for (Integer entry : weight.values()) + { + i += entry; + } + + for (int a = 0; a < 10; a++) + { + int luckyNumber = UtilMath.r(i); + + for (Entry entry : weight.entrySet()) + { + luckyNumber -= entry.getValue(); + + if (luckyNumber <= 0) + { + try + { + _currentAbility = (GolemAbility) entry.getKey().getConstructor(GolemCreature.class) + .newInstance(this); + + if (_currentAbility.getTarget() == null) + { + _currentAbility = null; + } + else + { + break; + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + + break; + } + } + } + } + + if (_currentAbility != null && _currentAbility.getTarget() != null) + { + + Bukkit.getPluginManager().registerEvents(_currentAbility, _boss.getEventManager().getPlugin()); + + // Bukkit.broadcastMessage("Ability: " + _currentAbility.getClass().getSimpleName()); + + System.out.print("Golem boss is using " + _currentAbility.getClass().getSimpleName()); + } + else + { + _currentAbility = null; + _lastAbility = 10; + } + } + + _lastAttack = null; + } + } + + if (_currentAbility != null) + { + _currentAbility.tick(); + } + + if (_currentAbility == null || _currentAbility.canMove()) + { + Player target = null; + double dist = 0; + + for (Player player : UtilServer.getPlayers()) + { + if (!player.hasLineOfSight(getEntity())) + { + continue; + } + + double d = player.getLocation().distance(getEntity().getLocation()); + + if (d > 1.5 && (d < 7 || d > 15) && (target == null || (d < 50 && dist > d))) + { + target = player; + dist = d; + } + } + + Vector vec = null; + boolean reverse = target != null && dist < 8; + + if (target != null) + { + vec = target.getLocation().subtract(getEntity().getLocation()).toVector(); + vec.setY(getEntity().getLocation().getY()); + + double len = vec.length(); + + vec.setX(vec.getX() * (UtilMath.random.nextDouble() / 3D)); + vec.setZ(vec.getZ() * (UtilMath.random.nextDouble() / 3D)); + + vec.multiply(len); + } + else if (UtilTime.elapsed(_lastWalked, 10000)) + { + vec = new Vector(UtilMath.r(50) - 25, 0, UtilMath.r(50) - 25); + } + + if (vec != null) + { + _lastWalked = System.currentTimeMillis(); + + if (reverse) + { + vec.multiply(-1); + } + + if (!UtilAlg.HasSight(getEntity().getLocation(), + getEntity().getLocation().add(vec.clone().normalize().multiply(2)))) + { + _reverseWalk = System.currentTimeMillis(); + } + + if (!UtilTime.elapsed(_reverseWalk, 4000)) + { + vec.multiply(-1); + } + + // if (vec.length() > 1) + { + UtilEnt.CreatureMoveFast(getEntity(), getEntity().getLocation().add(vec), 1.5F); + } + } + + _standing = getEntity().getLocation(); + } + else + { + Location l = getEntity().getLocation(); + + _standing.setYaw(l.getYaw()); + _standing.setPitch(l.getPitch()); + _standing.setY(l.getY()); + + getEntity().teleport(_standing); + } + } + + private ArrayList getPlayers(HashMap map, double maxDist) + { + ArrayList list = new ArrayList(); + + for (Player p : map.keySet()) + { + if (map.get(p) < maxDist) + { + list.add(p); + } + } + + return list; + } + + @EventHandler + public void onGolemDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().equals(getEntity())) + { + event.AddKnockback("Heavy Golem", 0.3); + } + } + + @Override + public void dieCustom() + { + if (_currentAbility != null) + { + _currentAbility.setFinished(); + HandlerList.unregisterAll(_currentAbility); + _currentAbility = null; + } + } +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/BlockHailBlock.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/BlockHailBlock.java new file mode 100644 index 000000000..9fff7eb67 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/BlockHailBlock.java @@ -0,0 +1,86 @@ +package mineplex.game.clans.clans.worldevent.event.golem.abilities; + +import mineplex.core.common.util.UtilEnt; +import net.minecraft.server.v1_7_R4.DataWatcher; +import net.minecraft.server.v1_7_R4.Packet; +import net.minecraft.server.v1_7_R4.PacketPlayOutAttachEntity; +import net.minecraft.server.v1_7_R4.PacketPlayOutEntityDestroy; +import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntity; +import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntityLiving; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.IronGolem; + +public class BlockHailBlock +{ + private int _block = UtilEnt.getNewEntityId(); + private int _chicken = UtilEnt.getNewEntityId(); + private Location _location; + private Material _mat; + + public BlockHailBlock(Location loc, Material mat) + { + _location = loc; + _mat = mat; + } + + public Packet getDestroyPacket() + { + return new PacketPlayOutEntityDestroy(new int[] + { + _chicken, _block + }); + } + + public Location getLocation() + { + return _location; + } + + public Material getMaterial() + { + return _mat; + } + + public Packet[] getSpawnPackets(IronGolem entity) + { + Packet[] packets = new Packet[3]; + + PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving(); + + DataWatcher watcher = new DataWatcher(null); + watcher.a(0, (byte) 32); + watcher.a(1, 0); + + packet1.a = _chicken; + packet1.b = EntityType.SILVERFISH.getTypeId(); + packet1.c = (int) Math.floor(_location.getX() * 32); + packet1.d = (int) Math.floor(_location.getY() * 32); + packet1.e = (int) Math.floor(_location.getZ() * 32); + packet1.l = watcher; + + packets[0] = packet1; + + PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70, _mat.getId()); + + packet2.a = _block; + + packet2.b = (int) Math.floor(_location.getX() * 32); + packet2.c = (int) Math.floor(entity.getLocation().getY() * 32); + packet2.d = (int) Math.floor(_location.getZ() * 32); + + packets[1] = packet2; + + PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity(); + + packet3.b = _block; + packet3.c = _chicken; + + packets[2] = packet3; + + return packets; + } +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemAbility.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemAbility.java new file mode 100644 index 000000000..2819662e9 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemAbility.java @@ -0,0 +1,98 @@ +package mineplex.game.clans.clans.worldevent.event.golem.abilities; + +import java.util.HashMap; +import java.util.UUID; + +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; + +public abstract class GolemAbility implements Listener +{ + private GolemCreature _creature; + private HashMap _damaged = new HashMap(); + + public boolean canDamage(Entity player) + { + if (_damaged.containsKey(player.getUniqueId())) + { + + if (!UtilTime.elapsed(_damaged.get(player.getUniqueId()), 400)) + { + return false; + } + } + + _damaged.put(player.getUniqueId(), System.currentTimeMillis()); + return true; + } + + public GolemAbility(GolemCreature creature) + { + _creature = creature; + } + + public abstract boolean canMove(); + + public int getCooldown() + { + return 60; + } + + public IronGolem getEntity() + { + return getGolem().getEntity(); + } + + public GolemCreature getGolem() + { + return _creature; + } + + public Location getLocation() + { + return getEntity().getLocation(); + } + + public Player getTarget() + { + return getTarget(30); + } + + public Player getTarget(double maxDistance) + { + Player target = null; + double dist = 0; + + for (Player player : UtilServer.getPlayers()) + { + if (!player.hasLineOfSight(getEntity())) + { + continue; + } + + double d = player.getLocation().distance(getLocation()); + + if (d <= maxDistance && (target == null || dist > d)) + { + target = player; + dist = d; + } + } + + return target; + } + + public abstract boolean hasFinished(); + + public abstract void setFinished(); + + public abstract void tick(); + +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemBlockHail.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemBlockHail.java new file mode 100644 index 000000000..fc6af6ae7 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemBlockHail.java @@ -0,0 +1,430 @@ +package mineplex.game.clans.clans.worldevent.event.golem.abilities; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilShapes; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import net.minecraft.server.v1_7_R4.AxisAlignedBB; +import net.minecraft.server.v1_7_R4.EntityIronGolem; +import net.minecraft.server.v1_7_R4.MathHelper; +import net.minecraft.server.v1_7_R4.MovingObjectPosition; +import net.minecraft.server.v1_7_R4.Packet; +import net.minecraft.server.v1_7_R4.Vec3D; + +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftIronGolem; +import org.bukkit.entity.Entity; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +/** + * Rumble is where the golem picks a target then starts playing a animation for a second where its obviously preparing to use it. + * Copy this from Wizards + */ +public class GolemBlockHail extends GolemAbility +{ + private int _currentBlock; + private int _currentLevel; + private ArrayList _fallingBlocks = new ArrayList(); + private HashMap> _floatingBlocks = new HashMap>(); + private int _levelToReach; + private boolean _spawned; + private ArrayList _spawnLocs = new ArrayList(); + private Player _target; + private Location _center; + private int _ticks; + + public GolemBlockHail(GolemCreature creature) + { + super(creature); + + _center = getLocation(); + + if (creature.getHealthPercent() > 0.75) + { + _levelToReach = 1; + } + else if (creature.getHealthPercent() > 0.5) + { + _levelToReach = 2; + } + else + { + _levelToReach = 3; + } + + _target = getTarget(); + } + + @Override + public Player getTarget() + { + Player target = null; + double dist = 0; + + for (Player player : UtilPlayer.getNearby(_center, 40)) + { + if (!player.hasLineOfSight(getEntity())) + { + continue; + } + + double d = player.getLocation().distance(_center); + + if (target == null || dist > d) + { + target = player; + dist = d; + } + } + + return target; + } + + @Override + public boolean canMove() + { + return _spawned && _floatingBlocks.isEmpty(); + } + + @Override + public boolean hasFinished() + { + return _target == null || !_target.isValid() || ((_fallingBlocks.isEmpty() && _spawned) && _ticks >= 8 * 9) + || _center.distance(_target.getLocation()) > 100; + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + Iterator fallingIterator = _fallingBlocks.iterator(); + + while (fallingIterator.hasNext()) + { + FallingBlock cur = fallingIterator.next(); + + if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + fallingIterator.remove(); + + Block block = cur.getLocation().getBlock(); + block.setTypeIdAndData(0, (byte) 0, true); + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + + // Expire + if (cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + cur.remove(); + continue; + } + + cur.remove(); + continue; + } + + double distanceToEntity = 0.0D; + LivingEntity victim = null; + + net.minecraft.server.v1_7_R4.Entity nmsEntity = ((CraftEntity) cur).getHandle(); + Vec3D vec3d = Vec3D.a(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + Vec3D vec3d1 = Vec3D.a(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + + nmsEntity.motZ); + + MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false); + vec3d = Vec3D.a(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + vec3d1 = Vec3D.a(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ); + + if (finalObjectPosition != null) + { + vec3d1 = Vec3D.a(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c); + } + + for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities( + ((CraftEntity) cur).getHandle(), + ((CraftEntity) cur).getHandle().boundingBox.a(((CraftEntity) cur).getHandle().motX, + ((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2))) + { + Entity bukkitEntity = ((net.minecraft.server.v1_7_R4.Entity) entity).getBukkitEntity(); + + if (bukkitEntity instanceof LivingEntity) + { + LivingEntity ent = (LivingEntity) bukkitEntity; + + // Avoid Self + if (ent.equals(getEntity())) + continue; + + // Creative or Spec + if (ent instanceof Player) + if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent)) + continue; + + // float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f); + AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().boundingBox.grow(1F, 1F, 1F); + MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1); + + if (entityCollisionPosition != null) + { + double d1 = vec3d.distanceSquared(entityCollisionPosition.pos); + if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D)) + { + victim = ent; + distanceToEntity = d1; + } + } + } + } + + if (victim != null) + { + cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId()); + + if (canDamage(victim)) + { + getGolem() + .getEvent() + .getDamageManager() + .NewDamageEvent((LivingEntity) victim, getEntity(), null, DamageCause.CONTACT, 6, true, true, false, + "Block Hail", "Block Hail"); + } + + if (victim instanceof Player) + { + getGolem().getEvent().getEventManager().getClans().getCondition().Factory() + .Slow("Block Hail", (LivingEntity) victim, getEntity(), 3, 2, false, false, false, false); + } + + fallingIterator.remove(); + cur.remove(); + } + else if (finalObjectPosition != null) + { + Block block = cur.getWorld().getBlockAt(finalObjectPosition.b, finalObjectPosition.c, finalObjectPosition.d); + + if (!UtilBlock.airFoliage(block) && !block.isLiquid()) + { + nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX)); + nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY)); + nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ)); + float f2 = MathHelper.sqrt(nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ + * nmsEntity.motZ); + nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D; + nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D; + nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D; + + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + + fallingIterator.remove(); + cur.remove(); + } + } + else + { + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), cur.getLocation() + .add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL, UtilServer.getPlayers()); + } + } + } + + @Override + public void setFinished() + { + for (ArrayList floatingBlocks : _floatingBlocks.values()) + { + for (BlockHailBlock falling : floatingBlocks) + { + Packet packet = falling.getDestroyPacket(); + + for (Player player : UtilServer.getPlayers()) + { + UtilPlayer.sendPacket(player, packet); + } + } + } + } + + @Override + public void tick() + { + if (!_spawned) + { + if (_currentBlock >= _spawnLocs.size()) + { + + if (_currentLevel + 1 <= _levelToReach) + { + _currentLevel++; + _currentBlock = 0; + + _spawnLocs = UtilShapes.getDistancedCircle(_center.clone().add(0, 2.8 + (_currentLevel * 0.75), 0), 1.3, + 1 + (_currentLevel * 1.3)); + } + } + + if (_currentBlock < _spawnLocs.size()) + { + if (_ticks % 2 == 0) + { + IronGolem entity = getEntity(); + + Location loc = _spawnLocs.get(_currentBlock++); + + ArrayList floatingBlocks = new ArrayList(); + + if (_floatingBlocks.containsKey(_currentLevel)) + { + floatingBlocks = _floatingBlocks.get(_currentLevel); + } + else + { + _floatingBlocks.put(_currentLevel, floatingBlocks); + } + + if (loc.getBlock().getType() == Material.AIR && UtilAlg.HasSight(entity.getLocation(), loc)) + { + + BlockHailBlock floating = new BlockHailBlock(loc, Material.STONE); + UtilEnt.CreatureLook(entity, _target); + + floatingBlocks.add(floating); + + Packet[] packets = floating.getSpawnPackets(entity); + + for (Player player : UtilServer.getPlayers()) + { + if (player.getLocation().distance(loc) < 100) + { + UtilPlayer.sendPacket(player, packets); + } + } + + entity.getWorld().playSound(entity.getLocation(), Sound.DIG_GRASS, 3, 0.9F); + } + + if (_floatingBlocks.size() % 2 == 0) + { + Collections.reverse(floatingBlocks); + } + } + } + else + { + _spawned = true; + _ticks = -20; + } + } + else if (_ticks > 0 && _ticks % 2 == 0 && !_floatingBlocks.isEmpty()) + { + IronGolem entity = getEntity(); + + if (_ticks % 16 == 0) + { + _target = getTarget(); + + if (_target == null) + return; + } + + EntityIronGolem golem = ((CraftIronGolem) entity).getHandle(); + + golem.world.broadcastEntityEffect(golem, (byte) 4); + UtilEnt.CreatureLook(entity, _target); + + BlockHailBlock floatingBlock = null; + + for (int i = 1; i <= _currentLevel; i++) + { + if (_floatingBlocks.containsKey(i)) + { + floatingBlock = _floatingBlocks.get(i).remove(0); + + if (_floatingBlocks.get(i).isEmpty()) + { + _floatingBlocks.remove(i); + } + + break; + } + } + + Packet packet = floatingBlock.getDestroyPacket(); + + for (Player player : UtilServer.getPlayers()) + { + UtilPlayer.sendPacket(player, packet); + } + + Location loc = floatingBlock.getLocation(); + + FallingBlock b = loc.getWorld().spawnFallingBlock(loc, floatingBlock.getMaterial(), (byte) 0); + b.setDropItem(false); + + Vector vec = UtilAlg.calculateVelocity( + loc.toVector(), + _target.getLocation() + .toVector() + .add(new Vector(UtilMath.r(6 + (_currentLevel * 2)) - (2 + _currentLevel), 0, UtilMath + .r(6 + (_currentLevel * 2)) - (2 + _currentLevel))), 6); + + b.setVelocity(vec); + + _fallingBlocks.add(b); + + entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 3, 0.9F); + } + + ArrayList points = new ArrayList(); + + for (int i = _currentLevel; i <= _currentLevel; i++) + { + points.addAll(UtilShapes.getDistancedCircle(_center.clone().add(0, 3.3 + (i * 0.75), 0), 0.3, 1 + (i * 1.3))); + } + + for (int i = 0; i < points.size(); i++) + { + if (_spawned || i < _ticks) + { + Location loc = points.get(i); + + UtilParticle.PlayParticle( + ParticleType.BLOCK_DUST.getParticle(_spawned && i < _ticks ? Material.STONE : Material.DIRT, 0), loc, 0, + 0, 0, 0, 0, UtilParticle.ViewDist.LONG, UtilServer.getPlayers()); + } + } + + _ticks++; + } + +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemBlockShot.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemBlockShot.java new file mode 100644 index 000000000..fa8f1e7a7 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemBlockShot.java @@ -0,0 +1,412 @@ +package mineplex.game.clans.clans.worldevent.event.golem.abilities; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map.Entry; +import java.util.UUID; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import net.minecraft.server.v1_7_R4.AxisAlignedBB; +import net.minecraft.server.v1_7_R4.EntityIronGolem; +import net.minecraft.server.v1_7_R4.MathHelper; +import net.minecraft.server.v1_7_R4.MovingObjectPosition; +import net.minecraft.server.v1_7_R4.PacketPlayOutEntityDestroy; +import net.minecraft.server.v1_7_R4.PacketPlayOutEntityVelocity; +import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntity; +import net.minecraft.server.v1_7_R4.Vec3D; + +import org.bukkit.Bukkit; +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftIronGolem; +import org.bukkit.entity.Entity; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +public class GolemBlockShot extends GolemAbility +{ + private HashMap _blockLoc = new HashMap(); + private HashMap _blockType = new HashMap(); + private ArrayList _current = new ArrayList(); + private HashMap _preshoot = new HashMap(); + private Player _target; + private HashMap _targetBlock = new HashMap(); + private HashMap _shotAt = new HashMap(); + private int _thrown; + private int _tick; + private int _toThrow; + + public GolemBlockShot(GolemCreature creature) + { + super(creature); + + if (creature.getHealthPercent() > 0.75) + { + _toThrow = 3; + } + else if (creature.getHealthPercent() > 0.5) + { + _toThrow = 6; + } + else + { + _toThrow = 9; + } + + _target = getTarget(); + } + + @Override + public boolean canMove() + { + return _current.isEmpty() && _thrown == _toThrow; + } + + @Override + public Player getTarget() + { + Player target = null; + double dist = 0; + + Location loc1 = getLocation(); + Location loc2 = loc1.clone().add(loc1.getDirection().setY(0).normalize()); + + LinkedList players = UtilPlayer.getNearby(getLocation(), 40); + + for (Player player : players) + { + if (_shotAt.containsKey(player.getUniqueId()) && _shotAt.get(player.getUniqueId()) >= 3) + { + continue; + } + + double dist1 = player.getLocation().distance(loc1); + double dist2 = player.getLocation().distance(loc2); + + double dist3 = dist1 - dist2; + + if (dist3 < 0.6 || dist1 > 30 || (target != null && dist3 < dist)) + { + continue; + } + + if (!player.hasLineOfSight(getEntity())) + { + continue; + } + + target = player; + dist = dist3; + } + + return target; + } + + @Override + public boolean hasFinished() + { + return _current.isEmpty() && _preshoot.isEmpty() && (_target == null || _thrown == _toThrow); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + Iterator fallingIterator = _current.iterator(); + + while (fallingIterator.hasNext()) + { + FallingBlock cur = fallingIterator.next(); + + if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + fallingIterator.remove(); + + Block block = cur.getLocation().getBlock(); + block.setTypeIdAndData(0, (byte) 0, true); + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + + // Expire + if (cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + cur.remove(); + continue; + } + + cur.remove(); + continue; + } + + double distanceToEntity = 0.0D; + LivingEntity victim = null; + + net.minecraft.server.v1_7_R4.Entity nmsEntity = ((CraftEntity) cur).getHandle(); + Vec3D vec3d = Vec3D.a(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + Vec3D vec3d1 = Vec3D.a(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + + nmsEntity.motZ); + + MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false); + vec3d = Vec3D.a(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + vec3d1 = Vec3D.a(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ); + + if (finalObjectPosition != null) + { + vec3d1 = Vec3D.a(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c); + } + + for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities( + ((CraftEntity) cur).getHandle(), + ((CraftEntity) cur).getHandle().boundingBox.a(((CraftEntity) cur).getHandle().motX, + ((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2))) + { + Entity bukkitEntity = ((net.minecraft.server.v1_7_R4.Entity) entity).getBukkitEntity(); + + if (bukkitEntity instanceof LivingEntity) + { + LivingEntity ent = (LivingEntity) bukkitEntity; + + // Avoid Self + if (ent.equals(getEntity())) + continue; + + // Creative or Spec + if (ent instanceof Player) + if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent)) + continue; + + // float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f); + AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().boundingBox.grow(1F, 1F, 1F); + MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1); + + if (entityCollisionPosition != null) + { + double d1 = vec3d.distanceSquared(entityCollisionPosition.pos); + if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D)) + { + victim = ent; + distanceToEntity = d1; + } + } + } + } + + if (victim != null) + { + cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId()); + + getGolem() + .getEvent() + .getDamageManager() + .NewDamageEvent((LivingEntity) victim, getEntity(), null, DamageCause.CONTACT, 6, true, true, false, + "Block Throw", "Block Throw"); + + cur.remove(); + fallingIterator.remove(); + + Vector vec = UtilAlg.getTrajectory(cur, victim); + vec.setY(0).normalize(); + + UtilAction.velocity(victim, vec, 1.2, true, 0, 0.1, 1, true); + } + else if (finalObjectPosition != null) + { + Block block = cur.getWorld().getBlockAt(finalObjectPosition.b, finalObjectPosition.c, finalObjectPosition.d); + + if (!UtilBlock.airFoliage(block) && !block.isLiquid()) + { + nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX)); + nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY)); + nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ)); + float f2 = MathHelper.sqrt(nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ + * nmsEntity.motZ); + nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D; + nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D; + nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D; + + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + cur.remove(); + fallingIterator.remove(); + } + } + else + { + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), cur.getLocation() + .add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL, UtilServer.getPlayers()); + } + } + } + + @Override + public void setFinished() + { + for (FallingBlock falling : _current) + { + falling.remove(); + } + + int[] ids = new int[_preshoot.size()]; + + int a = 0; + for (int id : _preshoot.keySet()) + { + ids[a++] = id; + } + + PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids); + + for (Player player : Bukkit.getOnlinePlayers()) + { + UtilPlayer.sendPacket(player, packet); + } + } + + @Override + public void tick() + { + if (_target == null || _target.getLocation().distance(getLocation()) > 30 || !_target.hasLineOfSight(getEntity())) + { + _target = getTarget(); + } + + Entity entity = getEntity(); + + if (_tick++ % 16 == 0 && _target != null && _thrown < _toThrow) + { + _thrown++; + + UtilEnt.CreatureLook(entity, _target); + EntityIronGolem golem = ((CraftIronGolem) entity).getHandle(); + + golem.world.broadcastEntityEffect(golem, (byte) 4); + + entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 2, 1); + + Location loc = entity.getLocation(); + loc.setYaw(loc.getYaw() + (UtilMath.r(150) - 75)); + loc.add(loc.getDirection().setY(0).normalize()); + + Block block = loc.getBlock(); + + if (block.getType() == Material.AIR) + { + block = block.getRelative(BlockFace.DOWN); + } + + Material mat = block.getType(); + + if (!UtilBlock.solid(block)) + { + mat = Material.STONE; + } + + int id = UtilEnt.getNewEntityId(); + + _preshoot.put(id, System.currentTimeMillis()); + _blockType.put(id, mat); + _blockLoc.put(id, loc.clone().add(0, 0.6, 0)); + _targetBlock.put(id, _target); + + PacketPlayOutSpawnEntity packet = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70, mat.getId()); + + packet.a = id; + + packet.b = (int) Math.floor(loc.getX() * 32); + packet.c = (int) Math.floor(loc.getY() * 32); + packet.d = (int) Math.floor(loc.getZ() * 32); + + packet.g = (int) ((0.45) * 8000); + + PacketPlayOutEntityVelocity packet2 = new PacketPlayOutEntityVelocity(id, 0, 0.45D, 0); + + for (Player player : UtilPlayer.getNearby(loc, 70)) + { + UtilPlayer.sendPacket(player, packet, packet2); + } + + _shotAt.put(_target.getUniqueId(), (_shotAt.containsKey(_target.getUniqueId()) ? _shotAt.get(_target.getUniqueId()) + : 0) + 1); + + _target = getTarget(); + } + else + { + Iterator> itel = _preshoot.entrySet().iterator(); + + while (itel.hasNext()) + { + Entry entry = itel.next(); + + if (UtilTime.elapsed(entry.getValue(), 900)) + { + itel.remove(); + + int id = entry.getKey(); + + PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(new int[] + { + id + }); + + for (Player player : Bukkit.getOnlinePlayers()) + { + UtilPlayer.sendPacket(player, packet); + } + + Location loc = _blockLoc.get(id); + FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, _blockType.get(id), (byte) 0); + falling.setDropItem(false); + + _current.add(falling); + + Player target = _targetBlock.get(id); + + UtilEnt.CreatureLook(entity, target); + EntityIronGolem golem = ((CraftIronGolem) entity).getHandle(); + + golem.world.broadcastEntityEffect(golem, (byte) 4); + + entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 2, 1.2F); + entity.getWorld().playEffect(falling.getLocation(), Effect.STEP_SOUND, falling.getBlockId()); + + Location l = falling.getLocation(); + l.setY(entity.getLocation().getY()); + + Vector vector = UtilAlg.getTrajectory(l, target.getEyeLocation()); + + falling.setVelocity(vector.multiply(0.5 + (l.distance(target.getEyeLocation()) / 10))); + } + } + } + } +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemCaveIn.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemCaveIn.java new file mode 100644 index 000000000..4fab784aa --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemCaveIn.java @@ -0,0 +1,316 @@ +package mineplex.game.clans.clans.worldevent.event.golem.abilities; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilShapes; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import net.minecraft.server.v1_7_R4.AxisAlignedBB; +import net.minecraft.server.v1_7_R4.MathHelper; +import net.minecraft.server.v1_7_R4.MovingObjectPosition; +import net.minecraft.server.v1_7_R4.Vec3D; + +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; +import org.bukkit.entity.Entity; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +public class GolemCaveIn extends GolemAbility +{ + private ArrayList _blocks = new ArrayList(); + private ArrayList _fallingBlocks = new ArrayList(); + private int _tick; + + public GolemCaveIn(GolemCreature creature) + { + super(creature); + } + + @Override + public boolean canMove() + { + return false; + } + + @Override + public Player getTarget() + { + if (getTarget(3) == null) + { + return getTarget(40); + } + + return null; + } + + @Override + public boolean hasFinished() + { + return _tick > 60 && _fallingBlocks.isEmpty(); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + Iterator fallingIterator = _fallingBlocks.iterator(); + + while (fallingIterator.hasNext()) + { + FallingBlock cur = fallingIterator.next(); + + if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + fallingIterator.remove(); + + Block block = cur.getLocation().getBlock(); + block.setTypeIdAndData(0, (byte) 0, true); + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + + // Expire + if (cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + cur.remove(); + continue; + } + + cur.remove(); + continue; + } + + double distanceToEntity = 0.0D; + LivingEntity victim = null; + + net.minecraft.server.v1_7_R4.Entity nmsEntity = ((CraftEntity) cur).getHandle(); + Vec3D vec3d = Vec3D.a(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + Vec3D vec3d1 = Vec3D.a(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + + nmsEntity.motZ); + + MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false); + vec3d = Vec3D.a(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + vec3d1 = Vec3D.a(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ); + + if (finalObjectPosition != null) + { + vec3d1 = Vec3D.a(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c); + } + + for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities( + ((CraftEntity) cur).getHandle(), + ((CraftEntity) cur).getHandle().boundingBox.a(((CraftEntity) cur).getHandle().motX, + ((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2))) + { + Entity bukkitEntity = ((net.minecraft.server.v1_7_R4.Entity) entity).getBukkitEntity(); + + if (bukkitEntity instanceof LivingEntity) + { + LivingEntity ent = (LivingEntity) bukkitEntity; + + // Avoid Self + if (ent.equals(getEntity())) + continue; + + // Creative or Spec + if (ent instanceof Player) + if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent)) + continue; + + // float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f); + AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().boundingBox.grow(1F, 1F, 1F); + MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1); + + if (entityCollisionPosition != null) + { + double d1 = vec3d.distanceSquared(entityCollisionPosition.pos); + if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D)) + { + victim = ent; + distanceToEntity = d1; + } + } + } + } + + if (victim != null) + { + cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId()); + + if (canDamage(victim)) + { + getGolem() + .getEvent() + .getDamageManager() + .NewDamageEvent((LivingEntity) victim, getEntity(), null, DamageCause.CONTACT, 6, true, true, false, + "Cave In", "Cave In"); + } + + cur.remove(); + fallingIterator.remove(); + } + else if (finalObjectPosition != null) + { + Block block = cur.getWorld().getBlockAt(finalObjectPosition.b, finalObjectPosition.c, finalObjectPosition.d); + + if (!UtilBlock.airFoliage(block) && !block.isLiquid()) + { + nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX)); + nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY)); + nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ)); + float f2 = MathHelper.sqrt(nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ + * nmsEntity.motZ); + nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D; + nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D; + nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D; + + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + cur.remove(); + fallingIterator.remove(); + } + } + else + { + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), cur.getLocation() + .add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL, UtilServer.getPlayers()); + } + } + } + + @Override + public void setFinished() + { + for (FallingBlock block : _fallingBlocks) + { + block.remove(); + } + + for (Block block : _blocks) + { + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId()); + block.setType(Material.AIR); + } + } + + @Override + public void tick() + { + if (_tick++ == 0) + { + Location l = getLocation(); + + ArrayList blocks = UtilShapes.getSphereBlocks(l, 3, 3, true); + + for (Location loc : blocks) + { + if (loc.getBlockY() >= l.getBlockY()) + { + Block b = loc.getBlock(); + + if (b.getType() == Material.AIR) + { + _blocks.add(b); + + loc.setY(l.getY() - 1); + + b.setType(loc.getBlock().getType()); + + b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, loc.getBlock().getTypeId()); + } + } + } + } + + if (_tick < 200) + { + Location loc = getLocation(); + loc.setY(loc.getY() + 8); + + for (int i = 0; i < 30; i++) + { + loc.setY(loc.getY() + 1); + Block b = loc.getBlock(); + + if (UtilBlock.solid(b)) + { + break; + } + } + + if (!UtilBlock.solid(loc.getBlock())) + { + return; + } + + LinkedList players = UtilPlayer.getNearby(getLocation(), 50); + + for (int i = 0; i < players.size(); i++) + { + int dist = UtilMath.r(10); + + if (dist < 3) + { + dist = 2; + } + else if (dist < 5) + { + dist = 5; + } + else + { + dist = 10; + } + + Location l = players.get(UtilMath.r(players.size())).getLocation() + .add(UtilMath.r(dist * 2) - dist, 0, UtilMath.r(dist * 2) - dist); + l.setY(loc.getY()); + + Block b = l.getBlock(); + l.subtract(0, 1, 0); + + if (UtilBlock.solid(b)) + { + if (l.getBlock().getType() == Material.AIR) + { + if (UtilAlg.HasSight(l, getLocation().add(0, 8, 0))) + { + FallingBlock block = b.getWorld().spawnFallingBlock(b.getLocation().add(0.5, -1, 0.5), b.getTypeId(), + b.getData()); + + block.setVelocity(new Vector(UtilMath.r(5) - 2.5D, 0, UtilMath.r(5) - 2.5D).multiply(0.1)); + block.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, block.getBlockId()); + block.setDropItem(false); + + _fallingBlocks.add(block); + } + } + } + } + } + } + +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemEarthquake.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemEarthquake.java new file mode 100644 index 000000000..df3b8b157 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemEarthquake.java @@ -0,0 +1,161 @@ +package mineplex.game.clans.clans.worldevent.event.golem.abilities; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.UUID; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilShapes; +import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +public class GolemEarthquake extends GolemAbility +{ + private Location _center; + private float _range; + private int _tick; + private ArrayList _damaged = new ArrayList(); + + public GolemEarthquake(GolemCreature creature) + { + super(creature); + _center = getLocation(); + } + + @Override + public boolean canMove() + { + return !UtilEnt.isGrounded(getEntity()) && _tick > 1; + } + + @Override + public Player getTarget() + { + return getTarget(7); + } + + @Override + public boolean hasFinished() + { + return _range > 15; + } + + @Override + public void setFinished() + { + } + + @Override + public void tick() + { + Entity entity = getEntity(); + + if (_tick == 0) + { + entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 4, 0); + + entity.setVelocity(new Vector(0, 1, 0)); + } + + if (_tick > 10 && UtilEnt.isGrounded(entity)) + { + _range += 0.7; + + for (float range = _range - 2; range <= _range; range++) + { + if (range <= 0) + { + continue; + } + + for (int x = -1; x <= 1; x++) + { + for (int z = -1; z <= 1; z++) + { + if ((x != 0) == (z != 0)) + { + continue; + } + + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0), + _center.clone().add(x * range, 0.1, z * range), (x != 0) ? 0 : (range / 2), 0.1F, (z != 0) ? 0 + : (range / 2), 0, (int) (range * 4), UtilParticle.ViewDist.NORMAL, UtilServer + .getPlayers()); + } + } + } + + _center.getWorld().playSound(_center, Sound.DIG_GRASS, 2, 0.8F); + + HashSet toDamage = new HashSet(); + + Location cornerA = _center.clone().add(-_range, -1, -_range); + Location cornerB = _center.clone().add(_range, 1, _range); + Location cornerA1 = _center.clone().add(-(_range - 1.5), -1, -(_range - 1.5)); + Location cornerB1 = _center.clone().add(_range - 1.5, 1, _range - 1.5); + + for (Player player : Bukkit.getOnlinePlayers()) + { + Location pLoc = player.getLocation(); + + if (_damaged.contains(player.getUniqueId())) + { + continue; + } + + if (!UtilAlg.inBoundingBox(pLoc, cornerA, cornerB)) + { + continue; + } + + if (UtilAlg.inBoundingBox(pLoc, cornerA1, cornerB1)) + { + continue; + } + + toDamage.add(player); + } + + for (Player player : toDamage) + { + _damaged.add(player.getUniqueId()); + + getGolem() + .getEvent() + .getDamageManager() + .NewDamageEvent((LivingEntity) player, getEntity(), null, DamageCause.CONTACT, 6, false, true, false, + "Earthquake", "Earthquake"); + + getGolem().getEvent().getEventManager().getClans().getCondition().Factory() + .Slow("Earthquake", (LivingEntity) player, getEntity(), 3, 1, false, false, false, false); + + // Velocity + UtilAction.velocity(player, UtilAlg.getTrajectory2d(getLocation().toVector(), player.getLocation().toVector()), + 1.8, true, 0, 0.5, 0.5, true); + + // Condition + getGolem().getEvent().getEventManager().getClans().getCondition().Factory() + .Falling("Earthquake", player, getEntity(), 10, false, true); + } + } + + _tick++; + } +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemExplosiveBlock.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemExplosiveBlock.java new file mode 100644 index 000000000..e92b279d2 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemExplosiveBlock.java @@ -0,0 +1,583 @@ +package mineplex.game.clans.clans.worldevent.event.golem.abilities; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilParticle.ViewDist; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; +import mineplex.minecraft.game.core.explosion.CustomExplosion; +import net.minecraft.server.v1_7_R4.AxisAlignedBB; +import net.minecraft.server.v1_7_R4.DataWatcher; +import net.minecraft.server.v1_7_R4.EntityIronGolem; +import net.minecraft.server.v1_7_R4.MathHelper; +import net.minecraft.server.v1_7_R4.MovingObjectPosition; +import net.minecraft.server.v1_7_R4.Packet; +import net.minecraft.server.v1_7_R4.PacketPlayOutAttachEntity; +import net.minecraft.server.v1_7_R4.PacketPlayOutEntityDestroy; +import net.minecraft.server.v1_7_R4.PacketPlayOutRelEntityMove; +import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntity; +import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntityLiving; +import net.minecraft.server.v1_7_R4.Vec3D; + +import org.bukkit.Bukkit; +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftIronGolem; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.util.Vector; + +public class GolemExplosiveBlock extends GolemAbility +{ + private HashMap _blocksLocation = new HashMap(); + private Location _center; + private int _explosionsLeft; + private FallingBlock _fallingBlock; + private HashMap _fallingBlocks = new HashMap(); + private ArrayList _items = new ArrayList(); + private int _strength; + private Player _target; + private int _tick; + + public GolemExplosiveBlock(GolemCreature creature, int strength) + { + super(creature); + + _strength = strength; + _center = getLocation().add(0, 3, 0); + _target = getTarget(); + + if (_target != null) + { + UtilEnt.CreatureLook(getEntity(), _target); + } + } + + @Override + public boolean canMove() + { + return _fallingBlock != null; + } + + private int clamp(int value) + { + if (value < -127) + return -127; + + if (value > 127) + return 127; + + return value; + } + + @Override + public Player getTarget() + { + HashMap locs = new HashMap(); + + for (Player player : UtilServer.getPlayers()) + { + double dist = player.getLocation().distance(_center); + + if (dist < 30) + { + double score = (dist > 10 ? 30 - dist : 10); + + for (Player p : UtilServer.getPlayers()) + { + if (player.getLocation().distance(p.getLocation()) < 4) + { + score += 7; + } + } + + if (player.hasLineOfSight(getEntity())) + { + score += 10; + } + + locs.put(player, score); + } + } + + Player lowest = null; + + for (Entry entry : locs.entrySet()) + { + if (lowest == null || locs.get(lowest) > locs.get(entry.getKey())) + { + lowest = entry.getKey(); + } + } + + return lowest; + } + + @Override + public boolean hasFinished() + { + return _target == null || (_fallingBlock != null && !_fallingBlock.isValid() && _explosionsLeft == 0); + } + + @EventHandler + public void onDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().equals(getEntity())) + { + if (_tick >= 40 + (40 * _strength) && _tick <= 50 + (40 * _strength)) + { + event.SetCancelled("Iron Wizard charging bomb"); + } + + event.SetKnockback(false); + } + } + + public void onExplode(final Location loc) + { + for (int i = 0; i < _strength * 2; i++) + { + if (i == 0) + { + onSubExplode(loc); + } + else + { + _explosionsLeft++; + + Bukkit.getScheduler().scheduleSyncDelayedTask(getGolem().getEvent().getEventManager().getPlugin(), new Runnable() + { + public void run() + { + onSubExplode(loc); + _explosionsLeft--; + } + }, 2 * i); + } + } + } + + public void onSubExplode(Location loc) + { + for (int i = 0; i < 2; i++) + { + Location l = loc.clone().add(UtilMath.r(_strength * 4) - (_strength * 2), UtilMath.r(_strength * 2), + UtilMath.r(_strength * 4) - (_strength * 2)); + + CustomExplosion explosion = new CustomExplosion(getGolem().getEvent().getDamageManager(), getGolem().getEvent() + .getEventManager().getClans().getExplosion(), l, _strength * 0.8F, "Golem Explosive Block"); + + explosion.setPlayer(getEntity(), false); + + explosion.setDamageBlocks(false); + + explosion.explode(); + + UtilParticle.PlayParticle(ParticleType.LARGE_EXPLODE, l, _strength * 3, 1, _strength * 3, 0, _strength * 4, + ViewDist.LONG, UtilServer.getPlayers()); + } + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + if (_fallingBlock == null) + { + return; + } + + if (_fallingBlock.isDead() + || !_fallingBlock.isValid() + || _fallingBlock.getTicksLived() > 400 + || !_fallingBlock.getWorld().isChunkLoaded(_fallingBlock.getLocation().getBlockX() >> 4, + _fallingBlock.getLocation().getBlockZ() >> 4)) + { + Block block = _fallingBlock.getLocation().getBlock(); + block.setTypeIdAndData(0, (byte) 0, true); + _fallingBlock.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, _fallingBlock.getBlockId()); + + // Expire + if (_fallingBlock.getTicksLived() > 400 + || !_fallingBlock.getWorld().isChunkLoaded(_fallingBlock.getLocation().getBlockX() >> 4, + _fallingBlock.getLocation().getBlockZ() >> 4)) + { + _fallingBlock.remove(); + return; + } + + _fallingBlock.remove(); + return; + } + + double distanceToEntity = 0.0D; + LivingEntity victim = null; + + net.minecraft.server.v1_7_R4.Entity nmsEntity = ((CraftEntity) _fallingBlock).getHandle(); + Vec3D vec3d = Vec3D.a(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + Vec3D vec3d1 = Vec3D.a(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ); + + MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false); + vec3d = Vec3D.a(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + vec3d1 = Vec3D.a(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ); + + if (finalObjectPosition != null) + { + vec3d1 = Vec3D.a(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c); + } + + for (Object entity : ((CraftWorld) _fallingBlock.getWorld()).getHandle().getEntities( + ((CraftEntity) _fallingBlock).getHandle(), + ((CraftEntity) _fallingBlock).getHandle().boundingBox.a(((CraftEntity) _fallingBlock).getHandle().motX, + ((CraftEntity) _fallingBlock).getHandle().motY, ((CraftEntity) _fallingBlock).getHandle().motZ).grow(2, + 2, 2))) + { + Entity bukkitEntity = ((net.minecraft.server.v1_7_R4.Entity) entity).getBukkitEntity(); + + if (bukkitEntity instanceof LivingEntity) + { + LivingEntity ent = (LivingEntity) bukkitEntity; + + // Avoid Self + if (ent.equals(getEntity())) + continue; + + // Creative or Spec + if (ent instanceof Player) + if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent)) + continue; + + // float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f); + AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().boundingBox.grow(1F, 1F, 1F); + MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1); + + if (entityCollisionPosition != null) + { + double d1 = vec3d.distanceSquared(entityCollisionPosition.pos); + if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D)) + { + victim = ent; + distanceToEntity = d1; + } + } + } + } + + if (victim != null) + { + onExplode(victim.getEyeLocation()); + + _fallingBlock.remove(); + } + else if (finalObjectPosition != null) + { + Block block = _fallingBlock.getWorld() + .getBlockAt(finalObjectPosition.b, finalObjectPosition.c, finalObjectPosition.d); + + if (!UtilBlock.airFoliage(block) && !block.isLiquid()) + { + nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX)); + nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY)); + nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ)); + float f2 = MathHelper.sqrt(nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ + * nmsEntity.motZ); + nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D; + nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D; + nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D; + + onExplode(block.getLocation().add(0.5, 0.5, 0.5)); + + _fallingBlock.remove(); + } + } + else + { + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), + _fallingBlock.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL, + UtilServer.getPlayers()); + } + } + + @Override + public void setFinished() + { + int[] ids = new int[_fallingBlocks.size() * 2]; + + int index = 0; + + for (Entry entry : _fallingBlocks.entrySet()) + { + ids[index] = entry.getKey(); + ids[index + 1] = entry.getValue(); + index += 2; + } + + PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids); + + for (Player player : Bukkit.getOnlinePlayers()) + { + UtilPlayer.sendPacket(player, packet); + } + + for (Item item : _items) + { + item.remove(); + } + + if (_fallingBlock != null) + { + _fallingBlock.remove(); + } + } + + @Override + public void tick() + { + IronGolem entity = getEntity(); + + Iterator itel = _items.iterator(); + + while (itel.hasNext()) + { + Item item = itel.next(); + + Vector vec = item.getVelocity(); + Location loc = item.getLocation(); + + if (item.getTicksLived() > 100 || vec.getY() <= 0 || loc.distance(_center) > loc.add(vec).distance(_center) + || UtilEnt.isGrounded(item)) + { + itel.remove(); + } + } + + // This spawns a floating block + if (_tick >= 20 && _tick % 60 == 0 && _fallingBlocks.size() < _strength) + { + int id = UtilEnt.getNewEntityId(); + int id2 = UtilEnt.getNewEntityId(); + + _fallingBlocks.put(id, id2); + _blocksLocation.put(id, _center.toVector()); + + Packet[] packets = new Packet[3]; + + PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving(); + + DataWatcher watcher = new DataWatcher(null); + watcher.a(0, (byte) 32); + watcher.a(1, 0); + + packet1.a = id; + packet1.b = EntityType.SILVERFISH.getTypeId(); + packet1.c = (int) Math.floor(_center.getX() * 32); + packet1.d = (int) Math.floor((_center.getY() - 0.125) * 32); + packet1.e = (int) Math.floor(_center.getZ() * 32); + packet1.l = watcher; + + packets[0] = packet1; + + PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70, + Material.DIRT.getId()); + + packet2.a = id2; + + packet2.b = (int) Math.floor(_center.getX() * 32); + packet2.c = (int) Math.floor(_center.getY() * 32); + packet2.d = (int) Math.floor(_center.getZ() * 32); + + packets[1] = packet2; + + PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity(); + + packet3.b = id2; + packet3.c = id; + + packets[2] = packet3; + + for (Player player : UtilServer.getPlayers()) + { + if (player.getLocation().distance(_center) < 80) + { + UtilPlayer.sendPacket(player, packets); + } + } + } + + // This spawns a item that flies above the golem's head and disappears + if (UtilMath.r(6) == 0 && _tick < 40 + (_strength * 40)) + { + double angle = ((2 * Math.PI) / 30) * UtilMath.r(30); + double x = 5 * Math.cos(angle); + double z = 5 * Math.sin(angle); + Location loc = _center.clone().add(x, -3, z); + + Material mat = null; + + switch (UtilMath.r(3)) + { + case 0: + mat = Material.DIRT; + break; + case 1: + mat = Material.STONE; + break; + case 2: + mat = Material.COBBLESTONE; + break; + default: + break; + } + + Item item = loc.getWorld().dropItem(loc, new ItemBuilder(mat).setTitle(System.currentTimeMillis() + "").build()); + + item.setPickupDelay(999999); + + Vector vec = UtilAlg.getTrajectory(_center, item.getLocation()); + + vec.normalize().multiply(5); + + item.setVelocity(vec); + + // TODO Fix velocity + + _items.add(item); + } + + // 10 being when items no longer fly in, 0 being when its shot. + int ticksTillFired = (60 + (40 * _strength)) - _tick; + + if (ticksTillFired > 20) + { + int strength = (int) Math.floor(_tick / 20D); + + int nine = 8 - strength; + + if (_tick % nine == 0) + { + _center.getWorld().playSound(_center, Sound.DIG_GRASS, strength + 1, 1F); + } + } + else if (ticksTillFired < 0) + { + if (_tick % 3 == 0) + { + _center.getWorld().playSound(_fallingBlock.getLocation(), Sound.WOOD_CLICK, _strength + 1, 0.4F); + } + } + + // The location the falling blocks need to stick by + Vector blockCenter = _center.toVector(); + + if (ticksTillFired >= 0 && ticksTillFired <= 20) + { + Vector vec = entity.getLocation().add(entity.getLocation().getDirection().setY(0).normalize().multiply(1.2)) + .add(0, 1, 0).toVector(); + + blockCenter = UtilAlg.getTrajectory(_center.toVector(), blockCenter); + vec.multiply(ticksTillFired / 10D); + + _center.getWorld().playSound(_center, Sound.DIG_SNOW, _strength + 1, 0); + } + else if (_fallingBlock != null) + { + blockCenter = _fallingBlock.getLocation().add(0, 0.5, 0).toVector(); + } + + // Move the fake floating blocks + for (Entry entry : _fallingBlocks.entrySet()) + { + int id = entry.getKey(); + Vector vec = _blocksLocation.get(id); + + int x = clamp((int) ((blockCenter.getX() - vec.getX()) * 32) + (UtilMath.r(8) - 4)); + int y = clamp((int) ((blockCenter.getY() - vec.getY()) * 32) + (UtilMath.r(8) - 4)); + int z = clamp((int) ((blockCenter.getZ() - vec.getZ()) * 32) + (UtilMath.r(8) - 4)); + + vec.add(new Vector(x, y, z)); + + PacketPlayOutRelEntityMove packet = new PacketPlayOutRelEntityMove(); + + packet.a = id; + + packet.b = (byte) x; + packet.c = (byte) y; + packet.d = (byte) z; + + for (Player player : UtilServer.getPlayers()) + { + if (player.getLocation().distance(_center) < 70) + { + UtilPlayer.sendPacket(player, packet); + + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), + vec.toLocation(_center.getWorld()), 0.7F, 0.7F, 0.7F, 0, 11, ViewDist.NORMAL, player); + } + } + } + + if (ticksTillFired == 0) + { + int id = _fallingBlocks.keySet().iterator().next(); + + PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(new int[] + { + id, _fallingBlocks.get(id) + }); + + for (Player player : Bukkit.getOnlinePlayers()) + { + UtilPlayer.sendPacket(player, packet); + } + + _fallingBlocks.remove(id); + + _fallingBlock = _center.getWorld().spawnFallingBlock(_blocksLocation.get(id).toLocation(_center.getWorld()), + Material.STONE, (byte) 0); + + Vector vec1 = _fallingBlock.getLocation().toVector(); + Vector vec2 = _target.getLocation().toVector(); + + Vector vec = UtilAlg.calculateVelocity(vec1, vec2, (int) (vec1.distanceSquared(vec2) / 4)); + + _fallingBlock.setVelocity(vec); + + EntityIronGolem golem = ((CraftIronGolem) entity).getHandle(); + + golem.world.broadcastEntityEffect(golem, (byte) 4); + } + + _tick++; + } + +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemMeleeAttack.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemMeleeAttack.java new file mode 100644 index 000000000..3a7dbbbeb --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemMeleeAttack.java @@ -0,0 +1,81 @@ +package mineplex.game.clans.clans.worldevent.event.golem.abilities; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; + +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +public class GolemMeleeAttack extends GolemAbility +{ + private boolean _attacked; + + public GolemMeleeAttack(GolemCreature creature) + { + super(creature); + } + + @Override + public boolean canMove() + { + return true; + } + + @Override + public int getCooldown() + { + return 20; + } + + @Override + public Player getTarget() + { + return getTarget(2); + } + + @Override + public boolean hasFinished() + { + return _attacked; + } + + @Override + public void setFinished() + { + } + + @Override + public void tick() + { + _attacked = true; + + for (Player target : UtilPlayer.getNearby(getLocation(), 2)) + { + if (target.getVelocity().length() > 0.5) + { + continue; + } + + UtilEnt.CreatureLook(getEntity(), target); + + getGolem() + .getEvent() + .getDamageManager() + .NewDamageEvent(target, getEntity(), null, DamageCause.ENTITY_ATTACK, 6, false, true, false, "Golem Attack", + "Golem Attack"); + + Vector vec = getLocation().getDirection(); + vec.setY(0).normalize().multiply(0.2); + vec.setY(1); + + UtilAction.velocity(target, vec, 1.4, false, 0, 0, 2, false); + + target.getWorld().playSound(target.getLocation(), Sound.IRONGOLEM_THROW, 3, 0.9F); + } + } + +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemRumble.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemRumble.java new file mode 100644 index 000000000..9e8ae2bc0 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemRumble.java @@ -0,0 +1,215 @@ +package mineplex.game.clans.clans.worldevent.event.golem.abilities; + +import java.util.ArrayList; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilPlayer; +import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import net.minecraft.server.v1_7_R4.EntityIronGolem; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftIronGolem; +import org.bukkit.entity.Damageable; +import org.bukkit.entity.Entity; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +/** + * Rumble is where the golem picks a target then starts playing a animation for a second where its obviously preparing to use it. + * Copy this from Wizards + */ +public class GolemRumble extends GolemAbility +{ + private Location _loc; + private Player _target; + private int _ticks; + private int _travelled; + private Vector _vec; + private int _width = 1; + + public GolemRumble(GolemCreature creature) + { + super(creature); + + _target = getTarget(); + UtilEnt.CreatureLook(getEntity(), _target); + } + + @Override + public boolean canMove() + { + return _ticks >= 20; + } + + @Override + public boolean hasFinished() + { + return _target == null || !_target.isValid() || getLocation().distance(_target.getLocation()) > 100; + } + + @Override + public void setFinished() + { + } + + @Override + public void tick() + { + if (_ticks++ < 14) + { + IronGolem entity = getEntity(); + EntityIronGolem golem = ((CraftIronGolem) entity).getHandle(); + + golem.world.broadcastEntityEffect(golem, (byte) 4); + + if (_ticks % 2 == 0) + { + entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 3, 2F); + UtilEnt.CreatureLook(entity, _target); + } + } + else if (_ticks % 2 == 0) + { + int oldWidth = _width; + + if ((_width <= 3 || _ticks % 4 == 0) && _width <= 5) + { + _width++; + } + + Location newLoc; + boolean validBlock = false; + ArrayList current = new ArrayList(); + + if (_vec == null) + { + _vec = _target.getLocation().subtract(getLocation()).toVector().setY(0).normalize();// .multiply(0.5); + _loc = getLocation().subtract(0, 1, 0).getBlock().getLocation().add(0, 0.99, 0); + newLoc = _loc; + current.add(_loc.getBlock()); + + validBlock = true; + } + else + { // Move rumble + newLoc = _loc.clone().add(_vec); + + // Check if the rumble needs to go up or drop a block or two + for (int y : new int[] + { + 0, 1, -1, -2 + }) + { + if (_loc.getBlockY() + y <= 0) + { + continue; + } + + for (int a = 1; a <= 2; a++) + { + Block b = newLoc.clone().add(_vec.clone().multiply(a)).getBlock().getRelative(0, y, 0); + + if (UtilBlock.solid(b) && !UtilBlock.solid(b.getRelative(0, 1, 0))) + { + validBlock = true; + newLoc.add(0, y, 0); + + break; + } + } + + if (validBlock) + { + break; + } + } + + for (int width = -_width; width <= _width; width++) + { + if (Math.abs(width) <= oldWidth) + { + Block b = _loc.clone().add(UtilAlg.getRight(_vec).multiply(width)).getBlock(); + + if (!current.contains(b)) + { + current.add(b); + } + } + + if (validBlock) + { + Block b = newLoc.clone().add(UtilAlg.getRight(_vec).multiply(width)).getBlock(); + + if (!current.contains(b)) + { + current.add(b); + + b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getTypeId()); + } + } + } + } + + UtilEnt.CreatureLook(getEntity(), _loc); + + for (Entity entity : getEntity().getWorld().getEntities()) + { + if (entity instanceof Damageable && !UtilPlayer.isSpectator(entity) && entity != getEntity()) + { + Block b = entity.getLocation().getBlock(); + boolean canDamage = false; + + for (int y = -1; y <= 0; y++) + { + if (current.contains(b.getRelative(0, y, 0))) + { + canDamage = true; + break; + } + } + + if (!canDamage) + { + continue; + } + + if (canDamage(entity)) + { + getGolem() + .getEvent() + .getDamageManager() + .NewDamageEvent((LivingEntity) entity, getEntity(), null, DamageCause.CONTACT, 6, false, true, + false, "Rumble", "Rumble"); + } + + UtilAction.velocity(entity, _vec.clone(), 1.5, true, 0, 0.2, 1, true); + + if (entity instanceof Player) + { + + getGolem().getEvent().getEventManager().getClans().getCondition().Factory() + .Slow("Rumble", (LivingEntity) entity, getEntity(), 3, 1, false, false, false, false); + } + } + } + + if (_travelled++ > 35 || !validBlock) + { + // TODO Explode? + _target = null; + } + + _loc = newLoc; + } + } + +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemWallExplode.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemWallExplode.java new file mode 100644 index 000000000..2ae35c202 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemWallExplode.java @@ -0,0 +1,403 @@ +package mineplex.game.clans.clans.worldevent.event.golem.abilities; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilShapes; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import net.minecraft.server.v1_7_R4.AxisAlignedBB; +import net.minecraft.server.v1_7_R4.MathHelper; +import net.minecraft.server.v1_7_R4.MovingObjectPosition; +import net.minecraft.server.v1_7_R4.Vec3D; + +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; +import org.bukkit.entity.Entity; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +public class GolemWallExplode extends GolemAbility +{ + private HashMap> _blockWalls = new HashMap>(); + private ArrayList _dontTarget = new ArrayList(); + private ArrayList _fallingBlocks = new ArrayList(); + private int _maxTimes = UtilMath.r(2) + 1; + private int _tick; + private int _timesDone; + private HashMap _wallTimers = new HashMap(); + + public GolemWallExplode(GolemCreature creature) + { + super(creature); + } + + @Override + public boolean canMove() + { + return true; + } + + @Override + public int getCooldown() + { + return 20; + } + + private float getMod(int div) + { + return UtilMath.random.nextFloat() / div; + } + + @Override + public Player getTarget() + { + for (Player player : UtilPlayer.getNearby(getLocation(), 15)) + { + if (_dontTarget.contains(player.getName())) + { + continue; + } + + if (player.getLocation().distance(getLocation()) <= 4) + { + continue; + } + + return player; + } + + return null; + } + + @Override + public boolean hasFinished() + { + return _wallTimers.isEmpty() && _fallingBlocks.isEmpty() && _timesDone >= _maxTimes; + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + Iterator fallingIterator = _fallingBlocks.iterator(); + + while (fallingIterator.hasNext()) + { + FallingBlock cur = fallingIterator.next(); + + if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + fallingIterator.remove(); + + Block block = cur.getLocation().getBlock(); + block.setTypeIdAndData(0, (byte) 0, true); + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + + // Expire + if (cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + cur.remove(); + continue; + } + + cur.remove(); + continue; + } + + double distanceToEntity = 0.0D; + LivingEntity victim = null; + + net.minecraft.server.v1_7_R4.Entity nmsEntity = ((CraftEntity) cur).getHandle(); + Vec3D vec3d = Vec3D.a(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + Vec3D vec3d1 = Vec3D.a(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + + nmsEntity.motZ); + + MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false); + vec3d = Vec3D.a(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + vec3d1 = Vec3D.a(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ); + + if (finalObjectPosition != null) + { + vec3d1 = Vec3D.a(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c); + } + + for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities( + ((CraftEntity) cur).getHandle(), + ((CraftEntity) cur).getHandle().boundingBox.a(((CraftEntity) cur).getHandle().motX, + ((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2))) + { + Entity bukkitEntity = ((net.minecraft.server.v1_7_R4.Entity) entity).getBukkitEntity(); + + if (bukkitEntity instanceof LivingEntity) + { + LivingEntity ent = (LivingEntity) bukkitEntity; + + // Avoid Self + if (ent.equals(getEntity())) + continue; + + // Creative or Spec + if (ent instanceof Player) + if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent)) + continue; + + // float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f); + AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().boundingBox.grow(1F, 1F, 1F); + MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1); + + if (entityCollisionPosition != null) + { + double d1 = vec3d.distanceSquared(entityCollisionPosition.pos); + if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D)) + { + victim = ent; + distanceToEntity = d1; + } + } + } + } + + if (victim != null) + { + cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId()); + + if (canDamage(victim)) + { + getGolem() + .getEvent() + .getDamageManager() + .NewDamageEvent((LivingEntity) victim, getEntity(), null, DamageCause.CONTACT, 6, true, true, false, + "Wall Explosion", "Wall Explosion"); + } + + cur.remove(); + fallingIterator.remove(); + + Vector vec = cur.getVelocity(); + + UtilAction.velocity(victim, vec, 1.5, true, 0, 0.2, 1, true); + } + else if (finalObjectPosition != null) + { + Block block = cur.getWorld().getBlockAt(finalObjectPosition.b, finalObjectPosition.c, finalObjectPosition.d); + + if (!UtilBlock.airFoliage(block) && !block.isLiquid()) + { + nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX)); + nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY)); + nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ)); + float f2 = MathHelper.sqrt(nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ + * nmsEntity.motZ); + nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D; + nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D; + nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D; + + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + cur.remove(); + fallingIterator.remove(); + } + } + else + { + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), cur.getLocation() + .add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL, UtilServer.getPlayers()); + } + } + } + + @Override + public void setFinished() + { + for (FallingBlock block : _fallingBlocks) + { + block.remove(); + } + + for (ArrayList list : _blockWalls.values()) + { + for (Block b : list) + { + b.setType(Material.AIR); + } + } + } + + @Override + public void tick() + { + if (_tick++ % 30 == 0 && _timesDone < _maxTimes) + { + _dontTarget.clear(); + + _timesDone++; + + for (int i = 0; i < 10; i++) + { + Player target = getTarget(); + + if (target == null) + { + if (_dontTarget.isEmpty()) + { + _timesDone = _maxTimes; + } + } + else + { + _dontTarget.add(target.getName()); + + UtilEnt.CreatureLook(getEntity(), target); + + BlockFace face = UtilShapes.getFacing(getLocation().getYaw()); + + if (_wallTimers.containsKey(face)) + { + continue; + } + + ArrayList blocks = new ArrayList(); + + Location loc = getLocation().getBlock().getLocation().add(0.5, 0, 0.5); + + int mul = (face.getModX() != 0 && face.getModZ() != 0) ? 2 : 3; + + loc.add(face.getModX() * mul, 0, face.getModZ() * mul); + + Block b = loc.getBlock(); + + BlockFace sideFace = UtilShapes.getSideBlockFaces(face, true)[0]; + boolean invalid = false; + + for (int mult = -2; mult <= 2; mult++) + { + Block block = b; + + if (Math.abs(mult) < 2) + { + block = block.getRelative(face); + } + + block = block.getRelative(sideFace, mult); + + if (Math.abs(mult) == 2 && face.getModX() != 0 && face.getModZ() != 0) + { + block = block.getRelative(UtilShapes.getSideBlockFaces(face, false)[mult < 0 ? 0 : 1]); + } + + if (!UtilAlg.HasSight(getLocation(), block.getLocation())) + { + invalid = true; + break; + } + + Block under = block.getRelative(0, -1, 0); + + if (!UtilBlock.solid(under)) + { + continue; + } + + for (int y = 0; y <= 1; y++) + { + block = block.getRelative(0, y, 0); + + if (block.getType() != Material.AIR) + { + invalid = true; + break; + } + + blocks.add(block); + } + + if (invalid) + { + break; + } + } + + if (invalid) + { + continue; + } + + for (Block block : blocks) + { + block.setType(block.getWorld().getBlockAt(block.getX(), b.getY() - 1, block.getZ()).getType()); + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId()); + } + + _blockWalls.put(face, blocks); + _wallTimers.put(face, System.currentTimeMillis()); + break; + } + } + } + + Iterator>> itel = _blockWalls.entrySet().iterator(); + + while (itel.hasNext()) + { + Entry> entry = itel.next(); + BlockFace face = entry.getKey(); + + if (UtilTime.elapsed(_wallTimers.get(face), 1000)) + { + itel.remove(); + _wallTimers.remove(face); + + for (Block b : entry.getValue()) + { + FallingBlock block = getEntity().getWorld().spawnFallingBlock(b.getLocation().add(0.5, 0, 0.5), b.getType(), + (byte) 0); + + block.setDropItem(false); + + int index = entry.getValue().indexOf(b); + + BlockFace f = index == 6 || index == 7 ? BlockFace.SELF + : UtilShapes.getSideBlockFaces(face, true)[index > 6 ? 0 : 1]; + + block.setVelocity(new Vector((face.getModX() * 0.65) + (f.getModX() * (0.05 + getMod(10))), 0.2 + getMod(15), + (face.getModZ() * 0.65) + (f.getModZ() * (0.05 + getMod(10))))); + + _fallingBlocks.add(block); + + b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getTypeId()); + b.setType(Material.AIR); + } + } + } + } + +} diff --git a/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/explosion/CustomExplosion.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/explosion/CustomExplosion.java index 4cdf04c68..9599b9a5d 100644 --- a/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/explosion/CustomExplosion.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/explosion/CustomExplosion.java @@ -36,7 +36,7 @@ import net.minecraft.server.v1_7_R4.World; public class CustomExplosion extends Explosion { - private Player _owner; + private org.bukkit.entity.LivingEntity _owner; private boolean _damageOwner; private int _i = 16; private World _world; @@ -142,7 +142,7 @@ public class CustomExplosion extends Explosion return this; } - public CustomExplosion setPlayer(Player player, boolean damageExplosionOwner) + public CustomExplosion setPlayer(org.bukkit.entity.LivingEntity player, boolean damageExplosionOwner) { _owner = player; _damageOwner = damageExplosionOwner; @@ -319,7 +319,7 @@ public class CustomExplosion extends Explosion } } - ExplosionEvent event = _owner == null ? new ExplosionEvent(blockList) : new ExplosionEvent(blockList, _owner); + ExplosionEvent event = _owner == null || !(_owner instanceof Player) ? new ExplosionEvent(blockList) : new ExplosionEvent(blockList, (Player) _owner); this._world.getServer().getPluginManager().callEvent(event); this.blocks.clear(); From 1e14d299991d25952ce747f829a260d0835382df Mon Sep 17 00:00:00 2001 From: libraryaddict Date: Mon, 17 Aug 2015 21:04:26 +1200 Subject: [PATCH 377/377] Clans: Migrate bosses to combat core, fix map to rotate its cursor, finished golem? --- .../clans/worldevent/WorldEventManager.java | 33 +- .../clans/worldevent/WorldEventType.java | 40 +- .../worldevent/event/golem/GolemCreature.java | 382 ------------- .../{event => }/kinghill/HillData.java | 6 +- .../{event => }/kinghill/KingHill.java | 21 +- .../{event => }/undead/CampSize.java | 2 +- .../{event => }/undead/CampType.java | 2 +- .../{event => }/undead/UndeadCamp.java | 43 +- .../undead/creature/UndeadArcher.java | 11 +- .../undead/creature/UndeadWarrior.java | 18 +- .../game/core/boss}/EventCreature.java | 14 +- .../minecraft/game/core/boss}/EventMap.java | 11 +- .../minecraft/game/core/boss}/EventState.java | 2 +- .../minecraft/game/core/boss}/WorldEvent.java | 90 ++-- .../game/core/boss/ironwizard}/GolemBoss.java | 22 +- .../core/boss/ironwizard/GolemCreature.java | 510 ++++++++++++++++++ .../ironwizard}/abilities/BlockHailBlock.java | 10 +- .../ironwizard}/abilities/GolemAbility.java | 11 +- .../ironwizard}/abilities/GolemBlockHail.java | 92 +++- .../ironwizard}/abilities/GolemBlockShot.java | 36 +- .../ironwizard}/abilities/GolemCaveIn.java | 17 +- .../abilities/GolemEarthquake.java | 32 +- .../abilities/GolemExplodingAura.java | 430 +++++++++++++++ .../abilities/GolemExplosiveBlock.java | 18 +- .../abilities/GolemMeleeAttack.java | 24 +- .../ironwizard}/abilities/GolemRumble.java | 70 ++- .../abilities/GolemWallExplode.java | 33 +- .../game/core/boss}/slimeking/SlimeBoss.java | 36 +- .../slimeking/ability/AbsorbAbility.java | 10 +- .../boss}/slimeking/ability/LeapAbility.java | 12 +- .../slimeking/ability/RocketAbility.java | 24 +- .../boss}/slimeking/ability/SlamAbility.java | 14 +- .../boss}/slimeking/ability/SlimeAbility.java | 4 +- .../slimeking/creature/SlimeCreature.java | 58 +- 34 files changed, 1442 insertions(+), 696 deletions(-) delete mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemCreature.java rename Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/{event => }/kinghill/HillData.java (96%) rename Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/{event => }/kinghill/KingHill.java (85%) rename Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/{event => }/undead/CampSize.java (96%) rename Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/{event => }/undead/CampType.java (95%) rename Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/{event => }/undead/UndeadCamp.java (94%) rename Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/{event => }/undead/creature/UndeadArcher.java (89%) rename Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/{event => }/undead/creature/UndeadWarrior.java (92%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/creature => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss}/EventCreature.java (96%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss}/EventMap.java (89%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss}/EventState.java (59%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss}/WorldEvent.java (79%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard}/GolemBoss.java (68%) create mode 100644 Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/GolemCreature.java rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard}/abilities/BlockHailBlock.java (91%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard}/abilities/GolemAbility.java (82%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard}/abilities/GolemBlockHail.java (83%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard}/abilities/GolemBlockShot.java (93%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard}/abilities/GolemCaveIn.java (96%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard}/abilities/GolemEarthquake.java (83%) create mode 100644 Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemExplodingAura.java rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard}/abilities/GolemExplosiveBlock.java (97%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard}/abilities/GolemMeleeAttack.java (64%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard}/abilities/GolemRumble.java (77%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard}/abilities/GolemWallExplode.java (92%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss}/slimeking/SlimeBoss.java (71%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss}/slimeking/ability/AbsorbAbility.java (90%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss}/slimeking/ability/LeapAbility.java (90%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss}/slimeking/ability/RocketAbility.java (93%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss}/slimeking/ability/SlamAbility.java (95%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss}/slimeking/ability/SlimeAbility.java (80%) rename Plugins/{Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event => Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss}/slimeking/creature/SlimeCreature.java (65%) diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventManager.java index 15c5d6bfa..43da47d9a 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventManager.java @@ -1,12 +1,24 @@ package mineplex.game.clans.clans.worldevent; import java.util.ArrayList; -import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Random; -import java.util.Set; + +import mineplex.core.MiniPlugin; +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.common.util.C; +import mineplex.core.scoreboard.ScoreboardManager; +import mineplex.core.scoreboard.elements.ScoreboardElement; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.loot.LootManager; +import mineplex.game.clans.clans.worldevent.command.WorldEventCommand; +import mineplex.minecraft.game.core.boss.EventState; +import mineplex.minecraft.game.core.boss.WorldEvent; +import mineplex.minecraft.game.core.damage.DamageManager; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -19,23 +31,6 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.plugin.java.JavaPlugin; -import mineplex.core.MiniPlugin; -import mineplex.core.blockrestore.BlockRestore; -import mineplex.core.common.util.C; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.common.util.UtilServer; -import mineplex.core.common.util.UtilWorld; -import mineplex.core.scoreboard.ScoreboardManager; -import mineplex.core.scoreboard.elements.ScoreboardElement; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.game.clans.clans.ClansManager; -import mineplex.game.clans.clans.loot.LootManager; -import mineplex.game.clans.clans.worldevent.command.WorldEventCommand; -import mineplex.game.clans.clans.worldevent.event.EventState; -import mineplex.game.clans.clans.worldevent.event.WorldEvent; -import mineplex.minecraft.game.core.damage.DamageManager; - public class WorldEventManager extends MiniPlugin implements ScoreboardElement { private final List _events; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventType.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventType.java index 34d174fee..e1598e018 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventType.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventType.java @@ -1,19 +1,19 @@ package mineplex.game.clans.clans.worldevent; +import java.lang.reflect.Constructor; + +import mineplex.game.clans.clans.worldevent.kinghill.KingHill; +import mineplex.game.clans.clans.worldevent.undead.UndeadCamp; +import mineplex.minecraft.game.core.boss.WorldEvent; +import mineplex.minecraft.game.core.boss.ironwizard.GolemBoss; +import mineplex.minecraft.game.core.boss.slimeking.SlimeBoss; + import org.bukkit.Location; -import mineplex.game.clans.clans.worldevent.event.WorldEvent; -import mineplex.game.clans.clans.worldevent.event.slimeking.SlimeBoss; -import mineplex.game.clans.clans.worldevent.event.golem.GolemBoss; -import mineplex.game.clans.clans.worldevent.event.kinghill.KingHill; -import mineplex.game.clans.clans.worldevent.event.undead.UndeadCamp; - public enum WorldEventType { - SLIME_KING("Slime King", SlimeBoss.class, 30), - KING_OF_THE_HILL("King of The Hill", KingHill.class, 30), - UNDEAD_CAMP("Undead Camp", UndeadCamp.class, 30), - Golem("Iron Wizard", GolemBoss.class, 30); + SLIME_KING("Slime King", SlimeBoss.class, 30), KING_OF_THE_HILL("King of The Hill", KingHill.class, 30), UNDEAD_CAMP( + "Undead Camp", UndeadCamp.class, 30), Golem("Iron Wizard", GolemBoss.class, 30); private String _name; private Class _clazz; @@ -37,7 +37,25 @@ public enum WorldEventType try { - worldEvent = _clazz.getConstructor(WorldEventManager.class, Location.class).newInstance(eventManager, centerLocation); + for (Constructor con : _clazz.getConstructors()) + { + Class[] classes = con.getParameterTypes(); + + if (classes[0] == WorldEventManager.class) + { + worldEvent = (WorldEvent) con.newInstance(eventManager, centerLocation); + } + else if (classes.length == 4) + { + worldEvent = (WorldEvent) con.newInstance(eventManager.getDamage(), eventManager.getBlockRestore(), + eventManager.getClans().getCondition(), centerLocation); + } + else + { + worldEvent = (WorldEvent) con.newInstance(eventManager.getDamage(), eventManager.getBlockRestore(), + eventManager.getClans().getCondition(), eventManager.getClans().getProjectile(), centerLocation); + } + } } catch (Exception e) { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemCreature.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemCreature.java deleted file mode 100644 index e8256a5a5..000000000 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemCreature.java +++ /dev/null @@ -1,382 +0,0 @@ -package mineplex.game.clans.clans.worldevent.event.golem; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.Map.Entry; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.IronGolem; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; -import org.bukkit.util.Vector; - -import mineplex.core.common.util.UtilAlg; -import mineplex.core.common.util.UtilBlock; -import mineplex.core.common.util.UtilEnt; -import mineplex.core.common.util.UtilMath; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.common.util.UtilServer; -import mineplex.core.common.util.UtilTime; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.game.clans.clans.worldevent.creature.EventCreature; -import mineplex.game.clans.clans.worldevent.event.golem.abilities.*; -import mineplex.minecraft.game.core.damage.CustomDamageEvent; - -public class GolemCreature extends EventCreature -{ - private GolemBoss _boss; - private GolemAbility _currentAbility; - private int _lastAbility; - private long _lastWalked; - private Location _standing; - private long _attackDelay = System.currentTimeMillis(); - private long _reverseWalk; - private HashMap _preferedCombos = new HashMap(); - private Class _lastAttack; - - public GolemCreature(GolemBoss boss, Location location, double maxHealth) - { - super(boss, location, "Iron Wizard", true, maxHealth, IronGolem.class); - _boss = boss; - - spawnEntity(); - - _preferedCombos.put(GolemEarthquake.class, new Class[] - { - GolemBlockHail.class, GolemRumble.class - }); - _preferedCombos.put(GolemMeleeAttack.class, new Class[] - { - GolemEarthquake.class, GolemRumble.class - }); - _preferedCombos.put(GolemCaveIn.class, new Class[] - { - GolemMeleeAttack.class - }); - _preferedCombos.put(GolemBlockShot.class, new Class[] - { - GolemEarthquake.class - }); - _preferedCombos.put(GolemRumble.class, new Class[] - { - GolemBlockShot.class - }); - } - - @Override - protected void spawnCustom() - { - UtilEnt.Vegetate(getEntity()); - // EntityInsentient creature = (EntityInsentient) ((CraftEntity) getEntity()).getHandle(); - - // creature.Vegetated = false; - - _standing = getEntity().getLocation(); - } - - @EventHandler - public void abilityTick(UpdateEvent event) - { - if (event.getType() != UpdateType.TICK) - return; - - if (!UtilTime.elapsed(_attackDelay, 5000)) - { - _standing = getEntity().getLocation(); - return; - } - - if (_currentAbility == null || _currentAbility.hasFinished()) - { - if (_currentAbility != null) - { - _lastAttack = _currentAbility.getClass(); - _currentAbility.setFinished(); - _lastAbility = 30;// _currentAbility.getCooldown(); - - HandlerList.unregisterAll(_currentAbility); - - System.out.print("Unregistered golem ability " + _currentAbility.getClass().getSimpleName()); - // Bukkit.broadcastMessage("Ability end"); - - _currentAbility = null; - } - - else if (_lastAbility-- <= 0 && UtilBlock.solid(getEntity().getLocation().getBlock().getRelative(BlockFace.DOWN))) - { - HashMap weight = new HashMap(); - HashMap dist = new HashMap(); - - for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50)) - { - if (player.hasLineOfSight(getEntity())) - { - dist.put(player, player.getLocation().distance(getEntity().getLocation())); - } - } - - if (!dist.isEmpty()) - { - - { // Melee - ArrayList players = getPlayers(dist, 3); - - if (!players.isEmpty()) - { - weight.put(GolemMeleeAttack.class, 3 + (players.size() * 5)); - } - } - - { // Earthquake - ArrayList players = getPlayers(dist, 6); - - if (!players.isEmpty()) - { - weight.put(GolemEarthquake.class, players.size() * 2); - } - } - - { // Wall explode - ArrayList players = getPlayers(dist, 12); - - for (Player player : players) - { - if (dist.get(player) > 4) - { - weight.put(GolemWallExplode.class, 4); - break; - } - } - } - - { // Rumble - ArrayList players = getPlayers(dist, 30); - - if (!players.isEmpty()) - { - weight.put(GolemRumble.class, (int) Math.min(5, dist.get(players.get(0)))); - } - } - - { // Cave in - ArrayList players = getPlayers(dist, 30); - - if (!players.isEmpty()) - { - weight.put(GolemCaveIn.class, (int) Math.min(players.size() * 2, 7)); - } - } - - {// Block Hail - ArrayList players = getPlayers(dist, 30); - - if (!players.isEmpty()) - { - weight.put(GolemBlockHail.class, (int) Math.min(5, dist.get(players.get(0)))); - } - } - - if (_lastAttack != null && _preferedCombos.containsKey(_lastAttack)) - { - weight.remove(_lastAttack); - - for (Class c : _preferedCombos.get(_lastAttack)) - { - if (weight.containsKey(c)) - { - weight.put(c, weight.get(c) + 5); - } - } - } - - if (!weight.isEmpty()) - { - int i = 0; - - for (Integer entry : weight.values()) - { - i += entry; - } - - for (int a = 0; a < 10; a++) - { - int luckyNumber = UtilMath.r(i); - - for (Entry entry : weight.entrySet()) - { - luckyNumber -= entry.getValue(); - - if (luckyNumber <= 0) - { - try - { - _currentAbility = (GolemAbility) entry.getKey().getConstructor(GolemCreature.class) - .newInstance(this); - - if (_currentAbility.getTarget() == null) - { - _currentAbility = null; - } - else - { - break; - } - } - catch (Exception ex) - { - ex.printStackTrace(); - } - - break; - } - } - } - } - - if (_currentAbility != null && _currentAbility.getTarget() != null) - { - - Bukkit.getPluginManager().registerEvents(_currentAbility, _boss.getEventManager().getPlugin()); - - // Bukkit.broadcastMessage("Ability: " + _currentAbility.getClass().getSimpleName()); - - System.out.print("Golem boss is using " + _currentAbility.getClass().getSimpleName()); - } - else - { - _currentAbility = null; - _lastAbility = 10; - } - } - - _lastAttack = null; - } - } - - if (_currentAbility != null) - { - _currentAbility.tick(); - } - - if (_currentAbility == null || _currentAbility.canMove()) - { - Player target = null; - double dist = 0; - - for (Player player : UtilServer.getPlayers()) - { - if (!player.hasLineOfSight(getEntity())) - { - continue; - } - - double d = player.getLocation().distance(getEntity().getLocation()); - - if (d > 1.5 && (d < 7 || d > 15) && (target == null || (d < 50 && dist > d))) - { - target = player; - dist = d; - } - } - - Vector vec = null; - boolean reverse = target != null && dist < 8; - - if (target != null) - { - vec = target.getLocation().subtract(getEntity().getLocation()).toVector(); - vec.setY(getEntity().getLocation().getY()); - - double len = vec.length(); - - vec.setX(vec.getX() * (UtilMath.random.nextDouble() / 3D)); - vec.setZ(vec.getZ() * (UtilMath.random.nextDouble() / 3D)); - - vec.multiply(len); - } - else if (UtilTime.elapsed(_lastWalked, 10000)) - { - vec = new Vector(UtilMath.r(50) - 25, 0, UtilMath.r(50) - 25); - } - - if (vec != null) - { - _lastWalked = System.currentTimeMillis(); - - if (reverse) - { - vec.multiply(-1); - } - - if (!UtilAlg.HasSight(getEntity().getLocation(), - getEntity().getLocation().add(vec.clone().normalize().multiply(2)))) - { - _reverseWalk = System.currentTimeMillis(); - } - - if (!UtilTime.elapsed(_reverseWalk, 4000)) - { - vec.multiply(-1); - } - - // if (vec.length() > 1) - { - UtilEnt.CreatureMoveFast(getEntity(), getEntity().getLocation().add(vec), 1.5F); - } - } - - _standing = getEntity().getLocation(); - } - else - { - Location l = getEntity().getLocation(); - - _standing.setYaw(l.getYaw()); - _standing.setPitch(l.getPitch()); - _standing.setY(l.getY()); - - getEntity().teleport(_standing); - } - } - - private ArrayList getPlayers(HashMap map, double maxDist) - { - ArrayList list = new ArrayList(); - - for (Player p : map.keySet()) - { - if (map.get(p) < maxDist) - { - list.add(p); - } - } - - return list; - } - - @EventHandler - public void onGolemDamage(CustomDamageEvent event) - { - if (event.GetDamageeEntity().equals(getEntity())) - { - event.AddKnockback("Heavy Golem", 0.3); - } - } - - @Override - public void dieCustom() - { - if (_currentAbility != null) - { - _currentAbility.setFinished(); - HandlerList.unregisterAll(_currentAbility); - _currentAbility = null; - } - } -} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/kinghill/HillData.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/kinghill/HillData.java similarity index 96% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/kinghill/HillData.java rename to Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/kinghill/HillData.java index e32bc4b3d..ba2308ad4 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/kinghill/HillData.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/kinghill/HillData.java @@ -1,13 +1,13 @@ -package mineplex.game.clans.clans.worldevent.event.kinghill; +package mineplex.game.clans.clans.worldevent.kinghill; import java.io.File; import java.io.IOException; -import org.bukkit.Location; - import mineplex.core.common.block.schematic.Schematic; import mineplex.core.common.block.schematic.UtilSchematic; +import org.bukkit.Location; + public class HillData { private Schematic _schematic; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/kinghill/KingHill.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/kinghill/KingHill.java similarity index 85% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/kinghill/KingHill.java rename to Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/kinghill/KingHill.java index 03f1e5de7..bc4261f35 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/kinghill/KingHill.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/kinghill/KingHill.java @@ -1,23 +1,26 @@ -package mineplex.game.clans.clans.worldevent.event.kinghill; +package mineplex.game.clans.clans.worldevent.kinghill; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.entity.Player; - +import mineplex.core.blockrestore.BlockRestore; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilTime; import mineplex.game.clans.clans.ClanInfo; import mineplex.game.clans.clans.ClansManager; -import mineplex.game.clans.clans.worldevent.EventMap; import mineplex.game.clans.clans.worldevent.WorldEventManager; -import mineplex.game.clans.clans.worldevent.event.EventState; -import mineplex.game.clans.clans.worldevent.event.WorldEvent; import mineplex.game.clans.economy.GoldManager; +import mineplex.minecraft.game.core.boss.EventMap; +import mineplex.minecraft.game.core.boss.EventState; +import mineplex.minecraft.game.core.boss.WorldEvent; +import mineplex.minecraft.game.core.condition.ConditionManager; +import mineplex.minecraft.game.core.damage.DamageManager; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; public class KingHill extends WorldEvent { @@ -45,7 +48,7 @@ public class KingHill extends WorldEvent public KingHill(WorldEventManager eventManager, Location centerLocation) { - super(eventManager, "King of the Hill", centerLocation); + super(eventManager.getDamage(), eventManager.getBlockRestore(), eventManager.getClans().getCondition(), "King of the Hill", centerLocation); _clansManager = eventManager.getClans(); _scoreMap = new HashMap(); _hill = LOADED_HILLS.get(0); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/CampSize.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/CampSize.java similarity index 96% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/CampSize.java rename to Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/CampSize.java index a9bbaf4b7..7d87361c1 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/CampSize.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/CampSize.java @@ -1,4 +1,4 @@ -package mineplex.game.clans.clans.worldevent.event.undead; +package mineplex.game.clans.clans.worldevent.undead; import mineplex.core.common.util.UtilMath; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/CampType.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/CampType.java similarity index 95% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/CampType.java rename to Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/CampType.java index 4511cbe32..2ba66823f 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/CampType.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/CampType.java @@ -1,4 +1,4 @@ -package mineplex.game.clans.clans.worldevent.event.undead; +package mineplex.game.clans.clans.worldevent.undead; import org.bukkit.Material; import org.bukkit.material.MaterialData; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/UndeadCamp.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/UndeadCamp.java similarity index 94% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/UndeadCamp.java rename to Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/UndeadCamp.java index 2aa441594..72c07120c 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/UndeadCamp.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/UndeadCamp.java @@ -1,25 +1,12 @@ -package mineplex.game.clans.clans.worldevent.event.undead; +package mineplex.game.clans.clans.worldevent.undead; import java.util.HashSet; import java.util.Iterator; -import org.bukkit.Effect; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.block.BlockState; -import org.bukkit.block.Chest; -import org.bukkit.event.EventHandler; -import org.bukkit.event.entity.EntityInteractEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.ItemStack; - +import mineplex.core.blockrestore.BlockRestore; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilMath; -import mineplex.core.common.util.UtilParticle; -import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilWorld; @@ -28,10 +15,20 @@ import mineplex.core.recharge.Recharge; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.game.clans.clans.worldevent.WorldEventManager; -import mineplex.game.clans.clans.worldevent.event.EventState; -import mineplex.game.clans.clans.worldevent.event.WorldEvent; -import mineplex.game.clans.clans.worldevent.event.undead.creature.UndeadArcher; -import mineplex.game.clans.clans.worldevent.event.undead.creature.UndeadWarrior; +import mineplex.game.clans.clans.worldevent.undead.creature.UndeadArcher; +import mineplex.game.clans.clans.worldevent.undead.creature.UndeadWarrior; +import mineplex.minecraft.game.core.boss.EventState; +import mineplex.minecraft.game.core.boss.WorldEvent; +import mineplex.minecraft.game.core.condition.ConditionManager; +import mineplex.minecraft.game.core.damage.DamageManager; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractEvent; public class UndeadCamp extends WorldEvent { @@ -43,10 +40,11 @@ public class UndeadCamp extends WorldEvent private final CampType _campType; private final CampSize _campSize; private HashSet _chests; + private WorldEventManager _eventManager; public UndeadCamp(WorldEventManager eventManager, Location centerLocation) { - super(eventManager, "Undead Camp", centerLocation); + super(eventManager.getDamage(), eventManager.getBlockRestore(), eventManager.getClans().getCondition(), "Undead Camp", centerLocation); _campSize = CampSize.getCampSize(UtilServer.getPlayers().length); _campType = CampType.values()[getRandom().nextInt(CampType.values().length)]; @@ -59,6 +57,11 @@ public class UndeadCamp extends WorldEvent setName(_campSize.getName()); } + + public WorldEventManager getEventManager() + { + return _eventManager; + } @Override protected void customStart() diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/creature/UndeadArcher.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/creature/UndeadArcher.java similarity index 89% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/creature/UndeadArcher.java rename to Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/creature/UndeadArcher.java index 57822be24..cbb07088f 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/creature/UndeadArcher.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/creature/UndeadArcher.java @@ -1,16 +1,15 @@ -package mineplex.game.clans.clans.worldevent.event.undead.creature; +package mineplex.game.clans.clans.worldevent.undead.creature; + +import mineplex.core.common.util.UtilMath; +import mineplex.minecraft.game.core.boss.EventCreature; +import mineplex.minecraft.game.core.boss.WorldEvent; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Skeleton; -import org.bukkit.entity.Zombie; import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.ItemStack; -import mineplex.core.common.util.UtilMath; -import mineplex.game.clans.clans.worldevent.creature.EventCreature; -import mineplex.game.clans.clans.worldevent.event.WorldEvent; - public class UndeadArcher extends EventCreature { public UndeadArcher(WorldEvent event, Location spawnLocation) diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/creature/UndeadWarrior.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/creature/UndeadWarrior.java similarity index 92% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/creature/UndeadWarrior.java rename to Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/creature/UndeadWarrior.java index e884b189c..9fa7fdbff 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/undead/creature/UndeadWarrior.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/undead/creature/UndeadWarrior.java @@ -1,4 +1,12 @@ -package mineplex.game.clans.clans.worldevent.event.undead.creature; +package mineplex.game.clans.clans.worldevent.undead.creature; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.boss.EventCreature; +import mineplex.minecraft.game.core.boss.WorldEvent; import org.bukkit.Location; import org.bukkit.Material; @@ -8,14 +16,6 @@ import org.bukkit.event.EventHandler; import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.ItemStack; -import mineplex.core.common.util.UtilAction; -import mineplex.core.common.util.UtilAlg; -import mineplex.core.common.util.UtilMath; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.game.clans.clans.worldevent.creature.EventCreature; -import mineplex.game.clans.clans.worldevent.event.WorldEvent; - public class UndeadWarrior extends EventCreature { public UndeadWarrior(WorldEvent event, Location spawnLocation) diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/creature/EventCreature.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/EventCreature.java similarity index 96% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/creature/EventCreature.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/EventCreature.java index a91ddd40d..1e7d59ebf 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/creature/EventCreature.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/EventCreature.java @@ -1,23 +1,21 @@ -package mineplex.game.clans.clans.worldevent.creature; +package mineplex.minecraft.game.core.boss; import java.util.UUID; +import mineplex.core.common.util.C; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + import org.bukkit.Location; import org.bukkit.entity.LivingEntity; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityCombustEvent; -import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.world.ChunkUnloadEvent; -import mineplex.core.common.util.C; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.game.clans.clans.worldevent.event.WorldEvent; -import mineplex.minecraft.game.core.damage.CustomDamageEvent; - public abstract class EventCreature implements Listener { private WorldEvent _event; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/EventMap.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/EventMap.java similarity index 89% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/EventMap.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/EventMap.java index e4791c313..c8445cc8d 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/EventMap.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/EventMap.java @@ -1,9 +1,9 @@ -package mineplex.game.clans.clans.worldevent; - -import org.bukkit.Location; +package mineplex.minecraft.game.core.boss; import mineplex.core.common.block.schematic.Schematic; +import org.bukkit.Location; + public class EventMap { private Schematic _schematic; @@ -16,7 +16,8 @@ public class EventMap private double _yLength; private double _zLength; - public EventMap(Schematic schematic, Location cornerLocation, double xDiff, double yDiff, double zDiff, double xLength, double yLength, double zLength) + public EventMap(Schematic schematic, Location cornerLocation, double xDiff, double yDiff, double zDiff, double xLength, + double yLength, double zLength) { _schematic = schematic; _cornerLocation = cornerLocation; @@ -51,6 +52,4 @@ public class EventMap return _schematic; } - - } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/EventState.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/EventState.java similarity index 59% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/EventState.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/EventState.java index 951486fe1..751f9e0cf 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/EventState.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/EventState.java @@ -1,4 +1,4 @@ -package mineplex.game.clans.clans.worldevent.event; +package mineplex.minecraft.game.core.boss; public enum EventState { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/WorldEvent.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/WorldEvent.java similarity index 79% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/WorldEvent.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/WorldEvent.java index 243af4d61..06bb620d3 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/WorldEvent.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/WorldEvent.java @@ -1,9 +1,24 @@ -package mineplex.game.clans.clans.worldevent.event; +package mineplex.minecraft.game.core.boss; import java.util.ArrayList; import java.util.List; import java.util.Random; +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.blockrestore.BlockRestoreMap; +import mineplex.core.common.block.BlockData; +import mineplex.core.common.block.schematic.SchematicRunnable; +import mineplex.core.common.util.C; +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.condition.ConditionManager; +import mineplex.minecraft.game.core.damage.DamageManager; + import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; @@ -11,30 +26,15 @@ import org.bukkit.block.Block; import org.bukkit.event.EventHandler; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; - -import mineplex.core.blockrestore.BlockRestoreMap; -import mineplex.core.common.block.schematic.SchematicRunnable; -import mineplex.core.common.util.C; -import mineplex.core.common.util.Callback; -import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilServer; -import mineplex.core.common.block.BlockData; -import mineplex.core.common.util.UtilTextMiddle; -import mineplex.core.common.util.UtilWorld; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.game.clans.clans.worldevent.EventMap; -import mineplex.game.clans.clans.worldevent.WorldEventManager; -import mineplex.game.clans.clans.worldevent.creature.EventCreature; -import mineplex.minecraft.game.core.damage.DamageManager; +import org.bukkit.plugin.java.JavaPlugin; public abstract class WorldEvent implements Listener { // 20 Minutes private static final int ACTIVE_TIMEOUT = 1200000; - private WorldEventManager _eventManager; private DamageManager _damageManager; + private ConditionManager _conditionManager; private String _name; private EventState _state; @@ -49,10 +49,11 @@ public abstract class WorldEvent implements Listener // Block Restore private BlockRestoreMap _blocks; - public WorldEvent(WorldEventManager eventManager, String name, Location cornerLocation) + public WorldEvent(DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager, String name, + Location cornerLocation) { - _eventManager = eventManager; - _damageManager = eventManager.getDamage(); + _damageManager = damageManager; + _conditionManager = conditionManager; _name = name; _state = EventState.PREPARE; @@ -62,10 +63,15 @@ public abstract class WorldEvent implements Listener _ticks = 0; _creatures = new ArrayList(); - _blocks = eventManager.getBlockRestore().createMap(); + _blocks = blockRestore.createMap(); _lastActive = System.currentTimeMillis(); } + public ConditionManager getCondition() + { + return _conditionManager; + } + public final void start() { customStart(); @@ -122,11 +128,6 @@ public abstract class WorldEvent implements Listener return _ticks; } - public WorldEventManager getEventManager() - { - return _eventManager; - } - public DamageManager getDamageManager() { return _damageManager; @@ -159,7 +160,7 @@ public abstract class WorldEvent implements Listener public void registerCreature(EventCreature creature) { - UtilServer.getServer().getPluginManager().registerEvents(creature, _eventManager.getPlugin()); + UtilServer.getServer().getPluginManager().registerEvents(creature, _damageManager.getPlugin()); _creatures.add(creature); } @@ -167,13 +168,14 @@ public abstract class WorldEvent implements Listener { HandlerList.unregisterAll(creature); _creatures.remove(creature); -} + } public void announceStart() { UtilTextMiddle.display(C.cGreen + getName(), UtilWorld.locToStrClean(getCenterLocation()), 10, 40, 10); - Bukkit.broadcastMessage(F.main("Event", F.elem(getName()) + " has started at coordinates " + F.elem(UtilWorld.locToStrClean(getCenterLocation())))); + Bukkit.broadcastMessage(F.main("Event", + F.elem(getName()) + " has started at coordinates " + F.elem(UtilWorld.locToStrClean(getCenterLocation())))); } public void clearCreatures() @@ -187,6 +189,11 @@ public abstract class WorldEvent implements Listener _creatures.clear(); } + public JavaPlugin getPlugin() + { + return _damageManager.getPlugin(); + } + public void restoreBlocks() { _blocks.restore(); @@ -206,19 +213,20 @@ public abstract class WorldEvent implements Listener { _map = map; - SchematicRunnable task = new SchematicRunnable(_eventManager.getPlugin(), map.getSchematic(), _cornerLocation.getBlock(), new Callback>() - { - @Override - public void run(List data) - { - for (BlockData blockData : data) + SchematicRunnable task = new SchematicRunnable(_damageManager.getPlugin(), map.getSchematic(), + _cornerLocation.getBlock(), new Callback>() { - _blocks.addBlockData(blockData); - } + @Override + public void run(List data) + { + for (BlockData blockData : data) + { + _blocks.addBlockData(blockData); + } - onComplete.run(); - } - }); + onComplete.run(); + } + }); task.setBlocksPerTick(100); task.start(); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemBoss.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/GolemBoss.java similarity index 68% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemBoss.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/GolemBoss.java index 862e79a0d..e23ec20c9 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/GolemBoss.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/GolemBoss.java @@ -1,27 +1,27 @@ -package mineplex.game.clans.clans.worldevent.event.golem; +package mineplex.minecraft.game.core.boss.ironwizard; import java.io.File; import java.io.IOException; +import mineplex.core.blockrestore.BlockRestore; import mineplex.core.common.block.schematic.Schematic; import mineplex.core.common.block.schematic.UtilSchematic; -import mineplex.game.clans.clans.worldevent.EventMap; -import mineplex.game.clans.clans.worldevent.WorldEventManager; -import mineplex.game.clans.clans.worldevent.creature.EventCreature; -import mineplex.game.clans.clans.worldevent.event.EventState; -import mineplex.game.clans.clans.worldevent.event.WorldEvent; -import mineplex.game.clans.clans.worldevent.event.slimeking.creature.SlimeCreature; +import mineplex.minecraft.game.core.boss.EventCreature; +import mineplex.minecraft.game.core.boss.EventMap; +import mineplex.minecraft.game.core.boss.EventState; +import mineplex.minecraft.game.core.boss.WorldEvent; +import mineplex.minecraft.game.core.condition.ConditionManager; +import mineplex.minecraft.game.core.damage.DamageManager; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.util.Vector; public class GolemBoss extends WorldEvent { - public GolemBoss(WorldEventManager eventManager, Location corner) + public GolemBoss(DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager, Location corner) { - super(eventManager, "Iron Wizard", corner); + super(damageManager, blockRestore, conditionManager, "Iron Wizard", corner); Schematic schematic = null; @@ -80,7 +80,7 @@ public class GolemBoss extends WorldEvent private GolemCreature spawnGolem(Location location) { - GolemCreature slimeCreature = new GolemCreature(this, location, 1500); + GolemCreature slimeCreature = new GolemCreature(this, location, 100); registerCreature(slimeCreature); return slimeCreature; } diff --git a/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/GolemCreature.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/GolemCreature.java new file mode 100644 index 000000000..b672c7a3d --- /dev/null +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/GolemCreature.java @@ -0,0 +1,510 @@ +package mineplex.minecraft.game.core.boss.ironwizard; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.boss.EventCreature; +import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemAbility; +import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemBlockHail; +import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemBlockShot; +import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemCaveIn; +import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemEarthquake; +import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemExplodingAura; +import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemMeleeAttack; +import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemRumble; +import mineplex.minecraft.game.core.boss.ironwizard.abilities.GolemWallExplode; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.util.Vector; + +public class GolemCreature extends EventCreature +{ + private GolemBoss _boss; + // private GolemAbility _currentAbility; + private int _lastAbility; + private long _lastWalked; + private Location _standing; + private long _spawnDelay = System.currentTimeMillis(); + private long _reverseWalk; + private HashMap _preferedCombos = new HashMap(); + private Class _lastAttack; + private boolean _usedFinalAttack; + private ArrayList _currentAbilities = new ArrayList(); + private double _canCaveIn = 450; + private Vector _afkWalk = new Vector(); + + public GolemCreature(GolemBoss boss, Location location, double maxHealth) + { + super(boss, location, "Iron Wizard", true, maxHealth, IronGolem.class); + _boss = boss; + + spawnEntity(); + + _preferedCombos.put(GolemEarthquake.class, new Class[] + { + GolemBlockHail.class, GolemRumble.class + }); + _preferedCombos.put(GolemMeleeAttack.class, new Class[] + { + GolemEarthquake.class, GolemRumble.class + }); + _preferedCombos.put(GolemCaveIn.class, new Class[] + { + GolemMeleeAttack.class + }); + _preferedCombos.put(GolemBlockShot.class, new Class[] + { + GolemEarthquake.class + }); + _preferedCombos.put(GolemRumble.class, new Class[] + { + GolemBlockShot.class + }); + } + + @Override + protected void spawnCustom() + { + UtilEnt.Vegetate(getEntity()); + // EntityInsentient creature = (EntityInsentient) ((CraftEntity) getEntity()).getHandle(); + + // creature.Vegetated = false; + + _standing = getEntity().getLocation(); + } + + @EventHandler + public void abilityTick(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + return; + + if (!UtilTime.elapsed(_spawnDelay, 5000)) + { + _standing = getEntity().getLocation(); + return; + } + + // if (_currentAbility == null || _currentAbility.hasFinished()) + // { + Iterator itel = _currentAbilities.iterator(); + boolean canDoNew = _currentAbilities.size() < 3; + + while (itel.hasNext()) + { + GolemAbility ability = itel.next(); + + if (ability.hasFinished()) + { + itel.remove(); + ability.setFinished(); + _lastAbility = 20;// _currentAbility.getCooldown(); + + HandlerList.unregisterAll(ability); + System.out.print("Unregistered golem ability " + ability.getClass().getSimpleName()); + } + else if (!ability.inProgress()) + { + canDoNew = false; + } + } + + if (_lastAbility-- <= 0 && canDoNew && UtilBlock.solid(getEntity().getLocation().getBlock().getRelative(BlockFace.DOWN))) + { + HashMap weight = new HashMap(); + HashMap dist = new HashMap(); + + for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true)) + { + if (player.hasLineOfSight(getEntity())) + { + dist.put(player, player.getLocation().distance(getEntity().getLocation())); + } + } + + if (!dist.isEmpty()) + { + double hp = getHealthPercent(); + + { // Melee + ArrayList players = getPlayers(dist, 2.5); + + if (!players.isEmpty()) + { + weight.put(GolemMeleeAttack.class, 999); + } + } + + if (hp < 0.7) + { // Earthquake + ArrayList players = getPlayers(dist, 8); + + double score = 0; + + for (Player player : players) + { + score += (8 - dist.get(player)) / 4; + } + + if (players.size() >= 3) + { + score += 7; + } + + if (score > 0) + { + weight.put(GolemEarthquake.class, (int) Math.ceil(score)); + } + } + + { // Wall explode + if (!getPlayers(dist, 12).isEmpty() && getPlayers(dist, 4).isEmpty()) + { + weight.put(GolemWallExplode.class, 5); + } + } + + { // Block Shot + ArrayList players = getPlayers(dist, 30); + + for (Player player : players) + { + if (dist.get(player) > 4) + { + weight.put(GolemBlockShot.class, 6); + break; + } + } + } + + { // Rumble + ArrayList players = getPlayers(dist, 30); + + if (!players.isEmpty()) + { + weight.put(GolemRumble.class, (int) Math.min(5, dist.get(players.get(0)))); + } + } + + if (_canCaveIn <= 0) + { // Cave in + + ArrayList players = getPlayers(dist, 30); + + for (GolemAbility ability : _currentAbilities) + { + if (ability instanceof GolemExplodingAura) + { + players.clear(); + } + } + + if (!players.isEmpty()) + { + // weight.put(GolemCaveIn.class, (int) Math.min(players.size() * 2, 7)); + weight.put(GolemCaveIn.class, (int) 30); + } + } + + {// Block Hail + ArrayList players = getPlayers(dist, 30); + + if (!players.isEmpty()) + { + int we = _lastAttack == GolemEarthquake.class ? 5 : UtilMath.r(4) - 2; + + if (we > 0) + { + weight.put(GolemBlockHail.class, we); + } + } + } + + if (!_usedFinalAttack && getHealth() < 90) + { + _usedFinalAttack = true; + weight.clear(); + + weight.put(GolemExplodingAura.class, 999); + } + + if (_lastAttack != null && _preferedCombos.containsKey(_lastAttack)) + { + weight.remove(_lastAttack); + + for (Class c : _preferedCombos.get(_lastAttack)) + { + if (weight.containsKey(c)) + { + weight.put(c, weight.get(c) * 4); + } + } + } + + for (GolemAbility ability : _currentAbilities) + { + weight.remove(ability.getClass()); + } + + GolemAbility ability = null; + + if (!weight.isEmpty()) + { + int i = 0; + + for (Integer entry : weight.values()) + { + i += entry; + } + + for (int a = 0; a < 10; a++) + { + int luckyNumber = UtilMath.r(i); + + for (Entry entry : weight.entrySet()) + { + luckyNumber -= entry.getValue(); + + if (luckyNumber <= 0) + { + try + { + ability = (GolemAbility) entry.getKey().getConstructor(GolemCreature.class).newInstance(this); + + if (ability.getTarget() == null) + { + ability = null; + } + else + { + break; + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + + break; + } + } + } + } + + if (ability != null && ability.getTarget() != null) + { + _lastAttack = ability.getClass(); + + if (ability instanceof GolemCaveIn) + { + _canCaveIn = 450; + } + + Bukkit.getPluginManager().registerEvents(ability, _boss.getPlugin()); + + // Bukkit.broadcastMessage("Ability: " + _currentAbility.getClass().getSimpleName()); + + System.out.print("Golem boss is using " + ability.getClass().getSimpleName()); + + _currentAbilities.add(ability); + } + + _lastAbility = 10; + } + + _lastAttack = null; + } + + boolean canMove = true; + + for (GolemAbility ability : _currentAbilities) + { + ability.tick(); + + if (!ability.canMove()) + { + canMove = false; + } + } + + if (canMove) + { + Player target = null; + double dist = 0; + + for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true)) + { + if (!player.hasLineOfSight(getEntity())) + { + continue; + } + + double d = player.getLocation().distance(getEntity().getLocation()); + + if (d > 1.5 && (d < 7 || d > 15) && (target == null || (d < 50 && dist > d))) + { + target = player; + dist = d; + } + } + + Vector vec = null; + + if (target != null) + { + vec = target.getLocation().subtract(getEntity().getLocation()).toVector(); + vec.setY(getEntity().getLocation().getY()); + + double len = vec.length(); + + vec.setX(vec.getX() * (UtilMath.random.nextDouble() / 3D)); + vec.setZ(vec.getZ() * (UtilMath.random.nextDouble() / 3D)); + + vec.multiply(len); + + if (target != null && dist < 8) + { + vec.multiply(-1); + } + + if (!UtilAlg.HasSight(getEntity().getLocation(), + getEntity().getLocation().add(vec.clone().normalize().multiply(2)))) + { + _reverseWalk = System.currentTimeMillis(); + } + + if (!UtilTime.elapsed(_reverseWalk, 4000)) + { + vec.multiply(-1); + } + + } + else if (!UtilTime.elapsed(_lastWalked, 7000)) + { + vec = _afkWalk; + } + else if (UtilTime.elapsed(_lastWalked, 12000)) + { + _afkWalk = new Vector(); + + for (int i = 0; i < 10; i++) + { + Vector vector = new Vector(UtilMath.r(20) - 10, 0, UtilMath.r(20) - 10); + + if (UtilAlg.HasSight(getEntity().getLocation(), + getEntity().getLocation().add(vector.clone().normalize().multiply(2)))) + { + vec = _afkWalk = vector; + break; + } + } + + _lastWalked = System.currentTimeMillis(); + } + + if (vec != null) + { + // if (vec.length() > 1) + { + UtilEnt.CreatureMoveFast(getEntity(), getEntity().getLocation().add(vec), target != null ? 1.5F : 1.1F); + } + } + + _standing = getEntity().getLocation(); + } + else + { + Location l = getEntity().getLocation(); + + _standing.setYaw(l.getYaw()); + _standing.setPitch(l.getPitch()); + _standing.setY(l.getY()); + + getEntity().teleport(_standing); + } + } + + private ArrayList getPlayers(final HashMap map, double maxDist) + { + ArrayList list = new ArrayList(); + + for (Player p : map.keySet()) + { + if (map.get(p) <= maxDist) + { + list.add(p); + } + } + + Collections.sort(list, new Comparator() + { + + @Override + public int compare(Player o1, Player o2) + { + return Double.compare(map.get(o2), map.get(o1)); + } + }); + + return list; + } + + @EventHandler + public void onGolemDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().equals(getEntity())) + { + event.AddKnockback("Heavy Golem", 0.3); + } + } + + @Override + public void dieCustom() + { + endAbility(); + } + + private void endAbility() + { + for (GolemAbility ability : _currentAbilities) + { + ability.setFinished(); + HandlerList.unregisterAll(ability); + } + + _currentAbilities.clear(); + } + + @Override + public void setHealth(double health) + { + _canCaveIn -= getHealth() - health; + + super.setHealth(health); + + if (getHealth() <= 100 && !_usedFinalAttack) + { + endAbility(); + } + } +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/BlockHailBlock.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/BlockHailBlock.java similarity index 91% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/BlockHailBlock.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/BlockHailBlock.java index 9fff7eb67..58dd30225 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/BlockHailBlock.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/BlockHailBlock.java @@ -1,4 +1,4 @@ -package mineplex.game.clans.clans.worldevent.event.golem.abilities; +package mineplex.minecraft.game.core.boss.ironwizard.abilities; import mineplex.core.common.util.UtilEnt; import net.minecraft.server.v1_7_R4.DataWatcher; @@ -17,7 +17,7 @@ import org.bukkit.entity.IronGolem; public class BlockHailBlock { private int _block = UtilEnt.getNewEntityId(); - private int _chicken = UtilEnt.getNewEntityId(); + private int _silverfish = UtilEnt.getNewEntityId(); private Location _location; private Material _mat; @@ -31,7 +31,7 @@ public class BlockHailBlock { return new PacketPlayOutEntityDestroy(new int[] { - _chicken, _block + _silverfish, _block }); } @@ -55,7 +55,7 @@ public class BlockHailBlock watcher.a(0, (byte) 32); watcher.a(1, 0); - packet1.a = _chicken; + packet1.a = _silverfish; packet1.b = EntityType.SILVERFISH.getTypeId(); packet1.c = (int) Math.floor(_location.getX() * 32); packet1.d = (int) Math.floor(_location.getY() * 32); @@ -77,7 +77,7 @@ public class BlockHailBlock PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity(); packet3.b = _block; - packet3.c = _chicken; + packet3.c = _silverfish; packets[2] = packet3; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemAbility.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemAbility.java similarity index 82% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemAbility.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemAbility.java index 2819662e9..a627bf5a2 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemAbility.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemAbility.java @@ -1,11 +1,12 @@ -package mineplex.game.clans.clans.worldevent.event.golem.abilities; +package mineplex.minecraft.game.core.boss.ironwizard.abilities; import java.util.HashMap; import java.util.UUID; +import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilTime; -import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature; import org.bukkit.Location; import org.bukkit.entity.Entity; @@ -40,6 +41,8 @@ public abstract class GolemAbility implements Listener public abstract boolean canMove(); + public abstract boolean inProgress(); + public int getCooldown() { return 60; @@ -70,7 +73,7 @@ public abstract class GolemAbility implements Listener Player target = null; double dist = 0; - for (Player player : UtilServer.getPlayers()) + for (Player player : UtilPlayer.getNearby(getLocation(), maxDistance, true)) { if (!player.hasLineOfSight(getEntity())) { @@ -79,7 +82,7 @@ public abstract class GolemAbility implements Listener double d = player.getLocation().distance(getLocation()); - if (d <= maxDistance && (target == null || dist > d)) + if (target == null || dist > d) { target = player; dist = d; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemBlockHail.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemBlockHail.java similarity index 83% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemBlockHail.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemBlockHail.java index fc6af6ae7..7ca1c3841 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemBlockHail.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemBlockHail.java @@ -1,4 +1,4 @@ -package mineplex.game.clans.clans.worldevent.event.golem.abilities; +package mineplex.minecraft.game.core.boss.ironwizard.abilities; import java.util.ArrayList; import java.util.Collections; @@ -16,7 +16,7 @@ import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilShapes; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature; import net.minecraft.server.v1_7_R4.AxisAlignedBB; import net.minecraft.server.v1_7_R4.EntityIronGolem; import net.minecraft.server.v1_7_R4.MathHelper; @@ -52,6 +52,7 @@ public class GolemBlockHail extends GolemAbility private int _currentLevel; private ArrayList _fallingBlocks = new ArrayList(); private HashMap> _floatingBlocks = new HashMap>(); + private HashMap _blocks = new HashMap(); private int _levelToReach; private boolean _spawned; private ArrayList _spawnLocs = new ArrayList(); @@ -87,19 +88,27 @@ public class GolemBlockHail extends GolemAbility Player target = null; double dist = 0; - for (Player player : UtilPlayer.getNearby(_center, 40)) + if (inProgress()) { - if (!player.hasLineOfSight(getEntity())) + for (Player player : UtilPlayer.getNearby(_center, 40, true)) { - continue; - } + if (!player.hasLineOfSight(getEntity())) + { + continue; + } - double d = player.getLocation().distance(_center); + if (target != null && _blocks.containsKey(player.getName()) && _blocks.get(player.getName()) > 8) + { + continue; + } - if (target == null || dist > d) - { - target = player; - dist = d; + double d = player.getLocation().distance(_center); + + if (target == null || dist > d) + { + target = player; + dist = d; + } } } @@ -211,19 +220,19 @@ public class GolemBlockHail extends GolemAbility { cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId()); - if (canDamage(victim)) + // if (canDamage(victim)) { getGolem() .getEvent() .getDamageManager() .NewDamageEvent((LivingEntity) victim, getEntity(), null, DamageCause.CONTACT, 6, true, true, false, - "Block Hail", "Block Hail"); + "Iron Wizard Block Hail", "Iron Wizard Block Hail"); } if (victim instanceof Player) { - getGolem().getEvent().getEventManager().getClans().getCondition().Factory() - .Slow("Block Hail", (LivingEntity) victim, getEntity(), 3, 2, false, false, false, false); + getGolem().getEvent().getCondition().Factory() + .Slow("Iron Wizard Block Hail", (LivingEntity) victim, getEntity(), 3, 2, false, false, false, false); } fallingIterator.remove(); @@ -273,11 +282,44 @@ public class GolemBlockHail extends GolemAbility } } } + + for (FallingBlock block : _fallingBlocks) + { + block.remove(); + } } @Override public void tick() { + if (inProgress()) + { + for (Player player : UtilPlayer.getNearby(_center, 5, true)) + { + Location loc = player.getLocation(); + + if (Math.abs(loc.getY() - (_center.getY() + 1)) <= 1) + { + loc.setY(_center.getY()); + + if (loc.distance(_center) < 2.8 + (_currentLevel * 0.75)) + { + if (canDamage(player)) + { + getGolem() + .getEvent() + .getDamageManager() + .NewDamageEvent(player, getEntity(), null, DamageCause.CONTACT, 6, true, true, false, + "Iron Wizard Protection", "Iron Wizard Protection"); + + loc.getWorld().playEffect(player.getLocation(), Effect.STEP_SOUND, Material.OBSIDIAN.getId()); + loc.getWorld().playEffect(player.getEyeLocation(), Effect.STEP_SOUND, Material.OBSIDIAN.getId()); + } + } + } + } + } + if (!_spawned) { if (_currentBlock >= _spawnLocs.size()) @@ -290,6 +332,11 @@ public class GolemBlockHail extends GolemAbility _spawnLocs = UtilShapes.getDistancedCircle(_center.clone().add(0, 2.8 + (_currentLevel * 0.75), 0), 1.3, 1 + (_currentLevel * 1.3)); + + for (int i = UtilMath.r(_spawnLocs.size()); i > 0; i--) + { + _spawnLocs.add(_spawnLocs.remove(0)); + } } } @@ -322,12 +369,9 @@ public class GolemBlockHail extends GolemAbility Packet[] packets = floating.getSpawnPackets(entity); - for (Player player : UtilServer.getPlayers()) + for (Player player : UtilPlayer.getNearby(loc, 100)) { - if (player.getLocation().distance(loc) < 100) - { - UtilPlayer.sendPacket(player, packets); - } + UtilPlayer.sendPacket(player, packets); } entity.getWorld().playSound(entity.getLocation(), Sound.DIG_GRASS, 3, 0.9F); @@ -403,6 +447,8 @@ public class GolemBlockHail extends GolemAbility _fallingBlocks.add(b); entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 3, 0.9F); + + _blocks.put(_target.getName(), _blocks.containsKey(_target.getName()) ? _blocks.get(_target.getName()) + 1 : 1); } ArrayList points = new ArrayList(); @@ -427,4 +473,10 @@ public class GolemBlockHail extends GolemAbility _ticks++; } + @Override + public boolean inProgress() + { + return !_spawned || !_floatingBlocks.isEmpty(); + } + } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemBlockShot.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemBlockShot.java similarity index 93% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemBlockShot.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemBlockShot.java index fa8f1e7a7..447ceed4a 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemBlockShot.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemBlockShot.java @@ -1,4 +1,4 @@ -package mineplex.game.clans.clans.worldevent.event.golem.abilities; +package mineplex.minecraft.game.core.boss.ironwizard.abilities; import java.util.ArrayList; import java.util.HashMap; @@ -19,7 +19,7 @@ import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilTime; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature; import net.minecraft.server.v1_7_R4.AxisAlignedBB; import net.minecraft.server.v1_7_R4.EntityIronGolem; import net.minecraft.server.v1_7_R4.MathHelper; @@ -96,7 +96,7 @@ public class GolemBlockShot extends GolemAbility Location loc1 = getLocation(); Location loc2 = loc1.clone().add(loc1.getDirection().setY(0).normalize()); - LinkedList players = UtilPlayer.getNearby(getLocation(), 40); + LinkedList players = UtilPlayer.getNearby(getLocation(), 40, true); for (Player player : players) { @@ -130,7 +130,7 @@ public class GolemBlockShot extends GolemAbility @Override public boolean hasFinished() { - return _current.isEmpty() && _preshoot.isEmpty() && (_target == null || _thrown == _toThrow); + return _current.isEmpty() && _preshoot.isEmpty() && (_target == null || _thrown >= _toThrow); } @EventHandler @@ -229,15 +229,22 @@ public class GolemBlockShot extends GolemAbility .getEvent() .getDamageManager() .NewDamageEvent((LivingEntity) victim, getEntity(), null, DamageCause.CONTACT, 6, true, true, false, - "Block Throw", "Block Throw"); + "Iron Wizard Block Shot", "Iron Wizard Block Shot"); cur.remove(); fallingIterator.remove(); - Vector vec = UtilAlg.getTrajectory(cur, victim); + Vector vec = UtilAlg.getTrajectory(getEntity(), victim); vec.setY(0).normalize(); - UtilAction.velocity(victim, vec, 1.2, true, 0, 0.1, 1, true); + double strength = 1; + + if (!(victim instanceof Player) || !((Player) victim).isBlocking()) + { + strength = 1.3; + } + + UtilAction.velocity(victim, vec, strength, true, 0, 0.2, 1, true); } else if (finalObjectPosition != null) { @@ -367,7 +374,7 @@ public class GolemBlockShot extends GolemAbility { Entry entry = itel.next(); - if (UtilTime.elapsed(entry.getValue(), 900)) + if (UtilTime.elapsed(entry.getValue(), 920)) { itel.remove(); @@ -404,9 +411,22 @@ public class GolemBlockShot extends GolemAbility Vector vector = UtilAlg.getTrajectory(l, target.getEyeLocation()); + vector.multiply(13).add(new Vector(UtilMath.r(3) - 1, 0, UtilMath.r(3) - 1)).normalize(); + falling.setVelocity(vector.multiply(0.5 + (l.distance(target.getEyeLocation()) / 10))); } } } + + if (_thrown >= 3 && !UtilPlayer.getNearby(getLocation(), 10, true).isEmpty()) + { + _thrown = 99; + } + } + + @Override + public boolean inProgress() + { + return _thrown < _toThrow || !_current.isEmpty(); } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemCaveIn.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemCaveIn.java similarity index 96% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemCaveIn.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemCaveIn.java index 4fab784aa..1dccc1e36 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemCaveIn.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemCaveIn.java @@ -1,4 +1,4 @@ -package mineplex.game.clans.clans.worldevent.event.golem.abilities; +package mineplex.minecraft.game.core.boss.ironwizard.abilities; import java.util.ArrayList; import java.util.Iterator; @@ -14,7 +14,7 @@ import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilShapes; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature; import net.minecraft.server.v1_7_R4.AxisAlignedBB; import net.minecraft.server.v1_7_R4.MathHelper; import net.minecraft.server.v1_7_R4.MovingObjectPosition; @@ -55,7 +55,7 @@ public class GolemCaveIn extends GolemAbility @Override public Player getTarget() { - if (getTarget(3) == null) + if (getTarget(4) == null) { return getTarget(40); } @@ -167,7 +167,7 @@ public class GolemCaveIn extends GolemAbility .getEvent() .getDamageManager() .NewDamageEvent((LivingEntity) victim, getEntity(), null, DamageCause.CONTACT, 6, true, true, false, - "Cave In", "Cave In"); + "Iron Wizard Cave In", "Iron Wizard Cave In"); } cur.remove(); @@ -266,7 +266,7 @@ public class GolemCaveIn extends GolemAbility return; } - LinkedList players = UtilPlayer.getNearby(getLocation(), 50); + LinkedList players = UtilPlayer.getNearby(getLocation(), 50, true); for (int i = 0; i < players.size(); i++) { @@ -301,7 +301,6 @@ public class GolemCaveIn extends GolemAbility FallingBlock block = b.getWorld().spawnFallingBlock(b.getLocation().add(0.5, -1, 0.5), b.getTypeId(), b.getData()); - block.setVelocity(new Vector(UtilMath.r(5) - 2.5D, 0, UtilMath.r(5) - 2.5D).multiply(0.1)); block.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, block.getBlockId()); block.setDropItem(false); @@ -313,4 +312,10 @@ public class GolemCaveIn extends GolemAbility } } + @Override + public boolean inProgress() + { + return true; + } + } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemEarthquake.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemEarthquake.java similarity index 83% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemEarthquake.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemEarthquake.java index df3b8b157..41ed9c38d 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemEarthquake.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemEarthquake.java @@ -1,4 +1,4 @@ -package mineplex.game.clans.clans.worldevent.event.golem.abilities; +package mineplex.minecraft.game.core.boss.ironwizard.abilities; import java.util.ArrayList; import java.util.HashSet; @@ -6,20 +6,16 @@ import java.util.UUID; import mineplex.core.common.util.UtilAction; import mineplex.core.common.util.UtilAlg; -import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilEnt; import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilServer; -import mineplex.core.common.util.UtilShapes; -import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Sound; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; @@ -32,6 +28,7 @@ public class GolemEarthquake extends GolemAbility private float _range; private int _tick; private ArrayList _damaged = new ArrayList(); + private boolean _earthquake; public GolemEarthquake(GolemCreature creature) { @@ -54,7 +51,7 @@ public class GolemEarthquake extends GolemAbility @Override public boolean hasFinished() { - return _range > 15; + return _range > 19; } @Override @@ -73,8 +70,12 @@ public class GolemEarthquake extends GolemAbility entity.setVelocity(new Vector(0, 1, 0)); } + else if (!_earthquake) + { + _earthquake = _tick > 10 && UtilEnt.isGrounded(entity); + } - if (_tick > 10 && UtilEnt.isGrounded(entity)) + if (_earthquake) { _range += 0.7; @@ -140,10 +141,10 @@ public class GolemEarthquake extends GolemAbility getGolem() .getEvent() .getDamageManager() - .NewDamageEvent((LivingEntity) player, getEntity(), null, DamageCause.CONTACT, 6, false, true, false, - "Earthquake", "Earthquake"); + .NewDamageEvent((LivingEntity) player, getEntity(), null, DamageCause.CONTACT, 12, false, true, false, + "Iron Wizard Earthquake", "Iron Wizard Earthquake"); - getGolem().getEvent().getEventManager().getClans().getCondition().Factory() + getGolem().getEvent().getCondition().Factory() .Slow("Earthquake", (LivingEntity) player, getEntity(), 3, 1, false, false, false, false); // Velocity @@ -151,11 +152,16 @@ public class GolemEarthquake extends GolemAbility 1.8, true, 0, 0.5, 0.5, true); // Condition - getGolem().getEvent().getEventManager().getClans().getCondition().Factory() - .Falling("Earthquake", player, getEntity(), 10, false, true); + getGolem().getEvent().getCondition().Factory().Falling("Earthquake", player, getEntity(), 10, false, true); } } _tick++; } + + @Override + public boolean inProgress() + { + return !_earthquake; + } } diff --git a/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemExplodingAura.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemExplodingAura.java new file mode 100644 index 000000000..8fad751c2 --- /dev/null +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemExplodingAura.java @@ -0,0 +1,430 @@ +package mineplex.minecraft.game.core.boss.ironwizard.abilities; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; + +import net.minecraft.server.v1_7_R4.AxisAlignedBB; +import net.minecraft.server.v1_7_R4.DataWatcher; +import net.minecraft.server.v1_7_R4.MathHelper; +import net.minecraft.server.v1_7_R4.MovingObjectPosition; +import net.minecraft.server.v1_7_R4.Packet; +import net.minecraft.server.v1_7_R4.PacketPlayOutAttachEntity; +import net.minecraft.server.v1_7_R4.PacketPlayOutEntityDestroy; +import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntity; +import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntityLiving; +import net.minecraft.server.v1_7_R4.Vec3D; + +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftEntity; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilParticle.ParticleType; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +public class GolemExplodingAura extends GolemAbility +{ + + private HashMap _blocks = new HashMap(); + private HashMap _blocksLoc = new HashMap(); + private ArrayList _fallingBlocks = new ArrayList(); + // private HashMap _blocksExplode = new HashMap(); + private HashMap _blockMaterial = new HashMap(); + private int _tick; + + public GolemExplodingAura(GolemCreature creature) + { + super(creature); + } + + @Override + public boolean canMove() + { + return false; + } + + @Override + public boolean hasFinished() + { + return _tick > 20 * 30 && _blocks.isEmpty() && _fallingBlocks.isEmpty(); + } + + @Override + public void setFinished() + { + for (FallingBlock block : _fallingBlocks) + { + block.remove(); + } + + int[] ids = new int[_blocks.size() * 2]; + + int i = 0; + + for (Entry id : _blocks.entrySet()) + { + ids[i] = id.getKey(); + ids[i + 1] = id.getValue(); + + i += 2; + } + + PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids); + + for (Player player : UtilServer.getPlayers()) + { + UtilPlayer.sendPacket(player, packet); + } + } + + @Override + public void tick() + { + if (_tick < 25 * 25) + { + double angle = (2 * Math.PI) / UtilMath.random.nextDouble(); + double x = 1.7 * Math.cos(angle); + double z = 1.7 * Math.sin(angle); + + Location loc = getLocation().add(x, 1 + (UtilMath.random.nextDouble() * 1.6), z); + + loc.getWorld().playEffect(loc, Effect.STEP_SOUND, Material.DIRT.getId()); + + for (Player player : UtilPlayer.getNearby(getLocation(), 3, true)) + { + getGolem() + .getEvent() + .getDamageManager() + .NewDamageEvent(player, getEntity(), null, DamageCause.CONTACT, 2, true, true, false, + "Iron Wizard Protection", "Iron Wizard Protection"); + UtilAction.velocity(player, UtilAlg.getTrajectory(getEntity(), player), 1, true, 0.3, 0, 0.3, false); + } + } + + if (_tick < 20 * 30) + { + int key = UtilEnt.getNewEntityId(); + int value = UtilEnt.getNewEntityId(); + + Location loc = null; + + for (int i = 0; i < 30; i++) + { + double angle = (2 * Math.PI) / UtilMath.random.nextDouble(); + double x = 1.7 * Math.cos(angle); + double z = 1.7 * Math.sin(angle); + + loc = getLocation().add(x, 1 + (UtilMath.random.nextDouble() * 1.6), z); + boolean found = false; + + for (Location l : _blocksLoc.values()) + { + if (l.distance(loc) < 0.3) + { + found = true; + break; + } + } + + if (found) + { + loc = null; + } + else + { + break; + } + } + + if (loc != null) + { + _blocks.put(key, value); + _blocksLoc.put(key, loc); + // _blocksExplode.put(key, System.currentTimeMillis() + UtilMath.r(800) + 100); + _blockMaterial.put(key, UtilMath.random.nextBoolean() ? Material.DIRT : Material.STONE); + + Packet[] packets = new Packet[3]; + + PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving(); + + DataWatcher watcher = new DataWatcher(null); + watcher.a(0, (byte) 32); + watcher.a(1, 0); + + packet1.a = key; + packet1.b = EntityType.SILVERFISH.getTypeId(); + packet1.c = (int) Math.floor(loc.getX() * 32); + packet1.d = (int) Math.floor((loc.getY() - 0.125) * 32); + packet1.e = (int) Math.floor(loc.getZ() * 32); + packet1.l = watcher; + + packets[0] = packet1; + + PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) getEntity()).getHandle(), 70, + _blockMaterial.get(key).getId()); + + packet2.a = value; + + packet2.b = (int) Math.floor(loc.getX() * 32); + packet2.c = (int) Math.floor(loc.getY() * 32); + packet2.d = (int) Math.floor(loc.getZ() * 32); + + packets[1] = packet2; + + PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity(); + + packet3.b = value; + packet3.c = key; + + packets[2] = packet3; + + for (Player player : UtilPlayer.getNearby(getLocation(), 70)) + { + UtilPlayer.sendPacket(player, packets); + } + } + } + + /*Iterator itel = _blocksExplode.keySet().iterator(); + + while (itel.hasNext()) + { + int key = itel.next(); + + if (_blocksExplode.get(key) < System.currentTimeMillis()) + { + itel.remove();*/ + if (_tick % 25 == 0) + { + for (int i = 0; i < 3; i++) + getLocation().getWorld().playSound(getLocation(), Sound.DIG_GRASS, 3, 2); + + for (int key : new ArrayList(_blocksLoc.keySet())) + { + + PacketPlayOutEntityDestroy destroyPacket = new PacketPlayOutEntityDestroy(new int[] + { + key, _blocks.remove(key) + }); + + for (Player player : UtilServer.getPlayers()) + { + UtilPlayer.sendPacket(player, destroyPacket); + } + + Location loc = _blocksLoc.remove(key); + + FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, _blockMaterial.remove(key), (byte) 0); + + _fallingBlocks.add(falling); + + Vector vec = UtilAlg.getTrajectory(getLocation().add(0, 1, 0), loc); + + vec.setY(Math.max(0.05, vec.getY())); + + falling.setVelocity(vec); + + loc.getWorld().playEffect(loc, Effect.STEP_SOUND, Material.DIRT.getId()); + } + } + + _tick++; + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.TICK) + { + return; + } + + Iterator fallingIterator = _fallingBlocks.iterator(); + + while (fallingIterator.hasNext()) + { + FallingBlock cur = fallingIterator.next(); + + if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + fallingIterator.remove(); + + Block block = cur.getLocation().getBlock(); + block.setTypeIdAndData(0, (byte) 0, true); + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + + // Expire + if (cur.getTicksLived() > 400 + || !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4)) + { + cur.remove(); + continue; + } + + cur.remove(); + continue; + } + + double distanceToEntity = 0.0D; + LivingEntity victim = null; + + net.minecraft.server.v1_7_R4.Entity nmsEntity = ((CraftEntity) cur).getHandle(); + Vec3D vec3d = Vec3D.a(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + Vec3D vec3d1 = Vec3D.a(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + + nmsEntity.motZ); + + MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false); + vec3d = Vec3D.a(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ); + vec3d1 = Vec3D.a(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ); + + if (finalObjectPosition != null) + { + vec3d1 = Vec3D.a(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c); + } + + for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities( + ((CraftEntity) cur).getHandle(), + ((CraftEntity) cur).getHandle().boundingBox.a(((CraftEntity) cur).getHandle().motX, + ((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2))) + { + Entity bukkitEntity = ((net.minecraft.server.v1_7_R4.Entity) entity).getBukkitEntity(); + + if (bukkitEntity instanceof LivingEntity) + { + LivingEntity ent = (LivingEntity) bukkitEntity; + + // Avoid Self + if (ent.equals(getEntity())) + continue; + + // Creative or Spec + if (ent instanceof Player) + if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent)) + continue; + + // float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f); + AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().boundingBox.grow(1F, 1F, 1F); + MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1); + + if (entityCollisionPosition != null) + { + double d1 = vec3d.distanceSquared(entityCollisionPosition.pos); + if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D)) + { + victim = ent; + distanceToEntity = d1; + } + } + } + } + + if (victim != null) + { + cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId()); + + // if (canDamage(victim)) + { + getGolem() + .getEvent() + .getDamageManager() + .NewDamageEvent((LivingEntity) victim, getEntity(), null, DamageCause.CONTACT, 6, true, true, false, + "Blocky Iron Wizard Aura", "Blocky Iron Wizard Aura"); + } + + if (victim instanceof Player) + { + getGolem() + .getEvent() + .getCondition() + .Factory() + .Slow("Blocky Iron Wizard Aura", (LivingEntity) victim, getEntity(), 3, 2, false, false, false, false); + } + + fallingIterator.remove(); + cur.remove(); + + Vector vec = UtilAlg.getTrajectory(getEntity(), victim); + vec.setY(0).normalize(); + + double strength = 1; + + if (!(victim instanceof Player) || !((Player) victim).isBlocking()) + { + strength = 1.3; + } + + UtilAction.velocity(victim, vec, strength, true, 0, 0.2, 1, true); + } + else if (finalObjectPosition != null) + { + Block block = cur.getWorld().getBlockAt(finalObjectPosition.b, finalObjectPosition.c, finalObjectPosition.d); + + if (!UtilBlock.airFoliage(block) && !block.isLiquid()) + { + nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX)); + nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY)); + nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ)); + float f2 = MathHelper.sqrt(nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ + * nmsEntity.motZ); + nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D; + nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D; + nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D; + + cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId()); + + fallingIterator.remove(); + cur.remove(); + } + } + else + { + UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0), cur.getLocation() + .add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL, UtilServer.getPlayers()); + } + } + } + + @EventHandler + public void onDamage(CustomDamageEvent event) + { + if (event.GetDamageeEntity().equals(getEntity())) + { + if (event.GetProjectile() != null) + { + event.AddMod("Ranged Resistance", 0.1); + } + } + } + + @Override + public boolean inProgress() + { + return false; + } +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemExplosiveBlock.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemExplosiveBlock.java similarity index 97% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemExplosiveBlock.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemExplosiveBlock.java index e92b279d2..eda1d77d3 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemExplosiveBlock.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemExplosiveBlock.java @@ -1,4 +1,4 @@ -package mineplex.game.clans.clans.worldevent.event.golem.abilities; +package mineplex.minecraft.game.core.boss.ironwizard.abilities; import java.util.ArrayList; import java.util.HashMap; @@ -17,9 +17,8 @@ import mineplex.core.common.util.UtilServer; import mineplex.core.itemstack.ItemBuilder; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature; import mineplex.minecraft.game.core.damage.CustomDamageEvent; -import mineplex.minecraft.game.core.explosion.CustomExplosion; import net.minecraft.server.v1_7_R4.AxisAlignedBB; import net.minecraft.server.v1_7_R4.DataWatcher; import net.minecraft.server.v1_7_R4.EntityIronGolem; @@ -171,7 +170,7 @@ public class GolemExplosiveBlock extends GolemAbility { _explosionsLeft++; - Bukkit.getScheduler().scheduleSyncDelayedTask(getGolem().getEvent().getEventManager().getPlugin(), new Runnable() + Bukkit.getScheduler().scheduleSyncDelayedTask(getGolem().getEvent().getPlugin(), new Runnable() { public void run() { @@ -190,14 +189,14 @@ public class GolemExplosiveBlock extends GolemAbility Location l = loc.clone().add(UtilMath.r(_strength * 4) - (_strength * 2), UtilMath.r(_strength * 2), UtilMath.r(_strength * 4) - (_strength * 2)); - CustomExplosion explosion = new CustomExplosion(getGolem().getEvent().getDamageManager(), getGolem().getEvent() + /* CustomExplosion explosion = new CustomExplosion(getGolem().getEvent().getDamageManager(), getGolem().getEvent() .getEventManager().getClans().getExplosion(), l, _strength * 0.8F, "Golem Explosive Block"); explosion.setPlayer(getEntity(), false); explosion.setDamageBlocks(false); - explosion.explode(); + explosion.explode();*/ UtilParticle.PlayParticle(ParticleType.LARGE_EXPLODE, l, _strength * 3, 1, _strength * 3, 0, _strength * 4, ViewDist.LONG, UtilServer.getPlayers()); @@ -580,4 +579,11 @@ public class GolemExplosiveBlock extends GolemAbility _tick++; } + @Override + public boolean inProgress() + { + // TODO Auto-generated method stub + return false; + } + } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemMeleeAttack.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemMeleeAttack.java similarity index 64% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemMeleeAttack.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemMeleeAttack.java index 3a7dbbbeb..9b9a9e220 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemMeleeAttack.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemMeleeAttack.java @@ -1,11 +1,13 @@ -package mineplex.game.clans.clans.worldevent.event.golem.abilities; +package mineplex.minecraft.game.core.boss.ironwizard.abilities; import mineplex.core.common.util.UtilAction; import mineplex.core.common.util.UtilEnt; import mineplex.core.common.util.UtilPlayer; -import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature; +import net.minecraft.server.v1_7_R4.EntityIronGolem; import org.bukkit.Sound; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftIronGolem; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.util.Vector; @@ -53,7 +55,7 @@ public class GolemMeleeAttack extends GolemAbility { _attacked = true; - for (Player target : UtilPlayer.getNearby(getLocation(), 2)) + for (Player target : UtilPlayer.getNearby(getLocation(), 2.5, true)) { if (target.getVelocity().length() > 0.5) { @@ -65,8 +67,8 @@ public class GolemMeleeAttack extends GolemAbility getGolem() .getEvent() .getDamageManager() - .NewDamageEvent(target, getEntity(), null, DamageCause.ENTITY_ATTACK, 6, false, true, false, "Golem Attack", - "Golem Attack"); + .NewDamageEvent(target, getEntity(), null, DamageCause.ENTITY_ATTACK, 6, false, true, false, + "Iron Wizard Melee Attack", "Iron Wizard Melee Attack"); Vector vec = getLocation().getDirection(); vec.setY(0).normalize().multiply(0.2); @@ -74,8 +76,20 @@ public class GolemMeleeAttack extends GolemAbility UtilAction.velocity(target, vec, 1.4, false, 0, 0, 2, false); + getGolem().getEvent().getCondition().Factory().Falling("Iron Wizard Throw", target, getEntity(), 3, false, false); + target.getWorld().playSound(target.getLocation(), Sound.IRONGOLEM_THROW, 3, 0.9F); + + EntityIronGolem golem = ((CraftIronGolem) getEntity()).getHandle(); + + golem.world.broadcastEntityEffect(golem, (byte) 4); } } + @Override + public boolean inProgress() + { + return _attacked; + } + } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemRumble.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemRumble.java similarity index 77% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemRumble.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemRumble.java index 9e8ae2bc0..6df54698c 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemRumble.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemRumble.java @@ -1,4 +1,4 @@ -package mineplex.game.clans.clans.worldevent.event.golem.abilities; +package mineplex.minecraft.game.core.boss.ironwizard.abilities; import java.util.ArrayList; @@ -7,7 +7,8 @@ import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilEnt; import mineplex.core.common.util.UtilPlayer; -import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import mineplex.core.common.util.UtilServer; +import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature; import net.minecraft.server.v1_7_R4.EntityIronGolem; import org.bukkit.Effect; @@ -30,18 +31,24 @@ import org.bukkit.util.Vector; public class GolemRumble extends GolemAbility { private Location _loc; - private Player _target; private int _ticks; private int _travelled; private Vector _vec; private int _width = 1; + private Location _target; public GolemRumble(GolemCreature creature) { super(creature); - _target = getTarget(); - UtilEnt.CreatureLook(getEntity(), _target); + Player target = getTarget(); + + if (target != null) + { + _target = target.getLocation(); + + UtilEnt.CreatureLook(getEntity(), _target); + } } @Override @@ -53,7 +60,7 @@ public class GolemRumble extends GolemAbility @Override public boolean hasFinished() { - return _target == null || !_target.isValid() || getLocation().distance(_target.getLocation()) > 100; + return _travelled > 35; } @Override @@ -74,14 +81,13 @@ public class GolemRumble extends GolemAbility if (_ticks % 2 == 0) { entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 3, 2F); - UtilEnt.CreatureLook(entity, _target); } } else if (_ticks % 2 == 0) { int oldWidth = _width; - if ((_width <= 3 || _ticks % 4 == 0) && _width <= 5) + if ((_width <= 3 || _ticks % 4 == 0) && _width <= 6) { _width++; } @@ -92,7 +98,7 @@ public class GolemRumble extends GolemAbility if (_vec == null) { - _vec = _target.getLocation().subtract(getLocation()).toVector().setY(0).normalize();// .multiply(0.5); + _vec = _target.subtract(getLocation()).toVector().setY(0).normalize();// .multiply(0.5); _loc = getLocation().subtract(0, 1, 0).getBlock().getLocation().add(0, 0.99, 0); newLoc = _loc; current.add(_loc.getBlock()); @@ -106,14 +112,9 @@ public class GolemRumble extends GolemAbility // Check if the rumble needs to go up or drop a block or two for (int y : new int[] { - 0, 1, -1, -2 + 0, 1, -1 }) { - if (_loc.getBlockY() + y <= 0) - { - continue; - } - for (int a = 1; a <= 2; a++) { Block b = newLoc.clone().add(_vec.clone().multiply(a)).getBlock().getRelative(0, y, 0); @@ -187,16 +188,15 @@ public class GolemRumble extends GolemAbility getGolem() .getEvent() .getDamageManager() - .NewDamageEvent((LivingEntity) entity, getEntity(), null, DamageCause.CONTACT, 6, false, true, - false, "Rumble", "Rumble"); + .NewDamageEvent((LivingEntity) entity, getEntity(), null, DamageCause.CONTACT, 4, false, true, + false, "Iron Wizard Rumble", "Iron Wizard Rumble"); } UtilAction.velocity(entity, _vec.clone(), 1.5, true, 0, 0.2, 1, true); if (entity instanceof Player) { - - getGolem().getEvent().getEventManager().getClans().getCondition().Factory() + getGolem().getEvent().getCondition().Factory() .Slow("Rumble", (LivingEntity) entity, getEntity(), 3, 1, false, false, false, false); } } @@ -204,12 +204,40 @@ public class GolemRumble extends GolemAbility if (_travelled++ > 35 || !validBlock) { - // TODO Explode? - _target = null; + _travelled = 100; } _loc = newLoc; } } + public Player getTarget() + { + Player target = null; + double dist = 0; + + for (Player player : UtilPlayer.getNearby(getLocation(), 30, true)) + { + if (!player.hasLineOfSight(getEntity())) + { + continue; + } + + double d = player.getLocation().distance(getLocation()); + + if (d > 2 && (target == null || dist > d)) + { + target = player; + dist = d; + } + } + + return target; + } + + @Override + public boolean inProgress() + { + return _ticks < 14; + } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemWallExplode.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemWallExplode.java similarity index 92% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemWallExplode.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemWallExplode.java index 2ae35c202..a96961311 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/golem/abilities/GolemWallExplode.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemWallExplode.java @@ -1,4 +1,4 @@ -package mineplex.game.clans.clans.worldevent.event.golem.abilities; +package mineplex.minecraft.game.core.boss.ironwizard.abilities; import java.util.ArrayList; import java.util.HashMap; @@ -18,7 +18,7 @@ import mineplex.core.common.util.UtilShapes; import mineplex.core.common.util.UtilTime; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.game.clans.clans.worldevent.event.golem.GolemCreature; +import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature; import net.minecraft.server.v1_7_R4.AxisAlignedBB; import net.minecraft.server.v1_7_R4.MathHelper; import net.minecraft.server.v1_7_R4.MovingObjectPosition; @@ -75,7 +75,7 @@ public class GolemWallExplode extends GolemAbility @Override public Player getTarget() { - for (Player player : UtilPlayer.getNearby(getLocation(), 15)) + for (Player player : UtilPlayer.getNearby(getLocation(), 15, true)) { if (_dontTarget.contains(player.getName())) { @@ -197,7 +197,7 @@ public class GolemWallExplode extends GolemAbility .getEvent() .getDamageManager() .NewDamageEvent((LivingEntity) victim, getEntity(), null, DamageCause.CONTACT, 6, true, true, false, - "Wall Explosion", "Wall Explosion"); + "Iron Wizard Wall Explosion", "Iron Wizard Wall Explosion"); } cur.remove(); @@ -298,18 +298,18 @@ public class GolemWallExplode extends GolemAbility BlockFace sideFace = UtilShapes.getSideBlockFaces(face, true)[0]; boolean invalid = false; - for (int mult = -2; mult <= 2; mult++) + for (int mult = -3; mult <= 3; mult++) { Block block = b; - if (Math.abs(mult) < 2) + if (Math.abs(mult) < 3) { block = block.getRelative(face); } block = block.getRelative(sideFace, mult); - if (Math.abs(mult) == 2 && face.getModX() != 0 && face.getModZ() != 0) + if (Math.abs(mult) == 3 && face.getModX() != 0 && face.getModZ() != 0) { block = block.getRelative(UtilShapes.getSideBlockFaces(face, false)[mult < 0 ? 0 : 1]); } @@ -365,6 +365,7 @@ public class GolemWallExplode extends GolemAbility } Iterator>> itel = _blockWalls.entrySet().iterator(); + boolean doExplode = false; while (itel.hasNext()) { @@ -373,6 +374,7 @@ public class GolemWallExplode extends GolemAbility if (UtilTime.elapsed(_wallTimers.get(face), 1000)) { + doExplode = true; itel.remove(); _wallTimers.remove(face); @@ -385,11 +387,11 @@ public class GolemWallExplode extends GolemAbility int index = entry.getValue().indexOf(b); - BlockFace f = index == 6 || index == 7 ? BlockFace.SELF + BlockFace f = index == 8 || index == 9 ? BlockFace.SELF : UtilShapes.getSideBlockFaces(face, true)[index > 6 ? 0 : 1]; - block.setVelocity(new Vector((face.getModX() * 0.65) + (f.getModX() * (0.05 + getMod(10))), 0.2 + getMod(15), - (face.getModZ() * 0.65) + (f.getModZ() * (0.05 + getMod(10))))); + block.setVelocity(new Vector((face.getModX() * 0.6) + (f.getModX() * (0.05 + getMod(10))), 0.2 + getMod(15), + (face.getModZ() * 0.6) + (f.getModZ() * (0.05 + getMod(10))))); _fallingBlocks.add(block); @@ -398,6 +400,17 @@ public class GolemWallExplode extends GolemAbility } } } + + if (doExplode) + { + onUpdate(new UpdateEvent(UpdateType.TICK)); + } + } + + @Override + public boolean inProgress() + { + return false; } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/SlimeBoss.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/SlimeBoss.java similarity index 71% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/SlimeBoss.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/SlimeBoss.java index 3fc49866e..9b968809d 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/SlimeBoss.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/SlimeBoss.java @@ -1,29 +1,36 @@ -package mineplex.game.clans.clans.worldevent.event.slimeking; +package mineplex.minecraft.game.core.boss.slimeking; import java.io.File; import java.io.IOException; +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.common.block.schematic.Schematic; +import mineplex.core.common.block.schematic.UtilSchematic; +import mineplex.core.projectile.ProjectileManager; +import mineplex.minecraft.game.core.boss.EventCreature; +import mineplex.minecraft.game.core.boss.EventMap; +import mineplex.minecraft.game.core.boss.EventState; +import mineplex.minecraft.game.core.boss.WorldEvent; +import mineplex.minecraft.game.core.boss.slimeking.creature.SlimeCreature; +import mineplex.minecraft.game.core.condition.ConditionManager; +import mineplex.minecraft.game.core.damage.DamageManager; + import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.util.Vector; -import mineplex.core.common.block.schematic.Schematic; -import mineplex.core.common.block.schematic.UtilSchematic; -import mineplex.game.clans.clans.worldevent.EventMap; -import mineplex.game.clans.clans.worldevent.WorldEventManager; -import mineplex.game.clans.clans.worldevent.creature.EventCreature; -import mineplex.game.clans.clans.worldevent.event.EventState; -import mineplex.game.clans.clans.worldevent.event.WorldEvent; -import mineplex.game.clans.clans.worldevent.event.slimeking.creature.SlimeCreature; - public class SlimeBoss extends WorldEvent { private static final int MAX_SIZE = 16; private static final int MIN_SIZE = 2; + private ProjectileManager _projectileManager; - public SlimeBoss(WorldEventManager eventManager, Location corner) + public SlimeBoss(DamageManager damageManager, BlockRestore blockRestore, ConditionManager conditionManager, + ProjectileManager projectileManager, Location corner) { - super(eventManager, "Slime King", corner); + super(damageManager, blockRestore, conditionManager, "Slime King", corner); + + _projectileManager = projectileManager; Schematic schematic = null; @@ -48,6 +55,11 @@ public class SlimeBoss extends WorldEvent }); } + public ProjectileManager getProjectileManager() + { + return _projectileManager; + } + @Override protected void customStart() { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/AbsorbAbility.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/AbsorbAbility.java similarity index 90% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/AbsorbAbility.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/AbsorbAbility.java index 051df0106..75c0b6e3d 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/AbsorbAbility.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/AbsorbAbility.java @@ -1,16 +1,16 @@ -package mineplex.game.clans.clans.worldevent.event.slimeking.ability; +package mineplex.minecraft.game.core.boss.slimeking.ability; import java.util.HashMap; import java.util.Map; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilPlayer; +import mineplex.minecraft.game.core.boss.slimeking.creature.SlimeCreature; + import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.util.Vector; -import mineplex.core.common.util.UtilAlg; -import mineplex.core.common.util.UtilPlayer; -import mineplex.game.clans.clans.worldevent.event.slimeking.creature.SlimeCreature; - public class AbsorbAbility extends SlimeAbility { private int _ticksPerPulse; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/LeapAbility.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/LeapAbility.java similarity index 90% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/LeapAbility.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/LeapAbility.java index faac3c0b8..126e22be5 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/LeapAbility.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/LeapAbility.java @@ -1,4 +1,9 @@ -package mineplex.game.clans.clans.worldevent.event.slimeking.ability; +package mineplex.minecraft.game.core.boss.slimeking.ability; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilPlayer; +import mineplex.minecraft.game.core.boss.slimeking.creature.SlimeCreature; import org.bukkit.Material; import org.bukkit.World; @@ -7,11 +12,6 @@ import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import mineplex.core.common.util.UtilAction; -import mineplex.core.common.util.UtilAlg; -import mineplex.core.common.util.UtilPlayer; -import mineplex.game.clans.clans.worldevent.event.slimeking.creature.SlimeCreature; - public class LeapAbility extends SlimeAbility { private Player _target; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/RocketAbility.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/RocketAbility.java similarity index 93% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/RocketAbility.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/RocketAbility.java index d1b10a69d..5b0319cad 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/RocketAbility.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/RocketAbility.java @@ -1,17 +1,8 @@ -package mineplex.game.clans.clans.worldevent.event.slimeking.ability; +package mineplex.minecraft.game.core.boss.slimeking.ability; import java.util.Iterator; import java.util.LinkedList; -import org.bukkit.Location; -import org.bukkit.Sound; -import org.bukkit.block.Block; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.entity.Slime; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.util.Vector; - import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilPlayer; @@ -20,7 +11,16 @@ import mineplex.core.projectile.IThrown; import mineplex.core.projectile.ProjectileManager; import mineplex.core.projectile.ProjectileUser; import mineplex.core.updater.UpdateType; -import mineplex.game.clans.clans.worldevent.event.slimeking.creature.SlimeCreature; +import mineplex.minecraft.game.core.boss.slimeking.creature.SlimeCreature; + +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Slime; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.util.Vector; public class RocketAbility extends SlimeAbility implements IThrown { @@ -98,7 +98,7 @@ public class RocketAbility extends SlimeAbility implements IThrown projectile.setSize(1); _shots.add(new ShotData(projectile, target)); - ProjectileManager pm = getSlime().getEvent().getEventManager().getClans().getProjectile(); + ProjectileManager pm = getSlime().getProjectileManager(); pm.AddThrow(projectile, getSlime().getEntity(), this, -1, true, true, true, null, 0, 0, UtilParticle.ParticleType.SLIME, UpdateType.FASTEST, 1F); // Bukkit.broadcastMessage("Shot Slime at target " + target); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/SlamAbility.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/SlamAbility.java similarity index 95% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/SlamAbility.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/SlamAbility.java index eaba235d8..3063aab0c 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/SlamAbility.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/SlamAbility.java @@ -1,19 +1,19 @@ -package mineplex.game.clans.clans.worldevent.event.slimeking.ability; +package mineplex.minecraft.game.core.boss.slimeking.ability; import java.util.LinkedList; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilParticle; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.minecraft.game.core.boss.slimeking.creature.SlimeCreature; + import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import mineplex.core.common.util.UtilAlg; -import mineplex.core.common.util.UtilParticle; -import mineplex.core.common.util.UtilPlayer; -import mineplex.core.common.util.UtilServer; -import mineplex.game.clans.clans.worldevent.event.slimeking.creature.SlimeCreature; - public class SlamAbility extends SlimeAbility { private int _findAttempts; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/SlimeAbility.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/SlimeAbility.java similarity index 80% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/SlimeAbility.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/SlimeAbility.java index e53101499..f18021878 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/ability/SlimeAbility.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/ability/SlimeAbility.java @@ -1,6 +1,6 @@ -package mineplex.game.clans.clans.worldevent.event.slimeking.ability; +package mineplex.minecraft.game.core.boss.slimeking.ability; -import mineplex.game.clans.clans.worldevent.event.slimeking.creature.SlimeCreature; +import mineplex.minecraft.game.core.boss.slimeking.creature.SlimeCreature; public abstract class SlimeAbility { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/creature/SlimeCreature.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/creature/SlimeCreature.java similarity index 65% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/creature/SlimeCreature.java rename to Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/creature/SlimeCreature.java index 6cbe06773..068f20380 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/slimeking/creature/SlimeCreature.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/slimeking/creature/SlimeCreature.java @@ -1,4 +1,15 @@ -package mineplex.game.clans.clans.worldevent.event.slimeking.creature; +package mineplex.minecraft.game.core.boss.slimeking.creature; + +import mineplex.core.projectile.ProjectileManager; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.core.boss.EventCreature; +import mineplex.minecraft.game.core.boss.slimeking.SlimeBoss; +import mineplex.minecraft.game.core.boss.slimeking.ability.AbsorbAbility; +import mineplex.minecraft.game.core.boss.slimeking.ability.LeapAbility; +import mineplex.minecraft.game.core.boss.slimeking.ability.RocketAbility; +import mineplex.minecraft.game.core.boss.slimeking.ability.SlamAbility; +import mineplex.minecraft.game.core.boss.slimeking.ability.SlimeAbility; import org.bukkit.Location; import org.bukkit.entity.MagmaCube; @@ -6,16 +17,6 @@ import org.bukkit.entity.Slime; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.SlimeSplitEvent; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; -import mineplex.game.clans.clans.worldevent.creature.EventCreature; -import mineplex.game.clans.clans.worldevent.event.slimeking.SlimeBoss; -import mineplex.game.clans.clans.worldevent.event.slimeking.ability.AbsorbAbility; -import mineplex.game.clans.clans.worldevent.event.slimeking.ability.LeapAbility; -import mineplex.game.clans.clans.worldevent.event.slimeking.ability.RocketAbility; -import mineplex.game.clans.clans.worldevent.event.slimeking.ability.SlamAbility; -import mineplex.game.clans.clans.worldevent.event.slimeking.ability.SlimeAbility; - public class SlimeCreature extends EventCreature { private SlimeBoss _boss; @@ -44,6 +45,11 @@ public class SlimeCreature extends EventCreature getEntity().setSize(_size); } + public ProjectileManager getProjectileManager() + { + return _boss.getProjectileManager(); + } + @EventHandler public void abilityTick(UpdateEvent event) { @@ -75,10 +81,10 @@ public class SlimeCreature extends EventCreature } // Disable Enrage -// if (!_enraged && _ticksLived >= _enrageTicks) -// { -// setEnraged(true); -// } + // if (!_enraged && _ticksLived >= _enrageTicks) + // { + // setEnraged(true); + // } _currentAbility.tick(); } @@ -90,17 +96,17 @@ public class SlimeCreature extends EventCreature event.setCancelled(true); } -// @EventHandler -// public void target(EntityTargetEvent event) -// { -// if (event.getEntity().equals(getEntity())) -// { -// Bukkit.broadcastMessage("Target Event"); -// Player player = UtilPlayer.getRandomTarget(getEntity().getLocation(), 30); -// Bukkit.broadcastMessage("Targetting: " + player); -// event.setTarget(player); -// } -// } + // @EventHandler + // public void target(EntityTargetEvent event) + // { + // if (event.getEntity().equals(getEntity())) + // { + // Bukkit.broadcastMessage("Target Event"); + // Player player = UtilPlayer.getRandomTarget(getEntity().getLocation(), 30); + // Bukkit.broadcastMessage("Targetting: " + player); + // event.setTarget(player); + // } + // } public void setEnraged(boolean enraged) {