summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/being.cpp4
-rw-r--r--src/being.h14
-rw-r--r--src/localplayer.cpp4
-rw-r--r--src/localplayer.h2
-rw-r--r--src/monster.cpp69
-rw-r--r--src/monster.h4
-rw-r--r--src/net/ea/beinghandler.cpp4
-rw-r--r--src/net/ea/charserverhandler.cpp2
-rw-r--r--src/npc.cpp40
-rw-r--r--src/npc.h4
-rw-r--r--src/player.cpp21
-rw-r--r--src/player.h4
-rw-r--r--src/resources/itemdb.cpp11
-rw-r--r--src/resources/itemdb.h2
-rw-r--r--src/resources/iteminfo.h28
15 files changed, 129 insertions, 84 deletions
diff --git a/src/being.cpp b/src/being.cpp
index 44293732..47c31c36 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -67,14 +67,14 @@ static const int DEFAULT_BEING_HEIGHT = 32;
int Being::mNumberOfHairstyles = 1;
// TODO: mWalkTime used by eAthena only
-Being::Being(int id, int job, Map *map):
+Being::Being(int id, int subtype, Map *map):
mFrame(0),
mWalkTime(0),
mEmotion(0), mEmotionTime(0),
mSpeechTime(0),
mAttackSpeed(350),
mAction(STAND),
- mJob(job),
+ mSubType(subtype),
mId(id),
mDirection(DOWN),
mSpriteDirection(DIRECTION_DOWN),
diff --git a/src/being.h b/src/being.h
index 3479a9a8..3d3dfa71 100644
--- a/src/being.h
+++ b/src/being.h
@@ -118,11 +118,11 @@ class Being : public Sprite, public ConfigListener
/**
* Constructor.
*
- * @param id a unique being id
- * @param job partly determines the type of the being
- * @param map the map the being is on
+ * @param id a unique being id
+ * @param subtype partly determines the type of the being
+ * @param map the map the being is on
*/
- Being(int id, int job, Map *map);
+ Being(int id, int subtype, Map *map);
virtual ~Being();
@@ -284,12 +284,12 @@ class Being : public Sprite, public ConfigListener
/**
* Return Being's current Job (player job, npc, monster, creature )
*/
- Uint16 getJob() const { return mJob; }
+ Uint16 getSubType() const { return mSubType; }
/**
* Set Being's current Job (player job, npc, monster, creature )
*/
- void setJob(Uint16 job) { mJob = job; }
+ virtual void setSubtype(Uint16 subtype) { mSubType = subtype; }
/**
* Sets the walk speed.
@@ -611,7 +611,7 @@ class Being : public Sprite, public ConfigListener
int mAttackSpeed; /**< Attack speed */
Action mAction; /**< Action the being is performing */
- Uint16 mJob; /**< Job (player job, npc, monster, creature ) */
+ Uint16 mSubType; /**< Subtype (graphical view, basically) */
int mId; /**< Unique sprite id */
Uint8 mDirection; /**< Facing direction */
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index ef2d7e4e..961248dc 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -75,8 +75,8 @@ const short walkingKeyboardDelay = 1000;
LocalPlayer *player_node = NULL;
-LocalPlayer::LocalPlayer(int id, int job):
- Player(id, job, 0),
+LocalPlayer::LocalPlayer(int id, int subtype):
+ Player(id, subtype, 0),
mEquipment(new Equipment),
mAttackRange(0),
mTargetTime(-1),
diff --git a/src/localplayer.h b/src/localplayer.h
index 65653d50..dd7b94d4 100644
--- a/src/localplayer.h
+++ b/src/localplayer.h
@@ -105,7 +105,7 @@ class LocalPlayer : public Player
/**
* Constructor.
*/
- LocalPlayer(int id= 65535, int job = 0);
+ LocalPlayer(int id= 65535, int subtype = 0);
/**
* Destructor.
diff --git a/src/monster.cpp b/src/monster.cpp
index 23be9395..0876b08d 100644
--- a/src/monster.cpp
+++ b/src/monster.cpp
@@ -35,37 +35,11 @@
#include "resources/monsterdb.h"
#include "resources/monsterinfo.h"
-Monster::Monster(int id, int job, Map *map):
- Being(id, job, map),
+Monster::Monster(int id, int subtype, Map *map):
+ Being(id, subtype, map),
mAttackType(1)
{
- const MonsterInfo &info = getInfo();
-
- // Setup Monster sprites
- const std::list<std::string> &sprites = info.getSprites();
-
- for (std::list<std::string>::const_iterator i = sprites.begin();
- i != sprites.end(); i++)
- {
- std::string file = "graphics/sprites/" + *i;
- mSprites.push_back(AnimatedSprite::load(file));
- }
-
- // Ensure that something is shown
- if (mSprites.size() == 0)
- {
- mSprites.push_back(AnimatedSprite::load("graphics/sprites/error.xml"));
- }
-
- if (Particle::enabled)
- {
- const std::list<std::string> &particleEffects = info.getParticleEffects();
- for (std::list<std::string>::const_iterator i = particleEffects.begin();
- i != particleEffects.end(); i++)
- {
- controlParticle(particleEngine->addEffect((*i), 0, 0));
- }
- }
+ setSubtype(subtype);
mNameColor = &userPalette->getColor(UserPalette::MONSTER);
mTextColor = &userPalette->getColor(UserPalette::MONSTER);
@@ -86,6 +60,7 @@ void Monster::logic()
Being::logic();
}
+
void Monster::setAction(Action action, int attackType)
{
SpriteAction currentAction = ACTION_INVALID;
@@ -144,6 +119,40 @@ void Monster::setAction(Action action, int attackType)
}
}
+void Monster::setSubtype(Uint16 subtype)
+{
+ Being::setSubtype(subtype);
+
+ const MonsterInfo &info = getInfo();
+
+ // Setup Monster sprites
+ const std::list<std::string> &sprites = info.getSprites();
+
+ mSprites.clear();
+ for (std::list<std::string>::const_iterator i = sprites.begin();
+ i != sprites.end(); i++)
+ {
+ std::string file = "graphics/sprites/" + *i;
+ mSprites.push_back(AnimatedSprite::load(file));
+ }
+
+ // Ensure that something is shown
+ if (mSprites.size() == 0)
+ {
+ mSprites.push_back(AnimatedSprite::load("graphics/sprites/error.xml"));
+ }
+
+ if (Particle::enabled)
+ {
+ const std::list<std::string> &particleEffects = info.getParticleEffects();
+ for (std::list<std::string>::const_iterator i = particleEffects.begin();
+ i != particleEffects.end(); i++)
+ {
+ controlParticle(particleEngine->addEffect((*i), 0, 0));
+ }
+ }
+}
+
void Monster::handleAttack(Being *victim, int damage, AttackType type)
{
Being::handleAttack(victim, damage, type);
@@ -170,7 +179,7 @@ Being::TargetCursorSize Monster::getTargetCursorSize() const
const MonsterInfo &Monster::getInfo() const
{
- return MonsterDB::get(mJob);
+ return MonsterDB::get(mSubType);
}
void Monster::updateCoords()
diff --git a/src/monster.h b/src/monster.h
index 6fb82c7f..9bb8e3b9 100644
--- a/src/monster.h
+++ b/src/monster.h
@@ -30,7 +30,7 @@ class Text;
class Monster : public Being
{
public:
- Monster(int id, int job, Map *map);
+ Monster(int id, int subtype, Map *map);
virtual void logic();
@@ -38,6 +38,8 @@ class Monster : public Being
virtual Type getType() const { return MONSTER; }
+ virtual void setSubtype(Uint16 subtype);
+
virtual TargetCursorSize
getTargetCursorSize() const;
diff --git a/src/net/ea/beinghandler.cpp b/src/net/ea/beinghandler.cpp
index 6dcf9631..649e93e8 100644
--- a/src/net/ea/beinghandler.cpp
+++ b/src/net/ea/beinghandler.cpp
@@ -167,7 +167,7 @@ void BeingHandler::handleMessage(Net::MessageIn &msg)
if (speed == 0) { speed = 150; }
dstBeing->setWalkSpeed(Vector(speed, speed, 0));
- dstBeing->setJob(job);
+ dstBeing->setSubtype(job);
hairStyle = msg.readInt16();
weapon = msg.readInt16();
headBottom = msg.readInt16();
@@ -550,7 +550,7 @@ void BeingHandler::handleMessage(Net::MessageIn &msg)
}
dstBeing->setWalkSpeed(Vector(speed, speed, 0));
- dstBeing->setJob(job);
+ dstBeing->setSubtype(job);
hairStyle = msg.readInt16();
weapon = msg.readInt16();
shield = msg.readInt16();
diff --git a/src/net/ea/charserverhandler.cpp b/src/net/ea/charserverhandler.cpp
index 64e1d427..8706727a 100644
--- a/src/net/ea/charserverhandler.cpp
+++ b/src/net/ea/charserverhandler.cpp
@@ -220,7 +220,7 @@ LocalPlayer *CharServerHandler::readPlayerData(Net::MessageIn &msg, int *slot)
tempPlayer->setMP(msg.readInt16());
tempPlayer->setMaxMP(msg.readInt16());
msg.readInt16(); // speed
- msg.readInt16(); // class
+ tempPlayer->setSubtype(msg.readInt16()); // class (used for race)
int hairStyle = msg.readInt16();
Uint16 weapon = msg.readInt16();
tempPlayer->setSprite(SPRITE_WEAPON, weapon, "", true);
diff --git a/src/npc.cpp b/src/npc.cpp
index 29a6c61c..cdfe5193 100644
--- a/src/npc.cpp
+++ b/src/npc.cpp
@@ -37,11 +37,32 @@
#include "resources/npcdb.h"
-NPC::NPC(int id, int job, Map *map):
- Player(id, job, map, true)
+NPC::NPC(int id, int subtype, Map *map):
+ Player(id, subtype, map, true)
{
- NPCInfo info = NPCDB::get(job);
+ setSubtype(subtype);
+ setShowName(true);
+}
+
+void NPC::setName(const std::string &name)
+{
+ const std::string displayName = name.substr(0, name.find('#', 0));
+
+ Being::setName(displayName);
+
+ mNameColor = &userPalette->getColor(UserPalette::NPC);
+
+ mDispName->setColor(mNameColor);
+}
+
+void NPC::setSubtype(Uint16 subtype)
+{
+ Being::setSubtype(subtype);
+
+ NPCInfo info = NPCDB::get(subtype);
+
+ mSprites.clear();
// Setup NPC sprites
for (std::list<NPCsprite*>::const_iterator i = info.sprites.begin();
i != info.sprites.end();
@@ -65,19 +86,6 @@ NPC::NPC(int id, int job, Map *map):
this->controlParticle(p);
}
}
-
- setShowName(true);
-}
-
-void NPC::setName(const std::string &name)
-{
- const std::string displayName = name.substr(0, name.find('#', 0));
-
- Being::setName(displayName);
-
- mNameColor = &userPalette->getColor(UserPalette::NPC);
-
- mDispName->setColor(mNameColor);
}
void NPC::talk()
diff --git a/src/npc.h b/src/npc.h
index c7db58f1..0abd2395 100644
--- a/src/npc.h
+++ b/src/npc.h
@@ -30,12 +30,14 @@ class Text;
class NPC : public Player
{
public:
- NPC(int id, int job, Map *map);
+ NPC(int id, int subtype, Map *map);
void setName(const std::string &name);
virtual Type getType() const { return Being::NPC; }
+ virtual void setSubtype(Uint16 subtype);
+
void talk();
void setSprite(unsigned int slot, int id,
diff --git a/src/player.cpp b/src/player.cpp
index ad8c1db4..9113b4ab 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -43,8 +43,8 @@
#include "utils/stringutils.h"
-Player::Player(int id, int job, Map *map, bool isNPC):
- Being(id, job, map),
+Player::Player(int id, int subtype, Map *map, bool isNPC):
+ Being(id, subtype, map),
mGender(GENDER_UNSPECIFIED),
mParty(NULL),
mIsGM(false)
@@ -58,11 +58,7 @@ Player::Player(int id, int job, Map *map, bool isNPC):
mSpriteColors.push_back("");
}
- /* Human base sprite. When implementing different races remove this
- * line and set the base sprite when setting the race of the player
- * character.
- */
- setSprite(Net::getCharHandler()->baseSprite(), -100);
+ setSubtype(subtype);
}
mShowName = config.getValue("visiblenames", 1);
config.addListener("visiblenames", this);
@@ -137,6 +133,17 @@ void Player::logic()
Being::logic();
}
+void Player::setSubtype(Uint16 subtype)
+{
+ Being::setSubtype(subtype);
+
+ int id = -100 - subtype;
+ if (ItemDB::exists(id)) // Prevent showing errors when sprite doesn't exist
+ setSprite(Net::getCharHandler()->baseSprite(), id);
+ else
+ setSprite(Net::getCharHandler()->baseSprite(), -100);
+}
+
void Player::setGender(Gender gender)
{
if (gender != mGender)
diff --git a/src/player.h b/src/player.h
index 670f6d84..e75870a0 100644
--- a/src/player.h
+++ b/src/player.h
@@ -47,7 +47,7 @@ class Player : public Being
/**
* Constructor.
*/
- Player(int id, int job, Map *map, bool isNPC = false);
+ Player(int id, int subtype, Map *map, bool isNPC = false);
~Player();
@@ -55,6 +55,8 @@ class Player : public Being
virtual Type getType() const { return PLAYER; }
+ virtual void setSubtype(Uint16 subtype);
+
/**
* Sets the gender of this being.
*/
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index d60e38da..4638f00e 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -78,6 +78,8 @@ static ItemType itemTypeFromString(const std::string &name, int id = 0)
else if (name=="equip-necklace") return ITEM_EQUIPMENT_NECKLACE;
else if (name=="equip-feet") return ITEM_EQUIPMENT_FEET;
else if (name=="equip-ammo") return ITEM_EQUIPMENT_AMMO;
+ else if (name=="racesprite") return ITEM_SPRITE_RACE;
+ else if (name=="hairsprite") return ITEM_SPRITE_HAIR;
else return ITEM_UNUSABLE;
}
@@ -255,6 +257,15 @@ void ItemDB::unload()
mLoaded = false;
}
+bool ItemDB::exists(int id)
+{
+ assert(mLoaded);
+
+ ItemInfos::const_iterator i = mItemInfos.find(id);
+
+ return i != mItemInfos.end();
+}
+
const ItemInfo &ItemDB::get(int id)
{
assert(mLoaded);
diff --git a/src/resources/itemdb.h b/src/resources/itemdb.h
index 63c016ba..be023073 100644
--- a/src/resources/itemdb.h
+++ b/src/resources/itemdb.h
@@ -43,6 +43,8 @@ namespace ItemDB
*/
void unload();
+ bool exists(int id);
+
const ItemInfo &get(int id);
const ItemInfo &get(const std::string &name);
diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h
index e14d62b8..a7c0ddca 100644
--- a/src/resources/iteminfo.h
+++ b/src/resources/iteminfo.h
@@ -72,19 +72,21 @@ enum EquipmentSlot
enum ItemType
{
ITEM_UNUSABLE = 0,
- ITEM_USABLE, // 1
- ITEM_EQUIPMENT_ONE_HAND_WEAPON, // 2
- ITEM_EQUIPMENT_TWO_HANDS_WEAPON,// 3
- ITEM_EQUIPMENT_TORSO,// 4
- ITEM_EQUIPMENT_ARMS,// 5
- ITEM_EQUIPMENT_HEAD,// 6
- ITEM_EQUIPMENT_LEGS,// 7
- ITEM_EQUIPMENT_SHIELD,// 8
- ITEM_EQUIPMENT_RING,// 9
- ITEM_EQUIPMENT_NECKLACE,// 10
- ITEM_EQUIPMENT_FEET,// 11
- ITEM_EQUIPMENT_AMMO,// 12
- ITEM_EQUIPMENT_CHARM// 13
+ ITEM_USABLE,
+ ITEM_EQUIPMENT_ONE_HAND_WEAPON,
+ ITEM_EQUIPMENT_TWO_HANDS_WEAPON,
+ ITEM_EQUIPMENT_TORSO,
+ ITEM_EQUIPMENT_ARMS, // 5
+ ITEM_EQUIPMENT_HEAD,
+ ITEM_EQUIPMENT_LEGS,
+ ITEM_EQUIPMENT_SHIELD,
+ ITEM_EQUIPMENT_RING,
+ ITEM_EQUIPMENT_NECKLACE, // 10
+ ITEM_EQUIPMENT_FEET,
+ ITEM_EQUIPMENT_AMMO,
+ ITEM_EQUIPMENT_CHARM,
+ ITEM_SPRITE_RACE,
+ ITEM_SPRITE_HAIR // 15
};
/**