diff --git a/build/built-jar.properties b/build/built-jar.properties index aa4fb80ec9..20990307a3 100644 --- a/build/built-jar.properties +++ b/build/built-jar.properties @@ -1,4 +1,4 @@ -#Mon, 12 Jun 2017 14:40:21 -0300 +#Tue, 13 Jun 2017 20:04:33 -0300 C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2= diff --git a/build/classes/client/MapleCharacter$1.class b/build/classes/client/MapleCharacter$1.class index 453570547d..0eff4df0bd 100644 Binary files a/build/classes/client/MapleCharacter$1.class and b/build/classes/client/MapleCharacter$1.class differ diff --git a/build/classes/client/MapleCharacter$10.class b/build/classes/client/MapleCharacter$10.class index 0c94467ef7..0b646bb9bb 100644 Binary files a/build/classes/client/MapleCharacter$10.class and b/build/classes/client/MapleCharacter$10.class differ diff --git a/build/classes/client/MapleCharacter$11.class b/build/classes/client/MapleCharacter$11.class index 90b2a95c62..272b892a78 100644 Binary files a/build/classes/client/MapleCharacter$11.class and b/build/classes/client/MapleCharacter$11.class differ diff --git a/build/classes/client/MapleCharacter$12.class b/build/classes/client/MapleCharacter$12.class index 3d7e57afdd..24e3db5287 100644 Binary files a/build/classes/client/MapleCharacter$12.class and b/build/classes/client/MapleCharacter$12.class differ diff --git a/build/classes/client/MapleCharacter$13.class b/build/classes/client/MapleCharacter$13.class index 563c8c25f8..76209ac700 100644 Binary files a/build/classes/client/MapleCharacter$13.class and b/build/classes/client/MapleCharacter$13.class differ diff --git a/build/classes/client/MapleCharacter$14.class b/build/classes/client/MapleCharacter$14.class index d4334e38c8..f61dfa482d 100644 Binary files a/build/classes/client/MapleCharacter$14.class and b/build/classes/client/MapleCharacter$14.class differ diff --git a/build/classes/client/MapleCharacter$15.class b/build/classes/client/MapleCharacter$15.class index c20247f2ec..0854f98674 100644 Binary files a/build/classes/client/MapleCharacter$15.class and b/build/classes/client/MapleCharacter$15.class differ diff --git a/build/classes/client/MapleCharacter$16.class b/build/classes/client/MapleCharacter$16.class index 8b3e2f8fb0..79898b5c87 100644 Binary files a/build/classes/client/MapleCharacter$16.class and b/build/classes/client/MapleCharacter$16.class differ diff --git a/build/classes/client/MapleCharacter$17.class b/build/classes/client/MapleCharacter$17.class index f664b9de83..e520ac3c5a 100644 Binary files a/build/classes/client/MapleCharacter$17.class and b/build/classes/client/MapleCharacter$17.class differ diff --git a/build/classes/client/MapleCharacter$18.class b/build/classes/client/MapleCharacter$18.class index 1cc5779651..ffdc7903ca 100644 Binary files a/build/classes/client/MapleCharacter$18.class and b/build/classes/client/MapleCharacter$18.class differ diff --git a/build/classes/client/MapleCharacter$2.class b/build/classes/client/MapleCharacter$2.class index 3a69b7c1a8..a314c4d1a0 100644 Binary files a/build/classes/client/MapleCharacter$2.class and b/build/classes/client/MapleCharacter$2.class differ diff --git a/build/classes/client/MapleCharacter$3.class b/build/classes/client/MapleCharacter$3.class index a96000beca..26352f663a 100644 Binary files a/build/classes/client/MapleCharacter$3.class and b/build/classes/client/MapleCharacter$3.class differ diff --git a/build/classes/client/MapleCharacter$4.class b/build/classes/client/MapleCharacter$4.class index a6f160f42d..2b893eebf9 100644 Binary files a/build/classes/client/MapleCharacter$4.class and b/build/classes/client/MapleCharacter$4.class differ diff --git a/build/classes/client/MapleCharacter$5.class b/build/classes/client/MapleCharacter$5.class index 048794eaf3..5d3abdfe32 100644 Binary files a/build/classes/client/MapleCharacter$5.class and b/build/classes/client/MapleCharacter$5.class differ diff --git a/build/classes/client/MapleCharacter$6.class b/build/classes/client/MapleCharacter$6.class index 3264c802e8..b14de10d83 100644 Binary files a/build/classes/client/MapleCharacter$6.class and b/build/classes/client/MapleCharacter$6.class differ diff --git a/build/classes/client/MapleCharacter$7.class b/build/classes/client/MapleCharacter$7.class index 3f6b1c79cb..21f54190fc 100644 Binary files a/build/classes/client/MapleCharacter$7.class and b/build/classes/client/MapleCharacter$7.class differ diff --git a/build/classes/client/MapleCharacter$8.class b/build/classes/client/MapleCharacter$8.class index d75ca0dd3f..d7d64736ff 100644 Binary files a/build/classes/client/MapleCharacter$8.class and b/build/classes/client/MapleCharacter$8.class differ diff --git a/build/classes/client/MapleCharacter$9.class b/build/classes/client/MapleCharacter$9.class index 7a3e5d0847..955f4dd2ff 100644 Binary files a/build/classes/client/MapleCharacter$9.class and b/build/classes/client/MapleCharacter$9.class differ diff --git a/build/classes/client/MapleCharacter$FameStatus.class b/build/classes/client/MapleCharacter$FameStatus.class index 65755cb3dc..5779bd2492 100644 Binary files a/build/classes/client/MapleCharacter$FameStatus.class and b/build/classes/client/MapleCharacter$FameStatus.class differ diff --git a/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class b/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class index ea01bf7f92..5c4f79fa8c 100644 Binary files a/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class and b/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class differ diff --git a/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class b/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class index f62461f241..40cb71201d 100644 Binary files a/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class and b/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class differ diff --git a/build/classes/client/MapleCharacter$SkillEntry.class b/build/classes/client/MapleCharacter$SkillEntry.class index 59947544f6..c15b8968c2 100644 Binary files a/build/classes/client/MapleCharacter$SkillEntry.class and b/build/classes/client/MapleCharacter$SkillEntry.class differ diff --git a/build/classes/client/MapleCharacter.class b/build/classes/client/MapleCharacter.class index 9a4f431270..6e4ca68a7f 100644 Binary files a/build/classes/client/MapleCharacter.class and b/build/classes/client/MapleCharacter.class differ diff --git a/build/classes/client/command/Commands.class b/build/classes/client/command/Commands.class index 59dab23829..b53b5a20c8 100644 Binary files a/build/classes/client/command/Commands.class and b/build/classes/client/command/Commands.class differ diff --git a/build/classes/net/server/channel/Channel.class b/build/classes/net/server/channel/Channel.class index 10c408c17d..8870918038 100644 Binary files a/build/classes/net/server/channel/Channel.class and b/build/classes/net/server/channel/Channel.class differ diff --git a/build/classes/net/server/channel/handlers/ChangeMapHandler.class b/build/classes/net/server/channel/handlers/ChangeMapHandler.class index 49fc83152b..20da458f47 100644 Binary files a/build/classes/net/server/channel/handlers/ChangeMapHandler.class and b/build/classes/net/server/channel/handlers/ChangeMapHandler.class differ diff --git a/build/classes/net/server/world/World$1.class b/build/classes/net/server/world/World$1.class index 56e9a73b06..baa56660b3 100644 Binary files a/build/classes/net/server/world/World$1.class and b/build/classes/net/server/world/World$1.class differ diff --git a/build/classes/net/server/world/World.class b/build/classes/net/server/world/World.class index 842b441318..eff849d181 100644 Binary files a/build/classes/net/server/world/World.class and b/build/classes/net/server/world/World.class differ diff --git a/build/classes/provider/wz/WZIMGFile.class b/build/classes/provider/wz/WZIMGFile.class index 37159ddda1..c1df24b70a 100644 Binary files a/build/classes/provider/wz/WZIMGFile.class and b/build/classes/provider/wz/WZIMGFile.class differ diff --git a/build/classes/scripting/AbstractPlayerInteraction.class b/build/classes/scripting/AbstractPlayerInteraction.class index 09fd139343..bae8646bea 100644 Binary files a/build/classes/scripting/AbstractPlayerInteraction.class and b/build/classes/scripting/AbstractPlayerInteraction.class differ diff --git a/build/classes/scripting/event/EventInstanceManager$1.class b/build/classes/scripting/event/EventInstanceManager$1.class index 07dfe3fb98..f899a45771 100644 Binary files a/build/classes/scripting/event/EventInstanceManager$1.class and b/build/classes/scripting/event/EventInstanceManager$1.class differ diff --git a/build/classes/scripting/event/EventInstanceManager$2.class b/build/classes/scripting/event/EventInstanceManager$2.class index c950298c1b..fd3ed07051 100644 Binary files a/build/classes/scripting/event/EventInstanceManager$2.class and b/build/classes/scripting/event/EventInstanceManager$2.class differ diff --git a/build/classes/scripting/event/EventInstanceManager$3.class b/build/classes/scripting/event/EventInstanceManager$3.class index ab7e253a22..cae9603442 100644 Binary files a/build/classes/scripting/event/EventInstanceManager$3.class and b/build/classes/scripting/event/EventInstanceManager$3.class differ diff --git a/build/classes/scripting/event/EventInstanceManager.class b/build/classes/scripting/event/EventInstanceManager.class index d8cc1af832..4a2833ce31 100644 Binary files a/build/classes/scripting/event/EventInstanceManager.class and b/build/classes/scripting/event/EventInstanceManager.class differ diff --git a/build/classes/scripting/event/EventManager$1.class b/build/classes/scripting/event/EventManager$1.class index 1fbcd7c95d..f3690101a1 100644 Binary files a/build/classes/scripting/event/EventManager$1.class and b/build/classes/scripting/event/EventManager$1.class differ diff --git a/build/classes/scripting/event/EventManager$2.class b/build/classes/scripting/event/EventManager$2.class index 70168bca2d..3b6b461520 100644 Binary files a/build/classes/scripting/event/EventManager$2.class and b/build/classes/scripting/event/EventManager$2.class differ diff --git a/build/classes/scripting/event/EventManager$3.class b/build/classes/scripting/event/EventManager$3.class index c96c54c2d8..06b4cc64ce 100644 Binary files a/build/classes/scripting/event/EventManager$3.class and b/build/classes/scripting/event/EventManager$3.class differ diff --git a/build/classes/scripting/event/EventManager.class b/build/classes/scripting/event/EventManager.class index 098144df1c..e5097b1c40 100644 Binary files a/build/classes/scripting/event/EventManager.class and b/build/classes/scripting/event/EventManager.class differ diff --git a/build/classes/server/MapleStatEffect.class b/build/classes/server/MapleStatEffect.class index 0bfbc621fb..085aa0cea3 100644 Binary files a/build/classes/server/MapleStatEffect.class and b/build/classes/server/MapleStatEffect.class differ diff --git a/build/classes/server/maps/MapleMap.class b/build/classes/server/maps/MapleMap.class index 0e2a60b9eb..2ada2f8c4f 100644 Binary files a/build/classes/server/maps/MapleMap.class and b/build/classes/server/maps/MapleMap.class differ diff --git a/dist/MapleSolaxia.jar b/dist/MapleSolaxia.jar index 856984c5cd..50a528771e 100644 Binary files a/dist/MapleSolaxia.jar and b/dist/MapleSolaxia.jar differ diff --git a/mychanges_ptbr.txt b/mychanges_ptbr.txt index 4c25d7f28f..147833c2e3 100644 --- a/mychanges_ptbr.txt +++ b/mychanges_ptbr.txt @@ -309,4 +309,8 @@ Corre Incrementada a documentação referente aos métodos usados nos scripts de eventos. 12 Junho 2016, -Correção de falha em criação de guilds, não atribuindo corretamente o título de mestre da guild ao criador. \ No newline at end of file +Correção de falha em criação de guilds, não atribuindo corretamente o título de mestre da guild ao criador. + +13 Junho 2016, +Mudança nas mecânicas de busca por portais ao transportar cada jogador: quando não for definido, escolhe-se um spawn point aleatoriamente. +Implementação de fila de espera para Guilds na GPQ (funciona em harmonia com o sistema de lobbys). \ No newline at end of file diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml index d46f8d4da1..22548efa3b 100644 --- a/nbproject/private/private.xml +++ b/nbproject/private/private.xml @@ -5,17 +5,21 @@ src/tools/MaplePacketCreator.java - 5939 + 5937 - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/event/OrbisPQ.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/event/0_EXAMPLE.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/event/BossRushPQ.js + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/event/GuildQuest.js + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/event/CWKPQ.js + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/9040000.js + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/scripting/AbstractPlayerInteraction.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/2040034.js + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleCharacter.java file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/scripting/event/EventManager.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/Channel.java diff --git a/scripts/event/GuildQuest.js b/scripts/event/GuildQuest.js index 92530b9295..db15e75c8e 100644 --- a/scripts/event/GuildQuest.js +++ b/scripts/event/GuildQuest.js @@ -19,197 +19,266 @@ along with this program. If not, see . */ -/* - * @Author Lerk - * - * Guild Quest - */ +/** + * @author: Ronan + * @event: Sharenian Guild PQ +*/ -var exitMap; -var waitingListCurrent = 0; - -importPackage(Packages.world); -importPackage(Packages.client); -importPackage(Packages.server.maps); -importPackage(java.lang); +var isPq = true; +var minPlayers = 1, maxPlayers = 30; +var minLevel = 1, maxLevel = 200; +var entryMap = 990000000; +var exitMap = 990001100; +var recruitMap = 101030104; +var clearMap = 990001101; + +var minMapId = 990000000; +var maxMapId = 990001101; + +var waitTime = 3; +var eventTime = 90; // 90 minutes + +var lobbyRange = [0, 0]; function init() { - em.setProperty("shuffleReactors","false"); - em.setProperty("canEnter", "true"); - em.setProperty("gpqOpen", "true"); + setEventRequirements(); } -function monsterValue(eim, mobId) { //should only trigger on ergoth - if (mobId == 9300028) { //but, just to be safe... - var rubian = new Packages.client.inventory.Item(4001024, 0, 1); - var map = eim.getMapInstance(990000900); - var reactor = map.getReactorByName("boss"); - map.spawnItemDrop(reactor, eim.getPlayers().get(0), rubian, reactor.getPosition(), true, false); - } - return -1; +function setLobbyRange() { + return lobbyRange; } - - -function setup(eim) { - exitMap = em.getChannelServer().getMapFactory().getMap(990001100); //returning path +function setEventRequirements() { + var reqStr = ""; - //shuffle reactors in two maps for stage 3 - eim.getMapInstance(990000501).shuffleReactors(); - eim.getMapInstance(990000502).shuffleReactors(); + reqStr += "\r\n Number of players: "; + if(maxPlayers - minPlayers >= 1) reqStr += minPlayers + " ~ " + maxPlayers; + else reqStr += minPlayers; - //force no-respawn on certain map reactors - eim.getMapInstance(990000611).getReactorByName("").setDelay(-1); - eim.getMapInstance(990000620).getReactorByName("").setDelay(-1); - eim.getMapInstance(990000631).getReactorByName("").setDelay(-1); - eim.getMapInstance(990000641).getReactorByName("").setDelay(-1); + reqStr += "\r\n Level range: "; + if(maxLevel - minLevel >= 1) reqStr += minLevel + " ~ " + maxLevel; + else reqStr += minLevel; - //activate three minutes after start - eim.setProperty("entryTimestamp", Packages.java.lang.System.currentTimeMillis()); - eim.setProperty("canEnter","true"); - eim.schedule("begin", 60000); - eim.startEventTimer(60000); + reqStr += "\r\n Time limit: "; + reqStr += eventTime + " minutes"; + + em.setProperty("party", reqStr); } -function begin(eim) { - eim.setProperty("canEnter","false"); - var party = eim.getPlayers(); - //if (party.size() < 6) { //not enough to start - // end(eim,"There are no longer enough players to continue, and those remaining shall be warped out."); - //} else { - var iter = party.iterator(); - while (iter.hasNext()) { - iter.next().dropMessage(6,"The quest has begun."); - } - - eim.startEventTimer(1000 * 60 * 90); - eim.schedule("timeOut", 1000 * 60 * 90); -//} +function setEventExclusives(eim) { + var itemSet = [1032033, 4001024, 4001025, 4001026, 4001027, 4001028, 4001029, 4001030, 4001031, 4001032, 4001033, 4001034, 4001035, 4001037]; + eim.setExclusiveItems(itemSet); } -function afterSetup(eim) {} +function setEventRewards(eim) { + var itemSet, itemQty, evLevel, expStages; -function timeOut(eim) { - end(eim, "Your allotted time to finish the quest has passed."); + evLevel = 1; //Rewards at clear PQ + itemSet = []; + itemQty = []; + eim.setEventRewards(evLevel, itemSet, itemQty); + + expStages = []; //bonus exp given on CLEAR stage signal + eim.setEventClearStageExp(expStages); } +function getEligibleParty(party) { //selects, from the given party, the team that is allowed to attempt this event + var eligible = []; + var hasLeader = false; + + var guildId = 0; + + if(party.size() > 0) { + var partyList = party.toArray(); + + for(var i = 0; i < party.size(); i++) { + var ch = partyList[i]; + if(ch.isLeader()) { + guildId = ch.getGuildId(); + break; + } + } + + for(var i = 0; i < party.size(); i++) { + var ch = partyList[i]; + + if(ch.getMapId() == recruitMap && ch.getLevel() >= minLevel && ch.getLevel() <= maxLevel && ch.getGuildId() == guildId) { + if(ch.isLeader()) hasLeader = true; + eligible.push(ch); + } + } + } + + if(!(hasLeader)) eligible = []; + return eligible; +} + +function setup(level, lobbyid) { + var eim = em.newInstance("Guild" + lobbyid); + eim.setProperty("level", level); + + eim.setProperty("guild", 0); + eim.setProperty("canJoin", 1); + eim.setProperty("statusStg1", -1); + + eim.getInstanceMap(990000000).resetPQ(level); + eim.getInstanceMap(990000100).resetPQ(level); + eim.getInstanceMap(990000200).resetPQ(level); + eim.getInstanceMap(990000300).resetPQ(level); + eim.getInstanceMap(990000301).resetPQ(level); + eim.getInstanceMap(990000400).resetPQ(level); + eim.getInstanceMap(990000401).resetPQ(level); + eim.getInstanceMap(990000410).resetPQ(level); + eim.getInstanceMap(990000420).resetPQ(level); + eim.getInstanceMap(990000430).resetPQ(level); + eim.getInstanceMap(990000431).resetPQ(level); + eim.getInstanceMap(990000440).resetPQ(level); + eim.getInstanceMap(990000500).resetPQ(level); + eim.getInstanceMap(990000501).resetPQ(level); + eim.getInstanceMap(990000502).resetPQ(level); + eim.getInstanceMap(990000600).resetPQ(level); + eim.getInstanceMap(990000610).resetPQ(level); + eim.getInstanceMap(990000611).resetPQ(level); + eim.getInstanceMap(990000620).resetPQ(level); + eim.getInstanceMap(990000630).resetPQ(level); + eim.getInstanceMap(990000631).resetPQ(level); + eim.getInstanceMap(990000640).resetPQ(level); + eim.getInstanceMap(990000641).resetPQ(level); + eim.getInstanceMap(990000700).resetPQ(level); + eim.getInstanceMap(990000800).resetPQ(level); + eim.getInstanceMap(990000900).resetPQ(level); + eim.getInstanceMap(990001000).resetPQ(level); + eim.getInstanceMap(990001100).resetPQ(level); + eim.getInstanceMap(990001101).resetPQ(level); + + respawnStages(eim); + + var ts = Date.now(); + ts += (60000 * waitTime); + eim.setProperty("entryTimestamp", "" + ts); + + eim.startEventTimer(waitTime * 60000); + + setEventRewards(eim); + setEventExclusives(eim); + + return eim; +} + +/* +function isTeamAllJobs(eim) { + var eventJobs = eim.getEventPlayersJobs(); + var rangeJobs = parseInt('111110', 2); + + return ((eventJobs & rangeJobs) == rangeJobs); +} +*/ + +function afterSetup(eim) { + eim.setProperty("guild", "" + eim.getLeader().getGuildId()); +} + +function respawnStages(eim) {} + function playerEntry(eim, player) { - var map = eim.getMapInstance(990000000); - player.changeMap(map, map.getPortal(0)); + var map = eim.getMapInstance(entryMap); + player.changeMap(map, map.getPortal(0)); + + var texttt = "So, here is the brief. You guys should be warned that, once out on the fortress outskirts, anyone that would not be equipping the #b#t1032033##k will die instantly due to the deteriorated state of the air around there. That being said, once your team move out to the next stage, make sure to #bhit the glowing rocks#k in that region and #bequip the dropped item#k before advancing stages. That will protect you thoroughly from the air sickness. Good luck!"; + player.getClient().getSession().write(Packages.tools.MaplePacketCreator.getNPCTalk(9040000, /*(byte)*/ 0, texttt, "00 00", /*(byte)*/ 0)); } -function playerRevive(eim, player) { - var returnMap = 990000200; - if (eim.getProperty("canEnter").equals("true")) { - returnMap = 990000000; - } - player.setHp(50); - player.setStance(0); - player.changeMap(eim.getMapInstance(returnMap), eim.getMapInstance(returnMap).getPortal(0)); - return false; -} - -function playerDead(eim, player) { -} - -function playerDisconnected(eim, player) { - var party = eim.getPlayers(); - if (player.getName().equals(eim.getProperty("leader"))) { //check for party leader - //boot all players and end - var iter = party.iterator(); - while (iter.hasNext()) { - var pl = iter.next(); - pl.dropMessage(6,"The leader of the instance has disconnected, and the remaining players shall be warped out."); - if (pl.equals(player)) { - removePlayer(eim, pl); - } - else { - eim.unregisterPlayer(pl); - pl.changeMap(exitMap, exitMap.getPortal(0)); - } +function scheduledTimeout(eim) { + if(eim.getIntProperty("canJoin") == 1) { + eim.setProperty("canJoin", 0); + + if(eim.checkEventTeamLacking(true, minPlayers)) { + end(eim); + } else { + eim.startEventTimer(eventTime * 60000); + } + } else { + end(eim); } - eim.dispose(); - } - else { //boot d/ced player and check if enough players left - removePlayer(eim, player); - if (party.size() < 6) { //five after player booted - end(eim,"There are no longer enough players to continue, and those remaining shall be warped out."); - } - } -} - -function leftParty(eim, player) { //ignore for GQ -} - -function disbandParty(eim) { //ignore for GQ } function playerUnregistered(eim, player) {} function playerExit(eim, player) { - eim.unregisterPlayer(player); - player.changeMap(exitMap, exitMap.getPortal(0)); - var party = eim.getPlayers(); - if (party.size() < 6) { //five after player booted - end(eim,"There are no longer enough players to continue, and those remaining shall be warped out."); - } -} - -function end(eim, msg) { - var iter = eim.getPlayers().iterator(); - while (iter.hasNext()) { - var player = iter.next(); - player.dropMessage(6,msg); eim.unregisterPlayer(player); - player.changeMap(exitMap, exitMap.getPortal(0)); - } - eim.dispose(); + player.changeMap(exitMap, 0); } -//for offline players -function removePlayer(eim, player) { - eim.unregisterPlayer(player); - player.getMap().removePlayer(player); - player.setMap(exitMap); +function changedMap(eim, player, mapid) { + if (mapid < minMapId || mapid > maxMapId) { + if (eim.isEventTeamLackingNow(true, minPlayers, player) && eim.getIntProperty("canJoin") == 0) { + eim.unregisterPlayer(player); + end(eim); + } + else + eim.unregisterPlayer(player); + } +} + +function changedLeader(eim, leader) {} + +function playerDead(eim, player) {} + +function playerRevive(eim, player) { // player presses ok on the death pop up. + if (eim.isEventTeamLackingNow(true, minPlayers, player) && eim.getIntProperty("canJoin") == 0) { + eim.unregisterPlayer(player); + end(eim); + } + else + eim.unregisterPlayer(player); +} + +function playerDisconnected(eim, player) { + if (eim.isEventTeamLackingNow(true, minPlayers, player) && eim.getIntProperty("canJoin") == 0) { + eim.unregisterPlayer(player); + end(eim); + } + else + eim.unregisterPlayer(player); +} + +function leftParty(eim, player) {} + +function disbandParty(eim) { + end(eim); +} + +function monsterValue(eim, mobId) { + return 1; +} + +function end(eim) { + var party = eim.getPlayers(); + for (var i = 0; i < party.size(); i++) { + playerExit(eim, party.get(i)); + } + eim.dispose(); +} + +function giveRandomEventReward(eim, player) { + eim.giveEventReward(player); } function clearPQ(eim) { - var iter = eim.getPlayers().iterator(); - var bonusMap = eim.getMapInstance(990001000); - eim.startEventTimer(40000); - while (iter.hasNext()) { - var player = iter.next(); - player.changeMap(bonusMap, bonusMap.getPortal(0)); - } - eim.schedule("finish", 40000) -} - -function finish(eim) { - var iter = eim.getPlayers().iterator(); - while (iter.hasNext()) { - var player = iter.next(); - eim.unregisterPlayer(player); - player.changeMap(exitMap, exitMap.getPortal(0)); - } - eim.dispose(); + eim.stopEventTimer(); + eim.setEventCleared(); } function monsterKilled(mob, eim) {} function allMonstersDead(eim) {} -function cancelSchedule() { -} +function cancelSchedule() {} function dispose(eim) { - em.schedule("openGPQ", 5000); + em.schedule("reopenGuildQuest", em.getLobbyDelay() * 1.5 * 1000); } -function openGPQ() { - em.setProperty("gpqOpen", "true"); -} - - -function timeOut() { - +function reopenGuildQuest() { + em.attemptStartGuildInstance(); } \ No newline at end of file diff --git a/scripts/event/KerningTrain.js b/scripts/event/KerningTrain.js index 1e87ef4278..267d13f62a 100644 --- a/scripts/event/KerningTrain.js +++ b/scripts/event/KerningTrain.js @@ -46,6 +46,6 @@ function playerDisconnected(eim, player) { function cancelSchedule() {} -function dispose() { - em.cancelSchedule(); +function dispose(eim) { + eim.cancelSchedule(); } \ No newline at end of file diff --git a/scripts/npc/1012113.js b/scripts/npc/1012113.js index 0b3e42dc69..7cb7b98421 100644 --- a/scripts/npc/1012113.js +++ b/scripts/npc/1012113.js @@ -38,7 +38,7 @@ function action(mode, type, selection) { if (status == 0) { cm.sendNext("Hello, there! I'm Tommy. There's a Pig Town nearby where we're standing. The pigs there are rowdy and uncontrollable to the point where they have stolen numerous weapons from travelers. They were kicked out from their towns, and are currently hiding out at the Pig Town."); } else if (status == 1) { - if(cm.isLeader()) { + if(cm.isEventLeader()) { cm.sendYesNo("What do you think about making your way there with your party members and teach those rowdy pigs a lesson?"); } else { diff --git a/scripts/npc/1012114.js b/scripts/npc/1012114.js index 357cb62893..bb2ddce7d7 100644 --- a/scripts/npc/1012114.js +++ b/scripts/npc/1012114.js @@ -35,7 +35,7 @@ function action(mode, type, selection) { status++; if (status == 0) { - if (cm.isLeader()) { + if (cm.isEventLeader()) { cm.sendSimple("Growl! I am Growlie, always ready to protect this place. What brought you here?\r\n#b#L0# Please tell me what this place is all about.#l\r\n#L1# I have brought #t4001101#.#l\r\n#L2# I would like to leave this place.#l"); } else { cm.sendSimple("Growl! I am Growlie, always ready to protect this place. What brought you here?\r\n#b#L0# Please tell me what this place is all about.#l\r\n#L2# I would like to leave this place.#l"); diff --git a/scripts/npc/2013001.js b/scripts/npc/2013001.js index d5e6773c80..83c00da76a 100644 --- a/scripts/npc/2013001.js +++ b/scripts/npc/2013001.js @@ -44,7 +44,7 @@ function action(mode, type, selection) { cm.dispose(); return; } - if (!cm.isLeader()) { + if (!cm.isEventLeader()) { if(cm.getPlayer().getMapId() == 920010000) { cm.warp(920010000, 2); cm.dispose(); diff --git a/scripts/npc/2040036.js b/scripts/npc/2040036.js index f6e545d0dc..c9136d6dd5 100644 --- a/scripts/npc/2040036.js +++ b/scripts/npc/2040036.js @@ -64,7 +64,7 @@ function action(mode, type, selection) { cm.sendNext("Hurry, goto the next stage, the portal is open!"); } else { - if (eim.isLeader(cm.getPlayer())) { + if (eim.isEventLeader(cm.getPlayer())) { var state = eim.getIntProperty("statusStg" + stage); if(state == -1) { // preamble diff --git a/scripts/npc/2040037.js b/scripts/npc/2040037.js index d9cc41273d..50862dc9f0 100644 --- a/scripts/npc/2040037.js +++ b/scripts/npc/2040037.js @@ -64,7 +64,7 @@ function action(mode, type, selection) { cm.sendNext("Hurry, goto the next stage, the portal is open!"); } else { - if (eim.isLeader(cm.getPlayer())) { + if (eim.isEventLeader(cm.getPlayer())) { var state = eim.getIntProperty("statusStg" + stage); if(state == -1) { // preamble diff --git a/scripts/npc/2040038.js b/scripts/npc/2040038.js index 4b928d6f36..bd88e83484 100644 --- a/scripts/npc/2040038.js +++ b/scripts/npc/2040038.js @@ -64,7 +64,7 @@ function action(mode, type, selection) { cm.sendNext("Hurry, goto the next stage, the portal is open!"); } else { - if (eim.isLeader(cm.getPlayer())) { + if (eim.isEventLeader(cm.getPlayer())) { var state = eim.getIntProperty("statusStg" + stage); if(state == -1) { // preamble diff --git a/scripts/npc/2040039.js b/scripts/npc/2040039.js index 63cd9ea51f..fc3d6818aa 100644 --- a/scripts/npc/2040039.js +++ b/scripts/npc/2040039.js @@ -64,7 +64,7 @@ function action(mode, type, selection) { cm.sendNext("Hurry, goto the next stage, the portal is open!"); } else { - if (eim.isLeader(cm.getPlayer())) { + if (eim.isEventLeader(cm.getPlayer())) { var state = eim.getIntProperty("statusStg" + stage); if(state == -1) { // preamble diff --git a/scripts/npc/2040040.js b/scripts/npc/2040040.js index 0c95cae66d..a5a0fcd786 100644 --- a/scripts/npc/2040040.js +++ b/scripts/npc/2040040.js @@ -64,7 +64,7 @@ function action(mode, type, selection) { cm.sendNext("Hurry, goto the next stage, the portal is open!"); } else { - if (eim.isLeader(cm.getPlayer())) { + if (eim.isEventLeader(cm.getPlayer())) { var state = eim.getIntProperty("statusStg" + stage); if(state == -1) { // preamble diff --git a/scripts/npc/2040042.js b/scripts/npc/2040042.js index 75595b99d5..5eb82c6803 100644 --- a/scripts/npc/2040042.js +++ b/scripts/npc/2040042.js @@ -67,7 +67,7 @@ function action(mode, type, selection) { cm.sendNext("Hurry, goto the next stage, the portal is open!"); } else { - if (eim.isLeader(cm.getPlayer())) { + if (eim.isEventLeader(cm.getPlayer())) { var state = eim.getIntProperty("statusStg" + stage); if(state == -1) { // preamble diff --git a/scripts/npc/2040043.js b/scripts/npc/2040043.js index ce25e1e47a..32d2610c39 100644 --- a/scripts/npc/2040043.js +++ b/scripts/npc/2040043.js @@ -89,7 +89,7 @@ function action(mode, type, selection) { cm.sendNext("Hurry, goto the next stage, the portal is open!"); } else { - if (eim.isLeader(cm.getPlayer())) { + if (eim.isEventLeader(cm.getPlayer())) { var state = eim.getIntProperty("statusStg" + stage); if(state == -1) { // preamble diff --git a/scripts/npc/2040044.js b/scripts/npc/2040044.js index 36b90235be..28a96baeb5 100644 --- a/scripts/npc/2040044.js +++ b/scripts/npc/2040044.js @@ -58,7 +58,7 @@ function action(mode, type, selection) { cm.sendNext("Hurry, goto the next stage, the portal is open!"); } else { - if (eim.isLeader(cm.getPlayer())) { + if (eim.isEventLeader(cm.getPlayer())) { var state = eim.getIntProperty("statusStg" + stage); if(state == -1) { // preamble diff --git a/scripts/npc/2094001.js b/scripts/npc/2094001.js index f3536c2f73..358f2332f4 100644 --- a/scripts/npc/2094001.js +++ b/scripts/npc/2094001.js @@ -43,7 +43,7 @@ function action(mode, type, selection) { if(cm.getMapId() == 925100500) { if (status == 0) { - if(cm.isLeader()) { + if(cm.isEventLeader()) { cm.sendOk("I have been saved thanks to your efforts! Thank you, guys!"); } else { diff --git a/scripts/npc/2094002.js b/scripts/npc/2094002.js index 4bc21569a5..97fad68641 100644 --- a/scripts/npc/2094002.js +++ b/scripts/npc/2094002.js @@ -22,7 +22,7 @@ function action(mode, type, selection) { return; } - if (!cm.isLeader()) { + if (!cm.isEventLeader()) { cm.sendYesNo("I wish for your leader to talk to me. Alternatively, you may be wanting to quit. Are you going to abandon this campaign?"); } else { diff --git a/scripts/npc/9000037.js b/scripts/npc/9000037.js index 9658041cb8..8ca5cc7821 100644 --- a/scripts/npc/9000037.js +++ b/scripts/npc/9000037.js @@ -65,7 +65,7 @@ function action(mode, type, selection) { cm.getEventInstance().setProperty("clear", "true"); } - if(cm.isLeader()) { + if(cm.isEventLeader()) { cm.sendOk("Your party completed such an astounding feat coming this far, #byou have defeated all the bosses#k, congratulations! Now I will be handing your reward as you are being transported out..."); } else { @@ -73,7 +73,7 @@ function action(mode, type, selection) { } } else if(state == 2) { - if(cm.isLeader()) { + if(cm.isEventLeader()) { if(cm.getPlayer().getEventInstance().isEventTeamTogether()) { cm.sendYesNo("Is your party ready to proceed to the next stages? Walk through the portal if you think you're done, the time is now.. Now, do you guys REALLY want to proceed?"); } @@ -126,7 +126,7 @@ function action(mode, type, selection) { if (cm.getParty() == null) { cm.sendOk("You can participate in the party quest only if you are in a party."); cm.dispose(); - } else if(!cm.isLeader()) { + } else if(!cm.isEventLeader()) { cm.sendOk("Your party leader must talk to me to start this party quest."); cm.dispose(); } else { diff --git a/scripts/npc/9020000.js b/scripts/npc/9020000.js index b60eee316e..ca6204f1a1 100644 --- a/scripts/npc/9020000.js +++ b/scripts/npc/9020000.js @@ -51,7 +51,7 @@ function action(mode, type, selection) { if (cm.getParty() == null) { cm.sendOk("You can participate in the party quest only if you are in a party."); cm.dispose(); - } else if(!cm.isLeader()) { + } else if(!cm.isEventLeader()) { cm.sendOk("Your party leader must talk to me to start this party quest."); cm.dispose(); } else { diff --git a/scripts/npc/9020001.js b/scripts/npc/9020001.js index 7dc4335f59..55a6826e46 100644 --- a/scripts/npc/9020001.js +++ b/scripts/npc/9020001.js @@ -136,7 +136,7 @@ function action(mode, type, selection) { } } else if(curMap == 103000800) { // stage 1 - if(cm.isLeader()) { + if(cm.isEventLeader()) { var numpasses = eim.getPlayerCount() - 1; // minus leader if(cm.hasItem(4001008, numpasses)) { @@ -184,7 +184,7 @@ function action(mode, type, selection) { var nthtext = "2nd", nthobj = "ropes", nthverb = "hang", nthpos = "hang on the ropes too low"; var nextStgId = 103000802; - if(!eim.isLeader(cm.getPlayer())) { + if(!eim.isEventLeader(cm.getPlayer())) { cm.sendOk("Follow the instructions given by your party leader to proceed through this stage."); } else if(eim.getProperty(stgProperty) == null) { @@ -214,7 +214,7 @@ function action(mode, type, selection) { var nthtext = "3rd", nthobj = "platforms", nthverb = "stand", nthpos = "stand too close to the edges"; var nextStgId = 103000803; - if(!eim.isLeader(cm.getPlayer())) { + if(!eim.isEventLeader(cm.getPlayer())) { cm.sendOk("Follow the instructions given by your party leader to proceed through this stage."); } else if(eim.getProperty(stgProperty) == null) { @@ -244,7 +244,7 @@ function action(mode, type, selection) { var nthtext = "4th", nthobj = "barrels", nthverb = "stand", nthpos = "stand too close to the edges"; var nextStgId = 103000804; - if(!eim.isLeader(cm.getPlayer())) { + if(!eim.isEventLeader(cm.getPlayer())) { cm.sendOk("Follow the instructions given by your party leader to proceed through this stage."); } else if(eim.getProperty(stgProperty) == null) { @@ -267,7 +267,7 @@ function action(mode, type, selection) { cm.dispose(); } else if(curMap == 103000804) { - if (eim.isLeader(cm.getPlayer())) { + if (eim.isEventLeader(cm.getPlayer())) { if (cm.haveItem(4001008, 10)) { cm.sendNext("Here's the portal that leads you to the last, bonus stage. It's a stage that allows you to defeat regular monsters a little easier. You'll be given a set amount of time to hunt as much as possible, but you can always leave the stage in the middle of it through the NPC. Again, congratulations on clearing all the stages. Let your party talk to me to receive their prizes as they are allowed to pass to the bonus stage. Take care..."); cm.gainItem(4001008, -10); diff --git a/scripts/npc/9040000.js b/scripts/npc/9040000.js index 14de75c41e..765f988852 100644 --- a/scripts/npc/9040000.js +++ b/scripts/npc/9040000.js @@ -1,122 +1,106 @@ -/* - This file is part of the OdinMS Maple Story Server - Copyright (C) 2008 Patrick Huy - Matthias Butz - Jan Christian Meyer - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation version 3 as published by - the Free Software Foundation. You may not use, modify or distribute - this program under any other version of the GNU Affero General Public - License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ -/* -* @Author Lerk -* -* Shuang, Victoria Road: Excavation Site (101030104) -* -* Start of Guild Quest +/** + * @author: Ronan + * @npc: Shuang + * @map: Victoria Road: Excavation Site (101030104) + * @func: Start Guild PQ */ var status = 0; -var GQItems = new Array(1032033, 4001024, 4001025, 4001026, 4001027, 4001028, 4001029, 4001030, 4001031, 4001032, 4001033, 4001034, 4001035, 4001037); +var sel; +var em = null; + +function findLobby(guild) { + for (var iterator = em.getInstances().iterator(); iterator.hasNext();) { + var lobby = iterator.next(); + + if(lobby.getIntProperty("guild") == guild) { + if(lobby.getIntProperty("canJoin") == 1) return lobby; + else return null; + } + } + + return null; +} function start() { - cm.sendSimple("The path to Sharenian starts here. What would you like to do? #b\r\n#L0#Start a Guild Quest#l\r\n#L1#Join your guild's Guild Quest#l"); + status = -1; + action(1, 0, 0); } function action(mode, type, selection) { - if (mode == -1) - cm.dispose(); - else { - if (mode == 0 && status == 0) { - cm.dispose(); - return; - } - if (mode == 1) - status++; - else - status--; - if (status == 1) { - if (selection == 0) { //Start - if (cm.getPlayer().getGuildId() == 0 || cm.getPlayer().getGuildRank() >= 3) { //no guild or not guild master/jr. master - cm.sendNext("Only a Master or Jr. Master of the guild can start an instance."); - cm.dispose(); + if (mode == -1) { + cm.dispose(); + } else { + if (mode == 0 && status == 0) { + cm.dispose(); + return; } - else { - var em = cm.getEventManager("GuildQuest"); - if (em == null) - cm.sendOk("This trial is currently under construction."); - else { - if(em.getProperty("gpqOpen").equals("false")) { - cm.sendOk("Another guild has already registered for the quest. Please try again later."); - } else if (getEimForGuild(em, cm.getPlayer().getGuildId()) != null) - cm.sendOk("Your guild already is already registered."); - else { - var guildId = cm.getPlayer().getGuildId(); - var eim = em.newInstance(guildId); - em.startInstance(eim, cm.getPlayer().getName()); - em.setProperty("gpqOpen", "false"); - var map = eim.getMapInstance(990000000); - map.getPortal(5).setScriptName("guildwaitingenter"); - map.getPortal(4).setScriptName("guildwaitingexit"); - eim.registerPlayer(cm.getPlayer()); - cm.guildMessage(5, "The guild has been entered into the Guild Quest. Please report to Shuang at the Excavation Camp on channel " + cm.getClient().getChannel() + "."); - for (var i = 0; i < GQItems.length; i++) - cm.removeAll(GQItems[i]); + if (mode == 1) + status++; + else + status--; + + if (status == 0) { + em = cm.getEventManager("GuildQuest"); + if(em == null) { + cm.sendOk("The Guild Quest has encountered an error."); + cm.dispose(); + return; } - } - cm.dispose(); - } - } - else if (selection == 1) { //entering existing GQ - if (cm.getPlayer().getGuildId() == 0) { //no guild or not guild master/jr. master - cm.sendNext("You must be in a guild to join an instance."); - cm.dispose(); - } - else { - var em = cm.getEventManager("GuildQuest"); - if (em == null) - cm.sendOk("This trial is currently under construction."); - else { - var eim = getEimForGuild(em, cm.getPlayer().getGuildId()); - if (eim == null) - cm.sendOk("Your guild is currently not registered for the Guild Quest."); - else { - if ("true".equals(eim.getProperty("canEnter"))) { - eim.registerPlayer(cm.getPlayer()); - for (var i = 0; i < GQItems.length; i++) - cm.removeAll(GQItems[i]); - } - else - cm.sendOk("I'm sorry, but the guild has gone on without you. Try again later."); + + cm.sendSimple("#e#b\r\n#k#n" + em.getProperty("party") + "\r\n\r\nThe path to Sharenian starts here. What would you like to do? #b\r\n#L0#Register your guild for Guild Quest#l\r\n#L1#Join your guild's Guild Quest#l\r\n#L2#I would like to hear more details.#l"); + } else if (status == 1) { + sel = selection; + if (selection == 0) { + if(!cm.isGuildLeader()) { + cm.sendOk("Your guild master/jr.master must talk to me to register this guild quest."); + cm.dispose(); + } else { + if(em.isQueueFull()) { + cm.sendOk("The queue on this channel is already full. Please be patient and try again after a while, or try on another channel."); + cm.dispose(); + } else { + var qsize = em.getQueueSize(); + cm.sendYesNo(((qsize > 0) ? "There is currently #r" + qsize + "#k guilds queued on. " : "") + "Do you wish for your guild to join this queue?"); + } + } + } else if (selection == 1) { + if(cm.getPlayer().getGuildId() > 0) { + var eim = findLobby(cm.getPlayer().getGuildId()); + if(eim == null) { + cm.sendOk("You don't have a guild registered and currently on strategy time to assist on this channel."); + } else { + if(cm.isLeader()) { + em.getEligibleParty(cm.getParty()); + eim.registerParty(cm.getPlayer()); + } else { + eim.registerPlayer(cm.getPlayer()); + } + } + } else { + cm.sendOk("You can't participate in the guild quest if you don't pertain on a guild yourself!"); + } + + cm.dispose(); + } else { + cm.sendOk("#e#b#k#n\r\n Team up with your guild members in an auspicious attempt to recover the Rubian from the skeleton's grasp, with teamwork overcoming many puzzles and challenges awaiting inside the Sharenian tombs. Great rewards can be obtained upon the instance completion, and Guild Points can be racked up for your Guild."); + cm.dispose(); } - } - cm.dispose(); + } else if (status == 2) { + if (sel == 0) { + var entry = em.addGuildToQueue(cm.getPlayer().getGuildId(), cm.getPlayer().getId()); + if(entry > 0) { + if(entry == 1) { + cm.sendOk("Your guild has been registered successfully. A message will pop on your chat keeping your guild aware about the registration status. Now, #rimportant#k: as the leader of this instance, #ryou must already be present on this channel#k the right moment your guild is called for the strategy time. #bThe missubmission of this action will void#k your guild registration as a whole, and the next guild will be called immediately. Must be noted also, that if you become absent from the end of the strategy time to any point on the duration of the instance, it will render the instance interrupted, and your guild will be moved out instantly, moving again the queue."); + } + } else if(entry == 0) { + cm.sendOk("The queue on this channel is already full. Please be patient and try again after a while, or try on another channel."); + } else { + cm.sendOk("Your guild is already queued on a channel. Please wait for your guild's turn."); + } + } + + cm.dispose(); } - } } - } -} - -function getEimForGuild(em, id) { - var stringId = "" + id; - return em.getInstance(stringId); -} - -function isGuildQuestOwner(em, id) { - var stringId = "" + id; - if(em.getProperty("curGuild").equals(stringId)) - return true; - - return false; } \ No newline at end of file diff --git a/scripts/npc/9103000.js b/scripts/npc/9103000.js index 869ed6d58d..dde1a4e58f 100644 --- a/scripts/npc/9103000.js +++ b/scripts/npc/9103000.js @@ -51,7 +51,7 @@ function action(mode, type, selection) { status--; if (status == 0) { - if(cm.isLeader()) { + if(cm.isEventLeader()) { if(!cm.getEventInstance().isEventTeamTogether()) { cm.sendOk("One or more event team members is missing, please wait for them to reach here first."); cm.dispose(); diff --git a/scripts/portal/guildwaitingenter.js b/scripts/portal/guildwaitingenter.js index 1dd12dd79a..634af77734 100644 --- a/scripts/portal/guildwaitingenter.js +++ b/scripts/portal/guildwaitingenter.js @@ -19,24 +19,23 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -/* @Author Lerk +/* @Author Lerk, Ronan * * Guild Quest Waiting Room - Entry Portal (map 990000000) */ function enter(pi) { - if (pi.getPlayer().getEventInstance() == null) { - pi.warp(101030104); - return true; - } - else { - if (pi.getPlayer().getEventInstance().getProperty("canEnter").equals("false")) { + var entryTime = pi.getPlayer().getEventInstance().getProperty("entryTimestamp"); + var timeNow = Date.now(); + + var timeLeft = Math.ceil((entryTime - timeNow) / 1000); + + if(timeLeft <= 0) { pi.warp(990000100); return true; } else { //cannot proceed while allies can still enter - pi.playerMessage(5, "The portal is not open yet."); + pi.playerMessage(5, "The portal will open in about " + timeLeft + " seconds."); return false; } - } } \ No newline at end of file diff --git a/scripts/portal/guildwaitingexit.js b/scripts/portal/guildwaitingexit.js index 1e8895518d..6393214b2b 100644 --- a/scripts/portal/guildwaitingexit.js +++ b/scripts/portal/guildwaitingexit.js @@ -20,8 +20,6 @@ along with this program. If not, see . */ function enter(pi) { - if (pi.getPlayer().getEventInstance() != null) { - pi.getPlayer().getEventInstance().removePlayer(pi.getPlayer()); - } + pi.warp(101030104); return true; } \ No newline at end of file diff --git a/scripts/portal/party3_gardenin.js b/scripts/portal/party3_gardenin.js index dfee2e3dd0..4ab499afd0 100644 --- a/scripts/portal/party3_gardenin.js +++ b/scripts/portal/party3_gardenin.js @@ -1,5 +1,5 @@ function enter(pi) { - if (pi.getPlayer().getParty() != null && pi.isLeader() && pi.haveItem(4001055,1)) { + if (pi.getPlayer().getParty() != null && pi.isEventLeader() && pi.haveItem(4001055,1)) { pi.getEventInstance().warpEventTeam(920010100); return true; } else { diff --git a/scripts/portal/party6_out.js b/scripts/portal/party6_out.js index 621f329db9..df3231fe5e 100644 --- a/scripts/portal/party6_out.js +++ b/scripts/portal/party6_out.js @@ -1,6 +1,6 @@ function enter(pi) { if ((pi.getMap().getMonsters().size() == 0 || pi.getMap().getMonsterById(9300183) != null) && (pi.getMap().getReactorByName("") == null || pi.getMap().getReactorByName("").getState() == 1)) { - if(pi.isLeader()) { + if(pi.isEventLeader()) { pi.getEventInstance().clearPQ(); return true; } diff --git a/scripts/portal/raid_rest.js b/scripts/portal/raid_rest.js index b8e202c9d4..2a49b8ca9d 100644 --- a/scripts/portal/raid_rest.js +++ b/scripts/portal/raid_rest.js @@ -27,7 +27,7 @@ BossRushPQ - Rest Spot portal function enter(pi) { var evLevel = ((pi.getMapId() - 1) % 5) + 1; - if(pi.getPlayer().getEventInstance().isLeader(pi.getPlayer()) && pi.getPlayer().getEventInstance().getPlayerCount() > 1) { + if(pi.getPlayer().getEventInstance().isEventLeader(pi.getPlayer()) && pi.getPlayer().getEventInstance().getPlayerCount() > 1) { pi.message("Being the party leader, you cannot leave before your teammates leave first or you pass leadership."); return false; } diff --git a/src/client/MapleCharacter.java b/src/client/MapleCharacter.java index dae423c560..f8681890b2 100644 --- a/src/client/MapleCharacter.java +++ b/src/client/MapleCharacter.java @@ -1124,7 +1124,14 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } public void changeMap(int map) { - changeMap(map, 0); + MapleMap warpMap; + if (getEventInstance() != null) { + warpMap = getEventInstance().getMapInstance(map); + } else { + warpMap = client.getChannelServer().getMapFactory().getMap(map); + } + + changeMap(warpMap, warpMap.getRandomPlayerSpawnpoint()); } public void changeMap(int map, int portal) { @@ -3343,6 +3350,10 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { public boolean isPartyLeader() { return party.getLeaderId() == getId(); } + + public boolean isGuildLeader() { // true on guild master or jr. master + return guildid > 0 && guildRank < 3; + } public void leaveMap() { controlled.clear(); diff --git a/src/client/command/Commands.java b/src/client/command/Commands.java index 7109b60d25..40919b2763 100644 --- a/src/client/command/Commands.java +++ b/src/client/command/Commands.java @@ -684,7 +684,7 @@ public class Commands { case "debugnearestportal": if(ServerConstants.USE_DEBUG) { MaplePortal portal = player.getMap().findClosestPortal(player.getPosition()); - if(portal != null) player.dropMessage(6, "Closest portal: " + portal.getId() + " '" + portal.getName() + "' --> toMap: " + portal.getTargetMapId() + " scriptname: '" + portal.getScriptName() + "' state: " + portal.getPortalState() + "."); + if(portal != null) player.dropMessage(6, "Closest portal: " + portal.getId() + " '" + portal.getName() + "' Type: " + portal.getType() + " --> toMap: " + portal.getTargetMapId() + " scriptname: '" + portal.getScriptName() + "' state: " + portal.getPortalState() + "."); else player.dropMessage(6, "There is no portal on this map."); } break; @@ -692,7 +692,7 @@ public class Commands { case "debugnearestspawnpoint": if(ServerConstants.USE_DEBUG) { SpawnPoint sp = player.getMap().findClosestSpawnpoint(player.getPosition()); - if(sp != null) player.dropMessage(6, "Closest spawn point: " + " Position: x " + sp.getPosition().getX() + " y " + sp.getPosition().getY() + " Spawns mobid: '" + ((sp.getMonster() != null) ? sp.getMonster().getId() : "null") + "' --> canSpawn: " + !sp.getDenySpawn() + " canSpawnRightNow: " + sp.shouldSpawn() + "."); + if(sp != null) player.dropMessage(6, "Closest mob spawn point: " + " Position: x " + sp.getPosition().getX() + " y " + sp.getPosition().getY() + " Spawns mobid: '" + ((sp.getMonster() != null) ? sp.getMonster().getId() : "null") + "' --> canSpawn: " + !sp.getDenySpawn() + " canSpawnRightNow: " + sp.shouldSpawn() + "."); else player.dropMessage(6, "There is no mob spawn point on this map."); } break; diff --git a/src/net/server/PlayerStorage.java b/src/net/server/PlayerStorage.java index d760327708..05f6930d2b 100644 --- a/src/net/server/PlayerStorage.java +++ b/src/net/server/PlayerStorage.java @@ -57,7 +57,7 @@ public class PlayerStorage { public MapleCharacter getCharacterByName(String name) { rlock.lock(); try { - for (MapleCharacter chr : storage.values()) { + for (MapleCharacter chr : storage.values()) { if (chr.getName().toLowerCase().equals(name.toLowerCase())) return chr; } diff --git a/src/net/server/channel/Channel.java b/src/net/server/channel/Channel.java index 0dcaaa194e..0a165a1745 100644 --- a/src/net/server/channel/Channel.java +++ b/src/net/server/channel/Channel.java @@ -296,14 +296,16 @@ public final class Channel { private static String [] getEvents(){ List events = new ArrayList(); for (File file : new File("scripts/event").listFiles()){ - events.add(file.getName().substring(0, file.getName().length() - 3)); + events.add(file.getName().substring(0, file.getName().length() - 3)); } return events.toArray(new String[0]); } - public int getStoredVar(int key) { - if(storedVars.containsKey(key)) + public int getStoredVar(int key) { + if(storedVars.containsKey(key)) { return storedVars.get(key); + } + return 0; } diff --git a/src/net/server/channel/handlers/ChangeMapHandler.java b/src/net/server/channel/handlers/ChangeMapHandler.java index 9234c0704b..ab0ea7be41 100644 --- a/src/net/server/channel/handlers/ChangeMapHandler.java +++ b/src/net/server/channel/handlers/ChangeMapHandler.java @@ -88,7 +88,7 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler { chr.setStance(0); } chr.setHp(50); - chr.changeMap(to, to.getPortal(0)); + chr.changeMap(to, to.getRandomPlayerSpawnpoint()); } } else if (targetid != -1 && chr.isGM()) { MapleMap to = c.getChannelServer().getMapFactory().getMap(targetid); diff --git a/src/net/server/world/World.java b/src/net/server/world/World.java index 995ef36e84..79800b3a3b 100644 --- a/src/net/server/world/World.java +++ b/src/net/server/world/World.java @@ -37,6 +37,8 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import java.util.Set; +import java.util.HashSet; import net.server.PlayerStorage; import net.server.Server; @@ -65,6 +67,7 @@ public class World { private Map families = new LinkedHashMap<>(); private Map gsStore = new HashMap<>(); private PlayerStorage players = new PlayerStorage(); + private Set queuedGuilds = new HashSet<>(); public World(int world, int flag, String eventmsg, int exprate, int droprate, int mesorate, int bossdroprate) { this.id = world; @@ -300,6 +303,18 @@ public class World { } } + public boolean isGuildQueued(int guildId) { + return queuedGuilds.contains(guildId); + } + + public void putGuildQueued(int guildId) { + queuedGuilds.add(guildId); + } + + public void removeGuildQueued(int guildId) { + queuedGuilds.remove(guildId); + } + public MapleParty createParty(MaplePartyCharacter chrfor) { int partyid = runningPartyId.getAndIncrement(); MapleParty party = new MapleParty(partyid, chrfor); @@ -364,13 +379,14 @@ public class World { party.updateMember(target); break; case CHANGE_LEADER: - if(party.getLeader().getPlayer().getEventInstance() != null) { - party.getLeader().getPlayer().getEventInstance().changedLeader(target.getPlayer()); + MapleCharacter mc = party.getLeader().getPlayer(); + if(mc.getEventInstance() != null && mc.getEventInstance().isEventLeader(mc)) { + mc.getEventInstance().changedLeader(target.getPlayer()); } party.setLeader(target); break; default: - System.out.println("Unhandeled updateParty operation " + operation.name()); + System.out.println("Unhandled updateParty operation " + operation.name()); } updateParty(party, operation, target); } diff --git a/src/provider/wz/WZIMGFile.java b/src/provider/wz/WZIMGFile.java index a4dd1b7fe8..bec06c78bd 100644 --- a/src/provider/wz/WZIMGFile.java +++ b/src/provider/wz/WZIMGFile.java @@ -221,7 +221,7 @@ public class WZIMGFile { System.out.println("Unknown UOL marker: " + uolmarker + " " + entry.getName()); } } else { - throw new RuntimeException("Unhandeled extended type: " + type); + throw new RuntimeException("Unhandled extended type: " + type); } } } diff --git a/src/scripting/AbstractPlayerInteraction.java b/src/scripting/AbstractPlayerInteraction.java index 268da7fbb6..c4714bbb27 100644 --- a/src/scripting/AbstractPlayerInteraction.java +++ b/src/scripting/AbstractPlayerInteraction.java @@ -528,6 +528,10 @@ public class AbstractPlayerInteraction { public MapleParty getParty() { return getPlayer().getParty(); } + + public boolean isGuildLeader() { + return getPlayer().isGuildLeader(); + } public boolean isLeader() { if(getParty() == null) @@ -535,6 +539,10 @@ public class AbstractPlayerInteraction { 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 (MapleCharacter chr : party) { diff --git a/src/scripting/event/EventInstanceManager.java b/src/scripting/event/EventInstanceManager.java index 11255c2cc3..dd4bda2eb4 100644 --- a/src/scripting/event/EventInstanceManager.java +++ b/src/scripting/event/EventInstanceManager.java @@ -31,6 +31,7 @@ import java.util.HashMap; import java.util.Map; import java.util.HashSet; import java.util.Set; +import java.util.Iterator; import java.util.Properties; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; @@ -69,7 +70,8 @@ import tools.MaplePacketCreator; * @author Matze, Ronan */ public class EventInstanceManager { - private List chars = new ArrayList<>(); + private Map chars = new HashMap<>(); + private int leaderId = -1; private List mobs = new LinkedList<>(); private Map killCount = new HashMap<>(); private EventManager em; @@ -103,7 +105,7 @@ public class EventInstanceManager { // registers all opened gates on the event. Will help late characters to encounter next stages gates already opened private Set openedGates = new HashSet<>(); - // forces deletion of items not supposed to be holding out of the event, dealt on a player's leave moment. + // 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) { @@ -209,7 +211,7 @@ public class EventInstanceManager { try { wL.lock(); try { - chars.add(chr); + chars.put(chr.getId(), chr); } finally { wL.unlock(); @@ -238,12 +240,15 @@ public class EventInstanceManager { timeStarted = System.currentTimeMillis(); eventTime = time; - for(MapleCharacter chr: getPlayers()) chr.announce(MaplePacketCreator.getClock((int) (time / 1000))); + for(MapleCharacter chr: getPlayers()) { + chr.announce(MaplePacketCreator.getClock((int) (time / 1000))); + } + event_schedule = TimerManager.getInstance().schedule(new Runnable() { public void run() { try { - em.getIv().invokeFunction("scheduledTimeout", EventInstanceManager.this); dismissEventTimer(); + em.getIv().invokeFunction("scheduledTimeout", EventInstanceManager.this); } catch (ScriptException | NoSuchMethodException ex) { Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex); } @@ -260,8 +265,8 @@ public class EventInstanceManager { event_schedule = TimerManager.getInstance().schedule(new Runnable() { public void run() { try { - em.getIv().invokeFunction("scheduledTimeout", EventInstanceManager.this); dismissEventTimer(); + em.getIv().invokeFunction("scheduledTimeout", EventInstanceManager.this); } catch (ScriptException | NoSuchMethodException ex) { Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex); } @@ -274,14 +279,6 @@ public class EventInstanceManager { } } - public void stopEventTimer() { - if(event_schedule != null) { - event_schedule.cancel(false); - event_schedule = null; - } - dismissEventTimer(); - } - private void dismissEventTimer() { for(MapleCharacter chr: getPlayers()) { chr.getClient().getSession().write(MaplePacketCreator.removeClock()); @@ -292,6 +289,14 @@ public class EventInstanceManager { 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; } @@ -300,6 +305,12 @@ public class EventInstanceManager { return eventTime - (System.currentTimeMillis() - timeStarted); } + public void registerParty(MapleCharacter chr) { + if(chr.isPartyLeader()) { + registerParty(chr.getParty(), chr.getMap()); + } + } + public void registerParty(MapleParty party, MapleMap map) { for (MaplePartyCharacter pc : party.getEligibleMembers()) { MapleCharacter c = map.getCharacterById(pc.getId()); @@ -321,7 +332,7 @@ public class EventInstanceManager { Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex); } - chars.remove(chr); + chars.remove(chr.getId()); gridRemove(chr); dropExclusiveItems(chr); } finally { @@ -344,7 +355,7 @@ public class EventInstanceManager { public List getPlayers() { rL.lock(); try { - return new ArrayList<>(chars); + return new ArrayList<>(chars.values()); } finally { rL.unlock(); @@ -354,7 +365,7 @@ public class EventInstanceManager { private List getPlayerList() { rL.lock(); try { - return new LinkedList<>(chars); + return new LinkedList<>(chars.values()); } finally { rL.unlock(); } @@ -478,7 +489,7 @@ public class EventInstanceManager { wL.lock(); try { - for(MapleCharacter chr: chars) chr.setEventInstance(null); + for(MapleCharacter chr: chars.values()) chr.setEventInstance(null); chars.clear(); mobs.clear(); @@ -612,6 +623,10 @@ public class EventInstanceManager { return (chr.getParty().getLeaderId() == chr.getId()); } + public boolean isEventLeader(MapleCharacter chr) { + return (chr.getId() == getLeaderId()); + } + public final MapleMap getInstanceMap(final int mapid) { //gets instance map from the channelserv if (disposed) { return getMapFactory().getMap(mapid); @@ -829,10 +844,27 @@ public class EventInstanceManager { return eventCleared; } + private boolean isEventTeamLeaderOn() { + for(MapleCharacter chr: getPlayers()) { + if(chr.getId() == getLeaderId()) return true; + } + + return false; + } + + public final boolean checkEventTeamLacking(boolean testLeader, int minPlayers) { + if(eventCleared && getPlayerCount() > 1) return false; + + if(!eventCleared && testLeader && !isEventTeamLeaderOn()) return true; + if(getPlayerCount() < minPlayers) return true; + + return false; + } + public final boolean isEventTeamLackingNow(boolean testLeader, int minPlayers, MapleCharacter quitter) { if(eventCleared && getPlayerCount() > 1) return false; - if(!eventCleared && testLeader && getLeader().getId() == quitter.getId()) return true; + if(!eventCleared && testLeader && getLeaderId() == quitter.getId()) return true; if(getPlayerCount() <= minPlayers) return true; return false; @@ -842,12 +874,16 @@ public class EventInstanceManager { rL.lock(); try { if(chars.size() <= 1) return true; - - int mapId = chars.get(0).getMapId(); - for(int i = 1; i < chars.size(); i++) { - if(chars.get(i).getMapId() != mapId) return false; + + Iterator iterator = chars.values().iterator(); + MapleCharacter mc = iterator.next(); + int mapId = mc.getMapId(); + + for (; iterator.hasNext();) { + mc = iterator.next(); + if(mc.getMapId() != mapId) return false; } - + return true; } finally { rL.unlock(); @@ -888,19 +924,33 @@ public class EventInstanceManager { } } - public final MapleCharacter getLeader() { + public final int getLeaderId() { rL.lock(); try { - for (MapleCharacter chr : chars) { - if(chr.isPartyLeader()) return chr; - } - - return null; + return leaderId; } finally { rL.unlock(); } } + public MapleCharacter getLeader() { + rL.lock(); + try { + return chars.get(leaderId); + } finally { + rL.unlock(); + } + } + + public final void setLeader(MapleCharacter chr) { + wL.lock(); + try { + leaderId = chr.getId(); + } finally { + wL.unlock(); + } + } + public final void showWrongEffect() { MapleMap map = getMapInstance(getLeader().getMapId()); map.broadcastMessage(MaplePacketCreator.showEffect("quest/party/wrong_kor")); diff --git a/src/scripting/event/EventManager.java b/src/scripting/event/EventManager.java index 866d0c0fc8..1068bf7479 100644 --- a/src/scripting/event/EventManager.java +++ b/src/scripting/event/EventManager.java @@ -33,7 +33,10 @@ import java.util.logging.Logger; import javax.script.Invocable; import javax.script.ScriptException; +import net.server.Server; +import net.server.world.World; import net.server.channel.Channel; +import net.server.guild.MapleGuild; import net.server.world.MapleParty; import net.server.world.MaplePartyCharacter; import server.TimerManager; @@ -43,10 +46,10 @@ import server.life.MapleMonster; import server.life.MapleLifeFactory; import client.MapleCharacter; -import java.util.LinkedList; import java.util.List; import java.util.ArrayList; -import java.lang.reflect.Array; +import java.util.LinkedList; +import java.util.Queue; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -57,20 +60,26 @@ import java.util.concurrent.locks.ReentrantLock; public class EventManager { private Invocable iv; private Channel cserv; + private World wserv; + private Server server; private Map instances = new HashMap(); private Map instanceLocks = new HashMap(); + private final Queue queuedGuilds = new LinkedList<>(); + private final Map queuedGuildLeaders = new HashMap<>(); private List openedLobbys; private Properties props = new Properties(); private String name; - private ScheduledFuture schedule = null; private Lock l = new ReentrantLock(); + private static final int limitGuilds = 10; // max numbers of guilds in queue for GPQ. private static final int maxLobbys = 8; // an event manager holds up to this amount of concurrent lobbys private static final long lobbyDelay = 10; // 10 seconds cooldown before reopening a lobby 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<>(); @@ -92,6 +101,10 @@ public class EventManager { return intList; } + public long getLobbyDelay() { + return lobbyDelay; + } + private List getLobbyRange() { try { return convertToIntegerArray((List)iv.invokeFunction("setLobbyRange", (Object) null)); @@ -104,12 +117,12 @@ public class EventManager { } } - public void schedule(String methodName, long delay) { - schedule(methodName, null, delay); + public ScheduledFuture schedule(String methodName, long delay) { + return schedule(methodName, null, delay); } - public void schedule(final String methodName, final EventInstanceManager eim, long delay) { - schedule = TimerManager.getInstance().schedule(new Runnable() { + public ScheduledFuture schedule(final String methodName, final EventInstanceManager eim, long delay) { + return TimerManager.getInstance().schedule(new Runnable() { public void run() { try { iv.invokeFunction(methodName, eim); @@ -120,11 +133,6 @@ public class EventManager { }, delay); } - public void cancelSchedule() { - if(schedule != null) - schedule.cancel(false); - } - public ScheduledFuture scheduleAtTimestamp(final String methodName, long timestamp) { return TimerManager.getInstance().scheduleAtTimestamp(new Runnable() { public void run() { @@ -250,9 +258,13 @@ public class EventManager { public boolean startInstance(MapleExpedition exped) { return startInstance(-1, exped); } + + public boolean startInstance(int lobbyId, MapleExpedition exped) { + return startInstance(lobbyId, exped, exped.getLeader()); + } //Expedition method: starts an expedition - public boolean startInstance(int lobbyId, MapleExpedition exped) { + public boolean startInstance(int lobbyId, MapleExpedition exped, MapleCharacter leader) { try { if(lobbyId == -1) { lobbyId = availableLobbyInstance(); @@ -269,6 +281,7 @@ public class EventManager { return false; } instanceLocks.put(eim.getName(), lobbyId); + eim.setLeader(leader); eim.registerExpedition(exped); exped.start(); @@ -286,6 +299,10 @@ public class EventManager { } public boolean startInstance(int lobbyId, MapleCharacter chr) { + return startInstance(lobbyId, chr, chr, 1); + } + + public boolean startInstance(int lobbyId, MapleCharacter chr, MapleCharacter leader, int difficulty) { try { if(lobbyId == -1) { lobbyId = availableLobbyInstance(); @@ -296,12 +313,13 @@ public class EventManager { startLobbyInstance(lobbyId); } - EventInstanceManager eim = (EventInstanceManager) (iv.invokeFunction("setup", (Object) null)); + EventInstanceManager eim = (EventInstanceManager) (iv.invokeFunction("setup", difficulty, (lobbyId > -1) ? lobbyId : leader.getId())); if(eim == null) { if(lobbyId > -1) setLockLobby(lobbyId, false); return false; } instanceLocks.put(eim.getName(), lobbyId); + eim.setLeader(leader); eim.registerPlayer(chr); iv.invokeFunction("afterSetup", eim); @@ -318,6 +336,10 @@ public class EventManager { } public boolean startInstance(int lobbyId, MapleParty party, MapleMap map) { + return startInstance(lobbyId, party, map, party.getLeader().getPlayer()); + } + + public boolean startInstance(int lobbyId, MapleParty party, MapleMap map, MapleCharacter leader) { try { if(lobbyId == -1) { lobbyId = availableLobbyInstance(); @@ -334,6 +356,7 @@ public class EventManager { return false; } instanceLocks.put(eim.getName(), lobbyId); + eim.setLeader(leader); eim.registerParty(party, map); party.setEligibleMembers(null); @@ -351,6 +374,10 @@ public class EventManager { } public boolean startInstance(int lobbyId, MapleParty party, MapleMap map, int difficulty) { + return startInstance(lobbyId, party, map, difficulty, party.getLeader().getPlayer()); + } + + public boolean startInstance(int lobbyId, MapleParty party, MapleMap map, int difficulty, MapleCharacter leader) { try { if(lobbyId == -1) { lobbyId = availableLobbyInstance(); @@ -367,6 +394,7 @@ public class EventManager { return false; } instanceLocks.put(eim.getName(), lobbyId); + eim.setLeader(leader); eim.registerParty(party, map); party.setEligibleMembers(null); @@ -379,11 +407,19 @@ public class EventManager { } //non-PQ method for starting instance - public boolean startInstance(EventInstanceManager eim, String leader) { - return startInstance(-1, eim, leader); + public boolean startInstance(EventInstanceManager eim, String ldr) { + return startInstance(-1, eim, ldr); } - public boolean startInstance(int lobbyId, EventInstanceManager eim, String leader) { + public boolean startInstance(EventInstanceManager eim, MapleCharacter 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, MapleCharacter leader) { try { if(lobbyId == -1) { lobbyId = availableLobbyInstance(); @@ -399,9 +435,10 @@ public class EventManager { return false; } instanceLocks.put(eim.getName(), lobbyId); + eim.setLeader(leader); iv.invokeFunction("setup", eim); - eim.setProperty("leader", leader); + eim.setProperty("leader", ldr); iv.invokeFunction("afterSetup", eim); } catch (ScriptException | NoSuchMethodException ex) { Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex); @@ -448,4 +485,115 @@ public class EventManager { public MapleMonster getMonster(int mid) { return(MapleLifeFactory.getMonster(mid)); } + + private static String ordinal(int i) { + String[] sufixes = new String[] { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" }; + switch (i % 100) { + case 11: + case 12: + case 13: + return i + "th"; + default: + return i + sufixes[i % 10]; + + } + } + + private void exportReadyGuild(Integer guildId) { + MapleGuild mg = server.getGuild(guildId); + String callout = "Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId() + + " and JUST STARTED THE STRATEGY PHASE. After 3 minutes, no more guild members will be allowed to join the effort."; + + mg.dropMessage(0, callout); + } + + private void exportMovedQueueToGuild(Integer guildId, int place) { + MapleGuild mg = server.getGuild(guildId); + String callout = "Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId() + + " and is currently on the " + ordinal(place) + " place on the waiting queue."; + + mg.dropMessage(0, callout); + } + + private List getNextGuildQueue() { + synchronized(queuedGuilds) { + Integer guildId = queuedGuilds.poll(); + if(guildId == null) return null; + + wserv.removeGuildQueued(guildId); + Integer leaderId = queuedGuildLeaders.remove(guildId); + + exportReadyGuild(guildId); + + int place = 1; + for(Integer i: queuedGuilds) { + exportMovedQueueToGuild(i, place); + place++; + } + + List list = new ArrayList<>(2); + list.add(guildId); list.add(leaderId); + return list; + } + } + + public boolean isQueueFull() { + synchronized(queuedGuilds) { + return queuedGuilds.size() >= limitGuilds; + } + } + + public int getQueueSize() { + synchronized(queuedGuilds) { + return queuedGuilds.size(); + } + } + + public byte addGuildToQueue(Integer guildId, Integer leaderId) { + if(wserv.isGuildQueued(guildId)) return -1; + + if(!isQueueFull()) { + boolean canStartAhead; + synchronized(queuedGuilds) { + canStartAhead = queuedGuilds.isEmpty(); + + queuedGuilds.add(guildId); + wserv.putGuildQueued(guildId); + queuedGuildLeaders.put(guildId, leaderId); + + int place = queuedGuilds.size(); + exportMovedQueueToGuild(guildId, place); + } + + if(canStartAhead) { + if(!attemptStartGuildInstance()) { + synchronized(queuedGuilds) { + queuedGuilds.add(guildId); + wserv.putGuildQueued(guildId); + queuedGuildLeaders.put(guildId, leaderId); + } + } else { + return 2; + } + } + + return 1; + } else { + return 0; + } + } + + public boolean attemptStartGuildInstance() { + MapleCharacter chr = null; + while(chr == null) { + List guildInstance = getNextGuildQueue(); + if(guildInstance == null) { + return false; + } + + chr = cserv.getPlayerStorage().getCharacterById(guildInstance.get(1)); + } + + return startInstance(chr); + } } diff --git a/src/server/MapleStatEffect.java b/src/server/MapleStatEffect.java index 7dd38bd901..0313730582 100644 --- a/src/server/MapleStatEffect.java +++ b/src/server/MapleStatEffect.java @@ -749,7 +749,7 @@ public class MapleStatEffect { return false; } } - applyto.changeMap(target); + applyto.changeMap(target, target.getRandomPlayerSpawnpoint()); } else { return false; } diff --git a/src/server/maps/MapleMap.java b/src/server/maps/MapleMap.java index e61fca0dc7..758dbc748f 100644 --- a/src/server/maps/MapleMap.java +++ b/src/server/maps/MapleMap.java @@ -1640,7 +1640,7 @@ public class MapleMap { public MaplePortal getRandomPlayerSpawnpoint() { List spawnPoints = new ArrayList<>(); for (MaplePortal portal : portals.values()) { - if (portal.getType() >= 0 && portal.getType() <= 2) { + if (portal.getType() >= 0 && portal.getType() <= 1) { spawnPoints.add(portal); } } @@ -1653,7 +1653,7 @@ public class MapleMap { double shortestDistance = Double.POSITIVE_INFINITY; for (MaplePortal portal : portals.values()) { double distance = portal.getPosition().distanceSq(from); - if (portal.getType() >= 0 && portal.getType() <= 2 && distance < shortestDistance && portal.getTargetMapId() == 999999999) { + if (portal.getType() >= 0 && portal.getType() <= 1 && distance < shortestDistance && portal.getTargetMapId() == 999999999) { closest = portal; shortestDistance = distance; } diff --git a/wz/Map.wz/Map/Map9/990000000.img.xml b/wz/Map.wz/Map/Map9/990000000.img.xml index aefe3816e6..fbcfeab6b7 100644 --- a/wz/Map.wz/Map/Map9/990000000.img.xml +++ b/wz/Map.wz/Map/Map9/990000000.img.xml @@ -2790,20 +2790,21 @@ - + - - - + + + - + - - + + +