From d389665bd7b3c32d0b0705c03618e36bfe32114d Mon Sep 17 00:00:00 2001 From: P0nk Date: Thu, 9 Sep 2021 23:26:45 +0200 Subject: [PATCH] Reformat and clean up "scripting" package --- .../scripting/AbstractPlayerInteraction.java | 2040 ++++++------- .../java/scripting/AbstractScriptManager.java | 1 - .../scripting/event/EventInstanceManager.java | 2558 +++++++++-------- .../java/scripting/event/EventManager.java | 451 +-- .../scripting/event/EventScheduledFuture.java | 5 +- .../scripting/event/EventScriptManager.java | 16 +- .../event/scheduler/EventScriptScheduler.java | 5 +- .../scripting/item/ItemScriptManager.java | 6 +- .../scripting/item/ItemScriptMethods.java | 3 +- .../java/scripting/map/MapScriptManager.java | 6 +- .../java/scripting/map/MapScriptMethods.java | 12 +- .../scripting/npc/NPCConversationManager.java | 1847 ++++++------ .../java/scripting/npc/NPCScriptManager.java | 3 +- .../scripting/portal/PortalScriptManager.java | 2 +- .../scripting/quest/QuestActionManager.java | 15 +- .../scripting/quest/QuestScriptManager.java | 127 +- .../reactor/ReactorActionManager.java | 96 +- .../reactor/ReactorScriptManager.java | 11 +- 18 files changed, 3636 insertions(+), 3568 deletions(-) diff --git a/src/main/java/scripting/AbstractPlayerInteraction.java b/src/main/java/scripting/AbstractPlayerInteraction.java index 5920e227ab..abb8f77119 100644 --- a/src/main/java/scripting/AbstractPlayerInteraction.java +++ b/src/main/java/scripting/AbstractPlayerInteraction.java @@ -57,166 +57,166 @@ import java.util.*; public class AbstractPlayerInteraction { - public Client c; + public Client c; - public AbstractPlayerInteraction(Client c) { - this.c = c; - } + public AbstractPlayerInteraction(Client c) { + this.c = c; + } - public Client getClient() { - return c; - } + public Client getClient() { + return c; + } - public Character getPlayer() { - return c.getPlayer(); - } - - public Character getChar() { - return c.getPlayer(); - } - - public int getJobId() { - return getPlayer().getJob().getId(); - } - - public Job getJob(){ - return getPlayer().getJob(); - } - - public int getLevel() { - return getPlayer().getLevel(); - } - - public MapleMap getMap() { - return c.getPlayer().getMap(); - } - - public int getHourOfDay() { - return Calendar.getInstance().get(Calendar.HOUR_OF_DAY); - } - - public int getMarketPortalId(int mapId) { - return getMarketPortalId(getWarpMap(mapId)); - } - - private int getMarketPortalId(MapleMap map) { - return (map.findMarketPortal() != null) ? map.findMarketPortal().getId() : map.getRandomPlayerSpawnpoint().getId(); - } - - public void warp(int mapid) { - getPlayer().changeMap(mapid); - } + public Character getPlayer() { + return c.getPlayer(); + } - public void warp(int map, int portal) { - getPlayer().changeMap(map, portal); - } + public Character getChar() { + return c.getPlayer(); + } - public void warp(int map, String portal) { - getPlayer().changeMap(map, portal); - } + public int getJobId() { + return getPlayer().getJob().getId(); + } - public void warpMap(int map) { - getPlayer().getMap().warpEveryone(map); - } + public Job getJob() { + return getPlayer().getJob(); + } - public void warpParty(int id) { - warpParty(id, 0); - } - - public void warpParty(int id, int portalId) { - int mapid = getMapId(); - warpParty(id, portalId, mapid, mapid); - } - - public void warpParty(int id, int fromMinId, int fromMaxId) { - warpParty(id, 0, fromMinId, fromMaxId); - } - - public void warpParty(int id, int portalId, int fromMinId, int fromMaxId) { - for (Character mc : this.getPlayer().getPartyMembersOnline()) { - if (mc.isLoggedinWorld()) { - if(mc.getMapId() >= fromMinId && mc.getMapId() <= fromMaxId) { - mc.changeMap(id, portalId); - } - } + public int getLevel() { + return getPlayer().getLevel(); + } + + public MapleMap getMap() { + return c.getPlayer().getMap(); + } + + public int getHourOfDay() { + return Calendar.getInstance().get(Calendar.HOUR_OF_DAY); + } + + public int getMarketPortalId(int mapId) { + return getMarketPortalId(getWarpMap(mapId)); + } + + private int getMarketPortalId(MapleMap map) { + return (map.findMarketPortal() != null) ? map.findMarketPortal().getId() : map.getRandomPlayerSpawnpoint().getId(); + } + + public void warp(int mapid) { + getPlayer().changeMap(mapid); + } + + public void warp(int map, int portal) { + getPlayer().changeMap(map, portal); + } + + public void warp(int map, String portal) { + getPlayer().changeMap(map, portal); + } + + public void warpMap(int map) { + getPlayer().getMap().warpEveryone(map); + } + + public void warpParty(int id) { + warpParty(id, 0); + } + + public void warpParty(int id, int portalId) { + int mapid = getMapId(); + warpParty(id, portalId, mapid, mapid); + } + + public void warpParty(int id, int fromMinId, int fromMaxId) { + warpParty(id, 0, fromMinId, fromMaxId); + } + + public void warpParty(int id, int portalId, int fromMinId, int fromMaxId) { + for (Character mc : this.getPlayer().getPartyMembersOnline()) { + if (mc.isLoggedinWorld()) { + if (mc.getMapId() >= fromMinId && mc.getMapId() <= fromMaxId) { + mc.changeMap(id, portalId); } - } + } + } + } - public MapleMap getWarpMap(int map) { - return getPlayer().getWarpMap(map); - } + public MapleMap getWarpMap(int map) { + return getPlayer().getWarpMap(map); + } - public MapleMap getMap(int map) { - return getWarpMap(map); - } - - public int countAllMonstersOnMap(int map) { - return getMap(map).countMonsters(); - } - - public int countMonster() { - return getPlayer().getMap().countMonsters(); - } - - public void resetMapObjects(int mapid) { - getWarpMap(mapid).resetMapObjects(); - } + public MapleMap getMap(int map) { + return getWarpMap(map); + } - public EventManager getEventManager(String event) { - return getClient().getEventManager(event); - } - - public EventInstanceManager getEventInstance() { - return getPlayer().getEventInstance(); - } - - public Inventory getInventory(int type) { - return getPlayer().getInventory(InventoryType.getByType((byte) type)); - } - - public Inventory getInventory(InventoryType type) { - return getPlayer().getInventory(type); - } - - public boolean hasItem(int itemid) { - return haveItem(itemid, 1); - } + public int countAllMonstersOnMap(int map) { + return getMap(map).countMonsters(); + } - public boolean hasItem(int itemid, int quantity) { - return haveItem(itemid, quantity); - } + public int countMonster() { + return getPlayer().getMap().countMonsters(); + } - public boolean haveItem(int itemid) { - return haveItem(itemid, 1); - } + public void resetMapObjects(int mapid) { + getWarpMap(mapid).resetMapObjects(); + } - public boolean haveItem(int itemid, int quantity) { - return getPlayer().getItemQuantity(itemid, false) >= quantity; - } - - public int getItemQuantity(int itemid) { - return getPlayer().getItemQuantity(itemid, false); - } + public EventManager getEventManager(String event) { + return getClient().getEventManager(event); + } - public boolean haveItemWithId(int itemid) { - return haveItemWithId(itemid, false); - } - - public boolean haveItemWithId(int itemid, boolean checkEquipped) { - return getPlayer().haveItemWithId(itemid, checkEquipped); - } - - public boolean canHold(int itemid) { - return canHold(itemid, 1); - } - - public boolean canHold(int itemid, int quantity) { - return canHoldAll(Collections.singletonList(itemid), Collections.singletonList(quantity), true); - } - - public boolean canHold(int itemid, int quantity, int removeItemid, int removeQuantity) { - return canHoldAllAfterRemoving(Collections.singletonList(itemid), Collections.singletonList(quantity), Collections.singletonList(removeItemid), Collections.singletonList(removeQuantity)); - } + public EventInstanceManager getEventInstance() { + return getPlayer().getEventInstance(); + } + + public Inventory getInventory(int type) { + return getPlayer().getInventory(InventoryType.getByType((byte) type)); + } + + public Inventory getInventory(InventoryType type) { + return getPlayer().getInventory(type); + } + + public boolean hasItem(int itemid) { + return haveItem(itemid, 1); + } + + public boolean hasItem(int itemid, int quantity) { + return haveItem(itemid, quantity); + } + + public boolean haveItem(int itemid) { + return haveItem(itemid, 1); + } + + public boolean haveItem(int itemid, int quantity) { + return getPlayer().getItemQuantity(itemid, false) >= quantity; + } + + public int getItemQuantity(int itemid) { + return getPlayer().getItemQuantity(itemid, false); + } + + public boolean haveItemWithId(int itemid) { + return haveItemWithId(itemid, false); + } + + public boolean haveItemWithId(int itemid, boolean checkEquipped) { + return getPlayer().haveItemWithId(itemid, checkEquipped); + } + + public boolean canHold(int itemid) { + return canHold(itemid, 1); + } + + public boolean canHold(int itemid, int quantity) { + return canHoldAll(Collections.singletonList(itemid), Collections.singletonList(quantity), true); + } + + public boolean canHold(int itemid, int quantity, int removeItemid, int removeQuantity) { + return canHoldAllAfterRemoving(Collections.singletonList(itemid), Collections.singletonList(quantity), Collections.singletonList(removeItemid), Collections.singletonList(removeQuantity)); + } private List convertToIntegerList(List objects) { List intList = new ArrayList<>(); @@ -238,279 +238,279 @@ public class AbstractPlayerInteraction { return canHoldAll(itemids, quantity); } - - public boolean canHoldAll(List itemids, List quantity) { - return canHoldAll(convertToIntegerList(itemids), convertToIntegerList(quantity), true); + + public boolean canHoldAll(List itemids, List quantity) { + return canHoldAll(convertToIntegerList(itemids), convertToIntegerList(quantity), true); + } + + private boolean canHoldAll(List itemids, List quantity, boolean isInteger) { + int size = Math.min(itemids.size(), quantity.size()); + + List> addedItems = new LinkedList<>(); + for (int i = 0; i < size; i++) { + Item it = new Item(itemids.get(i), (short) 0, quantity.get(i).shortValue()); + addedItems.add(new Pair<>(it, ItemConstants.getInventoryType(itemids.get(i)))); } - - private boolean canHoldAll(List itemids, List quantity, boolean isInteger) { - int size = Math.min(itemids.size(), quantity.size()); - - List> addedItems = new LinkedList<>(); - for(int i = 0; i < size; i++) { - Item it = new Item(itemids.get(i), (short) 0, quantity.get(i).shortValue()); - addedItems.add(new Pair<>(it, ItemConstants.getInventoryType(itemids.get(i)))); - } - - return Inventory.checkSpots(c.getPlayer(), addedItems); + + return Inventory.checkSpots(c.getPlayer(), addedItems); + } + + private List> prepareProofInventoryItems(List> items) { + List> addedItems = new LinkedList<>(); + for (Pair p : items) { + Item it = new Item(p.getLeft(), (short) 0, p.getRight().shortValue()); + addedItems.add(new Pair<>(it, InventoryType.CANHOLD)); } - - private List> prepareProofInventoryItems(List> items) { - List> addedItems = new LinkedList<>(); - for(Pair p : items) { - Item it = new Item(p.getLeft(), (short) 0, p.getRight().shortValue()); - addedItems.add(new Pair<>(it, InventoryType.CANHOLD)); - } - - return addedItems; + + return addedItems; + } + + private List>> prepareInventoryItemList(List itemids, List quantity) { + int size = Math.min(itemids.size(), quantity.size()); + + List>> invList = new ArrayList<>(6); + for (int i = InventoryType.UNDEFINED.getType(); i < InventoryType.CASH.getType(); i++) { + invList.add(new LinkedList<>()); } - - private List>> prepareInventoryItemList(List itemids, List quantity) { - int size = Math.min(itemids.size(), quantity.size()); - - List>> invList = new ArrayList<>(6); - for(int i = InventoryType.UNDEFINED.getType(); i < InventoryType.CASH.getType(); i++) { - invList.add(new LinkedList<>()); - } - - for(int i = 0; i < size; i++) { - int itemid = itemids.get(i); - invList.get(ItemConstants.getInventoryType(itemid).getType()).add(new Pair<>(itemid, quantity.get(i))); - } - - return invList; + + for (int i = 0; i < size; i++) { + int itemid = itemids.get(i); + invList.get(ItemConstants.getInventoryType(itemid).getType()).add(new Pair<>(itemid, quantity.get(i))); } - - public boolean canHoldAllAfterRemoving(List toAddItemids, List toAddQuantity, List toRemoveItemids, List toRemoveQuantity) { - List>> toAddItemList = prepareInventoryItemList(toAddItemids, toAddQuantity); - List>> toRemoveItemList = prepareInventoryItemList(toRemoveItemids, toRemoveQuantity); - - InventoryProof prfInv = (InventoryProof) this.getInventory(InventoryType.CANHOLD); - prfInv.lockInventory(); - try { - for(int i = InventoryType.EQUIP.getType(); i < InventoryType.CASH.getType(); i++) { - List> toAdd = toAddItemList.get(i); - - if(!toAdd.isEmpty()) { - List> toRemove = toRemoveItemList.get(i); - - Inventory inv = this.getInventory(i); - prfInv.cloneContents(inv); - - for(Pair p : toRemove) { - InventoryManipulator.removeById(c, InventoryType.CANHOLD, p.getLeft(), p.getRight(), false, false); - } - - List> addItems = prepareProofInventoryItems(toAdd); - - boolean canHold = Inventory.checkSpots(c.getPlayer(), addItems, true); - if(!canHold) { - return false; - } + + return invList; + } + + public boolean canHoldAllAfterRemoving(List toAddItemids, List toAddQuantity, List toRemoveItemids, List toRemoveQuantity) { + List>> toAddItemList = prepareInventoryItemList(toAddItemids, toAddQuantity); + List>> toRemoveItemList = prepareInventoryItemList(toRemoveItemids, toRemoveQuantity); + + InventoryProof prfInv = (InventoryProof) this.getInventory(InventoryType.CANHOLD); + prfInv.lockInventory(); + try { + for (int i = InventoryType.EQUIP.getType(); i < InventoryType.CASH.getType(); i++) { + List> toAdd = toAddItemList.get(i); + + if (!toAdd.isEmpty()) { + List> toRemove = toRemoveItemList.get(i); + + Inventory inv = this.getInventory(i); + prfInv.cloneContents(inv); + + for (Pair p : toRemove) { + InventoryManipulator.removeById(c, InventoryType.CANHOLD, p.getLeft(), p.getRight(), false, false); + } + + List> addItems = prepareProofInventoryItems(toAdd); + + boolean canHold = Inventory.checkSpots(c.getPlayer(), addItems, true); + if (!canHold) { + return false; } } - } finally { - prfInv.flushContents(); - prfInv.unlockInventory(); } - - return true; - } - - //---- \/ \/ \/ \/ \/ \/ \/ NOT TESTED \/ \/ \/ \/ \/ \/ \/ \/ \/ ---- - - public final QuestStatus getQuestRecord(final int id) { - return c.getPlayer().getQuestNAdd(Quest.getInstance(id)); + } finally { + prfInv.flushContents(); + prfInv.unlockInventory(); } - public final QuestStatus getQuestNoRecord(final int id) { - return c.getPlayer().getQuestNoAdd(Quest.getInstance(id)); - } - - //---- /\ /\ /\ /\ /\ /\ /\ NOT TESTED /\ /\ /\ /\ /\ /\ /\ /\ /\ ---- + return true; + } - public void openNpc(int npcid) { - openNpc(npcid, null); - } + //---- \/ \/ \/ \/ \/ \/ \/ NOT TESTED \/ \/ \/ \/ \/ \/ \/ \/ \/ ---- - public void openNpc(int npcid, String script) { - if (c.getCM() != null) { - return; - } - - c.removeClickedNPC(); - NPCScriptManager.getInstance().dispose(c); - NPCScriptManager.getInstance().start(c, npcid, script, null); - } + public final QuestStatus getQuestRecord(final int id) { + return c.getPlayer().getQuestNAdd(Quest.getInstance(id)); + } - public int getQuestStatus(int id) { - return c.getPlayer().getQuest(Quest.getInstance(id)).getStatus().getId(); - } - - private QuestStatus.Status getQuestStat(int id) { - return c.getPlayer().getQuest(Quest.getInstance(id)).getStatus(); - } - - public boolean isQuestCompleted(int id) { - try { - return getQuestStat(id) == QuestStatus.Status.COMPLETED; - } catch (NullPointerException e) { - e.printStackTrace(); - return false; - } - } + public final QuestStatus getQuestNoRecord(final int id) { + return c.getPlayer().getQuestNoAdd(Quest.getInstance(id)); + } - public boolean isQuestActive(int id) { - return isQuestStarted(id); - } - - public boolean isQuestStarted(int id) { - try { - return getQuestStat(id) == QuestStatus.Status.STARTED; - } catch (NullPointerException e) { - e.printStackTrace(); - return false; - } - } - - public void setQuestProgress(int id, String progress) { - setQuestProgress(id, 0, progress); - } - - public void setQuestProgress(int id, int progress) { - setQuestProgress(id, 0, "" + progress); - } - - public void setQuestProgress(int id, int infoNumber, int progress) { - setQuestProgress(id, infoNumber, "" + progress); - } - - public void setQuestProgress(int id, int infoNumber, String progress) { - c.getPlayer().setQuestProgress(id, infoNumber, progress); - } - - public String getQuestProgress(int id) { - return getQuestProgress(id, 0); - } - - public String getQuestProgress(int id, int infoNumber) { - QuestStatus qs = getPlayer().getQuest(Quest.getInstance(id)); - - if (qs.getInfoNumber() == infoNumber && infoNumber > 0) { - qs = getPlayer().getQuest(Quest.getInstance(infoNumber)); - infoNumber = 0; - } - - if (qs != null) { - return qs.getProgress(infoNumber); - } else { - return ""; - } - } - - public int getQuestProgressInt(int id) { - try { - return Integer.parseInt(getQuestProgress(id)); - } catch (NumberFormatException nfe) { - return 0; - } - } - - public int getQuestProgressInt(int id, int infoNumber) { - try { - return Integer.parseInt(getQuestProgress(id, infoNumber)); - } catch (NumberFormatException nfe) { - return 0; - } - } - - public void resetAllQuestProgress(int id) { - QuestStatus qs = getPlayer().getQuest(Quest.getInstance(id)); - if (qs != null) { - qs.resetAllProgress(); - getPlayer().announceUpdateQuest(DelayedQuestUpdate.UPDATE, qs, false); - } - } - - public void resetQuestProgress(int id, int infoNumber) { - QuestStatus qs = getPlayer().getQuest(Quest.getInstance(id)); - if (qs != null) { - qs.resetProgress(infoNumber); - getPlayer().announceUpdateQuest(DelayedQuestUpdate.UPDATE, qs, false); - } - } - - public boolean forceStartQuest(int id) { - return forceStartQuest(id, 9010000); + //---- /\ /\ /\ /\ /\ /\ /\ NOT TESTED /\ /\ /\ /\ /\ /\ /\ /\ /\ ---- + + public void openNpc(int npcid) { + openNpc(npcid, null); + } + + public void openNpc(int npcid, String script) { + if (c.getCM() != null) { + return; } - public boolean forceStartQuest(int id, int npc) { - return startQuest(id, npc); + c.removeClickedNPC(); + NPCScriptManager.getInstance().dispose(c); + NPCScriptManager.getInstance().start(c, npcid, script, null); + } + + public int getQuestStatus(int id) { + return c.getPlayer().getQuest(Quest.getInstance(id)).getStatus().getId(); + } + + private QuestStatus.Status getQuestStat(int id) { + return c.getPlayer().getQuest(Quest.getInstance(id)).getStatus(); + } + + public boolean isQuestCompleted(int id) { + try { + return getQuestStat(id) == QuestStatus.Status.COMPLETED; + } catch (NullPointerException e) { + e.printStackTrace(); + return false; + } + } + + public boolean isQuestActive(int id) { + return isQuestStarted(id); + } + + public boolean isQuestStarted(int id) { + try { + return getQuestStat(id) == QuestStatus.Status.STARTED; + } catch (NullPointerException e) { + e.printStackTrace(); + return false; + } + } + + public void setQuestProgress(int id, String progress) { + setQuestProgress(id, 0, progress); + } + + public void setQuestProgress(int id, int progress) { + setQuestProgress(id, 0, "" + progress); + } + + public void setQuestProgress(int id, int infoNumber, int progress) { + setQuestProgress(id, infoNumber, "" + progress); + } + + public void setQuestProgress(int id, int infoNumber, String progress) { + c.getPlayer().setQuestProgress(id, infoNumber, progress); + } + + public String getQuestProgress(int id) { + return getQuestProgress(id, 0); + } + + public String getQuestProgress(int id, int infoNumber) { + QuestStatus qs = getPlayer().getQuest(Quest.getInstance(id)); + + if (qs.getInfoNumber() == infoNumber && infoNumber > 0) { + qs = getPlayer().getQuest(Quest.getInstance(infoNumber)); + infoNumber = 0; } - public boolean forceCompleteQuest(int id) { - return forceCompleteQuest(id, 9010000); + if (qs != null) { + return qs.getProgress(infoNumber); + } else { + return ""; + } + } + + public int getQuestProgressInt(int id) { + try { + return Integer.parseInt(getQuestProgress(id)); + } catch (NumberFormatException nfe) { + return 0; + } + } + + public int getQuestProgressInt(int id, int infoNumber) { + try { + return Integer.parseInt(getQuestProgress(id, infoNumber)); + } catch (NumberFormatException nfe) { + return 0; + } + } + + public void resetAllQuestProgress(int id) { + QuestStatus qs = getPlayer().getQuest(Quest.getInstance(id)); + if (qs != null) { + qs.resetAllProgress(); + getPlayer().announceUpdateQuest(DelayedQuestUpdate.UPDATE, qs, false); + } + } + + public void resetQuestProgress(int id, int infoNumber) { + QuestStatus qs = getPlayer().getQuest(Quest.getInstance(id)); + if (qs != null) { + qs.resetProgress(infoNumber); + getPlayer().announceUpdateQuest(DelayedQuestUpdate.UPDATE, qs, false); + } + } + + public boolean forceStartQuest(int id) { + return forceStartQuest(id, 9010000); + } + + public boolean forceStartQuest(int id, int npc) { + return startQuest(id, npc); + } + + public boolean forceCompleteQuest(int id) { + return forceCompleteQuest(id, 9010000); + } + + public boolean forceCompleteQuest(int id, int npc) { + return completeQuest(id, npc); + } + + public boolean startQuest(short id) { + return startQuest((int) id); + } + + public boolean completeQuest(short id) { + return completeQuest((int) id); + } + + public boolean startQuest(int id) { + return startQuest(id, 9010000); + } + + public boolean completeQuest(int id) { + return completeQuest(id, 9010000); + } + + public boolean startQuest(short id, int npc) { + return startQuest((int) id, npc); + } + + public boolean completeQuest(short id, int npc) { + return completeQuest((int) id, npc); + } + + public boolean startQuest(int id, int npc) { + try { + return Quest.getInstance(id).forceStart(getPlayer(), npc); + } catch (NullPointerException ex) { + ex.printStackTrace(); + return false; + } + } + + public boolean completeQuest(int id, int npc) { + try { + return Quest.getInstance(id).forceComplete(getPlayer(), npc); + } catch (NullPointerException ex) { + ex.printStackTrace(); + return false; + } + } + + public Item evolvePet(byte slot, int afterId) { + Pet evolved = null; + Pet target; + + long period = (long) 90 * 24 * 60 * 60 * 1000; //refreshes expiration date: 90 days + + target = getPlayer().getPet(slot); + if (target == null) { + getPlayer().message("Pet could not be evolved..."); + return (null); } - public boolean forceCompleteQuest(int id, int npc) { - return completeQuest(id, npc); - } - - public boolean startQuest(short id) { - return startQuest((int) id); - } - - public boolean completeQuest(short id) { - return completeQuest((int) id); - } - - public boolean startQuest(int id) { - return startQuest(id, 9010000); - } - - public boolean completeQuest(int id) { - return completeQuest(id, 9010000); - } - - public boolean startQuest(short id, int npc) { - return startQuest((int) id, npc); - } - - public boolean completeQuest(short id, int npc) { - return completeQuest((int) id, npc); - } - - public boolean startQuest(int id, int npc) { - try { - return Quest.getInstance(id).forceStart(getPlayer(), npc); - } catch (NullPointerException ex) { - ex.printStackTrace(); - return false; - } - } - - public boolean completeQuest(int id, int npc) { - try { - return Quest.getInstance(id).forceComplete(getPlayer(), npc); - } catch (NullPointerException ex) { - ex.printStackTrace(); - return false; - } - } - - public Item evolvePet(byte slot, int afterId) { - Pet evolved = null; - Pet target; - - long period = (long) 90 * 24 * 60 * 60 * 1000; //refreshes expiration date: 90 days - - target = getPlayer().getPet(slot); - if(target == null) { - getPlayer().message("Pet could not be evolved..."); - return(null); - } - - Item tmp = gainItem(afterId, (short) 1, false, true, period, target); + Item tmp = gainItem(afterId, (short) 1, false, true, period, target); /* evolved = Pet.loadFromDb(tmp.getItemId(), tmp.getPosition(), tmp.getPetId()); @@ -532,662 +532,662 @@ public class AbstractPlayerInteraction { c.sendPacket(PacketCreator.enableActions()); chr.getClient().getWorldServer().registerPetHunger(chr, chr.getPetIndex(evolved)); */ - - InventoryManipulator.removeFromSlot(c, InventoryType.CASH, target.getPosition(), (short) 1, false); - - return evolved; - } - - public void gainItem(int id, short quantity) { - gainItem(id, quantity, false, true); - } - public void gainItem(int id, short quantity, boolean show) {//this will fk randomStats equip :P - gainItem(id, quantity, false, show); - } + InventoryManipulator.removeFromSlot(c, InventoryType.CASH, target.getPosition(), (short) 1, false); - public void gainItem(int id, boolean show) { - gainItem(id, (short) 1, false, show); - } + return evolved; + } - public void gainItem(int id) { - gainItem(id, (short) 1, false, true); - } + public void gainItem(int id, short quantity) { + gainItem(id, quantity, false, true); + } - public Item gainItem(int id, short quantity, boolean randomStats, boolean showMessage) { - return gainItem(id, quantity, randomStats, showMessage, -1); - } + public void gainItem(int id, short quantity, boolean show) {//this will fk randomStats equip :P + gainItem(id, quantity, false, show); + } - public Item gainItem(int id, short quantity, boolean randomStats, boolean showMessage, long expires) { - return gainItem(id, quantity, randomStats, showMessage, expires, null); - } - - public Item gainItem(int id, short quantity, boolean randomStats, boolean showMessage, long expires, Pet from) { - Item item = null; - Pet evolved; - int petId = -1; - - if (quantity >= 0) { - if (ItemConstants.isPet(id)) { - petId = Pet.createPet(id); + public void gainItem(int id, boolean show) { + gainItem(id, (short) 1, false, show); + } - if(from != null) { - evolved = Pet.loadFromDb(id, (short) 0, petId); + public void gainItem(int id) { + gainItem(id, (short) 1, false, true); + } - Point pos = getPlayer().getPosition(); - pos.y -= 12; - evolved.setPos(pos); - evolved.setFh(getPlayer().getMap().getFootholds().findBelow(evolved.getPos()).getId()); - evolved.setStance(0); - evolved.setSummoned(true); + public Item gainItem(int id, short quantity, boolean randomStats, boolean showMessage) { + return gainItem(id, quantity, randomStats, showMessage, -1); + } - evolved.setName(from.getName().compareTo(ItemInformationProvider.getInstance().getName(from.getItemId())) != 0 ? from.getName() : ItemInformationProvider.getInstance().getName(id)); - evolved.setCloseness(from.getCloseness()); - evolved.setFullness(from.getFullness()); - evolved.setLevel(from.getLevel()); - evolved.setExpiration(System.currentTimeMillis() + expires); - evolved.saveToDb(); - } + public Item gainItem(int id, short quantity, boolean randomStats, boolean showMessage, long expires) { + return gainItem(id, quantity, randomStats, showMessage, expires, null); + } - //InventoryManipulator.addById(c, id, (short) 1, null, petId, expires == -1 ? -1 : System.currentTimeMillis() + expires); - } - - ItemInformationProvider ii = ItemInformationProvider.getInstance(); + public Item gainItem(int id, short quantity, boolean randomStats, boolean showMessage, long expires, Pet from) { + Item item = null; + Pet evolved; + int petId = -1; - if (ItemConstants.getInventoryType(id).equals(InventoryType.EQUIP)) { - item = ii.getEquipById(id); - - if(item != null) { - Equip it = (Equip)item; - if (ItemConstants.isAccessory(item.getItemId()) && it.getUpgradeSlots() <= 0) { - it.setUpgradeSlots(3); - } - - if(YamlConfig.config.server.USE_ENHANCED_CRAFTING == true && c.getPlayer().getCS() == true) { - Equip eqp = (Equip)item; - if(!(c.getPlayer().isGM() && YamlConfig.config.server.USE_PERFECT_GM_SCROLL)) { - eqp.setUpgradeSlots((byte)(eqp.getUpgradeSlots() + 1)); - } - item = ItemInformationProvider.getInstance().scrollEquipWithId(item, 2049100, true, 2049100, c.getPlayer().isGM()); - } - } - } else { - item = new Item(id, (short) 0, quantity, petId); - } + if (quantity >= 0) { + if (ItemConstants.isPet(id)) { + petId = Pet.createPet(id); - if (expires >= 0) { - item.setExpiration(System.currentTimeMillis() + expires); - } + if (from != null) { + evolved = Pet.loadFromDb(id, (short) 0, petId); - if (!InventoryManipulator.checkSpace(c, id, quantity, "")) { - c.getPlayer().dropMessage(1, "Your inventory is full. Please remove an item from your " + ItemConstants.getInventoryType(id).name() + " inventory."); - return null; - } - if (ItemConstants.getInventoryType(id) == InventoryType.EQUIP) { - if (randomStats) { - InventoryManipulator.addFromDrop(c, ii.randomizeStats((Equip) item), false, petId); - } else { - InventoryManipulator.addFromDrop(c, item, false, petId); - } - } else { - InventoryManipulator.addFromDrop(c, item, false, petId); - } - } else { - InventoryManipulator.removeById(c, ItemConstants.getInventoryType(id), id, -quantity, true, false); - } - if (showMessage) { - c.sendPacket(PacketCreator.getShowItemGain(id, quantity, true)); - } + Point pos = getPlayer().getPosition(); + pos.y -= 12; + evolved.setPos(pos); + evolved.setFh(getPlayer().getMap().getFootholds().findBelow(evolved.getPos()).getId()); + evolved.setStance(0); + evolved.setSummoned(true); - return item; - } - - public void gainFame(int delta) { - getPlayer().gainFame(delta); - } - - public void changeMusic(String songName) { - getPlayer().getMap().broadcastMessage(PacketCreator.musicChange(songName)); - } - - public void playerMessage(int type, String message) { - c.sendPacket(PacketCreator.serverNotice(type, message)); - } - - public void message(String message) { - getPlayer().message(message); - } - - public void dropMessage(int type, String message) { - getPlayer().dropMessage(type, message); - } - - public void mapMessage(int type, String message) { - getPlayer().getMap().broadcastMessage(PacketCreator.serverNotice(type, message)); - } - - public void mapEffect(String path) { - c.sendPacket(PacketCreator.mapEffect(path)); - } - - public void mapSound(String path) { - c.sendPacket(PacketCreator.mapSound(path)); - } - - public void displayAranIntro() { - String intro = ""; - switch (c.getPlayer().getMapId()) { - case 914090010: - intro = "Effect/Direction1.img/aranTutorial/Scene0"; - break; - case 914090011: - intro = "Effect/Direction1.img/aranTutorial/Scene1" + (c.getPlayer().getGender() == 0 ? "0" : "1"); - break; - case 914090012: - intro = "Effect/Direction1.img/aranTutorial/Scene2" + (c.getPlayer().getGender() == 0 ? "0" : "1"); - break; - case 914090013: - intro = "Effect/Direction1.img/aranTutorial/Scene3"; - break; - case 914090100: - intro = "Effect/Direction1.img/aranTutorial/HandedPoleArm" + (c.getPlayer().getGender() == 0 ? "0" : "1"); - break; - case 914090200: - intro = "Effect/Direction1.img/aranTutorial/Maha"; - break; - } - showIntro(intro); - } - - public void showIntro(String path) { - c.sendPacket(PacketCreator.showIntro(path)); - } - - public void showInfo(String path) { - c.sendPacket(PacketCreator.showInfo(path)); - c.sendPacket(PacketCreator.enableActions()); - } - - public void guildMessage(int type, String message) { - if (getGuild() != null) { - getGuild().guildMessage(PacketCreator.serverNotice(type, message)); - } - } - - public Guild getGuild() { - try { - return Server.getInstance().getGuild(getPlayer().getGuildId(), getPlayer().getWorld(), null); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - public Party getParty() { - return getPlayer().getParty(); - } - - public boolean isLeader() { - return isPartyLeader(); - } - - public boolean isGuildLeader() { - return getPlayer().isGuildLeader(); - } - - public boolean isPartyLeader() { - if (getParty() == null) { - return false; + evolved.setName(from.getName().compareTo(ItemInformationProvider.getInstance().getName(from.getItemId())) != 0 ? from.getName() : ItemInformationProvider.getInstance().getName(id)); + evolved.setCloseness(from.getCloseness()); + evolved.setFullness(from.getFullness()); + evolved.setLevel(from.getLevel()); + evolved.setExpiration(System.currentTimeMillis() + expires); + evolved.saveToDb(); } - - return getParty().getLeaderId() == getPlayer().getId(); - } - - public boolean isEventLeader() { - return getEventInstance() != null && getPlayer().getId() == getEventInstance().getLeaderId(); - } - - public void givePartyItems(int id, short quantity, List party) { - for (Character chr : party) { - Client cl = chr.getClient(); - if (quantity >= 0) { - InventoryManipulator.addById(cl, id, quantity); - } else { - InventoryManipulator.removeById(cl, ItemConstants.getInventoryType(id), id, -quantity, true, false); - } - cl.sendPacket(PacketCreator.getShowItemGain(id, quantity, true)); - } - } - public void removeHPQItems() { - int[] items = {4001095, 4001096, 4001097, 4001098, 4001099, 4001100, 4001101}; + //InventoryManipulator.addById(c, id, (short) 1, null, petId, expires == -1 ? -1 : System.currentTimeMillis() + expires); + } + + ItemInformationProvider ii = ItemInformationProvider.getInstance(); + + if (ItemConstants.getInventoryType(id).equals(InventoryType.EQUIP)) { + item = ii.getEquipById(id); + + if (item != null) { + Equip it = (Equip) item; + if (ItemConstants.isAccessory(item.getItemId()) && it.getUpgradeSlots() <= 0) { + it.setUpgradeSlots(3); + } + + if (YamlConfig.config.server.USE_ENHANCED_CRAFTING == true && c.getPlayer().getCS() == true) { + Equip eqp = (Equip) item; + if (!(c.getPlayer().isGM() && YamlConfig.config.server.USE_PERFECT_GM_SCROLL)) { + eqp.setUpgradeSlots((byte) (eqp.getUpgradeSlots() + 1)); + } + item = ItemInformationProvider.getInstance().scrollEquipWithId(item, 2049100, true, 2049100, c.getPlayer().isGM()); + } + } + } else { + item = new Item(id, (short) 0, quantity, petId); + } + + if (expires >= 0) { + item.setExpiration(System.currentTimeMillis() + expires); + } + + if (!InventoryManipulator.checkSpace(c, id, quantity, "")) { + c.getPlayer().dropMessage(1, "Your inventory is full. Please remove an item from your " + ItemConstants.getInventoryType(id).name() + " inventory."); + return null; + } + if (ItemConstants.getInventoryType(id) == InventoryType.EQUIP) { + if (randomStats) { + InventoryManipulator.addFromDrop(c, ii.randomizeStats((Equip) item), false, petId); + } else { + InventoryManipulator.addFromDrop(c, item, false, petId); + } + } else { + InventoryManipulator.addFromDrop(c, item, false, petId); + } + } else { + InventoryManipulator.removeById(c, ItemConstants.getInventoryType(id), id, -quantity, true, false); + } + if (showMessage) { + c.sendPacket(PacketCreator.getShowItemGain(id, quantity, true)); + } + + return item; + } + + public void gainFame(int delta) { + getPlayer().gainFame(delta); + } + + public void changeMusic(String songName) { + getPlayer().getMap().broadcastMessage(PacketCreator.musicChange(songName)); + } + + public void playerMessage(int type, String message) { + c.sendPacket(PacketCreator.serverNotice(type, message)); + } + + public void message(String message) { + getPlayer().message(message); + } + + public void dropMessage(int type, String message) { + getPlayer().dropMessage(type, message); + } + + public void mapMessage(int type, String message) { + getPlayer().getMap().broadcastMessage(PacketCreator.serverNotice(type, message)); + } + + public void mapEffect(String path) { + c.sendPacket(PacketCreator.mapEffect(path)); + } + + public void mapSound(String path) { + c.sendPacket(PacketCreator.mapSound(path)); + } + + public void displayAranIntro() { + String intro = ""; + switch (c.getPlayer().getMapId()) { + case 914090010: + intro = "Effect/Direction1.img/aranTutorial/Scene0"; + break; + case 914090011: + intro = "Effect/Direction1.img/aranTutorial/Scene1" + (c.getPlayer().getGender() == 0 ? "0" : "1"); + break; + case 914090012: + intro = "Effect/Direction1.img/aranTutorial/Scene2" + (c.getPlayer().getGender() == 0 ? "0" : "1"); + break; + case 914090013: + intro = "Effect/Direction1.img/aranTutorial/Scene3"; + break; + case 914090100: + intro = "Effect/Direction1.img/aranTutorial/HandedPoleArm" + (c.getPlayer().getGender() == 0 ? "0" : "1"); + break; + case 914090200: + intro = "Effect/Direction1.img/aranTutorial/Maha"; + break; + } + showIntro(intro); + } + + public void showIntro(String path) { + c.sendPacket(PacketCreator.showIntro(path)); + } + + public void showInfo(String path) { + c.sendPacket(PacketCreator.showInfo(path)); + c.sendPacket(PacketCreator.enableActions()); + } + + public void guildMessage(int type, String message) { + if (getGuild() != null) { + getGuild().guildMessage(PacketCreator.serverNotice(type, message)); + } + } + + public Guild getGuild() { + try { + return Server.getInstance().getGuild(getPlayer().getGuildId(), getPlayer().getWorld(), null); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public Party getParty() { + return getPlayer().getParty(); + } + + public boolean isLeader() { + return isPartyLeader(); + } + + public boolean isGuildLeader() { + return getPlayer().isGuildLeader(); + } + + public boolean isPartyLeader() { + if (getParty() == null) { + return false; + } + + return getParty().getLeaderId() == getPlayer().getId(); + } + + public boolean isEventLeader() { + return getEventInstance() != null && getPlayer().getId() == getEventInstance().getLeaderId(); + } + + public void givePartyItems(int id, short quantity, List party) { + for (Character chr : party) { + Client cl = chr.getClient(); + if (quantity >= 0) { + InventoryManipulator.addById(cl, id, quantity); + } else { + InventoryManipulator.removeById(cl, ItemConstants.getInventoryType(id), id, -quantity, true, false); + } + cl.sendPacket(PacketCreator.getShowItemGain(id, quantity, true)); + } + } + + public void removeHPQItems() { + int[] items = {4001095, 4001096, 4001097, 4001098, 4001099, 4001100, 4001101}; for (int item : items) { removePartyItems(item); } - } - - public void removePartyItems(int id) { - if (getParty() == null) { - removeAll(id); - return; - } - for (PartyCharacter mpc : getParty().getMembers()) { - if (mpc == null || !mpc.isOnline()) { - continue; - } - - Character chr = mpc.getPlayer(); - if (chr != null && chr.getClient() != null){ - removeAll(id, chr.getClient()); - } - } - } - - public void giveCharacterExp(int amount, Character chr) { - chr.gainExp((amount * chr.getExpRate()), true, true); - } - - public void givePartyExp(int amount, List party) { - for (Character chr : party) { - giveCharacterExp(amount, chr); - } - } - - public void givePartyExp(String PQ) { - givePartyExp(PQ, true); - } - - public void givePartyExp(String PQ, boolean instance) { - //1 player = +0% bonus (100) - //2 players = +0% bonus (100) - //3 players = +0% bonus (100) - //4 players = +10% bonus (110) - //5 players = +20% bonus (120) - //6 players = +30% bonus (130) - Party party = getPlayer().getParty(); - int size = party.getMembers().size(); - - if(instance) { - for(PartyCharacter member: party.getMembers()) { - if(member == null || !member.isOnline()){ - size--; - } else { - Character chr = member.getPlayer(); - if(chr != null && chr.getEventInstance() == null) { - size--; - } - } - } - } - - int bonus = size < 4 ? 100 : 70 + (size * 10); - for (PartyCharacter member : party.getMembers()) { - if(member == null || !member.isOnline()){ - continue; - } - Character player = member.getPlayer(); - if(player == null) { - continue; - } - if(instance && player.getEventInstance() == null){ - continue; // They aren't in the instance, don't give EXP. - } - int base = PartyQuest.getExp(PQ, player.getLevel()); - int exp = base * bonus / 100; - player.gainExp(exp, true, true); - if(YamlConfig.config.server.PQ_BONUS_EXP_RATE > 0 && System.currentTimeMillis() <= YamlConfig.config.server.EVENT_END_TIMESTAMP) { - player.gainExp((int) (exp * YamlConfig.config.server.PQ_BONUS_EXP_RATE), true, true); - } - } - } - - public void removeFromParty(int id, List party) { - for (Character chr : party) { - InventoryType type = ItemConstants.getInventoryType(id); - Inventory iv = chr.getInventory(type); - int possesed = iv.countById(id); - if (possesed > 0) { - InventoryManipulator.removeById(c, ItemConstants.getInventoryType(id), id, possesed, true, false); - chr.sendPacket(PacketCreator.getShowItemGain(id, (short) -possesed, true)); - } - } - } - - public void removeAll(int id) { - removeAll(id, c); - } - - public void removeAll(int id, Client cl) { - InventoryType invType = ItemConstants.getInventoryType(id); - int possessed = cl.getPlayer().getInventory(invType).countById(id); - if (possessed > 0) { - InventoryManipulator.removeById(cl, ItemConstants.getInventoryType(id), id, possessed, true, false); - cl.sendPacket(PacketCreator.getShowItemGain(id, (short) -possessed, true)); - } - - if(invType == InventoryType.EQUIP) { - if(cl.getPlayer().getInventory(InventoryType.EQUIPPED).countById(id) > 0) { - InventoryManipulator.removeById(cl, InventoryType.EQUIPPED, id, 1, true, false); - cl.sendPacket(PacketCreator.getShowItemGain(id, (short) -1, true)); - } - } - } - - public int getMapId() { - return c.getPlayer().getMap().getId(); - } - - public int getPlayerCount(int mapid) { - return c.getChannelServer().getMapFactory().getMap(mapid).getCharacters().size(); - } - - public void showInstruction(String msg, int width, int height) { - c.sendPacket(PacketCreator.sendHint(msg, width, height)); - c.sendPacket(PacketCreator.enableActions()); - } - - public void disableMinimap() { - c.sendPacket(PacketCreator.disableMinimap()); - } - - public boolean isAllReactorState(final int reactorId, final int state) { - return c.getPlayer().getMap().isAllReactorState(reactorId, state); - } - - public void resetMap(int mapid) { - getMap(mapid).resetReactors(); - getMap(mapid).killAllMonsters(); - for (MapObject i : getMap(mapid).getMapObjectsInRange(c.getPlayer().getPosition(), Double.POSITIVE_INFINITY, Arrays.asList(MapObjectType.ITEM))) { - getMap(mapid).removeMapObject(i); - getMap(mapid).broadcastMessage(PacketCreator.removeItemFromMap(i.getObjectId(), 0, c.getPlayer().getId())); - } - } - - public void useItem(int id) { - ItemInformationProvider.getInstance().getItemEffect(id).applyTo(c.getPlayer()); - c.sendPacket(PacketCreator.getItemMessage(id));//Useful shet :3 - } - - public void cancelItem(final int id) { - getPlayer().cancelEffect(ItemInformationProvider.getInstance().getItemEffect(id), false, -1); - } - - public void teachSkill(int skillid, byte level, byte masterLevel, long expiration) { - teachSkill(skillid, level, masterLevel, expiration, false); } - public void teachSkill(int skillid, byte level, byte masterLevel, long expiration, boolean force) { - Skill skill = SkillFactory.getSkill(skillid); - Character.SkillEntry skillEntry = getPlayer().getSkills().get(skill); - if (skillEntry != null) { - if (!force && level > -1) { - getPlayer().changeSkillLevel(skill, (byte) Math.max(skillEntry.skillevel, level), Math.max(skillEntry.masterlevel, masterLevel), expiration == -1 ? -1 : Math.max(skillEntry.expiration, expiration)); - return; - } - } else if (GameConstants.isAranSkills(skillid)) { - c.sendPacket(PacketCreator.showInfo("Effect/BasicEff.img/AranGetSkill")); + public void removePartyItems(int id) { + if (getParty() == null) { + removeAll(id); + return; + } + for (PartyCharacter mpc : getParty().getMembers()) { + if (mpc == null || !mpc.isOnline()) { + continue; } - - getPlayer().changeSkillLevel(skill, level, masterLevel, expiration); - } - public void removeEquipFromSlot(short slot) { - Item tempItem = c.getPlayer().getInventory(InventoryType.EQUIPPED).getItem(slot); - InventoryManipulator.removeFromSlot(c, InventoryType.EQUIPPED, slot, tempItem.getQuantity(), false, false); - } - - public void gainAndEquip(int itemid, short slot) { - final Item old = c.getPlayer().getInventory(InventoryType.EQUIPPED).getItem(slot); - if (old != null) { - InventoryManipulator.removeFromSlot(c, InventoryType.EQUIPPED, slot, old.getQuantity(), false, false); - } - final Item newItem = ItemInformationProvider.getInstance().getEquipById(itemid); - newItem.setPosition(slot); - c.getPlayer().getInventory(InventoryType.EQUIPPED).addItemFromDB(newItem); - c.sendPacket(PacketCreator.modifyInventory(false, Collections.singletonList(new ModifyInventory(0, newItem)))); - } - - public void spawnNpc(int npcId, Point pos, MapleMap map) { - NPC npc = LifeFactory.getNPC(npcId); - if (npc != null) { - npc.setPosition(pos); - npc.setCy(pos.y); - npc.setRx0(pos.x + 50); - npc.setRx1(pos.x - 50); - npc.setFh(map.getFootholds().findBelow(pos).getId()); - map.addMapObject(npc); - map.broadcastMessage(PacketCreator.spawnNPC(npc)); - } + Character chr = mpc.getPlayer(); + if (chr != null && chr.getClient() != null) { + removeAll(id, chr.getClient()); + } } - - public void spawnMonster(int id, int x, int y) { - Monster monster = LifeFactory.getMonster(id); - monster.setPosition(new Point(x, y)); - getPlayer().getMap().spawnMonster(monster); - } - - public Monster getMonsterLifeFactory(int mid) { - return LifeFactory.getMonster(mid); - } - - public MobSkill getMobSkill(int skill, int level) { - return MobSkillFactory.getMobSkill(skill, level); - } + } - public void spawnGuide() { - c.sendPacket(PacketCreator.spawnGuide(true)); - } + public void giveCharacterExp(int amount, Character chr) { + chr.gainExp((amount * chr.getExpRate()), true, true); + } - public void removeGuide() { - c.sendPacket(PacketCreator.spawnGuide(false)); - } - - public void displayGuide(int num) { - c.sendPacket(PacketCreator.showInfo("UI/tutorial.img/" + num)); - } - - public void goDojoUp() { - c.sendPacket(PacketCreator.dojoWarpUp()); - } - - public void resetDojoEnergy() { - c.getPlayer().setDojoEnergy(0); - } - - public void resetPartyDojoEnergy() { - for(Character pchr: c.getPlayer().getPartyMembersOnSameMap()) { - pchr.setDojoEnergy(0); - } + public void givePartyExp(int amount, List party) { + for (Character chr : party) { + giveCharacterExp(amount, chr); } + } - public void enableActions() { - c.sendPacket(PacketCreator.enableActions()); - } + public void givePartyExp(String PQ) { + givePartyExp(PQ, true); + } - public void showEffect(String effect){ - c.sendPacket(PacketCreator.showEffect(effect)); - } + public void givePartyExp(String PQ, boolean instance) { + //1 player = +0% bonus (100) + //2 players = +0% bonus (100) + //3 players = +0% bonus (100) + //4 players = +10% bonus (110) + //5 players = +20% bonus (120) + //6 players = +30% bonus (130) + Party party = getPlayer().getParty(); + int size = party.getMembers().size(); - public void dojoEnergy() { - c.sendPacket(PacketCreator.getEnergy("energy", getPlayer().getDojoEnergy())); - } - - public void talkGuide(String message) { - c.sendPacket(PacketCreator.talkGuide(message)); - } - - public void guideHint(int hint) { - c.sendPacket(PacketCreator.guideHint(hint)); - } - - public void updateAreaInfo(Short area, String info) { - c.getPlayer().updateAreaInfo(area, info); - c.sendPacket(PacketCreator.enableActions());//idk, nexon does the same :P - } - - public boolean containsAreaInfo(short area, String info) { - return c.getPlayer().containsAreaInfo(area, info); - } - - public void earnTitle(String msg) { - c.sendPacket(PacketCreator.earnTitleMessage(msg)); - } - - public void showInfoText(String msg) { - c.sendPacket(PacketCreator.showInfoText(msg)); - } - - public void openUI(byte ui) { - c.sendPacket(PacketCreator.openUI(ui)); - } - - public void lockUI() { - c.sendPacket(PacketCreator.disableUI(true)); - c.sendPacket(PacketCreator.lockUI(true)); - } - - public void unlockUI() { - c.sendPacket(PacketCreator.disableUI(false)); - c.sendPacket(PacketCreator.lockUI(false)); - } - - public void playSound(String sound) { - getPlayer().getMap().broadcastMessage(PacketCreator.environmentChange(sound, 4)); - } - - public void environmentChange(String env, int mode) { - getPlayer().getMap().broadcastMessage(PacketCreator.environmentChange(env, mode)); - } - - public String numberWithCommas(int number) { - return GameConstants.numberWithCommas(number); - } - - public Pyramid getPyramid() { - return (Pyramid) getPlayer().getPartyQuest(); - } - - public int createExpedition(ExpeditionType type) { - return createExpedition(type, false, 0, 0); - } - - public int createExpedition(ExpeditionType type, boolean silent, int minPlayers, int maxPlayers) { - Character player = getPlayer(); - Expedition exped = new Expedition(player, type, silent, minPlayers, maxPlayers); - - int channel = player.getMap().getChannelServer().getId(); - if (!ExpeditionBossLog.attemptBoss(player.getId(), channel, exped, false)) { // thanks Conrad for noticing missing expeditions entry limit - return 1; - } - - if (exped.addChannelExpedition(player.getClient().getChannelServer())) { - return 0; + if (instance) { + for (PartyCharacter member : party.getMembers()) { + if (member == null || !member.isOnline()) { + size--; } else { - return -1; + Character chr = member.getPlayer(); + if (chr != null && chr.getEventInstance() == null) { + size--; + } } - } - - public void endExpedition(Expedition exped) { - exped.dispose(true); - exped.removeChannelExpedition(getPlayer().getClient().getChannelServer()); - } - - public Expedition getExpedition(ExpeditionType type) { - return getPlayer().getClient().getChannelServer().getExpedition(type); - } - - public String getExpeditionMemberNames(ExpeditionType type) { - String members = ""; - Expedition exped = getExpedition(type); - for (String memberName : exped.getMembers().values()) { - members += "" + memberName + ", "; - } - return members; + } } - public boolean isLeaderExpedition(ExpeditionType type) { - Expedition exped = getExpedition(type); - return exped.isLeader(getPlayer()); + int bonus = size < 4 ? 100 : 70 + (size * 10); + for (PartyCharacter member : party.getMembers()) { + if (member == null || !member.isOnline()) { + continue; + } + Character player = member.getPlayer(); + if (player == null) { + continue; + } + if (instance && player.getEventInstance() == null) { + continue; // They aren't in the instance, don't give EXP. + } + int base = PartyQuest.getExp(PQ, player.getLevel()); + int exp = base * bonus / 100; + player.gainExp(exp, true, true); + if (YamlConfig.config.server.PQ_BONUS_EXP_RATE > 0 && System.currentTimeMillis() <= YamlConfig.config.server.EVENT_END_TIMESTAMP) { + player.gainExp((int) (exp * YamlConfig.config.server.PQ_BONUS_EXP_RATE), true, true); + } } - - public long getJailTimeLeft() { - return getPlayer().getJailExpirationTimeLeft(); + } + + public void removeFromParty(int id, List party) { + for (Character chr : party) { + InventoryType type = ItemConstants.getInventoryType(id); + Inventory iv = chr.getInventory(type); + int possesed = iv.countById(id); + if (possesed > 0) { + InventoryManipulator.removeById(c, ItemConstants.getInventoryType(id), id, possesed, true, false); + chr.sendPacket(PacketCreator.getShowItemGain(id, (short) -possesed, true)); + } } - - public List getDriedPets() { - List list = new LinkedList<>(); - - long curTime = System.currentTimeMillis(); - for(Item it : getPlayer().getInventory(InventoryType.CASH).list()) { - if(ItemConstants.isPet(it.getItemId()) && it.getExpiration() < curTime) { - Pet pet = it.getPet(); - if (pet != null) { - list.add(pet); - } - } - } - - return list; - } - - public List getUnclaimedMarriageGifts() { - return Marriage.loadGiftItemsFromDb(this.getClient(), this.getPlayer().getId()); - } - - public boolean startDungeonInstance(int dungeonid) { - return c.getChannelServer().addMiniDungeon(dungeonid); - } - - public boolean canGetFirstJob(int jobType) { - if (YamlConfig.config.server.USE_AUTOASSIGN_STARTERS_AP) { - return true; - } - - Character chr = this.getPlayer(); - - switch(jobType) { - case 1: - return chr.getStr() >= 35; - - case 2: - return chr.getInt() >= 20; - - case 3: - case 4: - return chr.getDex() >= 25; - - case 5: - return chr.getDex() >= 20; - - default: - return true; - } - } - - public String getFirstJobStatRequirement(int jobType) { - switch(jobType) { - case 1: - return "STR " + 35; - - case 2: - return "INT " + 20; - - case 3: - case 4: - return "DEX " + 25; - - case 5: - return "DEX " + 20; - } - - return null; - } - - public void npcTalk(int npcid, String message) { - c.sendPacket(PacketCreator.getNPCTalk(npcid, (byte) 0, message, "00 00", (byte) 0)); + } + + public void removeAll(int id) { + removeAll(id, c); + } + + public void removeAll(int id, Client cl) { + InventoryType invType = ItemConstants.getInventoryType(id); + int possessed = cl.getPlayer().getInventory(invType).countById(id); + if (possessed > 0) { + InventoryManipulator.removeById(cl, ItemConstants.getInventoryType(id), id, possessed, true, false); + cl.sendPacket(PacketCreator.getShowItemGain(id, (short) -possessed, true)); } - public long getCurrentTime() { - return Server.getInstance().getCurrentTime(); - } + if (invType == InventoryType.EQUIP) { + if (cl.getPlayer().getInventory(InventoryType.EQUIPPED).countById(id) > 0) { + InventoryManipulator.removeById(cl, InventoryType.EQUIPPED, id, 1, true, false); + cl.sendPacket(PacketCreator.getShowItemGain(id, (short) -1, true)); + } + } + } + + public int getMapId() { + return c.getPlayer().getMap().getId(); + } + + public int getPlayerCount(int mapid) { + return c.getChannelServer().getMapFactory().getMap(mapid).getCharacters().size(); + } + + public void showInstruction(String msg, int width, int height) { + c.sendPacket(PacketCreator.sendHint(msg, width, height)); + c.sendPacket(PacketCreator.enableActions()); + } + + public void disableMinimap() { + c.sendPacket(PacketCreator.disableMinimap()); + } + + public boolean isAllReactorState(final int reactorId, final int state) { + return c.getPlayer().getMap().isAllReactorState(reactorId, state); + } + + public void resetMap(int mapid) { + getMap(mapid).resetReactors(); + getMap(mapid).killAllMonsters(); + for (MapObject i : getMap(mapid).getMapObjectsInRange(c.getPlayer().getPosition(), Double.POSITIVE_INFINITY, Arrays.asList(MapObjectType.ITEM))) { + getMap(mapid).removeMapObject(i); + getMap(mapid).broadcastMessage(PacketCreator.removeItemFromMap(i.getObjectId(), 0, c.getPlayer().getId())); + } + } + + public void useItem(int id) { + ItemInformationProvider.getInstance().getItemEffect(id).applyTo(c.getPlayer()); + c.sendPacket(PacketCreator.getItemMessage(id));//Useful shet :3 + } + + public void cancelItem(final int id) { + getPlayer().cancelEffect(ItemInformationProvider.getInstance().getItemEffect(id), false, -1); + } + + public void teachSkill(int skillid, byte level, byte masterLevel, long expiration) { + teachSkill(skillid, level, masterLevel, expiration, false); + } + + public void teachSkill(int skillid, byte level, byte masterLevel, long expiration, boolean force) { + Skill skill = SkillFactory.getSkill(skillid); + Character.SkillEntry skillEntry = getPlayer().getSkills().get(skill); + if (skillEntry != null) { + if (!force && level > -1) { + getPlayer().changeSkillLevel(skill, (byte) Math.max(skillEntry.skillevel, level), Math.max(skillEntry.masterlevel, masterLevel), expiration == -1 ? -1 : Math.max(skillEntry.expiration, expiration)); + return; + } + } else if (GameConstants.isAranSkills(skillid)) { + c.sendPacket(PacketCreator.showInfo("Effect/BasicEff.img/AranGetSkill")); + } + + getPlayer().changeSkillLevel(skill, level, masterLevel, expiration); + } + + public void removeEquipFromSlot(short slot) { + Item tempItem = c.getPlayer().getInventory(InventoryType.EQUIPPED).getItem(slot); + InventoryManipulator.removeFromSlot(c, InventoryType.EQUIPPED, slot, tempItem.getQuantity(), false, false); + } + + public void gainAndEquip(int itemid, short slot) { + final Item old = c.getPlayer().getInventory(InventoryType.EQUIPPED).getItem(slot); + if (old != null) { + InventoryManipulator.removeFromSlot(c, InventoryType.EQUIPPED, slot, old.getQuantity(), false, false); + } + final Item newItem = ItemInformationProvider.getInstance().getEquipById(itemid); + newItem.setPosition(slot); + c.getPlayer().getInventory(InventoryType.EQUIPPED).addItemFromDB(newItem); + c.sendPacket(PacketCreator.modifyInventory(false, Collections.singletonList(new ModifyInventory(0, newItem)))); + } + + public void spawnNpc(int npcId, Point pos, MapleMap map) { + NPC npc = LifeFactory.getNPC(npcId); + if (npc != null) { + npc.setPosition(pos); + npc.setCy(pos.y); + npc.setRx0(pos.x + 50); + npc.setRx1(pos.x - 50); + npc.setFh(map.getFootholds().findBelow(pos).getId()); + map.addMapObject(npc); + map.broadcastMessage(PacketCreator.spawnNPC(npc)); + } + } + + public void spawnMonster(int id, int x, int y) { + Monster monster = LifeFactory.getMonster(id); + monster.setPosition(new Point(x, y)); + getPlayer().getMap().spawnMonster(monster); + } + + public Monster getMonsterLifeFactory(int mid) { + return LifeFactory.getMonster(mid); + } + + public MobSkill getMobSkill(int skill, int level) { + return MobSkillFactory.getMobSkill(skill, level); + } + + public void spawnGuide() { + c.sendPacket(PacketCreator.spawnGuide(true)); + } + + public void removeGuide() { + c.sendPacket(PacketCreator.spawnGuide(false)); + } + + public void displayGuide(int num) { + c.sendPacket(PacketCreator.showInfo("UI/tutorial.img/" + num)); + } + + public void goDojoUp() { + c.sendPacket(PacketCreator.dojoWarpUp()); + } + + public void resetDojoEnergy() { + c.getPlayer().setDojoEnergy(0); + } + + public void resetPartyDojoEnergy() { + for (Character pchr : c.getPlayer().getPartyMembersOnSameMap()) { + pchr.setDojoEnergy(0); + } + } + + public void enableActions() { + c.sendPacket(PacketCreator.enableActions()); + } + + public void showEffect(String effect) { + c.sendPacket(PacketCreator.showEffect(effect)); + } + + public void dojoEnergy() { + c.sendPacket(PacketCreator.getEnergy("energy", getPlayer().getDojoEnergy())); + } + + public void talkGuide(String message) { + c.sendPacket(PacketCreator.talkGuide(message)); + } + + public void guideHint(int hint) { + c.sendPacket(PacketCreator.guideHint(hint)); + } + + public void updateAreaInfo(Short area, String info) { + c.getPlayer().updateAreaInfo(area, info); + c.sendPacket(PacketCreator.enableActions());//idk, nexon does the same :P + } + + public boolean containsAreaInfo(short area, String info) { + return c.getPlayer().containsAreaInfo(area, info); + } + + public void earnTitle(String msg) { + c.sendPacket(PacketCreator.earnTitleMessage(msg)); + } + + public void showInfoText(String msg) { + c.sendPacket(PacketCreator.showInfoText(msg)); + } + + public void openUI(byte ui) { + c.sendPacket(PacketCreator.openUI(ui)); + } + + public void lockUI() { + c.sendPacket(PacketCreator.disableUI(true)); + c.sendPacket(PacketCreator.lockUI(true)); + } + + public void unlockUI() { + c.sendPacket(PacketCreator.disableUI(false)); + c.sendPacket(PacketCreator.lockUI(false)); + } + + public void playSound(String sound) { + getPlayer().getMap().broadcastMessage(PacketCreator.environmentChange(sound, 4)); + } + + public void environmentChange(String env, int mode) { + getPlayer().getMap().broadcastMessage(PacketCreator.environmentChange(env, mode)); + } + + public String numberWithCommas(int number) { + return GameConstants.numberWithCommas(number); + } + + public Pyramid getPyramid() { + return (Pyramid) getPlayer().getPartyQuest(); + } + + public int createExpedition(ExpeditionType type) { + return createExpedition(type, false, 0, 0); + } + + public int createExpedition(ExpeditionType type, boolean silent, int minPlayers, int maxPlayers) { + Character player = getPlayer(); + Expedition exped = new Expedition(player, type, silent, minPlayers, maxPlayers); + + int channel = player.getMap().getChannelServer().getId(); + if (!ExpeditionBossLog.attemptBoss(player.getId(), channel, exped, false)) { // thanks Conrad for noticing missing expeditions entry limit + return 1; + } + + if (exped.addChannelExpedition(player.getClient().getChannelServer())) { + return 0; + } else { + return -1; + } + } + + public void endExpedition(Expedition exped) { + exped.dispose(true); + exped.removeChannelExpedition(getPlayer().getClient().getChannelServer()); + } + + public Expedition getExpedition(ExpeditionType type) { + return getPlayer().getClient().getChannelServer().getExpedition(type); + } + + public String getExpeditionMemberNames(ExpeditionType type) { + String members = ""; + Expedition exped = getExpedition(type); + for (String memberName : exped.getMembers().values()) { + members += "" + memberName + ", "; + } + return members; + } + + public boolean isLeaderExpedition(ExpeditionType type) { + Expedition exped = getExpedition(type); + return exped.isLeader(getPlayer()); + } + + public long getJailTimeLeft() { + return getPlayer().getJailExpirationTimeLeft(); + } + + public List getDriedPets() { + List list = new LinkedList<>(); + + long curTime = System.currentTimeMillis(); + for (Item it : getPlayer().getInventory(InventoryType.CASH).list()) { + if (ItemConstants.isPet(it.getItemId()) && it.getExpiration() < curTime) { + Pet pet = it.getPet(); + if (pet != null) { + list.add(pet); + } + } + } + + return list; + } + + public List getUnclaimedMarriageGifts() { + return Marriage.loadGiftItemsFromDb(this.getClient(), this.getPlayer().getId()); + } + + public boolean startDungeonInstance(int dungeonid) { + return c.getChannelServer().addMiniDungeon(dungeonid); + } + + public boolean canGetFirstJob(int jobType) { + if (YamlConfig.config.server.USE_AUTOASSIGN_STARTERS_AP) { + return true; + } + + Character chr = this.getPlayer(); + + switch (jobType) { + case 1: + return chr.getStr() >= 35; + + case 2: + return chr.getInt() >= 20; + + case 3: + case 4: + return chr.getDex() >= 25; + + case 5: + return chr.getDex() >= 20; + + default: + return true; + } + } + + public String getFirstJobStatRequirement(int jobType) { + switch (jobType) { + case 1: + return "STR " + 35; + + case 2: + return "INT " + 20; + + case 3: + case 4: + return "DEX " + 25; + + case 5: + return "DEX " + 20; + } + + return null; + } + + public void npcTalk(int npcid, String message) { + c.sendPacket(PacketCreator.getNPCTalk(npcid, (byte) 0, message, "00 00", (byte) 0)); + } + + public long getCurrentTime() { + return Server.getInstance().getCurrentTime(); + } } \ No newline at end of file diff --git a/src/main/java/scripting/AbstractScriptManager.java b/src/main/java/scripting/AbstractScriptManager.java index b600ca2df0..0df91bbbd5 100644 --- a/src/main/java/scripting/AbstractScriptManager.java +++ b/src/main/java/scripting/AbstractScriptManager.java @@ -32,7 +32,6 @@ import java.io.FileReader; import java.io.IOException; /** - * * @author Matze */ public abstract class AbstractScriptManager { diff --git a/src/main/java/scripting/event/EventInstanceManager.java b/src/main/java/scripting/event/EventInstanceManager.java index ea3c04dd20..c635913ca9 100644 --- a/src/main/java/scripting/event/EventInstanceManager.java +++ b/src/main/java/scripting/event/EventInstanceManager.java @@ -60,1302 +60,1354 @@ import java.util.logging.Level; import java.util.logging.Logger; /** - * * @author Matze * @author Ronan */ public class EventInstanceManager { - private Map chars = new HashMap<>(); - private int leaderId = -1; - private List mobs = new LinkedList<>(); - private Map killCount = new HashMap<>(); - private EventManager em; - private EventScriptScheduler ess; - private MapManager mapManager; - private String name; - private Properties props = new Properties(); - private Map objectProps = new HashMap<>(); - private long timeStarted = 0; - private long eventTime = 0; - private Expedition expedition = null; - private List mapIds = new LinkedList<>(); - - private final MonitoredReentrantReadWriteLock lock = new MonitoredReentrantReadWriteLock(MonitoredLockType.EIM, true); - private MonitoredReadLock rL = MonitoredReadLockFactory.createLock(lock); - private MonitoredWriteLock wL = MonitoredWriteLockFactory.createLock(lock); - - private MonitoredReentrantLock pL = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EIM_PARTY, true); - private MonitoredReentrantLock sL = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EIM_SCRIPT, true); - - private ScheduledFuture event_schedule = null; - private boolean disposed = false; - private boolean eventCleared = false; - private boolean eventStarted = false; - - // multi-leveled PQ rewards! - private Map> collectionSet = new HashMap<>(YamlConfig.config.server.MAX_EVENT_LEVELS); - private Map> collectionQty = new HashMap<>(YamlConfig.config.server.MAX_EVENT_LEVELS); - private Map collectionExp = new HashMap<>(YamlConfig.config.server.MAX_EVENT_LEVELS); - - // Exp/Meso rewards by CLEAR on a stage - private List onMapClearExp = new ArrayList<>(); - private List onMapClearMeso = new ArrayList<>(); - - // registers player status on an event (null on this Map structure equals to 0) - private Map playerGrid = new HashMap<>(); - - // registers all opened gates on the event. Will help late characters to encounter next stages gates already opened - private Map> openedGates = new HashMap<>(); - - // forces deletion of items not supposed to be held outside of the event, dealt on a player's leaving moment. - private Set exclusiveItems = new HashSet<>(); - - public EventInstanceManager(EventManager em, String name) { - this.em = em; - this.name = name; - this.ess = new EventScriptScheduler(); - this.mapManager = new MapManager(this, em.getWorldServer().getId(), em.getChannelServer().getId()); - } - - public void setName(String name) { - this.name = name; - } + private final Map chars = new HashMap<>(); + private int leaderId = -1; + private final List mobs = new LinkedList<>(); + private final Map killCount = new HashMap<>(); + private EventManager em; + private EventScriptScheduler ess; + private MapManager mapManager; + private String name; + private final Properties props = new Properties(); + private final Map objectProps = new HashMap<>(); + private long timeStarted = 0; + private long eventTime = 0; + private Expedition expedition = null; + private final List mapIds = new LinkedList<>(); - public EventManager getEm() { - sL.lock(); - try { - return em; - } finally { - sL.unlock(); - } - } - - public int getEventPlayersJobs() { - //Bits -> 0: BEGINNER 1: WARRIOR 2: MAGICIAN - // 3: BOWMAN 4: THIEF 5: PIRATE - - int mask = 0; - for(Character chr: getPlayers()) { - mask |= (1 << chr.getJob().getJobNiche()); - } - - return mask; - } - - public void applyEventPlayersItemBuff(int itemId) { - List players = getPlayerList(); - StatEffect mse = ItemInformationProvider.getInstance().getItemEffect(itemId); - - if(mse != null) { - for (Character player: players) { - mse.applyTo(player); - } - } - } - - public void applyEventPlayersSkillBuff(int skillId) { - applyEventPlayersSkillBuff(skillId, Integer.MAX_VALUE); - } - - public void applyEventPlayersSkillBuff(int skillId, int skillLv) { - List players = getPlayerList(); - Skill skill = SkillFactory.getSkill(skillId); - - if(skill != null) { - StatEffect mse = skill.getEffect(Math.min(skillLv, skill.getMaxLevel())); - if(mse != null) { - for (Character player: players) { - mse.applyTo(player); - } - } - } - } - - public void giveEventPlayersExp(int gain) { - giveEventPlayersExp(gain, -1); - } - - public void giveEventPlayersExp(int gain, int mapId) { - if(gain == 0) return; - - List players = getPlayerList(); - - if(mapId == -1) { - for(Character mc: players) { - mc.gainExp(gain * mc.getExpRate(), true, true); - } - } - else { - for(Character mc: players) { - if(mc.getMapId() == mapId) mc.gainExp(gain * mc.getExpRate(), true, true); - } - } - } - - public void giveEventPlayersMeso(int gain) { - giveEventPlayersMeso(gain, -1); - } - - public void giveEventPlayersMeso(int gain, int mapId) { - if(gain == 0) return; - - List players = getPlayerList(); - - if(mapId == -1) { - for(Character mc: players) { - mc.gainMeso(gain * mc.getMesoRate()); - } - } - else { - for(Character mc: players) { - if(mc.getMapId() == mapId) mc.gainMeso(gain * mc.getMesoRate()); - } - } - - } + private final MonitoredReentrantReadWriteLock lock = new MonitoredReentrantReadWriteLock(MonitoredLockType.EIM, true); + private final MonitoredReadLock rL = MonitoredReadLockFactory.createLock(lock); + private final MonitoredWriteLock wL = MonitoredWriteLockFactory.createLock(lock); - public Object invokeScriptFunction(String name, Object... args) throws ScriptException, NoSuchMethodException { - if (!disposed) { - return em.getIv().invokeFunction(name, args); - } else { - return null; - } - } + private MonitoredReentrantLock pL = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EIM_PARTY, true); + private MonitoredReentrantLock sL = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EIM_SCRIPT, true); - public synchronized void registerPlayer(final Character chr) { - registerPlayer(chr, true); - } - - public synchronized void registerPlayer(final Character chr, boolean runEntryScript) { - if (chr == null || !chr.isLoggedinWorld() || disposed) { - return; - } - - wL.lock(); - try { - if(chars.containsKey(chr.getId())) { - return; - } + private ScheduledFuture event_schedule = null; + private boolean disposed = false; + private boolean eventCleared = false; + private boolean eventStarted = false; - chars.put(chr.getId(), chr); - chr.setEventInstance(this); - } finally { - wL.unlock(); - } - - if (runEntryScript) { - try { - invokeScriptFunction("playerEntry", EventInstanceManager.this, chr); - } catch (ScriptException | NoSuchMethodException ex) { - ex.printStackTrace(); - } - } - } - - public void exitPlayer(final Character chr) { - if (chr == null || !chr.isLoggedin()){ - return; - } - - unregisterPlayer(chr); - - try { - invokeScriptFunction("playerExit", EventInstanceManager.this, chr); - } catch (ScriptException | NoSuchMethodException ex) { - ex.printStackTrace(); - } - } - - public void dropMessage(int type, String message) { - for (Character chr : getPlayers()) { - chr.dropMessage(type, message); - } - } + // multi-leveled PQ rewards! + private final Map> collectionSet = new HashMap<>(YamlConfig.config.server.MAX_EVENT_LEVELS); + private final Map> collectionQty = new HashMap<>(YamlConfig.config.server.MAX_EVENT_LEVELS); + private final Map collectionExp = new HashMap<>(YamlConfig.config.server.MAX_EVENT_LEVELS); - public void restartEventTimer(long time) { - stopEventTimer(); - startEventTimer(time); - } - - public void startEventTimer(long time) { - timeStarted = System.currentTimeMillis(); - eventTime = time; - - for(Character chr: getPlayers()) { - chr.sendPacket(PacketCreator.getClock((int) (time / 1000))); - } - - event_schedule = TimerManager.getInstance().schedule(() -> { - dismissEventTimer(); + // Exp/Meso rewards by CLEAR on a stage + private final List onMapClearExp = new ArrayList<>(); + private final List onMapClearMeso = new ArrayList<>(); - try { - invokeScriptFunction("scheduledTimeout", EventInstanceManager.this); - } catch (ScriptException | NoSuchMethodException ex) { - Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, "Event '" + em.getName() + "' does not implement scheduledTimeout function.", ex); - } - }, time); - } + // registers player status on an event (null on this Map structure equals to 0) + private final Map playerGrid = new HashMap<>(); - public void addEventTimer(long time) { - if (event_schedule != null) { - if (event_schedule.cancel(false)) { - long nextTime = getTimeLeft() + time; - eventTime += time; + // registers all opened gates on the event. Will help late characters to encounter next stages gates already opened + private final Map> openedGates = new HashMap<>(); - event_schedule = TimerManager.getInstance().schedule(() -> { - dismissEventTimer(); + // forces deletion of items not supposed to be held outside of the event, dealt on a player's leaving moment. + private final Set exclusiveItems = new HashSet<>(); - try { - invokeScriptFunction("scheduledTimeout", EventInstanceManager.this); - } catch (ScriptException | NoSuchMethodException ex) { - Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, "Event '" + em.getName() + "' does not implement scheduledTimeout function.", ex); - } - }, nextTime); - } - } else { - startEventTimer(time); - } - } - - private void dismissEventTimer() { - for (Character chr : getPlayers()) { - chr.sendPacket(PacketCreator.removeClock()); - } - - event_schedule = null; - eventTime = 0; - timeStarted = 0; - } - - public void stopEventTimer() { - if (event_schedule != null) { - event_schedule.cancel(false); - event_schedule = null; - } - - dismissEventTimer(); - } - - public boolean isTimerStarted() { - return eventTime > 0 && timeStarted > 0; - } - - public long getTimeLeft() { - return eventTime - (System.currentTimeMillis() - timeStarted); - } - - public void registerParty(Character chr) { - if (chr.isPartyLeader()) { - registerParty(chr.getParty(), chr.getMap()); - } - } - - public void registerParty(Party party, MapleMap map) { - for (PartyCharacter mpc : party.getEligibleMembers()) { - if (mpc.isOnline()) { // thanks resinate - Character chr = map.getCharacterById(mpc.getId()); - if (chr != null) { - registerPlayer(chr); - } - } - } - } - - public void registerExpedition(Expedition exped) { - expedition = exped; - registerExpeditionTeam(exped, exped.getRecruitingMap().getId()); - } - - private void registerExpeditionTeam(Expedition exped, int recruitMap) { - expedition = exped; - - for (Character chr: exped.getActiveMembers()) { - if (chr.getMapId() == recruitMap) { - registerPlayer(chr); - } - } - } - - public void unregisterPlayer(final Character chr) { - try { - invokeScriptFunction("playerUnregistered", EventInstanceManager.this, chr); - } catch (ScriptException | NoSuchMethodException ex) { - Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, "Event '" + em.getName() + "' does not implement playerUnregistered function.", ex); - } - - wL.lock(); - try { - chars.remove(chr.getId()); - chr.setEventInstance(null); - } finally { - wL.unlock(); - } - - gridRemove(chr); - dropExclusiveItems(chr); - } - - public int getPlayerCount() { - rL.lock(); - try { - return chars.size(); - } finally { - rL.unlock(); - } - } - - public Character getPlayerById(int id) { - rL.lock(); - try { - return chars.get(id); - } finally { - rL.unlock(); - } - } - - public List getPlayers() { - rL.lock(); - try { - return new ArrayList<>(chars.values()); - } finally { - rL.unlock(); - } - } - - private List getPlayerList() { - rL.lock(); - try { - return new LinkedList<>(chars.values()); - } finally { - rL.unlock(); - } - } - - public void registerMonster(Monster mob) { - if (!mob.getStats().isFriendly()) { //We cannot register moon bunny - mobs.add(mob); - } - } - - public void movePlayer(final Character chr) { - try { - invokeScriptFunction("moveMap", EventInstanceManager.this, chr); - } catch (ScriptException | NoSuchMethodException ex) { - ex.printStackTrace(); - } - } - - public void changedMap(final Character chr, final int mapId) { - try { - invokeScriptFunction("changedMap", EventInstanceManager.this, chr, mapId); - } catch (ScriptException | NoSuchMethodException ex) {} // optional - } - - public void afterChangedMap(final Character chr, final int mapId) { - try { - invokeScriptFunction("afterChangedMap", EventInstanceManager.this, chr, mapId); - } catch (ScriptException | NoSuchMethodException ex) {} // optional - } - - public synchronized void changedLeader(final PartyCharacter ldr) { - try { - invokeScriptFunction("changedLeader", EventInstanceManager.this, ldr); - } catch (ScriptException | NoSuchMethodException ex) { - ex.printStackTrace(); - } - - leaderId = ldr.getId(); - } - - public void monsterKilled(final Monster mob, final boolean hasKiller) { - int scriptResult = 0; - - sL.lock(); - try { - mobs.remove(mob); - - if(eventStarted) { - scriptResult = 1; - - if (mobs.isEmpty()) { - scriptResult = 2; - } - } - } finally { - sL.unlock(); - } - - if (scriptResult > 0) { - try { - invokeScriptFunction("monsterKilled", mob, EventInstanceManager.this, hasKiller); - } catch (ScriptException | NoSuchMethodException ex) { - ex.printStackTrace(); - } - - if (scriptResult > 1) { - try { - invokeScriptFunction("allMonstersDead", EventInstanceManager.this, hasKiller); - } catch (ScriptException | NoSuchMethodException ex) { - ex.printStackTrace(); - } - } - } - } - - public void friendlyKilled(final Monster mob, final boolean hasKiller) { - try { - invokeScriptFunction("friendlyKilled", mob, EventInstanceManager.this, hasKiller); - } catch (ScriptException | NoSuchMethodException ex) {} //optional - } - - public void friendlyDamaged(final Monster mob) { - try { - invokeScriptFunction("friendlyDamaged", EventInstanceManager.this, mob); - } catch (ScriptException | NoSuchMethodException ex) {} // optional - } - - public void friendlyItemDrop(final Monster mob) { - try { - invokeScriptFunction("friendlyItemDrop", EventInstanceManager.this, mob); - } catch (ScriptException | NoSuchMethodException ex) {} // optional - } - - public void playerKilled(final Character chr) { - ThreadManager.getInstance().newTask(() -> { - try { - invokeScriptFunction("playerDead", EventInstanceManager.this, chr); - } catch (ScriptException | NoSuchMethodException ex) {} // optional - }); - } - - public void reviveMonster(final Monster mob) { - try { - invokeScriptFunction("monsterRevive", EventInstanceManager.this, mob); - } catch (ScriptException | NoSuchMethodException ex) {} // optional - } - - public boolean revivePlayer(final Character chr) { - try { - Object b = invokeScriptFunction("playerRevive", EventInstanceManager.this, chr); - if (b instanceof Boolean) { - return (Boolean) b; - } - } catch (ScriptException | NoSuchMethodException ex) {} // optional - - return true; - } - - public void playerDisconnected(final Character chr) { - try { - invokeScriptFunction("playerDisconnected", EventInstanceManager.this, chr); - } catch (ScriptException | NoSuchMethodException ex) { - ex.printStackTrace(); - } - - EventRecallCoordinator.getInstance().storeEventInstance(chr.getId(), this); - } - - public void monsterKilled(Character chr, final Monster mob) { - try { - final int inc = (int) invokeScriptFunction("monsterValue", EventInstanceManager.this, mob.getId()); - - if (inc != 0) { - Integer kc = killCount.get(chr); - if (kc == null) { - kc = inc; - } else { - kc += inc; - } - killCount.put(chr, kc); - if (expedition != null) { - expedition.monsterKilled(chr, mob); - } - } - } catch (ScriptException | NoSuchMethodException ex) { - ex.printStackTrace(); - } + public EventInstanceManager(EventManager em, String name) { + this.em = em; + this.name = name; + this.ess = new EventScriptScheduler(); + this.mapManager = new MapManager(this, em.getWorldServer().getId(), em.getChannelServer().getId()); } - public int getKillCount(Character chr) { - Integer kc = killCount.get(chr); - return (kc == null) ? 0 : kc; - } - - public void dispose() { - rL.lock(); - try { - for(Character chr: chars.values()) chr.setEventInstance(null); - } finally { - rL.unlock(); - } - - dispose(false); - } - - public synchronized void dispose(boolean shutdown) { // should not trigger any event script method after disposed - if(disposed) return; - - try { - invokeScriptFunction("dispose", EventInstanceManager.this); - } catch (ScriptException | NoSuchMethodException ex) { - ex.printStackTrace(); - } - disposed = true; - - ess.dispose(); - - wL.lock(); - try { - for(Character chr: chars.values()) chr.setEventInstance(null); - chars.clear(); - mobs.clear(); - ess = null; - } finally { - wL.unlock(); - } - - if(event_schedule != null) { - event_schedule.cancel(false); - event_schedule = null; - } - - killCount.clear(); - mapIds.clear(); - props.clear(); - objectProps.clear(); - - disposeExpedition(); - - sL.lock(); - try { - if(!eventCleared) em.disposeInstance(name); - } finally { - sL.unlock(); - } - - TimerManager.getInstance().schedule(() -> { - mapManager.dispose(); // issues from instantly disposing some event objects found thanks to MedicOP - wL.lock(); - try { - mapManager = null; - em = null; - } finally { - wL.unlock(); - } + public void setName(String name) { + this.name = name; + } - disposeLocks(); - }, 60 * 1000); - } - - private void disposeLocks() { - LockCollector.getInstance().registerDisposeAction(() -> emptyLocks()); + public EventManager getEm() { + sL.lock(); + try { + return em; + } finally { + sL.unlock(); } - - private void emptyLocks() { - pL = pL.dispose(); - sL = sL.dispose(); + } + + public int getEventPlayersJobs() { + //Bits -> 0: BEGINNER 1: WARRIOR 2: MAGICIAN + // 3: BOWMAN 4: THIEF 5: PIRATE + + int mask = 0; + for (Character chr : getPlayers()) { + mask |= (1 << chr.getJob().getJobNiche()); } - public MapManager getMapFactory() { - return mapManager; - } + return mask; + } - public void schedule(final String methodName, long delay) { - rL.lock(); - try { - if (ess != null) { - Runnable r = () -> { - try { - invokeScriptFunction(methodName, EventInstanceManager.this); - } catch (ScriptException | NoSuchMethodException ex) { - ex.printStackTrace(); - } - }; + public void applyEventPlayersItemBuff(int itemId) { + List players = getPlayerList(); + StatEffect mse = ItemInformationProvider.getInstance().getItemEffect(itemId); - ess.registerEntry(r, delay); - } - } finally { - rL.unlock(); - } - } - - public String getName() { - return name; - } - - public MapleMap getMapInstance(int mapId) { - MapleMap map = mapManager.getMap(mapId); - map.setEventInstance(this); - - if (!mapManager.isMapLoaded(mapId)) { - sL.lock(); - try { - if (em.getProperty("shuffleReactors") != null && em.getProperty("shuffleReactors").equals("true")) { - map.shuffleReactors(); - } - } finally { - sL.unlock(); - } - } - return map; - } - - public void setIntProperty(String key, Integer value) { - setProperty(key, value); + if (mse != null) { + for (Character player : players) { + mse.applyTo(player); + } } - - public void setProperty(String key, Integer value) { - setProperty(key, "" + value); - } - - public void setProperty(String key, String value) { - pL.lock(); - try { - props.setProperty(key, value); - } finally { - pL.unlock(); - } - } + } - public Object setProperty(String key, String value, boolean prev) { - pL.lock(); - try { - return props.setProperty(key, value); - } finally { - pL.unlock(); - } - } - - public void setObjectProperty(String key, Object obj) { - pL.lock(); - try { - objectProps.put(key, obj); - } finally { - pL.unlock(); - } - } + public void applyEventPlayersSkillBuff(int skillId) { + applyEventPlayersSkillBuff(skillId, Integer.MAX_VALUE); + } - public String getProperty(String key) { - pL.lock(); - try { - return props.getProperty(key); - } finally { - pL.unlock(); - } - } + public void applyEventPlayersSkillBuff(int skillId, int skillLv) { + List players = getPlayerList(); + Skill skill = SkillFactory.getSkill(skillId); - public int getIntProperty(String key) { - pL.lock(); - try { - return Integer.parseInt(props.getProperty(key)); - } finally { - pL.unlock(); - } - } - - public Object getObjectProperty(String key) { - pL.lock(); - try { - return objectProps.get(key); - } finally { - pL.unlock(); - } - } - - public void leftParty(final Character chr) { - try { - invokeScriptFunction("leftParty", EventInstanceManager.this, chr); - } catch (ScriptException | NoSuchMethodException ex) { - ex.printStackTrace(); - } - } - - public void disbandParty() { - try { - invokeScriptFunction("disbandParty", EventInstanceManager.this); - } catch (ScriptException | NoSuchMethodException ex) { - ex.printStackTrace(); - } - } - - public void clearPQ() { - try { - invokeScriptFunction("clearPQ", EventInstanceManager.this); - } catch (ScriptException | NoSuchMethodException ex) { - ex.printStackTrace(); - } - } - - public void removePlayer(final Character chr) { - try { - invokeScriptFunction("playerExit", EventInstanceManager.this, chr); - } catch (ScriptException | NoSuchMethodException ex) { - ex.printStackTrace(); - } - } - - public boolean isLeader(Character chr) { - return (chr.getParty().getLeaderId() == chr.getId()); - } - - public boolean isEventLeader(Character chr) { - return (chr.getId() == getLeaderId()); - } - - public final MapleMap getInstanceMap(final int mapid) { - if (disposed) { - return null; - } - mapIds.add(mapid); - return getMapFactory().getMap(mapid); - } - - public final boolean disposeIfPlayerBelow(final byte size, final int towarp) { - if (disposed) { - return true; - } - if(chars == null) { - return false; - } - - MapleMap map = null; - if (towarp > 0) { - map = this.getMapFactory().getMap(towarp); - } - - List players = getPlayerList(); - - try { - if (players.size() < size) { - for (Character chr : players) { - if (chr == null) { - continue; - } - - unregisterPlayer(chr); - if (towarp > 0) { - chr.changeMap(map, map.getPortal(0)); - } - } - - dispose(); - return true; - } - } catch (Exception ex) { - ex.printStackTrace(); - } - - return false; - } - - public void spawnNpc(int npcId, Point pos, MapleMap map) { - NPC npc = LifeFactory.getNPC(npcId); - if (npc != null) { - npc.setPosition(pos); - npc.setCy(pos.y); - npc.setRx0(pos.x + 50); - npc.setRx1(pos.x - 50); - npc.setFh(map.getFootholds().findBelow(pos).getId()); - map.addMapObject(npc); - map.broadcastMessage(PacketCreator.spawnNPC(npc)); - } - } - - public void dispatchRaiseQuestMobCount(int mobid, int mapid) { - Map mapChars = getInstanceMap(mapid).getMapPlayers(); - if(!mapChars.isEmpty()) { - List eventMembers = getPlayers(); - - for (Character evChr : eventMembers) { - Character chr = mapChars.get(evChr.getId()); - - if(chr != null && chr.isLoggedinWorld()) { - chr.raiseQuestMobCount(mobid); - } + if (skill != null) { + StatEffect mse = skill.getEffect(Math.min(skillLv, skill.getMaxLevel())); + if (mse != null) { + for (Character player : players) { + mse.applyTo(player); } } } - - public Monster getMonster(int mid) { - return(LifeFactory.getMonster(mid)); + } + + public void giveEventPlayersExp(int gain) { + giveEventPlayersExp(gain, -1); + } + + public void giveEventPlayersExp(int gain, int mapId) { + if (gain == 0) { + return; } - private List convertToIntegerList(List objects) { - List intList = new ArrayList<>(); + List players = getPlayerList(); - for (Object object : objects) { - intList.add((Integer) object); + if (mapId == -1) { + for (Character mc : players) { + mc.gainExp(gain * mc.getExpRate(), true, true); + } + } else { + for (Character mc : players) { + if (mc.getMapId() == mapId) { + mc.gainExp(gain * mc.getExpRate(), true, true); } + } + } + } - return intList; + public void giveEventPlayersMeso(int gain) { + giveEventPlayersMeso(gain, -1); + } + + public void giveEventPlayersMeso(int gain, int mapId) { + if (gain == 0) { + return; } - - public void setEventClearStageExp(List gain) { - onMapClearExp.clear(); - onMapClearExp.addAll(convertToIntegerList(gain)); - } - - public void setEventClearStageMeso(List gain) { - onMapClearMeso.clear(); - onMapClearMeso.addAll(convertToIntegerList(gain)); - } - - public Integer getClearStageExp(int stage) { //stage counts from ONE. - if(stage > onMapClearExp.size()) return 0; - return onMapClearExp.get(stage - 1); - } - - public Integer getClearStageMeso(int stage) { //stage counts from ONE. - if(stage > onMapClearMeso.size()) return 0; - return onMapClearMeso.get(stage - 1); - } - - public List getClearStageBonus(int stage) { - List list = new ArrayList<>(); - list.add(getClearStageExp(stage)); - list.add(getClearStageMeso(stage)); - - return list; - } - - private void dropExclusiveItems(Character chr) { - AbstractPlayerInteraction api = chr.getAbstractPlayerInteraction(); - - for(Integer item: exclusiveItems) { - api.removeAll(item); + + List players = getPlayerList(); + + if (mapId == -1) { + for (Character mc : players) { + mc.gainMeso(gain * mc.getMesoRate()); + } + } else { + for (Character mc : players) { + if (mc.getMapId() == mapId) { + mc.gainMeso(gain * mc.getMesoRate()); } + } } - - public final void setExclusiveItems(List items) { - List exclusive = convertToIntegerList(items); - - wL.lock(); + + } + + public Object invokeScriptFunction(String name, Object... args) throws ScriptException, NoSuchMethodException { + if (!disposed) { + return em.getIv().invokeFunction(name, args); + } else { + return null; + } + } + + public synchronized void registerPlayer(final Character chr) { + registerPlayer(chr, true); + } + + public synchronized void registerPlayer(final Character chr, boolean runEntryScript) { + if (chr == null || !chr.isLoggedinWorld() || disposed) { + return; + } + + wL.lock(); + try { + if (chars.containsKey(chr.getId())) { + return; + } + + chars.put(chr.getId(), chr); + chr.setEventInstance(this); + } finally { + wL.unlock(); + } + + if (runEntryScript) { + try { + invokeScriptFunction("playerEntry", EventInstanceManager.this, chr); + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + } + } + + public void exitPlayer(final Character chr) { + if (chr == null || !chr.isLoggedin()) { + return; + } + + unregisterPlayer(chr); + + try { + invokeScriptFunction("playerExit", EventInstanceManager.this, chr); + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + } + + public void dropMessage(int type, String message) { + for (Character chr : getPlayers()) { + chr.dropMessage(type, message); + } + } + + public void restartEventTimer(long time) { + stopEventTimer(); + startEventTimer(time); + } + + public void startEventTimer(long time) { + timeStarted = System.currentTimeMillis(); + eventTime = time; + + for (Character chr : getPlayers()) { + chr.sendPacket(PacketCreator.getClock((int) (time / 1000))); + } + + event_schedule = TimerManager.getInstance().schedule(() -> { + dismissEventTimer(); + + try { + invokeScriptFunction("scheduledTimeout", EventInstanceManager.this); + } catch (ScriptException | NoSuchMethodException ex) { + Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, "Event '" + em.getName() + "' does not implement scheduledTimeout function.", ex); + } + }, time); + } + + public void addEventTimer(long time) { + if (event_schedule != null) { + if (event_schedule.cancel(false)) { + long nextTime = getTimeLeft() + time; + eventTime += time; + + event_schedule = TimerManager.getInstance().schedule(() -> { + dismissEventTimer(); + + try { + invokeScriptFunction("scheduledTimeout", EventInstanceManager.this); + } catch (ScriptException | NoSuchMethodException ex) { + Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, "Event '" + em.getName() + "' does not implement scheduledTimeout function.", ex); + } + }, nextTime); + } + } else { + startEventTimer(time); + } + } + + private void dismissEventTimer() { + for (Character chr : getPlayers()) { + chr.sendPacket(PacketCreator.removeClock()); + } + + event_schedule = null; + eventTime = 0; + timeStarted = 0; + } + + public void stopEventTimer() { + if (event_schedule != null) { + event_schedule.cancel(false); + event_schedule = null; + } + + dismissEventTimer(); + } + + public boolean isTimerStarted() { + return eventTime > 0 && timeStarted > 0; + } + + public long getTimeLeft() { + return eventTime - (System.currentTimeMillis() - timeStarted); + } + + public void registerParty(Character chr) { + if (chr.isPartyLeader()) { + registerParty(chr.getParty(), chr.getMap()); + } + } + + public void registerParty(Party party, MapleMap map) { + for (PartyCharacter mpc : party.getEligibleMembers()) { + if (mpc.isOnline()) { // thanks resinate + Character chr = map.getCharacterById(mpc.getId()); + if (chr != null) { + registerPlayer(chr); + } + } + } + } + + public void registerExpedition(Expedition exped) { + expedition = exped; + registerExpeditionTeam(exped, exped.getRecruitingMap().getId()); + } + + private void registerExpeditionTeam(Expedition exped, int recruitMap) { + expedition = exped; + + for (Character chr : exped.getActiveMembers()) { + if (chr.getMapId() == recruitMap) { + registerPlayer(chr); + } + } + } + + public void unregisterPlayer(final Character chr) { + try { + invokeScriptFunction("playerUnregistered", EventInstanceManager.this, chr); + } catch (ScriptException | NoSuchMethodException ex) { + Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, "Event '" + em.getName() + "' does not implement playerUnregistered function.", ex); + } + + wL.lock(); + try { + chars.remove(chr.getId()); + chr.setEventInstance(null); + } finally { + wL.unlock(); + } + + gridRemove(chr); + dropExclusiveItems(chr); + } + + public int getPlayerCount() { + rL.lock(); + try { + return chars.size(); + } finally { + rL.unlock(); + } + } + + public Character getPlayerById(int id) { + rL.lock(); + try { + return chars.get(id); + } finally { + rL.unlock(); + } + } + + public List getPlayers() { + rL.lock(); + try { + return new ArrayList<>(chars.values()); + } finally { + rL.unlock(); + } + } + + private List getPlayerList() { + rL.lock(); + try { + return new LinkedList<>(chars.values()); + } finally { + rL.unlock(); + } + } + + public void registerMonster(Monster mob) { + if (!mob.getStats().isFriendly()) { //We cannot register moon bunny + mobs.add(mob); + } + } + + public void movePlayer(final Character chr) { + try { + invokeScriptFunction("moveMap", EventInstanceManager.this, chr); + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + } + + public void changedMap(final Character chr, final int mapId) { + try { + invokeScriptFunction("changedMap", EventInstanceManager.this, chr, mapId); + } catch (ScriptException | NoSuchMethodException ex) { + } // optional + } + + public void afterChangedMap(final Character chr, final int mapId) { + try { + invokeScriptFunction("afterChangedMap", EventInstanceManager.this, chr, mapId); + } catch (ScriptException | NoSuchMethodException ex) { + } // optional + } + + public synchronized void changedLeader(final PartyCharacter ldr) { + try { + invokeScriptFunction("changedLeader", EventInstanceManager.this, ldr); + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + + leaderId = ldr.getId(); + } + + public void monsterKilled(final Monster mob, final boolean hasKiller) { + int scriptResult = 0; + + sL.lock(); + try { + mobs.remove(mob); + + if (eventStarted) { + scriptResult = 1; + + if (mobs.isEmpty()) { + scriptResult = 2; + } + } + } finally { + sL.unlock(); + } + + if (scriptResult > 0) { + try { + invokeScriptFunction("monsterKilled", mob, EventInstanceManager.this, hasKiller); + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + + if (scriptResult > 1) { try { - exclusiveItems.addAll(exclusive); - } finally { - wL.unlock(); - } - } - - public final void setEventRewards(List rwds, List qtys, int expGiven) { - setEventRewards(1, rwds, qtys, expGiven); - } - - public final void setEventRewards(List rwds, List qtys) { - setEventRewards(1, rwds, qtys); - } - - public final void setEventRewards(int eventLevel, List rwds, List qtys) { - setEventRewards(eventLevel, rwds, qtys, 0); - } - - public final void setEventRewards(int eventLevel, List rwds, List qtys, int expGiven) { - // fixed EXP will be rewarded at the same time the random item is given - - if(eventLevel <= 0 || eventLevel > YamlConfig.config.server.MAX_EVENT_LEVELS) return; - eventLevel--; //event level starts from 1 - - List rewardIds = convertToIntegerList(rwds); - List rewardQtys = convertToIntegerList(qtys); - - //rewardsSet and rewardsQty hold temporary values - wL.lock(); - try { - collectionSet.put(eventLevel, rewardIds); - collectionQty.put(eventLevel, rewardQtys); - collectionExp.put(eventLevel, expGiven); - } finally { - wL.unlock(); - } - } - - private byte getRewardListRequirements(int level) { - if(level >= collectionSet.size()) return 0; - - byte rewardTypes = 0; - List list = collectionSet.get(level); - - for (Integer itemId : list) { - rewardTypes |= (1 << ItemConstants.getInventoryType(itemId).getType()); - } - - return rewardTypes; - } - - private boolean hasRewardSlot(Character player, int eventLevel) { - byte listReq = getRewardListRequirements(eventLevel); //gets all types of items present in the event reward list - - //iterating over all valid inventory types - for(byte type = 1; type <= 5; type++) { - if((listReq >> type) % 2 == 1 && !player.hasEmptySlot(type)) - return false; - } - - return true; - } - - public final boolean giveEventReward(Character player) { - return giveEventReward(player, 1); - } - - //gives out EXP & a random item in a similar fashion of when clearing KPQ, LPQ, etc. - public final boolean giveEventReward(Character player, int eventLevel) { - List rewardsSet, rewardsQty; - Integer rewardExp; - - rL.lock(); - try { - eventLevel--; //event level starts counting from 1 - if(eventLevel >= collectionSet.size()) return true; - - rewardsSet = collectionSet.get(eventLevel); - rewardsQty = collectionQty.get(eventLevel); - - rewardExp = collectionExp.get(eventLevel); - } finally { - rL.unlock(); - } - - if(rewardExp == null) rewardExp = 0; - - if(rewardsSet == null || rewardsSet.isEmpty()) { - if(rewardExp > 0) player.gainExp(rewardExp); - return true; - } - - if(!hasRewardSlot(player, eventLevel)) return false; - - AbstractPlayerInteraction api = player.getAbstractPlayerInteraction(); - int rnd = (int)Math.floor(Math.random() * rewardsSet.size()); - - api.gainItem(rewardsSet.get(rnd), rewardsQty.get(rnd).shortValue()); - if(rewardExp > 0) player.gainExp(rewardExp); - return true; - } - - private void disposeExpedition() { - if (expedition != null) { - expedition.dispose(eventCleared); - - sL.lock(); - try { - expedition.removeChannelExpedition(em.getChannelServer()); - } finally { - sL.unlock(); - } - - expedition = null; - } - } - - public final synchronized void startEvent() { - eventStarted = true; - - try { - invokeScriptFunction("afterSetup", EventInstanceManager.this); + invokeScriptFunction("allMonstersDead", EventInstanceManager.this, hasKiller); } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + } + } + } + + public void friendlyKilled(final Monster mob, final boolean hasKiller) { + try { + invokeScriptFunction("friendlyKilled", mob, EventInstanceManager.this, hasKiller); + } catch (ScriptException | NoSuchMethodException ex) { + } //optional + } + + public void friendlyDamaged(final Monster mob) { + try { + invokeScriptFunction("friendlyDamaged", EventInstanceManager.this, mob); + } catch (ScriptException | NoSuchMethodException ex) { + } // optional + } + + public void friendlyItemDrop(final Monster mob) { + try { + invokeScriptFunction("friendlyItemDrop", EventInstanceManager.this, mob); + } catch (ScriptException | NoSuchMethodException ex) { + } // optional + } + + public void playerKilled(final Character chr) { + ThreadManager.getInstance().newTask(() -> { + try { + invokeScriptFunction("playerDead", EventInstanceManager.this, chr); + } catch (ScriptException | NoSuchMethodException ex) { + } // optional + }); + } + + public void reviveMonster(final Monster mob) { + try { + invokeScriptFunction("monsterRevive", EventInstanceManager.this, mob); + } catch (ScriptException | NoSuchMethodException ex) { + } // optional + } + + public boolean revivePlayer(final Character chr) { + try { + Object b = invokeScriptFunction("playerRevive", EventInstanceManager.this, chr); + if (b instanceof Boolean) { + return (Boolean) b; + } + } catch (ScriptException | NoSuchMethodException ex) { + } // optional + + return true; + } + + public void playerDisconnected(final Character chr) { + try { + invokeScriptFunction("playerDisconnected", EventInstanceManager.this, chr); + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + + EventRecallCoordinator.getInstance().storeEventInstance(chr.getId(), this); + } + + public void monsterKilled(Character chr, final Monster mob) { + try { + final int inc = (int) invokeScriptFunction("monsterValue", EventInstanceManager.this, mob.getId()); + + if (inc != 0) { + Integer kc = killCount.get(chr); + if (kc == null) { + kc = inc; + } else { + kc += inc; + } + killCount.put(chr, kc); + if (expedition != null) { + expedition.monsterKilled(chr, mob); + } + } + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + } + + public int getKillCount(Character chr) { + Integer kc = killCount.get(chr); + return (kc == null) ? 0 : kc; + } + + public void dispose() { + rL.lock(); + try { + for (Character chr : chars.values()) { + chr.setEventInstance(null); + } + } finally { + rL.unlock(); + } + + dispose(false); + } + + public synchronized void dispose(boolean shutdown) { // should not trigger any event script method after disposed + if (disposed) { + return; + } + + try { + invokeScriptFunction("dispose", EventInstanceManager.this); + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + disposed = true; + + ess.dispose(); + + wL.lock(); + try { + for (Character chr : chars.values()) { + chr.setEventInstance(null); + } + chars.clear(); + mobs.clear(); + ess = null; + } finally { + wL.unlock(); + } + + if (event_schedule != null) { + event_schedule.cancel(false); + event_schedule = null; + } + + killCount.clear(); + mapIds.clear(); + props.clear(); + objectProps.clear(); + + disposeExpedition(); + + sL.lock(); + try { + if (!eventCleared) { + em.disposeInstance(name); + } + } finally { + sL.unlock(); + } + + TimerManager.getInstance().schedule(() -> { + mapManager.dispose(); // issues from instantly disposing some event objects found thanks to MedicOP + wL.lock(); + try { + mapManager = null; + em = null; + } finally { + wL.unlock(); + } + + disposeLocks(); + }, 60 * 1000); + } + + private void disposeLocks() { + LockCollector.getInstance().registerDisposeAction(() -> emptyLocks()); + } + + private void emptyLocks() { + pL = pL.dispose(); + sL = sL.dispose(); + } + + public MapManager getMapFactory() { + return mapManager; + } + + public void schedule(final String methodName, long delay) { + rL.lock(); + try { + if (ess != null) { + Runnable r = () -> { + try { + invokeScriptFunction(methodName, EventInstanceManager.this); + } catch (ScriptException | NoSuchMethodException ex) { ex.printStackTrace(); - } - } - - public final void setEventCleared() { - eventCleared = true; - - for (Character chr : getPlayers()) { - chr.awardQuestPoint(YamlConfig.config.server.QUEST_POINT_PER_EVENT_CLEAR); - } - - sL.lock(); - try { - em.disposeInstance(name); - } finally { - sL.unlock(); - } - - disposeExpedition(); - } - - public final boolean isEventCleared() { - return eventCleared; - } - - public final boolean isEventDisposed() { - return disposed; - } - - private boolean isEventTeamLeaderOn() { - for(Character chr: getPlayers()) { - if(chr.getId() == getLeaderId()) return true; - } - - return false; - } - - public final boolean checkEventTeamLacking(boolean leavingEventMap, int minPlayers) { - if(eventCleared && getPlayerCount() > 1) return false; - - if(!eventCleared && leavingEventMap && !isEventTeamLeaderOn()) return true; - if(getPlayerCount() < minPlayers) return true; + } + }; - return false; + ess.registerEntry(r, delay); + } + } finally { + rL.unlock(); } - - public final boolean isExpeditionTeamLackingNow(boolean leavingEventMap, int minPlayers, Character quitter) { - if(eventCleared) { - if(leavingEventMap && getPlayerCount() <= 1) return true; - } else { - // thanks Conrad for noticing expeditions don't need to have neither the leader nor meet the minimum requirement inside the event - if(getPlayerCount() <= 1) return true; - } - - return false; - } - - public final boolean isEventTeamLackingNow(boolean leavingEventMap, int minPlayers, Character quitter) { - if(eventCleared) { - if(leavingEventMap && getPlayerCount() <= 1) return true; - } else { - if(leavingEventMap && getLeaderId() == quitter.getId()) return true; - if(getPlayerCount() <= minPlayers) return true; - } - - return false; - } - - public final boolean isEventTeamTogether() { - rL.lock(); - try { - if(chars.size() <= 1) return true; - - Iterator iterator = chars.values().iterator(); - Character mc = iterator.next(); - int mapId = mc.getMapId(); - - for (; iterator.hasNext();) { - mc = iterator.next(); - if(mc.getMapId() != mapId) return false; - } - - return true; - } finally { - rL.unlock(); - } - } - - public final void warpEventTeam(int warpFrom, int warpTo) { - List players = getPlayerList(); - - for (Character chr : players) { - if(chr.getMapId() == warpFrom) - chr.changeMap(warpTo); - } - } - - public final void warpEventTeam(int warpTo) { - List players = getPlayerList(); - - for (Character chr : players) { - chr.changeMap(warpTo); - } - } - - public final void warpEventTeamToMapSpawnPoint(int warpFrom, int warpTo, int toSp) { - List players = getPlayerList(); - - for (Character chr : players) { - if(chr.getMapId() == warpFrom) - chr.changeMap(warpTo, toSp); - } - } - - public final void warpEventTeamToMapSpawnPoint(int warpTo, int toSp) { - List players = getPlayerList(); - - for (Character chr : players) { - chr.changeMap(warpTo, toSp); - } - } - - public final int getLeaderId() { - rL.lock(); - try { - return leaderId; - } finally { - rL.unlock(); - } - } - - public Character getLeader() { - rL.lock(); - try { - return chars.get(leaderId); - } finally { - rL.unlock(); - } - } - - public final void setLeader(Character chr) { - wL.lock(); - try { - leaderId = chr.getId(); - } finally { - wL.unlock(); - } - } - - public final void showWrongEffect() { - showWrongEffect(getLeader().getMapId()); - } - - public final void showWrongEffect(int mapId) { - MapleMap map = getMapInstance(mapId); - map.broadcastMessage(PacketCreator.showEffect("quest/party/wrong_kor")); - map.broadcastMessage(PacketCreator.playSound("Party1/Failed")); - } - - public final void showClearEffect() { - showClearEffect(false); - } - - public final void showClearEffect(boolean hasGate) { - Character leader = getLeader(); - if(leader != null) showClearEffect(hasGate, leader.getMapId()); - } - - public final void showClearEffect(int mapId) { - showClearEffect(false, mapId); - } - - public final void showClearEffect(boolean hasGate, int mapId) { - showClearEffect(hasGate, mapId, "gate", 2); - } - - public final void showClearEffect(int mapId, String mapObj, int newState) { - showClearEffect(true, mapId, mapObj, newState); - } - - public final void showClearEffect(boolean hasGate, int mapId, String mapObj, int newState) { - MapleMap map = getMapInstance(mapId); - map.broadcastMessage(PacketCreator.showEffect("quest/party/clear")); - map.broadcastMessage(PacketCreator.playSound("Party1/Clear")); - if(hasGate) { - map.broadcastMessage(PacketCreator.environmentChange(mapObj, newState)); - wL.lock(); - try { - openedGates.put(map.getId(), new Pair<>(mapObj, newState)); - } finally { - wL.unlock(); - } - } - } - - public final void recoverOpenedGate(Character chr, int thisMapId) { - Pair gateData = null; - - rL.lock(); - try { - if(openedGates.containsKey(thisMapId)) { - gateData = openedGates.get(thisMapId); - } - } finally { - rL.unlock(); - } - - if(gateData != null) { - chr.sendPacket(PacketCreator.environmentChange(gateData.getLeft(), gateData.getRight())); - } - } - - public final void giveEventPlayersStageReward(int thisStage) { - List list = getClearStageBonus(thisStage); // will give bonus exp & mesos to everyone in the event - giveEventPlayersExp(list.get(0)); - giveEventPlayersMeso(list.get(1)); - } - - public final void linkToNextStage(int thisStage, String eventFamily, int thisMapId) { - giveEventPlayersStageReward(thisStage); - thisStage--; //stages counts from ONE, scripts from ZERO - - MapleMap nextStage = getMapInstance(thisMapId); - Portal portal = nextStage.getPortal("next00"); - if (portal != null) { - portal.setScriptName(eventFamily + thisStage); - } - } - - public final void linkPortalToScript(int thisStage, String portalName, String scriptName, int thisMapId) { - giveEventPlayersStageReward(thisStage); - thisStage--; //stages counts from ONE, scripts from ZERO - - MapleMap nextStage = getMapInstance(thisMapId); - Portal portal = nextStage.getPortal(portalName); - if (portal != null) { - portal.setScriptName(scriptName); - } - } - - // registers a player status in an event - public final void gridInsert(Character chr, int newStatus) { - wL.lock(); - try { - playerGrid.put(chr.getId(), newStatus); - } finally { - wL.unlock(); - } - } - - // unregisters a player status in an event - public final void gridRemove(Character chr) { - wL.lock(); - try { - playerGrid.remove(chr.getId()); - } finally { - wL.unlock(); - } - } - - // checks a player status - public final int gridCheck(Character chr) { - rL.lock(); - try { - Integer i = playerGrid.get(chr.getId()); - return (i != null) ? i : -1; - } finally { - rL.unlock(); - } - } - - public final int gridSize() { - rL.lock(); - try { - return playerGrid.size(); - } finally { - rL.unlock(); - } - } - - public final void gridClear() { - wL.lock(); - try { - playerGrid.clear(); - } finally { - wL.unlock(); - } - } - - public boolean activatedAllReactorsOnMap(int mapId, int minReactorId, int maxReactorId) { - return activatedAllReactorsOnMap(this.getMapInstance(mapId), minReactorId, maxReactorId); - } - - public boolean activatedAllReactorsOnMap(MapleMap map, int minReactorId, int maxReactorId) { - if(map == null) return true; - - for(Reactor mr : map.getReactorsByIdRange(minReactorId, maxReactorId)) { - if(mr.getReactorType() != -1) { - return false; - } + } + + public String getName() { + return name; + } + + public MapleMap getMapInstance(int mapId) { + MapleMap map = mapManager.getMap(mapId); + map.setEventInstance(this); + + if (!mapManager.isMapLoaded(mapId)) { + sL.lock(); + try { + if (em.getProperty("shuffleReactors") != null && em.getProperty("shuffleReactors").equals("true")) { + map.shuffleReactors(); + } + } finally { + sL.unlock(); + } + } + return map; + } + + public void setIntProperty(String key, Integer value) { + setProperty(key, value); + } + + public void setProperty(String key, Integer value) { + setProperty(key, "" + value); + } + + public void setProperty(String key, String value) { + pL.lock(); + try { + props.setProperty(key, value); + } finally { + pL.unlock(); + } + } + + public Object setProperty(String key, String value, boolean prev) { + pL.lock(); + try { + return props.setProperty(key, value); + } finally { + pL.unlock(); + } + } + + public void setObjectProperty(String key, Object obj) { + pL.lock(); + try { + objectProps.put(key, obj); + } finally { + pL.unlock(); + } + } + + public String getProperty(String key) { + pL.lock(); + try { + return props.getProperty(key); + } finally { + pL.unlock(); + } + } + + public int getIntProperty(String key) { + pL.lock(); + try { + return Integer.parseInt(props.getProperty(key)); + } finally { + pL.unlock(); + } + } + + public Object getObjectProperty(String key) { + pL.lock(); + try { + return objectProps.get(key); + } finally { + pL.unlock(); + } + } + + public void leftParty(final Character chr) { + try { + invokeScriptFunction("leftParty", EventInstanceManager.this, chr); + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + } + + public void disbandParty() { + try { + invokeScriptFunction("disbandParty", EventInstanceManager.this); + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + } + + public void clearPQ() { + try { + invokeScriptFunction("clearPQ", EventInstanceManager.this); + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + } + + public void removePlayer(final Character chr) { + try { + invokeScriptFunction("playerExit", EventInstanceManager.this, chr); + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + } + + public boolean isLeader(Character chr) { + return (chr.getParty().getLeaderId() == chr.getId()); + } + + public boolean isEventLeader(Character chr) { + return (chr.getId() == getLeaderId()); + } + + public final MapleMap getInstanceMap(final int mapid) { + if (disposed) { + return null; + } + mapIds.add(mapid); + return getMapFactory().getMap(mapid); + } + + public final boolean disposeIfPlayerBelow(final byte size, final int towarp) { + if (disposed) { + return true; + } + if (chars == null) { + return false; + } + + MapleMap map = null; + if (towarp > 0) { + map = this.getMapFactory().getMap(towarp); + } + + List players = getPlayerList(); + + try { + if (players.size() < size) { + for (Character chr : players) { + if (chr == null) { + continue; + } + + unregisterPlayer(chr); + if (towarp > 0) { + chr.changeMap(map, map.getPortal(0)); + } } + dispose(); return true; + } + } catch (Exception ex) { + ex.printStackTrace(); } + + return false; + } + + public void spawnNpc(int npcId, Point pos, MapleMap map) { + NPC npc = LifeFactory.getNPC(npcId); + if (npc != null) { + npc.setPosition(pos); + npc.setCy(pos.y); + npc.setRx0(pos.x + 50); + npc.setRx1(pos.x - 50); + npc.setFh(map.getFootholds().findBelow(pos).getId()); + map.addMapObject(npc); + map.broadcastMessage(PacketCreator.spawnNPC(npc)); + } + } + + public void dispatchRaiseQuestMobCount(int mobid, int mapid) { + Map mapChars = getInstanceMap(mapid).getMapPlayers(); + if (!mapChars.isEmpty()) { + List eventMembers = getPlayers(); + + for (Character evChr : eventMembers) { + Character chr = mapChars.get(evChr.getId()); + + if (chr != null && chr.isLoggedinWorld()) { + chr.raiseQuestMobCount(mobid); + } + } + } + } + + public Monster getMonster(int mid) { + return (LifeFactory.getMonster(mid)); + } + + private List convertToIntegerList(List objects) { + List intList = new ArrayList<>(); + + for (Object object : objects) { + intList.add((Integer) object); + } + + return intList; + } + + public void setEventClearStageExp(List gain) { + onMapClearExp.clear(); + onMapClearExp.addAll(convertToIntegerList(gain)); + } + + public void setEventClearStageMeso(List gain) { + onMapClearMeso.clear(); + onMapClearMeso.addAll(convertToIntegerList(gain)); + } + + public Integer getClearStageExp(int stage) { //stage counts from ONE. + if (stage > onMapClearExp.size()) { + return 0; + } + return onMapClearExp.get(stage - 1); + } + + public Integer getClearStageMeso(int stage) { //stage counts from ONE. + if (stage > onMapClearMeso.size()) { + return 0; + } + return onMapClearMeso.get(stage - 1); + } + + public List getClearStageBonus(int stage) { + List list = new ArrayList<>(); + list.add(getClearStageExp(stage)); + list.add(getClearStageMeso(stage)); + + return list; + } + + private void dropExclusiveItems(Character chr) { + AbstractPlayerInteraction api = chr.getAbstractPlayerInteraction(); + + for (Integer item : exclusiveItems) { + api.removeAll(item); + } + } + + public final void setExclusiveItems(List items) { + List exclusive = convertToIntegerList(items); + + wL.lock(); + try { + exclusiveItems.addAll(exclusive); + } finally { + wL.unlock(); + } + } + + public final void setEventRewards(List rwds, List qtys, int expGiven) { + setEventRewards(1, rwds, qtys, expGiven); + } + + public final void setEventRewards(List rwds, List qtys) { + setEventRewards(1, rwds, qtys); + } + + public final void setEventRewards(int eventLevel, List rwds, List qtys) { + setEventRewards(eventLevel, rwds, qtys, 0); + } + + public final void setEventRewards(int eventLevel, List rwds, List qtys, int expGiven) { + // fixed EXP will be rewarded at the same time the random item is given + + if (eventLevel <= 0 || eventLevel > YamlConfig.config.server.MAX_EVENT_LEVELS) { + return; + } + eventLevel--; //event level starts from 1 + + List rewardIds = convertToIntegerList(rwds); + List rewardQtys = convertToIntegerList(qtys); + + //rewardsSet and rewardsQty hold temporary values + wL.lock(); + try { + collectionSet.put(eventLevel, rewardIds); + collectionQty.put(eventLevel, rewardQtys); + collectionExp.put(eventLevel, expGiven); + } finally { + wL.unlock(); + } + } + + private byte getRewardListRequirements(int level) { + if (level >= collectionSet.size()) { + return 0; + } + + byte rewardTypes = 0; + List list = collectionSet.get(level); + + for (Integer itemId : list) { + rewardTypes |= (1 << ItemConstants.getInventoryType(itemId).getType()); + } + + return rewardTypes; + } + + private boolean hasRewardSlot(Character player, int eventLevel) { + byte listReq = getRewardListRequirements(eventLevel); //gets all types of items present in the event reward list + + //iterating over all valid inventory types + for (byte type = 1; type <= 5; type++) { + if ((listReq >> type) % 2 == 1 && !player.hasEmptySlot(type)) { + return false; + } + } + + return true; + } + + public final boolean giveEventReward(Character player) { + return giveEventReward(player, 1); + } + + //gives out EXP & a random item in a similar fashion of when clearing KPQ, LPQ, etc. + public final boolean giveEventReward(Character player, int eventLevel) { + List rewardsSet, rewardsQty; + Integer rewardExp; + + rL.lock(); + try { + eventLevel--; //event level starts counting from 1 + if (eventLevel >= collectionSet.size()) { + return true; + } + + rewardsSet = collectionSet.get(eventLevel); + rewardsQty = collectionQty.get(eventLevel); + + rewardExp = collectionExp.get(eventLevel); + } finally { + rL.unlock(); + } + + if (rewardExp == null) { + rewardExp = 0; + } + + if (rewardsSet == null || rewardsSet.isEmpty()) { + if (rewardExp > 0) { + player.gainExp(rewardExp); + } + return true; + } + + if (!hasRewardSlot(player, eventLevel)) { + return false; + } + + AbstractPlayerInteraction api = player.getAbstractPlayerInteraction(); + int rnd = (int) Math.floor(Math.random() * rewardsSet.size()); + + api.gainItem(rewardsSet.get(rnd), rewardsQty.get(rnd).shortValue()); + if (rewardExp > 0) { + player.gainExp(rewardExp); + } + return true; + } + + private void disposeExpedition() { + if (expedition != null) { + expedition.dispose(eventCleared); + + sL.lock(); + try { + expedition.removeChannelExpedition(em.getChannelServer()); + } finally { + sL.unlock(); + } + + expedition = null; + } + } + + public final synchronized void startEvent() { + eventStarted = true; + + try { + invokeScriptFunction("afterSetup", EventInstanceManager.this); + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } + } + + public final void setEventCleared() { + eventCleared = true; + + for (Character chr : getPlayers()) { + chr.awardQuestPoint(YamlConfig.config.server.QUEST_POINT_PER_EVENT_CLEAR); + } + + sL.lock(); + try { + em.disposeInstance(name); + } finally { + sL.unlock(); + } + + disposeExpedition(); + } + + public final boolean isEventCleared() { + return eventCleared; + } + + public final boolean isEventDisposed() { + return disposed; + } + + private boolean isEventTeamLeaderOn() { + for (Character chr : getPlayers()) { + if (chr.getId() == getLeaderId()) { + return true; + } + } + + return false; + } + + public final boolean checkEventTeamLacking(boolean leavingEventMap, int minPlayers) { + if (eventCleared && getPlayerCount() > 1) { + return false; + } + + if (!eventCleared && leavingEventMap && !isEventTeamLeaderOn()) { + return true; + } + return getPlayerCount() < minPlayers; + } + + public final boolean isExpeditionTeamLackingNow(boolean leavingEventMap, int minPlayers, Character quitter) { + if (eventCleared) { + return leavingEventMap && getPlayerCount() <= 1; + } else { + // thanks Conrad for noticing expeditions don't need to have neither the leader nor meet the minimum requirement inside the event + return getPlayerCount() <= 1; + } + } + + public final boolean isEventTeamLackingNow(boolean leavingEventMap, int minPlayers, Character quitter) { + if (eventCleared) { + return leavingEventMap && getPlayerCount() <= 1; + } else { + if (leavingEventMap && getLeaderId() == quitter.getId()) { + return true; + } + return getPlayerCount() <= minPlayers; + } + } + + public final boolean isEventTeamTogether() { + rL.lock(); + try { + if (chars.size() <= 1) { + return true; + } + + Iterator iterator = chars.values().iterator(); + Character mc = iterator.next(); + int mapId = mc.getMapId(); + + for (; iterator.hasNext(); ) { + mc = iterator.next(); + if (mc.getMapId() != mapId) { + return false; + } + } + + return true; + } finally { + rL.unlock(); + } + } + + public final void warpEventTeam(int warpFrom, int warpTo) { + List players = getPlayerList(); + + for (Character chr : players) { + if (chr.getMapId() == warpFrom) { + chr.changeMap(warpTo); + } + } + } + + public final void warpEventTeam(int warpTo) { + List players = getPlayerList(); + + for (Character chr : players) { + chr.changeMap(warpTo); + } + } + + public final void warpEventTeamToMapSpawnPoint(int warpFrom, int warpTo, int toSp) { + List players = getPlayerList(); + + for (Character chr : players) { + if (chr.getMapId() == warpFrom) { + chr.changeMap(warpTo, toSp); + } + } + } + + public final void warpEventTeamToMapSpawnPoint(int warpTo, int toSp) { + List players = getPlayerList(); + + for (Character chr : players) { + chr.changeMap(warpTo, toSp); + } + } + + public final int getLeaderId() { + rL.lock(); + try { + return leaderId; + } finally { + rL.unlock(); + } + } + + public Character getLeader() { + rL.lock(); + try { + return chars.get(leaderId); + } finally { + rL.unlock(); + } + } + + public final void setLeader(Character chr) { + wL.lock(); + try { + leaderId = chr.getId(); + } finally { + wL.unlock(); + } + } + + public final void showWrongEffect() { + showWrongEffect(getLeader().getMapId()); + } + + public final void showWrongEffect(int mapId) { + MapleMap map = getMapInstance(mapId); + map.broadcastMessage(PacketCreator.showEffect("quest/party/wrong_kor")); + map.broadcastMessage(PacketCreator.playSound("Party1/Failed")); + } + + public final void showClearEffect() { + showClearEffect(false); + } + + public final void showClearEffect(boolean hasGate) { + Character leader = getLeader(); + if (leader != null) { + showClearEffect(hasGate, leader.getMapId()); + } + } + + public final void showClearEffect(int mapId) { + showClearEffect(false, mapId); + } + + public final void showClearEffect(boolean hasGate, int mapId) { + showClearEffect(hasGate, mapId, "gate", 2); + } + + public final void showClearEffect(int mapId, String mapObj, int newState) { + showClearEffect(true, mapId, mapObj, newState); + } + + public final void showClearEffect(boolean hasGate, int mapId, String mapObj, int newState) { + MapleMap map = getMapInstance(mapId); + map.broadcastMessage(PacketCreator.showEffect("quest/party/clear")); + map.broadcastMessage(PacketCreator.playSound("Party1/Clear")); + if (hasGate) { + map.broadcastMessage(PacketCreator.environmentChange(mapObj, newState)); + wL.lock(); + try { + openedGates.put(map.getId(), new Pair<>(mapObj, newState)); + } finally { + wL.unlock(); + } + } + } + + public final void recoverOpenedGate(Character chr, int thisMapId) { + Pair gateData = null; + + rL.lock(); + try { + if (openedGates.containsKey(thisMapId)) { + gateData = openedGates.get(thisMapId); + } + } finally { + rL.unlock(); + } + + if (gateData != null) { + chr.sendPacket(PacketCreator.environmentChange(gateData.getLeft(), gateData.getRight())); + } + } + + public final void giveEventPlayersStageReward(int thisStage) { + List list = getClearStageBonus(thisStage); // will give bonus exp & mesos to everyone in the event + giveEventPlayersExp(list.get(0)); + giveEventPlayersMeso(list.get(1)); + } + + public final void linkToNextStage(int thisStage, String eventFamily, int thisMapId) { + giveEventPlayersStageReward(thisStage); + thisStage--; //stages counts from ONE, scripts from ZERO + + MapleMap nextStage = getMapInstance(thisMapId); + Portal portal = nextStage.getPortal("next00"); + if (portal != null) { + portal.setScriptName(eventFamily + thisStage); + } + } + + public final void linkPortalToScript(int thisStage, String portalName, String scriptName, int thisMapId) { + giveEventPlayersStageReward(thisStage); + thisStage--; //stages counts from ONE, scripts from ZERO + + MapleMap nextStage = getMapInstance(thisMapId); + Portal portal = nextStage.getPortal(portalName); + if (portal != null) { + portal.setScriptName(scriptName); + } + } + + // registers a player status in an event + public final void gridInsert(Character chr, int newStatus) { + wL.lock(); + try { + playerGrid.put(chr.getId(), newStatus); + } finally { + wL.unlock(); + } + } + + // unregisters a player status in an event + public final void gridRemove(Character chr) { + wL.lock(); + try { + playerGrid.remove(chr.getId()); + } finally { + wL.unlock(); + } + } + + // checks a player status + public final int gridCheck(Character chr) { + rL.lock(); + try { + Integer i = playerGrid.get(chr.getId()); + return (i != null) ? i : -1; + } finally { + rL.unlock(); + } + } + + public final int gridSize() { + rL.lock(); + try { + return playerGrid.size(); + } finally { + rL.unlock(); + } + } + + public final void gridClear() { + wL.lock(); + try { + playerGrid.clear(); + } finally { + wL.unlock(); + } + } + + public boolean activatedAllReactorsOnMap(int mapId, int minReactorId, int maxReactorId) { + return activatedAllReactorsOnMap(this.getMapInstance(mapId), minReactorId, maxReactorId); + } + + public boolean activatedAllReactorsOnMap(MapleMap map, int minReactorId, int maxReactorId) { + if (map == null) { + return true; + } + + for (Reactor mr : map.getReactorsByIdRange(minReactorId, maxReactorId)) { + if (mr.getReactorType() != -1) { + return false; + } + } + + return true; + } } diff --git a/src/main/java/scripting/event/EventManager.java b/src/main/java/scripting/event/EventManager.java index c2a8fceb1a..18a44b503d 100644 --- a/src/main/java/scripting/event/EventManager.java +++ b/src/main/java/scripting/event/EventManager.java @@ -54,7 +54,6 @@ import java.util.logging.Logger; //import jdk.nashorn.api.scripting.ScriptUtils; /** - * * @author Matze * @author Ronan */ @@ -63,59 +62,61 @@ public class EventManager { private Channel cserv; private World wserv; private Server server; - private EventScriptScheduler ess = new EventScriptScheduler(); - private Map instances = new HashMap<>(); - private Map instanceLocks = new HashMap<>(); + private final EventScriptScheduler ess = new EventScriptScheduler(); + private final Map instances = new HashMap<>(); + private final Map instanceLocks = new HashMap<>(); private final Queue queuedGuilds = new LinkedList<>(); private final Map queuedGuildLeaders = new HashMap<>(); - private List openedLobbys; - private List readyInstances = new LinkedList<>(); + private final List openedLobbys; + private final List readyInstances = new LinkedList<>(); private Integer readyId = 0, onLoadInstances = 0; - private Properties props = new Properties(); - private String name; + private final Properties props = new Properties(); + private final String name; private MonitoredReentrantLock lobbyLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EM_LOBBY); private MonitoredReentrantLock queueLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EM_QUEUE); private MonitoredReentrantLock startLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EM_START); - - private Set playerPermit = new HashSet<>(); - private Semaphore startSemaphore = new Semaphore(7); - + + private final Set playerPermit = new HashSet<>(); + private final Semaphore startSemaphore = new Semaphore(7); + private static final int maxLobbys = 8; // an event manager holds up to this amount of concurrent lobbys - + public EventManager(Channel cserv, Invocable iv, String name) { this.server = Server.getInstance(); this.iv = iv; this.cserv = cserv; this.wserv = server.getWorld(cserv.getWorld()); this.name = name; - + this.openedLobbys = new ArrayList<>(); - for(int i = 0; i < maxLobbys; i++) this.openedLobbys.add(false); + for (int i = 0; i < maxLobbys; i++) { + this.openedLobbys.add(false); + } } private boolean isDisposed() { return onLoadInstances <= -1000; } - + public void cancel() { // make sure to only call this when there are NO PLAYERS ONLINE to mess around with the event manager! ess.dispose(); - + try { iv.invokeFunction("cancelSchedule", (Object) null); } catch (ScriptException | NoSuchMethodException ex) { ex.printStackTrace(); } - + Collection eimList; - synchronized(instances) { + synchronized (instances) { eimList = getInstances(); instances.clear(); } - - for(EventInstanceManager eim : eimList) { + + for (EventInstanceManager eim : eimList) { eim.dispose(true); } - + List readyEims; queueLock.lock(); try { @@ -125,24 +126,24 @@ public class EventManager { } finally { queueLock.unlock(); } - - for(EventInstanceManager eim : readyEims) { + + for (EventInstanceManager eim : readyEims) { eim.dispose(true); } - + props.clear(); cserv = null; wserv = null; server = null; iv = null; - + disposeLocks(); } - + private void disposeLocks() { LockCollector.getInstance().registerDisposeAction(() -> emptyLocks()); } - + private void emptyLocks() { lobbyLock = lobbyLock.dispose(); queueLock = queueLock.dispose(); @@ -158,11 +159,11 @@ public class EventManager { return intList; } - + public long getLobbyDelay() { return YamlConfig.config.server.EVENT_LOBBY_DELAY; } - + private int getMaxLobbies() { try { return (int) iv.invokeFunction("getMaxLobbies"); @@ -183,9 +184,9 @@ public class EventManager { Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex); } }; - + ess.registerEntry(r, delay); - + // hate to do that, but those schedules can still be cancelled, so well... Let GC do it's job return new EventScheduledFuture(r, ess); } @@ -198,7 +199,7 @@ public class EventManager { Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex); } }; - + ess.registerEntry(r, timestamp - server.getCurrentTime()); return new EventScheduledFuture(r, ess); } @@ -206,11 +207,11 @@ public class EventManager { public World getWorldServer() { return wserv; } - + public Channel getChannelServer() { return cserv; } - + public Invocable getIv() { return iv; } @@ -227,31 +228,31 @@ public class EventManager { public EventInstanceManager newInstance(String name) throws EventInstanceInProgressException { EventInstanceManager ret = getReadyInstance(); - - if(ret == null) { + + if (ret == null) { ret = new EventInstanceManager(this, name); } else { ret.setName(name); } - + synchronized (instances) { if (instances.containsKey(name)) { throw new EventInstanceInProgressException(name, this.getName()); } - + instances.put(name, ret); } return ret; } - + public Marriage newMarriage(String name) throws EventInstanceInProgressException { Marriage ret = new Marriage(this, name); - + synchronized (instances) { if (instances.containsKey(name)) { throw new EventInstanceInProgressException(name, this.getName()); } - + instances.put(name, ret); } return ret; @@ -270,11 +271,11 @@ public class EventManager { public void setProperty(String key, String value) { props.setProperty(key, value); } - + public void setIntProperty(String key, int value) { setProperty(key, value); } - + public void setProperty(String key, int value) { props.setProperty(key, value + ""); } @@ -282,11 +283,11 @@ public class EventManager { public String getProperty(String key) { return props.getProperty(key); } - + public int getIntProperty(String key) { return Integer.parseInt(props.getProperty(key)); } - + private void setLockLobby(int lobbyId, boolean lock) { lobbyLock.lock(); try { @@ -295,7 +296,7 @@ public class EventManager { lobbyLock.unlock(); } } - + private boolean startLobbyInstance(int lobbyId) { lobbyLock.lock(); try { @@ -304,24 +305,28 @@ public class EventManager { } else if (lobbyId >= maxLobbys) { lobbyId = maxLobbys - 1; } - - if(!openedLobbys.get(lobbyId)) { + + if (!openedLobbys.get(lobbyId)) { openedLobbys.set(lobbyId, true); return true; } - + return false; } finally { lobbyLock.unlock(); } } - + private void freeLobbyInstance(String lobbyName) { Integer i = instanceLocks.get(lobbyName); - if(i == null) return; - + if (i == null) { + return; + } + instanceLocks.remove(lobbyName); - if(i > -1) setLockLobby(i, false); + if (i > -1) { + setLockLobby(i, false); + } } public String getName() { @@ -341,62 +346,67 @@ public class EventManager { return -1; } - + private String getInternalScriptExceptionMessage(Throwable a) { if (!(a instanceof ScriptException)) { return null; } - - while(true) { + + while (true) { Throwable t = a; a = a.getCause(); - + if (a == null) { return t.getMessage(); } } } - + private EventInstanceManager createInstance(String name, Object... args) throws ScriptException, NoSuchMethodException { return (EventInstanceManager) iv.invokeFunction(name, args); } - + private void registerEventInstance(String eventName, int lobbyId) { Integer oldLobby = instanceLocks.get(eventName); if (oldLobby != null) { setLockLobby(oldLobby, false); } - + instanceLocks.put(eventName, lobbyId); } - + public boolean startInstance(Expedition exped) { return startInstance(-1, exped); } - + public boolean startInstance(int lobbyId, Expedition exped) { return startInstance(lobbyId, exped, exped.getLeader()); } //Expedition method: starts an expedition public boolean startInstance(int lobbyId, Expedition exped, Character leader) { - if (this.isDisposed()) return false; - + if (this.isDisposed()) { + return false; + } + try { - if(!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) { + if (!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) { playerPermit.add(leader.getId()); - + startLock.lock(); try { try { - if(lobbyId == -1) { + if (lobbyId == -1) { lobbyId = availableLobbyInstance(); - if(lobbyId == -1) return false; + if (lobbyId == -1) { + return false; + } + } else { + if (!startLobbyInstance(lobbyId)) { + return false; + } } - else { - if(!startLobbyInstance(lobbyId)) return false; - } - + EventInstanceManager eim; try { eim = createInstance("setup", leader.getClient().getChannel()); @@ -406,13 +416,13 @@ public class EventManager { if (message != null && !message.startsWith(EventInstanceInProgressException.EIIP_KEY)) { throw e; } - - if(lobbyId > -1) { + + if (lobbyId > -1) { setLockLobby(lobbyId, false); } return false; } - + eim.setLeader(leader); exped.start(); @@ -430,10 +440,10 @@ public class EventManager { startSemaphore.release(); } } - } catch(InterruptedException ie) { + } catch (InterruptedException ie) { playerPermit.remove(leader.getId()); } - + return false; } @@ -441,33 +451,34 @@ public class EventManager { public boolean startInstance(Character chr) { return startInstance(-1, chr); } - + public boolean startInstance(int lobbyId, Character leader) { return startInstance(lobbyId, leader, leader, 1); } - + public boolean startInstance(int lobbyId, Character chr, Character leader, int difficulty) { - if (this.isDisposed()) return false; - + if (this.isDisposed()) { + return false; + } + try { - if(!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) { + if (!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) { playerPermit.add(leader.getId()); - + startLock.lock(); try { try { - if(lobbyId == -1) { + if (lobbyId == -1) { lobbyId = availableLobbyInstance(); - if(lobbyId == -1) { + if (lobbyId == -1) { + return false; + } + } else { + if (!startLobbyInstance(lobbyId)) { return false; } } - else { - if(!startLobbyInstance(lobbyId)) { - return false; - } - } - + EventInstanceManager eim; try { eim = createInstance("setup", difficulty, (lobbyId > -1) ? lobbyId : leader.getId()); @@ -477,15 +488,17 @@ public class EventManager { if (message != null && !message.startsWith(EventInstanceInProgressException.EIIP_KEY)) { throw e; } - - if(lobbyId > -1) { + + if (lobbyId > -1) { setLockLobby(lobbyId, false); } return false; } eim.setLeader(leader); - if(chr != null) eim.registerPlayer(chr); + if (chr != null) { + eim.registerPlayer(chr); + } eim.startEvent(); } catch (ScriptException | NoSuchMethodException ex) { @@ -499,40 +512,45 @@ public class EventManager { startSemaphore.release(); } } - } catch(InterruptedException ie) { + } catch (InterruptedException ie) { playerPermit.remove(leader.getId()); } - + return false; - } - + } + //PQ method: starts a PQ public boolean startInstance(Party party, MapleMap map) { return startInstance(-1, party, map); } - + public boolean startInstance(int lobbyId, Party party, MapleMap map) { return startInstance(lobbyId, party, map, party.getLeader().getPlayer()); } - + public boolean startInstance(int lobbyId, Party party, MapleMap map, Character leader) { - if (this.isDisposed()) return false; - + if (this.isDisposed()) { + return false; + } + try { - if(!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) { + if (!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) { playerPermit.add(leader.getId()); - + startLock.lock(); try { try { - if(lobbyId == -1) { + if (lobbyId == -1) { lobbyId = availableLobbyInstance(); - if(lobbyId == -1) return false; + if (lobbyId == -1) { + return false; + } + } else { + if (!startLobbyInstance(lobbyId)) { + return false; + } } - else { - if(!startLobbyInstance(lobbyId)) return false; - } - + EventInstanceManager eim; try { eim = createInstance("setup", (Object) null); @@ -542,13 +560,13 @@ public class EventManager { if (message != null && !message.startsWith(EventInstanceInProgressException.EIIP_KEY)) { throw e; } - - if(lobbyId > -1) { + + if (lobbyId > -1) { setLockLobby(lobbyId, false); } return false; } - + eim.setLeader(leader); eim.registerParty(party, map); @@ -566,40 +584,45 @@ public class EventManager { startSemaphore.release(); } } - } catch(InterruptedException ie) { + } catch (InterruptedException ie) { playerPermit.remove(leader.getId()); } - + return false; } - + //PQ method: starts a PQ with a difficulty level, requires function setup(difficulty, leaderid) instead of setup() public boolean startInstance(Party party, MapleMap map, int difficulty) { return startInstance(-1, party, map, difficulty); } - + public boolean startInstance(int lobbyId, Party party, MapleMap map, int difficulty) { return startInstance(lobbyId, party, map, difficulty, party.getLeader().getPlayer()); } - + public boolean startInstance(int lobbyId, Party party, MapleMap map, int difficulty, Character leader) { - if (this.isDisposed()) return false; - + if (this.isDisposed()) { + return false; + } + try { - if(!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) { + if (!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) { playerPermit.add(leader.getId()); - + startLock.lock(); try { try { - if(lobbyId == -1) { + if (lobbyId == -1) { lobbyId = availableLobbyInstance(); - if(lobbyId == -1) return false; + if (lobbyId == -1) { + return false; + } + } else { + if (!startLobbyInstance(lobbyId)) { + return false; + } } - else { - if(!startLobbyInstance(lobbyId)) return false; - } - + EventInstanceManager eim; try { eim = createInstance("setup", difficulty, (lobbyId > -1) ? lobbyId : party.getLeaderId()); @@ -609,13 +632,13 @@ public class EventManager { if (message != null && !message.startsWith(EventInstanceInProgressException.EIIP_KEY)) { throw e; } - - if(lobbyId > -1) { + + if (lobbyId > -1) { setLockLobby(lobbyId, false); } return false; } - + eim.setLeader(leader); eim.registerParty(party, map); @@ -633,10 +656,10 @@ public class EventManager { startSemaphore.release(); } } - } catch(InterruptedException ie) { + } catch (InterruptedException ie) { playerPermit.remove(leader.getId()); } - + return false; } @@ -644,35 +667,40 @@ public class EventManager { public boolean startInstance(EventInstanceManager eim, String ldr) { return startInstance(-1, eim, ldr); } - + public boolean startInstance(EventInstanceManager eim, Character ldr) { return startInstance(-1, eim, ldr.getName(), ldr); } - + public boolean startInstance(int lobbyId, EventInstanceManager eim, String ldr) { return startInstance(-1, eim, ldr, eim.getEm().getChannelServer().getPlayerStorage().getCharacterByName(ldr)); // things they make me do... } - + public boolean startInstance(int lobbyId, EventInstanceManager eim, String ldr, Character leader) { - if (this.isDisposed()) return false; - + if (this.isDisposed()) { + return false; + } + try { - if(!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) { + if (!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) { playerPermit.add(leader.getId()); - + startLock.lock(); try { try { - if(lobbyId == -1) { + if (lobbyId == -1) { lobbyId = availableLobbyInstance(); - if(lobbyId == -1) return false; - } - else { - if(!startLobbyInstance(lobbyId)) return false; + if (lobbyId == -1) { + return false; + } + } else { + if (!startLobbyInstance(lobbyId)) { + return false; + } } - if(eim == null) { - if(lobbyId > -1) { + if (eim == null) { + if (lobbyId > -1) { setLockLobby(lobbyId, false); } return false; @@ -695,20 +723,20 @@ public class EventManager { startSemaphore.release(); } } - } catch(InterruptedException ie) { + } catch (InterruptedException ie) { playerPermit.remove(leader.getId()); } - + return false; } - + public List getEligibleParty(Party party) { if (party == null) { return new ArrayList<>(); } try { Object o = iv.invokeFunction("getEligibleParty", party.getPartyMembersOnline()); - + if (o instanceof PartyCharacter[] partyChrs) { final List eligibleParty = new ArrayList<>(Arrays.asList(partyChrs)); party.setEligibleMembers(eligibleParty); @@ -720,7 +748,7 @@ public class EventManager { return new ArrayList<>(); } - + public void clearPQ(EventInstanceManager eim) { try { iv.invokeFunction("clearPQ", eim); @@ -728,7 +756,7 @@ public class EventManager { Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex); } } - + public void clearPQ(EventInstanceManager eim, MapleMap toMap) { try { iv.invokeFunction("clearPQ", eim, toMap); @@ -736,66 +764,71 @@ public class EventManager { Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex); } } - + public Monster getMonster(int mid) { - return(LifeFactory.getMonster(mid)); + return (LifeFactory.getMonster(mid)); } - + private void exportReadyGuild(Integer guildId) { Guild mg = server.getGuild(guildId); - String callout = "[Guild Quest] Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId() - + " and HAS JUST STARTED THE STRATEGY PHASE. After 3 minutes, no more guild members will be allowed to join the effort." - + " Check out Shuang at the excavation site in Perion for more info."; - + String callout = "[Guild Quest] Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId() + + " and HAS JUST STARTED THE STRATEGY PHASE. After 3 minutes, no more guild members will be allowed to join the effort." + + " Check out Shuang at the excavation site in Perion for more info."; + mg.dropMessage(6, callout); } - + private void exportMovedQueueToGuild(Integer guildId, int place) { Guild mg = server.getGuild(guildId); - String callout = "[Guild Quest] Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId() - + " and is currently on the " + GameConstants.ordinal(place) + " place on the waiting queue."; - + String callout = "[Guild Quest] Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId() + + " and is currently on the " + GameConstants.ordinal(place) + " place on the waiting queue."; + mg.dropMessage(6, callout); } - + private List getNextGuildQueue() { - synchronized(queuedGuilds) { + synchronized (queuedGuilds) { Integer guildId = queuedGuilds.poll(); - if(guildId == null) return null; - + if (guildId == null) { + return null; + } + wserv.removeGuildQueued(guildId); Integer leaderId = queuedGuildLeaders.remove(guildId); - + int place = 1; - for(Integer i: queuedGuilds) { + for (Integer i : queuedGuilds) { exportMovedQueueToGuild(i, place); place++; } - + List list = new ArrayList<>(2); - list.add(guildId); list.add(leaderId); + list.add(guildId); + list.add(leaderId); return list; } } - + public boolean isQueueFull() { - synchronized(queuedGuilds) { + synchronized (queuedGuilds) { return queuedGuilds.size() >= YamlConfig.config.server.EVENT_MAX_GUILD_QUEUE; } } - + public int getQueueSize() { - synchronized(queuedGuilds) { + synchronized (queuedGuilds) { return queuedGuilds.size(); } } - + public byte addGuildToQueue(Integer guildId, Integer leaderId) { - if(wserv.isGuildQueued(guildId)) return -1; - - if(!isQueueFull()) { + if (wserv.isGuildQueued(guildId)) { + return -1; + } + + if (!isQueueFull()) { boolean canStartAhead; - synchronized(queuedGuilds) { + synchronized (queuedGuilds) { canStartAhead = queuedGuilds.isEmpty(); queuedGuilds.add(guildId); @@ -805,10 +838,10 @@ public class EventManager { int place = queuedGuilds.size(); exportMovedQueueToGuild(guildId, place); } - - if(canStartAhead) { - if(!attemptStartGuildInstance()) { - synchronized(queuedGuilds) { + + if (canStartAhead) { + if (!attemptStartGuildInstance()) { + synchronized (queuedGuilds) { queuedGuilds.add(guildId); wserv.putGuildQueued(guildId); queuedGuildLeaders.put(guildId, leaderId); @@ -817,33 +850,33 @@ public class EventManager { return 2; } } - + return 1; } else { return 0; } } - + public boolean attemptStartGuildInstance() { Character chr = null; List guildInstance = null; - while(chr == null) { + while (chr == null) { guildInstance = getNextGuildQueue(); - if(guildInstance == null) { + if (guildInstance == null) { return false; } chr = cserv.getPlayerStorage().getCharacterById(guildInstance.get(1)); } - - if(startInstance(chr)) { - exportReadyGuild(guildInstance.get(0)); + + if (startInstance(chr)) { + exportReadyGuild(guildInstance.get(0)); return true; } else { return false; } } - + public void startQuest(Character chr, int id, int npcid) { try { Quest.getInstance(id).forceStart(chr, npcid); @@ -859,63 +892,65 @@ public class EventManager { ex.printStackTrace(); } } - + public int getTransportationTime(int travelTime) { return this.getWorldServer().getTransportationTime(travelTime); } - + private void fillEimQueue() { ThreadManager.getInstance().newTask(new EventManagerTask()); //call new thread to fill up readied instances queue } - + private EventInstanceManager getReadyInstance() { queueLock.lock(); try { - if(readyInstances.isEmpty()) { + if (readyInstances.isEmpty()) { fillEimQueue(); return null; } - + EventInstanceManager eim = readyInstances.remove(0); fillEimQueue(); - + return eim; } finally { queueLock.unlock(); } } - + private void instantiateQueuedInstance() { int nextEventId; queueLock.lock(); try { - if (this.isDisposed() || readyInstances.size() + onLoadInstances >= Math.ceil((double)maxLobbys / 3.0)) return; - + if (this.isDisposed() || readyInstances.size() + onLoadInstances >= Math.ceil((double) maxLobbys / 3.0)) { + return; + } + onLoadInstances++; nextEventId = readyId; readyId++; } finally { queueLock.unlock(); } - + EventInstanceManager eim = new EventInstanceManager(this, "sampleName" + nextEventId); queueLock.lock(); try { if (this.isDisposed()) { // EM already disposed return; } - + readyInstances.add(eim); onLoadInstances--; } finally { queueLock.unlock(); } - + instantiateQueuedInstance(); // keep filling the queue until reach threshold. } - + private class EventManagerTask implements Runnable { - + @Override public void run() { instantiateQueuedInstance(); diff --git a/src/main/java/scripting/event/EventScheduledFuture.java b/src/main/java/scripting/event/EventScheduledFuture.java index 8d0be3bbb4..0f9ae42a8c 100644 --- a/src/main/java/scripting/event/EventScheduledFuture.java +++ b/src/main/java/scripting/event/EventScheduledFuture.java @@ -22,18 +22,17 @@ package scripting.event; import scripting.event.scheduler.EventScriptScheduler; /** - * * @author Ronan */ public class EventScheduledFuture { Runnable r; EventScriptScheduler ess; - + public EventScheduledFuture(Runnable r, EventScriptScheduler ess) { this.r = r; this.ess = ess; } - + public void cancel(boolean dummy) { // will always implement "non-interrupt if running" regardless of boolean value ess.cancelEntry(r); } diff --git a/src/main/java/scripting/event/EventScriptManager.java b/src/main/java/scripting/event/EventScriptManager.java index 18a13d454d..ac474c185d 100644 --- a/src/main/java/scripting/event/EventScriptManager.java +++ b/src/main/java/scripting/event/EventScriptManager.java @@ -36,7 +36,6 @@ import java.util.logging.Level; import java.util.logging.Logger; /** - * * @author Matze */ public class EventScriptManager extends AbstractScriptManager { @@ -51,6 +50,7 @@ public class EventScriptManager extends AbstractScriptManager { this.iv = iv; this.em = em; } + public Invocable iv; public EventManager em; } @@ -61,7 +61,7 @@ public class EventScriptManager extends AbstractScriptManager { events.put(script, initializeEventEntry(script, channel)); } } - + init(); fallback = events.remove("0_EXAMPLE"); } @@ -73,11 +73,11 @@ public class EventScriptManager extends AbstractScriptManager { } return entry.em; } - + public boolean isActive() { return active; } - + public final void init() { for (EventEntry entry : events.values()) { try { @@ -87,7 +87,7 @@ public class EventScriptManager extends AbstractScriptManager { System.out.println("Error on script: " + entry.em.getName()); } } - + active = events.size() > 1; // bootup loads only 1 script } @@ -125,15 +125,15 @@ public class EventScriptManager extends AbstractScriptManager { entry.em.cancel(); } } - + public void dispose() { if (events.isEmpty()) { return; } - + Set eventEntries = new HashSet<>(events.values()); events.clear(); - + active = false; for (EventEntry entry : eventEntries) { entry.em.cancel(); diff --git a/src/main/java/scripting/event/scheduler/EventScriptScheduler.java b/src/main/java/scripting/event/scheduler/EventScriptScheduler.java index 6646a7df81..f0d1e85bc3 100644 --- a/src/main/java/scripting/event/scheduler/EventScriptScheduler.java +++ b/src/main/java/scripting/event/scheduler/EventScriptScheduler.java @@ -36,18 +36,17 @@ import java.util.Map.Entry; import java.util.concurrent.ScheduledFuture; /** - * * @author Ronan */ public class EventScriptScheduler { private boolean disposed = false; private int idleProcs = 0; - private Map registeredEntries = new HashMap<>(); + private final Map registeredEntries = new HashMap<>(); private ScheduledFuture schedulerTask = null; private MonitoredReentrantLock schedulerLock; - private Runnable monitorTask = () -> runBaseSchedule(); + private final Runnable monitorTask = () -> runBaseSchedule(); public EventScriptScheduler() { schedulerLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EM_SCHDL, true); diff --git a/src/main/java/scripting/item/ItemScriptManager.java b/src/main/java/scripting/item/ItemScriptManager.java index 657faf53de..4085eeed06 100644 --- a/src/main/java/scripting/item/ItemScriptManager.java +++ b/src/main/java/scripting/item/ItemScriptManager.java @@ -27,12 +27,12 @@ import server.ItemInformationProvider.ScriptedItem; public class ItemScriptManager { - private static ItemScriptManager instance = new ItemScriptManager(); - + private static final ItemScriptManager instance = new ItemScriptManager(); + public static ItemScriptManager getInstance() { return instance; } - + public void runItemScript(Client c, ScriptedItem scriptItem) { NPCScriptManager.getInstance().start(c, scriptItem, null); } diff --git a/src/main/java/scripting/item/ItemScriptMethods.java b/src/main/java/scripting/item/ItemScriptMethods.java index e63f5b5461..e6c745ba9b 100644 --- a/src/main/java/scripting/item/ItemScriptMethods.java +++ b/src/main/java/scripting/item/ItemScriptMethods.java @@ -25,11 +25,10 @@ import client.Client; import scripting.AbstractPlayerInteraction; /** - * * @author kevintjuh93 */ public class ItemScriptMethods extends AbstractPlayerInteraction { public ItemScriptMethods(Client c) { - super(c); + super(c); } } diff --git a/src/main/java/scripting/map/MapScriptManager.java b/src/main/java/scripting/map/MapScriptManager.java index 544416b095..b8f8e2dd0b 100644 --- a/src/main/java/scripting/map/MapScriptManager.java +++ b/src/main/java/scripting/map/MapScriptManager.java @@ -54,7 +54,7 @@ public class MapScriptManager extends AbstractScriptManager { chr.enteredScript(mapScriptPath, mapid); } } - + Invocable iv = scripts.get(mapScriptPath); if (iv != null) { try { @@ -64,13 +64,13 @@ public class MapScriptManager extends AbstractScriptManager { e.printStackTrace(); } } - + try { iv = (Invocable) getInvocableScriptEngine("map/" + mapScriptPath + ".js"); if (iv == null) { return false; } - + scripts.put(mapScriptPath, iv); iv.invokeFunction("start", new MapScriptMethods(c)); return true; diff --git a/src/main/java/scripting/map/MapScriptMethods.java b/src/main/java/scripting/map/MapScriptMethods.java index 3b1c71b2d4..f9ceea8743 100644 --- a/src/main/java/scripting/map/MapScriptMethods.java +++ b/src/main/java/scripting/map/MapScriptMethods.java @@ -29,13 +29,13 @@ import server.quest.Quest; import tools.PacketCreator; public class MapScriptMethods extends AbstractPlayerInteraction { - - private String rewardstring = " title has been rewarded. Please see NPC Dalair to receive your Medal."; - - public MapScriptMethods(Client c) { + + private final String rewardstring = " title has been rewarded. Please see NPC Dalair to receive your Medal."; + + public MapScriptMethods(Client c) { super(c); } - + public void displayCygnusIntro() { switch (c.getPlayer().getMapId()) { case 913040100: @@ -63,7 +63,7 @@ public class MapScriptMethods extends AbstractPlayerInteraction { break; } } - + public void displayAranIntro() { switch (c.getPlayer().getMapId()) { case 914090010: diff --git a/src/main/java/scripting/npc/NPCConversationManager.java b/src/main/java/scripting/npc/NPCConversationManager.java index d9277025d8..288e2cda43 100644 --- a/src/main/java/scripting/npc/NPCConversationManager.java +++ b/src/main/java/scripting/npc/NPCConversationManager.java @@ -70,1040 +70,1023 @@ import java.util.List; import java.util.*; /** - * * @author Matze */ public class NPCConversationManager extends AbstractPlayerInteraction { - - private int npc; - private int npcOid; - private String scriptName; - private String getText; - private boolean itemScript; - private List otherParty; - - private Map npcDefaultTalks = new HashMap<>(); - - private String getDefaultTalk(int npcid) { - String talk = npcDefaultTalks.get(npcid); - if (talk == null) { - talk = LifeFactory.getNPCDefaultTalk(npcid); - npcDefaultTalks.put(npcid, talk); - } - - return talk; - } - - public NPCConversationManager(Client c, int npc, String scriptName) { - this(c, npc, -1, scriptName, false); - } - - public NPCConversationManager(Client c, int npc, List otherParty, boolean test) { - super(c); - this.c = c; - this.npc = npc; - this.otherParty = otherParty; - } - - public NPCConversationManager(Client c, int npc, int oid, String scriptName, boolean itemScript) { - super(c); - this.npc = npc; - this.npcOid = oid; - this.scriptName = scriptName; - this.itemScript = itemScript; - } - public int getNpc() { - return npc; - } - - public int getNpcObjectId() { - return npcOid; - } + private final int npc; + private int npcOid; + private String scriptName; + private String getText; + private boolean itemScript; + private List otherParty; - public String getScriptName() { - return scriptName; - } - - public boolean isItemScript() { - return itemScript; - } - - public void resetItemScript() { - this.itemScript = false; + private final Map npcDefaultTalks = new HashMap<>(); + + private String getDefaultTalk(int npcid) { + String talk = npcDefaultTalks.get(npcid); + if (talk == null) { + talk = LifeFactory.getNPCDefaultTalk(npcid); + npcDefaultTalks.put(npcid, talk); } - public void dispose() { - NPCScriptManager.getInstance().dispose(this); - getClient().sendPacket(PacketCreator.enableActions()); - } + return talk; + } - public void sendNext(String text) { - getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "00 01", (byte) 0)); - } + public NPCConversationManager(Client c, int npc, String scriptName) { + this(c, npc, -1, scriptName, false); + } - public void sendPrev(String text) { - getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "01 00", (byte) 0)); - } + public NPCConversationManager(Client c, int npc, List otherParty, boolean test) { + super(c); + this.c = c; + this.npc = npc; + this.otherParty = otherParty; + } - public void sendNextPrev(String text) { - getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "01 01", (byte) 0)); - } + public NPCConversationManager(Client c, int npc, int oid, String scriptName, boolean itemScript) { + super(c); + this.npc = npc; + this.npcOid = oid; + this.scriptName = scriptName; + this.itemScript = itemScript; + } - public void sendOk(String text) { - getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "00 00", (byte) 0)); - } - - public void sendDefault() { - sendOk(getDefaultTalk(npc)); + public int getNpc() { + return npc; + } + + public int getNpcObjectId() { + return npcOid; + } + + public String getScriptName() { + return scriptName; + } + + public boolean isItemScript() { + return itemScript; + } + + public void resetItemScript() { + this.itemScript = false; + } + + public void dispose() { + NPCScriptManager.getInstance().dispose(this); + getClient().sendPacket(PacketCreator.enableActions()); + } + + public void sendNext(String text) { + getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "00 01", (byte) 0)); + } + + public void sendPrev(String text) { + getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "01 00", (byte) 0)); + } + + public void sendNextPrev(String text) { + getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "01 01", (byte) 0)); + } + + public void sendOk(String text) { + getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "00 00", (byte) 0)); + } + + public void sendDefault() { + sendOk(getDefaultTalk(npc)); + } + + public void sendYesNo(String text) { + getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 1, text, "", (byte) 0)); + } + + public void sendAcceptDecline(String text) { + getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0x0C, text, "", (byte) 0)); + } + + public void sendSimple(String text) { + getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 4, text, "", (byte) 0)); + } + + public void sendNext(String text, byte speaker) { + getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "00 01", speaker)); + } + + public void sendPrev(String text, byte speaker) { + getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "01 00", speaker)); + } + + public void sendNextPrev(String text, byte speaker) { + getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "01 01", speaker)); + } + + public void sendOk(String text, byte speaker) { + getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "00 00", speaker)); + } + + public void sendYesNo(String text, byte speaker) { + getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 1, text, "", speaker)); + } + + public void sendAcceptDecline(String text, byte speaker) { + getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0x0C, text, "", speaker)); + } + + public void sendSimple(String text, byte speaker) { + getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 4, text, "", speaker)); + } + + public void sendStyle(String text, int[] styles) { + if (styles.length > 0) { + getClient().sendPacket(PacketCreator.getNPCTalkStyle(npc, text, styles)); + } else { // thanks Conrad for noticing empty styles crashing players + sendOk("Sorry, there are no options of cosmetics available for you here at the moment."); + dispose(); } + } - public void sendYesNo(String text) { - getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 1, text, "", (byte) 0)); - } + public void sendGetNumber(String text, int def, int min, int max) { + getClient().sendPacket(PacketCreator.getNPCTalkNum(npc, text, def, min, max)); + } - public void sendAcceptDecline(String text) { - getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0x0C, text, "", (byte) 0)); - } + public void sendGetText(String text) { + getClient().sendPacket(PacketCreator.getNPCTalkText(npc, text, "")); + } - public void sendSimple(String text) { - getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 4, text, "", (byte) 0)); - } + /* + * 0 = ariant colliseum + * 1 = Dojo + * 2 = Carnival 1 + * 3 = Carnival 2 + * 4 = Ghost Ship PQ? + * 5 = Pyramid PQ + * 6 = Kerning Subway + */ + public void sendDimensionalMirror(String text) { + getClient().sendPacket(PacketCreator.getDimensionalMirror(text)); + } - public void sendNext(String text, byte speaker) { - getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "00 01", speaker)); - } + public void setGetText(String text) { + this.getText = text; + } - public void sendPrev(String text, byte speaker) { - getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "01 00", speaker)); - } + public String getText() { + return this.getText; + } - public void sendNextPrev(String text, byte speaker) { - getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "01 01", speaker)); - } + @Override + public boolean forceStartQuest(int id) { + return forceStartQuest(id, npc); + } - public void sendOk(String text, byte speaker) { - getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0, text, "00 00", speaker)); - } + @Override + public boolean forceCompleteQuest(int id) { + return forceCompleteQuest(id, npc); + } - public void sendYesNo(String text, byte speaker) { - getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 1, text, "", speaker)); - } + @Override + public boolean startQuest(short id) { + return startQuest((int) id); + } - public void sendAcceptDecline(String text, byte speaker) { - getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 0x0C, text, "", speaker)); - } + @Override + public boolean completeQuest(short id) { + return completeQuest((int) id); + } - public void sendSimple(String text, byte speaker) { - getClient().sendPacket(PacketCreator.getNPCTalk(npc, (byte) 4, text, "", speaker)); - } + @Override + public boolean startQuest(int id) { + return startQuest(id, npc); + } - public void sendStyle(String text, int[] styles) { - if (styles.length > 0) { - getClient().sendPacket(PacketCreator.getNPCTalkStyle(npc, text, styles)); - } else { // thanks Conrad for noticing empty styles crashing players - sendOk("Sorry, there are no options of cosmetics available for you here at the moment."); - dispose(); - } - } + @Override + public boolean completeQuest(int id) { + return completeQuest(id, npc); + } - public void sendGetNumber(String text, int def, int min, int max) { - getClient().sendPacket(PacketCreator.getNPCTalkNum(npc, text, def, min, max)); - } + public int getMeso() { + return getPlayer().getMeso(); + } - public void sendGetText(String text) { - getClient().sendPacket(PacketCreator.getNPCTalkText(npc, text, "")); - } + public void gainMeso(int gain) { + getPlayer().gainMeso(gain); + } - /* - * 0 = ariant colliseum - * 1 = Dojo - * 2 = Carnival 1 - * 3 = Carnival 2 - * 4 = Ghost Ship PQ? - * 5 = Pyramid PQ - * 6 = Kerning Subway - */ - public void sendDimensionalMirror(String text) { - getClient().sendPacket(PacketCreator.getDimensionalMirror(text)); - } + public void gainExp(int gain) { + getPlayer().gainExp(gain, true, true); + } - public void setGetText(String text) { - this.getText = text; - } + @Override + public void showEffect(String effect) { + getPlayer().getMap().broadcastMessage(PacketCreator.environmentChange(effect, 3)); + } - public String getText() { - return this.getText; - } + public void setHair(int hair) { + getPlayer().setHair(hair); + getPlayer().updateSingleStat(Stat.HAIR, hair); + getPlayer().equipChanged(); + } - @Override - public boolean forceStartQuest(int id) { - return forceStartQuest(id, npc); - } - - @Override - public boolean forceCompleteQuest(int id) { - return forceCompleteQuest(id, npc); - } - - @Override - public boolean startQuest(short id) { - return startQuest((int) id); - } - - @Override - public boolean completeQuest(short id) { - return completeQuest((int) id); - } - - @Override - public boolean startQuest(int id) { - return startQuest(id, npc); - } - - @Override - public boolean completeQuest(int id) { - return completeQuest(id, npc); - } - - public int getMeso() { - return getPlayer().getMeso(); - } + public void setFace(int face) { + getPlayer().setFace(face); + getPlayer().updateSingleStat(Stat.FACE, face); + getPlayer().equipChanged(); + } - public void gainMeso(int gain) { - getPlayer().gainMeso(gain); - } + public void setSkin(int color) { + getPlayer().setSkinColor(SkinColor.getById(color)); + getPlayer().updateSingleStat(Stat.SKIN, color); + getPlayer().equipChanged(); + } - public void gainExp(int gain) { - getPlayer().gainExp(gain, true, true); - } + public int itemQuantity(int itemid) { + return getPlayer().getInventory(ItemConstants.getInventoryType(itemid)).countById(itemid); + } - @Override - public void showEffect(String effect) { - getPlayer().getMap().broadcastMessage(PacketCreator.environmentChange(effect, 3)); - } + public void displayGuildRanks() { + Guild.displayGuildRanks(getClient(), npc); + } - public void setHair(int hair) { - getPlayer().setHair(hair); - getPlayer().updateSingleStat(Stat.HAIR, hair); - getPlayer().equipChanged(); - } + public boolean canSpawnPlayerNpc(int mapid) { + Character chr = getPlayer(); + return !YamlConfig.config.server.PLAYERNPC_AUTODEPLOY && chr.getLevel() >= chr.getMaxClassLevel() && !chr.isGM() && PlayerNPC.canSpawnPlayerNpc(chr.getName(), mapid); + } - public void setFace(int face) { - getPlayer().setFace(face); - getPlayer().updateSingleStat(Stat.FACE, face); - getPlayer().equipChanged(); - } + public PlayerNPC getPlayerNPCByScriptid(int scriptId) { + for (MapObject pnpcObj : getPlayer().getMap().getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapObjectType.PLAYER_NPC))) { + PlayerNPC pn = (PlayerNPC) pnpcObj; - public void setSkin(int color) { - getPlayer().setSkinColor(SkinColor.getById(color)); - getPlayer().updateSingleStat(Stat.SKIN, color); - getPlayer().equipChanged(); - } - - public int itemQuantity(int itemid) { - return getPlayer().getInventory(ItemConstants.getInventoryType(itemid)).countById(itemid); - } - - public void displayGuildRanks() { - Guild.displayGuildRanks(getClient(), npc); - } - - public boolean canSpawnPlayerNpc(int mapid) { - Character chr = getPlayer(); - return !YamlConfig.config.server.PLAYERNPC_AUTODEPLOY && chr.getLevel() >= chr.getMaxClassLevel() && !chr.isGM() && PlayerNPC.canSpawnPlayerNpc(chr.getName(), mapid); - } - - public PlayerNPC getPlayerNPCByScriptid(int scriptId) { - for(MapObject pnpcObj : getPlayer().getMap().getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapObjectType.PLAYER_NPC))) { - PlayerNPC pn = (PlayerNPC) pnpcObj; - - if(pn.getScriptId() == scriptId) { - return pn; - } - } - - return null; - } - - @Override - public Party getParty() { - return getPlayer().getParty(); - } - - @Override - public void resetMap(int mapid) { - getClient().getChannelServer().getMapFactory().getMap(mapid).resetReactors(); - } - - public void gainCloseness(int closeness) { - for (Pet pet : getPlayer().getPets()) { - if(pet != null) { - pet.gainClosenessFullness(getPlayer(), closeness, 0, 0); - } - } - } - - public String getName() { - return getPlayer().getName(); - } - - public int getGender() { - return getPlayer().getGender(); - } - - public void changeJobById(int a) { - getPlayer().changeJob(Job.getById(a)); - } - - public void changeJob(Job job) { - getPlayer().changeJob(job); - } - - public String getJobName(int id) { - return GameConstants.getJobName(id); - } - - public StatEffect getItemEffect(int itemId) { - return ItemInformationProvider.getInstance().getItemEffect(itemId); - } - - public void resetStats() { - getPlayer().resetStats(); - } - - public void openShopNPC(int id) { - Shop shop = ShopFactory.getInstance().getShop(id); - - if (shop != null) { - shop.sendShop(c); - } else { // check for missing shopids thanks to resinate - FilePrinter.printError(FilePrinter.NPC_UNCODED, "Shop ID: " + id + " is missing from database."); - ShopFactory.getInstance().getShop(11000).sendShop(c); + if (pn.getScriptId() == scriptId) { + return pn; } } - public void maxMastery() { - for (Data skill_ : DataProviderFactory.getDataProvider(WZFiles.STRING).getData("Skill.img").getChildren()) { - try { - Skill skill = SkillFactory.getSkill(Integer.parseInt(skill_.getName())); - getPlayer().changeSkillLevel(skill, (byte) 0, skill.getMaxLevel(), -1); - } catch (NumberFormatException nfe) { - nfe.printStackTrace(); - break; - } catch (NullPointerException npe) { - npe.printStackTrace(); - continue; - } - } - } + return null; + } - public void doGachapon() { - int[] maps = {100000000, 101000000, 102000000, 103000000, 105040300, 800000000, 809000101, 809000201, 600000000, 120000000}; + @Override + public Party getParty() { + return getPlayer().getParty(); + } - GachaponItem item = Gachapon.getInstance().process(npc); + @Override + public void resetMap(int mapid) { + getClient().getChannelServer().getMapFactory().getMap(mapid).resetReactors(); + } - Item itemGained = gainItem(item.getId(), (short) (item.getId() / 10000 == 200 ? 100 : 1), true, true); // For normal potions, make it give 100. - - sendNext("You have obtained a #b#t" + item.getId() + "##k."); - - String map = c.getChannelServer().getMapFactory().getMap(maps[(getNpc() != 9100117 && getNpc() != 9100109) ? (getNpc() - 9100100) : getNpc() == 9100109 ? 8 : 9]).getMapName(); - - LogHelper.logGacha(getPlayer(), item.getId(), map); - - if (item.getTier() > 0){ //Uncommon and Rare - Server.getInstance().broadcastMessage(c.getWorld(), PacketCreator.gachaponMessage(itemGained, map, getPlayer())); - } - } - - public void upgradeAlliance() { - Alliance alliance = Server.getInstance().getAlliance(c.getPlayer().getGuild().getAllianceId()); - alliance.increaseCapacity(1); - - Server.getInstance().allianceMessage(alliance.getId(), GuildPackets.getGuildAlliances(alliance, c.getWorld()), -1, -1); - Server.getInstance().allianceMessage(alliance.getId(), GuildPackets.allianceNotice(alliance.getId(), alliance.getNotice()), -1, -1); - - c.sendPacket(GuildPackets.updateAllianceInfo(alliance, c.getWorld())); // thanks Vcoc for finding an alliance update to leader issue - } - - public void disbandAlliance(Client c, int allianceId) { - Alliance.disbandAlliance(allianceId); - } - - public boolean canBeUsedAllianceName(String name) { - return Alliance.canBeUsedAllianceName(name); - } - - public Alliance createAlliance(String name) { - return Alliance.createAlliance(getParty(), name); - } - - public int getAllianceCapacity() { - return Server.getInstance().getAlliance(getPlayer().getGuild().getAllianceId()).getCapacity(); - } - - public boolean hasMerchant() { - return getPlayer().hasMerchant(); - } - - public boolean hasMerchantItems() { - try { - if (!ItemFactory.MERCHANT.loadItems(getPlayer().getId(), false).isEmpty()) { - return true; - } - } catch (SQLException e) { - e.printStackTrace(); - return false; - } - if (getPlayer().getMerchantMeso() == 0) { - return false; - } else { - return true; - } - } - - public void showFredrick() { - c.sendPacket(PacketCreator.getFredrick(getPlayer())); - } - - public int partyMembersInMap() { - int inMap = 0; - for (Character char2 : getPlayer().getMap().getCharacters()) { - if (char2.getParty() == getPlayer().getParty()) { - inMap++; - } - } - return inMap; - } - - public Event getEvent() { - return c.getChannelServer().getEvent(); - } - - public void divideTeams() { - if (getEvent() != null) { - getPlayer().setTeam(getEvent().getLimit() % 2); //muhaha :D - } - } - - public Character getMapleCharacter(String player) { - Character target = Server.getInstance().getWorld(c.getWorld()).getChannel(c.getChannel()).getPlayerStorage().getCharacterByName(player); - return target; - } - - public void logLeaf(String prize) { - LogHelper.logLeaf(getPlayer(), true, prize); - } - - public boolean createPyramid(String mode, boolean party) {//lol - PyramidMode mod = PyramidMode.valueOf(mode); - - Party partyz = getPlayer().getParty(); - MapManager mapManager = c.getChannelServer().getMapFactory(); - - MapleMap map = null; - int mapid = 926010100; - if (party) { - mapid += 10000; - } - mapid += (mod.getMode() * 1000); - - for (byte b = 0; b < 5; b++) {//They cannot warp to the next map before the timer ends (: - map = mapManager.getMap(mapid + b); - if (map.getCharacters().size() > 0) { - continue; - } else { - break; - } - } - - if (map == null) { - return false; - } - - if (!party) { - partyz = new Party(-1, new PartyCharacter(getPlayer())); - } - Pyramid py = new Pyramid(partyz, mod, map.getId()); - getPlayer().setPartyQuest(py); - py.warp(mapid); - dispose(); - return true; - } - - public boolean itemExists(int itemid) { - return ItemInformationProvider.getInstance().getName(itemid) != null; - } - - public int getCosmeticItem(int itemid) { - if (itemExists(itemid)) { - return itemid; - } - - int baseid; - if (itemid < 30000) { - baseid = (itemid / 1000) * 1000 + (itemid % 100); - } else { - baseid = (itemid / 10) * 10; - } - - return itemid != baseid && itemExists(baseid) ? baseid : -1; - } - - private int getEquippedCosmeticid(int itemid) { - if (itemid < 30000) { - return getPlayer().getFace(); - } else { - return getPlayer().getHair(); - } - } - - public boolean isCosmeticEquipped(int itemid) { - return getEquippedCosmeticid(itemid) == itemid; - } - - public boolean isUsingOldPqNpcStyle() { - return YamlConfig.config.server.USE_OLD_GMS_STYLED_PQ_NPCS && this.getPlayer().getParty() != null; - } - - public Object[] getAvailableMasteryBooks() { - return ItemInformationProvider.getInstance().usableMasteryBooks(this.getPlayer()).toArray(); - } - - public Object[] getAvailableSkillBooks() { - List ret = ItemInformationProvider.getInstance().usableSkillBooks(this.getPlayer()); - ret.addAll(SkillbookInformationProvider.getTeachableSkills(this.getPlayer())); - - return ret.toArray(); - } - - public Object[] getNamesWhoDropsItem(Integer itemId) { - return ItemInformationProvider.getInstance().getWhoDrops(itemId).toArray(); - } - - public String getSkillBookInfo(int itemid) { - SkillBookEntry sbe = SkillbookInformationProvider.getSkillbookAvailability(itemid); - switch (sbe) { - case UNAVAILABLE: - return ""; - - case REACTOR: - return " Obtainable through #rexploring#k (loot boxes)."; - - case SCRIPT: - return " Obtainable through #rexploring#k (field interaction)."; - - case QUEST_BOOK: - return " Obtainable through #rquestline#k (collecting book)."; - - case QUEST_REWARD: - return " Obtainable through #rquestline#k (quest reward)."; - - default: - return " Obtainable through #rquestline#k."; - } - } - - // (CPQ + WED wishlist) by -- Drago (Dragohe4rt) - public int cpqCalcAvgLvl(int map) { - int num = 0; - int avg = 0; - for (MapObject mmo : c.getChannelServer().getMapFactory().getMap(map).getAllPlayer()) { - avg += ((Character) mmo).getLevel(); - num++; - } - avg /= num; - return avg; - } - - public boolean sendCPQMapLists() { - String msg = LanguageConstants.getMessage(getPlayer(), LanguageConstants.CPQPickRoom); - int msgLen = msg.length(); - for (int i = 0; i < 6; i++) { - if (fieldTaken(i)) { - if (fieldLobbied(i)) { - msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (Level: " // "Carnival field" GMS-like improvement thanks to Jayd (jaydenseah) - + cpqCalcAvgLvl(980000100 + i * 100) + " / " - + getPlayerCount(980000100 + i * 100) + "x" - + getPlayerCount(980000100 + i * 100) + ") #l\r\n"; - } - } else { - if (i >= 0 && i <= 3) { - msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (2x2) #l\r\n"; - } else { - msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (3x3) #l\r\n"; - } - } - } - - if (msg.length() > msgLen) { - sendSimple(msg); - return true; - } else { - return false; + public void gainCloseness(int closeness) { + for (Pet pet : getPlayer().getPets()) { + if (pet != null) { + pet.gainClosenessFullness(getPlayer(), closeness, 0, 0); } } + } - public boolean fieldTaken(int field) { - if (!c.getChannelServer().canInitMonsterCarnival(true, field)) { - return true; - } - if (!c.getChannelServer().getMapFactory().getMap(980000100 + field * 100).getAllPlayer().isEmpty()) { - return true; - } - if (!c.getChannelServer().getMapFactory().getMap(980000101 + field * 100).getAllPlayer().isEmpty()) { - return true; - } - if (!c.getChannelServer().getMapFactory().getMap(980000102 + field * 100).getAllPlayer().isEmpty()) { - return true; - } - return false; + public String getName() { + return getPlayer().getName(); + } + + public int getGender() { + return getPlayer().getGender(); + } + + public void changeJobById(int a) { + getPlayer().changeJob(Job.getById(a)); + } + + public void changeJob(Job job) { + getPlayer().changeJob(job); + } + + public String getJobName(int id) { + return GameConstants.getJobName(id); + } + + public StatEffect getItemEffect(int itemId) { + return ItemInformationProvider.getInstance().getItemEffect(itemId); + } + + public void resetStats() { + getPlayer().resetStats(); + } + + public void openShopNPC(int id) { + Shop shop = ShopFactory.getInstance().getShop(id); + + if (shop != null) { + shop.sendShop(c); + } else { // check for missing shopids thanks to resinate + FilePrinter.printError(FilePrinter.NPC_UNCODED, "Shop ID: " + id + " is missing from database."); + ShopFactory.getInstance().getShop(11000).sendShop(c); } + } - public boolean fieldLobbied(int field) { - if (!c.getChannelServer().getMapFactory().getMap(980000100 + field * 100).getAllPlayer().isEmpty()) { - return true; - } - return false; - } - - public void cpqLobby(int field) { + public void maxMastery() { + for (Data skill_ : DataProviderFactory.getDataProvider(WZFiles.STRING).getData("Skill.img").getChildren()) { try { - final MapleMap map, mapExit; - Channel cs = c.getChannelServer(); - - map = cs.getMapFactory().getMap(980000100 + 100 * field); - mapExit = cs.getMapFactory().getMap(980000000); - for (PartyCharacter mpc : c.getPlayer().getParty().getMembers()) { - final Character mc = mpc.getPlayer(); - if (mc != null) { - mc.setChallenged(false); - mc.changeMap(map, map.getPortal(0)); - mc.sendPacket(PacketCreator.serverNotice(6, LanguageConstants.getMessage(mc, LanguageConstants.CPQEntryLobby))); - TimerManager tMan = TimerManager.getInstance(); - tMan.schedule(() -> mapClock(3 * 60), 1500); - - mc.setCpqTimer(TimerManager.getInstance().schedule(() -> mc.changeMap(mapExit, mapExit.getPortal(0)), 3 * 60 * 1000)); - } - } - } catch (Exception ex) { - ex.printStackTrace(); + Skill skill = SkillFactory.getSkill(Integer.parseInt(skill_.getName())); + getPlayer().changeSkillLevel(skill, (byte) 0, skill.getMaxLevel(), -1); + } catch (NumberFormatException nfe) { + nfe.printStackTrace(); + break; + } catch (NullPointerException npe) { + npe.printStackTrace(); + continue; + } + } + } + + public void doGachapon() { + int[] maps = {100000000, 101000000, 102000000, 103000000, 105040300, 800000000, 809000101, 809000201, 600000000, 120000000}; + + GachaponItem item = Gachapon.getInstance().process(npc); + + Item itemGained = gainItem(item.getId(), (short) (item.getId() / 10000 == 200 ? 100 : 1), true, true); // For normal potions, make it give 100. + + sendNext("You have obtained a #b#t" + item.getId() + "##k."); + + String map = c.getChannelServer().getMapFactory().getMap(maps[(getNpc() != 9100117 && getNpc() != 9100109) ? (getNpc() - 9100100) : getNpc() == 9100109 ? 8 : 9]).getMapName(); + + LogHelper.logGacha(getPlayer(), item.getId(), map); + + if (item.getTier() > 0) { //Uncommon and Rare + Server.getInstance().broadcastMessage(c.getWorld(), PacketCreator.gachaponMessage(itemGained, map, getPlayer())); + } + } + + public void upgradeAlliance() { + Alliance alliance = Server.getInstance().getAlliance(c.getPlayer().getGuild().getAllianceId()); + alliance.increaseCapacity(1); + + Server.getInstance().allianceMessage(alliance.getId(), GuildPackets.getGuildAlliances(alliance, c.getWorld()), -1, -1); + Server.getInstance().allianceMessage(alliance.getId(), GuildPackets.allianceNotice(alliance.getId(), alliance.getNotice()), -1, -1); + + c.sendPacket(GuildPackets.updateAllianceInfo(alliance, c.getWorld())); // thanks Vcoc for finding an alliance update to leader issue + } + + public void disbandAlliance(Client c, int allianceId) { + Alliance.disbandAlliance(allianceId); + } + + public boolean canBeUsedAllianceName(String name) { + return Alliance.canBeUsedAllianceName(name); + } + + public Alliance createAlliance(String name) { + return Alliance.createAlliance(getParty(), name); + } + + public int getAllianceCapacity() { + return Server.getInstance().getAlliance(getPlayer().getGuild().getAllianceId()).getCapacity(); + } + + public boolean hasMerchant() { + return getPlayer().hasMerchant(); + } + + public boolean hasMerchantItems() { + try { + if (!ItemFactory.MERCHANT.loadItems(getPlayer().getId(), false).isEmpty()) { + return true; + } + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return getPlayer().getMerchantMeso() != 0; + } + + public void showFredrick() { + c.sendPacket(PacketCreator.getFredrick(getPlayer())); + } + + public int partyMembersInMap() { + int inMap = 0; + for (Character char2 : getPlayer().getMap().getCharacters()) { + if (char2.getParty() == getPlayer().getParty()) { + inMap++; + } + } + return inMap; + } + + public Event getEvent() { + return c.getChannelServer().getEvent(); + } + + public void divideTeams() { + if (getEvent() != null) { + getPlayer().setTeam(getEvent().getLimit() % 2); //muhaha :D + } + } + + public Character getMapleCharacter(String player) { + Character target = Server.getInstance().getWorld(c.getWorld()).getChannel(c.getChannel()).getPlayerStorage().getCharacterByName(player); + return target; + } + + public void logLeaf(String prize) { + LogHelper.logLeaf(getPlayer(), true, prize); + } + + public boolean createPyramid(String mode, boolean party) {//lol + PyramidMode mod = PyramidMode.valueOf(mode); + + Party partyz = getPlayer().getParty(); + MapManager mapManager = c.getChannelServer().getMapFactory(); + + MapleMap map = null; + int mapid = 926010100; + if (party) { + mapid += 10000; + } + mapid += (mod.getMode() * 1000); + + for (byte b = 0; b < 5; b++) {//They cannot warp to the next map before the timer ends (: + map = mapManager.getMap(mapid + b); + if (map.getCharacters().size() > 0) { + continue; + } else { + break; } } - public Character getChrById(int id) { - return c.getChannelServer().getPlayerStorage().getCharacterById(id); + if (map == null) { + return false; } - public void cancelCPQLobby() { + if (!party) { + partyz = new Party(-1, new PartyCharacter(getPlayer())); + } + Pyramid py = new Pyramid(partyz, mod, map.getId()); + getPlayer().setPartyQuest(py); + py.warp(mapid); + dispose(); + return true; + } + + public boolean itemExists(int itemid) { + return ItemInformationProvider.getInstance().getName(itemid) != null; + } + + public int getCosmeticItem(int itemid) { + if (itemExists(itemid)) { + return itemid; + } + + int baseid; + if (itemid < 30000) { + baseid = (itemid / 1000) * 1000 + (itemid % 100); + } else { + baseid = (itemid / 10) * 10; + } + + return itemid != baseid && itemExists(baseid) ? baseid : -1; + } + + private int getEquippedCosmeticid(int itemid) { + if (itemid < 30000) { + return getPlayer().getFace(); + } else { + return getPlayer().getHair(); + } + } + + public boolean isCosmeticEquipped(int itemid) { + return getEquippedCosmeticid(itemid) == itemid; + } + + public boolean isUsingOldPqNpcStyle() { + return YamlConfig.config.server.USE_OLD_GMS_STYLED_PQ_NPCS && this.getPlayer().getParty() != null; + } + + public Object[] getAvailableMasteryBooks() { + return ItemInformationProvider.getInstance().usableMasteryBooks(this.getPlayer()).toArray(); + } + + public Object[] getAvailableSkillBooks() { + List ret = ItemInformationProvider.getInstance().usableSkillBooks(this.getPlayer()); + ret.addAll(SkillbookInformationProvider.getTeachableSkills(this.getPlayer())); + + return ret.toArray(); + } + + public Object[] getNamesWhoDropsItem(Integer itemId) { + return ItemInformationProvider.getInstance().getWhoDrops(itemId).toArray(); + } + + public String getSkillBookInfo(int itemid) { + SkillBookEntry sbe = SkillbookInformationProvider.getSkillbookAvailability(itemid); + switch (sbe) { + case UNAVAILABLE: + return ""; + + case REACTOR: + return " Obtainable through #rexploring#k (loot boxes)."; + + case SCRIPT: + return " Obtainable through #rexploring#k (field interaction)."; + + case QUEST_BOOK: + return " Obtainable through #rquestline#k (collecting book)."; + + case QUEST_REWARD: + return " Obtainable through #rquestline#k (quest reward)."; + + default: + return " Obtainable through #rquestline#k."; + } + } + + // (CPQ + WED wishlist) by -- Drago (Dragohe4rt) + public int cpqCalcAvgLvl(int map) { + int num = 0; + int avg = 0; + for (MapObject mmo : c.getChannelServer().getMapFactory().getMap(map).getAllPlayer()) { + avg += ((Character) mmo).getLevel(); + num++; + } + avg /= num; + return avg; + } + + public boolean sendCPQMapLists() { + String msg = LanguageConstants.getMessage(getPlayer(), LanguageConstants.CPQPickRoom); + int msgLen = msg.length(); + for (int i = 0; i < 6; i++) { + if (fieldTaken(i)) { + if (fieldLobbied(i)) { + msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (Level: " // "Carnival field" GMS-like improvement thanks to Jayd (jaydenseah) + + cpqCalcAvgLvl(980000100 + i * 100) + " / " + + getPlayerCount(980000100 + i * 100) + "x" + + getPlayerCount(980000100 + i * 100) + ") #l\r\n"; + } + } else { + if (i >= 0 && i <= 3) { + msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (2x2) #l\r\n"; + } else { + msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (3x3) #l\r\n"; + } + } + } + + if (msg.length() > msgLen) { + sendSimple(msg); + return true; + } else { + return false; + } + } + + public boolean fieldTaken(int field) { + if (!c.getChannelServer().canInitMonsterCarnival(true, field)) { + return true; + } + if (!c.getChannelServer().getMapFactory().getMap(980000100 + field * 100).getAllPlayer().isEmpty()) { + return true; + } + if (!c.getChannelServer().getMapFactory().getMap(980000101 + field * 100).getAllPlayer().isEmpty()) { + return true; + } + return !c.getChannelServer().getMapFactory().getMap(980000102 + field * 100).getAllPlayer().isEmpty(); + } + + public boolean fieldLobbied(int field) { + return !c.getChannelServer().getMapFactory().getMap(980000100 + field * 100).getAllPlayer().isEmpty(); + } + + public void cpqLobby(int field) { + try { + final MapleMap map, mapExit; + Channel cs = c.getChannelServer(); + + map = cs.getMapFactory().getMap(980000100 + 100 * field); + mapExit = cs.getMapFactory().getMap(980000000); for (PartyCharacter mpc : c.getPlayer().getParty().getMembers()) { - Character mc = mpc.getPlayer(); + final Character mc = mpc.getPlayer(); if (mc != null) { - mc.clearCpqTimer(); + mc.setChallenged(false); + mc.changeMap(map, map.getPortal(0)); + mc.sendPacket(PacketCreator.serverNotice(6, LanguageConstants.getMessage(mc, LanguageConstants.CPQEntryLobby))); + TimerManager tMan = TimerManager.getInstance(); + tMan.schedule(() -> mapClock(3 * 60), 1500); + + mc.setCpqTimer(TimerManager.getInstance().schedule(() -> mc.changeMap(mapExit, mapExit.getPortal(0)), 3 * 60 * 1000)); } } + } catch (Exception ex) { + ex.printStackTrace(); } - - private void warpoutCPQLobby(MapleMap lobbyMap) { - MapleMap out = lobbyMap.getChannelServer().getMapFactory().getMap((lobbyMap.getId() < 980030000) ? 980000000 : 980030000); - for (Character mc : lobbyMap.getAllPlayers()) { - mc.resetCP(); - mc.setTeam(-1); - mc.setMonsterCarnival(null); - mc.changeMap(out, out.getPortal(0)); + } + + public Character getChrById(int id) { + return c.getChannelServer().getPlayerStorage().getCharacterById(id); + } + + public void cancelCPQLobby() { + for (PartyCharacter mpc : c.getPlayer().getParty().getMembers()) { + Character mc = mpc.getPlayer(); + if (mc != null) { + mc.clearCpqTimer(); } } - - private int isCPQParty(MapleMap lobby, Party party) { - int cpqMinLvl, cpqMaxLvl; - - if (lobby.isCPQLobby()) { - cpqMinLvl = 30; - cpqMaxLvl = 50; - } else { - cpqMinLvl = 51; - cpqMaxLvl = 70; - } - - List partyMembers = party.getPartyMembers(); - for (PartyCharacter pchr : partyMembers) { - if (pchr.getLevel() >= cpqMinLvl && pchr.getLevel() <= cpqMaxLvl) { - if (lobby.getCharacterById(pchr.getId()) == null) { - return 1; // party member detected out of area - } - } else { - return 2; // party member doesn't fit requirements - } - } - - return 0; + } + + private void warpoutCPQLobby(MapleMap lobbyMap) { + MapleMap out = lobbyMap.getChannelServer().getMapFactory().getMap((lobbyMap.getId() < 980030000) ? 980000000 : 980030000); + for (Character mc : lobbyMap.getAllPlayers()) { + mc.resetCP(); + mc.setTeam(-1); + mc.setMonsterCarnival(null); + mc.changeMap(out, out.getPortal(0)); } - - private int canStartCPQ(MapleMap lobby, Party party, Party challenger) { - int ret = isCPQParty(lobby, party); - if (ret != 0) { - return ret; - } - - ret = isCPQParty(lobby, challenger); - if (ret != 0) { - return -ret; - } - - return 0; + } + + private int isCPQParty(MapleMap lobby, Party party) { + int cpqMinLvl, cpqMaxLvl; + + if (lobby.isCPQLobby()) { + cpqMinLvl = 30; + cpqMaxLvl = 50; + } else { + cpqMinLvl = 51; + cpqMaxLvl = 70; } - public void startCPQ(final Character challenger, final int field) { - try { - cancelCPQLobby(); - - final MapleMap lobbyMap = getPlayer().getMap(); - if (challenger != null) { - if (challenger.getParty() == null) { - throw new RuntimeException("No opponent found!"); + List partyMembers = party.getPartyMembers(); + for (PartyCharacter pchr : partyMembers) { + if (pchr.getLevel() >= cpqMinLvl && pchr.getLevel() <= cpqMaxLvl) { + if (lobby.getCharacterById(pchr.getId()) == null) { + return 1; // party member detected out of area + } + } else { + return 2; // party member doesn't fit requirements + } + } + + return 0; + } + + private int canStartCPQ(MapleMap lobby, Party party, Party challenger) { + int ret = isCPQParty(lobby, party); + if (ret != 0) { + return ret; + } + + ret = isCPQParty(lobby, challenger); + if (ret != 0) { + return -ret; + } + + return 0; + } + + public void startCPQ(final Character challenger, final int field) { + try { + cancelCPQLobby(); + + final MapleMap lobbyMap = getPlayer().getMap(); + if (challenger != null) { + if (challenger.getParty() == null) { + throw new RuntimeException("No opponent found!"); + } + + for (PartyCharacter mpc : challenger.getParty().getMembers()) { + Character mc = mpc.getPlayer(); + if (mc != null) { + mc.changeMap(lobbyMap, lobbyMap.getPortal(0)); + TimerManager tMan = TimerManager.getInstance(); + tMan.schedule(() -> mapClock(10), 1500); } - - for (PartyCharacter mpc : challenger.getParty().getMembers()) { - Character mc = mpc.getPlayer(); - if (mc != null) { - mc.changeMap(lobbyMap, lobbyMap.getPortal(0)); - TimerManager tMan = TimerManager.getInstance(); - tMan.schedule(() -> mapClock(10), 1500); - } + } + for (PartyCharacter mpc : getPlayer().getParty().getMembers()) { + Character mc = mpc.getPlayer(); + if (mc != null) { + TimerManager tMan = TimerManager.getInstance(); + tMan.schedule(() -> mapClock(10), 1500); } + } + } + final int mapid = c.getPlayer().getMapId() + 1; + TimerManager tMan = TimerManager.getInstance(); + tMan.schedule(() -> { + try { for (PartyCharacter mpc : getPlayer().getParty().getMembers()) { Character mc = mpc.getPlayer(); if (mc != null) { - TimerManager tMan = TimerManager.getInstance(); - tMan.schedule(() -> mapClock(10), 1500); + mc.setMonsterCarnival(null); } } - } - final int mapid = c.getPlayer().getMapId() + 1; - TimerManager tMan = TimerManager.getInstance(); - tMan.schedule(() -> { - try { - for (PartyCharacter mpc : getPlayer().getParty().getMembers()) { - Character mc = mpc.getPlayer(); - if (mc != null) { - mc.setMonsterCarnival(null); - } - } - for (PartyCharacter mpc : challenger.getParty().getMembers()) { - Character mc = mpc.getPlayer(); - if (mc != null) { - mc.setMonsterCarnival(null); - } - } - } catch (NullPointerException npe) { - warpoutCPQLobby(lobbyMap); - return; - } - - Party lobbyParty = getPlayer().getParty(), challengerParty = challenger.getParty(); - int status = canStartCPQ(lobbyMap, lobbyParty, challengerParty); - if (status == 0) { - new MonsterCarnival(lobbyParty, challengerParty, mapid, true, (field / 100) % 10); - } else { - warpoutCPQLobby(lobbyMap); - } - }, 11000); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void startCPQ2(final Character challenger, final int field) { - try { - cancelCPQLobby(); - - final MapleMap lobbyMap = getPlayer().getMap(); - if (challenger != null) { - if (challenger.getParty() == null) { - throw new RuntimeException("No opponent found!"); - } - for (PartyCharacter mpc : challenger.getParty().getMembers()) { Character mc = mpc.getPlayer(); if (mc != null) { - mc.changeMap(lobbyMap, lobbyMap.getPortal(0)); - mapClock(10); + mc.setMonsterCarnival(null); } } + } catch (NullPointerException npe) { + warpoutCPQLobby(lobbyMap); + return; } - final int mapid = c.getPlayer().getMapId() + 100; - TimerManager tMan = TimerManager.getInstance(); - tMan.schedule(() -> { - try { - for (PartyCharacter mpc : getPlayer().getParty().getMembers()) { - Character mc = mpc.getPlayer(); - if (mc != null) { - mc.setMonsterCarnival(null); - } - } - for (PartyCharacter mpc : challenger.getParty().getMembers()) { - Character mc = mpc.getPlayer(); - if (mc != null) { - mc.setMonsterCarnival(null); - } - } - } catch (NullPointerException npe) { - warpoutCPQLobby(lobbyMap); - return; - } - Party lobbyParty = getPlayer().getParty(), challengerParty = challenger.getParty(); - int status = canStartCPQ(lobbyMap, lobbyParty, challengerParty); - if (status == 0) { - new MonsterCarnival(lobbyParty, challengerParty, mapid, false, (field / 1000) % 10); - } else { - warpoutCPQLobby(lobbyMap); - } - }, 10000); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public boolean sendCPQMapLists2() { - String msg = LanguageConstants.getMessage(getPlayer(), LanguageConstants.CPQPickRoom); - int msgLen = msg.length(); - for (int i = 0; i < 3; i++) { - if (fieldTaken2(i)) { - if (fieldLobbied2(i)) { - msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (Level: " // "Carnival field" GMS-like improvement thanks to Jayd - + cpqCalcAvgLvl(980031000 + i * 1000) + " / " - + getPlayerCount(980031000 + i * 1000) + "x" - + getPlayerCount(980031000 + i * 1000) + ") #l\r\n"; - } + Party lobbyParty = getPlayer().getParty(), challengerParty = challenger.getParty(); + int status = canStartCPQ(lobbyMap, lobbyParty, challengerParty); + if (status == 0) { + new MonsterCarnival(lobbyParty, challengerParty, mapid, true, (field / 100) % 10); } else { - if (i == 0 || i == 1) { - msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (2x2) #l\r\n"; - } else { - msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (3x3) #l\r\n"; - } + warpoutCPQLobby(lobbyMap); } - } - - if (msg.length() > msgLen) { - sendSimple(msg); - return true; - } else { - return false; - } + }, 11000); + } catch (Exception e) { + e.printStackTrace(); } + } - public boolean fieldTaken2(int field) { - if (!c.getChannelServer().canInitMonsterCarnival(false, field)) { - return true; - } - if (!c.getChannelServer().getMapFactory().getMap(980031000 + field * 1000).getAllPlayer().isEmpty()) { - return true; - } - if (!c.getChannelServer().getMapFactory().getMap(980031100 + field * 1000).getAllPlayer().isEmpty()) { - return true; - } - if (!c.getChannelServer().getMapFactory().getMap(980031200 + field * 1000).getAllPlayer().isEmpty()) { - return true; - } - return false; - } + public void startCPQ2(final Character challenger, final int field) { + try { + cancelCPQLobby(); - public boolean fieldLobbied2(int field) { - if (!c.getChannelServer().getMapFactory().getMap(980031000 + field * 1000).getAllPlayer().isEmpty()) { - return true; - } - return false; - } + final MapleMap lobbyMap = getPlayer().getMap(); + if (challenger != null) { + if (challenger.getParty() == null) { + throw new RuntimeException("No opponent found!"); + } - public void cpqLobby2(int field) { - try { - final MapleMap map, mapExit; - Channel cs = c.getChannelServer(); - - mapExit = cs.getMapFactory().getMap(980030000); - map = cs.getMapFactory().getMap(980031000 + 1000 * field); - for (PartyCharacter mpc : c.getPlayer().getParty().getMembers()) { - final Character mc = mpc.getPlayer(); + for (PartyCharacter mpc : challenger.getParty().getMembers()) { + Character mc = mpc.getPlayer(); if (mc != null) { - mc.setChallenged(false); - mc.changeMap(map, map.getPortal(0)); - mc.sendPacket(PacketCreator.serverNotice(6, LanguageConstants.getMessage(mc, LanguageConstants.CPQEntryLobby))); - TimerManager tMan = TimerManager.getInstance(); - tMan.schedule(() -> mapClock(3 * 60), 1500); - - mc.setCpqTimer(TimerManager.getInstance().schedule(() -> mc.changeMap(mapExit, mapExit.getPortal(0)), 3 * 60 * 1000)); + mc.changeMap(lobbyMap, lobbyMap.getPortal(0)); + mapClock(10); } } - } catch (Exception ex) { - ex.printStackTrace(); } - } - - public void mapClock(int time) { - getPlayer().getMap().broadcastMessage(PacketCreator.getClock(time)); - } - - private boolean sendCPQChallenge(String cpqType, int leaderid) { - Set cpqLeaders = new HashSet<>(); - cpqLeaders.add(leaderid); - cpqLeaders.add(getPlayer().getId()); - - return c.getWorldServer().getMatchCheckerCoordinator().createMatchConfirmation(MatchCheckerType.CPQ_CHALLENGE, c.getWorld(), getPlayer().getId(), cpqLeaders, cpqType); - } - - public void answerCPQChallenge(boolean accept) { - c.getWorldServer().getMatchCheckerCoordinator().answerMatchConfirmation(getPlayer().getId(), accept); - } - - public void challengeParty2(int field) { - Character leader = null; - MapleMap map = c.getChannelServer().getMapFactory().getMap(980031000 + 1000 * field); - for (MapObject mmo : map.getAllPlayer()) { - Character mc = (Character) mmo; - if (mc.getParty() == null) { - sendOk(LanguageConstants.getMessage(mc, LanguageConstants.CPQFindError)); + final int mapid = c.getPlayer().getMapId() + 100; + TimerManager tMan = TimerManager.getInstance(); + tMan.schedule(() -> { + try { + for (PartyCharacter mpc : getPlayer().getParty().getMembers()) { + Character mc = mpc.getPlayer(); + if (mc != null) { + mc.setMonsterCarnival(null); + } + } + for (PartyCharacter mpc : challenger.getParty().getMembers()) { + Character mc = mpc.getPlayer(); + if (mc != null) { + mc.setMonsterCarnival(null); + } + } + } catch (NullPointerException npe) { + warpoutCPQLobby(lobbyMap); return; } - if (mc.getParty().getLeader().getId() == mc.getId()) { - leader = mc; - break; - } - } - if (leader != null) { - if (!leader.isChallenged()) { - if (!sendCPQChallenge("cpq2", leader.getId())) { - sendOk(LanguageConstants.getMessage(leader, LanguageConstants.CPQChallengeRoomAnswer)); - } + + Party lobbyParty = getPlayer().getParty(), challengerParty = challenger.getParty(); + int status = canStartCPQ(lobbyMap, lobbyParty, challengerParty); + if (status == 0) { + new MonsterCarnival(lobbyParty, challengerParty, mapid, false, (field / 1000) % 10); } else { - sendOk(LanguageConstants.getMessage(leader, LanguageConstants.CPQChallengeRoomAnswer)); + warpoutCPQLobby(lobbyMap); + } + }, 10000); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public boolean sendCPQMapLists2() { + String msg = LanguageConstants.getMessage(getPlayer(), LanguageConstants.CPQPickRoom); + int msgLen = msg.length(); + for (int i = 0; i < 3; i++) { + if (fieldTaken2(i)) { + if (fieldLobbied2(i)) { + msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (Level: " // "Carnival field" GMS-like improvement thanks to Jayd + + cpqCalcAvgLvl(980031000 + i * 1000) + " / " + + getPlayerCount(980031000 + i * 1000) + "x" + + getPlayerCount(980031000 + i * 1000) + ") #l\r\n"; } } else { - sendOk(LanguageConstants.getMessage(leader, LanguageConstants.CPQLeaderNotFound)); - } - } - - public void challengeParty(int field) { - Character leader = null; - MapleMap map = c.getChannelServer().getMapFactory().getMap(980000100 + 100 * field); - if (map.getAllPlayer().size() != getPlayer().getParty().getMembers().size()) { - sendOk("An unexpected error regarding the other party has occurred."); - return; - } - for (MapObject mmo : map.getAllPlayer()) { - Character mc = (Character) mmo; - if (mc.getParty() == null) { - sendOk(LanguageConstants.getMessage(mc, LanguageConstants.CPQFindError)); - return; - } - if (mc.getParty().getLeader().getId() == mc.getId()) { - leader = mc; - break; - } - } - if (leader != null) { - if (!leader.isChallenged()) { - if (!sendCPQChallenge("cpq1", leader.getId())) { - sendOk(LanguageConstants.getMessage(leader, LanguageConstants.CPQChallengeRoomAnswer)); - } + if (i == 0 || i == 1) { + msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (2x2) #l\r\n"; } else { - sendOk(LanguageConstants.getMessage(leader, LanguageConstants.CPQChallengeRoomAnswer)); + msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (3x3) #l\r\n"; } - } else { - sendOk(LanguageConstants.getMessage(leader, LanguageConstants.CPQLeaderNotFound)); } } - - private synchronized boolean setupAriantBattle(Expedition exped, int mapid) { - MapleMap arenaMap = this.getMap().getChannelServer().getMapFactory().getMap(mapid + 1); - if (!arenaMap.getAllPlayers().isEmpty()) { - return false; - } - - new AriantColiseum(arenaMap, exped); + + if (msg.length() > msgLen) { + sendSimple(msg); + return true; + } else { + return false; + } + } + + public boolean fieldTaken2(int field) { + if (!c.getChannelServer().canInitMonsterCarnival(false, field)) { return true; } - - public String startAriantBattle(ExpeditionType expedType, int mapid) { - if (!GameConstants.isAriantColiseumLobby(mapid)) { - return "You cannot start an Ariant tournament from outside the Battle Arena Entrance."; - } - - Expedition exped = this.getMap().getChannelServer().getExpedition(expedType); - if (exped == null) { - return "Please register on an expedition before attempting to start an Ariant tournament."; - } - - List players = exped.getActiveMembers(); - - int playersSize = players.size(); - if (!(playersSize >= exped.getMinSize() && playersSize <= exped.getMaxSize())) { - return "Make sure there are between #r" + exped.getMinSize() + " ~ " + exped.getMaxSize() + " players#k in this room to start the battle."; - } - - MapleMap leaderMap = this.getMap(); - for (Character mc : players) { - if (mc.getMap() != leaderMap) { - return "All competing players should be on this area to start the battle."; - } - - if (mc.getParty() != null) { - return "All competing players must not be on a party to start the battle."; - } - - int level = mc.getLevel(); - if (!(level >= expedType.getMinLevel() && level <= expedType.getMaxLevel())) { - return "There are competing players outside of the acceptable level range in this room. All players must be on #blevel between 20~30#k to start the battle."; - } - } - - if (setupAriantBattle(exped, mapid)) { - return ""; - } else { - return "Other players are already competing on the Ariant tournament in this room. Please wait a while until the arena becomes available again."; - } + if (!c.getChannelServer().getMapFactory().getMap(980031000 + field * 1000).getAllPlayer().isEmpty()) { + return true; } - - public void sendMarriageWishlist(boolean groom) { - Character player = this.getPlayer(); - Marriage marriage = player.getMarriageInstance(); - if(marriage != null) { - int cid = marriage.getIntProperty(groom ? "groomId" : "brideId"); - Character chr = marriage.getPlayerById(cid); - if (chr != null) { - if (chr.getId() == player.getId()) { - player.sendPacket(WeddingPackets.onWeddingGiftResult((byte) 0xA, marriage.getWishlistItems(groom), marriage.getGiftItems(player.getClient(), groom))); - } else { - marriage.setIntProperty("wishlistSelection", groom ? 0 : 1); - player.sendPacket(WeddingPackets.onWeddingGiftResult((byte) 0x09, marriage.getWishlistItems(groom), marriage.getGiftItems(player.getClient(), groom))); - } - } - } - } - - public void sendMarriageGifts(List gifts) { - this.getPlayer().sendPacket(WeddingPackets.onWeddingGiftResult((byte) 0xA, Collections.singletonList(""), gifts)); + if (!c.getChannelServer().getMapFactory().getMap(980031100 + field * 1000).getAllPlayer().isEmpty()) { + return true; } + return !c.getChannelServer().getMapFactory().getMap(980031200 + field * 1000).getAllPlayer().isEmpty(); + } - public boolean createMarriageWishlist() { - Marriage marriage = this.getPlayer().getMarriageInstance(); - if (marriage != null) { - Boolean groom = marriage.isMarriageGroom(this.getPlayer()); - if (groom != null) { - String wlKey; - if (groom) { - wlKey = "groomWishlist"; - } else { - wlKey = "brideWishlist"; - } - - if (marriage.getProperty(wlKey).contentEquals("")) { - getClient().sendPacket(WeddingPackets.sendWishList()); - return true; - } + public boolean fieldLobbied2(int field) { + return !c.getChannelServer().getMapFactory().getMap(980031000 + field * 1000).getAllPlayer().isEmpty(); + } + + public void cpqLobby2(int field) { + try { + final MapleMap map, mapExit; + Channel cs = c.getChannelServer(); + + mapExit = cs.getMapFactory().getMap(980030000); + map = cs.getMapFactory().getMap(980031000 + 1000 * field); + for (PartyCharacter mpc : c.getPlayer().getParty().getMembers()) { + final Character mc = mpc.getPlayer(); + if (mc != null) { + mc.setChallenged(false); + mc.changeMap(map, map.getPortal(0)); + mc.sendPacket(PacketCreator.serverNotice(6, LanguageConstants.getMessage(mc, LanguageConstants.CPQEntryLobby))); + TimerManager tMan = TimerManager.getInstance(); + tMan.schedule(() -> mapClock(3 * 60), 1500); + + mc.setCpqTimer(TimerManager.getInstance().schedule(() -> mc.changeMap(mapExit, mapExit.getPortal(0)), 3 * 60 * 1000)); } } - + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void mapClock(int time) { + getPlayer().getMap().broadcastMessage(PacketCreator.getClock(time)); + } + + private boolean sendCPQChallenge(String cpqType, int leaderid) { + Set cpqLeaders = new HashSet<>(); + cpqLeaders.add(leaderid); + cpqLeaders.add(getPlayer().getId()); + + return c.getWorldServer().getMatchCheckerCoordinator().createMatchConfirmation(MatchCheckerType.CPQ_CHALLENGE, c.getWorld(), getPlayer().getId(), cpqLeaders, cpqType); + } + + public void answerCPQChallenge(boolean accept) { + c.getWorldServer().getMatchCheckerCoordinator().answerMatchConfirmation(getPlayer().getId(), accept); + } + + public void challengeParty2(int field) { + Character leader = null; + MapleMap map = c.getChannelServer().getMapFactory().getMap(980031000 + 1000 * field); + for (MapObject mmo : map.getAllPlayer()) { + Character mc = (Character) mmo; + if (mc.getParty() == null) { + sendOk(LanguageConstants.getMessage(mc, LanguageConstants.CPQFindError)); + return; + } + if (mc.getParty().getLeader().getId() == mc.getId()) { + leader = mc; + break; + } + } + if (leader != null) { + if (!leader.isChallenged()) { + if (!sendCPQChallenge("cpq2", leader.getId())) { + sendOk(LanguageConstants.getMessage(leader, LanguageConstants.CPQChallengeRoomAnswer)); + } + } else { + sendOk(LanguageConstants.getMessage(leader, LanguageConstants.CPQChallengeRoomAnswer)); + } + } else { + sendOk(LanguageConstants.getMessage(leader, LanguageConstants.CPQLeaderNotFound)); + } + } + + public void challengeParty(int field) { + Character leader = null; + MapleMap map = c.getChannelServer().getMapFactory().getMap(980000100 + 100 * field); + if (map.getAllPlayer().size() != getPlayer().getParty().getMembers().size()) { + sendOk("An unexpected error regarding the other party has occurred."); + return; + } + for (MapObject mmo : map.getAllPlayer()) { + Character mc = (Character) mmo; + if (mc.getParty() == null) { + sendOk(LanguageConstants.getMessage(mc, LanguageConstants.CPQFindError)); + return; + } + if (mc.getParty().getLeader().getId() == mc.getId()) { + leader = mc; + break; + } + } + if (leader != null) { + if (!leader.isChallenged()) { + if (!sendCPQChallenge("cpq1", leader.getId())) { + sendOk(LanguageConstants.getMessage(leader, LanguageConstants.CPQChallengeRoomAnswer)); + } + } else { + sendOk(LanguageConstants.getMessage(leader, LanguageConstants.CPQChallengeRoomAnswer)); + } + } else { + sendOk(LanguageConstants.getMessage(leader, LanguageConstants.CPQLeaderNotFound)); + } + } + + private synchronized boolean setupAriantBattle(Expedition exped, int mapid) { + MapleMap arenaMap = this.getMap().getChannelServer().getMapFactory().getMap(mapid + 1); + if (!arenaMap.getAllPlayers().isEmpty()) { return false; } + + new AriantColiseum(arenaMap, exped); + return true; + } + + public String startAriantBattle(ExpeditionType expedType, int mapid) { + if (!GameConstants.isAriantColiseumLobby(mapid)) { + return "You cannot start an Ariant tournament from outside the Battle Arena Entrance."; + } + + Expedition exped = this.getMap().getChannelServer().getExpedition(expedType); + if (exped == null) { + return "Please register on an expedition before attempting to start an Ariant tournament."; + } + + List players = exped.getActiveMembers(); + + int playersSize = players.size(); + if (!(playersSize >= exped.getMinSize() && playersSize <= exped.getMaxSize())) { + return "Make sure there are between #r" + exped.getMinSize() + " ~ " + exped.getMaxSize() + " players#k in this room to start the battle."; + } + + MapleMap leaderMap = this.getMap(); + for (Character mc : players) { + if (mc.getMap() != leaderMap) { + return "All competing players should be on this area to start the battle."; + } + + if (mc.getParty() != null) { + return "All competing players must not be on a party to start the battle."; + } + + int level = mc.getLevel(); + if (!(level >= expedType.getMinLevel() && level <= expedType.getMaxLevel())) { + return "There are competing players outside of the acceptable level range in this room. All players must be on #blevel between 20~30#k to start the battle."; + } + } + + if (setupAriantBattle(exped, mapid)) { + return ""; + } else { + return "Other players are already competing on the Ariant tournament in this room. Please wait a while until the arena becomes available again."; + } + } + + public void sendMarriageWishlist(boolean groom) { + Character player = this.getPlayer(); + Marriage marriage = player.getMarriageInstance(); + if (marriage != null) { + int cid = marriage.getIntProperty(groom ? "groomId" : "brideId"); + Character chr = marriage.getPlayerById(cid); + if (chr != null) { + if (chr.getId() == player.getId()) { + player.sendPacket(WeddingPackets.onWeddingGiftResult((byte) 0xA, marriage.getWishlistItems(groom), marriage.getGiftItems(player.getClient(), groom))); + } else { + marriage.setIntProperty("wishlistSelection", groom ? 0 : 1); + player.sendPacket(WeddingPackets.onWeddingGiftResult((byte) 0x09, marriage.getWishlistItems(groom), marriage.getGiftItems(player.getClient(), groom))); + } + } + } + } + + public void sendMarriageGifts(List gifts) { + this.getPlayer().sendPacket(WeddingPackets.onWeddingGiftResult((byte) 0xA, Collections.singletonList(""), gifts)); + } + + public boolean createMarriageWishlist() { + Marriage marriage = this.getPlayer().getMarriageInstance(); + if (marriage != null) { + Boolean groom = marriage.isMarriageGroom(this.getPlayer()); + if (groom != null) { + String wlKey; + if (groom) { + wlKey = "groomWishlist"; + } else { + wlKey = "brideWishlist"; + } + + if (marriage.getProperty(wlKey).contentEquals("")) { + getClient().sendPacket(WeddingPackets.sendWishList()); + return true; + } + } + } + + return false; + } } \ No newline at end of file diff --git a/src/main/java/scripting/npc/NPCScriptManager.java b/src/main/java/scripting/npc/NPCScriptManager.java index c14130705b..3e8cb720c8 100644 --- a/src/main/java/scripting/npc/NPCScriptManager.java +++ b/src/main/java/scripting/npc/NPCScriptManager.java @@ -37,7 +37,6 @@ import java.util.List; import java.util.Map; /** - * * @author Matze */ public class NPCScriptManager extends AbstractScriptManager { @@ -190,7 +189,7 @@ public class NPCScriptManager extends AbstractScriptManager { } else { resetContext(scriptFolder + "/" + cm.getNpc() + ".js", c); } - + c.getPlayer().flushDelayedUpdateQuests(); } diff --git a/src/main/java/scripting/portal/PortalScriptManager.java b/src/main/java/scripting/portal/PortalScriptManager.java index e4ef1eb3e9..79a8c58c80 100644 --- a/src/main/java/scripting/portal/PortalScriptManager.java +++ b/src/main/java/scripting/portal/PortalScriptManager.java @@ -49,7 +49,7 @@ public class PortalScriptManager extends AbstractScriptManager { if (script != null) { return script; } - + ScriptEngine engine = getInvocableScriptEngine(scriptPath); if (!(engine instanceof Invocable iv)) { return null; diff --git a/src/main/java/scripting/quest/QuestActionManager.java b/src/main/java/scripting/quest/QuestActionManager.java index 84bc7fca61..3a4b76b559 100644 --- a/src/main/java/scripting/quest/QuestActionManager.java +++ b/src/main/java/scripting/quest/QuestActionManager.java @@ -29,12 +29,11 @@ import server.quest.actions.ExpAction; import server.quest.actions.MesoAction; /** - * * @author RMZero213 */ public class QuestActionManager extends NPCConversationManager { - private boolean start; // this is if the script in question is start or end - private int quest; + private final boolean start; // this is if the script in question is start or end + private final int quest; public QuestActionManager(Client c, int quest, int npc, boolean start) { super(c, npc, null); @@ -62,27 +61,27 @@ public class QuestActionManager extends NPCConversationManager { public boolean forceCompleteQuest() { return forceCompleteQuest(quest); } - + // For compatibility with some older scripts... public void startQuest() { forceStartQuest(); } - + // For compatibility with some older scripts... public void completeQuest() { forceCompleteQuest(); } - + @Override public void gainExp(int gain) { ExpAction.runAction(getPlayer(), gain); } - + @Override public void gainMeso(int gain) { MesoAction.runAction(getPlayer(), gain); } - + public String getMedalName() { // usable only for medal quests (id 299XX) Quest q = Quest.getInstance(quest); return ItemInformationProvider.getInstance().getName(q.getMedalRequirement()); diff --git a/src/main/java/scripting/quest/QuestScriptManager.java b/src/main/java/scripting/quest/QuestScriptManager.java index b521c893a0..f77867775c 100644 --- a/src/main/java/scripting/quest/QuestScriptManager.java +++ b/src/main/java/scripting/quest/QuestScriptManager.java @@ -35,14 +35,13 @@ import java.util.HashMap; import java.util.Map; /** - * * @author RMZero213 */ public class QuestScriptManager extends AbstractScriptManager { private static final QuestScriptManager instance = new QuestScriptManager(); - - private final Map qms = new HashMap<>(); - private final Map scripts = new HashMap<>(); + + private final Map qms = new HashMap<>(); + private final Map scripts = new HashMap<>(); public static QuestScriptManager getInstance() { return instance; @@ -56,8 +55,8 @@ public class QuestScriptManager extends AbstractScriptManager { return engine; } - - public void start(Client c, short questid, int npc) { + + public void start(Client c, short questid, int npc) { Quest quest = Quest.getInstance(questid); try { QuestActionManager qm = new QuestActionManager(c, questid, npc, true); @@ -95,20 +94,20 @@ public class QuestScriptManager extends AbstractScriptManager { } } - public void start(Client c, byte mode, byte type, int selection) { - Invocable iv = scripts.get(c); - if (iv != null) { - try { - c.setClickedNPC(); + public void start(Client c, byte mode, byte type, int selection) { + Invocable iv = scripts.get(c); + if (iv != null) { + try { + c.setClickedNPC(); iv.invokeFunction("start", mode, type, selection); - } catch (final Exception e) { - FilePrinter.printError(FilePrinter.QUEST + getQM(c).getQuest() + ".txt", e); - dispose(c); - } + } catch (final Exception e) { + FilePrinter.printError(FilePrinter.QUEST + getQM(c).getQuest() + ".txt", e); + dispose(c); + } } - } - - public void end(Client c, short questid, int npc) { + } + + public void end(Client c, short questid, int npc) { Quest quest = Quest.getInstance(questid); if (!c.getPlayer().getQuest(quest).getStatus().equals(QuestStatus.Status.STARTED) || !c.getPlayer().getMap().containsNPC(npc)) { dispose(c); @@ -150,50 +149,50 @@ public class QuestScriptManager extends AbstractScriptManager { } } - public void end(Client c, byte mode, byte type, int selection) { - Invocable iv = scripts.get(c); - if (iv != null) { - try { - c.setClickedNPC(); - iv.invokeFunction("end", mode, type, selection); - } catch (final Exception e) { - FilePrinter.printError(FilePrinter.QUEST + getQM(c).getQuest() + ".txt", e); - dispose(c); - } - } - } - - public void raiseOpen(Client c, short questid, int npc) { + public void end(Client c, byte mode, byte type, int selection) { + Invocable iv = scripts.get(c); + if (iv != null) { try { - QuestActionManager qm = new QuestActionManager(c, questid, npc, true); - if (qms.containsKey(c)) { - return; - } - if (c.canClickNPC()) { - qms.put(c, qm); - - ScriptEngine engine = getQuestScriptEngine(c, questid); - if (engine == null) { - //FilePrinter.printError(FilePrinter.QUEST_UNCODED, "RAISE Quest " + questid + " is uncoded."); - qm.dispose(); - return; - } - - engine.put("qm", qm); - - Invocable iv = (Invocable) engine; - scripts.put(c, iv); - c.setClickedNPC(); - iv.invokeFunction("raiseOpen"); - } - } catch (final UndeclaredThrowableException ute) { - FilePrinter.printError(FilePrinter.QUEST + questid + ".txt", ute); - dispose(c); - } catch (final Throwable t) { - FilePrinter.printError(FilePrinter.QUEST + getQM(c).getQuest() + ".txt", t); + c.setClickedNPC(); + iv.invokeFunction("end", mode, type, selection); + } catch (final Exception e) { + FilePrinter.printError(FilePrinter.QUEST + getQM(c).getQuest() + ".txt", e); dispose(c); } } + } + + public void raiseOpen(Client c, short questid, int npc) { + try { + QuestActionManager qm = new QuestActionManager(c, questid, npc, true); + if (qms.containsKey(c)) { + return; + } + if (c.canClickNPC()) { + qms.put(c, qm); + + ScriptEngine engine = getQuestScriptEngine(c, questid); + if (engine == null) { + //FilePrinter.printError(FilePrinter.QUEST_UNCODED, "RAISE Quest " + questid + " is uncoded."); + qm.dispose(); + return; + } + + engine.put("qm", qm); + + Invocable iv = (Invocable) engine; + scripts.put(c, iv); + c.setClickedNPC(); + iv.invokeFunction("raiseOpen"); + } + } catch (final UndeclaredThrowableException ute) { + FilePrinter.printError(FilePrinter.QUEST + questid + ".txt", ute); + dispose(c); + } catch (final Throwable t) { + FilePrinter.printError(FilePrinter.QUEST + getQM(c).getQuest() + ".txt", t); + dispose(c); + } + } public void dispose(QuestActionManager qm, Client c) { qms.remove(c); @@ -203,12 +202,12 @@ public class QuestScriptManager extends AbstractScriptManager { c.getPlayer().flushDelayedUpdateQuests(); } - public void dispose(Client c) { - QuestActionManager qm = qms.get(c); - if (qm != null) { - dispose(qm, c); - } - } + public void dispose(Client c) { + QuestActionManager qm = qms.get(c); + if (qm != null) { + dispose(qm, c); + } + } public QuestActionManager getQM(Client c) { return qms.get(c); diff --git a/src/main/java/scripting/reactor/ReactorActionManager.java b/src/main/java/scripting/reactor/ReactorActionManager.java index 85fbf1cf06..a2095bbcbe 100644 --- a/src/main/java/scripting/reactor/ReactorActionManager.java +++ b/src/main/java/scripting/reactor/ReactorActionManager.java @@ -66,19 +66,19 @@ public class ReactorActionManager extends AbstractPlayerInteraction { public void hitReactor() { reactor.hitReactor(c); } - + public void destroyNpc(int npcId) { reactor.getMap().destroyNPC(npcId); } - + private static void sortDropEntries(List from, List item, List visibleQuest, List otherQuest, Character chr) { ItemInformationProvider ii = ItemInformationProvider.getInstance(); - - for(ReactorDropEntry mde : from) { - if(!ii.isQuestItem(mde.itemId)) { + + for (ReactorDropEntry mde : from) { + if (!ii.isQuestItem(mde.itemId)) { item.add(mde); } else { - if(chr.needQuestItem(mde.questid, mde.itemId)) { + if (chr.needQuestItem(mde.questid, mde.itemId)) { visibleQuest.add(mde); } else { otherQuest.add(mde); @@ -86,25 +86,25 @@ public class ReactorActionManager extends AbstractPlayerInteraction { } } } - + private static List assembleReactorDropEntries(Character chr, List items) { final List dropEntry = new ArrayList<>(); final List visibleQuestEntry = new ArrayList<>(); final List otherQuestEntry = new ArrayList<>(); sortDropEntries(items, dropEntry, visibleQuestEntry, otherQuestEntry, chr); - + Collections.shuffle(dropEntry); Collections.shuffle(visibleQuestEntry); Collections.shuffle(otherQuestEntry); - + items.clear(); items.addAll(dropEntry); items.addAll(visibleQuestEntry); items.addAll(otherQuestEntry); - + List items1 = new ArrayList<>(items.size()); List items2 = new ArrayList<>(items.size() / 2); - + for (int i = 0; i < items.size(); i++) { if (i % 2 == 0) { items1.add(items.get(i)); @@ -112,10 +112,10 @@ public class ReactorActionManager extends AbstractPlayerInteraction { items2.add(items.get(i)); } } - + Collections.reverse(items1); items1.addAll(items2); - + return items1; } @@ -126,15 +126,15 @@ public class ReactorActionManager extends AbstractPlayerInteraction { public void sprayItems(boolean meso, int mesoChance, int minMeso, int maxMeso) { sprayItems(meso, mesoChance, minMeso, maxMeso, 0); } - + public void sprayItems(boolean meso, int mesoChance, int minMeso, int maxMeso, int minItems) { - sprayItems((int)reactor.getPosition().getX(), (int)reactor.getPosition().getY(), meso, mesoChance, minMeso, maxMeso, minItems); + sprayItems((int) reactor.getPosition().getX(), (int) reactor.getPosition().getY(), meso, mesoChance, minMeso, maxMeso, minItems); } public void sprayItems(int posX, int posY, boolean meso, int mesoChance, int minMeso, int maxMeso, int minItems) { dropItems(true, posX, posY, meso, mesoChance, minMeso, maxMeso, minItems); } - + public void dropItems() { dropItems(false, 0, 0, 0, 0); } @@ -142,31 +142,35 @@ public class ReactorActionManager extends AbstractPlayerInteraction { public void dropItems(boolean meso, int mesoChance, int minMeso, int maxMeso) { dropItems(meso, mesoChance, minMeso, maxMeso, 0); } - + public void dropItems(boolean meso, int mesoChance, int minMeso, int maxMeso, int minItems) { - dropItems((int)reactor.getPosition().getX(), (int)reactor.getPosition().getY(), meso, mesoChance, minMeso, maxMeso, minItems); + dropItems((int) reactor.getPosition().getX(), (int) reactor.getPosition().getY(), meso, mesoChance, minMeso, maxMeso, minItems); } public void dropItems(int posX, int posY, boolean meso, int mesoChance, int minMeso, int maxMeso, int minItems) { dropItems(true, posX, posY, meso, mesoChance, minMeso, maxMeso, minItems); // all reactors actually drop items sequentially... thanks inhyuk for pointing this out! } - + public void dropItems(boolean delayed, int posX, int posY, boolean meso, int mesoChance, final int minMeso, final int maxMeso, int minItems) { Character chr = c.getPlayer(); - if(chr == null) return; - + if (chr == null) { + return; + } + List items = assembleReactorDropEntries(chr, generateDropList(getDropChances(), chr.getDropRate(), meso, mesoChance, minItems)); - if(items.size() % 2 == 0) posX -= 12; + if (items.size() % 2 == 0) { + posX -= 12; + } final Point dropPos = new Point(posX, posY); - - if(!delayed) { + + if (!delayed) { ItemInformationProvider ii = ItemInformationProvider.getInstance(); - + byte p = 1; for (ReactorDropEntry d : items) { dropPos.x = posX + ((p % 2 == 0) ? (25 * ((p + 1) / 2)) : -(25 * (p / 2))); p++; - + if (d.itemId == 0) { int range = maxMeso - minMeso; int displayDrop = (int) (Math.random() * range) + minMeso; @@ -174,7 +178,7 @@ public class ReactorActionManager extends AbstractPlayerInteraction { reactor.getMap().spawnMesoDrop(mesoDrop, reactor.getMap().calcDropPos(dropPos, reactor.getPosition()), reactor, c.getPlayer(), false, (byte) 2); } else { Item drop; - + if (ItemConstants.getInventoryType(d.itemId) != InventoryType.EQUIP) { drop = new Item(d.itemId, (short) 0, (short) 1); } else { @@ -188,11 +192,11 @@ public class ReactorActionManager extends AbstractPlayerInteraction { final Reactor r = reactor; final List dropItems = items; final int worldMesoRate = c.getWorldServer().getMesoRate(); - + dropPos.x -= (12 * items.size()); - + sprayTask = TimerManager.getInstance().register(() -> { - if(dropItems.isEmpty()) { + if (dropItems.isEmpty()) { sprayTask.cancel(false); return; } @@ -224,23 +228,23 @@ public class ReactorActionManager extends AbstractPlayerInteraction { private List getDropChances() { return ReactorScriptManager.getInstance().getDrops(reactor.getId()); } - + private List generateDropList(List drops, int dropRate, boolean meso, int mesoChance, int minItems) { List items = new ArrayList<>(); if (meso && Math.random() < (1 / (double) mesoChance)) { items.add(new ReactorDropEntry(0, mesoChance, -1)); } - - for(ReactorDropEntry mde : drops) { + + for (ReactorDropEntry mde : drops) { if (Math.random() < (dropRate / (double) mde.chance)) { items.add(mde); } } - + while (items.size() < minItems) { items.add(new ReactorDropEntry(0, mesoChance, -1)); } - + return items; } @@ -271,28 +275,28 @@ public class ReactorActionManager extends AbstractPlayerInteraction { pos.y -= 10; return pos; } - + public void spawnNpc(int npcId) { spawnNpc(npcId, getPosition()); } - + public void spawnNpc(int npcId, Point pos) { spawnNpc(npcId, pos, reactor.getMap()); } - + public void hitMonsterWithReactor(int id, int hitsToKill) { // until someone comes with a better solution, why not? int customTime = YamlConfig.config.server.MOB_REACTOR_REFRESH_TIME; - if(customTime > 0) { + if (customTime > 0) { reactor.setDelay(customTime); } - + MapleMap map = reactor.getMap(); Monster mm = map.getMonsterById(id); - if(mm != null) { - int damage = (int)Math.ceil(mm.getMaxHp() / hitsToKill); + if (mm != null) { + int damage = (int) Math.ceil(mm.getMaxHp() / hitsToKill); Character chr = this.getPlayer(); - - if(chr != null) { + + if (chr != null) { map.damageMonster(chr, mm, damage); map.broadcastMessage(PacketCreator.damageMonster(mm.getObjectId(), damage)); } @@ -322,12 +326,12 @@ public class ReactorActionManager extends AbstractPlayerInteraction { changeMusic(bgmName); mapMessage(6, summonMessage); } - + public void dispelAllMonsters(int num, int team) { //dispels all mobs, cpq final MCSkill skil = CarnivalFactory.getInstance().getGuardian(num); if (skil != null) { for (Monster mons : getMap().getAllMonsters()) { - if(mons.getTeam() == team) { + if (mons.getTeam() == team) { mons.dispelSkill(skil.getSkill()); } } diff --git a/src/main/java/scripting/reactor/ReactorScriptManager.java b/src/main/java/scripting/reactor/ReactorScriptManager.java index 811b6c7413..a7e282a602 100644 --- a/src/main/java/scripting/reactor/ReactorScriptManager.java +++ b/src/main/java/scripting/reactor/ReactorScriptManager.java @@ -44,13 +44,13 @@ import java.util.Map; */ public class ReactorScriptManager extends AbstractScriptManager { private static final ReactorScriptManager instance = new ReactorScriptManager(); - + private final Map> drops = new HashMap<>(); public static ReactorScriptManager getInstance() { return instance; } - + public void onHit(Client c, Reactor reactor) { try { Invocable iv = initializeInvocable(c, reactor); @@ -59,9 +59,10 @@ public class ReactorScriptManager extends AbstractScriptManager { } iv.invokeFunction("hit"); - } catch (final NoSuchMethodException e) {} //do nothing, hit is OPTIONAL - - catch (final ScriptException | NullPointerException e) { + } catch (final NoSuchMethodException e) { + } //do nothing, hit is OPTIONAL + + catch (final ScriptException | NullPointerException e) { FilePrinter.printError(FilePrinter.REACTOR + reactor.getId() + ".txt", e); } }