summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2014-01-11 23:00:47 +0300
committerAndrei Karas <akaras@inbox.ru>2014-01-11 23:00:47 +0300
commit0fa192854595ebe03cce54ad2b251abc4c8e8827 (patch)
treeb0129f65bc0a70926adea202756d0794db974980
parentf9209b4a764e85a7ae0e40eee654b543d2ccf2ae (diff)
downloadmv-0fa192854595ebe03cce54ad2b251abc4c8e8827.tar.gz
mv-0fa192854595ebe03cce54ad2b251abc4c8e8827.tar.bz2
mv-0fa192854595ebe03cce54ad2b251abc4c8e8827.tar.xz
mv-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.cpp95
-rw-r--r--src/being/being.h18
-rw-r--r--src/commands.cpp2
-rw-r--r--src/gui/windows/chatwindow.cpp4
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);
}