summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/being.cpp6
-rw-r--r--src/being.h11
-rw-r--r--src/gui/charcreatedialog.cpp43
-rw-r--r--src/gui/charcreatedialog.h2
-rw-r--r--src/gui/register.cpp2
-rw-r--r--src/net/charhandler.h6
-rw-r--r--src/net/logindata.h4
-rw-r--r--src/net/manaserv/beinghandler.cpp10
-rw-r--r--src/net/manaserv/charhandler.cpp4
-rw-r--r--src/net/tmwa/beinghandler.cpp57
-rw-r--r--src/net/tmwa/charserverhandler.cpp20
-rw-r--r--src/net/tmwa/charserverhandler.h1
-rw-r--r--src/net/tmwa/gamehandler.cpp2
-rw-r--r--src/net/tmwa/loginhandler.cpp4
-rw-r--r--src/net/tmwa/protocol.h20
-rw-r--r--src/net/tmwa/token.h2
-rw-r--r--src/resources/hairdb.cpp8
-rw-r--r--src/resources/hairdb.h2
-rw-r--r--src/resources/itemdb.cpp16
-rw-r--r--src/resources/iteminfo.cpp28
-rw-r--r--src/resources/iteminfo.h7
-rw-r--r--src/resources/settingsmanager.cpp16
22 files changed, 164 insertions, 107 deletions
diff --git a/src/being.cpp b/src/being.cpp
index ad43ec52..46b499af 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -942,9 +942,9 @@ void Being::showName()
{
if (config.getBoolValue("showgender"))
{
- if (getGender() == GENDER_FEMALE)
+ if (getGender() == Gender::FEMALE)
mDisplayName += " \u2640";
- else if (getGender() == GENDER_MALE)
+ else if (getGender() == Gender::MALE)
mDisplayName += " \u2642";
}
@@ -1041,7 +1041,7 @@ void Being::setSprite(unsigned int slot, int id, const std::string &color,
}
else
{
- std::string filename = itemDb->get(id).getSprite(mGender);
+ std::string filename = itemDb->get(id).getSprite(mGender, mSubType);
AnimatedSprite *equipmentSprite = nullptr;
if (!filename.empty())
diff --git a/src/being.h b/src/being.h
index 411db3b7..32cfcf99 100644
--- a/src/being.h
+++ b/src/being.h
@@ -51,11 +51,12 @@ struct Position;
class SpeechBubble;
class Text;
-enum Gender
+enum class Gender
{
- GENDER_MALE = 0,
- GENDER_FEMALE = 1,
- GENDER_UNSPECIFIED = 2
+ MALE = 0,
+ FEMALE = 1,
+ UNSPECIFIED = 2,
+ HIDDEN = 3
};
class Being : public ActorSprite, public EventListener
@@ -505,7 +506,7 @@ class Being : public ActorSprite, public EventListener
std::vector<int> mSpriteIDs;
std::vector<std::string> mSpriteColors;
- Gender mGender = GENDER_UNSPECIFIED;
+ Gender mGender = Gender::UNSPECIFIED;
// Character guild information
std::map<int, Guild*> mGuilds;
diff --git a/src/gui/charcreatedialog.cpp b/src/gui/charcreatedialog.cpp
index 0d8a928e..fa1144b6 100644
--- a/src/gui/charcreatedialog.cpp
+++ b/src/gui/charcreatedialog.cpp
@@ -21,18 +21,13 @@
#include "gui/charcreatedialog.h"
-#include "game.h"
#include "localplayer.h"
-#include "main.h"
-#include "units.h"
#include "gui/charselectdialog.h"
-#include "gui/confirmdialog.h"
#include "gui/okdialog.h"
#include "gui/widgets/button.h"
#include "gui/widgets/label.h"
-#include "gui/widgets/layout.h"
#include "gui/widgets/playerbox.h"
#include "gui/widgets/radiobutton.h"
#include "gui/widgets/slider.h"
@@ -55,7 +50,7 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot):
mSlot(slot)
{
mPlayer = new Being(0, ActorSprite::PLAYER, 0, nullptr);
- mPlayer->setGender(GENDER_MALE);
+ mPlayer->setGender(Gender::MALE);
const std::vector<int> &items = CharDB::getDefaultItems();
for (size_t i = 0; i < items.size(); ++i)
@@ -66,6 +61,7 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot):
mHairStyleId = rand() * mHairStylesIds.size() / RAND_MAX;
mHairColorsIds = hairDB.getHairColorIds(
+ Net::getCharHandler()->getCharCreateMinHairColorId(),
Net::getCharHandler()->getCharCreateMaxHairColorId());
mHairColorId = rand() * mHairColorsIds.size() / RAND_MAX;
@@ -137,12 +133,21 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot):
add(mPlayerBox);
add(mNameField);
add(mNameLabel);
- add(mNextHairColorButton);
- add(mPrevHairColorButton);
- add(mHairColorLabel);
- add(mNextHairStyleButton);
- add(mPrevHairStyleButton);
- add(mHairStyleLabel);
+
+ if (mHairColorsIds.size() > 1)
+ {
+ add(mNextHairColorButton);
+ add(mPrevHairColorButton);
+ add(mHairColorLabel);
+ }
+
+ if (mHairStylesIds.size() > 1)
+ {
+ add(mNextHairStyleButton);
+ add(mPrevHairStyleButton);
+ add(mHairStyleLabel);
+ }
+
add(mAttributesLeft);
add(mCreateButton);
add(mCancelButton);
@@ -226,9 +231,9 @@ void CharCreateDialog::action(const gcn::ActionEvent &event)
else if (event.getId() == "gender")
{
if (mMale->isSelected())
- mPlayer->setGender(GENDER_MALE);
+ mPlayer->setGender(Gender::MALE);
else
- mPlayer->setGender(GENDER_FEMALE);
+ mPlayer->setGender(Gender::FEMALE);
}
}
@@ -366,9 +371,9 @@ void CharCreateDialog::setAttributes(const std::vector<std::string> &labels,
center();
}
-void CharCreateDialog::setFixedGender(bool fixed, Gender gender)
+void CharCreateDialog::setDefaultGender(Gender gender)
{
- if (gender == GENDER_FEMALE)
+ if (gender == Gender::FEMALE)
{
mFemale->setSelected(true);
mMale->setSelected(false);
@@ -380,12 +385,6 @@ void CharCreateDialog::setFixedGender(bool fixed, Gender gender)
}
mPlayer->setGender(gender);
-
- if (fixed)
- {
- mMale->setEnabled(false);
- mFemale->setEnabled(false);
- }
}
void CharCreateDialog::updateHair()
diff --git a/src/gui/charcreatedialog.h b/src/gui/charcreatedialog.h
index 89706b54..46db6229 100644
--- a/src/gui/charcreatedialog.h
+++ b/src/gui/charcreatedialog.h
@@ -61,7 +61,7 @@ class CharCreateDialog : public Window, public gcn::ActionListener
unsigned available,
unsigned min, unsigned max);
- void setFixedGender(bool fixed, Gender gender = GENDER_FEMALE);
+ void setDefaultGender(Gender gender);
private:
void updateSliders();
diff --git a/src/gui/register.cpp b/src/gui/register.cpp
index 0e23777c..d4ebb59c 100644
--- a/src/gui/register.cpp
+++ b/src/gui/register.cpp
@@ -227,7 +227,7 @@ void RegisterDialog::action(const gcn::ActionEvent &event)
mLoginData->password = mPasswordField->getText();
if (mFemaleButton)
mLoginData->gender = mFemaleButton->isSelected() ?
- GENDER_FEMALE : GENDER_MALE;
+ Gender::FEMALE : Gender::MALE;
if (mEmailField)
mLoginData->email = mEmailField->getText();
mLoginData->registerLogin = true;
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;
}
};
diff --git a/src/resources/hairdb.cpp b/src/resources/hairdb.cpp
index ff301a23..09ac14f4 100644
--- a/src/resources/hairdb.cpp
+++ b/src/resources/hairdb.cpp
@@ -104,15 +104,15 @@ std::vector<int> HairDB::getHairStyleIds(int maxId) const
return hairStylesIds;
}
-std::vector<int> HairDB::getHairColorIds(int maxId) const
+std::vector<int> HairDB::getHairColorIds(int minId, int maxId) const
{
std::vector<int> hairColorsIds;
- for (const auto &hairColor : mHairColors)
+ for (const auto &[id, _] : mHairColors)
{
// Don't give ids higher than the requested maximum.
- if (maxId > 0 && hairColor.first > maxId)
+ if ((maxId > 0 && id > maxId) || id < minId)
continue;
- hairColorsIds.push_back(hairColor.first);
+ hairColorsIds.push_back(id);
}
return hairColorsIds;
}
diff --git a/src/resources/hairdb.h b/src/resources/hairdb.h
index b4374985..1f75a33a 100644
--- a/src/resources/hairdb.h
+++ b/src/resources/hairdb.h
@@ -64,7 +64,7 @@ public:
* @param maxId the max permited id. If not 0, the hairDb won't
* return ids > to the parameter.
*/
- std::vector<int> getHairColorIds(int maxId = 0) const;
+ std::vector<int> getHairColorIds(int minId, int maxId) const;
/**
* Add a hair style to the database.
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index b910c639..77fda11b 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -66,8 +66,9 @@ void ItemDB::loadEmptyItemDefinition()
mUnknown->mName = _("Unknown item");
mUnknown->mDisplay = SpriteDisplay();
std::string errFile = paths.getStringValue("spriteErrorFile");
- mUnknown->setSprite(errFile, GENDER_MALE);
- mUnknown->setSprite(errFile, GENDER_FEMALE);
+ mUnknown->setSprite(errFile, Gender::MALE, 0);
+ mUnknown->setSprite(errFile, Gender::FEMALE, 0);
+ mUnknown->setSprite(errFile, Gender::HIDDEN, 0);
mUnknown->setHitEffectId(paths.getIntValue("hitEffectId"));
mUnknown->setCriticalHitEffectId(paths.getIntValue("criticalHitEffectId"));
}
@@ -122,14 +123,13 @@ void ItemDB::loadSpriteRef(ItemInfo *itemInfo, xmlNodePtr node)
std::string gender = XML::getProperty(node, "gender", "unisex");
std::string filename = (const char*) node->xmlChildrenNode->content;
+ const int race = XML::getProperty(node, "race", 0);
if (gender == "male" || gender == "unisex")
- {
- itemInfo->setSprite(filename, GENDER_MALE);
- }
+ itemInfo->setSprite(filename, Gender::MALE, race);
if (gender == "female" || gender == "unisex")
- {
- itemInfo->setSprite(filename, GENDER_FEMALE);
- }
+ itemInfo->setSprite(filename, Gender::FEMALE, race);
+ if (gender == "hidden" || gender == "other" || gender == "unisex")
+ itemInfo->setSprite(filename, Gender::HIDDEN, race);
}
void ItemDB::loadSoundRef(ItemInfo *itemInfo, xmlNodePtr node)
diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp
index 9e7fd6b7..b3208777 100644
--- a/src/resources/iteminfo.cpp
+++ b/src/resources/iteminfo.cpp
@@ -24,21 +24,22 @@
#include "resources/itemdb.h"
#include "configuration.h"
-const std::string &ItemInfo::getSprite(Gender gender) const
+const std::string &ItemInfo::getSprite(Gender gender, int race) const
{
if (mView)
{
// Forward the request to the item defining how to view this item
- return itemDb->get(mView).getSprite(gender);
+ return itemDb->get(mView).getSprite(gender, race);
}
- else
- {
- static const std::string empty;
- auto i =
- mAnimationFiles.find(gender);
- return (i != mAnimationFiles.end()) ? i->second : empty;
- }
+ auto i = mAnimationFiles.find(static_cast<int>(gender) + race * 4);
+
+ // Fall back to ignoring race
+ if (race != 0 && i == mAnimationFiles.end())
+ i = mAnimationFiles.find(static_cast<int>(gender));
+
+ static const std::string empty;
+ return i != mAnimationFiles.end() ? i->second : empty;
}
void ItemInfo::addSound(EquipmentSoundEvent event, const std::string &filename)
@@ -49,8 +50,11 @@ void ItemInfo::addSound(EquipmentSoundEvent event, const std::string &filename)
const std::string &ItemInfo::getSound(EquipmentSoundEvent event) const
{
static const std::string empty;
- std::map< EquipmentSoundEvent, std::vector<std::string> >::const_iterator i;
- i = mSounds.find(event);
-
+ auto i = mSounds.find(event);
return i == mSounds.end() ? empty : i->second[rand() % i->second.size()];
}
+
+void ItemInfo::setSprite(const std::string &animationFile, Gender gender, int race)
+{
+ mAnimationFiles[static_cast<int>(gender) + race * 4] = animationFile;
+}
diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h
index 5763e423..7344d668 100644
--- a/src/resources/iteminfo.h
+++ b/src/resources/iteminfo.h
@@ -106,7 +106,7 @@ class ItemInfo
int getWeight() const
{ return mWeight; }
- const std::string &getSprite(Gender gender) const;
+ const std::string &getSprite(Gender gender, int race) const;
// Handlers for seting and getting the string used for particles when attacking
void setMissileParticleFile(const std::string &s)
@@ -145,9 +145,8 @@ class ItemInfo
{ return mType; }
private:
-
- void setSprite(const std::string &animationFile, Gender gender)
- { mAnimationFiles[gender] = animationFile; }
+ void setSprite(const std::string &animationFile,
+ Gender gender, int race);
void addSound(EquipmentSoundEvent event, const std::string &filename);
diff --git a/src/resources/settingsmanager.cpp b/src/resources/settingsmanager.cpp
index 28c08617..eceedcf4 100644
--- a/src/resources/settingsmanager.cpp
+++ b/src/resources/settingsmanager.cpp
@@ -68,7 +68,7 @@ namespace SettingsManager
loadFile("npcs.xml");
loadFile("emotes.xml");
loadFile("status-effects.xml");
- loadFile("hair.xml");
+ loadFile("itemcolors.xml");
loadFile("units.xml");
}
@@ -194,6 +194,20 @@ namespace SettingsManager
{
hairDB.readHairColorNode(childNode, filename);
}
+ else if (xmlStrEqual(childNode->name, BAD_CAST "list"))
+ {
+ // todo: consider if we need a "color DB", but in tmwa clientdata
+ // I only see hair colors in the itemcolors.xml file.
+ const std::string name = XML::getProperty(childNode, "name", std::string());
+ if (name == "hair")
+ {
+ for_each_xml_child_node(hairColorNode, childNode)
+ {
+ if (xmlStrEqual(hairColorNode->name, BAD_CAST "color"))
+ hairDB.readHairColorNode(hairColorNode, filename);
+ }
+ }
+ }
else if (xmlStrEqual(childNode->name, BAD_CAST "item"))
{
itemDb->readItemNode(childNode, filename);