diff --git a/build/built-jar.properties b/build/built-jar.properties
index 20990307a3..a0f912d872 100644
--- a/build/built-jar.properties
+++ b/build/built-jar.properties
@@ -1,4 +1,4 @@
-#Tue, 13 Jun 2017 20:04:33 -0300
+#Sun, 18 Jun 2017 02:53:19 -0300
C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2=
diff --git a/build/classes/client/MapleCharacter$1.class b/build/classes/client/MapleCharacter$1.class
index 0eff4df0bd..8c915665a3 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 0b646bb9bb..5db70657ff 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 272b892a78..fd894efb84 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 24e3db5287..9e5dca18cf 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 76209ac700..9201666403 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 f61dfa482d..da427c2bdd 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 0854f98674..6749638e94 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 79898b5c87..80d6537289 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 e520ac3c5a..e832dbcf96 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 ffdc7903ca..f86ec6adca 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 a314c4d1a0..a2ea5df276 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 26352f663a..1887522ea6 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 2b893eebf9..4712a8fea3 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 5d3abdfe32..2f97916868 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 b14de10d83..002cc78e4f 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 21f54190fc..9520854af1 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 d7d64736ff..fc4c5544fb 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 955f4dd2ff..66829ca473 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$CancelCooldownAction.class b/build/classes/client/MapleCharacter$CancelCooldownAction.class
index a4d5ced0f9..a1c51341c8 100644
Binary files a/build/classes/client/MapleCharacter$CancelCooldownAction.class and b/build/classes/client/MapleCharacter$CancelCooldownAction.class differ
diff --git a/build/classes/client/MapleCharacter$FameStatus.class b/build/classes/client/MapleCharacter$FameStatus.class
index 5779bd2492..df59fb778a 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 5c4f79fa8c..dc55187e1a 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 40cb71201d..7682ba19da 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 c15b8968c2..ddc0380acf 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 6e4ca68a7f..84bc4e3401 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$1.class b/build/classes/client/command/Commands$1.class
index e00ce41e0f..f788196e57 100644
Binary files a/build/classes/client/command/Commands$1.class and b/build/classes/client/command/Commands$1.class differ
diff --git a/build/classes/client/command/Commands.class b/build/classes/client/command/Commands.class
index b53b5a20c8..e0068cdf88 100644
Binary files a/build/classes/client/command/Commands.class and b/build/classes/client/command/Commands.class differ
diff --git a/build/classes/constants/ServerConstants.class b/build/classes/constants/ServerConstants.class
index 2fd4a62ade..8f48ebf359 100644
Binary files a/build/classes/constants/ServerConstants.class and b/build/classes/constants/ServerConstants.class differ
diff --git a/build/classes/net/server/channel/handlers/ChangeMapHandler.class b/build/classes/net/server/channel/handlers/ChangeMapHandler.class
index 20da458f47..2b69cd743c 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/channel/handlers/ItemMoveHandler.class b/build/classes/net/server/channel/handlers/ItemMoveHandler.class
index 99e92eade1..f9972a7cd4 100644
Binary files a/build/classes/net/server/channel/handlers/ItemMoveHandler.class and b/build/classes/net/server/channel/handlers/ItemMoveHandler.class differ
diff --git a/build/classes/net/server/channel/handlers/NPCTalkHandler.class b/build/classes/net/server/channel/handlers/NPCTalkHandler.class
index 8004865152..577606c790 100644
Binary files a/build/classes/net/server/channel/handlers/NPCTalkHandler.class and b/build/classes/net/server/channel/handlers/NPCTalkHandler.class differ
diff --git a/build/classes/net/server/channel/handlers/PlayerLoggedinHandler$1.class b/build/classes/net/server/channel/handlers/PlayerLoggedinHandler$1.class
deleted file mode 100644
index 6d9ce2a135..0000000000
Binary files a/build/classes/net/server/channel/handlers/PlayerLoggedinHandler$1.class and /dev/null differ
diff --git a/build/classes/net/server/channel/handlers/PlayerLoggedinHandler.class b/build/classes/net/server/channel/handlers/PlayerLoggedinHandler.class
index 4e3ea583a0..4bf4f5bd26 100644
Binary files a/build/classes/net/server/channel/handlers/PlayerLoggedinHandler.class and b/build/classes/net/server/channel/handlers/PlayerLoggedinHandler.class differ
diff --git a/build/classes/net/server/channel/handlers/ReactorHitHandler.class b/build/classes/net/server/channel/handlers/ReactorHitHandler.class
index 1bcf040bbc..c8824d3c00 100644
Binary files a/build/classes/net/server/channel/handlers/ReactorHitHandler.class and b/build/classes/net/server/channel/handlers/ReactorHitHandler.class differ
diff --git a/build/classes/net/server/world/MaplePartyCharacter.class b/build/classes/net/server/world/MaplePartyCharacter.class
index 27bd0915c4..7c7a7b0069 100644
Binary files a/build/classes/net/server/world/MaplePartyCharacter.class and b/build/classes/net/server/world/MaplePartyCharacter.class differ
diff --git a/build/classes/scripting/AbstractPlayerInteraction.class b/build/classes/scripting/AbstractPlayerInteraction.class
index bae8646bea..84288ec78e 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.class b/build/classes/scripting/event/EventInstanceManager.class
index 4a2833ce31..92fc130936 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$3.class b/build/classes/scripting/event/EventManager$3.class
index 06b4cc64ce..14f26f70b6 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 e5097b1c40..1b5cab9d04 100644
Binary files a/build/classes/scripting/event/EventManager.class and b/build/classes/scripting/event/EventManager.class differ
diff --git a/build/classes/scripting/npc/NPCScriptManager.class b/build/classes/scripting/npc/NPCScriptManager.class
index 42ff0a8d4c..2cb16fd043 100644
Binary files a/build/classes/scripting/npc/NPCScriptManager.class and b/build/classes/scripting/npc/NPCScriptManager.class differ
diff --git a/build/classes/scripting/quest/QuestScriptManager.class b/build/classes/scripting/quest/QuestScriptManager.class
index 19802a4a27..c7ff3a1fb5 100644
Binary files a/build/classes/scripting/quest/QuestScriptManager.class and b/build/classes/scripting/quest/QuestScriptManager.class differ
diff --git a/build/classes/server/maps/MapleMap$10.class b/build/classes/server/maps/MapleMap$10.class
index 947cd0e213..9f7b023c79 100644
Binary files a/build/classes/server/maps/MapleMap$10.class and b/build/classes/server/maps/MapleMap$10.class differ
diff --git a/build/classes/server/maps/MapleMap$11.class b/build/classes/server/maps/MapleMap$11.class
index 973cba5190..67f2a13649 100644
Binary files a/build/classes/server/maps/MapleMap$11.class and b/build/classes/server/maps/MapleMap$11.class differ
diff --git a/build/classes/server/maps/MapleMap$12.class b/build/classes/server/maps/MapleMap$12.class
index 50ece27697..a7f19cf2ef 100644
Binary files a/build/classes/server/maps/MapleMap$12.class and b/build/classes/server/maps/MapleMap$12.class differ
diff --git a/build/classes/server/maps/MapleMap$13.class b/build/classes/server/maps/MapleMap$13.class
index 8cacf2754d..2197c3bcf1 100644
Binary files a/build/classes/server/maps/MapleMap$13.class and b/build/classes/server/maps/MapleMap$13.class differ
diff --git a/build/classes/server/maps/MapleMap$14.class b/build/classes/server/maps/MapleMap$14.class
index e1cd23bb83..0c5ad5f479 100644
Binary files a/build/classes/server/maps/MapleMap$14.class and b/build/classes/server/maps/MapleMap$14.class differ
diff --git a/build/classes/server/maps/MapleMap$15.class b/build/classes/server/maps/MapleMap$15.class
index bb8f0b24e6..5425774b7a 100644
Binary files a/build/classes/server/maps/MapleMap$15.class and b/build/classes/server/maps/MapleMap$15.class differ
diff --git a/build/classes/server/maps/MapleMap$16.class b/build/classes/server/maps/MapleMap$16.class
index ea578f65f4..b38aabf3fd 100644
Binary files a/build/classes/server/maps/MapleMap$16.class and b/build/classes/server/maps/MapleMap$16.class differ
diff --git a/build/classes/server/maps/MapleMap$17.class b/build/classes/server/maps/MapleMap$17.class
index cb47683f05..4a8ee2964c 100644
Binary files a/build/classes/server/maps/MapleMap$17.class and b/build/classes/server/maps/MapleMap$17.class differ
diff --git a/build/classes/server/maps/MapleMap$18.class b/build/classes/server/maps/MapleMap$18.class
index 8b918e0138..f7caf0518a 100644
Binary files a/build/classes/server/maps/MapleMap$18.class and b/build/classes/server/maps/MapleMap$18.class differ
diff --git a/build/classes/server/maps/MapleMap$19.class b/build/classes/server/maps/MapleMap$19.class
index ccc95a4734..a07608d038 100644
Binary files a/build/classes/server/maps/MapleMap$19.class and b/build/classes/server/maps/MapleMap$19.class differ
diff --git a/build/classes/server/maps/MapleMap$20.class b/build/classes/server/maps/MapleMap$20.class
index 0733fcdecc..3abb87449c 100644
Binary files a/build/classes/server/maps/MapleMap$20.class and b/build/classes/server/maps/MapleMap$20.class differ
diff --git a/build/classes/server/maps/MapleMap$21.class b/build/classes/server/maps/MapleMap$21.class
index 1996ac3a49..5edf33374e 100644
Binary files a/build/classes/server/maps/MapleMap$21.class and b/build/classes/server/maps/MapleMap$21.class differ
diff --git a/build/classes/server/maps/MapleMap$22.class b/build/classes/server/maps/MapleMap$22.class
index bcb9824a75..0b8b861685 100644
Binary files a/build/classes/server/maps/MapleMap$22.class and b/build/classes/server/maps/MapleMap$22.class differ
diff --git a/build/classes/server/maps/MapleMap$23.class b/build/classes/server/maps/MapleMap$23.class
index 206daa1a03..3decbf69c2 100644
Binary files a/build/classes/server/maps/MapleMap$23.class and b/build/classes/server/maps/MapleMap$23.class differ
diff --git a/build/classes/server/maps/MapleMap$24.class b/build/classes/server/maps/MapleMap$24.class
index f05af4cd02..d5c866da29 100644
Binary files a/build/classes/server/maps/MapleMap$24.class and b/build/classes/server/maps/MapleMap$24.class differ
diff --git a/build/classes/server/maps/MapleMap$25.class b/build/classes/server/maps/MapleMap$25.class
index dba447ac61..14d3ff85d4 100644
Binary files a/build/classes/server/maps/MapleMap$25.class and b/build/classes/server/maps/MapleMap$25.class differ
diff --git a/build/classes/server/maps/MapleMap$26.class b/build/classes/server/maps/MapleMap$26.class
index 4a45b894de..f67c821e95 100644
Binary files a/build/classes/server/maps/MapleMap$26.class and b/build/classes/server/maps/MapleMap$26.class differ
diff --git a/build/classes/server/maps/MapleMap$27.class b/build/classes/server/maps/MapleMap$27.class
index 80920b5bd6..809f0b6465 100644
Binary files a/build/classes/server/maps/MapleMap$27.class and b/build/classes/server/maps/MapleMap$27.class differ
diff --git a/build/classes/server/maps/MapleMap$28$1.class b/build/classes/server/maps/MapleMap$28$1.class
index d8f6056ee4..76776741e5 100644
Binary files a/build/classes/server/maps/MapleMap$28$1.class and b/build/classes/server/maps/MapleMap$28$1.class differ
diff --git a/build/classes/server/maps/MapleMap$28.class b/build/classes/server/maps/MapleMap$28.class
index 7c073ef345..22d1d0c16c 100644
Binary files a/build/classes/server/maps/MapleMap$28.class and b/build/classes/server/maps/MapleMap$28.class differ
diff --git a/build/classes/server/maps/MapleMap$29.class b/build/classes/server/maps/MapleMap$29.class
index ffd7186e3e..18a955dc7a 100644
Binary files a/build/classes/server/maps/MapleMap$29.class and b/build/classes/server/maps/MapleMap$29.class differ
diff --git a/build/classes/server/maps/MapleMap$3.class b/build/classes/server/maps/MapleMap$3.class
index c54ef7d508..4cd1edc447 100644
Binary files a/build/classes/server/maps/MapleMap$3.class and b/build/classes/server/maps/MapleMap$3.class differ
diff --git a/build/classes/server/maps/MapleMap$4.class b/build/classes/server/maps/MapleMap$4.class
index 7086b3e869..b49086ca0c 100644
Binary files a/build/classes/server/maps/MapleMap$4.class and b/build/classes/server/maps/MapleMap$4.class differ
diff --git a/build/classes/server/maps/MapleMap$5.class b/build/classes/server/maps/MapleMap$5.class
index a0cfcd292f..06c7600487 100644
Binary files a/build/classes/server/maps/MapleMap$5.class and b/build/classes/server/maps/MapleMap$5.class differ
diff --git a/build/classes/server/maps/MapleMap$6.class b/build/classes/server/maps/MapleMap$6.class
index 92de3ff904..edb6cc7d67 100644
Binary files a/build/classes/server/maps/MapleMap$6.class and b/build/classes/server/maps/MapleMap$6.class differ
diff --git a/build/classes/server/maps/MapleMap$7.class b/build/classes/server/maps/MapleMap$7.class
index df8446ac8b..b297c9dae6 100644
Binary files a/build/classes/server/maps/MapleMap$7.class and b/build/classes/server/maps/MapleMap$7.class differ
diff --git a/build/classes/server/maps/MapleMap$8.class b/build/classes/server/maps/MapleMap$8.class
index 1ace036bd7..9d01a1ba7a 100644
Binary files a/build/classes/server/maps/MapleMap$8.class and b/build/classes/server/maps/MapleMap$8.class differ
diff --git a/build/classes/server/maps/MapleMap$9.class b/build/classes/server/maps/MapleMap$9.class
index c705ead7b6..1c4503ebe9 100644
Binary files a/build/classes/server/maps/MapleMap$9.class and b/build/classes/server/maps/MapleMap$9.class differ
diff --git a/build/classes/server/maps/MapleMap$ActivateItemReactor$1.class b/build/classes/server/maps/MapleMap$ActivateItemReactor$1.class
index f4d69b6827..c000c48f1d 100644
Binary files a/build/classes/server/maps/MapleMap$ActivateItemReactor$1.class and b/build/classes/server/maps/MapleMap$ActivateItemReactor$1.class differ
diff --git a/build/classes/server/maps/MapleMap$ActivateItemReactor.class b/build/classes/server/maps/MapleMap$ActivateItemReactor.class
index 9f8bdbeaf2..49a530c3e5 100644
Binary files a/build/classes/server/maps/MapleMap$ActivateItemReactor.class and b/build/classes/server/maps/MapleMap$ActivateItemReactor.class differ
diff --git a/build/classes/server/maps/MapleMap$ExpireMapItemJob.class b/build/classes/server/maps/MapleMap$ExpireMapItemJob.class
index 069f846fea..bfb6ced6d5 100644
Binary files a/build/classes/server/maps/MapleMap$ExpireMapItemJob.class and b/build/classes/server/maps/MapleMap$ExpireMapItemJob.class differ
diff --git a/build/classes/server/maps/MapleMap.class b/build/classes/server/maps/MapleMap.class
index 2ada2f8c4f..16f27e5ff5 100644
Binary files a/build/classes/server/maps/MapleMap.class and b/build/classes/server/maps/MapleMap.class differ
diff --git a/build/classes/server/maps/MapleReactor$1.class b/build/classes/server/maps/MapleReactor$1.class
index 2a85c8e6be..c8635e4b7e 100644
Binary files a/build/classes/server/maps/MapleReactor$1.class and b/build/classes/server/maps/MapleReactor$1.class differ
diff --git a/build/classes/server/maps/MapleReactor.class b/build/classes/server/maps/MapleReactor.class
index 2205a8cec3..306e9ababc 100644
Binary files a/build/classes/server/maps/MapleReactor.class and b/build/classes/server/maps/MapleReactor.class differ
diff --git a/dist/MapleSolaxia.jar b/dist/MapleSolaxia.jar
index 50a528771e..b0407b9669 100644
Binary files a/dist/MapleSolaxia.jar and b/dist/MapleSolaxia.jar differ
diff --git a/feature_list.txt b/feature_list.txt
index 40eb5f935b..dd89a5d819 100644
--- a/feature_list.txt
+++ b/feature_list.txt
@@ -4,22 +4,27 @@ Ronan - Freelance Developer
Vcoc - Freelance Developer
---------------------------
-Working features:
+Feature list:
---------------------------
PQs/Quests:
* HPQ/KPQ/LPQ/LMPQ/OPQ/EllinPQ/PiratePQ 100%
-* BalrogPQ semi-functional
+* GuildPQ 100% + Guild queue and multi-lobby systems available.
* Brand-new PQ: Boss Rush PQ 100%
+* BalrogPQ semi-functional
* Doll house quest 100%
* Loads of quests have been patched.
Player Social Network:
-* Guild and Alliance system.
-* Lobby system - Limited multiple PQ instances on same channel.
+* Guild and Alliance system fully functional.
Cash:
* EXP/DROP/Cosmetic Coupons 100%
+* Great deal of cash items functional.
+
+PQ potentials:
+* Lobby system - Limited multiple PQ instances on same channel.
+* Guild queue system - Guilds can register themselves on a queue for GPQ.
Server potentials:
* Multi-worlds 100%
diff --git a/mychanges_ptbr.txt b/mychanges_ptbr.txt
index 147833c2e3..ac28d947fe 100644
--- a/mychanges_ptbr.txt
+++ b/mychanges_ptbr.txt
@@ -292,25 +292,32 @@ Diversos ajustes finos nos comandos existentes.
Adicionados novos comandos: proitem, seteqstats, buffme, buffmap.
Vários ajustes finos em alguns comandos.
-05 Junho 2016,
+05 Junho 2017,
Novo NPC Skillbook announcer: Abdula.
Consertada a função que retorna se uma skill pertence ou não à árvore de habilidades do jogador.
-06 Junho 2016,
+06 Junho 2017,
Corrigido command empowerme.
Corrigidos exploits relacionados a algumas das skills do empowerme.
Corrigido possivel loop infinito no sistema de EXP.
-07 - 10 Junho 2016,
+07 - 10 Junho 2017,
Implementação da OPQ.
-11 Junho 2016,
+11 Junho 2017,
Correção de alguns bugs vindos com o commit da OPQ.
Incrementada a documentação referente aos métodos usados nos scripts de eventos.
-12 Junho 2016,
+12 Junho 2017,
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,
+13 Junho 2017,
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
+Implementação de fila de espera para Guilds na GPQ (funciona em harmonia com o sistema de lobbys).
+
+14 Junho 2017,
+Correção de bug envolvendo abuso de conversa com NPC logo após o sinal de dispose, ocasionando frequentemente crashes no cliente.
+
+15 - 17 Junho 2017,
+Correção de bug na função de atribuição de EXP, que não permitia receber valores negativos de EXP.
+Implementação da GPQ.
\ No newline at end of file
diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml
index 22548efa3b..a0f2f44b10 100644
--- a/nbproject/private/private.xml
+++ b/nbproject/private/private.xml
@@ -13,13 +13,14 @@
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/scripts/npc/9040009.js
+ file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/ChangeMapHandler.java
+ file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/9040006.js
+ file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/reactor/2006001.js
+ file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/reactor/9208009.js
+ file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/constants/ServerConstants.java
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
+ file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/9040001.js
diff --git a/scripts/event/0_EXAMPLE.js b/scripts/event/0_EXAMPLE.js
index a6643b47b3..3a1ca2d447 100644
--- a/scripts/event/0_EXAMPLE.js
+++ b/scripts/event/0_EXAMPLE.js
@@ -10,7 +10,7 @@ var clearMap; // Upon event clearing, players may be moved to
var minMapId; // Event takes place inside these map id interval. Players found out is instantly dropped from the event.
var maxMapId;
-var eventTime; // Max time alloted for the event, in minutes.
+var eventTime; // Max time allotted for the event, in minutes.
var lobbyRange = [0, 0]; // Range of concurrent lobbies (min range is 0, max range is 7).
diff --git a/scripts/event/EllinPQ.js b/scripts/event/EllinPQ.js
index 8add53530d..e88e679c79 100644
--- a/scripts/event/EllinPQ.js
+++ b/scripts/event/EllinPQ.js
@@ -96,7 +96,7 @@ function setup(level, lobbyid) {
function afterSetup(eim) {}
function respawnStg2(eim) {
- if(!eim.getMapInstance(930000200).getAllPlayer().isEmpty()) eim.getMapInstance(930000200).instanceMapRespawn();
+ if(!eim.getMapInstance(930000200).getPlayers().isEmpty()) eim.getMapInstance(930000200).instanceMapRespawn();
eim.schedule("respawnStg2", 4 * 1000);
}
diff --git a/scripts/event/GuildQuest.js b/scripts/event/GuildQuest.js
index db15e75c8e..5eed997ff6 100644
--- a/scripts/event/GuildQuest.js
+++ b/scripts/event/GuildQuest.js
@@ -30,13 +30,14 @@ var minLevel = 1, maxLevel = 200;
var entryMap = 990000000;
var exitMap = 990001100;
var recruitMap = 101030104;
-var clearMap = 990001101;
+var clearMap = 990001000;
var minMapId = 990000000;
var maxMapId = 990001101;
-var waitTime = 3;
+var waitTime = 3; // 3 minutes
var eventTime = 90; // 90 minutes
+var bonusTime = 0.5; // 30 seconds
var lobbyRange = [0, 0];
@@ -119,7 +120,7 @@ function setup(level, lobbyid) {
eim.setProperty("guild", 0);
eim.setProperty("canJoin", 1);
- eim.setProperty("statusStg1", -1);
+ eim.setProperty("canRevive", 0);
eim.getInstanceMap(990000000).resetPQ(level);
eim.getInstanceMap(990000100).resetPQ(level);
@@ -175,7 +176,9 @@ function isTeamAllJobs(eim) {
*/
function afterSetup(eim) {
- eim.setProperty("guild", "" + eim.getLeader().getGuildId());
+ var leader = em.getChannelServer().getPlayerStorage().getCharacterById(eim.getLeaderId());
+ if(leader != null)
+ eim.setProperty("guild", "" + leader.getGuildId());
}
function respawnStages(eim) {}
@@ -189,16 +192,20 @@ function playerEntry(eim, player) {
}
function scheduledTimeout(eim) {
- if(eim.getIntProperty("canJoin") == 1) {
- eim.setProperty("canJoin", 0);
-
- if(eim.checkEventTeamLacking(true, minPlayers)) {
- end(eim);
- } else {
- eim.startEventTimer(eventTime * 60000);
- }
+ if(eim.isEventCleared()) {
+ eim.warpEventTeam(990001100);
} else {
- end(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);
+ }
}
}
@@ -222,15 +229,33 @@ function changedMap(eim, player, mapid) {
function changedLeader(eim, leader) {}
-function playerDead(eim, player) {}
+function playerDead(eim, player) {
+ if(player.getMapId() == 990000900) {
+ if(player.getMap().countAlivePlayers() == 0 && player.getMap().countMonsters() > 0) {
+ end(eim);
+ }
+ }
+}
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);
+ if(eim.getIntProperty("canRevive") == 0) {
+ if (eim.isEventTeamLackingNow(true, minPlayers, player) && eim.getIntProperty("canJoin") == 0) {
+ eim.unregisterPlayer(player);
+ player.setHp(50);
+ player.changeMap(exitMap);
+
+ end(eim);
+ }
+ else {
+ eim.unregisterPlayer(player);
+ player.setHp(50);
+ player.changeMap(exitMap);
+ }
+
+ return false;
}
- else
- eim.unregisterPlayer(player);
+
+ return true;
}
function playerDisconnected(eim, player) {
@@ -267,6 +292,9 @@ function giveRandomEventReward(eim, player) {
function clearPQ(eim) {
eim.stopEventTimer();
eim.setEventCleared();
+
+ eim.warpEventTeam(clearMap);
+ eim.startEventTimer(bonusTime * 60000);
}
function monsterKilled(mob, eim) {}
diff --git a/scripts/npc/2013001.js b/scripts/npc/2013001.js
index 83c00da76a..82176d693b 100644
--- a/scripts/npc/2013001.js
+++ b/scripts/npc/2013001.js
@@ -147,12 +147,12 @@ function action(mode, type, selection) {
var players = Array();
var total = 0;
for (var i = 0; i < 3; i++) {
- var z = cm.getMap().getNumPlayersItemsInArea(i);
+ var z = cm.getMap().getNumPlayersInArea(i);
players.push(z);
total += z;
}
if (total != 3) {
- cm.sendOk("There needs to be 3 players OR items on the platforms.");
+ cm.sendOk("There needs to be exactly 3 players on these platforms.");
} else {
var num_correct = 0;
for (var i = 0; i < 3; i++) {
diff --git a/scripts/npc/2040035.js b/scripts/npc/2040035.js
index 15006c97f0..7471ac6f3e 100644
--- a/scripts/npc/2040035.js
+++ b/scripts/npc/2040035.js
@@ -45,7 +45,7 @@ function action(mode, type, selection) {
var eim = cm.getEventInstance();
if(!eim.giveEventReward(cm.getPlayer())) {
- cm.sendNext("It seems you don't have a free slot in either your #rEquip#k, #rUse#k or #rEtc#k inventories. Please make room and try again.");
+ cm.sendNext("It seems you don't have a free slot in either your #rEquip#k, #rUse#k or #rEtc#k inventories. Please make some room and try again.");
} else {
cm.warp(221024500);
}
diff --git a/scripts/npc/2080000.js b/scripts/npc/2080000.js
index f2128e4ac3..6f15111272 100644
--- a/scripts/npc/2080000.js
+++ b/scripts/npc/2080000.js
@@ -68,7 +68,7 @@ function action(mode, type, selection) {
cm.sendNext("A stimulator is a special potion that I can add into the process of creating certain items. It gives it stats as though it had dropped from a monster. However, it is possible to have no change, and it is also possible for the item to be below average. There's also a 10% chance of not getting any item when using a stimulator, so please choose wisely.")
cm.dispose();
} else if (selectedType == 1){ //warrior weapon
- var selStr = "Very well, then which Warrior weapon shall recieve a dragon's power?#b";
+ var selStr = "Very well, then which Warrior weapon shall receive a dragon's power?#b";
var weapon = new Array ("Dragon Carbella#k - Lv. 110 One-Handed Sword#b","Dragon Axe#k - Lv. 110 One-Handed Axe#b","Dragon Mace#k - Lv. 110 One-Handed BW#b","Dragon Claymore#k - Lv. 110 Two-Handed Sword#b","Dragon Battle Axe#k - Lv. 110 Two-Handed Axe#b","Dragon Flame#k - Lv. 110 Two-Handed BW#b",
"Dragon Faltizan#k - Lv. 110 Spear#b","Dragon Chelbird#k - Lv. 110 Polearm#b");
for (var i = 0; i < weapon.length; i++){
@@ -76,28 +76,28 @@ function action(mode, type, selection) {
}
cm.sendSimple(selStr);
} else if (selectedType == 2){ //bowman weapon
- var selStr = "Very well, then which Bowman weapon shall recieve a dragon's power?#b";
+ var selStr = "Very well, then which Bowman weapon shall receive a dragon's power?#b";
var weapon = new Array ("Dragon Shiner Bow#k - Lv. 110 Bow#b","Dragon Shiner Cross#k - Lv. 110 Crossbow#b");
for (var i = 0; i < weapon.length; i++){
selStr += "\r\n#L" + i + "# " + weapon[i] + "#l";
}
cm.sendSimple(selStr);
} else if (selectedType == 3){ //magician weapon
- var selStr = "Very well, then which Magician weapon shall recieve a dragon's power?#b";
+ var selStr = "Very well, then which Magician weapon shall receive a dragon's power?#b";
var weapon = new Array ("Dragon Wand#k - Lv. 108 Wand#b","Dragon Staff#k - Lv. 110 Staff#b");
for (var i = 0; i < weapon.length; i++){
selStr += "\r\n#L" + i + "# " + weapon[i] + "#l";
}
cm.sendSimple(selStr);
} else if (selectedType == 4){ //thief weapon
- var selStr = "Very well, then which Thief weapon shall recieve a dragon's power?#b";
+ var selStr = "Very well, then which Thief weapon shall receive a dragon's power?#b";
var weapon = new Array ("Dragon Kanzir#k - Lv. 110 STR Dagger#b","Dragon Kreda#k - Lv. 110 LUK Dagger#b","Dragon Green Sleve#k - Lv. 110 Claw#b");
for (var i = 0; i < weapon.length; i++){
selStr += "\r\n#L" + i + "# " + weapon[i] + "#l";
}
cm.sendSimple(selStr);
} else if (selectedType == 5){ //pirate weapon
- var selStr = "Very well, then which Pirate weapon shall recieve a dragon's power?#b";
+ var selStr = "Very well, then which Pirate weapon shall receive a dragon's power?#b";
var weapon = new Array ("Dragon Slash Claw#k - Lv. 110 Knuckle#b","Dragonfire Revolver#k - Lv. 110 Gun#b");
for (var i = 0; i < weapon.length; i++){
selStr += "\r\n#L" + i + "# " + weapon[i] + "#l";
diff --git a/scripts/npc/9040000.js b/scripts/npc/9040000.js
index 765f988852..8736065a67 100644
--- a/scripts/npc/9040000.js
+++ b/scripts/npc/9040000.js
@@ -68,7 +68,7 @@ function action(mode, type, selection) {
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.");
+ cm.sendOk("Your guild is not currently on strategy time on this channel. Check again if your guild is currently planning a Guild Quest or, if so, the channel they are allotted on.");
} else {
if(cm.isLeader()) {
em.getEligibleParty(cm.getParty());
@@ -83,16 +83,22 @@ function action(mode, type, selection) {
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.");
+ var reqStr = "";
+ reqStr += "\r\n\r\n Team requirements:\r\n\r\n";
+ reqStr += " - 1 team member #rbelow or equal level 30#k.\r\n";
+ reqStr += " - 1 team member who is a #rThief with Dark Sight#k skill and #rmaxed Haste#k.\r\n";
+ reqStr += " - 1 team member who is a Magician with #rmaxed Teleport#k.\r\n";
+ reqStr += " - 1 team member who is a #rlong ranged attacker#k like Bowman, Assassin, or Gunslinger.\r\n";
+ reqStr += " - 1 team member with #rgood jumping skills#k like Assassin with maxed Flash Jump or Gunslinger with Wings.\r\n";
+
+ 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." + reqStr);
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.");
- }
+ cm.sendOk("Your guild has been registered successfully. A message will pop on your chat keeping your guild aware about the registration status.\r\n\r\nNow, #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 {
diff --git a/scripts/npc/9040001.js b/scripts/npc/9040001.js
index 8783cf5a5f..6ae76a4b3e 100644
--- a/scripts/npc/9040001.js
+++ b/scripts/npc/9040001.js
@@ -19,20 +19,48 @@
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
+/*
+@ Author : Ronan
+@
+@ NPC = Nuris (9040001)
+@ Map = Sharenian - Returning Path
+@ NPC MapId = 990001100
+@ NPC Exit-MapId = 101030104
+@
+ */
-/*
-* @Author Lerk
-*
-* Nuris, Sharenian: Returning Path (990001100)
-*
-* Exit of Guild Quest
-*/
-
-var GQItems = new Array(1032033, 4001024, 4001025, 4001026, 4001027, 4001028, 4001029, 4001030, 4001031, 4001032, 4001033, 4001034, 4001035, 4001037);
+var status;
function start() {
- for (var i = 0; i < GQItems.length; i++)
- cm.removeAll(GQItems[i]);
- cm.warp(101030104);
- cm.dispose();
+ status = -1;
+ action(1,0,0);
+}
+
+function action(mode, type, selection){
+ if (mode == 1)
+ status++;
+ else {
+ cm.dispose();
+ return;
+ }
+
+ if (status == 0) {
+ var outText = "It seems you have finished exploring Sharenian Keep, yes? Are you going to return to the recruitment map now?";
+ cm.sendYesNo(outText);
+ } else if (mode == 1) {
+ var eim = cm.getEventInstance();
+
+ if(eim != null && eim.isEventCleared()) {
+ if(!eim.giveEventReward(cm.getPlayer())) {
+ cm.sendNext("It seems you don't have a free slot in either your #rEquip#k, #rUse#k or #rEtc#k inventories. Please make some room first.");
+ } else {
+ cm.warp(101030104);
+ }
+
+ cm.dispose();
+ } else {
+ cm.warp(101030104);
+ cm.dispose();
+ }
+ }
}
\ No newline at end of file
diff --git a/scripts/npc/9040003.js b/scripts/npc/9040003.js
index 1a7e5433e9..55f2822ecb 100644
--- a/scripts/npc/9040003.js
+++ b/scripts/npc/9040003.js
@@ -20,13 +20,20 @@
along with this program. If not, see .
*/
/*
- * @Author TheRamon
+ * @Author TheRamon, Ronan
*
* Sharen III's Soul, Sharenian: Sharen III's Grave (990000700)
*
* Guild Quest - end of stage 4
*/
+function clearStage(stage, eim) {
+ eim.setProperty("stage" + stage + "clear", "true");
+ eim.showClearEffect(true);
+
+ eim.giveEventPlayersStageReward(stage);
+}
+
var status = 0;
function start() {
status = -1;
@@ -41,39 +48,30 @@ function action(mode, type, selection) {
status++;
else
cm.dispose();
+
+ var eim = cm.getPlayer().getEventInstance();
+
+ if (eim.getProperty("stage4clear") != null && eim.getProperty("stage4clear").equals("true")) {
+ cm.sendOk("After what I thought would be an immortal sleep, I have finally found someone that will save Sharenian. I can truly rest in peace now.");
+ cm.dispose();
+ return;
+ }
+
if (status == 0) {
- if (cm.getPlayer().getEventInstance().getProperty("leader").equals(cm.getPlayer().getName())) {
- if (cm.getPlayer().getEventInstance().getProperty("stage4clear") != null && cm.getPlayer().getEventInstance().getProperty("stage4clear").equals("true"))
- {
- cm.sendOk("After what I thought would be an immortal sleep, I have finally found someone that will save Sharenian. I can truly rest in peace now.");
- cm.dispose();
- }
- else {
- var prev = cm.getPlayer().getEventInstance().setProperty("stage4clear","true",true);
- if (prev == null) {
- cm.sendNext("After what I thought would be an immortal sleep, I have finally found someone that will save Sharenian. This old man will now pave the way for you to finish the quest." + mode);
- }
- else {//if not null, was set before, and Gp already gained
- cm.sendOk("After what I thought would be an immortal sleep, I have finally found someone that will save Sharenian. I can truly rest in peace now.");
- cm.dispose();
- }
- }
+ if (cm.isEventLeader()) {
+ cm.sendNext("After what I thought would be an immortal sleep, I have finally found someone that will save Sharenian. This old man will now pave the way for you to finish the quest.");
+
+ clearStage(4, eim);
+ cm.getGuild().gainGP(30);
+ cm.getPlayer().getMap().getReactorByName("ghostgate").forceHitReactor(1);
+
+ cm.dispose();
}
else
{
- if (cm.getPlayer().getEventInstance().getProperty("stage4clear") != null && cm.getPlayer().getEventInstance().getProperty("stage4clear").equals("true"))
- cm.sendOk("After what I thought would be an immortal sleep, I have finally found someone that will save Sharenian. I can truly rest in peace now.");
- else
- cm.sendOk("I need the leader of your party to speak with me, nobody else.");
+ cm.sendOk("I need the leader of your party to speak with me, nobody else.");
cm.dispose();
}
}
- else if (status == 1) {
- cm.getGuild().gainGP(30);
- cm.getPlayer().getMap().getReactorByName("ghostgate").hitReactor(cm.getClient());
- cm.showEffect("quest/party/clear");
- cm.playSound("Party1/Clear");
- cm.dispose();
- }
}
}
\ No newline at end of file
diff --git a/scripts/npc/9040005.js b/scripts/npc/9040005.js
index 248998daee..d01b2983cb 100644
--- a/scripts/npc/9040005.js
+++ b/scripts/npc/9040005.js
@@ -25,10 +25,7 @@ function start() {
function action(mode, type, selection) {
if(mode == 1) {
- var eim = cm.getPlayer().getEventInstance();
- if(eim != null) {
- eim.removePlayer(cm.getPlayer());
- }
+ cm.warp(990001100);
}
cm.dispose();
}
diff --git a/scripts/npc/9040006.js b/scripts/npc/9040006.js
index d213414d24..d45433c04e 100644
--- a/scripts/npc/9040006.js
+++ b/scripts/npc/9040006.js
@@ -1,254 +1,209 @@
-/* @Author Lerk
+/* @Author Lerk, Ronan
*
* Guardian Statue - Sharenian: Fountain of the Wiseman (990000500)
*
* Guild Quest Stage 3
*/
-
+
importPackage(Packages.tools);
+function clearStage(stage, eim) {
+ eim.setProperty("stage" + stage + "clear", "true");
+ eim.showClearEffect(true);
+
+ eim.giveEventPlayersStageReward(stage);
+}
+
function start() {
- //everything can be done in one status, so let's do it here.
+ if (cm.getPlayer().getMap().getReactorByName("watergate").getState() > 0){
+ cm.sendOk("Excellent work. You may proceed to the next stage.");
+ cm.dispose();
+ return;
+ }
+
var eim = cm.getPlayer().getEventInstance();
if (eim == null) {
cm.warp(990001100);
} else {
- if (eim.getProperty("leader").equals(cm.getName())) {
- if (cm.getPlayer().getMap().getReactorByName("watergate").getState() > 0){
- cm.sendOk("You may proceed.");
- } else {
- var currentCombo = eim.getProperty("stage3combo");
- if (currentCombo == null || currentCombo.equals("reset")) {
- var newCombo = makeCombo();
- eim.setProperty("stage3combo",newCombo);
- //cm.playerMessage("Debug: " + newCombo);
- eim.setProperty("stage3attempt","1");
- cm.sendOk("This fountain guards the secret passage to the throne room. Offer items in the area to the vassals to proceed. The vassals shall tell you whether your offerings are accepted, and if not, which vassals are displeased. You have seven attempts. Good luck.")
- } else {
- var attempt = parseInt(eim.getProperty("stage3attempt"));
- var combo = parseInt(currentCombo);
- var guess = getGroundItems();
- if (guess != null) {
- if (combo == guess) {
- cm.getPlayer().getMap().getReactorByName("watergate").hitReactor(cm.getClient());
- cm.sendOk("You may proceed.");
-
- cm.getPlayer().getMap().broadcastMessage(MaplePacketCreator.showEffect("quest/party/clear"));
- cm.getPlayer().getMap().broadcastMessage(MaplePacketCreator.playSound("Party1/Clear"));
- var prev = eim.getProperty("stage3clear");
- eim.setProperty("stage3clear","true");
- if (prev == null) {
- cm.getPlayer().getGuild().gainGP(100);
- }
- } else {
- if (attempt < 7) {
- //cm.playerMessage("Combo : " + combo);
- //cm.playerMessage("Guess : " + guess);
- var parsedCombo = parsePattern(combo);
- var parsedGuess = parsePattern(guess);
- var results = compare(parsedCombo, parsedGuess);
- var string = "";
- //cm.playerMessage("Results - Correct: " + results[0] + " | Incorrect: " + results[1] + " | Unknown: " + results[2]);
- if (results[0] != 0) {
- if (results[0] == 1) {
- string += "1 vassal is pleased with their offering.\r\n";
- } else {
- string += results[0] + " vassals are pleased with their offerings.\r\n";
- }
- }
- if (results[1] != 0) {
- if (results[1] == 1) {
- string += "1 vassal has recieved an incorrect offering.\r\n";
- } else {
- string += results[1] + " vassals have recieved incorrect offerings.\r\n";
- }
- }
- if (results[2] != 0) {
- if (results[2] == 1) {
- string += "1 vassal has recieved an unknown offering.\r\n";
- } else {
- string += results[2] + " vassals have recieved unknown offerings.\r\n";
- }
- }
- string += "This is your ";
- switch (attempt) {
- case 1:
- string += "1st";
- break;
- case 2:
- string += "2nd";
- break;
- case 3:
- string += "3rd";
- break;
- default:
- string += attempt + "th";
- break;
- }
- string += " attempt.";
+ if (cm.isEventLeader()) {
+ var currentCombo = eim.getProperty("stage3combo");
+ if (currentCombo == null || currentCombo.equals("reset")) {
+ var newCombo = makeCombo();
+ eim.setProperty("stage3combo",newCombo);
+ //cm.playerMessage("Debug: " + newCombo);
+ eim.setProperty("stage3attempt","1");
+ cm.sendOk("This fountain guards the secret passage to the throne room. Offer items in the area to the vassals to proceed. The vassals shall tell you whether your offerings are accepted, and if not, which vassals are displeased. You have seven attempts. Good luck.");
+ } else {
+ var attempt = parseInt(eim.getProperty("stage3attempt"));
+ var combo = parseInt(currentCombo);
+ var guess = getGroundItems();
+ if (guess != null) {
+ if (combo == guess) {
+ cm.getPlayer().getMap().getReactorByName("watergate").forceHitReactor(1);
+ clearStage(3, eim);
+ cm.getGuild().gainGP(25);
+
+ removeGroundItems();
+ cm.sendOk("Excellent work. You may proceed to the next stage.");
+ } else {
+ if (attempt < 7) {
+ var comboItems = [0, 0, 0, 0];
+ var guessItems = [0, 0, 0, 0];
+
+ var correct = 0, incorrect, unknown = 0;
+ for(var i = 0; i < 4; i++) {
+ var guessIdx = Math.floor(guess / Math.pow(10, i)) % 10;
+ var comboIdx = Math.floor(combo / Math.pow(10, i)) % 10;
+
+ if(guessIdx == comboIdx) correct++;
+ else {
+ (guessItems[guessIdx])++;
+ (comboItems[comboIdx])++;
+ }
+ }
+
+ for(var i = 0; i < 4; i++) {
+ var diff = guessItems[i] - comboItems[i];
+ if(diff > 0) unknown += diff;
+ }
+
+ incorrect = 4 - correct - unknown;
+
+ var string = "";
+ //cm.playerMessage("Results - Correct: " + results[0] + " | Incorrect: " + results[1] + " | Unknown: " + results[2]);
+ if (correct != 0) {
+ if (correct == 1) {
+ string += "1 vassal is pleased with their offering.\r\n";
+ } else {
+ string += correct + " vassals are pleased with their offerings.\r\n";
+ }
+ }
+ if (incorrect != 0) {
+ if (incorrect == 1) {
+ string += "1 vassal has received an incorrect offering.\r\n";
+ } else {
+ string += incorrect + " vassals have received incorrect offerings.\r\n";
+ }
+ }
+ if (unknown != 0) {
+ if (unknown == 1) {
+ string += "1 vassal has received an unknown offering.\r\n";
+ } else {
+ string += unknown + " vassals have received unknown offerings.\r\n";
+ }
+ }
+ string += "This is your ";
+ switch (attempt) {
+ case 1:
+ string += "1st";
+ break;
+ case 2:
+ string += "2nd";
+ break;
+ case 3:
+ string += "3rd";
+ break;
+ default:
+ string += attempt + "th";
+ break;
+ }
+ string += " attempt.";
- //spawn one black and one myst knight
- spawnMob(9300036, -350, 150, cm.getPlayer().getMap());
- spawnMob(9300037, 400, 150, cm.getPlayer().getMap());
+ //spawn one black and one myst knight
+ spawnMob(9300036, -350, 150, cm.getPlayer().getMap());
+ spawnMob(9300037, 400, 150, cm.getPlayer().getMap());
- cm.sendOk(string);
- eim.setProperty("stage3attempt",attempt + 1);
- } else {
- //reset the combo and mass spawn monsters
- eim.setProperty("stage3combo","reset");
- cm.sendOk("You have failed the test. Please compose yourselves and try again later.");
+ cm.sendOk(string);
+ eim.setProperty("stage3attempt",attempt + 1);
+ } else {
+ //reset the combo and mass spawn monsters
+ eim.setProperty("stage3combo","reset");
+ cm.sendOk("You have failed the test. Please compose yourselves and try again later.");
- for (var i = 0; i < 6; i++) {
- //keep getting new monsters, lest we spawn the same monster five times o.o!
- spawnMob(9300036, randX(), 150, cm.getPlayer().getMap());
- spawnMob(9300037, randX(), 150, cm.getPlayer().getMap());
- }
- }
- }
- } else {
- cm.sendOk("Please make sure your attempt is properly set in front of the vassals and talk to me again.");
- }
- }
- }
- } else {
- cm.sendOk("Please have your leader speak to me.");
- }
+ for (var i = 0; i < 6; i++) {
+ //keep getting new monsters, lest we spawn the same monster five times o.o!
+ spawnMob(9300036, randX(), 150, cm.getPlayer().getMap());
+ spawnMob(9300037, randX(), 150, cm.getPlayer().getMap());
+ }
+ }
+
+ eim.showWrongEffect();
+ }
+ } else {
+ cm.sendOk("Please make sure your attempt is properly set in front of the vassals and talk to me again.");
+ }
+ }
+ } else {
+ cm.sendOk("Please have your leader speak to me.");
+ }
}
+
cm.dispose();
}
-function action(mode, type, selection) {
-}
+function action(mode, type, selection) {}
function makeCombo() {
var combo = 0;
for (var i = 0; i < 4; i++) {
- combo += Math.floor(Math.random() * 4) * Math.pow(10, i);
+ combo += (Math.floor(Math.random() * 4) * Math.pow(10, i));
}
return combo;
}
-//check the items on ground and convert into an applicable string; null if items aren't proper
-function getGroundItems() {
- var items = cm.getPlayer().getMap().getMapObjectsInRange(cm.getPlayer().getPosition(), Packages.java.lang.Double.POSITIVE_INFINITY, Packages.java.util.Arrays.asList([Packages.server.maps.MapleMapObjectType.ITEM]));
- var itemInArea = new Array(-1, -1, -1, -1);
-
- if (items.size() != 4) {
- cm.getPlayer().dropMessage("There are too many items in the map. Please remove some");
- return null;
- }
-
- var iter = items.iterator();
+function getRawItems() {
+ var mapItems = cm.getPlayer().getMap().getItems();
+ var rawItems = new Array();
+
+ var iter = mapItems.iterator();
while (iter.hasNext()) {
var item = iter.next();
var id = item.getItem().getItemId();
if (id < 4001027 || id > 4001030) {
- cm.getPlayer().dropMessage("Some items in the map are not part of the 4 items needed");
- return null;
+ continue;
} else {
- //check item location
- for (var i = 0; i < 4; i++) {
- if (cm.getPlayer().getMap().getArea(i).contains(item.getPosition())) {
- itemInArea[i] = id - 4001027;
- //cm.getPlayer().dropMessage("Item in area "+i+": " + id);
- break;
- }
- }
+ rawItems.push(item);
}
}
+
+ return rawItems;
+}
+
+//check the items on ground and convert into an applicable string; null if items aren't proper
+function getGroundItems() {
+ var itemInArea = new Array(-1, -1, -1, -1);
+
+ var rawItems = getRawItems();
+ if (rawItems.length != 4) return null;
+
+ for(var j = 0; j < rawItems.length; j++) {
+ var item = rawItems[j];
+ var id = item.getItem().getItemId();
+
+ //check item location
+ for (var i = 0; i < 4; i++) {
+ if (cm.getPlayer().getMap().getArea(i).contains(item.getPosition())) {
+ itemInArea[i] = id - 4001027;
+ break;
+ }
+ }
+ }
//guaranteed four items that are part of the stage 3 item set by this point, check to see if each area has an item
- if (itemInArea[0] == -1 || itemInArea[1] == -1 || itemInArea[2] == -1 || itemInArea[3] == -1) {
- cm.getPlayer().dropMessage("Please place these in correct positions: " + (itemInArea[0] == -1 ? "Statue 1, " : "") + (itemInArea[1] == -1 ? "Statue 2, " : "") + (itemInArea[2] == -1 ? "Statue 3, " : "") + (itemInArea[3] == -1 ? "Statue 4. " : ""));
- /* for (var i = 0; i < 4; i++) {
- cm.getPlayer().dropMessage("Item in area "+i+": " + itemInArea[i]);
- }*/
+ if (itemInArea[0] == -1 || itemInArea[1] == -1 || itemInArea[2] == -1 || itemInArea[3] == -1)
return null;
- }
- return (itemInArea[0] * 1000 + itemInArea[1] * 100 + itemInArea[2] * 10 + itemInArea[3]);
+ return ((itemInArea[0] * 1000) + (itemInArea[1] * 100) + (itemInArea[2] * 10) + itemInArea[3]);
}
-//convert an integer for answer or guess into int array for comparison
-function parsePattern(pattern) {
- var tempPattern = pattern;
- var items = new Array(-1, -1, -1, -1);
- for (var i = 0; i < 4; i++) {
- items[i] = Math.floor(tempPattern / Math.pow(10, 3-i));
- tempPattern = tempPattern % Math.pow(10, 3-i);
+function removeGroundItems() {
+ var map = cm.getMap();
+ var rawItems = getRawItems();
+ for(var j = 0; j < rawItems.length; j++) {
+ map.makeDisappearItemFromMap(rawItems[j]);
}
- return items;
-}
-
-// compare two int arrays for the puzzle
-function compare(answer, guess) {
- var correct = 0;
- var incorrect = 0;
- /*var debugAnswer = "Combo : ";
- var debugGuess = "Guess : ";
-
- for (var d = 0; d < answer.length; d++) {
- debugAnswer += answer[d] + " ";
- debugGuess += guess[d] + " ";
- }
-
- cm.getPlayer().dropMessage(debugAnswer);
- cm.getPlayer().dropMessage(debugGuess);*/
-
- for (var i = 0; i < answer.length; i) {
- if (answer[i] == guess[i]) {
- correct++;
- //cm.getPlayer().dropMessage("Item match : " + answer[i]);
-
- //pop the answer/guess at i
- if (i != answer.length - 1) {
- answer[i] = answer[answer.length - 1];
- guess[i] = guess[guess.length - 1];
- }
-
- answer.pop();
- guess.pop();
-
- /*/debugAnswer = "Combo : ";
- debugGuess = "Guess : ";
-
- for (var d = 0; d < answer.length; d++) {
- debugAnswer += answer[d] + " ";
- debugGuess += guess[d] + " ";
- }
-
- cm.getPlayer().dropMessage(debugAnswer);
- cm.getPlayer().dropMessage(debugGuess);*/
- }
- else {
- i++;
- }
- }
-
- //check remaining answers for "incorrect": correct item in incorrect position
- var answerItems = new Array(0, 0, 0, 0);
- var guessItems = new Array(0, 0, 0, 0);
-
- for (var j = 0; j < answer.length; j++) {
- var aItem = answer[j];
- var gItem = guess[j]
- answerItems[aItem]++;
- guessItems[gItem]++;
- }
-
- /*for (var d = 0; d < answer.length; d++) {
- cm.getPlayer().dropMessage("Item " + d + " in combo: " + answerItems[d] + " | in guess: " + guessItems[d]);
- }*/
-
- for (var k = 0; k < answerItems.length; k++) {
- var inc = Math.min(answerItems[k], guessItems[k]);
- //cm.getPlayer().dropMessage("Incorrect for item " + k + ": " + inc);
- incorrect += inc;
- }
-
- return new Array(correct, incorrect, (4 - correct - incorrect));
}
//for mass spawn
diff --git a/scripts/npc/9040009.js b/scripts/npc/9040009.js
index 2cb37ea73b..73ea28eff0 100644
--- a/scripts/npc/9040009.js
+++ b/scripts/npc/9040009.js
@@ -22,6 +22,13 @@
var status;
var stage;
+function clearStage(stage, eim) {
+ eim.setProperty("stage" + stage + "clear", "true");
+ eim.showClearEffect(true);
+
+ eim.giveEventPlayersStageReward(stage);
+}
+
function start() {
status = -1;
action (1, 0, 0);
@@ -39,79 +46,77 @@ function action(mode, type, selection) {
status++;
else
status--;
+
var eim = cm.getPlayer().getEventInstance();
if (eim == null) {
cm.warp(990001100);
} else {
- if (eim.getProperty("leader").equals(cm.getPlayer().getName())) {
- if (cm.getPlayer().getMap().getReactorByName("statuegate").getState() > 0){
- cm.sendOk("Proceed.");
- cm.dispose();
- } else {
- if (status == 0) {
- if (eim.getProperty("stage1status") == null || eim.getProperty("stage1status").equals("waiting")) {
- if (eim.getProperty("stage1phase") == null) {
- stage = 1;
- eim.setProperty("stage1phase",stage);
- } else {
- stage = parseInt(eim.getProperty("stage1phase"));
- }
- if (stage == 1) {
- cm.sendOk("In this challenge, I shall show a pattern on the statues around me. When I give the word, repeat the pattern to me to proceed.");
- }
- else {
- cm.sendOk("I shall now present a more difficult puzzle for you. Good luck.")
- }
- }
- else if (eim.getProperty("stage1status").equals("active")) {
+ if(eim.getProperty("stage1clear") == "true") {
+ cm.sendOk("Excellent work. You may proceed to the next stage.");
+ cm.dispose();
+ return;
+ }
+
+ if (cm.isEventLeader()) {
+ if (status == 0) {
+ if (eim.getProperty("stage1status") == null || eim.getProperty("stage1status").equals("waiting")) {
+ if (eim.getProperty("stage1phase") == null) {
+ stage = 1;
+ eim.setProperty("stage1phase",stage);
+ } else {
stage = parseInt(eim.getProperty("stage1phase"));
- if (eim.getProperty("stage1combo").equals(eim.getProperty("stage1guess"))) {
- if (stage == 3) {
- cm.getPlayer().getMap().getReactorByName("statuegate").hitReactor(cm.getClient());
- cm.sendOk("Excellent work. Please proceed to the next stage.");
- cm.showEffect("quest/party/clear");
- cm.playSound("Party1/Clear");
- var prev = eim.getProperty("stage1clear");
- eim.setProperty("stage1clear","true");
- if (prev == null) {
- cm.getGuild().gainGP(15);
- }
- } else {
-
- cm.sendOk("Very good. You still have more to complete, however. Talk to me again when you're ready.");
- eim.setProperty("stage1phase", stage + 1);
- cm.mapMessage(5, "You have completed part " + stage + " of the Gatekeeper Test.");
- }
-
- } else {
- cm.sendOk("You have failed this test.");
- cm.mapMessage(5, "You have failed the Gatekeeper Test.");
- eim.setProperty("stage1phase","1")
- }
- eim.setProperty("stage1status", "waiting");
- cm.dispose();
+ }
+ if (stage == 1) {
+ cm.sendOk("In this challenge, I shall show a pattern on the statues around me. When I give the word, repeat the pattern to me to proceed.");
}
else {
- cm.sendOk("Please wait.");
- cm.dispose();
+ cm.sendOk("I shall now present a more difficult puzzle for you. Good luck.");
}
}
- else if (status == 1) {
- var reactors = getReactors();
- var combo = makeCombo(reactors);
- cm.mapMessage(5, "Please wait while the combination is revealed.");
- var delay = 5000;
- for (var i = 0; i < combo.length; i++) {
- cm.getPlayer().getMap().getReactorByOid(combo[i]).delayedHitReactor(cm.getClient(), delay + 3500*i);
+ else if (eim.getProperty("stage1status").equals("active")) {
+ stage = parseInt(eim.getProperty("stage1phase"));
+
+ if (eim.getProperty("stage1combo").equals(eim.getProperty("stage1guess"))) {
+ if (stage == 3) {
+ cm.getPlayer().getMap().getReactorByName("statuegate").forceHitReactor(1);
+ clearStage(1, eim);
+ cm.getGuild().gainGP(15);
+
+ cm.sendOk("Excellent work. You may proceed to the next stage.");
+ } else {
+ cm.sendOk("Very good. You still have more to complete, however. Talk to me again when you're ready.");
+ eim.setProperty("stage1phase", stage + 1);
+ cm.mapMessage(5, "You have completed part " + stage + " of the Gatekeeper Test.");
+ }
+
+ } else {
+ eim.showWrongEffect();
+ cm.sendOk("You have failed this test.");
+ cm.mapMessage(5, "You have failed the Gatekeeper Test.");
+ eim.setProperty("stage1phase","1");
}
- eim.setProperty("stage1status", "display");
- eim.setProperty("stage1combo","");
+ eim.setProperty("stage1status", "waiting");
+ cm.dispose();
+ }
+ else {
+ cm.sendOk("The statues are working on the pattern. Please wait.");
cm.dispose();
}
}
-
+ else if (status == 1) {
+ var reactors = getReactors();
+ var combo = makeCombo(reactors);
+ cm.mapMessage(5, "Please wait while the combination is revealed.");
+ var delay = 5000;
+ for (var i = 0; i < combo.length; i++) {
+ cm.getPlayer().getMap().getReactorByOid(combo[i]).delayedHitReactor(cm.getClient(), delay + 3500*i);
+ }
+ eim.setProperty("stage1status", "display");
+ eim.setProperty("stage1combo","");
+ cm.dispose();
+ }
} else {
- cm.sendOk("I need the leader of your party to speak with me, nobody else.");
+ cm.sendOk("I need the leader of this event to speak with me, nobody else.");
cm.dispose();
}
}
@@ -122,10 +127,10 @@ function action(mode, type, selection) {
function getReactors() {
var reactors = new Array();
- var iter = cm.getPlayer().getMap().getMapObjects().iterator();
+ var iter = cm.getPlayer().getMap().getReactors().iterator();
while (iter.hasNext()) {
var mo = iter.next();
- if (mo.getType() == Packages.server.maps.MapleMapObjectType.REACTOR && !mo.getName().equals("statuegate")) {
+ if (!mo.getName().equals("statuegate")) {
reactors.push(mo.getObjectId());
}
}
diff --git a/scripts/npc/9040010.js b/scripts/npc/9040010.js
index 46432c5e76..59244232be 100644
--- a/scripts/npc/9040010.js
+++ b/scripts/npc/9040010.js
@@ -22,26 +22,32 @@
function start() {
var eim = cm.getPlayer().getEventInstance();
if (eim != null) {
- if (eim.getProperty("leader").equals(cm.getPlayer().getName())) {
+ if (cm.isEventLeader()) {
if (cm.haveItem(4001024)) {
cm.removeAll(4001024);
- var prev = eim.setProperty("bossclear","true",true);
+ var prev = eim.setProperty("bossclear", "true");
if (prev == null) {
var start = parseInt(eim.getProperty("entryTimestamp"));
- var diff = Packages.java.lang.System.currentTimeMillis() - start;
+ var diff = Date.now() - start;
+
var points = 1000 - Math.floor(diff / (100 * 60));
- if(points < 100)
- points = 100;
+ if(points < 100) points = 100;
+
cm.getGuild().gainGP(points);
}
+
eim.clearPQ();
}
else {
cm.sendOk("This is your final challenge. Defeat the evil lurking within the Rubian and return it to me. That is all.");
}
}
+ else {
+ cm.sendOk("This is your final challenge. Defeat the evil lurking within the Rubian and let your event leader return it to me. That is all.");
+ }
}
else
cm.warp(990001100);
+
cm.dispose();
}
\ No newline at end of file
diff --git a/scripts/npc/9103002.js b/scripts/npc/9103002.js
index 1aada5cea9..49b9751838 100644
--- a/scripts/npc/9103002.js
+++ b/scripts/npc/9103002.js
@@ -51,7 +51,7 @@ function action(mode, type, selection){
var eim = cm.getEventInstance();
if(!eim.giveEventReward(cm.getPlayer())) {
- cm.sendNext("It seems you don't have a free slot in either your #rEquip#k, #rUse#k or #rEtc#k inventories. Please make room and try again.");
+ cm.sendNext("It seems you don't have a free slot in either your #rEquip#k, #rUse#k or #rEtc#k inventories. Please make some room and try again.");
} else {
cm.warp(809050017);
}
diff --git a/scripts/npc/9201005.js b/scripts/npc/9201005.js
index 32f9524666..125b078cbe 100644
--- a/scripts/npc/9201005.js
+++ b/scripts/npc/9201005.js
@@ -70,7 +70,7 @@ function action(mode, type, selection) {
cm.sendOk("You already have a Gold Maple Leaf. Go give them to your guests before you go into the wedding.");
cm.dispose();
} else if (hasEngageRing) {
- cm.sendOk("You have recieved 15 Gold Maple Leaves.");
+ cm.sendOk("You have received 15 Gold Maple Leaves.");
cm.gainItem(4000313,15);
cm.dispose();
} else {
diff --git a/scripts/npc/9201049.js b/scripts/npc/9201049.js
index eac86c25bd..5ffb9ccc9c 100644
--- a/scripts/npc/9201049.js
+++ b/scripts/npc/9201049.js
@@ -42,7 +42,7 @@ function start() {
break;
}
if (hasRing)
- cm.sendNext("You've reached the end of the wedding. You will recieve an Onyx Chest for Bride and Groom and an Onyx Chest. Exchange them at Pila, she is at the top of Amoria.");
+ cm.sendNext("You've reached the end of the wedding. You will receive an Onyx Chest for Bride and Groom and an Onyx Chest. Exchange them at Pila, she is at the top of Amoria.");
else if (cm.haveItem(4000313)) {
cm.sendNext("Wow the end of the wedding already ? Good bye then.!");
status = 20;
diff --git a/scripts/portal/guild1F00.js b/scripts/portal/guild1F00.js
index ca991ee27c..7edf4af15b 100644
--- a/scripts/portal/guild1F00.js
+++ b/scripts/portal/guild1F00.js
@@ -22,10 +22,13 @@
/*
Return from Sharen III's Grave - Guild Quest
-@Author Lerk
+@Author Ronan
*/
function enter(pi) {
- pi.warp(990000600, 1);
+ var backPortals = [6, 8, 9, 11];
+ var idx = pi.getEventInstance().gridCheck(pi.getPlayer());
+
+ pi.warp(990000600, backPortals[idx]);
return true;
}
\ No newline at end of file
diff --git a/scripts/portal/guild1F01.js b/scripts/portal/guild1F01.js
index 4c2a435176..f7b8802840 100644
--- a/scripts/portal/guild1F01.js
+++ b/scripts/portal/guild1F01.js
@@ -28,6 +28,7 @@ Save location to return.
*/
function enter(pi) {
+ pi.getEventInstance().gridInsert(pi.getPlayer(), 0);
pi.warp(990000700, "st00");
return true;
}
diff --git a/scripts/portal/guild1F02.js b/scripts/portal/guild1F02.js
index 4c2a435176..bafec7ac4f 100644
--- a/scripts/portal/guild1F02.js
+++ b/scripts/portal/guild1F02.js
@@ -28,6 +28,7 @@ Save location to return.
*/
function enter(pi) {
+ pi.getEventInstance().gridInsert(pi.getPlayer(), 1);
pi.warp(990000700, "st00");
return true;
}
diff --git a/scripts/portal/guild1F03.js b/scripts/portal/guild1F03.js
index 4c2a435176..2cb213bb53 100644
--- a/scripts/portal/guild1F03.js
+++ b/scripts/portal/guild1F03.js
@@ -28,6 +28,7 @@ Save location to return.
*/
function enter(pi) {
+ pi.getEventInstance().gridInsert(pi.getPlayer(), 3);
pi.warp(990000700, "st00");
return true;
}
diff --git a/scripts/portal/guild1F04.js b/scripts/portal/guild1F04.js
index 4c2a435176..9303540e9e 100644
--- a/scripts/portal/guild1F04.js
+++ b/scripts/portal/guild1F04.js
@@ -28,6 +28,7 @@ Save location to return.
*/
function enter(pi) {
+ pi.getEventInstance().gridInsert(pi.getPlayer(), 2);
pi.warp(990000700, "st00");
return true;
}
diff --git a/scripts/portal/kinggate_open.js b/scripts/portal/kinggate_open.js
index a49e287130..b4ffe0d4de 100644
--- a/scripts/portal/kinggate_open.js
+++ b/scripts/portal/kinggate_open.js
@@ -27,7 +27,7 @@ Stage 5: Door before Ergoth - Guild Quest
function enter(pi) {
if (pi.getPlayer().getMap().getReactorByName("kinggate").getState() == 1) {
- pi.warp(990000900);
+ pi.warp(990000900, 1);
if (pi.getPlayer().getEventInstance().getProperty("boss") != null && pi.getPlayer().getEventInstance().getProperty("boss").equals("true")) {
pi.changeMusic("Bgm10/Eregos");
}
diff --git a/scripts/portal/speargate_open.js b/scripts/portal/speargate_open.js
index 0b826b2ec2..33e1fa1707 100644
--- a/scripts/portal/speargate_open.js
+++ b/scripts/portal/speargate_open.js
@@ -26,7 +26,7 @@
function enter(pi) {
if (pi.getPlayer().getMap().getReactorByName("speargate").getState() == 4) {
- pi.warp(990000401);
+ pi.warp(990000401, 0);
return true;
} else {
pi.getPlayer().dropMessage(5, "This way forward is not open yet.");
diff --git a/scripts/portal/statuegate_open.js b/scripts/portal/statuegate_open.js
index 00563c43ab..e50ee5399b 100644
--- a/scripts/portal/statuegate_open.js
+++ b/scripts/portal/statuegate_open.js
@@ -25,7 +25,7 @@
*/
function enter(pi) {
if (pi.getPlayer().getMap().getReactorByName("statuegate").getState() == 1) {
- pi.warp(990000301);
+ pi.warp(990000301, 0);
return true;
} else {
pi.getPlayer().dropMessage(5, "The gate is closed.");
diff --git a/scripts/portal/watergate_open.js b/scripts/portal/watergate_open.js
index 557d2e7733..791044c150 100644
--- a/scripts/portal/watergate_open.js
+++ b/scripts/portal/watergate_open.js
@@ -26,7 +26,7 @@ Stage 3: Exit Door - Guild Quest
function enter(pi) {
if (pi.getPlayer().getMap().getReactorByName("watergate").getState() == 1) {
- pi.warp(990000600);
+ pi.warp(990000600, 1);
return true;
} else
pi.getPlayer().dropMessage(5, "This way forward is not open yet.");
diff --git a/scripts/reactor/9208000.js b/scripts/reactor/9208000.js
index c0f1941cdc..24ed334c6a 100644
--- a/scripts/reactor/9208000.js
+++ b/scripts/reactor/9208000.js
@@ -25,6 +25,11 @@
*
*/
+function padWithZeroes(n, width) {
+ while(n.length < width) n = '0' + n;
+ return n;
+}
+
function act() {
var eim = rm.getPlayer().getEventInstance();
if (eim != null) {
@@ -32,19 +37,25 @@ function act() {
if (status != null && !status.equals("waiting")) {
var stage = parseInt(eim.getProperty("stage1phase"));
if (status.equals("display")) {
- var prevCombo = eim.getProperty("stage1combo");
- prevCombo += rm.getReactor().getObjectId();
- rm.mapMessage(6,"Current Combo: " + prevCombo);
- eim.setProperty("stage1combo",prevCombo);
- if (prevCombo.length == (3 * (stage + 3))) { //end of displaying
- eim.setProperty("stage1status","active");
- rm.mapMessage(5, "The combo has been displayed; Proceed with caution.");
- eim.setProperty("stage1guess","");
+ if(!rm.getReactor().isRecentHitFromAttack()) {
+ var prevCombo = eim.getProperty("stage1combo");
+
+ var n = "" + rm.getReactor().getObjectId();
+ prevCombo += padWithZeroes(n, 3);
+
+ eim.setProperty("stage1combo",prevCombo);
+ if (prevCombo.length == (3 * (stage + 3))) { //end of displaying
+ eim.setProperty("stage1status","active");
+ rm.mapMessage(5, "The combo has been displayed; Proceed with caution.");
+ eim.setProperty("stage1guess","");
+ }
}
} else { //active
- var prevGuess = eim.getProperty("stage1guess");
+ var prevGuess = "" + eim.getProperty("stage1guess");
if (prevGuess.length != (3 * (stage + 3))) {
- prevGuess += rm.getReactor().getObjectId();
+ var n = "" + rm.getReactor().getObjectId();
+ prevGuess += padWithZeroes(n, 3);
+
eim.setProperty("stage1guess",prevGuess);
}
}
diff --git a/scripts/reactor/9208001.js b/scripts/reactor/9208001.js
index 522a7bc421..a03ee665e9 100644
--- a/scripts/reactor/9208001.js
+++ b/scripts/reactor/9208001.js
@@ -21,10 +21,16 @@
*/
/* @Author Lerk
*
- * 9208000.js: Guild Quest - Gatekeeper Puzzle Reactor
+ * 9208001.js: Guild Quest - Gatekeeper Puzzle Reactor
*
*/
+
+function padWithZeroes(n, width) {
+ while(n.length < width) n = '0' + n;
+ return n;
+}
+
function act() {
var eim = rm.getPlayer().getEventInstance();
if (eim != null) {
@@ -33,18 +39,25 @@ function act() {
var stage = parseInt(eim.getProperty("stage1phase"));
//rm.mapMessage(6,"Stage " + stage);
if (status.equals("display")) {
- var prevCombo = eim.getProperty("stage1combo");
- prevCombo += rm.getReactor().getObjectId();
- eim.setProperty("stage1combo",prevCombo);
- if (prevCombo.length == (3 * (stage + 3))) { //end of displaying
- eim.setProperty("stage1status","active");
- rm.mapMessage(5, "The combo has been displayed; Proceed with caution.");
- eim.setProperty("stage1guess","");
+ if(!rm.getReactor().isRecentHitFromAttack()) {
+ var prevCombo = eim.getProperty("stage1combo");
+
+ var n = "" + rm.getReactor().getObjectId();
+ prevCombo += padWithZeroes(n, 3);
+
+ eim.setProperty("stage1combo",prevCombo);
+ if (prevCombo.length == (3 * (stage + 3))) { //end of displaying
+ eim.setProperty("stage1status","active");
+ rm.mapMessage(5, "The combo has been displayed; Proceed with caution.");
+ eim.setProperty("stage1guess","");
+ }
}
} else { //active
- var prevGuess = eim.getProperty("stage1guess");
+ var prevGuess = "" + eim.getProperty("stage1guess");
if (prevGuess.length != (3 * (stage + 3))) {
- prevGuess += rm.getReactor().getObjectId();
+ var n = "" + rm.getReactor().getObjectId();
+ prevGuess += padWithZeroes(n, 3);
+
eim.setProperty("stage1guess",prevGuess);
}
//rm.mapMessage(6,"Current Guess: " + prevGuess);
diff --git a/scripts/reactor/9208002.js b/scripts/reactor/9208002.js
index 93a2d467b5..b015dc84eb 100644
--- a/scripts/reactor/9208002.js
+++ b/scripts/reactor/9208002.js
@@ -21,10 +21,15 @@
/* @Author Lerk
*
- * 9208000.js: Guild Quest - Gatekeeper Puzzle Reactor
+ * 9208002.js: Guild Quest - Gatekeeper Puzzle Reactor
*
*/
+function padWithZeroes(n, width) {
+ while(n.length < width) n = '0' + n;
+ return n;
+}
+
function act() {
var eim = rm.getPlayer().getEventInstance();
if (eim != null) {
@@ -32,18 +37,24 @@ function act() {
if (status != null && !status.equals("waiting")) {
var stage = parseInt(eim.getProperty("stage1phase"));
if (status.equals("display")) {
- var prevCombo = eim.getProperty("stage1combo");
- prevCombo += rm.getReactor().getObjectId();
- eim.setProperty("stage1combo",prevCombo);
- if (prevCombo.length == (3 * (stage + 3))) { //end of displaying
- eim.setProperty("stage1status","active");
- rm.mapMessage(5, "The combo has been displayed; Proceed with caution.");
- eim.setProperty("stage1guess","");
+ if(!rm.getReactor().isRecentHitFromAttack()) {
+ var prevCombo = eim.getProperty("stage1combo");
+ var n = "" + rm.getReactor().getObjectId();
+ prevCombo += padWithZeroes(n, 3);
+
+ eim.setProperty("stage1combo",prevCombo);
+ if (prevCombo.length == (3 * (stage + 3))) { //end of displaying
+ eim.setProperty("stage1status","active");
+ rm.mapMessage(5, "The combo has been displayed; Proceed with caution.");
+ eim.setProperty("stage1guess","");
+ }
}
} else { //active
- var prevGuess = eim.getProperty("stage1guess");
- if (prevGuess.length != (3 * stage + 9)) {
- prevGuess += rm.getReactor().getObjectId();
+ var prevGuess = "" + eim.getProperty("stage1guess");
+ if (prevGuess.length != (3 * (stage + 3))) {
+ var n = "" + rm.getReactor().getObjectId();
+ prevGuess += padWithZeroes(n, 3);
+
eim.setProperty("stage1guess",prevGuess);
}
}
diff --git a/scripts/reactor/9208007.js b/scripts/reactor/9208007.js
index 913f74ea94..f4196455c2 100644
--- a/scripts/reactor/9208007.js
+++ b/scripts/reactor/9208007.js
@@ -22,9 +22,21 @@
/*
Stage 2: Spear destinations - Guild Quest
-@Author Lerk
+@Author Lerk, Ronan
*/
function act() {
- rm.getPlayer().getEventInstance().getMapInstance(990000400).getReactorByName("speargate").hitReactor(rm.getPlayer().getClient());
+ var react = rm.getPlayer().getEventInstance().getMapInstance(990000400).getReactorByName("speargate");
+ react.forceHitReactor(react.getState() + 1);
+
+ if(react.getState() == 4) {
+ var eim = rm.getPlayer().getEventInstance();
+
+ var maps = [990000400, 990000410, 990000420, 990000430, 990000431, 990000440];
+ for(var i = 0; i < maps.length; i++) {
+ eim.showClearEffect(false, maps[i]);
+ }
+
+ rm.getGuild().gainGP(20);
+ }
}
\ No newline at end of file
diff --git a/scripts/reactor/9208009.js b/scripts/reactor/9208009.js
new file mode 100644
index 0000000000..0fe5410bb3
--- /dev/null
+++ b/scripts/reactor/9208009.js
@@ -0,0 +1,28 @@
+/*
+ * 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 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 .
+ */
+
+// Opened GPQ boss room, players may now revive and stay on the GPQ
+
+function act() {
+ if(rm.getEventInstance() != null) {
+ rm.getEventInstance().setProperty("canRevive", "1");
+ }
+}
diff --git a/sql/db_drops.sql b/sql/db_drops.sql
index 9a647f09aa..e609fdffe9 100644
--- a/sql/db_drops.sql
+++ b/sql/db_drops.sql
@@ -19035,7 +19035,14 @@
(9300043, 4001052, 1, 1, 0, 999999),
(9300040, 4001074, 1, 1, 0, 999999),
(9300048, 4001053, 1, 1, 0, 999999),
-(9300049, 4001074, 1, 1, 0, 999999);
+(9300049, 4001074, 1, 1, 0, 999999),
+(9300019, 4001026, 1, 1, 0, 999999),
+(9300022, 4001027, 1, 1, 0, 999999),
+(9300023, 4001028, 1, 1, 0, 999999),
+(9300024, 4001035, 1, 1, 0, 999999),
+(9300025, 4001036, 1, 1, 0, 999999),
+(9300027, 4001035, 1, 1, 0, 999999),
+(9300033, 4001035, 1, 1, 0, 999999);
# (dropperid, itemid, minqty, maxqty, questid, chance)
diff --git a/src/client/MapleCharacter.java b/src/client/MapleCharacter.java
index f8681890b2..3e5e1f5048 100644
--- a/src/client/MapleCharacter.java
+++ b/src/client/MapleCharacter.java
@@ -281,8 +281,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
private boolean loggedIn = false;
private MapleDragon dragon = null;
private boolean useCS; //chaos scroll upon crafting item.
- private long useDuey;
+ private long npcCd;
private long petLootCd;
+ private long lastHpDec = 0;
private int newWarpMap = -1;
private MapleCharacter() {
@@ -310,10 +311,6 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
petLootCd = System.currentTimeMillis();
}
- public void setHpDecreaseTask(ScheduledFuture> mapDotTask) {
- hpDecreaseTask = mapDotTask;
- }
-
public MapleJob getJobStyle() {
int jobtype = this.getJob().getId() / 100;
@@ -413,12 +410,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
useCS = cs;
}
- public long getDuey() {
- return useDuey;
+ public long getNpcCooldown() {
+ return npcCd;
}
- public void setDuey(long d) {
- useDuey = d;
+ public void setNpcCooldown(long d) {
+ npcCd = d;
}
public void addCooldown(int skillId, long startTime, long length, ScheduledFuture> timer) {
@@ -1104,7 +1101,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
}
- protected MapleMap getWarpMap(int map) {
+ public MapleMap getWarpMap(int map) {
MapleMap target;
if (getEventInstance() == null) {
target = client.getChannelServer().getMapFactory().getMap(map);
@@ -1221,14 +1218,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
client.announce(MaplePacketCreator.updateParty(client.getChannel(), party, PartyOperation.SILENT_UPDATE, null));
updatePartyMemberHP();
}
- if (getMap().getHPDec() > 0) {
- hpDecreaseTask = TimerManager.getInstance().schedule(new Runnable() {
- @Override
- public void run() {
- doHurtHp();
- }
- }, 10000);
- }
+
+ if (getMap().getHPDec() > 0) resetHpDecreaseTask();
}
else {
FilePrinter.printError(FilePrinter.MAPLE_MAP, "Character " + this.getName() + " got stuck when moving to map " + map.getId() + ".");
@@ -1381,7 +1372,13 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
this.getMap().broadcastMessage(pickupPacket, mapitem.getPosition());
this.getMap().removeMapObject(ob);
mapitem.setPickedUp(true);
- } else if (MapleInventoryManipulator.addFromDrop(client, mapitem.getItem(), false)) {
+ } else if(mapitem.getItemId() == 4031865 || mapitem.getItemId() == 4031866) {
+ // Add NX to account, show effect and make item disappear
+ this.getCashShop().gainCash(1, mapitem.getItemId() == 4031865 ? 100 : 250);
+ this.getMap().broadcastMessage(pickupPacket, mapitem.getPosition());
+ this.getMap().removeMapObject(ob);
+ mapitem.setPickedUp(true);
+ } else if (MapleInventoryManipulator.addFromDrop(client, mapitem.getItem(), true)) {
this.getMap().broadcastMessage(pickupPacket, mapitem.getPosition());
this.getMap().removeMapObject(ob);
mapitem.setPickedUp(true);
@@ -1928,9 +1925,10 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
}
- public void doHurtHp() {
+ private void doHurtHp() {
if (!(this.getInventory(MapleInventoryType.EQUIPPED).findById(getMap().getHPDecProtect()) != null || buffMapProtection())) {
addHP(-getMap().getHPDec());
+ lastHpDec = System.currentTimeMillis();
}
hpDecreaseTask = TimerManager.getInstance().schedule(new Runnable() {
@@ -1940,7 +1938,25 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
}, 10000);
}
-
+
+ public void resetHpDecreaseTask() {
+ if (hpDecreaseTask != null) {
+ hpDecreaseTask.cancel(false);
+ }
+
+ long lastHpTask = System.currentTimeMillis() - lastHpDec;
+ if(lastHpTask >= 10000) {
+ doHurtHp();
+ } else {
+ hpDecreaseTask = TimerManager.getInstance().schedule(new Runnable() {
+ @Override
+ public void run() {
+ doHurtHp();
+ }
+ }, lastHpTask);
+ }
+ }
+
public void dropMessage(String message) {
dropMessage(0, message);
}
@@ -2086,14 +2102,24 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
if(gain < 0) gain = Integer.MAX_VALUE; // integer overflow, heh.
+ if(party < 0) party = Integer.MAX_VALUE; // integer overflow, heh.
int equip = (int)Math.min((long)((gain / 10) * pendantExp), Integer.MAX_VALUE);
long total = gain + equip + party;
gainExpInternal(total, equip, party, show, inChat, white);
}
+ public void loseExp(int loss, boolean show, boolean inChat) {
+ loseExp(loss, show, inChat, true);
+ }
+
+ public void loseExp(int loss, boolean show, boolean inChat, boolean white) {
+ gainExpInternal(-loss, 0, 0, show, inChat, white);
+ }
+
private void gainExpInternal(long gain, int equip, int party, boolean show, boolean inChat, boolean white) {
- long total = gain;
+ long total = Math.max(gain, -exp.get());
+
if (level < getMaxLevel()) {
long leftover = 0;
long nextExp = exp.get() + total;
@@ -4265,9 +4291,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
}
if (getExp() > XPdummy) {
- gainExp(-XPdummy, false, false);
+ loseExp(XPdummy, false, false);
} else {
- gainExp(-getExp(), false, false);
+ loseExp(getExp(), false, false);
}
}
if (getBuffedValue(MapleBuffStat.MORPH) != null) {
diff --git a/src/client/MapleClient.java b/src/client/MapleClient.java
index c42ef3833a..c1d5a79d43 100644
--- a/src/client/MapleClient.java
+++ b/src/client/MapleClient.java
@@ -972,7 +972,7 @@ public class MapleClient {
}
public void setScriptEngine(String name, ScriptEngine e) {
- engines.put(name, e);
+ engines.put(name, e);
}
public ScriptEngine getScriptEngine(String name) {
@@ -980,7 +980,7 @@ public class MapleClient {
}
public void removeScriptEngine(String name) {
- engines.remove(name);
+ engines.remove(name);
}
public ScheduledFuture> getIdleTask() {
diff --git a/src/client/autoban/AutobanManager.java b/src/client/autoban/AutobanManager.java
index 372d26276f..85a05dcc9e 100644
--- a/src/client/autoban/AutobanManager.java
+++ b/src/client/autoban/AutobanManager.java
@@ -97,8 +97,8 @@ public class AutobanManager {
* 3: ItemIdSort
* 4: SpecialMove
* 5: UseCatchItem
- * 6: Item Drop
- * 7: Chat
+ * 6: Item Drop
+ * 7: Chat
*
* @param type type
* @return Timestamp checker
diff --git a/src/client/command/Commands.java b/src/client/command/Commands.java
index 40919b2763..6e8d9c4606 100644
--- a/src/client/command/Commands.java
+++ b/src/client/command/Commands.java
@@ -22,6 +22,7 @@
package client.command;
import java.awt.Point;
+import java.awt.Rectangle;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
@@ -708,13 +709,25 @@ public class Commands {
player.dropMessage(6, "Current map id " + player.getMap().getId() + ", event: '" + ((player.getMap().getEventInstance() != null) ? player.getMap().getEventInstance().getName() : "null") + "'; Players: " + player.getMap().getAllPlayers().size() + ", Mobs: " + player.getMap().countMonsters() + ", Reactors: " + player.getMap().countReactors() + ", Items: " + player.getMap().countItems() + ".");
}
break;
-
+
case "debugevent":
if(ServerConstants.USE_DEBUG) {
if(player.getEventInstance() == null) player.dropMessage(6, "Player currently not in an event.");
else player.dropMessage(6, "Current event name: " + player.getEventInstance().getName() + ".");
}
break;
+
+ case "debugareas":
+ if(ServerConstants.USE_DEBUG) {
+ player.dropMessage(6, "Configured areas on map " + player.getMapId() + ":");
+
+ byte index = 0;
+ for(Rectangle rect: player.getMap().getAreas()) {
+ player.dropMessage(6, "Id: " + index + " -> posX: " + rect.getX() + " posY: '" + rect.getY() + "' dX: " + rect.getWidth() + " dY: " + rect.getHeight() + ".");
+ index++;
+ }
+ }
+ break;
case "debugreactors":
if(ServerConstants.USE_DEBUG) {
@@ -722,7 +735,7 @@ public class Commands {
for(MapleMapObject mmo: player.getMap().getReactors()) {
MapleReactor mr = (MapleReactor) mmo;
- player.dropMessage(6, "Reactor id: " + mr.getId() + " name: '" + mr.getName() + "' -> Type: " + mr.getReactorType() + " State: " + mr.getState() + " Event State: " + mr.getEventState() + " Position: x " + mr.getPosition().getX() + " y " + mr.getPosition().getY() + ".");
+ player.dropMessage(6, "Id: " + mr.getId() + " Oid: " + mr.getObjectId() + " name: '" + mr.getName() + "' -> Type: " + mr.getReactorType() + " State: " + mr.getState() + " Event State: " + mr.getEventState() + " Position: x " + mr.getPosition().getX() + " y " + mr.getPosition().getY() + ".");
}
}
break;
@@ -986,7 +999,7 @@ public class Commands {
} else if (sub[0].equals("whereami")) { //This is so not going to work on the first commit
player.yellowMessage("Map ID: " + player.getMap().getId());
player.yellowMessage("Players on this map:");
- for (MapleMapObject mmo : player.getMap().getAllPlayer()) {
+ for (MapleMapObject mmo : player.getMap().getPlayers()) {
MapleCharacter chr = (MapleCharacter) mmo;
player.dropMessage(5, ">> " + chr.getName());
}
@@ -1203,18 +1216,25 @@ public class Commands {
}
}
if (victim != null) {
+ boolean changingEvent = true;
+
if (victim.getEventInstance() != null) {
- victim.getEventInstance().unregisterPlayer(victim);
+ if(player.getEventInstance() != null && victim.getEventInstance().getLeaderId() == player.getEventInstance().getLeaderId()) {
+ changingEvent = false;
+ }
+ else {
+ victim.getEventInstance().unregisterPlayer(victim);
+ }
}
//Attempt to join the warpers instance.
- if (player.getEventInstance() != null) {
+ if (player.getEventInstance() != null && changingEvent) {
if (player.getClient().getChannel() == victim.getClient().getChannel()) {//just in case.. you never know...
player.getEventInstance().registerPlayer(victim);
victim.changeMap(player.getEventInstance().getMapInstance(player.getMapId()), player.getMap().findClosestPortal(player.getPosition()));
} else {
player.dropMessage("Target isn't on your channel, not able to warp into event instance.");
}
- } else {//If victim isn't in an event instance, just warp them.
+ } else {//If victim isn't in an event instance or is in the same event instance as the one the caller is, just warp them.
victim.changeMap(player.getMapId(), player.getMap().findClosestPortal(player.getPosition()));
}
if (player.getClient().getChannel() != victim.getClient().getChannel()) {//And then change channel if needed.
@@ -1348,7 +1368,7 @@ public class Commands {
MapleMonster monster = (MapleMonster) monstermo;
if (!monster.getStats().isFriendly()) {
map.killMonster(monster, player, true);
- monster.giveExpToCharacter(player, monster.getExp() * c.getPlayer().getExpRate(), true, 1);
+ //monster.giveExpToCharacter(player, monster.getExp() * c.getPlayer().getExpRate(), true, 1);
}
}
player.dropMessage("Killed " + monsters.size() + " monsters.");
@@ -1367,7 +1387,7 @@ public class Commands {
}
player.setLevel(Integer.parseInt(sub[1]) - 1);
- player.gainExp(-player.getExp(), false, false);
+ player.loseExp(player.getExp(), false, false);
player.levelUp(false);
} else if (sub[0].equals("levelpro")) {
if (sub.length < 2){
@@ -1381,7 +1401,7 @@ public class Commands {
} else if (sub[0].equals("maxstat")) {
final String[] s = {"setall", String.valueOf(Short.MAX_VALUE)};
executeGMCommand(c, s, heading);
- player.gainExp(-player.getExp(), false, false);
+ player.loseExp(player.getExp(), false, false);
player.setLevel(255);
player.setFame(13337);
player.setMaxHp(30000);
diff --git a/src/constants/ServerConstants.java b/src/constants/ServerConstants.java
index f89753c0b7..d1c2b01976 100644
--- a/src/constants/ServerConstants.java
+++ b/src/constants/ServerConstants.java
@@ -47,12 +47,16 @@ public class ServerConstants {
public static final boolean USE_AUTOBAN = false; //Commands the server to detect infractors automatically.
public static final boolean USE_ANOTHER_AUTOASSIGN = true; //Based on distributing AP accordingly with higher secondary stat on equipments.
public static final boolean USE_REFRESH_RANK_MOVE = true;
- public static final int MAX_AP = 20000; //Max AP alloted on the auto-assigner.
- public static final int MAX_EVENT_LEVELS = 8; //Event has different levels of rewarding system.
- public static final long BLOCK_DUEY_RACE_COND = (long)(0.5 * 1000);
- public static final long PET_LOOT_UPON_ATTACK = (long)(0.7 * 1000); //Time the pet must wait before trying to pick items up.
public static final boolean USE_PERFECT_PITCH = true; //For lvl 30 or above, each lvlup player gains 1 perfect pitch.
+
+ public static final int MAX_AP = 20000; //Max AP allotted on the auto-assigner.
+ public static final int MAX_EVENT_LEVELS = 8; //Event has different levels of rewarding system.
+ public static final long BLOCK_NPC_RACE_CONDT = (long)(0.5 * 1000); //Time the player client must wait before reopening a conversation with an NPC.
+ public static final long PET_LOOT_UPON_ATTACK = (long)(0.7 * 1000); //Time the pet must wait before trying to pick items up.
+
+ public static final int ITEM_EXPIRE_TIME = 3 * 60 * 1000; //Time before items start disappearing. Recommended to be set up to 3 minutes.
+
//Some Gameplay Enhancing Configuration
public static final boolean USE_PERFECT_SCROLLING = true; //Scrolls doesn't use slots upon failure.
public static final boolean USE_ENHANCED_CHSCROLL = true; //Equips even more powerful with chaos upgrade.
diff --git a/src/net/server/channel/handlers/ChangeMapHandler.java b/src/net/server/channel/handlers/ChangeMapHandler.java
index ab0ea7be41..e3923ef816 100644
--- a/src/net/server/channel/handlers/ChangeMapHandler.java
+++ b/src/net/server/channel/handlers/ChangeMapHandler.java
@@ -49,7 +49,7 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler {
}
if (slea.available() == 0) { //Cash Shop :)
if(!chr.getCashShop().isOpened()) {
- c.disconnect(false, false);
+ c.disconnect(false, false);
return;
}
String[] socket = c.getChannelServer().getIP().split(":");
@@ -84,14 +84,14 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler {
chr.announce(MaplePacketCreator.showWheelsLeft(chr.getItemQuantity(5510000, false)));
} else {
chr.cancelAllBuffs(false);
- to = chr.getMap().getReturnMap();
+ to = chr.getWarpMap(chr.getMap().getReturnMapId());
chr.setStance(0);
}
chr.setHp(50);
chr.changeMap(to, to.getRandomPlayerSpawnpoint());
}
} else if (targetid != -1 && chr.isGM()) {
- MapleMap to = c.getChannelServer().getMapFactory().getMap(targetid);
+ MapleMap to = chr.getWarpMap(targetid);
chr.changeMap(to, to.getPortal(0));
} else if (targetid != -1 && !chr.isGM()) {//Thanks celino for saving me some time (:
final int divi = chr.getMapId() / 100;
@@ -124,7 +124,7 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler {
}
}
if (warp) {
- final MapleMap to = c.getChannelServer().getMapFactory().getMap(targetid);
+ final MapleMap to = chr.getWarpMap(targetid);
chr.changeMap(to, to.getPortal(0));
}
}
diff --git a/src/net/server/channel/handlers/DueyHandler.java b/src/net/server/channel/handlers/DueyHandler.java
index 0daf1a5a52..bc08736817 100644
--- a/src/net/server/channel/handlers/DueyHandler.java
+++ b/src/net/server/channel/handlers/DueyHandler.java
@@ -59,7 +59,7 @@ public final class DueyHandler extends AbstractMaplePacketHandler {
TOCLIENT_SAMEACC_ERROR(0x0D),
TOCLIENT_SUCCESSFULLY_SENT(0x12),
TOCLIENT_SUCCESSFUL_MSG(0x17),
- TOCLIENT_PACKAGE_MSG(0x1B); // Ending byte; 4 if recieved. 3 if delete.
+ TOCLIENT_PACKAGE_MSG(0x1B); // Ending byte; 4 if received. 3 if delete.
final byte code;
private Actions(int code) {
diff --git a/src/net/server/channel/handlers/GeneralChatHandler.java b/src/net/server/channel/handlers/GeneralChatHandler.java
index b0ee0923ec..2a3bdae9e7 100644
--- a/src/net/server/channel/handlers/GeneralChatHandler.java
+++ b/src/net/server/channel/handlers/GeneralChatHandler.java
@@ -37,9 +37,9 @@ public final class GeneralChatHandler extends net.AbstractMaplePacketHandler {
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
String s = slea.readMapleAsciiString();
MapleCharacter chr = c.getPlayer();
- if(chr.getAutobanManager().getLastSpam(7) + 200 > System.currentTimeMillis()) {
- return;
- }
+ if(chr.getAutobanManager().getLastSpam(7) + 200 > System.currentTimeMillis()) {
+ return;
+ }
if (s.length() > Byte.MAX_VALUE && !chr.isGM()) {
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit in General Chat.");
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to send text with length of " + s.length() + "\r\n");
@@ -70,13 +70,13 @@ public final class GeneralChatHandler extends net.AbstractMaplePacketHandler {
chr.dropMessage(5, "The map you are in is currently muted. Please try again later.");
return;
}
- if (!chr.isHidden()){
+ if (!chr.isHidden()) {
chr.getMap().broadcastMessage(MaplePacketCreator.getChatText(chr.getId(), s, chr.getWhiteChat(), show));
} else {
chr.getMap().broadcastGMMessage(MaplePacketCreator.getChatText(chr.getId(), s, chr.getWhiteChat(), show));
}
}
- chr.getAutobanManager().spam(7);
+ chr.getAutobanManager().spam(7);
}
}
diff --git a/src/net/server/channel/handlers/ItemMoveHandler.java b/src/net/server/channel/handlers/ItemMoveHandler.java
index c8ba9db5c0..69840839ba 100644
--- a/src/net/server/channel/handlers/ItemMoveHandler.java
+++ b/src/net/server/channel/handlers/ItemMoveHandler.java
@@ -54,6 +54,8 @@ public final class ItemMoveHandler extends AbstractMaplePacketHandler {
} else {
MapleInventoryManipulator.move(c, type, src, action);
}
+
+ if (c.getPlayer().getMap().getHPDec() > 0) c.getPlayer().resetHpDecreaseTask();
c.getPlayer().getAutobanManager().spam(6);
}
}
\ No newline at end of file
diff --git a/src/net/server/channel/handlers/NPCTalkHandler.java b/src/net/server/channel/handlers/NPCTalkHandler.java
index 889da416d0..c2bc7688d1 100644
--- a/src/net/server/channel/handlers/NPCTalkHandler.java
+++ b/src/net/server/channel/handlers/NPCTalkHandler.java
@@ -38,6 +38,9 @@ public final class NPCTalkHandler extends AbstractMaplePacketHandler {
return;
}
+ if(System.currentTimeMillis() - c.getPlayer().getNpcCooldown() < ServerConstants.BLOCK_NPC_RACE_CONDT)
+ return;
+
int oid = slea.readInt();
MapleMapObject obj = c.getPlayer().getMap().getMapObject(oid);
if (obj instanceof MapleNPC) {
@@ -45,10 +48,7 @@ public final class NPCTalkHandler extends AbstractMaplePacketHandler {
if(ServerConstants.USE_DEBUG == true) c.getPlayer().dropMessage(5, "Talking to NPC " + npc.getId());
if (npc.getId() == 9010009) { //is duey
- if(System.currentTimeMillis() - c.getPlayer().getDuey() < ServerConstants.BLOCK_DUEY_RACE_COND)
- return;
-
- c.getPlayer().setDuey(System.currentTimeMillis());
+ c.getPlayer().setNpcCooldown(System.currentTimeMillis());
c.announce(MaplePacketCreator.sendDuey((byte) 8, DueyHandler.loadItems(c.getPlayer())));
} else if (npc.hasShop()) {
if (c.getPlayer().getShop() != null) {
diff --git a/src/net/server/channel/handlers/PartySearchStartHandler.java b/src/net/server/channel/handlers/PartySearchStartHandler.java
index c14f8519f6..08f0c5d4b1 100644
--- a/src/net/server/channel/handlers/PartySearchStartHandler.java
+++ b/src/net/server/channel/handlers/PartySearchStartHandler.java
@@ -50,7 +50,7 @@ public class PartySearchStartHandler extends AbstractMaplePacketHandler {
int jobs = slea.readInt();
MapleCharacter chr = c.getPlayer();
MapleMap map = chr.getMap();
- Collection mapobjs = map.getAllPlayer();
+ Collection mapobjs = map.getPlayers();
for (MapleMapObject mapobj : mapobjs) {
if (chr.getParty().getMembers().size() > 5) {
break;
diff --git a/src/net/server/channel/handlers/PlayerLoggedinHandler.java b/src/net/server/channel/handlers/PlayerLoggedinHandler.java
index d0be625c8f..cd265431bd 100644
--- a/src/net/server/channel/handlers/PlayerLoggedinHandler.java
+++ b/src/net/server/channel/handlers/PlayerLoggedinHandler.java
@@ -267,18 +267,7 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
}
- if (player.getMap().getHPDec() > 0) {
- final MapleCharacter mc = player;
-
- ScheduledFuture> hpDecreaseTask = TimerManager.getInstance().schedule(new Runnable() {
- @Override
- public void run() {
- mc.doHurtHp();
- }
- }, 10000);
-
- mc.setHpDecreaseTask(hpDecreaseTask);
- }
+ if (player.getMap().getHPDec() > 0) player.resetHpDecreaseTask();
player.dispelBuffCoupons();
player.resetPlayerRates();
diff --git a/src/net/server/channel/handlers/ReactorHitHandler.java b/src/net/server/channel/handlers/ReactorHitHandler.java
index 43b9b39064..629d9c7cb3 100644
--- a/src/net/server/channel/handlers/ReactorHitHandler.java
+++ b/src/net/server/channel/handlers/ReactorHitHandler.java
@@ -41,7 +41,7 @@ public final class ReactorHitHandler extends AbstractMaplePacketHandler {
int skillid = slea.readInt();
MapleReactor reactor = c.getPlayer().getMap().getReactorByOid(oid);
if (reactor != null && reactor.isAlive()) {
- reactor.hitReactor(charPos, stance, skillid, c);
+ reactor.hitReactor(true, charPos, stance, skillid, c);
}
}
}
diff --git a/src/net/server/guild/MapleGuild.java b/src/net/server/guild/MapleGuild.java
index 1d3c936877..f972d38ef3 100644
--- a/src/net/server/guild/MapleGuild.java
+++ b/src/net/server/guild/MapleGuild.java
@@ -540,7 +540,7 @@ public class MapleGuild {
this.gp += amount;
this.writeToDB(false);
this.guildMessage(MaplePacketCreator.updateGP(this.id, this.gp));
- this.guildMessage(MaplePacketCreator.getGPMessage(amount));
+ this.guildMessage(MaplePacketCreator.getGPMessage(amount));
}
public void removeGP(int amount){
diff --git a/src/net/server/world/MaplePartyCharacter.java b/src/net/server/world/MaplePartyCharacter.java
index 88e9425945..6b92696030 100644
--- a/src/net/server/world/MaplePartyCharacter.java
+++ b/src/net/server/world/MaplePartyCharacter.java
@@ -111,6 +111,10 @@ public class MaplePartyCharacter {
public int getJobId() {
return jobid;
}
+
+ public int getGuildId() {
+ return character.getGuildId();
+ }
public void updateDoor(MapleDoor door) {
this.door.add(door);
diff --git a/src/scripting/AbstractPlayerInteraction.java b/src/scripting/AbstractPlayerInteraction.java
index c4714bbb27..a2d48c435c 100644
--- a/src/scripting/AbstractPlayerInteraction.java
+++ b/src/scripting/AbstractPlayerInteraction.java
@@ -131,13 +131,7 @@ public class AbstractPlayerInteraction {
}
public MapleMap getWarpMap(int map) {
- MapleMap target;
- if (getPlayer().getEventInstance() == null) {
- target = c.getChannelServer().getMapFactory().getMap(map);
- } else {
- target = getPlayer().getEventInstance().getMapInstance(map);
- }
- return target;
+ return getPlayer().getWarpMap(map);
}
public MapleMap getMap(int map) {
@@ -529,11 +523,15 @@ public class AbstractPlayerInteraction {
return getPlayer().getParty();
}
+ public boolean isLeader() {
+ return isPartyLeader();
+ }
+
public boolean isGuildLeader() {
return getPlayer().isGuildLeader();
}
- public boolean isLeader() {
+ public boolean isPartyLeader() {
if(getParty() == null)
return false;
diff --git a/src/scripting/event/EventInstanceManager.java b/src/scripting/event/EventInstanceManager.java
index dd4bda2eb4..9c6c8e7060 100644
--- a/src/scripting/event/EventInstanceManager.java
+++ b/src/scripting/event/EventInstanceManager.java
@@ -952,7 +952,11 @@ public class EventInstanceManager {
}
public final void showWrongEffect() {
- MapleMap map = getMapInstance(getLeader().getMapId());
+ showWrongEffect(getLeader().getMapId());
+ }
+
+ public final void showWrongEffect(int mapId) {
+ MapleMap map = getMapInstance(mapId);
map.broadcastMessage(MaplePacketCreator.showEffect("quest/party/wrong_kor"));
map.broadcastMessage(MaplePacketCreator.playSound("Party1/Failed"));
}
@@ -962,7 +966,11 @@ public class EventInstanceManager {
}
public final void showClearEffect(boolean hasGate) {
- MapleMap map = getMapInstance(getLeader().getMapId());
+ showClearEffect(hasGate, getLeader().getMapId());
+ }
+
+ public final void showClearEffect(boolean hasGate, int mapId) {
+ MapleMap map = getMapInstance(mapId);
map.broadcastMessage(MaplePacketCreator.showEffect("quest/party/clear"));
map.broadcastMessage(MaplePacketCreator.playSound("Party1/Clear"));
if(hasGate) {
diff --git a/src/scripting/event/EventManager.java b/src/scripting/event/EventManager.java
index 1068bf7479..f992ab3010 100644
--- a/src/scripting/event/EventManager.java
+++ b/src/scripting/event/EventManager.java
@@ -145,9 +145,17 @@ public class EventManager {
}, timestamp);
}
+ public World getWorldServer() {
+ return wserv;
+ }
+
public Channel getChannelServer() {
return cserv;
}
+
+ public Invocable getIv() {
+ return iv;
+ }
public EventInstanceManager getInstance(String name) {
return instances.get(name);
@@ -173,10 +181,6 @@ public class EventManager {
}, lobbyDelay * 1000);
}
- public Invocable getIv() {
- return iv;
- }
-
public void setProperty(String key, String value) {
props.setProperty(key, value);
}
@@ -298,8 +302,8 @@ public class EventManager {
return startInstance(-1, chr);
}
- public boolean startInstance(int lobbyId, MapleCharacter chr) {
- return startInstance(lobbyId, chr, chr, 1);
+ public boolean startInstance(int lobbyId, MapleCharacter leader) {
+ return startInstance(lobbyId, null, leader, 1);
}
public boolean startInstance(int lobbyId, MapleCharacter chr, MapleCharacter leader, int difficulty) {
@@ -321,7 +325,7 @@ public class EventManager {
instanceLocks.put(eim.getName(), lobbyId);
eim.setLeader(leader);
- eim.registerPlayer(chr);
+ if(chr != null) eim.registerPlayer(chr);
iv.invokeFunction("afterSetup", eim);
} catch (ScriptException | NoSuchMethodException ex) {
Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex);
@@ -502,7 +506,8 @@ public class EventManager {
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.";
+ + " 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(0, callout);
}
diff --git a/src/scripting/npc/NPCScriptManager.java b/src/scripting/npc/NPCScriptManager.java
index 6fca867ff8..1603e8aad2 100644
--- a/src/scripting/npc/NPCScriptManager.java
+++ b/src/scripting/npc/NPCScriptManager.java
@@ -118,6 +118,7 @@ public class NPCScriptManager extends AbstractScriptManager {
public void dispose(NPCConversationManager cm) {
MapleClient c = cm.getClient();
c.getPlayer().setCS(false);
+ c.getPlayer().setNpcCooldown(System.currentTimeMillis());
cms.remove(c);
scripts.remove(c);
diff --git a/src/scripting/quest/QuestScriptManager.java b/src/scripting/quest/QuestScriptManager.java
index a88faa94f6..4745dbb3e2 100644
--- a/src/scripting/quest/QuestScriptManager.java
+++ b/src/scripting/quest/QuestScriptManager.java
@@ -148,6 +148,7 @@ public class QuestScriptManager extends AbstractScriptManager {
public void dispose(QuestActionManager qm, MapleClient c) {
qms.remove(c);
scripts.remove(c);
+ c.getPlayer().setNpcCooldown(System.currentTimeMillis());
resetContext("quest/" + qm.getQuest() + ".js", c);
}
diff --git a/src/server/maps/MapleMap.java b/src/server/maps/MapleMap.java
index 758dbc748f..f01d71da50 100644
--- a/src/server/maps/MapleMap.java
+++ b/src/server/maps/MapleMap.java
@@ -479,7 +479,7 @@ public class MapleMap {
}
}, null);
- TimerManager.getInstance().schedule(new ExpireMapItemJob(mdrop), 180000);
+ TimerManager.getInstance().schedule(new ExpireMapItemJob(mdrop), ServerConstants.ITEM_EXPIRE_TIME);
activateItemReactors(mdrop, chr.getClient());
}
@@ -495,7 +495,7 @@ public class MapleMap {
}
}, null);
- TimerManager.getInstance().schedule(new ExpireMapItemJob(mdrop), 180000);
+ TimerManager.getInstance().schedule(new ExpireMapItemJob(mdrop), ServerConstants.ITEM_EXPIRE_TIME);
}
public final void disappearingItemDrop(final MapleMapObject dropper, final MapleCharacter owner, final Item item, final Point pos) {
@@ -551,6 +551,56 @@ public class MapleMap {
return getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.ITEM));
}
+ public int countPlayers() {
+ return getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.PLAYER)).size();
+ }
+
+ public List getPlayers() {
+ return getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.PLAYER));
+ }
+
+ public List getAllPlayers() {
+ List character = new LinkedList<>();
+ chrRLock.lock();
+ try {
+ for (MapleCharacter a : characters) {
+ character.add(a);
+ }
+ } finally {
+ chrRLock.unlock();
+ }
+
+ return character;
+ }
+
+ public List getPlayersInRange(Rectangle box, List chr) {
+ List character = new LinkedList<>();
+ chrRLock.lock();
+ try {
+ for (MapleCharacter a : characters) {
+ if (chr.contains(a.getClient().getPlayer())) {
+ if (box.contains(a.getPosition())) {
+ character.add(a);
+ }
+ }
+ }
+ } finally {
+ chrRLock.unlock();
+ }
+
+ return character;
+ }
+
+ public int countAlivePlayers() {
+ int count = 0;
+
+ for(MapleCharacter mc: getAllPlayers()) {
+ if(mc.isAlive()) count++;
+ }
+
+ return count;
+ }
+
public boolean damageMonster(final MapleCharacter chr, final MapleMonster monster, final int damage) {
if (monster.getId() == 8800000) {
for (MapleMapObject object : chr.getMap().getMapObjects()) {
@@ -658,7 +708,7 @@ public class MapleMap {
int buff = monster.getBuffToGive();
if (buff > -1) {
MapleItemInformationProvider mii = MapleItemInformationProvider.getInstance();
- for (MapleMapObject mmo : this.getAllPlayer()) {
+ for (MapleMapObject mmo : this.getPlayers()) {
MapleCharacter character = (MapleCharacter) mmo;
if (character.isAlive()) {
MapleStatEffect statEffect = mii.getItemEffect(buff);
@@ -725,14 +775,14 @@ public class MapleMap {
}
public void killFriendlies(MapleMonster mob) {
- this.killMonster(mob, (MapleCharacter) getAllPlayer().get(0), false);
+ this.killMonster(mob, (MapleCharacter) getPlayers().get(0), false);
}
public void killMonster(int monsId) {
for (MapleMapObject mmo : getMapObjects()) {
if (mmo instanceof MapleMonster) {
if (((MapleMonster) mmo).getId() == monsId) {
- this.killMonster((MapleMonster) mmo, (MapleCharacter) getAllPlayer().get(0), false);
+ this.killMonster((MapleMonster) mmo, (MapleCharacter) getPlayers().get(0), false);
}
}
}
@@ -788,43 +838,6 @@ public class MapleMap {
}
}
- public List getAllPlayer() {
- return getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.PLAYER));
- }
-
-
- public List getAllPlayers() {
- List character = new LinkedList<>();
- chrRLock.lock();
- try {
- for (MapleCharacter a : characters) {
- character.add(a);
- }
- } finally {
- chrRLock.unlock();
- }
-
- return character;
- }
-
- public List getPlayersInRange(Rectangle box, List chr) {
- List character = new LinkedList<>();
- chrRLock.lock();
- try {
- for (MapleCharacter a : characters) {
- if (chr.contains(a.getClient().getPlayer())) {
- if (box.contains(a.getPosition())) {
- character.add(a);
- }
- }
- }
- } finally {
- chrRLock.unlock();
- }
-
- return character;
- }
-
public void destroyReactor(int oid) {
final MapleReactor reactor = getReactorByOid(oid);
TimerManager tMan = TimerManager.getInstance();
@@ -1052,12 +1065,12 @@ public class MapleMap {
final ScheduledFuture> monsterItemDrop = TimerManager.getInstance().register(new Runnable() {
@Override
public void run() {
- if (MapleMap.this.getMonsterById(m.getId()) != null && !MapleMap.this.getAllPlayer().isEmpty()) {
+ if (MapleMap.this.getMonsterById(m.getId()) != null && !MapleMap.this.getPlayers().isEmpty()) {
if (item.getItemId() == 4001101) {
MapleMap.this.riceCakes++;
MapleMap.this.broadcastMessage(MaplePacketCreator.serverNotice(6, "The Moon Bunny made rice cake number " + (MapleMap.this.riceCakes)));
}
- spawnItemDrop(m, (MapleCharacter) getAllPlayer().get(0), item, m.getPosition(), false, false);
+ spawnItemDrop(m, (MapleCharacter) getPlayers().get(0), item, m.getPosition(), false, false);
}
}
}, delay, delay);
@@ -1345,7 +1358,7 @@ public class MapleMap {
broadcastMessage(MaplePacketCreator.dropItemFromMapObject(drop, dropper.getPosition(), droppos, (byte) 0));
if (!everlast) {
- TimerManager.getInstance().schedule(new ExpireMapItemJob(drop), 180000);
+ TimerManager.getInstance().schedule(new ExpireMapItemJob(drop), ServerConstants.ITEM_EXPIRE_TIME);
activateItemReactors(drop, owner.getClient());
}
}
@@ -1438,7 +1451,7 @@ public class MapleMap {
}
chr.setMapId(mapid);
if (onFirstUserEnter.length() != 0 && !chr.hasEntered(onFirstUserEnter, mapid) && MapScriptManager.getInstance().scriptExists(onFirstUserEnter, true)) {
- if (getAllPlayer().size() <= 1) {
+ if (countPlayers() <= 1) {
chr.enteredScript(onFirstUserEnter, mapid);
MapScriptManager.getInstance().getMapScript(chr.getClient(), onFirstUserEnter, true);
}
@@ -2116,6 +2129,28 @@ public class MapleMap {
}
return null;
}
+
+ public void makeDisappearItemFromMap(MapleMapObject mapobj) {
+ if(mapobj instanceof MapleMapItem) {
+ makeDisappearItemFromMap((MapleMapItem) mapobj);
+ }
+ }
+
+ public void makeDisappearItemFromMap(MapleMapItem mapitem) {
+ if (mapitem != null && mapitem == getMapObject(mapitem.getObjectId())) {
+ mapitem.itemLock.lock();
+ try {
+ if (mapitem.isPickedUp()) {
+ return;
+ }
+ MapleMap.this.broadcastMessage(MaplePacketCreator.removeItemFromMap(mapitem.getObjectId(), 0, 0), mapitem.getPosition());
+ mapitem.setPickedUp(true);
+ } finally {
+ mapitem.itemLock.unlock();
+ MapleMap.this.removeMapObject(mapitem);
+ }
+ }
+ }
private class ExpireMapItemJob implements Runnable {
@@ -2127,19 +2162,7 @@ public class MapleMap {
@Override
public void run() {
- if (mapitem != null && mapitem == getMapObject(mapitem.getObjectId())) {
- mapitem.itemLock.lock();
- try {
- if (mapitem.isPickedUp()) {
- return;
- }
- MapleMap.this.broadcastMessage(MaplePacketCreator.removeItemFromMap(mapitem.getObjectId(), 0, 0), mapitem.getPosition());
- mapitem.setPickedUp(true);
- } finally {
- mapitem.itemLock.unlock();
- MapleMap.this.removeMapObject(mapitem);
- }
- }
+ makeDisappearItemFromMap(mapitem);
}
}
diff --git a/src/server/maps/MapleReactor.java b/src/server/maps/MapleReactor.java
index faad95f1d2..08d3cb2189 100644
--- a/src/server/maps/MapleReactor.java
+++ b/src/server/maps/MapleReactor.java
@@ -49,6 +49,7 @@ public class MapleReactor extends AbstractMapleMapObject {
private String name;
private boolean alive;
private boolean shouldCollect;
+ private boolean attackHit;
private Lock reactorLock = new ReentrantLock(true);
public MapleReactor(MapleReactorStats stats, int rid) {
@@ -114,6 +115,10 @@ public class MapleReactor extends AbstractMapleMapObject {
public int getReactorType() {
return stats.getType(state);
}
+
+ public boolean isRecentHitFromAttack() {
+ return attackHit;
+ }
public void setMap(MapleMap map) {
this.map = map;
@@ -175,14 +180,17 @@ public class MapleReactor extends AbstractMapleMapObject {
}
public void hitReactor(MapleClient c) {
- hitReactor(0, (short) 0, 0, c);
+ hitReactor(false, 0, (short) 0, 0, c);
}
- public synchronized void hitReactor(int charPos, short stance, int skillid, MapleClient c) {
+ public synchronized void hitReactor(boolean wHit, int charPos, short stance, int skillid, MapleClient c) {
try {
if(!this.isAlive()) {
return;
}
+
+ attackHit = wHit;
+
if(ServerConstants.USE_DEBUG == true) c.getPlayer().dropMessage(5, "Hitted REACTOR " + this.getId() + " with POS " + charPos + " , STANCE " + stance + " , SkillID " + skillid + " , STATE " + stats.getType(state) + " STATESIZE " + stats.getStateSize(state));
ReactorScriptManager.getInstance().onHit(c, this);
diff --git a/wz/Reactor.wz/9202005.img.xml b/wz/Reactor.wz/9202005.img.xml
index 85e7b17287..b30b98cd47 100644
--- a/wz/Reactor.wz/9202005.img.xml
+++ b/wz/Reactor.wz/9202005.img.xml
@@ -102,6 +102,14 @@
+
+
+
+
+
+
+
+
diff --git a/wz/Reactor.wz/9208003.img.xml b/wz/Reactor.wz/9208003.img.xml
index 1dd5c49432..618f6ca709 100644
--- a/wz/Reactor.wz/9208003.img.xml
+++ b/wz/Reactor.wz/9208003.img.xml
@@ -49,6 +49,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+