summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFate <fate.tmw@googlemail.com>2008-11-01 23:45:48 +0000
committerFate <fate.tmw@googlemail.com>2008-11-01 23:45:48 +0000
commit8f1bf397990729c3a807bbbe0b643bc97446c923 (patch)
treeb2a531da277eeb9b48d3f0342dd96a4963b275d1
parent4cfdb3620ccbd0de6bd53c5f22e7b6d3801627bf (diff)
downloadmana-client-8f1bf397990729c3a807bbbe0b643bc97446c923.tar.gz
mana-client-8f1bf397990729c3a807bbbe0b643bc97446c923.tar.bz2
mana-client-8f1bf397990729c3a807bbbe0b643bc97446c923.tar.xz
mana-client-8f1bf397990729c3a807bbbe0b643bc97446c923.zip
* Use hair.xml to determine hair colours (#514)
* Auto-detect number of hair styles available (#514)
-rw-r--r--ChangeLog4
-rw-r--r--src/being.cpp95
-rw-r--r--src/being.h10
-rw-r--r--src/gui/char_select.cpp6
-rw-r--r--src/player.cpp22
5 files changed, 110 insertions, 27 deletions
diff --git a/ChangeLog b/ChangeLog
index 181a1de6..91e7de25 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2008-11-01 Fate <fate.tmw@googlemail.com>
+ * src/being.cpp (initializeHair): Read hair colours from external
+ `hair.xml' file (clientdata)
+ (initializeHair): Auto-detect number of hair colours
+
* src/gui/skill.cpp (SkillDialog): Display skills using a table
and using an external `skills.xml' file
(SkillDialog::update): No longer segfault when skills beyond 199
diff --git a/src/being.cpp b/src/being.cpp
index dca87677..1569fcc3 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -36,6 +36,7 @@
#include "localplayer.h"
#include "text.h"
+#include "resources/itemdb.h"
#include "resources/resourcemanager.h"
#include "resources/imageset.h"
#include "resources/iteminfo.h"
@@ -48,6 +49,7 @@
#include "utils/xml.h"
#define BEING_EFFECTS_FILE "effects.xml"
+#define HAIR_FILE "hair.xml"
int Being::instances = 0;
ImageSet *Being::emotionSet = NULL;
@@ -145,8 +147,8 @@ Being::setPath(const Path &path)
void
Being::setHairStyle(int style, int color)
{
- mHairStyle = style < 0 ? mHairStyle : style % NR_HAIR_STYLES;
- mHairColor = color < 0 ? mHairColor : color % NR_HAIR_COLORS;
+ mHairStyle = style < 0 ? mHairStyle : style % getHairStylesNr();
+ mHairColor = color < 0 ? mHairColor : color % getHairColorsNr();
}
void
@@ -304,7 +306,7 @@ Being::setDirection(Uint8 direction)
for (int i = 0; i < VECTOREND_SPRITE; i++)
{
- if (mSprites[i] != NULL)
+ if (mSprites[i] != NULL)
mSprites[i]->setDirection(dir);
}
}
@@ -516,7 +518,6 @@ Being::getHeight() const
}
-
struct EffectDescription {
std::string mGFXEffect;
std::string mSFXEffect;
@@ -609,3 +610,89 @@ Being::internalTriggerEffect(int effectId, bool sfx, bool gfx)
sound.playSfx(ed->mSFXEffect);
}
}
+
+
+
+
+static int hairStylesNr;
+static int hairColorsNr;
+static std::vector<std::string> hairColors;
+
+static void
+initializeHair(void);
+
+int
+Being::getHairStylesNr(void)
+{
+ initializeHair();
+ return hairStylesNr;
+}
+
+int
+Being::getHairColorsNr(void)
+{
+ initializeHair();
+ return hairColorsNr;
+}
+
+std::string
+Being::getHairColor(int index)
+{
+ initializeHair();
+ if (index < 0 || index >= hairColorsNr)
+ return "#000000";
+
+ return hairColors[index];
+}
+
+static bool hairInitialized = false;
+
+static void
+initializeHair(void)
+{
+ if (hairInitialized)
+ return;
+
+ // Hairstyles are encoded as negative numbers. Count how far negative we can go.
+ int hairstylesCtr = -1;
+ while (ItemDB::get(hairstylesCtr).getSprite(0) != "error.xml")
+ --hairstylesCtr;
+
+ hairStylesNr = -hairstylesCtr; // done.
+ if (hairStylesNr == 0)
+ hairStylesNr = 1; // No hair style -> no hair
+
+ hairColorsNr = 0;
+
+ XML::Document doc(HAIR_FILE);
+ xmlNodePtr root = doc.rootNode();
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "colors"))
+ {
+ logger->log("Error loading being hair configuration file");
+ } else {
+ for_each_xml_child_node(node, root)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "color"))
+ {
+ int index = atoi(XML::getProperty(node, "id", "-1").c_str());
+ std::string value = XML::getProperty(node, "value", "");
+
+ if (index >= 0 && value != "") {
+ if (index >= hairColorsNr) {
+ hairColorsNr = index + 1;
+ hairColors.resize(hairColorsNr, "#000000");
+ }
+ hairColors[index] = value;
+ }
+ }
+ }
+ } // done initializing
+
+ if (hairColorsNr == 0) { // No colours -> black only
+ hairColorsNr = 1;
+ hairColors.resize(hairColorsNr, "#000000");
+ }
+
+ hairInitialized = 1;
+}
diff --git a/src/being.h b/src/being.h
index d5fe7790..76317797 100644
--- a/src/being.h
+++ b/src/being.h
@@ -34,9 +34,6 @@
#include "map.h"
#include "animatedsprite.h"
-#define NR_HAIR_STYLES 8
-#define NR_HAIR_COLORS 10
-
#define FIRST_IGNORE_EMOTE 14
class AnimatedSprite;
@@ -370,6 +367,13 @@ class Being : public Sprite
const std::auto_ptr<Equipment> mEquipment;
+
+ static int getHairColorsNr(void);
+
+ static int getHairStylesNr(void);
+
+ static std::string getHairColor(int index);
+
protected:
/**
* Sets the new path for this being.
diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp
index 8ab3b879..661a9fa7 100644
--- a/src/gui/char_select.cpp
+++ b/src/gui/char_select.cpp
@@ -256,7 +256,7 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network,
{
mPlayer = new Player(0, 0, NULL);
mPlayer->setGender(gender);
- mPlayer->setHairStyle(rand() % NR_HAIR_STYLES, rand() % NR_HAIR_COLORS);
+ mPlayer->setHairStyle(rand() % Being::getHairStylesNr(), rand() % Being::getHairColorsNr());
mNameField = new TextField("");
mNameLabel = new gcn::Label("Name:");
@@ -340,13 +340,13 @@ CharCreateDialog::action(const gcn::ActionEvent &event)
mPlayer->setHairStyle(-1, mPlayer->getHairColor() + 1);
}
else if (event.getId() == "prevcolor") {
- mPlayer->setHairStyle(-1, mPlayer->getHairColor() + NR_HAIR_COLORS - 1);
+ mPlayer->setHairStyle(-1, mPlayer->getHairColor() + Being::getHairColorsNr() - 1);
}
else if (event.getId() == "nextstyle") {
mPlayer->setHairStyle(mPlayer->getHairStyle() + 1, -1);
}
else if (event.getId() == "prevstyle") {
- mPlayer->setHairStyle(mPlayer->getHairStyle() + NR_HAIR_STYLES - 1, -1);
+ mPlayer->setHairStyle(mPlayer->getHairStyle() + Being::getHairStylesNr() - 1, -1);
}
}
diff --git a/src/player.cpp b/src/player.cpp
index f86e7179..0e88da0b 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -140,27 +140,13 @@ void Player::setGender(int gender)
void Player::setHairStyle(int style, int color)
{
- style = style < 0 ? mHairStyle : style % NR_HAIR_STYLES;
- color = color < 0 ? mHairColor : color % NR_HAIR_COLORS;
+ style = style < 0 ? mHairStyle : style % getHairStylesNr();
+ color = color < 0 ? mHairColor : color % getHairColorsNr();
if (style == mHairStyle && color == mHairColor) return;
Being::setHairStyle(style, color);
- static char const *const colors[NR_HAIR_COLORS] =
- {
- "#8c4b41,da9041,ffffff", // light brown
- "#06372b,489e25,fdedcc", // green
- "#5f0b33,91191c,f9ad81", // red
- "#602486,934cc3,fdc689", // purple
- "#805e74,c6b09b,ffffff", // gray
- "#8c6625,dab425,ffffff", // yellow
- "#1d2d6d,1594a3,fdedcc", // blue
- "#831f2d,be4f2d,f8cc8b", // brown
- "#432482,584bbc,dae8e5", // light blue
- "#460850,611967,e7b4ae", // dark purple
- };
-
- setSprite(HAIR_SPRITE, style * -1, colors[color]);
+ setSprite(HAIR_SPRITE, style * -1, getHairColor(color));
setAction(mAction);
}
@@ -209,3 +195,5 @@ void Player::updateCoords()
mName->adviseXY(mPx + NAME_X_OFFSET, mPy + NAME_Y_OFFSET);
}
}
+
+