diff --git a/build/built-jar.properties b/build/built-jar.properties
index 636854a414..17f9a3d683 100644
--- a/build/built-jar.properties
+++ b/build/built-jar.properties
@@ -1,4 +1,4 @@
-#Wed, 04 Oct 2017 01:18:34 -0300
+#Thu, 05 Oct 2017 16:16:32 -0300
C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2=
diff --git a/build/classes/client/MapleCharacter$1.class b/build/classes/client/MapleCharacter$1.class
index 87c0423bca..6d2d50d386 100644
Binary files a/build/classes/client/MapleCharacter$1.class and b/build/classes/client/MapleCharacter$1.class differ
diff --git a/build/classes/client/MapleCharacter$10.class b/build/classes/client/MapleCharacter$10.class
index 408825533f..62301a7d17 100644
Binary files a/build/classes/client/MapleCharacter$10.class and b/build/classes/client/MapleCharacter$10.class differ
diff --git a/build/classes/client/MapleCharacter$11.class b/build/classes/client/MapleCharacter$11.class
index 3e208d85ff..95ffca82b9 100644
Binary files a/build/classes/client/MapleCharacter$11.class and b/build/classes/client/MapleCharacter$11.class differ
diff --git a/build/classes/client/MapleCharacter$12.class b/build/classes/client/MapleCharacter$12.class
index 8ff337fdfb..a9c062c5b6 100644
Binary files a/build/classes/client/MapleCharacter$12.class and b/build/classes/client/MapleCharacter$12.class differ
diff --git a/build/classes/client/MapleCharacter$13.class b/build/classes/client/MapleCharacter$13.class
index 9ab4c366a7..cdba36955f 100644
Binary files a/build/classes/client/MapleCharacter$13.class and b/build/classes/client/MapleCharacter$13.class differ
diff --git a/build/classes/client/MapleCharacter$14.class b/build/classes/client/MapleCharacter$14.class
index 80812804d5..cd29d89e56 100644
Binary files a/build/classes/client/MapleCharacter$14.class and b/build/classes/client/MapleCharacter$14.class differ
diff --git a/build/classes/client/MapleCharacter$15.class b/build/classes/client/MapleCharacter$15.class
index e324653e57..11227a4e18 100644
Binary files a/build/classes/client/MapleCharacter$15.class and b/build/classes/client/MapleCharacter$15.class differ
diff --git a/build/classes/client/MapleCharacter$16.class b/build/classes/client/MapleCharacter$16.class
index 5b7fe85aeb..b7ce2945dc 100644
Binary files a/build/classes/client/MapleCharacter$16.class and b/build/classes/client/MapleCharacter$16.class differ
diff --git a/build/classes/client/MapleCharacter$17.class b/build/classes/client/MapleCharacter$17.class
index dbf2eaa39d..ed074e2d34 100644
Binary files a/build/classes/client/MapleCharacter$17.class and b/build/classes/client/MapleCharacter$17.class differ
diff --git a/build/classes/client/MapleCharacter$18.class b/build/classes/client/MapleCharacter$18.class
index 462a28dfb5..35d4ee8f92 100644
Binary files a/build/classes/client/MapleCharacter$18.class and b/build/classes/client/MapleCharacter$18.class differ
diff --git a/build/classes/client/MapleCharacter$19.class b/build/classes/client/MapleCharacter$19.class
index 7ac743104c..a9020a676e 100644
Binary files a/build/classes/client/MapleCharacter$19.class and b/build/classes/client/MapleCharacter$19.class differ
diff --git a/build/classes/client/MapleCharacter$2.class b/build/classes/client/MapleCharacter$2.class
index 4ca6c42c00..7aa1c9676b 100644
Binary files a/build/classes/client/MapleCharacter$2.class and b/build/classes/client/MapleCharacter$2.class differ
diff --git a/build/classes/client/MapleCharacter$3.class b/build/classes/client/MapleCharacter$3.class
index db78c174f2..ad1df755af 100644
Binary files a/build/classes/client/MapleCharacter$3.class and b/build/classes/client/MapleCharacter$3.class differ
diff --git a/build/classes/client/MapleCharacter$4.class b/build/classes/client/MapleCharacter$4.class
index 0e98bcac15..fbc8edcf95 100644
Binary files a/build/classes/client/MapleCharacter$4.class and b/build/classes/client/MapleCharacter$4.class differ
diff --git a/build/classes/client/MapleCharacter$5.class b/build/classes/client/MapleCharacter$5.class
index 543b9cae3a..fef58f5292 100644
Binary files a/build/classes/client/MapleCharacter$5.class and b/build/classes/client/MapleCharacter$5.class differ
diff --git a/build/classes/client/MapleCharacter$6.class b/build/classes/client/MapleCharacter$6.class
index d43741149b..eaefe20185 100644
Binary files a/build/classes/client/MapleCharacter$6.class and b/build/classes/client/MapleCharacter$6.class differ
diff --git a/build/classes/client/MapleCharacter$7.class b/build/classes/client/MapleCharacter$7.class
index 199dab081e..99a7d5cbcd 100644
Binary files a/build/classes/client/MapleCharacter$7.class and b/build/classes/client/MapleCharacter$7.class differ
diff --git a/build/classes/client/MapleCharacter$8.class b/build/classes/client/MapleCharacter$8.class
index f8aafc7cc9..84b56a253f 100644
Binary files a/build/classes/client/MapleCharacter$8.class and b/build/classes/client/MapleCharacter$8.class differ
diff --git a/build/classes/client/MapleCharacter$9.class b/build/classes/client/MapleCharacter$9.class
index d99b8e9a87..9553405dd4 100644
Binary files a/build/classes/client/MapleCharacter$9.class and b/build/classes/client/MapleCharacter$9.class differ
diff --git a/build/classes/client/MapleCharacter$FameStatus.class b/build/classes/client/MapleCharacter$FameStatus.class
index e259067265..ca6634f047 100644
Binary files a/build/classes/client/MapleCharacter$FameStatus.class and b/build/classes/client/MapleCharacter$FameStatus.class differ
diff --git a/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class b/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class
index fc0b0782a7..6f70a435af 100644
Binary files a/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class and b/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class differ
diff --git a/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class b/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class
index 2104ebccee..6a2aed8e74 100644
Binary files a/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class and b/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class differ
diff --git a/build/classes/client/MapleCharacter$SkillEntry.class b/build/classes/client/MapleCharacter$SkillEntry.class
index 4778446029..8094589c60 100644
Binary files a/build/classes/client/MapleCharacter$SkillEntry.class and b/build/classes/client/MapleCharacter$SkillEntry.class differ
diff --git a/build/classes/client/MapleCharacter.class b/build/classes/client/MapleCharacter.class
index a7ec50c456..97d39a1af7 100644
Binary files a/build/classes/client/MapleCharacter.class and b/build/classes/client/MapleCharacter.class differ
diff --git a/build/classes/constants/ServerConstants.class b/build/classes/constants/ServerConstants.class
index 6b52815ae2..ca7ea4daa4 100644
Binary files a/build/classes/constants/ServerConstants.class and b/build/classes/constants/ServerConstants.class differ
diff --git a/build/classes/scripting/npc/NPCConversationManager.class b/build/classes/scripting/npc/NPCConversationManager.class
index 890f98269e..d48a1597ae 100644
Binary files a/build/classes/scripting/npc/NPCConversationManager.class and b/build/classes/scripting/npc/NPCConversationManager.class differ
diff --git a/build/classes/server/MapleItemInformationProvider.class b/build/classes/server/MapleItemInformationProvider.class
index 5fe4e6fd01..1b4c4f3ff0 100644
Binary files a/build/classes/server/MapleItemInformationProvider.class and b/build/classes/server/MapleItemInformationProvider.class differ
diff --git a/build/classes/server/life/MapleMonster$1.class b/build/classes/server/life/MapleMonster$1.class
index 0b90120e43..bf9b74d22d 100644
Binary files a/build/classes/server/life/MapleMonster$1.class and b/build/classes/server/life/MapleMonster$1.class differ
diff --git a/build/classes/server/life/MapleMonster$2.class b/build/classes/server/life/MapleMonster$2.class
index 947aba94f0..8be88f2d3f 100644
Binary files a/build/classes/server/life/MapleMonster$2.class and b/build/classes/server/life/MapleMonster$2.class differ
diff --git a/build/classes/server/life/MapleMonster$3.class b/build/classes/server/life/MapleMonster$3.class
index da2f603b71..2b8283dacc 100644
Binary files a/build/classes/server/life/MapleMonster$3.class and b/build/classes/server/life/MapleMonster$3.class differ
diff --git a/build/classes/server/life/MapleMonster$4.class b/build/classes/server/life/MapleMonster$4.class
index 2e0760ef23..f8ab42e84a 100644
Binary files a/build/classes/server/life/MapleMonster$4.class and b/build/classes/server/life/MapleMonster$4.class differ
diff --git a/build/classes/server/life/MapleMonster$5.class b/build/classes/server/life/MapleMonster$5.class
index 58f188cec9..33c13f8bd9 100644
Binary files a/build/classes/server/life/MapleMonster$5.class and b/build/classes/server/life/MapleMonster$5.class differ
diff --git a/build/classes/server/life/MapleMonster$6.class b/build/classes/server/life/MapleMonster$6.class
index 295643d0d0..e688f4b68c 100644
Binary files a/build/classes/server/life/MapleMonster$6.class and b/build/classes/server/life/MapleMonster$6.class differ
diff --git a/build/classes/server/life/MapleMonster$DamageTask.class b/build/classes/server/life/MapleMonster$DamageTask.class
index f7fd11c750..873b54e0ba 100644
Binary files a/build/classes/server/life/MapleMonster$DamageTask.class and b/build/classes/server/life/MapleMonster$DamageTask.class differ
diff --git a/build/classes/server/life/MapleMonster.class b/build/classes/server/life/MapleMonster.class
index 6a7f1efef2..10067c547f 100644
Binary files a/build/classes/server/life/MapleMonster.class and b/build/classes/server/life/MapleMonster.class differ
diff --git a/dist/MapleSolaxia.jar b/dist/MapleSolaxia.jar
index c29d4b19e2..c00fe5144d 100644
Binary files a/dist/MapleSolaxia.jar and b/dist/MapleSolaxia.jar differ
diff --git a/docs/mychanges_ptbr.txt b/docs/mychanges_ptbr.txt
index 0a52870436..d6934ef676 100644
--- a/docs/mychanges_ptbr.txt
+++ b/docs/mychanges_ptbr.txt
@@ -565,4 +565,7 @@ Adicionado prote
Corrigido bug em sistema de distribuição de EXP para party.
Corrigido bug de overflow em distribuição de EXP.
Corrigido bug com scrolls não usando slots quando resultam em sucesso.
-Refatorado sistema de schedules para disease expiretimes.
\ No newline at end of file
+Refatorado sistema de schedules para disease expiretimes.
+
+05 Outubro 2017,
+Alterado level mínimo para receber exp de um mob de base level - 5 para - 20 (cliente destaca infos do mob em vermelho se o jogador está abaixo desta faixa).
\ No newline at end of file
diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml
index 1037c26341..6b07bfcf3f 100644
--- a/nbproject/private/private.xml
+++ b/nbproject/private/private.xml
@@ -3,15 +3,9 @@
- file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/SendOpcode.java
- file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/TakeDamageHandler.java
- file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/scripting/AbstractPlayerInteraction.java
+ file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/scripting/npc/NPCConversationManager.java
file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/constants/ServerConstants.java
- file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/tools/data/output/GenericLittleEndianWriter.java
- file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleCharacter.java
- file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/life/MobSkill.java
- file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/MapleItemInformationProvider.java
- file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/tools/MaplePacketCreator.java
+ file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/life/MapleMonster.java
diff --git a/scripts/event/Cygnus_Magic_Library.js b/scripts/event/Cygnus_Magic_Library.js
new file mode 100644
index 0000000000..a5b237fe7a
--- /dev/null
+++ b/scripts/event/Cygnus_Magic_Library.js
@@ -0,0 +1,112 @@
+var minPlayers = 1;
+var timeLimit = 10; //10 minutes
+var eventTimer = 1000 * 60 * timeLimit;
+var entryMap = 101000000;
+var exitMap = 101000000;
+var eventMap = 910110000;
+
+function init(){}
+
+function setup(difficulty, lobbyId){
+ var eim = em.newInstance("Cygnus_Magic_Library_" +lobbyId);
+ eim.getInstanceMap(eventMap).resetFully();
+ eim.getInstanceMap(eventMap).allowSummonState(false);
+ respawn(eim);
+ eim.startEventTimer(eventTimer);
+ return eim;
+}
+
+function afterSetup(eim){}
+
+function respawn(eim){
+ var map = eim.getMapInstance(entryMap);
+ map.allowSummonState(true);
+ map.instanceMapRespawn();
+ eim.schedule("respawn", 10000);
+}
+
+function playerEntry(eim, player){
+ var magicLibrary = eim.getMapInstance(eventMap);
+ player.changeMap(magicLibrary, magicLibrary.getPortal(1));
+}
+
+function scheduledTimeout(eim){
+ var party = eim.getPlayers();
+
+ for(var i = 0; i < party.size(); i++)
+ playerExit(eim, party.get(i));
+
+ eim.dispose();
+}
+
+function playerRevive(eim, player){
+ player.setHp(50);
+ player.setStance(0);
+ eim.unregisterPlayer(player);
+ player.changeMap(entryMap);
+ return false;
+}
+
+function playerDead(eim, player){}
+
+function playerDisconnected(eim, player){
+ var party = eim.getPlayers();
+
+ for(var i = 0; i < party.size(); i++){
+ if(party.get(i).equals(player))
+ removePlayer(eim, player);
+ else
+ playerExit(eim, party.get(i));
+ }
+ eim.dispose();
+}
+
+function monsterValue(eim, mobId){
+ return -1;
+}
+
+function leftParty(eim, player){
+ var party = eim.getPlayers();
+
+ if(party.size() < minPlayers){
+ for(var i = 0; i < party.size(); i++){
+ playerExit(eim, party.get(i));
+ }
+ eim.dispose();
+ }
+ else{
+ playerExit(eim, player);
+ }
+}
+
+function disbandParty(eim){}
+
+function playerUnregistered(eim, player){}
+
+function playerExit(eim, player){
+ eim.unregisterPlayer(player);
+ player.changeMap(entryMap, 2);
+}
+
+function moveMap(eim, player){
+ if(player.getMap().getId() == exitMap){
+ removePlayer(eim, player);
+ eim.dispose();
+ }
+}
+
+function removePlayer(eim, player){
+ eim.unregisterPlayer(player);
+ player.getMap().removePlayer(player);
+ player.setMap(entryMap);
+}
+
+function cancelSchedule(){}
+
+function dispose(){}
+
+function clearPQ(eim){}
+
+function monsterKilled(mob, eim){}
+
+function allMonstersDead(eim){}
\ No newline at end of file
diff --git a/scripts/event/Puppeteer.js b/scripts/event/Puppeteer.js
new file mode 100644
index 0000000000..a2159a9d3f
--- /dev/null
+++ b/scripts/event/Puppeteer.js
@@ -0,0 +1,114 @@
+var minPlayers = 1;
+var timeLimit = 10; //10 minutes
+var eventTimer = 1000 * 60 * timeLimit;
+var entryMap = 910510001;
+var exitMap = 105070300;
+var eventMap = 910510000;
+
+function init(){}
+
+function setup(difficulty, lobbyId){
+ var eim = em.newInstance("Puppeteer_" +lobbyId);
+ eim.getInstanceMap(eventMap).resetFully();
+ eim.getInstanceMap(eventMap).allowSummonState(false);
+ respawn(eim);
+ eim.startEventTimer(eventTimer);
+ return eim;
+}
+
+function afterSetup(eim){}
+
+function respawn(eim){
+ var map = eim.getMapInstance(entryMap);
+ map.allowSummonState(true);
+ map.instanceMapRespawn();
+ eim.schedule("respawn", 10000);
+}
+
+function playerEntry(eim, player){
+ var cave = eim.getMapInstance(eventMap);
+ player.changeMap(cave);
+}
+
+function scheduledTimeout(eim){
+ var party = eim.getPlayers();
+
+ for(var i = 0; i < party.size(); i++)
+ playerExit(eim, party.get(i));
+
+ eim.dispose();
+}
+
+function playerRevive(eim, player){
+ player.setHp(50);
+ player.setStance(0);
+ eim.unregisterPlayer(player);
+ player.changeMap(entryMap);
+ return false;
+}
+
+function playerDead(eim, player){}
+
+function playerDisconnected(eim, player){
+ var party = eim.getPlayers();
+
+ for(var i = 0; i < party.size(); i++){
+ if(party.get(i).equals(player))
+ removePlayer(eim, player);
+ else
+ playerExit(eim, party.get(i));
+ }
+ eim.dispose();
+}
+
+function monsterValue(eim, mobId){
+ return -1;
+}
+
+function leftParty(eim, player){
+ var party = eim.getPlayers();
+
+ if(party.size() < minPlayers){
+ for(var i = 0; i < party.size(); i++){
+ playerExit(eim, party.get(i));
+ }
+ eim.dispose();
+ }
+ else{
+ playerExit(eim, player);
+ }
+}
+
+function disbandParty(eim){}
+
+function playerUnregistered(eim, player){}
+
+function playerExit(eim, player){
+ eim.unregisterPlayer(player);
+ player.changeMap(entryMap, 2);
+}
+
+function moveMap(eim, player){
+ if(player.getMap().getId() == exitMap || player.getMap().getId() == entryMap){
+ removePlayer(eim, player);
+ eim.stopEventTimer();
+ eim.setEventCleared();
+ eim.dispose();
+ }
+}
+
+function removePlayer(eim, player){
+ eim.unregisterPlayer(player);
+ player.getMap().removePlayer(player);
+ player.setMap(entryMap);
+}
+
+function cancelSchedule(){}
+
+function dispose(){}
+
+function clearPQ(eim){}
+
+function monsterKilled(mob, eim){}
+
+function allMonstersDead(eim){}
\ No newline at end of file
diff --git a/scripts/map/onUserEnter/910510000.js b/scripts/map/onUserEnter/910510000.js
new file mode 100644
index 0000000000..6ab8b0e1c3
--- /dev/null
+++ b/scripts/map/onUserEnter/910510000.js
@@ -0,0 +1,10 @@
+importPackage(Packages.server.life);
+
+function start(ms){
+ var mobId = 9300285;
+ var player = ms.getPlayer();
+ var map = player.getMap();
+
+ if(ms.isQuestStarted(20730) && ms.getQuestProgress(20730, 9300285) == 0)
+ map.spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(mobId), new java.awt.Point(680, 258));
+}
\ No newline at end of file
diff --git a/scripts/npc/1032109.js b/scripts/npc/1032109.js
new file mode 100644
index 0000000000..80c74e25b2
--- /dev/null
+++ b/scripts/npc/1032109.js
@@ -0,0 +1,47 @@
+/*
+ NPC: Corner of the Magic Library
+ MAP: Hidden Street - Magic Library (910110000)
+ QUEST: Maybe it's Grendel! (20718)
+*/
+importPackage(Packages.server.life);
+
+var status;
+var mobId = 2220100; //Blue Mushroom
+
+function start(){
+ status = -1;
+ action(1, 0, 0);
+}
+
+function action(mode, type, selection){
+ if(mode == -1 || (mode == 0 && status == 0)){
+ cm.dispose();
+ return;
+ }
+ else if(mode == 0)
+ status--;
+ else
+ status++;
+
+
+ if(status == 0){
+ cm.sendOk("A mysterious black figure appeared and summoned a lot of angry monsters!");
+ }
+ else if(status == 1){
+ var player = cm.getPlayer();
+ var map = player.getMap();
+
+ for(var i = 0; i < 10; i++)
+ map.spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(mobId), new java.awt.Point(117, 183));
+ for(var i = 0; i < 10; i++)
+ map.spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(mobId), new java.awt.Point(4, 183));
+ for(var i = 0; i < 10; i++)
+ map.spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(mobId), new java.awt.Point(-109, 183));
+
+ cm.completeQuest(20718, 1103003);
+ cm.gainExp(4000 * cm.getPlayer().getExpRate());
+
+ cm.dispose();
+ return;
+ }
+}
\ No newline at end of file
diff --git a/scripts/npc/1032110.js b/scripts/npc/1032110.js
new file mode 100644
index 0000000000..57043c7f4f
--- /dev/null
+++ b/scripts/npc/1032110.js
@@ -0,0 +1,32 @@
+/*
+ NPC: Corner of the Magic Library
+ MAP: Hidden Street - Magic Library (910110000)
+ QUEST: Maybe it's Grendel! (20718)
+*/
+
+var status;
+
+function start(){
+ status = -1;
+ action(1, 0, 0);
+}
+
+function action(mode, type, selection){
+ if(mode == -1 || (mode == 0 && status == 0)){
+ cm.dispose();
+ return;
+ }
+ else if(mode == 0)
+ status--;
+ else
+ status++;
+
+
+ if(status == 0){
+ cm.sendOk("Nothing remarkable here.");
+ }
+ else if(status == 1){
+ cm.dispose();
+ return;
+ }
+}
\ No newline at end of file
diff --git a/scripts/npc/1032111.js b/scripts/npc/1032111.js
new file mode 100644
index 0000000000..f7c419bfba
--- /dev/null
+++ b/scripts/npc/1032111.js
@@ -0,0 +1,45 @@
+/*
+ NPC: Small Tree Stump
+ MAP: Victoria Road - Top of the Tree That Grew (101010103)
+ QUEST: Maybe it's Arwen! (20716)
+*/
+
+var status;
+
+function start(){
+ status = -1;
+ action(1, 0, 0);
+}
+
+function action(mode, type, selection){
+ if(mode == -1 || (mode == 0 && status == 0)){
+ cm.dispose();
+ return;
+ }
+ else if(mode == 0)
+ status--;
+ else
+ status++;
+
+
+ if(status == 0){
+ if(cm.isQuestStarted(20716)){
+ if(!cm.hasItem(4032142)){
+ if(cm.canHold(4032142)){
+ cm.gainItem(4032142, 1);
+ cm.sendOk("You bottled up some of the clear tree sap. #i4032142#");
+ }
+ else
+ cm.sendOk("Make sure you have a free spot in your ETC inventory.");
+ }
+ else
+ cm.sendOk("A never ending flow of sap is coming from this small tree stump.");
+ }
+ else
+ cm.sendOk("A never ending flow of sap is coming from this small tree stump.");
+ }
+ else if(status == 1){
+ cm.dispose();
+ return;
+ }
+}
\ No newline at end of file
diff --git a/scripts/npc/1052111.js b/scripts/npc/1052111.js
index 6183aa9d0e..2d318bf28d 100644
--- a/scripts/npc/1052111.js
+++ b/scripts/npc/1052111.js
@@ -25,26 +25,22 @@ function action(mode, type, selection){
else
status++;
-
- if(cm.isQuestStarted(20710)){
- if(!cm.hasItem(4032136)){
- cm.sendNext("You have found a #b#t4032136##k in the trash can! #i4032136#");
-
- if(cm.canHold(4032136)){
- cm.gainItem(4032136, 1);
+ if(status == 0) {
+ if(cm.isQuestStarted(20710)) {
+ if(!cm.hasItem(4032136)) {
+ if(cm.canHold(4032136)) {
+ cm.gainItem(4032136, 1);
+ cm.sendNext("You have found a #b#t4032136##k in the trash can! #i4032136#");
+ } else {
+ cm.sendOk("#i4032136# Not enough space in your ETC inventory.");
+ }
+ } else {
+ cm.sendOk("Just a trash can sitting there.");
}
- else{
- cm.sendOk("#i4032136# Not enough space in your ETC inventory.");
- }
- cm.dispose();
- }
- else{
+ } else {
cm.sendOk("Just a trash can sitting there.");
- cm.dispose();
}
- }
- else{
- cm.sendOk("Just a trash can sitting there.");
+ } else if(status == 1){
cm.dispose();
}
}
diff --git a/scripts/npc/1104000.js b/scripts/npc/1104000.js
new file mode 100644
index 0000000000..6741c377ae
--- /dev/null
+++ b/scripts/npc/1104000.js
@@ -0,0 +1,30 @@
+var status;
+
+function start(){
+ status = -1;
+ action(1, 0, 0);
+}
+
+function action(mode, type, selection){
+ if(mode == -1 || (mode == 0 && status == 0)){
+ cm.dispose();
+ return;
+ }
+ else if(mode == 0)
+ status--;
+ else
+ status++;
+
+
+
+ if(status == 0){
+ cm.sendNext("What the... you don't belong here!");
+ }
+ else if(status == 1){
+ var puppet = cm.getEventManager("Puppeteer");
+ puppet.setProperty("player", cm.getPlayer().getName());
+ puppet.startInstance(cm.getPlayer());
+ cm.dispose();
+ return;
+ }
+}
\ No newline at end of file
diff --git a/scripts/npc/MaybeItsGrendel_end.js b/scripts/npc/MaybeItsGrendel_end.js
new file mode 100644
index 0000000000..8084fcdc3c
--- /dev/null
+++ b/scripts/npc/MaybeItsGrendel_end.js
@@ -0,0 +1,28 @@
+var status;
+
+function start(){
+ status = -1;
+ action(1, 0, 0);
+}
+
+function action(mode, type, selection){
+ if(mode == -1 || (mode == 0 && status == 0)){
+ cm.dispose();
+ return;
+ }
+ else if(mode == 0)
+ status--;
+ else
+ status++;
+
+
+ if(status == 0){
+ cm.sendNext("...a black shadowy figure came out and attacked you? How can this take place at #b#p1032001##k's house? This sounds like one big conspiracy here...");
+ }
+ else if(status == 1){
+ cm.sendNextPrev("I'll have to sort this all out in my mind. Talk to me in a bit.");
+ }
+ else if(status == 2){
+ cm.dispose();
+ }
+}
\ No newline at end of file
diff --git a/scripts/npc/PupeteerPassword.js b/scripts/npc/PupeteerPassword.js
new file mode 100644
index 0000000000..6c00cc35d3
--- /dev/null
+++ b/scripts/npc/PupeteerPassword.js
@@ -0,0 +1,40 @@
+var status;
+
+function start(){
+ status = -1;
+ action(1, 0, 0);
+}
+
+function action(mode, type, selection){
+ if(mode == -1 || (mode == 0 && status == 0)){
+ cm.dispose();
+ return;
+ }
+ else if(mode == 0)
+ status--;
+ else
+ status++;
+
+
+
+ if(status == 0){
+ cm.sendGetText("A suspicious voice pierces through the silence. #bPassword#k!");
+ }
+ else if(status == 1){
+ if(cm.getText() == "Francis is a genius Puppeteer!"){
+
+ if(cm.isQuestCompleted(20730) || !cm.isQuestStarted(20730) || (cm.isQuestStarted(20730) && cm.getQuestProgress(20730, 9300285) > 0))
+ cm.warp(910510000, 1);
+ else if(cm.isQuestStarted(20730))
+ cm.warp(910510001, 1);
+
+ cm.dispose();
+ }
+ else{
+ cm.sendOk("#rWrong!");
+ }
+ }
+ else if(status == 2){
+ cm.dispose();
+ }
+}
\ No newline at end of file
diff --git a/scripts/portal/enterDollcave.js b/scripts/portal/enterDollcave.js
new file mode 100644
index 0000000000..a88ac1b06c
--- /dev/null
+++ b/scripts/portal/enterDollcave.js
@@ -0,0 +1,4 @@
+function enter(pi) {
+ pi.openNpc(1063011, "PupeteerPassword");
+ return false;
+}
\ No newline at end of file
diff --git a/scripts/portal/enterMagiclibrar.js b/scripts/portal/enterMagiclibrar.js
index c4307cb2f1..d2872afa17 100644
--- a/scripts/portal/enterMagiclibrar.js
+++ b/scripts/portal/enterMagiclibrar.js
@@ -3,24 +3,31 @@
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 .
+
+ Edited by: Kevin
*/
function enter(pi) {
- pi.playPortalSound();
- pi.warp(101000003, 8);
- return true;
-}
+ if(pi.isQuestStarted(20718)){
+ pi.playPortalSound();
+ var cml = pi.getEventManager("Cygnus_Magic_Library");
+ cml.setProperty("player", pi.getPlayer().getName());
+ cml.startInstance(pi.getPlayer());
+ }
+ else{
+ pi.playPortalSound();
+ pi.warp(101000003, 8);
+ }
+ return true;
+}
\ No newline at end of file
diff --git a/scripts/portal/exit_puppeteer.js b/scripts/portal/exit_puppeteer.js
new file mode 100644
index 0000000000..0b85698087
--- /dev/null
+++ b/scripts/portal/exit_puppeteer.js
@@ -0,0 +1,17 @@
+function enter(pi) {
+ if(pi.getMap().countMonster(9300285) > 0){
+ pi.getPlayer().message("Defeat the Puppeteer before leaving.");
+ return false;
+ }
+ else{
+ var eim = pi.getEventInstance();
+ if(eim != null){
+ eim.stopEventTimer();
+ eim.dispose();
+ }
+
+ pi.playPortalSound();
+ pi.warp(105070300, 3);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/scripts/portal/outMagiclib.js b/scripts/portal/outMagiclib.js
new file mode 100644
index 0000000000..dfee023721
--- /dev/null
+++ b/scripts/portal/outMagiclib.js
@@ -0,0 +1,19 @@
+function enter(pi) {
+ if(pi.getMap().countMonster(2220100) > 0){
+ pi.getPlayer().message("Cannot leave until all Blue Mushrooms have been defeated.");
+ return false;
+ }
+ else{
+ var eim = pi.getEventInstance();
+ eim.stopEventTimer();
+ eim.dispose();
+
+ pi.playPortalSound();
+ pi.warp(101000000, 26);
+
+ if(pi.isQuestCompleted(20718))
+ pi.openNpc(1103003, "MaybeItsGrendel_end");
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/scripts/quest/20720.js b/scripts/quest/20720.js
new file mode 100644
index 0000000000..bbcacca9ec
--- /dev/null
+++ b/scripts/quest/20720.js
@@ -0,0 +1,28 @@
+/*
+ QUEST: Before the Mission in Perion Begins
+ NPC: Neinheart
+*/
+
+var status = -1;
+
+function start(mode, type, selection){
+ if(mode == -1 || (mode == 0 && status == 0)){
+ qm.dispose();
+ return;
+ }
+ else if(mode == 0)
+ status--;
+ else
+ status++;
+
+
+ else if(status == 0){
+ qm.sendAcceptDecline("How's the leveling up so far? By this time, you might be able to participate in the Party Quest at #m103000000#. Leveling up is important, yes, but we need you now to take on a mission as a Cygnus Knight. We just received a new information that may help us.");
+ }
+ else if(status == 1){
+ qm.forceStartQuest();
+ qm.dispose();
+ }
+}
+
+function end(mode, type, selection){}
\ No newline at end of file
diff --git a/sql/db_database.sql b/sql/db_database.sql
index e089143276..1872af372b 100644
--- a/sql/db_database.sql
+++ b/sql/db_database.sql
@@ -21080,7 +21080,9 @@ INSERT INTO `shops` (`shopid`, `npcid`) VALUES
INSERT INTO `shops` (`shopid`, `npcid`) VALUES
( 57, 2002001 ),
(1052116, 1052116),
-(1301000, 1301000);
+(1301000, 1301000),
+(1200001, 1200001),
+(1200002, 1200002);
INSERT INTO `shopitems` ( `shopid`, `itemid`, `price`, `position`) VALUES
( 57, 3990000, 500, 1 ),
diff --git a/sql/db_drops.sql b/sql/db_drops.sql
index f021bd77f7..60adc497c2 100644
--- a/sql/db_drops.sql
+++ b/sql/db_drops.sql
@@ -19780,7 +19780,16 @@ USE `maplesolaxia`;
(1110100, 4001369, 1, 1, 28259, 10000),
(1210101, 4001370, 1, 1, 28260, 10000),
(1110101, 4001371, 1, 1, 28261, 10000),
-(3300003, 4001317, 1, 1, 2326, 20000);
+(3300003, 4001317, 1, 1, 2326, 20000),
+(1210102, 4001364, 1, 1, 28192, 10000),
+(1120100, 4001365, 1, 1, 28192, 10000),
+(1210103, 4032137, 1, 1, 20711, 40000),
+(1210103, 4032139, 1, 1, 20713, 40000),
+(1210101, 4001357, 1, 1, 28244, 70000),
+(1120100, 4001361, 1, 1, 28250, 70000),
+(2230110, 4032146, 1, 1, 20722, 40000),
+(2230111, 4032147, 1, 1, 20723, 40000);
+
# (dropperid, itemid, minqty, maxqty, questid, chance)
# delete item drops from other mobs named Freezer
@@ -19910,9 +19919,9 @@ USE `maplesolaxia`;
UPDATE drop_data SET questid=6191 WHERE itemid=4001107;
UPDATE drop_data SET questid=28344 WHERE itemid=4032475;
- UPDATE drop_data SET questid=7777 WHERE itemid=4001358; #id 7777 for ALL "quest items" with no v83 quest.
- UPDATE drop_data SET questid=7777 WHERE itemid=4001359;
- UPDATE drop_data SET questid=7777 WHERE itemid=4001342;
+ UPDATE drop_data SET questid=28248 WHERE itemid=4001358;
+ UPDATE drop_data SET questid=28248 WHERE itemid=4001359;
+ UPDATE drop_data SET questid=7777 WHERE itemid=4001342; #id 7777 for ALL "quest items" with no v83 quest.
UPDATE drop_data SET questid=7777 WHERE itemid=4031906;
UPDATE drop_data SET chance=0 WHERE itemid=2050099;
UPDATE drop_data SET chance=40000 WHERE itemid=4031991;
@@ -21091,7 +21100,8 @@ USE `maplesolaxia`;
(9102001, 2020000, 2, -1),
(9102001, 2020001, 2, -1),
(9102001, 2020002, 2, -1),
- (2002018, 4161014, 1, 3099);
+ (2002018, 4161014, 1, 3099),
+ (1012000, 4032143, 6, 20717);
# adding wish tickets on APQ boxes
INSERT INTO `reactordrops` (`reactorid`, `itemid`, `chance`, `questid`) VALUES
diff --git a/sql/db_shopupdate.sql b/sql/db_shopupdate.sql
index 06f45652bb..18eecf7210 100644
--- a/sql/db_shopupdate.sql
+++ b/sql/db_shopupdate.sql
@@ -263,27 +263,27 @@ INSERT INTO `shopitems` ( `shopid`, `itemid`, `price`, `pitch`, `position`) VALU
(1200001, 1322005, 50, 0, 35),
(1200001, 1312004, 50, 0, 36),
(1200001, 1302000, 50, 0, 37),
- (1203590, 2330000, 600, 0, 104),
- (1203590, 2070000, 500, 0, 108),
- (1203590, 2061000, 1, 0, 120),
- (1203590, 2060000, 1, 0, 124),
- (1203590, 2030000, 400, 0, 132),
- (1203590, 2020028, 3000, 0, 136),
- (1203590, 2010004, 310, 0, 140),
- (1203590, 2010003, 100, 0, 144),
- (1203590, 2010001, 106, 0, 148),
- (1203590, 2010002, 50, 0, 152),
- (1203590, 2010000, 30, 0, 156),
- (1203590, 2002005, 500, 0, 160),
- (1203590, 2002004, 500, 0, 164),
- (1203590, 2002002, 500, 0, 168),
- (1203590, 2002001, 400, 0, 172),
- (1203590, 2002000, 500, 0, 176),
- (1203590, 2000006, 620, 0, 180),
- (1203590, 2000003, 200, 0, 184),
- (1203590, 2000002, 320, 0, 188),
- (1203590, 2000001, 160, 0, 192),
- (1203590, 2000000, 50, 0, 196),
+ (1200002, 2330000, 600, 0, 104),
+ (1200002, 2070000, 500, 0, 108),
+ (1200002, 2061000, 1, 0, 120),
+ (1200002, 2060000, 1, 0, 124),
+ (1200002, 2030000, 400, 0, 132),
+ (1200002, 2020028, 3000, 0, 136),
+ (1200002, 2010004, 310, 0, 140),
+ (1200002, 2010003, 100, 0, 144),
+ (1200002, 2010001, 106, 0, 148),
+ (1200002, 2010002, 50, 0, 152),
+ (1200002, 2010000, 30, 0, 156),
+ (1200002, 2002005, 500, 0, 160),
+ (1200002, 2002004, 500, 0, 164),
+ (1200002, 2002002, 500, 0, 168),
+ (1200002, 2002001, 400, 0, 172),
+ (1200002, 2002000, 500, 0, 176),
+ (1200002, 2000006, 620, 0, 180),
+ (1200002, 2000003, 200, 0, 184),
+ (1200002, 2000002, 320, 0, 188),
+ (1200002, 2000001, 160, 0, 192),
+ (1200002, 2000000, 50, 0, 196),
(1301000, 2330000, 600, 0, 1),
(1301000, 2070000, 500, 0, 2),
(1301000, 2061000, 1, 0, 3),
diff --git a/src/client/MapleCharacter.java b/src/client/MapleCharacter.java
index 58a332a990..264727ec8d 100644
--- a/src/client/MapleCharacter.java
+++ b/src/client/MapleCharacter.java
@@ -297,6 +297,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
private short extraRecInterval;
private int targetHpBarHash = 0;
private long targetHpBarTime = 0;
+ private long nextUnderlevelTime = 0;
private int banishMap = -1;
private int banishSp = -1;
private long banishTime = 0;
@@ -7074,6 +7075,20 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
}
+ public void showUnderleveledInfo(MapleMonster mob) {
+ chrLock.lock();
+ try {
+ long curTime = System.currentTimeMillis();
+ if(nextUnderlevelTime < curTime) {
+ nextUnderlevelTime = curTime + (60 * 1000); // show underlevel info again after 1 minute
+
+ showHint("You have gained #rno experience#k from defeating #e#b" + mob.getName() + "#k#n (lv. #b" + mob.getLevel() + "#k)! Take note you must have around the same level as the mob to start earning EXP from it.");
+ }
+ } finally {
+ chrLock.unlock();
+ }
+ }
+
public void showHint(String msg) {
client.announceHint(msg);
}
diff --git a/src/constants/ServerConstants.java b/src/constants/ServerConstants.java
index 566fd6496c..7268cc510d 100644
--- a/src/constants/ServerConstants.java
+++ b/src/constants/ServerConstants.java
@@ -53,7 +53,7 @@ public class ServerConstants {
public static final boolean USE_ERASE_UNTRADEABLE_DROP = true; //Forces flagged untradeable items to disappear when dropped.
public static final boolean USE_ERASE_PET_ON_EXPIRATION = false;//Forces pets to be removed from inventory when expire time comes, rather than converting it to a doll.
public static final boolean USE_BUFF_MOST_SIGNIFICANT = true; //When applying buffs, the player will stick with the highest stat boost among the listed, rather than overwriting stats.
- public static final boolean USE_UNDERLEVELED_EXP_GAIN = false; //Players below the threshold level will gain no experience from defeating higher leveled mobs.
+ public static final boolean USE_UNDERLEVELED_EXP_BLOCK = true; //Players 20 levels below the killed mob will gain no experience from defeating it.
//Server Rates And Experience
public static final int EXP_RATE = 10;
@@ -78,9 +78,9 @@ public class ServerConstants {
//Some Gameplay Enhancing Configurations
//Scroll Configuration
- public static final boolean USE_PERFECT_GM_SCROLL = false; //Scrolls from GMs never uses up slots nor fails.
- public static final boolean USE_PERFECT_SCROLLING = false; //Scrolls doesn't use slots upon failure.
- public static final boolean USE_ENHANCED_CHSCROLL = false; //Equips even more powerful with chaos upgrade.
+ public static final boolean USE_PERFECT_GM_SCROLL = true; //Scrolls from GMs never uses up slots nor fails.
+ public static final boolean USE_PERFECT_SCROLLING = true; //Scrolls doesn't use slots upon failure.
+ public static final boolean USE_ENHANCED_CHSCROLL = true; //Equips even more powerful with chaos upgrade.
public static final boolean USE_ENHANCED_CRAFTING = true; //Applys chaos scroll on every equip crafted.
public static final int SCROLL_CHANCE_RATE = 0; //Number of rolls for success on a scroll, set 0 for default.
public static final int CHSCROLL_STAT_RANGE = 6; //Stat upgrade range (-N, N) on chaos scrolls.
diff --git a/src/scripting/npc/NPCConversationManager.java b/src/scripting/npc/NPCConversationManager.java
index 9646b6b841..3ea6b8b23c 100644
--- a/src/scripting/npc/NPCConversationManager.java
+++ b/src/scripting/npc/NPCConversationManager.java
@@ -222,6 +222,38 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
}
}
+ public void startQuest(short id, int npcId) {
+ try {
+ MapleQuest.getInstance(id).forceStart(getPlayer(), npcId);
+ } catch (NullPointerException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ public void startQuest(int id, int npcId) {
+ try {
+ MapleQuest.getInstance(id).forceStart(getPlayer(), npcId);
+ } catch (NullPointerException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ public void completeQuest(short id, int npcId) {
+ try {
+ MapleQuest.getInstance(id).forceComplete(getPlayer(), npcId);
+ } catch (NullPointerException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ public void completeQuest(int id, int npcId) {
+ try {
+ MapleQuest.getInstance(id).forceComplete(getPlayer(), npcId);
+ } catch (NullPointerException ex) {
+ ex.printStackTrace();
+ }
+ }
+
public int getMeso() {
return getPlayer().getMeso();
}
diff --git a/src/server/life/MapleMonster.java b/src/server/life/MapleMonster.java
index 14429dcbf1..ad330d384f 100644
--- a/src/server/life/MapleMonster.java
+++ b/src/server/life/MapleMonster.java
@@ -48,6 +48,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
@@ -257,13 +258,13 @@ public class MapleMonster extends AbstractLoadedMapleLife {
return takenDamage.containsKey(chr.getId());
}
- private void distributeExperienceToParty(int pid, int exp, int killer, Map expDist) {
+ private void distributeExperienceToParty(int pid, int exp, int killer, Map expDist, Set underleveled) {
List members = new LinkedList<>();
MapleCharacter pchar = getMap().getAnyCharacterFromParty(pid);
if(pchar != null) {
- for(MapleCharacter chr : pchar.getPartyMembersOnSameMap()) {
- members.add(chr);
- }
+ for(MapleCharacter chr : pchar.getPartyMembersOnSameMap()) {
+ members.add(chr);
+ }
} else {
MapleCharacter chr = getMap().getCharacterById(killer);
if(chr == null) return;
@@ -271,25 +272,16 @@ public class MapleMonster extends AbstractLoadedMapleLife {
members.add(chr);
}
- final int minLevel = getLevel() - 5;
int partyLevel = 0;
- int leechMinLevel = 0;
+ int leechMinLevel = (ServerConstants.USE_UNDERLEVELED_EXP_BLOCK) ? getLevel() - 20 : 0; //NO EXP WILL BE GIVEN for those who are underleveled!
- if(!ServerConstants.USE_UNDERLEVELED_EXP_GAIN) { //NO EXP WILL BE GIVEN for those who are underleveled!
- leechMinLevel = minLevel;
-
- for (MapleCharacter mc : members) {
- if (mc.getLevel() >= minLevel) {
- leechMinLevel = Math.min(mc.getLevel() - 5, leechMinLevel);
- }
- }
- }
-
int leechCount = 0;
for (MapleCharacter mc : members) {
if (mc.getLevel() >= leechMinLevel) {
partyLevel += mc.getLevel();
leechCount++;
+ } else {
+ underleveled.add(mc);
}
}
@@ -327,6 +319,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
}
Collection chrs = map.getCharacters();
+ Set underleveled = new LinkedHashSet<>();
for (MapleCharacter mc : chrs) {
if (expDist.containsKey(mc.getId())) {
boolean isKiller = (mc.getId() == killerId);
@@ -340,16 +333,22 @@ public class MapleMonster extends AbstractLoadedMapleLife {
long pXP = (long)xp + (partyExp.containsKey(pID) ? partyExp.get(pID) : 0);
partyExp.put(pID, (int)Math.min(pXP, Integer.MAX_VALUE));
} else {
- if(ServerConstants.USE_UNDERLEVELED_EXP_GAIN || mc.getLevel() >= this.getLevel() - 5) {
+ if(!ServerConstants.USE_UNDERLEVELED_EXP_BLOCK || mc.getLevel() >= getLevel() - 20) {
//NO EXP WILL BE GIVEN for those who are underleveled!
giveExpToCharacter(mc, xp, isKiller, 1);
+ } else {
+ underleveled.add(mc);
}
}
}
}
for (Entry party : partyExp.entrySet()) {
- distributeExperienceToParty(party.getKey(), party.getValue(), killerId, expDist);
+ distributeExperienceToParty(party.getKey(), party.getValue(), killerId, expDist, underleveled);
+ }
+
+ for(MapleCharacter mc : underleveled) {
+ mc.showUnderleveledInfo(this);
}
}
diff --git a/wz/Map.wz/Map/Map9/910510000.img.xml b/wz/Map.wz/Map/Map9/910510000.img.xml
index ffade311fe..9f542f7e6f 100644
--- a/wz/Map.wz/Map/Map9/910510000.img.xml
+++ b/wz/Map.wz/Map/Map9/910510000.img.xml
@@ -2209,8 +2209,9 @@
-
-
+
+
+