From a4252ba2050b16a53247335cdddd7aa13a532239 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 25 Jul 2011 03:42:09 +0300 Subject: Add removing palyers sprite logic depend on players direction. --- src/being.cpp | 56 +++++++++++++--------- src/flooritem.cpp | 2 +- src/gui/popupmenu.cpp | 2 +- src/gui/widgets/chattab.cpp | 2 +- src/item.cpp | 4 +- src/localplayer.cpp | 2 +- src/resources/itemdb.cpp | 32 +++++++++++-- src/resources/iteminfo.cpp | 110 +++++++++++++++++++++++++++++++++++++++++--- src/resources/iteminfo.h | 36 ++++++--------- src/resources/spritedef.h | 16 +++---- 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 > spriteToItems - = info.getSpriteToItemReplaceMap(); - - std::map >::iterator it; + SpriteToItemMap *spriteToItems = info.getSpriteToItemReplaceMap( + mSpriteDirection); - for (it = spriteToItems.begin(); it != spriteToItems.end(); ++it) + if (spriteToItems) { - int removeSprite = it->first; - std::map &itemReplacer = it->second; - if (itemReplacer.size() == 0) - { - mSpriteHide[removeSprite] = 1; - } - else + SpriteToItemMap::iterator it; + + for (it = spriteToItems->begin(); + it != spriteToItems->end(); ++it) { - std::map::iterator repIt - = itemReplacer.find(mSpriteIDs[removeSprite]); - if (repIt != itemReplacer.end()) + int removeSprite = it->first; + std::map &itemReplacer = it->second; + if (itemReplacer.empty()) + { + mSpriteHide[removeSprite] = 1; + } + else { - mSpriteHide[removeSprite] = repIt->second; - if (repIt->second != 1) + std::map::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 &mapList = itemInfo->addReplaceSprite( - parseSpriteName(removeSprite)); + int direction = parseDirectionName(XML::getProperty( + replaceNode, "direction", "all")); + std::map *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 #include #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 &ItemInfo::addReplaceSprite(int sprite) +std::map *ItemInfo::addReplaceSprite(int sprite, int direction) { - std::map >::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 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, +typedef std::map > 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 &addReplaceSprite(int sprite); + std::map *addReplaceSprite(int sprite, int direction); - std::map > 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, - std::map > mSpriteToItemReplaceMap; + // sprite, [direction] + SpriteToItemMap *mSpriteToItemReplaceMap[9]; + + std::vector 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 }; -- cgit v1.2.3-60-g2f50