diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilInv.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilInv.java index f7b6cbec7..246105fc8 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilInv.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilInv.java @@ -447,6 +447,21 @@ public class UtilInv return false; } + + public static boolean hasSpace(Player player, int slots) + { + int slotsFree = 0; + + for (int slot = 0; slot < player.getInventory().getSize(); slot++) + { + if (player.getInventory().getItem(slot) == null) + { + slotsFree++; + } + } + + return slotsFree >= slots; + } public static void give(Player player, Material material) { diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/GemHunters.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/GemHunters.java index 5367faef4..c397b959a 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/GemHunters.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/GemHunters.java @@ -33,6 +33,7 @@ import mineplex.core.ignore.IgnoreManager; import mineplex.core.incognito.IncognitoManager; import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.memory.MemoryFix; +import mineplex.core.menu.MenuManager; import mineplex.core.message.MessageManager; import mineplex.core.monitor.LagMeter; import mineplex.core.npc.NpcManager; @@ -58,11 +59,14 @@ import mineplex.gemhunters.economy.EconomyModule; import mineplex.gemhunters.loot.InventoryModule; import mineplex.gemhunters.loot.LootModule; import mineplex.gemhunters.map.ItemMapModule; +import mineplex.gemhunters.quest.QuestModule; import mineplex.gemhunters.safezone.SafezoneModule; import mineplex.gemhunters.scoreboard.ScoreboardModule; import mineplex.gemhunters.shop.ShopModule; import mineplex.gemhunters.spawn.SpawnModule; import mineplex.gemhunters.supplydrop.SupplyDropModule; +import mineplex.gemhunters.world.SewerMobs; +import mineplex.gemhunters.world.TimeCycle; import mineplex.gemhunters.world.WorldListeners; import mineplex.gemhunters.worldevent.WorldEventModule; import mineplex.minecraft.game.core.combat.CombatManager; @@ -158,7 +162,7 @@ public class GemHunters extends JavaPlugin new DamageManager(this, new CombatManager(this), new NpcManager(this, creature), disguiseManager, new ConditionManager(this)); // GWEN - //require(AntiHack.class); + // require(AntiHack.class); // Block Restore BlockRestore blockRestore = require(BlockRestore.class); @@ -181,10 +185,10 @@ public class GemHunters extends JavaPlugin // Parties new PartyManager(); - + // Communities new CommunityManager(this, clientManager); - + // Fixes new MemoryFix(this); new FoodDupeFix(this); @@ -194,10 +198,10 @@ public class GemHunters extends JavaPlugin explosion.SetDebris(true); explosion.SetTemporaryDebris(false); - + // Inventories - //new InventoryManager(this, clientManager); - + // new InventoryManager(this, clientManager); + // Reports // SnapshotManager snapshotManager = new SnapshotManager(this, new // SnapshotRepository(serverStatusManager.getCurrentServerName(), @@ -213,7 +217,12 @@ public class GemHunters extends JavaPlugin // Holograms new HologramManager(this, packetHandler); + // Menus + new MenuManager(this); + // Now we finally get to enable the Gem Hunters modules + // Though if any other module needs one of these it will be generated in + // order, however they are all here just for good measure. require(DebugModule.class); require(BountyModule.class); require(CashOutModule.class); @@ -223,6 +232,7 @@ public class GemHunters extends JavaPlugin require(InventoryModule.class); require(LootModule.class); require(ItemMapModule.class); + require(QuestModule.class); require(SafezoneModule.class); require(ScoreboardModule.class); require(SpawnModule.class); @@ -230,10 +240,12 @@ public class GemHunters extends JavaPlugin require(SupplyDropModule.class); require(WorldEventModule.class); - // An arbitrary collection of world listeners such as block place/break, interact events etc... + // An arbitrary collection of world listeners such as block place/break, + // interact events etc... new WorldListeners(this); - //new TimeCycle(this); - + new TimeCycle(this); + new SewerMobs(this); + // UpdateEvent!!! new Updater(this); @@ -262,7 +274,7 @@ public class GemHunters extends JavaPlugin { continue; } - + entity.remove(); } } diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/death/DeathModule.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/death/DeathModule.java index 8bb509674..d83761810 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/death/DeathModule.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/death/DeathModule.java @@ -32,7 +32,7 @@ import mineplex.core.common.util.UtilTime; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.core.visibility.VisibilityManager; -import mineplex.gemhunters.death.events.PlayerCustomRespawnEvent; +import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent; import mineplex.gemhunters.spawn.SpawnModule; /** diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/death/events/PlayerCustomRespawnEvent.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/death/event/PlayerCustomRespawnEvent.java similarity index 91% rename from Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/death/events/PlayerCustomRespawnEvent.java rename to Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/death/event/PlayerCustomRespawnEvent.java index 6b2db56a6..e588841cf 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/death/events/PlayerCustomRespawnEvent.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/death/event/PlayerCustomRespawnEvent.java @@ -1,4 +1,4 @@ -package mineplex.gemhunters.death.events; +package mineplex.gemhunters.death.event; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/CashOutModule.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/CashOutModule.java index b9295969e..fa731b801 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/CashOutModule.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/CashOutModule.java @@ -34,13 +34,14 @@ import mineplex.core.itemstack.ItemBuilder; import mineplex.core.recharge.Recharge; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent; @ReflectivelyCreateMiniPlugin public class CashOutModule extends MiniPlugin { private static final DecimalFormat ARMOUR_STAND_FORMAT = new DecimalFormat("0.0"); - public static final ItemStack CASH_OUT_ITEM = new ItemBuilder(Material.EMERALD).setTitle(C.cGreen + "Cash Out").addLore("", C.cGray + "Click to begin the process to cash out.", C.cGray + "Cashing out saves your current loot.").build(); + private static final ItemStack CASH_OUT_ITEM = new ItemBuilder(Material.EMERALD).setTitle(C.cGreen + "Cash Out").addLore("", C.cGray + "Click to begin the process to cash out.", C.cGray + "Cashing out saves your current loot.").build(); private static final int CASH_OUT_COOLDOWN = 10000; private static final int CASH_OUT_MAX_MOVE_DISTANCE_SQUARED = 4; @@ -58,6 +59,17 @@ public class CashOutModule extends MiniPlugin _sessions = new HashMap<>(); } + @EventHandler + public void teleportIn(PlayerTeleportIntoMapEvent event) + { + if (event.isCancelled()) + { + return; + } + + event.getPlayer().getInventory().setItem(7, CASH_OUT_ITEM); + } + @EventHandler public void playerInteract(PlayerInteractEvent event) { @@ -95,7 +107,8 @@ public class CashOutModule extends MiniPlugin @EventHandler public void inventoryClick(InventoryClickEvent event) { - Inventory inv = event.getInventory(); + Player player = (Player) event.getWhoClicked(); + Inventory inv = event.getClickedInventory(); ItemStack itemStack = event.getCurrentItem(); if (inv == null || itemStack == null) @@ -103,10 +116,12 @@ public class CashOutModule extends MiniPlugin return; } - if (itemStack.isSimilar(CASH_OUT_ITEM)) + if (inv.equals(player.getInventory())) { - event.setCancelled(true); + return; } + + event.setCancelled(true); } @EventHandler diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/EconomyModule.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/EconomyModule.java index 528f2a648..b010714b4 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/EconomyModule.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/economy/EconomyModule.java @@ -8,14 +8,13 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerQuitEvent; import mineplex.core.MiniPlugin; import mineplex.core.ReflectivelyCreateMiniPlugin; import mineplex.core.common.currency.GlobalCurrency; import mineplex.core.common.util.F; -import mineplex.gemhunters.death.events.PlayerCustomRespawnEvent; +import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent; import mineplex.gemhunters.economy.command.GiveGemsCommand; @ReflectivelyCreateMiniPlugin @@ -103,15 +102,4 @@ public class EconomyModule extends MiniPlugin { return _storedGems.get(player.getUniqueId()); } - - @EventHandler - public void test(PlayerCommandPreprocessEvent event) - { - if (event.getMessage().startsWith("/test")) - { - event.setCancelled(true); - addToStore(event.getPlayer(), "Testing", 100); - } - } - } diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/InventoryModule.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/InventoryModule.java index 95a0ee616..f9552c0d3 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/InventoryModule.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/InventoryModule.java @@ -22,7 +22,7 @@ import mineplex.core.common.util.UtilEvent; import mineplex.core.common.util.UtilEvent.ActionType; import mineplex.core.common.util.UtilInv; import mineplex.core.itemstack.ItemBuilder; -import mineplex.gemhunters.death.events.PlayerCustomRespawnEvent; +import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent; import mineplex.gemhunters.debug.DebugModule; @ReflectivelyCreateMiniPlugin @@ -106,7 +106,7 @@ public class InventoryModule extends MiniPlugin LootItem lootItem = _loot.fromItemStack(itemStack); - if (lootItem == null || lootItem.getMetadata().equals(ITEM_METADATA)) + if (lootItem == null || lootItem.getMetadata() == null || !lootItem.getMetadata().equals(ITEM_METADATA)) { return; } diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/LootModule.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/LootModule.java index 9a1f6ef06..519b52154 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/LootModule.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/LootModule.java @@ -30,6 +30,7 @@ import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilEvent; import mineplex.core.common.util.UtilEvent.ActionType; import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilWorld; import mineplex.core.google.GoogleSheetsManager; @@ -41,6 +42,7 @@ import mineplex.gemhunters.loot.command.SpawnChestCommand; import mineplex.gemhunters.loot.command.UpdateLootCommand; import mineplex.gemhunters.loot.deserialisers.ChestPropertiesDeserialiser; import mineplex.gemhunters.loot.deserialisers.LootItemDeserialiser; +import mineplex.gemhunters.loot.event.PlayerChestOpenEvent; import mineplex.gemhunters.loot.rewards.LootItemReward; import mineplex.gemhunters.loot.rewards.LootRankReward; import mineplex.gemhunters.safezone.SafezoneModule; @@ -410,7 +412,7 @@ public class LootModule extends MiniPlugin { for (SpawnedChest chest : _spawnedChest) { - if (chest.getLocation().distanceSquared(location) < 4 && chest.isOpened()) + if (chest.getLocation().distanceSquared(location) < MAX_CHEST_CHECK_DISTANCE_SQUARED && chest.isOpened()) { return true; } @@ -444,7 +446,7 @@ public class LootModule extends MiniPlugin for (SpawnedChest chest : _spawnedChest) { - if (UtilMath.offset(chest.getLocation(), block.getLocation()) < MAX_CHEST_CHECK_DISTANCE_SQUARED) + if (UtilMath.offsetSquared(chest.getLocation(), block.getLocation()) < MAX_CHEST_CHECK_DISTANCE_SQUARED) { key = chest.getProperties().getDataKey(); chest.setOpened(); @@ -458,6 +460,15 @@ public class LootModule extends MiniPlugin return; } + PlayerChestOpenEvent openEvent = new PlayerChestOpenEvent(player, block, _chestProperties.get(key)); + UtilServer.CallEvent(openEvent); + + if (openEvent.isCancelled()) + { + event.setCancelled(true); + return; + } + fillChest(player, block, key); } diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/event/PlayerChestOpenEvent.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/event/PlayerChestOpenEvent.java new file mode 100644 index 000000000..fb7d40583 --- /dev/null +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/loot/event/PlayerChestOpenEvent.java @@ -0,0 +1,60 @@ +package mineplex.gemhunters.loot.event; + +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +import mineplex.gemhunters.loot.ChestProperties; + +public class PlayerChestOpenEvent extends PlayerEvent implements Cancellable +{ + + private static final HandlerList HANDLERS = new HandlerList(); + + private boolean _cancel; + private final Block _block; + private final ChestProperties _properties; + + public PlayerChestOpenEvent(Player who, Block block, ChestProperties properties) + { + super(who); + + _block = block; + _properties = properties; + } + + public Block getChest() + { + return _block; + } + + public ChestProperties getProperties() + { + return _properties; + } + + public HandlerList getHandlers() + { + return HANDLERS; + } + + public static HandlerList getHandlerList() + { + return HANDLERS; + } + + @Override + public boolean isCancelled() + { + return _cancel; + } + + @Override + public void setCancelled(boolean cancel) + { + _cancel = cancel; + } + +} diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/map/ItemMapModule.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/map/ItemMapModule.java index 57225f4d2..73fc579d1 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/map/ItemMapModule.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/map/ItemMapModule.java @@ -21,14 +21,12 @@ import org.bukkit.craftbukkit.v1_8_R3.CraftChunk; import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; import org.bukkit.craftbukkit.v1_8_R3.util.LongHash; import org.bukkit.craftbukkit.v1_8_R3.util.LongObjectHashMap; -import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.block.Action; import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerItemHeldEvent; import org.bukkit.event.player.PlayerQuitEvent; @@ -59,8 +57,8 @@ import mineplex.core.itemstack.ItemBuilder; import mineplex.core.portal.events.ServerTransferEvent; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; -import mineplex.gemhunters.death.events.PlayerCustomRespawnEvent; import mineplex.gemhunters.spawn.SpawnModule; +import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent; import net.minecraft.server.v1_8_R3.Block; import net.minecraft.server.v1_8_R3.BlockPosition; import net.minecraft.server.v1_8_R3.Blocks; @@ -357,19 +355,7 @@ public class ItemMapModule extends MiniPlugin view.addRenderer(new ItemMapRenderer()); } - - @EventHandler - public void preventMapInItemFrame(PlayerInteractEntityEvent event) - { - if (!(event.getRightClicked() instanceof ItemFrame)) - return; - - if (!isItemClansMap(event.getPlayer().getItemInHand())) - return; - - event.setCancelled(true); - } - + /** * Get the center of the map. */ @@ -678,7 +664,7 @@ public class ItemMapModule extends MiniPlugin } @EventHandler - public void respawn(PlayerCustomRespawnEvent event) + public void teleportIn(PlayerTeleportIntoMapEvent event) { MapInfo info = new MapInfo(_mapId); @@ -714,7 +700,7 @@ public class ItemMapModule extends MiniPlugin _mapInfo.remove(event.getPlayer().getName()); } - @EventHandler + //@EventHandler public void onServerTransfer(ServerTransferEvent event) { Player p = event.getPlayer(); @@ -748,8 +734,8 @@ public class ItemMapModule extends MiniPlugin for (Player player : Bukkit.getOnlinePlayers()) { MapInfo info = getMap(player); - - if (info.getScale() >= 3) + + if (info == null || info.getScale() >= 3) { continue; } diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestModule.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestModule.java new file mode 100644 index 000000000..433f7d3f2 --- /dev/null +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestModule.java @@ -0,0 +1,252 @@ +package mineplex.gemhunters.quest; + +import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.MiniClientPlugin; +import mineplex.core.ReflectivelyCreateMiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilItem; +import mineplex.core.common.util.UtilItem.ItemAttribute; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilTextMiddle; +import mineplex.core.common.util.UtilTime; +import mineplex.core.itemstack.ItemBuilder; +import mineplex.core.menu.Menu; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.quest.types.ChestOpenerQuest; +import mineplex.gemhunters.quest.types.Quest; +import mineplex.gemhunters.world.WorldDataModule; + +@ReflectivelyCreateMiniPlugin +public class QuestModule extends MiniClientPlugin +{ + + private static final int MAX_QUESTS = 5; + private static final long RESET_QUESTS_TIME = TimeUnit.MINUTES.toMillis(15); + + private final Quest[] _quests = { new ChestOpenerQuest(0, "Chest Opener", 100, 250, 5), new ChestOpenerQuest(1, "Grand Chest Opener", 200, 500, 20), new ChestOpenerQuest(2, "Superior Chest Opener", 500, 750, 40) }; + + private final WorldDataModule _worldData; + + private QuestModule() + { + super("Quest"); + + _worldData = require(WorldDataModule.class); + + Menu menu = new QuestUI(this); + + runSyncLater(() -> { + + for (Location location : _worldData.getCustomLocation("QUEST_NPC")) + { + new QuestNPC(this, location, menu); + } + + }, 20); + } + + @Override + protected QuestPlayerData addPlayer(UUID uuid) + { + return new QuestPlayerData(); + } + + @EventHandler + public void playerJoin(PlayerJoinEvent event) + { + updateQuests(event.getPlayer()); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.SLOW) + { + return; + } + + for (Player player : Bukkit.getOnlinePlayers()) + { + QuestPlayerData playerData = Get(player); + + if (!UtilTime.elapsed(playerData.getLastClear(), RESET_QUESTS_TIME)) + { + continue; + } + + player.sendMessage(F.main(C.cYellowB + "Quest Master", "I have " + F.count(String.valueOf(MAX_QUESTS)) + " new quests for you! Come and see me to start them!")); + + playerData.clear(); + updateQuests(player); + } + } + + public void updateQuests(Player player) + { + QuestPlayerData playerData = Get(player); + List quests = playerData.getPossibleQuests(); + + for (int i = 0; i < MAX_QUESTS; i++) + { + Quest quest = getRandomQuest(playerData, player); + + if (quest == null) + { + player.sendMessage(F.main(_moduleName, "It seems that there was some trouble finding you a new quest. Please try again later.")); + return; + } + + quests.add(quest.getId()); + } + } + + public void startQuest(Quest quest, Player player) + { + if (isActive(quest, player)) + { + player.sendMessage(F.main(_moduleName, "You have already accepted that quest.")); + return; + } + else if (isComplete(quest, player)) + { + player.sendMessage(F.main(_moduleName, "You have already completed that quest.")); + return; + } + + player.sendMessage(F.main(_moduleName, "Started " + F.name(quest.getName()) + ".")); + + QuestPlayerData playerData = Get(player); + playerData.getActiveQuests().add(quest.getId()); + + updateQuestItem(quest, player); + } + + public void completeQuest(Quest quest, Player player) + { + if (!isActive(quest, player)) + { + player.sendMessage(F.main(_moduleName, "This quest is not active for you.")); + return; + } + + QuestPlayerData playerData = Get(player); + playerData.getActiveQuests().remove(Integer.valueOf(quest.getId())); + playerData.getCompletedQuests().add(quest.getId()); + + updateQuestItem(quest, player); + } + + public Quest getRandomQuest(QuestPlayerData playerData, Player player) + { + int attempts = 0; + + while (attempts < _quests.length * 2) + { + attempts++; + + int index = UtilMath.r(_quests.length); + Quest quest = _quests[index]; + + if (isActive(quest, player) || playerData.getPossibleQuests().contains(quest.getId())) + { + continue; + } + + return quest; + } + + return null; + } + + public ItemStack getItemStack(Quest quest, Player player, boolean npc, boolean hasSpace) + { + ItemBuilder builder = new ItemBuilder(Material.PAPER); + + builder.setTitle(C.cGreen + quest.getName()); + builder.addLore(C.blankLine, quest.getDescription(), C.blankLine); + + boolean active = isActive(quest, player); + boolean complete = isComplete(quest, player); + + if (npc) + { + if (active) + { + builder.setGlow(true); + builder.addLore(C.cRed + "You have already started this quest!"); + } + else if (complete) + { + builder.addLore(C.cRed + "You have already completed this quest!"); + } + else if (hasSpace) + { + builder.addLore(C.cGreen + "Click to start this quest!"); + } + else + { + builder.addLore(C.cRed + "You do not have enough space in your inventory!"); + } + } + else + { + builder.addLore(UtilTextMiddle.progress(quest.getProgress(player)) + C.mBody + " [" + C.cGreen + quest.get(player) + C.mBody + "/" + C.cGreen + quest.getGoal() + C.mBody + "]"); + } + + return builder.build(); + } + + public void updateQuestItem(Quest quest, Player player) + { + ItemStack itemStack = getItemStack(quest, player, false, true); + + for (ItemStack items : player.getInventory().getContents()) + { + if (UtilItem.isSimilar(itemStack, items, ItemAttribute.MATERIAL, ItemAttribute.NAME, ItemAttribute.DATA)) + { + player.getInventory().remove(items); + } + } + + if (isActive(quest, player)) + { + player.getInventory().addItem(itemStack); + } + } + + public boolean isActive(Quest quest, Player player) + { + return Get(player).getActiveQuests().contains(quest.getId()); + } + + public boolean isComplete(Quest quest, Player player) + { + return Get(player).getCompletedQuests().contains(quest.getId()); + } + + public Quest getFromId(int id) + { + for (Quest quest : _quests) + { + if (quest.getId() == id) + { + return quest; + } + } + + return null; + } +} diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestNPC.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestNPC.java new file mode 100644 index 000000000..609f873bb --- /dev/null +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestNPC.java @@ -0,0 +1,43 @@ +package mineplex.gemhunters.quest; + +import org.bukkit.Location; +import org.bukkit.entity.Villager; +import org.bukkit.entity.Villager.Profession; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractEntityEvent; + +import mineplex.core.common.util.C; +import mineplex.core.menu.Menu; +import mineplex.gemhunters.util.SimpleNPC; + +public class QuestNPC extends SimpleNPC +{ + + private Menu _questMenu; + + public QuestNPC(QuestModule quest, Location spawn, Menu menu) + { + super(quest.getPlugin(), spawn, Villager.class, C.cYellowB + "Quest Master", null); + + _questMenu = menu; + + Villager villager = (Villager) _entity; + + villager.setProfession(Profession.LIBRARIAN); + } + + @Override + @EventHandler + public void npcClick(PlayerInteractEntityEvent event) + { + if (!event.getRightClicked().equals(_entity)) + { + return; + } + + event.setCancelled(true); + + _questMenu.open(event.getPlayer()); + } + +} diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestPlayerData.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestPlayerData.java new file mode 100644 index 000000000..dbfce2d62 --- /dev/null +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestPlayerData.java @@ -0,0 +1,53 @@ +package mineplex.gemhunters.quest; + +import java.util.ArrayList; +import java.util.List; + +public class QuestPlayerData +{ + + private final List _possibleQuests; + private final List _activeQuests; + private final List _completedQuests; + + private long _lastClear; + + public QuestPlayerData() + { + _possibleQuests = new ArrayList<>(); + _activeQuests = new ArrayList<>(); + _completedQuests = new ArrayList<>(); + + _lastClear = System.currentTimeMillis(); + } + + public void clear() + { + _possibleQuests.clear(); + _activeQuests.clear(); + _completedQuests.clear(); + + _lastClear = System.currentTimeMillis(); + } + + public List getPossibleQuests() + { + return _possibleQuests; + } + + public List getActiveQuests() + { + return _activeQuests; + } + + public List getCompletedQuests() + { + return _completedQuests; + } + + public long getLastClear() + { + return _lastClear; + } + +} diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestUI.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestUI.java new file mode 100644 index 000000000..1fac094f5 --- /dev/null +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/QuestUI.java @@ -0,0 +1,61 @@ +package mineplex.gemhunters.quest; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilUI; +import mineplex.core.menu.Button; +import mineplex.core.menu.Menu; +import mineplex.gemhunters.quest.types.Quest; + +public class QuestUI extends Menu +{ + + public QuestUI(QuestModule plugin) + { + super("Quest Master", plugin); + } + + @Override + protected Button[] setUp(Player player) + { + Button[] buttons = new Button[21]; + QuestPlayerData playerData = getPlugin().Get(player); + + int i = 0; + int[] slots = UtilUI.getIndicesFor(playerData.getPossibleQuests().size(), 1); + for (Integer id : playerData.getPossibleQuests()) + { + Quest quest = getPlugin().getFromId(id); + ItemStack itemStack = getPlugin().getItemStack(quest, player, true, UtilInv.hasSpace(player, 1)); + + buttons[slots[i++]] = new QuestSelectButton(getPlugin(), itemStack, quest); + } + + return buttons; + } + + public class QuestSelectButton extends Button + { + + private final Quest _quest; + + public QuestSelectButton(QuestModule plugin, ItemStack itemStack, Quest quest) + { + super(itemStack, plugin); + + _quest = quest; + } + + @Override + public void onClick(Player player, ClickType clickType) + { + getPlugin().startQuest(_quest, player); + resetAndUpdate(); + } + + } + +} diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/ChestOpenerQuest.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/ChestOpenerQuest.java new file mode 100644 index 000000000..8a8514b80 --- /dev/null +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/ChestOpenerQuest.java @@ -0,0 +1,56 @@ +package mineplex.gemhunters.quest.types; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import mineplex.core.common.util.F; +import mineplex.gemhunters.debug.DebugModule; +import mineplex.gemhunters.loot.event.PlayerChestOpenEvent; + +public class ChestOpenerQuest extends Quest +{ + + private final int _goal; + + public ChestOpenerQuest(int id, String name, int startCost, int completeReward, int goal) + { + super(id, name, "Open " + F.count(String.valueOf(goal)) + " Chests.", startCost, completeReward); + + _goal = goal; + } + + @Override + public float getProgress(Player player) + { + return (float) get(player) / (float) _goal; + } + + @Override + public int getGoal() + { + return _goal; + } + + @EventHandler + public void chestOpen(PlayerChestOpenEvent event) + { + DebugModule.getInstance().d(event.getEventName()); + Player player = event.getPlayer(); + + if (!isActive(player)) + { + DebugModule.getInstance().d("Not active."); + return; + } + + int amount = getAndIncrement(player, 1); + + DebugModule.getInstance().d("amount = " + amount); + + if (amount >= _goal) + { + onReward(player); + } + } + +} diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/Quest.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/Quest.java new file mode 100644 index 000000000..47a56ae0c --- /dev/null +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/quest/types/Quest.java @@ -0,0 +1,127 @@ +package mineplex.gemhunters.quest.types; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerQuitEvent; + +import mineplex.core.Managers; +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilServer; +import mineplex.core.donation.DonationManager; +import mineplex.gemhunters.economy.EconomyModule; +import mineplex.gemhunters.quest.QuestModule; + +public abstract class Quest implements Listener +{ + + private final int _id; + private final String _name; + private final String _description; + private final int _startCost; + private final int _completeReward; + + protected final QuestModule _quest; + protected final CoreClientManager _clientManager; + protected final DonationManager _donation; + protected final EconomyModule _economy; + + private final Map _counter; + + public Quest(int id, String name, String description, int startCost, int completeReward) + { + _id = id; + _name = name; + _description = description; + _startCost = startCost; + _completeReward = completeReward; + + _quest = Managers.require(QuestModule.class); + _clientManager = Managers.require(CoreClientManager.class); + _donation = Managers.require(DonationManager.class); + _economy = Managers.require(EconomyModule.class); + + _counter = new HashMap<>(); + + UtilServer.getServer().getPluginManager().registerEvents(this, UtilServer.getPlugin()); + } + + @EventHandler + public void playerQuit(PlayerQuitEvent event) + { + remove(event.getPlayer()); + } + + public int get(Player player) + { + return _counter.getOrDefault(player.getUniqueId(), 0); + } + + public int getAndIncrement(Player player, int amount) + { + int newAmount = get(player) + amount; + _counter.put(player.getUniqueId(), newAmount); + _quest.updateQuestItem(this, player); + + return newAmount; + } + + public int remove(Player player) + { + return _counter.remove(player.getUniqueId()); + } + + public void onStart(Player player) + { + _economy.removeFromStore(player, _startCost); + } + + public void onReward(Player player) + { + _economy.addToStore(player, "Completing " + F.elem(_name), _completeReward); + remove(player); + _quest.completeQuest(this, player); + } + + public boolean isActive(Player player) + { + return _quest.isActive(this, player); + } + + public abstract float getProgress(Player player); + + public int getGoal() + { + return 1; + } + + public final int getId() + { + return _id; + } + + public final String getName() + { + return _name; + } + + public final String getDescription() + { + return _description; + } + + public final int getStartCost() + { + return _startCost; + } + + public final int getCompleteReward() + { + return _completeReward; + } +} diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/TraderNPC.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/TraderNPC.java index 59af93f25..47576c345 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/TraderNPC.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/shop/TraderNPC.java @@ -110,7 +110,6 @@ public class TraderNPC extends SimpleNPC player.sendMessage(F.main(_entity.getCustomName(), "Purchased " + F.elem(itemName) + "!")); player.playSound(player.getLocation(), Sound.NOTE_PLING, 1, 1.2F); player.getInventory().addItem(itemStack); - player.closeInventory(); } public int fromItemStack(ItemStack itemStack) diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/SpawnModule.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/SpawnModule.java index ce51aa10c..e910bcfdf 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/SpawnModule.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/SpawnModule.java @@ -16,14 +16,14 @@ import org.bukkit.scheduler.BukkitRunnable; import mineplex.core.MiniPlugin; import mineplex.core.ReflectivelyCreateMiniPlugin; import mineplex.core.common.util.C; -import mineplex.core.common.util.Callback; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilServer; import mineplex.core.portal.Intent; import mineplex.core.portal.Portal; -import mineplex.gemhunters.economy.CashOutModule; import mineplex.gemhunters.safezone.SafezoneModule; +import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent; import mineplex.gemhunters.util.ColouredTextAnimation; import mineplex.gemhunters.util.SimpleNPC; import mineplex.gemhunters.world.WorldDataModule; @@ -34,7 +34,7 @@ public class SpawnModule extends MiniPlugin public static final int WORLD_BORDER_RADIUS = 768; private static final int MAX_SPAWNING_Y = 73; - + private final SafezoneModule _safezone; private final WorldDataModule _worldData; @@ -80,70 +80,66 @@ public class SpawnModule extends MiniPlugin location.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(location, _spawn))); - new SimpleNPC(_plugin, location, Villager.class, C.cDRed + "! " + C.cRedB + "Enter The World" + C.cDRed + " !", new Callback() - { + new SimpleNPC(_plugin, location, Villager.class, C.cDRed + "! " + C.cRedB + "Enter The World" + C.cDRed + " !", clicker -> { - @Override - public void run(Player player) + Location toTeleport = getRandomLocation(); + + if (toTeleport == null) { - Location location = getRandomLocation(); - - if (location == null) - { - player.sendMessage(F.main(_moduleName, "A suitable teleport location could not be found. Please try again in a few seconds.")); - return; - } - - player.teleport(location); - player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 4 * 20, 9)); - player.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 4 * 20, 9)); - - player.getInventory().setItem(8, CashOutModule.CASH_OUT_ITEM); - - ColouredTextAnimation animation = new ColouredTextAnimation("GEM HUNTERS", C.cGoldB + "M ", C.cGoldB + " M", new String[] { C.cDGreenB, C.cGreenB, C.cWhiteB }); - - runSyncTimer(new BukkitRunnable() - { - - @Override - public void run() - { - if (animation.displayAsTitle(player)) - { - cancel(); - } - } - }, 10, 4); + clicker.sendMessage(F.main(_moduleName, "A suitable teleport location could not be found. Please try again in a few seconds.")); + return; } + + PlayerTeleportIntoMapEvent teleportEvent = new PlayerTeleportIntoMapEvent(player, toTeleport); + + UtilServer.CallEvent(teleportEvent); + + if (teleportEvent.isCancelled()) + { + clicker.sendMessage(F.main(_moduleName, "Something went wrong there, sorry. Please try again in a few seconds.")); + return; + } + + clicker.teleport(toTeleport); + clicker.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 4 * 20, 9)); + clicker.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 4 * 20, 9)); + + ColouredTextAnimation animation = new ColouredTextAnimation("GEM HUNTERS", C.cGoldB + "M ", C.cGoldB + " M", new String[] { C.cDGreenB, C.cGreenB, C.cWhiteB }); + + runSyncTimer(new BukkitRunnable() + { + + @Override + public void run() + { + if (animation.displayAsTitle(player)) + { + cancel(); + } + } + }, 10, 4); }); } { Location location = _worldData.getCustomLocation("RETURN_TO_HUB").get(0); location.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(location, _spawn))); - - new SimpleNPC(_plugin, location, Villager.class, C.cGoldB + "Return To Hub", new Callback() - { - - @Override - public void run(Player data) - { - Portal.getInstance().sendToHub(data, null, Intent.PLAYER_REQUEST); - } + + new SimpleNPC(_plugin, location, Villager.class, C.cGoldB + "Return To Hub", clicker -> { + + Portal.getInstance().sendToHub(clicker, null, Intent.PLAYER_REQUEST); + }); } { Location location = _worldData.getCustomLocation("TUTORIAL").get(0); location.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(location, _spawn))); - - new SimpleNPC(_plugin, location, Villager.class, C.cGoldB + "Tutorial", new Callback() - { - - @Override - public void run(Player data) - { - } + + new SimpleNPC(_plugin, location, Villager.class, C.cGoldB + "Tutorial", clicker -> { + + clicker.sendMessage(F.main(_moduleName, "A tutorial will be coming soon.")); + }); } } diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/event/PlayerTeleportIntoMapEvent.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/event/PlayerTeleportIntoMapEvent.java new file mode 100644 index 000000000..51b6e6d6f --- /dev/null +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/spawn/event/PlayerTeleportIntoMapEvent.java @@ -0,0 +1,56 @@ +package mineplex.gemhunters.spawn.event; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +public class PlayerTeleportIntoMapEvent extends PlayerEvent implements Cancellable +{ + + private static final HandlerList HANDLERS = new HandlerList(); + + private boolean _cancel; + private Location _to; + + public PlayerTeleportIntoMapEvent(Player who, Location to) + { + super(who); + + _to = to; + } + + public void setTo(Location to) + { + _to = to; + } + + public Location getTo() + { + return _to; + } + + public HandlerList getHandlers() + { + return HANDLERS; + } + + public static HandlerList getHandlerList() + { + return HANDLERS; + } + + @Override + public boolean isCancelled() + { + return _cancel; + } + + @Override + public void setCancelled(boolean cancel) + { + _cancel = cancel; + } + +} diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/util/SimpleNPC.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/util/SimpleNPC.java index b0e9fa6df..5e265998e 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/util/SimpleNPC.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/util/SimpleNPC.java @@ -13,7 +13,6 @@ import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.plugin.java.JavaPlugin; -import mineplex.core.common.util.Callback; import mineplex.core.common.util.UtilEnt; public class SimpleNPC implements Listener diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/world/SewerMobs.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/world/SewerMobs.java new file mode 100644 index 000000000..b9e363f43 --- /dev/null +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/world/SewerMobs.java @@ -0,0 +1,95 @@ +package mineplex.gemhunters.world; + +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilBlock; +import mineplex.core.common.util.UtilMath; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.gemhunters.spawn.SpawnModule; + +public class SewerMobs implements Listener +{ + + private static final int MAX_MOBS = 100; + + private final Set _entities; + + public SewerMobs(JavaPlugin plugin) + { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + + _entities = new HashSet<>(); + } + + @EventHandler + public void update(UpdateEvent event) + { + if (event.getType() != UpdateType.SLOWEST) + { + return; + } + + World world = Bukkit.getWorlds().get(0); + + for (int i = 0; i < MAX_MOBS / 4; i++) + { + if (_entities.size() >= MAX_MOBS) + { + break; + } + + EntityType type = UtilMath.random.nextBoolean() ? EntityType.ZOMBIE : EntityType.SKELETON; + + _entities.add(world.spawnEntity(getRandomLocation(world), type)); + } + } + + public Location getRandomLocation(World world) + { + int attempts = 0; + + while (attempts < 40) + { + Location location = new Location(world, UtilMath.r(SpawnModule.WORLD_BORDER_RADIUS * 2) - SpawnModule.WORLD_BORDER_RADIUS, 46, UtilMath.r(SpawnModule.WORLD_BORDER_RADIUS * 2) - SpawnModule.WORLD_BORDER_RADIUS); + + if (!isSuitable(location.getBlock())) + { + continue; + } + + attempts++; + } + + return null; + } + + public boolean isSuitable(Block block) + { + Block up = block.getRelative(BlockFace.UP); + Block down = block.getRelative(BlockFace.DOWN); + + if (block.getType() != Material.AIR || up.getType() != Material.AIR || down.getType() == Material.AIR || UtilBlock.liquid(down) || UtilBlock.liquid(up) || UtilBlock.liquid(block)) + { + return false; + } + + return true; + } + +} diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/world/TimeCycle.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/world/TimeCycle.java index 32fc398ad..a3a61a617 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/world/TimeCycle.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/world/TimeCycle.java @@ -62,20 +62,20 @@ public class TimeCycle implements Listener if (!_night && _world.getTime() > 12000) { _night = true; - setStreetLights(); + //setStreetLights(); } if (_world.getTime() >= 23900) { _world.setTime(0); _night = false; - setStreetLights(); + //setStreetLights(); } _world.setTime(_world.getTime() + (isNight() ? TICKS_NIGHT : TICKS_DAY)); } - @EventHandler + //@EventHandler public void test(PlayerCommandPreprocessEvent event) { if (event.getMessage().startsWith("/lamp")) {