summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/being.cpp56
-rw-r--r--src/flooritem.cpp2
-rw-r--r--src/gui/popupmenu.cpp2
-rw-r--r--src/gui/widgets/chattab.cpp2
-rw-r--r--src/item.cpp4
-rw-r--r--src/localplayer.cpp2
-rw-r--r--src/resources/itemdb.cpp32
-rw-r--r--src/resources/iteminfo.cpp110
-rw-r--r--src/resources/iteminfo.h36
-rw-r--r--src/resources/spritedef.h16
10 files changed, 194 insertions, 68 deletions
diff --git a/src/being.cpp b/src/being.cpp
index d8e3119b5..904a59390 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -1073,6 +1073,7 @@ void Being::setDirection(Uint8 direction)
mSpriteDirection = dir;
CompoundSprite::setSpriteDirection(dir);
+ recalcSpritesOrder();
}
Uint8 Being::calcDirection() const
@@ -1660,7 +1661,7 @@ void Being::setSprite(unsigned int slot, int id, std::string color,
}
else
{
- ItemInfo info = ItemDB::get(id);
+ const ItemInfo &info = ItemDB::get(id);
std::string filename = info.getSprite(mGender);
AnimatedSprite *equipmentSprite = NULL;
@@ -2094,6 +2095,9 @@ void Being::recalcSpritesOrder()
{
slotRemap.push_back(slot);
+ if (mSpriteIDs.size() <= slot)
+ continue;
+
int id = mSpriteIDs[slot];
if (!id)
continue;
@@ -2102,35 +2106,39 @@ void Being::recalcSpritesOrder()
if (info.isRemoveSprites())
{
- std::map<int, std::map<int, int> > spriteToItems
- = info.getSpriteToItemReplaceMap();
-
- std::map<int, std::map<int, int> >::iterator it;
+ SpriteToItemMap *spriteToItems = info.getSpriteToItemReplaceMap(
+ mSpriteDirection);
- for (it = spriteToItems.begin(); it != spriteToItems.end(); ++it)
+ if (spriteToItems)
{
- int removeSprite = it->first;
- std::map<int, int> &itemReplacer = it->second;
- if (itemReplacer.size() == 0)
- {
- mSpriteHide[removeSprite] = 1;
- }
- else
+ SpriteToItemMap::iterator it;
+
+ for (it = spriteToItems->begin();
+ it != spriteToItems->end(); ++it)
{
- std::map<int, int>::iterator repIt
- = itemReplacer.find(mSpriteIDs[removeSprite]);
- if (repIt != itemReplacer.end())
+ int removeSprite = it->first;
+ std::map<int, int> &itemReplacer = it->second;
+ if (itemReplacer.empty())
+ {
+ mSpriteHide[removeSprite] = 1;
+ }
+ else
{
- mSpriteHide[removeSprite] = repIt->second;
- if (repIt->second != 1)
+ std::map<int, int>::iterator repIt
+ = itemReplacer.find(mSpriteIDs[removeSprite]);
+ if (repIt != itemReplacer.end())
{
- setSprite(removeSprite, repIt->second,
- mSpriteColors[removeSprite], 1, false, true);
+ mSpriteHide[removeSprite] = repIt->second;
+ if (repIt->second != 1)
+ {
+ setSprite(removeSprite, repIt->second,
+ mSpriteColors[removeSprite],
+ 1, false, true);
+ }
}
}
}
}
-
}
if (info.getDrawBefore() > 0)
@@ -2195,7 +2203,11 @@ void Being::recalcSpritesOrder()
{
int slot = searchSlotValue(slotRemap, slot0);
int val = slotRemap.at(slot);
- int id = mSpriteIDs[val];
+ int id = 0;
+
+ if ((int)mSpriteIDs.size() > val)
+ id = mSpriteIDs[val];
+
int idx = -1;
int idx1 = -1;
// logger->log("item %d, id=%d", slot, id);
diff --git a/src/flooritem.cpp b/src/flooritem.cpp
index 952e8eebb..63112511e 100644
--- a/src/flooritem.cpp
+++ b/src/flooritem.cpp
@@ -78,7 +78,7 @@ FloorItem::FloorItem(int id,
mPos.y = 0;
}
- ItemInfo info = ItemDB::get(itemId);
+ const ItemInfo &info = ItemDB::get(itemId);
setupSpriteDisplay(info.getDisplay(), true, 1,
info.getDyeColorsString(mColor));
}
diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp
index 2739f13a9..79618ad04 100644
--- a/src/gui/popupmenu.cpp
+++ b/src/gui/popupmenu.cpp
@@ -462,7 +462,7 @@ void PopupMenu::showPopup(int x, int y, FloorItem *floorItem)
return;
mFloorItem = floorItem;
- ItemInfo info = floorItem->getInfo();
+ const ItemInfo &info = floorItem->getInfo();
mBrowserBox->clearRows();
std::string name;
diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp
index 3f2166de0..42a39a20f 100644
--- a/src/gui/widgets/chattab.cpp
+++ b/src/gui/widgets/chattab.cpp
@@ -344,7 +344,7 @@ void ChatTab::chatInput(const std::string &message)
{
temp = msg.substr(start + 1, end - start - 1);
- const ItemInfo itemInfo = ItemDB::get(temp);
+ const ItemInfo &itemInfo = ItemDB::get(temp);
if (itemInfo.getId() != 0)
{
msg.insert(end, "@@");
diff --git a/src/item.cpp b/src/item.cpp
index f74d0e837..d76eaf401 100644
--- a/src/item.cpp
+++ b/src/item.cpp
@@ -70,7 +70,7 @@ void Item::setId(int id, unsigned char color)
mDrawImage->decRef();
ResourceManager *resman = ResourceManager::getInstance();
- ItemInfo info = getInfo();
+ const ItemInfo &info = getInfo();
mTags = info.getTags();
// logger->log("tag0=" + toString(mTags[1]));
@@ -107,7 +107,7 @@ bool Item::isHaveTag(int tagId)
Image *Item::getImage(int id, unsigned char color)
{
ResourceManager *resman = ResourceManager::getInstance();
- ItemInfo info = ItemDB::get(id);
+ const ItemInfo &info = ItemDB::get(id);
SpriteDisplay display = info.getDisplay();
std::string imagePath = "graphics/items/" + display.image;
Image *image;
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index 124f2dfe1..0310bb8ad 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -1470,7 +1470,7 @@ int LocalPlayer::getAttackRange()
Item *weapon = PlayerInfo::getEquipment(EQUIP_FIGHT1_SLOT);
if (weapon)
{
- const ItemInfo info = weapon->getInfo();
+ const ItemInfo &info = weapon->getInfo();
return info.getAttackRange();
}
return 48; // unarmed range
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index 1260fab58..bee988510 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -56,6 +56,7 @@ static void loadSoundRef(ItemInfo *itemInfo, xmlNodePtr node);
static void loadFloorSprite(SpriteDisplay *display, xmlNodePtr node);
static void loadReplaceSprite(ItemInfo *itemInfo, xmlNodePtr replaceNode);
static int parseSpriteName(std::string &name);
+static int parseDirectionName(std::string name);
static char const *const fields[][2] =
{
@@ -530,6 +531,29 @@ int parseSpriteName(std::string &name)
return id;
}
+int parseDirectionName(std::string name)
+{
+ int id = -1;
+ if (name == "down")
+ id = DIRECTION_DOWN;
+ else if (name == "downleft" || name == "leftdown")
+ id = DIRECTION_DOWNLEFT;
+ else if (name == "left")
+ id = DIRECTION_LEFT;
+ else if (name == "upleft" || name == "leftup")
+ id = DIRECTION_UPLEFT;
+ else if (name == "up")
+ id = DIRECTION_UP;
+ else if (name == "upright" || name == "rightup")
+ id = DIRECTION_UPRIGHT;
+ else if (name == "right")
+ id = DIRECTION_RIGHT;
+ else if (name == "downright" || name == "rightdown")
+ id = DIRECTION_DOWNRIGHT;
+
+ return id;
+}
+
void loadSpriteRef(ItemInfo *itemInfo, xmlNodePtr node)
{
std::string gender = XML::getProperty(node, "gender", "unisex");
@@ -588,8 +612,10 @@ void loadFloorSprite(SpriteDisplay *display, xmlNodePtr floorNode)
void loadReplaceSprite(ItemInfo *itemInfo, xmlNodePtr replaceNode)
{
std::string removeSprite = XML::getProperty(replaceNode, "sprite", "");
- std::map<int, int> &mapList = itemInfo->addReplaceSprite(
- parseSpriteName(removeSprite));
+ int direction = parseDirectionName(XML::getProperty(
+ replaceNode, "direction", "all"));
+ std::map<int, int> *mapList = itemInfo->addReplaceSprite(
+ parseSpriteName(removeSprite), direction);
itemInfo->setRemoveSprites();
@@ -599,7 +625,7 @@ void loadReplaceSprite(ItemInfo *itemInfo, xmlNodePtr replaceNode)
{
int from = XML::getProperty(itemNode, "from", 0);
int to = XML::getProperty(itemNode, "to", 1);
- mapList[from] = to;
+ (*mapList)[from] = to;
}
}
}
diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp
index 3eea45360..70c577da2 100644
--- a/src/resources/iteminfo.cpp
+++ b/src/resources/iteminfo.cpp
@@ -25,11 +25,62 @@
#include "resources/itemdb.h"
#include "configuration.h"
+#include "utils/dtor.h"
+
#include <set>
#include <map>
#include "debug.h"
+
+ItemInfo::ItemInfo(ItemInfo &info)
+{
+ mType = info.mType;
+ mWeight = info.mWeight;
+ mView = info.mView;
+ mId = info.mId;
+ mDrawBefore = info.mDrawBefore;
+ mDrawAfter = info.mDrawAfter;
+ mDrawPriority = info.mDrawPriority;
+ mIsRemoveSprites = info.mIsRemoveSprites;
+ mAttackAction = info.mAttackAction;
+ mAttackRange = info.mAttackRange;
+ mColors = info.mColors;
+ mColorList = info.mColorList;
+ mHitEffectId = info.mHitEffectId;
+ mCriticalHitEffectId = info.mCriticalHitEffectId;
+ for (int f = 0; f < 9; f ++)
+ mSpriteToItemReplaceMap[f] = 0;
+}
+
+ItemInfo::ItemInfo() :
+ mType(ITEM_UNUSABLE),
+ mWeight(0),
+ mView(0),
+ mId(0),
+ mDrawBefore(-1),
+ mDrawAfter(-1),
+ mDrawPriority(0),
+ mIsRemoveSprites(false),
+ mAttackAction(SpriteAction::INVALID),
+ mAttackRange(0),
+ mColors(0),
+ mColorList(""),
+ mHitEffectId(0),
+ mCriticalHitEffectId(0)
+{
+ for (int f = 0; f < 9; f ++)
+ mSpriteToItemReplaceMap[f] = 0;
+}
+
+ItemInfo::~ItemInfo()
+{
+ delete_all(mSpriteToItemReplaceList);
+ mSpriteToItemReplaceList.clear();
+ for (int f = 0;f < 9; f ++)
+ mSpriteToItemReplaceMap[f] = 0;
+}
+
const std::string &ItemInfo::getSprite(Gender gender) const
{
if (mView)
@@ -73,17 +124,45 @@ const std::string &ItemInfo::getSound(EquipmentSoundEvent event) const
return i->second.size() > 0 ? i->second[rand() % i->second.size()] : empty;
}
-std::map<int, int> &ItemInfo::addReplaceSprite(int sprite)
+std::map<int, int> *ItemInfo::addReplaceSprite(int sprite, int direction)
{
- std::map<int, std::map<int, int> >::iterator it
- = mSpriteToItemReplaceMap.find(sprite);
- if (it == mSpriteToItemReplaceMap.end())
+ if (direction == -1)
+ {
+ SpriteToItemMap *spMap = new SpriteToItemMap();
+ for (int f = 0; f < 9; f ++)
+ {
+ if (!mSpriteToItemReplaceMap[f])
+ {
+ mSpriteToItemReplaceMap[f] = spMap;
+ direction = f;
+ }
+ }
+ if (direction >= 0)
+ mSpriteToItemReplaceList.push_back(spMap);
+ else
+ delete spMap;
+ }
+
+ if (direction < 0 || direction >= 9)
+ return 0;
+
+ SpriteToItemMap *spMap = mSpriteToItemReplaceMap[direction];
+
+ if (!spMap)
+ {
+ spMap = new SpriteToItemMap();
+ mSpriteToItemReplaceMap[direction] = spMap;
+ mSpriteToItemReplaceList.push_back(spMap);
+ }
+
+ SpriteToItemMap::iterator it = spMap->find(sprite);
+ if (it == spMap->end())
{
std::map<int, int> tmp;
- mSpriteToItemReplaceMap[sprite] = tmp;
- it = mSpriteToItemReplaceMap.find(sprite);
+ (*mSpriteToItemReplaceMap[direction])[sprite] = tmp;
+ it = mSpriteToItemReplaceMap[direction]->find(sprite);
}
- return it->second;
+ return &it->second;
}
void ItemInfo::setColorsList(std::string name)
@@ -145,3 +224,20 @@ const std::string ItemInfo::replaceColors(std::string str,
return replaceAll(str, "%Color%", name);
}
+
+SpriteToItemMap *ItemInfo::getSpriteToItemReplaceMap(int direction) const
+{
+ if (direction < 0 || direction >= 9)
+ return 0;
+
+ SpriteToItemMap *spMap = mSpriteToItemReplaceMap[direction];
+ if (spMap)
+ return spMap;
+ if (direction == DIRECTION_UPLEFT || direction == DIRECTION_UPRIGHT)
+ return mSpriteToItemReplaceMap[DIRECTION_UP];
+
+ if (direction == DIRECTION_DOWNLEFT || direction == DIRECTION_DOWNRIGHT)
+ return mSpriteToItemReplaceMap[DIRECTION_DOWN];
+
+ return 0;
+}
diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h
index d0a577f6d..b977a94ce 100644
--- a/src/resources/iteminfo.h
+++ b/src/resources/iteminfo.h
@@ -92,6 +92,9 @@ enum ItemType
ITEM_SPRITE_HAIR // 15
};
+// sprite, <itemfrom, itemto>
+typedef std::map<int, std::map<int, int> > SpriteToItemMap;
+
/**
* Defines a class for storing item infos. This includes information used when
* the item is equipped.
@@ -102,23 +105,11 @@ class ItemInfo
/**
* Constructor.
*/
- ItemInfo():
- mType(ITEM_UNUSABLE),
- mWeight(0),
- mView(0),
- mId(0),
- mDrawBefore(-1),
- mDrawAfter(-1),
- mDrawPriority(0),
- mIsRemoveSprites(false),
- mAttackAction(SpriteAction::INVALID),
- mAttackRange(0),
- mColors(0),
- mColorList(""),
- mHitEffectId(0),
- mCriticalHitEffectId(0)
- {
- }
+ ItemInfo();
+
+ ItemInfo(ItemInfo &info);
+
+ ~ItemInfo();
void setId(int id)
{ mId = id; }
@@ -253,10 +244,9 @@ class ItemInfo
int getReplaceToSpriteId(int id) const;
- std::map<int, int> &addReplaceSprite(int sprite);
+ std::map<int, int> *addReplaceSprite(int sprite, int direction);
- std::map<int, std::map<int, int> > getSpriteToItemReplaceMap() const
- { return mSpriteToItemReplaceMap; }
+ SpriteToItemMap *getSpriteToItemReplaceMap(int directions) const;
std::string getDyeString(int color) const;
@@ -285,8 +275,10 @@ class ItemInfo
int mDrawAfter;
int mDrawPriority;
bool mIsRemoveSprites;
- // sprite, <itemfrom, itemto>
- std::map<int, std::map<int, int> > mSpriteToItemReplaceMap;
+ // sprite, <itemfrom, itemto> [direction]
+ SpriteToItemMap *mSpriteToItemReplaceMap[9];
+
+ std::vector<SpriteToItemMap*> mSpriteToItemReplaceList;
// Equipment related members.
/** Attack type, in case of weapon.
diff --git a/src/resources/spritedef.h b/src/resources/spritedef.h
index 475ab2e25..8fa64e7b9 100644
--- a/src/resources/spritedef.h
+++ b/src/resources/spritedef.h
@@ -92,14 +92,14 @@ namespace SpriteAction
enum SpriteDirection
{
DIRECTION_DEFAULT = 0,
- DIRECTION_UP,
- DIRECTION_DOWN,
- DIRECTION_LEFT,
- DIRECTION_RIGHT,
- DIRECTION_UPLEFT,
- DIRECTION_UPRIGHT,
- DIRECTION_DOWNLEFT,
- DIRECTION_DOWNRIGHT,
+ DIRECTION_UP = 1,
+ DIRECTION_DOWN = 2,
+ DIRECTION_LEFT = 3,
+ DIRECTION_RIGHT = 4,
+ DIRECTION_UPLEFT = 5,
+ DIRECTION_UPRIGHT = 6,
+ DIRECTION_DOWNLEFT = 7,
+ DIRECTION_DOWNRIGHT = 8,
DIRECTION_INVALID
};