summaryrefslogtreecommitdiff
path: root/src/resources
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2009-03-22 19:45:03 +0100
committerBjørn Lindeijer <bjorn@lindeijer.nl>2009-03-22 19:45:56 +0100
commit0c43d04b438d41c277ae80402d4b4888db1a0b64 (patch)
tree3aaeb75ecd1bcbe85decedab5f1fa426fe0411e3 /src/resources
parenta7f5eaeb7f643658d356533a608f0f18d85b6d32 (diff)
parent401802c1d7a1b3d659bdc53a45d9a6292fc1121e (diff)
downloadmana-client-0c43d04b438d41c277ae80402d4b4888db1a0b64.tar.gz
mana-client-0c43d04b438d41c277ae80402d4b4888db1a0b64.tar.bz2
mana-client-0c43d04b438d41c277ae80402d4b4888db1a0b64.tar.xz
mana-client-0c43d04b438d41c277ae80402d4b4888db1a0b64.zip
Merged the tmwserv client with the eAthena client
This merge involved major changes on both sides, and as such took several weeks. Lots of things are expected to be broken now, however, we now have a single code base to improve and extend, which can be compiled to support either eAthena or tmwserv. In the coming months, the plan is to work towards a client that supports both eAthena and tmwserv, without needing to be recompiled. Conflicts: Everywhere!
Diffstat (limited to 'src/resources')
-rw-r--r--src/resources/buddylist.cpp128
-rw-r--r--src/resources/buddylist.h79
-rw-r--r--src/resources/image.h2
-rw-r--r--src/resources/itemdb.cpp140
-rw-r--r--src/resources/itemdb.h2
-rw-r--r--src/resources/iteminfo.cpp21
-rw-r--r--src/resources/iteminfo.h91
-rw-r--r--src/resources/mapreader.cpp3
-rw-r--r--src/resources/monsterdb.cpp16
-rw-r--r--src/resources/monsterinfo.cpp45
-rw-r--r--src/resources/monsterinfo.h28
-rw-r--r--src/resources/spritedef.cpp32
-rw-r--r--src/resources/spritedef.h14
13 files changed, 526 insertions, 75 deletions
diff --git a/src/resources/buddylist.cpp b/src/resources/buddylist.cpp
new file mode 100644
index 00000000..c85105c5
--- /dev/null
+++ b/src/resources/buddylist.cpp
@@ -0,0 +1,128 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <algorithm>
+#include <cstring>
+#include <iostream>
+#include <fstream>
+
+#include "buddylist.h"
+
+#include "../main.h"
+#include "../configuration.h"
+
+BuddyList::BuddyList()
+{
+ // TODO: A buddy list would have to use the Configuration class to store
+ // the buddies. Also, there is now a player relationship manager
+ // which probably makes this buddy list kind of obsolete.
+
+ // Find saved buddy list file
+ //mFilename = homeDir + "/buddy.txt";
+
+ // Load buddy from file
+ loadFile();
+}
+
+void BuddyList::loadFile()
+{
+ // Open file
+ std::ifstream inputStream(mFilename.c_str(), std::ios::in);
+ if (!inputStream) {
+ std::cerr << "Error opening input stream" << std::endl;
+ return;
+ }
+
+ do {
+ char *buddy = new char[LEN_MAX_USERNAME];
+ inputStream.getline(buddy, LEN_MAX_USERNAME);
+ // Ugly ?
+ if(strcmp(buddy,"")) mBuddylist.push_back(buddy);
+ delete [] buddy;
+ } while(!inputStream.eof());
+
+ // Read buddy and close file
+ inputStream.close();
+}
+
+void BuddyList::saveFile()
+{
+ std::string str;
+
+ // Open file
+ std::ofstream outputStream(mFilename.c_str(), std::ios::trunc);
+ if (!outputStream) {
+ std::cerr << "Error opening output stream" << std::endl;
+ return;
+ }
+
+ // Write buddy and close file
+ for (BuddyIterator i = mBuddylist.begin(); i != mBuddylist.end(); ++i)
+ {
+ outputStream << (const char*) i->c_str() << std::endl;
+ }
+ outputStream.close();
+}
+
+bool BuddyList::addBuddy(const std::string buddy)
+{
+ if (find(mBuddylist.begin(), mBuddylist.end(), buddy) != mBuddylist.end())
+ {
+ return false;
+ }
+
+ // Buddy doesnt exist, add it
+ mBuddylist.push_back(buddy);
+
+ // Save file
+ saveFile();
+
+ return true;
+}
+
+bool BuddyList::removeBuddy(const std::string buddy)
+{
+ BuddyIterator i = find(mBuddylist.begin(), mBuddylist.end(), buddy);
+
+ if (i != mBuddylist.end()) {
+ mBuddylist.erase(i);
+ saveFile();
+ return true;
+ }
+
+ return false;
+}
+
+int BuddyList::getNumberOfElements()
+{
+ return mBuddylist.size();
+}
+
+std::string BuddyList::getElementAt(int number)
+{
+ if (number >= (int) mBuddylist.size()) {
+ return "";
+ }
+
+ BuddyIterator i = mBuddylist.begin();
+ std::advance(i, number);
+ return *i;
+}
diff --git a/src/resources/buddylist.h b/src/resources/buddylist.h
new file mode 100644
index 00000000..6a3de8c4
--- /dev/null
+++ b/src/resources/buddylist.h
@@ -0,0 +1,79 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _TMW_BUDDYLIST_H
+#define _TMW_BUDDYLIST_H
+
+#include <list>
+#include <string>
+
+#include <guichan/listmodel.hpp>
+
+class BuddyList : public gcn::ListModel {
+ public:
+ /**
+ * Constructor
+ */
+ BuddyList();
+
+ /**
+ * Destructor
+ */
+ virtual ~BuddyList() { }
+
+ /**
+ * Adds buddy to the list
+ */
+ bool addBuddy(const std::string buddy);
+
+ /**
+ * Removes buddy from the list
+ */
+ bool removeBuddy(const std::string buddy);
+
+ /**
+ * Returns the number of buddy on the list
+ */
+ int getNumberOfElements();
+
+ /**
+ * Returns the buddy of the number or null
+ */
+ std::string getElementAt(int number);
+
+ private:
+ /**
+ * Save buddy to file
+ */
+ void saveFile();
+
+ /**
+ * Load buddy from file
+ */
+ void loadFile();
+
+ typedef std::list<std::string> Buddies;
+ typedef Buddies::iterator BuddyIterator;
+ Buddies mBuddylist; /**< Buddy list */
+ std::string mFilename; /* File to work with */
+};
+
+#endif /* _TMW_BUDDYLIST_H */
diff --git a/src/resources/image.h b/src/resources/image.h
index fe3081ac..3160add8 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -40,8 +40,6 @@
#include "resource.h"
class Dye;
-class SDL_Rect;
-class SDL_Surface;
/**
* Defines a class for loading and storing images.
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index fec52150..7304f8a7 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -24,11 +24,13 @@
#include <libxml/tree.h>
#include "itemdb.h"
+#include "resourcemanager.h"
#include "../log.h"
#include "../utils/dtor.h"
#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
#include "../utils/stringutils.h"
#include "../utils/xml.h"
@@ -44,6 +46,48 @@ namespace
static void loadSpriteRef(ItemInfo *itemInfo, xmlNodePtr node);
static void loadSoundRef(ItemInfo *itemInfo, xmlNodePtr node);
+static char const *const fields[][2] =
+{
+ { "attack", N_("Attack %+d") },
+ { "defense", N_("Defense %+d") },
+ { "hp", N_("HP %+d") },
+ { "mp", N_("MP %+d") }
+};
+
+static ItemType itemTypeFromString(const std::string &name, int id = 0)
+{
+ if (name=="generic") return ITEM_UNUSABLE;
+ else if (name=="usable") return ITEM_USABLE;
+ else if (name=="equip-1hand") return ITEM_EQUIPMENT_ONE_HAND_WEAPON;
+ else if (name=="equip-2hand") return ITEM_EQUIPMENT_TWO_HANDS_WEAPON;
+ else if (name=="equip-torso") return ITEM_EQUIPMENT_TORSO;
+ else if (name=="equip-arms") return ITEM_EQUIPMENT_ARMS;
+ else if (name=="equip-head") return ITEM_EQUIPMENT_HEAD;
+ else if (name=="equip-legs") return ITEM_EQUIPMENT_LEGS;
+ else if (name=="equip-shield") return ITEM_EQUIPMENT_SHIELD;
+ else if (name=="equip-ring") return ITEM_EQUIPMENT_RING;
+ 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 return ITEM_UNUSABLE;
+}
+
+static WeaponType weaponTypeFromString(const std::string &name, int id = 0)
+{
+ if (name=="knife") return WPNTYPE_KNIFE;
+ else if (name=="sword") return WPNTYPE_SWORD;
+ else if (name=="polearm") return WPNTYPE_POLEARM;
+ else if (name=="staff") return WPNTYPE_STAFF;
+ else if (name=="whip") return WPNTYPE_WHIP;
+ else if (name=="bow") return WPNTYPE_BOW;
+ else if (name=="shooting") return WPNTYPE_SHOOTING;
+ else if (name=="mace") return WPNTYPE_MACE;
+ else if (name=="axe") return WPNTYPE_AXE;
+ else if (name=="thrown") return WPNTYPE_THROWN;
+
+ else return WPNTYPE_NONE;
+}
+
void ItemDB::load()
{
if (mLoaded)
@@ -82,57 +126,77 @@ void ItemDB::load()
logger->log("ItemDB: Redefinition of item ID %d", id);
}
- std::string type = XML::getProperty(node, "type", "other");
+ std::string typeStr = XML::getProperty(node, "type", "other");
int weight = XML::getProperty(node, "weight", 0);
int view = XML::getProperty(node, "view", 0);
std::string name = XML::getProperty(node, "name", "");
std::string image = XML::getProperty(node, "image", "");
std::string description = XML::getProperty(node, "description", "");
- std::string effect = XML::getProperty(node, "effect", "");
+#ifdef TMWSERV_SUPPORT
+ int weaponType = weaponTypeFromString(XML::getProperty(node, "weapon-type", ""));
+#else
int weaponType = XML::getProperty(node, "weapon_type", 0);
+#endif
+ int attackRange = XML::getProperty(node, "attack-range", 0);
+
+ ItemInfo *itemInfo = new ItemInfo;
+ itemInfo->setId(id);
+ itemInfo->setImageName(image);
+ itemInfo->setName(name.empty() ? _("Unnamed") : name);
+ itemInfo->setDescription(description);
+#ifdef TMWSERV_SUPPORT
+ int type = itemTypeFromString(typeStr);
+ itemInfo->setType(type);
+#else
+ itemInfo->setType(typeStr);
+#endif
+ itemInfo->setView(view);
+ itemInfo->setWeight(weight);
+ itemInfo->setWeaponType(weaponType);
+ itemInfo->setAttackRange(attackRange);
+
+#ifdef TMWSERV_SUPPORT
+ std::string effect;
+ for (int i = 0; i < int(sizeof(fields) / sizeof(fields[0])); ++i)
+ {
+ int value = XML::getProperty(node, fields[i][0], 0);
+ if (!value) continue;
+ if (!effect.empty()) effect += " / ";
+ effect += strprintf(gettext(fields[i][1]), value);
+ }
+#else
+ std::string effect = XML::getProperty(node, "effect", "");
+#endif
+ itemInfo->setEffect(effect);
+
- if (id)
+ for_each_xml_child_node(itemChild, node)
{
- ItemInfo *itemInfo = new ItemInfo;
- itemInfo->setId(id);
- itemInfo->setImageName(image);
- itemInfo->setName(name.empty() ? _("Unnamed") : name);
- itemInfo->setDescription(description);
- itemInfo->setEffect(effect);
- itemInfo->setType(type);
- itemInfo->setView(view);
- itemInfo->setWeight(weight);
- itemInfo->setWeaponType(weaponType);
-
- for_each_xml_child_node(itemChild, node)
+ if (xmlStrEqual(itemChild->name, BAD_CAST "sprite"))
+ {
+ loadSpriteRef(itemInfo, itemChild);
+ }
+ else if (xmlStrEqual(itemChild->name, BAD_CAST "sound"))
{
- if (xmlStrEqual(itemChild->name, BAD_CAST "sprite"))
- {
- loadSpriteRef(itemInfo, itemChild);
- }
- else if (xmlStrEqual(itemChild->name, BAD_CAST "sound"))
- {
- loadSoundRef(itemInfo, itemChild);
- }
+ loadSoundRef(itemInfo, itemChild);
}
+ }
- mItemInfos[id] = itemInfo;
- if (!name.empty())
+ mItemInfos[id] = itemInfo;
+ if (!name.empty())
+ {
+ NamedItemInfoIterator itr = mNamedItemInfos.find(name);
+ if (itr == mNamedItemInfos.end())
+ {
+ std::string temp = name;
+ toLower(trim(temp));
+
+ mNamedItemInfos[temp] = itemInfo;
+ }
+ else
{
- NamedItemInfoIterator itr = mNamedItemInfos.find(name);
- if (itr == mNamedItemInfos.end())
- {
- std::string temp = name;
- toLower(trim(temp));
-
- mNamedItemInfos[temp] = itemInfo;
- }
- else
- {
- logger->log("ItemDB: Duplicate name of item found item %d",
- id);
- }
+ logger->log("ItemDB: Duplicate name of item found item %d", id);
}
}
diff --git a/src/resources/itemdb.h b/src/resources/itemdb.h
index 08a7acd0..68f3b039 100644
--- a/src/resources/itemdb.h
+++ b/src/resources/itemdb.h
@@ -29,7 +29,7 @@
class ItemInfo;
/**
- * The namespace that holds the item information.
+ * Item information database.
*/
namespace ItemDB
{
diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp
index 2f118284..f7118755 100644
--- a/src/resources/iteminfo.cpp
+++ b/src/resources/iteminfo.cpp
@@ -44,6 +44,26 @@ void ItemInfo::setWeaponType(int type)
// See server item.hpp file for type values.
switch (type)
{
+#ifdef TMWSERV_SUPPORT
+ case WPNTYPE_NONE:
+ mAttackType = ACTION_DEFAULT;
+ break;
+ case WPNTYPE_KNIFE:
+ case WPNTYPE_SWORD:
+ mAttackType = ACTION_ATTACK_STAB;
+ break;
+ case WPNTYPE_THROWN:
+ mAttackType = ACTION_ATTACK_THROW;
+ break;
+ case WPNTYPE_BOW:
+ mAttackType = ACTION_ATTACK_BOW;
+ break;
+ case WPNTYPE_POLEARM:
+ mAttackType = ACTION_ATTACK_SWING;
+ break;
+ default:
+ mAttackType = ACTION_ATTACK;
+#else
case 0: // none
mAttackType = ACTION_DEFAULT;
break;
@@ -62,6 +82,7 @@ void ItemInfo::setWeaponType(int type)
break;
default:
mAttackType = ACTION_ATTACK;
+#endif
}
}
diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h
index c03dec28..10749c9e 100644
--- a/src/resources/iteminfo.h
+++ b/src/resources/iteminfo.h
@@ -36,6 +36,74 @@ enum EquipmentSoundEvent
EQUIP_EVENT_HIT
};
+enum EquipmentSlot
+{
+ // Equipment rules:
+ // 1 Brest equipment
+ EQUIP_TORSO_SLOT = 0,
+ // 1 arms equipment
+ EQUIP_ARMS_SLOT = 1,
+ // 1 head equipment
+ EQUIP_HEAD_SLOT = 2,
+ // 1 legs equipment
+ EQUIP_LEGS_SLOT = 3,
+ // 1 feet equipment
+ EQUIP_FEET_SLOT = 4,
+ // 2 rings
+ EQUIP_RING1_SLOT = 5,
+ EQUIP_RING2_SLOT = 6,
+ // 1 necklace
+ EQUIP_NECKLACE_SLOT = 7,
+ // Fight:
+ // 2 one-handed weapons
+ // or 1 two-handed weapon
+ // or 1 one-handed weapon + 1 shield.
+ EQUIP_FIGHT1_SLOT = 8,
+ EQUIP_FIGHT2_SLOT = 9,
+ // Projectile:
+ // this item does not amount to one, it only indicates the chosen projectile.
+ EQUIP_PROJECTILE_SLOT = 10
+};
+
+
+/**
+ * Enumeration of available Item types.
+ */
+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
+};
+
+/**
+ * Enumeration of available weapon's types.
+ */
+enum WeaponType
+{
+ WPNTYPE_NONE = 0,
+ WPNTYPE_KNIFE,
+ WPNTYPE_SWORD,
+ WPNTYPE_POLEARM,
+ WPNTYPE_STAFF,
+ WPNTYPE_WHIP,
+ WPNTYPE_BOW,
+ WPNTYPE_SHOOTING,
+ WPNTYPE_MACE,
+ WPNTYPE_AXE,
+ WPNTYPE_THROWN
+};
+
/**
* Defines a class for storing item infos. This includes information used when
* the item is equipped.
@@ -47,7 +115,11 @@ class ItemInfo
* Constructor.
*/
ItemInfo():
+#ifdef TMWSERV_SUPPORT
+ mType(ITEM_UNUSABLE),
+#else
mType(""),
+#endif
mWeight(0),
mView(0),
mAttackType(ACTION_DEFAULT)
@@ -83,10 +155,18 @@ class ItemInfo
const std::string& getEffect() const { return mEffect; }
+#ifdef TMWSERV_SUPPORT
+ void setType(short type)
+ { mType = type; }
+
+ short getType() const
+ { return mType; }
+#else
void setType(const std::string& type)
{ mType = type; }
const std::string& getType() const { return mType; }
+#endif
void setWeight(short weight)
{ mWeight = weight; }
@@ -107,6 +187,12 @@ class ItemInfo
SpriteAction getAttackType() const
{ return mAttackType; }
+ int getAttackRange() const
+ { return mAttackRange; }
+
+ void setAttackRange(int r)
+ { mAttackRange = r; }
+
void addSound(EquipmentSoundEvent event, const std::string &filename);
const std::string& getSound(EquipmentSoundEvent event) const;
@@ -116,13 +202,18 @@ class ItemInfo
std::string mName;
std::string mDescription; /**< Short description. */
std::string mEffect; /**< Description of effects. */
+#ifdef TMWSERV_SUPPORT
+ char mType; /**< Item type. */
+#else
std::string mType; /**< Item type. */
+#endif
short mWeight; /**< Weight in grams. */
int mView; /**< Item ID of how this item looks. */
int mId; /**< Item ID */
// Equipment related members
SpriteAction mAttackType; /**< Attack type, in case of weapon. */
+ int mAttackRange; /**< Attack range, will be zero if non weapon. */
/** Maps gender to sprite filenames. */
std::map<int, std::string> mAnimationFiles;
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
index 5fa47261..c4cb7447 100644
--- a/src/resources/mapreader.cpp
+++ b/src/resources/mapreader.cpp
@@ -310,7 +310,8 @@ static void setTile(Map *map, MapLayer *layer, int x, int y, int gid)
layer->setTile(x, y, img);
} else {
// Set collision tile
- map->setWalk(x, y, (!set || (gid - set->getFirstGid() == 0)));
+ if (set && (gid - set->getFirstGid() != 0))
+ map->blockTile(x, y, Map::BLOCKTYPE_WALL);
}
}
diff --git a/src/resources/monsterdb.cpp b/src/resources/monsterdb.cpp
index e0259b29..cee9eea5 100644
--- a/src/resources/monsterdb.cpp
+++ b/src/resources/monsterdb.cpp
@@ -95,8 +95,7 @@ void MonsterDB::load()
currentInfo->addSprite(
(const char*) spriteNode->xmlChildrenNode->content);
}
-
- if (xmlStrEqual(spriteNode->name, BAD_CAST "sound"))
+ else if (xmlStrEqual(spriteNode->name, BAD_CAST "sound"))
{
std::string event = XML::getProperty(spriteNode, "event", "");
const char *filename;
@@ -126,15 +125,16 @@ void MonsterDB::load()
currentInfo->getName().c_str());
}
}
-
- if (xmlStrEqual(spriteNode->name, BAD_CAST "attack"))
+ else if (xmlStrEqual(spriteNode->name, BAD_CAST "attack"))
{
- std::string event = XML::getProperty(
+ const int id = XML::getProperty(spriteNode, "id", 0);
+ const std::string particleEffect = XML::getProperty(
spriteNode, "particle-effect", "");
- currentInfo->addAttackParticleEffect(event);
+ SpriteAction spriteAction = SpriteDef::makeSpriteAction(
+ XML::getProperty(spriteNode, "action", "attack"));
+ currentInfo->addMonsterAttack(id, particleEffect, spriteAction);
}
-
- if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx"))
+ else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx"))
{
currentInfo->addParticleEffect(
(const char*) spriteNode->xmlChildrenNode->content);
diff --git a/src/resources/monsterinfo.cpp b/src/resources/monsterinfo.cpp
index 503990e7..2fc16bef 100644
--- a/src/resources/monsterinfo.cpp
+++ b/src/resources/monsterinfo.cpp
@@ -25,7 +25,6 @@
MonsterInfo::MonsterInfo()
{
-
}
MonsterInfo::~MonsterInfo()
@@ -35,8 +34,7 @@ MonsterInfo::~MonsterInfo()
mSounds.clear();
}
-
-void MonsterInfo::addSound(MonsterSoundEvent event, std::string filename)
+void MonsterInfo::addSound(MonsterSoundEvent event, const std::string &filename)
{
if (mSounds.find(event) == mSounds.end())
{
@@ -46,24 +44,41 @@ void MonsterInfo::addSound(MonsterSoundEvent event, std::string filename)
mSounds[event]->push_back("sfx/" + filename);
}
+const std::string &MonsterInfo::getSound(MonsterSoundEvent event) const
+{
+ static std::string empty("");
+ std::map<MonsterSoundEvent, std::vector<std::string>* >::const_iterator i =
+ mSounds.find(event);
+ return (i == mSounds.end()) ? empty :
+ i->second->at(rand() % i->second->size());
+}
-std::string MonsterInfo::getSound(MonsterSoundEvent event) const
+const std::string &MonsterInfo::getAttackParticleEffect(int attackType) const
{
- std::map<MonsterSoundEvent, std::vector<std::string>* >::const_iterator i;
+ static std::string empty("");
+ std::map<int, MonsterAttack*>::const_iterator i =
+ mMonsterAttacks.find(attackType);
+ return (i == mMonsterAttacks.end()) ? empty : (*i).second->particleEffect;
+}
- i = mSounds.find(event);
+SpriteAction MonsterInfo::getAttackAction(int attackType) const
+{
+ std::map<int, MonsterAttack*>::const_iterator i =
+ mMonsterAttacks.find(attackType);
+ return (i == mMonsterAttacks.end()) ? ACTION_ATTACK : (*i).second->action;
+}
- if (i == mSounds.end())
- {
- return "";
- }
- else
- {
- return i->second->at(rand()%i->second->size());
- }
+void MonsterInfo::addMonsterAttack(int id,
+ const std::string &particleEffect,
+ SpriteAction action)
+{
+ MonsterAttack *a = new MonsterAttack;
+ a->particleEffect = particleEffect;
+ a->action = action;
+ mMonsterAttacks[id] = a;
}
-void MonsterInfo::addParticleEffect(std::string filename)
+void MonsterInfo::addParticleEffect(const std::string &filename)
{
mParticleEffects.push_back(filename);
}
diff --git a/src/resources/monsterinfo.h b/src/resources/monsterinfo.h
index 359791fd..02574147 100644
--- a/src/resources/monsterinfo.h
+++ b/src/resources/monsterinfo.h
@@ -37,6 +37,12 @@ enum MonsterSoundEvent
MONSTER_EVENT_DIE
};
+struct MonsterAttack
+{
+ std::string particleEffect;
+ SpriteAction action;
+};
+
/**
* Holds information about a certain type of monster. This includes the name
* of the monster, the sprite to display and the sounds the monster makes.
@@ -56,16 +62,17 @@ class MonsterInfo
*/
~MonsterInfo();
- void setName(std::string name) { mName = name; }
+ void setName(const std::string &name) { mName = name; }
- void addSprite(std::string filename) { mSprites.push_back(filename); }
+ void addSprite(const std::string &filename)
+ { mSprites.push_back(filename); }
void setTargetCursorSize(Being::TargetCursorSize targetCursorSize)
{ mTargetCursorSize = targetCursorSize; }
- void addSound(MonsterSoundEvent event, std::string filename);
+ void addSound(MonsterSoundEvent event, const std::string &filename);
- void addParticleEffect(std::string filename);
+ void addParticleEffect(const std::string &filename);
const std::string& getName() const
{ return mName; }
@@ -76,22 +83,25 @@ class MonsterInfo
Being::TargetCursorSize getTargetCursorSize() const
{ return mTargetCursorSize; }
- std::string getSound(MonsterSoundEvent event) const;
+ const std::string &getSound(MonsterSoundEvent event) const;
+
+ void addMonsterAttack(int id,
+ const std::string &particleEffect,
+ SpriteAction action);
- std::string getAttackParticleEffect() const { return mAttackParticle; }
+ const std::string &getAttackParticleEffect(int attackType) const;
- void addAttackParticleEffect(const std::string &particleEffect)
- { mAttackParticle = particleEffect; }
+ SpriteAction getAttackAction(int attackType) const;
const std::list<std::string>& getParticleEffects() const
{ return mParticleEffects; }
private:
std::string mName;
- std::string mAttackParticle;
std::list<std::string> mSprites;
Being::TargetCursorSize mTargetCursorSize;
std::map<MonsterSoundEvent, std::vector<std::string>* > mSounds;
+ std::map<int, MonsterAttack*> mMonsterAttacks;
std::list<std::string> mParticleEffects;
};
diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp
index 0a87db16..390bd3d0 100644
--- a/src/resources/spritedef.cpp
+++ b/src/resources/spritedef.cpp
@@ -348,6 +348,38 @@ SpriteAction SpriteDef::makeSpriteAction(const std::string &action)
else if (action == "attack_throw") {
return ACTION_ATTACK_THROW;
}
+#ifdef TMWSERV_SUPPORT
+ else if (action == "special0") {
+ return ACTION_SPECIAL_0;
+ }
+ else if (action == "special1") {
+ return ACTION_SPECIAL_1;
+ }
+ else if (action == "special2") {
+ return ACTION_SPECIAL_2;
+ }
+ else if (action == "special3") {
+ return ACTION_SPECIAL_3;
+ }
+ else if (action == "special4") {
+ return ACTION_SPECIAL_4;
+ }
+ else if (action == "special5") {
+ return ACTION_SPECIAL_5;
+ }
+ else if (action == "special6") {
+ return ACTION_SPECIAL_6;
+ }
+ else if (action == "special7") {
+ return ACTION_SPECIAL_7;
+ }
+ else if (action == "special8") {
+ return ACTION_SPECIAL_8;
+ }
+ else if (action == "special9") {
+ return ACTION_SPECIAL_9;
+ }
+#endif
else if (action == "cast_magic") {
return ACTION_CAST_MAGIC;
}
diff --git a/src/resources/spritedef.h b/src/resources/spritedef.h
index b9d7b85d..c3db8d64 100644
--- a/src/resources/spritedef.h
+++ b/src/resources/spritedef.h
@@ -43,6 +43,18 @@ enum SpriteAction
ACTION_ATTACK_STAB,
ACTION_ATTACK_BOW,
ACTION_ATTACK_THROW,
+#ifdef TMWSERV_SUPPORT
+ ACTION_SPECIAL_0,
+ ACTION_SPECIAL_1,
+ ACTION_SPECIAL_2,
+ ACTION_SPECIAL_3,
+ ACTION_SPECIAL_4,
+ ACTION_SPECIAL_5,
+ ACTION_SPECIAL_6,
+ ACTION_SPECIAL_7,
+ ACTION_SPECIAL_8,
+ ACTION_SPECIAL_9,
+#endif
ACTION_CAST_MAGIC,
ACTION_USE_ITEM,
ACTION_SIT,
@@ -55,8 +67,8 @@ enum SpriteAction
enum SpriteDirection
{
DIRECTION_DEFAULT = 0,
- DIRECTION_DOWN,
DIRECTION_UP,
+ DIRECTION_DOWN,
DIRECTION_LEFT,
DIRECTION_RIGHT,
DIRECTION_INVALID