diff options
-rw-r--r-- | src/net/ea/playerhandler.cpp | 436 | ||||
-rw-r--r-- | src/net/ea/playerhandler.h | 16 | ||||
-rw-r--r-- | src/net/eathena/playerhandler.cpp | 8 | ||||
-rw-r--r-- | src/net/eathena/playerhandler.h | 5 | ||||
-rw-r--r-- | src/net/tmwa/playerhandler.cpp | 15 | ||||
-rw-r--r-- | src/net/tmwa/playerhandler.h | 5 |
6 files changed, 269 insertions, 216 deletions
diff --git a/src/net/ea/playerhandler.cpp b/src/net/ea/playerhandler.cpp index 01b83e143..b3e193e1f 100644 --- a/src/net/ea/playerhandler.cpp +++ b/src/net/ea/playerhandler.cpp @@ -173,48 +173,192 @@ void PlayerHandler::processPlayerWarp(Net::MessageIn &msg) BLOCK_END("PlayerHandler::processPlayerWarp") } -void PlayerHandler::processPlayerStatUpdate1(Net::MessageIn &msg) +void PlayerHandler::processPlayerStatUpdate1(Net::MessageIn &msg) const { BLOCK_START("PlayerHandler::processPlayerStatUpdate1") - const int type = msg.readInt16(); - const int value = msg.readInt32(); + const int type = msg.readInt16("type"); + const int value = msg.readInt32("value"); if (!localPlayer) { BLOCK_END("PlayerHandler::processPlayerStatUpdate1") return; } + setStat(type, value, -1, true); + + if (PlayerInfo::getAttribute(Attributes::HP) == 0 && !deathNotice) + { + // TRANSLATORS: message header + deathNotice = new OkDialog(_("Message"), + DeadDB::getRandomString(), + // TRANSLATORS: ok dialog button + _("Revive"), + DialogType::OK, + false, true, nullptr, 260); + deathNotice->addActionListener(&deathListener); + if (localPlayer->getCurrentAction() != BeingAction::DEAD) + { + localPlayer->setAction(BeingAction::DEAD, 0); + localPlayer->recalcSpritesOrder(); + } + } + BLOCK_END("PlayerHandler::processPlayerStatUpdate1") +} + +void PlayerHandler::processPlayerStatUpdate2(Net::MessageIn &msg) const +{ + BLOCK_START("PlayerHandler::processPlayerStatUpdate2") + const int type = msg.readInt16("type"); + const int value = msg.readInt32("value"); + setStat(type, value, -1, true); + BLOCK_END("PlayerHandler::processPlayerStatUpdate2") +} + +void PlayerHandler::processPlayerStatUpdate3(Net::MessageIn &msg) const +{ + BLOCK_START("PlayerHandler::processPlayerStatUpdate3") + const int type = msg.readInt32("type"); + const int base = msg.readInt32("base"); + const int bonus = msg.readInt32("bonus"); + + setStat(type, base, bonus, false); + if (type == EA_ATK || type == Attributes::ATTACK_DELAY) + PlayerInfo::updateAttrs(); + BLOCK_END("PlayerHandler::processPlayerStatUpdate3") +} + +void PlayerHandler::processPlayerStatUpdate4(Net::MessageIn &msg) const +{ + BLOCK_START("PlayerHandler::processPlayerStatUpdate4") + const int type = msg.readInt16(); + const uint8_t ok = msg.readUInt8(); + const int value = msg.readUInt8(); + + if (ok != 1) + { + const int oldValue = PlayerInfo::getStatBase(type); + const int points = PlayerInfo::getAttribute(Attributes::CHAR_POINTS) + + oldValue - value; + PlayerInfo::setAttribute(Attributes::CHAR_POINTS, points); + NotifyManager::notify(NotifyTypes::SKILL_RAISE_ERROR); + } + + setStat(type, value, -1, true); + BLOCK_END("PlayerHandler::processPlayerStatUpdate4") +} + +void PlayerHandler::processPlayerStatUpdate6(Net::MessageIn &msg) const +{ + BLOCK_START("PlayerHandler::processPlayerStatUpdate6") + const int type = msg.readInt16("type"); + const int value = msg.readUInt8("value"); + if (statusWindow) + setStat(type, value, -1, true); + BLOCK_END("PlayerHandler::processPlayerStatUpdate6") +} + +void PlayerHandler::processPlayerArrowMessage(Net::MessageIn &msg) +{ + BLOCK_START("PlayerHandler::processPlayerArrowMessage") + const int type = msg.readInt16(); switch (type) { + case 0: + NotifyManager::notify(NotifyTypes::ARROWS_EQUIP_NEEDED); + break; + case 3: + // arrows equiped + break; + default: + logger->log("QQQQ 0x013b: Unhandled message %i", type); + break; + } + BLOCK_END("PlayerHandler::processPlayerArrowMessage") +} + +bool PlayerHandler::canUseMagic() const +{ + return PlayerInfo::getStatEffective(EA_MATK) > 0; +} + +int PlayerHandler::getJobLocation() const +{ + return EA_JOB; +} + +int PlayerHandler::getAttackLocation() const +{ + return EA_ATK; +} + +#define setStatComplex(stat) \ + PlayerInfo::setStatBase(stat, base, notify); \ + if (mod != -1) \ + PlayerInfo::setStatMod(stat, mod) + +void PlayerHandler::setStat(const int type, + const int base, + const int mod, + const bool notify) const +{ + switch (type) + { + case EA_STR: + setStatComplex(EA_STR); + break; + case EA_AGI: + setStatComplex(EA_AGI); + break; + case EA_VIT: + setStatComplex(EA_VIT); + break; + case EA_INT: + setStatComplex(EA_INT); + break; + case EA_DEX: + setStatComplex(EA_DEX); + break; + case EA_LUK: + setStatComplex(EA_LUK); + break; + case 0x0000: localPlayer->setWalkSpeed(Vector(static_cast<float>( - value), static_cast<float>(value), 0)); - PlayerInfo::setStatBase(Attributes::WALK_SPEED, value); + base), static_cast<float>(base), 0)); + PlayerInfo::setStatBase(Attributes::WALK_SPEED, base); PlayerInfo::setStatMod(Attributes::WALK_SPEED, 0); break; + case 0x0001: + PlayerInfo::setAttribute(Attributes::EXP, base); + break; + case 0x0002: + PlayerInfo::setStatExperience(EA_JOB, base, + PlayerInfo::getStatExperience(EA_JOB).second); + break; case 0x0003: - PlayerInfo::setStatBase(Attributes::KARMA, value); + PlayerInfo::setStatBase(Attributes::KARMA, base); PlayerInfo::setStatMod(Attributes::KARMA, 0); break; case 0x0004: - PlayerInfo::setStatBase(Attributes::MANNER, value); + PlayerInfo::setStatBase(Attributes::MANNER, base); PlayerInfo::setStatMod(Attributes::MANNER, 0); break; case 0x0005: - PlayerInfo::setAttribute(Attributes::HP, value); + PlayerInfo::setAttribute(Attributes::HP, base); if (localPlayer->isInParty() && Party::getParty(1)) { PartyMember *const m = Party::getParty(1) ->getMember(localPlayer->getId()); if (m) { - m->setHp(value); + m->setHp(base); m->setMaxHp(PlayerInfo::getAttribute(Attributes::MAX_HP)); } } break; + case 0x0006: - PlayerInfo::setAttribute(Attributes::MAX_HP, value); + PlayerInfo::setAttribute(Attributes::MAX_HP, base); if (localPlayer->isInParty() && Party::getParty(1)) { @@ -223,32 +367,57 @@ void PlayerHandler::processPlayerStatUpdate1(Net::MessageIn &msg) if (m) { m->setHp(PlayerInfo::getAttribute(Attributes::HP)); - m->setMaxHp(value); + m->setMaxHp(base); } } break; case 0x0007: - PlayerInfo::setAttribute(Attributes::MP, value); + PlayerInfo::setAttribute(Attributes::MP, base); break; case 0x0008: - PlayerInfo::setAttribute(Attributes::MAX_MP, value); + PlayerInfo::setAttribute(Attributes::MAX_MP, base); break; case 0x0009: - PlayerInfo::setAttribute(Attributes::CHAR_POINTS, value); + PlayerInfo::setAttribute(Attributes::CHAR_POINTS, base); break; case 0x000b: - PlayerInfo::setAttribute(Attributes::LEVEL, value); + PlayerInfo::setAttribute(Attributes::LEVEL, base); if (localPlayer) { - localPlayer->setLevel(value); + localPlayer->setLevel(base); localPlayer->updateName(); } break; case 0x000c: - PlayerInfo::setAttribute(Attributes::SKILL_POINTS, value); + PlayerInfo::setAttribute(Attributes::SKILL_POINTS, base); if (skillDialog) skillDialog->update(); break; + case 0x0014: + { + const int oldMoney = PlayerInfo::getAttribute(Attributes::MONEY); + const int newMoney = base; + if (newMoney > oldMoney) + { + NotifyManager::notify(NotifyTypes::MONEY_GET, + Units::formatCurrency(newMoney - oldMoney)); + } + else if (newMoney < oldMoney) + { + NotifyManager::notify(NotifyTypes::MONEY_SPENT, + Units::formatCurrency(oldMoney - newMoney).c_str()); + } + + PlayerInfo::setAttribute(Attributes::MONEY, newMoney); + break; + } + case 0x0016: + PlayerInfo::setAttribute(Attributes::EXP_NEEDED, base); + break; + case 0x0017: + PlayerInfo::setStatExperience(EA_JOB, + PlayerInfo::getStatExperience(EA_JOB).first, base); + break; case 0x0018: if (!weightNotice && config.getBoolValue("weightMsg")) { @@ -256,7 +425,7 @@ void PlayerHandler::processPlayerStatUpdate1(Net::MessageIn &msg) Attributes::MAX_WEIGHT) / 2; const int total = PlayerInfo::getAttribute( Attributes::TOTAL_WEIGHT); - if (value >= max && total < max) + if (base >= max && total < max) { weightNoticeTime = cur_time + 5; // TRANSLATORS: message header @@ -272,7 +441,7 @@ void PlayerHandler::processPlayerStatUpdate1(Net::MessageIn &msg) weightNotice->addActionListener( &weightListener); } - else if (value < max && total >= max) + else if (base < max && total >= max) { weightNoticeTime = cur_time + 5; // TRANSLATORS: message header @@ -289,243 +458,88 @@ void PlayerHandler::processPlayerStatUpdate1(Net::MessageIn &msg) &weightListener); } } - PlayerInfo::setAttribute(Attributes::TOTAL_WEIGHT, value); + PlayerInfo::setAttribute(Attributes::TOTAL_WEIGHT, base); break; case 0x0019: - PlayerInfo::setAttribute(Attributes::MAX_WEIGHT, value); + PlayerInfo::setAttribute(Attributes::MAX_WEIGHT, base); + break; + case 0x0020: + statusWindow->setPointsNeeded(EA_STR, base); + break; + case 0x0021: + statusWindow->setPointsNeeded(EA_AGI, base); + break; + case 0x0022: + statusWindow->setPointsNeeded(EA_VIT, base); + break; + case 0x0023: + statusWindow->setPointsNeeded(EA_INT, base); + break; + case 0x0024: + statusWindow->setPointsNeeded(EA_DEX, base); + break; + case 0x0025: + statusWindow->setPointsNeeded(EA_LUK, base); break; case 0x0029: - PlayerInfo::setStatBase(EA_ATK, value); + PlayerInfo::setStatBase(EA_ATK, base); PlayerInfo::updateAttrs(); break; case 0x002a: - PlayerInfo::setStatMod(EA_ATK, value); + PlayerInfo::setStatMod(EA_ATK, base); PlayerInfo::updateAttrs(); break; case 0x002b: - PlayerInfo::setStatBase(EA_MATK, value); + PlayerInfo::setStatBase(EA_MATK, base); break; case 0x002c: - PlayerInfo::setStatMod(EA_MATK, value); + PlayerInfo::setStatMod(EA_MATK, base); break; - case 0x002d: - PlayerInfo::setStatBase(EA_DEF, value); + PlayerInfo::setStatBase(EA_DEF, base); break; case 0x002e: - PlayerInfo::setStatMod(EA_DEF, value); + PlayerInfo::setStatMod(EA_DEF, base); break; case 0x002f: - PlayerInfo::setStatBase(EA_MDEF, value); + PlayerInfo::setStatBase(EA_MDEF, base); break; case 0x0030: - PlayerInfo::setStatMod(EA_MDEF, value); + PlayerInfo::setStatMod(EA_MDEF, base); break; case 0x0031: - PlayerInfo::setStatBase(EA_HIT, value); + PlayerInfo::setStatBase(EA_HIT, base); break; case 0x0032: - PlayerInfo::setStatBase(EA_FLEE, value); + PlayerInfo::setStatBase(EA_FLEE, base); break; case 0x0033: - PlayerInfo::setStatMod(EA_FLEE, value); + PlayerInfo::setStatMod(EA_FLEE, base); break; - case 0x0034: - PlayerInfo::setStatBase(EA_CRIT, value); + PlayerInfo::setStatBase(EA_CRIT, base); break; case 0x0035: - localPlayer->setAttackSpeed(value); - PlayerInfo::setStatBase(Attributes::ATTACK_DELAY, value); + localPlayer->setAttackSpeed(base); + PlayerInfo::setStatBase(Attributes::ATTACK_DELAY, base); PlayerInfo::setStatMod(Attributes::ATTACK_DELAY, 0); PlayerInfo::updateAttrs(); break; - case 0x0037: - PlayerInfo::setStatBase(EA_JOB, value); - break; - - case 500: - localPlayer->setGMLevel(value); - break; - - default: - logger->log("QQQQ PLAYER_STAT_UPDATE_1 " - + toString(type) + "," + toString(value)); - break; - } - - if (PlayerInfo::getAttribute(Attributes::HP) == 0 && !deathNotice) - { - // TRANSLATORS: message header - deathNotice = new OkDialog(_("Message"), - DeadDB::getRandomString(), - // TRANSLATORS: ok dialog button - _("Revive"), - DialogType::OK, - false, true, nullptr, 260); - deathNotice->addActionListener(&deathListener); - if (localPlayer->getCurrentAction() != BeingAction::DEAD) - { - localPlayer->setAction(BeingAction::DEAD, 0); - localPlayer->recalcSpritesOrder(); - } - } - BLOCK_END("PlayerHandler::processPlayerStatUpdate1") -} - -void PlayerHandler::processPlayerStatUpdate2(Net::MessageIn &msg) -{ - BLOCK_START("PlayerHandler::processPlayerStatUpdate2") - const int type = msg.readInt16(); - switch (type) - { - case 0x0001: - PlayerInfo::setAttribute(Attributes::EXP, msg.readInt32()); + PlayerInfo::setStatBase(EA_JOB, base); break; - case 0x0002: - PlayerInfo::setStatExperience(EA_JOB, msg.readInt32(), - PlayerInfo::getStatExperience(EA_JOB).second); - break; - case 0x0014: - { - const int oldMoney = PlayerInfo::getAttribute(Attributes::MONEY); - const int newMoney = msg.readInt32(); - if (newMoney > oldMoney) - { - NotifyManager::notify(NotifyTypes::MONEY_GET, - Units::formatCurrency(newMoney - oldMoney)); - } - else if (newMoney < oldMoney) - { - NotifyManager::notify(NotifyTypes::MONEY_SPENT, - Units::formatCurrency(oldMoney - newMoney).c_str()); - } - - PlayerInfo::setAttribute(Attributes::MONEY, newMoney); - break; - } - case 0x0016: - PlayerInfo::setAttribute(Attributes::EXP_NEEDED, msg.readInt32()); - break; - case 0x0017: - PlayerInfo::setStatExperience(EA_JOB, - PlayerInfo::getStatExperience(EA_JOB).first, msg.readInt32()); - break; - default: - logger->log("QQQQ PLAYER_STAT_UPDATE_2 " + toString(type)); - break; - } - BLOCK_END("PlayerHandler::processPlayerStatUpdate2") -} -void PlayerHandler::processPlayerStatUpdate3(Net::MessageIn &msg) -{ - BLOCK_START("PlayerHandler::processPlayerStatUpdate3") - const int type = msg.readInt32(); - const int base = msg.readInt32(); - const int bonus = msg.readInt32(); - - PlayerInfo::setStatBase(type, base, false); - PlayerInfo::setStatMod(type, bonus); - if (type == EA_ATK || type == Attributes::ATTACK_DELAY) - PlayerInfo::updateAttrs(); - BLOCK_END("PlayerHandler::processPlayerStatUpdate3") -} - -void PlayerHandler::processPlayerStatUpdate4(Net::MessageIn &msg) -{ - BLOCK_START("PlayerHandler::processPlayerStatUpdate4") - const int type = msg.readInt16(); - const uint8_t ok = msg.readUInt8(); - const int value = msg.readUInt8(); - - if (ok != 1) - { - const int oldValue = PlayerInfo::getStatBase(type); - const int points = PlayerInfo::getAttribute(Attributes::CHAR_POINTS) - + oldValue - value; - PlayerInfo::setAttribute(Attributes::CHAR_POINTS, points); - NotifyManager::notify(NotifyTypes::SKILL_RAISE_ERROR); - } - - PlayerInfo::setStatBase(type, value); - BLOCK_END("PlayerHandler::processPlayerStatUpdate4") -} - -void PlayerHandler::processPlayerStatUpdate6(Net::MessageIn &msg) -{ - BLOCK_START("PlayerHandler::processPlayerStatUpdate6") - const int type = msg.readInt16(); - if (statusWindow) - { - switch (type) - { - case 0x0020: - statusWindow->setPointsNeeded(EA_STR, msg.readUInt8()); - break; - case 0x0021: - statusWindow->setPointsNeeded(EA_AGI, msg.readUInt8()); - break; - case 0x0022: - statusWindow->setPointsNeeded(EA_VIT, msg.readUInt8()); - break; - case 0x0023: - statusWindow->setPointsNeeded(EA_INT, msg.readUInt8()); - break; - case 0x0024: - statusWindow->setPointsNeeded(EA_DEX, msg.readUInt8()); - break; - case 0x0025: - statusWindow->setPointsNeeded(EA_LUK, msg.readUInt8()); - break; - default: - logger->log("QQQQ PLAYER_STAT_UPDATE_6 " - + toString(type)); - break; - } - } - BLOCK_END("PlayerHandler::processPlayerStatUpdate6") -} - -void PlayerHandler::processPlayerArrowMessage(Net::MessageIn &msg) -{ - BLOCK_START("PlayerHandler::processPlayerArrowMessage") - const int type = msg.readInt16(); - switch (type) - { - case 0: - NotifyManager::notify(NotifyTypes::ARROWS_EQUIP_NEEDED); - break; - case 3: - // arrows equiped - break; default: - logger->log("QQQQ 0x013b: Unhandled message %i", type); + logger->log("Error: Unknown stat set: %d, values: %d, %d", + type, base, mod); break; } - BLOCK_END("PlayerHandler::processPlayerArrowMessage") -} - -bool PlayerHandler::canUseMagic() const -{ - return PlayerInfo::getStatEffective(EA_MATK) > 0; -} - -int PlayerHandler::getJobLocation() const -{ - return EA_JOB; -} - -int PlayerHandler::getAttackLocation() const -{ - return EA_ATK; } } // namespace Ea diff --git a/src/net/ea/playerhandler.h b/src/net/ea/playerhandler.h index 6669da9ff..a2e126bc2 100644 --- a/src/net/ea/playerhandler.h +++ b/src/net/ea/playerhandler.h @@ -57,17 +57,23 @@ class PlayerHandler notfinal : public Net::PlayerHandler int getAttackLocation() const override final A_WARN_UNUSED; + protected: + virtual void setStat(const int type, + const int base, + const int mod, + const bool notify) const = 0; + static void processPlayerWarp(Net::MessageIn &msg); - static void processPlayerStatUpdate1(Net::MessageIn &msg); + void processPlayerStatUpdate1(Net::MessageIn &msg) const; - static void processPlayerStatUpdate2(Net::MessageIn &msg); + void processPlayerStatUpdate2(Net::MessageIn &msg) const; - static void processPlayerStatUpdate3(Net::MessageIn &msg); + void processPlayerStatUpdate3(Net::MessageIn &msg) const; - static void processPlayerStatUpdate4(Net::MessageIn &msg); + void processPlayerStatUpdate4(Net::MessageIn &msg) const; - static void processPlayerStatUpdate6(Net::MessageIn &msg); + void processPlayerStatUpdate6(Net::MessageIn &msg) const; static void processPlayerArrowMessage(Net::MessageIn &msg); }; diff --git a/src/net/eathena/playerhandler.cpp b/src/net/eathena/playerhandler.cpp index 3a4f46a2c..089a06d26 100644 --- a/src/net/eathena/playerhandler.cpp +++ b/src/net/eathena/playerhandler.cpp @@ -436,4 +436,12 @@ void PlayerHandler::processPlayerHeal(Net::MessageIn &msg) msg.readInt16("value"); } +void PlayerHandler::setStat(const int type, + const int base, + const int mod, + const bool notify) const +{ + Ea::PlayerHandler::setStat(type, base, mod, notify); +} + } // namespace EAthena diff --git a/src/net/eathena/playerhandler.h b/src/net/eathena/playerhandler.h index f94fd0652..3a0ba20fa 100644 --- a/src/net/eathena/playerhandler.h +++ b/src/net/eathena/playerhandler.h @@ -73,6 +73,11 @@ class PlayerHandler final : public MessageHandler, public Ea::PlayerHandler void setViewEquipment(const bool allow) const override final; protected: + void setStat(const int type, + const int base, + const int mod, + const bool notify) const override final; + void processPlayerStatUpdate5(Net::MessageIn &msg); void processPlayerGetExp(Net::MessageIn &msg); diff --git a/src/net/tmwa/playerhandler.cpp b/src/net/tmwa/playerhandler.cpp index 9ad631d71..f2b47c607 100644 --- a/src/net/tmwa/playerhandler.cpp +++ b/src/net/tmwa/playerhandler.cpp @@ -25,6 +25,7 @@ #include "configuration.h" #include "game.h" #include "soundmanager.h" +#include "units.h" #include "being/attributes.h" #include "being/beingflag.h" @@ -37,6 +38,7 @@ #include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" +#include "gui/windows/skilldialog.h" #include "gui/windows/whoisonline.h" #include "gui/onlineplayer.h" @@ -470,4 +472,17 @@ void PlayerHandler::setViewEquipment(const bool allow A_UNUSED) const { } +void PlayerHandler::setStat(const int type, + const int base, + const int mod, + const bool notify) const +{ + if (type == 500) + { + localPlayer->setGMLevel(base); + return; + } + Ea::PlayerHandler::setStat(type, base, mod, notify); +} + } // namespace TmwAthena diff --git a/src/net/tmwa/playerhandler.h b/src/net/tmwa/playerhandler.h index 3fb89db83..05b7b1d27 100644 --- a/src/net/tmwa/playerhandler.h +++ b/src/net/tmwa/playerhandler.h @@ -82,6 +82,11 @@ class PlayerHandler final : public MessageHandler, public Ea::PlayerHandler void setViewEquipment(const bool allow) const override final; protected: + void setStat(const int type, + const int base, + const int mod, + const bool notify) const override final; + void processPlayerStatUpdate5(Net::MessageIn &msg); static void processWalkResponse(Net::MessageIn &msg); |