diff --git a/.gitignore b/.gitignore
index c635df16b3..480e5c0c55 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,10 @@
/tools/MapleInvalidItemIdFetcher/dist/
/tools/MapleInvalidItemIdFetcher/nbproject/
+/tools/MapleInvalidItemWithNoNameFetcher/build/
+/tools/MapleInvalidItemWithNoNameFetcher/dist/
+/tools/MapleInvalidItemWithNoNameFetcher/nbproject/
+
/tools/MapleMapInfoRetriever/build/
/tools/MapleMapInfoRetriever/dist/
/tools/MapleMapInfoRetriever/nbproject/
diff --git a/README.md b/README.md
index 187491f2ef..8c249a1c77 100644
--- a/README.md
+++ b/README.md
@@ -51,7 +51,7 @@ Recommended localhost: https://hostr.co/m2bVtnizCtmD
---
### Development status
-Status: __Released__.
+Status: __In development (4th round)__.
HeavenMS development achieved an acceptable state-of-the-art and will get into a halt. A heartfelt thanks for everyone that contributed in some way for the progress of this server!
diff --git a/docs/feature_list.md b/docs/feature_list.md
index 9354192e89..4c32821c70 100644
--- a/docs/feature_list.md
+++ b/docs/feature_list.md
@@ -60,20 +60,24 @@ Player Social Network:
* Implemented Marriage system from the ground-up (excluding character packet encoding parts that were already present, proper credits given throughout the source files).
* Beginners can create and join a "beginner-only" party (characters up to level 10).
* Enhanced synchronization on Player Shops and Hired Merchants. Transactions made are instantly informed to the owner.
-* Game minirooms such as match cards and omok now has semi-functional password system.
+* Game minirooms such as match cards and omok now has a functional password system.
* Item pickup cooldown on non-owned/non-partyowned items functional.
* Further improved the server's ranking system, now displaying properly daily player ranking movement.
* Automated support for Player NPCs and Hall of Fame.
+* Protected concurrently and improved the face expression system, guarding from trivial packet spam and exploits.
Cash & Items:
* EXP/DROP/Cosmetic Coupons.
* EXP/DROP coupons now appears as a buff effect when on active time.
* Great deal of cash items functional.
+* MapleTV mechanics stabilized and separated by world.
+* GMS-esque omok/match card drop chances.
* New scroll: antibanish. For use only in cases where bosses send a player back to town.
* Inventory system properly checks for item slot free space and ownership.
* Storage with "Arrange Items" feature functional.
* Close-quarters evaluation mode for items (sandbox).
+* Further improved Karma scissors mechanics.
* Spikes on shoes.
* Vega's spell.
* Owl of Minerva.
@@ -91,11 +95,11 @@ Monsters, Maps & Reactors:
* Every skill/mastery book is now droppable by mobs.
* Mobs now can drop more than one of the same equipment (number of possible drops defined at droptime, uses the minimum/maximum quantity fields on DB).
* Redesigned HT mechanics for spawn and linked damage to the sponge.
-* Improved map bounding checks for item drop points, assuring most of the items dropped will be available to pickup inside the accessible map area.
* Limited item count on maps, smartly expiring oldest registered items, preventing potential item flooding.
* Implemented Zombify disease status.
* Added Boss HP Bar for dozens of bosses (needs provided custom wz).
* If multiple bosses are on the same area, client will prioritize Boss HP bar of the target of the player.
+* Improved map bounding checks for item drop points, assuring most of the items dropped will be available to pickup inside the accessible map area.
* Boats, elevator and other travelling mechanics fully working.
* HP decreasing overtime on maps and mechanics to prevent them (consumables, equips) fully functional.
* Crimson Balrog boat approaching visual effect made functional.
@@ -131,7 +135,9 @@ Server potentials:
* Enhanced buff system: smartly checks for the best available buff effects to be active on the player.
* Enhanced AP auto-assigner: exactly matches AP with the needed for the player's current level, surplus assigned to the primary attribute.
* Tweaked pet/mount hunger: calculations for fullness/tiredness takes active time of the subject into account.
+* Consistent experience gain system.
* NPC crafters (equips, plates/jewels, etc) now won't take items freely if the requirement conditions are not properly met.
+* Improved Duey mechanics: package received popup and reviewed many delivery mechanics.
* Pet item pickup now gives preference to player attacks rather than forcing attack disables when automatically picking up.
* Channel capacity bar functional and world servers with max capacity checks.
* Disease status are now visible for other players, even when changing maps.
@@ -140,6 +146,8 @@ Server potentials:
* Custom jail system (needs provided custom wz).
* Custom buyback system.
* Delete Character (requires ENABLE_PIC activated).
+* Smoothed up view-all-char feature, now showing properly all available characters and not disconnecting players too often.
+* Centralized getcurrenttime throughout several server handlers, boosting it's performance overall.
* Autosaver (periodically saves on DB current state of every player in-game).
* Both fixed and randomized versions of HP/MP growth rate available, regarding player job (enable one at ServerConstants). Placeholder for HP/MP washing feature.
* Reallocated mapobjectids utilization throughout the source, preventing issues such as "NPC disappearing mysteriously after some server time" from happening.
@@ -150,6 +158,7 @@ Server potentials:
Custom NPCs:
* Spiegelmann: automatized rock-refiner.
+* Asia: scroll & rarities shop NPC.
* Abdula: lists droppers of needed skill/mastery books.
* Agent E: accessory crafter.
* Donation Box: automatized item-buyer.
@@ -169,6 +178,7 @@ External tools:
* MapleCouponInstaller - Retrieves coupon info from the WZ and makes a SQL table with it. The server will use that table to gather info regarding rates and intervals.
* MapleIdRetriever - Two behaviors: generates a SQL table with relation (id, name) of the handbook given as input. Given a file with names, outputs a file with ids.
* MapleInvalidItemIdFetcher - Generates a file listing all inexistent itemid's currently laying on the DB.
+* MapleInvalidItemWithNoNameFetcher - Generates two files: one listing all itemid's with inexistent name and "cash" property. And other with a prepared XML to solve the name issue.
* MapleMapInfoRetriever - Basic tool for detecting missing info nodes on the map field structures (maps failing to have an info node on the WZ is an critical issue).
* MapleMesoFetcher - Creates meso drop data for mobs with more than 4 items (thus overworld mobs), calculations based on mob level and whether it's a boss or not.
* MapleMobBookIndexer - Generates a SQL table with all relations of cardid and mobid present in the mob book.
@@ -190,8 +200,11 @@ Project:
* Uncovered many Send/Recv opcodes throughout the source.
* Reviewed many Java object aspects that needed concurrency protection.
* Reviewed SQL data, eliminating duplicated entries on the tables.
+* Improved login phase, using cache over DB queries.
* Usage of HikariCP to improve the DB connection management.
+* Developed many survey tools for content profiling.
* Protected many flaws with login management system.
+* Channel, World and Server-wide timer management.
* Heavily reviewed future task management inside the project. Way less trivial schedules are spawned now, relieving task overload on the TimerManager.
* ThreadTracker: embedded auditing tool for run-time deadlock scanning throughout the server source (relies heavily on memory usage, designed only for debugging purposes).
diff --git a/docs/mychanges_ptbr.txt b/docs/mychanges_ptbr.txt
index 2f2affb4f8..9e4be79cc6 100644
--- a/docs/mychanges_ptbr.txt
+++ b/docs/mychanges_ptbr.txt
@@ -1129,4 +1129,18 @@ Corrigido função monsterValue dos scripts de eventos sendo processado múltipl
Corrigido pinkbean nao dropando itens dentro da expedição.
14 Julho 2018,
-Movido "recharge" de Donator para JrGM.
\ No newline at end of file
+Movido "recharge" de Donator para JrGM.
+Otimizado busca por currenttimemillis, agora buscando do objeto do servidor ao invés de verificar pelo ambiente JVM.
+Corrigido handlers de organização de inventários não protegendo concorrentemente inventários antes de realizar a ordenação.
+
+15 - 16 Julho 2018,
+Implementado parte da questline level 120+ de Cygnus Knights.
+Corrigido itens de cash sendo vendidos em player shop/hired merchant.
+Corrigido login atribuindo sempre conta de GM (limitando ações como trade) quando há pelo menos um char GM naquela conta - isso pode até ser mesmo necessário, criado um flag pra continuar enforcando o "GM account".
+Estabilizado mecânicas de MapleTV e separado atividade da MapleTV pra cada world.
+Normalizado Character.wz: agora todos os equipamentos que precisam ter "cash" o tem.
+Normalizado String.wz: agora todos os itens sem "name" o tem.
+Nova ferramenta: MapleInvalidItemWithNoNameFetcher. Busca por itemids sem as propriedades "cash" e "name" nos conjuntos de wz.xml.
+
+17 Julho 2018,
+Corrigido problema crítico no novo sistema de login, que impedia contas recém-criadas de logar no jogo.
\ No newline at end of file
diff --git a/scripts/npc/1103000.js b/scripts/npc/1103000.js
new file mode 100644
index 0000000000..67e606791f
--- /dev/null
+++ b/scripts/npc/1103000.js
@@ -0,0 +1,46 @@
+/*
+ This file is part of the HeavenMS MapleStory Server
+ Copyleft (L) 2016 - 2018 RonanLana
+
+ 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 .
+*/
+
+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("I am Advanced Knight #b#p1103000##k. Thanks to your bravery I and all of Ereve have been rescued from the grasps of Eleanor. By the kindness of our Empress, well battled!");
+ cm.dispose();
+ }
+ }
+}
diff --git a/scripts/npc/1104002.js b/scripts/npc/1104002.js
new file mode 100644
index 0000000000..2624091578
--- /dev/null
+++ b/scripts/npc/1104002.js
@@ -0,0 +1,61 @@
+/*
+ This file is part of the HeavenMS MapleStory Server
+ Copyleft (L) 2016 - 2018 RonanLana
+
+ 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 .
+*/
+
+var status;
+
+function start() {
+ status = -1;
+ action(1, 0, 0);
+}
+
+function action(mode, type, selection) {
+ if (mode == -1) {
+ cm.dispose();
+ } else {
+ var mapobj = cm.getMap();
+
+ if (mode == 0 && type > 0) {
+ cm.getPlayer().dropMessage(5, "Eleanor: Oh, lost the Empress and still challenging us? Now you've done it! Prepare yourself!!!");
+
+ mapobj.spawnMonsterOnGroundBelow(Packages.server.life.MapleLifeFactory.getMonster(9001010), new Packages.java.awt.Point(850, 0));
+ mapobj.destroyNPC(1104002);
+
+ cm.dispose();
+ return;
+ }
+ if (mode == 1)
+ status++;
+ else
+ status--;
+
+ if(status == 0) {
+ if(!cm.isQuestStarted(20407)) {
+ cm.sendOk("... Knight, you still #bseem unsure to face this fight#k, don't you? There's no grace in challenging someone when they are still not mentally ready for the battle. Talk your peace to that big clumsy bird of yours, maybe it'll put some guts on you.");
+ cm.dispose();
+ return;
+ }
+
+ cm.sendAcceptDecline("Hahahahaha! This place's Empress is already under my domain, that's surely a great advance on the #bBlack Wings#k' overthrow towards Maple World... And you, there? Still wants to face us? Or, better yet, #rfeel fancy to join us#k since there's nothing more you can do?");
+ } else if (status == 1) {
+ cm.sendOk("Heh, cowards have no place on the #rBlack Mage's#k army. Begone!");
+ cm.dispose();
+ }
+ }
+}
diff --git a/scripts/npc/1104200.js b/scripts/npc/1104200.js
new file mode 100644
index 0000000000..46fe5a106d
--- /dev/null
+++ b/scripts/npc/1104200.js
@@ -0,0 +1,55 @@
+/*
+ This file is part of the HeavenMS MapleStory Server
+ Copyleft (L) 2016 - 2018 RonanLana
+
+ 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 .
+*/
+
+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.sendNext("#b#p1104002##k... The black witch... Trapped me here... There's no time now, she's already on her way to #rattack Ereve#k!");
+ } else if (status == 1) {
+ cm.sendYesNo("Fellow Knight, you must reach to #rEreve#k right now, #rthe Empress is in danger#k!! Even in this condition, I can still Magic Warp you there. When you're ready talk to me. #bAre you ready to face Eleanor?#k");
+ } else if (status == 2) {
+ if(cm.getWarpMap(913030000).countPlayers() == 0) {
+ cm.warp(913030000, 0);
+ } else {
+ cm.sendOk("There's someone already challenging her. Please wait awhile.");
+ }
+
+ cm.dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/scripts/npc/1104201.js b/scripts/npc/1104201.js
new file mode 100644
index 0000000000..38b68df694
--- /dev/null
+++ b/scripts/npc/1104201.js
@@ -0,0 +1,52 @@
+/*
+ This file is part of the HeavenMS MapleStory Server
+ Copyleft (L) 2016 - 2018 RonanLana
+
+ 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 .
+*/
+
+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) {
+ if (!(cm.isQuestCompleted(20407) || cm.isQuestStarted(20407) && cm.getQuestProgress(20407, 9001010) != 0) && cm.getMap().countMonster(9001010) == 0 && cm.getMap().getNPCById(1104002) == null) {
+ cm.sendOk("... Hnngh... #b#h0##k, is that you...? #r#p1104002##k... She's already here... #b#h0##k, I'm truly sorry I can't help you right now in this state, just when a bigger threat appeared I could do nothing for my people.... Please I beg you, please defeat her, #b#h0##k!! ....");
+ cm.spawnNpc(1104002, new java.awt.Point(850, 0), cm.getMap());
+ } else {
+ cm.sendOk("...");
+ }
+
+ cm.dispose();
+ }
+ }
+}
diff --git a/scripts/npc/1104202.js b/scripts/npc/1104202.js
new file mode 100644
index 0000000000..e5600f02ab
--- /dev/null
+++ b/scripts/npc/1104202.js
@@ -0,0 +1,46 @@
+/*
+ This file is part of the HeavenMS MapleStory Server
+ Copyleft (L) 2016 - 2018 RonanLana
+
+ 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 .
+*/
+
+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("...");
+ cm.dispose();
+ }
+ }
+}
diff --git a/scripts/npc/1104203.js b/scripts/npc/1104203.js
new file mode 100644
index 0000000000..e5600f02ab
--- /dev/null
+++ b/scripts/npc/1104203.js
@@ -0,0 +1,46 @@
+/*
+ This file is part of the HeavenMS MapleStory Server
+ Copyleft (L) 2016 - 2018 RonanLana
+
+ 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 .
+*/
+
+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("...");
+ cm.dispose();
+ }
+ }
+}
diff --git a/scripts/npc/1104204.js b/scripts/npc/1104204.js
new file mode 100644
index 0000000000..e5600f02ab
--- /dev/null
+++ b/scripts/npc/1104204.js
@@ -0,0 +1,46 @@
+/*
+ This file is part of the HeavenMS MapleStory Server
+ Copyleft (L) 2016 - 2018 RonanLana
+
+ 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 .
+*/
+
+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("...");
+ cm.dispose();
+ }
+ }
+}
diff --git a/scripts/npc/1104205.js b/scripts/npc/1104205.js
new file mode 100644
index 0000000000..e5600f02ab
--- /dev/null
+++ b/scripts/npc/1104205.js
@@ -0,0 +1,46 @@
+/*
+ This file is part of the HeavenMS MapleStory Server
+ Copyleft (L) 2016 - 2018 RonanLana
+
+ 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 .
+*/
+
+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("...");
+ cm.dispose();
+ }
+ }
+}
diff --git a/scripts/npc/1104206.js b/scripts/npc/1104206.js
new file mode 100644
index 0000000000..e5600f02ab
--- /dev/null
+++ b/scripts/npc/1104206.js
@@ -0,0 +1,46 @@
+/*
+ This file is part of the HeavenMS MapleStory Server
+ Copyleft (L) 2016 - 2018 RonanLana
+
+ 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 .
+*/
+
+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("...");
+ cm.dispose();
+ }
+ }
+}
diff --git a/scripts/npc/1104207.js b/scripts/npc/1104207.js
new file mode 100644
index 0000000000..e5600f02ab
--- /dev/null
+++ b/scripts/npc/1104207.js
@@ -0,0 +1,46 @@
+/*
+ This file is part of the HeavenMS MapleStory Server
+ Copyleft (L) 2016 - 2018 RonanLana
+
+ 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 .
+*/
+
+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("...");
+ cm.dispose();
+ }
+ }
+}
diff --git a/scripts/npc/2100002.js b/scripts/npc/2100002.js
index c6d032441f..2cbe7b96f0 100644
--- a/scripts/npc/2100002.js
+++ b/scripts/npc/2100002.js
@@ -6,6 +6,6 @@ function start() {
}
function action(mode, type, selection) {
- cm.openShopNPC(48);
+ cm.openShopNPC(2100002);
cm.dispose();
}
\ No newline at end of file
diff --git a/scripts/npc/2100003.js b/scripts/npc/2100003.js
index 8e20e05d1b..2abc59d8aa 100644
--- a/scripts/npc/2100003.js
+++ b/scripts/npc/2100003.js
@@ -6,6 +6,6 @@ function start() {
}
function action(mode, type, selection) {
- cm.openShopNPC(52);
+ cm.openShopNPC(2100003);
cm.dispose();
}
\ No newline at end of file
diff --git a/scripts/npc/2103002.js b/scripts/npc/2103002.js
index f9a51575b0..eaf066d340 100644
--- a/scripts/npc/2103002.js
+++ b/scripts/npc/2103002.js
@@ -43,7 +43,7 @@ function action(mode, type, selection) {
if(status == 0) {
if(cm.isQuestStarted(3923) && !cm.haveItem(4031578, 1)) {
if(cm.canHold(4031578, 1)) {
- cm.sendOk("You have just swiped the ring. Clear the area asap.", 2);
+ cm.sendOk("You have just swiped the ring. Clear the area asap!", 2);
cm.gainItem(4031578, 1);
} else {
cm.sendOk("You don't have a ETC slot available.", 2);
diff --git a/scripts/npc/9977777.js b/scripts/npc/9977777.js
index 6d30fe0578..47fddf1b35 100644
--- a/scripts/npc/9977777.js
+++ b/scripts/npc/9977777.js
@@ -73,9 +73,10 @@ function writeFeatureTab_PlayerSocialNetwork() {
addFeature("Party for novices-only.");
addFeature("Thoroughly reviewed P. Shops and H. Merchants.");
addFeature("Transactions on Merchs instantly announced to owner.");
- addFeature("Game minirooms with semi-functional pw system.");
+ addFeature("Game minirooms with functional pw system.");
addFeature("Proper item pickup cooldown on non-owned items.");
addFeature("Improved ranking system, with daily movement.");
+ addFeature("Protected and improved face expression system.");
addFeature("Automated support for Player NPCs and Hall of Fame.");
addFeature("Engagement & Wedding system.");
}
@@ -84,6 +85,7 @@ function writeFeatureTab_CashItems() {
addFeature("EXP/DROP/Cosmetic Coupons.");
addFeature("EXP/DROP Coupon as buff effect during active time.");
addFeature("Great deal of cash items functional.");
+ addFeature("MapleTV mechanics stabilized and split by world.");
addFeature("GMS-esque omok/match card drop chances.");
addFeature("New town scroll: antibanish. Counters boss banishes.");
addFeature("Inventory system checks for free slot & stack space.");
@@ -112,6 +114,7 @@ function writeFeatureTab_MonstersMapsReactors() {
addFeature("Added Boss HP Bar for dozens of bosses.");
addFeature("Game will favor showing the targeted boss HPbar.");
addFeature("Dmg overtime on maps and neutralizers functional.");
+ addFeature("Items will consistently stay within the walking area.");
addFeature("Boats, elevator and other travel mechanics functional.");
addFeature("C. Balrog's boat approaching visual effect functional.");
addFeature("Maps having everlasting items no longer expires them.");
@@ -119,6 +122,7 @@ function writeFeatureTab_MonstersMapsReactors() {
addFeature("Uncovered missing portal SFX on scripted portals.");
addFeature("PQ boxes sprays items when opened, GMS-like.");
addFeature("Reactors pick items up smartly from the field.");
+ addFeature("Updated scripted portals now with proper portal SFX.");
addFeature("Reviewed Masteria, W. Tour, N. Desert and Neo City.");
addFeature("Giant Cake boss drops s. bags and Maple items.");
}
@@ -145,6 +149,7 @@ function writeFeatureTab_Serverpotentials() {
addFeature("Enhanced auto-pot system: smart pet potion handle.");
addFeature("Enhanced buff system: best buffs effects takes place.");
addFeature("Enhanced AP auto-assigner: focus on eqp demands.");
+ addFeature("Tweaked pet/mount hunger to a balanced growth rate.");
addFeature("Consistent experience gain system.");
addFeature("NPC crafters won't take items freely anymore.");
addFeature("Duey: pkg rcvd popup and many delivery mechanics.");
@@ -157,9 +162,11 @@ function writeFeatureTab_Serverpotentials() {
addFeature("Custom buyback system, uses mesos / NX, via MTS.");
addFeature("Delete Character.");
addFeature("Smooth view-all-char, now showing all account chars.");
+ addFeature("Centralized servertime, boosting handler performance.");
addFeature("Autosaver (periodically saves player's data on DB).");
addFeature("Fixed and randomized HP/MP growth rate available.");
addFeature("Prevented 'NPC gone after some uptime' issue.");
+ addFeature("Implemented starters' AP assigning for under level 11.");
addFeature("AP assigning available for novices level 10 or below.");
addFeature("Automatic account registration - thanks shavit!");
}
@@ -202,6 +209,7 @@ function writeFeatureTab_Project() {
addFeature("Reviewed SQL data, eliminating duplicated entries.");
addFeature("Improved login phase, using cache over DB queries.");
addFeature("Protected many flaws with login management system.");
+ addFeature("Usage of HikariCP to improve DB connection calls.");
addFeature("Developed many survey tools for content profiling.");
addFeature("ThreadTracker: runtime tool for deadlock detection.");
addFeature("Channel, World and Server-wide timer management.");
diff --git a/scripts/portal/elevator.js b/scripts/portal/elevator.js
index 72bddbe0bd..d793d9b1b8 100644
--- a/scripts/portal/elevator.js
+++ b/scripts/portal/elevator.js
@@ -1,12 +1,11 @@
function enter(pi) {
try {
- var elevator = pi.getEventManager("Elevator");
+ var elevator = pi.getEventManager("elevator");
if (elevator == null) {
pi.getPlayer().dropMessage(5, "The elevator is under maintenance.");
} else if (elevator.getProperty(pi.getMapId() == 222020100 ? ("goingUp") : ("goingDown")).equals("false")) {
pi.playPortalSound(); pi.warp(pi.getMapId() == 222020100 ? 222020110 : 222020210, 0);
- //elevator.getIv().invokeFunction(pi.getMapId() == 222020110 ? "goUp" : "goDown");
- return true;
+ return true;
} else if (elevator.getProperty(pi.getMapId() == 222020100 ? ("goingUp") : ("goingDown")).equals("true")) {
pi.getPlayer().dropMessage(5, "The elevator is currently moving.");
}
diff --git a/scripts/portal/enterWitch.js b/scripts/portal/enterWitch.js
index f4e3770f05..e21cb9dd55 100644
--- a/scripts/portal/enterWitch.js
+++ b/scripts/portal/enterWitch.js
@@ -1,13 +1,20 @@
function enter(pi) {
- if (pi.getQuestStatus(20407) == 2) {
- pi.playPortalSound(); pi.warp(924010200,0);
- return true;
- } else if (pi.getQuestStatus(20406) == 2) {
- pi.playPortalSound(); pi.warp(924010100,0);
- return true;
- } else if (pi.getQuestStatus(20404) == 2) {
- pi.playPortalSound(); pi.warp(924010000,0);
+ if (pi.isQuestCompleted(20404)) {
+ var warpMap;
+
+ if (pi.isQuestCompleted(20407)) {
+ warpMap = 924010200;
+ } else if (pi.isQuestCompleted(20406)) {
+ warpMap = 924010100;
+ } else {
+ warpMap = 924010000;
+ }
+
+ pi.playPortalSound();
+ pi.warp(warpMap, 1);
return true;
+
+
} else {
pi.playerMessage(5, "I shouldn't go here.. it's creepy!");
return false;
diff --git a/scripts/portal/outDarkEreb.js b/scripts/portal/outDarkEreb.js
new file mode 100644
index 0000000000..b56ce8f2ae
--- /dev/null
+++ b/scripts/portal/outDarkEreb.js
@@ -0,0 +1,27 @@
+/*
+ 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 .
+*/
+function enter(pi) {
+ var warpMap = pi.isQuestCompleted(20407) ? 924010200 : 924010100;
+
+ pi.playPortalSound(); pi.warp(warpMap, 0);
+ return true;
+}
\ No newline at end of file
diff --git a/scripts/quest/1021.js b/scripts/quest/1021.js
index 434a2b6c34..cf5140b563 100644
--- a/scripts/quest/1021.js
+++ b/scripts/quest/1021.js
@@ -29,68 +29,81 @@ importPackage(Packages.client);
var status = -1;
function start(mode, type, selection) {
- status++;
- if (mode != 1) {
- if(type == 1 && mode == 0)
- status -= 2;
- else{
+ if (mode == -1) {
+ qm.dispose();
+ } else {
+ if(mode == 0 && type > 0) {
qm.dispose();
return;
}
- }
- if (status == 0)
- qm.sendNext("Hey, Man~ What's up? Haha! I am Roger who can teach you adorable new Maplers lots of information.");
- else if (status == 1)
- qm.sendNextPrev("You are asking who made me do this? Ahahahaha!\r\nMyself! I wanted to do this and just be kind to you new travellers.");
- else if (status == 2)
- qm.sendAcceptDecline("So..... Let me just do this for fun! Abaracadabra~!");
- else if (status == 3) {
- if (qm.c.getPlayer().getHp() >= 50) {
- qm.c.getPlayer().setHp(25);
- qm.c.getPlayer().updateSingleStat(MapleStat.HP, 25);
- }
- if (!qm.haveItem(2010007))
- qm.gainItem(2010007, 1);
+
+ if (mode == 1)
+ status++;
+ else
+ status--;
+
+ if (status == 0)
+ qm.sendNext("Hey, Man~ What's up? Haha! I am Roger who can teach you adorable new Maplers lots of information.");
+ else if (status == 1)
+ qm.sendNextPrev("You are asking who made me do this? Ahahahaha!\r\nMyself! I wanted to do this and just be kind to you new travellers.");
+ else if (status == 2)
+ qm.sendAcceptDecline("So..... Let me just do this for fun! Abaracadabra~!");
+ else if (status == 3) {
+ if (qm.c.getPlayer().getHp() >= 50) {
+ qm.c.getPlayer().setHp(25);
+ qm.c.getPlayer().updateSingleStat(MapleStat.HP, 25);
+ }
+
+ if (!qm.haveItem(2010007)) {
+ qm.gainItem(2010007, 1);
+ }
+
qm.forceStartQuest();
qm.sendNext("Surprised? If HP becomes 0, then you are in trouble. Now, I will give you #rRoger's Apple#k. Please take it. You will feel stronger. Open the Item window and double click to consume. Hey, it's very simple to open the Item window. Just press #bI#k on your keyboard.");
- } else if (status == 4) {
- qm.sendNextPrev("Please take all Roger's Apples that I gave you. You will be able to see the HP bar increasing. Please talk to me again when you recover your HP 100%.");
- } else if (status == 5) {
- qm.showInfo("UI/tutorial.img/28");
- qm.dispose();
+ } else if (status == 4) {
+ qm.sendNextPrev("Please take all Roger's Apples that I gave you. You will be able to see the HP bar increasing. Please talk to me again when you recover your HP 100%.");
+ } else if (status == 5) {
+ qm.showInfo("UI/tutorial.img/28");
+ qm.dispose();
+ }
}
}
function end(mode, type, selection) {
- status++;
- if (mode != 1) {
- if(type == 1 && mode == 0)
- status -= 2;
- else{
+ if (mode == -1) {
+ qm.dispose();
+ } else {
+ if(mode == 0 && type > 0) {
qm.dispose();
return;
}
- }
- if (status == 0)
- if (qm.c.getPlayer().getHp() < 50) {
- qm.sendNext("Hey, your HP is not fully recovered yet. Did you take all the Roger's Apple that I gave you? Are you sure?");
+
+ if (mode == 1)
+ status++;
+ else
+ status--;
+
+ if (status == 0)
+ if (qm.c.getPlayer().getHp() < 50) {
+ qm.sendNext("Hey, your HP is not fully recovered yet. Did you take all the Roger's Apple that I gave you? Are you sure?");
+ qm.dispose();
+ } else
+ qm.sendNext("How easy is it to consume the item? Simple, right? You can set a #bhotkey#k on the right bottom slot. Haha you didn't know that! right? Oh, and if you are a beginner, HP will automatically recover itself as time goes by. Well it takes time but this is one of the strategies for the beginners.");
+ else if (status == 1)
+ qm.sendNextPrev("Alright! Now that you have learned alot, I will give you a present. This is a must for your travel in Maple World, so thank me! Please use this under emergency cases!");
+ else if (status == 2)
+ qm.sendNextPrev("Okay, this is all I can teach you. I know it's sad but it is time to say good bye. Well take care if yourself and Good luck my friend!\r\n\r\n#fUI/UIWindow.img/QuestIcon/4/0#\r\n#v2010000# 3 #t2010000#\r\n#v2010009# 3 #t2010009#\r\n\r\n#fUI/UIWindow.img/QuestIcon/8/0# 10 exp");
+ else if (status == 3) {
+ if(qm.isQuestCompleted(1021))
+ qm.dropMessage(1,"Unknown Error");
+ else if(qm.canHold(2010000) && qm.canHold(2010009)){
+ qm.gainExp(10);
+ qm.gainItem(2010000, 3);
+ qm.gainItem(2010009, 3);
+ qm.forceCompleteQuest();
+ }else
+ qm.dropMessage(1,"Your inventory is full");
qm.dispose();
- } else
- qm.sendNext("How easy is it to consume the item? Simple, right? You can set a #bhotkey#k on the right bottom slot. Haha you didn't know that! right? Oh, and if you are a beginner, HP will automatically recover itself as time goes by. Well it takes time but this is one of the strategies for the beginners.");
- else if (status == 1)
- qm.sendNextPrev("Alright! Now that you have learned alot, I will give you a present. This is a must for your travel in Maple World, so thank me! Please use this under emergency cases!");
- else if (status == 2)
- qm.sendNextPrev("Okay, this is all I can teach you. I know it's sad but it is time to say good bye. Well take care if yourself and Good luck my friend!\r\n\r\n#fUI/UIWindow.img/QuestIcon/4/0#\r\n#v2010000# 3 #t2010000#\r\n#v2010009# 3 #t2010009#\r\n\r\n#fUI/UIWindow.img/QuestIcon/8/0# 10 exp");
- else if (status == 3) {
- if(qm.isQuestCompleted(1021))
- qm.dropMessage(1,"Unknown Error");
- else if(qm.canHold(2010000) && qm.canHold(2010009)){
- qm.gainExp(10);
- qm.gainItem(2010000, 3);
- qm.gainItem(2010009, 3);
- qm.forceCompleteQuest();
- }else
- qm.dropMessage(1,"Your inventory is full");
- qm.dispose();
+ }
}
}
\ No newline at end of file
diff --git a/scripts/quest/20400.js b/scripts/quest/20400.js
new file mode 100644
index 0000000000..461973890c
--- /dev/null
+++ b/scripts/quest/20400.js
@@ -0,0 +1,48 @@
+/*
+ This file is part of the HeavenMS MapleStory Server
+ Copyleft (L) 2016 - 2018 RonanLana
+
+ 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 .
+*/
+/*
+ Chasing the Knight's Target
+
+ */
+
+var status = -1;
+
+function start(mode, type, selection) {
+ if (mode == -1) {
+ qm.dispose();
+ } else {
+ if(mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
+ if (mode == 1)
+ status++;
+ else
+ status--;
+
+ if (status == 0) {
+ qm.sendNext("Not long ago, we received a distress signal of #bAdvanced Knight #p1103000##k, currently stationed somewhere in #rEl Nath#k. His Your job is to find him, first go talk to #b#p1101002##k and receive further instructions on your mission.");
+ } else if (status == 1) {
+ qm.forceCompleteQuest();
+ qm.dispose();
+ }
+ }
+}
diff --git a/scripts/quest/20401.js b/scripts/quest/20401.js
new file mode 100644
index 0000000000..c69c702155
--- /dev/null
+++ b/scripts/quest/20401.js
@@ -0,0 +1,48 @@
+/*
+ This file is part of the HeavenMS MapleStory Server
+ Copyleft (L) 2016 - 2018 RonanLana
+
+ 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 .
+*/
+/*
+ Chasing the Knight's Target
+
+ */
+
+var status = -1;
+
+function start(mode, type, selection) {
+ if (mode == -1) {
+ qm.dispose();
+ } else {
+ if(mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
+ if (mode == 1)
+ status++;
+ else
+ status--;
+
+ if (status == 0) {
+ qm.sendNext("Last time #bAdvanced Knight #p1103000##k was seen, he was investigating the surging increase on #rzombies#k lately on the #rhigh-grounds of El Nath#k. You should get yourself there to see if you can find any clue of what could have happened.");
+ } else if (status == 1) {
+ qm.forceCompleteQuest();
+ qm.dispose();
+ }
+ }
+}
diff --git a/scripts/quest/20405.js b/scripts/quest/20405.js
new file mode 100644
index 0000000000..e61bf79baf
--- /dev/null
+++ b/scripts/quest/20405.js
@@ -0,0 +1,50 @@
+/*
+ This file is part of the HeavenMS MapleStory Server
+ Copyleft (L) 2016 - 2018 RonanLana
+
+ 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 .
+*/
+/*
+ Chasing the Knight's Target
+
+ */
+
+var status = -1;
+
+function start(mode, type, selection) {
+ if (mode == -1) {
+ qm.dispose();
+ } else {
+ if(mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
+ if (mode == 1)
+ status++;
+ else
+ status--;
+
+ if (status == 0) {
+ qm.sendNext("There's a note on the wall: 'The source of the curse still goes missing, but a strange device, that I suppose has been used by #rthem#k was found here.'", 3);
+ } else if (status == 1) {
+ qm.sendNextPrev("'The machine was sent to #rEreve#k for avaliation, I'll now set out to continue my mission. Let the Empress bless me on my journey.'", 3);
+ } else if (status == 2) {
+ qm.forceCompleteQuest();
+ qm.dispose();
+ }
+ }
+}
diff --git a/scripts/quest/20406.js b/scripts/quest/20406.js
new file mode 100644
index 0000000000..98e0fcc3fb
--- /dev/null
+++ b/scripts/quest/20406.js
@@ -0,0 +1,48 @@
+/*
+ This file is part of the HeavenMS MapleStory Server
+ Copyleft (L) 2016 - 2018 RonanLana
+
+ 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 .
+*/
+/*
+ Chasing the Knight's Target
+
+ */
+
+var status = -1;
+
+function start(mode, type, selection) {
+ if (mode == -1) {
+ qm.dispose();
+ } else {
+ if(mode == 0 && type > 0) {
+ qm.dispose();
+ return;
+ }
+
+ if (mode == 1)
+ status++;
+ else
+ status--;
+
+ if (status == 0) {
+ qm.sendNext("Is that so? All there was was a saying that #p1103000# set out to continue his journey? That can't be, there were further instructions for him to detail the progress of his mission until then. #rReturn to the cave#k and report again if it really has nothing more there.");
+ } else if (status == 1) {
+ qm.forceCompleteQuest();
+ qm.dispose();
+ }
+ }
+}
diff --git a/scripts/quest/3927.js b/scripts/quest/3927.js
index d3d3fa14a8..a1627dee23 100644
--- a/scripts/quest/3927.js
+++ b/scripts/quest/3927.js
@@ -53,14 +53,18 @@ function end(mode, type, selection) {
} else if (status == 2) {
if(selection == 0) {
qm.sendOk("If I had an iron hammer and a dagger... a bow and an arrow... what does that mean? Do you want me to tell you? I don't know myself. It's something you should think about. If you need a clue... it would go something like... a weapon is just an item... until someone uses it...?");
- qm.gainExp(1000 * qm.getPlayer().getExpRate());
- qm.forceCompleteQuest();
} else if(selection == 1) {
qm.sendOk("Man, Jiyur wrote on the wall again! Arrgh!!");
+ qm.dispose();
+ return;
} else {
qm.sendOk("What? You forgot? Do you remember where it was written?");
+ qm.dispose();
+ return;
}
-
+ } else if (status == 3) {
+ qm.gainExp(1000 * qm.getPlayer().getExpRate());
+ qm.forceCompleteQuest();
qm.dispose();
}
}
diff --git a/scripts/quest/3953.js b/scripts/quest/3953.js
index 78f7af11d8..f68cb68d4d 100644
--- a/scripts/quest/3953.js
+++ b/scripts/quest/3953.js
@@ -42,8 +42,7 @@ function end(mode, type, selection) {
qm.sendSimple("Ehh... Yeah, the city is not really doing well because of the currently ruling govern, that's indeed a fact. If only the Guardians of the Deserts returned to put order on this mess...\r\n\r\n#L0##bWhat is the Guardian of the Deserts doing when we're under the Queen's tyranny?#k");
} else if (status == 3) {
qm.sendSimple("They have departed on an expedition to get rid of some major threats in the desert that were ravaging Ariant, for quite some time now... It's strange, they should have already returned... Thinking about it now, the last attack on the merchants was around the direction the Guardians departed... No, that can't be... Can it?\r\n\r\n#L0##bPerhaps Deo has already turned into a monster.#k");
- }
- else if (status == 4) {
+ } else if (status == 4) {
qm.gainItem(4011008, -1);
qm.sendNext("We're in great trouble, if it is like this. And it really seems like it. If the Royal Cactus Deo has gone insane, Ariant is done for. You, can you do something to defeat Deo? We really need your help now.");
diff --git a/sql/db_drops.sql b/sql/db_drops.sql
index 4998b029af..3c076c7164 100644
--- a/sql/db_drops.sql
+++ b/sql/db_drops.sql
@@ -20264,6 +20264,8 @@ USE `heavenms`;
(4300008, 4032521, 1, 1, 2291, 120000),
(4300009, 4032521, 1, 1, 2291, 120000),
(4300010, 4032521, 1, 1, 2291, 120000),
+(5130107, 4001207, 1, 1, 0, 2285),
+(5130108, 4001207, 1, 1, 0, 2285),
(9400506, 2020020, 1, 1, 0, 100000),
(9400506, 4031217, 1, 1, 0, 40000),
(9400507, 2020020, 1, 1, 0, 100000),
diff --git a/src/client/MapleCharacter.java b/src/client/MapleCharacter.java
index 38b1600f35..5774b13b99 100644
--- a/src/client/MapleCharacter.java
+++ b/src/client/MapleCharacter.java
@@ -199,7 +199,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
private int expRate = 1, mesoRate = 1, dropRate = 1, expCoupon = 1, mesoCoupon = 1, dropCoupon = 1;
private int omokwins, omokties, omoklosses, matchcardwins, matchcardties, matchcardlosses;
private int owlSearch;
- private long lastfametime, lastUsedCashItem, lastHealed, lastBuyback = 0, lastDeathtime, lastMesoDrop = -1, jailExpiration = -1;
+ private long lastfametime, lastUsedCashItem, lastExpression = 0, lastHealed, lastBuyback = 0, lastDeathtime, lastMesoDrop = -1, jailExpiration = -1;
private transient int localmaxhp, localmaxmp, localstr, localdex, localluk, localint_, magic, watk;
private boolean hidden, canDoor = true, berserk, hasMerchant, hasSandboxItem = false, whiteChat = false;
private int linkedLevel = 0;
@@ -2369,7 +2369,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
}
- private boolean dispelSkills(int skillid) {
+ private static boolean dispelSkills(int skillid) {
switch (skillid) {
case DarkKnight.BEHOLDER:
case FPArchMage.ELQUINES:
@@ -2386,6 +2386,14 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
return false;
}
}
+
+ public void changeFaceExpression(int emote) {
+ long timeNow = Server.getInstance().getCurrentTime();
+ if(timeNow - lastExpression > 2000) {
+ lastExpression = timeNow;
+ client.getChannelServer().registerFaceExpression(map, this, emote);
+ }
+ }
private void doHurtHp() {
if (!(this.getInventory(MapleInventoryType.EQUIPPED).findById(getMap().getHPDecProtect()) != null || buffMapProtection())) {
diff --git a/src/client/MapleClient.java b/src/client/MapleClient.java
index f8181b6b65..8b294a4ea3 100644
--- a/src/client/MapleClient.java
+++ b/src/client/MapleClient.java
@@ -956,6 +956,7 @@ public class MapleClient {
Server.getInstance().unregisterLoginState(this);
+ this.session.setAttribute(MapleClient.CLIENT_KEY, null);
this.accountName = null;
this.macs = null;
this.hwid = null;
@@ -1153,6 +1154,10 @@ public class MapleClient {
lock.unlock();
}
+ public boolean trylockClient() {
+ return lock.tryLock();
+ }
+
public void lockEncoder() {
encoderLock.lock();
}
@@ -1356,12 +1361,16 @@ public class MapleClient {
this.sessionId = sessionId;
}
+ public boolean canRequestCharlist(){
+ return lastNpcClick + 877 < Server.getInstance().getCurrentTime();
+ }
+
public boolean canClickNPC(){
- return lastNpcClick + 500 < System.currentTimeMillis();
+ return lastNpcClick + 500 < Server.getInstance().getCurrentTime();
}
public void setClickedNPC(){
- lastNpcClick = System.currentTimeMillis();
+ lastNpcClick = Server.getInstance().getCurrentTime();
}
public void removeClickedNPC(){
diff --git a/src/client/command/Commands.java b/src/client/command/Commands.java
index 37c93969db..69d5fc4887 100644
--- a/src/client/command/Commands.java
+++ b/src/client/command/Commands.java
@@ -607,33 +607,40 @@ public class Commands {
case "dex":
case "int":
case "luk":
- int amount = (sub.length > 1) ? Integer.parseInt(sub[1]) : player.getRemainingAp();
+ int remainingAp = player.getRemainingAp();
+
+ int amount = (sub.length > 1) ? Math.min(Integer.parseInt(sub[1]), remainingAp) : remainingAp;
boolean str = sub[0].equalsIgnoreCase("str");
boolean Int = sub[0].equalsIgnoreCase("int");
boolean luk = sub[0].equalsIgnoreCase("luk");
boolean dex = sub[0].equalsIgnoreCase("dex");
- if (amount > 0 && amount <= player.getRemainingAp() && amount <= 32763 || amount < 0 && amount >= -32763 && Math.abs(amount) + player.getRemainingAp() <= 32767) {
- if (str && amount + player.getStr() <= 32767 && amount + player.getStr() >= 4) {
- player.setStr(player.getStr() + amount);
- player.updateSingleStat(MapleStat.STR, player.getStr());
- player.setRemainingAp(player.getRemainingAp() - amount);
- player.updateSingleStat(MapleStat.AVAILABLEAP, player.getRemainingAp());
- } else if (Int && amount + player.getInt() <= 32767 && amount + player.getInt() >= 4) {
- player.setInt(player.getInt() + amount);
- player.updateSingleStat(MapleStat.INT, player.getInt());
- player.setRemainingAp(player.getRemainingAp() - amount);
- player.updateSingleStat(MapleStat.AVAILABLEAP, player.getRemainingAp());
- } else if (luk && amount + player.getLuk() <= 32767 && amount + player.getLuk() >= 4) {
- player.setLuk(player.getLuk() + amount);
- player.updateSingleStat(MapleStat.LUK, player.getLuk());
- player.setRemainingAp(player.getRemainingAp() - amount);
- player.updateSingleStat(MapleStat.AVAILABLEAP, player.getRemainingAp());
- } else if (dex && amount + player.getDex() <= 32767 && amount + player.getDex() >= 4) {
- player.setDex(player.getDex() + amount);
- player.updateSingleStat(MapleStat.DEX, player.getDex());
- player.setRemainingAp(player.getRemainingAp() - amount);
- player.updateSingleStat(MapleStat.AVAILABLEAP, player.getRemainingAp());
+ if (amount > 0 && amount <= remainingAp && amount <= 32763) {
+ int playerStr = player.getStr();
+ int playerDex = player.getDex();
+ int playerInt = player.getInt();
+ int playerLuk = player.getLuk();
+
+ if (str && amount + playerStr <= 32767 && amount + playerStr >= 4) {
+ player.setStr(playerStr + amount);
+ player.updateSingleStat(MapleStat.STR, playerStr);
+ player.setRemainingAp(remainingAp - amount);
+ player.updateSingleStat(MapleStat.AVAILABLEAP, remainingAp);
+ } else if (Int && amount + playerInt <= 32767 && amount + playerInt >= 4) {
+ player.setInt(playerInt + amount);
+ player.updateSingleStat(MapleStat.INT, playerInt);
+ player.setRemainingAp(remainingAp - amount);
+ player.updateSingleStat(MapleStat.AVAILABLEAP, remainingAp);
+ } else if (luk && amount + playerLuk <= 32767 && amount + playerLuk >= 4) {
+ player.setLuk(playerLuk + amount);
+ player.updateSingleStat(MapleStat.LUK, playerLuk);
+ player.setRemainingAp(remainingAp - amount);
+ player.updateSingleStat(MapleStat.AVAILABLEAP, remainingAp);
+ } else if (dex && amount + playerDex <= 32767 && amount + playerDex >= 4) {
+ player.setDex(playerDex + amount);
+ player.updateSingleStat(MapleStat.DEX, playerDex);
+ player.setRemainingAp(remainingAp - amount);
+ player.updateSingleStat(MapleStat.AVAILABLEAP, remainingAp);
} else {
player.dropMessage("Please make sure the stat you are trying to raise is not over 32,767 or under 4.");
}
diff --git a/src/client/creator/CharacterFactory.java b/src/client/creator/CharacterFactory.java
index ba84b0e296..bbba6d86c2 100644
--- a/src/client/creator/CharacterFactory.java
+++ b/src/client/creator/CharacterFactory.java
@@ -56,7 +56,7 @@ public abstract class CharacterFactory {
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
int top = recipe.getTop(), bottom = recipe.getBottom(), shoes = recipe.getShoes(), weapon = recipe.getWeapon();
-
+
if(top > 0) {
Item eq_top = ii.getEquipById(top);
eq_top.setPosition((byte) -5);
@@ -85,7 +85,7 @@ public abstract class CharacterFactory {
return -2;
}
c.announce(MaplePacketCreator.addNewCharEntry(newchar));
-
+
Server.getInstance().createCharacterEntry(newchar);
Server.getInstance().broadcastGMMessage(c.getWorld(), MaplePacketCreator.sendYellowTip("[NEW CHAR]: " + c.getAccountName() + " has created a new character with IGN " + name));
diff --git a/src/client/processor/BuybackProcessor.java b/src/client/processor/BuybackProcessor.java
index 6ee8819189..8011121d1c 100644
--- a/src/client/processor/BuybackProcessor.java
+++ b/src/client/processor/BuybackProcessor.java
@@ -41,7 +41,7 @@ public class BuybackProcessor {
public static void processBuyback(MapleClient c) {
MapleCharacter chr = c.getPlayer();
boolean buyback;
-
+
c.lockClient();
try {
buyback = !chr.isAlive() && chr.couldBuyback();
diff --git a/src/constants/ItemConstants.java b/src/constants/ItemConstants.java
index a49234a84c..418506fe33 100644
--- a/src/constants/ItemConstants.java
+++ b/src/constants/ItemConstants.java
@@ -126,6 +126,11 @@ public final class ItemConstants {
return itemId >= 1110000 && itemId < 1140000;
}
+ public static boolean isTaming(int itemId) {
+ int itemType = itemId / 1000;
+ return itemType == 1902 || itemType == 1912;
+ }
+
public static boolean isTownScroll(int itemId) {
return itemId >= 2030000 && itemId < 2030100;
}
@@ -164,7 +169,15 @@ public final class ItemConstants {
public static boolean isPartyAllcure(int itemId) {
return itemId == 2022433;
}
-
+
+ public static boolean isHiredMerchant(int itemId) {
+ return itemId / 10000 == 503;
+ }
+
+ public static boolean isPlayerShop(int itemId) {
+ return itemId / 10000 == 514;
+ }
+
public static MapleInventoryType getInventoryType(final int itemId) {
if (inventoryTypeCache.containsKey(itemId)) {
return inventoryTypeCache.get(itemId);
diff --git a/src/constants/ServerConstants.java b/src/constants/ServerConstants.java
index 0f366cc88c..33bae6a4ec 100644
--- a/src/constants/ServerConstants.java
+++ b/src/constants/ServerConstants.java
@@ -23,7 +23,7 @@ public class ServerConstants {
public static final long PURGING_INTERVAL = 5 * 60 * 1000;
public static final long RANKING_INTERVAL = 60 * 60 * 1000; //60 minutes, 3600000.
public static final long COUPON_INTERVAL = 60 * 60 * 1000; //60 minutes, 3600000.
- public static final long UPDATE_INTERVAL = 777;
+ public static final long UPDATE_INTERVAL = 777; //Dictates the frequency on which the "centralized server time" is updated.
public static final boolean ENABLE_PIC = false; //Pick true/false to enable or disable Pic. Delete character needs this feature ENABLED.
public static final boolean ENABLE_PIN = false; //Pick true/false to enable or disable Pin.
@@ -62,10 +62,12 @@ public class ServerConstants {
public static final boolean USE_AUTOSAVE = true; //Enables server autosaving feature (saves characters to DB each 1 hour).
public static final boolean USE_SERVER_AUTOASSIGNER = true; //HeavenMS-builtin autoassigner, uses algorithm based on distributing AP accordingly with required secondary stat on equipments.
public static final boolean USE_REFRESH_RANK_MOVE = true;
+ public static final boolean USE_ENFORCE_ADMIN_ACCOUNT = false; //Forces accounts having GM characters to be treated as a "GM account" by the client (localhost). Some of the GM account perks is the ability to FLY, but unable to TRADE.
public static final boolean USE_ENFORCE_HPMP_SWAP = false; //Forces players to reuse stats (via AP Resetting) located on HP/MP pool only inside the HP/MP stats.
public static final boolean USE_ENFORCE_MOB_LEVEL_RANGE = true; //Players N levels below the killed mob will gain no experience from defeating it.
public static final boolean USE_ENFORCE_JOB_LEVEL_RANGE = false;//Caps the player level on the minimum required to advance their current jobs.
public static final boolean USE_ENFORCE_OWL_SUGGESTIONS = false;//Forces the Owl of Minerva to always display the defined item array on GameConstants.OWL_DATA instead of those featured by the players.
+ public static final boolean USE_ENFORCE_UNMERCHABLE_CASH = true;//Forces players to not sell CASH items via merchants.
public static final boolean USE_ENFORCE_UNMERCHABLE_PET = true; //Forces players to not sell pets via merchants. (since non-named pets gets dirty name and other possible DB-related issues)
public static final boolean USE_ENFORCE_MDOOR_POSITION = false; //Forces mystic door to be spawned near spawnpoints.
public static final boolean USE_ERASE_PERMIT_ON_OPENSHOP = true;//Forces "shop permit" item to be consumed when player deploy his/her player shop.
diff --git a/src/dropspider/DataTool.java b/src/dropspider/DataTool.java
deleted file mode 100644
index cb71379b82..0000000000
--- a/src/dropspider/DataTool.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package dropspider;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import provider.MapleData;
-import provider.MapleDataDirectoryEntry;
-import provider.MapleDataFileEntry;
-import provider.MapleDataProvider;
-import provider.MapleDataProviderFactory;
-import provider.MapleDataTool;
-import server.MapleItemInformationProvider;
-import tools.Pair;
-
-/**
- *
- * @author Simon
- */
-public class DataTool {
- private static Map hardcodedMobs = new HashMap<>();
-
- private static ArrayList> npc_list = null;
- private static LinkedList> mob_pairs = null;
- private static MapleDataProvider data = MapleDataProviderFactory.getDataProvider(MapleDataProviderFactory.fileInWZPath("Mob.wz"));
- private static HashSet bosses = null;
-
- public static void setHardcodedMobNames() {
- hardcodedMobs.put("Red Slime [2]", 7120103);
- hardcodedMobs.put("Gold Slime", 7120105);
- hardcodedMobs.put("Nibelung [3]", 8220015);
- }
-
- public static void addMonsterIdsFromHardcodedName(List monster_ids, String monster_name) {
- Integer id = hardcodedMobs.get(monster_name);
- if(id != null) {
- monster_ids.add(id);
- }
- }
-
- public static ArrayList monsterIdsFromName(String name) {
- MapleData data = null;
- MapleDataProvider dataProvider = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/" + "String.wz"));
- ArrayList ret = new ArrayList<>();
- data = dataProvider.getData("Mob.img");
- if (mob_pairs == null) {
- mob_pairs = new LinkedList<>();
- for (MapleData mobIdData : data.getChildren()) {
- int mobIdFromData = Integer.parseInt(mobIdData.getName());
- String mobNameFromData = MapleDataTool.getString(mobIdData.getChildByPath("name"), "NO-NAME");
- mob_pairs.add(new Pair<>(mobIdFromData, mobNameFromData));
- }
- }
- for (Pair mobPair : mob_pairs) {
- if (mobPair.getRight().toLowerCase().equals(name.toLowerCase())) {
- ret.add(mobPair.getLeft());
- }
- }
- return ret;
- }
-
- private static void populateBossList() {
- bosses = new HashSet<>();
- MapleDataDirectoryEntry mob_data = data.getRoot();
- for (MapleDataFileEntry mdfe : mob_data.getFiles()) {
- MapleData boss_candidate = data.getData(mdfe.getName());
- MapleData monsterInfoData = boss_candidate.getChildByPath("info");
- int mid = Integer.valueOf(boss_candidate.getName().replaceAll("[^0-9]", ""));
- boolean boss = MapleDataTool.getIntConvert("boss", monsterInfoData, 0) > 0 || mid == 8810018 || mid == 9410066;
- if (boss) {
- bosses.add(mid);
- }
- }
- }
-
- public static boolean isBoss(int mid) {
- if (bosses == null) {
- populateBossList();
- }
- return bosses.contains(mid);
- }
-
- public static ArrayList itemIdsFromName(String name) {
-
- ArrayList ret = new ArrayList<>();
- for (Pair itemPair : MapleItemInformationProvider.getInstance().getAllItems()) {
- String item_name = itemPair.getRight().toLowerCase().replaceAll("\\"", "");
- item_name = item_name.replaceAll("'", "");
- item_name = item_name.replaceAll("\\'", "");
-
- name = name.toLowerCase().replaceAll("\\"", "");
- name = name.replaceAll("'", "");
- name = name.replaceAll("\\'", "");
-
- if (item_name.equals(name)) {
- ret.add(itemPair.getLeft());
- return ret;
- }
- }
- return ret;
- }
-
- public static ArrayList npcIdsFromName(String name) {
- MapleDataProvider dataProvider = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/" + "String.wz"));
- ArrayList ret = new ArrayList<>();
- if (npc_list == null) {
- ArrayList> searchList = new ArrayList<>();
- for (MapleData searchData : dataProvider.getData("Npc.img").getChildren()) {
- int searchFromData = Integer.parseInt(searchData.getName());
- String infoFromData = MapleDataTool.getString(searchData.getChildByPath("name"), "NO-NAME");
- searchList.add(new Pair<>(searchFromData, infoFromData));
- }
- npc_list = searchList;
- }
- for (Pair searched : npc_list) {
- if (searched.getRight().toLowerCase().contains(name.toLowerCase())) {
- ret.add(searched.getLeft());
- }
- }
- return ret;
- }
-}
diff --git a/src/dropspider/DropEntry.java b/src/dropspider/DropEntry.java
deleted file mode 100644
index 9dc5457d87..0000000000
--- a/src/dropspider/DropEntry.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package dropspider;
-
-import client.inventory.MapleInventoryType;
-import constants.ItemConstants;
-
-/**
- *
- * @author Simon
- */
-public class DropEntry {
- private int version;
- private int item_id;
- private int monster_id;
- private int chance;
- private int mindrop;
- private int maxdrop;
-
- public DropEntry(int item_id, int monster_id, int version) {
- this.item_id = item_id;
- this.monster_id = monster_id;
- mindrop = 1;
- maxdrop = 1;
- chance = calculateChance(item_id);
- this.version = version;
- }
-
- private int calculateChance(int item_id) {
- MapleInventoryType mit = ItemConstants.getInventoryType(item_id);
- boolean boss = DataTool.isBoss(monster_id);
- int number = (item_id / 1000) % 1000;
- switch (mit) {
- case EQUIP:
- if (boss) {
- return 40000;
- }
- return 700;
- case USE:
- if (boss) {
- mindrop = 1;
- maxdrop = 4;
- }
- switch (number) {
- case 0: // normal potions
- mindrop = 1;
- if (version > 98) {
- maxdrop = 5;
- }
- return 40000;
- case 1: // watermelons, pills, speed potions, etc
- case 2: // same thing
- return 10000;
- case 3: // advanced potions from crafting (should not drop)
- case 4: // same thing
- case 11: // poison mushroom
- case 28: // cool items
- case 30: // return scrolls
- case 46: // gallant scrolls
- return 0;
- case 10: // strange potions like apples, eggs
- case 12: // drakes blood, sap of ancient tree (rare use)
- case 20: // salad, fried chicken, dews
- case 22: // air bubbles and stuff. ALSO nependeath honey but oh well
- case 50: // antidotes and stuff
- return 3000;
- case 290: // mastery books
- if(boss)
- return 40000;
- else
- return 1000;
- case 40: // Scrolls
- case 41: // Scrolls
- case 43: // Scrolls
- case 44: // Scrolls
- case 48: // pet scrolls
- if(boss)
- return 10000;
- else
- return 750;
- case 100: // summon bags
- case 101: // summon bags
- case 102: // summon bags
- case 109: // summon bags
- case 120: // pet food
- case 211: // cliffs special potion
- case 240: // rings
- case 270: // pheromone, additional weird stuff
- case 310: // teleport rock
- case 320: // weird drops
- case 390: // weird
- case 430: // Scripted items
- case 440: // jukebox
- case 460: // magnifying glass
- case 470: // golden hammer
- case 490: // crystanol
- case 500: // sp reset
- return 0;
- case 47: // tablets from dragon rider
- return 220000;
- case 49: // clean slats, potential scroll, ees
- case 70: // throwing stars
- case 210: // rare monster piece drops
- case 330: // bullets
- if(boss)
- return 2500;
- else
- return 400;
- case 60: // bow arrows
- case 61: // crossbow arrows
- mindrop = 10;
- maxdrop = 50;
- return 10000;
- case 213: // boss transfrom
- return 100000;
- case 280: // skill books
- if(boss)
- return 20000;
- else
- return 1000;
- case 381: // monster book things
- case 382:
- case 383:
- case 384:
- case 385:
- case 386:
- case 387:
- case 388:
- return 20000;
- case 510: // recipes
- case 511:
- case 512:
- return 10000;
- default:
- return 0;
-
- }
- case ETC:
- switch (number) {
- case 0: // monster pieces
- return 200000;
- case 4: // crystal ores
- case 130: // simulators
- case 131: // manuals
- return 3000;
- case 30: // game pieces
- return 10000;
- case 32: // misc items
- return 10000;
- default:
- return 7000;
- }
- default:
- return 7000;
- }
- }
-
- public String getQuerySegment() {
- StringBuilder sb = new StringBuilder();
- sb.append("(");
- sb.append(monster_id);
- sb.append(", ");
- sb.append(item_id);
- sb.append(", ");
- sb.append(mindrop);//min
- sb.append(", ");
- sb.append(maxdrop);//max
- sb.append(", ");
- sb.append(0);//quest
- sb.append(", ");
- sb.append(chance);
- sb.append(")");
- return sb.toString();
- }
-}
\ No newline at end of file
diff --git a/src/dropspider/Errors.java b/src/dropspider/Errors.java
deleted file mode 100644
index a54b8543ab..0000000000
--- a/src/dropspider/Errors.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package dropspider;
-
-import java.util.LinkedList;
-
-public class Errors {
-
- public String mobName;
- public LinkedList wrong = new LinkedList<>();
-
- public String createErrorLog() {
- StringBuilder sb = new StringBuilder();
-
- for (String w : wrong) {
- sb.append(mobName).append(" : ").append(w).append("\r\n");
- }
-
- return sb.toString();
- }
-}
diff --git a/src/dropspider/Main.java b/src/dropspider/Main.java
deleted file mode 100644
index 22499e9b79..0000000000
--- a/src/dropspider/Main.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package dropspider;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintWriter;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Scanner;
-
-/**
- *
- * @author Simon
- */
-public class Main {
-
- private static ArrayList drop_entries = new ArrayList<>();
- private static HashMap problems = new HashMap<>();
-// private static final String TEST_STRING = " Ligator Skin, The Magic Rock, Witch Grass Leaves ";
- private static final String BASE_URL = "http://bbb.hidden-street.net";
- private static final int VERSION = 83;
- private static String[] pages = {"1-10", "11-20", "21-30", "31-40", "41-50", "51-60", "61-70", "71-80", "81-90", "91-100"};
- private static String[] additionalPages88 = {"101-150", "151-200"};
- private static String[] additionalPagesBB = {"101-120,", "121-140", "141-160", "161-180", "181-200"};
-
- public static void main(String[] args) {
- System.setProperty("wzpath", "wz");
-
- //DataTool.setHardcodedMobNames();
- //parsePage("http://bbb.hidden-street.net/monster/nibelung-3");
-
- crawlProgram();
-
- dumpQuery();
- dumpErrors();
- }
-
- private static void crawlProgram() {
- //parseMonsterSection(TEST_STRING);
- for (String s : pages) {
- crawlPage("http://bbb.hidden-street.net/monster/" + s);
- }
- if (VERSION > 92) { // big bang
- for (String s : additionalPagesBB) {
- crawlPage("http://bbb.hidden-street.net/monster/" + s);
- }
- crawlPage("http://bbb.hidden-street.net/monster/101-120?page=1"); //page 1's bugged
- } else {
- for (String s : additionalPages88) {
- crawlPage("http://bbb.hidden-street.net/monster/" + s);
- }
- }
- }
-
- private static void crawlPage(String url) { //recursive method
- try {
- URL page = new URL(url);
- InputStream is = page.openStream();
- Scanner s = new Scanner(is);
- String temp_data = "";
- while (s.hasNext()) {
- temp_data += s.nextLine() + "\n";
- }
- s.close();
- is.close();
- while (temp_data.contains("class=\"monster\">")) {
- String monster_section = getStringBetween(temp_data, "class=\"monster\">", "");
- parseMonsterSection(monster_section);
- temp_data = trimUntil(temp_data, "");
- }
- if (temp_data.contains("Go to next page")) {
- String next_url_segment = getStringBetween(temp_data, "