diff --git a/build/built-jar.properties b/build/built-jar.properties index 5e42a873ed..636854a414 100644 --- a/build/built-jar.properties +++ b/build/built-jar.properties @@ -1,4 +1,4 @@ -#Fri, 29 Sep 2017 17:49:16 -0300 +#Wed, 04 Oct 2017 01:18:34 -0300 C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2= diff --git a/build/classes/client/MapleCharacter$1.class b/build/classes/client/MapleCharacter$1.class index b26efa68c3..87c0423bca 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 db098ae8c2..408825533f 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 4f3667e5fe..3e208d85ff 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 f9ba251f0f..8ff337fdfb 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 9d404e4ebe..9ab4c366a7 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 be350f1f1e..80812804d5 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 257f322e92..e324653e57 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 006fafebcd..5b7fe85aeb 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 aaef8453a4..dbf2eaa39d 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 f87b4848e5..462a28dfb5 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$19.class b/build/classes/client/MapleCharacter$19.class index 6f769f5371..7ac743104c 100644 Binary files a/build/classes/client/MapleCharacter$19.class and b/build/classes/client/MapleCharacter$19.class differ diff --git a/build/classes/client/MapleCharacter$2.class b/build/classes/client/MapleCharacter$2.class index 4429e2e258..4ca6c42c00 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 c3c5666d8f..db78c174f2 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 d3992c0b8c..0e98bcac15 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 7f59b82959..543b9cae3a 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 c94e935a6a..d43741149b 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 df470b6237..199dab081e 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 77092d280b..f8aafc7cc9 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 2ebee46129..d99b8e9a87 100644 Binary files a/build/classes/client/MapleCharacter$9.class and b/build/classes/client/MapleCharacter$9.class differ diff --git a/build/classes/client/MapleCharacter$FameStatus.class b/build/classes/client/MapleCharacter$FameStatus.class index 260e6e461a..e259067265 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 0c296f4973..fc0b0782a7 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 3d4a4254ef..2104ebccee 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 a3fa9642f0..4778446029 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 acdcd0f204..a7ec50c456 100644 Binary files a/build/classes/client/MapleCharacter.class and b/build/classes/client/MapleCharacter.class differ diff --git a/build/classes/client/MapleClient$1.class b/build/classes/client/MapleClient$1.class index 306f6e2420..14f584027f 100644 Binary files a/build/classes/client/MapleClient$1.class and b/build/classes/client/MapleClient$1.class differ diff --git a/build/classes/client/MapleClient.class b/build/classes/client/MapleClient.class index f6d0077b02..71dc907cf1 100644 Binary files a/build/classes/client/MapleClient.class and b/build/classes/client/MapleClient.class differ diff --git a/build/classes/client/command/Commands.class b/build/classes/client/command/Commands.class index 2aa0dfe49e..026abb3fdb 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 ee42fd9fed..6b52815ae2 100644 Binary files a/build/classes/constants/ServerConstants.class and b/build/classes/constants/ServerConstants.class differ diff --git a/build/classes/net/mina/MaplePacketDecoder.class b/build/classes/net/mina/MaplePacketDecoder.class index 552028c078..c24236f2a0 100644 Binary files a/build/classes/net/mina/MaplePacketDecoder.class and b/build/classes/net/mina/MaplePacketDecoder.class differ diff --git a/build/classes/net/mina/MaplePacketEncoder.class b/build/classes/net/mina/MaplePacketEncoder.class index 7c7770456d..bb60a586b7 100644 Binary files a/build/classes/net/mina/MaplePacketEncoder.class and b/build/classes/net/mina/MaplePacketEncoder.class differ diff --git a/build/classes/net/server/channel/handlers/EnterCashShopHandler.class b/build/classes/net/server/channel/handlers/EnterCashShopHandler.class index 4596d166cc..aeb8da9dad 100644 Binary files a/build/classes/net/server/channel/handlers/EnterCashShopHandler.class and b/build/classes/net/server/channel/handlers/EnterCashShopHandler.class differ diff --git a/build/classes/net/server/channel/handlers/EnterMTSHandler.class b/build/classes/net/server/channel/handlers/EnterMTSHandler.class index a36be5dc2c..4e999fd1e4 100644 Binary files a/build/classes/net/server/channel/handlers/EnterMTSHandler.class and b/build/classes/net/server/channel/handlers/EnterMTSHandler.class differ diff --git a/build/classes/net/server/channel/handlers/PartyOperationHandler.class b/build/classes/net/server/channel/handlers/PartyOperationHandler.class index a4fdd26446..76444de686 100644 Binary files a/build/classes/net/server/channel/handlers/PartyOperationHandler.class and b/build/classes/net/server/channel/handlers/PartyOperationHandler.class differ diff --git a/build/classes/net/server/channel/handlers/PlayerLoggedinHandler.class b/build/classes/net/server/channel/handlers/PlayerLoggedinHandler.class index a66fe6e5f2..18b3a932ba 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/world/MapleParty$1.class b/build/classes/net/server/world/MapleParty$1.class index 6a20d80984..fc9bc16440 100644 Binary files a/build/classes/net/server/world/MapleParty$1.class and b/build/classes/net/server/world/MapleParty$1.class differ diff --git a/build/classes/net/server/world/MapleParty.class b/build/classes/net/server/world/MapleParty.class index 91de42acd5..f6e35efcc6 100644 Binary files a/build/classes/net/server/world/MapleParty.class and b/build/classes/net/server/world/MapleParty.class differ diff --git a/build/classes/net/server/world/World$1.class b/build/classes/net/server/world/World$1.class index 994daaa622..04ce90d4a1 100644 Binary files a/build/classes/net/server/world/World$1.class and b/build/classes/net/server/world/World$1.class differ diff --git a/build/classes/net/server/world/World.class b/build/classes/net/server/world/World.class index 1c43e8c721..91d2968bf9 100644 Binary files a/build/classes/net/server/world/World.class and b/build/classes/net/server/world/World.class differ diff --git a/build/classes/scripting/AbstractPlayerInteraction.class b/build/classes/scripting/AbstractPlayerInteraction.class index a05872ab41..db93f32582 100644 Binary files a/build/classes/scripting/AbstractPlayerInteraction.class and b/build/classes/scripting/AbstractPlayerInteraction.class differ diff --git a/build/classes/server/MapleItemInformationProvider$1.class b/build/classes/server/MapleItemInformationProvider$1.class index 7d3a14d0fb..b933fe76d4 100644 Binary files a/build/classes/server/MapleItemInformationProvider$1.class and b/build/classes/server/MapleItemInformationProvider$1.class differ diff --git a/build/classes/server/MapleItemInformationProvider$RewardItem.class b/build/classes/server/MapleItemInformationProvider$RewardItem.class index c36cd1ad94..574fe92265 100644 Binary files a/build/classes/server/MapleItemInformationProvider$RewardItem.class and b/build/classes/server/MapleItemInformationProvider$RewardItem.class differ diff --git a/build/classes/server/MapleItemInformationProvider$scriptedItem.class b/build/classes/server/MapleItemInformationProvider$scriptedItem.class index b84ff88cc6..6de16c88cb 100644 Binary files a/build/classes/server/MapleItemInformationProvider$scriptedItem.class and b/build/classes/server/MapleItemInformationProvider$scriptedItem.class differ diff --git a/build/classes/server/MapleItemInformationProvider.class b/build/classes/server/MapleItemInformationProvider.class index 2cee15cbb8..5fe4e6fd01 100644 Binary files a/build/classes/server/MapleItemInformationProvider.class and b/build/classes/server/MapleItemInformationProvider.class differ diff --git a/build/classes/server/life/MapleMonster$1.class b/build/classes/server/life/MapleMonster$1.class index 5eba265f2e..0b90120e43 100644 Binary files a/build/classes/server/life/MapleMonster$1.class and b/build/classes/server/life/MapleMonster$1.class differ diff --git a/build/classes/server/life/MapleMonster$2.class b/build/classes/server/life/MapleMonster$2.class index 7490d5a677..947aba94f0 100644 Binary files a/build/classes/server/life/MapleMonster$2.class and b/build/classes/server/life/MapleMonster$2.class differ diff --git a/build/classes/server/life/MapleMonster$3.class b/build/classes/server/life/MapleMonster$3.class index 7d4d94292f..da2f603b71 100644 Binary files a/build/classes/server/life/MapleMonster$3.class and b/build/classes/server/life/MapleMonster$3.class differ diff --git a/build/classes/server/life/MapleMonster$4.class b/build/classes/server/life/MapleMonster$4.class index 0877f7700d..2e0760ef23 100644 Binary files a/build/classes/server/life/MapleMonster$4.class and b/build/classes/server/life/MapleMonster$4.class differ diff --git a/build/classes/server/life/MapleMonster$5.class b/build/classes/server/life/MapleMonster$5.class index 62f960585a..58f188cec9 100644 Binary files a/build/classes/server/life/MapleMonster$5.class and b/build/classes/server/life/MapleMonster$5.class differ diff --git a/build/classes/server/life/MapleMonster$6.class b/build/classes/server/life/MapleMonster$6.class index 42c2817f64..295643d0d0 100644 Binary files a/build/classes/server/life/MapleMonster$6.class and b/build/classes/server/life/MapleMonster$6.class differ diff --git a/build/classes/server/life/MapleMonster$DamageTask.class b/build/classes/server/life/MapleMonster$DamageTask.class index 8cb72a9590..f7fd11c750 100644 Binary files a/build/classes/server/life/MapleMonster$DamageTask.class and b/build/classes/server/life/MapleMonster$DamageTask.class differ diff --git a/build/classes/server/life/MapleMonster.class b/build/classes/server/life/MapleMonster.class index 90784264d8..6a7f1efef2 100644 Binary files a/build/classes/server/life/MapleMonster.class and b/build/classes/server/life/MapleMonster.class differ diff --git a/build/classes/server/maps/MapleMap$1.class b/build/classes/server/maps/MapleMap$1.class index 40a1810dc0..80658c3088 100644 Binary files a/build/classes/server/maps/MapleMap$1.class and b/build/classes/server/maps/MapleMap$1.class differ diff --git a/build/classes/server/maps/MapleMap$10.class b/build/classes/server/maps/MapleMap$10.class index 978c142bf6..1fa5f138b3 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 334fe659da..d317c29661 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 75ab674d8e..f6f1c55fba 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 4633113cec..d9174819c9 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 e82823231e..3114ac5613 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 1273909d55..416d5f5615 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 0fb35420f3..cd76704b06 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 66922f4f7b..2509483fba 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 df7e9c0c33..dc4637f64f 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 b47e254fe6..1c77fd2f88 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$2.class b/build/classes/server/maps/MapleMap$2.class index ee1593f851..f384bcd8a8 100644 Binary files a/build/classes/server/maps/MapleMap$2.class and b/build/classes/server/maps/MapleMap$2.class differ diff --git a/build/classes/server/maps/MapleMap$20.class b/build/classes/server/maps/MapleMap$20.class index de685fc2ee..84c0f6e3e9 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 933606c589..ffd289db59 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 03b1c3a871..1523cfa102 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 7aeddfc257..6ac0109238 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 01f91ea1cc..8a5c6026de 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 f4f278057a..e409dd8327 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 c15d6b8442..2f5cea00d4 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 9db8188fdb..e59a680f42 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.class b/build/classes/server/maps/MapleMap$28.class index b86cca5db7..8349ecebd0 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$1.class b/build/classes/server/maps/MapleMap$29$1.class index a14b598c54..f166f7fff8 100644 Binary files a/build/classes/server/maps/MapleMap$29$1.class and b/build/classes/server/maps/MapleMap$29$1.class differ diff --git a/build/classes/server/maps/MapleMap$29.class b/build/classes/server/maps/MapleMap$29.class index eadd6bfb55..7374e8bff2 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 4d1c84a4c6..ceb2145abd 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$30.class b/build/classes/server/maps/MapleMap$30.class index 87862d5d50..027519c30a 100644 Binary files a/build/classes/server/maps/MapleMap$30.class and b/build/classes/server/maps/MapleMap$30.class differ diff --git a/build/classes/server/maps/MapleMap$4.class b/build/classes/server/maps/MapleMap$4.class index 4aa29578c9..85f0bb93b6 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 bf69df5149..5921e9aa36 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 006c02fdd8..76b76e08e6 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 fcadc5aa3d..3c75135efd 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 13a1508217..65652d9a72 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 e5c60041c1..bc3acfc77f 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 efba39b13e..552d48405c 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 0bece63c9f..5540d6b4ab 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 63445a468d..a9028052bd 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 3c91a89739..aaf146c8c9 100644 Binary files a/build/classes/server/maps/MapleMap.class and b/build/classes/server/maps/MapleMap.class differ diff --git a/build/classes/tools/MaplePacketCreator$2.class b/build/classes/tools/MaplePacketCreator$2.class index 766057277e..485e378320 100644 Binary files a/build/classes/tools/MaplePacketCreator$2.class and b/build/classes/tools/MaplePacketCreator$2.class differ diff --git a/build/classes/tools/MaplePacketCreator.class b/build/classes/tools/MaplePacketCreator.class index 80cc3a333b..1f6cabd445 100644 Binary files a/build/classes/tools/MaplePacketCreator.class and b/build/classes/tools/MaplePacketCreator.class differ diff --git a/dist/MapleSolaxia.jar b/dist/MapleSolaxia.jar index 5fccb629ef..c29d4b19e2 100644 Binary files a/dist/MapleSolaxia.jar and b/dist/MapleSolaxia.jar differ diff --git a/docs/mychanges_ptbr.txt b/docs/mychanges_ptbr.txt index f096866b4f..0a52870436 100644 --- a/docs/mychanges_ptbr.txt +++ b/docs/mychanges_ptbr.txt @@ -558,4 +558,11 @@ Adicionado Owl of Minerva. Corrigido um bug no sistema de checagem de slots. 28 Setembro 2017, -Adidionado wish tickets à AmoriaPQ. \ No newline at end of file +Adidionado wish tickets à AmoriaPQ. + +02 - 03 Outubro 2017, +Adicionado proteção de acesso concorrente em MapleParty. +Corrigido bug em sistema de distribuição de EXP para party. +Corrigido bug de overflow em distribuição de EXP. +Corrigido bug com scrolls não usando slots quando resultam em sucesso. +Refatorado sistema de schedules para disease expiretimes. \ No newline at end of file diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml index 6bd1c4fef3..1037c26341 100644 --- a/nbproject/private/private.xml +++ b/nbproject/private/private.xml @@ -3,28 +3,15 @@ - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/RecvOpcode.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/tools/data/input/GenericLittleEndianAccessor.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/maps/MapleHiredMerchant.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/PacketProcessor.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/SendOpcode.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/TakeDamageHandler.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/scripting/AbstractPlayerInteraction.java file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/constants/ServerConstants.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/world/World.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/FredrickHandler.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/OwlWarpHandler.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/RemoteStoreHandler.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/PlayerInteractionHandler.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/inventory/MapleInventory.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/tools/MaplePacketCreator.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/UseCashItemHandler.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/UseOwlOfMinervaHandler.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/MapleTrade.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/MapleInventoryManipulator.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/MapleMiniGame.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/MaplePlayerShop.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/tools/data/output/GenericLittleEndianWriter.java file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleCharacter.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleClient.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/Channel.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/tools/data/input/LittleEndianAccessor.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/life/MobSkill.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/MapleItemInformationProvider.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/tools/MaplePacketCreator.java diff --git a/scripts/event/KingPepeAndYetis.js b/scripts/event/KingPepeAndYetis.js new file mode 100644 index 0000000000..cd2c2064e8 --- /dev/null +++ b/scripts/event/KingPepeAndYetis.js @@ -0,0 +1,110 @@ +var minPlayers = 1; +var timeLimit = 20; //20 minutes +var eventTimer = 1000 * 60 * timeLimit; +var exitMap = 106021400; + +function init(){} + +function setup(difficulty, lobbyId){ + var eim = em.newInstance("KingPepe_" +lobbyId); + eim.getInstanceMap(106021500).resetFully(); + eim.getInstanceMap(106021500).allowSummonState(false); + respawn(eim); + eim.startEventTimer(eventTimer); + return eim; +} + +function afterSetup(eim){} + +function respawn(eim){ + var map = eim.getMapInstance(exitMap); + map.allowSummonState(true); + map.instanceMapRespawn(); + eim.schedule("respawn", 10000); +} + +function playerEntry(eim, player){ + var yetiMap = eim.getMapInstance(106021500); + player.changeMap(yetiMap, yetiMap.getPortal(1)); +} + +function scheduledTimeout(eim){ + var party = eim.getPlayers(); + + for(var i = 0; i < party.size(); i++) + playerExit(eim, party.get(i)); + + eim.dispose(); +} + +function playerRevive(eim, player){ + player.setHp(50); + player.setStance(0); + eim.unregisterPlayer(player); + player.changeMap(exitMap); + return false; +} + +function playerDead(eim, player){} + +function playerDisconnected(eim, player){ + var party = eim.getPlayers(); + + for(var i = 0; i < party.size(); i++){ + if(party.get(i).equals(player)) + removePlayer(eim, player); + else + playerExit(eim, party.get(i)); + } + eim.dispose(); +} + +function monsterValue(eim, mobId){ + return -1; +} + +function leftParty(eim, player){ + var party = eim.getPlayers(); + + if(party.size() < minPlayers){ + for(var i = 0; i < party.size(); i++){ + playerExit(eim, party.get(i)); + } + eim.dispose(); + } + else{ + playerExit(eim, player); + } +} + +function disbandParty(eim){} + +function playerUnregistered(eim, player){} + +function playerExit(eim, player){ + eim.unregisterPlayer(player); + player.changeMap(exitMap, 2); +} + +function moveMap(eim, player){ + if(player.getMap().getId() == exitMap){ + removePlayer(eim, player); + eim.dispose(); + } +} + +function removePlayer(eim, player){ + eim.unregisterPlayer(player); + player.getMap().removePlayer(player); + player.setMap(exitMap); +} + +function cancelSchedule(){} + +function dispose(){} + +function clearPQ(eim){} + +function monsterKilled(mob, eim){} + +function allMonstersDead(eim){} \ No newline at end of file diff --git a/scripts/event/MK_PrimeMinister.js b/scripts/event/MK_PrimeMinister.js new file mode 100644 index 0000000000..f987227b10 --- /dev/null +++ b/scripts/event/MK_PrimeMinister.js @@ -0,0 +1,108 @@ +var minPlayers = 1; +var entryMap = 106021402; +var exitMap = 106021600; + +function init(){} + +function setup(difficulty, lobbyId){ + var eim = em.newInstance("MK_PrimeMinister_" +lobbyId); + eim.getInstanceMap(106021601).resetFully(); + eim.getInstanceMap(106021601).allowSummonState(false); + respawn(eim); + return eim; +} + +function afterSetup(eim){} + +function respawn(eim){ + var map = eim.getMapInstance(entryMap); + map.allowSummonState(true); + map.instanceMapRespawn(); + eim.schedule("respawn", 10000); +} + +function playerEntry(eim, player){ + var weddinghall = eim.getMapInstance(106021601); + player.changeMap(weddinghall, weddinghall.getPortal(1)); +} + +function scheduledTimeout(eim){ + var party = eim.getPlayers(); + + for(var i = 0; i < party.size(); i++) + playerExit(eim, party.get(i)); + + eim.dispose(); +} + +function playerRevive(eim, player){ + player.setHp(50); + player.setStance(0); + eim.unregisterPlayer(player); + player.changeMap(entryMap); + return false; +} + +function playerDead(eim, player){} + +function playerDisconnected(eim, player){ + var party = eim.getPlayers(); + + for(var i = 0; i < party.size(); i++){ + if(party.get(i).equals(player)) + removePlayer(eim, player); + else + playerExit(eim, party.get(i)); + } + eim.dispose(); +} + +function monsterValue(eim, mobId){ + return -1; +} + +function leftParty(eim, player){ + var party = eim.getPlayers(); + + if(party.size() < minPlayers){ + for(var i = 0; i < party.size(); i++){ + playerExit(eim, party.get(i)); + } + eim.dispose(); + } + else{ + playerExit(eim, player); + } +} + +function disbandParty(eim){} + +function playerUnregistered(eim, player){} + +function playerExit(eim, player){ + eim.unregisterPlayer(player); + player.changeMap(entryMap, 2); +} + +function moveMap(eim, player){ + if(player.getMap().getId() == exitMap || player.getMap().getId() == entryMap){ + removePlayer(eim, player); + eim.dispose(); + } +} + +function removePlayer(eim, player){ + eim.unregisterPlayer(player); + player.getMap().removePlayer(player); + player.setMap(entryMap); +} + +function cancelSchedule(){} + +function dispose(){} + +function clearPQ(eim){} + +function monsterKilled(mob, eim){} + +function allMonstersDead(eim){} \ No newline at end of file diff --git a/scripts/map/onUserEnter/pepeking_effect.js b/scripts/map/onUserEnter/pepeking_effect.js new file mode 100644 index 0000000000..5fd8439196 --- /dev/null +++ b/scripts/map/onUserEnter/pepeking_effect.js @@ -0,0 +1,9 @@ +importPackage(Packages.server.life); + +function start(ms){ + var mobId = 3300000 + (Math.floor(Math.random() * 3) + 5); + var player = ms.getPlayer(); + var map = player.getMap(); + + map.spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(mobId), new java.awt.Point(-28, -67)); +} \ No newline at end of file diff --git a/scripts/npc/1052109.js b/scripts/npc/1052109.js index 29f5c64340..826517af31 100644 --- a/scripts/npc/1052109.js +++ b/scripts/npc/1052109.js @@ -19,7 +19,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -/* Trash Can +/* Trash Can 1 */ diff --git a/scripts/npc/1052110.js b/scripts/npc/1052110.js new file mode 100644 index 0000000000..0bba942db2 --- /dev/null +++ b/scripts/npc/1052110.js @@ -0,0 +1,31 @@ +/* + Trash Can 2 + Kerning Subway +*/ + +var status; + +function start() { + status = -1; + action(1, 0, 0); +} + +function action(mode, type, selection) { + if (mode == -1) { + cm.dispose(); + } else { + if (mode == 0 && type > 0) { + cm.dispose(); + return; + } + if (mode == 1) + status++; + else + status--; + + if(status == 0) { + cm.sendOk("Just a trash can sitting there."); + cm.dispose(); + } + } +} \ No newline at end of file diff --git a/scripts/npc/1052111.js b/scripts/npc/1052111.js new file mode 100644 index 0000000000..6183aa9d0e --- /dev/null +++ b/scripts/npc/1052111.js @@ -0,0 +1,51 @@ +/* + Trash Can 3 + Kerning Subway +*/ + +var status; + +function start(){ + status = -1; + action(1, 0, 0); +} + +function action(mode, type, selection){ + if(mode == -1){ + cm.dispose(); + return; + } + else{ + if(mode == 0 && status == 0){ + cm.dispose(); + return; + } + else if(mode == 0) + status--; + else + status++; + + + if(cm.isQuestStarted(20710)){ + if(!cm.hasItem(4032136)){ + cm.sendNext("You have found a #b#t4032136##k in the trash can! #i4032136#"); + + if(cm.canHold(4032136)){ + cm.gainItem(4032136, 1); + } + else{ + cm.sendOk("#i4032136# Not enough space in your ETC inventory."); + } + cm.dispose(); + } + else{ + cm.sendOk("Just a trash can sitting there."); + cm.dispose(); + } + } + else{ + cm.sendOk("Just a trash can sitting there."); + cm.dispose(); + } + } +} \ No newline at end of file diff --git a/scripts/npc/1052112.js b/scripts/npc/1052112.js new file mode 100644 index 0000000000..58909d5be0 --- /dev/null +++ b/scripts/npc/1052112.js @@ -0,0 +1,31 @@ +/* + Trash Can 4 + Kerning Subway +*/ + +var status; + +function start() { + status = -1; + action(1, 0, 0); +} + +function action(mode, type, selection) { + if (mode == -1) { + cm.dispose(); + } else { + if (mode == 0 && type > 0) { + cm.dispose(); + return; + } + if (mode == 1) + status++; + else + status--; + + if(status == 0) { + cm.sendOk("Just a trash can sitting there."); + cm.dispose(); + } + } +} \ No newline at end of file diff --git a/scripts/npc/1092000.js b/scripts/npc/1092000.js index 74d6a2ae63..fcb55d97d8 100644 --- a/scripts/npc/1092000.js +++ b/scripts/npc/1092000.js @@ -3,19 +3,16 @@ Copyright (C) 2008 Patrick Huy Matthias Butz Jan Christian Meyer - This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation version 3 as published by the Free Software Foundation. You may not use, modify or distribute this program under any other version of the GNU Affero General Public License. - This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. - You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ @@ -24,28 +21,37 @@ * @Author xXOsirisXx (BubblesDev) */ -status = -1; +var status; function start() { - cm.sendNext("Okay, I'll now send you to the stable where my cows are. Watch out for the calves that drink all the milk. You don't want your effort to go to waste."); + status = -1; + action(1, 0, 0); } function action(mode, type, selection){ - if (mode == -1 || !cm.isQuestStarted(2180)){ - cm.dispose(); - return; - } else if (mode == 0) - status--; - else - status++; - if (status == 1) - cm.sendNextPrev("It won't be easy to tell at a glance between a calf and a cow. Those calves may only be a month or two old, but they have already grown to the size of their mother. They even look alike...even I get confused at times! Good luck!"); - else if (status == 2) { - if (cm.canHold(4031847)) { - cm.gainItem(4031847, 1); - cm.warp(912000100); - } else - cm.sendNextPrev("I can't give you the empty bottle because your inventory is full. Please make some room in your Etc window."); - cm.dispose(); - } + if (mode == -1 || !cm.isQuestStarted(2180)){ + cm.dispose(); + return; + } + else{ + if (mode == 1) status++; + else status --; + + if (status == 0){ + cm.sendNext("Okay, I'll now send you to the stable where my cows are. Watch out for the calves that drink all the milk. You don't want your effort to go to waste."); + } + else if (status == 1){ + cm.sendNextPrev("It won't be easy to tell at a glance between a calf and a cow. Those calves may only be a month or two old, but they have already grown to the size of their mother. They even look alike...even I get confused at times! Good luck!"); + } + else if (status == 2){ + if (cm.canHold(4031847)){ + cm.gainItem(4031847, 1); + cm.warp(912000100); + } + else{ + cm.sendOk("I can't give you the empty bottle because your inventory is full. Please make some room in your Etc window."); + } + cm.dispose(); + } + } } \ No newline at end of file diff --git a/scripts/npc/1300013.js b/scripts/npc/1300013.js new file mode 100644 index 0000000000..22913c9967 --- /dev/null +++ b/scripts/npc/1300013.js @@ -0,0 +1,40 @@ +/* + NPC: Blocked Entrance (portal?) + MAP: Mushroom Castle - East Castle Tower (106021400) +*/ + +var status; + +function start(){ + status = -1; + action(1, 0, 0); +} + +function action(mode, type, selection){ + if(mode == -1){ + cm.dispose(); + return; + } + else if(mode == 0 && status == 0){ + cm.dispose(); + return; + } + else if(mode == 0) + status--; + else + status++; + + + if(status == 0){ + cm.sendSimple("#L1#Enter to fight #bKing Pepe#k and #bYeti Brothers#k.#l"); + } + else if(status == 1){ + if(selection == 1){ + var pepe = cm.getEventManager("KingPepeAndYetis"); + pepe.setProperty("player", cm.getPlayer().getName()); + pepe.startInstance(cm.getPlayer()); + cm.dispose(); + return; + } + } +} \ No newline at end of file diff --git a/scripts/npc/2060005.js b/scripts/npc/2060005.js index 13937b4b4c..4ff99de789 100644 --- a/scripts/npc/2060005.js +++ b/scripts/npc/2060005.js @@ -46,7 +46,7 @@ function start() { } } else { - cm.sendSimple("Only few adventurers, from a selected public, are eligible to protect the Watch Hog."); + cm.sendOk("Only few adventurers, from a selected public, are eligible to protect the Watch Hog."); } cm.dispose(); diff --git a/scripts/npc/9000017.js b/scripts/npc/9000017.js index f9ee0e2205..e074b84fbc 100644 --- a/scripts/npc/9000017.js +++ b/scripts/npc/9000017.js @@ -46,7 +46,7 @@ function action(mode, type, selection) { var itemSet = new Array(2049100, 7777777); var matSet = new Array(new Array(4031203,4001356,4000136,4000082,4001126,4080100,4000021,4003005)); - var matQtySet = new Array(new Array(10,6,4,8,8,1,20,12)); + var matQtySet = new Array(new Array(100,60,40,80,80,8,200,120)); var costSet = new Array(1200000, 7777777); item = itemSet[selectedItem]; mats = matSet[selectedItem]; diff --git a/scripts/portal/TD_MC_Egate.js b/scripts/portal/TD_MC_Egate.js index 88a7ca6401..fe82c1f95c 100644 --- a/scripts/portal/TD_MC_Egate.js +++ b/scripts/portal/TD_MC_Egate.js @@ -1,5 +1,5 @@ function enter(pi) { pi.playPortalSound(); - pi.warp(106021300, 0); + pi.warp(106021300, 1); return true; } \ No newline at end of file diff --git a/scripts/portal/TD_MC_enterboss1.js b/scripts/portal/TD_MC_enterboss1.js index 9f2d7ad6a6..525c8e64f4 100644 --- a/scripts/portal/TD_MC_enterboss1.js +++ b/scripts/portal/TD_MC_enterboss1.js @@ -1,3 +1,23 @@ function enter(pi) { - pi.openNpc(1300013); + var questProgress = pi.getQuestProgress(2330, 3300005) + pi.getQuestProgress(2330, 3300006) + pi.getQuestProgress(2330, 3300007); //3 Yetis + + if(questProgress == 3 && !pi.hasItem(4032388) && !pi.isQuestCompleted(2332)){ + if(pi.canHold(4032388)){ + pi.getPlayer().message("You have aquired a key to the Wedding Hall. King Pepe must have dropped it.") + pi.gainItem(4032388, 1); + } + else{ + pi.getPlayer().message("Please make room in your ETC inventory."); + } + } + + if(pi.isQuestStarted(2330) && questProgress < 3){ + pi.openNpc(1300013); + } + else{ + pi.playPortalSound(); + pi.warp(106021401, 1); + } + + return true; } \ No newline at end of file diff --git a/scripts/portal/TD_MC_enterboss2.js b/scripts/portal/TD_MC_enterboss2.js index 41b63bcb0c..70994ceeb0 100644 --- a/scripts/portal/TD_MC_enterboss2.js +++ b/scripts/portal/TD_MC_enterboss2.js @@ -1,35 +1,48 @@ -/* - This file is part of the ZeroFusion MapleStory Server - Copyright (C) 2008 Patrick Huy - Matthias Butz - Jan Christian Meyer - ZeroFusion organized by "RMZero213" - - 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 . -*/ - -var dungeonid = 106021600; -var dungeons = 10; - function enter(pi) { - for(var i = 0; i < dungeons; i++) { - if (pi.getMap(dungeonid + i).getCharactersSize() == 0) { - pi.warp(dungeonid + i, 0); - return true; - } + if(pi.isQuestCompleted(2333) && pi.isQuestStarted(2331) && !pi.hasItem(4001318)){ + pi.getPlayer().message("Lost the Royal Seal, eh? Worry not! Kevin's code here to save your hide."); + if(pi.canHold(4001318)){ + pi.gainItem(4001318, 1); + } + else{ + pi.getPlayer().message("Hey, how do you plan to hold this Seal when your inventory is full?"); + } } - pi.playerMessage(5, "All of the Mini-Dungeons are in use right now, please try again later."); - return false; -} + + if(pi.isQuestCompleted(2333)){ + pi.playPortalSound(); + pi.warp(106021600, 1); + return true; + } + else if(pi.isQuestStarted(2332) && pi.hasItem(4032388)){ + if(pi.getPlayer().getParty() != null){ + pi.getPlayer().showHint("The next part of the quest is solo only! Must leave party."); + return false; + } + else{ + pi.forceCompleteQuest(2332, 1300002); + pi.getPlayer().message("You've found the princess!"); + pi.giveCharacterExp(4400 * 1.5, pi.getPlayer()); + var pm = pi.getEventManager("MK_PrimeMinister"); + pm.setProperty("player", pi.getPlayer().getName()); + pm.startInstance(pi.getPlayer()); + return true; + } + } + else if(pi.isQuestStarted(2333) || (pi.isQuestCompleted(2332) && !pi.isQuestStarted(2333))){ + if(pi.getPlayer.getParty() != null){ + pi.getPlayer().showHint("The next part of the quest is solo only! Must leave party."); + return false; + } + else{ + var pm = pi.getEventManager("MK_PrimeMinister"); + pm.setProperty("player", pi.getPlayer().getName()); + pm.startInstance(pi.getPlayer()); + return true; + } + } + else{ + pi.getPlayer().message("The door seems to be locked. Perhaps I can find a key to open it..."); + return false; + } +} \ No newline at end of file diff --git a/scripts/portal/end_cow.js b/scripts/portal/end_cow.js new file mode 100644 index 0000000000..5960392204 --- /dev/null +++ b/scripts/portal/end_cow.js @@ -0,0 +1,22 @@ +/* + By: Kevin + Map: Hidden Chamber - The Nautilus - Stable (912000100) + Quest: Find Fresh Milk (2180) +*/ + +function enter(pi){ + if (pi.isQuestStarted(2180) && (pi.hasItem(4031847) || pi.hasItem(4031848) || pi.hasItem(4031849) || pi.hasItem(4031850))){ + if (pi.hasItem(4031850)){ + pi.warp(120000103); + return true; + } + else{ + pi.getPlayer().dropMessage(5, "Your milk jug is not full..."); + return false; + } + } + else{ + pi.warp(120000103); + return true; + } +} \ No newline at end of file diff --git a/scripts/portal/go_secretroom.js b/scripts/portal/go_secretroom.js new file mode 100644 index 0000000000..cd87306ea9 --- /dev/null +++ b/scripts/portal/go_secretroom.js @@ -0,0 +1,16 @@ +function enter(pi) { + + if(!pi.isQuestStarted(2335) || (pi.isQuestStarted(2335) && !pi.hasItem(4032405))){ + pi.getPlayer().message("The door is locked securely. I will need a key if I want to go in there."); + return false; + } + + if(pi.isQuestStarted(2335) && pi.hasItem(4032405)){ + pi.forceCompleteQuest(2335, 1300002); + pi.giveCharacterExp(5000 * 1.5, pi.getPlayer()); + pi.gainItem(4032405, -1); + } + pi.playPortalSound(); + pi.warp(106021001, 1); + return true; +} \ No newline at end of file diff --git a/scripts/portal/out_pepeking.js b/scripts/portal/out_pepeking.js new file mode 100644 index 0000000000..6be6f1059a --- /dev/null +++ b/scripts/portal/out_pepeking.js @@ -0,0 +1,9 @@ +function enter(pi) { + var eim = pi.getEventInstance(); + eim.stopEventTimer(); + eim.dispose(); + + pi.playPortalSound(); + pi.warp(106021400, 2); + return true; +} \ No newline at end of file diff --git a/scripts/quest/20710.js b/scripts/quest/20710.js new file mode 100644 index 0000000000..6e6bdd7486 --- /dev/null +++ b/scripts/quest/20710.js @@ -0,0 +1,35 @@ +/* + Author: DietStory dev team + NPC: Matthias + Quest: Hidden Inside the Trash Can +*/ + + +var status = -1; + +function start(mode, type, selection){ + if(mode == -1){ + qm.dispose(); + return; + } + else if(mode == 0 && status == 0){ + qm.sendOk("What? Are you declining the mission? Fine, do it like that. I'll just report it straight to #p1101002#."); + qm.dispose(); + return; + } + else if(mode == 0){ + status--; + } + else{ + status++; + } + + + if(status == 0){ + qm.sendAcceptDecline("You don't really instill confidence in me, but since you're a Cygnus Knight and all... and since no one else can go on a search right now... Okay, let me explain to you what this mission is about."); + } + else if(status == 1){ + qm.forceStartQuest(); + qm.dispose(); + } +} \ No newline at end of file diff --git a/scripts/quest/2293.js b/scripts/quest/2293.js new file mode 100644 index 0000000000..1119170795 --- /dev/null +++ b/scripts/quest/2293.js @@ -0,0 +1,110 @@ +/* + This file is part of the DietStory Maple Story Server + Copyright (C) 2017 + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation version 3 as published by + the Free Software Foundation. You may not use, modify or distribute + this program under any other version of the GNU Affero General Public + License. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +/* Author: Benji + NPC Name: Maestro Rho + Map(s): Kerning Square Lobby + Description: The Last Song +*/ + +importPackage(Packages.client); + +var status = -1; + +function start(mode, type, selection) { + if(mode == -1 || (mode == 0 && status == 0)){ + qm.dispose(); + return; + } + else if(mode == 0) + status--; + else + status++; + + if(status == 0) + { + qm.sendNext("Do you remember the last song that the Spirit of Rock played? I can think of a few songs that he may be imitating, so listen carefully and tell me which song it is. #bYou only get one chance,#k so please choose wisely."); + } + qm.forceStartQuest(); + qm.dispose(); +} + +function end(mode, type, selection) +{ + if(mode == -1 || (mode == 0 && status == 0)){ + qm.dispose(); + return; + } + else if(mode == 0) + status--; + else + status++; + + if (status == 0) + { + qm.sendSimple("Here, I'll give you some samples. Please listen to them and choose one. Please listen carefully before making your choide.\r\n\ + \t#b#L1# Listen to song No. 1#l \r\n\ + \t#L2# Listen to Song No. 2#l \r\n\ + \t#L3# Listen to Song No. 3#l \r\n\ + \r\n\ + \t#e#L4# Enter the correct song.#l"); + } + else if(status == 1) + { + if(selection == 1) + { + qm.playSound("Party1/Failed"); + qm.sendOk("Awkwardly familiar..."); + status = -1; + } + else if(selection == 2) + { + qm.playSound("Coconut/Failed"); + qm.sendOk("Was it this?"); + status = -1; + } + else if(selection == 3) + { + qm.playSound("quest2293/Die"); + qm.sendOk("You heard that?"); + status = -1; + } + else if(selection == 4) + { + qm.sendGetNumber("Now, please tell me the answer. You only get #bone chance#k, so please choose wisely. Please enter #b1, 2, or 3#k in the window below.\r\n",1,1,3); + } + } + else if(status == 2) + { + if(selection == 1) + { + qm.sendOk("Obviously you don't enjoy music."); + qm.dispose(); + } + else if(selection == 2) + { + qm.sendOk("I suppose you could get #b#eone#n#k more chance."); + qm.dispose(); + } + else if(selection == 3) + { + qm.sendOk("So that was the song he was playing... Well, it wasn't my song after all, but I'm glad I can know that now with certainty. Thank you so much."); + qm.gainExp(32500 * qm.getPlayer().getExpRate()); + qm.forceCompleteQuest(); + qm.dispose(); + } + } +} \ No newline at end of file diff --git a/scripts/quest/2325.js b/scripts/quest/2325.js new file mode 100644 index 0000000000..2704bba250 --- /dev/null +++ b/scripts/quest/2325.js @@ -0,0 +1,30 @@ +/* + QUEST: Jame's Whereabouts (1) + NPC: James +*/ + +var status = -1; + +function end(mode, type, selection){ + if(mode == -1){ + qm.dispose(); + return; + } + else if(mode == 0) + status--; + else + status++; + + if(status == 0){ + qm.sendNext("I... I am scared... Please... please help me..."); + } + else if(status == 1){ + qm.sendNextPrev("Don't be afriad, #b#p1300005##k sent me here.", 2); + } + else if(status == 2){ + qm.sendOk("What? My brother sent you here? Ahhh... I am safe now. Thank you so much..."); + qm.forceCompleteQuest(); + qm.gainExp(6000 * qm.getPlayer().getExpRate()); + qm.dispose(); + } +} \ No newline at end of file diff --git a/scripts/quest/2327.js b/scripts/quest/2327.js new file mode 100644 index 0000000000..2299f14a8c --- /dev/null +++ b/scripts/quest/2327.js @@ -0,0 +1,33 @@ +/* + QUEST: James's Whereabouts (3) + NPC: James + Why tf does this quest exist?! +*/ + +var status = -1; + +function start(mode, type, selection){ + if(mode == -1){ + qm.dispose(); + return; + } + else if(mode == 0 && status == 0){ + qm.dispose(); + return; + } + else if(mode == 0) + status--; + else + status++; + + if(status == 0){ + qm.sendNext("Hey! Thank you for bringing me a #b#t4001317##k."); + } + else if(status == 1){ + qm.sendNextPrev("I plan to escape from here wearing the #b#t4001317##k. Give me a minute to put it on. Talk to you soon..."); + } + else if(status == 2){ + qm.forceStartQuest(); + qm.dispose(); + } +} \ No newline at end of file diff --git a/scripts/quest/2332.js b/scripts/quest/2332.js new file mode 100644 index 0000000000..432a2f9858 --- /dev/null +++ b/scripts/quest/2332.js @@ -0,0 +1,17 @@ +/* + QUEST: Where's Violetta? + NPC: none +*/ + +var status = -1; + +function start(mode, type, selection){ + if(qm.hasItem(4032388) && !qm.isQuestStarted(2332)){ + qm.forceStartQuest(); + qm.getPlayer().showHint("I must find Violetta. (quest started)"); + } + qm.dispose(); +} + +function end(mode, type, selection){ +} \ No newline at end of file diff --git a/scripts/quest/2333.js b/scripts/quest/2333.js new file mode 100644 index 0000000000..2eea658d7c --- /dev/null +++ b/scripts/quest/2333.js @@ -0,0 +1,65 @@ +/* + QUEST: Where's Violetta? + NPC: none +*/ +importPackage(Packages.server.life); + +var status = -1; +var timeLimit = 10; //10 minutes +var eventTimer = 1000 * 60 * timeLimit; +var mobId = 3300008; //Prime Minister + +function start(mode, type, selection){ + if(mode == -1 || (mode == 0 && status == 0)){ + qm.dispose(); + return; + } + else if(mode == 0) + status--; + else + status++; + + + if(status == 0){ + qm.sendAcceptDecline("Please help me!"); + } + else if(status == 1){ + qm.sendNext("The #bPrime Minister#k is the one who plotted all this! Oh no! Here he comes..."); + } + else if (status == 2){ + qm.forceStartQuest(); + var eim = qm.getEventInstance(); + eim.startEventTimer(eventTimer); + qm.getPlayer().getMap().getPortal(1).setPortalState(false); + qm.getPlayer().getMap().spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(mobId), new java.awt.Point(292, 143)); + qm.dispose(); + } +} + +function end(mode, type, selection){ + if(mode == -1 || (mode == 0 && status == 0)){ + qm.dispose(); + return; + } + else if(mode == 0) + status--; + else + status++; + + + if(status == 0){ + qm.sendNext("Hurray! #b#h ##k you defeated the #bPrime Minister#k."); + } + else if(status == 1){ + qm.gainExp(15000 * qm.getPlayer().getExpRate()); + qm.forceCompleteQuest(); + + var eim = qm.getEventInstance(); + qm.getPlayer().getMap().getPortal(1).setPortalState(true); + eim.stopEventTimer(); + eim.warpEventTeam(106021600); + + eim.dispose(); + qm.dispose(); + } +} \ No newline at end of file diff --git a/scripts/quest/2334.js b/scripts/quest/2334.js new file mode 100644 index 0000000000..ac0e2aea87 --- /dev/null +++ b/scripts/quest/2334.js @@ -0,0 +1,46 @@ +/* + QUEST: The Identity of the Princess + NPC: Violetta +*/ + +var status = -1; + +function start(mode, type, selection){ + if(mode == -1 || (mode == 0 && status == 0)){ + qm.dispose(); + return; + } + else if(mode == 0) + status--; + else + status++; + + + if(status == 0){ + qm.forceStartQuest(); + qm.sendNext("Thank you so much, #b#h ##k. You are the hero that has saved our empire from danger. I'm so grateful for what you've done. I dont know how to thank you. And please understand why I can't show you my face."); + } + else if(status == 1){ + qm.sendNextPrev("It's humiliating to say this, but ever since I was a baby, my family has kept my face veiled from the world. They feared of men falling hopelessly in love with me. I've grown so accustomed to it that I even shy away from women. I know, it's rude of me to have my back turned against the hero, but I'll need some time to muster my courage before I can greet you face to face."); + } + else if(status == 2){ + qm.sendNextPrev("I see...\r\n#b(Wow, how pretty could she be?)", 2); + } + else if(status == 3){ + qm.sendNextPrev("#b(What the--)", 2); + } + else if(status == 4){ + qm.sendNextPrev("#b(Is that what's considered pretty in the world of mushrooms?!)", 2); + } + else if(status == 5){ + qm.sendNextPrev("I'm so shy, I'm blushing. Anyways, thank you, #b#h ##k."); + } + else if(status == 6){ + qm.forceStartQuest(); + qm.gainExp(1000 * qm.getPlayer().getExpRate()); + qm.forceCompleteQuest(); + qm.dispose(); + } +} + +function end(mode, type, selection){} \ No newline at end of file diff --git a/scripts/quest/2335.js b/scripts/quest/2335.js new file mode 100644 index 0000000000..96117e0e4c --- /dev/null +++ b/scripts/quest/2335.js @@ -0,0 +1,41 @@ +/* + QUEST: Eliminating the Rest + NPC: Violetta +*/ + +var status = -1; + +function start(mode, type, selection){ + if(mode == -1 || (mode == 0 && status == 0)){ + qm.dispose(); + return; + } + else if(mode == 0) + status--; + else + status++; + + + if(status == 0){ + qm.sendNext("This is not the end, #b#h ##k. Minions of the #bPrime Minister#k can still be found scattered throughout the castle."); + } + else if(status == 1){ + qm.sendAcceptDecline("From what I've heard, there is a place near #bSkyscraper 3#k where a group of Prime Minister's minions can be found. I've picked up a key that the Prime Minister dropped the other day. Here, use this key."); + } + else if(status == 2){ + if(qm.canHold(4032405)){ + qm.gainItem(4032405, 1); + qm.sendNext("For one last time, good luck."); + } + else{ + qm.sendOk("Please have a free space in your ETC inventory."); + qm.dispose(); + } + } + else if(status == 3){ + qm.forceStartQuest(); + qm.dispose(); + } +} + +function end(mode, type, selection){} \ No newline at end of file diff --git a/scripts/quest/2342.js b/scripts/quest/2342.js new file mode 100644 index 0000000000..6c8aed8d0d --- /dev/null +++ b/scripts/quest/2342.js @@ -0,0 +1,28 @@ +/* + QUEST: Recovered Royal Seal. + NPC: Violetta +*/ + +var status = -1; + +function start(mode, type, selection){ + if(!qm.hasItem(4001318) && qm.isQuestStarted(2331) && !qm.isQuestCompleted(2331)){ + if(qm.canHold(4001318)){ + qm.forceStartQuest(); + qm.gainItem(4001318, 1); + qm.forceCompleteQuest(); + qm.sendOk("Looks like you forgot to pick up the #b#t4001318##k when you fought with the #bPrime Minister#k. This is very important to our kingdom, so please deliver this to my father as soon as possible."); + qm.dispose(); + } + else{ + qm.sendOk("Please free up one spot in your ETC inventory"); + qm.dispose(); + } + } + else{ + qm.dispose(); + } +} + +function end(mode, type, selection){ +} \ No newline at end of file diff --git a/sql/db_database.sql b/sql/db_database.sql index 36024833ee..e089143276 100644 --- a/sql/db_database.sql +++ b/sql/db_database.sql @@ -21079,7 +21079,8 @@ INSERT INTO `shops` (`shopid`, `npcid`) VALUES -- missing shops INSERT INTO `shops` (`shopid`, `npcid`) VALUES ( 57, 2002001 ), -(1052116, 1052116); +(1052116, 1052116), +(1301000, 1301000); INSERT INTO `shopitems` ( `shopid`, `itemid`, `price`, `position`) VALUES ( 57, 3990000, 500, 1 ), diff --git a/sql/db_drops.sql b/sql/db_drops.sql index a7cced0499..f021bd77f7 100644 --- a/sql/db_drops.sql +++ b/sql/db_drops.sql @@ -19779,7 +19779,8 @@ USE `maplesolaxia`; (2130100, 4001367, 1, 1, 28257, 10000), (1110100, 4001369, 1, 1, 28259, 10000), (1210101, 4001370, 1, 1, 28260, 10000), -(1110101, 4001371, 1, 1, 28261, 10000); +(1110101, 4001371, 1, 1, 28261, 10000), +(3300003, 4001317, 1, 1, 2326, 20000); # (dropperid, itemid, minqty, maxqty, questid, chance) # delete item drops from other mobs named Freezer @@ -19929,6 +19930,9 @@ USE `maplesolaxia`; # remove belts dropping from mobs DELETE FROM drop_data WHERE itemid>=1132000 AND itemid<=1132004; + # remove Liar Tree Sap (unusable) + DELETE FROM drop_data WHERE itemid=2049101; + # remove items being dropped from mobs in HPQ DELETE FROM drop_data WHERE dropperid >= 9300061 AND dropperid <= 9300064; DELETE FROM drop_data WHERE dropperid >= 9300081 AND dropperid <= 9300083; @@ -20549,6 +20553,12 @@ USE `maplesolaxia`; (9400533, 4031597, 1, 1, 0, 999999), (9400534, 4031597, 1, 1, 0, 999999); + -- Thanks to DietStory dev team + -- There are two Jr. Boogies mob ids for some unknown reason. 3230301 had no drops, but 3230300 had all the correct drops. + -- Just copying the drops from the one with the correct drop data. + INSERT IGNORE INTO drop_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`) + SELECT 3230301, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance` FROM drop_data WHERE dropperid = 3230300; + # update quest reactor items UPDATE reactordrops SET questid=2086 WHERE itemid=4031165; UPDATE reactordrops SET questid=3407 WHERE itemid=4031141; diff --git a/sql/db_shopupdate.sql b/sql/db_shopupdate.sql index 14bc29e15e..06f45652bb 100644 --- a/sql/db_shopupdate.sql +++ b/sql/db_shopupdate.sql @@ -283,4 +283,21 @@ INSERT INTO `shopitems` ( `shopid`, `itemid`, `price`, `pitch`, `position`) VALU (1203590, 2000003, 200, 0, 184), (1203590, 2000002, 320, 0, 188), (1203590, 2000001, 160, 0, 192), - (1203590, 2000000, 50, 0, 196); \ No newline at end of file + (1203590, 2000000, 50, 0, 196), + (1301000, 2330000, 600, 0, 1), + (1301000, 2070000, 500, 0, 2), + (1301000, 2061000, 1, 0, 3), + (1301000, 2060000, 1, 0, 4), + (1301000, 2030000, 400, 0, 5), + (1301000, 2022000, 1650, 0, 6), + (1301000, 2022003, 1100, 0, 7), + (1301000, 2002005, 500, 0, 8), + (1301000, 2002004, 500, 0, 9), + (1301000, 2002002, 500, 0, 10), + (1301000, 2002001, 400, 0, 11), + (1301000, 2002000, 500, 0, 12), + (1301000, 2000006, 620, 0, 13), + (1301000, 2000003, 200, 0, 14), + (1301000, 2000002, 320, 0, 15), + (1301000, 2000015, 160, 0, 16), + (1301000, 2000000, 50, 0, 17); \ No newline at end of file diff --git a/src/client/MapleCharacter.java b/src/client/MapleCharacter.java index ec7b35e8bb..58a332a990 100644 --- a/src/client/MapleCharacter.java +++ b/src/client/MapleCharacter.java @@ -242,6 +242,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { private Map activeCouponRates = new LinkedHashMap<>(); private EnumMap effects = new EnumMap<>(MapleBuffStat.class); private Map buffEffectsCount = new LinkedHashMap<>(); + private Map diseaseExpires = new LinkedHashMap<>(); private Map> buffEffects = new LinkedHashMap<>(); private Map buffExpires = new LinkedHashMap<>(); private Map keymap = new LinkedHashMap<>(); @@ -255,6 +256,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { private ScheduledFuture skillCooldownTask = null; private ScheduledFuture buffExpireTask = null; private ScheduledFuture itemExpireTask = null; + private ScheduledFuture diseaseExpireTask = null; private ScheduledFuture recoveryTask = null; private ScheduledFuture extraRecoveryTask = null; private ScheduledFuture chairRecoveryTask = null; @@ -263,6 +265,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { private Lock chrLock = new ReentrantLock(); private Lock effLock = new ReentrantLock(); private Lock petLock = new ReentrantLock(); + private Lock prtLock = new ReentrantLock(); private Map> excluded = new LinkedHashMap<>(); private Set excludedItems = new LinkedHashSet<>(); private List crushRings = new ArrayList<>(); @@ -866,8 +869,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } public static boolean canCreateChar(String name) { + String lname = name.toLowerCase(); for (String nameTest : BLOCKED_NAMES) { - if (name.toLowerCase().contains(nameTest)) { + if (lname.contains(nameTest)) { return false; } } @@ -1056,10 +1060,11 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { public MapleMap getWarpMap(int map) { MapleMap target; - if (getEventInstance() == null) { + EventInstanceManager eim = getEventInstance(); + if (eim == null) { target = client.getChannelServer().getMapFactory().getMap(map); } else { - target = getEventInstance().getMapInstance(map); + target = eim.getMapInstance(map); } return target; } @@ -1070,11 +1075,13 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } private void eventChangedMap(int map) { - if (getEventInstance() != null) getEventInstance().changedMap(this, map); + EventInstanceManager eim = getEventInstance(); + if (eim != null) eim.changedMap(this, map); } private void eventAfterChangedMap(int map) { - if (getEventInstance() != null) getEventInstance().afterChangedMap(this, map); + EventInstanceManager eim = getEventInstance(); + if (eim != null) eim.afterChangedMap(this, map); } public boolean canRecoverLastBanish() { @@ -1117,8 +1124,10 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { public void changeMap(int map) { MapleMap warpMap; - if (getEventInstance() != null) { - warpMap = getEventInstance().getMapInstance(map); + EventInstanceManager eim = getEventInstance(); + + if (eim != null) { + warpMap = eim.getMapInstance(map); } else { warpMap = client.getChannelServer().getMapFactory().getMap(map); } @@ -1128,8 +1137,10 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { public void changeMap(int map, int portal) { MapleMap warpMap; - if (getEventInstance() != null) { - warpMap = getEventInstance().getMapInstance(map); + EventInstanceManager eim = getEventInstance(); + + if (eim != null) { + warpMap = eim.getMapInstance(map); } else { warpMap = client.getChannelServer().getMapFactory().getMap(map); } @@ -1139,8 +1150,10 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { public void changeMap(int map, String portal) { MapleMap warpMap; - if (getEventInstance() != null) { - warpMap = getEventInstance().getMapInstance(map); + EventInstanceManager eim = getEventInstance(); + + if (eim != null) { + warpMap = eim.getMapInstance(map); } else { warpMap = client.getChannelServer().getMapFactory().getMap(map); } @@ -1150,8 +1163,10 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { public void changeMap(int map, MaplePortal portal) { MapleMap warpMap; - if (getEventInstance() != null) { - warpMap = getEventInstance().getMapInstance(map); + EventInstanceManager eim = getEventInstance(); + + if (eim != null) { + warpMap = eim.getMapInstance(map); } else { warpMap = client.getChannelServer().getMapFactory().getMap(map); } @@ -1231,11 +1246,17 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { map = to; setPosition(pos); map.addPlayer(this); - if (party != null) { - mpc.setMapId(to.getId()); - silentPartyUpdate(); - client.announce(MaplePacketCreator.updateParty(client.getChannel(), party, PartyOperation.SILENT_UPDATE, null)); - updatePartyMemberHP(); + + prtLock.lock(); + try { + if (party != null) { + mpc.setMapId(to.getId()); + silentPartyUpdateInternal(); + client.announce(MaplePacketCreator.updateParty(client.getChannel(), party, PartyOperation.SILENT_UPDATE, null)); + updatePartyMemberHPInternal(); + } + } finally { + prtLock.unlock(); } if (getMap().getHPDec() > 0) resetHpDecreaseTask(); @@ -1254,8 +1275,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } // if this event map has a gate already opened, render it - if(getEventInstance() != null) { - getEventInstance().recoverOpenedGate(this, map.getId()); + EventInstanceManager eim = getEventInstance(); + if(eim != null) { + eim.recoverOpenedGate(this, map.getId()); } // if this map has obstacle components moving, make it do so for this client @@ -1446,27 +1468,32 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { return; } if (mapitem.getMeso() > 0) { - if (this.getParty() != null) { - int mesosamm = mapitem.getMeso(); - if (mesosamm > 50000 * this.getMesoRate()) { - return; - } - int partynum = 0; - for (MaplePartyCharacter partymem : this.getParty().getMembers()) { - if (partymem.isOnline() && partymem.getMapId() == this.getMap().getId() && partymem.getChannel() == client.getChannel()) { - partynum++; + prtLock.lock(); + try { + if (this.party != null) { + int mesosamm = mapitem.getMeso(); + if (mesosamm > 50000 * this.getMesoRate()) { + return; } - } - for (MaplePartyCharacter partymem : this.getParty().getMembers()) { - if (partymem.isOnline() && partymem.getMapId() == this.getMap().getId()) { - MapleCharacter somecharacter = client.getChannelServer().getPlayerStorage().getCharacterById(partymem.getId()); - if (somecharacter != null) { - somecharacter.gainMeso(mesosamm / partynum, true, true, false); + int partynum = 0; + for (MaplePartyCharacter partymem : this.party.getMembers()) { + if (partymem.isOnline() && partymem.getMapId() == this.getMap().getId() && partymem.getChannel() == client.getChannel()) { + partynum++; } } + for (MaplePartyCharacter partymem : this.party.getMembers()) { + if (partymem.isOnline() && partymem.getMapId() == this.getMap().getId()) { + MapleCharacter somecharacter = client.getChannelServer().getPlayerStorage().getCharacterById(partymem.getId()); + if (somecharacter != null) { + somecharacter.gainMeso(mesosamm / partynum, true, true, false); + } + } + } + } else { + this.gainMeso(mapitem.getMeso(), true, true, false); } - } else { - this.gainMeso(mapitem.getMeso(), true, true, false); + } finally { + prtLock.unlock(); } } else if (mapitem.getItem().getItemId() / 10000 == 243) { MapleItemInformationProvider.scriptedItem info = ii.getScriptedItemInfo(mapitem.getItem().getItemId()); @@ -1930,16 +1957,11 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } } - TimerManager.getInstance().schedule(new Runnable() { - @Override - public void run() { - dispelDebuff(disease); - } - }, skill.getDuration()); - chrLock.lock(); try { - diseases.put(disease, new MapleDiseaseValueHolder(System.currentTimeMillis(), skill.getDuration())); + long curTime = System.currentTimeMillis(); + diseaseExpires.put(disease, curTime + skill.getDuration()); + diseases.put(disease, new MapleDiseaseValueHolder(curTime, skill.getDuration())); } finally { chrLock.unlock(); } @@ -1959,6 +1981,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { chrLock.lock(); try { diseases.remove(debuff); + diseaseExpires.remove(debuff); } finally { chrLock.unlock(); } @@ -2092,6 +2115,41 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } } + public void cancelDiseaseExpireTask() { + if (diseaseExpireTask != null) { + diseaseExpireTask.cancel(false); + diseaseExpireTask = null; + } + } + + public void diseaseExpireTask() { + if (diseaseExpireTask == null) { + diseaseExpireTask = TimerManager.getInstance().register(new Runnable() { + @Override + public void run() { + Set toExpire = new LinkedHashSet<>(); + + chrLock.lock(); + try { + long curTime = System.currentTimeMillis(); + + for(Entry d : diseaseExpires.entrySet()) { + if(d.getValue() < curTime) { + toExpire.add(d.getKey()); + } + } + } finally { + chrLock.unlock(); + } + + for(MapleDisease d : toExpire) { + dispelDebuff(d); + } + } + }, 1500); + } + } + public void cancelBuffExpireTask() { if (buffExpireTask != null) { buffExpireTask.cancel(false); @@ -2285,7 +2343,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { 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; + long total = (long)gain + equip + party; gainExpInternal(total, equip, party, show, inChat, white); } @@ -2918,12 +2976,17 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { destroyDoor.getTownDoor().sendDestroyData(chr.getClient()); } - if (party != null) { - for (MaplePartyCharacter partyMembers : getParty().getMembers()) { - partyMembers.getPlayer().removeDoor(this.getId()); - partyMembers.removeDoor(this.getId()); + prtLock.lock(); + try { + if (party != null) { + for (MaplePartyCharacter partyMembers : party.getMembers()) { + partyMembers.getPlayer().removeDoor(this.getId()); + partyMembers.removeDoor(this.getId()); + } + silentPartyUpdateInternal(); } - silentPartyUpdate(); + } finally { + prtLock.unlock(); } } } @@ -3816,7 +3879,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { public int getDoorSlot() { if(doorSlot == -1) { - doorSlot = (party == null) ? 0 : party.getPartyDoor(this.getId()); + prtLock.lock(); + try { + doorSlot = (party == null) ? 0 : party.getPartyDoor(this.getId()); + } finally { + prtLock.unlock(); + } } return doorSlot; @@ -3906,20 +3974,35 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } public MapleParty getParty() { - return party; + prtLock.lock(); + try { + return party; + } finally { + prtLock.unlock(); + } } public int getPartyId() { - return (party != null ? party.getId() : -1); + prtLock.lock(); + try { + return (party != null ? party.getId() : -1); + } finally { + prtLock.unlock(); + } } public List getPartyMembers() { List list = new LinkedList<>(); - if(party != null) { - for(MaplePartyCharacter partyMembers: party.getMembers()) { - list.add(partyMembers.getPlayer()); + prtLock.lock(); + try { + if(party != null) { + for(MaplePartyCharacter partyMembers: party.getMembers()) { + list.add(partyMembers.getPlayer()); + } } + } finally { + prtLock.unlock(); } return list; @@ -3929,10 +4012,15 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { List list = new LinkedList<>(); int thisMapHash = this.getMap().hashCode(); - if(party != null) { - for(MaplePartyCharacter partyMembers: party.getMembers()) { - if(partyMembers.getPlayer().getMap().hashCode() == thisMapHash) list.add(partyMembers.getPlayer()); + prtLock.lock(); + try { + if(party != null) { + for(MaplePartyCharacter partyMembers: party.getMembers()) { + if(partyMembers.getPlayer().getMap().hashCode() == thisMapHash) list.add(partyMembers.getPlayer()); + } } + } finally { + prtLock.unlock(); } return list; @@ -4593,7 +4681,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } public boolean isPartyLeader() { - return party.getLeaderId() == getId(); + prtLock.lock(); + try { + return party.getLeaderId() == getId(); + } finally { + prtLock.unlock(); + } } public boolean isGuildLeader() { // true on guild master or jr. master @@ -5545,8 +5638,10 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { private void playerDead() { cancelAllBuffs(false); dispelDebuffs(); - if (getEventInstance() != null) { - getEventInstance().playerKilled(this); + + EventInstanceManager eim = getEventInstance(); + if (eim != null) { + eim.playerKilled(this); } int[] charmID = {5130000, 4031283, 4140903}; int possesed = 0; @@ -5741,16 +5836,21 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } public void receivePartyMemberHP() { - if (party != null) { - int channel = client.getChannel(); - for (MaplePartyCharacter partychar : party.getMembers()) { - if (partychar.getMapId() == getMapId() && partychar.getChannel() == channel) { - MapleCharacter other = Server.getInstance().getWorld(world).getChannel(channel).getPlayerStorage().getCharacterByName(partychar.getName()); - if (other != null) { - client.announce(MaplePacketCreator.updatePartyMemberHP(other.getId(), other.getHp(), other.getCurrentMaxHp())); + prtLock.lock(); + try { + if (party != null) { + int channel = client.getChannel(); + for (MaplePartyCharacter partychar : party.getMembers()) { + if (partychar.getMapId() == getMapId() && partychar.getChannel() == channel) { + MapleCharacter other = Server.getInstance().getWorld(world).getChannel(channel).getPlayerStorage().getCharacterByName(partychar.getName()); + if (other != null) { + client.announce(MaplePacketCreator.updatePartyMemberHP(other.getId(), other.getHp(), other.getCurrentMaxHp())); + } } } } + } finally { + prtLock.unlock(); } } @@ -6128,11 +6228,18 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { ps.setInt(24, 0); } } - if (party != null) { - ps.setInt(25, party.getId()); - } else { - ps.setInt(25, -1); + + prtLock.lock(); + try { + if (party != null) { + ps.setInt(25, party.getId()); + } else { + ps.setInt(25, -1); + } + } finally { + prtLock.unlock(); } + ps.setInt(26, buddylist.getCapacity()); if (messenger != null) { ps.setInt(27, messenger.getId()); @@ -6782,15 +6889,20 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } } - public void setParty(MapleParty party) { - if (party == null) { - this.mpc = null; - doorSlot = -1; - - this.party = null; - //cancelMagicDoor(); // cancel magic doors if kicked out / quitted from party. - } else { - this.party = party; + public void setParty(MapleParty p) { + prtLock.lock(); + try { + if (p == null) { + this.mpc = null; + doorSlot = -1; + + party = null; + //cancelMagicDoor(); // cancel magic doors if kicked out / quitted from party. + } else { + party = p; + } + } finally { + prtLock.unlock(); } } @@ -6998,6 +7110,15 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } public void silentPartyUpdate() { + prtLock.lock(); + try { + silentPartyUpdateInternal(); + } finally { + prtLock.unlock(); + } + } + + private void silentPartyUpdateInternal() { if (party != null) { Server.getInstance().getWorld(world).updateParty(party.getId(), PartyOperation.SILENT_UPDATE, getMPC()); } @@ -7118,6 +7239,15 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } public void updatePartyMemberHP() { + prtLock.lock(); + try { + updatePartyMemberHPInternal(); + } finally { + prtLock.unlock(); + } + } + + private void updatePartyMemberHPInternal() { if (party != null) { int channel = client.getChannel(); for (MaplePartyCharacter partychar : party.getMembers()) { @@ -7628,8 +7758,10 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } cancelBuffExpireTask(); + cancelDiseaseExpireTask(); cancelSkillCooldownTask(); cancelExpirationTask(); + for (ScheduledFuture sf : timers) { sf.cancel(false); } diff --git a/src/client/MapleClient.java b/src/client/MapleClient.java index 160995bfe5..d3a3e4ebd4 100644 --- a/src/client/MapleClient.java +++ b/src/client/MapleClient.java @@ -88,7 +88,7 @@ public class MapleClient { public static final String CLIENT_KEY = "CLIENT"; private MapleAESOFB send; private MapleAESOFB receive; - private IoSession session; + private final IoSession session; private MapleCharacter player; private int channel = 1; private int accId = 1; @@ -123,15 +123,15 @@ public class MapleClient { this.session = session; } - public synchronized MapleAESOFB getReceiveCrypto() { + public MapleAESOFB getReceiveCrypto() { return receive; } - public synchronized MapleAESOFB getSendCrypto() { + public MapleAESOFB getSendCrypto() { return send; } - public synchronized IoSession getSession() { + public IoSession getSession() { return session; } @@ -459,7 +459,7 @@ public class MapleClient { public boolean checkPin(String other) { pinattempt++; if (pinattempt > 5) { - getSession().close(true); + session.close(false); } if (pin.equals(other)) { pinattempt = 0; @@ -493,7 +493,7 @@ public class MapleClient { picattempt++; if (picattempt > 5) { - getSession().close(true); + session.close(false); } if (pic.equals(other)) { picattempt = 0; @@ -505,7 +505,7 @@ public class MapleClient { public int login(String login, String pwd) { loginattempt++; if (loginattempt > 4) { - getSession().close(true); + session.close(false); } int loginok = 5; Connection con = null; @@ -934,12 +934,12 @@ public class MapleClient { if (!serverTransition && isLoggedIn()) { updateLoginState(MapleClient.LOGIN_NOTLOGGEDIN); session.removeAttribute(MapleClient.CLIENT_KEY); // prevents double dcing during login - session.close(); + session.close(false); } engines.clear(); } - private void clear() { + private void clear() { //usable when defining client = null shortly after this.accountName = null; this.macs = null; this.hwid = null; @@ -1013,8 +1013,8 @@ public class MapleClient { public void run() { try { if (lastPong < then) { - if (getSession() != null && getSession().isConnected()) { - getSession().close(true); + if (session != null && session.isConnected()) { + session.close(false); } } } catch (NullPointerException e) { @@ -1307,6 +1307,7 @@ public class MapleClient { server.getPlayerBuffStorage().addBuffsToStorage(player.getId(), player.getAllBuffs()); player.cancelAllBuffs(true); player.cancelBuffExpireTask(); + player.cancelDiseaseExpireTask(); player.cancelSkillCooldownTask(); //Cancelling magicdoor? Nope //Cancelling mounts? Noty diff --git a/src/client/command/Commands.java b/src/client/command/Commands.java index 145d4b1b23..76e119187e 100644 --- a/src/client/command/Commands.java +++ b/src/client/command/Commands.java @@ -1424,12 +1424,12 @@ public class Commands { String sendStr = ""; if(sub[1].equalsIgnoreCase("on")) { - sendStr += "GM Fly feature enabled. With fly active, GM's cannot attack."; + sendStr += "Enabled Fly feature (F1). With fly active, you cannot attack."; if(!srv.canFly(accid)) sendStr += " Re-login to take effect."; srv.changeFly(c.getAccID(), true); } else { - player.dropMessage(6, "GM Fly feature disabled. GM's can now attack."); + sendStr += "Disabled Fly feature. You can now attack."; if(srv.canFly(accid)) sendStr += " Re-login to take effect."; srv.changeFly(c.getAccID(), false); diff --git a/src/constants/ServerConstants.java b/src/constants/ServerConstants.java index 4f000c96d7..566fd6496c 100644 --- a/src/constants/ServerConstants.java +++ b/src/constants/ServerConstants.java @@ -53,6 +53,7 @@ public class ServerConstants { public static final boolean USE_ERASE_UNTRADEABLE_DROP = true; //Forces flagged untradeable items to disappear when dropped. public static final boolean USE_ERASE_PET_ON_EXPIRATION = false;//Forces pets to be removed from inventory when expire time comes, rather than converting it to a doll. public static final boolean USE_BUFF_MOST_SIGNIFICANT = true; //When applying buffs, the player will stick with the highest stat boost among the listed, rather than overwriting stats. + public static final boolean USE_UNDERLEVELED_EXP_GAIN = false; //Players below the threshold level will gain no experience from defeating higher leveled mobs. //Server Rates And Experience public static final int EXP_RATE = 10; @@ -77,10 +78,12 @@ public class ServerConstants { //Some Gameplay Enhancing Configurations //Scroll Configuration - public static final boolean USE_PERFECT_GM_SCROLL = true; //Scrolls from GMs never uses up slots nor fails. - 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. + public static final boolean USE_PERFECT_GM_SCROLL = false; //Scrolls from GMs never uses up slots nor fails. + public static final boolean USE_PERFECT_SCROLLING = false; //Scrolls doesn't use slots upon failure. + public static final boolean USE_ENHANCED_CHSCROLL = false; //Equips even more powerful with chaos upgrade. public static final boolean USE_ENHANCED_CRAFTING = true; //Applys chaos scroll on every equip crafted. + public static final int SCROLL_CHANCE_RATE = 0; //Number of rolls for success on a scroll, set 0 for default. + public static final int CHSCROLL_STAT_RANGE = 6; //Stat upgrade range (-N, N) on chaos scrolls. //Beginner Skills Configuration public static final boolean USE_ULTRA_NIMBLE_FEET = true; //Haste-like speed & jump upgrade. @@ -93,7 +96,6 @@ public class ServerConstants { public static final boolean USE_STACK_COUPON_RATES = true; //Multiple coupons effects builds up together. public static final boolean USE_PERFECT_PITCH = true; //For lvl 30 or above, each lvlup grants player 1 perfect pitch. public static final int FAME_GAIN_BY_QUEST = 4; //Fame gain each N quest completes, set 0 to disable. - public static final int SCROLL_CHANCE_RATE = 10; //Number of rolls for success on a scroll, set 0 for default. //Equipment Configuration public static final boolean USE_EQUIPMNT_LVLUP_SLOTS = true;//Equips can upgrade slots at level up. diff --git a/src/net/mina/MaplePacketDecoder.java b/src/net/mina/MaplePacketDecoder.java index 3f1390f681..847c2d84e0 100644 --- a/src/net/mina/MaplePacketDecoder.java +++ b/src/net/mina/MaplePacketDecoder.java @@ -38,14 +38,21 @@ public class MaplePacketDecoder extends CumulativeProtocolDecoder { @Override protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { final MapleClient client = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY); + if(client == null) { + session.close(true); + return false; + } + DecoderState decoderState = (DecoderState) session.getAttribute(DECODER_STATE_KEY); if (decoderState == null) { decoderState = new DecoderState(); session.setAttribute(DECODER_STATE_KEY, decoderState); } + + MapleAESOFB rcvdCrypto = client.getReceiveCrypto(); if (in.remaining() >= 4 && decoderState.packetlength == -1) { int packetHeader = in.getInt(); - if (!client.getReceiveCrypto().checkPacket(packetHeader)) { + if (!rcvdCrypto.checkPacket(packetHeader)) { session.close(true); return false; } @@ -57,7 +64,7 @@ public class MaplePacketDecoder extends CumulativeProtocolDecoder { byte decryptedPacket[] = new byte[decoderState.packetlength]; in.get(decryptedPacket, 0, decoderState.packetlength); decoderState.packetlength = -1; - client.getReceiveCrypto().crypt(decryptedPacket); + rcvdCrypto.crypt(decryptedPacket); MapleCustomEncryption.decryptData(decryptedPacket); out.write(decryptedPacket); return true; diff --git a/src/net/mina/MaplePacketEncoder.java b/src/net/mina/MaplePacketEncoder.java index f9cb0a30be..c14106b10c 100644 --- a/src/net/mina/MaplePacketEncoder.java +++ b/src/net/mina/MaplePacketEncoder.java @@ -62,6 +62,5 @@ public class MaplePacketEncoder implements ProtocolEncoder { } @Override - public void dispose(IoSession session) throws Exception { - } + public void dispose(IoSession session) throws Exception {} } \ No newline at end of file diff --git a/src/net/server/channel/handlers/EnterCashShopHandler.java b/src/net/server/channel/handlers/EnterCashShopHandler.java index 5af0f742a3..fac2f949c0 100644 --- a/src/net/server/channel/handlers/EnterCashShopHandler.java +++ b/src/net/server/channel/handlers/EnterCashShopHandler.java @@ -52,6 +52,7 @@ public class EnterCashShopHandler extends AbstractMaplePacketHandler { Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(mc.getId(), mc.getAllBuffs()); mc.cancelAllBuffs(true); mc.cancelBuffExpireTask(); + mc.cancelDiseaseExpireTask(); mc.cancelSkillCooldownTask(); mc.cancelExpirationTask(); diff --git a/src/net/server/channel/handlers/EnterMTSHandler.java b/src/net/server/channel/handlers/EnterMTSHandler.java index ef2767e56e..ba448f6093 100644 --- a/src/net/server/channel/handlers/EnterMTSHandler.java +++ b/src/net/server/channel/handlers/EnterMTSHandler.java @@ -61,6 +61,7 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler { Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(chr.getId(), chr.getAllBuffs()); chr.cancelAllBuffs(true); chr.cancelBuffExpireTask(); + chr.cancelDiseaseExpireTask(); chr.cancelSkillCooldownTask(); chr.cancelExpirationTask(); chr.saveToDB(); diff --git a/src/net/server/channel/handlers/PartyOperationHandler.java b/src/net/server/channel/handlers/PartyOperationHandler.java index 76c9a8d3b0..2b4f72af56 100644 --- a/src/net/server/channel/handlers/PartyOperationHandler.java +++ b/src/net/server/channel/handlers/PartyOperationHandler.java @@ -30,6 +30,8 @@ import tools.MaplePacketCreator; import tools.data.input.SeekableLittleEndianAccessor; import client.MapleCharacter; import client.MapleClient; +import scripting.event.EventInstanceManager; +import server.maps.MapleMap; public final class PartyOperationHandler extends AbstractMaplePacketHandler { @@ -50,6 +52,7 @@ public final class PartyOperationHandler extends AbstractMaplePacketHandler { party = world.createParty(partyplayer); player.setParty(party); player.setMPC(partyplayer); + player.getMap().addPartyMember(player); player.silentPartyUpdate(); c.announce(MaplePacketCreator.partyCreated(partyplayer)); } else { @@ -59,17 +62,22 @@ public final class PartyOperationHandler extends AbstractMaplePacketHandler { } case 2: { if (party != null && partyplayer != null) { - if (partyplayer.equals(party.getLeader())) { - world.updateParty(party.getId(), PartyOperation.DISBAND, partyplayer); - if (player.getEventInstance() != null) { - player.getEventInstance().disbandParty(); - } - } else { - world.updateParty(party.getId(), PartyOperation.LEAVE, partyplayer); - if (player.getEventInstance() != null) { - player.getEventInstance().leftParty(player); - } + if (partyplayer.getId() == party.getLeaderId()) { + c.getWorldServer().removeMapPartyMembers(party.getId()); + + world.updateParty(party.getId(), PartyOperation.DISBAND, partyplayer); + if (player.getEventInstance() != null) { + player.getEventInstance().disbandParty(); } + } else { + player.getMap().removePartyMember(player); + + world.updateParty(party.getId(), PartyOperation.LEAVE, partyplayer); + if (player.getEventInstance() != null) { + player.getEventInstance().leftParty(player); + } + } + player.setParty(null); } break; @@ -81,6 +89,8 @@ public final class PartyOperationHandler extends AbstractMaplePacketHandler { if (party != null) { if (party.getMembers().size() < 6) { partyplayer = new MaplePartyCharacter(player); + player.getMap().addPartyMember(player); + world.updateParty(party.getId(), PartyOperation.JOIN, partyplayer); player.receivePartyMemberHP(); player.updatePartyMemberHP(); @@ -109,6 +119,7 @@ public final class PartyOperationHandler extends AbstractMaplePacketHandler { party = world.createParty(partyplayer); player.setParty(party); player.setMPC(partyplayer); + player.getMap().addPartyMember(player); c.announce(MaplePacketCreator.partyCreated(partyplayer)); } if (party.getMembers().size() < 6) { @@ -129,12 +140,20 @@ public final class PartyOperationHandler extends AbstractMaplePacketHandler { if (partyplayer.equals(party.getLeader())) { MaplePartyCharacter expelled = party.getMemberById(cid); if (expelled != null) { - world.updateParty(party.getId(), PartyOperation.EXPEL, expelled); - if (player.getEventInstance() != null) { - if (expelled.isOnline()) { - player.getEventInstance().disbandParty(); + MapleCharacter emc = expelled.getPlayer(); + if(emc != null) { + MapleMap map = emc.getMap(); + if(map != null) map.removePartyMember(emc); + + EventInstanceManager eim = emc.getEventInstance(); + if(eim != null) { + eim.leftParty(emc); } + + emc.setParty(null); } + + world.updateParty(party.getId(), PartyOperation.EXPEL, expelled); } } break; diff --git a/src/net/server/channel/handlers/PlayerLoggedinHandler.java b/src/net/server/channel/handlers/PlayerLoggedinHandler.java index 6573b99da1..40aac49275 100644 --- a/src/net/server/channel/handlers/PlayerLoggedinHandler.java +++ b/src/net/server/channel/handlers/PlayerLoggedinHandler.java @@ -263,6 +263,7 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler { player.changeSkillLevel(SkillFactory.getSkill(10000000 * player.getJobType() + 12), (byte) (player.getLinkedLevel() / 10), 20, -1); player.checkBerserk(player.isHidden()); player.buffExpireTask(); + player.diseaseExpireTask(); player.skillCooldownTask(); player.expirationTask(); if (GameConstants.hasSPTable(player.getJob()) && player.getJob().getId() != 2001) { diff --git a/src/net/server/world/MapleParty.java b/src/net/server/world/MapleParty.java index 83a8707672..8eca3685ea 100644 --- a/src/net/server/world/MapleParty.java +++ b/src/net/server/world/MapleParty.java @@ -29,17 +29,21 @@ import java.util.HashMap; import java.util.Map.Entry; import java.util.Map; import java.util.Comparator; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.Lock; public class MapleParty { + private int id; + private int leaderId; - private List members = new LinkedList(); + private List members = new LinkedList<>(); private List pqMembers = null; private Map histMembers = new HashMap<>(); private int nextEntry = 0; - private int id; - + private Lock lock = new ReentrantLock(); + public MapleParty(int id, MaplePartyCharacter chrfor) { this.leaderId = chrfor.getId(); this.members.add(chrfor); @@ -47,20 +51,35 @@ public class MapleParty { } public boolean containsMembers(MaplePartyCharacter member) { - return members.contains(member); + lock.lock(); + try { + return members.contains(member); + } finally { + lock.unlock(); + } } public void addMember(MaplePartyCharacter member) { - histMembers.put(member.getId(), nextEntry); - nextEntry++; - - members.add(member); + lock.lock(); + try { + histMembers.put(member.getId(), nextEntry); + nextEntry++; + + members.add(member); + } finally { + lock.unlock(); + } } public void removeMember(MaplePartyCharacter member) { - histMembers.remove(member.getId()); - - members.remove(member); + lock.lock(); + try { + histMembers.remove(member.getId()); + + members.remove(member); + } finally { + lock.unlock(); + } } public void setLeader(MaplePartyCharacter victim) { @@ -68,28 +87,48 @@ public class MapleParty { } public void updateMember(MaplePartyCharacter member) { - for (int i = 0; i < members.size(); i++) { - if (members.get(i).getId() == member.getId()) { - members.set(i, member); + lock.lock(); + try { + for (int i = 0; i < members.size(); i++) { + if (members.get(i).getId() == member.getId()) { + members.set(i, member); + } } + } finally { + lock.unlock(); } } public MaplePartyCharacter getMemberById(int id) { - for (MaplePartyCharacter chr : members) { - if (chr.getId() == id) { - return chr; + lock.lock(); + try { + for (MaplePartyCharacter chr : members) { + if (chr.getId() == id) { + return chr; + } } + return null; + } finally { + lock.unlock(); } - return null; } public Collection getMembers() { - return Collections.unmodifiableList(members); + lock.lock(); + try { + return Collections.unmodifiableList(members); + } finally { + lock.unlock(); + } } public List getPartyMembers() { - return members; + lock.lock(); + try { + return Collections.unmodifiableList(members); + } finally { + lock.unlock(); + } } // used whenever entering PQs: will draw every party member that can attempt a target PQ while ingnoring those unfit. @@ -114,17 +153,30 @@ public class MapleParty { } public MaplePartyCharacter getLeader() { - for(MaplePartyCharacter mpc: members) { - if(mpc.getId() == leaderId) { - return mpc; + lock.lock(); + try { + for(MaplePartyCharacter mpc: members) { + if(mpc.getId() == leaderId) { + return mpc; + } } + + return null; + } finally { + lock.unlock(); } - - return null; } public byte getPartyDoor(int cid) { - List> histList = new LinkedList<>(histMembers.entrySet()); + List> histList; + + lock.lock(); + try { + histList = new LinkedList<>(histMembers.entrySet()); + } finally { + lock.unlock(); + } + Collections.sort(histList, new Comparator>() { @Override @@ -133,13 +185,13 @@ public class MapleParty { return ( o1.getValue() ).compareTo( o2.getValue() ); } }); - + byte slot = 0; for(Entry e: histList) { if(e.getKey() == cid) break; slot++; } - + return slot; } diff --git a/src/net/server/world/World.java b/src/net/server/world/World.java index 43eb976665..1dc1e45389 100644 --- a/src/net/server/world/World.java +++ b/src/net/server/world/World.java @@ -45,8 +45,10 @@ import java.util.Set; import java.util.HashSet; import java.util.concurrent.ScheduledFuture; +import scripting.event.EventInstanceManager; import server.TimerManager; import server.maps.MapleHiredMerchant; +import server.maps.MapleMap; import server.MaplePlayerShop; import net.server.worker.CharacterAutosaverWorker; import net.server.worker.MountTirednessWorker; @@ -357,16 +359,22 @@ public class World { public MapleParty createParty(MaplePartyCharacter chrfor) { int partyid = runningPartyId.getAndIncrement(); MapleParty party = new MapleParty(partyid, chrfor); - parties.put(party.getId(), party); + synchronized(parties) { + parties.put(party.getId(), party); + } return party; } public MapleParty getParty(int partyid) { - return parties.get(partyid); + synchronized(parties) { + return parties.get(partyid); + } } public MapleParty disbandParty(int partyid) { - return parties.remove(partyid); + synchronized(parties) { + return parties.remove(partyid); + } } public void updateParty(MapleParty party, PartyOperation operation, MaplePartyCharacter target) { @@ -419,8 +427,10 @@ public class World { break; case CHANGE_LEADER: MapleCharacter mc = party.getLeader().getPlayer(); - if(mc.getEventInstance() != null && mc.getEventInstance().isEventLeader(mc)) { - mc.getEventInstance().changedLeader(target.getPlayer()); + EventInstanceManager eim = mc.getEventInstance(); + + if(eim != null && eim.isEventLeader(mc)) { + eim.changedLeader(target.getPlayer()); } party.setLeader(target); break; @@ -430,6 +440,21 @@ public class World { updateParty(party, operation, target); } + public void removeMapPartyMembers(int partyid) { + MapleParty party = getParty(partyid); + if(party == null) return; + + for(MaplePartyCharacter mpc : party.getMembers()) { + MapleCharacter mc = mpc.getPlayer(); + if(mc != null) { + MapleMap map = mc.getMap(); + if(map != null) { + map.removeParty(partyid); + } + } + } + } + public int find(String name) { int channel = -1; MapleCharacter chr = getPlayerStorage().getCharacterByName(name); diff --git a/src/scripting/AbstractPlayerInteraction.java b/src/scripting/AbstractPlayerInteraction.java index 833994943b..4d09583236 100644 --- a/src/scripting/AbstractPlayerInteraction.java +++ b/src/scripting/AbstractPlayerInteraction.java @@ -449,10 +449,14 @@ public class AbstractPlayerInteraction { if(item != null) { Equip it = (Equip)item; if(isAccessory(item.getItemId()) && it.getUpgradeSlots() <= 0) it.setUpgradeSlots(3); - } - if(ServerConstants.USE_ENHANCED_CRAFTING == true && c.getPlayer().getCS() == true) - item = MapleItemInformationProvider.getInstance().scrollEquipWithId(item, 2049100, true, 0, c.getPlayer().isGM()); + if(ServerConstants.USE_ENHANCED_CRAFTING == true && c.getPlayer().getCS() == true) { + Equip eqp = (Equip)item; + eqp.setUpgradeSlots((byte)(eqp.getUpgradeSlots() + 1)); + + item = MapleItemInformationProvider.getInstance().scrollEquipWithId(item, 2049100, true, 0, c.getPlayer().isGM()); + } + } } else { item = new Item(id, (short) 0, quantity, petId); } diff --git a/src/server/MapleItemInformationProvider.java b/src/server/MapleItemInformationProvider.java index 7b91c3cb43..05e6b7a0c3 100644 --- a/src/server/MapleItemInformationProvider.java +++ b/src/server/MapleItemInformationProvider.java @@ -568,6 +568,223 @@ public class MapleItemInformationProvider { return (short)Math.min(Short.MAX_VALUE, value); } + private static short chscrollRandomizedStat() { + return (short) Randomizer.rand(-ServerConstants.CHSCROLL_STAT_RANGE, ServerConstants.CHSCROLL_STAT_RANGE); + } + + private void scrollEquipWithChaos(Equip nEquip) { + if(ServerConstants.SCROLL_CHANCE_RATE > 0) { + int temp; + short curStr, curDex, curInt, curLuk, curWatk, curWdef, curMatk, curMdef, curAcc, curAvoid, curSpeed, curJump, curHp, curMp; + + if(ServerConstants.USE_ENHANCED_CHSCROLL) { + curStr = nEquip.getStr(); + curDex = nEquip.getDex(); + curInt = nEquip.getInt(); + curLuk = nEquip.getLuk(); + curWatk = nEquip.getWatk(); + curWdef = nEquip.getWdef(); + curMatk = nEquip.getMatk(); + curMdef = nEquip.getMdef(); + curAcc = nEquip.getAcc(); + curAvoid = nEquip.getAvoid(); + curSpeed = nEquip.getSpeed(); + curJump = nEquip.getJump(); + curHp = nEquip.getHp(); + curMp = nEquip.getMp(); + } else { + curStr = Short.MIN_VALUE; + curDex = Short.MIN_VALUE; + curInt = Short.MIN_VALUE; + curLuk = Short.MIN_VALUE; + curWatk = Short.MIN_VALUE; + curWdef = Short.MIN_VALUE; + curMatk = Short.MIN_VALUE; + curMdef = Short.MIN_VALUE; + curAcc = Short.MIN_VALUE; + curAvoid = Short.MIN_VALUE; + curSpeed = Short.MIN_VALUE; + curJump = Short.MIN_VALUE; + curHp = Short.MIN_VALUE; + curMp = Short.MIN_VALUE; + } + + for(int i = 0; i < ServerConstants.SCROLL_CHANCE_RATE; i++) { + if (nEquip.getStr() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curStr + chscrollRandomizedStat(); + else temp = nEquip.getStr() + chscrollRandomizedStat(); + + curStr = getMaximumShortMaxIfOverflow(temp, curStr); + } + + if (nEquip.getDex() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curDex + chscrollRandomizedStat(); + else temp = nEquip.getDex() + chscrollRandomizedStat(); + + curDex = getMaximumShortMaxIfOverflow(temp, curDex); + } + + if (nEquip.getInt() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curInt + chscrollRandomizedStat(); + else temp = nEquip.getInt() + chscrollRandomizedStat(); + + curInt = getMaximumShortMaxIfOverflow(temp, curInt); + } + + if (nEquip.getLuk() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curLuk + chscrollRandomizedStat(); + else temp = nEquip.getLuk() + chscrollRandomizedStat(); + + curLuk = getMaximumShortMaxIfOverflow(temp, curLuk); + } + + if (nEquip.getWatk() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curWatk + chscrollRandomizedStat(); + else temp = nEquip.getWatk() + chscrollRandomizedStat(); + + curWatk = getMaximumShortMaxIfOverflow(temp, curWatk); + } + + if (nEquip.getWdef() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curWdef + chscrollRandomizedStat(); + else temp = nEquip.getWdef() + chscrollRandomizedStat(); + + curWdef = getMaximumShortMaxIfOverflow(temp, curWdef); + } + + if (nEquip.getMatk() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curMatk + chscrollRandomizedStat(); + else temp = nEquip.getMatk() + chscrollRandomizedStat(); + + curMatk = getMaximumShortMaxIfOverflow(temp, curMatk); + } + + if (nEquip.getMdef() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curMdef + chscrollRandomizedStat(); + else temp = nEquip.getMdef() + chscrollRandomizedStat(); + + curMdef = getMaximumShortMaxIfOverflow(temp, curMdef); + } + + if (nEquip.getAcc() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curAcc + chscrollRandomizedStat(); + else temp = nEquip.getAcc() + chscrollRandomizedStat(); + + curAcc = getMaximumShortMaxIfOverflow(temp, curAcc); + } + + if (nEquip.getAvoid() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curAvoid + chscrollRandomizedStat(); + else temp = nEquip.getAvoid() + chscrollRandomizedStat(); + + curAvoid = getMaximumShortMaxIfOverflow(temp, curAvoid); + } + + if (nEquip.getSpeed() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curSpeed + chscrollRandomizedStat(); + else temp = nEquip.getSpeed() + chscrollRandomizedStat(); + + curSpeed = getMaximumShortMaxIfOverflow(temp, curSpeed); + } + + if (nEquip.getJump() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curJump + chscrollRandomizedStat(); + else temp = nEquip.getJump() + chscrollRandomizedStat(); + + curJump = getMaximumShortMaxIfOverflow(temp, curJump); + } + + if (nEquip.getHp() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curHp + chscrollRandomizedStat(); + else temp = nEquip.getHp() + chscrollRandomizedStat(); + + curHp = getMaximumShortMaxIfOverflow(temp, curHp); + } + + if (nEquip.getMp() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) temp = curMp + chscrollRandomizedStat(); + else temp = nEquip.getMp() + chscrollRandomizedStat(); + + curMp = getMaximumShortMaxIfOverflow(temp, curMp); + } + } + + nEquip.setStr((short) Math.max(0, curStr)); + nEquip.setDex((short) Math.max(0, curDex)); + nEquip.setInt((short) Math.max(0, curInt)); + nEquip.setLuk((short) Math.max(0, curLuk)); + nEquip.setWatk((short) Math.max(0, curWatk)); + nEquip.setWdef((short) Math.max(0, curWdef)); + nEquip.setMatk((short) Math.max(0, curMatk)); + nEquip.setMdef((short) Math.max(0, curMdef)); + nEquip.setAcc((short) Math.max(0, curAcc)); + nEquip.setAvoid((short) Math.max(0, curAvoid)); + nEquip.setSpeed((short) Math.max(0, curSpeed)); + nEquip.setJump((short) Math.max(0, curJump)); + nEquip.setHp((short) Math.max(0, curHp)); + nEquip.setMp((short) Math.max(0, curMp)); + } + + else { + if (nEquip.getStr() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setStr(getMaximumShortMaxIfOverflow(nEquip.getStr(), (nEquip.getStr() + chscrollRandomizedStat()))); + else nEquip.setStr(getMaximumShortMaxIfOverflow(0, (nEquip.getStr() + chscrollRandomizedStat()))); + } + if (nEquip.getDex() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setDex(getMaximumShortMaxIfOverflow(nEquip.getDex(), (nEquip.getDex() + chscrollRandomizedStat()))); + else nEquip.setDex(getMaximumShortMaxIfOverflow(0, (nEquip.getDex() + chscrollRandomizedStat()))); + } + if (nEquip.getInt() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setInt(getMaximumShortMaxIfOverflow(nEquip.getInt(), (nEquip.getInt() + chscrollRandomizedStat()))); + else nEquip.setInt(getMaximumShortMaxIfOverflow(0, (nEquip.getInt() + chscrollRandomizedStat()))); + } + if (nEquip.getLuk() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setLuk(getMaximumShortMaxIfOverflow(nEquip.getLuk(), (nEquip.getLuk() + chscrollRandomizedStat()))); + else nEquip.setLuk(getMaximumShortMaxIfOverflow(0, (nEquip.getLuk() + chscrollRandomizedStat()))); + } + if (nEquip.getWatk() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setWatk(getMaximumShortMaxIfOverflow(nEquip.getWatk(), (nEquip.getWatk() + chscrollRandomizedStat()))); + else nEquip.setWatk(getMaximumShortMaxIfOverflow(0, (nEquip.getWatk() + chscrollRandomizedStat()))); + } + if (nEquip.getWdef() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setWdef(getMaximumShortMaxIfOverflow(nEquip.getWdef(), (nEquip.getWdef() + chscrollRandomizedStat()))); + else nEquip.setWdef(getMaximumShortMaxIfOverflow(0, (nEquip.getWdef() + chscrollRandomizedStat()))); + } + if (nEquip.getMatk() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setMatk(getMaximumShortMaxIfOverflow(nEquip.getMatk(), (nEquip.getMatk() + chscrollRandomizedStat()))); + else nEquip.setMatk(getMaximumShortMaxIfOverflow(0, (nEquip.getMatk() + chscrollRandomizedStat()))); + } + if (nEquip.getMdef() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setMdef(getMaximumShortMaxIfOverflow(nEquip.getMdef(), (nEquip.getMdef() + chscrollRandomizedStat()))); + else nEquip.setMdef(getMaximumShortMaxIfOverflow(0, (nEquip.getMdef() + chscrollRandomizedStat()))); + } + if (nEquip.getAcc() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setAcc(getMaximumShortMaxIfOverflow(nEquip.getAcc(), (nEquip.getAcc() + chscrollRandomizedStat()))); + else nEquip.setAcc(getMaximumShortMaxIfOverflow(0, (nEquip.getAcc() + chscrollRandomizedStat()))); + } + if (nEquip.getAvoid() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setAvoid(getMaximumShortMaxIfOverflow(nEquip.getAvoid(), (nEquip.getAvoid() + chscrollRandomizedStat()))); + else nEquip.setAvoid(getMaximumShortMaxIfOverflow(0, (nEquip.getAvoid() + chscrollRandomizedStat()))); + } + if (nEquip.getSpeed() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setSpeed(getMaximumShortMaxIfOverflow(nEquip.getSpeed(), (nEquip.getSpeed() + chscrollRandomizedStat()))); + else nEquip.setSpeed(getMaximumShortMaxIfOverflow(0, (nEquip.getSpeed() + chscrollRandomizedStat()))); + } + if (nEquip.getJump() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setJump(getMaximumShortMaxIfOverflow(nEquip.getJump(), (nEquip.getJump() + chscrollRandomizedStat()))); + else nEquip.setJump(getMaximumShortMaxIfOverflow(0, (nEquip.getJump() + chscrollRandomizedStat()))); + } + if (nEquip.getHp() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setHp(getMaximumShortMaxIfOverflow(nEquip.getHp(), (nEquip.getHp() + chscrollRandomizedStat()))); + else nEquip.setHp(getMaximumShortMaxIfOverflow(0, (nEquip.getHp() + chscrollRandomizedStat()))); + } + if (nEquip.getMp() > 0) { + if(ServerConstants.USE_ENHANCED_CHSCROLL) nEquip.setMp(getMaximumShortMaxIfOverflow(nEquip.getMp(), (nEquip.getMp() + chscrollRandomizedStat()))); + else nEquip.setMp(getMaximumShortMaxIfOverflow(0, (nEquip.getMp() + chscrollRandomizedStat()))); + } + } + } + public Item scrollEquipWithId(Item equip, int scrollId, boolean usingWhiteScroll, int vegaItemId, boolean isGM) { boolean assertGM = (isGM && ServerConstants.USE_PERFECT_GM_SCROLL); @@ -607,256 +824,7 @@ public class MapleItemInformationProvider { case 2049100: case 2049101: case 2049102: - int inc, i; - - if(ServerConstants.SCROLL_CHANCE_RATE > 0) { - //int tempStr, tempDex, tempInt, tempLuk, tempWatk, tempWdef, tempMatk, tempMdef, tempAcc, tempAvoid, tempSpeed, tempJump, tempHp, tempMp; - int temp; - int mdStr = nEquip.getStr(), mdDex = nEquip.getDex(), mdInt = nEquip.getInt(), mdLuk = nEquip.getLuk(), mdWatk = nEquip.getWatk(), mdWdef = nEquip.getWdef(), mdMatk = nEquip.getMatk(), mdMdef = nEquip.getMdef(), mdAcc = nEquip.getAcc(), mdAvoid = nEquip.getAvoid(), mdSpeed = nEquip.getSpeed(), mdJump = nEquip.getJump(), mdHp = nEquip.getHp(), mdMp = nEquip.getMp(); - - inc = 1; - if (Randomizer.nextInt(2) == 0) { - inc = -1; - } - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) inc = 1; - - for(i = 0; i < ServerConstants.SCROLL_CHANCE_RATE; i++) { - if (nEquip.getStr() > 0) { - temp = (nEquip.getStr() + Randomizer.nextInt(6) * inc); - nEquip.setStr(getMaximumShortMaxIfOverflow(mdStr, temp)); - - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) { - mdStr = nEquip.getStr(); - } - else { - temp = (mdStr + temp) / 2; - if(temp > mdStr) mdStr = temp; - } - } - if (nEquip.getDex() > 0) { - temp = (nEquip.getDex() + Randomizer.nextInt(6) * inc); - nEquip.setDex(getMaximumShortMaxIfOverflow(mdDex, temp)); - - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) { - mdDex = nEquip.getDex(); - } - else { - temp = (mdDex + temp) / 2; - if(temp > mdDex) mdDex = temp; - } - } - if (nEquip.getInt() > 0) { - temp = (nEquip.getInt() + Randomizer.nextInt(6) * inc); - nEquip.setInt(getMaximumShortMaxIfOverflow(mdInt, temp)); - - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) { - mdInt = nEquip.getInt(); - } - else { - temp = (mdInt + temp) / 2; - if(temp > mdInt) mdInt = temp; - } - } - if (nEquip.getLuk() > 0) { - temp = (nEquip.getLuk() + Randomizer.nextInt(6) * inc); - nEquip.setLuk(getMaximumShortMaxIfOverflow(mdLuk, temp)); - - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) { - mdLuk = nEquip.getLuk(); - } - else { - temp = (mdLuk + temp) / 2; - if(temp > mdLuk) mdLuk = temp; - } - } - if (nEquip.getWatk() > 0) { - temp = (nEquip.getWatk() + Randomizer.nextInt(6) * inc); - nEquip.setWatk(getMaximumShortMaxIfOverflow(mdWatk, temp)); - - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) { - mdWatk = nEquip.getWatk(); - } - else { - temp = (mdWatk + temp) / 2; - if(temp > mdWatk) mdWatk = temp; - } - } - if (nEquip.getWdef() > 0) { - temp = (nEquip.getWdef() + Randomizer.nextInt(6) * inc); - nEquip.setWdef(getMaximumShortMaxIfOverflow(mdWdef, temp)); - - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) { - mdWdef = nEquip.getWdef(); - } - else { - temp = (mdWdef + temp) / 2; - if(temp > mdWdef) mdWdef = temp; - } - } - if (nEquip.getMatk() > 0) { - temp = (nEquip.getMatk() + Randomizer.nextInt(6) * inc); - nEquip.setMatk(getMaximumShortMaxIfOverflow(mdMatk, temp)); - - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) { - mdMatk = nEquip.getMatk(); - } - else { - temp = (mdMatk + temp) / 2; - if(temp > mdMatk) mdMatk = temp; - } - } - if (nEquip.getMdef() > 0) { - temp = (nEquip.getMdef() + Randomizer.nextInt(6) * inc); - nEquip.setMdef(getMaximumShortMaxIfOverflow(mdMdef, temp)); - - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) { - mdMdef = nEquip.getMdef(); - } - else { - temp = (mdMdef + temp) / 2; - if(temp > mdMdef) mdMdef = temp; - } - } - if (nEquip.getAcc() > 0) { - temp = (nEquip.getAcc() + Randomizer.nextInt(6) * inc); - nEquip.setAcc(getMaximumShortMaxIfOverflow(mdAcc, temp)); - - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) { - mdAcc = nEquip.getAcc(); - } - else { - temp = (mdAcc + temp) / 2; - if(temp > mdAcc) mdAcc = temp; - } - } - if (nEquip.getAvoid() > 0) { - temp = (nEquip.getAvoid() + Randomizer.nextInt(6) * inc); - nEquip.setAvoid(getMaximumShortMaxIfOverflow(mdAvoid, temp)); - - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) { - mdAvoid = nEquip.getAvoid(); - } - else { - temp = (mdAvoid + temp) / 2; - if(temp > mdAvoid) mdAvoid = temp; - } - } - if (nEquip.getSpeed() > 0) { - temp = (nEquip.getSpeed() + Randomizer.nextInt(6) * inc); - nEquip.setSpeed(getMaximumShortMaxIfOverflow(mdSpeed, temp)); - - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) { - mdSpeed = nEquip.getSpeed(); - } - else { - temp = (mdSpeed + temp) / 2; - if(temp > mdSpeed) mdSpeed = temp; - } - } - if (nEquip.getJump() > 0) { - temp = (nEquip.getJump() + Randomizer.nextInt(6) * inc); - nEquip.setJump(getMaximumShortMaxIfOverflow(mdJump, temp)); - - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) { - mdJump = nEquip.getJump(); - } - else { - temp = (mdJump + temp) / 2; - if(temp > mdJump) mdJump = temp; - } - } - if (nEquip.getHp() > 0) { - temp = (nEquip.getHp() + Randomizer.nextInt(6) * inc); - nEquip.setHp(getMaximumShortMaxIfOverflow(mdHp, temp)); - - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) { - mdHp = nEquip.getHp(); - } - else { - temp = (mdHp + temp) / 2; - if(temp > mdHp) mdHp = temp; - } - } - if (nEquip.getMp() > 0) { - temp = (nEquip.getMp() + Randomizer.nextInt(6) * inc); - nEquip.setMp(getMaximumShortMaxIfOverflow(mdMp, temp)); - - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) { - mdMp = nEquip.getMp(); - } - else { - temp = (mdMp + temp) / 2; - if(temp > mdMp) mdMp = temp; - } - } - } - } - - else { - inc = 1; - - if (Randomizer.nextInt(2) == 0) { - inc = -1; - } - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) inc = 1; - - if (nEquip.getStr() > 0) { - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) nEquip.setStr(getMaximumShortMaxIfOverflow(nEquip.getStr(), (nEquip.getStr() + Randomizer.nextInt(6) * inc))); - else nEquip.setStr(getMaximumShortMaxIfOverflow(0, (nEquip.getStr() + Randomizer.nextInt(6) * inc))); - } - if (nEquip.getDex() > 0) { - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) nEquip.setDex(getMaximumShortMaxIfOverflow(nEquip.getDex(), (nEquip.getDex() + Randomizer.nextInt(6) * inc))); - else nEquip.setDex(getMaximumShortMaxIfOverflow(0, (nEquip.getDex() + Randomizer.nextInt(6) * inc))); - } - if (nEquip.getInt() > 0) { - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) nEquip.setInt(getMaximumShortMaxIfOverflow(nEquip.getInt(), (nEquip.getInt() + Randomizer.nextInt(6) * inc))); - else nEquip.setInt(getMaximumShortMaxIfOverflow(0, (nEquip.getInt() + Randomizer.nextInt(6) * inc))); - } - if (nEquip.getLuk() > 0) { - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) nEquip.setLuk(getMaximumShortMaxIfOverflow(nEquip.getLuk(), (nEquip.getLuk() + Randomizer.nextInt(6) * inc))); - else nEquip.setLuk(getMaximumShortMaxIfOverflow(0, (nEquip.getLuk() + Randomizer.nextInt(6) * inc))); - } - if (nEquip.getWatk() > 0) { - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) nEquip.setWatk(getMaximumShortMaxIfOverflow(nEquip.getWatk(), (nEquip.getWatk() + Randomizer.nextInt(6) * inc))); - else nEquip.setWatk(getMaximumShortMaxIfOverflow(0, (nEquip.getWatk() + Randomizer.nextInt(6) * inc))); - } - if (nEquip.getWdef() > 0) { - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) nEquip.setWdef(getMaximumShortMaxIfOverflow(nEquip.getWdef(), (nEquip.getWdef() + Randomizer.nextInt(6) * inc))); - else nEquip.setWdef(getMaximumShortMaxIfOverflow(0, (nEquip.getWdef() + Randomizer.nextInt(6) * inc))); - } - if (nEquip.getMatk() > 0) { - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) nEquip.setMatk(getMaximumShortMaxIfOverflow(nEquip.getMatk(), (nEquip.getMatk() + Randomizer.nextInt(6) * inc))); - else nEquip.setMatk(getMaximumShortMaxIfOverflow(0, (nEquip.getMatk() + Randomizer.nextInt(6) * inc))); - } - if (nEquip.getMdef() > 0) { - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) nEquip.setMdef(getMaximumShortMaxIfOverflow(nEquip.getMdef(), (nEquip.getMdef() + Randomizer.nextInt(6) * inc))); - else nEquip.setMdef(getMaximumShortMaxIfOverflow(0, (nEquip.getMdef() + Randomizer.nextInt(6) * inc))); - } - if (nEquip.getAcc() > 0) { - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) nEquip.setAcc(getMaximumShortMaxIfOverflow(nEquip.getAcc(), (nEquip.getAcc() + Randomizer.nextInt(6) * inc))); - else nEquip.setAcc(getMaximumShortMaxIfOverflow(0, (nEquip.getAcc() + Randomizer.nextInt(6) * inc))); - } - if (nEquip.getAvoid() > 0) { - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) nEquip.setAvoid(getMaximumShortMaxIfOverflow(nEquip.getAvoid(), (nEquip.getAvoid() + Randomizer.nextInt(6) * inc))); - else nEquip.setAvoid(getMaximumShortMaxIfOverflow(0, (nEquip.getAvoid() + Randomizer.nextInt(6) * inc))); - } - if (nEquip.getSpeed() > 0) { - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) nEquip.setSpeed(getMaximumShortMaxIfOverflow(nEquip.getSpeed(), (nEquip.getSpeed() + Randomizer.nextInt(6) * inc))); - else nEquip.setSpeed(getMaximumShortMaxIfOverflow(0, (nEquip.getSpeed() + Randomizer.nextInt(6) * inc))); - } - if (nEquip.getJump() > 0) { - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) nEquip.setJump(getMaximumShortMaxIfOverflow(nEquip.getJump(), (nEquip.getJump() + Randomizer.nextInt(6) * inc))); - else nEquip.setJump(getMaximumShortMaxIfOverflow(0, (nEquip.getJump() + Randomizer.nextInt(6) * inc))); - } - if (nEquip.getHp() > 0) { - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) nEquip.setHp(getMaximumShortMaxIfOverflow(nEquip.getHp(), (nEquip.getHp() + Randomizer.nextInt(6) * inc))); - else nEquip.setHp(getMaximumShortMaxIfOverflow(0, (nEquip.getHp() + Randomizer.nextInt(6) * inc))); - } - if (nEquip.getMp() > 0) { - if(ServerConstants.USE_ENHANCED_CHSCROLL == true) nEquip.setMp(getMaximumShortMaxIfOverflow(nEquip.getMp(), (nEquip.getMp() + Randomizer.nextInt(6) * inc))); - else nEquip.setMp(getMaximumShortMaxIfOverflow(0, (nEquip.getMp() + Randomizer.nextInt(6) * inc))); - } - } + scrollEquipWithChaos(nEquip); break; default: @@ -911,13 +879,13 @@ public class MapleItemInformationProvider { break; } if (!ItemConstants.isCleanSlate(scrollId)) { - if (ServerConstants.USE_PERFECT_SCROLLING == true && !assertGM && !usingWhiteScroll) { + if (!assertGM && !usingWhiteScroll) { nEquip.setUpgradeSlots((byte) (nEquip.getUpgradeSlots() - 1)); } nEquip.setLevel((byte) (nEquip.getLevel() + 1)); } - } else { - if (ServerConstants.USE_PERFECT_SCROLLING == false && !usingWhiteScroll && !ItemConstants.isCleanSlate(scrollId) && !assertGM) { + } else { + if (!ServerConstants.USE_PERFECT_SCROLLING && !usingWhiteScroll && !ItemConstants.isCleanSlate(scrollId) && !assertGM) { nEquip.setUpgradeSlots((byte) (nEquip.getUpgradeSlots() - 1)); } if (Randomizer.nextInt(101) < stats.get("cursed")) { diff --git a/src/server/life/MapleMonster.java b/src/server/life/MapleMonster.java index 990c59fcd3..14429dcbf1 100644 --- a/src/server/life/MapleMonster.java +++ b/src/server/life/MapleMonster.java @@ -48,6 +48,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; import net.server.world.MapleParty; @@ -257,26 +258,33 @@ public class MapleMonster extends AbstractLoadedMapleLife { } private void distributeExperienceToParty(int pid, int exp, int killer, Map expDist) { - LinkedList members = new LinkedList<>(); - Collection chrs = map.getCharacters(); - - for (MapleCharacter mc : chrs) { - if (mc.getPartyId() == pid) { - members.add(mc); - } + List members = new LinkedList<>(); + MapleCharacter pchar = getMap().getAnyCharacterFromParty(pid); + if(pchar != null) { + for(MapleCharacter chr : pchar.getPartyMembersOnSameMap()) { + members.add(chr); + } + } else { + MapleCharacter chr = getMap().getCharacterById(killer); + if(chr == null) return; + + members.add(chr); } - + final int minLevel = getLevel() - 5; - int partyLevel = 0; int leechMinLevel = 0; - for (MapleCharacter mc : members) { - if (mc.getLevel() >= minLevel) { - leechMinLevel = Math.min(mc.getLevel() - 5, minLevel); + if(!ServerConstants.USE_UNDERLEVELED_EXP_GAIN) { //NO EXP WILL BE GIVEN for those who are underleveled! + leechMinLevel = minLevel; + + for (MapleCharacter mc : members) { + if (mc.getLevel() >= minLevel) { + leechMinLevel = Math.min(mc.getLevel() - 5, leechMinLevel); + } } } - + int leechCount = 0; for (MapleCharacter mc : members) { if (mc.getLevel() >= leechMinLevel) { @@ -290,13 +298,12 @@ public class MapleMonster extends AbstractLoadedMapleLife { for (MapleCharacter mc : members) { int id = mc.getId(); int level = mc.getLevel(); - if (expDist.containsKey(id) - || level >= leechMinLevel) { + if (expDist.containsKey(id) || level >= leechMinLevel) { boolean isKiller = killer == id; boolean mostDamage = mostDamageCid == id; - int xp = (int) (exp * 0.80f * level / partyLevel); + int xp = (int) ((0.80f * exp * level) / partyLevel); if (mostDamage) { - xp += (exp * 0.20f); + xp += (0.20f * exp); } giveExpToCharacter(mc, xp, isKiller, leechCount); } @@ -311,26 +318,32 @@ public class MapleMonster extends AbstractLoadedMapleLife { int totalHealth = getMaxHp(); Map expDist = new HashMap<>(); Map partyExp = new HashMap<>(); - // 80% of pool is split amongst all the damagers + + float exp8 = (0.8f * exp); // 80% of pool is split amongst all the damagers + float exp2 = (0.2f * exp); // 20% of pool goes to the killer or his/her party + for (Entry damage : takenDamage.entrySet()) { - expDist.put(damage.getKey(), (int) (0.80f * exp * damage.getValue().get() / totalHealth)); + expDist.put(damage.getKey(), (int) (Math.min((exp8 * damage.getValue().get()) / totalHealth, Integer.MAX_VALUE))); } Collection chrs = map.getCharacters(); for (MapleCharacter mc : chrs) { if (expDist.containsKey(mc.getId())) { - boolean isKiller = mc.getId() == killerId; + boolean isKiller = (mc.getId() == killerId); int xp = expDist.get(mc.getId()); if (isKiller) { - xp += exp / 5; + xp = (int)Math.min(exp2 + xp, Integer.MAX_VALUE); } MapleParty p = mc.getParty(); if (p != null) { int pID = p.getId(); - int pXP = xp + (partyExp.containsKey(pID) ? partyExp.get(pID) : 0); - partyExp.put(pID, pXP); + long pXP = (long)xp + (partyExp.containsKey(pID) ? partyExp.get(pID) : 0); + partyExp.put(pID, (int)Math.min(pXP, Integer.MAX_VALUE)); } else { - giveExpToCharacter(mc, xp, isKiller, 1); + if(ServerConstants.USE_UNDERLEVELED_EXP_GAIN || mc.getLevel() >= this.getLevel() - 5) { + //NO EXP WILL BE GIVEN for those who are underleveled! + giveExpToCharacter(mc, xp, isKiller, 1); + } } } } diff --git a/src/server/maps/MapleMap.java b/src/server/maps/MapleMap.java index 2c269fe0e3..bc2c4704dd 100644 --- a/src/server/maps/MapleMap.java +++ b/src/server/maps/MapleMap.java @@ -43,6 +43,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; +import java.util.Set; import java.util.LinkedList; import java.util.List; import java.util.Iterator; @@ -93,6 +94,7 @@ public class MapleMap { private AtomicInteger spawnedMonstersOnMap = new AtomicInteger(0); private AtomicInteger droppedItemCount = new AtomicInteger(0); private Collection characters = new LinkedHashSet<>(); + private Map> mapParty = new LinkedHashMap<>(); private Map portals = new HashMap<>(); private Map backgroundTypes = new HashMap<>(); private Map environment = new LinkedHashMap<>(); @@ -133,6 +135,7 @@ public class MapleMap { private short mobInterval = 5000; private boolean allowSummons = true; // All maps should have this true at the beginning private int lastDoorOwner = -1; + // HPQ private int riceCakes = 0; private int bunnyDamage = 0; @@ -1781,10 +1784,84 @@ public class MapleMap { }, time); } + public MapleCharacter getAnyCharacterFromParty(int partyid) { + chrRLock.lock(); + try { + Set list = mapParty.get(partyid); + if(list == null) return null; + + for(Integer cid : list) { + for (MapleCharacter c : this.characters) { + if (c.getId() == cid) { + return c; + } + } + } + + return null; + } finally { + chrRLock.unlock(); + } + } + + private void addPartyMemberInternal(MapleCharacter chr) { + int partyid = chr.getPartyId(); + if(partyid == -1) return; + + Set partyEntry = mapParty.get(partyid); + if(partyEntry == null) { + partyEntry = new LinkedHashSet<>(); + partyEntry.add(chr.getId()); + + mapParty.put(partyid, partyEntry); + } else { + partyEntry.add(chr.getId()); + } + } + + private void removePartyMemberInternal(MapleCharacter chr) { + int partyid = chr.getPartyId(); + if(partyid == -1) return; + + Set partyEntry = mapParty.get(partyid); + if(partyEntry != null) { + if(partyEntry.size() > 1) partyEntry.remove(chr.getId()); + else mapParty.remove(partyid); + } + } + + public void addPartyMember(MapleCharacter chr) { + chrWLock.lock(); + try { + addPartyMemberInternal(chr); + } finally { + chrWLock.unlock(); + } + } + + public void removePartyMember(MapleCharacter chr) { + chrWLock.lock(); + try { + removePartyMemberInternal(chr); + } finally { + chrWLock.unlock(); + } + } + + public void removeParty(int partyid) { + chrWLock.lock(); + try { + mapParty.remove(partyid); + } finally { + chrWLock.unlock(); + } + } + public void addPlayer(final MapleCharacter chr) { chrWLock.lock(); try { characters.add(chr); + addPartyMemberInternal(chr); } finally { chrWLock.unlock(); } @@ -2047,6 +2124,7 @@ public class MapleMap { public void removePlayer(MapleCharacter chr) { chrWLock.lock(); try { + removePartyMemberInternal(chr); characters.remove(chr); } finally { chrWLock.unlock(); diff --git a/src/tools/MaplePacketCreator.java b/src/tools/MaplePacketCreator.java index ce5fee095c..7f91cb9c8a 100644 --- a/src/tools/MaplePacketCreator.java +++ b/src/tools/MaplePacketCreator.java @@ -2623,7 +2623,8 @@ public class MaplePacketCreator { mplew.writeShort(SendOpcode.GIVE_FOREIGN_BUFF.getValue()); mplew.writeInt(cid); writeLongMaskD(mplew, statups); - for (int i = 0; i < statups.size(); i++) { + for (Pair statup : statups) { + mplew.writeShort(statup.getRight().shortValue()); mplew.writeShort(skill.getSkillId()); mplew.writeShort(skill.getSkillLevel()); } diff --git a/wz/Quest.wz/Check.img.xml b/wz/Quest.wz/Check.img.xml index 8d70d78244..182d87d4ec 100644 --- a/wz/Quest.wz/Check.img.xml +++ b/wz/Quest.wz/Check.img.xml @@ -25248,6 +25248,7 @@ + @@ -25960,13 +25961,6 @@ - - - - - - - diff --git a/wz/Quest.wz/Say.img.xml b/wz/Quest.wz/Say.img.xml index 5451f266ce..5cbe91b8a5 100644 --- a/wz/Quest.wz/Say.img.xml +++ b/wz/Quest.wz/Say.img.xml @@ -12772,6 +12772,7 @@ + diff --git a/wz/Sound.wz/Field.img.xml b/wz/Sound.wz/Field.img.xml index a9bea020ef..ed8a2cdc37 100644 --- a/wz/Sound.wz/Field.img.xml +++ b/wz/Sound.wz/Field.img.xml @@ -76,4 +76,7 @@ + + +