From d50b7b69600ae6256c8b8b9b7ff4871dbf628d18 Mon Sep 17 00:00:00 2001 From: ronancpl Date: Sat, 23 Jun 2018 13:00:28 -0300 Subject: [PATCH] Experimental Character/Client Closure + Morph & Crash skills patch Player Trade is now enabled inside PQ & events. Refactored minigame code, now using enums rather than strings for logistics. Fixed Transformations not applying stat buffs properly. Warrior's Crash skills now acts accordingly with their description (rather than applying all combined debuffs). Added a server flag for Crash skills, to apply mob immunity debuffs as well. Fixed Shark Wave not stacking charges. Dragon Roar now properly stuns the mobs (stun effect won't show up, though). Refactored empty method on MapleCharacter, now freeing more resources. [EXPERIMENTAL] Upon lifetime's end of the object, empty function will be called alongside MapleClient's clear, should issues arise from that, it's TBD. --- README.md | 4 +- docs/fieldlimits.txt | 27 +++++++ docs/issues.txt | 1 + docs/mychanges_ptbr.txt | 15 +++- scripts/npc/2020008.js | 4 +- scripts/npc/2020009.js | 4 +- scripts/npc/2020010.js | 4 +- scripts/npc/2020011.js | 4 +- scripts/npc/2020013.js | 4 +- scripts/npc/2080000.js | 3 +- scripts/npc/credits.js | 11 ++- src/client/MapleCharacter.java | 77 ++++++++++++------- src/client/MapleClient.java | 17 ++-- src/client/MapleJob.java | 5 +- src/constants/CharsetConstants.java | 48 ++++++++++++ src/constants/ServerConstants.java | 1 + src/constants/skills/ThunderBreaker.java | 1 + src/net/server/PlayerStorage.java | 7 +- .../handlers/AbstractDealDamageHandler.java | 17 ++-- .../channel/handlers/CancelChairHandler.java | 1 + .../handlers/PlayerInteractionHandler.java | 58 +++++++++----- .../channel/handlers/RangedAttackHandler.java | 8 ++ src/server/MapleStatEffect.java | 21 +++-- src/server/life/MapleMonster.java | 42 ++++++---- src/server/maps/MapleMiniGame.java | 52 +++++++++---- src/tools/MaplePacketCreator.java | 77 +++++++++---------- .../output/GenericLittleEndianWriter.java | 3 +- wz/Item.wz/Consume/0202.img.xml | 2 +- wz/Skill.wz/131.img.xml | 30 ++++++++ wz/String.wz/Skill.img.xml | 2 +- 30 files changed, 387 insertions(+), 163 deletions(-) create mode 100644 docs/fieldlimits.txt create mode 100644 src/constants/CharsetConstants.java diff --git a/README.md b/README.md index b081593974..187491f2ef 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Recommended localhost: https://hostr.co/m2bVtnizCtmD Status: __Released__. -HeavenMS development achieved an acceptable state-of-art and will get into a halt. A heartfelt thanks for everyone that contributed in some way for the progress of this server! +HeavenMS development achieved an acceptable state-of-the-art and will get into a halt. A heartfelt thanks for everyone that contributed in some way for the progress of this server! Although development is halted, support for fixing features that were implemented here is still up. You can still actively help us improve the server by issuing pull requests with informative details about what's changing. @@ -153,7 +153,7 @@ The client's set-up is quite straightforward: 2. Once done, erase these files: "HShield" (folder), "ASPLauncher.exe", "MapleStory.exe" and "patcher.exe". 3. Extract into the client folder the "localhost.exe" from the provided link. 4. Overwrite the original WZ files with the ones provided from either one of those folders on the Google Drive: - - "rev???_wz" (last published RELEASE, referring to commit of same number). + - "commit???_wz" (last published RELEASE, referring to commit of same number). - "current_wz" (latest source update). #### Editing localhost IP target diff --git a/docs/fieldlimits.txt b/docs/fieldlimits.txt new file mode 100644 index 0000000000..f51a54bc6b --- /dev/null +++ b/docs/fieldlimits.txt @@ -0,0 +1,27 @@ +Provided by Arnah, source: http://forum.ragezone.com/f702/release-harepacker-resurrected-1149521/index2.html + +Field limits (v95): +FIELDOPT_MOVELIMIT = 0x1, +FIELDOPT_SKILLLIMIT = 0x2, +FIELDOPT_SUMMONLIMIT = 0x4, +FIELDOPT_MYSTICDOORLIMIT = 0x8, +FIELDOPT_MIGRATELIMIT = 0x10, +FIELDOPT_PORTALSCROLLLIMIT = 0x20, +FIELDOPT_TELEPORTITEMLIMIT = 0x40, +FIELDOPT_MINIGAMELIMIT = 0x80, +FIELDOPT_SPECIFICPORTALSCROLLLIMIT = 0x100, +FIELDOPT_TAMINGMOBLIMIT = 0x200, +FIELDOPT_STATCHANGEITEMCONSUMELIMIT = 0x400, +FIELDOPT_PARTYBOSSCHANGELIMIT = 0x800, +FIELDOPT_NOMOBCAPACITYLIMIT = 0x1000, +FIELDOPT_WEDDINGINVITATIONLIMIT = 0x2000, +FIELDOPT_CASHWEATHERCONSUMELIMIT = 0x4000, +FIELDOPT_NOPET = 0x8000, +FIELDOPT_ANTIMACROLIMIT = 0x10000, +FIELDOPT_FALLDOWNLIMIT = 0x20000, +FIELDOPT_SUMMONNPCLIMIT = 0x40000, +FIELDOPT_NOEXPDECREASE = 0x80000, +FIELDOPT_NODAMAGEONFALLING = 0x100000, +FIELDOPT_PARCELOPENLIMIT = 0x200000, +FIELDOPT_DROPLIMIT = 0x400000, +FIELDOPT_ROCKETBOOSTER_LIMIT = 0x800000, \ No newline at end of file diff --git a/docs/issues.txt b/docs/issues.txt index abb0fd94ed..6f68216c1f 100644 --- a/docs/issues.txt +++ b/docs/issues.txt @@ -12,6 +12,7 @@ Known issues: - Deadlocks may start appearing if the server stays online long enough with many players logged in. - If there are multiple bosses that shows HPBar on the map, if a player hits more than one the HPBar may start flickering on the screen. - Sometimes battleship may behave oddly with the enhanced buff system, making the character d/c in certain scenarios. +- Dragon Roar doesn't show the stun effect to players. --------------------------- --------------------------- diff --git a/docs/mychanges_ptbr.txt b/docs/mychanges_ptbr.txt index 2b9d973b38..e8afa71c51 100644 --- a/docs/mychanges_ptbr.txt +++ b/docs/mychanges_ptbr.txt @@ -1049,4 +1049,17 @@ Corrigido Heaven's Hammer e Combo Tempest não mostrando dano aos jogadores. Corrigido exploit onde jogadores poderiam criar minirooms em certos casos onde os mesmos não poderiam fazê-lo. Quest itens dropados de mobs que não visíveis pelo jogador atacante agora são mostrados mais nas pontas, de forma que o conjunto de drops agora aparente não ter espaço com itens invisíveis no meio. Corrigido Horntail não atruibuindo quest progress corretamente para a quest The Last Hour of Horntail. -Removido skill books agora desnecessários do drop data, uma vez que já foi implementado as quests para conseguir elas. \ No newline at end of file +Removido skill books agora desnecessários do drop data, uma vez que já foi implementado as quests para conseguir elas. + +16 Junho 2018, +Corrigido Trade não podendo ser realizado dentro de PQ, problema ocorrendo devido a uma mudança feita no último commit. +Refatorado minigames, agora utilizando enums ao invés de strings. +Corrigido Transformations não recebendo stat buffs corretamente. +Corrigido skills Crash agora atuando dentro de suas respectivas repartições. +Adicionado server flag para permitir skills Crash retirar invencibilidades do mob. +Corrigido Shark Wave não realizando contabilização de charges ao aplicar dano. +Dragon Roar agora aplica stun em mobs (efeito de stun aparentemente não está sendo mostrado aos jogadores). + +22 Junho 2018, +Refatorado método de empty em MapleCharacter, agora verificando e liberando mais recursos. +Corrigido exploit onde pacotes referentes à chairs poderiam ser processados e reenviados aos outros em casos onde o personagem está fora do world server. \ No newline at end of file diff --git a/scripts/npc/2020008.js b/scripts/npc/2020008.js index 41f43aa71e..79679a6727 100644 --- a/scripts/npc/2020008.js +++ b/scripts/npc/2020008.js @@ -56,8 +56,8 @@ function start() { var jobBase = parseInt(cm.getJobId() / 100); var jobStyle = 1; - if (!(cm.getPlayer().getLevel() >= 70 && jobBase == jobStyle)){ - if(cm.getPlayer().getLevel() >= 70 && jobBase % 10 == jobStyle) { + if (!(cm.getPlayer().getLevel() >= 70 && jobBase == jobStyle && cm.getJobId() % 10 == 0)){ + if(cm.getPlayer().getLevel() >= 50 && jobBase % 10 == jobStyle) { status++; action(1, 0, 1); return; diff --git a/scripts/npc/2020009.js b/scripts/npc/2020009.js index a118b1a7b9..0ed7c47477 100644 --- a/scripts/npc/2020009.js +++ b/scripts/npc/2020009.js @@ -28,8 +28,8 @@ actionx = {"Mental" : false, "Physical" : false}; function start() { var jobBase = parseInt(cm.getJobId() / 100); var jobStyle = 2; - if (!(cm.getPlayer().getLevel() >= 70 && jobBase == jobStyle)){ - if(cm.getPlayer().getLevel() >= 70 && jobBase % 10 == jobStyle) { + if (!(cm.getPlayer().getLevel() >= 70 && jobBase == jobStyle && cm.getJobId() % 10 == 0)){ + if(cm.getPlayer().getLevel() >= 50 && jobBase % 10 == jobStyle) { status++; action(1, 0, 1); return; diff --git a/scripts/npc/2020010.js b/scripts/npc/2020010.js index ad882702c6..8cadcdca12 100644 --- a/scripts/npc/2020010.js +++ b/scripts/npc/2020010.js @@ -30,8 +30,8 @@ actionx = {"Mental" : false, "Physical" : false}; function start() { var jobBase = parseInt(cm.getJobId() / 100); var jobStyle = 3; - if (!(cm.getPlayer().getLevel() >= 70 && jobBase == jobStyle)){ - if(cm.getPlayer().getLevel() >= 70 && jobBase % 10 == jobStyle) { + if (!(cm.getPlayer().getLevel() >= 70 && jobBase == jobStyle && cm.getJobId() % 10 == 0)){ + if(cm.getPlayer().getLevel() >= 50 && jobBase % 10 == jobStyle) { status++; action(1, 0, 1); return; diff --git a/scripts/npc/2020011.js b/scripts/npc/2020011.js index 44d0e62032..980ec018d3 100644 --- a/scripts/npc/2020011.js +++ b/scripts/npc/2020011.js @@ -28,8 +28,8 @@ actionx = {"Mental" : false, "Physical" : false}; function start() { var jobBase = parseInt(cm.getJobId() / 100); var jobStyle = 4; - if (!(cm.getPlayer().getLevel() >= 70 && jobBase == jobStyle)){ - if(cm.getPlayer().getLevel() >= 70 && jobBase % 10 == jobStyle) { + if (!(cm.getPlayer().getLevel() >= 70 && jobBase == jobStyle && cm.getJobId() % 10 == 0)){ + if(cm.getPlayer().getLevel() >= 50 && jobBase % 10 == jobStyle) { status++; action(1, 0, 1); return; diff --git a/scripts/npc/2020013.js b/scripts/npc/2020013.js index 7658c22e94..d8c6615f57 100644 --- a/scripts/npc/2020013.js +++ b/scripts/npc/2020013.js @@ -28,8 +28,8 @@ actionx = {"Mental" : false, "Physical" : false}; function start() { var jobBase = parseInt(cm.getJobId() / 100); var jobStyle = 5; - if (!(cm.getPlayer().getLevel() >= 70 && jobBase == jobStyle)){ - if(cm.getPlayer().getLevel() >= 70 && jobBase % 10 == jobStyle) { + if (!(cm.getPlayer().getLevel() >= 70 && jobBase == jobStyle && cm.getJobId() % 10 == 0)){ + if(cm.getPlayer().getLevel() >= 50 && jobBase % 10 == jobStyle) { status++; action(1, 0, 1); return; diff --git a/scripts/npc/2080000.js b/scripts/npc/2080000.js index c8e4a92eec..d063cc6ca2 100644 --- a/scripts/npc/2080000.js +++ b/scripts/npc/2080000.js @@ -40,9 +40,8 @@ function start() { var options = new Array("What's a stimulator?","Create a Warrior weapon","Create a Bowman weapon","Create a Magician weapon","Create a Thief weapon","Create a Pirate Weapon", "Create a Warrior weapon with a Stimulator","Create a Bowman weapon with a Stimulator","Create a Magician weapon with a Stimulator","Create a Thief weapon with a Stimulator","Create a Pirate Weapon with a Stimulator"); - if(cm.isQuestStarted(7301)) options.push("Make #t4001078#"); + if(cm.isQuestStarted(7301) || cm.isQuestStarted(7303)) options.push("Make #t4001078#"); - for (var i = 0; i < options.length; i++){ selStr += "\r\n#L" + i + "# " + options[i] + "#l"; } diff --git a/scripts/npc/credits.js b/scripts/npc/credits.js index 716f82e748..3dda183df6 100644 --- a/scripts/npc/credits.js +++ b/scripts/npc/credits.js @@ -11,7 +11,8 @@ var name_tree = []; var role_tree = []; var name_cursor, role_cursor; -// make sure the server names are lexicograffically EQUALS to the correspondent function. +// new server names are to be appended at the start of the name stack, building up the chronology. +// make sure the server names are lexicograffically equivalent to their correspondent function. var servers = ["HeavenMS", "MapleSolaxia", "MoopleDEV", "MetroMS", "BubblesDEV", "ThePackII", "OdinMS", "Contributors"]; var servers_history = []; @@ -24,6 +25,14 @@ function setHistory(from, to) { servers_history.push([from, to]); } +/* +function writeServerStaff_MapleNext() { + addPerson("John Doe", "The role"); + + setHistory(INITIAL_YEAR [, CURRENT_YEAR]); +} +*/ + function writeServerStaff_HeavenMS() { addPerson("Ronan", "Developer"); addPerson("Vcoc", "Freelance Developer"); diff --git a/src/client/MapleCharacter.java b/src/client/MapleCharacter.java index d29aa46de1..4516ec5b8c 100644 --- a/src/client/MapleCharacter.java +++ b/src/client/MapleCharacter.java @@ -88,6 +88,7 @@ import server.maps.MapleMapFactory; import server.maps.MapleMapObject; import server.maps.MapleMapObjectType; import server.maps.MapleMiniGame; +import server.maps.MapleMiniGame.MiniGameResult; import server.maps.MaplePlayerShop; import server.maps.MaplePlayerShopItem; import server.maps.MapleSummon; @@ -3600,9 +3601,18 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { toUpdateEffects.add(new Pair<>(mse.getBuffSourceId(), retrievedEffects.get(mse.getBuffSourceId()))); } + List> activeStatups = new LinkedList<>(); for(Pair> lmse: toUpdateEffects) { Pair msel = lmse.getRight(); - msel.getLeft().updateBuffEffect(this, getActiveStatupsFromSourceid(lmse.getLeft()), msel.getRight()); + + for(Pair statup : getActiveStatupsFromSourceid(lmse.getLeft())) { + if(!isSingletonStatup(statup.getLeft())) { + activeStatups.add(statup); + } + } + + msel.getLeft().updateBuffEffect(this, activeStatups, msel.getRight()); + activeStatups.clear(); } if (this.isRidingBattleship()) { @@ -4450,21 +4460,21 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { return miniGame; } - public int getMiniGamePoints(String type, boolean omok) { + public int getMiniGamePoints(MiniGameResult type, boolean omok) { if (omok) { switch (type) { - case "wins": + case WIN: return omokwins; - case "losses": + case LOSS: return omoklosses; default: return omokties; } } else { switch (type) { - case "wins": + case WIN: return matchcardwins; - case "losses": + case LOSS: return matchcardlosses; default: return matchcardties; @@ -5460,7 +5470,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { this.yellowMessage("You reached level " + level + ". Congratulations! As a token of your success, your inventory has been expanded a little bit."); } } - if (level % 20 == 0 && ServerConstants.USE_ADD_RATES_BY_LEVEL == true) { //For the drop & meso rate + if (level % 20 == 0 && ServerConstants.USE_ADD_RATES_BY_LEVEL == true) { //For the rate upgrade revertLastPlayerRates(); setPlayerRates(); this.yellowMessage("You managed to get level " + level + "! Getting experience and items seems a little easier now, huh?"); @@ -8613,33 +8623,42 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } public final void empty(final boolean remove) { - if (dragonBloodSchedule != null) { - dragonBloodSchedule.cancel(false); - } - if (hpDecreaseTask != null) { - hpDecreaseTask.cancel(false); - } - if (beholderHealingSchedule != null) { - beholderHealingSchedule.cancel(false); - } - if (beholderBuffSchedule != null) { - beholderBuffSchedule.cancel(false); - } - if (berserkSchedule != null) { - berserkSchedule.cancel(false); - } - if (recoveryTask != null) { - recoveryTask.cancel(false); - } - if (extraRecoveryTask != null) { - extraRecoveryTask.cancel(false); - } - + if (dragonBloodSchedule != null) { dragonBloodSchedule.cancel(true); } + dragonBloodSchedule = null; + + if (hpDecreaseTask != null) { hpDecreaseTask.cancel(true); } + hpDecreaseTask = null; + + if (beholderHealingSchedule != null) { beholderHealingSchedule.cancel(true); } + beholderHealingSchedule = null; + + if (beholderBuffSchedule != null) { beholderBuffSchedule.cancel(true); } + beholderBuffSchedule = null; + + if (berserkSchedule != null) { berserkSchedule.cancel(true); } + berserkSchedule = null; + unregisterChairBuff(); cancelBuffExpireTask(); cancelDiseaseExpireTask(); cancelSkillCooldownTask(); cancelExpirationTask(); + + if (questExpireTask != null) { questExpireTask.cancel(true); } + questExpireTask = null; + + if (recoveryTask != null) { recoveryTask.cancel(true); } + recoveryTask = null; + + if (extraRecoveryTask != null) { extraRecoveryTask.cancel(true); } + extraRecoveryTask = null; + + // already done on unregisterChairBuff + /* if (chairRecoveryTask != null) { chairRecoveryTask.cancel(true); } + chairRecoveryTask = null; */ + + if (pendantOfSpirit != null) { pendantOfSpirit.cancel(true); } + pendantOfSpirit = null; petLock.lock(); try { diff --git a/src/client/MapleClient.java b/src/client/MapleClient.java index 35cfa9b0ac..1831e1facc 100644 --- a/src/client/MapleClient.java +++ b/src/client/MapleClient.java @@ -843,7 +843,7 @@ public class MapleClient { player.saveCooldowns(); player.saveToDB(true); - player = null; + clear(); return; } @@ -935,25 +935,32 @@ public class MapleClient { player.saveCooldowns(); player.saveToDB(); } - player = null; } } if (!serverTransition && isLoggedIn()) { updateLoginState(MapleClient.LOGIN_NOTLOGGEDIN); session.removeAttribute(MapleClient.CLIENT_KEY); // prevents double dcing during login session.close(false); - } - engines.clear(); + + clear(); + } else { + engines.clear(); + } } private void clear() { //usable when defining client = null shortly after + // player hard reference removal thanks to Steve (kaito1410) + if (this.player != null) { + this.player.empty(true); // clears schedules and stuff + } + Server.getInstance().unregisterLoginState(this); this.accountName = null; this.macs = null; this.hwid = null; this.birthday = null; - //this.engines = null; + this.engines = null; this.player = null; this.receive = null; this.send = null; diff --git a/src/client/MapleJob.java b/src/client/MapleJob.java index 2bbc5ec4a1..60cc28f578 100644 --- a/src/client/MapleJob.java +++ b/src/client/MapleJob.java @@ -120,8 +120,9 @@ public enum MapleJob { || DAWNWARRIOR1 == beginners || NIGHTWALKER1 == beginners || BLAZEWIZARD1 == beginners; } - public boolean isA(MapleJob basejob) { - return getId() >= basejob.getId() && getId() / 100 == basejob.getId() / 100; + public boolean isA(MapleJob basejob) { // thanks Steve (kaito1410) for pointing out an improvement here + int basebranch = basejob.getId() / 10; + return (getId() / 10 == basebranch && getId() >= basejob.getId()) || (basebranch % 10 == 0 && getId() / 100 == basejob.getId() / 100); } public int getJobNiche() { diff --git a/src/constants/CharsetConstants.java b/src/constants/CharsetConstants.java new file mode 100644 index 0000000000..a9a3cd6973 --- /dev/null +++ b/src/constants/CharsetConstants.java @@ -0,0 +1,48 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package constants; + +/* + * Courtesy of GabrielSin (gabrielsin@playellin.net) + * Ellin + * MapleStory Server + * CharsetConstants + */ + +public class CharsetConstants { + + public static MapleLanguageType MAPLE_TYPE = MapleLanguageType.LANGUAGE_PT_BR; + + public enum MapleLanguageType { + LANGUAGE_PT_BR(1, "ISO-8859-1"), + LANGUAGE_US(2, "US-ASCII"); + final byte type; + final String ascii; + + private MapleLanguageType(int type, String ascii) { + this.type = (byte) type; + this.ascii = ascii; + } + + public String getAscii() { + return ascii; + } + + public byte getType() { + return type; + } + + public static MapleLanguageType getByType(byte type) { + for (MapleLanguageType l : MapleLanguageType.values()) { + if (l.getType() == type) { + return l; + } + } + return LANGUAGE_PT_BR; + } + } +} \ No newline at end of file diff --git a/src/constants/ServerConstants.java b/src/constants/ServerConstants.java index 435bb8894c..8761c07d63 100644 --- a/src/constants/ServerConstants.java +++ b/src/constants/ServerConstants.java @@ -140,6 +140,7 @@ public class ServerConstants { //Other Skills Configuration public static final boolean USE_FAST_REUSE_HERO_WILL = true;//Greatly reduce cooldown on Hero's Will. + public static final boolean USE_ANTI_IMMUNITY_CRASH = true; //Crash skills additionally removes the mob's invincibility buffs. //Character Configuration public static final boolean USE_ADD_SLOTS_BY_LEVEL = true; //Slots are added each 20 levels. diff --git a/src/constants/skills/ThunderBreaker.java b/src/constants/skills/ThunderBreaker.java index e54d6e8803..1558680b89 100644 --- a/src/constants/skills/ThunderBreaker.java +++ b/src/constants/skills/ThunderBreaker.java @@ -38,4 +38,5 @@ public class ThunderBreaker { public static final int TRANSFORMATION = 15111002; public static final int SPEED_INFUSION = 15111005; public static final int SPARK = 15111006; + public static final int SHARK_WAVE = 15111007; } diff --git a/src/net/server/PlayerStorage.java b/src/net/server/PlayerStorage.java index 852fa99878..c3bb66ce50 100644 --- a/src/net/server/PlayerStorage.java +++ b/src/net/server/PlayerStorage.java @@ -21,6 +21,7 @@ */ package net.server; +import client.MapleClient; import client.MapleCharacter; import java.util.Collection; import java.util.Iterator; @@ -93,7 +94,11 @@ public class PlayerStorage { try { final Iterator chrit = storage.values().iterator(); while (chrit.hasNext()) { - chrit.next().getClient().disconnect(true, false); + MapleClient client = chrit.next().getClient(); + if(client != null) { + client.disconnect(true, false); + } + chrit.remove(); } } finally { diff --git a/src/net/server/channel/handlers/AbstractDealDamageHandler.java b/src/net/server/channel/handlers/AbstractDealDamageHandler.java index 99210b695e..d8bb3416b8 100644 --- a/src/net/server/channel/handlers/AbstractDealDamageHandler.java +++ b/src/net/server/channel/handlers/AbstractDealDamageHandler.java @@ -29,7 +29,6 @@ import java.util.List; import java.util.Map; import net.AbstractMaplePacketHandler; -import server.MapleItemInformationProvider; import server.MapleStatEffect; import server.TimerManager; import server.life.Element; @@ -43,7 +42,6 @@ import server.maps.MapleMap; import server.maps.MapleMapItem; import server.maps.MapleMapObject; import server.maps.MapleMapObjectType; -import server.partyquest.Pyramid; import tools.MaplePacketCreator; import tools.Pair; import tools.Randomizer; @@ -55,13 +53,9 @@ import client.MapleStat; import client.Skill; import client.SkillFactory; import client.autoban.AutobanFactory; -import client.inventory.Equip; -import client.inventory.Item; -import client.inventory.MapleInventoryType; import client.status.MonsterStatus; import client.status.MonsterStatusEffect; import constants.GameConstants; -import constants.ItemConstants; import constants.ServerConstants; import constants.skills.Aran; import constants.skills.Assassin; @@ -304,7 +298,7 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl } } else if (attack.skill == Marauder.ENERGY_DRAIN || attack.skill == ThunderBreaker.ENERGY_DRAIN || attack.skill == NightWalker.VAMPIRE || attack.skill == Assassin.DRAIN) { player.addHP(Math.min(monster.getMaxHp(), Math.min((int) ((double) totDamage * (double) SkillFactory.getSkill(attack.skill).getEffect(player.getSkillLevel(SkillFactory.getSkill(attack.skill))).getX() / 100.0), player.getMaxHp() / 2))); - } else if (attack.skill == Bandit.STEAL) { + } else if (attack.skill == Bandit.STEAL) { Skill steal = SkillFactory.getSkill(Bandit.STEAL); if (monster.getStolen().size() < 1) { // One steal per mob <3 if (steal.getEffect(player.getSkillLevel(steal)).makeChanceResult()) { @@ -480,9 +474,12 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl } } } - if (totDamageToOneMonster > 0 && attackEffect != null && attackEffect.getMonsterStati().size() > 0) { - if (attackEffect.makeChanceResult()) { - monster.applyStatus(player, new MonsterStatusEffect(attackEffect.getMonsterStati(), theSkill, null, false), attackEffect.isPoison(), attackEffect.getDuration()); + if (totDamageToOneMonster > 0 && attackEffect != null) { + Map attackEffectStati = attackEffect.getMonsterStati(); + if(!attackEffectStati.isEmpty()) { + if (attackEffect.makeChanceResult()) { + monster.applyStatus(player, new MonsterStatusEffect(attackEffectStati, theSkill, null, false), attackEffect.isPoison(), attackEffect.getDuration()); + } } } if (attack.skill == Paladin.HEAVENS_HAMMER) { diff --git a/src/net/server/channel/handlers/CancelChairHandler.java b/src/net/server/channel/handlers/CancelChairHandler.java index f048f62ba6..e226841e13 100644 --- a/src/net/server/channel/handlers/CancelChairHandler.java +++ b/src/net/server/channel/handlers/CancelChairHandler.java @@ -33,6 +33,7 @@ public final class CancelChairHandler extends AbstractMaplePacketHandler { public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { int id = slea.readShort(); MapleCharacter mc = c.getPlayer(); + if(!mc.isLoggedinWorld()) return; if (id == -1) { // Cancel Chair mc.setChair(0); diff --git a/src/net/server/channel/handlers/PlayerInteractionHandler.java b/src/net/server/channel/handlers/PlayerInteractionHandler.java index 728292d783..f6d58f54c6 100644 --- a/src/net/server/channel/handlers/PlayerInteractionHandler.java +++ b/src/net/server/channel/handlers/PlayerInteractionHandler.java @@ -31,8 +31,6 @@ import client.inventory.manipulator.MapleKarmaManipulator; import constants.ItemConstants; import constants.ServerConstants; -import java.util.Arrays; - import net.AbstractMaplePacketHandler; import server.MapleItemInformationProvider; import server.MapleTrade; @@ -40,8 +38,8 @@ import constants.GameConstants; import server.maps.FieldLimit; import server.maps.MapleHiredMerchant; import server.maps.MapleMapObject; -import server.maps.MapleMapObjectType; import server.maps.MapleMiniGame; +import server.maps.MapleMiniGame.MiniGameType; import server.maps.MaplePlayerShop; import server.maps.MaplePlayerShopItem; import tools.FilePrinter; @@ -111,6 +109,22 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler { } } + private static int estabilishMiniroomStatus(MapleCharacter chr, boolean isMinigame) { + if (isMinigame && FieldLimit.CANNOTMINIGAME.check(chr.getMap().getFieldLimit())) { + return 11; + } + + if (chr.getChalkboard() != null) { + return 13; + } + + if(chr.getEventInstance() != null) { + return 5; + } + + return 0; + } + @Override public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { byte mode = slea.readByte(); @@ -122,17 +136,13 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler { return; } - if(chr.getEventInstance() != null) { - chr.getClient().announce(MaplePacketCreator.getMiniRoomError(5)); - return; - } - byte createType = slea.readByte(); if (createType == 3) {// trade MapleTrade.startTrade(chr); } else if (createType == 1) { // omok mini game - if (chr.getChalkboard() != null || FieldLimit.CANNOTMINIGAME.check(chr.getMap().getFieldLimit())) { - chr.getClient().announce(MaplePacketCreator.getMiniRoomError(11)); + int status = estabilishMiniroomStatus(chr, true); + if (status > 0) { + chr.getClient().announce(MaplePacketCreator.getMiniRoomError(status)); return; } @@ -143,13 +153,14 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler { MapleMiniGame game = new MapleMiniGame(chr, desc, pw); chr.setMiniGame(game); game.setPieceType(type); - game.setGameType("omok"); + game.setGameType(MiniGameType.OMOK); chr.getMap().addMapObject(game); chr.getMap().broadcastMessage(MaplePacketCreator.addOmokBox(chr, 1, 0)); game.sendOmok(c, type); } else if (createType == 2) { // matchcard - if (chr.getChalkboard() != null || FieldLimit.CANNOTMINIGAME.check(chr.getMap().getFieldLimit())) { - chr.getClient().announce(MaplePacketCreator.getMiniRoomError(11)); + int status = estabilishMiniroomStatus(chr, true); + if (status > 0) { + chr.getClient().announce(MaplePacketCreator.getMiniRoomError(status)); return; } @@ -166,16 +177,23 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler { } else if (type == 2) { game.setMatchesToWin(15); } - game.setGameType("matchcard"); + game.setGameType(MiniGameType.MATCH_CARD); chr.setMiniGame(game); chr.getMap().addMapObject(game); chr.getMap().broadcastMessage(MaplePacketCreator.addMatchCardBox(chr, 1, 0)); game.sendMatchCard(c, type); } else if (createType == 4 || createType == 5) { // shop - if (!chr.getMap().getMapObjectsInRange(chr.getPosition(), 23000, Arrays.asList(MapleMapObjectType.SHOP, MapleMapObjectType.HIRED_MERCHANT)).isEmpty()) { - chr.getClient().announce(MaplePacketCreator.getMiniRoomError(14)); + if(!GameConstants.isFreeMarketRoom(chr.getMapId())) { + chr.getClient().announce(MaplePacketCreator.getMiniRoomError(15)); return; } + + int status = estabilishMiniroomStatus(chr, false); + if (status > 0) { + chr.getClient().announce(MaplePacketCreator.getMiniRoomError(status)); + return; + } + String desc = slea.readMapleAsciiString(); slea.skip(3); int itemId = slea.readInt(); @@ -184,7 +202,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler { return; } - if (GameConstants.isFreeMarketRoom(chr.getMapId()) || itemId > 5030000 && itemId < 5030012 || itemId > 5140000 && itemId < 5140006) { + if (itemId > 5030000 && itemId < 5030012 || itemId > 5140000 && itemId < 5140006) { if (createType == 4) { MaplePlayerShop shop = new MaplePlayerShop(chr, desc); chr.setPlayerShop(shop); @@ -230,15 +248,15 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler { String pw = slea.available() > 1 ? slea.readMapleAsciiString() : ""; MapleMiniGame game = (MapleMiniGame) ob; - if(game.checkPassword(pw) || game.checkPassword(chr.getName())) { + if(game.checkPassword(pw)) { if (game.hasFreeSlot() && !game.isVisitor(chr)) { game.addVisitor(chr); chr.setMiniGame(game); switch (game.getGameType()) { - case "omok": + case OMOK: game.sendOmok(c, game.getPieceType()); break; - case "matchcard": + case MATCH_CARD: game.sendMatchCard(c, game.getPieceType()); break; } diff --git a/src/net/server/channel/handlers/RangedAttackHandler.java b/src/net/server/channel/handlers/RangedAttackHandler.java index 2deb447c78..73ba52fa2f 100644 --- a/src/net/server/channel/handlers/RangedAttackHandler.java +++ b/src/net/server/channel/handlers/RangedAttackHandler.java @@ -30,6 +30,7 @@ import tools.data.input.SeekableLittleEndianAccessor; import client.MapleBuffStat; import client.MapleCharacter; import client.MapleClient; +import client.MapleJob; import client.Skill; import client.SkillFactory; import client.inventory.Item; @@ -77,6 +78,13 @@ public final class RangedAttackHandler extends AbstractDealDamageHandler { if (attack.skill == Buccaneer.ENERGY_ORB || attack.skill == ThunderBreaker.SPARK || attack.skill == Shadower.TAUNT || attack.skill == NightLord.TAUNT) { chr.getMap().broadcastMessage(chr, MaplePacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, 0, attack.allDamage, attack.speed, attack.direction, attack.display), false); applyAttack(attack, chr, 1); + } else if (attack.skill == ThunderBreaker.SHARK_WAVE && chr.getSkillLevel(ThunderBreaker.SHARK_WAVE) > 0) { + chr.getMap().broadcastMessage(chr, MaplePacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, 0, attack.allDamage, attack.speed, attack.direction, attack.display), false); + applyAttack(attack, chr, 1); + + for (int i = 0; i < attack.numAttacked; i++) { + chr.handleEnergyChargeGain(); + } } else if (attack.skill == Aran.COMBO_SMASH || attack.skill == Aran.COMBO_FENRIR || attack.skill == Aran.COMBO_TEMPEST) { chr.getMap().broadcastMessage(chr, MaplePacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, 0, attack.allDamage, attack.speed, attack.direction, attack.display), false); if (attack.skill == Aran.COMBO_SMASH && chr.getCombo() >= 30) { diff --git a/src/server/MapleStatEffect.java b/src/server/MapleStatEffect.java index 7ca91b32ed..f82e506ec2 100644 --- a/src/server/MapleStatEffect.java +++ b/src/server/MapleStatEffect.java @@ -376,9 +376,6 @@ public class MapleStatEffect { case DragonKnight.DRAGON_BLOOD: statups.add(new Pair<>(MapleBuffStat.DRAGONBLOOD, Integer.valueOf(ret.x))); break; - case DragonKnight.DRAGON_ROAR: - ret.hpR = -x / 100.0; - break; case Hero.STANCE: case Paladin.STANCE: case DarkKnight.STANCE: @@ -571,7 +568,7 @@ public class MapleStatEffect { case Crusader.ARMOR_CRASH: case DragonKnight.POWER_CRASH: case WhiteKnight.MAGIC_CRASH: - monsterStatus.put(MonsterStatus.SEAL_SKILL, Integer.valueOf(1)); + monsterStatus.put(MonsterStatus.SEAL_SKILL, Integer.valueOf(1)); break; case Rogue.DISORDER: monsterStatus.put(MonsterStatus.WATK, Integer.valueOf(ret.x)); @@ -588,6 +585,10 @@ public class MapleStatEffect { monsterStatus.put(MonsterStatus.WATK, Integer.valueOf(ret.x)); monsterStatus.put(MonsterStatus.WDEF, Integer.valueOf(ret.y)); break; + case DragonKnight.DRAGON_ROAR: + ret.hpR = -x / 100.0; + monsterStatus.put(MonsterStatus.STUN, Integer.valueOf(1)); + break; case Crusader.AXE_COMA: case Crusader.SWORD_COMA: case Crusader.SHOUT: @@ -1007,7 +1008,7 @@ public class MapleStatEffect { public final void applyComboBuff(final MapleCharacter applyto, int combo) { final List> stat = Collections.singletonList(new Pair<>(MapleBuffStat.ARAN_COMBO, combo)); - applyto.getClient().announce(MaplePacketCreator.giveBuff(sourceid, 99999, stat)); + applyto.announce(MaplePacketCreator.giveBuff(sourceid, 99999, stat)); final long starttime = System.currentTimeMillis(); // final CancelEffectAction cancelAction = new CancelEffectAction(applyto, this, starttime); @@ -1021,8 +1022,7 @@ public class MapleStatEffect { long leftDuration = (starttime + localDuration) - System.currentTimeMillis(); if(leftDuration > 0) { - byte[] buff = MaplePacketCreator.giveBuff((skill ? sourceid : -sourceid), (int)leftDuration, activeStats); - target.getClient().announce(buff); + target.announce(MaplePacketCreator.giveBuff((skill ? sourceid : -sourceid), (int)leftDuration, activeStats)); } } @@ -1080,7 +1080,12 @@ public class MapleStatEffect { localsourceid = ridingMountId; localstatups = Collections.singletonList(new Pair<>(MapleBuffStat.MONSTER_RIDING, 0)); } else if (isSkillMorph()) { - localstatups = Collections.singletonList(new Pair<>(MapleBuffStat.MORPH, getMorph(applyto))); + for(int i = 0; i < localstatups.size(); i++) { + if(localstatups.get(i).getLeft().equals(MapleBuffStat.MORPH)) { + localstatups.set(i, new Pair<>(MapleBuffStat.MORPH, getMorph(applyto))); + break; + } + } } if (primary) { localDuration = alchemistModifyVal(applyfrom, localDuration, false); diff --git a/src/server/life/MapleMonster.java b/src/server/life/MapleMonster.java index 73138e6d5d..5f0108bb5c 100644 --- a/src/server/life/MapleMonster.java +++ b/src/server/life/MapleMonster.java @@ -30,11 +30,14 @@ import client.SkillFactory; import client.status.MonsterStatus; import client.status.MonsterStatusEffect; import constants.ServerConstants; +import constants.skills.Crusader; +import constants.skills.DragonKnight; import constants.skills.FPMage; import constants.skills.ILMage; import constants.skills.NightLord; import constants.skills.NightWalker; import constants.skills.Shadower; +import constants.skills.WhiteKnight; import java.awt.Point; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -990,22 +993,35 @@ public class MapleMonster extends AbstractLoadedMapleLife { effect.setCancelTask(timerManager.schedule(cancelTask, duration)); } + private void debuffMobStat(MonsterStatus stat) { + if (isBuffed(stat)) { + final MonsterStatusEffect oldEffect = stati.get(stat); + byte[] packet = MaplePacketCreator.cancelMonsterStatus(getObjectId(), oldEffect.getStati()); + map.broadcastMessage(packet, getPosition()); + + MapleCharacter controller = getController(); + if (controller != null && !controller.isMapObjectVisible(MapleMonster.this)) { + controller.getClient().announce(packet); + } + stati.remove(stat); + } + } + public void debuffMob(int skillid) { - //skillid is not going to be used for now until I get warrior debuff working - MonsterStatus[] stats = {MonsterStatus.WEAPON_ATTACK_UP, MonsterStatus.WEAPON_DEFENSE_UP, MonsterStatus.MAGIC_ATTACK_UP, MonsterStatus.MAGIC_DEFENSE_UP}; + MonsterStatus[] stats = {MonsterStatus.WEAPON_ATTACK_UP, MonsterStatus.WEAPON_DEFENSE_UP, MonsterStatus.MAGIC_ATTACK_UP}; statiLock.lock(); try { - for (int i = 0; i < stats.length; i++) { - if (isBuffed(stats[i])) { - final MonsterStatusEffect oldEffect = stati.get(stats[i]); - byte[] packet = MaplePacketCreator.cancelMonsterStatus(getObjectId(), oldEffect.getStati()); - map.broadcastMessage(packet, getPosition()); - - MapleCharacter controller = getController(); - if (controller != null && !controller.isMapObjectVisible(MapleMonster.this)) { - controller.getClient().announce(packet); - } - stati.remove(stats[i]); + int i = (skillid == Crusader.ARMOR_CRASH ? 1 : (skillid == WhiteKnight.MAGIC_CRASH ? 2 : 0)); + debuffMobStat(stats[i]); + + if(ServerConstants.USE_ANTI_IMMUNITY_CRASH) { + if (skillid == Crusader.ARMOR_CRASH) { + if(!isBuffed(MonsterStatus.WEAPON_REFLECT)) debuffMobStat(MonsterStatus.WEAPON_IMMUNITY); + if(!isBuffed(MonsterStatus.MAGIC_REFLECT)) debuffMobStat(MonsterStatus.MAGIC_IMMUNITY); + } else if (skillid == WhiteKnight.MAGIC_CRASH) { + if(!isBuffed(MonsterStatus.MAGIC_REFLECT)) debuffMobStat(MonsterStatus.MAGIC_IMMUNITY); + } else { + if(!isBuffed(MonsterStatus.WEAPON_REFLECT)) debuffMobStat(MonsterStatus.WEAPON_IMMUNITY); } } } finally { diff --git a/src/server/maps/MapleMiniGame.java b/src/server/maps/MapleMiniGame.java index e45f4d415a..507cac4a56 100644 --- a/src/server/maps/MapleMiniGame.java +++ b/src/server/maps/MapleMiniGame.java @@ -31,12 +31,13 @@ import tools.MaplePacketCreator; /** * * @author Matze + * @author Ronan (refactored String GameType to enum MiniGameType) */ public class MapleMiniGame extends AbstractMapleMapObject { private MapleCharacter owner; private MapleCharacter visitor; private String password; - private String GameType = null; + private MiniGameType GameType = MiniGameType.UNDEFINED; private int[] piece = new int[250]; private List list4x3 = new ArrayList<>(); private List list5x4 = new ArrayList<>(); @@ -49,6 +50,23 @@ public class MapleMiniGame extends AbstractMapleMapObject { private int ownerpoints = 0; private int matchestowin = 0; + public static enum MiniGameType { + UNDEFINED(0), OMOK(1), MATCH_CARD(2); + private int value = 0; + + private MiniGameType(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + + public static enum MiniGameResult { + WIN, LOSS, TIE; + } + public MapleMiniGame(MapleCharacter owner, String description, String password) { this.owner = owner; this.description = description; @@ -70,16 +88,16 @@ public class MapleMiniGame extends AbstractMapleMapObject { public boolean isOwner(MapleCharacter c) { return owner.equals(c); } - + public void addVisitor(MapleCharacter challenger) { visitor = challenger; - if (GameType.equals("omok")) { - this.getOwner().getClient().announce(MaplePacketCreator.getMiniGameNewVisitor(challenger, 1)); - this.getOwner().getMap().broadcastMessage(MaplePacketCreator.addOmokBox(owner, 2, 0)); - } - if (GameType.equals("matchcard")) { - this.getOwner().getClient().announce(MaplePacketCreator.getMatchCardNewVisitor(challenger, 1)); - this.getOwner().getMap().broadcastMessage(MaplePacketCreator.addMatchCardBox(owner, 2, 0)); + MapleCharacter owner = this.getOwner(); + if (GameType == MiniGameType.OMOK) { + owner.announce(MaplePacketCreator.getMiniGameNewVisitor(challenger, 1)); + owner.getMap().broadcastMessage(MaplePacketCreator.addOmokBox(owner, 2, 0)); + } else if (GameType == MiniGameType.MATCH_CARD) { + owner.announce(MaplePacketCreator.getMatchCardNewVisitor(challenger, 1)); + owner.getMap().broadcastMessage(MaplePacketCreator.addMatchCardBox(owner, 2, 0)); } } @@ -87,10 +105,9 @@ public class MapleMiniGame extends AbstractMapleMapObject { if (visitor == challenger) { visitor = null; this.getOwner().getClient().announce(MaplePacketCreator.getMiniGameRemoveVisitor()); - if (GameType.equals("omok")) { + if (GameType == MiniGameType.OMOK) { this.getOwner().getMap().broadcastMessage(MaplePacketCreator.addOmokBox(owner, 1, 0)); - } - if (GameType.equals("matchcard")) { + } else if (GameType == MiniGameType.MATCH_CARD) { this.getOwner().getMap().broadcastMessage(MaplePacketCreator.addMatchCardBox(owner, 1, 0)); } } @@ -156,9 +173,9 @@ public class MapleMiniGame extends AbstractMapleMapObject { return piecetype; } - public void setGameType(String game) { + public void setGameType(MiniGameType game) { GameType = game; - if (game.equals("matchcard")) { + if (GameType == MiniGameType.MATCH_CARD) { if (matchestowin == 6) { for (int i = 0; i < 6; i++) { list4x3.add(i); @@ -178,7 +195,7 @@ public class MapleMiniGame extends AbstractMapleMapObject { } } - public String getGameType() { + public MiniGameType getGameType() { return GameType; } @@ -217,8 +234,9 @@ public class MapleMiniGame extends AbstractMapleMapObject { } public void broadcast(final byte[] packet) { - if (owner.getClient() != null && owner.getClient().getSession() != null) { - owner.getClient().announce(packet); + MapleClient c = owner.getClient(); + if (c != null && c.getSession() != null) { + c.announce(packet); } broadcastToVisitor(packet); } diff --git a/src/tools/MaplePacketCreator.java b/src/tools/MaplePacketCreator.java index 0cfcae201e..7db90e26e8 100644 --- a/src/tools/MaplePacketCreator.java +++ b/src/tools/MaplePacketCreator.java @@ -68,6 +68,7 @@ import server.maps.MapleMap; import server.maps.MapleMapItem; import server.maps.MapleMist; import server.maps.MapleMiniGame; +import server.maps.MapleMiniGame.MiniGameResult; import server.maps.MaplePlayerShop; import server.maps.MaplePlayerShopItem; import server.maps.MapleReactor; @@ -672,7 +673,6 @@ public class MaplePacketCreator { * Gets a successful authentication packet. * * @param c - * @param account The account name. * @return the successful authentication packet */ public static byte[] getAuthSuccess(MapleClient c) { @@ -683,9 +683,8 @@ public class MaplePacketCreator { mplew.writeInt(c.getAccID()); mplew.write(c.getGender()); - mplew.writeBool(c.getGMLevel() > 0); - - mplew.write((c.getGMLevel() > 0 && Server.getInstance().canFly(c.getAccID())) ? 0x80 : 0); // Admin Byte. 0x80,0x40,0x20.. Rubbish. + mplew.writeBool(c.getGMLevel() > 1); // thanks Steve(kaito1410) for pointing this out + mplew.write((c.getGMLevel() > 1 && Server.getInstance().canFly(c.getAccID())) ? 0x80 : 0); // Admin Byte. 0x80,0x40,0x20.. Rubbish. mplew.write(0); // Country Code. mplew.writeMapleAsciiString(c.getAccountName()); @@ -1967,9 +1966,9 @@ public class MaplePacketCreator { MapleMiniGame miniGame = chr.getMiniGame(); if (miniGame != null && miniGame.isOwner(chr)) { if (miniGame.hasFreeSlot()) { - spawnAnnounceBox(mplew, miniGame, 1, 0, 1, 0); + spawnAnnounceBox(mplew, miniGame, 0, 1, 0); } else { - spawnAnnounceBox(mplew, miniGame, 1, 0, 2, 1); + spawnAnnounceBox(mplew, miniGame, 0, 2, 1); } } else { mplew.write(0); @@ -2141,8 +2140,8 @@ public class MaplePacketCreator { mplew.write(0); } - private static void addAnnounceBox(final MaplePacketLittleEndianWriter mplew, MapleMiniGame game, int gametype, int type, int ammount, int joinable) { - mplew.write(gametype); + private static void addAnnounceBox(final MaplePacketLittleEndianWriter mplew, MapleMiniGame game, int type, int ammount, int joinable) { + mplew.write(game.getGameType().getValue()); mplew.writeInt(game.getObjectId()); // gameid/shopid mplew.writeMapleAsciiString(game.getDescription()); // desc mplew.writeMapleAsciiString(game.getPassword()); @@ -2152,14 +2151,14 @@ public class MaplePacketCreator { mplew.write(joinable); } - private static void spawnAnnounceBox(final MaplePacketLittleEndianWriter mplew, MapleMiniGame game, int gametype, int type, int ammount, int joinable) { - mplew.write(gametype); + private static void spawnAnnounceBox(final MaplePacketLittleEndianWriter mplew, MapleMiniGame game, int type, int ammount, int joinable) { + mplew.write(game.getGameType().getValue()); mplew.writeInt(game.getObjectId()); // gameid/shopid mplew.writeMapleAsciiString(game.getDescription()); // desc - mplew.write(0); + mplew.writeBool(!game.getPassword().isEmpty()); // password here, thanks GabrielSin! mplew.write(type); mplew.write(ammount); - mplew.write(2); + mplew.write(2); //player capacity mplew.write(joinable); } @@ -4937,17 +4936,17 @@ public class MaplePacketCreator { mplew.write(0xFF); mplew.write(0); mplew.writeInt(1); - mplew.writeInt(minigame.getOwner().getMiniGamePoints("wins", true)); - mplew.writeInt(minigame.getOwner().getMiniGamePoints("ties", true)); - mplew.writeInt(minigame.getOwner().getMiniGamePoints("losses", true)); + mplew.writeInt(minigame.getOwner().getMiniGamePoints(MiniGameResult.WIN, true)); + mplew.writeInt(minigame.getOwner().getMiniGamePoints(MiniGameResult.TIE, true)); + mplew.writeInt(minigame.getOwner().getMiniGamePoints(MiniGameResult.LOSS, true)); mplew.writeInt(2000); if (minigame.getVisitor() != null) { MapleCharacter visitor = minigame.getVisitor(); mplew.write(1); mplew.writeInt(1); - mplew.writeInt(visitor.getMiniGamePoints("wins", true)); - mplew.writeInt(visitor.getMiniGamePoints("ties", true)); - mplew.writeInt(visitor.getMiniGamePoints("losses", true)); + mplew.writeInt(visitor.getMiniGamePoints(MiniGameResult.WIN, true)); + mplew.writeInt(visitor.getMiniGamePoints(MiniGameResult.TIE, true)); + mplew.writeInt(visitor.getMiniGamePoints(MiniGameResult.LOSS, true)); mplew.writeInt(2000); } mplew.write(0xFF); @@ -5047,9 +5046,9 @@ public class MaplePacketCreator { addCharLook(mplew, c, false); mplew.writeMapleAsciiString(c.getName()); mplew.writeInt(1); - mplew.writeInt(c.getMiniGamePoints("wins", true)); - mplew.writeInt(c.getMiniGamePoints("ties", true)); - mplew.writeInt(c.getMiniGamePoints("losses", true)); + mplew.writeInt(c.getMiniGamePoints(MiniGameResult.WIN, true)); + mplew.writeInt(c.getMiniGamePoints(MiniGameResult.TIE, true)); + mplew.writeInt(c.getMiniGamePoints(MiniGameResult.LOSS, true)); mplew.writeInt(2000); return mplew.getPacket(); } @@ -5075,14 +5074,14 @@ public class MaplePacketCreator { } mplew.write(0); // owner mplew.writeInt(1); // unknown - mplew.writeInt(game.getOwner().getMiniGamePoints("wins", omok) + win); // wins - mplew.writeInt(game.getOwner().getMiniGamePoints("ties", omok) + tie); // ties - mplew.writeInt(game.getOwner().getMiniGamePoints("losses", omok) + lose); // losses + mplew.writeInt(game.getOwner().getMiniGamePoints(MiniGameResult.WIN, omok) + win); // wins + mplew.writeInt(game.getOwner().getMiniGamePoints(MiniGameResult.TIE, omok) + tie); // ties + mplew.writeInt(game.getOwner().getMiniGamePoints(MiniGameResult.LOSS, omok) + lose); // losses mplew.writeInt(2000); // points mplew.writeInt(1); // start of visitor; unknown - mplew.writeInt(game.getVisitor().getMiniGamePoints("wins", omok) + lose); // wins - mplew.writeInt(game.getVisitor().getMiniGamePoints("ties", omok) + tie); // ties - mplew.writeInt(game.getVisitor().getMiniGamePoints("losses", omok) + win); // losses + mplew.writeInt(game.getVisitor().getMiniGamePoints(MiniGameResult.WIN, omok) + lose); // wins + mplew.writeInt(game.getVisitor().getMiniGamePoints(MiniGameResult.TIE, omok) + tie); // ties + mplew.writeInt(game.getVisitor().getMiniGamePoints(MiniGameResult.LOSS, omok) + win); // losses mplew.writeInt(2000); // points game.getOwner().setMiniGamePoints(game.getVisitor(), result, omok); return mplew.getPacket(); @@ -5136,17 +5135,17 @@ public class MaplePacketCreator { mplew.write(0xFF); mplew.write(0); mplew.writeInt(2); - mplew.writeInt(minigame.getOwner().getMiniGamePoints("wins", false)); - mplew.writeInt(minigame.getOwner().getMiniGamePoints("ties", false)); - mplew.writeInt(minigame.getOwner().getMiniGamePoints("losses", false)); + mplew.writeInt(minigame.getOwner().getMiniGamePoints(MiniGameResult.WIN, false)); + mplew.writeInt(minigame.getOwner().getMiniGamePoints(MiniGameResult.TIE, false)); + mplew.writeInt(minigame.getOwner().getMiniGamePoints(MiniGameResult.LOSS, false)); mplew.writeInt(2000); if (minigame.getVisitor() != null) { MapleCharacter visitor = minigame.getVisitor(); mplew.write(1); mplew.writeInt(2); - mplew.writeInt(visitor.getMiniGamePoints("wins", false)); - mplew.writeInt(visitor.getMiniGamePoints("ties", false)); - mplew.writeInt(visitor.getMiniGamePoints("losses", false)); + mplew.writeInt(visitor.getMiniGamePoints(MiniGameResult.WIN, false)); + mplew.writeInt(visitor.getMiniGamePoints(MiniGameResult.TIE, false)); + mplew.writeInt(visitor.getMiniGamePoints(MiniGameResult.LOSS, false)); mplew.writeInt(2000); } mplew.write(0xFF); @@ -5182,9 +5181,9 @@ public class MaplePacketCreator { addCharLook(mplew, c, false); mplew.writeMapleAsciiString(c.getName()); mplew.writeInt(1); - mplew.writeInt(c.getMiniGamePoints("wins", false)); - mplew.writeInt(c.getMiniGamePoints("ties", false)); - mplew.writeInt(c.getMiniGamePoints("losses", false)); + mplew.writeInt(c.getMiniGamePoints(MiniGameResult.WIN, false)); + mplew.writeInt(c.getMiniGamePoints(MiniGameResult.TIE, false)); + mplew.writeInt(c.getMiniGamePoints(MiniGameResult.LOSS, false)); mplew.writeInt(2000); return mplew.getPacket(); } @@ -5267,7 +5266,7 @@ public class MaplePacketCreator { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendOpcode.UPDATE_CHAR_BOX.getValue()); mplew.writeInt(c.getId()); - addAnnounceBox(mplew, c.getMiniGame(), 1, 0, ammount, type); + addAnnounceBox(mplew, c.getMiniGame(), 0, ammount, type); return mplew.getPacket(); } @@ -5283,11 +5282,11 @@ public class MaplePacketCreator { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendOpcode.UPDATE_CHAR_BOX.getValue()); mplew.writeInt(c.getId()); - addAnnounceBox(mplew, c.getMiniGame(), 2, 0, ammount, type); + addAnnounceBox(mplew, c.getMiniGame(), 0, ammount, type); return mplew.getPacket(); } - public static byte[] removeMatchcardBox(MapleCharacter c) { + public static byte[] removeMatchCardBox(MapleCharacter c) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendOpcode.UPDATE_CHAR_BOX.getValue()); mplew.writeInt(c.getId()); diff --git a/src/tools/data/output/GenericLittleEndianWriter.java b/src/tools/data/output/GenericLittleEndianWriter.java index 560bf50cf9..91779e4d57 100644 --- a/src/tools/data/output/GenericLittleEndianWriter.java +++ b/src/tools/data/output/GenericLittleEndianWriter.java @@ -23,6 +23,7 @@ package tools.data.output; import java.awt.Point; import java.nio.charset.Charset; +import constants.CharsetConstants.MapleLanguageType; /** * Provides a generic writer of a little-endian sequence of bytes. @@ -32,7 +33,7 @@ import java.nio.charset.Charset; * @since Revision 323 */ public class GenericLittleEndianWriter implements LittleEndianWriter { - private static Charset ASCII = Charset.forName("US-ASCII"); + private static Charset ASCII = Charset.forName(MapleLanguageType.LANGUAGE_US.getAscii()); private ByteOutputStream bos; /** diff --git a/wz/Item.wz/Consume/0202.img.xml b/wz/Item.wz/Consume/0202.img.xml index 1a7597047c..000d0fbdfc 100644 --- a/wz/Item.wz/Consume/0202.img.xml +++ b/wz/Item.wz/Consume/0202.img.xml @@ -2125,7 +2125,7 @@ - + diff --git a/wz/Skill.wz/131.img.xml b/wz/Skill.wz/131.img.xml index 032e147e69..e55bf5efa2 100644 --- a/wz/Skill.wz/131.img.xml +++ b/wz/Skill.wz/131.img.xml @@ -1702,6 +1702,7 @@ + @@ -1712,6 +1713,7 @@ + @@ -1722,6 +1724,7 @@ + @@ -1732,6 +1735,7 @@ + @@ -1742,6 +1746,7 @@ + @@ -1752,6 +1757,7 @@ + @@ -1762,6 +1768,7 @@ + @@ -1772,6 +1779,7 @@ + @@ -1782,6 +1790,7 @@ + @@ -1792,6 +1801,7 @@ + @@ -1802,6 +1812,7 @@ + @@ -1812,6 +1823,7 @@ + @@ -1822,6 +1834,7 @@ + @@ -1832,6 +1845,7 @@ + @@ -1842,6 +1856,7 @@ + @@ -1852,6 +1867,7 @@ + @@ -1862,6 +1878,7 @@ + @@ -1872,6 +1889,7 @@ + @@ -1882,6 +1900,7 @@ + @@ -1892,6 +1911,7 @@ + @@ -1902,6 +1922,7 @@ + @@ -1912,6 +1933,7 @@ + @@ -1922,6 +1944,7 @@ + @@ -1932,6 +1955,7 @@ + @@ -1942,6 +1966,7 @@ + @@ -1952,6 +1977,7 @@ + @@ -1962,6 +1988,7 @@ + @@ -1972,6 +1999,7 @@ + @@ -1982,6 +2010,7 @@ + @@ -1992,6 +2021,7 @@ + diff --git a/wz/String.wz/Skill.img.xml b/wz/String.wz/Skill.img.xml index 6df695f054..f7b13e9526 100644 --- a/wz/String.wz/Skill.img.xml +++ b/wz/String.wz/Skill.img.xml @@ -3215,7 +3215,7 @@ - +