From 3805d1384894a33ecb09e4852d47afb04ddb0687 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 14 Feb 2011 03:54:55 +0200 Subject: Replace sprites functionality (need support in client data). --- src/being.cpp | 67 ++++++++++++++++++++++++++++++++++++---------- src/being.h | 4 ++- src/resources/itemdb.cpp | 26 +++++++++++++++--- src/resources/iteminfo.cpp | 17 +++++++----- src/resources/iteminfo.h | 29 +++++++++++--------- src/utils/stringutils.cpp | 11 ++++++++ src/utils/stringutils.h | 2 ++ 7 files changed, 118 insertions(+), 38 deletions(-) (limited to 'src') 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::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 > spriteToItems + = info.getSpriteToItemReplaceMap(); + + std::map >::iterator it; + + for (it = spriteToItems.begin(); it != spriteToItems.end(); ++it) + { + int removeSprite = it->first; + std::map &itemReplacer = it->second; + if (itemReplacer.size() == 0) + { + mSpriteHide[removeSprite] = 1; + } + else + { + std::map::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 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 &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 +#include 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 &ItemInfo::addReplaceSprite(int sprite) { - if (!mRemoveSpriteIds.size() - || mRemoveSpriteIds.find(id) != mRemoveSpriteIds.end()) + std::map >::iterator it + = mSpriteToItemReplaceMap.find(sprite); + if (it == mSpriteToItemReplaceMap.end()) { - return true; + std::map 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 getTags() const { return mTags; } void addTag(int tag) { mTags[tag] = 1; } - void setRemoveSpriteIds(std::set ids) - { mRemoveSpriteIds = ids; } + void setRemoveSprites() + { mIsRemoveSprites = true; } + + bool isRemoveSprites() const + { return mIsRemoveSprites; } + + bool isRemoveItemId(int id) const; + + int getReplaceToSpriteId(int id) const; + + std::map &addReplaceSprite(int sprite); - bool isRemoveSpriteId(int id) const; + std::map > 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 mRemoveSpriteIds; + bool mIsRemoveSprites; + // sprite, + std::map > 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 splitToIntSet(const std::string &text, char separator) return tokens; } + +std::list splitToIntList(const std::string &text, char separator) +{ + std::list 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 splitToIntSet(const std::string &text, char separator); +std::list splitToIntList(const std::string &text, char separator); + #endif // UTILS_STRINGUTILS_H -- cgit v1.2.3-60-g2f50