summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-08-12 11:05:13 +0200
committerThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-08-12 11:05:17 +0200
commit91f2c508390c2344a44d2959708f95001afdb8ff (patch)
tree6f558e00f455f9142a32a2b8ce45180d09fbbd4b
parentaaa371290fff214657eeada8bd4e0f0b5c0026c3 (diff)
downloadmana-91f2c508390c2344a44d2959708f95001afdb8ff.tar.gz
mana-91f2c508390c2344a44d2959708f95001afdb8ff.tar.bz2
mana-91f2c508390c2344a44d2959708f95001afdb8ff.tar.xz
mana-91f2c508390c2344a44d2959708f95001afdb8ff.zip
Work around player invisibility caused by "unspecified" gender
The "Unspecified" gender was causing some older players to be invisible since no sprites were displayed at all. I think this is a bug in TMWA, which should never send SEX::UNSPECIFIED for player characters, but while this bug exists we can make sure to map this to Gender::Neutral (renamed from "Hidden"). The Gender::Unspecified value was removed entirely because it never makes sense for beings. One "neutral" value should be enough.
-rw-r--r--src/being.h9
-rw-r--r--src/net/logindata.h4
-rw-r--r--src/net/manaserv/beinghandler.cpp25
-rw-r--r--src/net/manaserv/charhandler.cpp12
-rw-r--r--src/net/manaserv/manaserv_protocol.h14
-rw-r--r--src/net/tmwa/charserverhandler.cpp9
-rw-r--r--src/net/tmwa/protocol.h8
-rw-r--r--src/resources/itemdb.cpp4
8 files changed, 30 insertions, 55 deletions
diff --git a/src/being.h b/src/being.h
index 43cc546c..682d2fd5 100644
--- a/src/being.h
+++ b/src/being.h
@@ -56,10 +56,9 @@ class Text;
enum class Gender
{
- Male = 0,
- Female = 1,
- Unspecified = 2,
- Hidden = 3
+ Neutral,
+ Male,
+ Female
};
class Being : public ActorSprite, public EventListener, public gcn::DeathListener
@@ -530,7 +529,7 @@ class Being : public ActorSprite, public EventListener, public gcn::DeathListene
std::vector<SpriteState> mSpriteStates;
bool mRestoreParticlesOnLogic = false;
- Gender mGender = Gender::Unspecified;
+ Gender mGender = Gender::Neutral;
// Character guild information
std::map<int, Guild*> mGuilds;
diff --git a/src/net/logindata.h b/src/net/logindata.h
index 4af402ec..36d197e7 100644
--- a/src/net/logindata.h
+++ b/src/net/logindata.h
@@ -39,7 +39,7 @@ public:
std::string email;
std::string captchaResponse;
- Gender gender = Gender::Unspecified;
+ Gender gender = Gender::Neutral;
bool remember; /**< Whether to store the username. */
bool registerLogin; /**< Whether an account is being registered. */
@@ -63,7 +63,7 @@ public:
updateHost.clear();
email.clear();
captchaResponse.clear();
- gender = Gender::Unspecified;
+ gender = Gender::Neutral;
resetCharacterSlots();
}
};
diff --git a/src/net/manaserv/beinghandler.cpp b/src/net/manaserv/beinghandler.cpp
index 9bb52ac1..6caa90d4 100644
--- a/src/net/manaserv/beinghandler.cpp
+++ b/src/net/manaserv/beinghandler.cpp
@@ -146,24 +146,13 @@ static void handleLooks(Being *being, MessageIn &msg)
void BeingHandler::handleBeingEnterMessage(MessageIn &msg)
{
- int type = msg.readInt8();
- int id = msg.readInt16();
- auto action = (Being::Action)msg.readInt8();
- int px = msg.readInt16();
- int py = msg.readInt16();
- auto direction = (BeingDirection)msg.readInt8();
-
- Gender gender = Gender::Unspecified;
- switch (getGender(msg.readInt8())) {
- case GENDER_MALE:
- gender = Gender::Male;
- break;
- case GENDER_FEMALE:
- gender = Gender::Female;
- break;
- case GENDER_UNSPECIFIED:
- break;
- }
+ const int type = msg.readInt8();
+ const int id = msg.readInt16();
+ const auto action = static_cast<Being::Action>(msg.readInt8());
+ const int px = msg.readInt16();
+ const int py = msg.readInt16();
+ const auto direction = static_cast<BeingDirection>(msg.readInt8());
+ const Gender gender = getGender(msg.readInt8());
Being *being;
diff --git a/src/net/manaserv/charhandler.cpp b/src/net/manaserv/charhandler.cpp
index 8d7c5511..215cf380 100644
--- a/src/net/manaserv/charhandler.cpp
+++ b/src/net/manaserv/charhandler.cpp
@@ -106,17 +106,7 @@ void CharHandler::handleCharacterInfo(MessageIn &msg)
info.slot = msg.readInt8();
info.name = msg.readString();
- switch (getGender(msg.readInt8())) {
- case GENDER_MALE:
- info.gender = Gender::Male;
- break;
- case GENDER_FEMALE:
- info.gender = Gender::Female;
- break;
- case GENDER_UNSPECIFIED:
- info.gender = Gender::Unspecified;
- break;
- }
+ info.gender = getGender(msg.readInt8());
info.hairStyle = msg.readInt8();
info.hairColor = msg.readInt8();
info.characterPoints = msg.readInt16();
diff --git a/src/net/manaserv/manaserv_protocol.h b/src/net/manaserv/manaserv_protocol.h
index cb27d6f4..5ade87bc 100644
--- a/src/net/manaserv/manaserv_protocol.h
+++ b/src/net/manaserv/manaserv_protocol.h
@@ -21,6 +21,8 @@
#pragma once
+#include "being.h"
+
namespace ManaServ {
enum {
@@ -464,16 +466,16 @@ enum BeingGender
/**
* Helper function for getting gender by int
*/
-inline ManaServ::BeingGender getGender(int gender)
+inline Gender getGender(int gender)
{
switch (gender)
{
- case 0:
- return ManaServ::GENDER_MALE;
- case 1:
- return ManaServ::GENDER_FEMALE;
+ case GENDER_MALE:
+ return Gender::Male;
+ case GENDER_FEMALE:
+ return Gender::Female;
default:
- return ManaServ::GENDER_UNSPECIFIED;
+ return Gender::Neutral;
}
}
diff --git a/src/net/tmwa/charserverhandler.cpp b/src/net/tmwa/charserverhandler.cpp
index e8562bf9..f248388b 100644
--- a/src/net/tmwa/charserverhandler.cpp
+++ b/src/net/tmwa/charserverhandler.cpp
@@ -268,9 +268,7 @@ void CharServerHandler::readPlayerData(MessageIn &msg, Net::Character *character
character->data.mStats[i + STRENGTH].base = msg.readInt8();
character->slot = msg.readInt8(); // character slot
- const Gender gender = sexToGender(static_cast<SEX>(msg.readInt8()));
- if (gender != Gender::Unspecified)
- tempPlayer->setGender(gender);
+ tempPlayer->setGender(sexToGender(static_cast<SEX>(msg.readInt8())));
}
void CharServerHandler::setCharSelectDialog(CharSelectDialog *window)
@@ -309,9 +307,8 @@ void CharServerHandler::setCharCreateDialog(CharCreateDialog *window)
mCharCreateDialog->setAttributes(attributes, sumStat, minStat, maxStat);
- const Gender gender = sexToGender(token.sex);
- if (gender != Gender::Unspecified)
- mCharCreateDialog->setDefaultGender(gender);
+ if (token.sex != SEX::UNSPECIFIED)
+ mCharCreateDialog->setDefaultGender(sexToGender(token.sex));
}
void CharServerHandler::requestCharacters()
diff --git a/src/net/tmwa/protocol.h b/src/net/tmwa/protocol.h
index 1f91616f..b93c81e1 100644
--- a/src/net/tmwa/protocol.h
+++ b/src/net/tmwa/protocol.h
@@ -107,12 +107,10 @@ inline Gender sexToGender(SEX sex)
{
switch (sex)
{
- case SEX::FEMALE: return Gender::Female;
- case SEX::MALE: return Gender::Male;
- case SEX::UNSPECIFIED: return Gender::Unspecified;
- case SEX::NEUTRAL: return Gender::Hidden;
+ case SEX::FEMALE: return Gender::Female;
+ case SEX::MALE: return Gender::Male;
+ default: return Gender::Neutral;
}
- return Gender::Unspecified;
}
enum NpcCommand
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index 1d217fc2..7f4cbdec 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -125,7 +125,7 @@ void ItemDB::loadEmptyItemDefinition()
std::string errFile = paths.getStringValue("spriteErrorFile");
mUnknown->setSprite(errFile, Gender::Male, 0);
mUnknown->setSprite(errFile, Gender::Female, 0);
- mUnknown->setSprite(errFile, Gender::Hidden, 0);
+ mUnknown->setSprite(errFile, Gender::Neutral, 0);
mUnknown->hitEffectId = paths.getIntValue("hitEffectId");
mUnknown->criticalHitEffectId = paths.getIntValue("criticalHitEffectId");
}
@@ -184,7 +184,7 @@ void ItemDB::loadSpriteRef(ItemInfo &itemInfo, XML::Node node)
if (gender == "female" || gender == "unisex")
itemInfo.setSprite(filename, Gender::Female, race);
if (gender == "hidden" || gender == "other" || gender == "unisex")
- itemInfo.setSprite(filename, Gender::Hidden, race);
+ itemInfo.setSprite(filename, Gender::Neutral, race);
}
void ItemDB::loadSoundRef(ItemInfo &itemInfo, XML::Node node)