From a56312ddd30f54ebc73ceda528bc9267bf8b4105 Mon Sep 17 00:00:00 2001 From: ronancpl Date: Mon, 15 May 2017 15:52:24 -0300 Subject: [PATCH] Ludibrium Maze PQ Implemented Ludibrium Maze PQ. --- mychanges_ptbr.txt | 9 +- nbproject/private/private.xml | 38 +- scripts/event/BossRushPQ.js | 11 +- scripts/event/CWKPQ.js | 2 +- scripts/event/Ellin.js | 20 +- scripts/event/KerningPQ.js | 11 +- scripts/event/LudiMazePQ.js | 275 +- scripts/event/LudiPQ.js | 59 +- scripts/event/PiratePQ.js | 29 +- scripts/event/s4aWorld.js | 2 +- scripts/npc/world0/1012112.js | 69 +- scripts/npc/world0/2040034.js | 7 +- scripts/npc/world0/2040035.js | 2 +- scripts/npc/world0/2040036.js | 2 +- scripts/npc/world0/2040037.js | 2 +- scripts/npc/world0/2040038.js | 2 +- scripts/npc/world0/2040039.js | 2 +- scripts/npc/world0/2040040.js | 2 +- scripts/npc/world0/2040042.js | 2 +- scripts/npc/world0/2094000.js | 2 +- scripts/npc/world0/2133000.js | 2 +- scripts/npc/world0/9000037.js | 33 +- scripts/npc/world0/9000038.js | 4 +- scripts/npc/world0/9020000.js | 2 +- scripts/npc/world0/9103000.js | 96 +- scripts/npc/world0/9103001.js | 156 +- scripts/npc/world0/9103002.js | 89 +- scripts/npc/world0/9103003.js | 31 +- sql/db_drops.sql | 3 + src/scripting/AbstractPlayerInteraction.java | 4 + src/scripting/event/EventInstanceManager.java | 2 +- src/scripting/event/EventManager.java | 39 +- wz/Character.wz/Accessory/01032030.img.xml | 2 +- wz/Character.wz/Accessory/01032070.img.xml | 2 +- wz/Map.wz/Map/Map9/922010800.img.xml | 15083 ++++++++-------- 35 files changed, 8081 insertions(+), 8015 deletions(-) diff --git a/mychanges_ptbr.txt b/mychanges_ptbr.txt index 7bc28de884..a25568c5a5 100644 --- a/mychanges_ptbr.txt +++ b/mychanges_ptbr.txt @@ -211,4 +211,11 @@ Sistema de lobbys para PQs agora. 12 - 13 Maio 2017, Nova ferramenta: monta uma tabela SQL que armazena id-nome de todos os itens descritos nos arquivos handbook e realiza buscas por nomes, retornando seus ids. -Implementação da LPQ. \ No newline at end of file +Implementação da LPQ. + +14 Maio 2017, +Sistema de Lobbys na BRPQ: aloca lobbys disponiveis para times de acordo com o level medio dos jogadores. +Sword Earrings: +30HP -> +1 W.att / Shield Earrings: +1ACC -> +1 M.att + +15 Maio 2017, +Implementação da LMPQ. \ No newline at end of file diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml index 23ab2ece90..331d35f788 100644 --- a/nbproject/private/private.xml +++ b/nbproject/private/private.xml @@ -3,41 +3,11 @@ - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/2040038.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/command/Commands.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/2040041.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/reactor/2202004.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/portal/lpq5.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/event/Boats.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/scripting/AbstractPlayerInteraction.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/portal/lpq7.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/event/KerningPQ.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/portal/lpq0.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/2040043.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/9020002.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/2040039.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/9020001.js + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/world/MaplePartyCharacter.java file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/scripting/event/EventInstanceManager.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/2040035.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/2040037.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleCharacter.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/maps/MapleMap.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/event/PiratePQ.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/scripting/reactor/ReactorActionManager.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/2040034.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/2040045.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/portal/lpq4.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/2040036.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/scripting/reactor/ReactorScriptManager.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/event/LudiPQ.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/portal/lpq1.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/2040047.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/2040042.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/portal/lpq6.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/2040044.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/portal/lpq2.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/2040040.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/portal/lpq3.js + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/event/BossRushPQ.js + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/world0/9000037.js + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/scripting/event/EventManager.java diff --git a/scripts/event/BossRushPQ.js b/scripts/event/BossRushPQ.js index 9c949b2b23..7346ea53f5 100644 --- a/scripts/event/BossRushPQ.js +++ b/scripts/event/BossRushPQ.js @@ -9,6 +9,8 @@ var clearMap = 970030000; var minMapId = 970030001; var maxMapId = 970042711; +var eventTime = 5; //5 minutes + var lobbyRange = [0, 7]; function init() { @@ -30,6 +32,9 @@ function setEventRequirements() { if(maxLevel - minLevel >= 1) reqStr += minLevel + " ~ " + maxLevel; else reqStr += minLevel; + reqStr += "\r\n Time limit: "; + reqStr += eventTime + " minutes"; + em.setProperty("party", reqStr); } @@ -39,12 +44,12 @@ function setEventRewards(eim) { var itemSet, itemQty, evLevel; evLevel = 6; //Rewards at event completion - itemSet = [1122018, 1122005, 1022088, 1402013, 1032048, 1032070, 1102046, 2330004, 2041013, 2041016, 2041019, 2041022, 2049100, 2049003, 2020012, 2020013, 2020014, 2020015, 2022029, 2022045, 2022068, 2022069, 2022180, 2022179, 4004000, 4004001, 4004002, 4004003, 4004004, 4003000]; + itemSet = [1122018, 1122005, 1022088, 1402013, 1032030, 1032070, 1102046, 2330004, 2041013, 2041016, 2041019, 2041022, 2049100, 2049003, 2020012, 2020013, 2020014, 2020015, 2022029, 2022045, 2022068, 2022069, 2022180, 2022179, 4004000, 4004001, 4004002, 4004003, 4004004, 4003000]; itemQty = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 25, 25, 25, 25, 25, 25, 25, 4, 4, 12, 12, 12, 12, 12, 25]; eim.setEventRewards(evLevel, itemSet, itemQty); evLevel = 5; //Rewards at Rest Spot V - itemSet = [1122018, 1122005, 1022088, 1402013, 1032048, 1032070, 1102046, 2330004, 2041013, 2041016, 2041019, 2041022, 2049100, 2049003, 2020012, 2020013, 2020014, 2020015, 2022029, 2022045, 2022068, 2022069, 2022180, 2022179, 4004000, 4004001, 4004002, 4004003, 4004004, 4003000]; + itemSet = [1122018, 1122005, 1022088, 1402013, 1032030, 1032070, 1102046, 2330004, 2041013, 2041016, 2041019, 2041022, 2049100, 2049003, 2020012, 2020013, 2020014, 2020015, 2022029, 2022045, 2022068, 2022069, 2022180, 2022179, 4004000, 4004001, 4004002, 4004003, 4004004, 4003000]; itemQty = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 8, 8, 8, 8, 8, 12]; eim.setEventRewards(evLevel, itemSet, itemQty); @@ -95,7 +100,7 @@ function setup(level, lobbyid) { eim.setProperty("level", level); eim.setProperty("lobby", lobbyid); - eim.startEventTimer(45 * 60000); //45 mins + eim.startEventTimer(eventTime * 60000); setEventRewards(eim); setEventExclusives(eim); return eim; diff --git a/scripts/event/CWKPQ.js b/scripts/event/CWKPQ.js index 2dff2741b1..01b7d9d9b4 100644 --- a/scripts/event/CWKPQ.js +++ b/scripts/event/CWKPQ.js @@ -33,7 +33,7 @@ em.setProperty("state", "1"); em.setProperty("glpq6", "0"); var eim = em.newInstance("CWKPQ" + leaderid); for (var i = 0; i < mapz.length; i++) { - var map = eim.setInstanceMap(610030000 + mapz[i]); + var map = eim.getInstanceMap(610030000 + mapz[i]); if (map != null) { map.resetFully(); if (map.getId() == 610030400) { diff --git a/scripts/event/Ellin.js b/scripts/event/Ellin.js index b1610d5605..e853b8d4f2 100644 --- a/scripts/event/Ellin.js +++ b/scripts/event/Ellin.js @@ -9,6 +9,8 @@ var clearMap = 930000800; var minMapId = 930000000; var maxMapId = 930000800; +var eventTime = 30; // 30 minutes + var lobbyRange = [0, 0]; function init() { @@ -67,20 +69,20 @@ function setup(level, lobbyid) { var eim = em.newInstance("Ellin" + lobbyid); eim.setProperty("level", level); - eim.setInstanceMap(930000000).resetPQ(level); - eim.setInstanceMap(930000100).resetPQ(level); - eim.setInstanceMap(930000200).resetPQ(level); - eim.setInstanceMap(930000300).resetPQ(level); - eim.setInstanceMap(930000400).resetPQ(level); - var map = eim.setInstanceMap(930000500); + eim.getInstanceMap(930000000).resetPQ(level); + eim.getInstanceMap(930000100).resetPQ(level); + eim.getInstanceMap(930000200).resetPQ(level); + eim.getInstanceMap(930000300).resetPQ(level); + eim.getInstanceMap(930000400).resetPQ(level); + var map = eim.getInstanceMap(930000500); map.resetPQ(level); map.shuffleReactors(); - eim.setInstanceMap(930000600).resetPQ(level); - eim.setInstanceMap(930000700).resetPQ(level); + eim.getInstanceMap(930000600).resetPQ(level); + eim.getInstanceMap(930000700).resetPQ(level); respawnStg2(eim); - eim.startEventTimer(30 * 60000); //30 mins + eim.startEventTimer(eventTime * 60000); setEventRewards(eim); setEventExclusives(eim); return eim; diff --git a/scripts/event/KerningPQ.js b/scripts/event/KerningPQ.js index 3c422fb68a..0238193a07 100644 --- a/scripts/event/KerningPQ.js +++ b/scripts/event/KerningPQ.js @@ -1,6 +1,6 @@ var isPq = true; -var minPlayers = 1, maxPlayers = 6; -var minLevel = 21, maxLevel = 200; +var minPlayers = 3, maxPlayers = 4; +var minLevel = 21, maxLevel = 30; var entryMap = 103000800; var exitMap = 103000890; var recruitMap = 103000000; @@ -9,6 +9,8 @@ var clearMap = 103000805; var minMapId = 103000800; var maxMapId = 103000805; +var eventTime = 30; // 30 minutes + var lobbyRange = [0, 0]; function init() { @@ -30,6 +32,9 @@ function setEventRequirements() { if(maxLevel - minLevel >= 1) reqStr += minLevel + " ~ " + maxLevel; else reqStr += minLevel; + reqStr += "\r\n Time limit: "; + reqStr += eventTime + " minutes"; + em.setProperty("party", reqStr); } @@ -76,7 +81,7 @@ function setup(level, lobbyid) { eim.setProperty("level", level); respawnStages(eim); - eim.startEventTimer(30 * 60000); //30 mins + eim.startEventTimer(eventTime * 60000); setEventRewards(eim); setEventExclusives(eim); return eim; diff --git a/scripts/event/LudiMazePQ.js b/scripts/event/LudiMazePQ.js index 439c452d4c..604d59c602 100644 --- a/scripts/event/LudiMazePQ.js +++ b/scripts/event/LudiMazePQ.js @@ -1,129 +1,185 @@ -/* - * This file is part of the OdinMS Maple Story Server - Copyright (C) 2008 Patrick Huy - Matthias Butz - Jan Christian Meyer +var isPq = true; +var minPlayers = 3, maxPlayers = 6; +var minLevel = 51, maxLevel = 70; +var entryMap = 809050000; +var exitMap = 809050017; +var recruitMap = 220000000; +var clearMap = 809050016; - 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. +var minMapId = 809050000; +var maxMapId = 809050016; - 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. +var eventTime = 15; // 15 minutes - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - */ - -/* - * @Author Raz - * - * Ludi Maze PQ - */ - -var exitMap; -var instanceId; -var finishMap; +var lobbyRange = [0, 0]; function init() { - instanceId = 1; - em.setProperty("shuffleReactors", "true"); + setEventRequirements(); } - - -function monsterValue(eim, mobId) { - return 1; +function setLobbyRange() { + return lobbyRange; } -function setup() { - exitMap = em.getChannelServer().getMapFactory().getMap(809050017); - finishMap = em.getChannelServer().getMapFactory().getMap(809050016); - var instanceName = "LudiMazePQ" + instanceId; - var eim = em.newInstance(instanceName); - var mf = eim.getMapFactory(); - instanceId++; - var eventTime = 15 * (1000 * 60); - em.schedule("timeOut", eim, eventTime); - eim.startEventTimer(eventTime); - return eim; +function setEventRequirements() { + var reqStr = ""; + + reqStr += "\r\n Number of players: "; + if(maxPlayers - minPlayers >= 1) reqStr += minPlayers + " ~ " + maxPlayers; + else reqStr += minPlayers; + + reqStr += "\r\n Level range: "; + if(maxLevel - minLevel >= 1) reqStr += minLevel + " ~ " + maxLevel; + else reqStr += minLevel; + + reqStr += "\r\n Time limit: "; + reqStr += eventTime + " minutes"; + + em.setProperty("party", reqStr); } +function setEventExclusives(eim) { + var itemSet = [4001106]; + eim.setExclusiveItems(itemSet); +} + +function setEventRewards(eim) { + var itemSet, itemQty, evLevel, expStages; + + evLevel = 1; //Rewards at clear PQ + itemSet = [1442017, 1322025, 1032013, 1302016, 1072263, 1032043, 2000005, 2000004, 2001001, 2001002, 2020008, 2020010, 2030008, 2030010, 2030009, 2022000, 2001000, 2022019, 2020007, 2020006, 2020009, 2000006, 2040601, 2040605, 2040602, 2041027, 2041028, 2041004, 2041029, 2041017, 2041020, 2040008, 2040001, 2040009, 2040002, 2040504, 2040511, 2040505, 2040501, 2040904, 2040901, 2040905, 2040902, 2040404, 2040401, 2040405, 2040402]; + itemQty = [1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 20, 20, 20, 20, 20, 50, 50, 50, 100, 100, 100, 100, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; + eim.setEventRewards(evLevel, itemSet, itemQty); + + expStages = []; //bonus exp given on CLEAR stage signal + eim.setEventClearStageExp(expStages); +} + +function getEligibleParty(party) { //selects, from the given party, the team that is allowed to attempt this event + var eligible = []; + var hasLeader = false; + + if(party.size() > 0) { + var partyList = party.toArray(); + + for(var i = 0; i < party.size(); i++) { + var ch = partyList[i]; + + if(ch.getMapId() == recruitMap && ch.getLevel() >= minLevel && ch.getLevel() <= maxLevel) { + if(ch.isLeader()) hasLeader = true; + eligible.push(ch); + } + } + } + + if(!(hasLeader && eligible.length >= minPlayers && eligible.length <= maxPlayers)) eligible = []; + return eligible; +} + +function setup(level, lobbyid) { + var eim = em.newInstance("LudiMaze" + lobbyid); + eim.setProperty("level", level); + + for(var i = 809050000; i <= 809050016; i++) { + eim.getInstanceMap(i).resetPQ(level); + eim.getInstanceMap(i).shuffleReactors(); + } + + respawnStages(eim); + eim.startEventTimer(eventTime * 60000); + setEventRewards(eim); + setEventExclusives(eim); + return eim; +} + +function respawnStages(eim) {} + function playerEntry(eim, player) { - var random = Math.floor((Math.random() * 16)); - var map = eim.getMapInstance(809050000 + random); - player.changeMap(map, map.getPortal(0)); - + var map = eim.getMapInstance(entryMap); + player.changeMap(map, map.getPortal(0)); } -function playerDead(eim, player) { - if (player.isAlive()) { //don't trigger on death, trigger on manual revive - if (eim.isLeader(player)) { //check for party leader - var party = eim.getPlayers(); - for (var i = 0; i < party.size(); i++) - playerExit(eim, party.get(i)); - eim.dispose(); - } - else - playerExit(eim, player); - } -} - -function playerDisconnected(eim, player) { - if (eim.isLeader(player)) { //check for party leader - //boot whole party and end - var party = eim.getPlayers(); - for (var i = 0; i < party.size(); i++) - if (party.get(i).equals(player)) - removePlayer(eim, player); - else - playerExit(eim, party.get(i)); - eim.dispose(); - } - else - removePlayer(eim, player); -} - -function leftParty(eim, player) { - playerExit(eim, player); -} - -function disbandParty(eim) { - //boot whole party and end - var party = eim.getPlayers(); - for (var i = 0; i < party.size(); i++) - playerExit(eim, party.get(i)); - eim.dispose(); +function scheduledTimeout(eim) { + end(eim); } function playerExit(eim, player) { - eim.unregisterPlayer(player); - player.changeMap(exitMap, exitMap.getPortal(0)); + eim.unregisterPlayer(player); + player.changeMap(exitMap, 0); } - -function playerFinish(eim, player) { - eim.unregisterPlayer(player); - player.changeMap(finishMap, finishMap.getPortal(0)); +function changedMap(eim, player, mapid) { + if (mapid < minMapId || mapid > maxMapId) { + if (eim.isEventTeamLackingNow(true, minPlayers, player)) { + eim.unregisterPlayer(player); + end(eim); + } + else + eim.unregisterPlayer(player); + } } -//for offline players -function removePlayer(eim, player) { - eim.unregisterPlayer(player); - player.getMap().removePlayer(player); - player.setMap(exitMap); +function changedLeader(eim, leader) { + var mapid = leader.getMapId(); + if (!eim.isEventCleared() && (mapid < minMapId || mapid > maxMapId)) { + end(eim); + } +} + +function playerDead(eim, player) {} + +function playerRevive(eim, player) { // player presses ok on the death pop up. + if (eim.isEventTeamLackingNow(true, minPlayers, player)) { + eim.unregisterPlayer(player); + end(eim); + } + else + eim.unregisterPlayer(player); +} + +function playerDisconnected(eim, player) { + if (eim.isEventTeamLackingNow(true, minPlayers, player)) { + eim.unregisterPlayer(player); + end(eim); + } + else + eim.unregisterPlayer(player); +} + +function leftParty(eim, player) { + if (eim.isEventTeamLackingNow(false, minPlayers, player)) { + eim.unregisterPlayer(player); + end(eim); + } + else + eim.unregisterPlayer(player); +} + +function disbandParty(eim) { + end(eim); +} + +function monsterValue(eim, mobId) { + return 1; +} + +function end(eim) { + var party = eim.getPlayers(); + for (var i = 0; i < party.size(); i++) { + playerExit(eim, party.get(i)); + } + eim.dispose(); +} + +function giveRandomEventReward(eim, player) { + eim.giveEventReward(player); } function clearPQ(eim) { - var party = eim.getPlayers(); - for (var i = 0; i < party.size(); i++) { - playerFinish(eim, party.get(i)); - } - eim.dispose(); + eim.stopEventTimer(); + eim.setEventCleared(); + + eim.warpEventTeam(809050016); } function monsterKilled(mob, eim) {} @@ -133,18 +189,3 @@ function allMonstersDead(eim) {} function cancelSchedule() {} function dispose(eim) {} - -function timeOut(eim) { - if (eim != null) { - if (eim.getPlayerCount() > 0) { - var pIter = eim.getPlayers().iterator(); - while (pIter.hasNext()) - playerExit(eim, pIter.next()); - } - eim.dispose(); - } -} - -function playerRevive(eim, player) { - -} \ No newline at end of file diff --git a/scripts/event/LudiPQ.js b/scripts/event/LudiPQ.js index 06b5d30063..8469542404 100644 --- a/scripts/event/LudiPQ.js +++ b/scripts/event/LudiPQ.js @@ -1,6 +1,6 @@ var isPq = true; -var minPlayers = 1, maxPlayers = 6; -var minLevel = 1, maxLevel = 200; +var minPlayers = 5, maxPlayers = 6; +var minLevel = 35, maxLevel = 50; var entryMap = 922010100; var exitMap = 922010000; var recruitMap = 221024500; @@ -9,6 +9,8 @@ var clearMap = 922011000; var minMapId = 922010100; var maxMapId = 922011100; +var eventTime = 45; // 45 minutes + var lobbyRange = [0, 0]; function init() { @@ -30,6 +32,9 @@ function setEventRequirements() { if(maxLevel - minLevel >= 1) reqStr += minLevel + " ~ " + maxLevel; else reqStr += minLevel; + reqStr += "\r\n Time limit: "; + reqStr += eventTime + " minutes"; + em.setProperty("party", reqStr); } @@ -85,33 +90,33 @@ function setup(level, lobbyid) { eim.setProperty("statusStg8", -1); eim.setProperty("statusStg9", -1); - eim.setInstanceMap(922010100).resetPQ(level); - eim.setInstanceMap(922010200).resetPQ(level); - eim.setInstanceMap(922010201).resetPQ(level); - eim.setInstanceMap(922010300).resetPQ(level); - eim.setInstanceMap(922010400).resetPQ(level); - eim.setInstanceMap(922010401).resetPQ(level); - eim.setInstanceMap(922010402).resetPQ(level); - eim.setInstanceMap(922010403).resetPQ(level); - eim.setInstanceMap(922010404).resetPQ(level); - eim.setInstanceMap(922010405).resetPQ(level); - eim.setInstanceMap(922010500).resetPQ(level); - eim.setInstanceMap(922010500).resetPQ(level); - eim.setInstanceMap(922010501).resetPQ(level); - eim.setInstanceMap(922010502).resetPQ(level); - eim.setInstanceMap(922010503).resetPQ(level); - eim.setInstanceMap(922010504).resetPQ(level); - eim.setInstanceMap(922010505).resetPQ(level); - eim.setInstanceMap(922010506).resetPQ(level); - eim.setInstanceMap(922010600).resetPQ(level); - eim.setInstanceMap(922010700).resetPQ(level); - eim.setInstanceMap(922010800).resetPQ(level); - eim.setInstanceMap(922010900).resetPQ(level); - eim.setInstanceMap(922011000).resetPQ(level); - eim.setInstanceMap(922011100).resetPQ(level); + eim.getInstanceMap(922010100).resetPQ(level); + eim.getInstanceMap(922010200).resetPQ(level); + eim.getInstanceMap(922010201).resetPQ(level); + eim.getInstanceMap(922010300).resetPQ(level); + eim.getInstanceMap(922010400).resetPQ(level); + eim.getInstanceMap(922010401).resetPQ(level); + eim.getInstanceMap(922010402).resetPQ(level); + eim.getInstanceMap(922010403).resetPQ(level); + eim.getInstanceMap(922010404).resetPQ(level); + eim.getInstanceMap(922010405).resetPQ(level); + eim.getInstanceMap(922010500).resetPQ(level); + eim.getInstanceMap(922010500).resetPQ(level); + eim.getInstanceMap(922010501).resetPQ(level); + eim.getInstanceMap(922010502).resetPQ(level); + eim.getInstanceMap(922010503).resetPQ(level); + eim.getInstanceMap(922010504).resetPQ(level); + eim.getInstanceMap(922010505).resetPQ(level); + eim.getInstanceMap(922010506).resetPQ(level); + eim.getInstanceMap(922010600).resetPQ(level); + eim.getInstanceMap(922010700).resetPQ(level); + eim.getInstanceMap(922010800).resetPQ(level); + eim.getInstanceMap(922010900).resetPQ(level); + eim.getInstanceMap(922011000).resetPQ(level); + eim.getInstanceMap(922011100).resetPQ(level); respawnStages(eim); - eim.startEventTimer(45 * 60000); //45 mins + eim.startEventTimer(eventTime * 60000); setEventRewards(eim); setEventExclusives(eim); return eim; diff --git a/scripts/event/PiratePQ.js b/scripts/event/PiratePQ.js index de515b02fd..f077674c7d 100644 --- a/scripts/event/PiratePQ.js +++ b/scripts/event/PiratePQ.js @@ -9,6 +9,8 @@ var clearMap = 925100600; var minMapId = 925100000; var maxMapId = 925100500; +var eventTime = 20; // 20 minutes + var lobbyRange = [0, 0]; function init() { @@ -30,6 +32,9 @@ function setEventRequirements() { if(maxLevel - minLevel >= 1) reqStr += minLevel + " ~ " + maxLevel; else reqStr += minLevel; + reqStr += "\r\n Time limit: "; + reqStr += eventTime + " minutes"; + em.setProperty("party", reqStr); } @@ -74,11 +79,11 @@ function setup(level, lobbyid) { eim.setProperty("stage5", "0"); eim.setProperty("openedChests", "0"); - eim.setInstanceMap(925100000).resetPQ(level); - eim.setInstanceMap(925100000).shuffleReactors(); + eim.getInstanceMap(925100000).resetPQ(level); + eim.getInstanceMap(925100000).shuffleReactors(); - eim.setInstanceMap(925100100).resetPQ(level); - var map = eim.setInstanceMap(925100200); + eim.getInstanceMap(925100100).resetPQ(level); + var map = eim.getInstanceMap(925100200); map.resetPQ(level); map.shuffleReactors(); for (var i = 0; i < 5; i++) { @@ -99,7 +104,7 @@ function setup(level, lobbyid) { map.spawnMonsterOnGroundBelow(mob3, new java.awt.Point(430, 238)); map.spawnMonsterOnGroundBelow(mob4, new java.awt.Point(1600, 238)); } - map = eim.setInstanceMap(925100201); + map = eim.getInstanceMap(925100201); map.resetPQ(level); for (var i = 0; i < 10; i++) { var mob = em.getMonster(9300112); @@ -111,8 +116,8 @@ function setup(level, lobbyid) { map.spawnMonsterOnGroundBelow(mob, new java.awt.Point(0, 238)); map.spawnMonsterOnGroundBelow(mob2, new java.awt.Point(1700, 238)); } - eim.setInstanceMap(925100202).resetPQ(level); - map = eim.setInstanceMap(925100300); + eim.getInstanceMap(925100202).resetPQ(level); + map = eim.getInstanceMap(925100300); map.resetPQ(level); map.shuffleReactors(); for (var i = 0; i < 5; i++) { @@ -133,7 +138,7 @@ function setup(level, lobbyid) { map.spawnMonsterOnGroundBelow(mob3, new java.awt.Point(430, 238)); map.spawnMonsterOnGroundBelow(mob4, new java.awt.Point(1600, 238)); } - map = eim.setInstanceMap(925100301); + map = eim.getInstanceMap(925100301); map.resetPQ(level); for (var i = 0; i < 10; i++) { var mob = em.getMonster(9300112); @@ -145,13 +150,13 @@ function setup(level, lobbyid) { map.spawnMonsterOnGroundBelow(mob, new java.awt.Point(0, 238)); map.spawnMonsterOnGroundBelow(mob2, new java.awt.Point(1700, 238)); } - eim.setInstanceMap(925100302).resetPQ(level); - eim.setInstanceMap(925100400).resetPQ(level); - eim.setInstanceMap(925100500).resetPQ(level); + eim.getInstanceMap(925100302).resetPQ(level); + eim.getInstanceMap(925100400).resetPQ(level); + eim.getInstanceMap(925100500).resetPQ(level); respawnStg4(eim); - eim.startEventTimer(20 * 60000); //20 mins + eim.startEventTimer(eventTime * 60000); setEventRewards(eim); setEventExclusives(eim); return eim; diff --git a/scripts/event/s4aWorld.js b/scripts/event/s4aWorld.js index c02ce36be4..ad3bacd9e4 100644 --- a/scripts/event/s4aWorld.js +++ b/scripts/event/s4aWorld.js @@ -15,7 +15,7 @@ function monsterValue(eim, mobId) { function setup() { var eim = em.newInstance("s4aWorld"); - eim.setInstanceMap(910500000).resetFully(); + eim.getInstanceMap(910500000).resetFully(); eim.startEventTimer(1200000); em.setProperty("started", "true"); diff --git a/scripts/npc/world0/1012112.js b/scripts/npc/world0/1012112.js index 688791cd55..8be4481649 100644 --- a/scripts/npc/world0/1012112.js +++ b/scripts/npc/world0/1012112.js @@ -20,9 +20,73 @@ along with this program. If not, see . */ /** - * @author BubblesDev + * @author BubblesDev, Ronan * @NPC Tory */ + +var status = 0; +var em = null; + +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) { + em = cm.getEventManager("HenesysPQ"); + if(em == null) { + cm.sendOk("The Henesys PQ has encountered an error."); + cm.dispose(); + 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."); + } 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 { + 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(); + } + } + } +} + +/* var status = 0; var chosen = 0; var min = 3; @@ -142,4 +206,5 @@ function action(mode, type, selection) { } } } -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/scripts/npc/world0/2040034.js b/scripts/npc/world0/2040034.js index 1eafdb15c1..3195432b52 100644 --- a/scripts/npc/world0/2040034.js +++ b/scripts/npc/world0/2040034.js @@ -46,14 +46,9 @@ function action(mode, type, selection) { } else { var eli = em.getEligibleParty(cm.getParty()); if(eli.size() > 0) { - if(!em.startInstance(0, cm.getParty(), cm.getPlayer().getMap(), 1)) { + if(!em.startInstance(cm.getParty(), cm.getPlayer().getMap(), 1)) { cm.sendOk("Another party has already entered the #rParty Quest#k in this channel. Please try another channel, or wait for the current party to finish."); } - /* - else { - cm.gainItem(4001022, 200); - } - */ } 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."); diff --git a/scripts/npc/world0/2040035.js b/scripts/npc/world0/2040035.js index 8f1a737c61..15006c97f0 100644 --- a/scripts/npc/world0/2040035.js +++ b/scripts/npc/world0/2040035.js @@ -45,7 +45,7 @@ function action(mode, type, selection) { var eim = cm.getEventInstance(); if(!eim.giveEventReward(cm.getPlayer())) { - cm.sendNext("It seems you don't have a free slot in your #rEquip#k, #rUse#k or #rEtc#k inventories. Please make room and try again."); + cm.sendNext("It seems you don't have a free slot in either your #rEquip#k, #rUse#k or #rEtc#k inventories. Please make room and try again."); } else { cm.warp(221024500); } diff --git a/scripts/npc/world0/2040036.js b/scripts/npc/world0/2040036.js index a1afa5665e..f6e545d0dc 100644 --- a/scripts/npc/world0/2040036.js +++ b/scripts/npc/world0/2040036.js @@ -73,7 +73,7 @@ function action(mode, type, selection) { } else { // check stage completion if (cm.haveItem(4001022, 25)) { - cm.sendOk("Good job! you have collected all 25 #b#t4001022#'s.#k"); + cm.sendOk("Good job! You have collected all 25 #b#t4001022#'s.#k"); cm.gainItem(4001022, -25); eim.setProperty("statusStg" + stage, 1); diff --git a/scripts/npc/world0/2040037.js b/scripts/npc/world0/2040037.js index af86013370..d9cc41273d 100644 --- a/scripts/npc/world0/2040037.js +++ b/scripts/npc/world0/2040037.js @@ -73,7 +73,7 @@ function action(mode, type, selection) { } else { // check stage completion if (cm.haveItem(4001022, 15)) { - cm.sendOk("Good job! you have collected all 15 #b#t4001022#'s.#k"); + cm.sendOk("Good job! You have collected all 15 #b#t4001022#'s.#k"); cm.gainItem(4001022, -15); eim.setProperty("statusStg" + stage, 1); diff --git a/scripts/npc/world0/2040038.js b/scripts/npc/world0/2040038.js index 18476d2f7b..4b928d6f36 100644 --- a/scripts/npc/world0/2040038.js +++ b/scripts/npc/world0/2040038.js @@ -73,7 +73,7 @@ function action(mode, type, selection) { } else { // check stage completion if (cm.haveItem(4001022, 32)) { - cm.sendOk("Good job! you have collected all 32 #b#t4001022#'s.#k"); + cm.sendOk("Good job! You have collected all 32 #b#t4001022#'s.#k"); cm.gainItem(4001022, -32); eim.setProperty("statusStg" + stage, 1); diff --git a/scripts/npc/world0/2040039.js b/scripts/npc/world0/2040039.js index cd29a61e60..63cd9ea51f 100644 --- a/scripts/npc/world0/2040039.js +++ b/scripts/npc/world0/2040039.js @@ -73,7 +73,7 @@ function action(mode, type, selection) { } else { // check stage completion if (cm.haveItem(4001022, 6)) { - cm.sendOk("Good job! you have collected all 6 #b#t4001022#'s.#k"); + cm.sendOk("Good job! You have collected all 6 #b#t4001022#'s.#k"); cm.gainItem(4001022, -6); eim.setProperty("statusStg" + stage, 1); diff --git a/scripts/npc/world0/2040040.js b/scripts/npc/world0/2040040.js index 815ace14e2..0c95cae66d 100644 --- a/scripts/npc/world0/2040040.js +++ b/scripts/npc/world0/2040040.js @@ -73,7 +73,7 @@ function action(mode, type, selection) { } else { // check stage completion if (cm.haveItem(4001022, 24)) { - cm.sendOk("Good job! you have collected all 24 #b#t4001022#'s.#k"); + cm.sendOk("Good job! You have collected all 24 #b#t4001022#'s.#k"); cm.gainItem(4001022, -24); eim.setProperty("statusStg" + stage, 1); diff --git a/scripts/npc/world0/2040042.js b/scripts/npc/world0/2040042.js index aa8fabb313..75595b99d5 100644 --- a/scripts/npc/world0/2040042.js +++ b/scripts/npc/world0/2040042.js @@ -76,7 +76,7 @@ function action(mode, type, selection) { } else if(state == 0) { // check stage completion if (cm.haveItem(4001022, 3)) { - cm.sendOk("Good job! you have collected all 3 #b#t4001022#'s.#k"); + cm.sendOk("Good job! You have collected all 3 #b#t4001022#'s.#k"); cm.gainItem(4001022, -3); eim.setProperty("statusStg" + stage, 1); diff --git a/scripts/npc/world0/2094000.js b/scripts/npc/world0/2094000.js index a00f71666b..51062545b2 100644 --- a/scripts/npc/world0/2094000.js +++ b/scripts/npc/world0/2094000.js @@ -46,7 +46,7 @@ function action(mode, type, selection) { } else { var eli = em.getEligibleParty(cm.getParty()); if(eli.size() > 0) { - if(!em.startInstance(0, cm.getParty(), cm.getPlayer().getMap(), 1)) { + if(!em.startInstance(cm.getParty(), cm.getPlayer().getMap(), 1)) { cm.sendOk("Another party has already entered the #rParty Quest#k in this channel. Please try another channel, or wait for the current party to finish."); } } diff --git a/scripts/npc/world0/2133000.js b/scripts/npc/world0/2133000.js index 746f26a7a3..cbbcf62708 100644 --- a/scripts/npc/world0/2133000.js +++ b/scripts/npc/world0/2133000.js @@ -46,7 +46,7 @@ function action(mode, type, selection) { } else { var eli = em.getEligibleParty(cm.getParty()); if(eli.size() > 0) { - if(!em.startInstance(0, cm.getParty(), cm.getPlayer().getMap(), 1)) { + if(!em.startInstance(cm.getParty(), cm.getPlayer().getMap(), 1)) { cm.sendOk("Another party has already entered the #rParty Quest#k in this channel. Please try another channel, or wait for the current party to finish."); } } diff --git a/scripts/npc/world0/9000037.js b/scripts/npc/world0/9000037.js index 0e739a6f11..9658041cb8 100644 --- a/scripts/npc/world0/9000037.js +++ b/scripts/npc/world0/9000037.js @@ -17,6 +17,28 @@ function isFinalBossDone() { return cm.getMapId() >= 970032700 && cm.getMapId() < 970032800 && cm.getMap().getMonsters().isEmpty(); } +function detectTeamLobby(team) { + var midLevel = 0; + + for(var i = 0; i < team.size(); i++) { + var player = team.get(i); + midLevel += player.getLevel(); + } + midLevel = Math.floor(midLevel / team.size()); + + var lobby; // teams low level can be allocated at higher leveled lobbys + if(midLevel <= 20) lobby = 0; + else if(midLevel <= 40) lobby = 1; + else if(midLevel <= 60) lobby = 2; + else if(midLevel <= 80) lobby = 3; + else if(midLevel <= 90) lobby = 4; + else if(midLevel <= 100) lobby = 5; + else if(midLevel <= 110) lobby = 6; + else lobby = 7; + + return lobby; +} + function start() { status = -1; state = (cm.getMapId() >= 970030001 && cm.getMapId() <= 970042711) ? (!onRestingSpot() ? (isFinalBossDone() ? 3 : 1) : 2) : 0; @@ -91,7 +113,9 @@ function action(mode, type, selection) { cm.dispose(); } else if(state == 2) { var restSpot = ((cm.getMapId() - 1) % 5) + 1; + cm.getPlayer().getEventInstance().addEventTimer(restSpot * 4 * 60000); // adds (restspot number * 4) minutes cm.getPlayer().getEventInstance().warpEventTeam(970030100 + cm.getEventInstance().getIntProperty("lobby") + (500 * restSpot)); + cm.dispose(); } else if(state == 1) { cm.warp(970030000); @@ -108,7 +132,12 @@ function action(mode, type, selection) { } else { var eli = em.getEligibleParty(cm.getParty()); if(eli.size() > 0) { - if(!em.startInstance(0, cm.getParty(), cm.getPlayer().getMap(), 1)) { + var lobby = detectTeamLobby(eli), i; + for(i = lobby; i < 8; i++) { + if(em.startInstance(i, cm.getParty(), cm.getPlayer().getMap(), 1)) break; + } + + if(i == 8) { cm.sendOk("Another party has already entered the #rParty Quest#k in this channel. Please try another channel, or wait for the current party to finish."); } } @@ -122,7 +151,7 @@ function action(mode, type, selection) { cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!"); cm.dispose(); } else { - cm.sendOk("#e#b#k#n\r\nBrave adventurers from all over the places travels here to test their skills and abilities in combat, as they face even more powerful bosses from MapleStory. Join forces with fellow adventurers or face all the burden by yourself and receive all the glory, it is up to you. REWARDS are given accordingly to how far the adventurers reach and extra prizes may are given to a random member of the party, all attributed at the end of an expedition."); + cm.sendOk("#e#b#k#n\r\nBrave adventurers from all over the places travels here to test their skills and abilities in combat, as they face even more powerful bosses from MapleStory. Join forces with fellow adventurers or face all the burden by yourself and receive all the glory, it is up to you. REWARDS are given accordingly to how far the adventurers reach and extra prizes may are given to a random member of the party, all attributed at the end of an expedition.\r\n\r\nThis event also supports #bmultiple lobbies for matchmaking several ranges of team levels#k at once: team up with players with lower level if you want better chances to swiftly set up a boss rush for your team."); cm.dispose(); } } diff --git a/scripts/npc/world0/9000038.js b/scripts/npc/world0/9000038.js index c73915332d..b477674518 100644 --- a/scripts/npc/world0/9000038.js +++ b/scripts/npc/world0/9000038.js @@ -7,10 +7,10 @@ var status; -var itemSet_lv6 = [1122018, 1122005, 1022088, 1402013, 1032048, 1032070, 1102046, 2330004, 2041013, 2041016, 2041019, 2041022, 2049100, 2049003, 2020012, 2020013, 2020014, 2020015, 2022029, 2022045, 2022068, 2022069, 2022179, 2022180, 4004000, 4004001, 4004002, 4004003, 4004004, 4003000]; +var itemSet_lv6 = [1122018, 1122005, 1022088, 1402013, 1032030, 1032070, 1102046, 2330004, 2041013, 2041016, 2041019, 2041022, 2049100, 2049003, 2020012, 2020013, 2020014, 2020015, 2022029, 2022045, 2022068, 2022069, 2022179, 2022180, 4004000, 4004001, 4004002, 4004003, 4004004, 4003000]; var itemQty_lv6 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 25, 25, 25, 25, 25, 25, 25, 4, 4, 12, 12, 12, 12, 12, 25]; -var itemSet_lv5 = [1122018, 1122005, 1022088, 1402013, 1032048, 1032070, 1102046, 2330004, 2041013, 2041016, 2041019, 2041022, 2049100, 2049003, 2020012, 2020013, 2020014, 2020015, 2022029, 2022045, 2022068, 2022069, 2022179, 2022180, 4004000, 4004001, 4004002, 4004003, 4004004, 4003000]; +var itemSet_lv5 = [1122018, 1122005, 1022088, 1402013, 1032030, 1032070, 1102046, 2330004, 2041013, 2041016, 2041019, 2041022, 2049100, 2049003, 2020012, 2020013, 2020014, 2020015, 2022029, 2022045, 2022068, 2022069, 2022179, 2022180, 4004000, 4004001, 4004002, 4004003, 4004004, 4003000]; var itemQty_lv5 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 8, 8, 8, 8, 8, 12]; var itemSet_lv4 = [1122001, 1122006, 1022103, 1442065, 1032042, 1032021, 1102168, 2070005, 2040025, 2040029, 2040301, 2040413, 2040701, 2040817, 2002028, 2020009, 2020010, 2020011, 2022004, 2022005, 2022025, 2022027, 2022048, 2022049, 4020000, 4020001, 4020002, 4020003, 4020004, 4020005, 4020006, 4020007, 4020008, 4003000]; diff --git a/scripts/npc/world0/9020000.js b/scripts/npc/world0/9020000.js index 366a744296..b60eee316e 100644 --- a/scripts/npc/world0/9020000.js +++ b/scripts/npc/world0/9020000.js @@ -57,7 +57,7 @@ function action(mode, type, selection) { } else { var eli = em.getEligibleParty(cm.getParty()); if(eli.size() > 0) { - if(!em.startInstance(0, cm.getParty(), cm.getPlayer().getMap(), 1)) { + if(!em.startInstance(cm.getParty(), cm.getPlayer().getMap(), 1)) { cm.sendOk("Another party has already entered the #rParty Quest#k in this channel. Please try another channel, or wait for the current party to finish."); } } diff --git a/scripts/npc/world0/9103000.js b/scripts/npc/world0/9103000.js index c1ce008b85..869ed6d58d 100644 --- a/scripts/npc/world0/9103000.js +++ b/scripts/npc/world0/9103000.js @@ -20,60 +20,60 @@ along with this program. If not, see . */ /* - *@Author RMZero213 - * Ludibrium Maze Party Quest - * Do not release anywhere other than RaGEZONE. Give credit if used. - */ +* Author : Raz, Ronan +* +* NPC = 9103000 - Pierre +* Map = Ludibrium - Ludibrium Maze 16 +* NPC MapId = 809050015 +* Function = Gives LMPQ EXP reward +* +*/ var status = 0; -var minimumCouponsNeeded = 200; +var qty = 0; + function start() { status = -1; - action(1,0,0); + action(1, 0, 0); } -function action(mode, type, selection){ - if (mode == -1|| (mode == 0 && status == 0)) - cm.dispose(); - else { - if (mode == 1) - status++; - else - status--; - if (status == 0) { - if (!isLeader()) { - cm.sendOk("Give any coupons to the leader of the party and tell them to talk to me."); +function action(mode, type, selection) { + if (mode == -1) { cm.dispose(); - } else { - cm.sendYesNo("Do you have all the coupons of the party and would like to get out of here?"); - } - } else if (status == 1) { - if (cm.itemQuantity(4001106) < minimumCouponsNeeded){ - cm.sendOk("Sorry, but you do not have at least " + minimumCouponsNeeded + " coupons! Talk to me again when you've collected more!"); - cm.dispose(); - return; - } - var party = cm.getPartyMembers(); - for (var i = 0; i < party.size(); i++) { - if (party.get(i).getMap().getId() != 809050015) { - cm.sendOk("A member of your party is not presently in the map."); - cm.dispose(); - return; + } else { + if (mode == 0 && status == 0) { + cm.dispose(); + return; } - } - var members = cm.getPlayer().getEventInstance().getPlayers(); - //cm.removeFromParty(4001106, members); - cm.gainItem(4001106, -200); - cm.givePartyExp("LudiMazePQ"); - cm.warpParty(809050016); - cm.dispose(); - } - } -} - -function isLeader(){ - if(cm.getParty() == null) - return false; - else - return cm.isLeader(); + if (mode == 1) + status++; + else + status--; + + if (status == 0) { + if(cm.isLeader()) { + if(!cm.getEventInstance().isEventTeamTogether()) { + cm.sendOk("One or more event team members is missing, please wait for them to reach here first."); + cm.dispose(); + } + else if(cm.hasItem(4001106, 30)) { + qty = cm.getItemQuantity(4001106); + cm.sendYesNo("Splendid! You have retrieved " + qty + " #t4001106# from this run, now your team will receive the fair amount of EXP from this action. Are you ready to get transported out?"); + } + else { + cm.sendOk("Your party cannot finish this PQ yet, as you have not reached the minimum of 30 #t4001106#'s in hand yet."); + cm.dispose(); + } + } + else { + cm.sendOk("Let your party leader talk to me to end this quest."); + cm.dispose(); + } + } else if(status == 1) { + cm.removeAll(4001106); + cm.getEventInstance().giveEventPlayersExp(50 * qty); + cm.getEventInstance().clearPQ(); + cm.dispose(); + } + } } \ No newline at end of file diff --git a/scripts/npc/world0/9103001.js b/scripts/npc/world0/9103001.js index 3fd9fc5e86..27891371f3 100644 --- a/scripts/npc/world0/9103001.js +++ b/scripts/npc/world0/9103001.js @@ -20,22 +20,16 @@ along with this program. If not, see . */ /* -@ Author : Raz -@ -@ NPC = 9103001 - Rolly -@ Map = Ludibrium - -@ NPC MapId = 220000000 -@ Function = Start LMPQ -@ +* Author : Raz, Ronan +* +* NPC = 9103001 - Rolly +* Map = Ludibrium - +* NPC MapId = 220000000 +* Function = Start LMPQ +* */ var status = 0; -var minlvl = 51; -var maxlvl = 200; -var minplayers = 3; -var maxplayers = 6; -var time = 15; -var open = true; function start() { status = -1; @@ -43,97 +37,55 @@ function start() { } function action(mode, type, selection) { - if (mode == -1) { - cm.dispose(); - } else if (mode == 0) { - cm.dispose(); - } else { - if (mode == 1) - status++; - else - status--; - - if (status == 0) { - cm.sendSimple("This is the entrance to the Ludibrium Maze. Enjoy!\r\n#b#L0#Enter the Lubidrium Maze#l\r\n#L1#What is the Ludibrium Maze?"); - - } else if (status == 1) { - var em = cm.getEventManager("LudiMazePQ"); - if(selection == 0) {//ENTER THE PQ - if (!hasParty()) {//NO PARTY - cm.sendOk("Try taking on the Maze Quest with your party. If you DO decide to tackle it, please have your Party Leader notify me!"); - } else if (!isLeader()) {//NOT LEADER - cm.sendOk("Try taking on the Maze Quest with your party. If you DO decide to tackle it, please have your Party Leader notify me!"); - } else if (!checkPartySize()) {//PARTY SIZE WRONG - cm.sendOk("Your party needs to consist of at least " + minplayers + " members in order to tackle this maze"); - } else if (!checkPartyLevels()) {//WRONG LEVELS - cm.sendOk("One of your party members has not met the level requirements of " + minlvl + "~" + maxlvl + "."); - } else if (em == null) {//EVENT ERROR - cm.sendOk("ERROR IN EVENT"); - } else if (!open){ - cm.sendOk("The PQ is #rclosed#k for now."); - } else { - if(!em.startInstance(cm.getParty(), cm.getPlayer().getMap())) { - cm.sendOk("A party in your name is already registered in this event."); + if (mode == -1) { + cm.dispose(); + } else { + if (mode == 0 && status == 0) { cm.dispose(); return; - } - var party = cm.getPlayer().getEventInstance().getPlayers(); - cm.removeFromParty(4001106, party); } - cm.dispose(); - } else if(selection == 1) { - cm.sendOk("This maze is available to all parties of " + minplayers + " or more members, and all participants must be between Level " + minlvl + "~" + maxlvl + ". You will be given " + time + " minutes to escape the maze. At the center of the room, there will be a Warp Portal set up to transport you to a different room. These portals will transport you to other rooms where you'll (hopefully) find the exit. Pietri will be waiting at the exit, so all you need to do is talk to him, and he'll let you out. Break all the boxes located in the room, and a monster inside the box will drop a coupon. After escaping the maze, you will be awarded with EXP based on the coupons collected. Additionally, if the leader possesses at least 200 coupons, then a special gift will be presented to the party. If you cannot escape the maze within the allotted " + time +" minutes, you will receive 0 EXP for your time in the maze. If you decide to log off while you're in the maze, you will be automatically kicked out of the maze. Even if the members of the party leave in the middle of the quest, the remaining members will be able to continue on with the quest. If you are in critical condition and unable to hunt down the monsters, you may avoid them to save yourself. Your fighting spirit and wits will be tested! Good luck!"); - cm.dispose(); - } + if (mode == 1) + status++; + else + status--; + + if (status == 0) { + em = cm.getEventManager("LudiMazePQ"); + if(em == null) { + cm.sendOk("The Ludibrium Maze PQ has encountered an error."); + cm.dispose(); + return; + } + + cm.sendSimple("#e#b\r\n#k#n" + em.getProperty("party") + "\r\n\r\nThis is the entrance to the Ludibrium Maze. Enjoy!\r\n#b#L0#Enter the Lubidrium Maze#l\r\n#L1#I want to find party members.\r\n#L2#What is the Ludibrium Maze?"); + } else if (status == 1) { + if (selection == 0) { + if (cm.getParty() == null) { + cm.sendOk("Try taking on the Maze Quest with your party."); + cm.dispose(); + } else if(!cm.isLeader()) { + cm.sendOk("If you DO decide to tackle it, please have your Party Leader notify me!"); + cm.dispose(); + } else { + var eli = em.getEligibleParty(cm.getParty()); + if(eli.size() > 0) { + if(!em.startInstance(cm.getParty(), cm.getPlayer().getMap(), 1)) { + cm.sendOk("Another party has already entered the #rParty Quest#k in this channel. Please try another channel, or wait for the current party to finish."); + } + } + else { + cm.sendOk("Your party needs to consist of at least 3 members in order to tackle this maze."); + } + + cm.dispose(); + } + } else if (selection == 1) { + cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!"); + cm.dispose(); + } else { + cm.sendOk("#e#b#k#n\r\nThis maze is available to all parties of 3 or more members, and all participants must be between Level 51~70. You will be given 15 minutes to escape the maze. At the center of the room, there will be a Warp Portal set up to transport you to a different room. These portals will transport you to other rooms where you'll (hopefully) find the exit. Pietri will be waiting at the exit, so all you need to do is talk to him, and he'll let you out. Break all the boxes located in the room, and a monster inside the box will drop a coupon. After escaping the maze, you will be awarded with EXP based on the coupons collected. Additionally, if the leader possesses at least 30 coupons, then a special gift will be presented to the party. If you cannot escape the maze within the allotted 15 minutes, you will receive 0 EXP for your time in the maze. If you decide to log off while you're in the maze, you will be automatically kicked out of the maze. Even if the members of the party leave in the middle of the quest, the remaining members will be able to continue on with the quest, except if they run out of the minimum amount of party members in the maze. If you are in critical condition and unable to hunt down the monsters, you may avoid them to save yourself. Your fighting spirit and wits will be tested! Good luck!"); + cm.dispose(); + } + } } - } -} - -function getPartySize(){ - if(cm.getPlayer().getParty() == null){ - return 0; - }else{ - return (cm.getPlayer().getParty().getMembers().size()); - } -} - -function isLeader(){ - return cm.isLeader(); -} - -function checkPartySize(){ - var size = 0; - if(cm.getPlayer().getParty() == null){ - size = 0; - }else{ - size = (cm.getPlayer().getParty().getMembers().size()); - } - if(size < minplayers || size > maxplayers){ - return false; - }else{ - return true; - } -} - -function checkPartyLevels(){ - var pass = true; - var party = cm.getPlayer().getParty().getMembers(); - if(cm.getPlayer().getParty() == null){ - pass = false; - }else{ - for (var i = 0; i < party.size() && pass; i++) { - if ((party.get(i).getLevel() < minlvl) || (party.get(i).getLevel() > maxlvl) || (party.get(i).getPlayer().getMapId() != cm.getPlayer().getMapId())) { - pass = false; - } - } - } - return pass; -} - -function hasParty(){ - if(cm.getPlayer().getParty() == null){ - return false; - }else{ - return true; - } } \ No newline at end of file diff --git a/scripts/npc/world0/9103002.js b/scripts/npc/world0/9103002.js index 22e7f178e2..1aada5cea9 100644 --- a/scripts/npc/world0/9103002.js +++ b/scripts/npc/world0/9103002.js @@ -20,61 +20,13 @@ along with this program. If not, see . */ /* - *@Author RMZero213 - * Ludibrium Maze Party Quest - * Do not release anywhere other than RaGEZONE. Give credit if used. + *@Author Ronan + * Rolly + * Ludibrium - Exit of the Maze (809050016) + * Gives Ludibrium Maze Party Quest reward */ var status = 0; -var rewards = new Array( - 1442017, 1, //Blood Snowboard - 1322025, 1, //Emergency Rescue Tube - 1032013, 1, //Red-Hearted Earrings - 1302016, 1, //Yellow Umbrella - 1072263, 1, //Green Strap Shoes - 1032043, 1, //Cecelia's Earrings - 2000005, 1, //Power Elixir - 2000004, 5, //Elixir - 2001001, 5, //Ice Cream Pop - 2001002, 5, //Red Bean Sundae - 2020008, 20, //Fat Sausage - 2020010, 20, //Grape Juice - 2030008, 20, //Coffee Milk - 2030010, 20, //Fruit Milk - 2030009, 20, //Strawberry Milk - 2022000, 50, //Pure Water - 2001000, 50, //Watermelon - 2022019, 50, //Kinoko Ramen (Pig Head) - 2020007, 100, //Dried Squid - 2020006, 100, //Hot Dog Supreme - 2020009, 100, //Orange Juice - 2000006, 100, //Mana Elixir - 2040601, 1, //Scroll for Bottomwear for Def (60%) - 2040605, 1, //Dark Scroll for Bottomwear for DEF 30% - 2040602, 1, //Scroll for Bottomwear for DEF (10%) - 2041027, 1, //Dark Scroll for Cape for Magic Def 30% - 2041028, 1, //Dark Scroll for Cape for Weapon Def 70% - 2041004, 1, //Scroll for Cape for Weapon Def 60% - 2041029, 1, //Dark Scroll for Cape for Weapon Def 30% - 2041017, 1, //Scroll for Cape for INT 10% - 2041020, 1, //Scroll for Cape for DEX 10% - 2040008, 1, //Dark Scroll for Helmet for DEF 70% - 2040001, 1, //Scroll for Helmet for DEF 60% - 2040009, 1, //Dark Scroll for Helmet for DEF 30% - 2040002, 1, //Scroll for Helmet for DEF 10% - 2040504, 1, //Scroll for Overall Armor for DEF 60% - 2040511, 1, //Dark Scroll for Overall Armor for DEF 30% - 2040505, 1, //Scroll for Overall Armor for DEF 10% - 2040501, 1, //Scroll for Overall Armor for DEX 60% - 2040904, 1, //Dark Scroll for Shield for DEF 70% - 2040901, 1, //Scroll for Shield for DEF 60% - 2040905, 1, //Dark Scroll for Shield for DEF 30% - 2040902, 1, //Scroll for Shield for DEF 10% - 2040404, 1, //Dark Scroll for Topwear for DEF 70% - 2040401, 1, //Scroll for Topwear for DEF 60% - 2040405, 1, //Dark Scroll for Topwear for DEF 30% - 2040402, 1 //Scroll for Topwear for DEF 10% - ); function start() { status = -1; @@ -94,28 +46,17 @@ function action(mode, type, selection){ else status--; if (status == 0) { - var index = Math.floor(Math.random()*rewards.length); - var reward; - var quantity; - if (index % 2 == 0){ //The index was an item id - reward = rewards[index]; - quantity = rewards[index + 1]; - } else { - reward = rewards[index - 1]; - quantity = rewards[index]; - } - if(!cm.canHold(reward)){ - cm.sendOk("Please make space in your inventory!"); - return; - } - cm.gainItem(reward, quantity); - var eim = cm.getPlayer().getEventInstance(); - if (eim != null) { - eim.unregisterPlayer(cm.getPlayer()); - } - cm.warp(220000000, 0); - cm.gainItem(4001106, -cm.itemQuantity(4001106)) - cm.dispose(); + cm.sendYesNo("Your party gave a stellar effort and gathered up at least 30 coupons. For that, I have a present for each and every one of you. After receiving the present, you will be sent back to Ludibrium. Now, would you like to receive the present right now?"); + } else if(status == 1) { + var eim = cm.getEventInstance(); + + if(!eim.giveEventReward(cm.getPlayer())) { + cm.sendNext("It seems you don't have a free slot in either your #rEquip#k, #rUse#k or #rEtc#k inventories. Please make room and try again."); + } else { + cm.warp(809050017); + } + + cm.dispose(); } } } \ No newline at end of file diff --git a/scripts/npc/world0/9103003.js b/scripts/npc/world0/9103003.js index 2fd6aa2146..f89a83d54f 100644 --- a/scripts/npc/world0/9103003.js +++ b/scripts/npc/world0/9103003.js @@ -20,21 +20,34 @@ along with this program. If not, see . */ /* - *@Author SharpAceX (Alan) + *@Author Ronan * Ludibrium Maze Party Quest */ var status = 0; function start() { status = -1; - action(1,0,0); + action(1, 0, 0); } function action(mode, type, selection){ - var eim = cm.getPlayer().getEventInstance(); - if (eim != null) { - eim.unregisterPlayer(cm.getPlayer()); - } - cm.warp(220000000, 0); - cm.dispose(); -} \ No newline at end of file + if (mode == -1) { + cm.dispose(); + } else { + if (mode == 0 && status == 0) { + cm.dispose(); + return; + } + if (mode == 1) + status++; + else + status--; + + if (status == 0) { + cm.sendNext("Come this way to return to Ludibrium."); + } else { + cm.warp(220000000, 0); + cm.dispose(); + } + } +} diff --git a/sql/db_drops.sql b/sql/db_drops.sql index 304da9c821..cf708d1e7a 100644 --- a/sql/db_drops.sql +++ b/sql/db_drops.sql @@ -19109,6 +19109,9 @@ # remove key of dimension dropping outside PQ DELETE FROM drop_data where itemid=4001023 and dropperid!=9300012; + # make Sword Earrings not drop by normal means, just like Shield Earrings + DELETE FROM drop_data where itemid=1032030; + # remove every not-card drop from bosses out of their natural habitat DELETE FROM drop_data WHERE dropperid >= 9300184 AND dropperid < 9300215 AND (itemid < 2380000 OR itemid >= 2390000); DELETE FROM drop_data WHERE dropperid >= 9500337 AND dropperid < 9500364 AND (itemid < 2380000 OR itemid >= 2390000); diff --git a/src/scripting/AbstractPlayerInteraction.java b/src/scripting/AbstractPlayerInteraction.java index fdb172aeb8..d172a5ddca 100644 --- a/src/scripting/AbstractPlayerInteraction.java +++ b/src/scripting/AbstractPlayerInteraction.java @@ -182,6 +182,10 @@ public class AbstractPlayerInteraction { public boolean haveItem(int itemid, int quantity) { return getPlayer().getItemQuantity(itemid, false) >= quantity; } + + public int getItemQuantity(int itemid) { + return getPlayer().getItemQuantity(itemid, false); + } public boolean canHold(int itemid) { return canHold(itemid, 1); diff --git a/src/scripting/event/EventInstanceManager.java b/src/scripting/event/EventInstanceManager.java index a6529a5204..53d524d25e 100644 --- a/src/scripting/event/EventInstanceManager.java +++ b/src/scripting/event/EventInstanceManager.java @@ -552,7 +552,7 @@ public class EventInstanceManager { return (chr.getParty().getLeaderId() == chr.getId()); } - public final MapleMap setInstanceMap(final int mapid) { //gets instance map from the channelserv + public final MapleMap getInstanceMap(final int mapid) { //gets instance map from the channelserv if (disposed) { return getMapFactory().getMap(mapid); } diff --git a/src/scripting/event/EventManager.java b/src/scripting/event/EventManager.java index 932804379b..6ac3e53a1f 100644 --- a/src/scripting/event/EventManager.java +++ b/src/scripting/event/EventManager.java @@ -183,6 +183,15 @@ public class EventManager { return Integer.parseInt(props.getProperty(key)); } + private boolean getLockLobby(int lobbyId) { + l.lock(); + try { + return openedLobbys.get(lobbyId); + } finally { + l.unlock(); + } + } + private void setLockLobby(int lobbyId, boolean lock) { l.lock(); try { @@ -243,10 +252,14 @@ public class EventManager { //Expedition method: starts an expedition public boolean startInstance(int lobbyId, MapleExpedition exped) { try { - if(lobbyId > -1) { + if(lobbyId == -1) { lobbyId = availableLobbyInstance(); if(lobbyId == -1) return false; } + else { + if(getLockLobby(lobbyId)) return false; + startLobbyInstance(lobbyId); + } EventInstanceManager eim = (EventInstanceManager) (iv.invokeFunction("setup", (Object) null)); if(eim == null) { @@ -271,10 +284,14 @@ public class EventManager { public boolean startInstance(int lobbyId, MapleCharacter chr) { try { - if(lobbyId > -1) { + if(lobbyId == -1) { lobbyId = availableLobbyInstance(); if(lobbyId == -1) return false; } + else { + if(getLockLobby(lobbyId)) return false; + startLobbyInstance(lobbyId); + } EventInstanceManager eim = (EventInstanceManager) (iv.invokeFunction("setup", (Object) null)); if(eim == null) { @@ -298,10 +315,14 @@ public class EventManager { public boolean startInstance(int lobbyId, MapleParty party, MapleMap map) { try { - if(lobbyId > -1) { + if(lobbyId == -1) { lobbyId = availableLobbyInstance(); if(lobbyId == -1) return false; } + else { + if(getLockLobby(lobbyId)) return false; + startLobbyInstance(lobbyId); + } EventInstanceManager eim = (EventInstanceManager) (iv.invokeFunction("setup", (Object) null)); if(eim == null) { @@ -326,10 +347,14 @@ public class EventManager { public boolean startInstance(int lobbyId, MapleParty party, MapleMap map, int difficulty) { try { - if(lobbyId > -1) { + if(lobbyId == -1) { lobbyId = availableLobbyInstance(); if(lobbyId == -1) return false; } + else { + if(getLockLobby(lobbyId)) return false; + startLobbyInstance(lobbyId); + } EventInstanceManager eim = (EventInstanceManager) (iv.invokeFunction("setup", difficulty, (lobbyId > -1) ? lobbyId : party.getLeaderId())); if(eim == null) { @@ -354,10 +379,14 @@ public class EventManager { public boolean startInstance(int lobbyId, EventInstanceManager eim, String leader) { try { - if(lobbyId > -1) { + if(lobbyId == -1) { lobbyId = availableLobbyInstance(); if(lobbyId == -1) return false; } + else { + if(getLockLobby(lobbyId)) return false; + startLobbyInstance(lobbyId); + } if(eim == null) { if(lobbyId > -1) setLockLobby(lobbyId, false); diff --git a/wz/Character.wz/Accessory/01032030.img.xml b/wz/Character.wz/Accessory/01032030.img.xml index 509262973e..871ded8a5e 100644 --- a/wz/Character.wz/Accessory/01032030.img.xml +++ b/wz/Character.wz/Accessory/01032030.img.xml @@ -16,7 +16,7 @@ - + diff --git a/wz/Character.wz/Accessory/01032070.img.xml b/wz/Character.wz/Accessory/01032070.img.xml index a78506d928..bc3a344476 100644 --- a/wz/Character.wz/Accessory/01032070.img.xml +++ b/wz/Character.wz/Accessory/01032070.img.xml @@ -16,10 +16,10 @@ - + diff --git a/wz/Map.wz/Map/Map9/922010800.img.xml b/wz/Map.wz/Map/Map9/922010800.img.xml index 75945f48c0..36cf865640 100644 --- a/wz/Map.wz/Map/Map9/922010800.img.xml +++ b/wz/Map.wz/Map/Map9/922010800.img.xml @@ -1,7546 +1,21 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + @@ -7551,31 +26,7551 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +