diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2024-03-04 16:29:14 +0100 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2024-03-04 20:20:52 +0100 |
commit | 5c7f9d1d216fd1edca231ed274ac3077cb34909f (patch) | |
tree | 234405f8f9d0b422a02d8cc44854aaa6992cf2d9 /src/net | |
parent | d5ebad4e74da011777f9ba1a13fbb37d18c827b9 (diff) | |
download | mana-5c7f9d1d216fd1edca231ed274ac3077cb34909f.tar.gz mana-5c7f9d1d216fd1edca231ed274ac3077cb34909f.tar.bz2 mana-5c7f9d1d216fd1edca231ed274ac3077cb34909f.tar.xz mana-5c7f9d1d216fd1edca231ed274ac3077cb34909f.zip |
Fixed character display
This change fixes hair style to take into account "race", which makes
the faces visible again. Hair colors should also be fixed now, with
partial support for itemcolors.xml added.
The Mana client now also supports per-character gender, and it now hides
the hair style and color buttons on character creation, when there are
none to choose from.
Closes #43
Diffstat (limited to 'src/net')
-rw-r--r-- | src/net/charhandler.h | 6 | ||||
-rw-r--r-- | src/net/logindata.h | 4 | ||||
-rw-r--r-- | src/net/manaserv/beinghandler.cpp | 10 | ||||
-rw-r--r-- | src/net/manaserv/charhandler.cpp | 4 | ||||
-rw-r--r-- | src/net/tmwa/beinghandler.cpp | 57 | ||||
-rw-r--r-- | src/net/tmwa/charserverhandler.cpp | 20 | ||||
-rw-r--r-- | src/net/tmwa/charserverhandler.h | 1 | ||||
-rw-r--r-- | src/net/tmwa/gamehandler.cpp | 2 | ||||
-rw-r--r-- | src/net/tmwa/loginhandler.cpp | 4 | ||||
-rw-r--r-- | src/net/tmwa/protocol.h | 20 | ||||
-rw-r--r-- | src/net/tmwa/token.h | 2 |
11 files changed, 85 insertions, 45 deletions
diff --git a/src/net/charhandler.h b/src/net/charhandler.h index ee8f2298..cebf0b93 100644 --- a/src/net/charhandler.h +++ b/src/net/charhandler.h @@ -78,6 +78,12 @@ class CharHandler virtual unsigned int maxSprite() const = 0; /** + * Returns the min permitted hair color Id at character creation time, + * or 0 if there is no minimum. + */ + virtual int getCharCreateMinHairColorId() const { return 0; } + + /** * Returns the max permitted hair color Id at character creation time, * or 0 if no limit should be applied. */ diff --git a/src/net/logindata.h b/src/net/logindata.h index 1e19b541..34b259fb 100644 --- a/src/net/logindata.h +++ b/src/net/logindata.h @@ -40,7 +40,7 @@ public: std::string email; std::string captchaResponse; - Gender gender = GENDER_UNSPECIFIED; + Gender gender = Gender::UNSPECIFIED; bool remember; /**< Whether to store the username. */ bool registerLogin; /**< Whether an account is being registered. */ @@ -64,7 +64,7 @@ public: updateHost.clear(); email.clear(); captchaResponse.clear(); - gender = GENDER_UNSPECIFIED; + gender = Gender::UNSPECIFIED; resetCharacterSlots(); } }; diff --git a/src/net/manaserv/beinghandler.cpp b/src/net/manaserv/beinghandler.cpp index 6193fed1..186239c1 100644 --- a/src/net/manaserv/beinghandler.cpp +++ b/src/net/manaserv/beinghandler.cpp @@ -115,12 +115,12 @@ void BeingHandler::handleBeingEnterMessage(MessageIn &msg) auto direction = (BeingDirection)msg.readInt8(); Gender gender; int genderAsInt = msg.readInt8(); - if (genderAsInt == ::GENDER_FEMALE) - gender = ::GENDER_FEMALE; - else if (genderAsInt == ::GENDER_MALE) - gender = ::GENDER_MALE; + if (genderAsInt == GENDER_FEMALE) + gender = Gender::FEMALE; + else if (genderAsInt == GENDER_MALE) + gender = Gender::MALE; else - gender = ::GENDER_UNSPECIFIED; + gender = Gender::UNSPECIFIED; Being *being; switch (type) diff --git a/src/net/manaserv/charhandler.cpp b/src/net/manaserv/charhandler.cpp index 61e44506..83919d4e 100644 --- a/src/net/manaserv/charhandler.cpp +++ b/src/net/manaserv/charhandler.cpp @@ -102,8 +102,8 @@ void CharHandler::handleCharacterInfo(MessageIn &msg) CachedCharacterInfo info; info.slot = msg.readInt8(); info.name = msg.readString(); - info.gender = msg.readInt8() == ManaServ::GENDER_MALE ? - ::GENDER_MALE : ::GENDER_FEMALE; + info.gender = msg.readInt8() == ManaServ::GENDER_MALE ? Gender::MALE + : Gender::FEMALE; info.hairStyle = msg.readInt8(); info.hairColor = msg.readInt8(); info.level = msg.readInt16(); diff --git a/src/net/tmwa/beinghandler.cpp b/src/net/tmwa/beinghandler.cpp index 50585970..33adb93b 100644 --- a/src/net/tmwa/beinghandler.cpp +++ b/src/net/tmwa/beinghandler.cpp @@ -242,8 +242,8 @@ void BeingHandler::handleMessage(MessageIn &msg) if (dstBeing->getType() == ActorSprite::PLAYER) { - dstBeing->setGender((gender == 0) - ? GENDER_FEMALE : GENDER_MALE); + dstBeing->setGender(gender == 0 ? Gender::FEMALE + : Gender::MALE); // Set these after the gender, as the sprites may be gender-specific dstBeing->setSprite(SPRITE_HAIR, hairStyle * -1, hairDB.getHairColor(hairColor)); @@ -415,53 +415,60 @@ void BeingHandler::handleMessage(MessageIn &msg) break; } - int type = msg.readInt8(); - int id = msg.readInt16(); - int id2 = msg.readInt16(); + const LOOK type = static_cast<LOOK>(msg.readInt8()); + const int id = msg.readInt16(); + const int id2 = msg.readInt16(); switch (type) { - case 1: // eAthena LOOK_HAIR - dstBeing->setSpriteID(SPRITE_HAIR, id *-1); + case LOOK::HAIR: + { + // const int look = id / 256; + const int hair = id % 256; + dstBeing->setSpriteID(SPRITE_HAIR, hair * -1); break; - case 2: // Weapon ID in id, Shield ID in id2 - dstBeing->setSprite(SPRITE_WEAPON, id, "", true); + } + case LOOK::WEAPON: // Weapon ID in id, Shield ID in id2 + dstBeing->setSprite(SPRITE_WEAPON, id, std::string(), true); dstBeing->setSprite(SPRITE_SHIELD, id2); break; - case 3: // Change lower headgear for eAthena, pants for us + case LOOK::HEAD_BOTTOM: // Change lower headgear for eAthena, pants for us dstBeing->setSprite(SPRITE_BOTTOMCLOTHES, id); break; - case 4: // Change upper headgear for eAthena, hat for us + case LOOK::HEAD_TOP: // Change upper headgear for eAthena, hat for us dstBeing->setSprite(SPRITE_HAT, id); break; - case 5: // Change middle headgear for eathena, armor for us + case LOOK::HEAD_MID: // Change middle headgear for eathena, armor for us dstBeing->setSprite(SPRITE_TOPCLOTHES, id); break; - case 6: // eAthena LOOK_HAIR_COLOR + case LOOK::HAIR_COLOR: dstBeing->setSpriteColor(SPRITE_HAIR, hairDB.getHairColor(id)); break; - case 8: // eAthena LOOK_SHIELD + case LOOK::CLOTHES_COLOR: + // ignoring it + break; + case LOOK::SHIELD: dstBeing->setSprite(SPRITE_SHIELD, id); break; - case 9: // eAthena LOOK_SHOES + case LOOK::SHOES: dstBeing->setSprite(SPRITE_SHOE, id); break; - case 10: // LOOK_GLOVES + case LOOK::GLOVES: dstBeing->setSprite(SPRITE_GLOVES, id); break; - case 11: // LOOK_CAPE + case LOOK::CAPE: dstBeing->setSprite(SPRITE_CAPE, id); break; - case 12: + case LOOK::MISC1: dstBeing->setSprite(SPRITE_MISC1, id); break; - case 13: + case LOOK::MISC2: dstBeing->setSprite(SPRITE_MISC2, id); break; default: logger->log("SMSG_BEING_CHANGE_LOOKS2: unsupported type: " - "%d, id: %d", type, id); + "%d, id: %d", static_cast<int>(type), id); break; } } @@ -549,9 +556,8 @@ void BeingHandler::handleMessage(MessageIn &msg) msg.readInt16(); // manner dstBeing->setStatusEffectBlock(32, msg.readInt16()); // opt3 msg.readInt8(); // karma - dstBeing->setGender((msg.readInt8() == 0) - ? GENDER_FEMALE : GENDER_MALE); - + dstBeing->setGender(msg.readInt8() == 0 ? Gender::FEMALE + : Gender::MALE); // Set these after the gender, as the sprites may be gender-specific dstBeing->setSprite(SPRITE_WEAPON, weapon, "", true); dstBeing->setSprite(SPRITE_SHIELD, shield); @@ -629,9 +635,8 @@ void BeingHandler::handleMessage(MessageIn &msg) dstBeing = actorSpriteManager->findBeing(id); if (dstBeing) { - Uint16 x, y; - x = msg.readInt16(); - y = msg.readInt16(); + Uint16 x = msg.readInt16(); + Uint16 y = msg.readInt16(); handlePosMessage(map, dstBeing, x, y); } } diff --git a/src/net/tmwa/charserverhandler.cpp b/src/net/tmwa/charserverhandler.cpp index 324afd2d..d6b1f5a0 100644 --- a/src/net/tmwa/charserverhandler.cpp +++ b/src/net/tmwa/charserverhandler.cpp @@ -229,7 +229,7 @@ void CharServerHandler::readPlayerData(MessageIn &msg, Net::Character *character msg.readInt32(); // option msg.readInt32(); // karma msg.readInt32(); // manner - msg.skip(2); // unknown + msg.readInt16(); // character points left character->data.mAttributes[HP] = msg.readInt16(); character->data.mAttributes[MAX_HP] = msg.readInt16(); @@ -237,8 +237,10 @@ void CharServerHandler::readPlayerData(MessageIn &msg, Net::Character *character character->data.mAttributes[MAX_MP] = msg.readInt16(); msg.readInt16(); // speed - tempPlayer->setSubtype(msg.readInt16()); // class (used for race) - int hairStyle = msg.readInt16(); + const uint16_t race = msg.readInt16(); // class (used for race) + int hairStyle = msg.readInt8(); + msg.readInt8(); // look + tempPlayer->setSubtype(race); Uint16 weapon = msg.readInt16(); tempPlayer->setSprite(SPRITE_WEAPON, weapon, "", true); @@ -260,7 +262,8 @@ void CharServerHandler::readPlayerData(MessageIn &msg, Net::Character *character character->data.mStats[i + STRENGTH].base = msg.readInt8(); character->slot = msg.readInt8(); // character slot - msg.readInt8(); // unknown + const uint8_t sex = msg.readInt8(); + tempPlayer->setGender(sex ? Gender::MALE : Gender::FEMALE); } void CharServerHandler::setCharSelectDialog(CharSelectDialog *window) @@ -298,7 +301,7 @@ void CharServerHandler::setCharCreateDialog(CharCreateDialog *window) sumStat = Attributes::getCreationPoints(); mCharCreateDialog->setAttributes(attributes, sumStat, minStat, maxStat); - mCharCreateDialog->setFixedGender(true, token.sex); + mCharCreateDialog->setDefaultGender(token.sex); } void CharServerHandler::requestCharacters() @@ -361,6 +364,11 @@ unsigned int CharServerHandler::maxSprite() const return SPRITE_VECTOREND; } +int CharServerHandler::getCharCreateMinHairColorId() const +{ + return CharDB::getMinHairColor(); +} + int CharServerHandler::getCharCreateMaxHairColorId() const { const int max = CharDB::getMaxHairColor(); @@ -387,7 +395,7 @@ void CharServerHandler::connect() // [Fate] The next word is unused by the old char server, so we squeeze in // mana client version information outMsg.writeInt16(CLIENT_PROTOCOL_VERSION); - outMsg.writeInt8((token.sex == GENDER_MALE) ? 1 : 0); + outMsg.writeInt8(token.sex == Gender::MALE ? 1 : 0); // We get 4 useless bytes before the real answer comes in (what are these?) mNetwork->skip(4); diff --git a/src/net/tmwa/charserverhandler.h b/src/net/tmwa/charserverhandler.h index 1102bb08..c8ba4f6f 100644 --- a/src/net/tmwa/charserverhandler.h +++ b/src/net/tmwa/charserverhandler.h @@ -68,6 +68,7 @@ class CharServerHandler : public MessageHandler, public Net::CharHandler unsigned int maxSprite() const override; + int getCharCreateMinHairColorId() const override; int getCharCreateMaxHairColorId() const override; int getCharCreateMaxHairStyleId() const override; diff --git a/src/net/tmwa/gamehandler.cpp b/src/net/tmwa/gamehandler.cpp index 0f423d8d..6f276e66 100644 --- a/src/net/tmwa/gamehandler.cpp +++ b/src/net/tmwa/gamehandler.cpp @@ -140,7 +140,7 @@ void GameHandler::connect() outMsg.writeInt32(mCharID); outMsg.writeInt32(token.session_ID1); outMsg.writeInt32(token.session_ID2); - outMsg.writeInt8((token.sex == GENDER_MALE) ? 1 : 0); + outMsg.writeInt8(token.sex == Gender::MALE ? 1 : 0); // We get 4 useless bytes before the real answer comes in (what are these?) mNetwork->skip(4); diff --git a/src/net/tmwa/loginhandler.cpp b/src/net/tmwa/loginhandler.cpp index 725e0e35..1e0c6eda 100644 --- a/src/net/tmwa/loginhandler.cpp +++ b/src/net/tmwa/loginhandler.cpp @@ -126,7 +126,7 @@ void LoginHandler::handleMessage(MessageIn &msg) mToken.account_ID = msg.readInt32(); mToken.session_ID2 = msg.readInt32(); msg.skip(30); // unknown - mToken.sex = msg.readInt8() ? GENDER_MALE : GENDER_FEMALE; + mToken.sex = msg.readInt8() ? Gender::MALE : Gender::FEMALE; for (int i = 0; i < worldCount; i++) { @@ -305,7 +305,7 @@ void LoginHandler::chooseServer(unsigned int server) void LoginHandler::registerAccount(LoginData *loginData) { std::string username = loginData->username; - username.append((loginData->gender == GENDER_FEMALE) ? "_F" : "_M"); + username.append(loginData->gender == Gender::FEMALE ? "_F" : "_M"); sendLoginRegister(username, loginData->password); } diff --git a/src/net/tmwa/protocol.h b/src/net/tmwa/protocol.h index e50948c5..609b18a5 100644 --- a/src/net/tmwa/protocol.h +++ b/src/net/tmwa/protocol.h @@ -22,6 +22,8 @@ #ifndef TA_PROTOCOL_H #define TA_PROTOCOL_H +#include <cstdint> + namespace TmwAthena { enum { @@ -60,6 +62,24 @@ enum SPRITE_VECTOREND }; +enum class LOOK : uint8_t +{ + BASE = 0, + HAIR = 1, + WEAPON = 2, + HEAD_BOTTOM = 3, + HEAD_TOP = 4, + HEAD_MID = 5, + HAIR_COLOR = 6, + CLOTHES_COLOR = 7, + SHIELD = 8, + SHOES = 9, + GLOVES = 10, + CAPE = 11, + MISC1 = 12, + MISC2 = 13, +}; + enum NpcCommand { NPC_REQUEST_LANG = 0, diff --git a/src/net/tmwa/token.h b/src/net/tmwa/token.h index b5e84238..c0a2b3c8 100644 --- a/src/net/tmwa/token.h +++ b/src/net/tmwa/token.h @@ -36,7 +36,7 @@ struct Token account_ID = 0; session_ID1 = 0; session_ID2 = 0; - sex = GENDER_UNSPECIFIED; + sex = Gender::UNSPECIFIED; } }; |