Merge remote-tracking branch 'refs/remotes/origin/develop' into feature/moba

This commit is contained in:
Sam 2017-06-08 16:10:49 +01:00
commit 206dd56d14
33 changed files with 1020 additions and 495 deletions

View File

@ -1201,7 +1201,31 @@ public enum Achievement
new String[]{"Skyfall.SupplyDropsOpened"}, new String[]{"Skyfall.SupplyDropsOpened"},
new String[]{"Be the first to open 20 Supply Drops"}, new String[]{"Be the first to open 20 Supply Drops"},
new int[]{20}, new int[]{20},
AchievementCategory.SKYFALL); AchievementCategory.SKYFALL),
GEM_HUNTERS_KILLS("Gem Killer", 5000,
new String[]{"Gem Hunters.Kills"},
new String[]{"+1 for each kill"},
new int[]{10,25,50,100,1000},
AchievementCategory.GEM_HUNTERS),
GEM_HUNTERS_GEMS_EARNED("Gem Millionaire", 5000,
new String[]{"Gem Hunters.GemsEarned"},
new String[]{"+1 for each Gem cashed out"},
new int[]{1000,2500,5000,10000,100000},
AchievementCategory.GEM_HUNTERS),
GEM_HUNTERS_QUESTS("Quest Complete", 5000,
new String[]{"Gem Hunters.QuestsCompleted"},
new String[]{"+1 for each quest completed"},
new int[]{10,25,50,100,1000},
AchievementCategory.GEM_HUNTERS),
GEM_HUNTERS_CHESTS_OPENED("Loot Get!", 5000,
new String[]{"Gem Hunters.ChestsOpened"},
new String[]{"+1 for each chest opened"},
new int[]{50,100,200,400,1000},
AchievementCategory.GEM_HUNTERS);
private String _name; private String _name;
private String[] _desc; private String[] _desc;

View File

@ -213,7 +213,11 @@ public enum AchievementCategory
StatDisplay.fromGame("Wins", GameDisplay.SkyfallTeams, "Wins"), StatDisplay.fromGame("Games Played", GameDisplay.SkyfallTeams, "Wins", "Losses"), StatDisplay.fromGame("Wins", GameDisplay.SkyfallTeams, "Wins"), StatDisplay.fromGame("Games Played", GameDisplay.SkyfallTeams, "Wins", "Losses"),
StatDisplay.fromGame("Kills", GameDisplay.SkyfallTeams, "Kills"), StatDisplay.fromGame("Deaths", GameDisplay.SkyfallTeams, "Deaths"), StatDisplay.fromGame("Kills", GameDisplay.SkyfallTeams, "Kills"), StatDisplay.fromGame("Deaths", GameDisplay.SkyfallTeams, "Deaths"),
StatDisplay.fromGame("Gems Earned", GameDisplay.SkyfallTeams, "GemsEarned"), null, StatDisplay.fromGame("Booster Rings", GameDisplay.SkyfallTeams, "Rings")}, StatDisplay.fromGame("Gems Earned", GameDisplay.SkyfallTeams, "GemsEarned"), null, StatDisplay.fromGame("Booster Rings", GameDisplay.SkyfallTeams, "Rings")},
Material.DIAMOND_BOOTS, 0, GameCategory.SURVIVAL, null, false, GameDisplay.Skyfall.getGameId(), GameDisplay.SkyfallTeams.getGameId()); Material.DIAMOND_BOOTS, 0, GameCategory.SURVIVAL, null, false, GameDisplay.Skyfall.getGameId(), GameDisplay.SkyfallTeams.getGameId()),
GEM_HUNTERS("Gem Hunters", null,
new StatDisplay[] {StatDisplay.KILLS, StatDisplay.GEMS_EARNED, StatDisplay.fromGame("Quests Completed", GameDisplay.GemHunters, "QuestsCompleted"), StatDisplay.fromGame("Chests Opened", GameDisplay.GemHunters, "ChestsOpened")},
Material.EMERALD, 0, GameCategory.SURVIVAL, null, false, GameDisplay.GemHunters.getGameId());
private String _name; private String _name;
private String[] _statsToPull; private String[] _statsToPull;

View File

@ -5,11 +5,9 @@ import java.time.YearMonth;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
import mineplex.core.common.util.LineFormat; import mineplex.core.common.util.LineFormat;
@ -21,12 +19,16 @@ import mineplex.core.hologram.Hologram;
import mineplex.core.hologram.HologramManager; import mineplex.core.hologram.HologramManager;
import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.recharge.Recharge; import mineplex.core.recharge.Recharge;
import mineplex.core.treasure.event.TreasureFinishEvent;
import mineplex.core.treasure.event.TreasureStartEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
@ -48,17 +50,14 @@ import mineplex.core.utils.UtilGameProfile;
*/ */
public class MorphBobRoss extends MorphGadget public class MorphBobRoss extends MorphGadget
{ {
/** Radius within which painting is not allowed near treasure chests */
private static final int TREASURE_RADIUS = 4;
/** The inventory slot in which the paint brush is placed */ /** The inventory slot in which the paint brush is placed */
private static final int PAINT_BRUSH_SLOT = 2; private static final int PAINT_BRUSH_SLOT = 2;
/** Max # of blocks that can be destroyed every quarter second, per player */ /** The # of milliseconds for which paint blocks exist */
private static final int DESTROY_LIMIT = 4; private static final long PAINT_MILLISECONDS = 30000;
/** The # of seconds for which paint blocks exist */
private static final int PAINT_SECONDS = 30;
/** The # of minutes after which the code will stop trying to remove paint */
private static final int PAINT_EXPIRE = 10;
/** Height above a player's location at which quotes are to be displayed */ /** Height above a player's location at which quotes are to be displayed */
private static final double QUOTE_HEIGHT = 2.25; private static final double QUOTE_HEIGHT = 2.25;
@ -196,10 +195,11 @@ public class MorphBobRoss extends MorphGadget
/** Map of items in players' inventories */ /** Map of items in players' inventories */
private final Map<UUID, ItemStack> _inventoryItems = new HashMap<>(); private final Map<UUID, ItemStack> _inventoryItems = new HashMap<>();
private final Map<UUID, Integer> _paintColors = new HashMap<>(); /** Colors that are being used by painting players */
private final Map<UUID, Byte> _paintColors = new HashMap<>();
/** Blocks that have been painted */ /** Locations at which treasure is currently being opened */
private final List<PaintedBlock> _paintBlocks = new ArrayList<>(); private final Map<UUID, Location> _openingTreasure = new HashMap<>();
private final HologramManager _holograms; private final HologramManager _holograms;
@ -277,6 +277,7 @@ public class MorphBobRoss extends MorphGadget
{ {
if (Recharge.Instance.use(event.getPlayer(), COLOR_KEY, COLOR_COOLDOWN, false, false)) if (Recharge.Instance.use(event.getPlayer(), COLOR_KEY, COLOR_COOLDOWN, false, false))
{ {
changePaintColor(event.getPlayer(), true); changePaintColor(event.getPlayer(), true);
} }
} }
@ -284,6 +285,7 @@ public class MorphBobRoss extends MorphGadget
{ {
if (Recharge.Instance.use(event.getPlayer(), COLOR_KEY, COLOR_COOLDOWN, false, false)) if (Recharge.Instance.use(event.getPlayer(), COLOR_KEY, COLOR_COOLDOWN, false, false))
{ {
changePaintColor(event.getPlayer(), false); changePaintColor(event.getPlayer(), false);
} }
} }
@ -296,40 +298,7 @@ public class MorphBobRoss extends MorphGadget
@EventHandler @EventHandler
public void updateEvent(UpdateEvent event) public void updateEvent(UpdateEvent event)
{ {
if (event.getType() == UpdateType.FASTER) // do paint removal if (event.getType() == UpdateType.TICK) // do quote displaying
{
int limit = 0;
int offset = 0;
// destroy paint blocks that are too old
while (!_paintBlocks.isEmpty()
&& offset < _paintBlocks.size()
&& _paintBlocks.get(offset).time < System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(PAINT_SECONDS)
&& limit < DESTROY_LIMIT * getActive().size())
{
Block block = _paintBlocks.get(offset).block;
if (block.getType() == Material.CARPET)
{
_paintBlocks.remove(offset);
block.setType(Material.AIR);
limit++;
}
else
{
// stop trying to remove paint after a certain amount of time
if (_paintBlocks.get(offset).time > System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(PAINT_EXPIRE))
{
_paintBlocks.remove(offset);
}
else
{
offset++;
}
}
}
}
else if (event.getType() == UpdateType.TICK) // do quote displaying
{ {
for (Player player : getActive()) for (Player player : getActive())
{ {
@ -377,10 +346,12 @@ public class MorphBobRoss extends MorphGadget
if (item.getType() == Material.STICK && player.getItemInHand().equals(item)) if (item.getType() == Material.STICK && player.getItemInHand().equals(item))
{ {
togglePainting(player); togglePainting(player);
} }
else if (!player.getItemInHand().equals(item) && item.getType() != Material.STICK) else if (!player.getItemInHand().equals(item) && item.getType() != Material.STICK)
{ {
togglePainting(player); togglePainting(player);
} }
} }
@ -401,6 +372,14 @@ public class MorphBobRoss extends MorphGadget
return; return;
} }
for (Location location : _openingTreasure.values())
{
if (location.toVector().isInSphere(event.getPlayer().getLocation().toVector(), TREASURE_RADIUS))
{
return;
}
}
// check if the player has been issued a paintbrush // check if the player has been issued a paintbrush
if (_inventoryItems.containsKey(player.getUniqueId())) if (_inventoryItems.containsKey(player.getUniqueId()))
{ {
@ -419,28 +398,15 @@ public class MorphBobRoss extends MorphGadget
// check that there is room to paint and that the block below is solid and not more paint. // check that there is room to paint and that the block below is solid and not more paint.
if ((block.isEmpty() || carpet) && UtilBlock.fullSolid(down) && !UtilBlock.bottomSlab(down)) if ((block.isEmpty() || carpet) && UtilBlock.fullSolid(down) && !UtilBlock.bottomSlab(down))
{ {
int index; // if the block is a non-paint carpet
PaintedBlock blk = new PaintedBlock(block); if (carpet && !Manager.getBlockRestore().contains(block))
if (carpet) // if block is a carpet
{
// remove old paint if it was painted
if ((index = _paintBlocks.indexOf(blk)) != -1)
{
_paintBlocks.remove(index);
}
else // if it's non-paint carpet
{ {
return; // don't paint return; // don't paint
} }
}
// mark block as painted // mark block as painted
_paintBlocks.add(blk); Manager.getBlockRestore().add(block, Material.CARPET.getId(), (byte) (15 - item.getData().getData()),
block.getTypeId(), block.getData(), PAINT_MILLISECONDS);
// actually paint block
block.setType(Material.CARPET);
block.setData((byte) (15 - item.getData().getData()));
} }
} }
} }
@ -456,6 +422,7 @@ public class MorphBobRoss extends MorphGadget
UUID uuid = event.getPlayer().getUniqueId(); UUID uuid = event.getPlayer().getUniqueId();
_inventoryItems.remove(uuid); _inventoryItems.remove(uuid);
_paintColors.remove(uuid); _paintColors.remove(uuid);
} }
} }
@ -466,6 +433,7 @@ public class MorphBobRoss extends MorphGadget
*/ */
private void changePaintColor(Player player, boolean reverse) private void changePaintColor(Player player, boolean reverse)
{ {
ItemStack item = _inventoryItems.remove(player.getUniqueId()); ItemStack item = _inventoryItems.remove(player.getUniqueId());
byte data = selectPaintColor(player, reverse); byte data = selectPaintColor(player, reverse);
@ -483,22 +451,27 @@ public class MorphBobRoss extends MorphGadget
*/ */
private void togglePainting(Player player) private void togglePainting(Player player)
{ {
ItemStack item = _inventoryItems.remove(player.getUniqueId()); ItemStack item = _inventoryItems.remove(player.getUniqueId());
ItemStack newItem; ItemStack newItem;
if (item.getType() == Material.STICK) if (item.getType() == Material.STICK)
{ {
byte data = selectPaintColor(player, false); byte data;
if (!_paintColors.containsKey(player.getUniqueId()))
{
data = selectPaintColor(player, false);
}
else
{
data = COLOR_ORDER[_paintColors.get(player.getUniqueId())];
}
newItem = ItemStackFactory.Instance.CreateStack(Material.INK_SACK, data, 1, newItem = ItemStackFactory.Instance.CreateStack(Material.INK_SACK, data, 1,
PAINT_COLORS[data] + " " + PAINT_BRUSHES[ThreadLocalRandom.current().nextInt(0, PAINT_BRUSHES.length)]); PAINT_COLORS[data] + " " + PAINT_BRUSHES[ThreadLocalRandom.current().nextInt(0, PAINT_BRUSHES.length)]);
} }
else else
{ {
if (_paintColors.containsKey(player.getUniqueId()))
{
_paintColors.remove(player.getUniqueId());
}
newItem = ItemStackFactory.Instance.CreateStack(Material.STICK, (byte) 0, 1, BRUSH_NAME); newItem = ItemStackFactory.Instance.CreateStack(Material.STICK, (byte) 0, 1, BRUSH_NAME);
} }
@ -521,11 +494,11 @@ public class MorphBobRoss extends MorphGadget
{ {
UUID uuid = player.getUniqueId(); UUID uuid = player.getUniqueId();
int value; byte value;
if (!_paintColors.containsKey(uuid)) if (!_paintColors.containsKey(uuid))
{ {
value = ThreadLocalRandom.current().nextInt(0, 16); value = (byte) ThreadLocalRandom.current().nextInt(0, 16);
_paintColors.put(uuid, value); _paintColors.put(uuid, value);
} }
else else
@ -588,43 +561,24 @@ public class MorphBobRoss extends MorphGadget
} }
/** /**
* Data class holding information on blocks which have been painted * Disable painting in the area around treasure being opened.
*/ */
private class PaintedBlock @EventHandler(priority = EventPriority.LOW)
public void disableOnTreasureStart(TreasureStartEvent event)
{ {
/** The time at which the block was painted */ _openingTreasure.put(event.getPlayer().getUniqueId(), event.getPlayer().getLocation());
long time; Manager.getBlockRestore().restoreBlockAround(Material.CARPET, event.getPlayer().getLocation(), TREASURE_RADIUS);
/** The block which was painted */
Block block;
/**
* Construct a PaintedBlock
*
* @param block The block which has been painted.
*/
public PaintedBlock(Block block)
{
this.block = block;
this.time = System.currentTimeMillis();
} }
/** /**
* Overrides default equals behavior to have comparisons between * Enable painting in the area around treasure no longer being opened.
* multiple {@link PaintedBlock} objects match comparisons between
* their contained {@link PaintedBlock#block} fields.
*/ */
@Override @EventHandler(priority = EventPriority.HIGH)
public boolean equals(Object o) public void enableOnTreasureFinish(TreasureFinishEvent event)
{ {
if (o instanceof PaintedBlock) if (_openingTreasure.containsKey(event.getPlayer().getUniqueId()))
{ {
return block.equals(((PaintedBlock) o).block); _openingTreasure.remove(event.getPlayer().getUniqueId());
}
else
{
return super.equals(o);
}
} }
} }
} }

View File

@ -106,6 +106,8 @@ public enum GameDisplay
MOBA("Heroes of the Craft", Material.SKULL_ITEM, (byte)1, GameCategory.CLASSICS, 70, true), MOBA("Heroes of the Craft", Material.SKULL_ITEM, (byte)1, GameCategory.CLASSICS, 70, true),
GemHunters("Gem Hunters", Material.EMERALD, (byte) 0, GameCategory.SURVIVAL, 71, false),
Event("Mineplex Event", Material.CAKE, (byte)0, GameCategory.EVENT, 999, false), Event("Mineplex Event", Material.CAKE, (byte)0, GameCategory.EVENT, 999, false),
Brawl("Brawl", Material.DIAMOND, (byte) 0, GameCategory.EVENT, 998, false); Brawl("Brawl", Material.DIAMOND, (byte) 0, GameCategory.EVENT, 998, false);

View File

@ -78,7 +78,7 @@ public class Track implements Listener
return this._trackRequirements; return this._trackRequirements;
} }
public final String getStatName() public String getStatName()
{ {
return "track." + _id; return "track." + _id;
} }

View File

@ -9,6 +9,7 @@ import java.util.function.Consumer;
import mineplex.core.titles.tracks.award.AlienInvasionTrack; import mineplex.core.titles.tracks.award.AlienInvasionTrack;
import mineplex.core.titles.tracks.award.AprilFools2017Track; import mineplex.core.titles.tracks.award.AprilFools2017Track;
import mineplex.core.titles.tracks.standard.GemHuntersTrack;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -79,6 +80,7 @@ public class TrackManager extends MiniPlugin
// registerTrack(new SurvivorTrack()); // registerTrack(new SurvivorTrack());
registerTrack(new LevelerTrack()); registerTrack(new LevelerTrack());
registerTrack(new PerfectionistTrack()); registerTrack(new PerfectionistTrack());
registerTrack(new GemHuntersTrack());
// Awarded tracks // Awarded tracks
registerTrack(new Bridges2017Track()); registerTrack(new Bridges2017Track());

View File

@ -0,0 +1,71 @@
package mineplex.core.titles.tracks.standard;
import mineplex.core.titles.tracks.Track;
import mineplex.core.titles.tracks.TrackFormat;
import mineplex.core.titles.tracks.TrackTier;
import net.md_5.bungee.api.ChatColor;
public class GemHuntersTrack extends Track
{
public GemHuntersTrack()
{
super("gem-hunters-gems", "GH Millionaire", "This track is unlocked by earning gems in Gem Hunters");
getRequirements()
.addTier(new TrackTier(
"Beggar",
"Gain 1,000 Gems in Gem Hunters",
this::getStat,
1000,
new TrackFormat(ChatColor.GRAY)
))
.addTier(new TrackTier(
"Poor",
"Gain 5,000 Gems in Gem Hunters",
this::getStat,
5000,
new TrackFormat(ChatColor.AQUA)
))
.addTier(new TrackTier(
"Middle Class",
"Gain 7,500 Gems in Gem Hunters",
this::getStat,
7500,
new TrackFormat(ChatColor.GREEN)
))
.addTier(new TrackTier(
"Wealthy",
"Gain 10,000 Gems in Gem Hunters",
this::getStat,
10000,
new TrackFormat(ChatColor.DARK_GREEN)
))
.addTier(new TrackTier(
"Loaded",
"Gain 25,000 Gems in Gem Hunters",
this::getStat,
25000,
new TrackFormat(ChatColor.GOLD)
))
.addTier(new TrackTier(
"Millionaire",
"Gain 50,000 Gems in Gem Hunters",
this::getStat,
50000,
new TrackFormat(ChatColor.GOLD, ChatColor.YELLOW)
));
getRequirements()
.withRequirement(1, "Gem Earned in Gem Hunters");
}
/**
* Overriding this means we can hit two birds with one stat.
*/
@Override
public String getStatName()
{
return "Gem Hunters.GemsEarned";
}
}

View File

@ -176,22 +176,21 @@ public class TreasureLocation implements Listener
Treasure treasure = new Treasure(_treasureManager, player, rewards, treasureType.getRewardType(), _chestBlock, _chestSpawns, treasureType, _treasureManager.getBlockRestore(), _hologramManager, _statusManager); Treasure treasure = new Treasure(_treasureManager, player, rewards, treasureType.getRewardType(), _chestBlock, _chestSpawns, treasureType, _treasureManager.getBlockRestore(), _hologramManager, _statusManager);
_currentTreasure = treasure; _currentTreasure = treasure;
TreasureStartEvent startEvent = new TreasureStartEvent(player, treasure, Arrays.asList(rewards));
UtilServer.CallEvent(startEvent);
UtilTextMiddle.display(treasureType.getName(), "Choose " + rewards.length + " " + UtilText.plural("Chest", rewards.length) + " To Open", 20, 180, 20, player);
UtilPlayer.message(player, F.main("Treasure", "Choose " + rewards.length + " " + UtilText.plural("Chest", rewards.length) + " To Open"));
Location teleportLocation = treasure.getCenterBlock().getLocation().add(0.5, 0, 0.5);
teleportLocation.setPitch(player.getLocation().getPitch());
teleportLocation.setYaw(player.getLocation().getYaw());
for (Entity entity : player.getNearbyEntities(3, 3, 3)) for (Entity entity : player.getNearbyEntities(3, 3, 3))
{ {
UtilAction.velocity(entity, UtilAlg.getTrajectory(entity.getLocation(), treasure.getCenterBlock().getLocation()).multiply(-1), 1.5, true, 0.8, 0, 1.0, true); UtilAction.velocity(entity, UtilAlg.getTrajectory(entity.getLocation(), treasure.getCenterBlock().getLocation()).multiply(-1), 1.5, true, 0.8, 0, 1.0, true);
} }
Location teleportLocation = treasure.getCenterBlock().getLocation().add(0.5, 0, 0.5);
teleportLocation.setPitch(player.getLocation().getPitch());
teleportLocation.setYaw(player.getLocation().getYaw());
player.teleport(teleportLocation); player.teleport(teleportLocation);
TreasureStartEvent startEvent = new TreasureStartEvent(player, treasure, Arrays.asList(rewards));
UtilServer.CallEvent(startEvent);
UtilTextMiddle.display(treasureType.getName(), "Choose " + rewards.length + " " + UtilText.plural("Chest", rewards.length) + " To Open", 20, 180, 20, player);
UtilPlayer.message(player, F.main("Treasure", "Choose " + rewards.length + " " + UtilText.plural("Chest", rewards.length) + " To Open"));
_treasureManager.addOpenStat(player, treasureType); _treasureManager.addOpenStat(player, treasureType);
} }

View File

@ -1,13 +1,5 @@
package mineplex.gemhunters; package mineplex.gemhunters;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.plugin.java.JavaPlugin;
import org.spigotmc.SpigotConfig;
import mineplex.core.CustomTagFix; import mineplex.core.CustomTagFix;
import mineplex.core.FoodDupeFix; import mineplex.core.FoodDupeFix;
import mineplex.core.TimingsFix; import mineplex.core.TimingsFix;
@ -65,6 +57,7 @@ import mineplex.core.task.TaskManager;
import mineplex.core.teleport.Teleport; import mineplex.core.teleport.Teleport;
import mineplex.core.texttutorial.TextTutorialManager; import mineplex.core.texttutorial.TextTutorialManager;
import mineplex.core.thank.ThankManager; import mineplex.core.thank.ThankManager;
import mineplex.core.titles.Titles;
import mineplex.core.twofactor.TwoFactorAuth; import mineplex.core.twofactor.TwoFactorAuth;
import mineplex.core.updater.FileUpdater; import mineplex.core.updater.FileUpdater;
import mineplex.core.updater.Updater; import mineplex.core.updater.Updater;
@ -92,6 +85,7 @@ import mineplex.gemhunters.spawn.SpawnModule;
import mineplex.gemhunters.supplydrop.SupplyDropModule; import mineplex.gemhunters.supplydrop.SupplyDropModule;
import mineplex.gemhunters.tutorial.GemHuntersTutorial; import mineplex.gemhunters.tutorial.GemHuntersTutorial;
import mineplex.gemhunters.world.DebugListeners; import mineplex.gemhunters.world.DebugListeners;
import mineplex.gemhunters.world.Leaderboards;
import mineplex.gemhunters.world.TimeCycle; import mineplex.gemhunters.world.TimeCycle;
import mineplex.gemhunters.world.UndergroundMobs; import mineplex.gemhunters.world.UndergroundMobs;
import mineplex.gemhunters.world.WorldListeners; import mineplex.gemhunters.world.WorldListeners;
@ -99,6 +93,12 @@ import mineplex.gemhunters.worldevent.WorldEventModule;
import mineplex.minecraft.game.core.combat.CombatManager; import mineplex.minecraft.game.core.combat.CombatManager;
import mineplex.minecraft.game.core.condition.ConditionManager; import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.DamageManager; import mineplex.minecraft.game.core.damage.DamageManager;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.plugin.java.JavaPlugin;
import org.spigotmc.SpigotConfig;
import static mineplex.core.Managers.require; import static mineplex.core.Managers.require;
@ -186,6 +186,7 @@ public class GemHunters extends JavaPlugin
// Creatures // Creatures
Creature creature = new Creature(this); Creature creature = new Creature(this);
creature.SetDisableCustomDrops(true);
// The old classic Damage Manager // The old classic Damage Manager
DamageManager damageManager = new DamageManager(this, new CombatManager(this), new NpcManager(this, creature), disguiseManager, new ConditionManager(this)); DamageManager damageManager = new DamageManager(this, new CombatManager(this), new NpcManager(this, creature), disguiseManager, new ConditionManager(this));
@ -270,6 +271,8 @@ public class GemHunters extends JavaPlugin
TextTutorialManager tutorialManager = new TextTutorialManager(this, donationManager, new TaskManager(this, clientManager)); TextTutorialManager tutorialManager = new TextTutorialManager(this, donationManager, new TaskManager(this, clientManager));
tutorialManager.addTutorial(new GemHuntersTutorial()); tutorialManager.addTutorial(new GemHuntersTutorial());
require(Titles.class).forceDisable();
// Now we finally get to enable the Gem Hunters modules // Now we finally get to enable the Gem Hunters modules
// Though if any other module needs one of these it will be generated in // Though if any other module needs one of these it will be generated in
// order, however they are all here just for good measure. // order, however they are all here just for good measure.
@ -302,6 +305,7 @@ public class GemHunters extends JavaPlugin
new TimeCycle(this); new TimeCycle(this);
new UndergroundMobs(this); new UndergroundMobs(this);
new DebugListeners(this); new DebugListeners(this);
new Leaderboards();
// UpdateEvent!!! // UpdateEvent!!!
new Updater(this); new Updater(this);

View File

@ -19,7 +19,8 @@ public class BetaModule extends MiniPlugin
"Thank you for playing Gem Hunters!", "Thank you for playing Gem Hunters!",
"Safezones are marked as green areas on your map!", "Safezones are marked as green areas on your map!",
"Players that have super valuable items show up on your map!", "Players that have super valuable items show up on your map!",
"Tell us what you want added next by voting on our features Trello! https://trello.com/b/ia1kjwcx" "Tell us what you want added next by voting on our features Trello! https://trello.com/b/ia1kjwcx",
"The highest value player is shown on the map as a red pointer."
}; };
private int _lastIndex; private int _lastIndex;
@ -30,7 +31,7 @@ public class BetaModule extends MiniPlugin
} }
@EventHandler @EventHandler
public void annouce(UpdateEvent event) public void announce(UpdateEvent event)
{ {
if (event.getType() != UpdateType.MIN_01) if (event.getType() != UpdateType.MIN_01)
{ {

View File

@ -1,5 +1,7 @@
package mineplex.gemhunters.chat; package mineplex.gemhunters.chat;
import mineplex.gemhunters.economy.EconomyModule;
import mineplex.gemhunters.progression.ProgressionModule;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -26,7 +28,9 @@ public class ChatModule extends MiniPlugin
private final CoreClientManager _clientManager; private final CoreClientManager _clientManager;
private final Chat _chat; private final Chat _chat;
private final EconomyModule _economy;
private final PartyManager _party; private final PartyManager _party;
private final ProgressionModule _progression;
private ChatModule() private ChatModule()
{ {
@ -34,7 +38,9 @@ public class ChatModule extends MiniPlugin
_clientManager = require(CoreClientManager.class); _clientManager = require(CoreClientManager.class);
_chat = require(Chat.class); _chat = require(Chat.class);
_economy = require(EconomyModule.class);
_party = require(PartyManager.class); _party = require(PartyManager.class);
_progression = require(ProgressionModule.class);
} }
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
@ -90,7 +96,7 @@ public class ChatModule extends MiniPlugin
} }
else else
{ {
message += C.cWhite; message = _progression.getTitle(_economy.getGems(player)).getTitle() + " " + message + C.cWhite;
} }
message += _chat.getFilteredMessage(player, event.getMessage()); message += _chat.getFilteredMessage(player, event.getMessage());

View File

@ -1,11 +1,20 @@
package mineplex.gemhunters.death; package mineplex.gemhunters.death;
import java.util.HashMap; import com.google.common.collect.Sets;
import java.util.Iterator; import mineplex.core.MiniPlugin;
import java.util.Map; import mineplex.core.ReflectivelyCreateMiniPlugin;
import java.util.Set; import mineplex.core.common.util.C;
import java.util.UUID; 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.stats.StatsManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent;
import mineplex.gemhunters.playerstatus.PlayerStatusModule;
import mineplex.gemhunters.playerstatus.PlayerStatusType;
import mineplex.gemhunters.spawn.SpawnModule;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
@ -13,7 +22,6 @@ import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
@ -22,25 +30,14 @@ import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerPickupItemEvent; import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import com.google.common.collect.Sets; import java.util.HashMap;
import java.util.Iterator;
import mineplex.core.MiniPlugin; import java.util.Map;
import mineplex.core.ReflectivelyCreateMiniPlugin; import java.util.Set;
import mineplex.core.common.util.C; import java.util.UUID;
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.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent;
import mineplex.gemhunters.playerstatus.PlayerStatusModule;
import mineplex.gemhunters.playerstatus.PlayerStatusType;
import mineplex.gemhunters.spawn.SpawnModule;
/** /**
* This module handles anything to do with a players death * This module handles anything to do with a players death
@ -56,6 +53,7 @@ public class DeathModule extends MiniPlugin
private static final int DEATH_ANIMATION_COUNTDOWN = 2000; private static final int DEATH_ANIMATION_COUNTDOWN = 2000;
private final PlayerStatusModule _playerStatus; private final PlayerStatusModule _playerStatus;
private final StatsManager _stats;
private final SpawnModule _spawn; private final SpawnModule _spawn;
private final Map<UUID, Long> _toRemove; private final Map<UUID, Long> _toRemove;
@ -65,6 +63,7 @@ public class DeathModule extends MiniPlugin
super("Death"); super("Death");
_playerStatus = require(PlayerStatusModule.class); _playerStatus = require(PlayerStatusModule.class);
_stats = require(StatsManager.class);
_spawn = require(SpawnModule.class); _spawn = require(SpawnModule.class);
_toRemove = new HashMap<>(); _toRemove = new HashMap<>();
@ -80,6 +79,14 @@ public class DeathModule extends MiniPlugin
player.setFoodLevel(20); player.setFoodLevel(20);
player.setExhaustion(0); player.setExhaustion(0);
// Record the stats
Player killer = player.getKiller();
if (killer != null)
{
_stats.incrementStat(killer, "Gem Hunters.Kills", 1);
}
startAnimation(player); startAnimation(player);
_toRemove.put(player.getUniqueId(), System.currentTimeMillis()); _toRemove.put(player.getUniqueId(), System.currentTimeMillis());
} }

View File

@ -3,14 +3,20 @@ package mineplex.gemhunters.economy;
import mineplex.core.MiniPlugin; import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin; import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.currency.GlobalCurrency; import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.*; import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilEvent.ActionType; import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.donation.DonationManager; import mineplex.core.donation.DonationManager;
import mineplex.core.itemstack.ItemBuilder; import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.portal.GenericServer; import mineplex.core.portal.GenericServer;
import mineplex.core.portal.Intent; import mineplex.core.portal.Intent;
import mineplex.core.portal.Portal; import mineplex.core.portal.Portal;
import mineplex.core.recharge.Recharge; import mineplex.core.recharge.Recharge;
import mineplex.core.stats.StatsManager;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.economy.command.CashOutItemCommand; import mineplex.gemhunters.economy.command.CashOutItemCommand;
@ -30,7 +36,12 @@ import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.*; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@ReflectivelyCreateMiniPlugin @ReflectivelyCreateMiniPlugin
public class CashOutModule extends MiniPlugin public class CashOutModule extends MiniPlugin
@ -44,6 +55,7 @@ public class CashOutModule extends MiniPlugin
private static final int CASH_OUT_MAX_MOVE_DISTANCE_SQUARED = 4; private static final int CASH_OUT_MAX_MOVE_DISTANCE_SQUARED = 4;
private final DonationManager _donation; private final DonationManager _donation;
private final StatsManager _stats;
private final Map<UUID, CashOutSession> _sessions; private final Map<UUID, CashOutSession> _sessions;
private final Set<UUID> _aboutToCashOut; private final Set<UUID> _aboutToCashOut;
@ -53,6 +65,7 @@ public class CashOutModule extends MiniPlugin
super("Cash Out"); super("Cash Out");
_donation = require(DonationManager.class); _donation = require(DonationManager.class);
_stats = require(StatsManager.class);
_sessions = new HashMap<>(); _sessions = new HashMap<>();
_aboutToCashOut = new HashSet<>(); _aboutToCashOut = new HashSet<>();
@ -147,6 +160,11 @@ public class CashOutModule extends MiniPlugin
_aboutToCashOut.add(player.getUniqueId()); _aboutToCashOut.add(player.getUniqueId());
if (completeEvent.getGems() != EconomyModule.GEM_START_COST)
{
_stats.incrementStat(player, "Gem Hunters.GemsEarned", completeEvent.getGems());
}
_donation.rewardCurrencyUntilSuccess(GlobalCurrency.GEM, player, "Earned", completeEvent.getGems()); _donation.rewardCurrencyUntilSuccess(GlobalCurrency.GEM, player, "Earned", completeEvent.getGems());
session.endSession(); session.endSession();

View File

@ -1,12 +1,5 @@
package mineplex.gemhunters.economy; package mineplex.gemhunters.economy;
import java.util.UUID;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.PlayerDeathEvent;
import mineplex.core.MiniClientPlugin; import mineplex.core.MiniClientPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin; import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.currency.GlobalCurrency; import mineplex.core.common.currency.GlobalCurrency;
@ -14,11 +7,16 @@ import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilServer;
import mineplex.core.donation.DonationManager; import mineplex.core.donation.DonationManager;
import mineplex.core.donation.Donor; import mineplex.core.donation.Donor;
import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent;
import mineplex.gemhunters.economy.command.GiveGemsCommand; import mineplex.gemhunters.economy.command.GiveGemsCommand;
import mineplex.gemhunters.economy.event.PlayerCashOutCompleteEvent; import mineplex.gemhunters.economy.event.PlayerCashOutCompleteEvent;
import mineplex.gemhunters.economy.event.PlayerEarnGemsEvent; import mineplex.gemhunters.economy.event.PlayerEarnGemsEvent;
import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent; import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.PlayerDeathEvent;
import java.util.UUID;
@ReflectivelyCreateMiniPlugin @ReflectivelyCreateMiniPlugin
public class EconomyModule extends MiniClientPlugin<Integer> public class EconomyModule extends MiniClientPlugin<Integer>
@ -29,6 +27,9 @@ public class EconomyModule extends MiniClientPlugin<Integer>
private final DonationManager _donation; private final DonationManager _donation;
private Player _mostValuable;
private int _mostGems;
public EconomyModule() public EconomyModule()
{ {
super("Economy"); super("Economy");
@ -117,6 +118,23 @@ public class EconomyModule extends MiniClientPlugin<Integer>
return Get(player); return Get(player);
} }
@Override
protected void Set(Player player, Integer data)
{
super.Set(player, data);
if (_mostValuable == null || _mostGems < data)
{
_mostValuable = player;
_mostGems = data;
}
}
public Player getMostValuablePlayer()
{
return _mostValuable;
}
@Override @Override
protected Integer addPlayer(UUID uuid) protected Integer addPlayer(UUID uuid)
{ {

View File

@ -2,9 +2,16 @@ package mineplex.gemhunters.loot;
import mineplex.core.MiniPlugin; import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin; import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.*; import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilEvent.ActionType; import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilInv;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.google.GoogleSheetsManager; import mineplex.core.google.GoogleSheetsManager;
import mineplex.core.stats.StatsManager;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.economy.EconomyModule; import mineplex.gemhunters.economy.EconomyModule;
@ -14,7 +21,11 @@ import mineplex.gemhunters.loot.command.UpdateLootCommand;
import mineplex.gemhunters.loot.deserialisers.ChestPropertiesDeserialiser; import mineplex.gemhunters.loot.deserialisers.ChestPropertiesDeserialiser;
import mineplex.gemhunters.loot.deserialisers.LootItemDeserialiser; import mineplex.gemhunters.loot.deserialisers.LootItemDeserialiser;
import mineplex.gemhunters.loot.event.PlayerChestOpenEvent; import mineplex.gemhunters.loot.event.PlayerChestOpenEvent;
import mineplex.gemhunters.loot.rewards.*; import mineplex.gemhunters.loot.rewards.LootChestReward;
import mineplex.gemhunters.loot.rewards.LootGadgetReward;
import mineplex.gemhunters.loot.rewards.LootItemReward;
import mineplex.gemhunters.loot.rewards.LootRankReward;
import mineplex.gemhunters.loot.rewards.LootShardReward;
import mineplex.gemhunters.safezone.SafezoneModule; import mineplex.gemhunters.safezone.SafezoneModule;
import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent; import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent;
import mineplex.gemhunters.world.WorldDataModule; import mineplex.gemhunters.world.WorldDataModule;
@ -26,8 +37,14 @@ import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.block.Chest; import org.bukkit.block.Chest;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
<<<<<<< HEAD
=======
import org.bukkit.event.EventPriority;
>>>>>>> refs/remotes/origin/develop
import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
@ -35,7 +52,13 @@ import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.util.*; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ReflectivelyCreateMiniPlugin @ReflectivelyCreateMiniPlugin
@ -59,6 +82,7 @@ public class LootModule extends MiniPlugin
private final EconomyModule _economy; private final EconomyModule _economy;
private final GoogleSheetsManager _sheets; private final GoogleSheetsManager _sheets;
private final SafezoneModule _safezone; private final SafezoneModule _safezone;
private final StatsManager _stats;
private final WorldDataModule _worldData; private final WorldDataModule _worldData;
private final Map<String, Set<LootItem>> _chestLoot; private final Map<String, Set<LootItem>> _chestLoot;
@ -74,6 +98,7 @@ public class LootModule extends MiniPlugin
_economy = require(EconomyModule.class); _economy = require(EconomyModule.class);
_sheets = require(GoogleSheetsManager.class); _sheets = require(GoogleSheetsManager.class);
_safezone = require(SafezoneModule.class); _safezone = require(SafezoneModule.class);
_stats = require(StatsManager.class);
_worldData = require(WorldDataModule.class); _worldData = require(WorldDataModule.class);
_chestLoot = new HashMap<>(); _chestLoot = new HashMap<>();
_chestProperties = new HashMap<>(); _chestProperties = new HashMap<>();
@ -455,6 +480,7 @@ public class LootModule extends MiniPlugin
return; return;
} }
_stats.incrementStat(player, "Gem Hunters.ChestsOpened", 1);
fillChest(player, block, key); fillChest(player, block, key);
} }
@ -476,10 +502,10 @@ public class LootModule extends MiniPlugin
handleRewardItem((Player) event.getWhoClicked(), itemStack); handleRewardItem((Player) event.getWhoClicked(), itemStack);
} }
@EventHandler @EventHandler(priority = EventPriority.HIGH)
public void pickupItem(PlayerPickupItemEvent event) public void pickupItem(PlayerPickupItemEvent event)
{ {
if (event.getItem() == null) if (event.getItem() == null || event.isCancelled())
{ {
return; return;
} }
@ -623,10 +649,35 @@ public class LootModule extends MiniPlugin
{ {
LootItemReward reward = iterator.next(); LootItemReward reward = iterator.next();
if (player.equals(reward.getPlayer()) && player.getInventory().contains(reward.getItemStack())) if (reward.getPlayer() != null && player.equals(reward.getPlayer()))
{ {
reward.success(); reward.success();
iterator.remove(); iterator.remove();
for (Entity entity : reward.getPlayer().getWorld().getEntities())
{
if (entity instanceof Item)
{
Item item = (Item) entity;
if (item.getItemStack().getType() == reward.getItemStack().getType())
{
entity.remove();
}
}
}
}
}
}
@EventHandler
public void playerDeath(PlayerDeathEvent event)
{
for (LootItemReward reward : _itemRewards)
{
if (reward.getPlayer().equals(event.getEntity()))
{
reward.death(event);
} }
} }
} }

View File

@ -38,7 +38,7 @@ public abstract class LootItemReward
public final void collectItem(Player player) public final void collectItem(Player player)
{ {
if (player.equals(_player)) if (_player != null && player.equals(_player))
{ {
return; return;
} }
@ -73,6 +73,7 @@ public abstract class LootItemReward
public final void death(PlayerDeathEvent event) public final void death(PlayerDeathEvent event)
{ {
_player = null;
} }
public boolean isFirstPickup() public boolean isFirstPickup()

View File

@ -1,29 +1,24 @@
package mineplex.gemhunters.map; package mineplex.gemhunters.map;
import java.awt.Color;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapCursorCollection;
import org.bukkit.map.MapPalette;
import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView;
import mineplex.core.Managers; import mineplex.core.Managers;
import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime;
import mineplex.core.party.Party; import mineplex.core.party.Party;
import mineplex.core.party.PartyManager; import mineplex.core.party.PartyManager;
import mineplex.gemhunters.economy.EconomyModule;
import mineplex.gemhunters.loot.LootModule; import mineplex.gemhunters.loot.LootModule;
import mineplex.gemhunters.safezone.SafezoneModule; import mineplex.gemhunters.safezone.SafezoneModule;
import mineplex.gemhunters.supplydrop.SupplyDrop; import mineplex.gemhunters.supplydrop.SupplyDrop;
import mineplex.gemhunters.supplydrop.SupplyDropModule; import mineplex.gemhunters.supplydrop.SupplyDropModule;
import mineplex.gemhunters.worldevent.WorldEvent; import mineplex.gemhunters.worldevent.WorldEvent;
import mineplex.gemhunters.worldevent.WorldEventModule; import mineplex.gemhunters.worldevent.WorldEventModule;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.map.*;
import java.awt.*;
import java.util.Set;
import java.util.UUID;
/** /**
* <b>All item map code was adapted from Clans.</b><br> * <b>All item map code was adapted from Clans.</b><br>
@ -35,6 +30,7 @@ public class ItemMapRenderer extends MapRenderer
private static final int STANDARD_Y = 70; private static final int STANDARD_Y = 70;
private final ItemMapModule _itemMap; private final ItemMapModule _itemMap;
private final EconomyModule _economy;
private final LootModule _loot; private final LootModule _loot;
private final SafezoneModule _safezone; private final SafezoneModule _safezone;
private final SupplyDropModule _supply; private final SupplyDropModule _supply;
@ -47,6 +43,7 @@ public class ItemMapRenderer extends MapRenderer
super(true); super(true);
_itemMap = Managers.require(ItemMapModule.class); _itemMap = Managers.require(ItemMapModule.class);
_economy = Managers.require(EconomyModule.class);
_loot = Managers.require(LootModule.class); _loot = Managers.require(LootModule.class);
_safezone = Managers.require(SafezoneModule.class); _safezone = Managers.require(SafezoneModule.class);
_supply = Managers.require(SupplyDropModule.class); _supply = Managers.require(SupplyDropModule.class);
@ -273,6 +270,10 @@ public class ItemMapRenderer extends MapRenderer
{ {
cursorDisplay = MapCursor.Type.GREEN_POINTER; cursorDisplay = MapCursor.Type.GREEN_POINTER;
} }
else if (other.equals(_economy.getMostValuablePlayer()))
{
cursorDisplay = MapCursor.Type.RED_POINTER;
}
if (cursorDisplay == null) if (cursorDisplay == null)
{ {

View File

@ -0,0 +1,41 @@
package mineplex.gemhunters.progression;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.C;
import java.util.Arrays;
import java.util.List;
@ReflectivelyCreateMiniPlugin
public class ProgressionModule extends MiniPlugin
{
private static final List<ProgressionTitle> TITLE_LIST = Arrays.asList(
new ProgressionTitle(C.cGray + "Bankrupt", 0),
new ProgressionTitle(C.cAqua + "Beggar", 100),
new ProgressionTitle(C.cGreen + "Poor", 250),
new ProgressionTitle(C.cGreen + "MiddleClass", 500),
new ProgressionTitle(C.cGold + "Wealthy", 750),
new ProgressionTitle(C.cGold + "Loaded", 1000),
new ProgressionTitle(C.cRed + "Millionaire", 5000)
);
public ProgressionModule()
{
super("Progression");
}
public ProgressionTitle getTitle(int gems)
{
for (ProgressionTitle title : TITLE_LIST)
{
if (title.getRequiredGems() >= gems)
{
return title;
}
}
return TITLE_LIST.get(TITLE_LIST.size() - 1);
}
}

View File

@ -0,0 +1,24 @@
package mineplex.gemhunters.progression;
public class ProgressionTitle
{
private String _title;
private int _requiredGems;
public ProgressionTitle(String title, int requiredGems)
{
_title = title;
_requiredGems = requiredGems;
}
public String getTitle()
{
return _title;
}
public int getRequiredGems()
{
return _requiredGems;
}
}

View File

@ -5,6 +5,7 @@ import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import mineplex.core.common.util.*; import mineplex.core.common.util.*;
import mineplex.core.stats.StatsManager;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -87,6 +88,7 @@ public class QuestModule extends MiniClientPlugin<QuestPlayerData>
}; };
private final EconomyModule _economy; private final EconomyModule _economy;
private final StatsManager _stats;
private final WorldDataModule _worldData; private final WorldDataModule _worldData;
private QuestModule() private QuestModule()
@ -94,6 +96,7 @@ public class QuestModule extends MiniClientPlugin<QuestPlayerData>
super("Quest"); super("Quest");
_economy = require(EconomyModule.class); _economy = require(EconomyModule.class);
_stats = require(StatsManager.class);
_worldData = require(WorldDataModule.class); _worldData = require(WorldDataModule.class);
Menu<?> menu = new QuestUI(this); Menu<?> menu = new QuestUI(this);
@ -312,6 +315,8 @@ public class QuestModule extends MiniClientPlugin<QuestPlayerData>
player.sendMessage(F.main(_moduleName, "Completed " + F.name(quest.getName()) + ".")); player.sendMessage(F.main(_moduleName, "Completed " + F.name(quest.getName()) + "."));
_stats.incrementStat(player, "Gem Hunters.QuestsCompleted", 1);
QuestPlayerData playerData = Get(player); QuestPlayerData playerData = Get(player);
playerData.getActiveQuests().remove(Integer.valueOf(quest.getId())); playerData.getActiveQuests().remove(Integer.valueOf(quest.getId()));
playerData.getCompletedQuests().add(quest.getId()); playerData.getCompletedQuests().add(quest.getId());

View File

@ -9,6 +9,7 @@ import mineplex.core.recharge.Recharge;
import mineplex.gemhunters.death.event.QuitNPCSpawnEvent; import mineplex.gemhunters.death.event.QuitNPCSpawnEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -18,6 +19,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent; import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import mineplex.core.MiniPlugin; import mineplex.core.MiniPlugin;
@ -212,6 +214,17 @@ public class SafezoneModule extends MiniPlugin
} }
} }
@EventHandler
public void flintAndSteelInteract(PlayerInteractEvent event)
{
if (event.getItem() == null || event.getItem().getType() != Material.FLINT_AND_STEEL || event.getClickedBlock() == null || !isInSafeZone(event.getClickedBlock().getLocation()))
{
return;
}
event.setCancelled(true);
}
public boolean isInSafeZone(HumanEntity player) public boolean isInSafeZone(HumanEntity player)
{ {
return isInSafeZone(player.getLocation()) && _playerStatus.Get((Player) player).getStatusType() != PlayerStatusType.COMBAT; return isInSafeZone(player.getLocation()) && _playerStatus.Get((Player) player).getStatusType() != PlayerStatusType.COMBAT;

View File

@ -1,5 +1,7 @@
package mineplex.gemhunters.scoreboard; package mineplex.gemhunters.scoreboard;
import mineplex.gemhunters.progression.ProgressionModule;
import mineplex.gemhunters.progression.ProgressionTitle;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import mineplex.core.Managers; import mineplex.core.Managers;
@ -17,6 +19,7 @@ public class GemHuntersScoreboard extends WritableMineplexScoreboard
private final EconomyModule _economy; private final EconomyModule _economy;
private final PlayerStatusModule _playerStatus; private final PlayerStatusModule _playerStatus;
private final ProgressionModule _progression;
private final SupplyDropModule _supplyDrop; private final SupplyDropModule _supplyDrop;
public GemHuntersScoreboard(Player player) public GemHuntersScoreboard(Player player)
@ -25,6 +28,7 @@ public class GemHuntersScoreboard extends WritableMineplexScoreboard
_economy = Managers.get(EconomyModule.class); _economy = Managers.get(EconomyModule.class);
_playerStatus = Managers.get(PlayerStatusModule.class); _playerStatus = Managers.get(PlayerStatusModule.class);
_progression = Managers.get(ProgressionModule.class);
_supplyDrop = Managers.get(SupplyDropModule.class); _supplyDrop = Managers.get(SupplyDropModule.class);
} }
@ -60,4 +64,9 @@ public class GemHuntersScoreboard extends WritableMineplexScoreboard
{ {
return _economy.getGems(player); return _economy.getGems(player);
} }
public String getPrefix(Player perspective, Player subject)
{
return _progression.getTitle(_economy.getGems(subject)).getTitle() + " " + C.cYellow;
}
} }

View File

@ -106,26 +106,52 @@ public class ScoreboardModule extends MiniPlugin
_scoreboards.remove(player.getUniqueId()); _scoreboards.remove(player.getUniqueId());
} }
@EventHandler
public void updateScoreboard(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC_20)
{
return;
}
for (Player player : Bukkit.getOnlinePlayers())
{
createPlayerScoreboard(player);
}
}
public void createPlayerScoreboard(Player player) public void createPlayerScoreboard(Player player)
{ {
if (!_scoreboards.containsKey(player.getUniqueId())) GemHuntersScoreboard scoreboard;
{
GemHuntersScoreboard scoreboard = new GemHuntersScoreboard(player);
Scoreboard handle = scoreboard.getHandle();
if (_scoreboards.containsKey(player.getUniqueId()))
{
scoreboard = _scoreboards.get(player.getUniqueId());
}
else
{
scoreboard = new GemHuntersScoreboard(player);
_scoreboards.put(player.getUniqueId(), scoreboard); _scoreboards.put(player.getUniqueId(), scoreboard);
// Gem Counter Undername // Gem Counter Undername
Objective gemCounter = handle.registerNewObjective("Gems", "Gems"); Objective gemCounter = scoreboard.getHandle().registerNewObjective("Gems", "Gems");
gemCounter.setDisplaySlot(DisplaySlot.BELOW_NAME); gemCounter.setDisplaySlot(DisplaySlot.BELOW_NAME);
}
Scoreboard handle = scoreboard.getHandle();
for (GemHuntersScoreboard other : _scoreboards.values()) for (GemHuntersScoreboard other : _scoreboards.values())
{ {
// Set the other player's name tag for the player joining // Set the other player's name tag for the player joining
Player otherPlayer = other.getOwner(); Player otherPlayer = other.getOwner();
Team team = handle.registerNewTeam(otherPlayer.getName()); Team team = handle.getTeam(otherPlayer.getName());
team.setPrefix(C.cYellow); if (team == null)
{
team = handle.registerNewTeam(otherPlayer.getName());
}
team.setPrefix(scoreboard.getPrefix(player, otherPlayer));
//team.setSuffix(scoreboard.getSuffix(player, otherPlayer)); //team.setSuffix(scoreboard.getSuffix(player, otherPlayer));
team.addEntry(otherPlayer.getName()); team.addEntry(otherPlayer.getName());
@ -136,15 +162,19 @@ public class ScoreboardModule extends MiniPlugin
// Set the player that is joining // Set the player that is joining
Scoreboard otherHandle = other.getHandle(); Scoreboard otherHandle = other.getHandle();
Team otherTeam = otherHandle.registerNewTeam(player.getName()); Team otherTeam = otherHandle.getTeam(player.getName());
otherTeam.setPrefix(C.cYellow); if (otherTeam == null)
{
otherTeam = otherHandle.registerNewTeam(player.getName());
}
otherTeam.setPrefix(other.getPrefix(other.getOwner(), player));
//otherTeam.setSuffix(other.getSuffix(other.getOwner(), player)); //otherTeam.setSuffix(other.getSuffix(other.getOwner(), player));
otherTeam.addEntry(player.getName()); otherTeam.addEntry(player.getName());
} }
player.setScoreboard(scoreboard.getHandle()); player.setScoreboard(handle);
}
} }
public void updateTitles() public void updateTitles()

View File

@ -199,7 +199,7 @@ public class ShopModule extends MiniPlugin
String name = NAMES[UtilMath.r(NAMES.length)]; String name = NAMES[UtilMath.r(NAMES.length)];
name = (properties.isSelling() ? C.cGold + "Buying" : C.cGreen + "Selling") + C.cGray + " - " + C.cWhite + name; name = (properties.isSelling() ? C.cGold + "Buy" : C.cGreen + "Sell") + C.cGray + " - " + C.cWhite + name;
//DebugModule.getInstance().d("Trader at " + UtilWorld.locToStrClean(randomLocation) + " with key=" + key + " and index=" + index + " and max=" + spawned + "/" + max); //DebugModule.getInstance().d("Trader at " + UtilWorld.locToStrClean(randomLocation) + " with key=" + key + " and index=" + index + " and max=" + spawned + "/" + max);
if (properties.isSelling()) if (properties.isSelling())

View File

@ -0,0 +1,33 @@
package mineplex.gemhunters.world;
import mineplex.core.Managers;
import mineplex.core.common.Pair;
import mineplex.core.common.util.UtilServer;
import mineplex.core.leaderboard.Leaderboard;
import mineplex.core.leaderboard.LeaderboardManager;
import mineplex.core.leaderboard.LeaderboardRepository.LeaderboardSQLType;
public class Leaderboards
{
private final LeaderboardManager _manager;
private final WorldDataModule _worldData;
public Leaderboards()
{
_manager = Managers.require(LeaderboardManager.class);
_worldData = Managers.require(WorldDataModule.class);
// Make sure the world is loaded
UtilServer.runSyncLater(this::createLeaderboards, 20);
}
private void createLeaderboards()
{
_manager.registerLeaderboard("TOP_GEM_HUNTERS_KILLS", new Leaderboard("Top Kills", Pair.create("Kill", "Kills"), new String[] {"Gem Hunters.Kills"}, LeaderboardSQLType.ALL, _worldData.getCustomLocation("TOP_KILLS").get(0), 10));
_manager.registerLeaderboard("TOP_GEM_HUNTERS_DAILY_KILLS", new Leaderboard("Top Daily Kills", Pair.create("Kill", "Kills"), new String[] {"Gem Hunters.Kills"}, LeaderboardSQLType.DAILY, _worldData.getCustomLocation("TOP_DAILY_KILLS").get(0), 10));
_manager.registerLeaderboard("TOP_GEM_HUNTERS_GEMS", new Leaderboard("Top Gems Cashed Out", Pair.create("Gem", "Gems"), new String[] {"Gem Hunters.GemsEarned"}, LeaderboardSQLType.ALL, _worldData.getCustomLocation("TOP_GEMS").get(0), 10));
_manager.registerLeaderboard("TOP_GEM_HUNTERS_DAILY_GEMS", new Leaderboard("Top Daily Gems Cashed Out", Pair.create("Gem", "Gems"), new String[] {"Gem Hunters.GemsEarned"}, LeaderboardSQLType.DAILY, _worldData.getCustomLocation("TOP_DAILY_GEMS").get(0), 10));
}
}

View File

@ -8,6 +8,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import mineplex.gemhunters.worldevent.ufo.UFOWorldEvent;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import mineplex.core.MiniPlugin; import mineplex.core.MiniPlugin;
@ -45,7 +46,8 @@ public class WorldEventModule extends MiniPlugin
new BlizzardWorldEvent(), new BlizzardWorldEvent(),
//new NetherPortalWorldEvent(), //new NetherPortalWorldEvent(),
new WitherWorldEvent(), new WitherWorldEvent(),
new GwenMartWorldEvent() new GwenMartWorldEvent(),
new UFOWorldEvent()
); );
} }

View File

@ -8,6 +8,7 @@ public enum WorldEventType
NETHER("Dark Portal", WorldEventPriority.TRIGGERED), NETHER("Dark Portal", WorldEventPriority.TRIGGERED),
WITHER("Wither Temple", WorldEventPriority.TRIGGERED), WITHER("Wither Temple", WorldEventPriority.TRIGGERED),
GWEN_MART("Gwen-Mart Mega Sale", WorldEventPriority.GLOBAL), GWEN_MART("Gwen-Mart Mega Sale", WorldEventPriority.GLOBAL),
UFO("UFO", WorldEventPriority.GLOBAL),
; ;
@ -15,7 +16,7 @@ public enum WorldEventType
private WorldEventPriority _priority; private WorldEventPriority _priority;
private long _last; private long _last;
private WorldEventType(String name, WorldEventPriority priority) WorldEventType(String name, WorldEventPriority priority)
{ {
_name = name; _name = name;
_priority = priority; _priority = priority;

View File

@ -0,0 +1,204 @@
package mineplex.gemhunters.worldevent.ufo;
import mineplex.core.Managers;
import mineplex.core.common.block.schematic.Schematic;
import mineplex.core.common.block.schematic.SchematicData;
import mineplex.core.common.block.schematic.UtilSchematic;
import mineplex.core.common.skin.SkinData;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilTime;
import mineplex.core.utils.UtilVariant;
import mineplex.gemhunters.economy.EconomyModule;
import mineplex.gemhunters.loot.LootModule;
import mineplex.gemhunters.loot.rewards.LootChestReward;
import mineplex.gemhunters.worldevent.WorldEvent;
import mineplex.gemhunters.worldevent.WorldEventState;
import mineplex.gemhunters.worldevent.WorldEventType;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.BlockVector;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class UFOWorldEvent extends WorldEvent
{
private static final String SCHEMATIC_PATH = ".." + File.separator + ".." + File.separator + "update" + File.separator + "files" + File.separator + "UFO.schematic";
private static final long MAX_TIME = TimeUnit.MINUTES.toMillis(10);
private static final ItemStack HELMET = new ItemStack(Material.GLASS);
private static final ItemStack SWORD = new ItemStack(Material.STONE_SWORD);
private static final ItemStack SWORD_LEADER = new ItemStack(Material.IRON_SWORD);
private static final long CASH_OUT_DELAY = TimeUnit.MINUTES.toMillis(10);
private final EconomyModule _economy;
private final LootModule _loot;
private Skeleton _leader;
private Set<Skeleton> _skeletons;
private Set<Block> _ufoBlocks;
public UFOWorldEvent()
{
super(WorldEventType.UFO);
_economy = Managers.require(EconomyModule.class);
_loot = Managers.require(LootModule.class);
_skeletons = new HashSet<>();
_ufoBlocks = new HashSet<>();
}
@Override
public void onStart()
{
Location location = UtilAlg.Random(_worldData.getCustomLocation("NETHER_PORTAL")).clone().subtract(5, -10, 5);
Schematic schematic;
try
{
schematic = UtilSchematic.loadSchematic(new File(SCHEMATIC_PATH));
}
catch (IOException e)
{
e.printStackTrace();
return;
}
SchematicData data = schematic.paste(location, false, false, false);
for (BlockVector vector : data.getBlocks())
{
Location block = location.add(vector);
_ufoBlocks.add(block.getBlock());
location.subtract(vector);
}
_leader = UtilVariant.spawnWitherSkeleton(location);
_leader.setMaxHealth(200);
_leader.setHealth(_leader.getMaxHealth());
_leader.getEquipment().setItemInHand(SWORD_LEADER);
_leader.setCustomName(C.cDGreenB + "Alien Leader");
prepareSkeleton(_leader);
for (int i = 0; i < 10; i++)
{
Skeleton skeleton = _leader.getWorld().spawn(location, Skeleton.class);
skeleton.getEquipment().setItemInHand(SWORD);
skeleton.setCustomName(C.cGreenB + "Alien");
prepareSkeleton(skeleton);
_skeletons.add(skeleton);
}
setEventState(WorldEventState.LIVE);
}
private void prepareSkeleton(Skeleton skeleton)
{
skeleton.getEquipment().setHelmet(HELMET);
skeleton.setRemoveWhenFarAway(false);
skeleton.setCustomNameVisible(true);
}
@EventHandler
public void entityDeath(EntityDeathEvent event)
{
LivingEntity entity = event.getEntity();
if (_skeletons.remove(entity))
{
event.getDrops().clear();
event.setDroppedExp(0);
Player killer = entity.getKiller();
if (killer != null)
{
_economy.addToStore(killer, "Killing an Alien", 10);
}
}
if (_leader != null && _leader.equals(entity))
{
Player killer = _leader.getKiller();
if (killer != null)
{
ItemStack itemStack = SkinData.OMEGA_CHEST.getSkull(C.cAqua + "Omega Chest", new ArrayList<>());
LootChestReward reward = new LootChestReward(CASH_OUT_DELAY, itemStack, "Omega", 1);
_leader.getWorld().dropItemNaturally(_leader.getEyeLocation(), itemStack);
_loot.addItemReward(reward);
_economy.addToStore(killer, "Killing The Alien Leader", 1000);
}
}
}
@EventHandler
public void entityDamage(EntityCombustEvent event)
{
Entity entity = event.getEntity();
if (entity.equals(_leader) || _skeletons.contains(entity))
{
event.setCancelled(true);
}
}
@Override
public boolean checkToEnd()
{
return _leader.isDead() || UtilTime.elapsed(_start, MAX_TIME);
}
@Override
public void onEnd()
{
_leader.remove();
for (Skeleton skeleton : _skeletons)
{
skeleton.remove();
}
_skeletons.clear();
for (Block block : _ufoBlocks)
{
block.setType(Material.AIR);
}
_ufoBlocks.clear();
}
@Override
public Location[] getEventLocations()
{
return new Location[]{_leader.getLocation()};
}
@Override
public double getProgress()
{
return _leader.getHealth() / _leader.getMaxHealth();
}
}