summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/being.cpp67
-rw-r--r--src/being.h4
-rw-r--r--src/resources/itemdb.cpp26
-rw-r--r--src/resources/iteminfo.cpp17
-rw-r--r--src/resources/iteminfo.h29
-rw-r--r--src/utils/stringutils.cpp11
-rw-r--r--src/utils/stringutils.h2
7 files changed, 118 insertions, 38 deletions
diff --git a/src/being.cpp b/src/being.cpp
index 6d26f74a7..88a923268 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -1483,7 +1483,7 @@ void Being::updateColors()
}
void Being::setSprite(unsigned int slot, int id, const std::string &color,
- bool isWeapon)
+ bool isWeapon, bool isTempSprite)
{
if (slot >= Net::getCharHandler()->maxSprite())
return;
@@ -1530,9 +1530,12 @@ void Being::setSprite(unsigned int slot, int id, const std::string &color,
setAction(mAction);
}
- mSpriteIDs[slot] = id;
- mSpriteColors[slot] = color;
- recalcSpritesOrder();
+ if (!isTempSprite)
+ {
+ mSpriteIDs[slot] = id;
+ mSpriteColors[slot] = color;
+ recalcSpritesOrder();
+ }
}
void Being::setSpriteID(unsigned int slot, int id)
@@ -1702,10 +1705,10 @@ bool Being::draw(Graphics *graphics, int offsetX, int offsetY) const
void Being::drawSprites(Graphics* graphics, int posX, int posY) const
{
-// CompoundSprite::drawSprites(graphics, posX, posY);
for (int f = 0; f < getNumberOfLayers(); f ++)
{
- if (mSpriteHide[mSpriteRemap[f]])
+ const int rSprite = mSpriteHide[mSpriteRemap[f]];
+ if (rSprite == 1)
continue;
Sprite *sprite = getSprite(mSpriteRemap[f]);
@@ -1719,13 +1722,10 @@ void Being::drawSprites(Graphics* graphics, int posX, int posY) const
void Being::drawSpritesSDL(Graphics* graphics, int posX, int posY) const
{
-// CompoundSprite::drawSprites(graphics, posX, posY);
-
-// logger->log("getNumberOfLayers: %d", getNumberOfLayers());
-
for (unsigned f = 0; f < size(); f ++)
{
- if (mSpriteHide[mSpriteRemap[f]])
+ const int rSprite = mSpriteHide[mSpriteRemap[f]];
+ if (rSprite == 1)
continue;
Sprite *sprite = getSprite(mSpriteRemap[f]);
@@ -1887,9 +1887,13 @@ void Being::recalcSpritesOrder()
// logger->log("preparation start");
std::vector<int>::iterator it;
+ int *oldHide = new int[20];
for (unsigned slot = 0; slot < sz; slot ++)
+ {
+ oldHide[slot] = mSpriteHide[slot];
mSpriteHide[slot] = 0;
+ }
for (unsigned slot = 0; slot < sz; slot ++)
{
@@ -1900,10 +1904,37 @@ void Being::recalcSpritesOrder()
continue;
const ItemInfo &info = ItemDB::get(id);
- if (info.getRemoveSprite() > 0)
+ bool isRemove = false;
+ bool isRemoved = mSpriteHide[slot] != 0 && mSpriteHide[slot] != 1;
+
+ if (info.isRemoveSprites())
{
- if (info.isRemoveSpriteId(mSpriteIDs[info.getRemoveSprite()]))
- mSpriteHide[info.getRemoveSprite()] = 1;
+ std::map<int, std::map<int, int> > spriteToItems
+ = info.getSpriteToItemReplaceMap();
+
+ std::map<int, std::map<int, int> >::iterator it;
+
+ for (it = spriteToItems.begin(); it != spriteToItems.end(); ++it)
+ {
+ int removeSprite = it->first;
+ std::map<int, int> &itemReplacer = it->second;
+ if (itemReplacer.size() == 0)
+ {
+ mSpriteHide[removeSprite] = 1;
+ }
+ else
+ {
+ std::map<int, int>::iterator repIt
+ = itemReplacer.find(mSpriteIDs[removeSprite]);
+ if (repIt != itemReplacer.end())
+ {
+ mSpriteHide[removeSprite] = repIt->second;
+ setSprite(removeSprite, repIt->second,
+ mSpriteColors[removeSprite], false, true);
+ }
+ }
+ }
+
}
if (info.getDrawBefore() > 0)
@@ -2027,6 +2058,14 @@ void Being::recalcSpritesOrder()
for (unsigned slot = 0; slot < sz; slot ++)
{
mSpriteRemap[slot] = slotRemap[slot];
+ if (oldHide[slot] != 0 && oldHide[slot] != 1 && mSpriteHide[slot] == 0)
+ {
+ int id = mSpriteIDs[slot];
+ if (!id)
+ continue;
+
+ setSprite(slot, id, mSpriteColors[slot], false, true);
+ }
// logger->log("slot %d = %d", slot, mSpriteRemap[slot]);
}
}
diff --git a/src/being.h b/src/being.h
index db170af30..1dfc9bb4d 100644
--- a/src/being.h
+++ b/src/being.h
@@ -50,6 +50,7 @@
#define SPEECH_TIME 500
#define SPEECH_MAX_TIME 1000
+class AnimatedSprite;
class BeingCacheEntry;
class BeingInfo;
class FlashText;
@@ -331,7 +332,8 @@ class Being : public ActorSprite, public ConfigListener
* Sets visible equipments for this being.
*/
void setSprite(unsigned int slot, int id,
- const std::string &color = "", bool isWeapon = false);
+ const std::string &color = "", bool isWeapon = false,
+ bool isTempSprite = false);
void setSpriteID(unsigned int slot, int id);
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index 00987ff9d..ce2ec40a2 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -50,6 +50,7 @@ namespace
static void loadSpriteRef(ItemInfo *itemInfo, xmlNodePtr node);
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 char const *const fields[][2] =
@@ -205,8 +206,6 @@ void ItemDB::load()
std::string drawBefore = XML::getProperty(node, "drawBefore", "");
std::string drawAfter = XML::getProperty(node, "drawAfter", "");
std::string removeSprite = XML::getProperty(node, "removeSprite", "");
- std::string removeSpriteIds = XML::getProperty(node, "removeSpriteIds", "");
- std::set<int> rSprites = splitToIntSet(removeSpriteIds, ',');
std::string tags[3];
tags[0] = XML::getProperty(node, "tag",
@@ -266,8 +265,6 @@ void ItemDB::load()
itemInfo->setDrawBefore(parseSpriteName(drawBefore));
itemInfo->setDrawAfter(parseSpriteName(drawAfter));
itemInfo->setDrawPriority(drawPriority);
- itemInfo->setRemoveSprite(parseSpriteName(removeSprite));
- itemInfo->setRemoveSpriteIds(rSprites);
std::string effect;
for (int i = 0; i < int(sizeof(fields) / sizeof(fields[0])); ++i)
@@ -313,6 +310,10 @@ void ItemDB::load()
{
loadFloorSprite(&display, itemChild);
}
+ else if (xmlStrEqual(itemChild->name, BAD_CAST "replace"))
+ {
+ loadReplaceSprite(itemInfo, itemChild);
+ }
}
itemInfo->setDisplay(display);
@@ -554,3 +555,20 @@ 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));
+ itemInfo->setRemoveSprites();
+
+ for_each_xml_child_node(itemNode, replaceNode)
+ {
+ if (xmlStrEqual(itemNode->name, BAD_CAST "item"))
+ {
+ int from = XML::getProperty(itemNode, "from", 0);
+ int to = XML::getProperty(itemNode, "to", 1);
+ mapList[from] = to;
+ }
+ }
+}
diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp
index f65e0396a..c2d3aafef 100644
--- a/src/resources/iteminfo.cpp
+++ b/src/resources/iteminfo.cpp
@@ -25,6 +25,7 @@
#include "configuration.h"
#include <set>
+#include <map>
const std::string &ItemInfo::getSprite(Gender gender) const
{
@@ -67,13 +68,15 @@ const std::string &ItemInfo::getSound(EquipmentSoundEvent event) const
return i == mSounds.end() ? empty : i->second[rand() % i->second.size()];
}
-bool ItemInfo::isRemoveSpriteId(int id) const
+std::map<int,int> &ItemInfo::addReplaceSprite(int sprite)
{
- if (!mRemoveSpriteIds.size()
- || mRemoveSpriteIds.find(id) != mRemoveSpriteIds.end())
+ std::map<int, std::map<int, int> >::iterator it
+ = mSpriteToItemReplaceMap.find(sprite);
+ if (it == mSpriteToItemReplaceMap.end())
{
- return true;
+ std::map<int, int> tmp;
+ mSpriteToItemReplaceMap[sprite] = tmp;
+ it = mSpriteToItemReplaceMap.find(sprite);
}
-
- return false;
-} \ No newline at end of file
+ return it->second;
+}
diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h
index ba7866518..28f4b2e35 100644
--- a/src/resources/iteminfo.h
+++ b/src/resources/iteminfo.h
@@ -108,7 +108,7 @@ class ItemInfo
mDrawBefore(-1),
mDrawAfter(-1),
mDrawPriority(0),
- mRemoveSprite(0),
+ mIsRemoveSprites(false),
mAttackAction(SpriteAction::INVALID),
mAttackRange(0)
{
@@ -209,22 +209,26 @@ class ItemInfo
void setDrawPriority(int n)
{ mDrawPriority = n; }
- int getRemoveSprite() const
- { return mRemoveSprite; }
-
- void setRemoveSprite(int n)
- { mRemoveSprite = n; }
-
std::map<int, int> getTags() const
{ return mTags; }
void addTag(int tag)
{ mTags[tag] = 1; }
- void setRemoveSpriteIds(std::set<int> ids)
- { mRemoveSpriteIds = ids; }
+ void setRemoveSprites()
+ { mIsRemoveSprites = true; }
+
+ bool isRemoveSprites() const
+ { return mIsRemoveSprites; }
+
+ bool isRemoveItemId(int id) const;
+
+ int getReplaceToSpriteId(int id) const;
+
+ std::map<int,int> &addReplaceSprite(int sprite);
- bool isRemoveSpriteId(int id) const;
+ std::map<int, std::map<int, int> > getSpriteToItemReplaceMap() const
+ { return mSpriteToItemReplaceMap; }
protected:
SpriteDisplay mDisplay; /**< Display info (like icon) */
@@ -239,8 +243,9 @@ class ItemInfo
int mDrawBefore;
int mDrawAfter;
int mDrawPriority;
- int mRemoveSprite;
- std::set<int> mRemoveSpriteIds;
+ bool mIsRemoveSprites;
+ // sprite, <itemfrom, itemto>
+ std::map<int, std::map<int, int> > mSpriteToItemReplaceMap;
// Equipment related members.
/** Attack type, in case of weapon.
diff --git a/src/utils/stringutils.cpp b/src/utils/stringutils.cpp
index 99316ce32..357938fb8 100644
--- a/src/utils/stringutils.cpp
+++ b/src/utils/stringutils.cpp
@@ -375,3 +375,14 @@ std::set<int> splitToIntSet(const std::string &text, char separator)
return tokens;
}
+
+std::list<int> splitToIntList(const std::string &text, char separator)
+{
+ std::list<int> tokens;
+ std::stringstream ss(text);
+ std::string item;
+ while(std::getline(ss, item, separator))
+ tokens.push_back(atoi(item.c_str()));
+
+ return tokens;
+}
diff --git a/src/utils/stringutils.h b/src/utils/stringutils.h
index 934c0f82d..a69d30914 100644
--- a/src/utils/stringutils.h
+++ b/src/utils/stringutils.h
@@ -167,4 +167,6 @@ std::string normalize(const std::string &name);
std::set<int> splitToIntSet(const std::string &text, char separator);
+std::list<int> splitToIntList(const std::string &text, char separator);
+
#endif // UTILS_STRINGUTILS_H