Index: src/map/ai/ai_char_normal.cpp =================================================================== --- src/map/ai/ai_char_normal.cpp (revision 1629) +++ src/map/ai/ai_char_normal.cpp (working copy) @@ -39,6 +39,7 @@ #include "../petentity.h" #include "../ai/ai_pet_dummy.h" #include "../lua/luautils.h" +#include "../alliance.h" #include "../packets/action.h" #include "../packets/char.h" @@ -197,8 +198,29 @@ { return true; } + + + if (m_PChar->PParty != NULL) { + if (m_PChar->PParty->m_PAlliance != NULL) + { + for (int32 a = 0; a < m_PChar->PParty->m_PAlliance->partyList.size(); ++a) + { + for (uint8 i = 0; i < m_PChar->PParty->m_PAlliance->partyList.at(a)->members.size(); ++i) + { + if (m_PChar->PParty->m_PAlliance->partyList.at(a)->members[i]->id == PBattleTarget->m_OwnerID.id) + { + return true; + } + } + } + } + } + + + if (m_PChar->PParty != NULL) + { for (uint8 i = 0; i < m_PChar->PParty->members.size(); ++i) { if (m_PChar->PParty->members[i]->id == PBattleTarget->m_OwnerID.id) @@ -1933,6 +1955,24 @@ { if (m_PChar->PParty != NULL) { + if ( m_PChar->PParty->m_PAlliance != NULL) + { + for (int32 a = 0; a < m_PChar->PParty->m_PAlliance->partyList.size(); ++a) + { + for (uint8 i = 0; i < m_PChar->PParty->m_PAlliance->partyList.at(a)->members.size(); ++i) + { + if (PTarget->m_OwnerID.id == m_PChar->PParty->m_PAlliance->partyList.at(a)->members[i]->id || + (PTarget->m_OwnerID.id == 0 && PTarget->PBattleAI->GetBattleTarget() == m_PChar->PParty->m_PAlliance->partyList.at(a)->members[i])) + { + m_PBattleTarget = PTarget; + m_PChar->pushPacket(new CLockOnPacket(m_PChar, m_PBattleTarget)); + return; + } + } + } + } + + for (uint8 i = 0; i < m_PChar->PParty->members.size(); ++i) { if (PTarget->m_OwnerID.id == m_PChar->PParty->members[i]->id || Index: src/map/ai/ai_mob_dummy.cpp =================================================================== --- src/map/ai/ai_mob_dummy.cpp (revision 1629) +++ src/map/ai/ai_mob_dummy.cpp (working copy) @@ -32,6 +32,7 @@ #include "../status_effect.h" #include "../petentity.h" #include "../zone.h" +#include "../alliance.h" #include "ai_mob_dummy.h" @@ -41,7 +42,6 @@ #include "../packets/entity_update.h" #include "../packets/fade_out.h" #include "../packets/message_basic.h" -#include "../alliance.h" /************************************************************************ @@ -223,17 +223,33 @@ if (DropList != NULL && DropList->size()) { - uint16 highestTH = PChar->getMod(MOD_TREASURE_HUNTER); + uint8 highestTH = PChar->getMod(MOD_TREASURE_HUNTER); - //get highest Treasure Hunter in pt + //get highest Treasure Hunter in pt - if no alliance if(PChar->PParty != NULL){ - for(uint8 i = 0; i < PChar->PParty->members.size(); i++){ - if(PChar->PParty->members.at(i)->getMod(MOD_TREASURE_HUNTER) > highestTH){ - highestTH = PChar->PParty->members.at(i)->getMod(MOD_TREASURE_HUNTER); + if(PChar->PParty->m_PAlliance == NULL){ + for(uint8 i = 0; i < PChar->PParty->members.size(); i++){ + if(PChar->PParty->members.at(i)->getMod(MOD_TREASURE_HUNTER) > highestTH){ + highestTH = PChar->PParty->members.at(i)->getMod(MOD_TREASURE_HUNTER); + } } } } + //get highest Treasure Hunter in pt - if alliance + if(PChar->PParty != NULL){ + if(PChar->PParty->m_PAlliance != NULL){ + for(int32 a = 0; a < PChar->PParty->m_PAlliance->partyList.size(); ++a) + { + for(uint8 i = 0; i < PChar->PParty->m_PAlliance->partyList.at(a)->members.size(); i++){ + if(PChar->PParty->m_PAlliance->partyList.at(a)->members.at(i)->getMod(MOD_TREASURE_HUNTER) > highestTH){ + highestTH = PChar->PParty->m_PAlliance->partyList.at(a)->members.at(i)->getMod(MOD_TREASURE_HUNTER); + } + } + } + } + } + for(uint8 i = 0; i < DropList->size(); ++i) { //highestTH is the number of 'extra chances' at an item. If the item is obtained, then break out. @@ -423,7 +439,7 @@ m_PMobSkill = MobSkills.at(rand() % MobSkills.size()); if(m_PMob->m_Type & MOBTYPE_NOTORIOUS){ - for(uint16 i=0;igetID() == 0){ //TWO-HOUR if(m_PMob->GetHPP() <= 50 && m_PMob->m_SkillStatus==0){//<50% HP and not used skill m_PMobSkill = MobSkills[i]; @@ -541,12 +557,8 @@ //AOE=1 means the circle is around the MONSTER //AOE=2 means the circle is around the BATTLE TARGET //AOE=4 means conal (breath) - if(m_PMobSkill->getAoe() == 1 || m_PMobSkill->getAoe() == 2) - { - //to handle both types of aoe - if(m_PMobSkill->getValidTargets() == TARGET_ENEMY) - { - //aoe on the players + if(m_PMobSkill->getAoe()==1 || m_PMobSkill->getAoe()==2){ //to handle both types of aoe + if(m_PMobSkill->getValidTargets() == TARGET_ENEMY){//aoe on the players //hit the target + the target's PT/alliance apAction_t Action; @@ -560,43 +572,76 @@ Action.flag = 0; m_PMob->m_ActionList.push_back(Action); - //determine the type of circle - position_t radiusAround = m_PMob->loc.p; + if(m_PBattleTarget->objtype==TYPE_PC){ + CCharEntity* m_PChar = (CCharEntity*)m_PBattleTarget; + if(m_PChar->PParty != NULL) + { + if(m_PChar->PParty->m_PAlliance == NULL) + { + //determine the type of circle + position_t radiusAround = m_PMob->loc.p; + if(m_PMobSkill->getAoe()==2){//radius around TARGET not the monster + radiusAround = m_PBattleTarget->loc.p; + } - if(m_PMobSkill->getAoe() == 2) - { - //radius around TARGET not the monster - radiusAround = m_PBattleTarget->loc.p; - } + for (uint32 i = 0; i < m_PChar->PParty->members.size(); i++) + { + CCharEntity* PTarget = (CCharEntity*)m_PChar->PParty->members[i]; + + if(!PTarget->isDead() && PTarget!=m_PBattleTarget && PTarget->getZone() == m_PChar->getZone() && + distance(radiusAround, PTarget->loc.p) <= m_PMobSkill->getDistance()) + { + Action.ActionTarget = PTarget; + Action.param = luautils::OnMobWeaponSkill(PTarget, m_PMob,m_PMobSkill); + Action.messageID = m_PMobSkill->getMsg(); - // TODO: AOERANGE needs to be dynamic, some monsters can hit an entire alliance, or anything within range. - std::vector targets = GetAdditionalTargets(AOE_PARTY, radiusAround, m_PMobSkill->getDistance()); + //handle aoe damage text + if(Action.messageID == 185){ + Action.messageID = 264; //just the damage value needed + } + m_PMob->m_ActionList.push_back(Action); + } + } + + }else if(m_PChar->PParty->m_PAlliance != NULL){ + //ability will hit everyone in the alliance if they are in range - for (uint32 i = 0; i < targets.size(); i++) - { - Action.ActionTarget = targets.at(i); - Action.param = luautils::OnMobWeaponSkill(targets.at(i), m_PMob, m_PMobSkill); - Action.messageID = m_PMobSkill->getMsg(); + //determine the type of circle + position_t radiusAround = m_PMob->loc.p; + if(m_PMobSkill->getAoe()==2){//radius around TARGET not the monster + radiusAround = m_PBattleTarget->loc.p; + } - //handle aoe damage text - if(Action.messageID == 185) - { - Action.messageID = 264; //just the damage value needed - } + for (int32 a = 0; a < m_PChar->PParty->m_PAlliance->partyList.size(); ++a) + { + for (uint32 i = 0; i < m_PChar->PParty->m_PAlliance->partyList.at(a)->members.size(); i++) + { + CCharEntity* PTarget = (CCharEntity*)m_PChar->PParty->m_PAlliance->partyList.at(a)->members[i]; + + if(!PTarget->isDead() && PTarget!=m_PBattleTarget && PTarget->getZone() == m_PChar->getZone() && + distance(radiusAround, PTarget->loc.p) <= m_PMobSkill->getDistance()) + { + Action.ActionTarget = PTarget; + Action.param = luautils::OnMobWeaponSkill(PTarget, m_PMob,m_PMobSkill); + Action.messageID = m_PMobSkill->getMsg(); - m_PMob->m_ActionList.push_back(Action); - } - - } // Valid Target - else if(m_PMobSkill->getValidTargets() == TARGET_SELF) - { - //aoe on the enemy (e.g. aoe cure) + //handle aoe damage text + if(Action.messageID == 185){ + Action.messageID = 264; //just the damage value needed + } + m_PMob->m_ActionList.push_back(Action); + } + } + } + } + } + } + } + else if(m_PMobSkill->getValidTargets() == TARGET_SELF){ //aoe on the enemy (e.g. aoe cure) //TODO: hit self and all targets of the same family? pt? } } - else - { - //single target moves + else{//single target moves apAction_t Action; if(m_PMobSkill->getValidTargets() == TARGET_ENEMY){ Action.ActionTarget = m_PBattleTarget; @@ -1010,113 +1055,3 @@ m_PMob->loc.zone->PushPacket(m_PMob,CHAR_INRANGE, new CEntityUpdatePacket(m_PMob, ENTITY_UPDATE)); } -std::vector CAIMobDummy::GetAdditionalTargets(AOERANGE AoeRange, position_t radiusAround, float radius) -{ - DSP_DEBUG_BREAK_IF(m_PBattleTarget == NULL); - //ShowInfo("Getting Additional Targets\n"); - - std::vector results; - - CParty* PParty = NULL; - CAlliance* PAlliance = NULL; - CZone* PZone = NULL; - - switch(m_PBattleTarget->objtype) - { - case TYPE_PC: // Use player's info - { - //ShowInfo("Target: PC\n"); - //PZone = m_PBattleTarget->loc.zone; // TODO: Zone wide aoe not implemented - //PAlliance = ((CCharEntity*)m_PBattleTarget)->PAlliance; // TODO: Alliances not implemented - PParty = ((CCharEntity*)m_PBattleTarget)->PParty; - break; - } - - case TYPE_PET: // Use owner's info - { - //ShowInfo("Target: Pet\n"); - if(m_PBattleTarget->PMaster) - { - if(m_PBattleTarget->PMaster->objtype == TYPE_PC) - { - // Pet has an owner, and the owner is a player. - //PZone = m_PBattleTarget->PMaster->loc.zone; // TODO: Zone wide aoe not implemented - //PAlliance = ((CCharEntity*)m_PBattleTarget->PMaster)->PAlliance; // TODO: Alliances not implemented - PParty = ((CCharEntity*)m_PBattleTarget->PMaster)->PParty; - } - else - { - // TODO: AoEs initiated from a monster to a monster's or npc's pet. - } - } - break; - } - - default: // TODO: NPC as an AoE target? - { - //ShowInfo("Target: Else\n"); - break; - } - } - - // TODO: Implement zone wide AoEs - //if(AoeRange & AOE_ZONE > 0 && PZone != NULL) - //{ - // ShowInfo("Adding Zone\n"); - // // When checking the entire zone there is no need to check alliance, party, owner, etc. - // for(uint16 i = 0; i < PZone->m_charList.size; i++) // m_charList is private. - // { - // results.push_back((CBattleEntity*)PZone->m_charList[i]); - // } - //} - // TODO: Implement alliances - //else if(AoeRange & AOE_ALLIANCE > 0 && PAlliance != NULL) - //{ - // ShowInfo("Adding Alliance\n"); - // // When checking the alliance there is no need to check party, owner, etc. - // for(uint16 i = 0; i < PAlliance->members.size(); i++) - // { - // results.push_back(PAlliance->members[i]); - // } - //} - /*else*/ if(((AoeRange & AOE_PARTY) > 0) && PParty != NULL) - { - //ShowInfo("Adding Party\n"); - - // When checking the party there is no need to check owner, etc. - for(uint16 i = 0; i < PParty->members.size(); i++) - { - results.push_back(PParty->members[i]); - } - } - else if(m_PBattleTarget->PMaster && m_PBattleTarget->PMaster->objtype == TYPE_PC) - { - //ShowInfo("Adding Owner\n"); - - // When all else fails at least check the master - results.push_back(m_PBattleTarget->PMaster); - } - - // Prune entities that aren't in range/zone/alive/etc - for (std::vector::const_iterator itr = results.begin(); itr != results.end();) - { - CBattleEntity* PTarget = (*itr); - - //ShowInfo("Checking Target: %d %s\n", PTarget->id, PTarget->GetName()); - - if((PTarget->isDead()) || - PTarget == m_PBattleTarget || - PTarget->getZone() != m_PBattleTarget->getZone() || - distance(radiusAround, PTarget->loc.p) > radius) - { - //ShowInfo("Removed"); - itr = results.erase(itr); - } - else - { - itr++; - } - } - - return results; -} Index: src/map/alliance.cpp =================================================================== --- src/map/alliance.cpp (revision 1629) +++ src/map/alliance.cpp (working copy) @@ -22,171 +22,180 @@ */ #include "alliance.h" +#include "../common/showmsg.h" + +#include + +#include "battleentity.h" +#include "charutils.h" +#include "conquest_system.h" +#include "jailutils.h" +#include "map.h" #include "party.h" -#include "charutils.h" +#include "treasure_pool.h" -CAlliance::CAlliance(void) -{ - this->aLeader = NULL; -} +#include "packets/char_sync.h" +#include "packets/char_update.h" +#include "packets/menu_config.h" +#include "packets/party_define.h" +#include "packets/party_member_update.h" -CAlliance::~CAlliance(void) +CAlliance::CAlliance(CBattleEntity* PEntity) { + DSP_DEBUG_BREAK_IF(PEntity->PParty == NULL); + m_AllianceID = PEntity->PParty->GetPartyID(); + + //will need to deal with these + //m_PSyncTarget = NULL; +// m_PQuaterMaster = NULL; + + + addParty(PEntity->PParty); + this->aLeader = PEntity->PParty; + } -int CAlliance::dissolveAlliance(void) + + +void CAlliance::dissolveAlliance(void) { - /* - - //kick all of the parties out - for (int i=0;i<(int)partyList.size();i++) { - partyList[i]->setAlliance(NULL); - //Drops the treasure pool - partyList[i]->dropTreasurePool(); - partyList[i]->rebuildTreasurePool(); - } - //Send the party updates once everyone is removed - for (int i=0;i<(int)partyList.size();i++) { - //Send the removal updates... THERE -HAS- TO BE A BETTER WAY THAN THIS + //first kick out the third party if it exsists + if (this->partyCount() == 3) + this->removeParty(this->partyList.at(2)); - this->unlockAllianceList(); - //Redefine the party removing the alliances - //partyList[i]->getLeader()->insertPacket(CHAR_INPARTY_SELF,CDefinePartyPacket(partyList[i])); + //kick out the second party + this->removeParty(this->partyList.at(1)); - PushPacketList(partyList[i]->getLeader(),CHAR_INPARTY_SELF,CDefinePartyPacket(partyList[i])); - this->lockAllianceList(); + CParty* party = this->partyList.at(0); + this->partyList.clear(); - //Loop through every party - for (int x=0;x<(int)partyList.size();x++) { - // ignoring your own party - if (x != i) { - partyList[i]->lockPartyList(); - //Remove the other parties members from your display - for (int y=0;y<(int)partyList[i]->memberCount();y++) { - partyList[x]->reloadParty(partyList[i]->members[y],true); - } - partyList[i]->unlockPartyList(); - } - } - } - //Empty the alliance - partyList.clear(); - this->unlockAllianceList(); - */ - return 0; + party->m_PAlliance = NULL; + + party->ReloadParty(); + + delete this; } -unsigned int CAlliance::partyCount(void) + +uint32 CAlliance::partyCount(void) { if (!partyList.empty()) return (unsigned int) partyList.size(); return 0; } -int CAlliance::removeParty(CParty * party) +void CAlliance::removeParty(CParty * party) { - /* //Verify that the main party is not being dropped. - if ( party != this->getMainParty() ) { - //Remove the party from the alliance - party->setAlliance(NULL); - //Drop the parties treasure pool - party->dropTreasurePool(); - //Rebuild the treasure pool for the party - party->rebuildTreasurePool(); - //Send the single party definition for everyone in the leaving party - //party->getLeader()->insertPacket(CHAR_INALLIANCE_SELF,CDefinePartyPacket(party)); - PushPacketList(party->getLeader(),CHAR_INALLIANCE_SELF,CDefinePartyPacket(party)); - this->lockAllianceList(); - for (unsigned int x = 0; x < this->partyList.size(); x++) { - //Check to see if the member is the one we are removing - if (party == this->partyList.at(x)) { - //Match found, shift down the inAlliance numbers - for (unsigned int y = (x+1); y < this->partyList.size(); y++) { - //Is this member a valid pointer? - if (this->partyList.at(y) != NULL) { - //Valid party, do a quick refresh of the alliance index - this->partyList.at(y)->inAlliance--; - //Lock the party members list - party->lockPartyList(); - for (unsigned int z = 0; z < party->memberCount(); z++) { - //Remove the old alliance party information from the leaving party - this->partyList[x]->reloadParty(party->members[z], true); - } - //unlock the party members - party->unlockPartyList(); - } - } - //Erase the party out of the party list - this->partyList.erase(this->partyList.begin()+x,this->partyList.begin()+x+1); - //Quickly unlock the list - this->unlockAllianceList(); - //Now that the leaving party is fully removed from the alliance, we can update the remaining parties - //this->getMainParty()->getLeader()->insertPacket(CHAR_INALLIANCE_SELF,CDefinePartyPacket(this->getMainParty())); + if ( party != this->getMainParty() ) + { - PushPacketList(this->getMainParty()->getLeader(),CHAR_INALLIANCE_SELF,CDefinePartyPacket(this->getMainParty())); - //Lock the party list to update the remaining parties - this->lockAllianceList(); - for (unsigned int y = 0; y < this->partyList.size(); y++) { - //Update every party member in the parties that are not being dropped about the removal - this->partyList[y]->lockPartyList(); - for (unsigned int z = 0; z < this->partyList[y]->memberCount(); z++) { - //party is being removed, update partyList[y]->members[z] of the removal - party->reloadParty(this->partyList[y]->members[z],true); - } - this->partyList[y]->unlockPartyList(); - } - break; - } else if (this->partyList[x] != NULL) { - //Update every party member in the party that is being dropped about the removal - party->lockPartyList(); - for (unsigned int z = 0; z < party->memberCount(); z++) { - //Remove the old alliance party information from the leaving party - this->partyList[x]->reloadParty(party->members[z], true); - } - party->unlockPartyList(); + CAlliance* alliance = party->m_PAlliance; + + //delete the party from the alliance list + for (uint32 i = 0; i < party->m_PAlliance->partyList.size(); ++i) + { + if (party == party->m_PAlliance->partyList.at(i)) + party->m_PAlliance->partyList.erase(partyList.begin()+i); + } + + party->m_PAlliance = NULL; + + //update the remaining members of the alliance to show the party left + if (alliance != NULL) + { + for (uint32 i = 0; i < alliance->partyList.size(); ++i) + { + alliance->partyList.at(i)->ReloadParty(); } } - this->unlockAllianceList(); - } - */ - return 0; + + //remove party members from the alliance treasure pool + for (uint32 i = 0; i < party->members.size(); ++i) + { + CCharEntity* PChar = (CCharEntity*)party->members.at(i); + PChar->PTreasurePool->DelMember(PChar); + //PChar->PTreasurePool = NULL; + } + + CCharEntity* PChar = (CCharEntity*)party->GetLeader(); + PChar->PTreasurePool = new CTreasurePool(TREASUREPOOL_PARTY); + PChar->PTreasurePool->AddMember(PChar); + PChar->PTreasurePool->UpdatePool(PChar); + + for (uint32 i = 0; i < party->members.size(); ++i) + { + CCharEntity* PChar = (CCharEntity*)party->members.at(i); + party->ReloadPartyMembers((CCharEntity*)party->members.at(i)); + + if (PChar->PParty->GetLeader() != PChar) + { + //crash is here on disband + PChar->PTreasurePool = ((CCharEntity*)PChar->PParty->GetLeader())->PTreasurePool; + ((CCharEntity*)PChar->PParty->GetLeader())->PTreasurePool->AddMember(PChar); + ((CCharEntity*)PChar->PParty->GetLeader())->PTreasurePool->UpdatePool(PChar); + //PChar->PParty->ReloadTreasurePool(PChar); + } + + } + } + party->ReloadParty(); + // Sql_Query(SqlHandle,"UPDATE accounts_sessions SET partyid = %u WHERE partyid = %u", 0, m_PartyID); } -int CAlliance::addParty(CParty * party) +void CAlliance::addParty(CParty * party) { + party->m_PAlliance = this; + partyList.push_back(party); + /* - if (this->partyCount() < 3) { - this->lockAllianceList(); - partyList.push_back(party); - this->unlockAllianceList(); - party->dropTreasurePool(); - party->setAlliance(this); - party->inAlliance = this->partyCount(); - party->rebuildTreasurePool(); + if (this->partyCount() > 1) + { + //add the new party to the leading party's treasure pool + for (int32 i = 0; i < party->members.size(); ++i) + { + CCharEntity* PChar = (CCharEntity*)party->members.at(i); + PChar->PTreasurePool->DelMember(PChar); + PChar->PTreasurePool = NULL; + + PChar->PTreasurePool = ((CCharEntity*)PChar->PParty->m_PAlliance->getMainParty()->GetLeader())->PTreasurePool; + ((CCharEntity*)PChar->PParty->m_PAlliance->getMainParty()->GetLeader())->PTreasurePool->AddMember(PChar); + ((CCharEntity*)PChar->PParty->m_PAlliance->getMainParty()->GetLeader())->PTreasurePool->UpdatePool(PChar); + PChar->PParty->ReloadTreasurePool(PChar); + } } */ - return 0; + + for (int32 a = 0; a < this->partyList.size(); ++a) + { + this->partyList.at(a)->ReloadParty(); + + for (int32 i = 0; i < this->partyList.at(a)->members.size(); ++i) + { + CCharEntity* PChar = (CCharEntity*)this->partyList.at(a)->members.at(i); + this->partyList.at(a)->ReloadTreasurePool(PChar); + charutils::SaveCharStats(PChar); + } + } + } -CParty * CAlliance::getMainParty(void) + + + + +CParty* CAlliance::getMainParty() { - /* - if (this->aLeader != NULL) - return this->aLeader; - else - */ - return 0; + return aLeader; } //Assigns a party leader for the party -int CAlliance::setMainParty(CParty * aLeader) +void CAlliance::setMainParty(CParty * aLeader) { - /* + //Having no leader is bad so lets check if the pointer is not null. if (aLeader != NULL) { this->aLeader = aLeader; } - */ - return 0; + } \ No newline at end of file Index: src/map/alliance.h =================================================================== --- src/map/alliance.h (revision 1629) +++ src/map/alliance.h (working copy) @@ -28,27 +28,32 @@ #include +class CBasicPacket; +class CBattleEntity; class CCharEntity; class CParty; + //it's assumed here that the alliance leader is the party leader of the lead party. sounds confusing, but it's logical. -class CAlliance +class CAlliance { public: - CAlliance(void); - ~CAlliance(void); - CParty * getMainParty(); - int setMainParty(CParty * aLeader); - int addParty(CParty * party); - int removeParty(CParty * party); - int dissolveAlliance(void); - unsigned int partyCount(void); + CAlliance(CBattleEntity* PEntity); + + uint32 m_AllianceID; + CParty* getMainParty(); + void setMainParty(CParty * aLeader); + void addParty(CParty * party); + void removeParty(CParty * party); + void dissolveAlliance(void); + uint32 partyCount(void); + std::vector partyList; //list of parties in alliance private: - CParty * aLeader; //alliance lead party + CParty* aLeader; //alliance lead party }; #endif Index: src/map/charutils.cpp =================================================================== --- src/map/charutils.cpp (revision 1629) +++ src/map/charutils.cpp (working copy) @@ -34,6 +34,7 @@ #include "lua/luautils.h" +#include "alliance.h" #include "packets/automaton_update.h" #include "packets/char_abilities.h" #include "packets/char_appearance.h" @@ -1971,10 +1972,22 @@ DSP_DEBUG_BREAK_IF(PChar->objtype != TYPE_PC); if (PChar->status == STATUS_NORMAL) PChar->status = STATUS_UPDATE; + if (PChar->PParty != NULL) { - PChar->PParty->PushPacket(PChar, PChar->getZone(), new CCharHealthPacket(PChar)); + if (PChar->PParty->m_PAlliance == NULL) + { + PChar->PParty->PushPacket(PChar, PChar->getZone(), new CCharHealthPacket(PChar)); + + }else if (PChar->PParty->m_PAlliance != NULL) + { + for (int32 i = 0; i < PChar->PParty->m_PAlliance->partyList.size(); ++i) + { + ((CParty*)PChar->PParty->m_PAlliance->partyList.at(i))->PushPacket(PChar, PChar->getZone(), new CCharHealthPacket(PChar)); + } + } } + PChar->pushPacket(new CCharHealthPacket(PChar)); } Index: src/map/enmity_container.cpp =================================================================== --- src/map/enmity_container.cpp (revision 1629) +++ src/map/enmity_container.cpp (working copy) @@ -28,6 +28,7 @@ #include "enmity_container.h" #include "battleutils.h" #include "charentity.h" +#include "alliance.h" /************************************************************************ @@ -140,15 +141,33 @@ if (PChar->PParty != NULL) { - for (uint8 i = 0; i < PChar->PParty->members.size(); ++i) - { - CBattleEntity* PTarget = (CBattleEntity*)PChar->PParty->members[i]; - if (distance(PChar->loc.p, PTarget->loc.p) <= 40) - { - AddBaseEnmity(PTarget); - } - } + if (PChar->PParty->m_PAlliance == NULL) + { + for (uint8 i = 0; i < PChar->PParty->members.size(); ++i) + { + CBattleEntity* PTarget = (CBattleEntity*)PChar->PParty->members[i]; + if (distance(PChar->loc.p, PTarget->loc.p) <= 40) + { + AddBaseEnmity(PTarget); + } + } + }else if (PChar->PParty->m_PAlliance != NULL) + { + for (int32 a = 0; a < PChar->PParty->m_PAlliance->partyList.size(); ++a) + { + for (uint8 i = 0; i < PChar->PParty->m_PAlliance->partyList.at(a)->members.size(); ++i) + { + CBattleEntity* PTarget = (CBattleEntity*)PChar->PParty->m_PAlliance->partyList.at(a)->members[i]; + if (distance(PChar->loc.p, PTarget->loc.p) <= 40) + { + AddBaseEnmity(PTarget); + } + } + } + } + } + } bool CEnmityContainer::HasTargetID(uint16 TargetID){ Index: src/map/lua/lua_baseentity.cpp =================================================================== --- src/map/lua/lua_baseentity.cpp (revision 1629) +++ src/map/lua/lua_baseentity.cpp (working copy) @@ -3315,6 +3315,8 @@ PChar->jobs.unlocked |= (1 << (uint8)lua_tointeger(L,1)); PChar->SetMJob((uint8)lua_tointeger(L,1)); + + charutils::CalculateStats(PChar); charutils::CheckValidEquipment(PChar); charutils::BuildingCharSkillsTable(PChar); @@ -3342,9 +3344,10 @@ return 0; } + /************************************************************************ * * -* GM command @changeJOB !!! FOR DEBUG ONLY !!! * +* GM command @setlevel !!! FOR DEBUG ONLY !!! * * * ************************************************************************/ Index: src/map/lua/luautils.cpp =================================================================== --- src/map/lua/luautils.cpp (revision 1629) +++ src/map/lua/luautils.cpp (working copy) @@ -38,6 +38,7 @@ #include "lua_trade_container.h" #include "lua_zone.h" +#include "../alliance.h" #include "../ability.h" #include "../baseentity.h" #include "../battleentity.h" @@ -1296,34 +1297,73 @@ if (PChar->PParty != NULL) { - for (uint8 i = 0; i < PChar->PParty->members.size(); ++i) - { - if (PChar->PParty->members[i] == PChar || - PChar->PParty->members[i]->getZone() != PChar->getZone()) - continue; + if (PChar->PParty->m_PAlliance == NULL) + { + for (uint8 i = 0; i < PChar->PParty->members.size(); ++i) + { + if (PChar->PParty->members[i] == PChar || + PChar->PParty->members[i]->getZone() != PChar->getZone()) + continue; - ((CCharEntity*)PChar->PParty->members[i])->m_event.reset(); - ((CCharEntity*)PChar->PParty->members[i])->m_event.Target = PMob; - ((CCharEntity*)PChar->PParty->members[i])->m_event.Script.insert(0,File); + ((CCharEntity*)PChar->PParty->members[i])->m_event.reset(); + ((CCharEntity*)PChar->PParty->members[i])->m_event.Target = PMob; + ((CCharEntity*)PChar->PParty->members[i])->m_event.Script.insert(0,File); - lua_getfield(LuaHandle, LUA_GLOBALSINDEX, "onMobDeath"); - if (lua_isnil(LuaHandle,-1)) - { - ShowError("luautils::OnMobDeath: undefined procedure onMobDeath\n"); - return -1; - } - CLuaBaseEntity LuaKillerEntity(PChar->PParty->members[i]); + lua_getfield(LuaHandle, LUA_GLOBALSINDEX, "onMobDeath"); + if (lua_isnil(LuaHandle,-1)) + { + ShowError("luautils::OnMobDeath: undefined procedure onMobDeath\n"); + return -1; + } + CLuaBaseEntity LuaKillerEntity(PChar->PParty->members[i]); - Lunar::push(LuaHandle,&LuaMobEntity); - Lunar::push(LuaHandle,&LuaKillerEntity); + Lunar::push(LuaHandle,&LuaMobEntity); + Lunar::push(LuaHandle,&LuaKillerEntity); - if( lua_pcall(LuaHandle,2,LUA_MULTRET,0) ) - { - ShowError("luautils::OnMobDeath: %s\n",lua_tostring(LuaHandle,-1)); - lua_pop(LuaHandle, 1); - return -1; - } - } + if( lua_pcall(LuaHandle,2,LUA_MULTRET,0) ) + { + ShowError("luautils::OnMobDeath: %s\n",lua_tostring(LuaHandle,-1)); + lua_pop(LuaHandle, 1); + return -1; + } + } + + }else if (PChar->PParty->m_PAlliance != NULL) + { + + for (int32 a = 0; a < PChar->PParty->m_PAlliance->partyList.size(); ++a) + { + for (uint8 i = 0; i < PChar->PParty->m_PAlliance->partyList.at(a)->members.size(); ++i) + { + if (PChar->PParty->m_PAlliance->partyList.at(a)->members.at(i) == PChar || PChar->PParty->m_PAlliance->partyList.at(a)->members.at(i)->getZone() != PChar->getZone()) + continue; + + ((CCharEntity*)PChar->PParty->m_PAlliance->partyList.at(a)->members[i])->m_event.reset(); + ((CCharEntity*)PChar->PParty->m_PAlliance->partyList.at(a)->members[i])->m_event.Target = PMob; + ((CCharEntity*)PChar->PParty->m_PAlliance->partyList.at(a)->members[i])->m_event.Script.insert(0,File); + + lua_getfield(LuaHandle, LUA_GLOBALSINDEX, "onMobDeath"); + if (lua_isnil(LuaHandle,-1)) + { + ShowError("luautils::OnMobDeath: undefined procedure onMobDeath\n"); + return -1; + } + CLuaBaseEntity LuaKillerEntity(PChar->PParty->m_PAlliance->partyList.at(a)->members[i]); + + Lunar::push(LuaHandle,&LuaMobEntity); + Lunar::push(LuaHandle,&LuaKillerEntity); + + if( lua_pcall(LuaHandle,2,LUA_MULTRET,0) ) + { + ShowError("luautils::OnMobDeath: %s\n",lua_tostring(LuaHandle,-1)); + lua_pop(LuaHandle, 1); + return -1; + } + } + } + + + } } return (!lua_isnil(LuaHandle,-1) && lua_isnumber(LuaHandle,-1) ? (int32)lua_tonumber(LuaHandle,-1) : 0); } Index: src/map/mobutils.cpp =================================================================== --- src/map/mobutils.cpp (revision 1629) +++ src/map/mobutils.cpp (working copy) @@ -219,4 +219,7 @@ } } + + + }; // namespace mobutils \ No newline at end of file Index: src/map/mobutils.h =================================================================== --- src/map/mobutils.h (revision 1629) +++ src/map/mobutils.h (working copy) @@ -34,6 +34,7 @@ { void CalculateStats(CMobEntity* PMob); uint16 GetWeaponDamage(CMobEntity* PMob); + uint8 checkMultiHits(CMobEntity * PMob,uint32 mobid); }; #endif \ No newline at end of file Index: src/map/packet_system.cpp =================================================================== --- src/map/packet_system.cpp (revision 1629) +++ src/map/packet_system.cpp (working copy) @@ -33,6 +33,7 @@ #include +#include "alliance.h" #include "packet_system.h" #include "conquest_system.h" #include "battleutils.h" @@ -280,6 +281,8 @@ { PChar->PParty->ReloadParty(); } + + // TODO: в MogHouse TreasurePool сейчас не создается, по этому необходима проверка if (PChar->PTreasurePool != NULL) { @@ -2120,15 +2123,34 @@ if (PInvitee != NULL && !jailutils::InPrison(PInvitee)) { - if (PInvitee->PParty != NULL) + //make sure intvitee isn't dead and that they dont already have an invite pending + if (PInvitee->isDead() || PInvitee->InvitePending.id != 0) { - PChar->pushPacket(new CMessageStandardPacket(PChar, 0, 0, 12)); + PChar->pushPacket(new CMessageStandardPacket(PChar, 0, 0, 23)); return; } - if (PInvitee->isDead() || - PInvitee->InvitePending.id != 0) + + + //check to see if user is adding a party leader for alliance + if (PInvitee->PParty != NULL)// && PChar->Party != NULL { - PChar->pushPacket(new CMessageStandardPacket(PChar, 0, 0, 23)); + if (PInvitee->PParty->GetLeader() == PInvitee) + { + //make sure invitee does not already have alliance + if (PInvitee->PParty->m_PAlliance == NULL) + { + //party is not already in alliance so add them + PInvitee->InvitePending.id = PChar->id; + PInvitee->InvitePending.targid = PChar->targid; + PInvitee->pushPacket(new CPartyInvitePacket(PInvitee, PChar, INVITE_ALLIANCE)); + return; + } + } + } + + if (PInvitee->PParty != NULL) + { + PChar->pushPacket(new CMessageStandardPacket(PChar, 0, 0, 12)); return; } @@ -2154,8 +2176,37 @@ void SmallPacket0x06F(map_session_data_t* session, CCharEntity* PChar, int8* data) { + //alliance - party leader dispands dropping the party from the alliance if (PChar->PParty != NULL) { + if (PChar->PParty->m_PAlliance != NULL) + { + if (PChar->PParty->m_PAlliance->getMainParty() != PChar->PParty) + { + if (PChar->PParty->GetLeader() == PChar) + { + //if there are only 2 parties then dissolve alliance + if (PChar->PParty->m_PAlliance->partyCount() == 2) + { + PChar->PParty->m_PAlliance->dissolveAlliance(); + return; + } + PChar->PParty->m_PAlliance->removeParty(PChar->PParty); + return; + } + + }else if(PChar->PParty->m_PAlliance->getMainParty() == PChar->PParty) + {//alliance leader dissolve alliance + PChar->PParty->m_PAlliance->dissolveAlliance(); + return; + } + } + } + + + //normal party member disband + if (PChar->PParty != NULL) + { PChar->PParty->RemoveMember(PChar); } return; @@ -2238,10 +2289,48 @@ if (InviteAnswer == 0) { + //invitee declined invite PInviter->pushPacket(new CMessageStandardPacket(PInviter, 0, 0, 11)); + PChar->InvitePending.clean(); + return; } - else if (PChar->PParty == NULL) + + //check for alliance invite + if (PChar->PParty != NULL && PInviter->PParty != NULL) { + //both invitee and and inviter are party leaders + if(PInviter->PParty->GetLeader() == PInviter && PChar->PParty->GetLeader() == PChar) + { + + //the inviter already has an alliance and wants to add another party - only add if they have room for another party + if(PInviter->PParty->GetLeader() == PInviter && PInviter->PParty->m_PAlliance != NULL) + { + if(PInviter->PParty->m_PAlliance->getMainParty()->GetLeader() == PInviter) + { + //break if alliance is full + if(PInviter->PParty->m_PAlliance->partyCount() == 3) return; + + + //alliance is not full, add the new party + PInviter->PParty->m_PAlliance->addParty(PChar->PParty); + PChar->InvitePending.clean(); + return; + } + } + + + //party leaders have no alliance - create a new one! + CAlliance* PAlliance = new CAlliance(PInviter); + PInviter->PParty->m_PAlliance->addParty(PChar->PParty); + PChar->InvitePending.clean(); + return; + } + } + + + //the rest is for a standard party invitation + if (PChar->PParty == NULL) + { if (PInviter->PParty == NULL) { CParty* PParty = new CParty(PInviter); @@ -2270,8 +2359,26 @@ void SmallPacket0x076(map_session_data_t* session, CCharEntity* PChar, int8* data) { + //alliance if (PChar->PParty != NULL) { + if (PChar->PParty->m_PAlliance != NULL) + { + for (int32 i = 0; i < PChar->PParty->m_PAlliance->partyList.size(); ++i) + { + + for (int32 a = 0; a < PChar->PParty->m_PAlliance->partyList.at(i)->members.size(); ++a) + { + PChar->PParty->m_PAlliance->partyList.at(i)->ReloadPartyMembers((CCharEntity*)PChar->PParty->m_PAlliance->partyList.at(i)->members.at(a)); + } + } + return; + } + } + + //normal party - no alliance + if (PChar->PParty != NULL) + { PChar->PParty->ReloadPartyMembers(PChar); } return; @@ -2549,8 +2656,18 @@ { if (PChar->PParty != NULL) { - PChar->PParty->PushPacket(PChar, 0, new CChatMessagePacket(PChar, MESSAGE_PARTY, data+6)); - } + if (PChar->PParty->m_PAlliance == NULL) + { + PChar->PParty->PushPacket(PChar, 0, new CChatMessagePacket(PChar, MESSAGE_PARTY, data+6)); + + }else if(PChar->PParty->m_PAlliance != NULL) + { + for (int32 i = 0; i < PChar->PParty->m_PAlliance->partyList.size(); ++i) + { + PChar->PParty->m_PAlliance->partyList.at(i)->PushPacket(PChar, 0, new CChatMessagePacket(PChar, MESSAGE_PARTY, data+6)); + } + } + } } break; case MESSAGE_YELL: PChar->pushPacket(new CMessageStandardPacket(PChar, 0, 256)); break; @@ -2772,8 +2889,33 @@ void SmallPacket0x0D2(map_session_data_t* session, CCharEntity* PChar, int8* data) { + //alliance if (PChar->PParty != NULL) { + if (PChar->PParty->m_PAlliance != NULL) + { + for (int32 a = 0; a < PChar->PParty->m_PAlliance->partyList.size(); ++a) + { + for (int32 i = 0; i < PChar->PParty->m_PAlliance->partyList.at(a)->members.size(); ++i) + { + CCharEntity* PPartyMember = (CCharEntity*)PChar->PParty->m_PAlliance->partyList.at(a)->members.at(i); + + if (PPartyMember->getZone() == PChar->getZone()) + { + PChar->pushPacket(new CPartyMapPacket(PPartyMember)); + } + } + } + + return; + } + } + + + + //normal party - no alliance + if (PChar->PParty != NULL) + { for (int32 i = 0; i < PChar->PParty->members.size(); ++i) { CCharEntity* PPartyMember = (CCharEntity*)PChar->PParty->members.at(i); @@ -3729,7 +3871,7 @@ PacketParser[0x0AD] = &SmallPacket0x0AD; PacketParser[0x0B5] = &SmallPacket0x0B5; PacketParser[0x0B6] = &SmallPacket0x0B6; - PacketParser[0x0BE] = &SmallPacket0xFFF; // not implemented + PacketParser[0x0BE] = &SmallPacket0x0BE; // merit packet PacketParser[0x0C3] = &SmallPacket0x0C3; PacketParser[0x0C4] = &SmallPacket0x0C4; PacketParser[0x0CB] = &SmallPacket0xFFF; // not implemented Index: src/map/packets/party_define.cpp =================================================================== --- src/map/packets/party_define.cpp (revision 1629) +++ src/map/packets/party_define.cpp (working copy) @@ -27,15 +27,48 @@ #include "../charentity.h" #include "../party.h" +#include "../alliance.h" CPartyDefinePacket::CPartyDefinePacket(CParty* PParty) { this->type = 0xC8; this->size = 0x7C; + int nextPosition = 1; + + //party is an alliance do the double loop if (PParty != NULL) { + if (PParty->m_PAlliance!= NULL) + { + CAlliance* ourAlliance = PParty->m_PAlliance; + + for (int32 a = 0; a < ourAlliance->partyList.size(); ++a) + { + + for (int32 i = 0; i < ourAlliance->partyList.at(a)->members.size(); ++i) + { + CBattleEntity* PChar = ourAlliance->partyList.at(a)->members.at(i); + + WBUFL(data,12*nextPosition+(0x08)-4) = PChar->id; + WBUFW(data,12*nextPosition+(0x0C)-4) = PChar->targid; + WBUFW(data,12*nextPosition+(0x0E)-4) = PChar->PParty->GetMemberFlags(PChar); + WBUFB(data,12*nextPosition+(0x10)-4) = PChar->getZone(); + nextPosition++; + } + + } + return; + } + } + + + + + //regular party + if (PParty != NULL) + { DSP_DEBUG_BREAK_IF(PParty->members.size() > 6); for (int32 i = 0; i < PParty->members.size(); ++i) @@ -48,4 +81,7 @@ WBUFB(data,12*i+(0x10)-4) = PChar->getZone(); } } + + + } \ No newline at end of file Index: src/map/packets/party_member_update.cpp =================================================================== --- src/map/packets/party_member_update.cpp (revision 1629) +++ src/map/packets/party_member_update.cpp (working copy) @@ -28,34 +28,40 @@ #include "party_member_update.h" #include "../charentity.h" +#include "../alliance.h" +#include "../party.h" - CPartyMemberUpdatePacket::CPartyMemberUpdatePacket(CCharEntity* PChar, uint8 MemberNumber, uint8 ZoneID) -{ - this->type = 0xDD; - this->size = 0x20; +{ - DSP_DEBUG_BREAK_IF(PChar == NULL); + this->type = 0xDD; + this->size = 0x20; - WBUFL(data,(0x04)-4) = PChar->id; - if (PChar->PParty != NULL) - { - WBUFW(data,(0x14)-4) = PChar->PParty->GetMemberFlags(PChar); - } - if (PChar->getZone() != ZoneID) - { - WBUFB(data,(0x1F)-4) = PChar->getZone(); - } - else - { - WBUFL(data,(0x08)-4) = PChar->health.hp; - WBUFL(data,(0x0C)-4) = PChar->health.mp; - WBUFW(data,(0x10)-4) = PChar->health.tp; - WBUFW(data,(0x18)-4) = PChar->targid; - WBUFB(data,(0x1D)-4) = PChar->GetHPP(); - WBUFB(data,(0x1E)-4) = PChar->GetMPP(); - WBUFB(data,(0x1A)-4) = MemberNumber; - } - memcpy(data+(0x22)-4, PChar->GetName(), PChar->name.size()); -} \ No newline at end of file + DSP_DEBUG_BREAK_IF(PChar == NULL); + + WBUFL(data,(0x04)-4) = PChar->id; + + if (PChar->PParty != NULL) + { + WBUFW(data,(0x14)-4) = PChar->PParty->GetMemberFlags(PChar); + } + if (PChar->getZone() != ZoneID) + { + WBUFB(data,(0x1F)-4) = PChar->getZone(); + } + else + { + WBUFL(data,(0x08)-4) = PChar->health.hp; + WBUFL(data,(0x0C)-4) = PChar->health.mp; + WBUFW(data,(0x10)-4) = PChar->health.tp; + WBUFW(data,(0x18)-4) = PChar->targid; + WBUFB(data,(0x1D)-4) = PChar->GetHPP(); + WBUFB(data,(0x1E)-4) = PChar->GetMPP(); + WBUFB(data,(0x1A)-4) = MemberNumber; + } + memcpy(data+(0x22)-4, PChar->GetName(), PChar->name.size()); + +} + + Index: src/map/packets/party_member_update.h =================================================================== --- src/map/packets/party_member_update.h (revision 1629) +++ src/map/packets/party_member_update.h (working copy) @@ -28,6 +28,7 @@ #include "basic.h" + /************************************************************************ * * * * @@ -35,6 +36,7 @@ ************************************************************************/ class CCharEntity; +class CAlliance; class CPartyMemberUpdatePacket : public CBasicPacket { Index: src/map/party.cpp =================================================================== --- src/map/party.cpp (revision 1629) +++ src/map/party.cpp (working copy) @@ -23,8 +23,9 @@ #include "../common/showmsg.h" +#include #include - +#include "alliance.h" #include "battleentity.h" #include "charutils.h" #include "conquest_system.h" @@ -55,13 +56,16 @@ m_PartyType = PEntity->objtype == TYPE_PC ? PARTY_PCS : PARTY_MOBS; m_PLeader = NULL; + m_PAlliance = NULL; m_PSyncTarget = NULL; m_PQuaterMaster = NULL; + AddMember(PEntity); SetLeader(PEntity); } + /************************************************************************ * * * Распускаем группу * @@ -74,6 +78,7 @@ SetQuaterMaster(NULL); m_PLeader = NULL; + m_PAlliance = NULL; if (m_PartyType == PARTY_PCS) { @@ -281,7 +286,7 @@ { DSP_DEBUG_BREAK_IF(PEntity->objtype != TYPE_PC); - CCharEntity* PChar = (CCharEntity*)PEntity; + CCharEntity* PChar = (CCharEntity*)PEntity; ReloadParty(); ReloadTreasurePool(PChar); @@ -347,6 +352,8 @@ return m_PQuaterMaster; } + + /************************************************************************ * * * Получаем список флагов персонажа * @@ -360,8 +367,22 @@ uint16 Flags = 0; + if (PEntity->PParty->m_PAlliance != NULL) + { + if (PEntity == m_PLeader && PEntity->PParty->m_PAlliance->getMainParty() == PEntity->PParty) + Flags |= ALLIANCE_LEADER; + + if (PEntity->PParty->m_PAlliance->partyList.size() > 1) + if (PEntity->PParty->m_PAlliance->partyList.at(1) == PEntity->PParty) + Flags += PARTY_SECOND; + + if (PEntity->PParty->m_PAlliance->partyList.size() > 2) + if (PEntity->PParty->m_PAlliance->partyList.at(2) == PEntity->PParty) + Flags += PARTY_THIRD; + } + if (PEntity == m_PLeader) Flags |= PARTY_LEADER; - if (PEntity == m_PQuaterMaster) Flags |= PARTY_QM; + if (PEntity == m_PQuaterMaster) Flags |= PARTY_QM; if (PEntity == m_PSyncTarget) Flags |= PARTY_SYNC; return Flags; @@ -375,18 +396,44 @@ void CParty::ReloadParty() { - for (int32 i = 0; i < members.size(); ++i) + + //alliance + if (this->m_PAlliance != NULL) { - CCharEntity* PChar = (CCharEntity*)members.at(i); + CAlliance* ourAlliance = this->m_PAlliance; - PChar->pushPacket(new CPartyDefinePacket(this)); - for (uint8 y = 0; y < members.size(); ++y) - { - PChar->pushPacket(new CPartyMemberUpdatePacket((CCharEntity*)members.at(y), y, PChar->getZone())); - } - } + for (int32 a = 0; a < ourAlliance->partyList.size(); ++a) + { + for (int32 i = 0; i < ourAlliance->partyList.at(a)->members.size(); ++i) + { + CCharEntity* PChar = (CCharEntity*)ourAlliance->partyList.at(a)->members.at(i); + + PChar->pushPacket(new CPartyDefinePacket(ourAlliance->partyList.at(a))); + for (uint8 y = 0; y < ourAlliance->partyList.at(a)->members.size(); ++y) + { + PChar->pushPacket(new CPartyMemberUpdatePacket((CCharEntity*)ourAlliance->partyList.at(a)->members.at(y),y, PChar->getZone())); + } + } + } + return; + } + + + //regular party + for (int32 i = 0; i < members.size(); ++i) + { + CCharEntity* PChar = (CCharEntity*)members.at(i); + + PChar->pushPacket(new CPartyDefinePacket(this)); + for (uint8 y = 0; y < members.size(); ++y) + { + PChar->pushPacket(new CPartyMemberUpdatePacket((CCharEntity*)members.at(y), y, PChar->getZone())); + } + } + } + /************************************************************************ * * * Обновляем статусы членов группы для выбранного персонажа * @@ -396,6 +443,25 @@ void CParty::ReloadPartyMembers(CCharEntity* PChar) { + + if(PChar->PParty != NULL) + { + if(PChar->PParty->m_PAlliance != NULL) + { + CAlliance* ourAlliance = PChar->PParty->m_PAlliance; + + for (int32 a = 0; a < ourAlliance->partyList.size(); ++a) + { + for (int32 i = 0; i < ourAlliance->partyList.at(a)->members.size(); ++i) + { + PChar->pushPacket(new CPartyMemberUpdatePacket((CCharEntity*)ourAlliance->partyList.at(a)->members.at(i), i, PChar->getZone())); + } + } + return; + } + } + + //normal party - no alliance DSP_DEBUG_BREAK_IF(PChar == NULL); DSP_DEBUG_BREAK_IF(PChar->PParty != this); @@ -414,29 +480,66 @@ void CParty::ReloadTreasurePool(CCharEntity* PChar) { DSP_DEBUG_BREAK_IF(PChar == NULL); - DSP_DEBUG_BREAK_IF(PChar->PParty != this); + //cant have this for alliance + //DSP_DEBUG_BREAK_IF(PChar->PParty != this); if (PChar->PTreasurePool != NULL && PChar->PTreasurePool->GetPoolType() == TREASUREPOOL_ZONE) return; - for (uint32 i = 0; i < members.size(); ++i) + + //alliance + if(PChar->PParty != NULL) { - CCharEntity* PPartyMember = (CCharEntity*)members.at(i); + if (PChar->PParty->m_PAlliance != NULL) + { + for (int32 a = 0; a < PChar->PParty->m_PAlliance->partyList.size(); ++a) + { + for (uint32 i = 0; i < PChar->PParty->m_PAlliance->partyList.at(a)->members.size(); ++i) + { + CCharEntity* PPartyMember = (CCharEntity*)PChar->PParty->m_PAlliance->partyList.at(a)->members.at(i); - if (PPartyMember != PChar && - PPartyMember->PTreasurePool != NULL && - PPartyMember->getZone() == PChar->getZone()) - { - if (PChar->PTreasurePool != NULL) - { - PChar->PTreasurePool->DelMember(PChar); + if (PPartyMember != PChar && + PPartyMember->PTreasurePool != NULL && + PPartyMember->getZone() == PChar->getZone()) + { + if (PChar->PTreasurePool != NULL) + { + PChar->PTreasurePool->DelMember(PChar); + } + PChar->PTreasurePool = PPartyMember->PTreasurePool; + PChar->PTreasurePool->AddMember(PChar); + return; + } + } + } - PChar->PTreasurePool = PPartyMember->PTreasurePool; - PChar->PTreasurePool->AddMember(PChar); - return; } } + + //regular party + if (PChar->PParty->m_PAlliance == NULL) + { + for (uint32 i = 0; i < members.size(); ++i) + { + CCharEntity* PPartyMember = (CCharEntity*)members.at(i); + + if (PPartyMember != PChar && + PPartyMember->PTreasurePool != NULL && + PPartyMember->getZone() == PChar->getZone()) + { + if (PChar->PTreasurePool != NULL) + { + PChar->PTreasurePool->DelMember(PChar); + } + PChar->PTreasurePool = PPartyMember->PTreasurePool; + PChar->PTreasurePool->AddMember(PChar); + return; + } + } + } + + if (PChar->PTreasurePool == NULL) { PChar->PTreasurePool = new CTreasurePool(TREASUREPOOL_SOLO); Index: src/map/party.h =================================================================== --- src/map/party.h (revision 1629) +++ src/map/party.h (working copy) @@ -31,6 +31,7 @@ class CBasicPacket; class CBattleEntity; class CCharEntity; +class CAlliance; enum PARTYTYPE { @@ -79,13 +80,18 @@ void AssignPartyRole(int8* MemberName, uint8 role); // назначаем роли участникам группы void PushPacket(CCharEntity* PPartyMember, uint8 ZoneID, CBasicPacket* packet); // отправляем пакет всем членам группы, за исключением PPartyMember + + CAlliance* m_PAlliance; + //int32 m_AlliancePosition; + // ВНИМАНИЕ: НЕ ИЗМЕНЯТЬ ЗНАЧЕНИЯ СПИСКА ВНЕ КЛАССА ГРУППЫ std::vector members; // список участников группы private: + uint32 m_PartyID; // уникальный ID группы PARTYTYPE m_PartyType; // тип существ, составляющих группу @@ -93,6 +99,7 @@ CBattleEntity* m_PSyncTarget; // цель синхронизации уровней CBattleEntity* m_PQuaterMaster; // владелец сокровищ + void SetLeader(CBattleEntity* PEntity); // устанавливаем лидера группы void SetSyncTarget(CBattleEntity* PEntity); // устанавливаем цель синхронизации уровней void SetQuaterMaster(CBattleEntity* PEntity); // устанавливаем владельца сокровищ