diff options
author | Andrei Karas <akaras@inbox.ru> | 2014-01-11 23:00:47 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2014-01-11 23:00:47 +0300 |
commit | 0fa192854595ebe03cce54ad2b251abc4c8e8827 (patch) | |
tree | b0129f65bc0a70926adea202756d0794db974980 | |
parent | f9209b4a764e85a7ae0e40eee654b543d2ccf2ae (diff) | |
download | manaplus-0fa192854595ebe03cce54ad2b251abc4c8e8827.tar.gz manaplus-0fa192854595ebe03cce54ad2b251abc4c8e8827.tar.bz2 manaplus-0fa192854595ebe03cce54ad2b251abc4c8e8827.tar.xz manaplus-0fa192854595ebe03cce54ad2b251abc4c8e8827.zip |
add support for multiply pets for one player at same time.
But one item still can have only one pet.
-rw-r--r-- | src/being/being.cpp | 95 | ||||
-rw-r--r-- | src/being/being.h | 18 | ||||
-rw-r--r-- | src/commands.cpp | 2 | ||||
-rw-r--r-- | src/gui/windows/chatwindow.cpp | 4 |
4 files changed, 86 insertions, 33 deletions
diff --git a/src/being/being.cpp b/src/being/being.cpp index 5d4e741c4..399b3883c 100644 --- a/src/being/being.cpp +++ b/src/being/being.cpp @@ -151,7 +151,7 @@ Being::Being(const int id, const Type type, const uint16_t subtype, mSpriteHide(new int[20]), mSpriteDraw(new int[20]), mComment(), - mPet(nullptr), + mPets(), mOwner(nullptr), mSpecialParticle(nullptr), mX(0), @@ -176,7 +176,6 @@ Being::Being(const int id, const Type type, const uint16_t subtype, mCriticalHit(0), mPvpRank(0), mNumber(100), - mPetId(0), mLook(0), mHairColor(0), mErased(false), @@ -242,14 +241,18 @@ Being::~Being() mAnimationEffect = nullptr; if (mOwner) - mOwner->setPet(nullptr); - if (mPet) + mOwner->unassignPet(this); + FOR_EACH (std::vector<Being*>::iterator, it, mPets) { - mPet->setOwner(nullptr); - actorManager->erase(mPet); - delete mPet; - mPet = nullptr; + Being *pet = *it; + if (pet) + { + pet->setOwner(nullptr); + actorManager->erase(pet); + delete pet; + } } + mPets.clear(); removeAllItemsParticles(); } @@ -1609,8 +1612,12 @@ void Being::logic() actorManager->destroy(this); } - if (mPet) - mPet->petLogic(); + FOR_EACH (std::vector<Being*>::iterator, it, mPets) + { + Being *const pet = *it; + if (pet) + pet->petLogic(); + } const SoundInfo *const sound = mNextSound.sound; if (sound) @@ -2121,11 +2128,11 @@ void Being::setSprite(const unsigned int slot, const int id, if (id1) { const ItemInfo &info = ItemDB::get(id1); - if (mMap) + if (mMap && mType == PLAYER) { const int pet = info.getPet(); if (pet) - removePet(); + removePet(pet); } removeItemParticles(id1); } @@ -3207,14 +3214,15 @@ void Being::addPet(const int id) if (!actorManager || !config.getBoolValue("usepets")) return; - removePet(); + if (findChildPet(id)) + return; + Being *const being = actorManager->createBeing( id, ActorSprite::PET, 0); if (being) { being->setOwner(this); - mPetId = id; - mPet = being; + mPets.push_back(being); int dstX = mX; int dstY = mY; being->fixPetSpawnPos(dstX, dstY); @@ -3223,24 +3231,53 @@ void Being::addPet(const int id) } } -void Being::removePet() +Being *Being::findChildPet(const int id) +{ + FOR_EACH (std::vector<Being*>::iterator, it, mPets) + { + Being *const pet = *it; + if (pet && pet->mId == id) + return pet; + } + return nullptr; +} + +void Being::removePet(const int id) { if (!actorManager) return; - mPetId = 0; - if (mPet) + FOR_EACH (std::vector<Being*>::iterator, it, mPets) { - mPet->setOwner(nullptr); - actorManager->erase(mPet); - delete mPet; - mPet = nullptr; + Being *const pet = *it; + if (pet && pet->mId == id) + { + pet->setOwner(nullptr); + actorManager->erase(pet); + mPets.erase(it); + delete pet; + } } } +void Being::removeAllPets() +{ + FOR_EACH (std::vector<Being*>::iterator, it, mPets) + { + Being *const pet = *it; + if (pet) + { + pet->setOwner(nullptr); + actorManager->erase(pet); + delete pet; + } + } + mPets.clear(); +} + void Being::updatePets() { - removePet(); + removeAllPets(); FOR_EACH (std::vector<int>::const_iterator, it, mSpriteIDs) { const int id = *it; @@ -3249,8 +3286,18 @@ void Being::updatePets() const ItemInfo &info = ItemDB::get(id); const int pet = info.getPet(); if (pet) - { addPet(pet); + } +} + +void Being::unassignPet(Being *const pet1) +{ + FOR_EACH (std::vector<Being*>::iterator, it, mPets) + { + Being *const pet = *it; + if (pet == pet1) + { + mPets.erase(it); return; } } diff --git a/src/being/being.h b/src/being/being.h index 634c26d23..a93d0e3db 100644 --- a/src/being/being.h +++ b/src/being/being.h @@ -877,21 +877,27 @@ class Being : public ActorSprite, public ConfigListener void addPet(const int id); - void removePet(); + void removePet(const int id); void updatePets(); void fixPetSpawnPos(int &dstX, int &dstY) const; - Being *getPet() - { return mPet; } + const std::vector<Being*> &getPets() const + { return mPets; } - void setPet(Being *const pet) - { mPet = pet; } + Being *getFirstPet() + { return mPets.empty() ? nullptr : mPets[0]; } void setOwner(Being *const owner) { mOwner = owner; } + void unassignPet(Being *const pet); + + void removeAllPets(); + + Being *findChildPet(const int id); + void playSfx(const SoundInfo &sound, Being *const being, const bool main, const int x, const int y) const; @@ -1029,7 +1035,7 @@ class Being : public ActorSprite, public ConfigListener int *mSpriteHide; int *mSpriteDraw; std::string mComment; - Being *mPet; + std::vector<Being*> mPets; Being *mOwner; Particle *mSpecialParticle; diff --git a/src/commands.cpp b/src/commands.cpp index 96369c53e..10abd6d43 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -1261,7 +1261,7 @@ impHandler1(talkRaw) impHandler1(talkPet) { // in future probably need add channel detection - if (player_node->getPet()) + if (!player_node->getPets().empty()) Net::getChatHandler()->talkPet(args, GENERAL_CHANNEL); else Net::getChatHandler()->talk(args, GENERAL_CHANNEL); diff --git a/src/gui/windows/chatwindow.cpp b/src/gui/windows/chatwindow.cpp index 015e58b61..c434bea2f 100644 --- a/src/gui/windows/chatwindow.cpp +++ b/src/gui/windows/chatwindow.cpp @@ -1577,7 +1577,7 @@ void ChatWindow::localPetSay(const std::string &nick, const std::string &text) Being *pet = nullptr; if (being) { - pet = being->getPet(); + pet = being->getFirstPet(); if (pet) pet->setSpeech(text, GENERAL_CHANNEL); } @@ -1601,7 +1601,7 @@ void ChatWindow::localPetEmote(const std::string &nick, const uint8_t emoteId) nick, ActorSprite::PLAYER); if (being) { - Being *const pet = being->getPet(); + Being *const pet = being->getFirstPet(); if (pet) pet->setEmote(emoteId, 0); } |