diff --git a/.gitignore b/.gitignore index 72982b47a8..4b64dd716f 100644 --- a/.gitignore +++ b/.gitignore @@ -55,4 +55,13 @@ /tools/MapleSkillMakerReagentIndexer/dist/ /tools/MapleSkillMakerReagentIndexer/nbproject/private/ -/out \ No newline at end of file +/out +/tools/MapleQuestItemQuantityFetcher/nbproject/private/ +/tools/MapleQuestItemQuantityFetcher/build/ +/tools/MapleQuestItemQuantityFetcher/dist/ +/tools/MapleQuestItemCountFetcher/nbproject/private/ +/tools/MapleQuestItemCountFetcher/build/ +/tools/MapleQuestItemCountFetcher/dist/ +/tools/MapleBossHpBarFetcher/nbproject/private/ +/tools/MapleBossHpBarFetcher/build/ +/tools/MapleBossHpBarFetcher/dist/ \ No newline at end of file diff --git a/docs/feature_list.md b/docs/feature_list.md index 55c3c0e1d4..749dd01f3c 100644 --- a/docs/feature_list.md +++ b/docs/feature_list.md @@ -43,6 +43,7 @@ Quests: * Loads of quests have been patched. * Quest rewards according to jobs works properly. * Enchanced rewarding system: checks for stacking opportunities on the inventory before checking for new slots. +* Complete overhaul on the 3rd job quiz (explorers), with all 40-question pool now made available. Player Social Network: @@ -116,6 +117,7 @@ Admin/GM commands: External tools: * MapleArrowFetcher - Updates min/max quantity dropped on all arrows drop data, calculations based on mob level and whether it's a boss or not. +* MapleBossHpBarFetcher - Searches the quest WZ files and reports in all relevant data regarding mobs that has a boss HP bar whilst not having a proper "boss" label. * MapleCouponInstaller - Retrieves coupon info from the WZ and makes a SQL table with it. The server will use that table to gather info regarding rates and intervals. * MapleIdRetriever - Two behaviors: generates a SQL table with relation (id, name) of the handbook given as input. Given a file with names, outputs a file with ids. * MapleInvalidItemIdFetcher - Generates a file listing all inexistent itemid's currently laying on the DB. @@ -123,6 +125,7 @@ External tools: * MapleMesoFetcher - Creates meso drop data for mobs with more than 4 items (thus overworld mobs), calculations based on mob level and whether it's a boss or not. * MapleMobBookIndexer - Generates a SQL table with all relations of cardid and mobid present in the mob book. * MapleMobBookUpdate - Generates a wz.xml that is a copy of the original MonsterBook.wz.xml, except it updates the drop data info in the book with those currently on DB. +* MapleQuestItemCountFetcher - Searches the quest WZ files and reports in all relevant data regarding missing "count" labels on item acts at "complete quest". * MapleQuestItemFetcher - Searches the SQL tables and project files and reports in all relevant data regarding missing/erroneous quest items. * MapleQuestMesoFetcher - Searches the quest WZ files and reports in all relevant data regarding missing/erroneous quest fee checks. * MapleSkillMakerFetcher - Updates the DB Maker-related tables with the current info present on the WZs. diff --git a/docs/mychanges_ptbr.txt b/docs/mychanges_ptbr.txt index 2e7169a687..47aa8d5567 100644 --- a/docs/mychanges_ptbr.txt +++ b/docs/mychanges_ptbr.txt @@ -839,4 +839,13 @@ Corrigido tempo de duração do Body Pressure sendo resetado sempre que acerta u 26 - 27 Março 2018, Corrigido animação de spawn dos bosses do dojo que foi quebrada recentemente. Corrigido autoassigner para piratas somente preenchendo requisitos de gunslinger. -Mobs agora podem dropar mais de um equip de mesmo tipo, sistema utiliza quantidades min/max na tabela de drops. \ No newline at end of file +Mobs agora podem dropar mais de um equip de mesmo tipo, sistema utiliza quantidades min/max na tabela de drops. +Nova ferramenta: MapleQuestItemCountFetcher. Localiza no Quest.wz possíveis locais onde um item deveria estar sendo tirado ao completar determinada quest, mas não o é (caso comum onde campo "count" não existe). + +28 - 29 Março 2018, +Adicionado itens de pirata nas lojas de NPC em Singapore. +Adicionado drop data para Flaming Racoon e Big Cloud Fox. +Adicionado ganho de EXP em várias quests da região de Zipangu. +Adicionado sistema de bonus para expedição de Showa, atingível se nenhum jogador morrer no evento. +Nova ferramenta: MapleBossHpBarFetcher. Localiza no Mob.wz ids de mobs que possuem um boss hp bar mas não são labelados como "boss". +Incrementado quiz de 3rd job, agora utilizando um pool de 40 perguntas com escolha arbitrária. \ No newline at end of file diff --git a/scripts/event/ShowaBattle.js b/scripts/event/ShowaBattle.js index 1b34e13428..56b42bc91b 100644 --- a/scripts/event/ShowaBattle.js +++ b/scripts/event/ShowaBattle.js @@ -12,7 +12,7 @@ var recruitMap = 801040004; var clearMap = 801040101; var minMapId = 801040100; -var maxMapId = 801040100; +var maxMapId = 801040101; var eventTime = 60; // 60 minutes for boss stg @@ -68,6 +68,7 @@ function afterSetup(eim) {} function setup(channel) { var eim = em.newInstance("Showa" + channel); eim.setProperty("canJoin", 1); + eim.setProperty("playerDied", 0); var level = 1; eim.getInstanceMap(801040100).resetPQ(level); @@ -112,7 +113,9 @@ function changedMap(eim, player, mapid) { function changedLeader(eim, leader) {} -function playerDead(eim, player) {} +function playerDead(eim, player) { + eim.setIntProperty("playerDied", 1); +} function playerRevive(eim, player) { if (eim.isEventTeamLackingNow(true, minPlayers, player)) { @@ -170,6 +173,12 @@ function clearPQ(eim) { eim.stopEventTimer(); eim.setEventCleared(); + + if(eim.getIntProperty("playerDied") == 0) { + var mob = eim.getMonster(9400114); + eim.getMapInstance(801040101).spawnMonsterOnGroundBelow(mob, new java.awt.Point(500, -50)); + eim.dropMessage(5, "Konpei: The Boss has been defeated with no casualties, well done! We found a suspicious machine inside, we're moving it out."); + } } function isTheBoss(mob) { diff --git a/scripts/npc/1061010.js b/scripts/npc/1061010.js index 6d9bdefe9f..ba0685ada2 100644 --- a/scripts/npc/1061010.js +++ b/scripts/npc/1061010.js @@ -18,17 +18,19 @@ function action(mode, type, selection) { else status--; - if(status == 0){ - cm.sendYesNo("Would you like to leave?"); - }else if(status == 1){ - if(cm.getMapId() == 108010101)cm.getPlayer().changeMap(105040305); - if(cm.getMapId() == 108010201)cm.getPlayer().changeMap(100040106); - if(cm.getMapId() == 108010301)cm.getPlayer().changeMap(105070001); - if(cm.getMapId() == 108010401)cm.getPlayer().changeMap(107000402); - if(cm.getMapId() == 108010501)cm.getPlayer().changeMap(105040305); - var em = cm.getEventManager("3rdjob"); - em.getInstance(cm.getPlayer().getName()).unregisterPlayer(cm.getPlayer()); - cm.dispose(); - } + if(status == 0){ + cm.sendYesNo("Would you like to leave?"); + }else if(status == 1){ + var mapid = cm.getMapId(); + if(mapid == 108010101) cm.getPlayer().changeMap(105040305); + else if(mapid == 108010201) cm.getPlayer().changeMap(100040106); + else if(mapid == 108010301) cm.getPlayer().changeMap(105070001); + else if(mapid == 108010401) cm.getPlayer().changeMap(107000402); + else if(mapid == 108010501) cm.getPlayer().changeMap(105070200); + + var em = cm.getEventManager("3rdjob"); + em.getInstance(cm.getPlayer().getName()).unregisterPlayer(cm.getPlayer()); + cm.dispose(); + } } } \ No newline at end of file diff --git a/scripts/npc/2030006.js b/scripts/npc/2030006.js index 2b52ec0cc4..6b9e1792e4 100644 --- a/scripts/npc/2030006.js +++ b/scripts/npc/2030006.js @@ -1,8 +1,6 @@ /* - 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 HeavenMS (MapleSolaxiaV2) MapleStory Server + Copyleft (L) 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 @@ -19,44 +17,183 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -status = -1; -//Need more questions. -quest = ["Which of these NPC's will you NOT see at Ellinia of Victoria Island#b\r\n#L0#Shane\r\n#L1#Francois\r\n#L2#Grendel the Really Old\r\n#L3#Arwen the Fairy\r\n#L4#Roel", "Which of these monsters will you NOT be facing at Ossyria...?#b\r\n#L0#White Fang\r\n#L1#Croco\r\n#L2#Yeti\r\n#L3#Lycanthrope\r\n#L4#Luster Pixie", "Which of these monsters have the highest level...?#b\r\n#L0#Octopus\r\n#L1#Ribbon Pig\r\n#L2#Green Mushroom\r\n#L3#Axe Stump\r\n#L4#Bubbling", "In MapleStory, which of these pairings of potion/results doesn't match...?#b\r\n#L0#Holy Water - Recover from the state of being cursed or sealed up.\r\n#L1#Sunrise Dew - Recover MP 3000\r\n#L2#Hamburger - Recover HP 400\r\n#L3#Salad - Recover MP 200\r\n#L4#Blue Potion - Recover MP 100", "Which of these NPC's have NOTHING to do with pets...?#b\r\n#L0#Cloy\r\n#L1#Mar the Fairy\r\n#L2#Trainer Frod\r\n#L3#Vicious\r\n#L4#Doofus"]; -ans = [4, 1, 3, 1, 3]; -rand = parseInt(Math.random() * quest.length); +/* Holy Stone + Holy Ground at the Snowfield (211040401) + 3rd job advancement - Question trial. + */ + +var questionTree = [ + //Questions Related to CHARACTERS + ["In MapleStory, what is the EXP needed to level up from Lv1 to Lv2?", ["20", "15", "4", "12", "16"], 1], + ["In 1st job adv. which of the following is WRONG requirement?", ["Magician - Level 8", "Pirate - 20 DEX or more", "Archer - 25 DEX or more", "Thief - 20 LUK or more", "Swordman - 35 STR or more"], 3], + ["When you hit by monster, which of the following is not fully explained?", ["Sealed - skills become disabled", "Undead - turns undead & halved recovery amounts", "Weaken - slow down moving speed", "Cursed - EXP received are decreased", "Stunned - cannot move"], 2], + ["For the 1st job adv. Which job fully states the job adv. requirement?", ["Pirate - 25 LUK", "Magician - Level 10", "Thief - 25 LUK", "Warrior - 30 STR", "Bowman - 25 DEX"], 4], + + //Questions Related to ITEMS + ["Which of following monsters got CORRECT item corresponding to the monster?", ["Royal cactus - Needle", "Wild Boar - Boar fang", "Lazy Buffy - Buffy hat", "Chipmunk - Nut", "Stirge - Stirge's wing"], 4], + ["Which of following monsters got WRONG item corresponding to the monster?", ["Greatest Oldies - Greatest oldies", "Nependeath - Nependeath's leaf", "Ghost stump - Seedling", "Sparker - Seal tooth", "Miner Zombie - Zombie's lost tooth"], 1], + ["In GM Event, how many FRUIT CAKE you can get as reward?", ["20", "200", "5", "25", "100"], 2], + ["Which of following potions got CORRECT info.?", ["Warrior Elixir - Attack +5 for 3 minutes", "Pure Water - Recover 700 MP", "Cake - Recover 150 HP & MP", "Salad - Recover 300 MP", "Pizza - Recover 400 HP"], 4], + ["Which of following potions got WRONG info.?", ["Mana Elixir - Recover 300 MP", "Tonic - Cures state of weakness", "Apple - Recover 30 HP", "Sunrise Dew - Recover 3000 MP", "Ramen - Recover 1000 HP"], 3], + + //Questions Related to MONSTERS + ["Green Mushroom, Tree Stump, Bubbling, Axe Stump, Octopus, which is highest level of all?", ["Tree Stump", "Bubbling", "Axe Stump", "Octopus", "Green Mushroom"], 2], + ["Which monster will be seen during the ship trip to Orbis/Ellinia?", ["Werewolf", "Slime", "Crimson Balrog", "Zakum", "Star Pixie"], 2], + ["Maple Island doesn't have which following monsters?", ["Shroom", "Blue Snail", "Orange Mushroom", "Red Snail", "Pig"], 4], + ["Which monster is not at Victoria Island and Sleepywood?", ["Evil Eye", "Sentinel", "Jr. Balrog", "Ghost Stump", "Snail"], 1], + ["El Nath doesn't have which following monsters?", ["Dark Yeti", "Dark Ligator", "Yeti & Pepe", "Bain", "Coolie Zombie"], 1], + ["Which of following monsters can fly?", ["Malady", "Ligator", "Cold Eye", "Meerkat", "Alishar"], 0], + ["Which of these monsters will you NOT be facing in Ossyria?", ["Lunar Pixie", "Lioner", "Cellion", "Croco", "Hector"], 3], + ["Which monster has not appeared in Maple Island?", ["Snail", "Shroom", "Evil Eye", "Orange Mushroom", "Blue Snail"], 2], + + //Questions Related to QUESTS + ["Which material doesn't need for awaken Hero's Gladius?", ["Flaming Feather", "Old Gladius", "Piece of Ice", "Ancient Scroll", "Fairy Wing"], 4], + ["Which of following quests can be repeated?", ["Mystery of Niora Hospital", "Rightful Donation Culture", "The Ghost Whereabout", "Arwen and the Glass Shoe", "Maya and the Weird Medicine"], 3], + ["Which of following are not 2nd job adv.?", ["Mage", "Cleric", "Assassin", "Gunslinger", "Fighter"], 0], + ["Which of following is the highest level quest?", ["Cupid's Courier", "Lost in the Ocean", "Alcaster and the Dark Crystal", "Eliminating the Drumming Bunny", "War of Pang Pang"], 2], + + //Questions Related to TOWN/NPC + ["Which town is not at Victoria Island?", ["Florina Beach or Nautilus", "Amherst or Southperry", "Kerning City & Square", "Perion or Ellinia", "Sleepywood"], 1], + ["Which is the first NPC you meet in Maple Island?", ["Sera", "Heena", "Lucas", "Roger", "Shanks"], 1], + ["Which NPC cannot be seen in El Nath?", ["Vogen", "Sophia", "Pedro", "Master Sergeant Fox", "Rumi"], 1], + ["Which NPC cannot be seen in El Nath snowfield?", ["Hidden Rock", "Glibber", "Jeff", "Holy Stone", "Elma the Housekeeper"], 4], + ["Which NPC cannot be seen in Perion?", ["Ayan", "Sophia", "Mr. Smith", "Francois", "Manji"], 3], + ["Which NPC cannot be seen in Henesys?", ["Teo", "Vicious", "Mia", "Doofus", "Casey"], 0], + ["Which NPC cannot be seen in Ellinia?", ["Mr. Park", "Mar the Fairy", "Roel", "Ria", "Shane"], 2], + ["Which NPC cannot be seen in Kerning City?", ["Dr. Faymus", "Mong from Kong", "Ervine", "Luke", "Nella"], 3], + ["Which NPC is not related to pets?", ["Doofus", "Vicious", "Patricia", "Weaver", "Cloy"], 1], + ["In Kerning City, who is the father of Alex, the runaway kid?", ["Chief Stan", "JM From tha Streetz", "Dr. Faymus", "Vicious", "Luke"], 0], + ["Which NPC is not belong to Alpha Platoon's Network of Communication?", ["Staff Sergeant Charlie", "Sergeant Bravo", "Corporal Easy", "Master Sergeant Fox", "Peter"], 4], + ["What do you receive in return from giving 30 Dark Marbles to the 2nd job advancement NPC?", ["Old Ring", "Memory Powder", "Fairy Dust", "Proof of Hero", "Scroll of Secrets"], 3], + ["Which item you give Maya at Henesys in order to cure her sickness?", ["Apple", "Power Elixir", "Weird Medicine", "Chrysanthemum", "Orange Juice"], 2], + ["Which of following NPC is not related to item synthesis/refine?", ["Neve", "Serryl", "Shane", "Francois", "JM From tha Streetz"], 2], + ["Which NPC cannot be seen in Maple Island?", ["Bari", "Teo", "Pio", "Sid", "Maria"], 1], + ["Who do you see in the monitor in the navigation room with Kyrin?", ["Lucas", "Dr. Kim", "Chief Stan", "Scadur", "Professor Foxwit"], 1], + ["You know Athena Pierce in Henesys? What color are her eyes?", ["Blue", "Green", "Brown", "Red", "Black"], 1], + ["How many feathers are there on Dances with Barlog's Hat?", ["7", "8", "3", "13", "16"], 3], + ["What's the color of the marble Grendel the Really Old from Ellinia carries with him?", ["White", "Orange", "Blue", "Purple", "Green"], 2] + ]; + +var status; +var question; + +var unusedQuestions; +var unusedQuestionsCursor; function start() { - if (cm.getPlayer().gotPartyQuestItem("JBQ") && !cm.haveItem(4031058)) - if (cm.haveItem(4005004)) { - cm.sendNext("Alright... I'll be testing out your wisdom here. Answer all the questions correctly, and you will pass the test BUT, if you even lie to me once, then you'll have to start over again ok, here we go."); - return; - } else - cm.sendNext("Bring me a #b#t4005004##k to proceed with the questions."); - cm.dispose(); + status = -1; + action(1, 0, 0); } function action(mode, type, selection) { - status++; - if (mode != 1) { + if (mode == -1) { cm.dispose(); - return; - } - if (status == 0) - cm.gainItem(4005004, -1); - if (status > 0) - if (selection != ans[rand]) { - cm.sendNext("You have failed the question."); + } else { + if (mode == 0 && type > 0) { cm.dispose(); return; } - while (quest[rand].equals("") && status <= 4) - rand = parseInt(Math.random() * quest.length); - if (status <= 4) { - cm.sendSimple("Here's the " + (status + 1) + (status == 0 ? "st" : status == 1 ? "nd" : status == 2 ? "rd" : "th") + " question. " + quest[rand]); - quest[rand] = ""; - } else { - cm.sendOk("Alright. All your answers have been proven as the truth. Your wisdom has been proven.\r\nTake this necklace and go back."); - cm.gainItem(4031058, 1); - cm.dispose(); + if (mode == 1) + status++; + else + status--; + + if(status == 0) { + if(cm.getPlayer().gotPartyQuestItem("JBQ") && !cm.haveItem(4031058, 1)) { + if(cm.haveItem(4005004, 1)) { + if(!cm.canHold(4031058)) { + cm.sendNext("Have a free ETC slot available before accepting this trial."); + cm.dispose(); + } else { + instantiateUnusedQuestions(); + + cm.sendNext("Alright... I'll be testing out your wisdom here. Answer all the questions correctly, and you will pass the test BUT, if you even lie to me once, then you'll have to start over again ok, here we go."); + } + } else { + cm.sendNext("Bring me a #b#t4005004##k to proceed with the trial."); + cm.dispose(); + } + } else { + cm.dispose(); + } + } else if(status == 1) { + cm.gainItem(4005004, -1); + + question = fetchNextQuestion(); + var questionHead = generateQuestionHeading(); + var questionEntry = questionTree[question][0]; + var questionOptions = generateSelectionMenu(questionTree[question][1]); + + cm.sendSimple(questionHead + questionEntry + "\r\n\r\n#b" + questionOptions + "#k"); + } else if(status >= 2 && status <= 5) { + if(!evaluateAnswer(selection)) { + cm.sendNext("You have failed the question."); + cm.dispose(); + return; + } + + question = fetchNextQuestion(); + var questionHead = generateQuestionHeading(); + var questionEntry = questionTree[question][0]; + var questionOptions = generateSelectionMenu(questionTree[question][1]); + + cm.sendSimple(questionHead + questionEntry + "\r\n\r\n#b" + questionOptions + "#k"); + } else if(status == 6) { + if(!evaluateAnswer(selection)) { + cm.sendNext("You have failed the question."); + cm.dispose(); + return; + } + + cm.sendOk("Alright. All your answers have been proven as the truth. Your wisdom has been proven.\r\nTake this necklace and go back."); + cm.gainItem(4031058, 1); + cm.dispose(); + } else { + cm.sendOk("Unexpected branch."); + cm.dispose(); + } } +} + +function evaluateAnswer(selection) { + return selection == questionTree[question][2]; +} + +function generateQuestionHeading() { + return "Here's the " + (status) + (status == 1 ? "st" : status == 2 ? "nd" : status == 3 ? "rd" : "th") + " question. "; +} + +function shuffleArray(array) { + for (var i = array.length - 1; i > 0; i--) { + var j = Math.floor(Math.random() * (i + 1)); + var temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } +} + +function instantiateUnusedQuestions() { + unusedQuestions = []; + + for(var i = 0; i < questionTree.length; i++) { + unusedQuestions.push(i); + } + + shuffleArray(unusedQuestions); + unusedQuestionsCursor = 0; +} + +function fetchNextQuestion() { + var next = unusedQuestions[unusedQuestionsCursor]; + unusedQuestionsCursor++; + + return next; +} + +function generateSelectionMenu(array) { // nice tool for generating a string for the sendSimple functionality + var menu = ""; + for (var i = 0; i < array.length; i++) { + menu += "#L" + i + "#" + array[i] + "#l\r\n"; + } + return menu; } \ No newline at end of file diff --git a/scripts/npc/2030006_old.js b/scripts/npc/2030006_old.js new file mode 100644 index 0000000000..fb496c3847 --- /dev/null +++ b/scripts/npc/2030006_old.js @@ -0,0 +1,66 @@ +/* + 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 . +*/ +status = -1; +//Need more questions. +quest = ["Which of these NPC's will you NOT see at Ellinia of Victoria Island#b\r\n#L0#Shane\r\n#L1#Francois\r\n#L2#Grendel the Really Old\r\n#L3#Arwen the Fairy\r\n#L4#Roel", "Which of these monsters will you NOT be facing at Ossyria...?#b\r\n#L0#White Fang\r\n#L1#Croco\r\n#L2#Yeti\r\n#L3#Lycanthrope\r\n#L4#Luster Pixie", "Which of these monsters have the highest level...?#b\r\n#L0#Octopus\r\n#L1#Ribbon Pig\r\n#L2#Green Mushroom\r\n#L3#Axe Stump\r\n#L4#Bubbling", "In MapleStory, which of these pairings of potion/results doesn't match...?#b\r\n#L0#Holy Water - Recover from the state of being cursed or sealed up.\r\n#L1#Sunrise Dew - Recover MP 3000\r\n#L2#Hamburger - Recover HP 400\r\n#L3#Salad - Recover MP 200\r\n#L4#Blue Potion - Recover MP 100", "Which of these NPC's have NOTHING to do with pets...?#b\r\n#L0#Cloy\r\n#L1#Mar the Fairy\r\n#L2#Trainer Frod\r\n#L3#Vicious\r\n#L4#Doofus"]; +ans = [4, 1, 3, 1, 3]; +rand = parseInt(Math.random() * quest.length); + +function start() { + if (cm.getPlayer().gotPartyQuestItem("JBQ") && !cm.haveItem(4031058)) + if (cm.haveItem(4005004)) { + if(!cm.canHold(4031058)) { + cm.sendNext("Have a free ETC slot available before accepting this trial."); + } else { + cm.sendNext("Alright... I'll be testing out your wisdom here. Answer all the questions correctly, and you will pass the test BUT, if you even lie to me once, then you'll have to start over again ok, here we go."); + return; + } + } else + cm.sendNext("Bring me a #b#t4005004##k to proceed with the questions."); + cm.dispose(); +} + +function action(mode, type, selection) { + status++; + if (mode != 1) { + cm.dispose(); + return; + } + if (status == 0) + cm.gainItem(4005004, -1); + if (status > 0) + if (selection != ans[rand]) { + cm.sendNext("You have failed the question."); + cm.dispose(); + return; + } + while (quest[rand].equals("") && status <= 4) + rand = parseInt(Math.random() * quest.length); + if (status <= 4) { + cm.sendSimple("Here's the " + (status + 1) + (status == 0 ? "st" : status == 1 ? "nd" : status == 2 ? "rd" : "th") + " question. " + quest[rand]); + quest[rand] = ""; + } else { + cm.sendOk("Alright. All your answers have been proven as the truth. Your wisdom has been proven.\r\nTake this necklace and go back."); + cm.gainItem(4031058, 1); + cm.dispose(); + } +} \ No newline at end of file diff --git a/scripts/npc/9120010.js b/scripts/npc/9120010.js index c34d7752a9..836d4b3524 100644 --- a/scripts/npc/9120010.js +++ b/scripts/npc/9120010.js @@ -22,17 +22,17 @@ var status = 0; var eQuestChoices = new Array (4000064,4000065,4000066,4000075,4000077,4000089,4000090,4000091,4000092,4000093,4000094); var eQuestPrizes = new Array(); -eQuestPrizes[0] = new Array ([2000000,1],[2000006,1],[2000003,5],[2000002,5],[4020006,2],[4020000,2],[4020004,2],[2000003,10],[2000003,20],[2000002,10],[2000002,20],[2022026,15],[2022024,15],[1002393,1]); // Pink Bandana -eQuestPrizes[1] = new Array ([2000006,1],[2000002,5],[4020006,2],[2000002,10],[2000003,10],[2000002,20],[2000003,20],[2022024,15],[2022026,15]); // Yakisoba -eQuestPrizes[2] = new Array ([2000006,1],[2000002,5],[2000003,5],[4020000,2],[2000003,10],[2000002,10],[2000003,20],[2000002,20],[2022024,15],[1002393,1]); // Pink Bandana -eQuestPrizes[3] = new Array ([2060003,1000],[4010004,2],[4010006,2],[2022022,5],[2022022,10],[2022022,15],[2022019,5],[2022019,10],[2022019,15],[2001002,15],[2001001,15],[1102040,1],[1102043,1]); // Brown Adventurer Cape -eQuestPrizes[4] = new Array ([2000003,1],[2022019,5],[2000006,5],[4010002,2],[4010003,2],[2000006,10],[2000006,15],[2022019,10],[2022019,15],[2060003,1000],[2061003,1000],[1082150,1],[1082149,1]); // Brown Work Gloves -eQuestPrizes[5] = new Array ([2000006,1],[2000003,5],[2000002,5],[2000003,10],[2000003,20],[2000002,10],[2000002,15],[2060003,1000],[2061003,1000], [2022026,15],[1002395,1]); -eQuestPrizes[6] = new Array ([2022019,5],[2000006,5],[4010003,2],[2022019,10],[2022019,15],[2000006,10],[2000006,15],[2060003,1000],[2061003,1000]); // Blue Arrow for Crossbow -eQuestPrizes[7] = new Array ([2000003,1], [2000006,1],[2022019,1],[2000006,5],[4010002,2],[4020001,2],[2022019,10],[2022019,15],[2000006,10],[2000006,15],[2060003,1000],[2061003,1000]); -eQuestPrizes[8] = new Array ([2022019,5],[2022022,5],[4010006,2],[2022019,10],[2022019,15],[2022022,10],[2022022,15],[2001002,15],[2001001,15],[1102043,1]); // Brown Adventurer Cape -eQuestPrizes[9] = new Array ([4010004,5],[2022019,5],[2022022,15],[2022019,15],[2001002,15],[2001001,15],[1102043,1]); // Brown Adventurer Cape -eQuestPrizes[10] = new Array([2000006,1],[4020008,15],[2022018,5],[2022018,10],[2022018,15],[2022000,10],[2022000,20],[2022025,15]); // Takoyaki (Jumbo) +eQuestPrizes[0] = new Array ([2000000,1],[2000006,1],[2000003,5],[2000002,5],[4020006,2],[4020000,2],[4020004,2],[2000003,10],[2000003,20],[2000002,10],[2000002,20],[2022026,15],[2022024,15],[1002393,1]); // Crow feather +eQuestPrizes[1] = new Array ([2000006,1],[2000002,5],[4020006,2],[2000002,10],[2000003,10],[2000002,20],[2000003,20],[2022024,15],[2022026,15]); // Raccoon firewood +eQuestPrizes[2] = new Array ([2000006,1],[2000002,5],[2000003,5],[4020000,2],[2000003,10],[2000002,10],[2000003,20],[2000002,20],[2022024,15],[1002393,1]); // Cloud foxtail +eQuestPrizes[3] = new Array ([2060003,1000],[4010004,2],[4010006,2],[2022022,5],[2022022,10],[2022022,15],[2022019,5],[2022019,10],[2022019,15],[2001002,15],[2001001,15],[1102040,1],[1102043,1]); // Tringular bandana of the nightghost +eQuestPrizes[4] = new Array ([2000003,1],[2022019,5],[2000006,5],[4010002,2],[4010003,2],[2000006,10],[2000006,15],[2022019,10],[2022019,15],[2060003,1000],[2061003,1000],[1082150,1],[1082149,1]); // Dark cloud foxtail +eQuestPrizes[5] = new Array ([2000006,1],[2000003,5],[2000002,5],[2000003,10],[2000003,20],[2000002,10],[2000002,15],[2060003,1000],[2061003,1000],[2022026,15],[1002395,1]); // Littleman A's badge +eQuestPrizes[6] = new Array ([2022019,5],[2000006,5],[4010003,2],[2022019,10],[2022019,15],[2000006,10],[2000006,15],[2060003,1000],[2061003,1000]); // Littleman B's name plate +eQuestPrizes[7] = new Array ([2000003,1], [2000006,1],[2022019,1],[2000006,5],[4010002,2],[4020001,2],[2022019,10],[2022019,15],[2000006,10],[2000006,15],[2060003,1000],[2061003,1000]); // Littleman C's necklace +eQuestPrizes[8] = new Array ([2022019,5],[2022022,5],[4010006,2],[2022019,10],[2022019,15],[2022022,10],[2022022,15],[2001002,15],[2001001,15],[1102043,1]); // Leader A's shades +eQuestPrizes[9] = new Array ([4010004,5],[2022019,5],[2022022,15],[2022019,15],[2001002,15],[2001001,15],[1102043,1]); // Leader B's charm +eQuestPrizes[10] = new Array([1102207,1],[1442026,1],[1302037,1],[2070007,1],[2340000,1],[2330005,1],[2022060,25],[2022061,20],[2022062,15]); // Boss pomade var requiredItem = 0; var lastSelection = 0; var prizeItem = 0; @@ -73,10 +73,10 @@ function action(mode, type, selection) { prizeQuantity = reward[itemSet][1]; if (!cm.canHold(prizeItem)){ cm.sendNext("I can't give you the reward if your equip, use, or etc. inventory is full. Please go take a look right now."); - } else if (hasItem(requiredItem, 100)){ // check they have >= 100 in Inventory + } else if (cm.hasItem(requiredItem, 100)){ // check they have >= 100 in Inventory cm.gainItem(requiredItem,-100); cm.gainItem(prizeItem,prizeQuantity); - cm.sendOk("Hmmm ... if not for this minor scratch ... sigh. I'm afaird I can only deem this a standard-quality item. Well, here's \r\n#t"+ prizeItem +"# for you."); + cm.sendOk("Hmmm ... if not for this minor scratch ... sigh. I'm afraid I can only deem this a standard-quality item. Well, here's \r\n#t"+ prizeItem +"# for you."); } else{ cm.sendOk("Hey, what do you think you're doing? Go lie to someone that DOESN'T know what he's talking about. Not me!"); } diff --git a/sql/db_database.sql b/sql/db_database.sql index 11e0ebe93c..ddfc68660b 100644 --- a/sql/db_database.sql +++ b/sql/db_database.sql @@ -11431,7 +11431,7 @@ INSERT IGNORE INTO `temp_data` (`id`, `dropperid`, `itemid`, `minimum_quantity`, (11209, 9001001, 4031059, 1, 1, 0, 999999), (11210, 9001002, 4031059, 1, 1, 0, 999999), (11211, 9001003, 4031059, 1, 1, 0, 999999), -(11212, 9001008, 4031059, 1, 1, 0, 499999), +(11212, 9001004, 4031059, 1, 1, 0, 999999), (11213, 9001005, 4031857, 1, 1, 0, 300000), (11214, 9001012, 4032311, 1, 1, 0, 300000), (11215, 9001012, 4032311, 1, 1, 0, 300000), @@ -20045,7 +20045,7 @@ INSERT INTO `shopitems` (`shopitemid`, `shopid`, `itemid`, `price`, `pitch`, `po (2657, 9120002, 2001001, 2300, 0, 132), (2658, 9120002, 2000002, 320, 0, 136), (2659, 9120002, 2000001, 160, 0, 140), -(2660, 9120002, 2060003, 40, 0, 144), +(2660, 9120002, 2060003, 40, 0, 100), (2661, 9120004, 2070000, 500, 0, 104), (2662, 9120004, 2030010, 500, 0, 108), (2663, 9120004, 2030009, 500, 0, 112), @@ -21323,7 +21323,7 @@ INSERT INTO `shopitems` ( `shopid`, `itemid`, `price`, `position`) VALUES (1052116, 2000002, 320, 212), (1052116, 2000001, 160, 216), (1052116, 2000000, 50, 220), -(9120002, 2061003, 40, 100), +(9120002, 2061003, 40, 96), (2030009, 2022001, 700, 100), (1337, 1912005, 1, 35), (1337, 1902005, 1, 36), diff --git a/sql/db_drops.sql b/sql/db_drops.sql index 0812abb511..27e0fadcca 100644 --- a/sql/db_drops.sql +++ b/sql/db_drops.sql @@ -19771,28 +19771,27 @@ USE `heavenms`; (9300347, 4001272, 1, 1, 0, 400000), (9300347, 4032324, 1, 1, 21736, 40000), (9300344, 4032322, 1, 1, 21731, 999999), -(3400008, 1302008, 1, 1, 0, 8500), -(3400008, 1412004, 1, 1, 0, 8500), -(3400008, 1422007, 1, 1, 0, 8500), -(3400008, 1442009, 1, 1, 0, 8500), -(3400008, 1332010, 1, 1, 0, 8500), -(3400008, 1372001, 1, 1, 0, 8500), -(3400008, 1382002, 1, 1, 0, 8500), -(3400008, 1002013, 1, 1, 0, 8500), -(3400008, 1002152, 1, 1, 0, 8500), -(3400008, 1061047, 1, 1, 0, 8500), -(3400008, 1072090, 1, 1, 0, 8500), -(3400008, 1002137, 1, 1, 0, 8500), -(3400008, 1040023, 1, 1, 0, 8500), -(3400008, 1040072, 1, 1, 0, 8500), -(3400008, 1060062, 1, 1, 0, 8500), -(3400008, 1082049, 1, 1, 0, 8500), -(3400008, 1082072, 1, 1, 0, 8500), -(3400008, 1072081, 1, 1, 0, 8500), -(3400008, 1332031, 1, 1, 0, 8500), -(3400008, 1482003, 1, 1, 0, 8500), +(3400008, 1302008, 1, 1, 0, 4200), +(3400008, 1412004, 1, 1, 0, 4200), +(3400008, 1422007, 1, 1, 0, 4200), +(3400008, 1442009, 1, 1, 0, 4200), +(3400008, 1332010, 1, 1, 0, 4200), +(3400008, 1372001, 1, 1, 0, 4200), +(3400008, 1382002, 1, 1, 0, 4200), +(3400008, 1002013, 1, 1, 0, 4200), +(3400008, 1002152, 1, 1, 0, 4200), +(3400008, 1061047, 1, 1, 0, 4200), +(3400008, 1072090, 1, 1, 0, 4200), +(3400008, 1002137, 1, 1, 0, 4200), +(3400008, 1040023, 1, 1, 0, 4200), +(3400008, 1040072, 1, 1, 0, 4200), +(3400008, 1060062, 1, 1, 0, 4200), +(3400008, 1082049, 1, 1, 0, 4200), +(3400008, 1082072, 1, 1, 0, 4200), +(3400008, 1072081, 1, 1, 0, 4200), +(3400008, 1332031, 1, 1, 0, 4200), +(3400008, 1482003, 1, 1, 0, 4200), (3400008, 4032508, 1, 1, 2273, 80000), - (8140101, 4032511, 1, 1, 3718, 60000), (8140102, 4032511, 1, 1, 3718, 60000), (8140103, 4032511, 1, 1, 3718, 60000), @@ -20101,7 +20100,90 @@ USE `heavenms`; (9400748, 1002858, 1, 1, 0, 40000), (9400748, 1002859, 1, 1, 0, 40000), (9400748, 1002860, 1, 1, 0, 40000), -(9400748, 1002861, 1, 1, 0, 80000); +(9400748, 1002861, 1, 1, 0, 80000), +(9400001, 0, 56, 84, 0, 400000), +(9400001, 4000065, 1, 1, 0, 400000), +(9400001, 4130013, 1, 1, 0, 7000), +(9400001, 4130002, 1, 1, 0, 7000), +(9400001, 4130001, 1, 1, 0, 7000), +(9400001, 1332020, 1, 1, 0, 800), +(9400001, 1032004, 1, 1, 0, 1000), +(9400001, 1442021, 1, 1, 0, 700), +(9400001, 1432016, 1, 1, 0, 700), +(9400001, 1322015, 1, 1, 0, 800), +(9400001, 1322010, 1, 1, 0, 800), +(9400001, 1322011, 1, 1, 0, 800), +(9400001, 1072076, 1, 1, 0, 800), +(9400001, 1072077, 1, 1, 0, 800), +(9400001, 1041067, 1, 1, 0, 800), +(9400001, 1041068, 1, 1, 0, 800), +(9400001, 1060063, 1, 1, 0, 800), +(9400001, 1060064, 1, 1, 0, 800), +(9400001, 1051008, 1, 1, 0, 800), +(9400001, 4010006, 1, 1, 0, 7000), +(9400001, 4020004, 1, 1, 0, 9000), +(9400001, 2022020, 1, 1, 0, 32000), +(9400001, 2022023, 1, 1, 0, 32000), +(9400001, 2022024, 1, 1, 0, 32000), +(9400001, 2040404, 1, 1, 0, 1000), +(9400001, 2044205, 1, 1, 0, 1000), +(9400004, 1302025, 1, 1, 0, 800), +(9400004, 1032011, 1, 1, 0, 800), +(9400004, 1402014, 1, 1, 0, 800), +(9400004, 1060077, 1, 1, 0, 800), +(9400004, 1382001, 1, 1, 0, 800), +(9400004, 1061080, 1, 1, 0, 800), +(9400004, 1061079, 1, 1, 0, 800), +(9400004, 0, 148, 222, 0, 400000), +(9400004, 4000077, 1, 1, 0, 400000), +(9400004, 4130008, 1, 1, 0, 7000), +(9400004, 4130009, 1, 1, 0, 7000), +(9400004, 4130010, 1, 1, 0, 7000), +(9400004, 4010002, 1, 1, 0, 7000), +(9400004, 4020002, 1, 1, 0, 7000), +(9400004, 4020007, 1, 1, 0, 9000), +(9400004, 4004004, 1, 1, 0, 9000), +(9400004, 2022019, 1, 1, 0, 32000), +(9400004, 2022022, 1, 1, 0, 32000), +(9400004, 2022026, 1, 1, 0, 32000), +(9400004, 2070004, 1, 1, 0, 400), +(9400004, 2040510, 1, 1, 0, 1000), +(9400004, 2043305, 1, 1, 0, 1000), +(9400114, 1122001, 5, 5, 0, 20000), +(9400114, 1122002, 1, 2, 0, 20000), +(9400114, 1122003, 5, 5, 0, 20000), +(9400114, 1122004, 2, 3, 0, 20000), +(9400114, 1122005, 1, 2, 0, 20000), +(9400114, 1122006, 2, 3, 0, 20000), +(9400114, 1012181, 3, 4, 0, 20000), +(9400114, 1012182, 2, 2, 0, 20000), +(9400114, 1012183, 1, 2, 0, 20000), +(9400114, 1112407, 3, 4, 0, 20000), +(9400114, 1112408, 3, 4, 0, 20000), +(9400114, 1132005, 3, 4, 0, 20000), +(9400114, 1132006, 2, 3, 0, 20000), +(9400114, 1132007, 2, 2, 0, 20000), +(9400114, 1132008, 2, 2, 0, 20000), +(9400114, 1132009, 1, 1, 0, 20000), +(9400114, 1102084, 2, 2, 0, 20000), +(9400114, 1102085, 2, 2, 0, 20000), +(9400114, 1102086, 2, 2, 0, 20000), +(9400114, 1102087, 2, 2, 0, 20000), +(9400114, 1402013, 1, 1, 0, 50000), +(9400114, 1332030, 1, 1, 0, 50000), +(9400114, 1032030, 1, 1, 0, 40000), +(9400114, 1032070, 1, 1, 0, 40000), +(9400114, 4005000, 1, 1, 0, 70000), +(9400114, 4005001, 1, 1, 0, 70000), +(9400114, 4005002, 1, 1, 0, 70000), +(9400114, 4005003, 1, 1, 0, 70000), +(9400114, 4005004, 1, 1, 0, 70000), +(9400114, 2022015, 10, 30, 0, 200000), +(9400114, 2022016, 10, 30, 0, 200000), +(9400114, 2022063, 10, 30, 0, 200000), +(9400114, 2022064, 10, 30, 0, 200000), +(9400120, 4000094, 1, 1, 0, 400000), +(9400122, 4000094, 1, 1, 0, 400000); # (dropperid, itemid, minqty, maxqty, questid, chance) diff --git a/sql/db_shopupdate.sql b/sql/db_shopupdate.sql index 22de23d3ef..3cd5ad5b74 100644 --- a/sql/db_shopupdate.sql +++ b/sql/db_shopupdate.sql @@ -166,7 +166,7 @@ INSERT IGNORE INTO `shopitems` (`shopid`, `itemid`, `price`, `pitch`, `position` (9270022, 2030100, 450, 0, 118); # Thanks to Vcoc -# GMShop: Sacks, GmEquip, Cheese & Onix, Utils, +# GMShop: Sacks, GmEquip, Cheese & Onyx, Utils, # Arrows, Bullets, Throwings and Capsules, # Others, Equips, Mounts, Scrolls. @@ -335,4 +335,16 @@ INSERT INTO `shopitems` ( `shopid`, `itemid`, `price`, `pitch`, `position`) VALU (1301000, 2000003, 200, 0, 160), (1301000, 2000002, 320, 0, 164), (1301000, 2000015, 160, 0, 168), - (1301000, 2000000, 50, 0, 172); \ No newline at end of file + (1301000, 2000000, 50, 0, 172); + +# adding missing pirate items at Singapore npc's +INSERT INTO `shopitems` ( `shopid`, `itemid`, `price`, `pitch`, `position`) VALUES + (9270019, 1492006, 160000, 0, 80), + (9270019, 1492005, 100000, 0, 84), + (9270019, 1492004, 75000, 0, 88), + (9270019, 1482006, 150000, 0, 92), + (9270019, 1482005, 100000, 0, 96), + (9270019, 1482004, 75000, 0, 100), + (9270020, 1052113, 120000, 0, 92), + (9270020, 1052110, 100000, 0, 96), + (9270020, 1002625, 75000, 0, 100); \ No newline at end of file diff --git a/src/client/command/Commands.java b/src/client/command/Commands.java index e9257c8562..8e2fa5b4bd 100644 --- a/src/client/command/Commands.java +++ b/src/client/command/Commands.java @@ -923,6 +923,7 @@ public class Commands { case "cleardrops": player.getMap().clearDrops(player); + player.dropMessage(5, "Cleared dropped items"); break; case "clearslot": diff --git a/src/net/server/channel/handlers/MonsterBombHandler.java b/src/net/server/channel/handlers/MonsterBombHandler.java index 5cfbf079ff..56568d1f9d 100644 --- a/src/net/server/channel/handlers/MonsterBombHandler.java +++ b/src/net/server/channel/handlers/MonsterBombHandler.java @@ -28,6 +28,7 @@ import tools.MaplePacketCreator; import tools.data.input.SeekableLittleEndianAccessor; public final class MonsterBombHandler extends AbstractMaplePacketHandler { + @Override public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { int oid = slea.readInt(); MapleMonster monster = c.getPlayer().getMap().getMonsterByOid(oid); diff --git a/src/scripting/event/EventInstanceManager.java b/src/scripting/event/EventInstanceManager.java index d462fcb1f8..53eca1fc6e 100644 --- a/src/scripting/event/EventInstanceManager.java +++ b/src/scripting/event/EventInstanceManager.java @@ -271,10 +271,8 @@ public class EventInstanceManager { } public void dropMessage(int type, String message) { - if(!eventCleared) { - for (MapleCharacter chr : getPlayers()) { - chr.dropMessage(type, message); - } + for (MapleCharacter chr : getPlayers()) { + chr.dropMessage(type, message); } } diff --git a/src/scripting/event/EventManager.java b/src/scripting/event/EventManager.java index 8e99546b5a..cd7a4be21d 100644 --- a/src/scripting/event/EventManager.java +++ b/src/scripting/event/EventManager.java @@ -114,11 +114,11 @@ public class EventManager { try { return convertToIntegerArray((List)iv.invokeFunction("setLobbyRange", (Object) null)); } catch (ScriptException | NoSuchMethodException ex) { // they didn't define a lobby range - List defaultList = new ArrayList<>(); - defaultList.add(0); - defaultList.add(maxLobbys); + List defaultRange = new ArrayList<>(); + defaultRange.add(0); + defaultRange.add(maxLobbys); - return defaultList; + return defaultRange; } } @@ -502,13 +502,13 @@ public class EventManager { private static String ordinal(int i) { String[] sufixes = new String[] { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" }; switch (i % 100) { - case 11: - case 12: - case 13: - return i + "th"; - default: - return i + sufixes[i % 10]; - + case 11: + case 12: + case 13: + return i + "th"; + + default: + return i + sufixes[i % 10]; } } diff --git a/src/tools/MaplePacketCreator.java b/src/tools/MaplePacketCreator.java index fdd0f27497..397bf0dbc2 100644 --- a/src/tools/MaplePacketCreator.java +++ b/src/tools/MaplePacketCreator.java @@ -3364,13 +3364,31 @@ public class MaplePacketCreator { return mplew.getPacket(); } - public static byte[] customShowBossHP(byte call, int oid, int currHP, int maxHP, byte tagColor, byte tagBgColor) { + private static Pair normalizedCustomMaxHP(long currHP, long maxHP) { + int sendHP, sendMaxHP; + + if(maxHP <= Integer.MAX_VALUE) { + sendHP = (int) currHP; + sendMaxHP = (int) maxHP; + } else { + float f = ((float) currHP) / maxHP; + + sendHP = (int) (Integer.MAX_VALUE * f); + sendMaxHP = Integer.MAX_VALUE; + } + + return new Pair<>(sendHP, sendMaxHP); + } + + public static byte[] customShowBossHP(byte call, int oid, long currHP, long maxHP, byte tagColor, byte tagBgColor) { + Pair customHP = normalizedCustomMaxHP(currHP, maxHP); + final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendOpcode.FIELD_EFFECT.getValue()); mplew.write(call); mplew.writeInt(oid); - mplew.writeInt(currHP); - mplew.writeInt(maxHP); + mplew.writeInt(customHP.left); + mplew.writeInt(customHP.right); mplew.write(tagColor); mplew.write(tagBgColor); return mplew.getPacket(); diff --git a/tools/MapleBossHpBarFetcher/build.xml b/tools/MapleBossHpBarFetcher/build.xml new file mode 100644 index 0000000000..5d78857e06 --- /dev/null +++ b/tools/MapleBossHpBarFetcher/build.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + Builds, tests, and runs the project MapleBossHpBarFetcher. + + + diff --git a/tools/MapleBossHpBarFetcher/lib/Report.txt b/tools/MapleBossHpBarFetcher/lib/Report.txt new file mode 100644 index 0000000000..b2f432b4c2 --- /dev/null +++ b/tools/MapleBossHpBarFetcher/lib/Report.txt @@ -0,0 +1,14 @@ + # Report File autogenerated from the MapleBossHpBarFetcher feature by Ronan Lana. + # Generated data takes into account several data info from the server-side WZ.xmls. + +Missing 'isBoss' on id: 3300005 +Missing 'isBoss' on id: 3300006 +Missing 'isBoss' on id: 3300007 +Missing 'isBoss' on id: 8820010 +Missing 'isBoss' on id: 8820011 +Missing 'isBoss' on id: 8820012 +Missing 'isBoss' on id: 8820013 +Missing 'isBoss' on id: 8820014 +Missing 'isBoss' on id: 8830003 +Missing 'isBoss' on id: 8830010 +Missing 'isBoss' on id: 9001008 diff --git a/tools/MapleBossHpBarFetcher/lib/commons-io-2.6.jar b/tools/MapleBossHpBarFetcher/lib/commons-io-2.6.jar new file mode 100644 index 0000000000..00556b119d Binary files /dev/null and b/tools/MapleBossHpBarFetcher/lib/commons-io-2.6.jar differ diff --git a/tools/MapleBossHpBarFetcher/manifest.mf b/tools/MapleBossHpBarFetcher/manifest.mf new file mode 100644 index 0000000000..328e8e5bc3 --- /dev/null +++ b/tools/MapleBossHpBarFetcher/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/tools/MapleBossHpBarFetcher/nbproject/build-impl.xml b/tools/MapleBossHpBarFetcher/nbproject/build-impl.xml new file mode 100644 index 0000000000..88ce96307e --- /dev/null +++ b/tools/MapleBossHpBarFetcher/nbproject/build-impl.xml @@ -0,0 +1,1448 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set platform.home + Must set platform.bootcp + Must set platform.java + Must set platform.javac + + The J2SE Platform is not correctly set up. + Your active platform is: ${platform.active}, but the corresponding property "platforms.${platform.active}.home" is not found in the project's properties files. + Either open the project in the IDE and setup the Platform with the same name or add it manually. + For example like this: + ant -Duser.properties.file=<path_to_property_file> jar (where you put the property "platforms.${platform.active}.home" in a .properties file) + or ant -Dplatforms.${platform.active}.home=<path_to_JDK_home> jar (where no properties file is used) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + ${platform.java} -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/MapleBossHpBarFetcher/nbproject/genfiles.properties b/tools/MapleBossHpBarFetcher/nbproject/genfiles.properties new file mode 100644 index 0000000000..e875490d97 --- /dev/null +++ b/tools/MapleBossHpBarFetcher/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=55ba2920 +build.xml.script.CRC32=0d90f850 +build.xml.stylesheet.CRC32=8064a381@1.75.2.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=55ba2920 +nbproject/build-impl.xml.script.CRC32=bcc6d523 +nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.75.2.48 diff --git a/tools/MapleBossHpBarFetcher/nbproject/project.properties b/tools/MapleBossHpBarFetcher/nbproject/project.properties new file mode 100644 index 0000000000..bb3ea9e0d0 --- /dev/null +++ b/tools/MapleBossHpBarFetcher/nbproject/project.properties @@ -0,0 +1,79 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=MapleBossHpBarFetcher +application.vendor=USER +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# Os arquivos em build.classes.dir que devem ser exclu\u00eddos do jar de distribui\u00e7\u00e3o +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/MapleBossHpBarFetcher.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.commons-io-2.6.jar=lib/commons-io-2.6.jar +file.reference.mysql-connector-java-bin.jar=../../cores/mysql-connector-java-bin.jar +includes=** +jar.compress=false +javac.classpath=\ + ${file.reference.mysql-connector-java-bin.jar}:\ + ${file.reference.commons-io-2.6.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.7 +javac.target=1.7 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=maplebosshpbarfetcher.MapleBossHpBarFetcher +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=JDK_1.7 +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/tools/MapleBossHpBarFetcher/nbproject/project.xml b/tools/MapleBossHpBarFetcher/nbproject/project.xml new file mode 100644 index 0000000000..cdbefdd1cb --- /dev/null +++ b/tools/MapleBossHpBarFetcher/nbproject/project.xml @@ -0,0 +1,16 @@ + + + org.netbeans.modules.java.j2seproject + + + MapleBossHpBarFetcher + + + + + + + + + + diff --git a/tools/MapleBossHpBarFetcher/src/maplebosshpbarfetcher/MapleBossHpBarFetcher.java b/tools/MapleBossHpBarFetcher/src/maplebosshpbarfetcher/MapleBossHpBarFetcher.java new file mode 100644 index 0000000000..507d41ad20 --- /dev/null +++ b/tools/MapleBossHpBarFetcher/src/maplebosshpbarfetcher/MapleBossHpBarFetcher.java @@ -0,0 +1,240 @@ +/* + This file is part of the HeavenMS (MapleSolaxiaV2) 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 . +*/ +package maplebosshpbarfetcher; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.sql.Connection; +import java.util.LinkedList; +import java.util.List; +import java.io.File; + +/** + * + * @author RonanLana + + This application parses the Mob.wz file inputted and generates a report showing + all cases where a mob has a boss HP bar and doesn't have a "boss" label. + + Running it should generate a report file under "lib" folder with the search results. + + */ +public class MapleBossHpBarFetcher { + static String mobDirectory = "../../wz/Mob.wz/"; + static String newFile = "lib/Report.txt"; + + static Connection con = null; + static PrintWriter printWriter = null; + static InputStreamReader fileReader = null; + static BufferedReader bufferedReader = null; + + static int initialLength = 200; + static int initialStringLength = 50; + + static byte status = 0; + + static int curBoss; + static int curHpTag; + static int curMobId; + + static List missingBosses = new LinkedList<>(); + + private static String getName(String token) { + int i, j; + char[] dest; + String d; + + i = token.lastIndexOf("name"); + i = token.indexOf("\"", i) + 1; //lower bound of the string + j = token.indexOf("\"", i); //upper bound + + dest = new char[initialStringLength]; + token.getChars(i, j, dest, 0); + + d = new String(dest); + return(d.trim()); + } + + private static String getValue(String token) { + int i, j; + char[] dest; + String d; + + i = token.lastIndexOf("value"); + i = token.indexOf("\"", i) + 1; //lower bound of the string + j = token.indexOf("\"", i); //upper bound + + dest = new char[initialStringLength]; + token.getChars(i, j, dest, 0); + + d = new String(dest); + return(d.trim()); + } + + private static void forwardCursor(int st) { + String line = null; + + try { + while(status >= st && (line = bufferedReader.readLine()) != null) { + simpleToken(line); + } + } + catch(Exception e) { + e.printStackTrace(); + } + } + + private static void simpleToken(String token) { + if(token.contains("/imgdir")) { + status -= 1; + } + else if(token.contains("imgdir")) { + status += 1; + } + } + + private static void readMobLabel(String token) { + String name = getName(token); + String value = getValue(token); + + switch(name) { + case "boss": + curBoss = Integer.parseInt(value); + break; + + case "hpTagColor": + curHpTag = Integer.parseInt(value); + break; + } + } + + private static void processMobData() { + if(curHpTag != Integer.MAX_VALUE && curBoss == Integer.MAX_VALUE) { + missingBosses.add(curMobId); + } + } + + private static void translateToken(String token) { + String d; + + if(token.contains("/imgdir")) { + status -= 1; + + if(status == 1) { + processMobData(); + } + } + else if(token.contains("imgdir")) { + if(status == 0) { + String mobText = getName(token); + curMobId = Integer.valueOf(mobText.substring(0, mobText.lastIndexOf('.'))); + } + else if(status == 1) { //getting info + d = getName(token); + + if(!d.contentEquals("info")) { + forwardCursor(status); + } else { + curBoss = Integer.MAX_VALUE; + curHpTag = Integer.MAX_VALUE; + } + } + else if(status == 2) { + forwardCursor(status); + } + + status += 1; + } + else { + if(status == 2) { //info tags + readMobLabel(token); + } + } + } + + private static void readBossHpBarData() throws IOException { + String line; + + File folder = new File(mobDirectory); + for(File file : folder.listFiles()) { + if (file.isFile()) { + fileReader = new InputStreamReader(new FileInputStream(file), "UTF-8"); + bufferedReader = new BufferedReader(fileReader); + + while((line = bufferedReader.readLine()) != null) { + translateToken(line); + } + + bufferedReader.close(); + fileReader.close(); + } + } + } + + private static void printReportFileHeader() { + printWriter.println(" # Report File autogenerated from the MapleBossHpBarFetcher feature by Ronan Lana."); + printWriter.println(" # Generated data takes into account several data info from the server-side WZ.xmls."); + printWriter.println(); + } + + private static void printReportFileResults() { + for(Integer mid : missingBosses) { + printWriter.println("Missing 'isBoss' on id: " + mid); + } + } + + private static void ReportBossHpBarData() { + // This will reference one line at a time + + try { + System.out.println("Reading WZs..."); + readBossHpBarData(); + + System.out.println("Reporting results..."); + printWriter = new PrintWriter(newFile, "UTF-8"); + + printReportFileHeader(); + printReportFileResults(); + + printWriter.close(); + System.out.println("Done!"); + } + + catch(FileNotFoundException ex) { + System.out.println("Unable to open mob file."); + } + catch(IOException ex) { + System.out.println("Error reading mob file."); + } + + catch(Exception e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + ReportBossHpBarData(); + } + +} diff --git a/tools/MapleIdRetriever/dist/MapleIdRetriever.jar b/tools/MapleIdRetriever/dist/MapleIdRetriever.jar index a89f093c87..2cff0d0139 100644 Binary files a/tools/MapleIdRetriever/dist/MapleIdRetriever.jar and b/tools/MapleIdRetriever/dist/MapleIdRetriever.jar differ diff --git a/tools/MapleIdRetriever/lib/fetch.txt b/tools/MapleIdRetriever/lib/fetch.txt index ff68f13fc0..7f21619401 100644 --- a/tools/MapleIdRetriever/lib/fetch.txt +++ b/tools/MapleIdRetriever/lib/fetch.txt @@ -1,24 +1,25 @@ -Gladius -Niam -Titan -Crescent Polearm -Iron Dagger -White Crusader Chainmail (Male) -Wizard Wand -Wizard Staff -Golden Pride -Blue Guiltian -Red Amorian Skirt (Female) -Red Salt Shoes -Green Pole-Feather Hat -Black Bennis Chainmail (Male) -Red Legolier (Male) -Blue Legolier Pants (Male) -Green Marker -Gold Brace -Green Hunter Boots -Dragon Toenail -Rouge Way -Guardian Katara -Justice Katara -Norman Grip +Dark Cloud Foxtail +Pole Arm Forging Stimulator +Spear Forging Stimulator +Wand Production Stimulator + +Red Umbrella +Blue Moon +Thermometer + +Oaker Shouldermail Pants +Arc Staff +White Piettra Skirt +Red Moon Pants + +Mithril Ore +Aquamarine Ore +Diamond Ore +Dark Crystal Ore + +Kinoko Ramen (Pig Head) +Yakisoba +Fish Cake (Dish) +Tobi Throwing-Star +Dark Scroll for Overall Armor for DEF 70% +Dark Scroll for Dagger for ATT 30% \ No newline at end of file diff --git a/tools/MapleIdRetriever/lib/result.txt b/tools/MapleIdRetriever/lib/result.txt index 766d1fdfef..4e2f065af0 100644 --- a/tools/MapleIdRetriever/lib/result.txt +++ b/tools/MapleIdRetriever/lib/result.txt @@ -1,20 +1,26 @@ -1302008 -1412004 -1422007 -1442009 -1332010 -1372001 -1382002 -1002013 -1002152 -1061047 -1072090 -1002137 -1040023 -1040072 -1060062 -1082049 -1082072 -1072081 -1332031 -1482003 +4000077 +4130009 +4130008 +4130010 + +1302025 +1032011 1041078 +1402014 + +1060077 +1382001 1382020 1382025 1382030 +1061080 +1061079 + +4010002 +4020002 +4020007 +4004004 + +2022019 +2022026 +2022022 + +2070004 * +2040510 +2043305 diff --git a/tools/MapleIdRetriever/nbproject/private/private.xml b/tools/MapleIdRetriever/nbproject/private/private.xml index 6807a2ba19..172306f156 100644 --- a/tools/MapleIdRetriever/nbproject/private/private.xml +++ b/tools/MapleIdRetriever/nbproject/private/private.xml @@ -2,6 +2,8 @@ - + + file:/C:/Nexon/MapleSolaxia/HeavenMS/tools/MapleIdRetriever/src/mapleidretriever/MapleIdRetriever.java + diff --git a/tools/MapleQuestItemCountFetcher/build.xml b/tools/MapleQuestItemCountFetcher/build.xml new file mode 100644 index 0000000000..865790e343 --- /dev/null +++ b/tools/MapleQuestItemCountFetcher/build.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + Builds, tests, and runs the project MapleQuestItemCountFetcher. + + + diff --git a/tools/MapleQuestItemCountFetcher/lib/QuestReport.txt b/tools/MapleQuestItemCountFetcher/lib/QuestReport.txt new file mode 100644 index 0000000000..2ac6bb6388 --- /dev/null +++ b/tools/MapleQuestItemCountFetcher/lib/QuestReport.txt @@ -0,0 +1,22 @@ + # Report File autogenerated from the MapleQuestItemCountFetcher feature by Ronan Lana. + # Generated data takes into account several data info from the server-side WZ.xmls. + +Questid 2167 : Itemid 4031841 should have qty -1 +Questid 1018 : Itemid 4000142 should have qty -1 +Questid 6361 : Itemid 4031870 should have qty -1 +Questid 6360 : Itemid 4031869 should have qty -1 +Questid 10430 : Itemid 4220152 should have qty -1 +Questid 6390 : Itemid 4031874 should have qty -50 +Questid 2173 : Itemid 4031846 should have qty -1 +Questid 2169 : Itemid 4031843 should have qty -1 +Questid 2168 : Itemid 4031842 should have qty -1 +Questid 2185 : Itemid 4031852 should have qty -1 +Questid 6380 : Itemid 4031873 should have qty -50 +Questid 6350 : Itemid 4031871 should have qty -50 +Questid 2052 : Itemid 4031025 should have qty -10 +Questid 2053 : Itemid 4031026 should have qty -20 +Questid 2054 : Itemid 4031028 should have qty -30 +Questid 6340 : Itemid 4031872 should have qty -50 +Questid 28120 : Itemid 4032306 should have qty -4 +Questid 2180 : Itemid 4031850 should have qty -1 +Questid 2183 : Itemid 4031851 should have qty -1 diff --git a/tools/MapleQuestItemCountFetcher/manifest.mf b/tools/MapleQuestItemCountFetcher/manifest.mf new file mode 100644 index 0000000000..328e8e5bc3 --- /dev/null +++ b/tools/MapleQuestItemCountFetcher/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/tools/MapleQuestItemCountFetcher/nbproject/build-impl.xml b/tools/MapleQuestItemCountFetcher/nbproject/build-impl.xml new file mode 100644 index 0000000000..16aab72b63 --- /dev/null +++ b/tools/MapleQuestItemCountFetcher/nbproject/build-impl.xml @@ -0,0 +1,1448 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set platform.home + Must set platform.bootcp + Must set platform.java + Must set platform.javac + + The J2SE Platform is not correctly set up. + Your active platform is: ${platform.active}, but the corresponding property "platforms.${platform.active}.home" is not found in the project's properties files. + Either open the project in the IDE and setup the Platform with the same name or add it manually. + For example like this: + ant -Duser.properties.file=<path_to_property_file> jar (where you put the property "platforms.${platform.active}.home" in a .properties file) + or ant -Dplatforms.${platform.active}.home=<path_to_JDK_home> jar (where no properties file is used) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + ${platform.java} -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/MapleQuestItemCountFetcher/nbproject/genfiles.properties b/tools/MapleQuestItemCountFetcher/nbproject/genfiles.properties new file mode 100644 index 0000000000..7aecb1e95a --- /dev/null +++ b/tools/MapleQuestItemCountFetcher/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=012f695b +build.xml.script.CRC32=254e2ce9 +build.xml.stylesheet.CRC32=8064a381@1.75.2.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=012f695b +nbproject/build-impl.xml.script.CRC32=fa2290c4 +nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.75.2.48 diff --git a/tools/MapleQuestItemCountFetcher/nbproject/project.properties b/tools/MapleQuestItemCountFetcher/nbproject/project.properties new file mode 100644 index 0000000000..f2ee825b49 --- /dev/null +++ b/tools/MapleQuestItemCountFetcher/nbproject/project.properties @@ -0,0 +1,79 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=MapleQuestItemCountFetcher +application.vendor=USER +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# Os arquivos em build.classes.dir que devem ser exclu\u00eddos do jar de distribui\u00e7\u00e3o +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/MapleQuestItemCountFetcher.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.commons-io-2.6.jar=lib/commons-io-2.6.jar +file.reference.mysql-connector-java-bin.jar=../../cores/mysql-connector-java-bin.jar +includes=** +jar.compress=false +javac.classpath=\ + ${file.reference.mysql-connector-java-bin.jar}:\ + ${file.reference.commons-io-2.6.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.7 +javac.target=1.7 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=maplequestitemcountfetcher.MapleQuestItemCountFetcher +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=JDK_1.7 +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/tools/MapleQuestItemCountFetcher/nbproject/project.xml b/tools/MapleQuestItemCountFetcher/nbproject/project.xml new file mode 100644 index 0000000000..a48b9ef156 --- /dev/null +++ b/tools/MapleQuestItemCountFetcher/nbproject/project.xml @@ -0,0 +1,16 @@ + + + org.netbeans.modules.java.j2seproject + + + MapleQuestItemCountFetcher + + + + + + + + + + diff --git a/tools/MapleQuestItemCountFetcher/src/maplequestitemcountfetcher/MapleQuestItemCountFetcher.java b/tools/MapleQuestItemCountFetcher/src/maplequestitemcountfetcher/MapleQuestItemCountFetcher.java new file mode 100644 index 0000000000..ddb709ed49 --- /dev/null +++ b/tools/MapleQuestItemCountFetcher/src/maplequestitemcountfetcher/MapleQuestItemCountFetcher.java @@ -0,0 +1,331 @@ +/* + This file is part of the HeavenMS (MapleSolaxiaV2) 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 . +*/ +package maplequestitemcountfetcher; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.sql.Connection; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; +import java.util.LinkedHashMap; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.HashSet; +import java.util.Set; + +/** + * + * @author RonanLana + + This application parses the Quest.wz file inputted and generates a report showing + all cases where a quest requires an item, but doesn't take them, which may happen + because the node representing the item doesn't have a "count" clause. + + Running it should generate a report file under "lib" folder with the search results. + + */ +public class MapleQuestItemCountFetcher { + static String actName = "../../wz/Quest.wz/Act.img.xml"; + static String checkName = "../../wz/Quest.wz/Check.img.xml"; + static String directoryName = "../.."; + static String newFile = "lib/QuestReport.txt"; + + static Connection con = null; + static PrintWriter printWriter = null; + static InputStreamReader fileReader = null; + static BufferedReader bufferedReader = null; + + static int initialLength = 200; + static int initialStringLength = 50; + + static byte status = 0; + static int questId = -1; + static int isCompleteState = 0; + + static int curItemId; + static int curItemCount; + + static Map> checkItems = new HashMap<>(); + static Map> actItems = new HashMap<>(); + + private static String getName(String token) { + int i, j; + char[] dest; + String d; + + i = token.lastIndexOf("name"); + i = token.indexOf("\"", i) + 1; //lower bound of the string + j = token.indexOf("\"", i); //upper bound + + dest = new char[initialStringLength]; + token.getChars(i, j, dest, 0); + + d = new String(dest); + return(d.trim()); + } + + private static String getValue(String token) { + int i, j; + char[] dest; + String d; + + i = token.lastIndexOf("value"); + i = token.indexOf("\"", i) + 1; //lower bound of the string + j = token.indexOf("\"", i); //upper bound + + dest = new char[initialStringLength]; + token.getChars(i, j, dest, 0); + + d = new String(dest); + return(d.trim()); + } + + private static void forwardCursor(int st) { + String line = null; + + try { + while(status >= st && (line = bufferedReader.readLine()) != null) { + simpleToken(line); + } + } + catch(Exception e) { + e.printStackTrace(); + } + } + + private static void simpleToken(String token) { + if(token.contains("/imgdir")) { + status -= 1; + } + else if(token.contains("imgdir")) { + status += 1; + } + } + + private static void readItemLabel(String token) { + String name = getName(token); + String value = getValue(token); + + switch(name) { + case "id": + curItemId = Integer.parseInt(value); + break; + + case "count": + curItemCount = Integer.parseInt(value); + break; + } + } + + private static void commitQuestItemPair(Map> map) { + Map list = map.get(questId); + if(list == null) { + list = new LinkedHashMap<>(); + map.put(questId, list); + } + + list.put(curItemId, curItemCount); + } + + private static void translateTokenAct(String token) { + String d; + + if(token.contains("/imgdir")) { + status -= 1; + + if(status == 4) { + if(curItemCount == Integer.MAX_VALUE && isCompleteState == 1) { + commitQuestItemPair(actItems); + } + } + } + else if(token.contains("imgdir")) { + if(status == 1) { //getting QuestId + d = getName(token); + questId = Integer.parseInt(d); + } + else if(status == 2) { //start/complete + d = getName(token); + isCompleteState = Integer.parseInt(d); + } + else if(status == 3) { + if(!token.contains("item")) { + forwardCursor(status); + } + } + else if(status == 4) { + curItemId = Integer.MAX_VALUE; + curItemCount = Integer.MAX_VALUE; + } + + status += 1; + } + else { + if(status == 5) { + readItemLabel(token); + } + } + } + + private static void translateTokenCheck(String token) { + String d; + + if(token.contains("/imgdir")) { + status -= 1; + + if(status == 4) { + Map missedItems = actItems.get(questId); + + if(missedItems != null && missedItems.containsKey(curItemId) && isCompleteState == 1) { + commitQuestItemPair(checkItems); + } + } + } + else if(token.contains("imgdir")) { + if(status == 1) { //getting QuestId + d = getName(token); + questId = Integer.parseInt(d); + } + else if(status == 2) { //start/complete + d = getName(token); + isCompleteState = Integer.parseInt(d); + } + else if(status == 3) { + if(!token.contains("item")) { + forwardCursor(status); + } + } + else if(status == 4) { + curItemId = Integer.MAX_VALUE; + curItemCount = Integer.MAX_VALUE; + } + + status += 1; + } + else { + if(status == 5) { + readItemLabel(token); + } + } + } + + private static void readQuestItemCountData() throws IOException { + String line; + + fileReader = new InputStreamReader(new FileInputStream(actName), "UTF-8"); + bufferedReader = new BufferedReader(fileReader); + + while((line = bufferedReader.readLine()) != null) { + translateTokenAct(line); + } + + bufferedReader.close(); + fileReader.close(); + + fileReader = new InputStreamReader(new FileInputStream(checkName), "UTF-8"); + bufferedReader = new BufferedReader(fileReader); + + while((line = bufferedReader.readLine()) != null) { + translateTokenCheck(line); + } + + bufferedReader.close(); + fileReader.close(); + } + + private static void printReportFileHeader() { + printWriter.println(" # Report File autogenerated from the MapleQuestItemCountFetcher feature by Ronan Lana."); + printWriter.println(" # Generated data takes into account several data info from the server-side WZ.xmls."); + printWriter.println(); + } + + private static void printReportFileResults() { + List>> reports = new ArrayList<>(); + List> notChecked = new ArrayList<>(); + + for(Entry> actItem : actItems.entrySet()) { + int questid = actItem.getKey(); + + for(Entry actData : actItem.getValue().entrySet()) { + int itemid = actData.getKey(); + + Map checkData = checkItems.get(questid); + if(checkData != null) { + Integer count = checkData.get(itemid); + if(count != null) { + reports.add(new Pair<>(questid, new Pair<>(itemid, -count))); + } + } else { + notChecked.add(new Pair<>(questid, itemid)); + } + } + } + + for(Pair> r : reports) { + printWriter.println("Questid " + r.left + " : Itemid " + r.right.left + " should have qty " + r.right.right); + } + + for(Pair r : notChecked) { + printWriter.println("Questid " + r.left + " : Itemid " + r.right + " is unchecked"); + } + } + + private static void ReportQuestItemCountData() { + // This will reference one line at a time + + try { + System.out.println("Reading WZs..."); + readQuestItemCountData(); + + System.out.println("Reporting results..."); + printWriter = new PrintWriter(newFile, "UTF-8"); + + printReportFileHeader(); + printReportFileResults(); + + printWriter.close(); + System.out.println("Done!"); + } + + catch(FileNotFoundException ex) { + System.out.println("Unable to open quest file."); + } + catch(IOException ex) { + System.out.println("Error reading quest file."); + } + + catch(Exception e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + ReportQuestItemCountData(); + } + +} diff --git a/tools/MapleQuestItemCountFetcher/src/maplequestitemcountfetcher/Pair.java b/tools/MapleQuestItemCountFetcher/src/maplequestitemcountfetcher/Pair.java new file mode 100644 index 0000000000..ee34966714 --- /dev/null +++ b/tools/MapleQuestItemCountFetcher/src/maplequestitemcountfetcher/Pair.java @@ -0,0 +1,121 @@ +/* +This file is part of the OdinMS Maple Story Server +Copyright (C) 2008 ~ 2010 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 . + */ +package maplequestitemcountfetcher; + +/** + * Represents a pair of values. + * + * @author Frz + * @since Revision 333 + * @version 1.0 + * + * @param The type of the left value. + * @param The type of the right value. + */ +public class Pair { + + public E left; + public F right; + + /** + * Class constructor - pairs two objects together. + * + * @param left The left object. + * @param right The right object. + */ + public Pair(E left, F right) { + this.left = left; + this.right = right; + } + + /** + * Gets the left value. + * + * @return The left value. + */ + public E getLeft() { + return left; + } + + /** + * Gets the right value. + * + * @return The right value. + */ + public F getRight() { + return right; + } + + /** + * Turns the pair into a string. + * + * @return Each value of the pair as a string joined by a colon. + */ + @Override + public String toString() { + return left.toString() + ":" + right.toString(); + } + + /** + * Gets the hash code of this pair. + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((left == null) ? 0 : left.hashCode()); + result = prime * result + ((right == null) ? 0 : right.hashCode()); + return result; + } + + /** + * Checks to see if two pairs are equal. + */ + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Pair other = (Pair) obj; + if (left == null) { + if (other.left != null) { + return false; + } + } else if (!left.equals(other.left)) { + return false; + } + if (right == null) { + if (other.right != null) { + return false; + } + } else if (!right.equals(other.right)) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/wz/Map.wz/Map/Map8/801030000.img.xml b/wz/Map.wz/Map/Map8/801030000.img.xml index 5a9ddf45a1..1098267088 100644 --- a/wz/Map.wz/Map/Map8/801030000.img.xml +++ b/wz/Map.wz/Map/Map8/801030000.img.xml @@ -140,7 +140,7 @@ - + diff --git a/wz/Map.wz/Map/Map8/801040004.img.xml b/wz/Map.wz/Map/Map8/801040004.img.xml index 94e114fccf..f31e66bed7 100644 --- a/wz/Map.wz/Map/Map8/801040004.img.xml +++ b/wz/Map.wz/Map/Map8/801040004.img.xml @@ -182,7 +182,7 @@ - + diff --git a/wz/Map.wz/Map/Map8/801040100.img.xml b/wz/Map.wz/Map/Map8/801040100.img.xml index c80a48d1d9..20a97c7cc3 100644 --- a/wz/Map.wz/Map/Map8/801040100.img.xml +++ b/wz/Map.wz/Map/Map8/801040100.img.xml @@ -119,7 +119,7 @@ - + diff --git a/wz/Mob.wz/3300005.img.xml b/wz/Mob.wz/3300005.img.xml index 775dbd0219..ad6048e004 100644 --- a/wz/Mob.wz/3300005.img.xml +++ b/wz/Mob.wz/3300005.img.xml @@ -32,6 +32,7 @@ + diff --git a/wz/Mob.wz/3300006.img.xml b/wz/Mob.wz/3300006.img.xml index 953a979033..7298cb82da 100644 --- a/wz/Mob.wz/3300006.img.xml +++ b/wz/Mob.wz/3300006.img.xml @@ -32,6 +32,7 @@ + diff --git a/wz/Mob.wz/3300007.img.xml b/wz/Mob.wz/3300007.img.xml index 7f358755cc..370bdd925e 100644 --- a/wz/Mob.wz/3300007.img.xml +++ b/wz/Mob.wz/3300007.img.xml @@ -32,6 +32,7 @@ + diff --git a/wz/Mob.wz/8820010.img.xml b/wz/Mob.wz/8820010.img.xml index 9860596b10..e06c51e4fb 100644 --- a/wz/Mob.wz/8820010.img.xml +++ b/wz/Mob.wz/8820010.img.xml @@ -29,6 +29,7 @@ + diff --git a/wz/Mob.wz/8820011.img.xml b/wz/Mob.wz/8820011.img.xml index 36598e257b..75e397b06e 100644 --- a/wz/Mob.wz/8820011.img.xml +++ b/wz/Mob.wz/8820011.img.xml @@ -29,6 +29,7 @@ + diff --git a/wz/Mob.wz/8820012.img.xml b/wz/Mob.wz/8820012.img.xml index cdd4f130b0..30d375cb72 100644 --- a/wz/Mob.wz/8820012.img.xml +++ b/wz/Mob.wz/8820012.img.xml @@ -29,6 +29,7 @@ + diff --git a/wz/Mob.wz/8820013.img.xml b/wz/Mob.wz/8820013.img.xml index 95c38c236b..e844d90ae1 100644 --- a/wz/Mob.wz/8820013.img.xml +++ b/wz/Mob.wz/8820013.img.xml @@ -29,6 +29,7 @@ + diff --git a/wz/Mob.wz/8820014.img.xml b/wz/Mob.wz/8820014.img.xml index 8c85fd0283..d8d78e62bb 100644 --- a/wz/Mob.wz/8820014.img.xml +++ b/wz/Mob.wz/8820014.img.xml @@ -24,6 +24,7 @@ + diff --git a/wz/Mob.wz/8830003.img.xml b/wz/Mob.wz/8830003.img.xml index a384b36193..34f4f5c8a1 100644 --- a/wz/Mob.wz/8830003.img.xml +++ b/wz/Mob.wz/8830003.img.xml @@ -35,6 +35,7 @@ + diff --git a/wz/Mob.wz/8830010.img.xml b/wz/Mob.wz/8830010.img.xml index 9f64bcffaf..db1906c99e 100644 --- a/wz/Mob.wz/8830010.img.xml +++ b/wz/Mob.wz/8830010.img.xml @@ -40,6 +40,7 @@ + diff --git a/wz/Mob.wz/9001008.img.xml b/wz/Mob.wz/9001008.img.xml index 2789444b3b..e160bf0303 100644 --- a/wz/Mob.wz/9001008.img.xml +++ b/wz/Mob.wz/9001008.img.xml @@ -41,6 +41,7 @@ + diff --git a/wz/Mob.wz/9500340.img.xml b/wz/Mob.wz/9500340.img.xml index 7a499732d1..38f7e133ac 100644 --- a/wz/Mob.wz/9500340.img.xml +++ b/wz/Mob.wz/9500340.img.xml @@ -1 +1,49 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wz/Quest.wz/Act.img.xml b/wz/Quest.wz/Act.img.xml index 1d2c8b3f82..809fa9339f 100644 --- a/wz/Quest.wz/Act.img.xml +++ b/wz/Quest.wz/Act.img.xml @@ -1846,6 +1846,7 @@ + @@ -3986,6 +3987,7 @@ + @@ -7129,6 +7131,7 @@ + @@ -7306,6 +7309,7 @@ + @@ -7395,6 +7399,7 @@ + @@ -11046,6 +11051,7 @@ + @@ -11065,6 +11071,7 @@ + @@ -11085,6 +11092,7 @@ + @@ -11496,6 +11504,7 @@ + @@ -11969,6 +11978,7 @@ + @@ -12022,6 +12032,7 @@ + @@ -14526,6 +14537,7 @@ + @@ -36690,6 +36702,7 @@ + @@ -36711,6 +36724,7 @@ + @@ -36741,6 +36755,7 @@ + @@ -36759,6 +36774,7 @@ + @@ -36836,6 +36852,7 @@ + @@ -36865,6 +36882,7 @@ + @@ -37657,6 +37675,7 @@ + @@ -37686,6 +37705,7 @@ + @@ -37699,6 +37719,7 @@ + @@ -37740,6 +37761,7 @@ + @@ -37756,6 +37778,7 @@ + @@ -37837,7 +37860,7 @@ - + @@ -37864,6 +37887,7 @@ + @@ -37878,6 +37902,7 @@ + @@ -37903,6 +37928,7 @@ + @@ -37959,6 +37985,7 @@ + @@ -37975,6 +38002,7 @@ + @@ -37996,6 +38024,7 @@ + @@ -38017,13 +38046,14 @@ + - + @@ -38059,11 +38089,12 @@ + - + @@ -38088,6 +38119,7 @@ + @@ -38111,6 +38143,7 @@ + @@ -38138,6 +38171,7 @@ + @@ -38152,6 +38186,7 @@ + @@ -38179,7 +38214,7 @@ - + @@ -38239,6 +38274,7 @@ + @@ -38524,6 +38560,7 @@ + @@ -38658,6 +38695,7 @@ + @@ -38671,6 +38709,7 @@ + @@ -38780,6 +38819,7 @@ + @@ -38872,6 +38912,7 @@ +