summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/being.cpp94
-rw-r--r--src/being.h10
-rw-r--r--src/gui/char_select.cpp7
-rw-r--r--src/player.cpp22
4 files changed, 108 insertions, 25 deletions
diff --git a/src/being.cpp b/src/being.cpp
index bade64b6..fbee967f 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -31,6 +31,7 @@
#include "map.h"
#include "particle.h"
+#include "resources/itemdb.h"
#include "resources/resourcemanager.h"
#include "resources/imageset.h"
#include "resources/iteminfo.h"
@@ -40,11 +41,14 @@
#include "utils/dtor.h"
#include "utils/tostring.h"
+#include "utils/xml.h"
namespace {
const bool debug_movement = true;
}
+#define HAIR_FILE "hair.xml"
+
int Being::instances = 0;
ImageSet *Being::emotionSet = NULL;
@@ -291,8 +295,8 @@ void 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 Being::setSprite(int slot, int id, const std::string &color)
@@ -605,3 +609,89 @@ int Being::getHeight() const
return 0;
}
}
+
+
+
+
+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(GENDER_MALE) != "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 cce5e99f..5e8cb2dc 100644
--- a/src/being.h
+++ b/src/being.h
@@ -33,9 +33,6 @@
#include "animatedsprite.h"
#include "vector.h"
-#define NR_HAIR_STYLES 8
-#define NR_HAIR_COLORS 10
-
class AnimatedSprite;
class Equipment;
class ItemInfo;
@@ -363,6 +360,13 @@ class Being : public Sprite
*/
const Path &getPath() const { return mPath; }
+
+ 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 3adfbc08..67cb3c7b 100644
--- a/src/gui/char_select.cpp
+++ b/src/gui/char_select.cpp
@@ -266,7 +266,8 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot):
Window(_("Create Character"), true, parent), mSlot(slot)
{
mPlayer = new Player(0, 0, NULL);
- mPlayer->setHairStyle(rand() % NR_HAIR_STYLES, rand() % NR_HAIR_COLORS);
+ mPlayer->setHairStyle(rand() % Being::getHairStylesNr(),
+ rand() % Being::getHairColorsNr());
mPlayer->setGender(GENDER_MALE);
mNameField = new TextField("");
@@ -422,13 +423,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);
}
else if (event.getId() == "statslider") {
UpdateSliders();
diff --git a/src/player.cpp b/src/player.cpp
index e24a2d8c..19486d6e 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -85,27 +85,13 @@ void Player::setGender(Gender 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);
}
@@ -194,3 +180,5 @@ void Player::setInParty(bool value)
{
mInParty = value;
}
+
+