From 828a8a02a2d1496722ac85c529028a33bfa134fb Mon Sep 17 00:00:00 2001 From: ronancpl Date: Sat, 22 Apr 2017 16:35:27 -0300 Subject: [PATCH] Implemented EllinPQ + some bug fixes Implemented EllinPQ, adjusted several drop rates and data, fixes some bugs at quests at client-side. --- README.txt | 93 ++++--------- mychanges_ptbr.txt | 12 +- nbproject/private/private.xml | 15 +- scripts/event/0_EXAMPLE.js | 21 ++- scripts/event/3rdjob.js | 1 + scripts/event/4jberserk.js | 2 + scripts/event/4jrush.js | 6 +- scripts/event/CWKPQ.js | 2 + scripts/event/CathedralWedding.js | 8 +- scripts/event/Ellin.js | 129 ++++++++++++------ scripts/event/GuildQuest.js | 6 +- scripts/event/HenesysPQ.js | 2 + scripts/event/HorntailFight.js | 11 +- scripts/event/KerningPQ.js | 8 +- scripts/event/LudiMazePQ.js | 12 +- scripts/event/LudiPQ.js | 5 +- scripts/event/OrbisPQ.js | 6 +- scripts/event/PiratePQ.js | 21 +-- scripts/event/RockSpirit.js | 2 + scripts/event/ScargaBattle.js | 18 +-- scripts/event/VIPRockSpirit.js | 2 + scripts/event/ZakumBattle.js | 8 +- scripts/event/ZakumPQ.js | 6 +- scripts/event/s4aWorld.js | 9 +- scripts/npc/world0/1072008.js | 8 +- scripts/npc/world0/2094000.js | 2 +- scripts/npc/world0/2133000.js | 12 +- scripts/npc/world0/2133000.txt | 73 ---------- scripts/npc/world0/2133001.js | 9 +- scripts/npc/world0/2133002.js | 6 +- scripts/npc/world0/9120023.js | 4 + scripts/portal/party6_out.js | 9 ++ scripts/portal/party6_stage.js | 30 ++++ scripts/portal/party6_stage501.js | 9 ++ scripts/portal/party6_stage502.js | 9 ++ scripts/portal/party6_stage503.js | 9 ++ scripts/portal/party6_stage504.js | 9 ++ scripts/portal/party6_stage505.js | 9 ++ scripts/portal/party6_stage506.js | 9 ++ scripts/portal/party6_stage507.js | 9 ++ scripts/portal/party6_stage508.js | 9 ++ scripts/portal/party6_stage509.js | 9 ++ scripts/portal/party6_stage510.js | 9 ++ scripts/portal/party6_stage511.js | 9 ++ scripts/portal/party6_stage512.js | 9 ++ scripts/portal/party6_stage513.js | 9 ++ scripts/portal/party6_stage514.js | 9 ++ scripts/portal/party6_stage515.js | 9 ++ scripts/portal/party6_stage800.js | 19 +++ scripts/reactor/1202002.js | 30 ++++ scripts/reactor/3001000.js | 4 + scripts/reactor/3002000.js | 28 ++++ scripts/reactor/3002001.js | 3 + scripts/reactor/3008000.js | 3 + sql/db_database.sql | 18 +-- sql/db_drops.sql | 9 +- sql/db_shopupdate.sql | 12 +- src/client/MapleCharacter.java | 113 ++++++++++++--- src/client/command/Commands.java | 27 +++- src/client/inventory/Equip.java | 6 +- src/constants/ServerConstants.java | 5 +- .../channel/handlers/AutoAssignHandler.java | 4 +- .../channel/handlers/BeholderHandler.java | 4 +- .../handlers/CloseRangeDamageHandler.java | 2 +- .../channel/handlers/DamageSummonHandler.java | 2 +- .../channel/handlers/MagicDamageHandler.java | 2 +- .../channel/handlers/MoveSummonHandler.java | 2 +- .../channel/handlers/RangedAttackHandler.java | 2 +- .../channel/handlers/ReactorHitHandler.java | 2 +- .../channel/handlers/SpecialMoveHandler.java | 2 +- .../channel/handlers/SummonDamageHandler.java | 2 +- src/scripting/event/EventInstanceManager.java | 23 +++- .../reactor/ReactorActionManager.java | 11 +- src/server/maps/MapleMap.java | 67 ++++++--- src/server/maps/MapleMapFactory.java | 1 + src/server/maps/MapleReactor.java | 26 ++-- wz/Map.wz/Map/Map3/300000100.img.xml | 2 +- wz/Map.wz/Map/Map9/930000200.img.xml | 2 +- wz/Quest.wz/Act.img.xml | 2 + wz/Reactor.wz/2408001.img.xml | 2 +- wz/Reactor.wz/3002000.img.xml | 7 - wz/String.wz/Consume.img.xml | 2 +- 82 files changed, 753 insertions(+), 386 deletions(-) delete mode 100644 scripts/npc/world0/2133000.txt create mode 100644 scripts/npc/world0/9120023.js create mode 100644 scripts/portal/party6_out.js create mode 100644 scripts/portal/party6_stage.js create mode 100644 scripts/portal/party6_stage501.js create mode 100644 scripts/portal/party6_stage502.js create mode 100644 scripts/portal/party6_stage503.js create mode 100644 scripts/portal/party6_stage504.js create mode 100644 scripts/portal/party6_stage505.js create mode 100644 scripts/portal/party6_stage506.js create mode 100644 scripts/portal/party6_stage507.js create mode 100644 scripts/portal/party6_stage508.js create mode 100644 scripts/portal/party6_stage509.js create mode 100644 scripts/portal/party6_stage510.js create mode 100644 scripts/portal/party6_stage511.js create mode 100644 scripts/portal/party6_stage512.js create mode 100644 scripts/portal/party6_stage513.js create mode 100644 scripts/portal/party6_stage514.js create mode 100644 scripts/portal/party6_stage515.js create mode 100644 scripts/portal/party6_stage800.js create mode 100644 scripts/reactor/1202002.js create mode 100644 scripts/reactor/3001000.js create mode 100644 scripts/reactor/3002000.js create mode 100644 scripts/reactor/3002001.js create mode 100644 scripts/reactor/3008000.js diff --git a/README.txt b/README.txt index caed4a1a1b..0d5ee42075 100644 --- a/README.txt +++ b/README.txt @@ -2,18 +2,11 @@ MapleSolaxiaV2 Freelance developer: Ronan C. P. Lana -Credits are to be given to the original MapleSolaxia staff and other colaborators, as just some minor -changes/patches on the game were applied by myself, in which some of them diverged from the original v83 -patch contents. +Credits are to be given to the original MapleSolaxia staff and other colaborators, as just some minor changes/patches on the game were applied by myself, in which some of them diverged from the original v83 patch contents. -This is a NetBeans 8.0.2 Project. This means that it's easier to install the project via opening the server -project folder inside NetBeans' IDE. Once installed, build this project on your machine and run the server using -the "launch.bat" application. +This is a NetBeans 8.0.2 Project. This means that it's easier to install the project via opening the server project folder inside NetBeans' IDE. Once installed, build this project on your machine and run the server using the "launch.bat" application. -In this project, many gameplay-wise issues generated from either the original WZ files and the server sources -have been partially or completely solved. From now on, considering the use of some of this system's edited WZ -and server-side files should be a great asset for new private server instances. My opinion, though! Refer to -"README_wzchanges.txt" for more information on what have been changed from Nexon's v83 WZ files. +In this project, many gameplay-wise issues generated from either the original WZ files and the server sources have been partially or completely solved. From now on, considering the use of some of this system's edited WZ and server-side files should be a great asset for new private server instances. My opinion, though! Refer to "README_wzchanges.txt" for more information on what have been changed from Nexon's v83 WZ files. ---- Download items ---- @@ -22,8 +15,7 @@ Client files & general tools: https://drive.google.com/drive/folders/0BzDsHSr-0V ---- Preparing the ambient ---- -The following link teaches on how to install a MapleStory v83 private server, however IT DIFFERS on what is -used here: http://forum.ragezone.com/f428/maplestory-private-server-v83-741739/ +The following link teaches on how to install a MapleStory v83 private server, however IT DIFFERS on what is used here: http://forum.ragezone.com/f428/maplestory-private-server-v83-741739/ Use that link ONLY AS AN ORIENTATION on where here things become ambiguous. @@ -56,9 +48,7 @@ The Wamp icon must look completely green (if its orange or red, you have a probl For Hamachi: Try opening it. It's that simple. -Hamachi is optional, though. You don't have to install Hamachi if you want to make the server just for use on -your own machine. However, if you want to let other players access your server, consider alternatively using -port-forwarding methods. +Hamachi is optional, though. You don't have to install Hamachi if you want to make the server just for use on your own machine. However, if you want to let other players access your server, consider alternatively using port-forwarding methods. ---- Installing the SERVER ---- @@ -75,43 +65,30 @@ Now it is OPTIONAL, you don't need to run it if you don't want, as it will simpl some new goods, not present in the original MapleStory, to sell: - File -> Open Script... -> Browse for "C:\MapleSolaxia\sql" -> db_shopupdate.sql, and execute it. -At the end of the execution of these SQLs, you should have installed a database schema named "maplesolaxia". REGISTER -YOUR FIRST ACCOUNT to be used in-game by creating manually a entry on the table "accounts" at that database with a -login and a password. +At the end of the execution of these SQLs, you should have installed a database schema named "maplesolaxia". REGISTER YOUR FIRST ACCOUNT to be used in-game by creating manually a entry on the table "accounts" at that database with a login and a password. -Configure the IP you want to use for your MapleStory server in "configuration.ini" file, or set it as "localhost" -if you want to run it only on your machine. Alternatively, you can use the IP given by Hamachi to use on a -Hamachi network, or you can use a non-Hamachi method of port-forwarding. Neither will be approached here. +Configure the IP you want to use for your MapleStory server in "configuration.ini" file, or set it as "localhost" if you want to run it only on your machine. Alternatively, you can use the IP given by Hamachi to use on a Hamachi network, or you can use a non-Hamachi method of port-forwarding. Neither will be approached here. -Now open NetBeans, and choose to Open a project... Select then the "MapleSolaxia" folder, that should already be -a project recognizable by NetBeans. If it doesn't, you have a problem. +Now open NetBeans, and choose to Open a project... Select then the "MapleSolaxia" folder, that should already be a project recognizable by NetBeans. If it doesn't, you have a problem. -Finally, select "Clean and Build project" to build the JAR file for the MapleStory server. Once done, make sure both -WampServer and Hamachi are on and functioning, and then execute "launch.bat" on the root of the project. If no errors -were raised from this action, your MapleStory server is now online. +Finally, select "Clean and Build project" to build the JAR file for the MapleStory server. Once done, make sure both WampServer and Hamachi are on and functioning, and then execute "launch.bat" on the root of the project. If no errors were raised from this action, your MapleStory server is now online. ---- Installing the CLIENT ---- The client's set-up is quite straightforward: - - From "ManagerMsv83.exe", install MapleStory on your folder of preference (e.g. "C:\Nexon\MapleStory") and -follow their instructions. + - From "ManagerMsv83.exe", install MapleStory on your folder of preference (e.g. "C:\Nexon\MapleStory") and follow their instructions. - Once done, erase these files: "HShield" (folder), "ASPLauncher.exe", "MapleStory.exe" and "patcher.exe". - Extract into the client folder the "localhost.exe" from Localhostv83. - Overwrite the original WZ files with the ones provided from "client_wz" folder on the Google Drive. -If you are not using "localhost" as the target IP on the server's config file, you will need to HEX-EDIT "localhost.exe" -to fetch your IP. The "localhost.exe" uses the following byte addresses to store the server's IP address: +If you are not using "localhost" as the target IP on the server's config file, you will need to HEX-EDIT "localhost.exe" to fetch your IP. The "localhost.exe" uses the following byte addresses to store the server's IP address: - 006FE084; - 006FE094; - 006FE0A4; -To hex-edit, install the Neo Hex Editor from "free-hex-editor-neo.exe" and follow their instructions. Once done, open -"localhost.exe" for editing and overwrite the IP values under these 3 addresses. Save the changes and exit the editor. +To hex-edit, install the Neo Hex Editor from "free-hex-editor-neo.exe" and follow their instructions. Once done, open "localhost.exe" for editing and overwrite the IP values under these 3 addresses. Save the changes and exit the editor. -Open the "localhost.exe" client. If by any means the program did not open, and checking que server log your ping has -been listened and you are using Windows 8 or 10, it probably might be some compatibility issue. Extract "lolwut.exe" -from "lolwut-v0.01.rar" and place it on the MapleStory client folder ("C:\Nexon\MapleStory"). Your "localhost.exe" -property settings must follow these: +Open the "localhost.exe" client. If by any means the program did not open, and checking que server log your ping has been listened and you are using Windows 8 or 10, it probably might be some compatibility issue. Extract "lolwut.exe" from "lolwut-v0.01.rar" and place it on the MapleStory client folder ("C:\Nexon\MapleStory"). Your "localhost.exe" property settings must follow these: - Run in compatibility mode: Windows 7; - Unchecked reduced color mode; - 640 x 480 resolution; @@ -119,12 +96,9 @@ property settings must follow these: - Run as an administrator; - Opening "lolwut.exe", use Fraysa's method. -Alternatively, there is available the No-Damage Cap version of the MapleStory client. Just extract and use the -"localhost.exe" from the one package with the given name. +Alternatively, there is available the No-Damage Cap version of the MapleStory client. Just extract and use the "localhost.exe" from the one package with the given name. -Important: should the client being refused to connect to the game server, it may be because firewall issues. Head to -the end of this file to proceed to enabling this connection with the computer's firewall. Alternatively, one can -deactivate the firewall and try opening the client again. +Important: should the client being refused to connect to the game server, it may be because firewall issues. Head to the end of this file to proceed to enabling this connection with the computer's firewall. Alternatively, one can deactivate the firewall and try opening the client again. ---- Important note about CLIENT EDITING ---- @@ -132,54 +106,37 @@ DO NOT USE the server's XMLs for reimporting into the client's WZ, it WILL gener - Use instead the HaRepacker 4.2.4, encryption "GMS (old)". - Open the desired WZ for editing and, USING THE UI, make the desired changes. - Save the changed WZ, overwriting the original content at the client folder. - - Finally, RE-EXPORT ("Private Server..." exporting option) the changed XMLs into the server's WZ.XML files, -overwriting the old contents. + - Finally, RE-EXPORT ("Private Server..." exporting option) the changed XMLs into the server's WZ.XML files, overwriting the old contents. These steps are IMPORTANT to maintain synchronization between the server and client modules. -As an example of client WZ editing, consider the MobBookUpdate project I developed, for updating all reported drop -data of the mobs in the game based on the current drop data on the database: - +As an example of client WZ editing, consider the MobBookUpdate project I developed, for updating all reported drop data of the mobs in the game based on the current drop data on the database: - Open the MobBookUpdate project on NetBeans, located at "C:\Nexon\MapleSolaxia\MobBookUpdate", and build it. - At the subfolder "lib", copy the file "MonsterBook.img.xml". This is from the original WZ v83. - Paste it on the "dist" subfolder. - Inside "dist", open the command prompt by alt+right clicking there. - Execute "java -jar MobBookUpdate.jar". It will generate a "MonsterBook_updated.img.xml" file. - - At last, overwrite the "MonsterBook.img.xml" on "C:\Nexon\MapleSolaxia\wz\String.wz" with this file, renaming -it back to "MonsterBook.img.xml". + - At last, overwrite the "MonsterBook.img.xml" on "C:\Nexon\MapleSolaxia\wz\String.wz" with this file, renaming it back to "MonsterBook.img.xml". -At this point, the server-side Monster Book has been updated with the current state of the database's drop data. Then, -open HaRepacker 4.2.2 and load "String.wz" from "C:\Nexon\MapleStory". Drop the "MonsterBook.img" node by removing it -from the hierarchy tree, then (CONTRARY TO WHAT SHOULD BE DONE NORMALLY!) import the server's "MonsterBook.img.xml". +At this point, the server-side Monster Book has been updated with the current state of the database's drop data. Then, open HaRepacker 4.2.2 and load "String.wz" from "C:\Nexon\MapleStory". Drop the "MonsterBook.img" node by removing it from the hierarchy tree, then (CONTRARY TO WHAT SHOULD BE DONE NORMALLY!) import the server's "MonsterBook.img.xml". -Take note that this is absolutely dangerous if done unwary. Once the MonsterBook does not hold client specific data in -it's node contents, importing the XML causes no harm at all. However, try not to remove/reimport nodes from WZ files, -as it may cause data losses. Use the HaRepacker's UI instead to make the changes. +Take note that this is absolutely dangerous if done unwary. Once the MonsterBook does not hold client specific data in it's node contents, importing the XML causes no harm at all. However, try not to remove/reimport nodes from WZ files, as it may cause data losses. Use the HaRepacker's UI instead to make the changes. Save the changes and overwrite the older WZ on the MapleStory client folder. ---- Portforwarding the SERVER ---- -To use portforward, you will need to have permission to change things on the LAN router. Access yor router using the -Internet browser. URLs vary accordingly with the manufacturer. To discover it, open the command prompt and type -"ipconfig" and search for the "default gateway" field. The IP shown there is the URL needed to access the router. -Also, look for the IP given to your machine (aka "IPv4 address" field), which will be the server one. +To use portforward, you will need to have permission to change things on the LAN router. Access yor router using the Internet browser. URLs vary accordingly with the manufacturer. To discover it, open the command prompt and type "ipconfig" and search for the "default gateway" field. The IP shown there is the URL needed to access the router. Also, look for the IP given to your machine (aka "IPv4 address" field), which will be the server one. -The default login/password also varies, so use the link http://www.routerpasswords.com/ as reference. Usually, login -as "admin" and password as "password" completes the task well. +The default login/password also varies, so use the link http://www.routerpasswords.com/ as reference. Usually, login as "admin" and password as "password" completes the task well. -Now you have logged in the router system, find for anything related to portforwarding. Should the system prompts you -between portforwarding and portriggering, pick the first, it is what we will be using. +Now you have logged in the router system, find for anything related to portforwarding. Should the system prompts you between portforwarding and portriggering, pick the first, it is what we will be using. -Now, it is needed to enable the right ports for the Internet. For MapleSolaxia, it is basically needed to open ports -7575 to 7575 + (number of channels) and port 8484. Create a new custom service which enables that range of ports for -the server's channel and opt to use TCP/UDP protocols. Finally, create a custom service now for using port 8484. +Now, it is needed to enable the right ports for the Internet. For MapleSolaxia, it is basically needed to open ports 7575 to 7575 + (number of channels) and port 8484. Create a new custom service which enables that range of ports for the server's channel and opt to use TCP/UDP protocols. Finally, create a custom service now for using port 8484. Optionally, if you want to host a webpage, portforward the port 80 (the HTTP port) as well. -It is not done yet, sometimes the firewalls will block connections between the LAN and the Internet. To overcome this, -it is needed to create some rules for the firewall to permit these connections. Search for the advanced options with -firewalls on your computer and, with it open, create two rules (one outbound and one inbound). +It is not done yet, sometimes the firewalls will block connections between the LAN and the Internet. To overcome this, it is needed to create some rules for the firewall to permit these connections. Search for the advanced options with firewalls on your computer and, with it open, create two rules (one outbound and one inbound). These rules must target "one application", "enable connections" and must target your MapleStory client (aka localhost). diff --git a/mychanges_ptbr.txt b/mychanges_ptbr.txt index cf707e70f8..650b8d5239 100644 --- a/mychanges_ptbr.txt +++ b/mychanges_ptbr.txt @@ -159,4 +159,14 @@ Corre 18 Abril 2017, Adição de area boss: giant centipede. Correção do evento Hak: viajantes não estavam sendo devidamente liberados no fim do evento. -Adição de documentação para portforwarding do sistema. \ No newline at end of file +Adição de documentação para portforwarding do sistema. + +21 Abril 2017, +Implementação do EllinPQ. +Correção em módulos da classe ActivateItemReactor. +Atualização em diversos drops nos SQLs. + +22 Abril 2017, +Várias correções envolvendo concorrências em propriedades do MapleCharacter. +Adição de constante USE_EQUIPMNT_LVLUP: dá pra nivelar qualquer equip até o nível desejado. +Algumas correções em quests no cliente e no servidor. \ No newline at end of file diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml index a8d24b8d6e..19a5a99d4b 100644 --- a/nbproject/private/private.xml +++ b/nbproject/private/private.xml @@ -3,16 +3,13 @@ - file:/C:/Nexon/MapleSolaxia/src/scripting/event/EventManager.java - file:/C:/Nexon/MapleSolaxia/src/net/server/channel/Channel.java - file:/C:/Nexon/MapleSolaxia/scripts/npc/world0/2090005.js - file:/C:/Nexon/MapleSolaxia/scripts/event/Hak.js - file:/C:/Nexon/MapleSolaxia/src/net/server/PlayerStorage.java - file:/C:/Nexon/MapleSolaxia/scripts/event/PiratePQ.js + file:/C:/Nexon/MapleSolaxia/src/net/server/channel/handlers/BeholderHandler.java + file:/C:/Nexon/MapleSolaxia/src/client/inventory/Equip.java + file:/C:/Nexon/MapleSolaxia/src/net/server/world/MapleParty.java + file:/C:/Nexon/MapleSolaxia/src/net/server/channel/handlers/PlayerLoggedinHandler.java file:/C:/Nexon/MapleSolaxia/src/client/MapleCharacter.java - file:/C:/Nexon/MapleSolaxia/src/client/command/Commands.java - file:/C:/Nexon/MapleSolaxia/src/scripting/event/EventInstanceManager.java - file:/C:/Nexon/MapleSolaxia/scripts/event/Boats.js + file:/C:/Nexon/MapleSolaxia/src/tools/MaplePacketCreator.java + file:/C:/Nexon/MapleSolaxia/src/constants/ServerConstants.java file:/C:/Nexon/MapleSolaxia/src/server/maps/MapleMap.java diff --git a/scripts/event/0_EXAMPLE.js b/scripts/event/0_EXAMPLE.js index 1687a153fc..7a92c046e0 100644 --- a/scripts/event/0_EXAMPLE.js +++ b/scripts/event/0_EXAMPLE.js @@ -15,14 +15,23 @@ function changedMap(eim, player, mapid) { } function scheduledTimeout(eim) { - // When event timeout.. - - // restartEventTimer(long time) - // stopEventTimer() - // startEventTimer(long time) - // isTimerStarted() + // When event timeout without before completion.. } +function timeOut(eim) { + if (eim.getPlayerCount() > 0) { + var pIter = eim.getPlayers().iterator(); + while (pIter.hasNext()){ + var player = pIter.next(); + player.dropMessage(6, "You have run out of time to complete this event!"); + playerExit(eim, player); + } + } + eim.dispose(); +} + +function monsterKilled(mob, eim) {} + function allMonstersDead(eim) { // When invoking unregisterMonster(MapleMonster mob) OR killed // Happens only when size = 0 diff --git a/scripts/event/3rdjob.js b/scripts/event/3rdjob.js index ad099f0b98..e3d0d53c98 100644 --- a/scripts/event/3rdjob.js +++ b/scripts/event/3rdjob.js @@ -89,6 +89,7 @@ function playerDisconnected(eim, player) { eim.dispose(); } +function monsterKilled(mob, eim) {} function allMonstersDead(eim) { var winner = eim.getPlayers().get(0); diff --git a/scripts/event/4jberserk.js b/scripts/event/4jberserk.js index 264ab62204..114960b820 100644 --- a/scripts/event/4jberserk.js +++ b/scripts/event/4jberserk.js @@ -154,6 +154,8 @@ function clearPQ(eim) { eim.dispose(); } +function monsterKilled(mob, eim) {} + function allMonstersDead(eim) { eim.setProperty("canWarp","true"); } diff --git a/scripts/event/4jrush.js b/scripts/event/4jrush.js index dc448ce1d4..629942683b 100644 --- a/scripts/event/4jrush.js +++ b/scripts/event/4jrush.js @@ -122,9 +122,9 @@ function clearPQ(eim) { eim.dispose(); } -function allMonstersDead(eim) { -//do nothing; KPQ has nothing to do with monster killing -} +function monsterKilled(mob, eim) {} + +function allMonstersDead(eim) {} function cancelSchedule() { } diff --git a/scripts/event/CWKPQ.js b/scripts/event/CWKPQ.js index 49e94a70fd..c78bfd5937 100644 --- a/scripts/event/CWKPQ.js +++ b/scripts/event/CWKPQ.js @@ -180,6 +180,8 @@ function clearPQ(eim) { end(eim); } +function monsterKilled(mob, eim) {} + function allMonstersDead(eim) { } diff --git a/scripts/event/CathedralWedding.js b/scripts/event/CathedralWedding.js index 368641e462..bf9a06fe79 100644 --- a/scripts/event/CathedralWedding.js +++ b/scripts/event/CathedralWedding.js @@ -164,11 +164,11 @@ function clearPQ(eim) { eim.dispose(); } -function allMonstersDead(eim) { -} +function monsterKilled(mob, eim) {} -function cancelSchedule() { -} +function allMonstersDead(eim) {} + +function cancelSchedule() {} function timeOut() { var iter = em.getInstances().iterator(); diff --git a/scripts/event/Ellin.js b/scripts/event/Ellin.js index 576581133a..93343be898 100644 --- a/scripts/event/Ellin.js +++ b/scripts/event/Ellin.js @@ -1,5 +1,9 @@ +importPackage(Packages.client.inventory); +importPackage(Packages.tools); + var minPlayers = 2; var entryMap = 930000000; +var exitMap = 930000800; function init() { em.setProperty("state", "0"); @@ -18,73 +22,116 @@ function setup(level, leaderid) { eim.setInstanceMap(930000400).resetPQ(level); var map = eim.setInstanceMap(930000500); map.resetPQ(level); - map.shuffleReactors(); + map.shuffleReactors(); eim.setInstanceMap(930000600).resetPQ(level); eim.setInstanceMap(930000700).resetPQ(level); - eim.startEventTimer(20 * 60000); //20 mins + respawnStg2(eim); + eim.startEventTimer(30 * 60000); //30 mins return eim; } -function playerEntry(eim, player) { - var map = eim.getMapInstance(entryMap); - player.changeMap(map, map.getPortal(0)); -} - -function playerRevive(eim, player) { -} - -function scheduledTimeout(eim) { - end(eim); +function respawnStg2(eim) { + if(!eim.getMapInstance(930000200).getAllPlayer().isEmpty()) eim.getMapInstance(930000200).instanceMapRespawn(); + em.schedule("respawnStg2", eim, 4 * 1000); } function changedMap(eim, player, mapid) { - if (mapid < 930000000 || mapid > 930000700) { + if (mapid < 930000000 || mapid > 930000800) { eim.unregisterPlayer(player); - - if (eim.disposeIfPlayerBelow(0, 0)) { - em.setProperty("state", "0"); - em.setProperty("leader", "true"); - } + if(eim.getPlayers().isEmpty()) end(eim); } } +function playerEntry(eim, player) { + var map = eim.getMapInstance(entryMap); + player.changeMap(map, map.getPortal(0)); +} + +function scheduledTimeout(eim) { + end(eim); +} + +function removePlayer(eim, player) { + eim.unregisterPlayer(player); + player.changeMap(exitMap, 0); +} + +function playerDead(eim, player) {} + +function playerRevive(eim, player) { // player presses ok on the death pop up. + if (eim.isLeader(player) || party.size() <= minPlayers) { // Check for party leader + var party = eim.getPlayers(); + for (var i = 0; i < party.size(); i++) + playerExit(eim, party.get(i)); + eim.dispose(); + } else + playerExit(eim, player); +} + + function playerDisconnected(eim, player) { - return 0; + var party = eim.getPlayers(); + if (eim.isLeader(player) || party.size() < minPlayers) { + 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(); + } else + removePlayer(eim, player); +} + +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) { + var party = eim.getPlayers(); + for (var i = 0; i < party.size(); i++) { + playerExit(eim, party.get(i)); + } + eim.dispose(); +} + +function playerExit(eim, player) { + eim.unregisterPlayer(player); + player.changeMap(exitMap, 0); } function monsterValue(eim, mobId) { return 1; } -function playerExit(eim, player) { - eim.unregisterPlayer(player); - - if (eim.disposeIfPlayerBelow(0, 0)) { - em.setProperty("state", "0"); - em.setProperty("leader", "true"); - } -} - function end(eim) { - eim.disposeIfPlayerBelow(100, 930000800); - em.setProperty("state", "0"); - em.setProperty("leader", "true"); + var party = eim.getPlayers(); + for (var i = 0; i < party.size(); i++) { + playerExit(eim, party.get(i)); + } + eim.dispose(); } function clearPQ(eim) { end(eim); } -function allMonstersDead(eim) { -} +function monsterKilled(mob, eim) {} -function leftParty (eim, player) { - // If only 2 players are left, uncompletable: - end(eim); +function allMonstersDead(eim) {} + +function cancelSchedule() {} + +function dispose(eim) { + em.cancelSchedule(); + + em.setProperty("state", "0"); + em.setProperty("leader", "true"); } -function disbandParty (eim) { - end(eim); -} -function playerDead(eim, player) {} -function cancelSchedule() {} \ No newline at end of file diff --git a/scripts/event/GuildQuest.js b/scripts/event/GuildQuest.js index cf3a1d013e..ebc48f38d0 100644 --- a/scripts/event/GuildQuest.js +++ b/scripts/event/GuildQuest.js @@ -190,9 +190,9 @@ function finish(eim) { eim.dispose(); } -function allMonstersDead(eim) { -//do nothing; GQ has nothing to do with monster killing -} +function monsterKilled(mob, eim) {} + +function allMonstersDead(eim) {} function cancelSchedule() { } diff --git a/scripts/event/HenesysPQ.js b/scripts/event/HenesysPQ.js index a404b516b9..cbf8af191c 100644 --- a/scripts/event/HenesysPQ.js +++ b/scripts/event/HenesysPQ.js @@ -165,6 +165,8 @@ function clearPQ(eim) { eim.dispose(); } +function monsterKilled(mob, eim) {} + function allMonstersDead(eim) {} function dispose() { diff --git a/scripts/event/HorntailFight.js b/scripts/event/HorntailFight.js index 15bfd530be..ceecb12b8f 100644 --- a/scripts/event/HorntailFight.js +++ b/scripts/event/HorntailFight.js @@ -136,14 +136,13 @@ function finish(eim) { eim.dispose(); } -function allMonstersDead(eim) { -} +function monsterKilled(mob, eim) {} -function cancelSchedule() { -} +function allMonstersDead(eim) {} -function timeOut() { -} +function cancelSchedule() {} + +function timeOut() {} function debug(eim,msg) { var iter = eim.getPlayers().iterator(); diff --git a/scripts/event/KerningPQ.js b/scripts/event/KerningPQ.js index 983d06c218..322c98ad0e 100644 --- a/scripts/event/KerningPQ.js +++ b/scripts/event/KerningPQ.js @@ -137,11 +137,11 @@ function clearPQ(eim) { eim.dispose(); } -function allMonstersDead(eim) { -} +function monsterKilled(mob, eim) {} -function cancelSchedule() { -} +function allMonstersDead(eim) {} + +function cancelSchedule() {} function dispose(eim) { em.cancelSchedule(); diff --git a/scripts/event/LudiMazePQ.js b/scripts/event/LudiMazePQ.js index e43c458198..439c452d4c 100644 --- a/scripts/event/LudiMazePQ.js +++ b/scripts/event/LudiMazePQ.js @@ -126,16 +126,14 @@ function clearPQ(eim) { eim.dispose(); } -function allMonstersDead(eim) { -//do nothing; LMPQ has nothing to do with monster killing -} +function monsterKilled(mob, eim) {} -function cancelSchedule() { -} +function allMonstersDead(eim) {} -function dispose(eim) { +function cancelSchedule() {} + +function dispose(eim) {} -} function timeOut(eim) { if (eim != null) { if (eim.getPlayerCount() > 0) { diff --git a/scripts/event/LudiPQ.js b/scripts/event/LudiPQ.js index 2e598702d2..1e382ab818 100644 --- a/scripts/event/LudiPQ.js +++ b/scripts/event/LudiPQ.js @@ -146,8 +146,9 @@ function clearPQ(eim) { eim.dispose(); } -function allMonstersDead(eim) { -} +function monsterKilled(mob, eim) {} + +function allMonstersDead(eim) {} function dispose() { em.schedule("OpenLPQ", 10000); // 10 seconds ? diff --git a/scripts/event/OrbisPQ.js b/scripts/event/OrbisPQ.js index d5c57ce134..25d9f76ec3 100644 --- a/scripts/event/OrbisPQ.js +++ b/scripts/event/OrbisPQ.js @@ -224,9 +224,9 @@ function finish(eim) { eim.dispose(); } -function allMonstersDead(eim) { -//Open Portal? o.O -} +function monsterKilled(mob, eim) {} + +function allMonstersDead(eim) {} //Open Portal? o.O function cancelSchedule() { } diff --git a/scripts/event/PiratePQ.js b/scripts/event/PiratePQ.js index 5b3d9f535d..438fc0ffce 100644 --- a/scripts/event/PiratePQ.js +++ b/scripts/event/PiratePQ.js @@ -22,9 +22,12 @@ function setup(level, leaderid) { em.setProperty("level", level); em.setProperty("openedChests", "0"); eim.setInstanceMap(925100000).resetPQ(level); + eim.setInstanceMap(925100000).shuffleReactors(); + eim.setInstanceMap(925100100).resetPQ(level); var map = eim.setInstanceMap(925100200); map.resetPQ(level); + map.shuffleReactors(); for (var i = 0; i < 5; i++) { var mob = em.getMonster(9300124); var mob2 = em.getMonster(9300125); @@ -58,6 +61,7 @@ function setup(level, leaderid) { eim.setInstanceMap(925100202).resetPQ(level); map = eim.setInstanceMap(925100300); map.resetPQ(level); + map.shuffleReactors(); for (var i = 0; i < 5; i++) { var mob = em.getMonster(9300124); var mob2 = em.getMonster(9300125); @@ -93,7 +97,7 @@ function setup(level, leaderid) { eim.setInstanceMap(925100500).resetPQ(level); respawnStg4(eim); - eim.startEventTimer(1200000); //20 mins + eim.startEventTimer(20 * 60000); //20 mins return eim; } @@ -108,8 +112,7 @@ function scheduledTimeout(eim) { function removePlayer(eim, player) { eim.unregisterPlayer(player); - player.getMap().removePlayer(player); - player.setMap(exitMap); + player.changeMap(exitMap, 0); } function changedMap(eim, player, mapid) { @@ -170,7 +173,7 @@ function disbandParty(eim) { function playerExit(eim, player) { eim.unregisterPlayer(player); - player.changeMap(exitMap, exitMap.getPortal(0)); + player.changeMap(exitMap, 0); } function monsterValue(eim, mobId) { @@ -189,15 +192,15 @@ function clearPQ(eim) { end(eim); } +function monsterKilled(mob, eim) {} + function allMonstersDead(eim) {} function cancelSchedule() {} -function respawnStg4(eim) { - //if(em.getProperty("stage4") == "0") { - eim.getMapInstance(925100400).instanceMapRespawn(); - em.schedule("respawnStg4", eim, 10 * 1000); - //} +function respawnStg4(eim) { + eim.getMapInstance(925100400).instanceMapRespawn(); + em.schedule("respawnStg4", eim, 10 * 1000); } function dispose(eim) { diff --git a/scripts/event/RockSpirit.js b/scripts/event/RockSpirit.js index 8149ed17a0..1634c255d8 100644 --- a/scripts/event/RockSpirit.js +++ b/scripts/event/RockSpirit.js @@ -120,6 +120,8 @@ function dispose() {} function clearPQ(eim) {} +function monsterKilled(mob, eim) {} + function allMonstersDead(eim) {} function timeOut(eim) { diff --git a/scripts/event/ScargaBattle.js b/scripts/event/ScargaBattle.js index 3a7c4ef2fe..ef923bd3aa 100644 --- a/scripts/event/ScargaBattle.js +++ b/scripts/event/ScargaBattle.js @@ -36,10 +36,10 @@ function init() { } function setup() { - var eim = em.newInstance("ScargaBattle_" + em.getProperty("channel")); + var eim = em.newInstance("ScargaBattle_" + em.getProperty("channel")); var timer = 1000 * 60 * fightTime; eim.setProperty("summoned", "false"); - em.schedule("timeOut", eim, timer); + em.schedule("timeOut", eim, timer); eim.startEventTimer(timer); return eim; } @@ -133,21 +133,21 @@ function finish(eim) { eim.dispose(); } -function allMonstersDead(eim) { -} +function monsterKilled(mob, eim) {} -function cancelSchedule() { -} +function allMonstersDead(eim) {} + +function cancelSchedule() {} function timeOut(eim) { if (eim != null) { if (eim.getPlayerCount() > 0) { var pIter = eim.getPlayers().iterator(); while (pIter.hasNext()){ - var player = pIter.next(); - player.dropMessage(6, "You have run out of time to defeat Scarlion and Targa!"); + var player = pIter.next(); + player.dropMessage(6, "You have run out of time to defeat Scarlion and Targa!"); playerExit(eim, player); - } + } } eim.dispose(); } diff --git a/scripts/event/VIPRockSpirit.js b/scripts/event/VIPRockSpirit.js index 6f35f68774..383fc20352 100644 --- a/scripts/event/VIPRockSpirit.js +++ b/scripts/event/VIPRockSpirit.js @@ -120,6 +120,8 @@ function dispose() {} function clearPQ(eim) {} +function monsterKilled(mob, eim) {} + function allMonstersDead(eim) {} function timeOut(eim) { diff --git a/scripts/event/ZakumBattle.js b/scripts/event/ZakumBattle.js index cd0a9c296b..874802136f 100644 --- a/scripts/event/ZakumBattle.js +++ b/scripts/event/ZakumBattle.js @@ -151,11 +151,11 @@ function finish(eim) { eim.dispose(); } -function allMonstersDead(eim) { -} +function monsterKilled(mob, eim) {} -function cancelSchedule() { -} +function allMonstersDead(eim) {} + +function cancelSchedule() {} function altarTimeOut(eim) { if (eim != null && eim.getProperty("summoned").equals("false")) { diff --git a/scripts/event/ZakumPQ.js b/scripts/event/ZakumPQ.js index 3f73024c87..f54ae1515d 100644 --- a/scripts/event/ZakumPQ.js +++ b/scripts/event/ZakumPQ.js @@ -139,9 +139,9 @@ function clearPQ(eim) { eim.dispose(); } -function allMonstersDead(eim) { -//do nothing; ZPQ has nothing to do with monster killing -} +function monsterKilled(mob, eim) {} + +function allMonstersDead(eim) {} function cancelSchedule() { } diff --git a/scripts/event/s4aWorld.js b/scripts/event/s4aWorld.js index 2cc476082e..f05813503b 100644 --- a/scripts/event/s4aWorld.js +++ b/scripts/event/s4aWorld.js @@ -76,9 +76,8 @@ function clearPQ(eim) { em.setProperty("started", "false"); } -function allMonstersDead(eim) { -//has nothing to do with monster killing -} +function monsterKilled(mob, eim) {} -function cancelSchedule() { -} \ No newline at end of file +function allMonstersDead(eim) {} + +function cancelSchedule() {} \ No newline at end of file diff --git a/scripts/npc/world0/1072008.js b/scripts/npc/world0/1072008.js index dae6e0194f..78226f09d1 100644 --- a/scripts/npc/world0/1072008.js +++ b/scripts/npc/world0/1072008.js @@ -15,19 +15,19 @@ function action(mode,type,selection) { if (status == -1) { if (cm.getMapId() == 108000502) { if (!(cm.haveItem(4031856,15))) { - cm.sendNext("Go, and get me 15 #bPotent Wind Crystals#k."); + cm.sendNext("Go, and get me 15 #b#t4031856##k."); cm.dispose(); } else { status = 2; - cm.sendNext("Wow, you have brought me 15 #bPotent Wind Crystals#k! Congratulations. Let me warp you out now."); + cm.sendNext("Wow, you have brought me 15 #b#t4031856##k! Congratulations. Let me warp you out now."); } } else if (cm.getMapId() == 108000501) { if (!(cm.haveItem(4031857,15))) { - cm.sendNext("Go, and get me 15 #bPotent Power Crystals#k."); + cm.sendNext("Go, and get me 15 #b#t4031857##k."); cm.dispose(); } else { status = 2; - cm.sendNext("Wow, you have brought me 15 #bPotent Power Crystals#k! Congratulations. Let me warp you out now."); + cm.sendNext("Wow, you have brought me 15 #b#t4031857##k! Congratulations. Let me warp you out now."); } } else { cm.sendNext("Error. Please report this."); diff --git a/scripts/npc/world0/2094000.js b/scripts/npc/world0/2094000.js index 122f665534..246f67d876 100644 --- a/scripts/npc/world0/2094000.js +++ b/scripts/npc/world0/2094000.js @@ -84,7 +84,7 @@ function action(mode, type, selection) { cm.dispose(); } else { - cm.sendOk("Your party is not a party of two to six members. Make sure all your members are present and qualified to participate in this quest. I see #b" + levelValid.toString() + " #kmembers are in the right level range, and #b" + inMap.toString() + "#k are in my map. If this seems wrong, #blog out and log back in,#k or reform the party."); + cm.sendOk("Your party is not a party of 2 to 6 members between level " + minLevel + " and " + maxLevel + ". Make sure all your members are present and qualified to participate in this quest."); cm.dispose(); } } diff --git a/scripts/npc/world0/2133000.js b/scripts/npc/world0/2133000.js index 64608e1a78..e055145b67 100644 --- a/scripts/npc/world0/2133000.js +++ b/scripts/npc/world0/2133000.js @@ -1,4 +1,7 @@ var status = -1; +var minPlayers = 0; + +var minLevel = 44, maxLevel = 170; function start() { action(1,0,0); @@ -14,9 +17,6 @@ function action(mode, type, selection) { status--; } if (status == 0) { - cm.removeAll(4001163); - cm.removeAll(4001169); - cm.removeAll(2270004); cm.sendSimple("#b#L0#Give me Altaire Earrings.#l\r\n#L1#Give me Glittering Altaire Earrings.#l\r\n#L3#Give me Brilliant Altaire Earrings.#l\r\n#L2#Attempt Forest of Poison Haze.#l#k"); } else if (status == 1) { if (selection == 0) { @@ -54,13 +54,13 @@ function action(mode, type, selection) { while (it.hasNext()) { var cPlayer = it.next(); var ccPlayer = cm.getPlayer().getMap().getCharacterById(cPlayer.getId()); - if (ccPlayer == null || ccPlayer.getLevel() < 44 || ccPlayer.getLevel() > 55) { + if (ccPlayer == null || ccPlayer.getLevel() < minLevel || ccPlayer.getLevel() > maxLevel) { next = false; break; } size += (ccPlayer.isGM() ? 4 : 1); } - if (next && size >= 2) { + if (next && size >= minPlayers) { var em = cm.getEventManager("Ellin"); if (em == null) { cm.sendOk("Please try again later."); @@ -68,7 +68,7 @@ function action(mode, type, selection) { em.startInstance(cm.getPlayer().getParty(), cm.getPlayer().getMap(), 1); //common level only } } else { - cm.sendOk("All 2+ members of your party must be here and between level 44 and 55."); + cm.sendOk("All 2+ members of your party must be here and between level " + minLevel + " and " + maxLevel + "."); } } } diff --git a/scripts/npc/world0/2133000.txt b/scripts/npc/world0/2133000.txt deleted file mode 100644 index c76e2bd7a3..0000000000 --- a/scripts/npc/world0/2133000.txt +++ /dev/null @@ -1,73 +0,0 @@ -var status = -1; - -function action(mode, type, selection) { - if (mode == 1) { - status++; - } else { - if (status == 0) { - cm.dispose(); - } - status--; - } - if (status == 0) { - cm.removeAll(4001163); - cm.removeAll(4001169); - cm.removeAll(2270004); - cm.sendSimple("#b#L0#Give me Altaire Earrings.#l\r\n#L1#Give me Glittering Altaire Earrings.#l\r\n#L3#Give me Brilliant Altaire Earrings.#l\r\n#L2#Attempt Forest of Poison Haze.#l#k"); - } else if (status == 1) { - if (selection == 0) { - if (!cm.haveItem(1032060) && cm.haveItem(4001198, 10)) { - cm.gainItem(1032060,1); - cm.gainItem(4001198, -10); - } else { - cm.sendOk("You either have Altair Earrings already or you do not have 10 Altair Fragments"); - } - } else if (selection == 1){ - if (cm.haveItem(1032060) && !cm.haveItem(1032061) && cm.haveItem(4001198, 10)) { - cm.gainItem(1032060,-1); - cm.gainItem(1032061, 1); - cm.gainItem(4001198, -10); - } else { - cm.sendOk("You either don't have Altair Earrings already or you do not have 10 Altair Fragments"); - } - } else if (selection == 1){ - if (cm.haveItem(1032061) && !cm.haveItem(1032101) && cm.haveItem(4001198, 10)) { - cm.gainItem(1032061,-1); - cm.gainItem(1032101, 1); - cm.gainItem(4001198, -10); - } else { - cm.sendOk("You either don't have Glittering Altair Earrings already or you do not have 10 Altair Fragments"); - } - } else if (selection == 2) { - if (cm.getPlayer().getParty() == null || !cm.isLeader()) { - cm.sendOk("The leader of the party must be here."); - } else { - var party = cm.getPlayer().getParty().getMembers(); - var mapId = cm.getPlayer().getMapId(); - var next = true; - var size = 0; - var it = party.iterator(); - while (it.hasNext()) { - var cPlayer = it.next(); - var ccPlayer = cm.getPlayer().getMap().getCharacterById(cPlayer.getId()); - if (ccPlayer == null || ccPlayer.getLevel() < 70 || ccPlayer.getLevel() > 255) { - next = false; - break; - } - size += (ccPlayer.isGM() ? 4 : 1); - } - if (next && size >= 2) { - var em = cm.getEventManager("Ellin"); - if (em == null) { - cm.sendOk("Please try again later."); - } else { - em.startInstance(cm.getPlayer().getParty(), cm.getPlayer().getMap(), 120); - } - } else { - cm.sendOk("All 2+ members of your party must be here and above level 70."); - } - } - } - cm.dispose(); - } -} \ No newline at end of file diff --git a/scripts/npc/world0/2133001.js b/scripts/npc/world0/2133001.js index aa0fe46249..0e626c4614 100644 --- a/scripts/npc/world0/2133001.js +++ b/scripts/npc/world0/2133001.js @@ -28,8 +28,13 @@ function action(mode, type, selection) { cm.warpParty(930000500); cm.gainItem(4001169,-20); } else if (!cm.haveItem(2270004)) { - cm.gainItem(2270004,10); - cm.sendOk("Good luck in purifying these monsters!"); + if(cm.canHold(2270004,10)) { + cm.gainItem(2270004,10); + cm.sendOk("Good luck in purifying these monsters!"); + } + else { + cm.sendOk("Make space on your USE inventory before receiving the purifiers!"); + } } else { cm.sendOk("We have to purify all these contaminated monsters! Get me 20 Monster Marbles from them!"); } diff --git a/scripts/npc/world0/2133002.js b/scripts/npc/world0/2133002.js index a9f0e82e07..4ac0936ee6 100644 --- a/scripts/npc/world0/2133002.js +++ b/scripts/npc/world0/2133002.js @@ -16,9 +16,9 @@ function action(mode, type, selection) { if (status == 0) { cm.sendYesNo("Would you like to get out?"); } else if (status == 1) { - cm.removeAll(4001163); - cm.removeAll(4001169); - cm.removeAll(2270004); + cm.removeAll(4001163); + cm.removeAll(4001169); + cm.removeAll(2270004); cm.warp(930000800,0); cm.dispose(); } diff --git a/scripts/npc/world0/9120023.js b/scripts/npc/world0/9120023.js new file mode 100644 index 0000000000..0a85afe598 --- /dev/null +++ b/scripts/npc/world0/9120023.js @@ -0,0 +1,4 @@ +function start() { + cm.sendOk("The quality of the movies they are launching these days are impressive!"); + cm.dispose(); +} \ No newline at end of file diff --git a/scripts/portal/party6_out.js b/scripts/portal/party6_out.js new file mode 100644 index 0000000000..1adad84b73 --- /dev/null +++ b/scripts/portal/party6_out.js @@ -0,0 +1,9 @@ +function enter(pi) { + if ((pi.getMap().getMonsters().size() == 0 || pi.getMap().getMonsterById(9300183) != null) && (pi.getMap().getReactorByName("") == null || pi.getMap().getReactorByName("").getState() == 1)) { + pi.warp(930000800,0); + return true; + } else { + pi.playerMessage(5, "Please eliminate the Poison Golem."); + return false; + } +} \ No newline at end of file diff --git a/scripts/portal/party6_stage.js b/scripts/portal/party6_stage.js new file mode 100644 index 0000000000..4c42fd8832 --- /dev/null +++ b/scripts/portal/party6_stage.js @@ -0,0 +1,30 @@ +function enter(pi) { + switch(pi.getMapId()) { + case 930000000: + pi.warp(930000100,0); + return true; + break; + case 930000100: + if (pi.getMap().getMonsters().size() == 0) { + pi.warp(930000200,0); + return true; + } else { + pi.playerMessage(5, "Eliminate all the monsters."); + return false; + } + break; + case 930000200: + if (pi.getMap().getReactorByName("spine") != null && pi.getMap().getReactorByName("spine").getState() < 4) { + pi.playerMessage(5, "The spine blocks the way."); + return false; + } else { + pi.warp(930000300,0); //assuming they cant get past reactor without it being gone + return true; + } + break; + + default: + pi.playerMessage(5, "This portal leads to an unbound path."); + return false; + } +} \ No newline at end of file diff --git a/scripts/portal/party6_stage501.js b/scripts/portal/party6_stage501.js new file mode 100644 index 0000000000..d0c7fb034f --- /dev/null +++ b/scripts/portal/party6_stage501.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "02st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage502.js b/scripts/portal/party6_stage502.js new file mode 100644 index 0000000000..494ab57871 --- /dev/null +++ b/scripts/portal/party6_stage502.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "03st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage503.js b/scripts/portal/party6_stage503.js new file mode 100644 index 0000000000..f7b4f86b97 --- /dev/null +++ b/scripts/portal/party6_stage503.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "04st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage504.js b/scripts/portal/party6_stage504.js new file mode 100644 index 0000000000..867dd3c9c0 --- /dev/null +++ b/scripts/portal/party6_stage504.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "05st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage505.js b/scripts/portal/party6_stage505.js new file mode 100644 index 0000000000..d577846d32 --- /dev/null +++ b/scripts/portal/party6_stage505.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "06st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage506.js b/scripts/portal/party6_stage506.js new file mode 100644 index 0000000000..0f665872d0 --- /dev/null +++ b/scripts/portal/party6_stage506.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "07st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage507.js b/scripts/portal/party6_stage507.js new file mode 100644 index 0000000000..61b94556cd --- /dev/null +++ b/scripts/portal/party6_stage507.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "08st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage508.js b/scripts/portal/party6_stage508.js new file mode 100644 index 0000000000..e6d3719430 --- /dev/null +++ b/scripts/portal/party6_stage508.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "09st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage509.js b/scripts/portal/party6_stage509.js new file mode 100644 index 0000000000..cecdd2c598 --- /dev/null +++ b/scripts/portal/party6_stage509.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "10st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage510.js b/scripts/portal/party6_stage510.js new file mode 100644 index 0000000000..1b58a5b5b3 --- /dev/null +++ b/scripts/portal/party6_stage510.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "11st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage511.js b/scripts/portal/party6_stage511.js new file mode 100644 index 0000000000..bf25c56979 --- /dev/null +++ b/scripts/portal/party6_stage511.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "12st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage512.js b/scripts/portal/party6_stage512.js new file mode 100644 index 0000000000..0aa9b3e9e3 --- /dev/null +++ b/scripts/portal/party6_stage512.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "13st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage513.js b/scripts/portal/party6_stage513.js new file mode 100644 index 0000000000..c265e24fe6 --- /dev/null +++ b/scripts/portal/party6_stage513.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "14st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage514.js b/scripts/portal/party6_stage514.js new file mode 100644 index 0000000000..59dfd30e57 --- /dev/null +++ b/scripts/portal/party6_stage514.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "15st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage515.js b/scripts/portal/party6_stage515.js new file mode 100644 index 0000000000..887fd53a90 --- /dev/null +++ b/scripts/portal/party6_stage515.js @@ -0,0 +1,9 @@ +function enter(pi) { + if (java.lang.Math.random() < 0.1) { + pi.warp(930000300,"16st"); + } else { + pi.warp(930000300, "01st"); + } + + return true; +} \ No newline at end of file diff --git a/scripts/portal/party6_stage800.js b/scripts/portal/party6_stage800.js new file mode 100644 index 0000000000..53a860e4d4 --- /dev/null +++ b/scripts/portal/party6_stage800.js @@ -0,0 +1,19 @@ +function enter(pi) { + pi.removeAll(4001162); + pi.removeAll(4001163); + pi.removeAll(4001164); + pi.removeAll(4001169); + pi.removeAll(2270004); + + if(pi.getMap().getReactorByName("") != null && pi.getMap().getReactorByName("").getState() == 1) { + if(!pi.canHold(4001198, 1)) { + pi.playerMessage(5, "Check for a free space on your ETC inventory before entering this portal."); + return false; + } + + pi.gainItem(4001198, 1); + } + + pi.warp(300030100,0); + return true; +} \ No newline at end of file diff --git a/scripts/reactor/1202002.js b/scripts/reactor/1202002.js new file mode 100644 index 0000000000..bcd3f8b777 --- /dev/null +++ b/scripts/reactor/1202002.js @@ -0,0 +1,30 @@ +/* + This file is part of the OdinMS Maple Story Server + Copyright (C) 2008 Patrick Huy + Matthias Butz + Jan Christian Meyer + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation version 3 as published by + the Free Software Foundation. You may not use, modify or distribute + this program under any other version of the GNU Affero General Public + License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +/* @Author Ronan + * + * 1102002.js: Nautilus bottom shells +*/ + +function act() { + rm.dropItems(); +} \ No newline at end of file diff --git a/scripts/reactor/3001000.js b/scripts/reactor/3001000.js new file mode 100644 index 0000000000..b29c20ad9b --- /dev/null +++ b/scripts/reactor/3001000.js @@ -0,0 +1,4 @@ +function act(){ + rm.playerMessage(5, "Poison Golem has been spawned."); + rm.spawnMonster(9300180,1); +} \ No newline at end of file diff --git a/scripts/reactor/3002000.js b/scripts/reactor/3002000.js new file mode 100644 index 0000000000..918a2d06d1 --- /dev/null +++ b/scripts/reactor/3002000.js @@ -0,0 +1,28 @@ +/* + This file is part of the OdinMS Maple Story Server + Copyright (C) 2008 Patrick Huy + Matthias Butz + Jan Christian Meyer + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License 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 . +*/ +/*3002000.js - Pond at Ellin PQ. + *@author Ronan + */ + +function act() { + rm.dropItems(); +} diff --git a/scripts/reactor/3002001.js b/scripts/reactor/3002001.js new file mode 100644 index 0000000000..bbad6f2f1e --- /dev/null +++ b/scripts/reactor/3002001.js @@ -0,0 +1,3 @@ +function act() { + rm.dropItems(); +} diff --git a/scripts/reactor/3008000.js b/scripts/reactor/3008000.js new file mode 100644 index 0000000000..1d5be87389 --- /dev/null +++ b/scripts/reactor/3008000.js @@ -0,0 +1,3 @@ +function act() { + rm.givePartyExp(52000, rm.getPlayer().getPartyMembers()); +} \ No newline at end of file diff --git a/sql/db_database.sql b/sql/db_database.sql index bc4cd0c759..4cffab1c86 100644 --- a/sql/db_database.sql +++ b/sql/db_database.sql @@ -4113,7 +4113,7 @@ INSERT IGNORE INTO `temp_data` (`id`, `dropperid`, `itemid`, `minimum_quantity`, (3904, 5120100, 4020001, 1, 1, 0, 90000), (3905, 5120100, 4010006, 1, 1, 0, 90000), (3906, 5120100, 4020007, 1, 1, 0, 90000), -(3907, 5120100, 4011007, 1, 1, 0, 90000), +(3907, 5120100, 4011007, 1, 1, 0, 30000), (3908, 5120100, 2044602, 1, 1, 0, 3000), (3909, 5120100, 1041082, 1, 1, 0, 8000), (3910, 5120100, 1061081, 1, 1, 0, 8000), @@ -5827,7 +5827,7 @@ INSERT IGNORE INTO `temp_data` (`id`, `dropperid`, `itemid`, `minimum_quantity`, (5617, 6400000, 2000004, 1, 1, 0, 20000), (5618, 6400000, 4020003, 1, 1, 0, 9000), (5619, 6400000, 4010006, 1, 1, 0, 9000), -(5620, 6400000, 4003002, 1, 1, 0, 200000), +(5620, 6400000, 4003002, 1, 1, 0, 20000), (5621, 6400000, 4004001, 1, 1, 0, 10000), (5622, 6400000, 1082084, 1, 1, 0, 1000), (5623, 6400000, 1072142, 1, 1, 0, 800), @@ -11423,7 +11423,7 @@ INSERT IGNORE INTO `temp_data` (`id`, `dropperid`, `itemid`, `minimum_quantity`, (11210, 9001002, 4031059, 1, 1, 0, 999999), (11211, 9001003, 4031059, 1, 1, 0, 999999), (11212, 9001008, 4031059, 1, 1, 0, 499999), -(11213, 9001005, 4031013, 1, 1, 0, 300000), +(11213, 9001005, 4031857, 1, 1, 0, 300000), (11214, 9001012, 4032311, 1, 1, 0, 300000), (11215, 9001012, 4032311, 1, 1, 0, 300000), (11216, 9001013, 4032312, 1, 1, 0, 999999), @@ -11622,7 +11622,7 @@ INSERT IGNORE INTO `temp_data` (`id`, `dropperid`, `itemid`, `minimum_quantity`, (11628, 6220000, 1472055, 1, 1, 0, 1250), (11627, 5120500, 1472055, 1, 1, 0, 750), (11626, 5120000, 1472055, 1, 1, 0, 750), -(11625, 9001006, 4031013, 1, 1, 0, 400000), +(11625, 9001006, 4031856, 1, 1, 0, 400000), (11624, 8190003, 4031461, 1, 1, 6169, 1000), (11623, 9400218, 4001106, 25, 50, 0, 999999), (11622, 9400217, 4001106, 1, 3, 0, 999999), @@ -12786,11 +12786,11 @@ CREATE TABLE IF NOT EXISTS `drop_data_global` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC AUTO_INCREMENT=5 ; INSERT INTO `drop_data_global` (`id`, `continent`, `dropType`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`, `comments`) VALUES -(1, 0, 0, 4031865, 1, 1, 0, 40000, 'NX Card 100 PTS'), -(2, 0, 0, 4031866, 1, 1, 0, 25000, 'NX Card 250 PTS'), -(3, 0, 0, 4001126, 1, 2, 0, 10000, 'Maple Leaves'), -(4, 0, 0, 2049100, 1, 1, 0, 1500, 'Chaos Scroll 60%'), -(5, 0, 0, 4001006, 1, 1, 0, 12000, 'Flaming Feather'); +(1, 0, 0, 4031865, 1, 1, 0, 35000, 'NX Card 100 PTS'), +(2, 0, 0, 4031866, 1, 1, 0, 20000, 'NX Card 250 PTS'), +(3, 0, 0, 4001126, 1, 2, 0, 8000, 'Maple Leaves'), +(4, 0, 0, 2049100, 1, 1, 0, 1200, 'Chaos Scroll 60%'), +(5, 0, 0, 4001006, 1, 1, 0, 10000, 'Flaming Feather'); CREATE TABLE IF NOT EXISTS `dueyitems` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, diff --git a/sql/db_drops.sql b/sql/db_drops.sql index 11d71bffdc..922086d6e9 100644 --- a/sql/db_drops.sql +++ b/sql/db_drops.sql @@ -7802,7 +7802,6 @@ (5100000, 4000048, 1, 1, 0, 200000), (5100000, 4000021, 1, 1, 0, 200000), (5100000, 4003005, 1, 1, 0, 7000), -(5100000, 2022066, 1, 1, 0, 3000), (5100000, 2000002, 1, 1, 0, 40000), (5100000, 2000003, 1, 1, 0, 40000), (5100000, 2040804, 1, 1, 0, 750), @@ -18794,11 +18793,14 @@ (9300106, 4031551, 1, 1, 3829, 40000), (9300107, 4031551, 1, 1, 3829, 40000), (9300119, 4031551, 1, 1, 3829, 40000), -(9300119, 0, 801, 1199, 0, 400000); - +(9300119, 0, 801, 1199, 0, 400000), +(9300173, 4001161, 1, 1, 0, 200000); # (dropperid, itemid, minqty, maxqty, questid, chance) + # delete item drops from Seruf shell + DELETE FROM temp_data WHERE dropperid=4220001; + UPDATE IGNORE temp_data SET chance=700 WHERE itemid=1302056; UPDATE IGNORE temp_data SET dropperid=9000002 WHERE dropperid=9000000; @@ -18866,6 +18868,7 @@ UPDATE drop_data SET questid=7777 WHERE itemid=4001359; UPDATE drop_data SET questid=7777 WHERE itemid=4001342; UPDATE drop_data SET questid=7777 WHERE itemid=4031906; + UPDATE drop_data SET questid=7777 WHERE itemid=4032474; UPDATE drop_data SET chance=0 WHERE itemid=2050099; UPDATE drop_data SET chance=40000 WHERE itemid=4031991; UPDATE drop_data SET questid=6191 WHERE itemid=4031477; diff --git a/sql/db_shopupdate.sql b/sql/db_shopupdate.sql index 0e160f6364..7b02358529 100644 --- a/sql/db_shopupdate.sql +++ b/sql/db_shopupdate.sql @@ -36,7 +36,7 @@ INSERT IGNORE INTO `shopitems` (`shopitemid`, `shopid`, `itemid`, `price`, `pitc (995056, 9201082, 2043801, 520000, 0, 25), (995057, 9201082, 2044601, 520000, 0, 26), (995058, 9201082, 2040727, 10000, 0, 27), -(995059, 9201082, 2040807, 1500000, 0, 28), +(995059, 9201082, 2040807, 1000000, 0, 28), (995060, 9201082, 2040026, 15000, 0, 29), (995061, 9201082, 2040031, 15000, 0, 30), (995062, 9201082, 2040302, 25000, 0, 31), @@ -75,9 +75,9 @@ INSERT IGNORE INTO `shopitems` (`shopitemid`, `shopid`, `itemid`, `price`, `pitc (996009, 9201082, 2049209, 170000, 0, 64), (996010, 9201082, 2049210, 140000, 0, 65), (996011, 9201082, 2049211, 170000, 0, 66), -(996196, 9201082, 2070016, 100000000, 0, 67), -(996197, 9201082, 2070018, 175000000, 0, 68), -(994782, 9201082, 2030007, 700000, 0, 69), -(994783, 9201082, 4001017, 30000000, 0, 70); +(996196, 9201082, 2070016, 120000000, 0, 67), +(996197, 9201082, 2070018, 190000000, 0, 68), +(994782, 9201082, 2030007, 1800000, 0, 69), +(994783, 9201082, 4001017, 60000000, 0, 70); -UPDATE shopitems SET price = 11*price WHERE (`position` >= 27 and `position` <= 66); \ No newline at end of file +UPDATE shopitems SET price = 11*price WHERE (`position` >= 27 and `position` <= 66 and `shopid` = 9201082); \ No newline at end of file diff --git a/src/client/MapleCharacter.java b/src/client/MapleCharacter.java index 4a4549f736..61f76fe54d 100644 --- a/src/client/MapleCharacter.java +++ b/src/client/MapleCharacter.java @@ -48,6 +48,8 @@ import java.util.Set; //import java.util.TimeZone; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.Lock; import java.util.regex.Pattern; import net.server.PlayerBuffValueHolder; @@ -274,6 +276,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { private long useDuey; private long petLootCd; private int newWarpMap = -1; + private Lock sLock = new ReentrantLock(true); private MapleCharacter() { setStance(0); @@ -552,7 +555,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } public void addSummon(int id, MapleSummon summon) { - summons.put(id, summon); + sLock.lock(); + try { + summons.put(id, summon); + } finally { + sLock.unlock(); + } } public void addVisibleMapObject(MapleMapObject mo) { @@ -1360,22 +1368,28 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } } else if (stat == MapleBuffStat.SUMMON || stat == MapleBuffStat.PUPPET) { int summonId = mbsvh.effect.getSourceId(); - MapleSummon summon = summons.get(summonId); - if (summon != null) { - getMap().broadcastMessage(MaplePacketCreator.removeSummon(summon, true), summon.getPosition()); - getMap().removeMapObject(summon); - removeVisibleMapObject(summon); - summons.remove(summonId); - } - if (summon.getSkill() == DarkKnight.BEHOLDER) { - if (beholderHealingSchedule != null) { - beholderHealingSchedule.cancel(false); - beholderHealingSchedule = null; + + sLock.lock(); + try { + MapleSummon summon = summons.get(summonId); + if (summon != null) { + getMap().broadcastMessage(MaplePacketCreator.removeSummon(summon, true), summon.getPosition()); + getMap().removeMapObject(summon); + removeVisibleMapObject(summon); + summons.remove(summonId); } - if (beholderBuffSchedule != null) { - beholderBuffSchedule.cancel(false); - beholderBuffSchedule = null; + if (summon.getSkill() == DarkKnight.BEHOLDER) { + if (beholderHealingSchedule != null) { + beholderHealingSchedule.cancel(false); + beholderHealingSchedule = null; + } + if (beholderBuffSchedule != null) { + beholderBuffSchedule.cancel(false); + beholderBuffSchedule = null; + } } + } finally { + sLock.unlock(); } } else if (stat == MapleBuffStat.DRAGONBLOOD) { dragonBloodSchedule.cancel(false); @@ -1725,7 +1739,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { return ret; } - public List> getAllStatups() { + public List> getAllStatups() { List> ret = new ArrayList<>(); for (MapleBuffStat mbs : effects.keySet()) { MapleBuffStatValueHolder mbsvh = effects.get(mbs); @@ -1827,6 +1841,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { private List getBuffStats(MapleStatEffect effect, long startTime) { List stats = new ArrayList<>(); for (Entry stateffect : effects.entrySet()) { + if(stateffect.getValue() == null) continue; + if (stateffect.getValue().effect.sameSource(effect) && (startTime == -1 || startTime == stateffect.getValue().startTime)) { stats.add(stateffect.getKey()); } @@ -2284,6 +2300,18 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { public int getPartyId() { return (party != null ? party.getId() : -1); } + + public List getPartyMembers() { + List list = new LinkedList<>(); + + if(party != null) { + for(MaplePartyCharacter partyMembers: party.getMembers()) { + list.add(partyMembers.getPlayer()); + } + } + + return list; + } public MaplePlayerShop getPlayerShop() { return playerShop; @@ -2500,9 +2528,50 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { public int getStr() { return str; } - - public Map getSummons() { - return summons; + + public Collection getSummonsValues() { + sLock.lock(); + try { + return summons.values(); + } finally { + sLock.unlock(); + } + } + + public void clearSummons() { + sLock.lock(); + try { + summons.clear(); + } finally { + sLock.unlock(); + } + } + + public MapleSummon getSummonByKey(int id) { + sLock.lock(); + try { + return summons.get(id); + } finally { + sLock.unlock(); + } + } + + public boolean isSummonsEmpty() { + sLock.lock(); + try { + return summons.isEmpty(); + } finally { + sLock.unlock(); + } + } + + public boolean containsSummon(MapleSummon summon) { + sLock.lock(); + try { + return summons.containsValue(summon); + } finally { + sLock.unlock(); + } } public int getTotalStr() { @@ -4908,7 +4977,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } } - public boolean skillisCooling(int skillId) { + public boolean skillIsCooling(int skillId) { return coolDowns.containsKey(Integer.valueOf(skillId)); } @@ -5403,8 +5472,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { continue; } - if ((itemName.contains("Reverse") && nEquip.getItemLevel() < 4) || itemName.contains("Timeless") && nEquip.getItemLevel() < 6) { - nEquip.gainItemExp(client, mobexp, itemName.contains("Timeless")); + if ((nEquip.getItemLevel() < ServerConstants.USE_EQUIPMNT_LVLUP) && (itemName.contains("Reverse") && nEquip.getItemLevel() < 4) || itemName.contains("Timeless") && nEquip.getItemLevel() < 6) { + nEquip.gainItemExp(client, mobexp, itemName.contains("Reverse")); } } } diff --git a/src/client/command/Commands.java b/src/client/command/Commands.java index fa83c536de..1d56e7c146 100644 --- a/src/client/command/Commands.java +++ b/src/client/command/Commands.java @@ -638,17 +638,34 @@ public class Commands { break; //debug only - case "map": + case "debugpos": if(ServerConstants.USE_DEBUG) { player.dropMessage("Current map position: (" + player.getPosition().getX() + ", " + player.getPosition().getY() + ")."); - break; } - case "mapcount": + break; + + case "debugmapcount": if(ServerConstants.USE_DEBUG) { player.dropMessage("Current map count: (" + player.getMap().getAllPlayers().size() + ")."); - break; } - + break; + + case "debugevent": + if(ServerConstants.USE_DEBUG) { + if(player.getEventInstance() == null) player.dropMessage("Player currently not in a event."); + else player.dropMessage("Current event name: " + player.getEventInstance().getName() + "."); + } + break; + + case "debugreactors": + if(ServerConstants.USE_DEBUG) { + player.dropMessage("Current reactor states on map " + player.getMapId() + ":"); + for(Pair p: player.getMap().reportReactorStates()) { + player.dropMessage("Reactor id: " + p.getLeft() + " -> State: " + p.getRight() + "."); + } + } + break; + default: if (player.gmLevel() == 0) { player.yellowMessage("Player Command " + heading + sub[0] + " does not exist, see @help for a list of commands."); diff --git a/src/client/inventory/Equip.java b/src/client/inventory/Equip.java index 179ecb8f57..5eb5eabedf 100644 --- a/src/client/inventory/Equip.java +++ b/src/client/inventory/Equip.java @@ -312,14 +312,14 @@ public class Equip extends Item { return (int) itemExp; } - public void gainItemExp(MapleClient c, int gain, boolean timeless) { - int expneeded = timeless ? (10 * itemLevel + 70) : (5 * itemLevel + 65); + public void gainItemExp(MapleClient c, int gain, boolean reverse) { + int expneeded = !reverse ? (10 * itemLevel + 70) : (5 * itemLevel + 65); float modifier = 364 / expneeded; float exp = (expneeded / (1000000 * modifier * modifier)) * gain; itemExp += exp; if (itemExp >= 364) { itemExp = (itemExp - 364); - gainLevel(c, timeless); + gainLevel(c, !reverse); } else { c.getPlayer().forceUpdateItem(this); } diff --git a/src/constants/ServerConstants.java b/src/constants/ServerConstants.java index 670f58cd1a..e8bfa62b56 100644 --- a/src/constants/ServerConstants.java +++ b/src/constants/ServerConstants.java @@ -49,8 +49,9 @@ public class ServerConstants { //public static final boolean USE_ULTRA_THREE_SNAILS = true; public static final boolean USE_ADD_SLOTS_BY_LEVEL = true; //slots are added each 20 levels. public static final boolean USE_ADD_RATES_BY_LEVEL = true; //rates are added each 20 levels. - 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 tries for success on a scroll, set 0 for default. + public static final int USE_EQUIPMNT_LVLUP = 7; //all equips lvlup at max level as N, set 0 to disable. + 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 tries for success on a scroll, set 0 for default. //Pet auto-pot recovery rates public static final double PET_AUTOHP_RATIO = 0.99; //will automatically consume potions until given ratio of the MaxHP/MaxMP is reached. diff --git a/src/net/server/channel/handlers/AutoAssignHandler.java b/src/net/server/channel/handlers/AutoAssignHandler.java index 76943f2dc1..8522533d06 100644 --- a/src/net/server/channel/handlers/AutoAssignHandler.java +++ b/src/net/server/channel/handlers/AutoAssignHandler.java @@ -75,8 +75,8 @@ public class AutoAssignHandler extends AbstractMaplePacketHandler { //c.getPlayer().message("----------------------------------------SDL: " + eqpStr + eqpDex + eqpLuk + " BASE STATS --> STR: " + chr.getStr() + " DEX: " + chr.getDex() + " INT: " + chr.getInt() + " LUK: " + chr.getLuk()); //c.getPlayer().message("SUM EQUIP STATS -> STR: " + str + " DEX: " + dex + " LUK: " + luk + " INT: " + int_); - //---------- Ronan Lana's AUTOASSIGN ------------- - //this method excels for possibility to assign APs properly and not blocking the requirements when swapping one guaranteed equipment. + // ---------- Ronan Lana's AUTOASSIGN ------------- + // This method excels for assigning APs in such a way to cover all equipments AP requirements. if (chr.getRemainingAp() < 1) { return; } diff --git a/src/net/server/channel/handlers/BeholderHandler.java b/src/net/server/channel/handlers/BeholderHandler.java index 2ebec954a2..527c1b9063 100644 --- a/src/net/server/channel/handlers/BeholderHandler.java +++ b/src/net/server/channel/handlers/BeholderHandler.java @@ -37,7 +37,7 @@ public final class BeholderHandler extends AbstractMaplePacketHandler {//Summon @Override public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { //System.out.println(slea.toString()); - Collection summons = c.getPlayer().getSummons().values(); + Collection summons = c.getPlayer().getSummonsValues(); int oid = slea.readInt(); MapleSummon summon = null; for (MapleSummon sum : summons) { @@ -53,7 +53,7 @@ public final class BeholderHandler extends AbstractMaplePacketHandler {//Summon slea.readByte(); //Not sure. } //show to others here } else { - c.getPlayer().getSummons().clear(); + c.getPlayer().clearSummons(); } } } diff --git a/src/net/server/channel/handlers/CloseRangeDamageHandler.java b/src/net/server/channel/handlers/CloseRangeDamageHandler.java index 33a4ee3389..74fe99fb6f 100644 --- a/src/net/server/channel/handlers/CloseRangeDamageHandler.java +++ b/src/net/server/channel/handlers/CloseRangeDamageHandler.java @@ -145,7 +145,7 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler { Skill skill = SkillFactory.getSkill(attack.skill); MapleStatEffect effect_ = skill.getEffect(player.getSkillLevel(skill)); if (effect_.getCooldown() > 0) { - if (player.skillisCooling(attack.skill)) { + if (player.skillIsCooling(attack.skill)) { return; } else { c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown())); diff --git a/src/net/server/channel/handlers/DamageSummonHandler.java b/src/net/server/channel/handlers/DamageSummonHandler.java index a0245b2043..f953bbfe40 100644 --- a/src/net/server/channel/handlers/DamageSummonHandler.java +++ b/src/net/server/channel/handlers/DamageSummonHandler.java @@ -38,7 +38,7 @@ public final class DamageSummonHandler extends AbstractMaplePacketHandler { int monsterIdFrom = slea.readInt(); if (SkillFactory.getSkill(skillid) != null) { MapleCharacter player = c.getPlayer(); - MapleSummon summon = player.getSummons().get(skillid); + MapleSummon summon = player.getSummonByKey(skillid); if (summon != null) { summon.addHP(-damage); if (summon.getHP() <= 0) { diff --git a/src/net/server/channel/handlers/MagicDamageHandler.java b/src/net/server/channel/handlers/MagicDamageHandler.java index 78ec6f0ec5..1e3052df3c 100644 --- a/src/net/server/channel/handlers/MagicDamageHandler.java +++ b/src/net/server/channel/handlers/MagicDamageHandler.java @@ -67,7 +67,7 @@ public final class MagicDamageHandler extends AbstractDealDamageHandler { Skill skill = SkillFactory.getSkill(attack.skill); MapleStatEffect effect_ = skill.getEffect(player.getSkillLevel(skill)); if (effect_.getCooldown() > 0) { - if (player.skillisCooling(attack.skill)) { + if (player.skillIsCooling(attack.skill)) { return; } else { c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown())); diff --git a/src/net/server/channel/handlers/MoveSummonHandler.java b/src/net/server/channel/handlers/MoveSummonHandler.java index e7b7198bc4..78117909d2 100644 --- a/src/net/server/channel/handlers/MoveSummonHandler.java +++ b/src/net/server/channel/handlers/MoveSummonHandler.java @@ -38,7 +38,7 @@ public final class MoveSummonHandler extends AbstractMovementPacketHandler { Point startPos = new Point(slea.readShort(), slea.readShort()); List res = parseMovement(slea); MapleCharacter player = c.getPlayer(); - Collection summons = player.getSummons().values(); + Collection summons = player.getSummonsValues(); MapleSummon summon = null; for (MapleSummon sum : summons) { if (sum.getObjectId() == oid) { diff --git a/src/net/server/channel/handlers/RangedAttackHandler.java b/src/net/server/channel/handlers/RangedAttackHandler.java index 925501c5da..a386af7ae0 100644 --- a/src/net/server/channel/handlers/RangedAttackHandler.java +++ b/src/net/server/channel/handlers/RangedAttackHandler.java @@ -198,7 +198,7 @@ public final class RangedAttackHandler extends AbstractDealDamageHandler { Skill skill = SkillFactory.getSkill(attack.skill); MapleStatEffect effect_ = skill.getEffect(player.getSkillLevel(skill)); if (effect_.getCooldown() > 0) { - if (player.skillisCooling(attack.skill)) { + if (player.skillIsCooling(attack.skill)) { return; } else { c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown())); diff --git a/src/net/server/channel/handlers/ReactorHitHandler.java b/src/net/server/channel/handlers/ReactorHitHandler.java index d502ee464f..43b9b39064 100644 --- a/src/net/server/channel/handlers/ReactorHitHandler.java +++ b/src/net/server/channel/handlers/ReactorHitHandler.java @@ -41,7 +41,7 @@ public final class ReactorHitHandler extends AbstractMaplePacketHandler { int skillid = slea.readInt(); MapleReactor reactor = c.getPlayer().getMap().getReactorByOid(oid); if (reactor != null && reactor.isAlive()) { - reactor.hitReactor(charPos, stance, skillid, c, false); + reactor.hitReactor(charPos, stance, skillid, c); } } } diff --git a/src/net/server/channel/handlers/SpecialMoveHandler.java b/src/net/server/channel/handlers/SpecialMoveHandler.java index fc7b84da67..b81550354c 100644 --- a/src/net/server/channel/handlers/SpecialMoveHandler.java +++ b/src/net/server/channel/handlers/SpecialMoveHandler.java @@ -73,7 +73,7 @@ public final class SpecialMoveHandler extends AbstractMaplePacketHandler { MapleStatEffect effect = skill.getEffect(skillLevel); if (effect.getCooldown() > 0) { - if (chr.skillisCooling(skillid)) { + if (chr.skillIsCooling(skillid)) { return; } else if (skillid != Corsair.BATTLE_SHIP) { c.announce(MaplePacketCreator.skillCooldown(skillid, effect.getCooldown())); diff --git a/src/net/server/channel/handlers/SummonDamageHandler.java b/src/net/server/channel/handlers/SummonDamageHandler.java index 3d827af481..a83372d4bb 100644 --- a/src/net/server/channel/handlers/SummonDamageHandler.java +++ b/src/net/server/channel/handlers/SummonDamageHandler.java @@ -63,7 +63,7 @@ public final class SummonDamageHandler extends AbstractMaplePacketHandler { return; } MapleSummon summon = null; - for (MapleSummon sum : player.getSummons().values()) { + for (MapleSummon sum : player.getSummonsValues()) { if (sum.getObjectId() == oid) { summon = sum; } diff --git a/src/scripting/event/EventInstanceManager.java b/src/scripting/event/EventInstanceManager.java index 9360091b51..49f27edcff 100644 --- a/src/scripting/event/EventInstanceManager.java +++ b/src/scripting/event/EventInstanceManager.java @@ -46,6 +46,9 @@ import server.maps.MapleMap; import server.maps.MapleMapFactory; import tools.DatabaseConnection; import client.MapleCharacter; +import java.util.concurrent.ScheduledFuture; +import java.util.logging.Level; +import java.util.logging.Logger; /** * @@ -67,6 +70,7 @@ public class EventInstanceManager { private final ReentrantReadWriteLock mutex = new ReentrantReadWriteLock(); private final ReadLock rL = mutex.readLock(); private final WriteLock wL = mutex.writeLock(); + private ScheduledFuture event_schedule = null; private boolean disposed = false; public EventInstanceManager(EventManager em, String name) { @@ -114,8 +118,18 @@ public class EventInstanceManager { } public void startEventTimer(long time) { - timeStarted = System.currentTimeMillis(); + timeStarted = System.currentTimeMillis(); eventTime = time; + + event_schedule = TimerManager.getInstance().schedule(new Runnable() { + public void run() { + try { + em.getIv().invokeFunction("scheduledTimeout", EventInstanceManager.this); + } catch (ScriptException | NoSuchMethodException ex) { + Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex); + } + } + }, time); } public boolean isTimerStarted() { @@ -186,6 +200,11 @@ public class EventInstanceManager { public void monsterKilled(MapleMonster mob) { mobs.remove(mob); + try { + em.getIv().invokeFunction("monsterKilled", mob, this); + } catch (ScriptException | NoSuchMethodException ex) { + ex.printStackTrace(); + } if (mobs.isEmpty()) { try { em.getIv().invokeFunction("allMonstersDead", this); @@ -268,6 +287,8 @@ public class EventInstanceManager { } finally { wL.unlock(); } + + event_schedule.cancel(true); mobs.clear(); killCount.clear(); diff --git a/src/scripting/reactor/ReactorActionManager.java b/src/scripting/reactor/ReactorActionManager.java index dce4f943a4..0b8a5115ce 100644 --- a/src/scripting/reactor/ReactorActionManager.java +++ b/src/scripting/reactor/ReactorActionManager.java @@ -58,8 +58,12 @@ public class ReactorActionManager extends AbstractPlayerInteraction { public void dropItems(boolean meso, int mesoChance, int minMeso, int maxMeso) { dropItems(meso, mesoChance, minMeso, maxMeso, 0); } - + public void dropItems(boolean meso, int mesoChance, int minMeso, int maxMeso, int minItems) { + dropItems((int)reactor.getPosition().getX(), (int)reactor.getPosition().getY(), meso, mesoChance, minMeso, maxMeso, minItems); + } + + public void dropItems(int posX, int posY, boolean meso, int mesoChance, int minMeso, int maxMeso, int minItems) { List chances = getDropChances(); List items = new LinkedList<>(); int numItems = 0; @@ -79,8 +83,10 @@ public class ReactorActionManager extends AbstractPlayerInteraction { numItems++; } java.util.Collections.shuffle(items); - final Point dropPos = reactor.getPosition(); + + final Point dropPos = new Point(posX, posY); dropPos.x -= (12 * numItems); + for (ReactorDropEntry d : items) { if (d.itemId == 0) { int range = maxMeso - minMeso; @@ -98,7 +104,6 @@ public class ReactorActionManager extends AbstractPlayerInteraction { reactor.getMap().spawnItemDrop(reactor, getPlayer(), drop, dropPos, false, false); } dropPos.x += 25; - } } diff --git a/src/server/maps/MapleMap.java b/src/server/maps/MapleMap.java index 7bd34c9611..cfa50845b4 100644 --- a/src/server/maps/MapleMap.java +++ b/src/server/maps/MapleMap.java @@ -223,7 +223,15 @@ public class MapleMap { for (MapleMapObject o : mapobjects.values()) { if (o.getType() == MapleMapObjectType.REACTOR) { if (((MapleReactor) o).getState() < 1) { - ((MapleReactor) o).setState((byte) 1); + MapleReactor mr = (MapleReactor) o; + mr.lockReactor(); + try { + mr.setState((byte) 1); + mr.setShouldCollect(true); + } finally { + mr.unlockReactor(); + } + broadcastMessage(MaplePacketCreator.triggerReactor((MapleReactor) o, 1)); } } @@ -511,6 +519,16 @@ public class MapleMap { return count; } + public List reportReactorStates() { + List list = new LinkedList<>(); + + for (MapleMapObject m : getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.REACTOR))) { + MapleReactor mr = (MapleReactor) m; + list.add(new Pair(mr.getId(), mr.getState())); + } + return list; + } + public int countAllMonsters() { return getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.MONSTER)).size(); } @@ -797,13 +815,6 @@ public class MapleMap { reactor.setAlive(false); removeMapObject(reactor); - reactor.lockReactor(); - try { - reactor.setShouldCollect(true); - } finally { - reactor.unlockReactor(); - } - if (reactor.getDelay() > 0) { tMan.schedule(new Runnable() { @Override @@ -820,10 +831,10 @@ public class MapleMap { for (MapleMapObject o : mapobjects.values()) { if (o.getType() == MapleMapObjectType.REACTOR) { final MapleReactor r = ((MapleReactor) o); - r.setState((byte) 0); r.lockReactor(); try { + r.setState((byte) 0); r.setShouldCollect(true); } finally { r.unlockReactor(); @@ -1213,8 +1224,15 @@ public class MapleMap { } private void respawnReactor(final MapleReactor reactor) { - reactor.setState((byte) 0); - reactor.setAlive(true); + reactor.lockReactor(); + try { + reactor.setShouldCollect(true); + reactor.setState((byte) 0); + reactor.setAlive(true); + } finally { + reactor.unlockReactor(); + } + spawnReactor(reactor); } @@ -1533,7 +1551,7 @@ public class MapleMap { MapleStatEffect summonStat = chr.getStatForBuff(MapleBuffStat.SUMMON); if (summonStat != null) { - MapleSummon summon = chr.getSummons().get(summonStat.getSourceId()); + MapleSummon summon = chr.getSummonByKey(summonStat.getSourceId()); summon.setPosition(chr.getPosition()); chr.getMap().spawnSummon(summon); updateMapObjectVisibility(chr, summon); @@ -1624,7 +1642,7 @@ public class MapleMap { } chr.leaveMap(); chr.cancelMapTimeLimitTask(); - for (MapleSummon summon : chr.getSummons().values()) { + for (MapleSummon summon : chr.getSummonsValues()) { if (summon.isStationary()) { chr.cancelBuffStats(MapleBuffStat.PUPPET); } else { @@ -1734,7 +1752,7 @@ public class MapleMap { if (o.getType() == MapleMapObjectType.SUMMON) { MapleSummon summon = (MapleSummon) o; if (summon.getOwner() == chr) { - if (chr.getSummons().isEmpty() || !chr.getSummons().containsValue(summon)) { + if (chr.isSummonsEmpty() || !chr.containsSummon(summon)) { objectWLock.lock(); try { mapobjects.remove(o); @@ -2105,13 +2123,19 @@ public class MapleMap { reactor.setShouldCollect(false); MapleMap.this.broadcastMessage(MaplePacketCreator.removeItemFromMap(mapitem.getObjectId(), 0, 0), mapitem.getPosition()); MapleMap.this.removeMapObject(mapitem); - reactor.hitReactor(c, true); + reactor.hitReactor(c); if (reactor.getDelay() > 0) { tMan.schedule(new Runnable() { @Override public void run() { - reactor.setState((byte) 0); + reactor.lockReactor(); + try { + reactor.setState((byte) 0); + reactor.setShouldCollect(true); + } finally { + reactor.unlockReactor(); + } broadcastMessage(MaplePacketCreator.triggerReactor(reactor, 0)); } }, reactor.getDelay()); @@ -2120,8 +2144,7 @@ public class MapleMap { mapitem.itemLock.unlock(); } } - } - finally { + } finally { reactor.unlockReactor(); } } @@ -2560,12 +2583,12 @@ public class MapleMap { resetMapObjects(); } - public void resetPQ(int difficulty) { - resetMapObjects(difficulty, true); + public void resetPQ() { + resetPQ(1); } - public void resetPQ() { - resetMapObjects(1, true); + public void resetPQ(int difficulty) { + resetMapObjects(difficulty, true); } public void resetMapObjects(int difficulty, boolean isPq) { diff --git a/src/server/maps/MapleMapFactory.java b/src/server/maps/MapleMapFactory.java index 2adf055787..3354b0111d 100644 --- a/src/server/maps/MapleMapFactory.java +++ b/src/server/maps/MapleMapFactory.java @@ -255,6 +255,7 @@ public class MapleMapFactory { myReactor.setPosition(new Point(x, y)); myReactor.setDelay(MapleDataTool.getInt(reactor.getChildByPath("reactorTime")) * 1000); myReactor.setState((byte) 0); + myReactor.setShouldCollect(true); myReactor.setName(MapleDataTool.getString(reactor.getChildByPath("name"), "")); return myReactor; } diff --git a/src/server/maps/MapleReactor.java b/src/server/maps/MapleReactor.java index 9f840d353b..ecb7894f8f 100644 --- a/src/server/maps/MapleReactor.java +++ b/src/server/maps/MapleReactor.java @@ -26,6 +26,7 @@ import constants.ServerConstants; import java.awt.Rectangle; import java.util.List; + import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -46,7 +47,7 @@ public class MapleReactor extends AbstractMapleMapObject { private MapleMap map; private String name; private boolean alive; - private boolean shouldCollect = true; + private boolean shouldCollect; private Lock reactorLock = new ReentrantLock(true); public MapleReactor(MapleReactorStats stats, int rid) { @@ -143,14 +144,14 @@ public class MapleReactor extends AbstractMapleMapObject { } public void forceHitReactor(final byte newState) { - setState((byte) newState); + this.lockReactor(); try { - this.lockReactor(); + setState((byte) newState); this.setShouldCollect(true); - } - finally { + } finally { this.unlockReactor(); } + map.broadcastMessage(MaplePacketCreator.triggerReactor(this, (short) 0)); } @@ -158,16 +159,16 @@ public class MapleReactor extends AbstractMapleMapObject { TimerManager.getInstance().schedule(new Runnable() { @Override public void run() { - hitReactor(c, false); + hitReactor(c); } }, delay); } - public void hitReactor(MapleClient c, boolean itemDrop) { - hitReactor(0, (short) 0, 0, c, itemDrop); + public void hitReactor(MapleClient c) { + hitReactor(0, (short) 0, 0, c); } - public synchronized void hitReactor(int charPos, short stance, int skillid, MapleClient c, boolean itemDrop) { + public synchronized void hitReactor(int charPos, short stance, int skillid, MapleClient c) { try { if(!this.isAlive()) { return; @@ -196,11 +197,12 @@ public class MapleReactor extends AbstractMapleMapObject { ReactorScriptManager.getInstance().act(c, this); } else { //reactor not broken yet - if (itemDrop) state++; // Duh, if the reactor is triggered by itemdrop, go directly to next state (in this case, instead of staying at 1, it goes to 2)! :) map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance)); - if (state == stats.getNextState(state, b) || itemDrop) {//current state = next state, looping reactor + if (state == stats.getNextState(state, b)) {//current state = next state, looping reactor ReactorScriptManager.getInstance().act(c, this); } + + setShouldCollect(true); // refresh collectability on item drop-based reactors } break; } @@ -209,6 +211,8 @@ public class MapleReactor extends AbstractMapleMapObject { state++; map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance)); ReactorScriptManager.getInstance().act(c, this); + setShouldCollect(true); + System.out.println("ehh"); } } catch(Exception e) { e.printStackTrace(); diff --git a/wz/Map.wz/Map/Map3/300000100.img.xml b/wz/Map.wz/Map/Map3/300000100.img.xml index 68a6940165..c3a28c95e9 100644 --- a/wz/Map.wz/Map/Map3/300000100.img.xml +++ b/wz/Map.wz/Map/Map3/300000100.img.xml @@ -1314,7 +1314,7 @@ - + diff --git a/wz/Map.wz/Map/Map9/930000200.img.xml b/wz/Map.wz/Map/Map9/930000200.img.xml index e4cce1eead..46adf93101 100644 --- a/wz/Map.wz/Map/Map9/930000200.img.xml +++ b/wz/Map.wz/Map/Map9/930000200.img.xml @@ -458,7 +458,7 @@ - + diff --git a/wz/Quest.wz/Act.img.xml b/wz/Quest.wz/Act.img.xml index 626cb6f3c9..09757970c0 100644 --- a/wz/Quest.wz/Act.img.xml +++ b/wz/Quest.wz/Act.img.xml @@ -12075,6 +12075,7 @@ + @@ -12094,6 +12095,7 @@ + diff --git a/wz/Reactor.wz/2408001.img.xml b/wz/Reactor.wz/2408001.img.xml index c64a4f2237..e0724ce704 100644 --- a/wz/Reactor.wz/2408001.img.xml +++ b/wz/Reactor.wz/2408001.img.xml @@ -93,7 +93,7 @@ - + diff --git a/wz/Reactor.wz/3002000.img.xml b/wz/Reactor.wz/3002000.img.xml index f4151a0fa3..ebc3d205a4 100644 --- a/wz/Reactor.wz/3002000.img.xml +++ b/wz/Reactor.wz/3002000.img.xml @@ -25,13 +25,6 @@ - - - - - - - diff --git a/wz/String.wz/Consume.img.xml b/wz/String.wz/Consume.img.xml index 6fef3552be..df84fbb380 100644 --- a/wz/String.wz/Consume.img.xml +++ b/wz/String.wz/Consume.img.xml @@ -6633,7 +6633,7 @@ - +