diff --git a/scripts/npc/1012112.js b/scripts/npc/1012112.js index 0ebfe39966..ca0f753f7e 100644 --- a/scripts/npc/1012112.js +++ b/scripts/npc/1012112.js @@ -1,24 +1,24 @@ /* - 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 . -*/ + This file is part of the OdinMS Maple Story Server + Copyright (C) 2008 Patrick Huy + Matthias Butz + Jan Christian Meyer + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation version 3 as published by + the Free Software Foundation. You may not use, modify or distribute + this program under any other version of the GNU Affero General Public + License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ /** * @author BubblesDev * @author Ronan @@ -29,104 +29,104 @@ var status = 0; var em = null; function start() { - status = -1; - action(1, 0, 0); + status = -1; + action(1, 0, 0); } function action(mode, type, selection) { - if (mode == -1) { - cm.dispose(); - } else { - if (mode == 0 && status == 0) { - cm.dispose(); - return; - } - if (mode == 1) - status++; - else - status--; - - if(cm.getMapId() == 100000200) { - if (status == 0) { - em = cm.getEventManager("HenesysPQ"); - if(em == null) { - cm.sendOk("The Henesys PQ has encountered an error."); - cm.dispose(); - return; - } else if(cm.isUsingOldPqNpcStyle()) { - action(1, 0, 0); - return; - } - - cm.sendSimple("#e#b\r\n#k#n" + em.getProperty("party") + "\r\n\r\nI'm Tory. Inside here is a beautiful hill where the primrose blooms. There's a tiger that lives in the hill, Growlie, and he seems to be looking for something to eat. Would you like to head over to the hill of primrose and join forces with your party members to help Growlie out?#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.\r\n#L3#I would like to redeem an instance hat."); - } else if (status == 1) { - if (selection == 0) { - if (cm.getParty() == null) { - cm.sendOk("Hi there! I'm Tory. This place is covered with mysterious aura of the full moon, and no one person can enter here by him/herself."); - cm.dispose(); - } else if(!cm.isLeader()) { - cm.sendOk("If you'd like to enter here, the leader of your party will have to talk to me. Talk to your party leader about this."); - cm.dispose(); - } else { - var eli = em.getEligibleParty(cm.getParty()); - if(eli.size() > 0) { - if(!em.startInstance(cm.getParty(), cm.getPlayer().getMap(), 1)) { - cm.sendOk("Someone is already attempting the PQ. Please wait for them to finish, or find another channel."); - } - } - else { - cm.sendOk("You cannot start this party quest yet, because either your party is not in the range size, some of your party members are not eligible to attempt it or they are not in this map. If you're having trouble finding party members, try Party Search."); - } - - cm.dispose(); - } - } else if (selection == 1) { - cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!"); - cm.dispose(); - } else if (selection == 2) { - cm.sendOk("#e#b#k#n\r\nCollect primrose seeds from the flowers at the bottom part of the map and drop them by the platforms above the stage. Primrose seed color must match to grow the seeds, so test until you find the correct combination. When all the seeds have been planted, that is, starting second part of the mission, scout the Moon Bunny while it prepares Rice Cakes for the hungry Growlie. Once Growlie becomes satisfied, your mission is complete."); - cm.dispose(); - } else { - cm.sendYesNo("So you want to exchange #b20 #b#t4001158##k for the instance-designed hat?"); - } - } else { - if(cm.hasItem(4001158, 20)) { - if(cm.canHold(1002798)) { - cm.gainItem(4001158, -20); - cm.gainItem(1002798, 20); - cm.sendNext("Here it is. Enjoy!"); - } - } else { - cm.sendNext("You don't have enough #t4001158# to buy it yet!"); - } - - cm.dispose(); - } - } else if (cm.getMapId() == 910010100) { - if (status == 0) { - cm.sendYesNo("Thank you for aiding in the effort of feeding the Growlie. As a matter of fact, your team has already been rewarded for reaching this far. With this problem now solved, there is another issue happening right now, if you are interessed check #bTommy#k there for the info. So, are you returning straight to Henesys now?"); - } else if (status == 1) { - if(cm.getEventInstance().giveEventReward(cm.getPlayer())) { - cm.warp(100000200); - } - else { - cm.sendOk("It seems you are short on space in one of your inventories. Please check that first to get rewarded properly."); - } - cm.dispose(); - } - } else if (cm.getMapId() == 910010400) { - if (status == 0) { - cm.sendYesNo("So, are you returning to Henesys now?"); - } else if (status == 1) { - if(cm.getEventInstance() == null) { - cm.warp(100000200); - } else if(cm.getEventInstance().giveEventReward(cm.getPlayer())) { - cm.warp(100000200); - } else { - cm.sendOk("It seems you are short on space in one of your inventories. Please check that first to get rewarded properly."); - } - cm.dispose(); - } - } + if (mode == -1) { + cm.dispose(); + } else { + if (mode == 0 && status == 0) { + cm.dispose(); + return; } + if (mode == 1) + status++; + else + status--; + + if (cm.getMapId() == 100000200) { + if (status == 0) { + em = cm.getEventManager("HenesysPQ"); + if (em == null) { + cm.sendOk("The Henesys PQ has encountered an error."); + cm.dispose(); + return; + } else if (cm.isUsingOldPqNpcStyle()) { + action(1, 0, 0); + return; + } + + cm.sendSimple("#e#b\r\n#k#n" + em.getProperty("party") + "\r\n\r\nI'm Tory. Inside here is a beautiful hill where the primrose blooms. There's a tiger that lives in the hill, Growlie, and he seems to be looking for something to eat. Would you like to head over to the hill of primrose and join forces with your party members to help Growlie out?#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.\r\n#L3#I would like to redeem an instance hat."); + } else if (status == 1) { + if (selection == 0) { + if (cm.getParty() == null) { + cm.sendOk("Hi there! I'm Tory. This place is covered with mysterious aura of the full moon, and no one person can enter here by him/herself."); + cm.dispose(); + } else if (!cm.isLeader()) { + cm.sendOk("If you'd like to enter here, the leader of your party will have to talk to me. Talk to your party leader about this."); + cm.dispose(); + } else { + var eli = em.getEligibleParty(cm.getParty()); + if (eli.size() > 0) { + if (!em.startInstance(cm.getParty(), cm.getPlayer().getMap(), 1)) { + cm.sendOk("Someone is already attempting the PQ. Please wait for them to finish, or find another channel."); + } + } + else { + cm.sendOk("You cannot start this party quest yet, because either your party is not in the range size, some of your party members are not eligible to attempt it or they are not in this map. If you're having trouble finding party members, try Party Search."); + } + + cm.dispose(); + } + } else if (selection == 1) { + cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!"); + cm.dispose(); + } else if (selection == 2) { + cm.sendOk("#e#b#k#n\r\nCollect primrose seeds from the flowers at the bottom part of the map and drop them by the platforms above the stage. Primrose seed color must match to grow the seeds, so test until you find the correct combination. When all the seeds have been planted, that is, starting second part of the mission, scout the Moon Bunny while it prepares Rice Cakes for the hungry Growlie. Once Growlie becomes satisfied, your mission is complete."); + cm.dispose(); + } else { + cm.sendYesNo("So you want to exchange #b20 #b#t4001158##k for the instance-designed hat?"); + } + } else { + if (cm.hasItem(4001158, 20)) { + if (cm.canHold(1002798)) { + cm.gainItem(4001158, -20); + cm.gainItem(1002798, 20); + cm.sendNext("Here it is. Enjoy!"); + } + } else { + cm.sendNext("You don't have enough #t4001158# to buy it yet!"); + } + + cm.dispose(); + } + } else if (cm.getMapId() == 910010100) { + if (status == 0) { + cm.sendYesNo("Thank you for aiding in the effort of feeding the Growlie. As a matter of fact, your team has already been rewarded for reaching this far. With this problem now solved, there is another issue happening right now, if you are interessed check #bTommy#k there for the info. So, are you returning straight to Henesys now?"); + } else if (status == 1) { + if (cm.getEventInstance().giveEventReward(cm.getPlayer())) { + cm.warp(100000200); + } + else { + cm.sendOk("It seems you are short on space in one of your inventories. Please check that first to get rewarded properly."); + } + cm.dispose(); + } + } else if (cm.getMapId() == 910010400) { + if (status == 0) { + cm.sendYesNo("So, are you returning to Henesys now?"); + } else if (status == 1) { + if (cm.getEventInstance() == null) { + cm.warp(100000200); + } else if (cm.getEventInstance().giveEventReward(cm.getPlayer())) { + cm.warp(100000200); + } else { + cm.sendOk("It seems you are short on space in one of your inventories. Please check that first to get rewarded properly."); + } + cm.dispose(); + } + } + } } \ No newline at end of file diff --git a/scripts/npc/1012113.js b/scripts/npc/1012113.js index 542f6c75be..d07fdd6504 100644 --- a/scripts/npc/1012113.js +++ b/scripts/npc/1012113.js @@ -1,24 +1,24 @@ /* - 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 . -*/ + This file is part of the OdinMS Maple Story Server + Copyright (C) 2008 Patrick Huy + Matthias Butz + Jan Christian Meyer + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation version 3 as published by + the Free Software Foundation. You may not use, modify or distribute + this program under any other version of the GNU Affero General Public + License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ /** * @author BubblesDev * @author Ronan @@ -31,45 +31,45 @@ function start() { } function action(mode, type, selection) { - if (mode < 1) { - cm.dispose(); - } else { - status++; - if (cm.getPlayer().getMap().getId() == 910010100) { //Clear map - if (status == 0) { - cm.sendNext("Hello, there! I'm Tommy. There's a Pig Town nearby where we're standing. The pigs there are rowdy and uncontrollable to the point where they have stolen numerous weapons from travelers. They were kicked out from their towns, and are currently hiding out at the Pig Town."); - } else if (status == 1) { - if(cm.isEventLeader()) { - cm.sendYesNo("What do you think about making your way there with your party members and teach those rowdy pigs a lesson?"); - } - else { - cm.sendOk("Interessed? Tell your party leader to talk to me to head there!"); - cm.dispose(); - return; - } - } else if (status == 2) { - cm.getEventInstance().startEventTimer(5 * 60000); - cm.getEventInstance().warpEventTeam(910010200); - - cm.dispose(); - return; - } - } else if (cm.getPlayer().getMap().getId() == 910010200) { //Bonus map - if (status == 0) { - cm.sendYesNo("Would you like to exit the bonus now?"); - } else { - cm.warp(910010400); - cm.dispose(); - return; - } - } else if (cm.getPlayer().getMap().getId() == 910010300) { //Exit map - if (status == 0) { - cm.sendOk("You will now be warped out, thank you for helping us!"); - } else { - cm.warp(100000200); - cm.dispose(); - return; - } + if (mode < 1) { + cm.dispose(); + } else { + status++; + if (cm.getPlayer().getMap().getId() == 910010100) { //Clear map + if (status == 0) { + cm.sendNext("Hello, there! I'm Tommy. There's a Pig Town nearby where we're standing. The pigs there are rowdy and uncontrollable to the point where they have stolen numerous weapons from travelers. They were kicked out from their towns, and are currently hiding out at the Pig Town."); + } else if (status == 1) { + if (cm.isEventLeader()) { + cm.sendYesNo("What do you think about making your way there with your party members and teach those rowdy pigs a lesson?"); } + else { + cm.sendOk("Interessed? Tell your party leader to talk to me to head there!"); + cm.dispose(); + return; + } + } else if (status == 2) { + cm.getEventInstance().startEventTimer(5 * 60000); + cm.getEventInstance().warpEventTeam(910010200); + + cm.dispose(); + return; + } + } else if (cm.getPlayer().getMap().getId() == 910010200) { //Bonus map + if (status == 0) { + cm.sendYesNo("Would you like to exit the bonus now?"); + } else { + cm.warp(910010400); + cm.dispose(); + return; + } + } else if (cm.getPlayer().getMap().getId() == 910010300) { //Exit map + if (status == 0) { + cm.sendOk("You will now be warped out, thank you for helping us!"); + } else { + cm.warp(100000200); + cm.dispose(); + return; + } } + } } diff --git a/scripts/npc/2042000.js b/scripts/npc/2042000.js index 45d5ef912b..726519e0b7 100644 --- a/scripts/npc/2042000.js +++ b/scripts/npc/2042000.js @@ -1,232 +1,84 @@ -/* - This file is part of the HeavenMS MapleStory Server - Copyleft (L) 2016 - 2018 RonanLana +var map = 980000000; +var minLvl = 0; +var maxLvl = 255; +var minAmt = 0; +var maxAmt = 6; - 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 . -*/ -/* Spiegelmann - Refining NPC: - * Auto ore refiner - * - * @author RonanLana -*/ - -var status; -var refineRocks = true; // enables moon rock, star rock -var refineCrystals = true; // enables common crystals -var refineSpecials = true; // enables lithium, special crystals -var feeMultiplier = 7.0; - function start() { - status = -1; - action(1, 0, 0); + 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 (!Packages.constants.ServerConstants.USE_ENABLE_CUSTOM_NPC_SCRIPT) { - cm.sendOk("The Monster Carnival is currently unavailable."); - cm.dispose(); - return; - } - - var selStr = "The Monster Carnival is currently unavailable, but instead I offer a steadfast #bore refining#k service for you, taxing #r" + ((feeMultiplier * 100) | 0) + "%#k over the usual fee to synthetize them. What will you do?#b"; - - var options = new Array("Refine mineral ores","Refine jewel ores"); - if(refineCrystals) { - options.push("Refine crystal ores"); - } - if(refineRocks) { - options.push("Refine plates/jewels"); - } - - for (var i = 0; i < options.length; i++){ - selStr += "\r\n#L" + i + "# " + options[i] + "#l"; - } - - cm.sendSimple(selStr); - } else if(status == 1) { - var allDone; - - if (selection == 0) { - allDone = refineItems(0); // minerals - } else if (selection == 1) { - allDone = refineItems(1); // jewels - } else if (selection == 2 && refineCrystals) { - allDone = refineItems(2); // crystals - } else if (selection == 2 && !refineCrystals || selection == 3) { - allDone = refineRockItems(); // moon/star rock - } - - if(allDone) { - cm.sendOk("Done. Thanks for showing up~."); - } else { - cm.sendOk("Done. Be aware some of the items #rcould not be synthetized#k because either you have a lack of space on your ETC inventory or there's not enough mesos to cover the fee."); - } - cm.dispose(); - } + if (mode == -1) { + cm.dispose(); + } else { + if (mode == 0 && status == 0) { + cm.dispose(); + return; } -} - -function getRefineFee(fee) { - return ((feeMultiplier * fee) | 0); -} - -function isRefineTarget(refineType, refineItemid) { - if(refineType == 0) { //mineral refine - return refineItemid >= 4010000 && refineItemid <= 4010007 && !(refineItemid == 4010007 && !refineSpecials); - } else if(refineType == 1) { //jewel refine - return refineItemid >= 4020000 && refineItemid <= 4020008 && !(refineItemid == 4020008 && !refineSpecials); - } else if(refineType == 2) { //crystal refine - return refineItemid >= 4004000 && refineItemid <= 4004004 && !(refineItemid == 4004004 && !refineSpecials); - } - - return false; -} - -function getRockRefineTarget(refineItemid) { - if(refineItemid >= 4011000 && refineItemid <= 4011006) { - return 0; - } else if(refineItemid >= 4021000 && refineItemid <= 4021008) { - return 1; - } - - return -1; -} - -function refineItems(refineType) { - var allDone = true; - - var refineFees = [[300,300,300,500,500,500,800,270],[500,500,500,500,500,500,500,1000,3000],[5000,5000,5000,5000,1000000]]; - var itemCount = {}; - - var iter = cm.getPlayer().getInventory(Packages.client.inventory.MapleInventoryType.ETC).iterator(); - while (iter.hasNext()) { - var it = iter.next(); - var itemid = it.getItemId(); - - if(isRefineTarget(refineType, itemid)) { - var ic = itemCount[itemid]; - - if(ic != undefined) { - itemCount[itemid] += it.getQuantity(); + if (mode == 1) + status++; + else + status--; + if (status == 0) { + if (cm.getParty() == null) { + status = 10; + cm.sendOk("#eÉ necessário criar um grupo antes de começar o Festival de Monstros!#k"); + } else if (!cm.isLeader()) { + status = 10; + cm.sendOk("Se você quer começar o Festival, avise o #blíder do grupo#k para falar comigo."); } else { - itemCount[itemid] = it.getQuantity(); - } - } - } - - for(var key in itemCount) { - var itemqty = itemCount[key]; - var itemid = parseInt(key); - - var refineQty = ((itemqty / 10) | 0); - if(refineQty <= 0) continue; - - while(true) { - itemqty = refineQty * 10; - - var fee = getRefineFee(refineFees[refineType][(itemid % 100) | 0] * refineQty); - if(cm.canHold(itemid + 1000, refineQty, itemid, itemqty) && cm.getMeso() >= fee) { - cm.gainMeso(-fee); - cm.gainItem(itemid, -itemqty); - cm.gainItem(itemid + (itemid != 4010007 ? 1000 : 1001), refineQty); - - break; - } else if(refineQty <= 1) { - allDone = false; - break; - } else { - refineQty--; - } - } - } - - return allDone; -} - -function refineRockItems() { - var allDone = true; - var minItems = [[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]]; - var minRocks = [2147483647, 2147483647]; - - var rockItems = [4011007, 4021009]; - var rockFees = [10000, 15000]; - - var iter = cm.getPlayer().getInventory(Packages.client.inventory.MapleInventoryType.ETC).iterator(); - while (iter.hasNext()) { - var it = iter.next(); - var itemid = it.getItemId(); - var rockRefine = getRockRefineTarget(itemid); - if(rockRefine >= 0) { - var rockItem = ((itemid % 100) | 0); - var itemqty = it.getQuantity(); - - minItems[rockRefine][rockItem] += itemqty; - } - } - - for(var i = 0; i < minRocks.length; i++) { - for(var j = 0; j < minItems[i].length; j++) { - if(minRocks[i] > minItems[i][j]) { - minRocks[i] = minItems[i][j]; - } - } - if(minRocks[i] <= 0 || minRocks[i] == 2147483647) continue; - - var refineQty = minRocks[i]; - while(true) { - var fee = getRefineFee(rockFees[i] * refineQty); - if(cm.canHold(rockItems[i], refineQty) && cm.getMeso() >= fee) { - cm.gainMeso(-fee); - - var j; - if(i == 0) { - for(j = 4011000; j < 4011007; j++) { - cm.gainItem(j, -refineQty); + var party = cm.getParty().getMembers(); + var inMap = cm.partyMembersInMap(); + var lvlOk = 0; + var isInMap = 0; + for (var i = 0; i < party.size(); i++) { + if (party.get(i).getLevel() >= minLvl && party.get(i).getLevel() <= maxLvl) { + lvlOk++; } - cm.gainItem(j, refineQty); + if (party.get(i).getPlayer().getMapId() != 980000000) { + //isInMap = false; + isInMap++ + } + } + + if (party >= 1) { + status = 10; + cm.sendOk("Você não tem número suficiente de pessoas em seu grupo. Você precisa de um grupo com #b" + minAmt + "#k - #r" + maxAmt + "#k membros e eles devem estar no mapa com você."); + } else if (lvlOk != inMap) { + status = 10; + cm.sendOk("Certifique se todos em seu grupo estão dentre os níveis corretos (" + minLvl + "~" + maxLvl + ")!"); + } else if (isInMap > 0) { + status = 10; + cm.sendOk("Existe alguém do grupo que não esta no mapa!"); } else { - for(j = 4021000; j < 4021009; j++) { - cm.gainItem(j, -refineQty); - } - cm.gainItem(j, refineQty); + cm.sendCPQMapLists(); } - - break; - } else if(refineQty <= 1) { - allDone = false; - break; - } else { - refineQty--; } + } else if (status == 1) { + + if (cm.fieldTaken(selection)) { + if (cm.fieldLobbied(selection)) { + cm.challengeParty(selection); + cm.dispose(); + } else { + cm.sendOk("A sala esta cheia."); + cm.dispose(); + } + } else { + var party = cm.getParty().getMembers(); + if ((selection === 0 || selection === 1 || selection === 2 || selection === 3) && party.size() < 2) { + cm.sendOk("Você precisa de no mínimo 2 player para entrar na competição."); + } else if ((selection === 4 || selection === 5) && party.size() < 3) { + cm.sendOk("Você precisa de no mínimo 3 player para entrar na competição."); + } else { + cm.cpqLobby(selection); + } + cm.dispose(); + } + } else if (status == 11) { + cm.dispose(); } } - - return allDone; -} +} \ No newline at end of file diff --git a/scripts/npc/2042002.js b/scripts/npc/2042002.js index 1d539fa0b3..4f7ae7d9c3 100644 --- a/scripts/npc/2042002.js +++ b/scripts/npc/2042002.js @@ -1,226 +1,320 @@ -/* - This file is part of the HeavenMS MapleStory Server - Copyleft (L) 2016 - 2018 RonanLana +importPackage(Packages.server.maps); - 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. +var status = 0; +var rnk = -1; +var n1 = 50; //??? +var n2 = 40; //??? ??? +var n3 = 7; //35 +var n4 = 10; //40 +var n5 = 20; //50 - 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 . -*/ -/* Spiegelmann - Refining NPC: - * Auto ore refiner - * - * @author RonanLana -*/ - -var status; -var refineRocks = true; // enables moon rock, star rock -var refineCrystals = true; // enables common crystals -var refineSpecials = true; // enables lithium, special crystals -var feeMultiplier = 7.0; - function start() { - status = -1; - action(1, 0, 0); + status = -1; + action(1, 0, 0); } function action(mode, type, selection) { - if (mode == -1) { + if (mode == -1) { + cm.dispose(); + } else { + if (status >= 0 && mode == 0) { + cm.dispose(); + return; + } + if (mode == 1) + status++; + else + status--; + if (cm.getPlayer().getMapId() == 980000010) { + if (status == 0) { + cm.sendNext("Eu espero que você tinha divertido na Folia dos Monstros!"); + } else if (status > 0) { + cm.warp(980000000, 0); cm.dispose(); + } + } else if (cm.getChar().getMap().isCPQLoserMap()) { + if (status == 0) { + if (cm.getChar().getParty() != null) { + var shiu = ""; + if (cm.getPlayer().getFestivalPoints() >= 100) { + shiu += "#rA#k"; + cm.sendOk("Infelizmente, você ou empatou ou perdeu a batalha, apesar da sua excelente performance. A vitória pode ser sua da próxima vez.\r\n\r\n#bNota da Folia de Monstros : " + shiu); + rnk = 10; + } else if (cm.getPlayer().getFestivalPoints() >= 50 && cm.getPlayer().getFestivalPoints() < 100) { + shiu += "#rB#k"; + rnk = 20; + cm.sendOk("Infelizmente, você ou empatou ou perdeu a batalha, mesmo com sua ótima performance. Só mais um pouquinho, e a vitória poderia ter sido sua.\r\n\r\n#bNota da Folia de Monstros : " + shiu); + } else if (cm.getPlayer().getFestivalPoints() >= 30 && cm.getPlayer().getFestivalPoints() < 50) { + shiu += "#rC#k"; + rnk = 30; + cm.sendOk("Infelizmente, você ou empatou ou perdeu a batalha. A vitória está para aqueles que se esforçam. Vejo seus esforços, então a vitória não está tão longe do seu alcance. Continue assim!\r\n\r\n#bNota da Folia de Monstros : " + shiu); + } else { + shiu += "#rD#k"; + rnk = 40; + cm.sendOk("Infelizmente, você ou empatou ou perdeu a batalha, e sua performance claramente reflete nisso. Espero mais de você da próxima vez.\r\n\r\n#bNota da Folia de Monstros : " + shiu); + } + } else { + cm.warp(980000000, 0); + cm.dispose(); + } + } else if (status == 1) { + switch (rnk) { + case 10: + cm.warp(980000000, 0); + cm.gainExp(17500); + cm.dispose(); + break; + case 20: + cm.warp(980000000, 0); + cm.gainExp(1200); + cm.dispose(); + break; + case 30: + cm.warp(980000000, 0); + cm.gainExp(5000); + cm.dispose(); + break; + case 40: + cm.warp(980000000, 0); + cm.gainExp(2500); + cm.dispose(); + break; + default: + cm.warp(980000000, 0); + cm.dispose(); + break; + } + } + } else if (cm.getChar().getMap().isCPQWinnerMap()) { + if (status == 0) { + if (cm.getChar().getParty() != null) { + var shi = ""; + if (cm.getPlayer().getFestivalPoints() >= 300) { + shi += "#rA#k"; + rnk = 1; + cm.sendOk("Parabéns pela sua vitória!!! Que ótima performance! O grupo adversário não pôde fazer nada! Espero o mesmo bom trabalho da próxima vez!\r\n\r\n#bNota da Folia de Monstros : " + shi); + } else if (cm.getPlayer().getFestivalPoints() >= 100 && cm.getPlayer().getFestivalPoints() < 300) { + shi += "#rB#k"; + rnk = 2; + cm.sendOk("Parabéns pela sua vitória! Isso foi impressionante! Você fez um bom trabalho contra o grupo adversário! Só mais um pouco, e você definitivamente vai conseguir um A na próxima vez. \r\n\r\n#bNota da Folia de Monstros : " + shi); + } else if (cm.getPlayer().getFestivalPoints() >= 50 && cm.getPlayer().getFestivalPoints() < 100) { + shi += "#rC#k"; + rnk = 3; + cm.sendOk("Parabéns pela sua vitória. Você fez algumas coisas cá e lá, mas essa não pode ser considerada uma boa vitória. Espero mais de ti da próxima vez.\r\n\r\n#bNota da Folia de Monstros : " + shi); + } else { + shi += "#rD#k"; + rnk = 4; + cm.sendOk("Parabéns pela sua vitória, entretanto sua performance não refletiu muito bem isso. Seja mais ativo na sua próxima participação da Folia de Monstros!\r\n\r\n#bNota da Folia de Monstros : " + shi); + } + } else { + cm.warp(980000000, 0); + cm.dispose(); + } + } else if (status == 1) { + switch (rnk) { + case 1: + cm.warp(980000000, 0); + cm.gainExp(50000); + cm.dispose(); + break; + case 2: + cm.warp(980000000, 0); + cm.gainExp(25500); + cm.dispose(); + break; + case 3: + cm.warp(980000000, 0); + cm.gainExp(21000); + cm.dispose(); + break; + case 4: + cm.warp(980000000, 0); + cm.gainExp(19505); + cm.dispose(); + break; + default: + cm.warp(980000000, 0); + cm.dispose(); + break; + } + } } else { - if (mode == 0 && type > 0) { + if (status == 0) { + // cm.sendSimple("O que gostaria de fazer? Se você nunca participou da Folia de Monstros, você precisará saber de algumas coisas antes de participar.\r\n#b#L0# Ir para o campo da Folia de Monstros 1.#l\r\n#L1# Aprender sobre a Folia de Monstros.#l\r\n#L2# Trocar #t4001129#.#l"); + cm.sendSimple("O que gostaria de fazer? Se você nunca participou da Folia de Monstros, você precisará saber de algumas coisas antes de participar.\r\n#b#L0# Ir para o campo da Folia de Monstros 1.#l\r\n#L3# Ir para o campo da Folia de Monstros 2.#l\r\n#L1# Aprender sobre a Folia de Monstros.#l\r\n#L2# Trocar #t4001129#.#l"); + } else if (status == 1) { + if (selection == 0) { + if ((cm.getLevel() > 29 && cm.getLevel() < 51) || cm.getPlayer().isGM()) { + cm.getChar().saveLocation("MONSTER_CARNIVAL"); + cm.warp(980000000, 0); cm.dispose(); return; - } - if (mode == 1) - status++; - else - status--; - - if(status == 0) { - var selStr = "The Monster Carnival is currently unavailable, but instead I offer a steadfast #bore refining#k service for you, taxing #r" + ((feeMultiplier * 100) | 0) + "%#k over the usual fee to synthetize them. What will you do?#b"; - - var options = new Array("Refine mineral ores","Refine jewel ores"); - if(refineCrystals) { - options.push("Refine crystal ores"); - } - if(refineRocks) { - options.push("Refine plates/jewels"); - } - - for (var i = 0; i < options.length; i++){ - selStr += "\r\n#L" + i + "# " + options[i] + "#l"; - } - - cm.sendSimple(selStr); - } else if(status == 1) { - var allDone; - - if (selection == 0) { - allDone = refineItems(0); // minerals - } else if (selection == 1) { - allDone = refineItems(1); // jewels - } else if (selection == 2 && refineCrystals) { - allDone = refineItems(2); // crystals - } else if (selection == 2 && !refineCrystals || selection == 3) { - allDone = refineRockItems(); // moon/star rock - } - - if(allDone) { - cm.sendOk("Done. Thanks for showing up~."); - } else { - cm.sendOk("Done. Be aware some of the items could not be synthetized because either you have a lack of space on your ETC inventory or there's not enough mesos to cover the fee."); - } + } else if (cm.getLevel() < 30) { + cm.sendOk("Você precisa ser no mínimo nível 30 para participar da Folia de Monstros. Fale comigo quando for forte o bastante."); cm.dispose(); - } - } -} - -function getRefineFee(fee) { - return ((feeMultiplier * fee) | 0); -} - -function isRefineTarget(refineType, refineItemid) { - if(refineType == 0) { //mineral refine - return refineItemid >= 4010000 && refineItemid <= 4010007 && !(refineItemid == 4010007 && !refineSpecials); - } else if(refineType == 1) { //jewel refine - return refineItemid >= 4020000 && refineItemid <= 4020008 && !(refineItemid == 4020008 && !refineSpecials); - } else if(refineType == 2) { //crystal refine - return refineItemid >= 4004000 && refineItemid <= 4004004 && !(refineItemid == 4004004 && !refineSpecials); - } - - return false; -} - -function getRockRefineTarget(refineItemid) { - if(refineItemid >= 4011000 && refineItemid <= 4011006) { - return 0; - } else if(refineItemid >= 4021000 && refineItemid <= 4021008) { - return 1; - } - - return -1; -} - -function refineItems(refineType) { - var allDone = true; - - var refineFees = [[300,300,300,500,500,500,800,270],[500,500,500,500,500,500,500,1000,3000],[5000,5000,5000,5000,1000000]]; - var itemCount = {}; - - var iter = cm.getPlayer().getInventory(Packages.client.inventory.MapleInventoryType.ETC).iterator(); - while (iter.hasNext()) { - var it = iter.next(); - var itemid = it.getItemId(); - - if(isRefineTarget(refineType, itemid)) { - var ic = itemCount[itemid]; - - if(ic != undefined) { - itemCount[itemid] += it.getQuantity(); - } else { - itemCount[itemid] = it.getQuantity(); - } - } - } - - for(var key in itemCount) { - var itemqty = itemCount[key]; - var itemid = parseInt(key); - - var refineQty = ((itemqty / 10) | 0); - if(refineQty <= 0) continue; - - while(true) { - itemqty = refineQty * 10; - - var fee = getRefineFee(refineFees[refineType][(itemid % 100) | 0] * refineQty); - if(cm.canHold(itemid + 1000, refineQty, itemid, itemqty) && cm.getMeso() >= fee) { - cm.gainMeso(-fee); - cm.gainItem(itemid, -itemqty); - cm.gainItem(itemid + (itemid != 4010007 ? 1000 : 1001), refineQty); - - break; - } else if(refineQty <= 1) { - allDone = false; - break; - } else { - refineQty--; - } - } - } - - return allDone; -} - -function refineRockItems() { - var allDone = true; - var minItems = [[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]]; - var minRocks = [2147483647, 2147483647]; - - var rockItems = [4011007, 4021009]; - var rockFees = [10000, 15000]; - - var iter = cm.getPlayer().getInventory(Packages.client.inventory.MapleInventoryType.ETC).iterator(); - while (iter.hasNext()) { - var it = iter.next(); - var itemid = it.getItemId(); - var rockRefine = getRockRefineTarget(itemid); - if(rockRefine >= 0) { - var rockItem = ((itemid % 100) | 0); - var itemqty = it.getQuantity(); - - minItems[rockRefine][rockItem] += itemqty; - } - } - - for(var i = 0; i < minRocks.length; i++) { - for(var j = 0; j < minItems[i].length; j++) { - if(minRocks[i] > minItems[i][j]) { - minRocks[i] = minItems[i][j]; - } - } - if(minRocks[i] <= 0 || minRocks[i] == 2147483647) continue; - - var refineQty = minRocks[i]; - while(true) { - var fee = getRefineFee(rockFees[i] * refineQty); - if(cm.canHold(rockItems[i], refineQty) && cm.getMeso() >= fee) { - cm.gainMeso(-fee); - - var j; - if(i == 0) { - for(j = 4011000; j < 4011007; j++) { - cm.gainItem(j, -refineQty); + return; + } else { + cm.sendOk("Sinto muito, mas apenas os jogadores de nível 30~50 podem participar da Folia de Monstros."); + cm.dispose(); + return; } - cm.gainItem(j, refineQty); + } else if (selection == 1) { + status = 60; + cm.sendSimple("O que gostaria de fazer?\r\n#b#L0# O que é a Folia de Monstros?#l\r\n#L1# Visão geral sobre a Folia de Monstros#l\r\n#L2# Informações detalhadas sobre a Folia de Monstros#l\r\n#L3# Nada, de verdade. Mudei de ideia.#l"); + } else if (selection == 2) { + cm.sendSimple("Lembre-se se você possui #t4001129#, você pode trocá-las por itens. Tenha certeza que você possui #t4001129# suficientes para o item que você deseja. Selecione o item que você gostaria de trocá-las! \r\n#b#L0# #t1122007#(" + n1 + " moedas)#l\r\n#L1# #t2041211#(" + n2 + " moedas)#l\r\n#L2# Armas para Guerreiros#l\r\n#L3# Armas para Bruxos#l\r\n#L4# Armas para Arqueiros#l\r\n#L5# Armas para Gatunos#l"); + } else if (selection == 3) { + cm.getChar().saveLocation("MONSTER_CARNIVAL"); + cm.warp(980030000, 0); + cm.dispose(); + return; + } + + } else if (status == 2) { + select = selection; + if (select == 0) { + if (cm.haveItem(4001129, n1) && cm.canHold(4001129)) { + cm.gainItem(1122007, 1); + cm.gainItem(4001129, -n1); + cm.dispose(); + } else { + cm.sendOk("Verifique e veja se estão faltando #b#t4001129##k ou se seu inventário de Equipamentos está cheio."); + cm.dispose(); + } + } else if (select == 1) { + if (cm.haveItem(4001129, n2) && cm.canHold(2041211)) { + cm.gainItem(2041211, 1); + cm.gainItem(4001129, -n2); + cm.dispose(); + } else { + cm.sendOk("Verifique e veja se estão faltando #b#t4001129##k ou se seu inventário de Uso está cheio."); + cm.dispose(); + } + } else if (select == 2) {//S2 Warrior 26 S3 Magician 6 S4 Bowman 6 S5 Thief 8 + status = 10; + cm.sendSimple("Por favor tenha certeza que você possui #t4001129# para a arma que você deseja. Selecione a arma que você gostaria de trocar #t4001129# por. As opções que tenho são realmente boas, e eu não sou eu que falo é o povo que diz! \r\n#b#L0# #z1302004#(" + n3 + " moedas)#l\r\n#L1# #z1402006#(" + n3 + " moedas)#l\r\n#L2# #z1302009#(" + n4 + " moedas)#l\r\n#L3# #z1402007#(" + n4 + " moedas)#l\r\n#L4# #z1302010#(" + n5 + " moedas)#l\r\n#L5# #z1402003#(" + n5 + " moedas)#l\r\n#L6# #z1312006#(" + n3 + " moedas)#l\r\n#L7# #z1412004#(" + n3 + " moedas)#l\r\n#L8# #z1312007#(" + n4 + " moedas)#l\r\n#L9# #z1412005#(" + n4 + " moedas)#l\r\n#L10# #z1312008#(" + n5 + " moedas)#l\r\n#L11# #z1412003#(" + n5 + " moedas)#l\r\n#L12# Ir para a próxima página(1/2)#l"); + } else if (select == 3) { + status = 20; + cm.sendSimple("Selecione a arma que você gostaria de trocar. As armas que eu tenho aqui são extremamente atraentes. Veja você mesmo! \r\n#b#L0# #z1372001#(" + n3 + " moedas)#l\r\n#L1# #z1382018#(" + n3 + " moedas)#l\r\n#L2# #z1372012#(" + n4 + "moedas)#l\r\n#L3# #z1382019#(" + n4 + "moedas)#l\r\n#L4# #z1382001#(" + n5 + " moedas)#l\r\n#L5# #z1372007#(" + n5 + " moedas)#l"); + } else if (select == 4) { + status = 30; + cm.sendSimple("Selecione a arma que você gostaria de trocar. As armas que eu tenho aqui são extremamente atraentes. Veja você mesmo! \r\n#b#L0# #z1452006#(" + n3 + " moedas)#l\r\n#L1# #z1452007#(" + n4 + " moedas)#l\r\n#L2# #z1452008#(" + n5 + " moedas)#l\r\n#L3# #z1462005#(" + n3 + " moedas)#l\r\n#L4# #z1462006#(" + n4 + " moedas)#l\r\n#L5# #z1462007#(" + n5 + " moedas)#l"); + } else if (select == 5) { + status = 40; + cm.sendSimple("Selecione a arma que você gostaria de trocar por. As armas que eu tenho são da maior qualidade. Seleciona a mais atraente para você! \r\n#b#L0# #z1472013#(" + n3 + " moedas)#l\r\n#L1# #z1472017#(" + n4 + "moedas)#l\r\n#L2# #z1472021#(" + n5 + " moedas)#l\r\n#L3# #z1332014#(" + n3 + " moedas)#l\r\n#L4# #z1332031#(" + n4 + "moedas)#l\r\n#L5# #z1332011#(" + n4 + "moedas)#l\r\n#L6# #z1332016#(" + n5 + " moedas)#l\r\n#L7# #z1332003#(" + n5 + " moedas)#l"); + } + } else if (status == 11) { + if (selection == 12) { + cm.sendSimple("Selecione a arma que você gostaria de trocar. As armas que eu tenho aqui são extremamente úteis. Dá uma olhada! \r\n#b#L0# #z1322015#(" + n3 + " moedas)#l\r\n#L1# #z1422008#(" + n3 + " moedas)#l\r\n#L2# #z1322016#(" + n4 + "moedas)#l\r\n#L3# #z1422007#(" + n4 + "moedas)#l\r\n#L4# #z1322017#(" + n5 + " moedas)#l\r\n#L5# #z1422005#(" + n5 + " moedas)#l\r\n#L6# #z1432003#(" + n3 + " moedas)#l\r\n#L7# #z1442003#(" + n3 + " moedas)#l\r\n#L8# #z1432005#(" + n4 + "moedas)#l\r\n#L9# #z1442009#(" + n4 + "moedas)#l\r\n#L10# #z1442005#(" + n5 + " moedas)#l\r\n#L11# #z1432004#(" + n5 + " moedas)#l\r\n#L12# Voltar para a página inicial(2/2)#l"); } else { - for(j = 4021000; j < 4021009; j++) { - cm.gainItem(j, -refineQty); + var item = new Array(1302004, 1402006, 1302009, 1402007, 1302010, 1402003, 1312006, 1412004, 1312007, 1412005, 1312008, 1412003); + var cost = new Array(n3, n3, n4, n4, n5, n5, n3, n3, n4, n4, n5); + if (cm.haveItem(4001129, cost[selection]) && cm.canHold(item[selection])) { + cm.gainItem(item[selection], 1); + cm.gainItem(4001129, -cost[selection]); + cm.dispose(); + } else { + cm.sendOk("Você ou não possui #b#t4001129##k suficientes, ou seu inventário está cheio. Verifique novamente."); + cm.dispose(); } - cm.gainItem(j, refineQty); } - - break; - } else if(refineQty <= 1) { - allDone = false; - break; - } else { - refineQty--; + } else if (status == 12) { + if (selection == 12) { + status = 10; + cm.sendSimple("Por favor tenha certeza que você possui #t4001129# para a arma que você deseja. Selecione a arma que você gostaria de trocar #t4001129# por. As opções que tenho são realmente boas, e eu não sou eu que falo é o povo que diz! \r\n#b#L0# #z1302004#(" + n3 + " moedas)#l\r\n#L1# #z1402006#(" + n3 + " moedas)#l\r\n#L2# #z1302009#(" + n4 + " moedas)#l\r\n#L3# #z1402007#(" + n4 + " moedas)#l\r\n#L4# #z1302010#(" + n5 + " moedas)#l\r\n#L5# #z1402003#(" + n5 + " moedas)#l\r\n#L6# #z1312006#(" + n3 + " moedas)#l\r\n#L7# #z1412004#(" + n3 + " moedas)#l\r\n#L8# #z1312007#(" + n4 + " moedas)#l\r\n#L9# #z1412005#(" + n4 + " moedas)#l\r\n#L10# #z1312008#(" + n5 + " moedas)#l\r\n#L11# #z1412003#(" + n5 + " moedas)#l\r\n#L12# Ir para a próxima página(1/2)#l"); + } else { + var item = new Array(1322015, 1422008, 1322016, 1422007, 1322017, 1422005, 1432003, 1442003, 1432005, 1442009, 1442005, 1432004); + var cost = new Array(n3, n3, n4, n4, n5, n5, n3, n3, n4, n4, n5, n5); + if (cm.haveItem(4001129, cost[selection]) && cm.canHold(item[selection])) { + cm.gainItem(item[selection], 1); + cm.gainItem(4001129, -cost[selection]); + cm.dispose(); + } else { + cm.sendOk("Você ou não possui #b#t4001129##k suficientes, ou seu inventário está cheio. Verifique novamente."); + cm.dispose(); + } + } + } else if (status == 21) { + var item = new Array(1372001, 1382018, 1372012, 1382019, 1382001, 1372007); + var cost = new Array(n3, n3, n4, n4, n5, n5); + if (cm.haveItem(4001129, cost[selection]) && cm.canHold(item[selection])) { + cm.gainItem(item[selection], 1); + cm.gainItem(4001129, -cost[selection]); + cm.dispose(); + } else { + cm.sendOk("Ou você não possui #b#t4001129##k suficientes, ou seu inventário está cheio. Verifique novamente."); + cm.dispose(); + } + } else if (status == 31) { + var item = new Array(1452006, 1452007, 1452008, 1462005, 1462006, 1462007); + var cost = new Array(n3, n4, n5, n3, n4, n5); + if (cm.haveItem(4001129, cost[selection]) && cm.canHold(item[selection])) { + cm.gainItem(item[selection], 1); + cm.gainItem(4001129, -cost[selection]); + cm.dispose(); + } else { + cm.sendOk("Ou você não possui #b#t4001129##k suficientes, ou seu inventário está cheio. Verifique novamente."); + cm.dispose(); + } + } else if (status == 41) { + var item = new Array(1472013, 1472017, 1472021, 1332014, 1332031, 1332011, 1332016, 1332003); + var cost = new Array(n3, n4, n5, n3, n4, n4, n5, n5); + if (cm.haveItem(4001129, cost[selection]) && cm.canHold(item[selection])) { + cm.gainItem(item[selection], 1); + cm.gainItem(4001129, -cost[selection]); + cm.dispose(); + } else { + cm.sendOk("Ou você não possui #b#t4001129##k suficientes, ou seu inventário está cheio. Verifique novamente."); + cm.dispose(); + } + } else if (status == 61) { + select = selection; + if (selection == 0) { + cm.sendNext("Haha! Eu sou Spiegelmann, o líder dessa Folia. Eu comecei a primeira #bFolia de Monstros#k aqui, aguardando por viajantes como você para participar dessa extravaganza!"); + } else if (selection == 1) { + cm.sendNext("#bFolia de Monstros#k consiste em 2 grupos entrando no campo de batalha, e caçando os monstros invocados pelo outro grupo. É uma #bmissão de combate que determina o vitorioso pela quantia de Pontos de Folia (CP) recebidos#k."); + } else if (selection == 2) { + cm.sendNext("Quando entrar no Campo da Folia, você verá a janela da Folia de Monstros aparecer. Tudo que precisa fazer é #bselecionar o que vocêe quer usar, e pressionar OK#k. Muito fácil, né?"); + } else { + cm.dispose(); + } + } else if (status == 62) { + if (select == 0) { + cm.sendNext("O que é a #bFolia de Monstros#k? Hahaha! Vamos dizer que é uma experiência que jamais esquecerá! É uma #bbatalha contra outros viajantes assim como você!#k"); + } else if (select == 1) { + cm.sendNext("Quando entrar no Campo da Folia, sua tarefa é #breceber CP caçando os monstros do grupo oposto, e usar estes CP's para distrair o grupo oposto de caçar monstros.#k."); + } else if (select == 2) { + cm.sendNext("Assim que se acostumar com os comandos, tente usar #bas teclas TAB e F1 ~ F12#k. #bTAB alterna entre Invocação de Monstros/Habilidades/Protetor,#k e, #bF1~ F12 possibilita-o de acessar uma das janelas diretamente#k."); + } + } else if (status == 63) { + if (select == 0) { + cm.sendNext("Eu sei que é muito perigoso para vocês lutarem uns com os outros usando armas de verdade; e eu não sugeriria um ato tão barbárico. Não meu amigo, o que eu ofereço é competição. A emoção da batalha e a emoção de competir contra pessoas tão fortes e motivadas. Eu ofereço a premissa de que seu grupo e o grupo oposto ambos #binvoquem os monstros, e derrote os monstros invocados pelo grupo adversário. Essa é a essência da Folia de Monstros. Além disso, você pode usar Maple Coins ganhos durante a Folia de Monstros para obter novos itens e armas! #k"); + } else if (select == 1) { + cm.sendNext("Existem 3 maneiras de distrair o grupo adversário: #bInvodar um monstro, Habilidade, and Protetor#k. Vou dar-lhe um olhar mais aprofundado, se você quiser saber mais sobre 'Instruções detalhadas'."); + } else if (select == 2) { + cm.sendNext("#bInvocar um Monstro#k chama um monstro que ataca o grupo adversário, sob seu controle. Use CP para trazer um Monstro Invocado, e ele irá aparecer na mesma área, atacando o grupo oposto."); + } + } else if (status == 64) { + if (select == 0) { + cm.sendNext("Claro, não é tão simples assim. Existem outras maneiras de prevenir o outro grupo de caçar monstros, e cabe a você descobrir como fazê-lo. O que acha? Interessado em uma competição amigável?"); + cm.dispose(); + } else if (select == 1) { + cm.sendNext("Por favor lembre-se. Nunca é uma boa ideia guardar seus CP's. #bOs CP's que você usou irão ajudar a determinar o vencedor e o perdedor da Folia."); + } else if (select == 2) { + cm.sendNext("#bHabilidade#k é uma opção de usar habilidades tais como Escuridão, Fraqueza, e outras para prevenir o grupo oposto de matar outros monstros. São necessários muitos CP's, mas vale muito a pena. O único problema é que eles não duram muito. Use essa tática com sabedoria!"); + } + } else if (status == 65) { + if (select == 1) { + cm.sendNext("Oh, e não se preocupe em tranformar-se em um fantasma. Na Folia de Monstros, #bvocê não perderá EXP após a morte#k. É realmente uma experência como nenhuma outra!"); + cm.dispose(); + } else if (select == 2) { + cm.sendNext("#bProtetor#k é basicamente um item invocado que aumenta drásticamente as habilidades dos monstros invocados pelo seu grupo. Protetor funciona enquanto não for demolido pelo grupo oposto, então eu surigo que você invoque vários monstros primeiro, e então traga o Protetor."); + } + } else if (status == 66) { + cm.sendNext("Por último, enquanto estiver na Folia de Monstros, #bvocê não pode usar items/poções de recuperação que você leva por ai contigo.#k Entretanto, os monstros deixam esses items cair de vez em quando, e #bassim que pegá-los, o item ativará imediatamente#k. É por isso que é importante saber quando pegar estes items."); + cm.dispose(); } } } - - return allDone; } + diff --git a/scripts/npc/2042003.js b/scripts/npc/2042003.js new file mode 100644 index 0000000000..4a475a35ff --- /dev/null +++ b/scripts/npc/2042003.js @@ -0,0 +1,30 @@ +var status = 0; +var request; + +function start() { + status = -1; + action(1, 0, 0); +} + + +function action(mode, type, selection) { + if (mode == -1) { + cm.dispose(); + } else { + if (mode == 0 && status == 0) { + cm.dispose(); + return; + } + if (mode == 1) + status++; + else + status--; + if (status == 0) { + cm.warpParty(980000000); + cm.cancelarSaida(); + cm.dispose(); + } + } +} + + diff --git a/scripts/npc/2042004.js b/scripts/npc/2042004.js new file mode 100644 index 0000000000..fa5965c5bf --- /dev/null +++ b/scripts/npc/2042004.js @@ -0,0 +1,16 @@ +var status = 0; +var request; + +function start() { + status = -1; + action(1, 0, 0); +} + + +function action(mode, type, selection) { + cm.warpParty(980000000); + cm.cancelarSaida(); + cm.dispose(); +} + + diff --git a/scripts/npc/2042005.js b/scripts/npc/2042005.js new file mode 100644 index 0000000000..0cf77cbf77 --- /dev/null +++ b/scripts/npc/2042005.js @@ -0,0 +1,83 @@ +var map = 980030000; +var minLvl = 30; +var maxLvl = 255; +var minAmt = 0; +var maxAmt = 6; + +function start() { + status = -1; + action(1, 0, 0); +} + +function action(mode, type, selection) { + if (mode == -1) { + cm.dispose(); + } else { + if (mode == 0 && status == 0) { + cm.dispose(); + return; + } + if (mode == 1) + status++; + else + status--; + if (status == 0) { + if (cm.getParty() == null) { + status = 10; + cm.sendOk("#eÉ necessário criar um grupo antes de começar o Festival de Monstros!#k"); + } else if (!cm.isLeader()) { + status = 10; + cm.sendOk("Se você quer começar o Festival, avise o #blíder do grupo#k para falar comigo."); + } else { + var party = cm.getParty().getMembers(); + var inMap = cm.partyMembersInMap(); + var lvlOk = 0; + var isInMap = 0; + for (var i = 0; i < party.size(); i++) { + if (party.get(i).getLevel() >= minLvl && party.get(i).getLevel() <= maxLvl) { + lvlOk++; + } + if (party.get(i).getPlayer().getMapId()!= 980030000) { + //isInMap = false; + isInMap++ + } + } + + if (party >= 1) { + status = 10; + cm.sendOk("Você não tem número suficiente de pessoas em seu grupo. Você precisa de um grupo com #b" + minAmt + "#k - #r" + maxAmt + "#k membros e eles devem estar no mapa com você."); + } else if (lvlOk != inMap) { + status = 10; + cm.sendOk("Certifique se todos em seu grupo estão dentre os níveis corretos (" + minLvl + "~" + maxLvl + ")!"); + } else if (isInMap > 0) { + status = 10; + cm.sendOk("Existe alguém do grupo que não esta no mapa!"); + } else { + cm.sendCPQMapLists2(); + } + } + } else if (status == 1) { + if (cm.fieldTaken2(selection)) { + if (cm.fieldLobbied2(selection)) { + cm.challengeParty2(selection); + cm.dispose(); + } else { + cm.sendOk("A sala esta cheia."); + cm.dispose(); + } + } else { + var party = cm.getParty().getMembers(); + if ((selection === 0 || selection === 1 ) && party.size() < 2) { + cm.sendOk("Você precisa de no mínimo 2 player para entrar na competição."); + } else if ((selection === 2 ) && party.size() < 3) { + cm.sendOk("Você precisa de no mínimo 3 player para entrar na competição."); + } else { + cm.cpqLobby2(selection); + } + cm.dispose(); + } + } else if (status == 11) { + cm.dispose(); + } + } +} \ No newline at end of file diff --git a/scripts/npc/2042007.js b/scripts/npc/2042007.js new file mode 100644 index 0000000000..722f0229dc --- /dev/null +++ b/scripts/npc/2042007.js @@ -0,0 +1,132 @@ +importPackage(net.sf.odinms.server.maps); + +var status = 0; +var rnk = -1; + +function start() { + status = -1; + action(1, 0, 0); +} + +function action(mode, type, selection) { + if (mode == -1) { + cm.dispose(); + } else { + if (status >= 0 && mode == 0) { + cm.sendOk("Alright then, I hope we can chat later next time."); + cm.dispose(); + return; + } + if (mode == 1) + status++; + else + status--; + if (cm.getChar().getMap().isCPQLoserMap()) { + if (status == 0) { + if (cm.getChar().getParty() != null) { + var shiu = ""; + if (cm.getPlayer().getFestivalPoints() >= 100) { + shiu += "#rA#k"; + cm.sendOk("Infelizmente, você ou empatou ou perdeu a batalha, apesar da sua excelente performance. A vitória pode ser sua da próxima vez.\r\n\r\n#bNota da Folia de Monstros : " + shiu); + rnk = 10; + } else if (cm.getPlayer().getFestivalPoints() >= 50 && cm.getPlayer().getFestivalPoints() < 100) { + shiu += "#rB#k"; + rnk = 20; + cm.sendOk("Infelizmente, você ou empatou ou perdeu a batalha, mesmo com sua ótima performance. Só mais um pouquinho, e a vitória poderia ter sido sua.\r\n\r\n#bNota da Folia de Monstros : " + shiu); + } else if (cm.getPlayer().getFestivalPoints() >= 30 && cm.getPlayer().getFestivalPoints() < 50) { + shiu += "#rC#k"; + rnk = 30; + cm.sendOk("Infelizmente, você ou empatou ou perdeu a batalha. A vitória está para aqueles que se esforçam. Vejo seus esforços, então a vitória não está tão longe do seu alcance. Continue assim!\r\n\r\n#bNota da Folia de Monstros : " + shiu); + } else { + shiu += "#rD#k"; + rnk = 40; + cm.sendOk("Infelizmente, você ou empatou ou perdeu a batalha, e sua performance claramente reflete nisso. Espero mais de você da próxima vez.\r\n\r\n#bNota da Folia de Monstros : " + shiu); + } + } else { + cm.warp(980030000, 0); + cm.dispose(); + } + } else if (status == 1) { + switch (rnk) { + case 10: + cm.warp(980030000, 0); + cm.gainExp(35000); + cm.dispose(); + break; + case 20: + cm.warp(980030000, 0); + cm.gainExp(25000); + cm.dispose(); + break; + case 30: + cm.warp(980030000, 0); + cm.gainExp(12500); + cm.dispose(); + break; + case 40: + cm.warp(980030000, 0); + cm.gainExp(3500); + cm.dispose(); + break; + default: + cm.warp(980030000, 0); + cm.dispose(); + break; + } + } + } else if (cm.getChar().getMap().isCPQWinnerMap()) { + if (status == 0) { + if (cm.getChar().getParty() != null) { + var shi = ""; + if (cm.getPlayer().getFestivalPoints() >= 300) { + shi += "#rA#k"; + rnk = 1; + cm.sendOk("Parabéns pela sua vitória!!! Que ótima performance! O grupo adversário não pôde fazer nada! Espero o mesmo bom trabalho da próxima vez!\r\n\r\n#bNota da Folia de Monstros : " + shi); + } else if (cm.getPlayer().getFestivalPoints() >= 100 && cm.getPlayer().getFestivalPoints() < 300) { + shi += "#rB#k"; + rnk = 2; + cm.sendOk("Parabéns pela sua vitória! Isso foi impressionante! Você fez um bom trabalho contra o grupo adversário! Só mais um pouco, e você definitivamente vai conseguir um A na próxima vez. \r\n\r\n#bNota da Folia de Monstros : " + shi); + } else if (cm.getPlayer().getFestivalPoints() >= 50 && cm.getPlayer().getFestivalPoints() < 100) { + shi += "#rC#k"; + rnk = 3; + cm.sendOk("Parabéns pela sua vitória. Você fez algumas coisas cá e lá, mas essa não pode ser considerada uma boa vitória. Espero mais de ti da próxima vez.\r\n\r\n#bNota da Folia de Monstros : " + shi); + } else { + shi += "#rD#k"; + rnk = 4; + cm.sendOk("Parabéns pela sua vitória, entretanto sua performance não refletiu muito bem isso. Seja mais ativo na sua próxima participação da Folia de Monstros!\r\n\r\n#bNota da Folia de Monstros : " + shi); + } + } else { + cm.warp(980030000, 0); + cm.dispose(); + } + } else if (status == 1) { + switch (rnk) { + case 1: + cm.warp(980030000, 0); + cm.gainExp(875000); + cm.dispose(); + break; + case 2: + cm.warp(980030000, 0); + cm.gainExp(700000); + cm.dispose(); + break; + case 3: + cm.warp(980030000, 0); + cm.gainExp(555000); + cm.dispose(); + break; + case 4: + cm.warp(980030000, 0); + cm.gainExp(100000); + cm.dispose(); + break; + default: + cm.warp(980030000, 0); + cm.dispose(); + break; + } + } + } + } +} \ No newline at end of file diff --git a/scripts/npc/2042008.js b/scripts/npc/2042008.js new file mode 100644 index 0000000000..d8ec8d8465 --- /dev/null +++ b/scripts/npc/2042008.js @@ -0,0 +1,30 @@ +var status = 0; +var request; + +function start() { + status = -1; + action(1, 0, 0); +} + + +function action(mode, type, selection) { + if (mode == -1) { + cm.dispose(); + } else { + if (mode == 0 && status == 0) { + cm.dispose(); + return; + } + if (mode == 1) + status++; + else + status--; + if (status == 0) { + cm.warpParty(980030000, 4); + cm.cancelarSaida(); + cm.dispose(); + } + } +} + + diff --git a/scripts/npc/2042009.js b/scripts/npc/2042009.js new file mode 100644 index 0000000000..d8ec8d8465 --- /dev/null +++ b/scripts/npc/2042009.js @@ -0,0 +1,30 @@ +var status = 0; +var request; + +function start() { + status = -1; + action(1, 0, 0); +} + + +function action(mode, type, selection) { + if (mode == -1) { + cm.dispose(); + } else { + if (mode == 0 && status == 0) { + cm.dispose(); + return; + } + if (mode == 1) + status++; + else + status--; + if (status == 0) { + cm.warpParty(980030000, 4); + cm.cancelarSaida(); + cm.dispose(); + } + } +} + + diff --git a/scripts/npc/9201002.js b/scripts/npc/9201002.js index b7e8d3b4f3..aa7e970fee 100644 --- a/scripts/npc/9201002.js +++ b/scripts/npc/9201002.js @@ -1,24 +1,24 @@ /* - This file is part of the HeavenMS MapleStory Server - Copyleft (L) 2017 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 . -*/ + This file is part of the HeavenMS MapleStory Server + Copyleft (L) 2017 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 . + */ /* High Priest John - Marriage NPC + Marriage NPC */ importPackage(Packages.constants); @@ -40,14 +40,14 @@ function isWeddingIndoors(mapid) { function getMarriageInstance(player) { var em = cm.getEventManager(weddingEventName); - - for (var iterator = em.getInstances().iterator(); iterator.hasNext();) { + + for (var iterator = em.getInstances().iterator(); iterator.hasNext(); ) { var eim = iterator.next(); - if(eim.isEventLeader(player)) { + if (eim.isEventLeader(player)) { return eim; } } - + return null; } @@ -57,7 +57,7 @@ function detectPlayerItemid(player) { return x; } } - + return -1; } @@ -67,31 +67,35 @@ function getRingId(boxItemId) { function isSuitedForWedding(player, equipped) { var baseid = (player.getGender() == 0) ? 1050131 : 1051150; - - if(equipped) { - for(var i = 0; i < 4; i++) { - if(player.haveItemEquipped(baseid + i)) { + + if (equipped) { + for (var i = 0; i < 4; i++) { + if (player.haveItemEquipped(baseid + i)) { return true; } } } else { - for(var i = 0; i < 4; i++) { - if(player.haveItemWithId(baseid + i, true)) { + for (var i = 0; i < 4; i++) { + if (player.haveItemWithId(baseid + i, true)) { return true; } } } - + return false; } function getWeddingPreparationStatus(player, partner) { - if(!player.haveItem(4000313)) return -3; - if(!partner.haveItem(4000313)) return 3; - - if(!isSuitedForWedding(player, true)) return -4; - if(!isSuitedForWedding(partner, true)) return 4; - + if (!player.haveItem(4000313)) + return -3; + if (!partner.haveItem(4000313)) + return 3; + + if (!isSuitedForWedding(player, true)) + return -4; + if (!isSuitedForWedding(partner, true)) + return 4; + var hasEngagement = false; for (var x = 4031357; x <= 4031364; x++) { if (player.haveItem(x)) { @@ -99,7 +103,8 @@ function getWeddingPreparationStatus(player, partner) { break; } } - if(!hasEngagement) return -1; + if (!hasEngagement) + return -1; hasEngagement = false; for (var x = 4031357; x <= 4031364; x++) { @@ -108,24 +113,28 @@ function getWeddingPreparationStatus(player, partner) { break; } } - if(!hasEngagement) return -2; + if (!hasEngagement) + return -2; - if(!player.canHold(1112803)) return 1; - if(!partner.canHold(1112803)) return 2; + if (!player.canHold(1112803)) + return 1; + if (!partner.canHold(1112803)) + return 2; return 0; } function giveCoupleBlessings(eim, player, partner) { var blessCount = eim.gridSize(); - + player.gainExp(blessCount * weddingBlessingExp); partner.gainExp(blessCount * weddingBlessingExp); } -function start() { +function start() { weddingIndoors = isWeddingIndoors(cm.getMapId()); - if(weddingIndoors) eim = cm.getEventInstance(); + if (weddingIndoors) + eim = cm.getEventInstance(); status = -1; action(1, 0, 0); @@ -144,8 +153,8 @@ function action(mode, type, selection) { else status--; - if(!weddingIndoors) { - if(status == 0) { + if (!weddingIndoors) { + if (status == 0) { var hasEngagement = false; for (var x = 4031357; x <= 4031364; x++) { if (cm.haveItem(x, 1)) { @@ -154,7 +163,7 @@ function action(mode, type, selection) { } } - if(hasEngagement) { + if (hasEngagement) { var text = "Hi there. How can I help you?"; var choice = new Array("We're ready to get married."); for (x = 0; x < choice.length; x++) { @@ -165,32 +174,32 @@ function action(mode, type, selection) { cm.sendOk("Hmm, today two fluttering hearts are about to be joined together by the blessings of love!"); cm.dispose(); } - } else if(status == 1) { + } else if (status == 1) { var wid = cm.getClient().getWorldServer().getRelationshipId(cm.getPlayer().getId()); var cserv = cm.getClient().getChannelServer(); - if(cserv.isWeddingReserved(wid)) { - if(wid == cserv.getOngoingWedding(cathedralWedding)) { + if (cserv.isWeddingReserved(wid)) { + if (wid == cserv.getOngoingWedding(cathedralWedding)) { var partner = cserv.getPlayerStorage().getCharacterById(cm.getPlayer().getPartnerId()); - if(!(partner == null || !cm.getMap().equals(partner.getMap()))) { - if(!cm.canHold(4000313)) { + if (!(partner == null || !cm.getMap().equals(partner.getMap()))) { + if (!cm.canHold(4000313)) { cm.sendOk("Please have a free ETC slot available to get the #b#t4000313##k."); cm.dispose(); return; - } else if(!partner.canHold(4000313)) { + } else if (!partner.canHold(4000313)) { cm.sendOk("Please let your partner know they must have a free ETC slot available to get the #b#t4000313##k."); cm.dispose(); return; - } else if(!isSuitedForWedding(cm.getPlayer(), false)) { + } else if (!isSuitedForWedding(cm.getPlayer(), false)) { cm.sendOk("Please purchase a #rwedding garment#k for the ceremony, quickly! Without it I am not able to marry you."); cm.dispose(); return; - } else if(!isSuitedForWedding(partner, false)) { + } else if (!isSuitedForWedding(partner, false)) { cm.sendOk("Please let your partner know they must have a #rwedding garment#k ready for the ceremony."); cm.dispose(); return; } - + cm.sendOk("Very well, the preparatives here are finished too. This indeed is a beautiful day, you two are truly blessed to marry on such a day. Let us begin the marriage!!"); } else { cm.sendOk("Hmm, it seems your partner is elsewhere... Please let them come here before starting the ceremony."); @@ -206,19 +215,19 @@ function action(mode, type, selection) { cm.sendOk("Hmm, I'm sorry but there are no reservations made for you at this channel for the time being."); cm.dispose(); } - } else if(status == 2) { + } else if (status == 2) { var cserv = cm.getClient().getChannelServer(); var wtype = cserv.getOngoingWeddingType(cathedralWedding); - + var partner = cserv.getPlayerStorage().getCharacterById(cm.getPlayer().getPartnerId()); - if(!(partner == null || !cm.getMap().equals(partner.getMap()))) { - if(cserv.acceptOngoingWedding(cathedralWedding)) { + if (!(partner == null || !cm.getMap().equals(partner.getMap()))) { + if (cserv.acceptOngoingWedding(cathedralWedding)) { var wid = cm.getClient().getWorldServer().getRelationshipId(cm.getPlayer().getId()); - if(wid > 0) { + if (wid > 0) { var em = cm.getEventManager(weddingEventName); - if(em.startInstance(cm.getPlayer())) { + if (em.startInstance(cm.getPlayer())) { eim = getMarriageInstance(cm.getPlayer()); - if(eim != null) { + if (eim != null) { eim.setIntProperty("weddingId", wid); eim.setIntProperty("groomId", cm.getPlayer().getId()); eim.setIntProperty("brideId", cm.getPlayer().getPartnerId()); @@ -248,20 +257,20 @@ function action(mode, type, selection) { } } else { if (status == 0) { - if(eim == null) { - cm.warp(680000000,0); + if (eim == null) { + cm.warp(680000000, 0); cm.dispose(); return; } - + var playerId = cm.getPlayer().getId(); - if(playerId == eim.getIntProperty("groomId") || playerId == eim.getIntProperty("brideId")) { + if (playerId == eim.getIntProperty("groomId") || playerId == eim.getIntProperty("brideId")) { var wstg = eim.getIntProperty("weddingStage"); - - if(wstg == 2) { + + if (wstg == 2) { cm.sendYesNo("Very well, the guests has bestowed all their blessings to you now. The time has come, #rshould I make you Husband and Wife#k?"); state = 1; - } else if(wstg == 1) { + } else if (wstg == 1) { cm.sendOk("While you two are making your wedding vows to each other, your guests are currently giving their blessings to you. This is a time of happiness for both of you, please rejoice the ceremony."); cm.dispose(); } else { @@ -270,12 +279,12 @@ function action(mode, type, selection) { } } else { var wstg = eim.getIntProperty("weddingStage"); - if(wstg == 1) { - if(eim.gridCheck(cm.getPlayer()) != -1) { + if (wstg == 1) { + if (eim.gridCheck(cm.getPlayer()) != -1) { cm.sendOk("Everyone give your blessings to this lovely couple!"); cm.dispose(); } else { - if(eim.getIntProperty("guestBlessings") == 1) { + if (eim.getIntProperty("guestBlessings") == 1) { cm.sendYesNo("Do you want to bless this couple?"); state = 0; } else { @@ -283,7 +292,7 @@ function action(mode, type, selection) { cm.dispose(); } } - } else if(wstg == 3) { + } else if (wstg == 3) { cm.sendOk("The two loving birds are now married. What a lively day! Please #rget ready for the afterparty#k, it should start soon. Follow the married couple's lead."); cm.dispose(); } else { @@ -292,10 +301,10 @@ function action(mode, type, selection) { } } } else if (status == 1) { - if(state == 0) { // give player blessings + if (state == 0) { // give player blessings eim.gridInsert(cm.getPlayer(), 1); - - if(ServerConstants.WEDDING_BLESSER_SHOWFX) { + + if (ServerConstants.WEDDING_BLESSER_SHOWFX) { var target = cm.getPlayer(); target.announce(MaplePacketCreator.showSpecialEffect(9)); target.getMap().broadcastMessage(target, MaplePacketCreator.showForeignEffect(target.getId(), 9), false); @@ -308,15 +317,15 @@ function action(mode, type, selection) { target.announce(MaplePacketCreator.showSpecialEffect(9)); target.getMap().broadcastMessage(target, MaplePacketCreator.showForeignEffect(target.getId(), 9), false); } - + cm.sendOk("Your blessings have been added to their love. What a noble act for a lovely couple!"); cm.dispose(); } else { // couple wants to complete the wedding var wstg = eim.getIntProperty("weddingStage"); - - if(wstg == 2) { + + if (wstg == 2) { var pid = cm.getPlayer().getPartnerId(); - if(pid <= 0) { + if (pid <= 0) { cm.sendOk("It seems you are no longer engaged to your partner, just before the altar... Where did all that happiness you two had sported a while ago went?"); cm.dispose(); return; @@ -324,14 +333,14 @@ function action(mode, type, selection) { var player = cm.getPlayer(); var partner = cm.getMap().getCharacterById(cm.getPlayer().getPartnerId()); - if(partner != null) { + if (partner != null) { state = getWeddingPreparationStatus(player, partner); - switch(state) { + switch (state) { case 0: var pid = eim.getIntProperty("confirmedVows"); - if(pid != -1) { - if(pid == player.getId()) { + if (pid != -1) { + if (pid == player.getId()) { cm.sendOk("You have already confirmed your vows. All that is left is for your partner to confirm now."); } else { eim.setIntProperty("weddingStage", 3); @@ -362,7 +371,7 @@ function action(mode, type, selection) { eim.setIntProperty("confirmedVows", player.getId()); cm.getMap().dropMessage(6, "Wedding Assistant: " + player.getName() + " has confirmed vows! Alright, one step away to make it official. Tighten your seatbelts!"); } - + break; case -1: @@ -376,7 +385,7 @@ function action(mode, type, selection) { case -3: cm.sendOk("It seems you don't have the #r#t4000313##k given at the entrance... Please find it, I can't marry you without that item in hands."); break; - + case -4: cm.sendOk("Pardon my rudiness, but the garments are a essential part of the ceremony. Please #rsuit yourself properly#k for a wedding."); break; @@ -392,7 +401,7 @@ function action(mode, type, selection) { case 3: cm.sendOk("It seems your partner don't have the #r#t4000313##k given at the entrance... Please find it, I can't marry you without that item in hands."); break; - + case 4: cm.sendOk("It seems your partner is not properly dressed for the wedding... Pardon my rudiness, but the garments are a essential part of the ceremony."); break; diff --git a/scripts/npc/9201006.js b/scripts/npc/9201006.js index 2a37253361..ec23bcf5fb 100644 --- a/scripts/npc/9201006.js +++ b/scripts/npc/9201006.js @@ -50,6 +50,7 @@ function action(mode, type, selection) { var eim = cm.getEventInstance(); if(eim == null) { cm.warp(680000000,0); + //cm.criarLista(); cm.dispose(); return; } @@ -71,7 +72,7 @@ function action(mode, type, selection) { cm.sendOk("Congratulations on your wedding. Please talk to #b#p9201007##k to start the afterparty."); cm.dispose(); } else if(hasEngagement) { - cm.sendOk("Please continue with the wedding."); + cm.criarLista(); cm.dispose(); } else { cm.sendOk("You do not have the required item to continue through this wedding. Unfortunately, it's over..."); diff --git a/scripts/npc/9201014.js b/scripts/npc/9201014.js index 9fd36866af..7d1bc9da2f 100644 --- a/scripts/npc/9201014.js +++ b/scripts/npc/9201014.js @@ -27,75 +27,25 @@ 1.0 - First Version by Angel 2.0 - Second Version by happydud3 & XotiCraze 3.0 - Third Version by RonanLana (HeavenMS) + 4.0 - Four Version bby Drago(MapleStorySA) --------------------------------------------------------------------------------------------------- **/ - -var bgPrizes = [[2022179,10], [2022282,10], [2210005,5], [2210003,5]]; -var cmPrizes = [[2022011,10], [2000005,50], [2022273,10], [2022179,3]]; - -var status; +var status = -1; function start() { status = -1; action(1, 0, 0); } -function action(mode, type, selection) { - if (mode == -1 || mode == 0) { - cm.sendOk("Goodbye then."); - cm.dispose(); - return; - } else if (mode == 1) { +function action(mode, type, selection) { + if (mode == 1) { status++; } else { - status--; + cm.dispose(); + return; } - if (status == 0) { - var msg = "Hello I exchange Onyx Chest for Bride and Groom and the Onyx Chest for prizes!#b"; - var choice1 = new Array("I have an Onyx Chest for Bride and Groom", "I have an Onyx Chest"); - for (var i = 0; i < choice1.length; i++) { - msg += "\r\n#L" + i + "#" + choice1[i] + "#l"; - } - cm.sendSimple(msg); - } else if (status == 1) { - if (selection == 0) { - if (cm.haveItem(4031424)) { - if (cm.getPlayer().isMarried()) { // thanks MedicOP for solving an issue here - if(cm.getInventory(2).getNextFreeSlot() >= 0) { - var rand = Math.floor(Math.random() * bgPrizes.length); - cm.gainItem(bgPrizes[rand][0], bgPrizes[rand][1]); - - cm.gainItem(4031424,-1); - cm.dispose(); - } else { - cm.sendOk("You don't have a free USE slot right now."); - cm.dispose(); - } - } else { - cm.sendOk("You must be married to claim the prize for this box."); - cm.dispose(); - } - } else { - cm.sendOk("You don't have an Onyx Chest for Bride and Groom."); - cm.dispose(); - } - } else if (selection == 1) { - if (cm.haveItem(4031423)) { - if(cm.getInventory(2).getNextFreeSlot() >= 0) { - var rand = Math.floor(Math.random() * cmPrizes.length); - cm.gainItem(cmPrizes[rand][0], cmPrizes[rand][1]); - - cm.gainItem(4031423,-1); - cm.dispose(); - } else { - cm.sendOk("You don't have a free USE slot right now."); - cm.dispose(); - } - } else { - cm.sendOk("You don't have an Onyx Chest."); - cm.dispose(); - } - } + cm.enviarLista(); + cm.dispose(); } -} +} \ No newline at end of file diff --git a/scripts/npc/cpqchallenge.js b/scripts/npc/cpqchallenge.js new file mode 100644 index 0000000000..2a1fe89c04 --- /dev/null +++ b/scripts/npc/cpqchallenge.js @@ -0,0 +1,54 @@ +/* global cm */ + +var status = 0; +var party; + +function start(chrs) { + status = -1; + party = chrs; + action(1, 0, 0); +} + +function action(mode, type, selection) { + if (mode == -1) { + cm.getChar().setChallenged(false); + cm.dispose(); + } else { + if (mode == 0) { + cm.sendOk("Come back once you have thought about it some more."); + cm.getChar().setChallenged(false); + cm.dispose(); + return; + } + } + if (mode == -1) + cm.dispose(); + else { + if (mode == 1) + status++; + else + status--; + if (status == 0) { + if (cm.getParty().getMembers().size() == party.size()) { + cm.getPlayer().setChallenged(true); + var snd = ""; + for (var i = 0; i < party.size(); i++) + snd += "#bNome: " + party.get(i).getName() + " / (Level: " + party.get(i).getLevel() + ") / " + party.get(i).getJobNameById(party.get(i).getJobId()) + "#k\r\n\r\n"; + cm.sendAcceptDecline(snd + "Gostaria de lutar contra este grupo no Festival de Monstros?"); + } else { + return; + } + } else if (status == 1) { + var ch = cm.getChrById(party.get(0).getId()); + if (party.size() == cm.getParty().getMembers().size()) { + cm.startCPQ(ch, ch.getMapId() + 1); + ch.getParty().setEnemy(cm.getPlayer().getParty()); + cm.getChar().getParty().setEnemy(ch.getParty()); + cm.getChar().setChallenged(false); + } else { + cm.sendOk("O numero de players entre os times não esta igual."); + } + cm.dispose(); + } + } +} \ No newline at end of file diff --git a/scripts/npc/cpqchallenge2.js b/scripts/npc/cpqchallenge2.js new file mode 100644 index 0000000000..8795e8467a --- /dev/null +++ b/scripts/npc/cpqchallenge2.js @@ -0,0 +1,48 @@ +var status = 0; +var party; + +function start(chrs) { + status = -1; + party = chrs; + action(1, 0, 0); +} + +function action(mode, type, selection) { + if (mode == -1) { + cm.getChar().setChallenged(false); + cm.dispose(); + } else { + if (mode == 0) { + cm.sendOk("Come back once you have thought about it some more."); + cm.getChar().setChallenged(false); + cm.dispose(); + return; + } + } + if (mode == -1) + cm.dispose(); + else { + if (mode == 1) + status++; + else + status--; + if (status == 0) { + if (cm.getParty().getMembers().size() == party.size()) { + cm.getPlayer().setChallenged(true); + var snd = ""; + for (var i = 0; i < party.size(); i++) + snd += "#bNome: " + party.get(i).getName() + " / (Level: " + party.get(i).getLevel() + ") / " + party.get(i).getJobNameById(party.get(i).getJobId()) + "#k\r\n\r\n"; + cm.sendAcceptDecline(snd + "Gostaria de lutar contra este grupo no Festival de Monstros?"); + } else { + return; + } + } else if (status == 1) { + var ch = cm.getChrById(party.get(0).getId()); + cm.startCPQ2(ch, ch.getMapId() + 1); + ch.getParty().setEnemy(cm.getPlayer().getParty()); + cm.getChar().getParty().setEnemy(ch.getParty()); + cm.getChar().setChallenged(false); + cm.dispose(); + } + } +} \ No newline at end of file diff --git a/scripts/portal/MC2revive.js b/scripts/portal/MC2revive.js new file mode 100644 index 0000000000..07e4002729 --- /dev/null +++ b/scripts/portal/MC2revive.js @@ -0,0 +1,8 @@ +function enter(pi) { + if ( pi.getPlayer().getTeam() == 0 ) { + pi.warp( pi.getMapId() - 100); + } else { + pi.warp( pi.getMapId() - 100); + } + return true; +} \ No newline at end of file diff --git a/scripts/portal/MCRevive1.js b/scripts/portal/MCRevive1.js new file mode 100644 index 0000000000..6b83b15910 --- /dev/null +++ b/scripts/portal/MCRevive1.js @@ -0,0 +1,10 @@ +importPackage(Packages.server.maps); + +/* + [CelticMS] Monster Carnival Reviving Field 1 + */ + +function enter(pi) { + pi.warp(980000101, 0); + return true; +} diff --git a/scripts/portal/MCRevive2.js b/scripts/portal/MCRevive2.js new file mode 100644 index 0000000000..333958c6d2 --- /dev/null +++ b/scripts/portal/MCRevive2.js @@ -0,0 +1,10 @@ +importPackage(Packages.server.maps); + +/* + [CelticMS] Monster Carnival Reviving Field 1 + */ + +function enter(pi) { + pi.warp(980000201, 0); + return true; +} diff --git a/scripts/portal/MCRevive3.js b/scripts/portal/MCRevive3.js new file mode 100644 index 0000000000..2ec50bacda --- /dev/null +++ b/scripts/portal/MCRevive3.js @@ -0,0 +1,19 @@ +importPackage(Packages.server.maps); + +/* +[CelticMS] Monster Carnival Reviving Field 1 +*/ + +function enter(pi) { + var portal = 0; + switch (pi.getPlayer().getTeam()) { + case 0: + portal = 4; + break; + case 1: + portal = 3; + break; + } + pi.warp(980000301, portal); + return true; +} diff --git a/scripts/portal/MCRevive4.js b/scripts/portal/MCRevive4.js new file mode 100644 index 0000000000..95fc0f1ad7 --- /dev/null +++ b/scripts/portal/MCRevive4.js @@ -0,0 +1,19 @@ +importPackage(Packages.server.maps); + +/* +[CelticMS] Monster Carnival Reviving Field 1 +*/ + +function enter(pi) { + var portal = 0; + switch (pi.getPlayer().getTeam()) { + case 0: + portal = 4; + break; + case 1: + portal = 3; + break; + } + pi.warp(980000401, portal); + return true; +} diff --git a/scripts/portal/MCRevive5.js b/scripts/portal/MCRevive5.js new file mode 100644 index 0000000000..7ced4ab4be --- /dev/null +++ b/scripts/portal/MCRevive5.js @@ -0,0 +1,10 @@ +importPackage(Packages.server.maps); + +/* +[CelticMS] Monster Carnival Reviving Field 1 +*/ + +function enter(pi) { + pi.warp(980000501, 0); + return true; +} diff --git a/scripts/portal/MCRevive6.js b/scripts/portal/MCRevive6.js new file mode 100644 index 0000000000..26c1a63ca0 --- /dev/null +++ b/scripts/portal/MCRevive6.js @@ -0,0 +1,10 @@ +importPackage(Packages.server.maps); + +/* +[CelticMS] Monster Carnival Reviving Field 1 +*/ + +function enter(pi) { + pi.warp(980000601, 0); + return true; +} diff --git a/scripts/portal/mc_out.js b/scripts/portal/mc_out.js index 28ab17cf5b..cc38a8f14b 100644 --- a/scripts/portal/mc_out.js +++ b/scripts/portal/mc_out.js @@ -1,28 +1,35 @@ /* - This file is part of the OdinMS Maple Story Server - Copyright (C) 2008 Patrick Huy - Matthias Butz - Jan Christian Meyer + This file is part of the OdinMS Maple Story Server + Copyright (C) 2008 Patrick Huy + Matthias Butz + Jan Christian Meyer + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License version 3 + as published by the Free Software Foundation. You may not use, modify + or distribute this program under any other version of the + GNU Affero General Public License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License version 3 - as published by the Free Software Foundation. You may not use, modify - or distribute this program under any other version of the - GNU Affero General Public License. +importPackage(Packages.server.maps); - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ /* -Author: kevintjuh93 -*/ + */ function enter(pi) { - pi.playPortalSound(); pi.warp(pi.getPlayer().getSavedLocation("MIRROR")); + var returnMap = pi.getPlayer().getSavedLocation("MONSTER_CARNIVAL"); + if (returnMap < 0) { + returnMap = 102000000; // Just Incase there is no saved location. + } + var target = pi.getPlayer().getClient().getChannelServer().getMapFactory().getMap(returnMap); + pi.getPlayer().changeMap(target); return true; } \ No newline at end of file diff --git a/scripts/reactor/9980000.js b/scripts/reactor/9980000.js index 2524923a6e..278c67dfea 100644 --- a/scripts/reactor/9980000.js +++ b/scripts/reactor/9980000.js @@ -1,28 +1,3 @@ -/* - * This file is part of the OdinMS Maple Story Server - Copyright (C) 2008 Patrick Huy - Matthias Butz - Jan Christian Meyer - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License version 3 - as published by the Free Software Foundation. You may not use, modify - or distribute this program under any other version of the - GNU Affero General Public License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - */ - -/* -@Author kevintjuh93 -*/ - function act() { - rm.getReactor().removeMonsterStatus(); + rm.dispelAllMonsters(parseInt(rm.getReactor().getName().substring(1,2)), parseInt(rm.getReactor().getName().substring(0,1))); } \ No newline at end of file diff --git a/scripts/reactor/9980001.js b/scripts/reactor/9980001.js index 2524923a6e..278c67dfea 100644 --- a/scripts/reactor/9980001.js +++ b/scripts/reactor/9980001.js @@ -1,28 +1,3 @@ -/* - * This file is part of the OdinMS Maple Story Server - Copyright (C) 2008 Patrick Huy - Matthias Butz - Jan Christian Meyer - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License version 3 - as published by the Free Software Foundation. You may not use, modify - or distribute this program under any other version of the - GNU Affero General Public License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - */ - -/* -@Author kevintjuh93 -*/ - function act() { - rm.getReactor().removeMonsterStatus(); + rm.dispelAllMonsters(parseInt(rm.getReactor().getName().substring(1,2)), parseInt(rm.getReactor().getName().substring(0,1))); } \ No newline at end of file diff --git a/sql/db_database.sql b/sql/db_database.sql index aaaf8c9f6b..cba5708fd7 100644 --- a/sql/db_database.sql +++ b/sql/db_database.sql @@ -42,6 +42,7 @@ CREATE TABLE IF NOT EXISTS `accounts` ( `rewardpoints` int(11) NOT NULL DEFAULT '0', `votepoints` int(11) NOT NULL DEFAULT '0', `hwid` varchar(12) NOT NULL DEFAULT '', + `lingua` int(1) NOT NULL DEFAULT '2', PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`), KEY `ranking1` (`id`,`banned`), @@ -17452,7 +17453,7 @@ CREATE TABLE IF NOT EXISTS `rings` ( CREATE TABLE IF NOT EXISTS `savedlocations` ( `id` int(11) NOT NULL AUTO_INCREMENT, `characterid` int(11) NOT NULL, - `locationtype` enum('FREE_MARKET','WORLDTOUR','FLORINA','INTRO','SUNDAY_MARKET','MIRROR','EVENT','BOSSPQ','HAPPYVILLE','DEVELOPER') NOT NULL, + `locationtype` enum('FREE_MARKET','WORLDTOUR','FLORINA','INTRO','SUNDAY_MARKET','MIRROR','EVENT','BOSSPQ','HAPPYVILLE','DEVELOPER','MONSTER_CARNIVAL') NOT NULL, `map` int(11) NOT NULL, `portal` int(11) NOT NULL, PRIMARY KEY (`id`) diff --git a/src/client/MapleCharacter.java b/src/client/MapleCharacter.java index ccc2792c6b..818514ab69 100644 --- a/src/client/MapleCharacter.java +++ b/src/client/MapleCharacter.java @@ -130,6 +130,7 @@ import client.processor.FredrickProcessor; import constants.ExpTable; import constants.GameConstants; import constants.ItemConstants; +import constants.LinguaConstants; import constants.ServerConstants; import constants.skills.Aran; import constants.skills.Beginner; @@ -276,6 +277,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject { private ScheduledFuture extraRecoveryTask = null; private ScheduledFuture chairRecoveryTask = null; private ScheduledFuture pendantOfSpirit = null; //1122017 + public ScheduledFuture timer; private Lock chrLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHARACTER_CHR, true); private Lock evtLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHARACTER_EVT, true); private Lock petLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHARACTER_PET, true); @@ -387,24 +389,22 @@ public class MapleCharacter extends AbstractMapleCharacterObject { if(jobtype == MapleJob.WARRIOR.getId() / 100 || jobtype == MapleJob.DAWNWARRIOR1.getId() / 100 || jobtype == MapleJob.ARAN1.getId() / 100) { return(MapleJob.WARRIOR); - } - - else if(jobtype == MapleJob.MAGICIAN.getId() / 100 || jobtype == MapleJob.BLAZEWIZARD1.getId() / 100 || jobtype == MapleJob.EVAN1.getId() / 100) { + } else if(jobtype == MapleJob.MAGICIAN.getId() / 100 || jobtype == MapleJob.BLAZEWIZARD1.getId() / 100 || jobtype == MapleJob.EVAN1.getId() / 100) { return(MapleJob.MAGICIAN); - } - - else if(jobtype == MapleJob.BOWMAN.getId() / 100 || jobtype == MapleJob.WINDARCHER1.getId() / 100) { - if(jobid / 10 == MapleJob.CROSSBOWMAN.getId() / 10) return(MapleJob.CROSSBOWMAN); - else return(MapleJob.BOWMAN); - } - - else if(jobtype == MapleJob.THIEF.getId() / 100 || jobtype == MapleJob.NIGHTWALKER1.getId() / 100) { + } else if(jobtype == MapleJob.BOWMAN.getId() / 100 || jobtype == MapleJob.WINDARCHER1.getId() / 100) { + if(jobid / 10 == MapleJob.CROSSBOWMAN.getId() / 10) { + return(MapleJob.CROSSBOWMAN); + } else { + return(MapleJob.BOWMAN); + } + } else if(jobtype == MapleJob.THIEF.getId() / 100 || jobtype == MapleJob.NIGHTWALKER1.getId() / 100) { return(MapleJob.THIEF); - } - - else if(jobtype == MapleJob.PIRATE.getId() / 100 || jobtype == MapleJob.THUNDERBREAKER1.getId() / 100) { - if(opt == (byte) 0x80) return(MapleJob.BRAWLER); - else return(MapleJob.GUNSLINGER); + } else if(jobtype == MapleJob.PIRATE.getId() / 100 || jobtype == MapleJob.THUNDERBREAKER1.getId() / 100) { + if(opt == (byte) 0x80) { + return(MapleJob.BRAWLER); + } else { + return(MapleJob.GUNSLINGER); + } } return(MapleJob.BEGINNER); @@ -450,8 +450,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject { selectedKey = GameConstants.getCustomKey(true); selectedType = GameConstants.getCustomType(true); selectedAction = GameConstants.getCustomAction(true); - } - else { + } else { selectedKey = GameConstants.getCustomKey(false); selectedType = GameConstants.getCustomType(false); selectedAction = GameConstants.getCustomAction(false); @@ -919,7 +918,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } public void removeSandboxItems() { // sandbox idea thanks to Morty - if(!hasSandboxItem) return; + if (!hasSandboxItem) { + return; + } MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); for(MapleInventoryType invType : MapleInventoryType.values()) { @@ -1027,7 +1028,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { if (skillId != 0) { Skill skill = SkillFactory.getSkill(skillId); final int skilllevel = getSkillLevel(skill); - if(skilllevel > 0) continue; + if (skilllevel > 0) { + continue; + } changeSkillLevel(skill, (byte) 0, 10, -1); } @@ -1211,12 +1214,16 @@ public class MapleCharacter extends AbstractMapleCharacterObject { private void eventChangedMap(int map) { EventInstanceManager eim = getEventInstance(); - if (eim != null) eim.changedMap(this, map); + if (eim != null) { + eim.changedMap(this, map); + } } private void eventAfterChangedMap(int map) { EventInstanceManager eim = getEventInstance(); - if (eim != null) eim.afterChangedMap(this, map); + if (eim != null) { + eim.afterChangedMap(this, map); + } } public boolean canRecoverLastBanish() { @@ -1242,7 +1249,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { public void changeMapBanish(int mapid, String portal, String msg) { if(ServerConstants.USE_SPIKES_AVOID_BANISH) { for(Item it: this.getInventory(MapleInventoryType.EQUIPPED).list()) { - if((it.getFlag() & ItemConstants.SPIKES) == ItemConstants.SPIKES) return; + if((it.getFlag() & ItemConstants.SPIKES) == ItemConstants.SPIKES) { + return; + } } } @@ -1250,7 +1259,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { int banSp = this.getMap().findClosestPlayerSpawnpoint(this.getPosition()).getId(); long banTime = System.currentTimeMillis(); - if (msg != null) dropMessage(5, msg); + if (msg != null) { + dropMessage(5, msg); + } MapleMap map_ = getWarpMap(mapid); MaplePortal portal_ = map_.getPortal(portal); @@ -1328,7 +1339,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { canWarpMap = false; canWarpCounter--; - if(canWarpCounter == 0) canWarpMap = true; + if(canWarpCounter == 0) { + canWarpMap = true; + } eventAfterChangedMap(this.getMapId()); } @@ -1342,7 +1355,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { canWarpMap = false; canWarpCounter--; - if(canWarpCounter == 0) canWarpMap = true; + if(canWarpCounter == 0) { + canWarpMap = true; + } eventAfterChangedMap(this.getMapId()); } @@ -1372,7 +1387,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { canWarpMap = false; canWarpCounter--; - if(canWarpCounter == 0) canWarpMap = true; + if(canWarpCounter == 0) { + canWarpMap = true; + } eventAfterChangedMap(this.getMapId()); } @@ -1590,7 +1607,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } private void changeMapInternal(final MapleMap to, final Point pos, final byte[] warpPacket) { - if(!canWarpMap) return; + if (!canWarpMap) { + return; + } this.mapTransitioning.set(true); @@ -1599,6 +1618,12 @@ public class MapleCharacter extends AbstractMapleCharacterObject { MapleTrade.cancelTrade(this, MapleTrade.TradeResult.UNSUCCESSFUL_ANOTHER_MAP); this.closePlayerInteractions(); + MapleParty e = null; + if (this.getParty() != null && this.getParty().getEnemy() != null) { + e = this.getParty().getEnemy(); + } + final MapleParty k = e; + client.announce(warpPacket); map.removePlayer(this); if (client.getChannelServer().getPlayerStorage().getCharacterById(getId()) != null) { @@ -1617,9 +1642,14 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } finally { prtLock.unlock(); } + if (MapleCharacter.this.getParty() != null) { + MapleCharacter.this.getParty().setEnemy(k); + } silentPartyUpdateInternal(getParty()); // EIM script calls inside - if (getMap().getHPDec() > 0) resetHpDecreaseTask(); + if (getMap().getHPDec() > 0) { + resetHpDecreaseTask(); + } } else { FilePrinter.printError(FilePrinter.MAPLE_MAP, "Character " + this.getName() + " got stuck when moving to map " + map.getId() + "."); } @@ -1702,11 +1732,16 @@ public class MapleCharacter extends AbstractMapleCharacterObject { berserkSchedule = TimerManager.getInstance().register(new Runnable() { @Override public void run() { - if(awayFromWorld.get()) return; + if (awayFromWorld.get()) { + return; + } client.announce(MaplePacketCreator.showOwnBerserk(skilllevel, berserk)); - if(!isHidden) getMap().broadcastMessage(MapleCharacter.this, MaplePacketCreator.showBerserk(getId(), skilllevel, berserk), false); - else getMap().broadcastGMMessage(MapleCharacter.this, MaplePacketCreator.showBerserk(getId(), skilllevel, berserk), false); + if (!isHidden) { + getMap().broadcastMessage(MapleCharacter.this, MaplePacketCreator.showBerserk(getId(), skilllevel, berserk), false); + } else { + getMap().broadcastGMMessage(MapleCharacter.this, MaplePacketCreator.showBerserk(getId(), skilllevel, berserk), false); + } } }, 5000, 3000); } @@ -2111,7 +2146,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } } - if(con.isClosed()) con = DatabaseConnection.getConnection(); //wtf tho + if (con.isClosed()) { //wtf tho + con = DatabaseConnection.getConnection(); + } try (PreparedStatement ps = con.prepareStatement("DELETE FROM wishlists WHERE charid = ?")) { ps.setInt(1, cid); @@ -2323,7 +2360,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } private void startChairTask() { - if (chair.get() == 0) return; + if (chair.get() == 0) { + return; + } int healInterval; effLock.lock(); @@ -2504,7 +2543,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { chrLock.lock(); try { // Poison damage visibility and diseases status visibility, extended through map transitions thanks to Ronan - if(!this.isLoggedinWorld()) return; + if (!this.isLoggedinWorld()) { + return; + } chrDiseases = new LinkedHashSet<>(diseases.entrySet()); } finally { @@ -2516,8 +2557,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject { MobSkill skill = di.getValue().getRight(); final List> debuff = Collections.singletonList(new Pair<>(disease, Integer.valueOf(skill.getX()))); - if(disease != MapleDisease.SLOW) map.broadcastMessage(MaplePacketCreator.giveForeignDebuff(id, debuff, skill)); - else map.broadcastMessage(MaplePacketCreator.giveForeignSlowDebuff(id, debuff, skill)); + if (disease != MapleDisease.SLOW) { + map.broadcastMessage(MaplePacketCreator.giveForeignDebuff(id, debuff, skill)); + } else { + map.broadcastMessage(MaplePacketCreator.giveForeignSlowDebuff(id, debuff, skill)); + } } } @@ -2545,8 +2589,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject { final List> debuff = Collections.singletonList(new Pair<>(disease, Integer.valueOf(skill.getX()))); client.announce(MaplePacketCreator.giveDebuff(debuff, skill)); - if(disease != MapleDisease.SLOW) map.broadcastMessage(this, MaplePacketCreator.giveForeignDebuff(id, debuff, skill), false); - else map.broadcastMessage(this, MaplePacketCreator.giveForeignSlowDebuff(id, debuff, skill), false); + if (disease != MapleDisease.SLOW) { + map.broadcastMessage(this, MaplePacketCreator.giveForeignDebuff(id, debuff, skill), false); + } else { + map.broadcastMessage(this, MaplePacketCreator.giveForeignSlowDebuff(id, debuff, skill), false); + } } } @@ -2555,8 +2602,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject { long mask = debuff.getValue(); announce(MaplePacketCreator.cancelDebuff(mask)); - if(debuff != MapleDisease.SLOW) map.broadcastMessage(this, MaplePacketCreator.cancelForeignDebuff(id, mask), false); - else map.broadcastMessage(this, MaplePacketCreator.cancelForeignSlowDebuff(id), false); + if (debuff != MapleDisease.SLOW) { + map.broadcastMessage(this, MaplePacketCreator.cancelForeignDebuff(id, mask), false); + } else { + map.broadcastMessage(this, MaplePacketCreator.cancelForeignSlowDebuff(id), false); + } chrLock.lock(); try { @@ -2871,6 +2921,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } public enum FameStatus { + OK, NOT_TODAY, NOT_THIS_MONTH } @@ -2920,8 +2971,14 @@ public class MapleCharacter extends AbstractMapleCharacterObject { party *= 0.5; } - if(gain < 0) gain = Integer.MAX_VALUE; // integer overflow, heh. - if(party < 0) party = Integer.MAX_VALUE; // integer overflow, heh. + if(gain < 0) { + gain = Integer.MAX_VALUE; // integer overflow, heh. + } + + if(party < 0) { + party = Integer.MAX_VALUE; // integer overflow, heh. + } + int equip = (int) Math.min((long)(gain / 10) * pendantExp, Integer.MAX_VALUE); long total = (long) gain + equip + party; @@ -3348,7 +3405,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } } - if(mbsvh != null) effects.put(mbs, mbsvh); + if(mbsvh != null) { + effects.put(mbs, mbsvh); + } return mbsvh; } @@ -3576,7 +3635,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { Map> bestEffects = new LinkedHashMap<>(); Set retrievedStats = new LinkedHashSet<>(); for(Entry> lmsee: maxStatups.entrySet()) { - if(isSingletonStatup(lmsee.getKey())) continue; + if(isSingletonStatup(lmsee.getKey())) { + continue; + } Integer srcid = lmsee.getValue().getLeft(); if(!bestEffects.containsKey(srcid)) { @@ -3668,7 +3729,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { chrLock.unlock(); } - for(MapleBuffStat mbs : cancelStats) removedStats.add(mbs); + for(MapleBuffStat mbs : cancelStats) { + removedStats.add(mbs); + } cancelPlayerBuffs(cancelStats); } @@ -3755,7 +3818,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { if(b != null) { stats.put(mbs, (byte) (b + 1)); - if(mbsvhe.getValue().value < minStatBuffs.get(mbs).value) minStatBuffs.put(mbs, mbsvhe.getValue()); + if(mbsvhe.getValue().value < minStatBuffs.get(mbs).value) { + minStatBuffs.put(mbs, mbsvhe.getValue()); + } } else { stats.put(mbs, (byte) 1); minStatBuffs.put(mbs, mbsvhe.getValue()); @@ -3778,7 +3843,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { lpbe.remove(it.getKey()); buffEffectsCount.put(it.getKey(), (byte)(buffEffectsCount.get(it.getKey()) - 1)); - if(lpbe.isEmpty()) buffEffects.remove(mbsvh.effect.getBuffSourceId()); + if(lpbe.isEmpty()) { + buffEffects.remove(mbsvh.effect.getBuffSourceId()); + } extractedStatBuffs.put(it.getKey(), mbsvh); } } @@ -3790,7 +3857,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } private void propagateBuffEffectUpdates(Map> retrievedEffects, Set retrievedStats) { - if(retrievedStats.isEmpty()) return; + if (retrievedStats.isEmpty()) { + return; + } Map> maxBuffValue = new LinkedHashMap<>(); for(MapleBuffStat mbs : retrievedStats) { @@ -3822,9 +3891,13 @@ public class MapleCharacter extends AbstractMapleCharacterObject { boolean relevantStatup = true; if(mbs == MapleBuffStat.WATK) { // not relevant for mages - if(mageJob) relevantStatup = false; + if(mageJob) { + relevantStatup = false; + } } else if(mbs == MapleBuffStat.MATK) { // not relevant for non-mages - if(!mageJob) relevantStatup = false; + if(!mageJob) { + relevantStatup = false; + } } Pair mbv = maxBuffValue.get(mbs); @@ -3861,18 +3934,17 @@ public class MapleCharacter extends AbstractMapleCharacterObject { updateEffectsList.add(new Pair<>(ue.getKey(), ue.getValue())); } - Collections.sort(updateEffectsList, new Comparator>>() + Collections.sort(updateEffectsList, new Comparator>>() { + @Override + public int compare(Pair> o1, Pair> o2) { - @Override - public int compare( Pair> o1, Pair> o2 ) - { - if(o1.getRight().getLeft().equals(o2.getRight().getLeft())) { - return o1.getRight().getRight().compareTo(o2.getRight().getRight()); - } else { - return o1.getRight().getLeft().compareTo(o2.getRight().getLeft()); - } + if(o1.getRight().getLeft().equals(o2.getRight().getLeft())) { + return o1.getRight().getRight().compareTo(o2.getRight().getRight()); + } else { + return o1.getRight().getLeft().compareTo(o2.getRight().getLeft()); } - }); + } + }); List>> toUpdateEffects = new LinkedList<>(); for(Pair> msep : updateEffectsList) { @@ -3957,7 +4029,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { beholderHealingSchedule = TimerManager.getInstance().register(new Runnable() { @Override public void run() { - if(awayFromWorld.get()) return; + if (awayFromWorld.get()) { + return; + } addHP(healEffect.getHp()); client.announce(MaplePacketCreator.showOwnBuffEffect(beholder, 2)); @@ -3973,7 +4047,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { beholderBuffSchedule = TimerManager.getInstance().register(new Runnable() { @Override public void run() { - if(awayFromWorld.get()) return; + if (awayFromWorld.get()) { + return; + } buffEffect.applyTo(MapleCharacter.this); client.announce(MaplePacketCreator.showOwnBuffEffect(beholder, 2)); @@ -4072,8 +4148,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } Byte val = buffEffectsCount.get(statup.getKey()); - if(val != null) val = (byte)(val + 1); - else val = (byte) 1; + if (val != null) { + val = (byte) (val + 1); + } else { + val = (byte) 1; + } buffEffectsCount.put(statup.getKey(), val); } @@ -4090,8 +4169,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } else { for (Entry statup : appliedStatups.entrySet()) { Byte val = buffEffectsCount.get(statup.getKey()); - if(val != null) val = (byte)(val + 1); - else val = (byte) 1; + if (val != null) { + val = (byte) (val + 1); + } else { + val = (byte) 1; + } buffEffectsCount.put(statup.getKey(), val); } @@ -4123,7 +4205,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } public boolean unregisterChairBuff() { - if(!ServerConstants.USE_CHAIR_EXTRAHEAL) return false; + if (!ServerConstants.USE_CHAIR_EXTRAHEAL) { + return false; + } int skillId = getJobMapChair(job); int skillLv = getSkillLevel(skillId); @@ -4136,7 +4220,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } public boolean registerChairBuff() { - if(!ServerConstants.USE_CHAIR_EXTRAHEAL) return false; + if (!ServerConstants.USE_CHAIR_EXTRAHEAL) { + return false; + } int skillId = getJobMapChair(job); int skillLv = getSkillLevel(skillId); @@ -4303,8 +4389,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject { try { Set petExclude = excluded.get(petId); - if(petExclude != null) petExclude.clear(); - else excluded.put(petId, new LinkedHashSet()); + if (petExclude != null) { + petExclude.clear(); + } else { + excluded.put(petId, new LinkedHashSet()); + } } finally { chrLock.unlock(); } @@ -4331,7 +4420,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { for(Map.Entry> pe : petExcluded.entrySet()) { byte petIndex = this.getPetIndex(pe.getKey()); - if(petIndex < 0) continue; + if (petIndex < 0) { + continue; + } Set exclItems = pe.getValue(); if (!exclItems.isEmpty()) { @@ -4353,7 +4444,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { Map> petExcluded = this.getExcluded(); for(Map.Entry> pe : petExcluded.entrySet()) { byte petIndex = this.getPetIndex(pe.getKey()); - if(petIndex < 0) continue; + if (petIndex < 0) { + continue; + } Set exclItems = pe.getValue(); if (!exclItems.isEmpty()) { @@ -4615,8 +4708,8 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } public boolean haveItemWithId(int itemid, boolean checkEquipped) { - return (inventory[ItemConstants.getInventoryType(itemid).ordinal()].findById(itemid) != null) || - (checkEquipped && inventory[MapleInventoryType.EQUIPPED.ordinal()].findById(itemid) != null); + return (inventory[ItemConstants.getInventoryType(itemid).ordinal()].findById(itemid) != null) + || (checkEquipped && inventory[MapleInventoryType.EQUIPPED.ordinal()].findById(itemid) != null); } public boolean haveItemEquipped(int itemid) { @@ -4997,7 +5090,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } } - if(pchars.isEmpty()) pchars.add(this); + if (pchars.isEmpty()) { + pchars.add(this); + } return MapleLootManager.retrieveRelevantDrops(monsterId, pchars); } @@ -5032,7 +5127,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { public void closePlayerShop() { MaplePlayerShop mps = this.getPlayerShop(); - if(mps == null) return; + if (mps == null) { + return; + } if (mps.isOwner(this)) { mps.setOpen(false); @@ -5056,7 +5153,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { public void closeMiniGame() { MapleMiniGame game = this.getMiniGame(); - if(game == null) return; + if (game == null) { + return; + } this.setMiniGame(null); if (game.isOwner(this)) { @@ -5069,7 +5168,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { public void closeHiredMerchant(boolean closeMerchant) { MapleHiredMerchant merchant = this.getHiredMerchant(); - if(merchant == null) return; + if (merchant == null) { + return; + } if (closeMerchant) { if (merchant.isOwner(this) && merchant.getItems().isEmpty()) { @@ -5095,7 +5196,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { public void closePlayerMessenger() { MapleMessenger m = this.getMessenger(); - if(m == null) return; + if (m == null) { + return; + } World w = getWorldServer(); MapleMessengerCharacter messengerplayer = new MapleMessengerCharacter(this, this.getMessengerPosition()); @@ -5115,7 +5218,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } public MaplePet getPet(int index) { - if(index < 0) return null; + if (index < 0) { + return null; + } petLock.lock(); try { @@ -5230,7 +5335,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { //---- /\ /\ /\ /\ /\ /\ /\ NOT TESTED /\ /\ /\ /\ /\ /\ /\ /\ /\ ---- public boolean needQuestItem(int questid, int itemid) { - if (questid <= 0) return true; //For non quest items :3 + if (questid <= 0) { //For non quest items :3 + return true; + } int amountNeeded, questStatus = this.getQuestStatus(questid); if (questStatus == 0) { @@ -5603,7 +5710,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { int grade = Math.min(Math.max(level, 30), 120) - 30; fee += (grade * ServerConstants.BUYBACK_LEVEL_STACK_FEE); - if (ServerConstants.USE_BUYBACK_WITH_MESOS) fee *= ServerConstants.BUYBACK_MESO_MULTIPLIER; + if (ServerConstants.USE_BUYBACK_WITH_MESOS) { + fee *= ServerConstants.BUYBACK_MESO_MULTIPLIER; + } return (int) Math.floor(fee); } @@ -6010,7 +6119,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } if (party != null) { - if(partyLeader) party.assignNewLeader(client); + if(partyLeader) { + party.assignNewLeader(client); + } PartyOperationHandler.leaveParty(party, mpc, client); showHint("You have reached #blevel 10#k, therefore you must leave your #rstarter party#k."); @@ -6230,11 +6341,13 @@ public class MapleCharacter extends AbstractMapleCharacterObject { toCommitEffect.add(couponId); - if(ItemConstants.isExpCoupon(couponId)) setExpCouponRate(couponId, couponQty); - else setDropCouponRate(couponId, couponQty); + if (ItemConstants.isExpCoupon(couponId)) { + setExpCouponRate(couponId, couponQty); + } else { + setDropCouponRate(couponId, couponQty); + } } - } - else { + } else { int maxExpRate = 1, maxDropRate = 1, maxExpCouponId = -1, maxDropCouponId = -1; for(Entry coupon: activeCoupons.entrySet()) { @@ -6254,8 +6367,12 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } } - if(maxExpCouponId > -1) toCommitEffect.add(maxExpCouponId); - if(maxDropCouponId > -1) toCommitEffect.add(maxDropCouponId); + if (maxExpCouponId > -1) { + toCommitEffect.add(maxExpCouponId); + } + if (maxDropCouponId > -1) { + toCommitEffect.add(maxDropCouponId); + } this.expCoupon = maxExpRate; this.dropCoupon = maxDropRate; @@ -6280,8 +6397,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { if (ItemConstants.isRateCoupon(it.getItemId()) && active.contains(it.getItemId())) { Integer count = activeCoupons.get(it.getItemId()); - if(count != null) activeCoupons.put(it.getItemId(), count + 1); - else { + if(count != null) { + activeCoupons.put(it.getItemId(), count + 1); + } else { activeCoupons.put(it.getItemId(), 1); activeCouponRates.put(it.getItemId(), coupons.get(it.getItemId())); } @@ -6290,7 +6408,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } private void commitBuffCoupon(int couponid) { - if (!isLoggedin() || getCashShop().isOpened()) return; + if (!isLoggedin() || getCashShop().isOpened()) { + return; + } MapleStatEffect mse = ii.getItemEffect(couponid); mse.applyTo(this); @@ -6547,7 +6667,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } } } - if((sandboxCheck & ItemConstants.SANDBOX) == ItemConstants.SANDBOX) ret.setHasSandboxItem(); + if ((sandboxCheck & ItemConstants.SANDBOX) == ItemConstants.SANDBOX) { + ret.setHasSandboxItem(); + } World wserv = Server.getInstance().getWorld(ret.world); @@ -6775,7 +6897,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { rs = ps.executeQuery(); while (rs.next()) { final MapleDisease disease = MapleDisease.ordinal(rs.getInt("disease")); - if(disease == MapleDisease.NULL) continue; + if (disease == MapleDisease.NULL) { + continue; + } final int skillid = rs.getInt("mobskillid"), skilllv = rs.getInt("mobskilllv"); final long length = rs.getInt("length"); @@ -6791,7 +6915,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { ps.setInt(1, ret.getId()); ps.executeUpdate(); ps.close(); - if(!loadedDiseases.isEmpty()) Server.getInstance().getPlayerBuffStorage().addDiseasesToStorage(ret.id, loadedDiseases); + if (!loadedDiseases.isEmpty()) { + Server.getInstance().getPlayerBuffStorage().addDiseasesToStorage(ret.id, loadedDiseases); + } ps = con.prepareStatement("SELECT * FROM skillmacros WHERE characterid = ?"); ps.setInt(1, charid); rs = ps.executeQuery(); @@ -6894,6 +7020,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } public static class MapleCoolDownValueHolder { + public int skillId; public long startTime, length; @@ -6951,6 +7078,16 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } private void playerDead() { + if (this.getMap().isCPQMap()) { + int lost = getCP(); + if (lost > 6) { + lost = 6; + } + getMap().broadcastMessage(MaplePacketCreator.playerDiedMessage(getName(), lost, getTeam())); + gainCP(-lost); + return; + } + cancelAllBuffs(false); dispelDebuffs(); lastDeathtime = Server.getInstance().getCurrentTime(); @@ -6974,8 +7111,6 @@ public class MapleCharacter extends AbstractMapleCharacterObject { MapleInventoryManipulator.removeById(client, ItemConstants.getInventoryType(charmID[i]), charmID[i], 1, true, false); } else if (mapid > 925020000 && mapid < 925030000) { this.dojoStage = 0; - } else if (mapid > 980000100 && mapid < 980000700) { - getMap().broadcastMessage(this, MaplePacketCreator.CPQDied(this)); } else if (getJob() != MapleJob.BEGINNER) { //Hmm... int XPdummy = ExpTable.getExpNeededForLevel(getLevel()); if (getMap().isTown()) { @@ -7061,7 +7196,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } public void respawn(EventInstanceManager eim, int returnMap) { - if (eim != null) eim.unregisterPlayer(this); // some event scripts uses this... + if (eim != null) { + eim.unregisterPlayer(this); // some event scripts uses this... + } changeMap(returnMap); cancelAllBuffs(false); // thanks Oblivium91 for finding out players still could revive in area and take damage before returning to town @@ -7076,7 +7213,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { dragonBloodSchedule = TimerManager.getInstance().register(new Runnable() { @Override public void run() { - if(awayFromWorld.get()) return; + if (awayFromWorld.get()) { + return; + } addHP(-bloodEffect.getX()); announce(MaplePacketCreator.showOwnBuffEffect(bloodEffect.getSourceId(), 5)); @@ -7655,8 +7794,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject { selectedKey = GameConstants.getCustomKey(true); selectedType = GameConstants.getCustomType(true); selectedAction = GameConstants.getCustomAction(true); - } - else { + } else { selectedKey = GameConstants.getCustomKey(false); selectedType = GameConstants.getCustomType(false); selectedAction = GameConstants.getCustomAction(false); @@ -7736,12 +7874,17 @@ public class MapleCharacter extends AbstractMapleCharacterObject { //ItemFactory saveItems and monsterbook.saveCards are the most time consuming here. public synchronized void saveCharToDB(boolean notAutosave) { - if(!loggedIn) return; + if (!loggedIn) { + return; + } Calendar c = Calendar.getInstance(); - if(notAutosave) FilePrinter.print(FilePrinter.SAVING_CHARACTER, "Attempting to save " + name + " at " + c.getTime().toString()); - else FilePrinter.print(FilePrinter.AUTOSAVING_CHARACTER, "Attempting to autosave " + name + " at " + c.getTime().toString()); + if(notAutosave) { + FilePrinter.print(FilePrinter.SAVING_CHARACTER, "Attempting to save " + name + " at " + c.getTime().toString()); + } else { + FilePrinter.print(FilePrinter.AUTOSAVING_CHARACTER, "Attempting to autosave " + name + " at " + c.getTime().toString()); + } Server.getInstance().updateCharacterEntry(this); @@ -8450,7 +8593,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { return false; } - if (cannotApplyHp) nextHp = 1; + if (cannotApplyHp) { + nextHp = 1; + } } updateHpMp(nextHp, nextMp); @@ -8557,7 +8702,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } public int getDoorSlot() { - if(doorSlot != -1) return doorSlot; + if(doorSlot != -1) { + return doorSlot; + } return fetchDoorSlot(); } @@ -8648,7 +8795,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { inv.lockInventory(); try { for(short i = pos; i <= inv.getSlotLimit(); i++) { - if(inv.getItem(i) == null) continue; + if (inv.getItem(i) == null) { + continue; + } mesoGain += standaloneSell(getClient(), ii, type, i, inv.getItem(i).getQuantity()); } } finally { @@ -9015,7 +9164,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { public void runFullnessSchedule(int petSlot) { MaplePet pet = getPet(petSlot); - if(pet == null) return; + if (pet == null) { + return; + } int newFullness = pet.getFullness() - PetDataFactory.getHunger(pet.getItemId()); if (newFullness <= 5) { @@ -9141,7 +9292,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } public void awardQuestPoint(int awardedPoints) { - if (ServerConstants.QUEST_POINT_REQUIREMENT < 1 || awardedPoints < 1) return; + if (ServerConstants.QUEST_POINT_REQUIREMENT < 1 || awardedPoints < 1) { + return; + } int delta; synchronized (quests) { @@ -9183,8 +9336,12 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } private void expireQuest(MapleQuest quest) { - if(getQuestStatus(quest.getId()) == MapleQuestStatus.Status.COMPLETED.getId()) return; - if(System.currentTimeMillis() < getMapleQuestStatus(quest.getId()).getExpirationTime()) return; + if(getQuestStatus(quest.getId()) == MapleQuestStatus.Status.COMPLETED.getId()) { + return; + } + if(System.currentTimeMillis() < getMapleQuestStatus(quest.getId()).getExpirationTime()) { + return; + } announce(MaplePacketCreator.questExpire(quest.getId())); MapleQuestStatus newStatus = new MapleQuestStatus(quest, MapleQuestStatus.Status.NOT_STARTED); @@ -9242,7 +9399,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { List expireList = new LinkedList<>(); for(Entry qe : questExpirations.entrySet()) { - if(qe.getValue() <= timeNow) expireList.add(qe.getKey()); + if(qe.getValue() <= timeNow) { + expireList.add(qe.getKey()); + } } if(!expireList.isEmpty()) { @@ -9547,99 +9706,6 @@ public class MapleCharacter extends AbstractMapleCharacterObject { return false; } - //EVENTS - private byte team = 0; - private MapleFitness fitness; - private MapleOla ola; - private long snowballattack; - - public byte getTeam() { - return team; - } - - public void setTeam(int team) { - this.team = (byte) team; - } - - public MapleOla getOla() { - return ola; - } - - public void setOla(MapleOla ola) { - this.ola = ola; - } - - public MapleFitness getFitness() { - return fitness; - } - - public void setFitness(MapleFitness fit) { - this.fitness = fit; - } - - public long getLastSnowballAttack() { - return snowballattack; - } - - public void setLastSnowballAttack(long time) { - this.snowballattack = time; - } - - //Monster Carnival - private int cp = 0; - private int obtainedcp = 0; - private MonsterCarnivalParty carnivalparty; - private MonsterCarnival carnival; - - public MonsterCarnivalParty getCarnivalParty() { - return carnivalparty; - } - - public void setCarnivalParty(MonsterCarnivalParty party) { - this.carnivalparty = party; - } - - public MonsterCarnival getCarnival() { - return carnival; - } - - public void setCarnival(MonsterCarnival car) { - this.carnival = car; - } - - public int getCP() { - return cp; - } - - public int getObtainedCP() { - return obtainedcp; - } - - public void addCP(int cp) { - this.cp += cp; - this.obtainedcp += cp; - } - - public void useCP(int cp) { - this.cp -= cp; - } - - public void setObtainedCP(int cp) { - this.obtainedcp = cp; - } - - public int getAndRemoveCP() { - int rCP = 10; - if (cp < 9) { - rCP = cp; - cp = 0; - } else { - cp -= 10; - } - - return rCP; - } - public AutobanManager getAutobanManager() { return autoban; } @@ -9725,7 +9791,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { } public void increaseEquipExp(int expGain) { - if(expGain < 0) expGain = Integer.MAX_VALUE; + if(expGain < 0) { + expGain = Integer.MAX_VALUE; + } for (Item item : getUpgradeableEquipList()) { Equip nEquip = (Equip) item; @@ -9818,6 +9886,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject { if (pendantOfSpirit != null) { pendantOfSpirit.cancel(true); } pendantOfSpirit = null; + if (timer != null) { timer.cancel(true); } + timer = null; + evtLock.lock(); try { if (questExpireTask != null) { @@ -9934,8 +10005,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject { public void addJailExpirationTime(long time) { long timeLeft = getJailExpirationTimeLeft(); - if(timeLeft <= 0) setFutureJailExpiration(time); - else setFutureJailExpiration(timeLeft + time); + if(timeLeft <= 0) { + setFutureJailExpiration(time); + } else { + setFutureJailExpiration(timeLeft + time); + } } public void removeJailExpirationTime() { @@ -10050,4 +10124,203 @@ public class MapleCharacter extends AbstractMapleCharacterObject { setLevel(0); levelUp(true); } -} + + //EVENTS + private byte team = 0; + private MapleFitness fitness; + private MapleOla ola; + private long snowballattack; + public static final List itens = new ArrayList(); + public static final List item = new ArrayList(); + + public byte getTeam() { + return team; + } + + public void setTeam(int team) { + this.team = (byte) team; + } + + public MapleOla getOla() { + return ola; + } + + public void setOla(MapleOla ola) { + this.ola = ola; + } + + public MapleFitness getFitness() { + return fitness; + } + + public void setFitness(MapleFitness fit) { + this.fitness = fit; + } + + public long getLastSnowballAttack() { + return snowballattack; + } + + public void setLastSnowballAttack(long time) { + this.snowballattack = time; + } + + // MCPQ + + private int cp = 0; + private int totCP = 0; + private MonsterCarnival monsterCarnival; + private MonsterCarnivalParty monsterCarnivalParty = null; + private int FestivalPoints; + private boolean challenged = false; + + public void gainFestivalPoints(int gain) { + this.FestivalPoints += gain; + } + + public int getFestivalPoints() { + return this.FestivalPoints; + } + + public void setFestivalPoints(int pontos) { + this.FestivalPoints = pontos; + } + + public int getCP() { + return cp; + } + + public short totalCP, availableCP; + + public void addCP(int ammount) { + totalCP += ammount; + availableCP += ammount; + } + + public void useCP(int ammount) { + availableCP -= ammount; + } + + public void gainCP(int gain) { + if (this.getMonsterCarnival() != null) { + if (gain > 0) { + this.setTotalCP(this.getTotalCP() + gain); + } + this.setCP(this.getCP() + gain); + if (this.getParty() != null) { + this.getMonsterCarnival().setCP(this.getMonsterCarnival().getCP(team) + gain, team); + if (gain > 0) { + this.getMonsterCarnival().setTotalCP(this.getMonsterCarnival().getTotalCP(team) + gain, team); + } + } + if (this.getCP() > this.getTotalCP()) { + this.setTotalCP(this.getCP()); + } + this.getClient().announce(MaplePacketCreator.CPUpdate(false, this.getCP(), this.getTotalCP(), getTeam())); + if (this.getParty() != null && getTeam() != -1) { + this.getMap().broadcastMessage(MaplePacketCreator.CPUpdate(true, this.getMonsterCarnival().getCP(team), this.getMonsterCarnival().getTotalCP(team), getTeam())); + } else { + } + } + } + + public void setTotalCP(int a) { + this.totCP = a; + } + + public void setCP(int a) { + this.cp = a; + } + + public int getTotalCP() { + return totCP; + } + + public int getAvailableCP() { + return availableCP; + } + + public void resetCP() { + this.cp = 0; + this.totCP = 0; + this.monsterCarnival = null; + } + + public MonsterCarnival getMonsterCarnival() { + return monsterCarnival; + } + + public void setMonsterCarnival(MonsterCarnival monsterCarnival) { + this.monsterCarnival = monsterCarnival; + } + + public MonsterCarnivalParty getMonsterCarnivalParty() { + return this.monsterCarnivalParty; + } + + public void setMonsterCarnivalParty(MonsterCarnivalParty mcp) { + this.monsterCarnivalParty = mcp; + } + + public boolean isChallenged() { + return challenged; + } + + public void setChallenged(boolean challenged) { + this.challenged = challenged; + } + + public void setLingua(int num) { + getClient().setLingua(num); + try { + Connection con = DatabaseConnection.getConnection(); + try (PreparedStatement ps = con.prepareStatement("UPDATE accounts SET lingua = ? WHERE id = ?")) { + ps.setInt(1, num); + ps.setInt(2, getClient().getAccID()); + ps.executeUpdate(); + } finally { + con.close(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public int getLingua() { + return getClient().getLingua(); + } + + public void setItens(String item) { + if (!itens.contains(item)) { + this.itens.add(item); + } + } + + public static List getItens() { + return itens; + } + + public void setEquips(Item item) { + this.item.add(item); + } + + public static List getItem() { + return item; + } + + public Item getItemid(int numb) { + return this.item.get(numb); + } + + public void removeItem(Item item) { + if (this.item.contains(item)) { + this.item.remove(item); + } + } + + public void obterItens() { + for (Item item : getItem()) { + getClient().getAbstractPlayerInteraction().gainItem(item.getItemId(), item.getQuantity()); + } + } +} \ No newline at end of file diff --git a/src/client/MapleClient.java b/src/client/MapleClient.java index 7cd65524ed..2847ee87e5 100644 --- a/src/client/MapleClient.java +++ b/src/client/MapleClient.java @@ -124,6 +124,7 @@ public class MapleClient { private int visibleWorlds; private long lastNpcClick; private long sessionId; + private int lingua = 0; static { for (int i = 0; i < 200; i++) { @@ -269,8 +270,9 @@ public class MapleClient { } public boolean hasBannedHWID() { - if(hwid == null) - return false; + if(hwid == null) { + return false; + } boolean ret = false; PreparedStatement ps = null; @@ -509,7 +511,9 @@ public class MapleClient { } public boolean checkPic(String other) { - if(!(ServerConstants.ENABLE_PIC && !canBypassPic())) return true; + if (!(ServerConstants.ENABLE_PIC && !canBypassPic())) { + return true; + } picattempt++; if (picattempt > 5) { @@ -538,7 +542,7 @@ public class MapleClient { ResultSet rs = null; try { con = DatabaseConnection.getConnection(); - ps = con.prepareStatement("SELECT id, password, gender, banned, pin, pic, characterslots, tos FROM accounts WHERE name = ?"); + ps = con.prepareStatement("SELECT id, password, gender, banned, pin, pic, characterslots, tos, lingua FROM accounts WHERE name = ?"); ps.setString(1, login); rs = ps.executeQuery(); if (rs.next()) { @@ -556,6 +560,7 @@ public class MapleClient { pic = rs.getString("pic"); gender = rs.getByte("gender"); characterSlots = rs.getByte("characterslots"); + lingua = rs.getInt("lingua"); String passhash = rs.getString("password"); byte tos = rs.getByte("tos"); @@ -888,6 +893,10 @@ public class MapleClient { if (eim != null) { eim.playerDisconnected(player); } + + if (player.getMonsterCarnival() != null) { + player.getMonsterCarnival().playerDisconnected(getPlayer().getId()); + } } if (player.getMap() != null) { @@ -985,7 +994,9 @@ public class MapleClient { FilePrinter.printError(FilePrinter.ACCOUNT_STUCK, e); } finally { if (!this.serverTransition) { - if(chrg != null) chrg.setCharacter(null); + if(chrg != null) { + chrg.setCharacter(null); + } wserv.removePlayer(player); //getChannelServer().removePlayer(player); already being done @@ -1533,4 +1544,12 @@ public class MapleClient { public boolean canBypassPic() { return MapleLoginBypassCoordinator.getInstance().canLoginBypass(getNibbleHWID(), accId, true); } -} + + public int getLingua() { + return lingua; + } + + public void setLingua(int lingua) { + this.lingua = lingua; + } +} \ No newline at end of file diff --git a/src/client/MapleDisease.java b/src/client/MapleDisease.java index 784be02d6e..f84ad4f1d9 100644 --- a/src/client/MapleDisease.java +++ b/src/client/MapleDisease.java @@ -21,34 +21,34 @@ */ package client; -import java.util.ArrayList; -import java.util.List; +import tools.Randomizer; public enum MapleDisease { NULL(0x0), - SLOW(0x1), - SEDUCE(0x80), + SLOW(0x1, 126), + SEDUCE(0x80, 128), FISHABLE(0x100), ZOMBIFY(0x4000), CONFUSE(0x80000), - STUN(0x2000000000000L), - POISON(0x4000000000000L), - SEAL(0x8000000000000L), - DARKNESS(0x10000000000000L), - WEAKEN(0x4000000000000000L), - CURSE(0x8000000000000000L); + STUN(0x2000000000000L, 123), + POISON(0x4000000000000L, 125), + SEAL(0x8000000000000L, 120), + DARKNESS(0x10000000000000L, 121), + WEAKEN(0x4000000000000000L, 122), + CURSE(0x8000000000000000L, 124); private long i; private boolean first; + private int disease; private MapleDisease(long i) { this.i = i; this.first = false; } - private MapleDisease(long i, boolean first) { + private MapleDisease(long i, int disease) { this.i = i; - this.first = first; + this.disease = disease; } public long getValue() { @@ -58,6 +58,10 @@ public enum MapleDisease { public boolean isFirst() { return first; } + + public int getDisease() { + return disease; + } public static MapleDisease ordinal(int ord) { try { @@ -66,4 +70,24 @@ public enum MapleDisease { return NULL; } } + + public static final MapleDisease getRandom() { + while (true) { + for (MapleDisease dis : MapleDisease.values()) { + if (Randomizer.nextInt(MapleDisease.values().length) == 0) { + return dis; + } + } + } + } + + public static final MapleDisease getBySkill(final int skill) { + for (MapleDisease d : MapleDisease.values()) { + if (d.getDisease() == skill && d.getDisease() != 0) { + return d; + } + } + return null; + } + } diff --git a/src/client/command/CommandsExecutor.java b/src/client/command/CommandsExecutor.java index 3a899c2231..61227d15ea 100644 --- a/src/client/command/CommandsExecutor.java +++ b/src/client/command/CommandsExecutor.java @@ -186,6 +186,7 @@ public class CommandsExecutor { addCommand("uptime", UptimeCommand.class); addCommand("gacha", GachaCommand.class); addCommand("dispose", DisposeCommand.class); + addCommand("changel", ChangeLinguaCommand.class); addCommand("equiplv", EquipLvCommand.class); addCommand("showrates", ShowRatesCommand.class); addCommand("rates", RatesCommand.class); diff --git a/src/client/command/commands/gm0/ChangeLinguaCommand.java b/src/client/command/commands/gm0/ChangeLinguaCommand.java new file mode 100644 index 0000000000..219279a99f --- /dev/null +++ b/src/client/command/commands/gm0/ChangeLinguaCommand.java @@ -0,0 +1,42 @@ +/* + This file is part of the HeavenMS MapleStory Server, commands OdinMS-based + 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 . +*/ + +/* + @Author: Arthur L - Refactored command content into modules +*/ +package client.command.commands.gm0; + +import client.command.Command; +import client.MapleClient; + +public class ChangeLinguaCommand extends Command { + { + setDescription(""); + } + + @Override + public void execute(MapleClient c, String[] params) { + if (params.length < 1) { + c.getPlayer().yellowMessage("Syntax: !changel <0=ptb, 1=esp, 2=eng>"); + return; + } + c.setLingua(Integer.parseInt(params[0])); + } +} diff --git a/src/client/command/commands/gm5/DebugCommand.java b/src/client/command/commands/gm5/DebugCommand.java index 517ca62525..edc53da9cb 100644 --- a/src/client/command/commands/gm5/DebugCommand.java +++ b/src/client/command/commands/gm5/DebugCommand.java @@ -39,6 +39,7 @@ import tools.MaplePacketCreator; import java.awt.*; import java.util.Arrays; import java.util.List; +import tools.packets.Wedding; public class DebugCommand extends Command { private final static String debugTypes[] = {"monster", "packet", "portal", "spawnpoint", "pos", "map", "mobsp", "event", "areas", "reactors", "servercoupons", "playercoupons", "timer", "marriage", ""}; diff --git a/src/constants/LinguaConstants.java b/src/constants/LinguaConstants.java new file mode 100644 index 0000000000..af1089d60e --- /dev/null +++ b/src/constants/LinguaConstants.java @@ -0,0 +1,69 @@ +package constants; + +import client.MapleCharacter; + +/** + * + * @author Drago - Dragohe4rt + */ +public class LinguaConstants { + // Portugues + public static String CPQAzul; + public static String CPQErro; + public static String CPQEntrada; + public static String CPQEscolha; + public static String CPQVermelho; + public static String CPQPlayerExit; + public static String CPQEntradaLobby; + public static String CPQInicioEscolha; + public static String CPQTempoExtendido; + public static String CPQLiderNaoEncontrado; + public static String CPQInicioEscolhaEmEscolha; + + public static LinguaConstants Linguas(MapleCharacter chr) { + if (chr.getLingua() == 0) { + LinguaConstants.CPQAzul = "Maple Azul"; + LinguaConstants.CPQVermelho = "Maple Vermelho"; + LinguaConstants.CPQTempoExtendido = "O tempo foi estendido."; + LinguaConstants.CPQPlayerExit = " deixou o Carnaval de Monstros."; + LinguaConstants.CPQErro = "Ocorreu um problema. Favor recriar a sala."; + LinguaConstants.CPQLiderNaoEncontrado = "Não foi possível encontrar o Lider."; + LinguaConstants.CPQInicioEscolha = "Inscreva-se no Festival de Monstros!\\r\\n"; + LinguaConstants.CPQInicioEscolhaEmEscolha = "O grupo esta respondendo um desafio no momento."; + LinguaConstants.CPQEscolha = "Não foi possí­vel encontrar um grupo nesta sala.\\r\\nProvavelmente o grupo foi desfeito dentro da sala!"; + LinguaConstants.CPQEntradaLobby = "[CPQ MapleStorySA] Agora você irá receber desafios de outros grupos. Se você não aceitar um desafio em 3 minutos, você será levado para fora."; + LinguaConstants.CPQEntrada = "Você pode selecionar \"Invocar Monstros\", \"Habilidade\", ou \"Protetor\" como sua tática durante o Carnaval dos Monstros. Use Tab a F1~F12 para acesso rápido!"; + + + + } else if (chr.getLingua() == 1) { + LinguaConstants.CPQAzul = "Maple Azul"; + LinguaConstants.CPQVermelho = "Maple Rojo"; + LinguaConstants.CPQTempoExtendido = "El tiempo se ha ampliado."; + LinguaConstants.CPQPlayerExit = " ha dejado el Carnaval de Monstruos."; + LinguaConstants.CPQLiderNaoEncontrado = "No se pudo encontrar el Lider."; + LinguaConstants.CPQInicioEscolha = "¡Inscríbete en el Festival de Monstruos!\\r\\n"; + LinguaConstants.CPQErro = "Se ha producido un problema. Por favor, volver a crear una sala."; + LinguaConstants.CPQInicioEscolhaEmEscolha = "El grupo esta respondiendo un desafío en el momento."; + LinguaConstants.CPQEscolha = "No se pudo encontrar un grupo en esta sala.\\r\\nProbablemente el grupo fue deshecho dentro de la sala!"; + LinguaConstants.CPQEntradaLobby = "[CPQ MapleStorySA] Ahora usted recibirá los retos de otros grupos. Si usted no acepta un desafío en 3 minutos, usted será llevado hacia fuera."; + LinguaConstants.CPQEntrada = "Usted puede seleccionar \"Invocar Monstruos \", \"Habilidad \", o \"Protector \" como su táctica durante el Carnaval de los Monstruos. Utilice Tab y F1 ~ F12 para acceso rápido!"; + + + } else if (chr.getLingua() == 2) { + LinguaConstants.CPQAzul = "Maple Blue"; + LinguaConstants.CPQVermelho = "Maple Red"; + LinguaConstants.CPQPlayerExit = " left the Carnival of Monsters."; + LinguaConstants.CPQTempoExtendido = "The time has been extended."; + LinguaConstants.CPQLiderNaoEncontrado = "Could not find the Leader."; + LinguaConstants.CPQErro = "There was a problem. Please re-create a room."; + LinguaConstants.CPQInicioEscolha = "Sign up for the Monster Festival!\\r\\n"; + LinguaConstants.CPQInicioEscolhaEmEscolha = "The group is currently facing a challenge."; + LinguaConstants.CPQEscolha = "We could not find a group in this room.\\r\\nProbably the group was scrapped inside the room!"; + LinguaConstants.CPQEntradaLobby = "[CPQ MapleStorySA] You will now receive challenges from other groups. If you do not accept a challenge within 3 minutes, you will be taken out."; + LinguaConstants.CPQEntrada = "You can select \"Summon Monsters \", \"Ability \", or \"Protector \" as your tactic during the Monster Carnival. Use Tab and F1 ~ F12 for quick access!"; + + } + return null; + } +} diff --git a/src/constants/ServerConstants.java b/src/constants/ServerConstants.java index cd07a535c8..7a9b0fac83 100644 --- a/src/constants/ServerConstants.java +++ b/src/constants/ServerConstants.java @@ -34,7 +34,7 @@ public class ServerConstants { public static final int BYPASS_PIC_EXPIRATION = 20; //Enables PIC bypass, which will remain active for that account by that client machine for N minutes. Set 0 to disable. public static final int BYPASS_PIN_EXPIRATION = 15; //Enables PIN bypass, which will remain active for that account by that client machine for N minutes. Set 0 to disable. - public static final boolean AUTOMATIC_REGISTER = true; //Automatically register players when they login with a nonexistent username. + public static final boolean AUTOMATIC_REGISTER = false; //Automatically register players when they login with a nonexistent username. public static final boolean BCRYPT_MIGRATION = true; //Performs a migration from old SHA-1 and SHA-512 password to bcrypt. public static final boolean COLLECTIVE_CHARSLOT = false; //Available character slots are contabilized globally rather than per world server. public static final boolean DETERRED_MULTICLIENT = false; //Enables multi-client and suspicious remote IP detection on the login system. @@ -59,7 +59,7 @@ public class ServerConstants { public static final boolean USE_CUSTOM_KEYSET = true; //Enables auto-setup of the HeavenMS's custom keybindings when creating characters. public static final boolean USE_DEBUG = false; //Will enable some text prints on the client, oriented for debugging purposes. public static final boolean USE_DEBUG_SHOW_INFO_EQPEXP = false; //Prints on the cmd all equip exp gain info. - public static boolean USE_DEBUG_SHOW_RCVD_PACKET = false; //Prints on the cmd all received packet ids. + public static boolean USE_DEBUG_SHOW_RCVD_PACKET = true; //Prints on the cmd all received packet ids. public static boolean USE_DEBUG_SHOW_RCVD_MVLIFE = false; //Prints on the cmd all received move life content. public static boolean USE_SUPPLY_RATE_COUPONS = true; //Allows rate coupons to be sold through the Cash Shop. diff --git a/src/net/server/channel/handlers/ChangeMapHandler.java b/src/net/server/channel/handlers/ChangeMapHandler.java index 8f2bd4b4d3..424ad492b6 100644 --- a/src/net/server/channel/handlers/ChangeMapHandler.java +++ b/src/net/server/channel/handlers/ChangeMapHandler.java @@ -101,11 +101,10 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler { } } } else { - if(chr.isGM()) { + if (chr.isGM()) { MapleMap to = chr.getWarpMap(targetid); chr.changeMap(to, to.getPortal(0)); - } - else { + } else { final int divi = chr.getMapId() / 100; boolean warp = false; if (divi == 0) { @@ -170,4 +169,4 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler { } } } -} +} \ No newline at end of file diff --git a/src/net/server/channel/handlers/MonsterCarnivalHandler.java b/src/net/server/channel/handlers/MonsterCarnivalHandler.java index ccf29d9a38..fe18b82532 100644 --- a/src/net/server/channel/handlers/MonsterCarnivalHandler.java +++ b/src/net/server/channel/handlers/MonsterCarnivalHandler.java @@ -1,223 +1,154 @@ /* - This file is part of the OdinMS Maple Story Server - Copyright (C) 2008 Patrick Huy - Matthias Butz - Jan Christian Meyer + 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 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 . -*/ + 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 . + */ package net.server.channel.handlers; import client.MapleCharacter; import client.MapleClient; +import client.MapleDisease; import java.awt.Point; +import java.util.List; import net.AbstractMaplePacketHandler; -import server.partyquest.MonsterCarnival; +import net.server.world.MapleParty; +import net.server.world.MaplePartyCharacter; import server.life.MapleLifeFactory; -import server.maps.MapleReactor; -import server.maps.MapleReactorFactory; +import server.life.MapleMonster; +import server.partyquest.MapleCarnivalFactory; +import server.partyquest.MapleCarnivalFactory.MCSkill; import tools.MaplePacketCreator; +import tools.Pair; import tools.data.input.SeekableLittleEndianAccessor; + /** - * - * @author kevintjuh93 - */ -public final class MonsterCarnivalHandler extends AbstractMaplePacketHandler{ + *@author Drago/Dragohe4rt +*/ + +public final class MonsterCarnivalHandler extends AbstractMaplePacketHandler { + + @Override public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { - MapleCharacter chr = c.getPlayer(); - MonsterCarnival carnival = chr.getCarnival(); - int tab = slea.readByte(); - int number = slea.readShort(); - if (carnival != null) { - if (chr.getCarnivalParty() != carnival.getPartyRed() || chr.getCarnivalParty() != carnival.getPartyBlue()) { - chr.getMap().broadcastMessage(MaplePacketCreator.leaveCPQ(chr)); - chr.changeMap(980000010); - } - if (chr.getCP() > getPrice(tab, number)) { - if (tab == 0) { //SPAWNING - if (chr.getCarnivalParty().canSummon()) { - chr.getMap().spawnCPQMonster(MapleLifeFactory.getMonster(getMonster(number)), new Point(1, 1), carnival.oppositeTeam(chr.getCarnivalParty()).getTeam()); - chr.getCarnivalParty().summon(); - } else - chr.announce(MaplePacketCreator.CPQMessage((byte) 2)); - - } else if (tab == 1) { - - } else if (tab == 2) { - int rid = 9980000 + chr.getTeam(); - MapleReactor reactor = new MapleReactor(MapleReactorFactory.getReactor(rid), rid); - /*switch (number) { - case 0: - reactor.setMonsterStatus(tab, MonsterStatus.WEAPON_ATTACK_UP, MobSkillFactory.getMobSkill(150, 1)); - break; - case 1: - reactor.setMonsterStatus(tab, MonsterStatus.WEAPON_DEFENSE_UP, MobSkillFactory.getMobSkill(151, 1)); - break; - case 2: - reactor.setMonsterStatus(tab, MonsterStatus.MAGIC_ATTACK_UP, MobSkillFactory.getMobSkill(152, 1)); - break; - case 3: - reactor.setMonsterStatus(tab, MonsterStatus.MAGIC_DEFENSE_UP, MobSkillFactory.getMobSkill(153, 1)); - break; - case 4: - reactor.setMonsterStatus(tab, MonsterStatus.ACC, MobSkillFactory.getMobSkill(154, 1)); - break; - case 5: - reactor.setMonsterStatus(tab, MonsterStatus.AVOID, MobSkillFactory.getMobSkill(155, 1)); - break; - case 6: - reactor.setMonsterStatus(tab, MonsterStatus.SPEED, MobSkillFactory.getMobSkill(156, 1)); - break; - case 7: - reactor.setMonsterStatus(tab, MonsterStatus.WEAPON_IMMUNITY, MobSkillFactory.getMobSkill(140, 1)); - break; - case 8: - reactor.setMonsterStatus(tab, MonsterStatus.MAGIC_IMMUNITY, MobSkillFactory.getMobSkill(141, 1)); - break; - } */ - chr.getMap().spawnReactor(reactor); + try { + int tab = slea.readByte(); + int num = slea.readByte(); + int neededCP = 0; + if (tab == 0) { + final List> mobs = c.getPlayer().getMap().getMobsToSpawn(); + if (num >= mobs.size() || c.getPlayer().getCP() < mobs.get(num).right) { + c.announce(MaplePacketCreator.CPQMessage((byte) 1)); + c.getSession().write(MaplePacketCreator.enableActions()); + return; } - } else { - chr.getMap().broadcastMessage(MaplePacketCreator.CPQMessage((byte) 1)); - } - } else { - chr.announce(MaplePacketCreator.CPQMessage((byte) 5)); - } - chr.announce(MaplePacketCreator.enableActions()); - } - public int getMonster(int num) { - int mid = 0; - num++; - switch (num) { - case 1: - mid = 9300127; - break; - case 2: - mid = 9300128; - break; - case 3: - mid = 9300129; - break; - case 4: - mid = 9300130; - break; - case 5: - mid = 9300131; - break; - case 6: - mid = 9300132; - break; - case 7: - mid = 9300133; - break; - case 8: - mid = 9300134; - break; - case 9: - mid = 9300135; - break; - case 10: - mid = 9300136; - break; + final MapleMonster mob = MapleLifeFactory.getMonster(mobs.get(num).left); + if (c.getPlayer().getMonsterCarnival() != null) { + Point spawnPos = c.getPlayer().getMap().getRandomSP(c.getPlayer().getTeam()); + if (!c.getPlayer().getMonsterCarnival().canSummon() && c.getPlayer().getTeam() == 0 || !c.getPlayer().getMonsterCarnival().canSummons() && c.getPlayer().getTeam() == 1) { + c.announce(MaplePacketCreator.CPQMessage((byte) 2)); + c.getSession().write(MaplePacketCreator.enableActions()); + return; + } + mob.setPosition(spawnPos); + if (c.getPlayer().getTeam() == 0) { + c.getPlayer().getMonsterCarnival().summon(); + } else { + c.getPlayer().getMonsterCarnival().summons(); + } + c.getPlayer().getMap().addMonsterSpawn(mob, 1, c.getPlayer().getTeam()); + c.getSession().write(MaplePacketCreator.enableActions()); + } + neededCP = mobs.get(num).right; + } else if (tab == 1) { //debuffs + final List skillid = c.getPlayer().getMap().getSkillIds(); + if (num >= skillid.size()) { + c.getPlayer().dropMessage(5, "Ocorreu um erro."); + c.getSession().write(MaplePacketCreator.enableActions()); + return; + } + final MCSkill skil = MapleCarnivalFactory.getInstance().getSkill(skillid.get(num)); //ugh wtf + if (skil == null || c.getPlayer().getCP() < skil.cpLoss) { + c.announce(MaplePacketCreator.CPQMessage((byte) 1)); + c.getSession().write(MaplePacketCreator.enableActions()); + return; + } + final MapleDisease dis = skil.getDisease(); + MapleParty inimigos = c.getPlayer().getParty().getEnemy(); + if (skil.targetsAll) { + int chanceAcerto = 0; + if (dis.getDisease() == 121 || dis.getDisease() == 122 || dis.getDisease() == 125 || dis.getDisease() == 126) { + chanceAcerto = (int) (Math.random() * 100); + } + if (chanceAcerto <= 80) { + for (MaplePartyCharacter chrS : inimigos.getPartyMembers()) { + if (dis == null) { + chrS.getPlayer().dispel(); + } else { + chrS.getPlayer().giveDebuff(dis, skil.getSkill()); + } + if (!skil.targetsAll) { + break; + } + } + } + } else { + int amount = inimigos.getMembers().size() - 1; + int randd = (int) Math.floor(Math.random() * amount); + MapleCharacter chrApp = c.getChannelServer().getPlayerStorage().getCharacterById(inimigos.getMemberByPos(randd).getId()); + if (chrApp != null && chrApp.getMap().isCPQMap()) { + if (dis == null) { + chrApp.dispel(); + } else { + chrApp.giveDebuff(dis, skil.getSkill()); + } + } + } + neededCP = skil.cpLoss; + c.getSession().write(MaplePacketCreator.enableActions()); + } else if (tab == 2) { //protectors + final MCSkill skil = MapleCarnivalFactory.getInstance().getGuardian(num); + if (skil == null || c.getPlayer().getCP() < skil.cpLoss) { + c.announce(MaplePacketCreator.CPQMessage((byte) 1)); + c.getSession().write(MaplePacketCreator.enableActions()); + return; + } + int success = c.getPlayer().getMap().spawnGuardian(c.getPlayer().getTeam(), num); + if (success == -1 || success == 0 || success == 2) { + if (success == -1) { + c.announce(MaplePacketCreator.CPQMessage((byte) 3)); + } else if (success == 0) { + c.announce(MaplePacketCreator.CPQMessage((byte) 4)); + } else if (success == 2) { + c.announce(MaplePacketCreator.CPQMessage((byte) 3)); + } + c.getSession().write(MaplePacketCreator.enableActions()); + return; + } else { + neededCP = skil.cpLoss; + } + } + c.getPlayer().gainCP(-neededCP); + c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.playerSummoned(c.getPlayer().getName(), tab, num)); + }catch (Exception e) { + e.printStackTrace(); } - return mid; - } - - public int getPrice(int num, int tab) { - int price = 0; - num++; - - if (tab == 0) { - switch (num) { - case 1: - case 2: - price = 7; - break; - case 3: - case 4: - price = 8; - break; - case 5: - case 6: - price = 9; - break; - case 7: - price = 10; - break; - case 8: - price = 11; - break; - case 9: - price = 12; - break; - case 10: - price = 30; - break; - } - } else if (tab == 1) { - switch (num) { - case 1: - price = 17; - break; - case 2: - case 4: - price = 19; - break; - case 3: - price = 12; - break; - case 5: - price = 16; - break; - case 6: - price = 14; - break; - case 7: - price = 22; - break; - case 8: - price = 18; - break; - } - } else { - switch (num) { - case 1: - case 3: - price = 17; - break; - case 2: - case 4: - case 6: - price = 16; - break; - case 5: - price = 13; - break; - case 7: - price = 12; - break; - case 8: - case 9: - price = 35; - break; - } } - return price; + } -} diff --git a/src/net/server/channel/handlers/RingActionHandler.java b/src/net/server/channel/handlers/RingActionHandler.java index aaab19a914..33a9f29648 100644 --- a/src/net/server/channel/handlers/RingActionHandler.java +++ b/src/net/server/channel/handlers/RingActionHandler.java @@ -21,8 +21,6 @@ */ package net.server.channel.handlers; -//import java.sql.Connection; -//import java.sql.PreparedStatement; import client.MapleClient; import client.MapleCharacter; import client.inventory.MapleInventoryType; @@ -31,14 +29,10 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -//import tools.DatabaseConnection; import net.AbstractMaplePacketHandler; import client.inventory.manipulator.MapleInventoryManipulator; import tools.DatabaseConnection; import tools.data.input.SeekableLittleEndianAccessor; -//import scripting.npc.NPCScriptManager; import tools.Pair; import tools.MaplePacketCreator; import tools.packets.Wedding; @@ -52,6 +46,7 @@ import client.inventory.Item; /** * @author Jvlaple * @author Ronan - major overhaul on Ring handling mechanics + * @author Drago/Dragohe4rt on Wishlist */ public final class RingActionHandler extends AbstractMaplePacketHandler { private static int getBoxId(int useItemId) { @@ -467,11 +462,16 @@ public final class RingActionHandler extends AbstractMaplePacketHandler { break; - case 9: // Groom and Bride's Wishlist - short size = slea.readShort(); - List itemnames = new ArrayList<>(size); - for (int i = 0; i < size; i++) { - itemnames.add(slea.readMapleAsciiString()); + case 9: + // By Drago/Dragohe4rt + // Groom and Bride's Wishlist + //short size = slea.readShort(); + int amount = slea.readShort(); + if (amount > 10) { + amount = 10; + } + for (int i = 0; i < amount; i++) { + c.getPlayer().setItens(slea.readMapleAsciiString()); } //System.out.println("G&B WISHLIST: " + itemnames); diff --git a/src/net/server/channel/handlers/WeddingHandler.java b/src/net/server/channel/handlers/WeddingHandler.java index 903fadb363..301c3ce5db 100644 --- a/src/net/server/channel/handlers/WeddingHandler.java +++ b/src/net/server/channel/handlers/WeddingHandler.java @@ -10,84 +10,61 @@ import client.inventory.Item; import client.inventory.MapleInventoryType; import client.MapleCharacter; import client.MapleClient; +import client.inventory.Equip; import constants.ItemConstants; -import tools.DatabaseConnection; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; import net.AbstractMaplePacketHandler; import client.inventory.manipulator.MapleInventoryManipulator; +import net.server.channel.Channel; +import scripting.event.EventInstanceManager; import tools.MaplePacketCreator; import tools.data.input.SeekableLittleEndianAccessor; import tools.packets.Wedding; /** * - * @author Eric + * @author By Drago/Dragohe4rt */ public final class WeddingHandler extends AbstractMaplePacketHandler { - /* - public static final void OnWeddingProgress(byte action, MapleClient c) { - // -- Pelvis Bebop: - // 0x00: "We are gathered here today..." - // 0x01: "Very well! I pronounce you..." - // 0x02: "You two truly are a sight to..." - // 0x03: Wedding Ceremony Ended, initialize the Wedding Effect upon the two married characters - // -- High Priest John: (Unknown action bytes) - // 0x00: " " - // 0x01: " " - // 0x02: "Do you wish to bless this couple?..." - // 0x03: Wedding Ceremony Ended, initialize the Wedding Effect upon the two married characters - if (c.getPlayer().getWedding() != null) { - if (c.getPlayer().getGender() == 0 ? c.getPlayer().getWedding().isExistantGroom(c.getPlayer().getId()) : c.getPlayer().getWedding().isExistantBride(c.getPlayer().getId())) { - c.getPlayer().getMap().broadcastMessage(Wedding.OnWeddingProgress(action == 2, c.getPlayer().getId(), c.getPlayer().getPartnerId(), (byte)(action+1))); - c.getPlayer().getWedding().incrementStage(); - c.getPlayer().getPartner().getWedding().incrementStage(); // pls don't b a bitch and throw npe ):< - if (action == 2) { - c.getPlayer().setMarried(true); - c.getChannelServer().getPlayerStorage().getCharacterById(c.getPlayer().getPartnerId()).setMarried(true); - } - } - } - c.announce(MaplePacketCreator.enableActions()); - } - - public static final void OnWeddingGiftResult(SeekableLittleEndianAccessor slea, MapleClient c) { - System.out.println("New WEDDING_GIFT_RESULT: " + slea.toString()); - byte mode = slea.readByte(); - switch(mode) { - case 0x06: // "SEND ITEM" - short slot = slea.readShort(); // isn't this a byte? o.O - int itemId = slea.readInt(); - short quantity = slea.readShort(); - if (c.getPlayer().getInventory(ItemConstants.getInventoryType(itemId)).getItem((byte)slot).getItemId() == itemId && c.getPlayer().getInventory(InventoryConstants.getInventoryType(itemId)).getItem((byte)slot).getQuantity() >= quantity) { - if (c.getPlayer().getWedding() == null) { - c.getPlayer().startWedding(); // TODO - } - List itemnames = new ArrayList<>(); - Item item = c.getPlayer().getInventory(ItemConstants.getInventoryType(itemId)).getItem((byte)slot); - boolean bride = false; - c.getPlayer().getWedding().registerWishlistItem(item, bride); - c.announce(Wedding.OnWeddingGiftResult((byte)11, itemnames, c.getPlayer().getWedding().getWishlistItems(bride))); // todo: remove item from inventory if success - } - case 0x08: // "EXIT" - if (slea.available() != 0) { - System.out.println("WEDDING_GIFT_RESULT: " + slea.toString()); - } - c.announce(MaplePacketCreator.enableActions()); - break; - default: { - System.out.println("Unknown Mode Found: " + mode + " : " + slea.toString()); - } - } - } - */ @Override public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { - c.announce(MaplePacketCreator.enableActions()); + MapleCharacter chr = c.getPlayer(); + final byte mode = slea.readByte(); + Channel cs = c.getChannelServer(); + + if (mode == 6) { //additem + short slot = slea.readShort(); + int itemid = slea.readInt(); + short quantity = slea.readShort(); + EventInstanceManager eim = c.getPlayer().getEventInstance(); + if (eim != null) { + String name = eim.getProperty("brideId"); + MapleCharacter chrs = cs.getPlayerStorage().getCharacterById(Integer.parseInt(name)); + //MapleCharacter chrs = cs.getPlayerStorage().getCharacterById(3); + MapleInventoryType type = ItemConstants.getInventoryType(itemid); + Item item = chr.getInventory(type).getItem((byte) slot); + if (itemid == item.getItemId() && quantity <= item.getQuantity()) { + if(!(item instanceof Equip)) { + item = new Item(itemid, slot, quantity); + } + chrs.setEquips(item); + MapleInventoryManipulator.removeById(chr.getClient(), type, itemid, quantity, false, false); + c.announce(Wedding.OnWeddingGiftResult((byte) 0xB, chrs.getItens(), chrs.getItem())); + } + } + } else if (mode == 7) { // noiva abre e pega itens + byte inventId = slea.readByte(); + int itemPos = slea.readByte(); + MapleInventoryType inv = MapleInventoryType.getByType(inventId); + Item item = chr.getItemid(itemPos); + c.getAbstractPlayerInteraction().gainItem(item.getItemId(), item.getQuantity()); + chr.removeItem(item); + c.announce(Wedding.OnWeddingGiftResult((byte) 0xF, chr.getItens(), chr.getItem())); + } else if (mode == 8) { // sair update? + + c.announce(MaplePacketCreator.enableActions()); + } else { + System.out.println(mode); + } } } \ No newline at end of file diff --git a/src/net/server/world/MapleParty.java b/src/net/server/world/MapleParty.java index 721a5e1131..a3f155d8cc 100644 --- a/src/net/server/world/MapleParty.java +++ b/src/net/server/world/MapleParty.java @@ -1,24 +1,24 @@ /* - This file is part of the OdinMS Maple Story Server - Copyright (C) 2008 Patrick Huy - Matthias Butz - Jan Christian Meyer + 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 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. + 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 . -*/ + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ package net.server.world; import client.MapleClient; @@ -37,19 +37,20 @@ import net.server.audit.locks.factory.MonitoredReentrantLockFactory; import server.maps.MapleDoor; public class MapleParty { + private int id; - + private MapleParty enemy = null; private int leaderId; private List members = new LinkedList<>(); private List pqMembers = null; - + private Map histMembers = new HashMap<>(); private int nextEntry = 0; - + private Map doors = new HashMap<>(); - + private MonitoredReentrantLock lock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.PARTY, true); - + public MapleParty(int id, MaplePartyCharacter chrfor) { this.leaderId = chrfor.getId(); this.id = id; @@ -103,7 +104,7 @@ public class MapleParty { lock.unlock(); } } - + public MaplePartyCharacter getMemberById(int id) { lock.lock(); try { @@ -126,7 +127,7 @@ public class MapleParty { lock.unlock(); } } - + public List getPartyMembers() { lock.lock(); try { @@ -135,16 +136,16 @@ public class MapleParty { lock.unlock(); } } - + // used whenever entering PQs: will draw every party member that can attempt a target PQ while ingnoring those unfit. public Collection getEligibleMembers() { return Collections.unmodifiableList(pqMembers); } - + public void setEligibleMembers(List eliParty) { pqMembers = eliParty; } - + public int getId() { return id; } @@ -152,7 +153,7 @@ public class MapleParty { public void setId(int id) { this.id = id; } - + public int getLeaderId() { return leaderId; } @@ -160,8 +161,8 @@ public class MapleParty { public MaplePartyCharacter getLeader() { lock.lock(); try { - for(MaplePartyCharacter mpc: members) { - if(mpc.getId() == leaderId) { + for (MaplePartyCharacter mpc : members) { + if (mpc.getId() == leaderId) { return mpc; } } @@ -171,45 +172,53 @@ public class MapleParty { lock.unlock(); } } - + + public MapleParty getEnemy() { + return enemy; + } + + public void setEnemy(MapleParty enemy) { + this.enemy = enemy; + } + public List getMembersSortedByHistory() { List> histList; - + lock.lock(); try { histList = new LinkedList<>(histMembers.entrySet()); } finally { lock.unlock(); } - - Collections.sort(histList, new Comparator>() - { - @Override - public int compare( Entry o1, Entry o2 ) - { - return ( o1.getValue() ).compareTo( o2.getValue() ); - } - }); - + + Collections.sort(histList, new Comparator>() { + @Override + public int compare(Entry o1, Entry o2) { + return (o1.getValue()).compareTo(o2.getValue()); + } + }); + List histSort = new LinkedList<>(); - for(Entry e : histList) { + for (Entry e : histList) { histSort.add(e.getKey()); } - + return histSort; } - + public byte getPartyDoor(int cid) { List histList = getMembersSortedByHistory(); byte slot = 0; - for(Integer e: histList) { - if(e == cid) break; + for (Integer e : histList) { + if (e == cid) { + break; + } slot++; } return slot; } - + public void addDoor(Integer owner, MapleDoor door) { lock.lock(); try { @@ -218,33 +227,33 @@ public class MapleParty { lock.unlock(); } } - + public void removeDoor(Integer owner) { - lock.lock(); + lock.lock(); try { this.doors.remove(owner); } finally { lock.unlock(); } } - + public Map getDoors() { - lock.lock(); + lock.lock(); try { return Collections.unmodifiableMap(doors); } finally { lock.unlock(); } } - + public void assignNewLeader(MapleClient c) { World world = c.getWorldServer(); MaplePartyCharacter newLeadr = null; - + lock.lock(); try { - for(MaplePartyCharacter mpc : members) { - if(mpc.getId() != leaderId && (newLeadr == null || newLeadr.getLevel() < mpc.getLevel())) { + for (MaplePartyCharacter mpc : members) { + if (mpc.getId() != leaderId && (newLeadr == null || newLeadr.getLevel() < mpc.getLevel())) { newLeadr = mpc; } } @@ -252,9 +261,11 @@ public class MapleParty { lock.unlock(); } - if(newLeadr != null) world.updateParty(this.getId(), PartyOperation.CHANGE_LEADER, newLeadr); + if (newLeadr != null) { + world.updateParty(this.getId(), PartyOperation.CHANGE_LEADER, newLeadr); + } } - + public void disposeLocks() { LockCollector.getInstance().registerDisposeAction(new Runnable() { @Override @@ -263,11 +274,11 @@ public class MapleParty { } }); } - + private void emptyLocks() { lock = lock.dispose(); } - + @Override public int hashCode() { final int prime = 31; @@ -276,6 +287,17 @@ public class MapleParty { return result; } + public MaplePartyCharacter getMemberByPos(int pos) { + int i = 0; + for (MaplePartyCharacter chr : members) { + if (pos == i) { + return chr; + } + i++; + } + return null; + } + @Override public boolean equals(Object obj) { if (this == obj) { diff --git a/src/net/server/world/MaplePartyCharacter.java b/src/net/server/world/MaplePartyCharacter.java index 70d4f50cab..d2c4096c51 100644 --- a/src/net/server/world/MaplePartyCharacter.java +++ b/src/net/server/world/MaplePartyCharacter.java @@ -141,4 +141,100 @@ public class MaplePartyCharacter { public int getWorld() { return world; } + + public String getJobNameById(int job) { + switch (job) { + case 0: + return "Aprendiz"; + case 100: + return "Guerreiro";// Warrior + case 110: + return "Soldado"; + case 111: + return "Templario"; + case 112: + return "Heroi"; + case 120: + return "Escudeiro"; + case 121: + return "Cavaleiro Branco"; + case 122: + return "Paladino"; + case 130: + return "Lanceiro"; + case 131: + return "Cavaleiro Draconiano"; + case 132: + return "Cavaleiro Negro"; + + case 200: + return "Bruxo"; + case 210: + return "Feiticeiro (Fogo, Veneno)"; + case 211: + return "Mago (Fogo, Veneno)"; + case 212: + return "Arquimago (Fogo, Veneno)"; + case 220: + return "Feiticeiro (Gelo, Raio)"; + case 221: + return "Mago (Gelo, Raio)"; + case 222: + return "Arquimago (Gelo, Raio)"; + case 230: + return "Clérigo"; + case 231: + return "Sacerdote"; + case 232: + return "Sumo Sacerdote"; + + case 300: + return "Arqueiro"; + case 310: + return "Caçador"; + case 311: + return "Rastreador"; + case 312: + return "Mestre Arqueiro"; + case 320: + return "Balestreiro"; + case 321: + return "Atirador"; + case 322: + return "Atirador De Elite"; + + case 400: + return "Gatuno"; + case 410: + return "Mercenario"; + case 411: + return "Andarilho"; + case 412: + return "Lorde Negro"; + case 420: + return "Arruaceiro"; + case 421: + return "Mestre Arruaceiro"; + case 422: + return "Mestre Das Sombras"; + + case 500: + return "Pirata"; + case 510: + return "Lutador"; + case 511: + return "Saqueador"; + case 512: + return "Foragido"; + case 520: + return "Pistoleiro"; + case 521: + return "Bucaneiro"; + case 522: + return "Captain"; + + default: + return "Unknown Job"; + } + } } diff --git a/src/scripting/AbstractPlayerInteraction.java b/src/scripting/AbstractPlayerInteraction.java index e314184218..5085fee67e 100644 --- a/src/scripting/AbstractPlayerInteraction.java +++ b/src/scripting/AbstractPlayerInteraction.java @@ -237,7 +237,9 @@ public class AbstractPlayerInteraction { private static List convertToIntegerArray(List list) { List intList = new LinkedList<>(); - for(Double d: list) intList.add(d.intValue()); + for(Double d: list) { + intList.add(d.intValue()); + } return intList; } @@ -346,7 +348,9 @@ public class AbstractPlayerInteraction { } public void openNpc(int npcid, String script) { - if(c.getCM() != null) return; + if (c.getCM() != null) { + return; + } c.removeClickedNPC(); NPCScriptManager.getInstance().dispose(c); @@ -423,17 +427,23 @@ public class AbstractPlayerInteraction { MapleQuestStatus status = c.getPlayer().getQuest(MapleQuest.getInstance(qid)); String progress = status.getProgress(status.getAnyProgressKey()); - if(progress.isEmpty()) return 0; + if (progress.isEmpty()) { + return 0; + } return Integer.parseInt(progress); } public int getQuestProgress(int qid, int pid) { - if(getPlayer().getQuest(MapleQuest.getInstance(qid)).getProgress(pid).isEmpty()) return 0; + if (getPlayer().getQuest(MapleQuest.getInstance(qid)).getProgress(pid).isEmpty()) { + return 0; + } return Integer.parseInt(getPlayer().getQuest(MapleQuest.getInstance(qid)).getProgress(pid)); } public String getStringQuestProgress(int qid, int pid) { - if(getPlayer().getQuest(MapleQuest.getInstance(qid)).getProgress(pid).isEmpty()) return ""; + if (getPlayer().getQuest(MapleQuest.getInstance(qid)).getProgress(pid).isEmpty()) { + return ""; + } return getPlayer().getQuest(MapleQuest.getInstance(qid)).getProgress(pid); } @@ -548,7 +558,9 @@ public class AbstractPlayerInteraction { if(item != null) { Equip it = (Equip)item; - if(ItemConstants.isAccessory(item.getItemId()) && it.getUpgradeSlots() <= 0) it.setUpgradeSlots(3); + if (ItemConstants.isAccessory(item.getItemId()) && it.getUpgradeSlots() <= 0) { + it.setUpgradeSlots(3); + } if(ServerConstants.USE_ENHANCED_CRAFTING == true && c.getPlayer().getCS() == true) { Equip eqp = (Equip)item; @@ -562,8 +574,9 @@ public class AbstractPlayerInteraction { item = new Item(id, (short) 0, quantity, petId); } - if(expires >= 0) - item.setExpiration(System.currentTimeMillis() + expires); + if (expires >= 0) { + item.setExpiration(System.currentTimeMillis() + expires); + } if (!MapleInventoryManipulator.checkSpace(c, id, quantity, "")) { c.getPlayer().dropMessage(1, "Your inventory is full. Please remove an item from your " + ItemConstants.getInventoryType(id).name() + " inventory."); @@ -641,8 +654,6 @@ public class AbstractPlayerInteraction { showIntro(intro); } - - public void showIntro(String path) { c.announce(MaplePacketCreator.showIntro(path)); } @@ -680,8 +691,9 @@ public class AbstractPlayerInteraction { } public boolean isPartyLeader() { - if(getParty() == null) + if (getParty() == null) { return false; + } return getParty().getLeaderId() == getPlayer().getId(); } @@ -735,7 +747,6 @@ public class AbstractPlayerInteraction { givePartyExp(PQ, true); } - public void givePartyExp(String PQ, boolean instance) { //1 player = +0% bonus (100) //2 players = +0% bonus (100) @@ -1093,4 +1104,4 @@ public class AbstractPlayerInteraction { public long getCurrentTime() { return System.currentTimeMillis(); } -} +} \ No newline at end of file diff --git a/src/scripting/event/EventScriptManager.java b/src/scripting/event/EventScriptManager.java index 56c05d5f6a..2d7d16d905 100644 --- a/src/scripting/event/EventScriptManager.java +++ b/src/scripting/event/EventScriptManager.java @@ -1,24 +1,24 @@ /* - This file is part of the OdinMS Maple Story Server - Copyright (C) 2008 Patrick Huy - Matthias Butz - Jan Christian Meyer + 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 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. + 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 . -*/ + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ package scripting.event; import java.util.LinkedHashMap; @@ -38,8 +38,9 @@ import scripting.AbstractScriptManager; * @author Matze */ public class EventScriptManager extends AbstractScriptManager { - + private class EventEntry { + public EventEntry(Invocable iv, EventManager em) { this.iv = iv; this.em = em; @@ -78,10 +79,12 @@ public class EventScriptManager extends AbstractScriptManager { } } } - + private void reloadScripts() { - if (events.isEmpty()) return; - + if (events.isEmpty()) { + return; + } + Channel cserv = events.values().iterator().next().em.getChannelServer(); for (Entry entry : events.entrySet()) { String script = entry.getKey(); @@ -89,11 +92,11 @@ public class EventScriptManager extends AbstractScriptManager { events.put(script, new EventEntry(iv, new EventManager(cserv, iv, script))); } } - + public void reload() { - cancel(); + cancel(); reloadScripts(); - init(); + init(); } public void cancel() { @@ -101,4 +104,4 @@ public class EventScriptManager extends AbstractScriptManager { entry.em.cancel(); } } -} \ No newline at end of file +} diff --git a/src/scripting/event/worker/EventScriptScheduler.java b/src/scripting/event/worker/EventScriptScheduler.java index c762ae5b07..a9b1f4b421 100644 --- a/src/scripting/event/worker/EventScriptScheduler.java +++ b/src/scripting/event/worker/EventScriptScheduler.java @@ -1,22 +1,22 @@ /* - This file is part of the HeavenMS MapleStory Server - Copyleft (L) 2016 - 2018 RonanLana + 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 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. + 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 . -*/ + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ package scripting.event.worker; import constants.ServerConstants; @@ -39,63 +39,64 @@ import server.ThreadManager; * @author Ronan */ public class EventScriptScheduler { + private boolean disposed = false; private int idleProcs = 0; private Map registeredEntries = new HashMap<>(); - + private ScheduledFuture schedulerTask = null; private MonitoredReentrantLock schedulerLock; private Runnable monitorTask = new Runnable() { - @Override - public void run() { - runBaseSchedule(); - } - }; - + @Override + public void run() { + runBaseSchedule(); + } + }; + public EventScriptScheduler() { schedulerLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EM_SCHDL, true); } - + private void runBaseSchedule() { List toRemove; Map registeredEntriesCopy; - + schedulerLock.lock(); try { - if(registeredEntries.isEmpty()) { + if (registeredEntries.isEmpty()) { idleProcs++; - - if(idleProcs >= ServerConstants.MOB_STATUS_MONITOR_LIFE) { - if(schedulerTask != null) { + + if (idleProcs >= ServerConstants.MOB_STATUS_MONITOR_LIFE) { + if (schedulerTask != null) { schedulerTask.cancel(false); schedulerTask = null; } } - + return; } - + idleProcs = 0; registeredEntriesCopy = new HashMap<>(registeredEntries); } finally { schedulerLock.unlock(); } - + long timeNow = Server.getInstance().getCurrentTime(); toRemove = new LinkedList<>(); - for(Entry rmd : registeredEntriesCopy.entrySet()) { - if(rmd.getValue() < timeNow) { + for (Entry rmd : registeredEntriesCopy.entrySet()) { + if (rmd.getValue() < timeNow) { Runnable r = rmd.getKey(); - + r.run(); // runs the scheduled action toRemove.add(r); } } - - if(!toRemove.isEmpty()) { + + if (!toRemove.isEmpty()) { schedulerLock.lock(); try { - for(Runnable r : toRemove) { + for (Runnable r : toRemove) { registeredEntries.remove(r); } } finally { @@ -103,17 +104,19 @@ public class EventScriptScheduler { } } } - + public void registerEntry(final Runnable scheduledAction, final long duration) { - + ThreadManager.getInstance().newTask(new Runnable() { @Override public void run() { schedulerLock.lock(); try { idleProcs = 0; - if(schedulerTask == null) { - if(disposed) return; + if (schedulerTask == null) { + if (disposed) { + return; + } schedulerTask = TimerManager.getInstance().register(monitorTask, ServerConstants.MOB_STATUS_MONITOR_PROC, ServerConstants.MOB_STATUS_MONITOR_PROC); } @@ -125,9 +128,9 @@ public class EventScriptScheduler { } }); } - + public void cancelEntry(final Runnable scheduledAction) { - + ThreadManager.getInstance().newTask(new Runnable() { @Override public void run() { @@ -140,15 +143,15 @@ public class EventScriptScheduler { } }); } - + public void dispose() { - + ThreadManager.getInstance().newTask(new Runnable() { @Override public void run() { schedulerLock.lock(); try { - if(schedulerTask != null) { + if (schedulerTask != null) { schedulerTask.cancel(false); schedulerTask = null; } @@ -163,7 +166,7 @@ public class EventScriptScheduler { } }); } - + private void disposeLocks() { LockCollector.getInstance().registerDisposeAction(new Runnable() { @Override @@ -172,7 +175,7 @@ public class EventScriptScheduler { } }); } - + private void emptyLocks() { schedulerLock = schedulerLock.dispose(); } diff --git a/src/scripting/item/ItemScriptMethods.java b/src/scripting/item/ItemScriptMethods.java new file mode 100644 index 0000000000..206a7105bc --- /dev/null +++ b/src/scripting/item/ItemScriptMethods.java @@ -0,0 +1,35 @@ +/* + 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 . +*/ +package scripting.item; + +import client.MapleClient; +import scripting.AbstractPlayerInteraction; + +/** + * + * @author kevintjuh93 + */ +public class ItemScriptMethods extends AbstractPlayerInteraction { + public ItemScriptMethods(MapleClient c) { + super(c); + } +} diff --git a/src/scripting/npc/NPCConversationManager.java b/src/scripting/npc/NPCConversationManager.java index 906e33c2fa..cb42d07499 100644 --- a/src/scripting/npc/NPCConversationManager.java +++ b/src/scripting/npc/NPCConversationManager.java @@ -58,28 +58,47 @@ import client.inventory.Item; import client.inventory.ItemFactory; import client.inventory.MaplePet; import constants.ItemConstants; -import java.awt.Point; -import java.util.Arrays; +import constants.LinguaConstants; +import net.server.channel.Channel; +import scripting.event.EventInstanceManager; import server.MapleSkillbookInformationProvider; import server.MapleSkillbookInformationProvider.SkillBookEntry; +import server.TimerManager; import server.maps.MapleMapObject; import server.maps.MapleMapObjectType; +import server.partyquest.MonsterCarnival; +import tools.FilePrinter; +import tools.packets.Wedding; + +import java.awt.Point; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; /** * * @author Matze */ public class NPCConversationManager extends AbstractPlayerInteraction { + private int npc; private int npcOid; private String scriptName; private String getText; private boolean itemScript; + private List otherParty; public NPCConversationManager(MapleClient c, int npc, String scriptName) { this(c, npc, -1, scriptName, false); } + public NPCConversationManager(MapleClient c, int npc, List otherParty, boolean test) { + super(c); + this.c = c; + this.npc = npc; + this.otherParty = otherParty; + } + public NPCConversationManager(MapleClient c, int npc, int oid, String scriptName, boolean itemScript) { super(c); this.npc = npc; @@ -549,7 +568,9 @@ public class NPCConversationManager extends AbstractPlayerInteraction { } public int getCosmeticItem(int itemid) { - if (itemExists(itemid)) return itemid; + if (itemExists(itemid)) { + return itemid; + } int baseid; if (itemid < 30000) { @@ -594,4 +615,370 @@ public class NPCConversationManager extends AbstractPlayerInteraction { return sbe != SkillBookEntry.UNAVAILABLE ? " Obtainable through #rquestline#k." : ""; } -} + // By Drago/Dragohe4rt CPQ + WED + public int calcAvgLvl(int map) { + int num = 0; + int avg = 0; + for (MapleMapObject mmo + : c.getChannelServer().getMapFactory().getMap(map).getAllPlayer()) { + avg += ((MapleCharacter) mmo).getLevel(); + num++; + } + avg /= num; + return avg; + } + + public void sendCPQMapLists() { + String msg = LinguaConstants.Linguas(getPlayer()).CPQInicioEscolha; + for (int i = 0; i < 6; i++) { + if (fieldTaken(i)) { + if (fieldLobbied(i)) { + msg += "#b#L" + i + "#Map " + (i + 1) + " (nível: " + + calcAvgLvl(980000100 + i * 100) + " / " + + getPlayerCount(980000100 + i * 100) + "x" + + getPlayerCount(980000100 + i * 100) + ") #l\\r\\n"; + } else { + continue; + } + } else { + if (i == 0 || i == 1 || i == 2 || i == 3) { + msg += "#b#L" + i + "#Map " + (i + 1) + " (2x2) #l\\r\\n"; + } else { + msg += "#b#L" + i + "#Map " + (i + 1) + " (3x3) #l\\r\\n"; + } + } + } + sendSimple(msg); + } + + public boolean fieldTaken(int field) { + if (!c.getChannelServer().getMapFactory().getMap(980000100 + field * 100).getAllPlayer().isEmpty()) { + return true; + } + if (!c.getChannelServer().getMapFactory().getMap(980000101 + field * 100).getAllPlayer().isEmpty()) { + return true; + } + if (!c.getChannelServer().getMapFactory().getMap(980000102 + field * 100).getAllPlayer().isEmpty()) { + return true; + } + return false; + } + + public boolean fieldLobbied(int field) { + if (!c.getChannelServer().getMapFactory().getMap(980000100 + field * 100).getAllPlayer().isEmpty()) { + return true; + } + return false; + } + + public void cpqLobby(int field) { + try { + final MapleMap map, mapsaida; + Channel cs = c.getChannelServer(); + map = cs.getMapFactory().getMap(980000100 + 100 * field); + mapsaida = cs.getMapFactory().getMap(980000000); + for (MaplePartyCharacter mpc : c.getPlayer().getParty().getMembers()) { + final MapleCharacter mc; + mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + mc.changeMap(map, map.getPortal(0)); + mc.getClient().getSession().write(MaplePacketCreator.serverNotice(6, LinguaConstants.Linguas(mc).CPQEntradaLobby)); + TimerManager tMan = TimerManager.getInstance(); + tMan.schedule(new Runnable() { + @Override + public void run() { + mapClock(3 * 60); + } + }, 1500); + } + mc.timer = TimerManager.getInstance().schedule(new Runnable() { + @Override + public void run() { + mc.changeMap(mapsaida, mapsaida.getPortal(0)); + } + }, 3 * 60 * 1000); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public MapleCharacter getChrById(int id) { + Channel cs = c.getChannelServer(); + return cs.getPlayerStorage().getCharacterById(id); + } + + public void cancelarSaida() { + Channel cs = c.getChannelServer(); + for (MaplePartyCharacter mpc : c.getPlayer().getParty().getMembers()) { + MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc.timer != null) { + mc.timer.cancel(true); + mc.timer = null; + } + } + } + + public void startCPQ(final MapleCharacter challenger, final int field) { + try { + cancelarSaida(); + if (challenger != null) { + if (challenger.getParty() == null) { + throw new RuntimeException("Nao existe oponente!"); + } + for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) { + MapleCharacter mc = c.getChannelServer().getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + mc.changeMap(getPlayer().getMap(), getPlayer().getMap().getPortal(0)); + TimerManager tMan = TimerManager.getInstance(); + tMan.schedule(new Runnable() { + @Override + public void run() { + mapClock(10); + } + }, 1500); + } + } + for (MaplePartyCharacter mpc : getPlayer().getParty().getMembers()) { + MapleCharacter mc = c.getChannelServer().getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + TimerManager tMan = TimerManager.getInstance(); + tMan.schedule(new Runnable() { + @Override + public void run() { + mapClock(10); + } + }, 1500); + } + } + } + final int mapid = c.getPlayer().getMapId() + 1; + TimerManager tMan = TimerManager.getInstance(); + tMan.schedule(new Runnable() { + @Override + public void run() { + Channel cs = c.getChannelServer(); + for (MaplePartyCharacter mpc : getPlayer().getParty().getMembers()) { + MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + mc.setMonsterCarnival(null); + } + for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) { + MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + mc.setMonsterCarnival(null); + } + + new MonsterCarnival(getPlayer().getParty(), challenger.getParty(), mapid, true); + } + }, 11000); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void startCPQ2(final MapleCharacter challenger, final int field) { + try { + cancelarSaida(); + if (challenger != null) { + if (challenger.getParty() == null) { + throw new RuntimeException("Não existe oponente!"); + } + for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) { + MapleCharacter mc = c.getChannelServer().getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + mc.changeMap(getPlayer().getMap(), getPlayer().getMap().getPortal(0)); + mapClock(10); + } + } + } + final int mapid = c.getPlayer().getMapId() + 100; + TimerManager tMan = TimerManager.getInstance(); + tMan.schedule(new Runnable() { + @Override + public void run() { + Channel cs = c.getChannelServer(); + for (MaplePartyCharacter mpc : getPlayer().getParty().getMembers()) { + MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + mc.setMonsterCarnival(null); + } + for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) { + MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + mc.setMonsterCarnival(null); + } + + new MonsterCarnival(getPlayer().getParty(), challenger.getParty(), mapid, false); + } + }, 10000); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void sendCPQMapLists2() { + String msg = LinguaConstants.Linguas(getPlayer()).CPQInicioEscolha; + for (int i = 0; i < 3; i++) { + if (fieldTaken2(i)) { + if (fieldLobbied2(i)) { + msg += "#b#L" + i + "#Map " + (i + 1) + " (Nível: " + + calcAvgLvl(980031000 + i * 1000) + "#l\\r\\n"; + } else { + continue; + } + } else { + if (i == 0 || i == 1) { + msg += "#b#L" + i + "#Map " + (i + 1) + " (2x2) #l\\r\\n"; + } else { + msg += "#b#L" + i + "#Map " + (i + 1) + " (3x3) #l\\r\\n"; + } + } + } + sendSimple(msg); + } + + public boolean fieldTaken2(int field) { + if (!c.getChannelServer().getMapFactory().getMap(980031000 + field * 1000).getAllPlayer().isEmpty()) { + return true; + } + if (!c.getChannelServer().getMapFactory().getMap(980031000 + field * 1000).getAllPlayer().isEmpty()) { + return true; + } + if (!c.getChannelServer().getMapFactory().getMap(980031000 + field * 1000).getAllPlayer().isEmpty()) { + return true; + } + return false; + } + + public boolean fieldLobbied2(int field) { + if (!c.getChannelServer().getMapFactory().getMap(980031000 + field * 1000).getAllPlayer().isEmpty()) { + return true; + } + return false; + } + + public void cpqLobby2(int field) { + try { + final MapleMap map, mapsaida; + Channel cs = c.getChannelServer(); + mapsaida = cs.getMapFactory().getMap(980030000); + map = cs.getMapFactory().getMap(980031000 + 1000 * field); + for (MaplePartyCharacter mpc : c.getPlayer().getParty().getMembers()) { + final MapleCharacter mc; + mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + mc.changeMap(map, map.getPortal(0)); + mc.getClient().getSession().write(MaplePacketCreator.serverNotice(6, LinguaConstants.Linguas(mc).CPQEntradaLobby)); + TimerManager tMan = TimerManager.getInstance(); + tMan.schedule(new Runnable() { + @Override + public void run() { + mapClock(3 * 60); + } + }, 1500); + } + mc.timer = TimerManager.getInstance().schedule(new Runnable() { + @Override + public void run() { + mc.changeMap(mapsaida, mapsaida.getPortal(0)); + } + }, 3 * 60 * 1000); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void challengeParty2(int field) { + MapleCharacter leader = null; + MapleMap map = c.getChannelServer().getMapFactory().getMap(980031000 + 1000 * field); + for (MapleMapObject mmo : map.getAllPlayer()) { + MapleCharacter mc = (MapleCharacter) mmo; + if (mc.getParty() == null) { + sendOk(LinguaConstants.Linguas(mc).CPQEscolha); + return; + } + if (mc.getParty().getLeader().getId() == mc.getId()) { + leader = mc; + break; + } + } + if (leader != null) { + if (!leader.isChallenged()) { + List members = new LinkedList<>(); + for (MaplePartyCharacter fucker : c.getPlayer().getParty().getMembers()) { + members.add(fucker); + } + NPCScriptManager.getInstance().start("cpqchallenge2", leader.getClient(), npc, members); + } else { + sendOk(LinguaConstants.Linguas(leader).CPQInicioEscolhaEmEscolha); + } + } else { + sendOk(LinguaConstants.Linguas(leader).CPQLiderNaoEncontrado); + } + } + + public void mapClock(int time) { + //getPlayer().getMap().broadcastMessage(MaplePacketCreator.serverNotice(type, message)); + getPlayer().getMap().broadcastMessage(MaplePacketCreator.getClock(time)); + } + + public void challengeParty(int field) { + MapleCharacter leader = null; + MapleMap map = c.getChannelServer().getMapFactory().getMap(980000100 + 100 * field); + if (map.getAllPlayer().size() != getPlayer().getParty().getMembers().size()) { + sendOk("erro"); + return; + } + for (MapleMapObject mmo : map.getAllPlayer()) { + MapleCharacter mc = (MapleCharacter) mmo; + if (mc.getParty() == null) { + sendOk(LinguaConstants.Linguas(mc).CPQEscolha); + return; + } + if (mc.getParty().getLeader().getId() == mc.getId()) { + leader = mc; + break; + } + } + if (leader != null) { + if (!leader.isChallenged()) { + List members = new LinkedList<>(); + for (MaplePartyCharacter fucker : c.getPlayer().getParty().getMembers()) { + members.add(fucker); + } + NPCScriptManager.getInstance().start("cpqchallenge", leader.getClient(), npc, members); + } else { + sendOk(LinguaConstants.Linguas(leader).CPQInicioEscolhaEmEscolha); + } + } else { + sendOk(LinguaConstants.Linguas(leader).CPQLiderNaoEncontrado); + } + } + + public MapleCharacter getCharByName(String namee) { + try { + return getClient().getChannelServer().getPlayerStorage().getCharacterByName(namee); + } catch (Exception e) { + return null; + } + } + + public void enviarLista() { + EventInstanceManager eim = getEventInstance(); + if(eim != null) { + String name = eim.getProperty("brideId"); + MapleCharacter chr = getChrById(Integer.parseInt(name)); + //MapleCharacter chr = getChrById(3); + if (chr != null) { + if (chr.getId() == getPlayer().getId()) { + getPlayer().announce(Wedding.OnWeddingGiftResult((byte) 0xA, chr.getItens(), chr.getItem())); + } else { + getPlayer().announce(Wedding.OnWeddingGiftResult((byte) 0x09, chr.getItens(), chr.getItem())); + } + } + } + } + + public void criarLista() { + getClient().getSession().write(Wedding.sendWishList()); + } + +} \ No newline at end of file diff --git a/src/scripting/npc/NPCScriptManager.java b/src/scripting/npc/NPCScriptManager.java index 120ec9ec6f..ecda65e399 100644 --- a/src/scripting/npc/NPCScriptManager.java +++ b/src/scripting/npc/NPCScriptManager.java @@ -26,10 +26,12 @@ import client.MapleClient; import java.lang.reflect.UndeclaredThrowableException; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.script.Invocable; import javax.script.ScriptException; +import net.server.world.MaplePartyCharacter; import scripting.AbstractScriptManager; import server.MapleItemInformationProvider.ScriptedItem; @@ -43,43 +45,86 @@ import tools.MaplePacketCreator; public class NPCScriptManager extends AbstractScriptManager { private static NPCScriptManager instance = new NPCScriptManager(); - + public static NPCScriptManager getInstance() { return instance; } - + private Map cms = new HashMap<>(); private Map scripts = new HashMap<>(); - + public boolean isNpcScriptAvailable(MapleClient c, String fileName) { Invocable iv = null; if (fileName != null) { iv = getInvocable("npc/" + fileName + ".js", c); } - + return iv != null; } - + public boolean start(MapleClient c, int npc, MapleCharacter chr) { return start(c, npc, -1, chr); } - + public boolean start(MapleClient c, int npc, int oid, MapleCharacter chr) { return start(c, npc, oid, null, chr); } - + public boolean start(MapleClient c, int npc, String fileName, MapleCharacter chr) { return start(c, npc, -1, fileName, chr); } - + public boolean start(MapleClient c, int npc, int oid, String fileName, MapleCharacter chr) { return start(c, npc, oid, fileName, chr, false, "cm"); } - + public boolean start(MapleClient c, ScriptedItem scriptItem, MapleCharacter chr) { return start(c, scriptItem.getNpc(), -1, scriptItem.getScript(), chr, true, "im"); } + public void start(String filename, MapleClient c, int npc, List chrs) { + try { + NPCConversationManager cm = new NPCConversationManager(c, npc, chrs, true); + cm.dispose(); + if (cms.containsKey(c)) { + return; + } + cms.put(c, cm); + Invocable iv = null; + iv = getInvocable("npc/" + filename + ".js", c); + NPCScriptManager npcsm = NPCScriptManager.getInstance(); + + if (iv == null || NPCScriptManager.getInstance() == null) { + c.getPlayer().dropMessage(1, npc + ""); + cm.dispose(); + return; + } + if (iv == null || npcsm == null) { + c.getPlayer().dropMessage(1, npc + ""); + cm.dispose(); + return; + } + engine.put("cm", cm); + scripts.put(c, iv); + try { + iv.invokeFunction("start", chrs); + } catch (final NoSuchMethodException nsme) { + try { + iv.invokeFunction("start", chrs); + } catch (final NoSuchMethodException nsma) { + nsma.printStackTrace(); + } + } + + } catch (final UndeclaredThrowableException ute) { + FilePrinter.printError(FilePrinter.NPC + npc + ".txt", ute); + dispose(c); + } catch (final Exception e) { + FilePrinter.printError(FilePrinter.NPC + npc + ".txt", e); + dispose(c); + } + } + private boolean start(MapleClient c, int npc, int oid, String fileName, MapleCharacter chr, boolean itemScript, String engineName) { try { NPCConversationManager cm = new NPCConversationManager(c, npc, oid, fileName, itemScript); @@ -121,17 +166,17 @@ public class NPCScriptManager extends AbstractScriptManager { } else { c.announce(MaplePacketCreator.enableActions()); } - + return true; } catch (final UndeclaredThrowableException | ScriptException ute) { FilePrinter.printError(FilePrinter.NPC + npc + ".txt", ute); dispose(c); - + return false; } catch (final Exception e) { FilePrinter.printError(FilePrinter.NPC + npc + ".txt", e); dispose(c); - + return false; } } @@ -157,9 +202,9 @@ public class NPCScriptManager extends AbstractScriptManager { c.getPlayer().setNpcCooldown(System.currentTimeMillis()); cms.remove(c); scripts.remove(c); - + String scriptFolder = (cm.isItemScript() ? "item" : "npc"); - if(cm.getScriptName() != null) { + if (cm.getScriptName() != null) { resetContext(scriptFolder + "/" + cm.getScriptName() + ".js", c); } else { resetContext(scriptFolder + "/" + cm.getNpc() + ".js", c); diff --git a/src/scripting/reactor/ReactorActionManager.java b/src/scripting/reactor/ReactorActionManager.java index 9dcc75aa4f..267282c7d9 100644 --- a/src/scripting/reactor/ReactorActionManager.java +++ b/src/scripting/reactor/ReactorActionManager.java @@ -47,6 +47,8 @@ import server.maps.MapMonitor; import server.maps.MapleMap; import server.maps.MapleReactor; import server.maps.ReactorDropEntry; +import server.partyquest.MapleCarnivalFactory; +import server.partyquest.MapleCarnivalFactory.MCSkill; import tools.MaplePacketCreator; /** @@ -311,4 +313,20 @@ public class ReactorActionManager extends AbstractPlayerInteraction { } }, timestamp); } + + public void dispelAllMonsters(int num, int team) { //dispels all mobs, cpq + final MCSkill skil = MapleCarnivalFactory.getInstance().getGuardian(num); + if (skil != null) { + for (MapleMonster mons : getMap().getMonsters()) { + if(mons.getTeam() == team) { + mons.dispelSkill(skil.getSkill()); + } + } + } + if (team == 0) { + getPlayer().getMap().getRedTeamBuffs().remove(skil); + } else { + getPlayer().getMap().getBlueTeamBuffs().remove(skil); + } + } } \ No newline at end of file diff --git a/src/server/MapleStatEffect.java b/src/server/MapleStatEffect.java index 9df69bcf91..5c83c32285 100644 --- a/src/server/MapleStatEffect.java +++ b/src/server/MapleStatEffect.java @@ -50,7 +50,6 @@ import client.MapleCharacter; import client.MapleDisease; import client.MapleJob; import client.MapleMount; -import client.MapleStat; import client.Skill; import client.SkillFactory; import client.inventory.Item; @@ -111,6 +110,10 @@ import constants.skills.SuperGM; import constants.skills.ThunderBreaker; import constants.skills.WhiteKnight; import constants.skills.WindArcher; +import net.server.world.MapleParty; +import net.server.world.MaplePartyCharacter; +import server.partyquest.MapleCarnivalFactory; +import server.partyquest.MapleCarnivalFactory.MCSkill; /** * @author Matze @@ -129,6 +132,8 @@ public class MapleStatEffect { private boolean overTime, repeatEffect; private int sourceid; private int moveTo; + private int cp, nuffSkill; + private List cureDebuffs; private boolean skill; private List> statups; private Map monsterStatus; @@ -155,17 +160,15 @@ public class MapleStatEffect { } private static byte mapProtection(int sourceid) { - if(sourceid == 2022001 || sourceid == 2022186) { + if (sourceid == 2022001 || sourceid == 2022186) { return 1; //elnath cold - } - - else if(sourceid == 2022040) { + } else if (sourceid == 2022040) { return 2; //aqua road underwater + } else { + return 0; } - - else return 0; } - + private static MapleStatEffect loadFromData(MapleData source, int sourceid, boolean skill, boolean overTime) { MapleStatEffect ret = new MapleStatEffect(); ret.duration = MapleDataTool.getIntConvert("time", source, -1); @@ -177,6 +180,27 @@ public class MapleStatEffect { ret.hpCon = (short) MapleDataTool.getInt("hpCon", source, 0); int iprop = MapleDataTool.getInt("prop", source, 100); ret.prop = iprop / 100.0; + + ret.cp = MapleDataTool.getInt("cp", source, 0); + List cure = new ArrayList(5); + if (MapleDataTool.getInt("poison", source, 0) > 0) { + cure.add(MapleDisease.POISON); + } + if (MapleDataTool.getInt("seal", source, 0) > 0) { + cure.add(MapleDisease.SEAL); + } + if (MapleDataTool.getInt("darkness", source, 0) > 0) { + cure.add(MapleDisease.DARKNESS); + } + if (MapleDataTool.getInt("weakness", source, 0) > 0) { + cure.add(MapleDisease.WEAKEN); + } + if (MapleDataTool.getInt("curse", source, 0) > 0) { + cure.add(MapleDisease.CURSE); + } + ret.cureDebuffs = cure; + ret.nuffSkill = MapleDataTool.getInt("nuffSkill", source, 0); + ret.mobCount = MapleDataTool.getInt("mobCount", source, 1); ret.cooldown = MapleDataTool.getInt("cooltime", source, 0); ret.morphId = MapleDataTool.getInt("morph", source, 0); @@ -192,7 +216,7 @@ public class MapleStatEffect { ret.duration *= 1000; // items have their times stored in ms, of course ret.overTime = overTime; } - + ArrayList> statups = new ArrayList<>(); ret.watk = (short) MapleDataTool.getInt("pad", source, 0); ret.wdef = (short) MapleDataTool.getInt("pdd", source, 0); @@ -200,23 +224,23 @@ public class MapleStatEffect { ret.mdef = (short) MapleDataTool.getInt("mdd", source, 0); ret.acc = (short) MapleDataTool.getIntConvert("acc", source, 0); ret.avoid = (short) MapleDataTool.getInt("eva", source, 0); - + ret.speed = (short) MapleDataTool.getInt("speed", source, 0); ret.jump = (short) MapleDataTool.getInt("jump", source, 0); - + ret.mapProtection = mapProtection(sourceid); addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MAP_PROTECTION, Integer.valueOf(ret.mapProtection)); - + if (ret.overTime && ret.getSummonMovementType() == null) { - if(!skill) { - if(isPyramidBuff(sourceid)) { + if (!skill) { + if (isPyramidBuff(sourceid)) { ret.berserk = MapleDataTool.getInt("berserk", source, 0); ret.booster = MapleDataTool.getInt("booster", source, 0); - + addBuffStatPairToListIfNotZero(statups, MapleBuffStat.BERSERK, Integer.valueOf(ret.berserk)); addBuffStatPairToListIfNotZero(statups, MapleBuffStat.BOOSTER, Integer.valueOf(ret.booster)); - - } else if(isDojoBuff(sourceid) || isHpMpRecovery(sourceid)) { + + } else if (isDojoBuff(sourceid) || isHpMpRecovery(sourceid)) { ret.mhpR = (byte) MapleDataTool.getInt("mhpR", source, 0); ret.mhpRRate = (short) (MapleDataTool.getInt("mhpRRate", source, 0) * 100); ret.mmpR = (byte) MapleDataTool.getInt("mmpR", source, 0); @@ -224,9 +248,9 @@ public class MapleStatEffect { addBuffStatPairToListIfNotZero(statups, MapleBuffStat.HPREC, Integer.valueOf(ret.mhpR)); addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MPREC, Integer.valueOf(ret.mmpR)); - - } else if(isRateCoupon(sourceid)) { - switch(MapleDataTool.getInt("expR", source, 0)) { + + } else if (isRateCoupon(sourceid)) { + switch (MapleDataTool.getInt("expR", source, 0)) { case 1: addBuffStatPairToListIfNotZero(statups, MapleBuffStat.COUPON_EXP1, 1); break; @@ -244,7 +268,7 @@ public class MapleStatEffect { break; } - switch(MapleDataTool.getInt("drpR", source, 0)) { + switch (MapleDataTool.getInt("drpR", source, 0)) { case 1: addBuffStatPairToListIfNotZero(statups, MapleBuffStat.COUPON_DRP1, 1); break; @@ -257,18 +281,18 @@ public class MapleStatEffect { addBuffStatPairToListIfNotZero(statups, MapleBuffStat.COUPON_DRP3, 1); break; } - } else if(isExpIncrease(sourceid)) { + } else if (isExpIncrease(sourceid)) { addBuffStatPairToListIfNotZero(statups, MapleBuffStat.EXP_INCREASE, MapleDataTool.getInt("expinc", source, 0)); } } else { - if(isMapChair(sourceid)) { + if (isMapChair(sourceid)) { addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MAP_CHAIR, 1); - } else if((sourceid == Beginner.NIMBLE_FEET || sourceid == Noblesse.NIMBLE_FEET || sourceid == Evan.NIMBLE_FEET || sourceid == Legend.AGILE_BODY) && ServerConstants.USE_ULTRA_NIMBLE_FEET == true) { - ret.jump = (short)(ret.speed * 4); + } else if ((sourceid == Beginner.NIMBLE_FEET || sourceid == Noblesse.NIMBLE_FEET || sourceid == Evan.NIMBLE_FEET || sourceid == Legend.AGILE_BODY) && ServerConstants.USE_ULTRA_NIMBLE_FEET == true) { + ret.jump = (short) (ret.speed * 4); ret.speed *= 15; } } - + addBuffStatPairToListIfNotZero(statups, MapleBuffStat.WATK, Integer.valueOf(ret.watk)); addBuffStatPairToListIfNotZero(statups, MapleBuffStat.WDEF, Integer.valueOf(ret.wdef)); addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MATK, Integer.valueOf(ret.matk)); @@ -278,26 +302,26 @@ public class MapleStatEffect { addBuffStatPairToListIfNotZero(statups, MapleBuffStat.SPEED, Integer.valueOf(ret.speed)); addBuffStatPairToListIfNotZero(statups, MapleBuffStat.JUMP, Integer.valueOf(ret.jump)); } - + MapleData ltd = source.getChildByPath("lt"); if (ltd != null) { ret.lt = (Point) ltd.getData(); ret.rb = (Point) source.getChildByPath("rb").getData(); - - if(ServerConstants.USE_MAXRANGE_ECHO_OF_HERO && (sourceid == Beginner.ECHO_OF_HERO || sourceid == Noblesse.ECHO_OF_HERO || sourceid == Legend.ECHO_OF_HERO || sourceid == Evan.ECHO_OF_HERO)) { + + if (ServerConstants.USE_MAXRANGE_ECHO_OF_HERO && (sourceid == Beginner.ECHO_OF_HERO || sourceid == Noblesse.ECHO_OF_HERO || sourceid == Legend.ECHO_OF_HERO || sourceid == Evan.ECHO_OF_HERO)) { ret.lt = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE); ret.rb = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); } } - + int x = MapleDataTool.getInt("x", source, 0); - - if((sourceid == Beginner.RECOVERY || sourceid == Noblesse.RECOVERY || sourceid == Evan.RECOVERY || sourceid == Legend.RECOVERY) && ServerConstants.USE_ULTRA_RECOVERY == true) { + + if ((sourceid == Beginner.RECOVERY || sourceid == Noblesse.RECOVERY || sourceid == Evan.RECOVERY || sourceid == Legend.RECOVERY) && ServerConstants.USE_ULTRA_RECOVERY == true) { x *= 10; } ret.x = x; ret.y = MapleDataTool.getInt("y", source, 0); - + ret.damage = MapleDataTool.getIntConvert("damage", source, 100); ret.fixdamage = MapleDataTool.getIntConvert("fixdamage", source, -1); ret.attackCount = MapleDataTool.getIntConvert("attackCount", source, 1); @@ -416,8 +440,8 @@ public class MapleStatEffect { break; case BlazeWizard.ELEMENTAL_RESET: case Evan.ELEMENTAL_RESET: - statups.add(new Pair<>(MapleBuffStat.ELEMENTAL_RESET, Integer.valueOf(x))); - break; + statups.add(new Pair<>(MapleBuffStat.ELEMENTAL_RESET, Integer.valueOf(x))); + break; case Evan.MAGIC_SHIELD: statups.add(new Pair<>(MapleBuffStat.MAGIC_SHIELD, Integer.valueOf(x))); break; @@ -425,7 +449,7 @@ public class MapleStatEffect { statups.add(new Pair<>(MapleBuffStat.MAGIC_RESISTANCE, Integer.valueOf(x))); break; case Evan.SLOW: - statups.add(new Pair<>(MapleBuffStat.SLOW, Integer.valueOf(x))); + statups.add(new Pair<>(MapleBuffStat.SLOW, Integer.valueOf(x))); // BOWMAN case Priest.MYSTIC_DOOR: case Hunter.SOUL_ARROW: @@ -474,7 +498,7 @@ public class MapleStatEffect { break; case ChiefBandit.PICKPOCKET: statups.add(new Pair<>(MapleBuffStat.PICKPOCKET, Integer.valueOf(x))); - break; + break; case NightLord.SHADOW_STARS: statups.add(new Pair<>(MapleBuffStat.SHADOW_CLAW, Integer.valueOf(0))); break; @@ -605,7 +629,7 @@ public class MapleStatEffect { case Buccaneer.BARRAGE: case Gunslinger.BLANK_SHOT: case DawnWarrior.COMA: - case ThunderBreaker.BARRAGE: + case ThunderBreaker.BARRAGE: case Aran.ROLLING_SPIN: case Evan.FIRE_BREATH: case Evan.BLAZE: @@ -633,7 +657,7 @@ public class MapleStatEffect { case ILWizard.SLOW: case BlazeWizard.SLOW: monsterStatus.put(MonsterStatus.SPEED, Integer.valueOf(ret.x)); - break; + break; case FPWizard.POISON_BREATH: case FPMage.ELEMENT_COMPOSITION: monsterStatus.put(MonsterStatus.POISON, Integer.valueOf(1)); @@ -655,7 +679,7 @@ public class MapleStatEffect { monsterStatus.put(MonsterStatus.FREEZE, Integer.valueOf(1)); break; case Evan.PHANTOM_IMPRINT: - monsterStatus.put(MonsterStatus.PHANTOM_IMPRINT, Integer.valueOf(x)); + monsterStatus.put(MonsterStatus.PHANTOM_IMPRINT, Integer.valueOf(x)); //ARAN case Aran.COMBO_ABILITY: statups.add(new Pair<>(MapleBuffStat.ARAN_COMBO, Integer.valueOf(100))); @@ -723,19 +747,19 @@ public class MapleStatEffect { public boolean applyEchoOfHero(MapleCharacter applyfrom) { Map mapPlayers = applyfrom.getMap().getMapPlayers(); mapPlayers.remove(applyfrom.getId()); - + boolean hwResult = applyTo(applyfrom); for (MapleCharacter chr : mapPlayers.values()) { // Echo of Hero not buffing players in the map detected thanks to Masterrulax applyTo(applyfrom, chr, false, null, false, 1); } - + return hwResult; } - + public boolean applyTo(MapleCharacter chr) { return applyTo(chr, chr, true, null, false, 1); } - + public boolean applyTo(MapleCharacter chr, boolean useMaxRange) { return applyTo(chr, chr, true, null, useMaxRange, 1); } @@ -750,16 +774,16 @@ public class MapleStatEffect { applyto.toggleHide(false); return true; } - + if (primary && isHeal()) { affectedPlayers = applyBuff(applyfrom, useMaxRange); } - + int hpchange = calcHPChange(applyfrom, primary, affectedPlayers); int mpchange = calcMPChange(applyfrom, primary); if (primary) { if (itemConNo != 0) { - if(!applyto.getClient().getAbstractPlayerInteraction().hasItem(itemCon, itemConNo)) { + if (!applyto.getClient().getAbstractPlayerInteraction().hasItem(itemCon, itemConNo)) { applyto.announce(MaplePacketCreator.enableActions()); return false; } @@ -771,7 +795,7 @@ public class MapleStatEffect { applyto.broadcastStance(applyto.isFacingLeft() ? 5 : 4); } } - + if (isDispel() && makeChanceResult()) { applyto.dispelDebuffs(); } else if (isCureAllAbnormalStatus()) { @@ -784,24 +808,26 @@ public class MapleStatEffect { /*if (applyfrom.getMp() < getMpCon()) { AutobanFactory.MPCON.addPoint(applyfrom.getAutobanManager(), "mpCon hack for skill:" + sourceid + "; Player MP: " + applyto.getMp() + " MP Needed: " + getMpCon()); } */ - + if (!applyto.applyHpMpChange(hpCon, hpchange, mpchange)) { applyto.announce(MaplePacketCreator.enableActions()); return false; } - + if (moveTo != -1) { if (moveTo != applyto.getMapId()) { MapleMap target; MaplePortal pt; - + if (moveTo == 999999999) { - if(sourceid != 2030100) { + if (sourceid != 2030100) { target = applyto.getMap().getReturnMap(); pt = target.getRandomPlayerSpawnpoint(); } else { - if(!applyto.canRecoverLastBanish()) return false; - + if (!applyto.canRecoverLastBanish()) { + return false; + } + Pair lastBanishInfo = applyto.getLastBanishData(); target = applyto.getWarpMap(lastBanishInfo.getLeft()); pt = target.getPortal(lastBanishInfo.getRight()); @@ -810,12 +836,12 @@ public class MapleStatEffect { target = applyto.getClient().getWorldServer().getChannel(applyto.getClient().getChannel()).getMapFactory().getMap(moveTo); int targetid = target.getId() / 10000000; if (targetid != 60 && applyto.getMapId() / 10000000 != 61 && targetid != applyto.getMapId() / 10000000 && targetid != 21 && targetid != 20 && targetid != 12 && (applyto.getMapId() / 10000000 != 10 && applyto.getMapId() / 10000000 != 12)) { - return false; + return false; } - + pt = target.getRandomPlayerSpawnpoint(); } - + applyto.changeMap(target, pt); } else { return false; @@ -842,15 +868,15 @@ public class MapleStatEffect { SummonMovementType summonMovementType = getSummonMovementType(); if (overTime || isCygnusFA() || summonMovementType != null) { if (summonMovementType != null && pos != null) { - if(summonMovementType.getValue() == summonMovementType.STATIONARY.getValue()) { + if (summonMovementType.getValue() == summonMovementType.STATIONARY.getValue()) { applyto.cancelBuffStats(MapleBuffStat.PUPPET); } else { applyto.cancelBuffStats(MapleBuffStat.SUMMON); } - + applyto.announce(MaplePacketCreator.enableActions()); } - + applyBuffEffect(applyfrom, applyto, primary); } @@ -863,7 +889,7 @@ public class MapleStatEffect { applyMonsterBuff(applyfrom); } } - + if (this.getFatigue() != 0) { applyto.getMount().setTiredness(applyto.getMount().getTiredness() + this.getFatigue()); } @@ -880,25 +906,29 @@ public class MapleStatEffect { if (isMagicDoor() && !FieldLimit.DOOR.check(applyto.getMap().getFieldLimit())) { // Magic Door int y = applyto.getFh(); if (y == 0) { - y = applyto.getPosition().y; + y = applyto.getPosition().y; } Point doorPosition = new Point(applyto.getPosition().x, y); MapleDoor door = new MapleDoor(applyto, doorPosition); - - if(door.getOwnerId() >= 0) { + + if (door.getOwnerId() >= 0) { applyto.applyPartyDoor(door, false); door.getTarget().spawnDoor(door.getAreaDoor()); door.getTown().spawnDoor(door.getTownDoor()); - + applyto.disableDoorSpawn(); } else { MapleInventoryManipulator.addFromDrop(applyto.getClient(), new Item(4006000, (short) 0, (short) 1), false); - - if(door.getOwnerId() == -3) applyto.dropMessage(5, "Mystic Door cannot be cast far from a spawn point. Nearest one is at " + door.getDoorStatus().getRight() + "pts " + door.getDoorStatus().getLeft()); - else if(door.getOwnerId() == -2) applyto.dropMessage(5, "Mystic Door cannot be cast on a slope, try elsewhere."); - else applyto.dropMessage(5, "There are no door portals available for the town at this moment. Try again later."); - + + if (door.getOwnerId() == -3) { + applyto.dropMessage(5, "Mystic Door cannot be cast far from a spawn point. Nearest one is at " + door.getDoorStatus().getRight() + "pts " + door.getDoorStatus().getLeft()); + } else if (door.getOwnerId() == -2) { + applyto.dropMessage(5, "Mystic Door cannot be cast on a slope, try elsewhere."); + } else { + applyto.dropMessage(5, "There are no door portals available for the town at this moment. Try again later."); + } + applyto.cancelBuffStats(MapleBuffStat.SOULARROW); // cancel door buff } } else if (isMist()) { @@ -907,14 +937,51 @@ public class MapleStatEffect { applyfrom.getMap().spawnMist(mist, getDuration(), mist.isPoisonMist(), false, mist.isRecoveryMist()); } else if (isTimeLeap()) { applyto.removeAllCooldownsExcept(Buccaneer.TIME_LEAP, true); + } else if (cp != 0 && applyto.getMonsterCarnival() != null) { + applyto.gainCP(cp); + } else if (nuffSkill != 0 && applyto.getParty() != null && applyto.getMap().isCPQMap()) { // by Drago-Dragohe4rt + final MCSkill skil = MapleCarnivalFactory.getInstance().getSkill(nuffSkill); + if (skil != null) { + final MapleDisease dis = skil.getDisease(); + MapleParty inimigos = applyfrom.getParty().getEnemy(); + if (nuffSkill == 8) { + int amount = inimigos.getMembers().size() - 1; + int randd = (int) Math.floor(Math.random() * amount); + MapleCharacter chrApp = applyfrom.getClient().getChannelServer().getPlayerStorage().getCharacterById(inimigos.getMemberByPos(randd).getId()); + if (chrApp != null && chrApp.getMap().isCPQMap()) { + chrApp.dispel(); + } + } else { + for (MaplePartyCharacter chrsInimigos : inimigos.getPartyMembers()) { + MapleCharacter chrApp = chrsInimigos.getPlayer(); + if (chrApp != null && chrApp.getMap().isCPQMap()) { + if (dis == null) { + chrApp.dispel(); + } else if (skil.getSkill() != null) { + chrApp.giveDebuff(dis, skil.getSkill()); + } + } + } + } + } + } else if (cureDebuffs.size() > 0) { // by Drago-Dragohe4rt + for (final MapleDisease debuff : cureDebuffs) { + if (applyfrom.getParty() != null) { + for (MaplePartyCharacter chrs : applyfrom.getParty().getPartyMembers()) { + chrs.getPlayer().dispelDebuff(debuff); + } + } else { + applyfrom.dispelDebuff(debuff); + } + } } - + return true; } private int applyBuff(MapleCharacter applyfrom, boolean useMaxRange) { int affectedc = 1; - + if (isPartyBuff() && (applyfrom.getParty() != null || isGmBuff())) { Rectangle bounds = (!useMaxRange) ? calculateBoundingBox(applyfrom.getPosition(), applyfrom.isFacingLeft()) : new Rectangle(Integer.MIN_VALUE / 2, Integer.MIN_VALUE / 2, Integer.MAX_VALUE, Integer.MAX_VALUE); List affecteds = applyfrom.getMap().getMapObjectsInRect(bounds, Arrays.asList(MapleMapObjectType.PLAYER)); @@ -933,7 +1000,7 @@ public class MapleStatEffect { } } } - + affectedc += affectedp.size(); // used for heal for (MapleCharacter affected : affectedp) { applyTo(applyfrom, affected, false, null, useMaxRange, affectedc); @@ -941,7 +1008,7 @@ public class MapleStatEffect { affected.getMap().broadcastMessage(affected, MaplePacketCreator.showBuffeffect(affected.getId(), sourceid, 2), false); } } - + return affectedc; } @@ -952,15 +1019,15 @@ public class MapleStatEffect { int i = 0; for (MapleMapObject mo : affected) { MapleMonster monster = (MapleMonster) mo; - if (isDispel()) { - monster.debuffMob(skill_.getId()); + if (isDispel()) { + monster.debuffMob(skill_.getId()); } else { - if (makeChanceResult()) { - monster.applyStatus(applyfrom, new MonsterStatusEffect(getMonsterStati(), skill_, null, false), isPoison(), getDuration()); - if (isCrash()) { - monster.debuffMob(skill_.getId()); - } + if (makeChanceResult()) { + monster.applyStatus(applyfrom, new MonsterStatusEffect(getMonsterStati(), skill_, null, false), isPoison(), getDuration()); + if (isCrash()) { + monster.debuffMob(skill_.getId()); } + } } i++; if (i >= mobCount) { @@ -982,17 +1049,17 @@ public class MapleStatEffect { Rectangle bounds = new Rectangle(mylt.x, mylt.y, myrb.x - mylt.x, myrb.y - mylt.y); return bounds; } - + public int getBuffLocalDuration() { return !ServerConstants.USE_BUFF_EVERLASTING ? duration : Integer.MAX_VALUE; } - + public void silentApplyBuff(MapleCharacter chr, long localStartTime) { int localDuration = getBuffLocalDuration(); localDuration = alchemistModifyVal(chr, localDuration, false); //CancelEffectAction cancelAction = new CancelEffectAction(chr, this, starttime); //ScheduledFuture schedule = TimerManager.getInstance().schedule(cancelAction, ((starttime + localDuration) - Server.getInstance().getCurrentTime())); - + chr.registerEffect(this, localStartTime, localStartTime + localDuration, true); SummonMovementType summonMovementType = getSummonMovementType(); if (summonMovementType != null) { @@ -1016,7 +1083,7 @@ public class MapleStatEffect { // final ScheduledFuture schedule = TimerManager.getInstance().schedule(cancelAction, ((starttime + 99999) - Server.getInstance().getCurrentTime())); applyto.registerEffect(this, starttime, Long.MAX_VALUE, false); } - + public final void applyBeaconBuff(final MapleCharacter applyto, int objectid) { // thanks Thora & Hyun for reporting an issue with homing beacon autoflagging mobs when changing maps final List> stat = Collections.singletonList(new Pair<>(MapleBuffStat.HOMING_BEACON, objectid)); applyto.announce(MaplePacketCreator.giveBuff(1, sourceid, stat)); @@ -1024,14 +1091,14 @@ public class MapleStatEffect { final long starttime = Server.getInstance().getCurrentTime(); applyto.registerEffect(this, starttime, Long.MAX_VALUE, false); } - + public void updateBuffEffect(MapleCharacter target, List> activeStats, long starttime) { int localDuration = getBuffLocalDuration(); localDuration = alchemistModifyVal(target, localDuration, false); - + long leftDuration = (starttime + localDuration) - Server.getInstance().getCurrentTime(); - if(leftDuration > 0) { - target.announce(MaplePacketCreator.giveBuff((skill ? sourceid : -sourceid), (int)leftDuration, activeStats)); + if (leftDuration > 0) { + target.announce(MaplePacketCreator.giveBuff((skill ? sourceid : -sourceid), (int) leftDuration, activeStats)); } } @@ -1067,7 +1134,7 @@ public class MapleStatEffect { if (applyto.getMount() == null) { applyto.mount(ridingMountId, sourceid); } - + applyto.getClient().getWorldServer().registerMountHunger(applyto); } if (sourceid == Corsair.BATTLE_SHIP) { @@ -1089,8 +1156,8 @@ public class MapleStatEffect { localsourceid = ridingMountId; localstatups = Collections.singletonList(new Pair<>(MapleBuffStat.MONSTER_RIDING, 0)); } else if (isSkillMorph()) { - for(int i = 0; i < localstatups.size(); i++) { - if(localstatups.get(i).getLeft().equals(MapleBuffStat.MORPH)) { + for (int i = 0; i < localstatups.size(); i++) { + if (localstatups.get(i).getLeft().equals(MapleBuffStat.MORPH)) { localstatups.set(i, new Pair<>(MapleBuffStat.MORPH, getMorph(applyto))); break; } @@ -1110,7 +1177,7 @@ public class MapleStatEffect { buff = MaplePacketCreator.givePirateBuff(statups, sourceid, seconds); mbuff = MaplePacketCreator.giveForeignPirateBuff(applyto.getId(), sourceid, seconds, localstatups); } else if (isInfusion()) { - buff = MaplePacketCreator.givePirateBuff(localstatups, sourceid, seconds); + buff = MaplePacketCreator.givePirateBuff(localstatups, sourceid, seconds); mbuff = MaplePacketCreator.giveForeignPirateBuff(applyto.getId(), sourceid, seconds, localstatups); } else if (isDs()) { List> dsstat = Collections.singletonList(new Pair<>(MapleBuffStat.DARKSIGHT, 0)); @@ -1125,10 +1192,10 @@ public class MapleStatEffect { if (applyto.getBattleshipHp() <= 0) { applyto.resetBattleshipHp(); } - + localstatups = statups; } - + buff = MaplePacketCreator.giveBuff(localsourceid, localDuration, localstatups); mbuff = MaplePacketCreator.showMonsterRiding(applyto.getId(), givemount); localDuration = duration; @@ -1144,15 +1211,15 @@ public class MapleStatEffect { List> stat = Collections.singletonList(new Pair<>(MapleBuffStat.MORPH, Integer.valueOf(getMorph(applyto)))); mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), stat); } - + if (buff != null) { - if (!hasNoIcon()) { //Thanks flav for such a simple release! :) + if (!hasNoIcon()) { //Thanks flav for such a simple release! :) applyto.announce(buff); - } else { + } else { System.out.println(" NO buff icon for id " + sourceid); } } - + long starttime = Server.getInstance().getCurrentTime(); //CancelEffectAction cancelAction = new CancelEffectAction(applyto, this, starttime); //ScheduledFuture schedule = TimerManager.getInstance().schedule(cancelAction, localDuration); @@ -1273,7 +1340,7 @@ public class MapleStatEffect { case Beginner.ECHO_OF_HERO: case Noblesse.ECHO_OF_HERO: case Legend.ECHO_OF_HERO: - case Evan.ECHO_OF_HERO: + case Evan.ECHO_OF_HERO: case SuperGM.HEAL_PLUS_DISPEL: case SuperGM.HASTE: case SuperGM.HOLY_SYMBOL: @@ -1346,45 +1413,44 @@ public class MapleStatEffect { public boolean isRecovery() { return sourceid == Beginner.RECOVERY || sourceid == Noblesse.RECOVERY || sourceid == Legend.RECOVERY || sourceid == Evan.RECOVERY; } - + public boolean isMapChair() { return sourceid == Beginner.MAP_CHAIR || sourceid == Noblesse.MAP_CHAIR || sourceid == Legend.MAP_CHAIR; } - + public static boolean isMapChair(int sourceid) { return sourceid == Beginner.MAP_CHAIR || sourceid == Noblesse.MAP_CHAIR || sourceid == Legend.MAP_CHAIR; } - - + public boolean isDojoBuff() { return sourceid >= 2022359 && sourceid <= 2022421; } - + public static boolean isDojoBuff(int sourceid) { return sourceid >= 2022359 && sourceid <= 2022421; } - + public static boolean isHpMpRecovery(int sourceid) { return sourceid == 2022198 || sourceid == 2022337; } - + public static boolean isPyramidBuff(int sourceid) { return sourceid >= 2022585 && sourceid <= 2022617; } - + public static boolean isRateCoupon(int sourceid) { int itemType = sourceid / 1000; return itemType == 5211 || itemType == 5360; } - + public static boolean isExpIncrease(int sourceid) { return sourceid >= 2022450 && sourceid <= 2022452; } - + private boolean isDs() { return skill && (sourceid == Rogue.DARK_SIGHT || sourceid == NightWalker.DARK_SIGHT); } - + private boolean isWw() { return skill && (sourceid == WindArcher.WIND_WALK); } @@ -1412,11 +1478,11 @@ public class MapleStatEffect { private boolean isCouponBuff() { return isRateCoupon(sourceid); } - + private boolean isMysticDoor() { return skill && sourceid == Priest.MYSTIC_DOOR; } - + public boolean isMonsterRiding() { return skill && (sourceid % 10000000 == 1004 || sourceid == Corsair.BATTLE_SHIP || sourceid == Beginner.SPACESHIP || sourceid == Noblesse.SPACESHIP || sourceid == Beginner.YETI_MOUNT1 || sourceid == Beginner.YETI_MOUNT2 || sourceid == Beginner.WITCH_BROOMSTICK || sourceid == Beginner.BALROG_MOUNT @@ -1431,11 +1497,11 @@ public class MapleStatEffect { public boolean isPoison() { return skill && (sourceid == FPMage.POISON_MIST || sourceid == FPWizard.POISON_BREATH || sourceid == FPMage.ELEMENT_COMPOSITION || sourceid == NightWalker.POISON_BOMB || sourceid == BlazeWizard.FLAME_GEAR); } - + public boolean isMorph() { return morphId > 0; } - + public boolean isMorphWithoutAttack() { return morphId > 0 && morphId < 100; // Every morph item I have found has been under 100, pirate skill transforms start at 1000. } @@ -1453,9 +1519,9 @@ public class MapleStatEffect { } private boolean isCrash() { - return skill && (sourceid == DragonKnight.POWER_CRASH || sourceid == Crusader.ARMOR_CRASH || sourceid == WhiteKnight.MAGIC_CRASH); + return skill && (sourceid == DragonKnight.POWER_CRASH || sourceid == Crusader.ARMOR_CRASH || sourceid == WhiteKnight.MAGIC_CRASH); } - + private boolean isDispel() { return skill && (sourceid == Priest.DISPEL || sourceid == SuperGM.HEAL_PLUS_DISPEL); } @@ -1463,13 +1529,15 @@ public class MapleStatEffect { private boolean isCureAllAbnormalStatus() { if (skill) { return isHerosWill(sourceid); - } else if (sourceid == 2022544) return true; - + } else if (sourceid == 2022544) { + return true; + } + return false; } - + public static boolean isHerosWill(int skillid) { - switch(skillid) { + switch (skillid) { case Hero.HEROS_WILL: case Paladin.HEROS_WILL: case DarkKnight.HEROS_WILL: @@ -1504,7 +1572,7 @@ public class MapleStatEffect { private boolean isCygnusFA() { return skill && (sourceid == DawnWarrior.FINAL_ATTACK || sourceid == WindArcher.FINAL_ATTACK); } - + private boolean isHyperBody() { return skill && (sourceid == Spearman.HYPER_BODY || sourceid == GM.HYPER_BODY || sourceid == SuperGM.HYPER_BODY); } @@ -1561,17 +1629,16 @@ public class MapleStatEffect { return null; } - public boolean hasNoIcon() { return (sourceid == 3111002 || sourceid == 3211002 || + // puppet, puppet - sourceid == 3211005 || + // golden eagle + sourceid == 3211005 || + // golden eagle sourceid == 2121005 || sourceid == 2221005 || + // elquines, ifrit sourceid == 2321003 || sourceid == 3121006 || + // bahamut, phoenix sourceid == 3221005 || sourceid == 3111005 || + // frostprey, silver hawk sourceid == 2311006 || sourceid == 5220002 || + // summon dragon, wrath of the octopi sourceid == 5211001 || sourceid == 5211002); // octopus, gaviota } - + public boolean isSkill() { return skill; } @@ -1579,7 +1646,7 @@ public class MapleStatEffect { public int getSourceId() { return sourceid; } - + public int getBuffSourceId() { return skill ? sourceid : -sourceid; } @@ -1589,28 +1656,27 @@ public class MapleStatEffect { } /* - private static class CancelEffectAction implements Runnable { + private static class CancelEffectAction implements Runnable { - private MapleStatEffect effect; - private WeakReference target; - private long startTime; + private MapleStatEffect effect; + private WeakReference target; + private long startTime; - public CancelEffectAction(MapleCharacter target, MapleStatEffect effect, long startTime) { - this.effect = effect; - this.target = new WeakReference<>(target); - this.startTime = startTime; - } - - @Override - public void run() { - MapleCharacter realTarget = target.get(); - if (realTarget != null) { - realTarget.cancelEffect(effect, false, startTime); - } - } - } - */ + public CancelEffectAction(MapleCharacter target, MapleStatEffect effect, long startTime) { + this.effect = effect; + this.target = new WeakReference<>(target); + this.startTime = startTime; + } + @Override + public void run() { + MapleCharacter realTarget = target.get(); + if (realTarget != null) { + realTarget.cancelEffect(effect, false, startTime); + } + } + } + */ public short getHp() { return hp; } @@ -1618,7 +1684,7 @@ public class MapleStatEffect { public short getMp() { return mp; } - + public double getHpRate() { return hpR; } @@ -1626,7 +1692,7 @@ public class MapleStatEffect { public double getMpRate() { return mpR; } - + public byte getHpR() { return mhpR; } @@ -1634,7 +1700,7 @@ public class MapleStatEffect { public byte getMpR() { return mmpR; } - + public short getHpRRate() { return mhpRRate; } @@ -1654,7 +1720,7 @@ public class MapleStatEffect { public short getMatk() { return matk; } - + public short getWatk() { return watk; } @@ -1714,4 +1780,4 @@ public class MapleStatEffect { public Map getMonsterStati() { return monsterStatus; } -} \ No newline at end of file +} diff --git a/src/server/life/MapleMonster.java b/src/server/life/MapleMonster.java index b4e4f29a00..dc98c71dc2 100644 --- a/src/server/life/MapleMonster.java +++ b/src/server/life/MapleMonster.java @@ -75,6 +75,7 @@ import server.MapleStatEffect; import server.maps.MapleSummon; public class MapleMonster extends AbstractLoadedMapleLife { + private ChangeableStats ostats = null; //unused, v83 WZs offers no support for changeable stats. private MapleMonsterStats stats; private AtomicInteger hp = new AtomicInteger(1); @@ -216,7 +217,9 @@ public class MapleMonster extends AbstractLoadedMapleLife { } public synchronized void addHp(int hp) { - if(this.hp.get() <= 0) return; + if (this.hp.get() <= 0) { + return; + } this.hp.addAndGet(hp); } @@ -300,7 +303,9 @@ public class MapleMonster extends AbstractLoadedMapleLife { } private boolean applyAnimationIfRoaming(int attackPos, MobSkill skill) { // roam: not casting attack or skill animations - if(!animationLock.tryLock()) return false; + if (!animationLock.tryLock()) { + return false; + } try { long animationTime; @@ -328,7 +333,9 @@ public class MapleMonster extends AbstractLoadedMapleLife { } if(delta >= 0) { - if(stayAlive) curHp--; + if (stayAlive) { + curHp--; + } int trueDamage = Math.min(curHp, delta); hp.addAndGet(-trueDamage); @@ -428,7 +435,9 @@ public class MapleMonster extends AbstractLoadedMapleLife { return; } - if(ServerConstants.USE_DEBUG) from.dropMessage(5, "Hitted MOB " + this.getId() + ", OID " + this.getObjectId()); + if (ServerConstants.USE_DEBUG) { + from.dropMessage(5, "Hitted MOB " + this.getId() + ", OID " + this.getObjectId()); + } dispatchMonsterDamaged(from, trueDamage); if (!takenDamage.containsKey(from.getId())) { @@ -442,7 +451,9 @@ public class MapleMonster extends AbstractLoadedMapleLife { public void heal(int hp, int mp) { Integer hpHealed = applyAndGetHpDamage(-hp, false); - if(hpHealed == null) return; + if (hpHealed == null) { + return; + } int mp2Heal = getMp() + mp; int maxMp = getMaxMp(); @@ -451,7 +462,9 @@ public class MapleMonster extends AbstractLoadedMapleLife { } setMp(mp2Heal); - if(hp > 0) getMap().broadcastMessage(MaplePacketCreator.healMonster(getObjectId(), hp, getHp(), getMaxHp())); + if (hp > 0) { + getMap().broadcastMessage(MaplePacketCreator.healMonster(getObjectId(), hp, getHp(), getMaxHp())); + } maxHpPlusHeal.addAndGet(hpHealed); dispatchMonsterHealed(hpHealed); @@ -465,7 +478,7 @@ public class MapleMonster extends AbstractLoadedMapleLife { MapleCharacter pchar = getMap().getAnyCharacterFromParty(pid); // thanks G h o s t, Alfred, Vcoc, BHB for poiting out a bug in detecting party members after membership transactions in a party took place List members; - if(pchar != null) { + if (pchar != null) { members = pchar.getPartyMembersOnSameMap(); } else { members = new LinkedList<>(); @@ -902,7 +915,9 @@ public class MapleMonster extends AbstractLoadedMapleLife { } private void setControllerHasAggro(boolean controllerHasAggro) { - if (!fake) this.controllerHasAggro = controllerHasAggro; + if (!fake) { + this.controllerHasAggro = controllerHasAggro; + } } public boolean isControllerKnowsAboutAggro() { @@ -910,7 +925,9 @@ public class MapleMonster extends AbstractLoadedMapleLife { } private void setControllerKnowsAboutAggro(boolean controllerKnowsAboutAggro) { - if (!fake) this.controllerKnowsAboutAggro = controllerKnowsAboutAggro; + if (!fake) { + this.controllerKnowsAboutAggro = controllerKnowsAboutAggro; + } } private void setControllerHasPuppet(boolean controllerHasPuppet) { @@ -1181,7 +1198,20 @@ public class MapleMonster extends AbstractLoadedMapleLife { ch.registerMobStatus(mapid, status, cancelTask, duration + animationTime - 100, overtimeAction, overtimeDelay); return true; } - + + public final void dispelSkill(final MobSkill skillId) { + List toCancel = new ArrayList(); + for (Entry effects : stati.entrySet()) { + MonsterStatusEffect mse = effects.getValue(); + if (mse.getMobSkill() != null && mse.getMobSkill().getSkillId() == skillId.getSkillId()) { //not checking for level. + toCancel.add(effects.getKey()); + } + } + for (MonsterStatus stat : toCancel) { + debuffMobStat(stat); + } + } + public void applyMonsterBuff(final Map stats, final int x, int skillId, long duration, MobSkill skill, final List reflection) { final Runnable cancelTask = new Runnable() { @@ -1265,12 +1295,20 @@ public class MapleMonster extends AbstractLoadedMapleLife { if(ServerConstants.USE_ANTI_IMMUNITY_CRASH) { if (skillid == Crusader.ARMOR_CRASH) { - if(!isBuffed(MonsterStatus.WEAPON_REFLECT)) debuffMobStat(MonsterStatus.WEAPON_IMMUNITY); - if(!isBuffed(MonsterStatus.MAGIC_REFLECT)) debuffMobStat(MonsterStatus.MAGIC_IMMUNITY); + if(!isBuffed(MonsterStatus.WEAPON_REFLECT)) { + debuffMobStat(MonsterStatus.WEAPON_IMMUNITY); + } + if(!isBuffed(MonsterStatus.MAGIC_REFLECT)) { + debuffMobStat(MonsterStatus.MAGIC_IMMUNITY); + } } else if (skillid == WhiteKnight.MAGIC_CRASH) { - if(!isBuffed(MonsterStatus.MAGIC_REFLECT)) debuffMobStat(MonsterStatus.MAGIC_IMMUNITY); + if(!isBuffed(MonsterStatus.MAGIC_REFLECT)) { + debuffMobStat(MonsterStatus.MAGIC_IMMUNITY); + } } else { - if(!isBuffed(MonsterStatus.WEAPON_REFLECT)) debuffMobStat(MonsterStatus.WEAPON_IMMUNITY); + if(!isBuffed(MonsterStatus.WEAPON_REFLECT)) { + debuffMobStat(MonsterStatus.WEAPON_IMMUNITY); + } } } } @@ -1669,11 +1707,16 @@ public class MapleMonster extends AbstractLoadedMapleLife { private float getDifficultyRate(final int difficulty) { switch(difficulty) { - case 6: return(7.7f); - case 5: return(5.6f); - case 4: return(3.2f); - case 3: return(2.1f); - case 2: return(1.4f); + case 6: + return(7.7f); + case 5: + return(5.6f); + case 4: + return(3.2f); + case 3: + return(2.1f); + case 2: + return(1.4f); } return(1.0f); @@ -1862,8 +1905,8 @@ public class MapleMonster extends AbstractLoadedMapleLife { } /** - * Finds a new controller for the given monster from the chars with deployed puppet - * nearby on the map it is from... + * Finds a new controller for the given monster from the chars with deployed + * puppet nearby on the map it is from... * */ private void aggroUpdatePuppetController(MapleCharacter newController) { @@ -1960,8 +2003,8 @@ public class MapleMonster extends AbstractLoadedMapleLife { } /** - * Applied damage input for this mob, enough damage taken implies - * an aggro target update for the attacker shortly. + * Applied damage input for this mob, enough damage taken implies an aggro + * target update for the attacker shortly. * */ public void aggroMonsterDamage(MapleCharacter attacker, int damage) { @@ -2014,7 +2057,9 @@ public class MapleMonster extends AbstractLoadedMapleLife { } public void aggroUpdatePuppetVisibility() { - if (!availablePuppetUpdate) return; + if (!availablePuppetUpdate) { + return; + } availablePuppetUpdate = false; Runnable r = new Runnable() { @@ -2022,7 +2067,9 @@ public class MapleMonster extends AbstractLoadedMapleLife { public void run() { try { MapleCharacter chrController = MapleMonster.this.getActiveController(); - if (chrController == null) return; + if (chrController == null) { + return; + } MapleStatEffect puppetEffect = chrController.getBuffEffect(MapleBuffStat.PUPPET); if (puppetEffect != null) { @@ -2052,7 +2099,8 @@ public class MapleMonster extends AbstractLoadedMapleLife { } /** - * Clears all applied damage input for this mob, doesn't refresh target aggro. + * Clears all applied damage input for this mob, doesn't refresh target + * aggro. * */ public void aggroClearDamages() { @@ -2073,6 +2121,10 @@ public class MapleMonster extends AbstractLoadedMapleLife { } } + public final int getRemoveAfter() { + return stats.removeAfter(); + } + public void dispose() { this.getMap().dismissRemoveAfter(this); disposeLocks(); @@ -2093,4 +2145,4 @@ public class MapleMonster extends AbstractLoadedMapleLife { statiLock = statiLock.dispose(); animationLock = animationLock.dispose(); } -} +} \ No newline at end of file diff --git a/src/server/life/MapleMonsterInformationProvider.java b/src/server/life/MapleMonsterInformationProvider.java index 901526b33e..4854d125be 100644 --- a/src/server/life/MapleMonsterInformationProvider.java +++ b/src/server/life/MapleMonsterInformationProvider.java @@ -44,306 +44,308 @@ import tools.Pair; import tools.Randomizer; public class MapleMonsterInformationProvider { - // Author : LightPepsi + // Author : LightPepsi - private static final MapleMonsterInformationProvider instance = new MapleMonsterInformationProvider(); - - public static MapleMonsterInformationProvider getInstance() { - return instance; - } - - private final Map> drops = new HashMap<>(); - private final List globaldrops = new ArrayList<>(); - private final Map> continentdrops = new HashMap<>(); - - private final Map> dropsChancePool = new HashMap<>(); // thanks to ronan - private final Set hasNoMultiEquipDrops = new HashSet<>(); - private final Map> extraMultiEquipDrops = new HashMap<>(); - - private final Map, Integer> mobAttackAnimationTime = new HashMap<>(); - private final Map mobSkillAnimationTime = new HashMap<>(); - - private final Map> mobAttackInfo = new HashMap<>(); - - private final Map mobBossCache = new HashMap<>(); - private final Map mobNameCache = new HashMap<>(); + private static final MapleMonsterInformationProvider instance = new MapleMonsterInformationProvider(); - protected MapleMonsterInformationProvider() { - retrieveGlobal(); - } - - public final List getRelevantGlobalDrops(int mapid) { - int continentid = mapid / 100000000; - - List contiItems = continentdrops.get(continentid); - if (contiItems == null) { // continent separated global drops found thanks to marcuswoon - contiItems = new ArrayList<>(); - - for (MonsterGlobalDropEntry e : globaldrops) { - if (e.continentid < 0 || e.continentid == continentid) { - contiItems.add(e); - } + public static MapleMonsterInformationProvider getInstance() { + return instance; + } + + private final Map> drops = new HashMap<>(); + private final List globaldrops = new ArrayList<>(); + private final Map> continentdrops = new HashMap<>(); + + private final Map> dropsChancePool = new HashMap<>(); // thanks to ronan + private final Set hasNoMultiEquipDrops = new HashSet<>(); + private final Map> extraMultiEquipDrops = new HashMap<>(); + + private final Map, Integer> mobAttackAnimationTime = new HashMap<>(); + private final Map mobSkillAnimationTime = new HashMap<>(); + + private final Map> mobAttackInfo = new HashMap<>(); + + private final Map mobBossCache = new HashMap<>(); + private final Map mobNameCache = new HashMap<>(); + + protected MapleMonsterInformationProvider() { + retrieveGlobal(); + } + + public final List getRelevantGlobalDrops(int mapid) { + int continentid = mapid / 100000000; + + List contiItems = continentdrops.get(continentid); + if (contiItems == null) { // continent separated global drops found thanks to marcuswoon + contiItems = new ArrayList<>(); + + for (MonsterGlobalDropEntry e : globaldrops) { + if (e.continentid < 0 || e.continentid == continentid) { + contiItems.add(e); + } + } + + continentdrops.put(continentid, contiItems); + } + + return contiItems; + } + + private void retrieveGlobal() { + PreparedStatement ps = null; + ResultSet rs = null; + Connection con = null; + + try { + con = DatabaseConnection.getConnection(); + ps = con.prepareStatement("SELECT * FROM drop_data_global WHERE chance > 0"); + rs = ps.executeQuery(); + + while (rs.next()) { + globaldrops.add( + new MonsterGlobalDropEntry( + rs.getInt("itemid"), + rs.getInt("chance"), + rs.getByte("continent"), + rs.getInt("minimum_quantity"), + rs.getInt("maximum_quantity"), + rs.getShort("questid"))); + } + + rs.close(); + ps.close(); + con.close(); + } catch (SQLException e) { + System.err.println("Error retrieving drop" + e); + } finally { + try { + if (ps != null && !ps.isClosed()) { + ps.close(); + } + if (rs != null && !rs.isClosed()) { + rs.close(); + } + if (con != null && !con.isClosed()) { + con.close(); + } + } catch (SQLException ignore) { + ignore.printStackTrace(); + } + } + } + + public List retrieveEffectiveDrop(final int monsterId) { + // this reads the drop entries searching for multi-equip, properly processing them + + List list = retrieveDrop(monsterId); + if (hasNoMultiEquipDrops.contains(monsterId) || !ServerConstants.USE_MULTIPLE_SAME_EQUIP_DROP) { + return list; + } + + List multiDrops = extraMultiEquipDrops.get(monsterId), extra = new LinkedList<>(); + if (multiDrops == null) { + multiDrops = new LinkedList<>(); + + for (MonsterDropEntry mde : list) { + if (ItemConstants.isEquipment(mde.itemId) && mde.Maximum > 1) { + multiDrops.add(mde); + + int rnd = Randomizer.rand(mde.Minimum, mde.Maximum); + for (int i = 0; i < rnd - 1; i++) { + extra.add(mde); // this passes copies of the equips' MDE with min/max quantity > 1, but idc it'll be unused anyways } - - continentdrops.put(continentid, contiItems); } - - return contiItems; - } + } - private void retrieveGlobal() { - PreparedStatement ps = null; - ResultSet rs = null; - Connection con = null; - - try { - con = DatabaseConnection.getConnection(); - ps = con.prepareStatement("SELECT * FROM drop_data_global WHERE chance > 0"); - rs = ps.executeQuery(); - - while (rs.next()) { - globaldrops.add( - new MonsterGlobalDropEntry( - rs.getInt("itemid"), - rs.getInt("chance"), - rs.getByte("continent"), - rs.getInt("minimum_quantity"), - rs.getInt("maximum_quantity"), - rs.getShort("questid"))); - } - - rs.close(); - ps.close(); - con.close(); - } catch (SQLException e) { - System.err.println("Error retrieving drop" + e); - } finally { - try { - if (ps != null && !ps.isClosed()) { - ps.close(); - } - if (rs != null && !rs.isClosed()) { - rs.close(); - } - if (con != null && !con.isClosed()) { - con.close(); - } - } catch (SQLException ignore) { - ignore.printStackTrace(); - } - } - } - - public List retrieveEffectiveDrop(final int monsterId) { - // this reads the drop entries searching for multi-equip, properly processing them - - List list = retrieveDrop(monsterId); - if (hasNoMultiEquipDrops.contains(monsterId) || !ServerConstants.USE_MULTIPLE_SAME_EQUIP_DROP) { - return list; - } - - List multiDrops = extraMultiEquipDrops.get(monsterId), extra = new LinkedList<>(); - if(multiDrops == null) { - multiDrops = new LinkedList<>(); - - for(MonsterDropEntry mde : list) { - if(ItemConstants.isEquipment(mde.itemId) && mde.Maximum > 1) { - multiDrops.add(mde); - - int rnd = Randomizer.rand(mde.Minimum, mde.Maximum); - for(int i = 0; i < rnd - 1; i++) { - extra.add(mde); // this passes copies of the equips' MDE with min/max quantity > 1, but idc it'll be unused anyways - } - } - } - - if(!multiDrops.isEmpty()) extraMultiEquipDrops.put(monsterId, multiDrops); - else hasNoMultiEquipDrops.add(monsterId); - } else { - for(MonsterDropEntry mde : multiDrops) { - int rnd = Randomizer.rand(mde.Minimum, mde.Maximum); - for(int i = 0; i < rnd - 1; i++) { - extra.add(mde); - } - } + if (!multiDrops.isEmpty()) { + extraMultiEquipDrops.put(monsterId, multiDrops); + } else { + hasNoMultiEquipDrops.add(monsterId); + } + } else { + for (MonsterDropEntry mde : multiDrops) { + int rnd = Randomizer.rand(mde.Minimum, mde.Maximum); + for (int i = 0; i < rnd - 1; i++) { + extra.add(mde); } - - List ret = new LinkedList<>(list); - ret.addAll(extra); - + } + } + + List ret = new LinkedList<>(list); + ret.addAll(extra); + + return ret; + } + + public final List retrieveDrop(final int monsterId) { + if (drops.containsKey(monsterId)) { + return drops.get(monsterId); + } + final List ret = new LinkedList<>(); + + if (monsterId >= 9300127 && monsterId <= 9300136 || monsterId >= 9300315 && monsterId <= 9300324) { + int dropArray[] = {2022157, 2022158, 2022159, 2022160, 2022161, 2022162, 2022163, 2022164, 2022165, 2022166, 2022167, 2022168, 2022169, 2022170, 2022171, 2022172, 2022173, 2022174, 2022175, 2022176, 2022177, 2022178, 4001129}; //These are the drops, -1 means meso :D + for (int id : dropArray) { + ret.add(new MonsterDropEntry(id, 2000, 1, 1, (short) 0)); + } + } else { + PreparedStatement ps = null; + ResultSet rs = null; + Connection con = null; + try { + con = DatabaseConnection.getConnection(); + ps = con.prepareStatement("SELECT itemid, chance, minimum_quantity, maximum_quantity, questid FROM drop_data WHERE dropperid = ?"); + ps.setInt(1, monsterId); + rs = ps.executeQuery(); + + while (rs.next()) { + ret.add(new MonsterDropEntry(rs.getInt("itemid"), rs.getInt("chance"), rs.getInt("minimum_quantity"), rs.getInt("maximum_quantity"), rs.getShort("questid"))); + } + + con.close(); + } catch (SQLException e) { + e.printStackTrace(); return ret; - } - - public final List retrieveDrop(final int monsterId) { - if (drops.containsKey(monsterId)) { - return drops.get(monsterId); - } - final List ret = new LinkedList<>(); - - PreparedStatement ps = null; - ResultSet rs = null; - Connection con = null; - try { - con = DatabaseConnection.getConnection(); - ps = con.prepareStatement("SELECT itemid, chance, minimum_quantity, maximum_quantity, questid FROM drop_data WHERE dropperid = ?"); - ps.setInt(1, monsterId); - rs = ps.executeQuery(); - - while (rs.next()) { - ret.add( - new MonsterDropEntry( - rs.getInt("itemid"), - rs.getInt("chance"), - rs.getInt("minimum_quantity"), - rs.getInt("maximum_quantity"), - rs.getShort("questid"))); - } - + } finally { + try { + if (ps != null && !ps.isClosed()) { + ps.close(); + } + if (rs != null && !rs.isClosed()) { + rs.close(); + } + if (con != null && !con.isClosed()) { con.close(); - } catch (SQLException e) { - e.printStackTrace(); - return ret; - } finally { - try { - if (ps != null && !ps.isClosed()) { - ps.close(); - } - if (rs != null && !rs.isClosed()) { - rs.close(); - } - if (con != null && !con.isClosed()) { - con.close(); - } - } catch (SQLException ignore) { - ignore.printStackTrace(); - return ret; - } - } - drops.put(monsterId, ret); - return ret; - } - - public final List retrieveDropPool(final int monsterId) { // ignores Quest and Party Quest items - if (dropsChancePool.containsKey(monsterId)) { - return dropsChancePool.get(monsterId); - } - - MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); - - List dropList = retrieveDrop(monsterId); - List ret = new ArrayList<>(); - - int accProp = 0; - for(MonsterDropEntry mde : dropList) { - if(!ii.isQuestItem(mde.itemId) && !ii.isPartyQuestItem(mde.itemId)) { - accProp += mde.chance; - } - - ret.add(accProp); + } + } catch (SQLException ignore) { + ignore.printStackTrace(); + return ret; } - - if(accProp == 0) ret.clear(); // don't accept mobs dropping no relevant items - - dropsChancePool.put(monsterId, ret); - return ret; - } - - public final void setMobAttackAnimationTime(int monsterId, int attackPos, int animationTime) { - mobAttackAnimationTime.put(new Pair<>(monsterId, attackPos), animationTime); + } } - - public final Integer getMobAttackAnimationTime(int monsterId, int attackPos) { - Integer time = mobAttackAnimationTime.get(new Pair<>(monsterId, attackPos)); - return time == null ? 0 : time; - } - - public final void setMobSkillAnimationTime(MobSkill skill, int animationTime) { - mobSkillAnimationTime.put(skill, animationTime); - } - - public final Integer getMobSkillAnimationTime(MobSkill skill) { - Integer time = mobSkillAnimationTime.get(skill); - return time == null ? 0 : time; - } - - public final void setMobAttackInfo(int monsterId, int attackPos, int mpCon, int coolTime) { - mobAttackInfo.put((monsterId << 3) + attackPos, new Pair<>(mpCon, coolTime)); - } - - public final Pair getMobAttackInfo(int monsterId, int attackPos) { - if (attackPos < 0 || attackPos > 7) return null; - return mobAttackInfo.get((monsterId << 3) + attackPos); + drops.put(monsterId, ret); + return ret; + } + + public final List retrieveDropPool(final int monsterId) { // ignores Quest and Party Quest items + if (dropsChancePool.containsKey(monsterId)) { + return dropsChancePool.get(monsterId); } - public static ArrayList> getMobsIDsFromName(String search) { - MapleDataProvider dataProvider = MapleDataProviderFactory.getDataProvider(new File("wz/String.wz")); - ArrayList> retMobs = new ArrayList>(); - MapleData data = dataProvider.getData("Mob.img"); - List> mobPairList = new LinkedList>(); - for (MapleData mobIdData : data.getChildren()) { - int mobIdFromData = Integer.parseInt(mobIdData.getName()); - String mobNameFromData = MapleDataTool.getString(mobIdData.getChildByPath("name"), "NO-NAME"); - mobPairList.add(new Pair(mobIdFromData, mobNameFromData)); - } - for (Pair mobPair : mobPairList) { - if (mobPair.getRight().toLowerCase().contains(search.toLowerCase())) { - retMobs.add(mobPair); - } - } - return retMobs; - } + MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); - public boolean isBoss(int id) { - Boolean boss = mobBossCache.get(id); - if (boss == null) { - try { - boss = MapleLifeFactory.getMonster(id).isBoss(); - } catch (NullPointerException npe) { - boss = false; - } catch (Exception e) { //nonexistant mob - boss = false; - - e.printStackTrace(); - System.err.println("Nonexistant mob id " + id); - } - - mobBossCache.put(id, boss); - } - - return boss; - } - - public String getMobNameFromId(int id) { - String mobName = mobNameCache.get(id); - if (mobName == null) { - try - { - mobName = MapleLifeFactory.getMonster(id).getName(); - } - catch (NullPointerException npe) - { - mobName = ""; //nonexistant mob - } - catch (Exception e) - { - e.printStackTrace(); - System.err.println("Nonexistant mob id " + id); - mobName = ""; //nonexistant mob - } - - mobNameCache.put(id, mobName); - } - - return mobName; - } + List dropList = retrieveDrop(monsterId); + List ret = new ArrayList<>(); - public final void clearDrops() { - drops.clear(); - hasNoMultiEquipDrops.clear(); - extraMultiEquipDrops.clear(); - dropsChancePool.clear(); - globaldrops.clear(); - continentdrops.clear(); - retrieveGlobal(); - } -} \ No newline at end of file + int accProp = 0; + for (MonsterDropEntry mde : dropList) { + if (!ii.isQuestItem(mde.itemId) && !ii.isPartyQuestItem(mde.itemId)) { + accProp += mde.chance; + } + + ret.add(accProp); + } + + if (accProp == 0) { + ret.clear(); // don't accept mobs dropping no relevant items + } + dropsChancePool.put(monsterId, ret); + return ret; + } + + public final void setMobAttackAnimationTime(int monsterId, int attackPos, int animationTime) { + mobAttackAnimationTime.put(new Pair<>(monsterId, attackPos), animationTime); + } + + public final Integer getMobAttackAnimationTime(int monsterId, int attackPos) { + Integer time = mobAttackAnimationTime.get(new Pair<>(monsterId, attackPos)); + return time == null ? 0 : time; + } + + public final void setMobSkillAnimationTime(MobSkill skill, int animationTime) { + mobSkillAnimationTime.put(skill, animationTime); + } + + public final Integer getMobSkillAnimationTime(MobSkill skill) { + Integer time = mobSkillAnimationTime.get(skill); + return time == null ? 0 : time; + } + + public final void setMobAttackInfo(int monsterId, int attackPos, int mpCon, int coolTime) { + mobAttackInfo.put((monsterId << 3) + attackPos, new Pair<>(mpCon, coolTime)); + } + + public final Pair getMobAttackInfo(int monsterId, int attackPos) { + if (attackPos < 0 || attackPos > 7) { + return null; + } + return mobAttackInfo.get((monsterId << 3) + attackPos); + } + + public static ArrayList> getMobsIDsFromName(String search) { + MapleDataProvider dataProvider = MapleDataProviderFactory.getDataProvider(new File("wz/String.wz")); + ArrayList> retMobs = new ArrayList>(); + MapleData data = dataProvider.getData("Mob.img"); + List> mobPairList = new LinkedList>(); + for (MapleData mobIdData : data.getChildren()) { + int mobIdFromData = Integer.parseInt(mobIdData.getName()); + String mobNameFromData = MapleDataTool.getString(mobIdData.getChildByPath("name"), "NO-NAME"); + mobPairList.add(new Pair(mobIdFromData, mobNameFromData)); + } + for (Pair mobPair : mobPairList) { + if (mobPair.getRight().toLowerCase().contains(search.toLowerCase())) { + retMobs.add(mobPair); + } + } + return retMobs; + } + + public boolean isBoss(int id) { + Boolean boss = mobBossCache.get(id); + if (boss == null) { + try { + boss = MapleLifeFactory.getMonster(id).isBoss(); + } catch (NullPointerException npe) { + boss = false; + } catch (Exception e) { //nonexistant mob + boss = false; + + e.printStackTrace(); + System.err.println("Nonexistant mob id " + id); + } + + mobBossCache.put(id, boss); + } + + return boss; + } + + public String getMobNameFromId(int id) { + String mobName = mobNameCache.get(id); + if (mobName == null) { + try { + mobName = MapleLifeFactory.getMonster(id).getName(); + } catch (NullPointerException npe) { + mobName = ""; //nonexistant mob + } catch (Exception e) { + e.printStackTrace(); + System.err.println("Nonexistant mob id " + id); + mobName = ""; //nonexistant mob + } + + mobNameCache.put(id, mobName); + } + + return mobName; + } + + public final void clearDrops() { + drops.clear(); + hasNoMultiEquipDrops.clear(); + extraMultiEquipDrops.clear(); + dropsChancePool.clear(); + globaldrops.clear(); + continentdrops.clear(); + retrieveGlobal(); + } +} diff --git a/src/server/life/MobSkill.java b/src/server/life/MobSkill.java index c58775a0db..03606d2e5e 100644 --- a/src/server/life/MobSkill.java +++ b/src/server/life/MobSkill.java @@ -1,24 +1,24 @@ /* - This file is part of the OdinMS Maple Story Server - Copyright (C) 2008 Patrick Huy - Matthias Butz - Jan Christian Meyer + 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 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. + 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 . -*/ + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ package server.life; import java.awt.Point; @@ -44,6 +44,7 @@ import tools.ArrayMap; * @author Danny (Leifde) */ public class MobSkill { + private int skillId, skillLevel, mpCon; private List toSummon = new ArrayList(); private int spawnEffect, hp, x, y; @@ -106,17 +107,17 @@ public class MobSkill { public void applyDelayedEffect(final MapleCharacter player, final MapleMonster monster, final boolean skill, int animationTime) { Runnable toRun = new Runnable() { - @Override - public void run() { - if(monster.isAlive()) { - applyEffect(player, monster, skill, null); - } - } - }; - + @Override + public void run() { + if (monster.isAlive()) { + applyEffect(player, monster, skill, null); + } + } + }; + monster.getMap().getChannelServer().registerOverallAction(monster.getMap().getId(), toRun, animationTime); } - + public void applyEffect(MapleCharacter player, MapleMonster monster, boolean skill, List banishPlayers) { MapleDisease disease = null; Map stats = new ArrayMap(); @@ -142,50 +143,50 @@ public class MobSkill { case 153: stats.put(MonsterStatus.MAGIC_DEFENSE_UP, Integer.valueOf(x)); break; - case 114: - if (lt != null && rb != null && skill) { - List objects = getObjectsInRange(monster, MapleMapObjectType.MONSTER); - final int hps = (getX() / 1000) * (int) (950 + 1050 * Math.random()); - for (MapleMapObject mons : objects) { - ((MapleMonster) mons).heal(hps, getY()); - } - } else { - monster.heal(getX(), getY()); - } - break; - case 120: + case 114: + if (lt != null && rb != null && skill) { + List objects = getObjectsInRange(monster, MapleMapObjectType.MONSTER); + final int hps = (getX() / 1000) * (int) (950 + 1050 * Math.random()); + for (MapleMapObject mons : objects) { + ((MapleMonster) mons).heal(hps, getY()); + } + } else { + monster.heal(getX(), getY()); + } + break; + case 120: disease = MapleDisease.SEAL; - break; - case 121: - disease = MapleDisease.DARKNESS; - break; - case 122: - disease = MapleDisease.WEAKEN; - break; - case 123: - disease = MapleDisease.STUN; - break; - case 124: - disease = MapleDisease.CURSE; - break; - case 125: - disease = MapleDisease.POISON; - break; - case 126: // Slow - disease = MapleDisease.SLOW; - break; - case 127: - if (lt != null && rb != null && skill) { - for (MapleCharacter character : getPlayersInRange(monster, player)) { - character.dispel(); - } - } else { - player.dispel(); - } - break; - case 128: // Seduce - disease = MapleDisease.SEDUCE; - break; + break; + case 121: + disease = MapleDisease.DARKNESS; + break; + case 122: + disease = MapleDisease.WEAKEN; + break; + case 123: + disease = MapleDisease.STUN; + break; + case 124: + disease = MapleDisease.CURSE; + break; + case 125: + disease = MapleDisease.POISON; + break; + case 126: // Slow + disease = MapleDisease.SLOW; + break; + case 127: + if (lt != null && rb != null && skill) { + for (MapleCharacter character : getPlayersInRange(monster, player)) { + character.dispel(); + } + } else { + player.dispel(); + } + break; + case 128: // Seduce + disease = MapleDisease.SEDUCE; + break; case 129: // Banish if (lt != null && rb != null && skill) { for (MapleCharacter chr : getPlayersInRange(monster, player)) { @@ -214,35 +215,40 @@ public class MobSkill { stats.put(MonsterStatus.MAGIC_IMMUNITY, Integer.valueOf(x)); } break; - case 143: // Weapon Reflect - stats.put(MonsterStatus.WEAPON_REFLECT, 10); - stats.put(MonsterStatus.WEAPON_IMMUNITY, 10); - reflection.add(x); - break; - case 144: // Magic Reflect - stats.put(MonsterStatus.MAGIC_REFLECT, 10); - stats.put(MonsterStatus.MAGIC_IMMUNITY, 10); - reflection.add(x); - break; - case 145: // Weapon / Magic reflect - stats.put(MonsterStatus.WEAPON_REFLECT, 10); - stats.put(MonsterStatus.WEAPON_IMMUNITY, 10); - stats.put(MonsterStatus.MAGIC_REFLECT, 10); - stats.put(MonsterStatus.MAGIC_IMMUNITY, 10); - reflection.add(x); + case 143: // Weapon Reflect + stats.put(MonsterStatus.WEAPON_REFLECT, 10); + stats.put(MonsterStatus.WEAPON_IMMUNITY, 10); + reflection.add(x); break; - case 154: // accuracy up - case 155: // avoid up - case 156: // speed up + case 144: // Magic Reflect + stats.put(MonsterStatus.MAGIC_REFLECT, 10); + stats.put(MonsterStatus.MAGIC_IMMUNITY, 10); + reflection.add(x); + break; + case 145: // Weapon / Magic reflect + stats.put(MonsterStatus.WEAPON_REFLECT, 10); + stats.put(MonsterStatus.WEAPON_IMMUNITY, 10); + stats.put(MonsterStatus.MAGIC_REFLECT, 10); + stats.put(MonsterStatus.MAGIC_IMMUNITY, 10); + reflection.add(x); + break; + case 154: + stats.put(MonsterStatus.ACC, Integer.valueOf(x)); + break; + case 155: + stats.put(MonsterStatus.AVOID, Integer.valueOf(x)); + break; + case 156: + stats.put(MonsterStatus.SPEED, Integer.valueOf(x)); break; case 200: // summon int skillLimit = this.getLimit(); MapleMap map = monster.getMap(); - + if (map.isDojoMap()) { // spawns in dojo should be unlimited skillLimit = Integer.MAX_VALUE; } - + if (map.getSpawnedMonstersOnMap() < 80) { List summons = getSummons(); int summonLimit = monster.countAvailableMobSummons(summons.size(), skillLimit); @@ -252,9 +258,10 @@ public class MobSkill { for (Integer mobId : summons.subList(0, summonLimit)) { MapleMonster toSpawn = MapleLifeFactory.getMonster(mobId); - if(toSpawn != null) { - if(bossRushMap) toSpawn.disableDrops(); // no littering on BRPQ pls - + if (toSpawn != null) { + if (bossRushMap) { + toSpawn.disableDrops(); // no littering on BRPQ pls + } toSpawn.setPosition(monster.getPosition()); int ypos, xpos; xpos = (int) monster.getPosition().getX(); @@ -277,7 +284,7 @@ public class MobSkill { } else { xpos = (int) (monster.getPosition().getX() + Randomizer.nextInt(1000) - 500); } - break; + break; } switch (map.getId()) { case 220080001: //Pap map @@ -297,9 +304,9 @@ public class MobSkill { } toSpawn.setPosition(new Point(xpos, ypos)); if (toSpawn.getId() == 8500004) { - map.spawnFakeMonster(toSpawn); + map.spawnFakeMonster(toSpawn); } else { - map.spawnMonsterWithEffect(toSpawn, getSpawnEffect(), toSpawn.getPosition()); + map.spawnMonsterWithEffect(toSpawn, getSpawnEffect(), toSpawn.getPosition()); } monster.addSummonedMob(toSpawn); } diff --git a/src/server/maps/MapleMap.java b/src/server/maps/MapleMap.java index 2f2e7026b1..c912ce82f9 100644 --- a/src/server/maps/MapleMap.java +++ b/src/server/maps/MapleMap.java @@ -84,18 +84,21 @@ import server.life.MapleNPC; import server.life.MonsterDropEntry; import server.life.MonsterGlobalDropEntry; import server.life.SpawnPoint; -import server.partyquest.MonsterCarnival; -import server.partyquest.MonsterCarnivalParty; -//import server.partyquest.Pyramid; import scripting.event.EventInstanceManager; import server.life.MaplePlayerNPC; +import server.life.MobSkill; +import server.life.MobSkillFactory; import server.life.MonsterListener; +import server.partyquest.GuardianSpawnPoint; +import server.partyquest.MapleCarnivalFactory; +import server.partyquest.MapleCarnivalFactory.MCSkill; import tools.FilePrinter; import tools.MaplePacketCreator; import tools.Pair; import tools.Randomizer; public class MapleMap { + private static final List rangedMapobjectTypes = Arrays.asList(MapleMapObjectType.SHOP, MapleMapObjectType.ITEM, MapleMapObjectType.NPC, MapleMapObjectType.MONSTER, MapleMapObjectType.DOOR, MapleMapObjectType.SUMMON, MapleMapObjectType.REACTOR); private static final Map> dropBoundsCache = new HashMap<>(100); @@ -275,7 +278,9 @@ public class MapleMap { } public MapleMap getReturnMap() { - if(returnMapId == 999999999) return this; + if (returnMapId == 999999999) { + return this; + } return getChannelServer().getMapFactory().getMap(returnMapId); } @@ -538,8 +543,11 @@ public class MapleMap { } public Point calcDropPos(Point initial, Point fallback) { - if(initial.x < xLimits.left) initial.x = xLimits.left; - else if(initial.x > xLimits.right) initial.x = xLimits.right; + if (initial.x < xLimits.left) { + initial.x = xLimits.left; + } else if(initial.x > xLimits.right) { + initial.x = xLimits.right; + } Point ret = calcPointBelow(new Point(initial.x, initial.y - 85)); if (ret == null) { @@ -559,8 +567,8 @@ public class MapleMap { } /** - * Fetches angle relative between spawn and door points - * where 3 O'Clock is 0 and 12 O'Clock is 270 degrees + * Fetches angle relative between spawn and door points where 3 O'Clock is 0 + * and 12 O'Clock is 270 degrees * * @param spawnPoint * @param doorPoint @@ -574,10 +582,11 @@ public class MapleMap { double inRads = Math.atan2(dy, dx); // We need to map to coord system when 0 degree is at 3 O'clock, 270 at 12 O'clock - if (inRads < 0) + if (inRads < 0) { inRads = Math.abs(inRads); - else + } else { inRads = 2 * Math.PI - inRads; + } return Math.toDegrees(inRads); } @@ -650,7 +659,9 @@ public class MapleMap { mesos = (int) (mesos * chr.getBuffedValue(MapleBuffStat.MESOUP).doubleValue() / 100.0); } mesos = mesos * chr.getMesoRate(); - if(mesos <= 0) mesos = Integer.MAX_VALUE; + if (mesos <= 0) { + mesos = Integer.MAX_VALUE; + } spawnMesoDrop(mesos, calcDropPos(pos, mob.getPosition()), mob, chr, false, droptype); } @@ -713,7 +724,9 @@ public class MapleMap { chRate *= (stati.getStati().get(MonsterStatus.SHOWDOWN).doubleValue() / 100.0 + 1.0); } - if(useBaseRate) chRate = 1; + if (useBaseRate) { + chRate = 1; + } final MapleMonsterInformationProvider mi = MapleMonsterInformationProvider.getInstance(); final List globalEntry = mi.getRelevantGlobalDrops(this.getId()); @@ -773,7 +786,9 @@ public class MapleMap { private void startItemMonitor() { chrWLock.lock(); try { - if(itemMonitor != null) return; + if (itemMonitor != null) { + return; + } itemMonitor = TimerManager.getInstance().register(new Runnable() { @Override @@ -806,7 +821,9 @@ public class MapleMap { objectRLock.unlock(); } - if(tryClean) cleanItemMonitor(); + if (tryClean) { + cleanItemMonitor(); + } } }, ServerConstants.ITEM_MONITOR_TIME, ServerConstants.ITEM_MONITOR_TIME); @@ -861,7 +878,9 @@ public class MapleMap { try { mapobj = registeredDrops.remove(0).get(); while(mapobj == null) { - if(registeredDrops.isEmpty()) break; + if (registeredDrops.isEmpty()) { + break; + } mapobj = registeredDrops.remove(0).get(); } } finally { @@ -1004,7 +1023,9 @@ public class MapleMap { if(mdrop.getOwnerId() == charid) { mdrop.lockItem(); try { - if(mdrop.isPickedUp()) return; + if (mdrop.isPickedUp()) { + return; + } mdrop.setPartyOwnerId(partyid); @@ -1197,7 +1218,9 @@ public class MapleMap { int count = 0; for(MapleCharacter mc: getAllPlayers()) { - if(mc.isAlive()) count++; + if (mc.isAlive()) { + count++; + } } return count; @@ -1233,7 +1256,9 @@ public class MapleMap { public List getMonsters() { List mobs = new ArrayList<>(); for (MapleMapObject object : this.getMapObjects()) { - if(object instanceof MapleMonster) mobs.add((MapleMonster)object); + if (object instanceof MapleMonster) { + mobs.add((MapleMonster)object); + } } return mobs; } @@ -1276,7 +1301,9 @@ public class MapleMap { } public void killMonster(final MapleMonster monster, final MapleCharacter chr, final boolean withDrops, int animation) { - if(monster == null) return; + if (monster == null) { + return; + } if (chr == null) { if(removeKilledMonsterObject(monster)) { @@ -1288,12 +1315,18 @@ public class MapleMap { if (monster.getStats().getLevel() >= chr.getLevel() + 30 && !chr.isGM()) { AutobanFactory.GENERAL.alert(chr, " for killing a " + monster.getName() + " which is over 30 levels higher."); } + /*if (chr.getQuest(MapleQuest.getInstance(29400)).getStatus().equals(MapleQuestStatus.Status.STARTED)) { if (chr.getLevel() >= 120 && monster.getStats().getLevel() >= 120) { //FIX MEDAL SHET } else if (monster.getStats().getLevel() >= chr.getLevel()) { } }*/ + + if (monster.getCP() > 0 && chr.getMap().isCPQMap()) { + chr.gainCP(monster.getCP()); + } + int buff = monster.getBuffToGive(); if (buff > -1) { MapleItemInformationProvider mii = MapleItemInformationProvider.getInstance(); @@ -1307,13 +1340,7 @@ public class MapleMap { } } } - - if (monster.getCP() > 0 && chr.getCarnival() != null) { - chr.getCarnivalParty().addCP(chr, monster.getCP()); - chr.announce(MaplePacketCreator.updateCP(chr.getCP(), chr.getObtainedCP())); - broadcastMessage(MaplePacketCreator.updatePartyCP(chr.getCarnivalParty())); - //they drop items too ): - } + if (monster.getId() >= 8800003 && monster.getId() <= 8800010) { boolean makeZakReal = true; Collection objects = getMapObjects(); @@ -1389,7 +1416,9 @@ public class MapleMap { for (MapleMonster mob : mobList) { if (mob.getId() == mobId) { MapleCharacter chr = mapChars.get(mob.getHighestDamagerId()); - if(chr == null) chr = defaultChr; + if (chr == null) { + chr = defaultChr; + } this.killMonster(mob, chr, true); } @@ -1788,7 +1817,9 @@ public class MapleMap { public void spawnRevives(final MapleMonster monster) { monster.setMap(this); - if(getEventInstance() != null) getEventInstance().registerMonster(monster); + if (getEventInstance() != null) { + getEventInstance().registerMonster(monster); + } spawnAndAddRangedMapObject(monster, new DelayedPacketCreation() { @Override @@ -1890,7 +1921,9 @@ public class MapleMap { monster.changeDifficulty(difficulty, isPq); monster.setMap(this); - if(getEventInstance() != null) getEventInstance().registerMonster(monster); + if (getEventInstance() != null) { + getEventInstance().registerMonster(monster); + } spawnAndAddRangedMapObject(monster, new DelayedPacketCreation() { @Override @@ -1901,6 +1934,22 @@ public class MapleMap { monster.aggroUpdateController(); + if ((monster.getTeam() == 1 || monster.getTeam() == 0) && (isCPQMap() || isCPQMap2())) { + List teamS = null; + if (monster.getTeam() == 0) { + teamS = redTeamBuffs; + } else if (monster.getTeam() == 1) { + teamS = blueTeamBuffs; + } + if (teamS != null) { + for (MCSkill skil : teamS) { + if (skil != null) { + skil.getSkill().applyEffect(null, monster, false, null); + } + } + } + } + if (monster.hasBossHPBar()) { broadcastBossHpMessage(monster, monster.hashCode(), monster.makeBossHPBarPacket(), monster.getPosition()); } @@ -1932,9 +1981,13 @@ public class MapleMap { monster.setMap(this); Point spos = new Point(pos.x, pos.y - 1); spos = calcPointBelow(spos); - if(spos == null) return; + if (spos == null) { + return; + } - if(getEventInstance() != null) getEventInstance().registerMonster(monster); + if (getEventInstance() != null) { + getEventInstance().registerMonster(monster); + } spos.y--; monster.setPosition(spos); @@ -2008,7 +2061,9 @@ public class MapleMap { } c.announce(MaplePacketCreator.spawnPortal(door.getFrom().getId(), door.getTo().getId(), door.toPosition())); - if(!door.inTown()) c.announce(MaplePacketCreator.spawnDoor(door.getOwnerId(), door.getPosition(), false)); + if (!door.inTown()) { + c.announce(MaplePacketCreator.spawnDoor(door.getOwnerId(), door.getPosition(), false)); + } } c.announce(MaplePacketCreator.enableActions()); @@ -2153,7 +2208,9 @@ public class MapleMap { // spawns item instances of all defined item ids on a list public final void spawnItemDropList(List list, int minCopies, int maxCopies, final MapleMapObject dropper, final MapleCharacter owner, Point pos, final boolean ffaDrop, final boolean playerDrop) { int copies = (maxCopies - minCopies) + 1; - if(copies < 1) return; + if(copies < 1) { + return; + } Collections.shuffle(list); @@ -2166,8 +2223,7 @@ public class MapleMap { for(int i = 0; i < list.size(); i++) { if(list.get(i) == 0) { spawnMesoDrop(owner != null ? 10 * owner.getMesoRate() : 10, calcDropPos(dropPos, pos), dropper, owner, playerDrop, (byte) (ffaDrop ? 2 : 0)); - } - else { + } else { final Item drop; int randomedId = list.get(i); @@ -2280,7 +2336,9 @@ public class MapleMap { private void addPartyMemberInternal(MapleCharacter chr) { int partyid = chr.getPartyId(); - if(partyid == -1) return; + if (partyid == -1) { + return; + } Set partyEntry = mapParty.get(partyid); if(partyEntry == null) { @@ -2295,12 +2353,17 @@ public class MapleMap { private void removePartyMemberInternal(MapleCharacter chr) { int partyid = chr.getPartyId(); - if(partyid == -1) return; + if (partyid == -1) { + return; + } Set partyEntry = mapParty.get(partyid); if(partyEntry != null) { - if(partyEntry.size() > 1) partyEntry.remove(chr.getId()); - else mapParty.remove(partyid); + if (partyEntry.size() > 1) { + partyEntry.remove(chr.getId()); + } else { + mapParty.remove(partyid); + } } } @@ -2441,7 +2504,9 @@ public class MapleMap { }, travelTime); } else if (MapleMiniDungeonInfo.isDungeonMap(mapid)) { MapleMiniDungeon mmd = chr.getClient().getChannelServer().getMiniDungeon(mapid); - if(mmd != null) mmd.registerPlayer(chr); + if (mmd != null) { + mmd.registerPlayer(chr); + } } MaplePet[] pets = chr.getPets(); @@ -2454,6 +2519,23 @@ public class MapleMap { } } + if (chr.getMonsterCarnival() != null) { + chr.getClient().announce(MaplePacketCreator.getClock(chr.getMonsterCarnival().getTimeLeftSeconds())); + if (isCPQMap()) { + int team = -1; + int oposition = -1; + if (chr.getTeam() == 0) { + team = 0; + oposition = 1; + } + if (chr.getTeam() == 1) { + team = 1; + oposition = 0; + } + chr.getClient().announce(MaplePacketCreator.startMonsterCarnival(chr, team, oposition)); + } + } + chr.removeSandboxItems(); if (chr.getChalkboard() != null) { @@ -2537,19 +2619,16 @@ public class MapleMap { chr.announce(MaplePacketCreator.rollSnowBall(true, 0, null, null)); } - MonsterCarnival carnival = chr.getCarnival(); - MonsterCarnivalParty cparty = chr.getCarnivalParty(); - if (carnival != null && cparty != null && (mapid == 980000101 || mapid == 980000201 || mapid == 980000301 || mapid == 980000401 || mapid == 980000501 || mapid == 980000601)) { - chr.getClient().announce(MaplePacketCreator.getClock((int) (carnival.getTimeLeft() / 1000))); - chr.getClient().announce(MaplePacketCreator.startCPQ(chr, carnival.oppositeTeam(cparty))); - } if (hasClock()) { Calendar cal = Calendar.getInstance(); chr.getClient().announce((MaplePacketCreator.getClockTime(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND)))); } if (hasBoat() > 0) { - if(hasBoat() == 1) chr.getClient().announce((MaplePacketCreator.boatPacket(true))); - else chr.getClient().announce(MaplePacketCreator.boatPacket(false)); + if (hasBoat() == 1) { + chr.getClient().announce((MaplePacketCreator.boatPacket(true))); + } else { + chr.getClient().announce(MaplePacketCreator.boatPacket(false)); + } } chr.receivePartyMemberHP(); @@ -3222,6 +3301,10 @@ public class MapleMap { public boolean hasClock() { return clock; } + + public void addClock(int seconds) { + broadcastMessage(MaplePacketCreator.getClock(seconds)); + } public void setTown(boolean isTown) { this.town = isTown; @@ -3324,6 +3407,7 @@ public class MapleMap { } private class MobLootEntry implements Runnable { + private byte droptype; private int mobpos; private int chRate; @@ -3434,7 +3518,9 @@ public class MapleMap { } public void instanceMapRespawn() { - if(!allowSummons) return; + if (!allowSummons) { + return; + } final int numShouldSpawn = (short) ((monsterSpawn.size() - spawnedMonstersOnMap.get()));//Fking lol'd if (numShouldSpawn > 0) { @@ -3454,7 +3540,9 @@ public class MapleMap { } public void instanceMapForceRespawn() { - if(!allowSummons) return; + if (!allowSummons) { + return; + } final int numShouldSpawn = (short) ((monsterSpawn.size() - spawnedMonstersOnMap.get()));//Fking lol'd if (numShouldSpawn > 0) { @@ -3537,7 +3625,9 @@ public class MapleMap { } public void respawn() { - if(!allowSummons) return; + if (!allowSummons) { + return; + } int numPlayers; chrRLock.lock(); @@ -3996,7 +4086,9 @@ public class MapleMap { public boolean isHorntailDefeated() { // all parts of dead horntail can be found here? for(int i = 8810010; i <= 8810017; i++) { - if(getMonsterById(i) == null) return false; + if (getMonsterById(i) == null) { + return false; + } } return true; @@ -4100,6 +4192,241 @@ public class MapleMap { } } + private final List takenSpawns = new LinkedList<>(); + private final List guardianSpawns = new LinkedList<>(); + private final List blueTeamBuffs = new ArrayList(); + private final List redTeamBuffs = new ArrayList(); + private List skillIds = new ArrayList(); + private List> mobsToSpawn = new ArrayList(); + + public List getBlueTeamBuffs() { + return blueTeamBuffs; + } + + public List getRedTeamBuffs() { + return redTeamBuffs; + } + + public void clearBuffList() { + redTeamBuffs.clear(); + blueTeamBuffs.clear(); + } + + public List getAllPlayer() { + return getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.PLAYER)); + } + + public boolean isCPQMap() { + switch (this.getId()) { + case 980000101: + case 980000201: + case 980000301: + case 980000401: + case 980000501: + case 980000601: + case 980031100: + case 980032100: + case 980033100: + return true; + } + return false; + } + + public boolean isCPQMap2() { + switch (this.getId()) { + case 980031100: + case 980032100: + case 980033100: + return true; + } + return false; + } + + public boolean isCPQLobby() { + switch (this.getId()) { + case 980000100: + case 980000200: + case 980000300: + case 980000400: + case 980000500: + case 980000600: + return true; + } + return false; + } + + public boolean isBlueCPQMap() { + switch (this.getId()) { + case 980000501: + case 980000601: + case 980031200: + case 980032200: + case 980033200: + return true; + } + return false; + } + + public boolean isPurpleCPQMap() { + switch (this.getId()) { + case 980000301: + case 980000401: + case 980031200: + case 980032200: + case 980033200: + return true; + } + return false; + } + + public Point getRandomSP(int team) { + if (takenSpawns.size() > 0) { + for (SpawnPoint sp : monsterSpawn) { + for (Point pt : takenSpawns) { + if ((sp.getPosition().x == pt.x && sp.getPosition().y == pt.y) || (sp.getTeam() != team && !this.isBlueCPQMap())) { + continue; + } else { + takenSpawns.add(pt); + return sp.getPosition(); + } + } + } + } else { + for (SpawnPoint sp : monsterSpawn) { + if (sp.getTeam() == team || this.isBlueCPQMap()) { + takenSpawns.add(sp.getPosition()); + return sp.getPosition(); + } + } + } + return null; + } + + public GuardianSpawnPoint getRandomGuardianSpawn(int team) { + boolean alltaken = false; + for (GuardianSpawnPoint a : this.guardianSpawns) { + if (!a.isTaken()) { + alltaken = false; + break; + } + } + if (alltaken) { + return null; + } + if (this.guardianSpawns.size() > 0) { + while (true) { + for (GuardianSpawnPoint gsp : this.guardianSpawns) { + if (!gsp.isTaken() && Math.random() < 0.3 && (gsp.getTeam() == -1 || gsp.getTeam() == team)) { + return gsp; + } + } + } + } + return null; + } + + public void addGuardianSpawnPoint(GuardianSpawnPoint a) { + this.guardianSpawns.add(a); + } + + public int spawnGuardian(int team, int num) { + try { + if (team == 0 && redTeamBuffs.size() >= 4 || team == 1 && blueTeamBuffs.size() >= 4) { + return 2; + } + final MCSkill skil = MapleCarnivalFactory.getInstance().getGuardian(num); + if (team == 0 && redTeamBuffs.contains(skil)) { + return 0; + } else if (team == 1 && blueTeamBuffs.contains(skil)) { + return 0; + } + GuardianSpawnPoint pt = this.getRandomGuardianSpawn(team); + if (pt == null) { + return -1; + } + int reactorID = 9980000 + team; + MapleReactor reactor = new MapleReactor(MapleReactorFactory.getReactorS(reactorID), reactorID); + pt.setTaken(true); + reactor.setPosition(pt.getPosition()); + reactor.setName(team + "" + num); //lol + reactor.resetReactorActions(0); + this.spawnReactor(reactor); + reactor.setGuardian(pt); + this.buffMonsters(team, skil); + getReactorByOid(reactor.getObjectId()).hitReactor(((MapleCharacter) this.getAllPlayer().get(0)).getClient()); + } catch (Exception e) { + e.printStackTrace(); + } + return 1; + } + + public void buffMonsters(int team, MCSkill skil) { + if (team == 0) { + redTeamBuffs.add(skil); + } else if (team == 1) { + blueTeamBuffs.add(skil); + } + for (MapleMapObject mmo : this.mapobjects.values()) { + if (mmo.getType() == MapleMapObjectType.MONSTER) { + MapleMonster mob = (MapleMonster) mmo; + if (mob.getTeam() == team) { + if (skil != null) { + skil.getSkill().applyEffect(null, mob, false, null); + } + } + + } + } + } + + public final List getSkillIds() { + return skillIds; + } + + public final void addSkillId(int z) { + this.skillIds.add(z); + } + + public final void addMobSpawn(int mobId, int spendCP) { + this.mobsToSpawn.add(new Pair(mobId, spendCP)); + } + + public final List> getMobsToSpawn() { + return mobsToSpawn; + } + + public boolean isCPQWinnerMap() { + switch (this.getId()) { + case 980000103: + case 980000203: + case 980000303: + case 980000403: + case 980000503: + case 980000603: + case 980031300: + case 980032300: + case 980033300: + return true; + } + return false; + } + + public boolean isCPQLoserMap() { + switch (this.getId()) { + case 980000104: + case 980000204: + case 980000304: + case 980000404: + case 980000504: + case 980000604: + case 980031400: + case 980032400: + case 980033400: + return true; + } + return false; + } + public void dispose() { for(MapleMonster mm : this.getMonsters()) { mm.dispose(); @@ -4140,4 +4467,4 @@ public class MapleMap { chrWLock.unlock(); } } -} +} \ No newline at end of file diff --git a/src/server/maps/MapleMapFactory.java b/src/server/maps/MapleMapFactory.java index 9b2c0d3f98..05a41ef13c 100644 --- a/src/server/maps/MapleMapFactory.java +++ b/src/server/maps/MapleMapFactory.java @@ -48,12 +48,14 @@ import server.life.MapleMonster; import server.life.MaplePlayerNPC; import server.life.MaplePlayerNPCFactory; import scripting.event.EventInstanceManager; +import server.partyquest.GuardianSpawnPoint; import tools.DatabaseConnection; import tools.StringUtil; public class MapleMapFactory { + private static Map mapRecoveryRate = new HashMap<>(); - + private MapleDataProvider source; private MapleData nameData; private EventInstanceManager event; @@ -68,12 +70,12 @@ public class MapleMapFactory { this.world = world; this.channel = channel; this.event = eim; - + ReentrantReadWriteLock rrwl = new MonitoredReentrantReadWriteLock(MonitoredLockType.MAP_FACTORY); this.mapsRLock = rrwl.readLock(); this.mapsWLock = rrwl.writeLock(); } - + public MapleMap resetMap(int mapid) { mapsWLock.lock(); try { @@ -81,14 +83,23 @@ public class MapleMapFactory { } finally { mapsWLock.unlock(); } - + return getMap(mapid); } - + private void loadLifeFromWz(MapleMap map, MapleData mapData) { for (MapleData life : mapData.getChildByPath("life")) { + life.getName(); String id = MapleDataTool.getString(life.getChildByPath("id")); String type = MapleDataTool.getString(life.getChildByPath("type")); + int team = MapleDataTool.getInt("team", life, -1); + if (map.isCPQMap2() && type.equals("m")) { + if((Integer.parseInt(life.getName()) % 2) == 0) { + team = 0; + } else { + team = 1; + } + } int cy = MapleDataTool.getInt(life.getChildByPath("cy")); MapleData dF = life.getChildByPath("f"); int f = (dF != null) ? MapleDataTool.getInt(dF) : 0; @@ -99,12 +110,11 @@ public class MapleMapFactory { int y = MapleDataTool.getInt(life.getChildByPath("y")); int hide = MapleDataTool.getInt("hide", life, 0); int mobTime = MapleDataTool.getInt("mobTime", life, 0); - int team = MapleDataTool.getInt("team", life, -1); loadLifeRaw(map, Integer.parseInt(id), type, cy, f, fh, rx0, rx1, x, y, hide, mobTime, team); } } - + private void loadLifeFromDb(MapleMap map) { try { Connection con = DatabaseConnection.getConnection(); @@ -113,7 +123,7 @@ public class MapleMapFactory { ps.setInt(2, map.getWorld()); ResultSet rs = ps.executeQuery(); - while(rs.next()) { + while (rs.next()) { int id = rs.getInt("life"); String type = rs.getString("type"); int cy = rs.getInt("cy"); @@ -137,12 +147,12 @@ public class MapleMapFactory { sqle.printStackTrace(); } } - + private void loadLifeRaw(MapleMap map, int id, String type, int cy, int f, int fh, int rx0, int rx1, int x, int y, int hide, int mobTime, int team) { AbstractLoadedMapleLife myLife = loadLife(id, type, cy, f, fh, rx0, rx1, x, y, hide); if (myLife instanceof MapleMonster) { MapleMonster monster = (MapleMonster) myLife; - + if (mobTime == -1) { //does not respawn, force spawn once map.spawnMonster(monster); } else { @@ -155,10 +165,10 @@ public class MapleMapFactory { map.addMapObject(myLife); } } - + private synchronized MapleMap loadMapFromWz(int mapid, Integer omapid) { MapleMap map; - + mapsRLock.lock(); try { map = maps.get(omapid); @@ -169,7 +179,7 @@ public class MapleMapFactory { if (map != null) { return map; } - + String mapName = getMapName(mapid); MapleData mapData = source.getData(mapName); // source.getData issue with giving nulls in rare ocasions found thanks to MedicOP MapleData infoData = mapData.getChildByPath("info"); @@ -209,9 +219,9 @@ public class MapleMapFactory { bounds[0] = MapleDataTool.getInt(infoData.getChildByPath("VRTop")); bounds[1] = MapleDataTool.getInt(infoData.getChildByPath("VRBottom")); - if(bounds[0] == bounds[1]) { // old-style baked map + if (bounds[0] == bounds[1]) { // old-style baked map MapleData minimapData = mapData.getChildByPath("miniMap"); - if(minimapData != null) { + if (minimapData != null) { bounds[0] = MapleDataTool.getInt(minimapData.getChildByPath("centerX")) * -1; bounds[1] = MapleDataTool.getInt(minimapData.getChildByPath("centerY")) * -1; bounds[2] = MapleDataTool.getInt(minimapData.getChildByPath("height")); @@ -272,7 +282,7 @@ public class MapleMapFactory { map.addMapleArea(new Rectangle(x1, y1, (x2 - x1), (y2 - y1))); } } - if(event == null) { + if (event == null) { try { Connection con = DatabaseConnection.getConnection(); try (PreparedStatement ps = con.prepareStatement("SELECT * FROM playernpcs WHERE map = ? AND world = ?")) { @@ -288,23 +298,47 @@ public class MapleMapFactory { } catch (SQLException e) { e.printStackTrace(); } - + List dnpcs = MaplePlayerNPCFactory.getDeveloperNpcsFromMapid(mapid); - if(dnpcs != null) { - for(MaplePlayerNPC dnpc : dnpcs) { + if (dnpcs != null) { + for (MaplePlayerNPC dnpc : dnpcs) { map.addPlayerNPCMapObject(dnpc); } } } - + loadLifeFromWz(map, mapData); loadLifeFromDb(map); - + + if (map.isCPQMap()) { + MapleData mcData = mapData.getChildByPath("monsterCarnival"); + if (mcData != null) { + MapleData guardianGenData = mcData.getChildByPath("guardianGenPos"); + for (MapleData node : guardianGenData.getChildren()) { + GuardianSpawnPoint pt = new GuardianSpawnPoint(new Point(MapleDataTool.getIntConvert("x", node), MapleDataTool.getIntConvert("y", node))); + pt.setTeam(MapleDataTool.getIntConvert("team", node, -1)); + pt.setTaken(false); + map.addGuardianSpawnPoint(pt); + } + } + if (mcData.getChildByPath("skill") != null) { + for (MapleData area : mcData.getChildByPath("skill")) { + map.addSkillId(MapleDataTool.getInt(area)); + } + } + + if (mcData.getChildByPath("mob") != null) { + for (MapleData area : mcData.getChildByPath("mob")) { + map.addMobSpawn(MapleDataTool.getInt(area.getChildByPath("id")), MapleDataTool.getInt(area.getChildByPath("spendCP"))); + } + } + } + if (mapData.getChildByPath("reactor") != null) { for (MapleData reactor : mapData.getChildByPath("reactor")) { String id = MapleDataTool.getString(reactor.getChildByPath("id")); if (id != null) { - MapleReactor newReactor = loadReactor(reactor, id); + MapleReactor newReactor = loadReactor(reactor, id, (byte) MapleDataTool.getInt(reactor.getChildByPath("f"), 0)); map.spawnReactor(newReactor); } } @@ -313,7 +347,7 @@ public class MapleMapFactory { map.setMapName(MapleDataTool.getString("mapName", nameData.getChildByPath(getMapStringName(omapid)), "")); map.setStreetName(MapleDataTool.getString("streetName", nameData.getChildByPath(getMapStringName(omapid)), "")); } catch (Exception e) { - if(omapid / 1000 != 1020) { // explorer job introducion scenes + if (omapid / 1000 != 1020) { // explorer job introducion scenes e.printStackTrace(); System.err.println("Not found mapid " + omapid); } @@ -332,13 +366,13 @@ public class MapleMapFactory { map.setTimeLimit(MapleDataTool.getIntConvert("timeLimit", infoData, -1)); map.setFieldType(MapleDataTool.getIntConvert("fieldType", infoData, 0)); map.setMobCapacity(MapleDataTool.getIntConvert("fixedMobCapacity", infoData, 500));//Is there a map that contains more than 500 mobs? - + MapleData recData = infoData.getChildByPath("recovery"); - if(recData != null) { + if (recData != null) { float recoveryRate = MapleDataTool.getFloat(recData); mapRecoveryRate.put(mapid, recoveryRate); } - + HashMap backTypes = new HashMap<>(); try { for (MapleData layer : mapData.getChildByPath("back")) { // yolo @@ -351,7 +385,7 @@ public class MapleMapFactory { e.printStackTrace(); // swallow cause I'm cool } - + map.setBackgroundTypes(backTypes); map.generateMapDropRangeCache(); @@ -361,21 +395,21 @@ public class MapleMapFactory { } finally { mapsWLock.unlock(); } - + return map; } - + public MapleMap getMap(int mapid) { Integer omapid = Integer.valueOf(mapid); MapleMap map; - + mapsRLock.lock(); try { map = maps.get(omapid); } finally { mapsRLock.unlock(); } - + return (map != null) ? map : loadMapFromWz(mapid, omapid); } @@ -387,7 +421,7 @@ public class MapleMapFactory { mapsRLock.unlock(); } } - + private AbstractLoadedMapleLife loadLife(int id, String type, int cy, int f, int fh, int rx0, int rx1, int x, int y, int hide) { AbstractLoadedMapleLife myLife = MapleLifeFactory.getLife(id, type); myLife.setCy(cy); @@ -402,10 +436,11 @@ public class MapleMapFactory { return myLife; } - private MapleReactor loadReactor(MapleData reactor, String id) { + private MapleReactor loadReactor(MapleData reactor, String id, final byte FacingDirection) { MapleReactor myReactor = new MapleReactor(MapleReactorFactory.getReactor(Integer.parseInt(id)), Integer.parseInt(id)); int x = MapleDataTool.getInt(reactor.getChildByPath("x")); int y = MapleDataTool.getInt(reactor.getChildByPath("y")); + myReactor.setFacingDirection(FacingDirection); myReactor.setPosition(new Point(x, y)); myReactor.setDelay(MapleDataTool.getInt(reactor.getChildByPath("reactorTime")) * 1000); myReactor.setName(MapleDataTool.getString(reactor.getChildByPath("name"), "")); @@ -442,7 +477,7 @@ public class MapleMapFactory { } else if (mapid >= 677000000 && mapid < 677100000) { builder.append("Episode1GL"); } else if (mapid >= 670000000 && mapid < 682000000) { - if((mapid >= 674030000 && mapid < 674040000) || (mapid >= 680100000 && mapid < 680200000)) { + if ((mapid >= 674030000 && mapid < 674040000) || (mapid >= 680100000 && mapid < 680200000)) { builder.append("etc"); } else { builder.append("weddingGL"); @@ -452,7 +487,7 @@ public class MapleMapFactory { } else if (mapid >= 683000000 && mapid < 684000000) { builder.append("event"); } else if (mapid >= 800000000 && mapid < 900000000) { - if((mapid >= 889100000 && mapid < 889200000)) { + if ((mapid >= 889100000 && mapid < 889200000)) { builder.append("etc"); } else { builder.append("jp"); @@ -480,17 +515,17 @@ public class MapleMapFactory { mapsRLock.unlock(); } } - + public void dispose() { Collection mapValues = getMaps().values(); - - for(MapleMap map: mapValues) { + + for (MapleMap map : mapValues) { map.dispose(); } - + this.event = null; } - + public static float getMapRecoveryRate(int mapid) { Float recRate = mapRecoveryRate.get(mapid); return recRate != null ? recRate : 1.0f; diff --git a/src/server/maps/MapleReactor.java b/src/server/maps/MapleReactor.java index 72df5fcfbc..42179421d5 100644 --- a/src/server/maps/MapleReactor.java +++ b/src/server/maps/MapleReactor.java @@ -1,27 +1,28 @@ /* - This file is part of the OdinMS Maple Story Server - Copyright (C) 2008 Patrick Huy - Matthias Butz - Jan Christian Meyer + 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 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. + 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 . -*/ + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ package server.maps; import client.MapleClient; +import client.status.MonsterStatus; import constants.ServerConstants; import java.awt.Rectangle; @@ -36,6 +37,7 @@ import server.TimerManager; import tools.MaplePacketCreator; import tools.Pair; import net.server.audit.locks.MonitoredLockType; +import server.partyquest.GuardianSpawnPoint; /** * @@ -43,6 +45,7 @@ import net.server.audit.locks.MonitoredLockType; * @author Ronan */ public class MapleReactor extends AbstractMapleMapObject { + private int rid; private MapleReactorStats stats; private byte state; @@ -54,28 +57,30 @@ public class MapleReactor extends AbstractMapleMapObject { private boolean shouldCollect; private boolean attackHit; private ScheduledFuture timeoutTask = null; + private GuardianSpawnPoint guardian = null; + private byte facingDirection = 0; private Lock reactorLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.REACTOR, true); private Lock hitLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.REACTOR_HIT, true); public MapleReactor(MapleReactorStats stats, int rid) { - this.evstate = (byte)0; + this.evstate = (byte) 0; this.stats = stats; this.rid = rid; this.alive = true; } - + public void setShouldCollect(boolean collect) { this.shouldCollect = collect; } - + public boolean getShouldCollect() { return shouldCollect; } - + public void lockReactor() { reactorLock.lock(); } - + public void unlockReactor() { reactorLock.unlock(); } @@ -83,19 +88,19 @@ public class MapleReactor extends AbstractMapleMapObject { public void setState(byte state) { this.state = state; } - + public byte getState() { return state; } - + public void setEventState(byte substate) { this.evstate = substate; } - + public byte getEventState() { return evstate; } - + public MapleReactorStats getStats() { return stats; } @@ -120,7 +125,7 @@ public class MapleReactor extends AbstractMapleMapObject { public int getReactorType() { return stats.getType(state); } - + public boolean isRecentHitFromAttack() { return attackHit; } @@ -140,7 +145,7 @@ public class MapleReactor extends AbstractMapleMapObject { public boolean isAlive() { return alive; } - + public boolean isActive() { return alive && stats.getType(state) != -1; } @@ -172,10 +177,12 @@ public class MapleReactor extends AbstractMapleMapObject { cancelReactorTimeout(); setShouldCollect(true); refreshReactorTimeout(); - - if(map != null) map.searchItemReactors(this); + + if (map != null) { + map.searchItemReactors(this); + } } - + public void forceHitReactor(final byte newState) { this.lockReactor(); try { @@ -185,10 +192,12 @@ public class MapleReactor extends AbstractMapleMapObject { this.unlockReactor(); } } - + private void tryForceHitReactor(final byte newState) { // weak hit state signal, if already changed reactor state before timeout then drop this - if(!this.reactorLock.tryLock()) return; - + if (!this.reactorLock.tryLock()) { + return; + } + try { this.resetReactorActions(newState); map.broadcastMessage(MaplePacketCreator.triggerReactor(this, (short) 0)); @@ -196,19 +205,19 @@ public class MapleReactor extends AbstractMapleMapObject { this.reactorLock.unlock(); } } - + public void cancelReactorTimeout() { if (timeoutTask != null) { timeoutTask.cancel(false); timeoutTask = null; } } - + private void refreshReactorTimeout() { int timeOut = stats.getTimeout(state); - if(timeOut > -1) { + if (timeOut > -1) { final byte nextState = stats.getTimeoutState(state); - + timeoutTask = TimerManager.getInstance().schedule(new Runnable() { @Override public void run() { @@ -218,7 +227,7 @@ public class MapleReactor extends AbstractMapleMapObject { }, timeOut); } } - + public void delayedHitReactor(final MapleClient c, long delay) { TimerManager.getInstance().schedule(new Runnable() { @Override @@ -231,20 +240,22 @@ public class MapleReactor extends AbstractMapleMapObject { public void hitReactor(MapleClient c) { hitReactor(false, 0, (short) 0, 0, c); } - + public void hitReactor(boolean wHit, int charPos, short stance, int skillid, MapleClient c) { try { - if(!this.isActive()) { + if (!this.isActive()) { return; } - - if(hitLock.tryLock()) { + + if (hitLock.tryLock()) { this.lockReactor(); try { cancelReactorTimeout(); attackHit = wHit; - if(ServerConstants.USE_DEBUG == true) c.getPlayer().dropMessage(5, "Hitted REACTOR " + this.getId() + " with POS " + charPos + " , STANCE " + stance + " , SkillID " + skillid + " , STATE " + stats.getType(state) + " STATESIZE " + stats.getStateSize(state)); + if (ServerConstants.USE_DEBUG == true) { + c.getPlayer().dropMessage(5, "Hitted REACTOR " + this.getId() + " with POS " + charPos + " , STANCE " + stance + " , SkillID " + skillid + " , STATE " + stats.getType(state) + " STATESIZE " + stats.getStateSize(state)); + } ReactorScriptManager.getInstance().onHit(c, this); int reactorType = stats.getType(state); @@ -253,7 +264,9 @@ public class MapleReactor extends AbstractMapleMapObject { for (byte b = 0; b < stats.getStateSize(state); b++) {//YAY? List activeSkills = stats.getActiveSkills(state, b); if (activeSkills != null) { - if (!activeSkills.contains(skillid)) continue; + if (!activeSkills.contains(skillid)) { + continue; + } } state = stats.getNextState(state, b); if (stats.getNextState(state, b) == -1) {//end of reactor @@ -276,7 +289,7 @@ public class MapleReactor extends AbstractMapleMapObject { setShouldCollect(true); // refresh collectability on item drop-based reactors refreshReactorTimeout(); - if(stats.getType(state) == 100) { + if (stats.getType(state) == 100) { map.searchItemReactors(this); } } @@ -286,21 +299,23 @@ public class MapleReactor extends AbstractMapleMapObject { } else { state++; map.broadcastMessage(MaplePacketCreator.triggerReactor(this, stance)); - ReactorScriptManager.getInstance().act(c, this); + if (this.getId() != 9980000 && this.getId() != 9980001) { + ReactorScriptManager.getInstance().act(c, this); + } setShouldCollect(true); refreshReactorTimeout(); - if(stats.getType(state) == 100) { + if (stats.getType(state) == 100) { map.searchItemReactors(this); } } } finally { this.unlockReactor(); } - + hitLock.unlock(); } - } catch(Exception e) { + } catch (Exception e) { e.printStackTrace(); } } @@ -316,4 +331,20 @@ public class MapleReactor extends AbstractMapleMapObject { public void setName(String name) { this.name = name; } + + public GuardianSpawnPoint getGuardian() { + return guardian; + } + + public void setGuardian(GuardianSpawnPoint guardian) { + this.guardian = guardian; + } + + public final void setFacingDirection(final byte facingDirection) { + this.facingDirection = facingDirection; + } + + public final byte getFacingDirection() { + return facingDirection; + } } diff --git a/src/server/maps/MapleReactorFactory.java b/src/server/maps/MapleReactorFactory.java index 55e72fd305..f5a68fe7e9 100644 --- a/src/server/maps/MapleReactorFactory.java +++ b/src/server/maps/MapleReactorFactory.java @@ -38,6 +38,61 @@ public class MapleReactorFactory { private static MapleDataProvider data = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Reactor.wz")); private static Map reactorStats = new HashMap(); + + public static final MapleReactorStats getReactorS(int rid) { + MapleReactorStats stats = reactorStats.get(Integer.valueOf(rid)); + if (stats == null) { + int infoId = rid; + MapleData reactorData = data.getData(StringUtil.getLeftPaddedStr(Integer.toString(infoId) + ".img", '0', 11)); + MapleData link = reactorData.getChildByPath("info/link"); + if (link != null) { + infoId = MapleDataTool.getIntConvert("info/link", reactorData); + stats = reactorStats.get(Integer.valueOf(infoId)); + } + if (stats == null) { + stats = new MapleReactorStats(); + reactorData = data.getData(StringUtil.getLeftPaddedStr(Integer.toString(infoId) + ".img", '0', 11)); + if (reactorData == null) { + return stats; + } + boolean canTouch = MapleDataTool.getInt("info/activateByTouch", reactorData, 0) > 0; + boolean areaSet = false; + boolean foundState = false; + for (byte i = 0; true; i++) { + MapleData reactorD = reactorData.getChildByPath(String.valueOf(i)); + if (reactorD == null) { + break; + } + MapleData reactorInfoData_ = reactorD.getChildByPath("event"); + if (reactorInfoData_ != null && reactorInfoData_.getChildByPath("0") != null) { + MapleData reactorInfoData = reactorInfoData_.getChildByPath("0"); + Pair reactItem = null; + int type = MapleDataTool.getIntConvert("type", reactorInfoData); + if (type == 100) { //reactor waits for item + reactItem = new Pair(MapleDataTool.getIntConvert("0", reactorInfoData), MapleDataTool.getIntConvert("1", reactorInfoData, 1)); + if (!areaSet) { //only set area of effect for item-triggered reactors once + stats.setTL(MapleDataTool.getPoint("lt", reactorInfoData)); + stats.setBR(MapleDataTool.getPoint("rb", reactorInfoData)); + areaSet = true; + } + } + foundState = true; + stats.addState(i, type, reactItem, (byte) MapleDataTool.getIntConvert("state", reactorInfoData), MapleDataTool.getIntConvert("timeOut", reactorInfoData_, -1), (byte) (canTouch ? 2 : (MapleDataTool.getIntConvert("2", reactorInfoData, 0) > 0 || reactorInfoData.getChildByPath("clickArea") != null || type == 9 ? 1 : 0))); + } else { + stats.addState(i, 999, null, (byte) (foundState ? -1 : (i + 1)), 0, (byte) 0); + } + } + reactorStats.put(Integer.valueOf(infoId), stats); + if (rid != infoId) { + reactorStats.put(Integer.valueOf(rid), stats); + } + } else { // stats exist at infoId but not rid; add to map + reactorStats.put(Integer.valueOf(rid), stats); + } + } + return stats; + } + public static MapleReactorStats getReactor(int rid) { MapleReactorStats stats = reactorStats.get(Integer.valueOf(rid)); if (stats == null) { diff --git a/src/server/maps/MapleReactorStats.java b/src/server/maps/MapleReactorStats.java index 88507a4277..21f9d5f4c2 100644 --- a/src/server/maps/MapleReactorStats.java +++ b/src/server/maps/MapleReactorStats.java @@ -22,6 +22,7 @@ package server.maps; import java.awt.Point; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -58,6 +59,12 @@ public class MapleReactorStats { if(timeOut > -1) timeoutInfo.put(state, timeOut); } + public void addState(byte state, int type, Pair reactItem, byte nextState, int timeOut, byte canTouch) { + List data = new ArrayList<>(); + data.add(new StateData(type, reactItem, null, nextState)); + stateInfo.put(state, data); + } + public int getTimeout(byte state) { Integer i = timeoutInfo.get(state); return (i == null) ? -1 : i; diff --git a/src/server/maps/SavedLocationType.java b/src/server/maps/SavedLocationType.java index 238e135873..b0e8cd8893 100644 --- a/src/server/maps/SavedLocationType.java +++ b/src/server/maps/SavedLocationType.java @@ -31,6 +31,7 @@ public enum SavedLocationType { EVENT, BOSSPQ, HAPPYVILLE, + MONSTER_CARNIVAL, DEVELOPER; public static SavedLocationType fromString(String Str) { diff --git a/src/server/partyquest/GuardianSpawnPoint.java b/src/server/partyquest/GuardianSpawnPoint.java new file mode 100644 index 0000000000..9f918f22d4 --- /dev/null +++ b/src/server/partyquest/GuardianSpawnPoint.java @@ -0,0 +1,43 @@ +package server.partyquest; + +import java.awt.Point; + +/** + * + * @author David + */ +public class GuardianSpawnPoint { + + private Point position; + private boolean taken; + private int team = -1; + + public GuardianSpawnPoint(Point a) { + this.position = a; + this.taken = true; + } + + public Point getPosition() { + return position; + } + + public void setPosition(Point position) { + this.position = position; + } + + public boolean isTaken() { + return taken; + } + + public void setTaken(boolean taken) { + this.taken = taken; + } + + public int getTeam() { + return team; + } + + public void setTeam(int team) { + this.team = team; + } +} diff --git a/src/server/partyquest/MapleCarnivalFactory.java b/src/server/partyquest/MapleCarnivalFactory.java new file mode 100644 index 0000000000..a38d2e6680 --- /dev/null +++ b/src/server/partyquest/MapleCarnivalFactory.java @@ -0,0 +1,76 @@ +package server.partyquest; + +import client.MapleDisease; +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import server.life.MobSkillFactory; +import provider.MapleDataProvider; +import provider.MapleDataProviderFactory; +import provider.MapleData; +import provider.MapleDataTool; +import server.life.MobSkill; + +/** + *@author Drago/Dragohe4rt +*/ +public class MapleCarnivalFactory { + + private final static MapleCarnivalFactory instance = new MapleCarnivalFactory(); + private final Map skills = new HashMap(); + private final Map guardians = new HashMap(); + private final MapleDataProvider dataRoot = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Skill.wz")); + + public MapleCarnivalFactory() { + //whoosh + initialize(); + } + + public static final MapleCarnivalFactory getInstance() { + return instance; + } + + private void initialize() { + if (skills.size() != 0) { + return; + } + for (MapleData z : dataRoot.getData("MCSkill.img")) { + skills.put(Integer.parseInt(z.getName()), new MCSkill(MapleDataTool.getInt("spendCP", z, 0), MapleDataTool.getInt("mobSkillID", z, 0), MapleDataTool.getInt("level", z, 0), MapleDataTool.getInt("target", z, 1) > 1)); + } + for (MapleData z : dataRoot.getData("MCGuardian.img")) { + guardians.put(Integer.parseInt(z.getName()), new MCSkill(MapleDataTool.getInt("spendCP", z, 0), MapleDataTool.getInt("mobSkillID", z, 0), MapleDataTool.getInt("level", z, 0), true)); + } + } + + public MCSkill getSkill(final int id) { + return skills.get(id); + } + + public MCSkill getGuardian(final int id) { + return guardians.get(id); + } + + public static class MCSkill { + + public int cpLoss, skillid, level; + public boolean targetsAll; + + public MCSkill(int _cpLoss, int _skillid, int _level, boolean _targetsAll) { + cpLoss = _cpLoss; + skillid = _skillid; + level = _level; + targetsAll = _targetsAll; + } + + public MobSkill getSkill() { + return MobSkillFactory.getMobSkill(skillid, 1); //level? + } + + public MapleDisease getDisease() { + if (skillid <= 0) { + return MapleDisease.getRandom(); + } + return MapleDisease.getBySkill(skillid); + } + } +} diff --git a/src/server/partyquest/MonsterCarnival.java b/src/server/partyquest/MonsterCarnival.java index 89945d7e82..490322a237 100644 --- a/src/server/partyquest/MonsterCarnival.java +++ b/src/server/partyquest/MonsterCarnival.java @@ -1,174 +1,489 @@ -/* - 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 . -*/ - package server.partyquest; -import client.MapleCharacter; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; import java.util.concurrent.ScheduledFuture; +import client.MapleCharacter; +import constants.LinguaConstants; +import net.server.Server; +import net.server.channel.Channel; +import net.server.world.MapleParty; +import net.server.world.MaplePartyCharacter; import server.TimerManager; import server.maps.MapleMap; -import tools.DatabaseConnection; import tools.MaplePacketCreator; /** - * - * @author kevintjuh93 - LOST MOTIVATION >=( + * @author Drago/Dragohe4rt */ + public class MonsterCarnival { - private MonsterCarnivalParty red, blue; + + public static int D = 3; + public static int C = 2; + public static int B = 1; + public static int A = 0; + + private MapleParty p1, p2; private MapleMap map; - private int room; - private long time = 0; - private long timeStarted = 0; - private ScheduledFuture schedule = null; + private ScheduledFuture timer, effectTimer; + private long startTime = 0; + private int summons = 8, summonss = 8; + private MapleCharacter leader1, leader2, Grupo1, Grupo2; + private int redCP, blueCP, redTotalCP, blueTotalCP; + private boolean cpq1; - public MonsterCarnival(int room, byte channel, MonsterCarnivalParty red1, MonsterCarnivalParty blue1) { - //this.map = Channel.getInstance(channel).getMapFactory().getMap(980000001 + (room * 100)); - this.room = room; - this.red = red1; - this.blue = blue1; - this.timeStarted = System.currentTimeMillis(); - this.time = 600000; - map.broadcastMessage(MaplePacketCreator.getClock((int) (time / 1000))); - - for (MapleCharacter chr : red.getMembers()) - chr.setCarnival(this); - for (MapleCharacter chr : blue.getMembers()) - chr.setCarnival(this); - - this.schedule = TimerManager.getInstance().schedule(new Runnable() { + public MonsterCarnival(MapleParty p1, MapleParty p2, int mapid, boolean cpq1) { + try { + this.cpq1 = cpq1; + this.p1 = p1; + this.p2 = p2; + Channel cs = Server.getInstance().getWorld(p2.getLeader().getWorld()).getChannel(p2.getLeader().getChannel()); + p1.setEnemy(p2); + p2.setEnemy(p1); + map = cs.getMapFactory().resetMap(mapid); + int redPortal = 0; + int bluePortal = 0; + if (map.isPurpleCPQMap()) { + redPortal = 2; + bluePortal = 1; + } + for (MaplePartyCharacter mpc : p1.getMembers()) { + MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + mc.setMonsterCarnival(this); + mc.setTeam(0); + mc.setFestivalPoints(0); + mc.changeMap(map, map.getPortal(redPortal)); + mc.dropMessage(6, LinguaConstants.Linguas(mc).CPQEntrada); + if (p1.getLeader().getId() == mc.getId()) { + leader1 = mc; + } + Grupo1 = mc; + } + } + for (MaplePartyCharacter mpc : p2.getMembers()) { + MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + mc.setMonsterCarnival(this); + mc.setTeam(1); + mc.setFestivalPoints(0); + mc.changeMap(map, map.getPortal(bluePortal)); + mc.dropMessage(6, LinguaConstants.Linguas(mc).CPQEntrada); + if (p2.getLeader().getId() == mc.getId()) { + leader2 = mc; + } + Grupo2 = mc; + } + } + if (Grupo1 == null || Grupo2 == null) { + for (MaplePartyCharacter mpc : p2.getMembers()) { + mpc.getPlayer().dropMessage(5, LinguaConstants.Linguas(mpc.getPlayer()).CPQErro); + } + for (MaplePartyCharacter mpc : p2.getMembers()) { + mpc.getPlayer().dropMessage(5, LinguaConstants.Linguas(mpc.getPlayer()).CPQErro); + } + return; + } + Grupo1.getClient().announce(MaplePacketCreator.startMonsterCarnival(Grupo1, 0, 1)); + Grupo2.getClient().announce(MaplePacketCreator.startMonsterCarnival(Grupo2, 1, 0)); + startTime = System.currentTimeMillis() + 60 * 10000; + timer = TimerManager.getInstance().schedule(new Runnable() { @Override public void run() { - if (red.getTotalCP() > blue.getTotalCP()) { - red.setWinner(true); - blue.setWinner(false); - red.displayMatchResult(); - blue.displayMatchResult(); - } else if (blue.getTotalCP() > red.getTotalCP()) { - red.setWinner(false); - blue.setWinner(true); - red.displayMatchResult(); - blue.displayMatchResult(); - } else { - red.setWinner(false); - blue.setWinner(false); - red.displayMatchResult(); - blue.displayMatchResult(); - } - saveResults(); - warpOut(); + timeUp(); } - - }, time); - /* if (room == 0) { - MapleData data = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Map.wz")).getData("Map/Map9" + (980000001 + (room * 100)) + ".img").getChildByPath("monsterCarnival"); - if (data != null) { - for (MapleData p : data.getChildByPath("mobGenPos").getChildren()) { - MapleData team = p.getChildByPath("team"); - if (team != null) { - if (team.getData().equals(0)) - redmonsterpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y")))); - else - bluemonsterpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y")))); - } else - monsterpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y")))); - } - for (MapleData p : data.getChildByPath("guardianGenPos").getChildren()) { - MapleData team = p.getChildByPath("team"); - if (team != null) { - if (team.getData().equals(0)) - redreactorpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y")))); - else - bluereactorpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y")))); - } else - reactorpoints.add(new Point(MapleDataTool.getInt(p.getChildByPath("x")), MapleDataTool.getInt(p.getChildByPath("y")))); - } - } - } */ - } - - public long getTimeLeft() { - return time - (System.currentTimeMillis() - timeStarted); - } - - public MonsterCarnivalParty getPartyRed() { - return red; - } - - public MonsterCarnivalParty getPartyBlue() { - return blue; - } - - public MonsterCarnivalParty oppositeTeam(MonsterCarnivalParty team) { - if (team == red) - return blue; - else - return red; - } - - public void playerLeft(MapleCharacter chr) { - map.broadcastMessage(chr, MaplePacketCreator.leaveCPQ(chr)); - } - - private void warpOut() { - this.schedule = TimerManager.getInstance().schedule(new Runnable() { + }, 10 * 60 * 1000); + effectTimer = TimerManager.getInstance().schedule(new Runnable() { @Override public void run() { - red.warpOut(); - blue.warpOut(); + complete(); } - }, 12000); + }, 10 * 60 * 1000 - 10 * 1000); + TimerManager.getInstance().schedule(new Runnable() { + @Override + public void run() { + map.addClock(60 * 10); + } + }, 2000); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void playerDisconnected(int charid) { + int team = -1; + for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) { + if (mpc.getId() == charid) { + team = 0; + } + } + for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) { + if (mpc.getId() == charid) { + team = 1; + } + } + for (MapleCharacter chrMap : map.getAllPlayers()) { + if (team == -1) { + team = 1; + } + String teamS = ""; + switch (team) { + case 0: + teamS = LinguaConstants.Linguas(chrMap).CPQVermelho; + break; + case 1: + teamS = LinguaConstants.Linguas(chrMap).CPQAzul; + break; + } + chrMap.dropMessage(5, teamS + LinguaConstants.Linguas(chrMap).CPQPlayerExit); + } + earlyFinish(); + } + + public void earlyFinish() { + dispose(true); + } + + public void leftParty(int charid) { + playerDisconnected(charid); + } + + protected void dispose() { + dispose(false); + } + + public void summon() { + this.summons--; + } + + public boolean canSummon() { + return this.summons > 0; + } + + public void summons() { + this.summonss--; + } + + public boolean canSummons() { + return this.summonss > 0; + } + + protected void dispose(boolean warpout) { + Channel cs = Server.getInstance().getWorld(p1.getLeader().getWorld()).getChannel(p1.getLeader().getChannel()); + MapleMap out; + if (!cpq1) { // cpq2 + out = cs.getMapFactory().getMap(980030000); + } else { + out = cs.getMapFactory().getMap(980000000); + } + for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) { + MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + mc.resetCP(); + mc.setTeam(-1); + mc.setMonsterCarnival(null); + if (warpout) { + mc.changeMap(out, out.getPortal(0)); + } + } + } + for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) { + MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + mc.resetCP(); + mc.setTeam(-1); + mc.setMonsterCarnival(null); + if (warpout) { + mc.changeMap(out, out.getPortal(0)); + } + } + } + if (this.timer != null) { + this.timer.cancel(true); + this.timer = null; + } + if (this.effectTimer != null) { + this.effectTimer.cancel(true); + this.effectTimer = null; + } + redTotalCP = 0; + blueTotalCP = 0; + leader1.getParty().setEnemy(null); + leader2.getParty().setEnemy(null); + + } + + public void exit() { + dispose(); + } + + public ScheduledFuture getTimer() { + return this.timer; + } + + public void finish(int winningTeam) { + try { + Channel cs = Server.getInstance().getWorld(p1.getLeader().getWorld()).getChannel(p1.getLeader().getChannel()); + if (winningTeam == 0) { + for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) { + MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + mc.gainFestivalPoints(this.redTotalCP); + mc.setMonsterCarnival(null); + if (cpq1) { + mc.changeMap(cs.getMapFactory().getMap(map.getId() + 2), cs.getMapFactory().getMap(map.getId() + 2).getPortal(0)); + } else { + mc.changeMap(cs.getMapFactory().getMap(map.getId() + 200), cs.getMapFactory().getMap(map.getId() + 200).getPortal(0)); + } + mc.setTeam(-1); + mc.dispelDebuffs(); + } + } + for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) { + MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + mc.gainFestivalPoints(this.blueTotalCP); + mc.setMonsterCarnival(null); + if (cpq1) { + mc.changeMap(cs.getMapFactory().getMap(map.getId() + 3), cs.getMapFactory().getMap(map.getId() + 3).getPortal(0)); + } else { + mc.changeMap(cs.getMapFactory().getMap(map.getId() + 300), cs.getMapFactory().getMap(map.getId() + 300).getPortal(0)); + } + mc.setTeam(-1); + mc.dispelDebuffs(); + } + } + } else if (winningTeam == 1) { + for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) { + MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + mc.gainFestivalPoints(this.blueTotalCP); + mc.setMonsterCarnival(null); + if (cpq1) { + mc.changeMap(cs.getMapFactory().getMap(map.getId() + 2), cs.getMapFactory().getMap(map.getId() + 2).getPortal(0)); + } else { + mc.changeMap(cs.getMapFactory().getMap(map.getId() + 200), cs.getMapFactory().getMap(map.getId() + 200).getPortal(0)); + } + mc.setTeam(-1); + mc.dispelDebuffs(); + } + } + for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) { + MapleCharacter mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + mc.gainFestivalPoints(this.redTotalCP); + mc.setMonsterCarnival(null); + if (cpq1) { + mc.changeMap(cs.getMapFactory().getMap(map.getId() + 3), cs.getMapFactory().getMap(map.getId() + 3).getPortal(0)); + } else { + mc.changeMap(cs.getMapFactory().getMap(map.getId() + 300), cs.getMapFactory().getMap(map.getId() + 300).getPortal(0)); + } + mc.setTeam(-1); + mc.dispelDebuffs(); + } + } + } + dispose(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void timeUp() { + int cp1 = this.redTotalCP; + int cp2 = this.blueTotalCP; + if (cp1 == cp2) { + extendTime(); + return; + } + if (cp1 > cp2) { + finish(0); + } else { + finish(1); + } + } + + public long getTimeLeft() { + return (startTime - System.currentTimeMillis()); + } + + public int getTimeLeftSeconds() { + return (int) (getTimeLeft() / 1000); + } + + public void extendTime() { + for (MapleCharacter chrMap : map.getAllPlayers()) { + chrMap.dropMessage(5, LinguaConstants.Linguas(chrMap).CPQTempoExtendido); + } + startTime = System.currentTimeMillis() + 3 * 1000; + map.addClock(3 * 60); + timer = TimerManager.getInstance().schedule(new Runnable() { + @Override + public void run() { + timeUp(); + } + }, 3 * 60 * 1000); + effectTimer = TimerManager.getInstance().schedule(new Runnable() { + @Override + public void run() { + complete(); + } + }, 3 * 60 * 1000 - 10); + } + + public void complete() { + int cp1 = this.redTotalCP; + int cp2 = this.blueTotalCP; + if (cp1 == cp2) { + return; + } + boolean redWin = cp1 > cp2; + int chnl = leader1.getClient().getChannel(); + int chnl1 = leader2.getClient().getChannel(); + if (chnl != chnl1) { + throw new RuntimeException("Os líderes estão em canais diferentes."); } - public int getRoom() { - return room; - } - - public void saveResults() { - Connection con = null; - try { - con = DatabaseConnection.getConnection(); - PreparedStatement ps = con.prepareStatement("INSERT INTO carnivalresults VALUES (?,?,?,?)"); - for (MapleCharacter chr : red.getMembers()) { - ps.setInt(1, chr.getId()); - ps.setInt(2, chr.getCP()); - ps.setInt(3, red.getTotalCP()); - ps.setInt(4, red.isWinner() ? 1 : 0); - ps.execute(); - } - for (MapleCharacter chr : blue.getMembers()) { - ps.setInt(1, chr.getId()); - ps.setInt(2, chr.getCP()); - ps.setInt(3, blue.getTotalCP()); - ps.setInt(4, blue.isWinner() ? 1 : 0); - ps.execute(); - } - ps.close(); - con.close(); - } catch (SQLException ex) { - ex.printStackTrace(); + Channel cs = Server.getInstance().getWorld(p1.getLeader().getWorld()).getChannel(p1.getLeader().getChannel()); + map.killAllMonsters(); + for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) { + MapleCharacter mc; + mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + if (redWin) { + mc.getClient().announce(MaplePacketCreator.showEffect("quest/carnival/win")); + mc.getClient().announce(MaplePacketCreator.playSound("MobCarnival/Win")); + mc.dispelDebuffs(); + } else { + mc.getClient().announce(MaplePacketCreator.showEffect("quest/carnival/lose")); + mc.getClient().announce(MaplePacketCreator.playSound("MobCarnival/Lose")); + mc.dispelDebuffs(); } + } } + for (MaplePartyCharacter mpc : leader2.getParty().getMembers()) { + MapleCharacter mc; + mc = cs.getPlayerStorage().getCharacterByName(mpc.getName()); + if (mc != null) { + if (!redWin) { + mc.getClient().announce(MaplePacketCreator.showEffect("quest/carnival/win")); + mc.getClient().announce(MaplePacketCreator.playSound("MobCarnival/Win")); + mc.dispelDebuffs(); + } else { + mc.getClient().announce(MaplePacketCreator.showEffect("quest/carnival/lose")); + mc.getClient().announce(MaplePacketCreator.playSound("MobCarnival/Lose")); + mc.dispelDebuffs(); + } + } + } + } + + public MapleParty getRed() { + return p1; + } + + public void setRed(MapleParty p1) { + this.p1 = p1; + } + + public MapleParty getBlue() { + return p2; + } + + public void setBlue(MapleParty p2) { + this.p2 = p2; + } + + public MapleCharacter getLeader1() { + return leader1; + } + + public void setLeader1(MapleCharacter leader1) { + this.leader1 = leader1; + } + + public MapleCharacter getLeader2() { + return leader2; + } + + public void setLeader2(MapleCharacter leader2) { + this.leader2 = leader2; + } + + public MapleCharacter getEnemyLeader(int team) { + switch (team) { + case 0: + return leader2; + case 1: + return leader1; + } + return null; + } + + public int getBlueCP() { + return blueCP; + } + + public void setBlueCP(int blueCP) { + this.blueCP = blueCP; + } + + public int getBlueTotalCP() { + return blueTotalCP; + } + + public void setBlueTotalCP(int blueTotalCP) { + this.blueTotalCP = blueTotalCP; + } + + public int getRedCP() { + return redCP; + } + + public void setRedCP(int redCP) { + this.redCP = redCP; + } + + public int getRedTotalCP() { + return redTotalCP; + } + + public void setRedTotalCP(int redTotalCP) { + this.redTotalCP = redTotalCP; + } + + public int getTotalCP(int team) { + if (team == 0) { + return redTotalCP; + } else if (team == 1) { + return blueTotalCP; + } else { + throw new RuntimeException("Equipe desconhecida"); + } + } + + public void setTotalCP(int totalCP, int team) { + if (team == 0) { + this.redTotalCP = totalCP; + } else if (team == 1) { + this.blueTotalCP = totalCP; + } + } + + public int getCP(int team) { + if (team == 0) { + return redCP; + } else if (team == 1) { + return blueCP; + } else { + throw new RuntimeException("Equipe desconhecida" + team); + } + } + + public void setCP(int CP, int team) { + if (team == 0) { + this.redCP = CP; + } else if (team == 1) { + this.blueCP = CP; + } + } } diff --git a/src/tools/MaplePacketCreator.java b/src/tools/MaplePacketCreator.java index b0bd968959..bd50472cef 100644 --- a/src/tools/MaplePacketCreator.java +++ b/src/tools/MaplePacketCreator.java @@ -75,7 +75,6 @@ import server.maps.MapleReactor; import server.maps.MapleSummon; import server.life.MaplePlayerNPC; import server.movement.LifeMovementFragment; -import server.partyquest.MonsterCarnivalParty; import tools.data.output.LittleEndianWriter; import tools.data.output.MaplePacketLittleEndianWriter; import client.BuddylistEntry; @@ -407,6 +406,7 @@ public class MaplePacketCreator { mplew.write(pet.getFullness()); addExpirationTime(mplew, item.getExpiration()); mplew.writeInt(pet.getPetFlag()); /* pet flags found by -- Irenex & Spoon */ + mplew.write(new byte[]{(byte) 0x50, (byte) 0x46}); //wonder what this is mplew.writeInt(0); return; @@ -1503,23 +1503,12 @@ public class MaplePacketCreator { /** - * -4: Fake - * -3: Appear after linked mob is dead - * -2: Fade in - * 1: Smoke - * 3: King Slime spawn - * 4: Summoning rock thing, used for 3rd job? - * 6: Magical shit - * 7: Smoke shit - * 8: 'The Boss' - * 9/10: Grim phantom shit? - * 11/12: Nothing? - * 13: Frankenstein - * 14: Angry ^ - * 15: Orb animation thing, ?? - * 16: ?? - * 19: Mushroom castle boss thing - */ + * -4: Fake -3: Appear after linked mob is dead -2: Fade in 1: Smoke 3: + * King Slime spawn 4: Summoning rock thing, used for 3rd job? 6: + * Magical shit 7: Smoke shit 8: 'The Boss' 9/10: Grim phantom shit? + * 11/12: Nothing? 13: Frankenstein 14: Angry ^ 15: Orb animation thing, + * ?? 16: ?? 19: Mushroom castle boss thing + */ if (life.getParentMobOid() != 0) { MapleMonster parentMob = life.getMap().getMonsterByOid(life.getParentMobOid()); @@ -2988,7 +2977,9 @@ public class MaplePacketCreator { mplew.writeInt(cid); writeLongMaskD(mplew, statups); for (Pair statup : statups) { - if(statup.getLeft() == MapleDisease.POISON) mplew.writeShort(statup.getRight().shortValue()); + if (statup.getLeft() == MapleDisease.POISON) { + mplew.writeShort(statup.getRight().shortValue()); + } mplew.writeShort(skill.getSkillId()); mplew.writeShort(skill.getSkillLevel()); } @@ -3084,7 +3075,9 @@ public class MaplePacketCreator { mplew.writeInt(cid); writeLongMaskSlowD(mplew); for (Pair statup : statups) { - if(statup.getLeft() == MapleDisease.POISON) mplew.writeShort(statup.getRight().shortValue()); + if (statup.getLeft() == MapleDisease.POISON) { + mplew.writeShort(statup.getRight().shortValue()); + } mplew.writeShort(skill.getSkillId()); mplew.writeShort(skill.getSkillLevel()); } @@ -3121,7 +3114,7 @@ public class MaplePacketCreator { mplew.writeShort(0); mplew.writeShort(900); - for(int i = 0; i < 7; i++) mplew.write(0); + mplew.skip(7); return mplew.getPacket(); } @@ -3634,7 +3627,7 @@ public class MaplePacketCreator { mplew.write(0xF); mplew.write(slots); mplew.write(124); - for(byte i = 0; i < 10; i++) mplew.write(0); + mplew.skip(10); mplew.write(items.size()); for (Item item : items) { addItemInfo(mplew, item, true); @@ -3973,7 +3966,31 @@ public class MaplePacketCreator { mplew.writeInt(firstmask); mplew.writeInt(secondmask); } - + + public static byte[] applyMonsterStatus(int oid, Map stats, int skill, boolean monsterSkill, int delay, MobSkill mobskill) { + MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); + mplew.writeShort(SendOpcode.APPLY_MONSTER_STATUS.getValue()); + mplew.writeInt(oid); + int mask = 0; + for (MonsterStatus stat : stats.keySet()) { + mask |= stat.getValue(); + } + mplew.writeInt(mask); + for (Integer val : stats.values()) { + mplew.writeShort(val); + if (monsterSkill) { + mplew.writeShort(mobskill.getSkillId()); + mplew.writeShort(mobskill.getSkillLevel()); + } else { + mplew.writeInt(skill); + } + mplew.writeShort(0); // as this looks similar to giveBuff this + } + mplew.writeShort(delay); // delay in ms + mplew.write(1); // ? + return mplew.getPacket(); + } + public static byte[] applyMonsterStatus(final int oid, final MonsterStatusEffect mse, final List reflection) { Map stati = mse.getStati(); final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); @@ -4196,7 +4213,7 @@ public class MaplePacketCreator { mplew.write(reactor.getState()); mplew.writePos(pos); mplew.writeShort(0); - mplew.write(0); + mplew.write(reactor.getFacingDirection()); // stance, thanks to Drago/Dragohe4rt return mplew.getPacket(); } @@ -6518,9 +6535,11 @@ public class MaplePacketCreator { } /** - * 0 = Levelup 6 = Exp did not drop (Safety Charms) 7 = Enter portal sound 8 = Job - * change 9 = Quest complete 10 = Recovery 11 = Buff effect 14 = Monster book pickup 15 = - * Equipment levelup 16 = Maker Skill Success 17 = Buff effect w/ sfx 19 = Exp card [500, 200, 50] 21 = Wheel of destiny 26 = Spirit Stone + * 0 = Levelup 6 = Exp did not drop (Safety Charms) 7 = Enter portal sound + * 8 = Job change 9 = Quest complete 10 = Recovery 11 = Buff effect + * 14 = Monster book pickup 15 = Equipment levelup 16 = Maker Skill Success + * 17 = Buff effect w/ sfx 19 = Exp card [500, 200, 50] 21 = Wheel of destiny + * 26 = Spirit Stone * * @param effect * @return @@ -7693,82 +7712,59 @@ public class MaplePacketCreator { return mplew.getPacket(); } - public static byte[] startCPQ(MapleCharacter chr, MonsterCarnivalParty enemy) { - final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(25); - mplew.writeShort(SendOpcode.MONSTER_CARNIVAL_START.getValue()); - mplew.write(chr.getTeam()); //team - mplew.writeShort(chr.getCP()); //Obtained CP - Used CP - mplew.writeShort(chr.getObtainedCP()); //Total Obtained CP - mplew.writeShort(chr.getCarnivalParty().getAvailableCP()); //Obtained CP - Used CP of the team - mplew.writeShort(chr.getCarnivalParty().getTotalCP()); //Total Obtained CP of the team - mplew.writeShort(enemy.getAvailableCP()); //Obtained CP - Used CP of the team - mplew.writeShort(enemy.getTotalCP()); //Total Obtained CP of the team - mplew.writeShort(0); //Probably useless nexon shit - mplew.writeLong(0); //Probably useless nexon shit - return mplew.getPacket(); - } + public static byte[] CPUpdate(boolean party, int curCP, int totalCP, int team) { // CPQ + MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); + if (!party) { + mplew.writeShort(SendOpcode.MONSTER_CARNIVAL_OBTAINED_CP.getValue()); + } else { + mplew.writeShort(SendOpcode.MONSTER_CARNIVAL_PARTY_CP.getValue()); + mplew.write(team); // team? + } + mplew.writeShort(curCP); + mplew.writeShort(totalCP); + return mplew.getPacket(); + } - public static byte[] updateCP(int cp, int tcp) { - final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(6); - mplew.writeShort(SendOpcode.MONSTER_CARNIVAL_OBTAINED_CP.getValue()); - mplew.writeShort(cp); //Obtained CP - Used CP - mplew.writeShort(tcp); //Total Obtained CP - return mplew.getPacket(); - } + public static byte[] CPQMessage(byte message) { + final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(3); + mplew.writeShort(SendOpcode.MONSTER_CARNIVAL_MESSAGE.getValue()); + mplew.write(message); // Message + return mplew.getPacket(); + } - public static byte[] updatePartyCP(MonsterCarnivalParty party) { - final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(7); - mplew.writeShort(SendOpcode.MONSTER_CARNIVAL_PARTY_CP.getValue()); - mplew.write(party.getTeam()); //Team where the points are given to. - mplew.writeShort(party.getAvailableCP()); //Obtained CP - Used CP - mplew.writeShort(party.getTotalCP()); //Total Obtained CP - return mplew.getPacket(); - } + public static byte[] playerSummoned(String name, int tab, int number) { + MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); + mplew.writeShort(SendOpcode.MONSTER_CARNIVAL_SUMMON.getValue()); + mplew.write(tab); + mplew.write(number); + mplew.writeMapleAsciiString(name); + return mplew.getPacket(); + } - public static byte[] CPQSummon(int tab, int number, String name) { - final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); - mplew.writeShort(SendOpcode.MONSTER_CARNIVAL_SUMMON.getValue()); - mplew.write(tab); //Tab - mplew.writeShort(number); //Number of summon inside the tab - mplew.writeMapleAsciiString(name); //Name of the player that summons - return mplew.getPacket(); - } + public static byte[] playerDiedMessage(String name, int lostCP, int team) { // CPQ + MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); - public static byte[] CPQDied(MapleCharacter chr) { - final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); - mplew.writeShort(SendOpcode.MONSTER_CARNIVAL_DIED.getValue()); - mplew.write(chr.getTeam()); //Team - mplew.writeMapleAsciiString(chr.getName()); //Name of the player that died - mplew.write(chr.getAndRemoveCP()); //Lost CP - return mplew.getPacket(); - } + mplew.writeShort(SendOpcode.MONSTER_CARNIVAL_DIED.getValue()); + mplew.write(team); // team + mplew.writeMapleAsciiString(name); + mplew.write(lostCP); + return mplew.getPacket(); + } - /** - * Sends a CPQ Message
- * - * Possible values for message:
1: You don't have enough CP - * to continue.
2: You can no longer summon the Monster.
3: You can - * no longer summon the being.
4: This being is already summoned.
5: - * This request has failed due to an unknown error.
- * - * @param message Displays a message inside Carnival PQ - * - */ - public static byte[] CPQMessage(byte message) { - final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(3); - mplew.writeShort(SendOpcode.MONSTER_CARNIVAL_MESSAGE.getValue()); - mplew.write(message); //Message - return mplew.getPacket(); - } - - public static byte[] leaveCPQ(MapleCharacter chr) { - final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); - mplew.writeShort(SendOpcode.MONSTER_CARNIVAL_LEAVE.getValue()); - mplew.write(0); //Something - mplew.write(chr.getTeam()); //Team - mplew.writeMapleAsciiString(chr.getName()); //Player name - return mplew.getPacket(); - } + public static byte[] startMonsterCarnival(MapleCharacter chr, int team, int oposition) { + final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(25); + mplew.writeShort(SendOpcode.MONSTER_CARNIVAL_START.getValue()); + mplew.write(team); // team + mplew.writeShort(chr.getCP()); // Obtained CP - Used CP + mplew.writeShort(chr.getTotalCP()); // Total Obtained CP + mplew.writeShort(chr.getMonsterCarnival().getCP(team)); // Obtained CP - Used CP of the team + mplew.writeShort(chr.getMonsterCarnival().getTotalCP(team)); // Total Obtained CP of the team + mplew.writeShort(chr.getMonsterCarnival().getCP(oposition)); // Obtained CP - Used CP of the team + mplew.writeShort(chr.getMonsterCarnival().getTotalCP(oposition)); // Total Obtained CP of the team + mplew.writeShort(0); // Probably useless nexon shit + mplew.writeLong(0); // Probably useless nexon shit + return mplew.getPacket(); + } public static byte[] sheepRanchInfo(byte wolf, byte sheep) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); @@ -7867,4 +7863,4 @@ public class MaplePacketCreator { mplew.writeInt(transition); return mplew.getPacket(); } -} +} \ No newline at end of file diff --git a/src/tools/data/output/GenericLittleEndianWriter.java b/src/tools/data/output/GenericLittleEndianWriter.java index 91779e4d57..bc8351be8a 100644 --- a/src/tools/data/output/GenericLittleEndianWriter.java +++ b/src/tools/data/output/GenericLittleEndianWriter.java @@ -33,7 +33,7 @@ import constants.CharsetConstants.MapleLanguageType; * @since Revision 323 */ public class GenericLittleEndianWriter implements LittleEndianWriter { - private static Charset ASCII = Charset.forName(MapleLanguageType.LANGUAGE_US.getAscii()); + private static Charset ASCII = Charset.forName(MapleLanguageType.LANGUAGE_PT_BR.getAscii()); private ByteOutputStream bos; /** diff --git a/src/tools/packets/Wedding.java b/src/tools/packets/Wedding.java index 97ef9bb347..95946051de 100644 --- a/src/tools/packets/Wedding.java +++ b/src/tools/packets/Wedding.java @@ -18,7 +18,7 @@ import tools.data.output.MaplePacketLittleEndianWriter; /** * CField_Wedding, CField_WeddingPhoto, CWeddingMan, OnMarriageResult, and all Wedding/Marriage enum/structs. * - * @author Eric + * @author Eric edited by Drago/Dragohe4rt on Wishlist */ public class Wedding extends MaplePacketCreator { private static final short MARRIAGE_REQUEST = 0x48; @@ -375,7 +375,7 @@ public class Wedding extends MaplePacketCreator { } /** - * Handles all of WeddingWishlist packets + * Handles all of WeddingWishlist packets * * @param mode * @param itemnames @@ -392,17 +392,16 @@ public class Wedding extends MaplePacketCreator { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(WEDDING_GIFT_RESULT); mplew.write(mode); - switch(mode) { + switch (mode) { case 0x09: { // Load Wedding Registry mplew.write(itemnames.size()); for (String names : itemnames) { mplew.writeMapleAsciiString(names); } - mplew.write(itemnames.size()); - for (String names : itemnames) { - mplew.writeMapleAsciiString(names); + mplew.write(items.size()); + for (Item item : items) { + addItemInfo(mplew, item, true); } - // need to load items somehow break; } case 0xA: // Load Bride's Wishlist @@ -415,30 +414,31 @@ public class Wedding extends MaplePacketCreator { mplew.writeMapleAsciiString(names); } } - switch (items.get((items.size() - 1)).getInventoryType()) { - case EQUIP: - mplew.writeLong(4); - break; - case USE: - mplew.writeLong(8); - break; - case SETUP: - mplew.writeLong(16); - break; - case ETC: - mplew.writeLong(32); - break; - default: // impossible flag, cash item can't be sent - if (items.get((items.size() - 1)).getInventoryType() != MapleInventoryType.CASH) { - mplew.writeLong(0); - } - } - if (mode == 0xA) { // random unknown bytes involved within Bride's Wishlist - mplew.writeInt(0); + if (items.size() >= 1) { + switch (items.get((items.size() - 1)).getInventoryType()) { + case EQUIP: + mplew.writeLong(4); + break; + case USE: + mplew.writeLong(8); + break; + case SETUP: + mplew.writeLong(16); + break; + case ETC: + mplew.writeLong(32); + break; + default: // impossible flag, cash item can't be sent + if (items.get((items.size() - 1)).getInventoryType() != MapleInventoryType.CASH) { + mplew.writeLong(0); + } + } + } else { + mplew.writeLong(0); } mplew.write(items.size()); for (Item item : items) { - MaplePacketCreator.addItemInfo(mplew, item, true); + addItemInfo(mplew, item, true); } break; }