Index: Group.cpp =================================================================== --- Group.cpp (revision 5259) +++ Group.cpp (working copy) @@ -1050,6 +1068,29 @@ return true; } +bool Group::IsInCombatRange(Player* who) +{ + CombatMapItr itr, next; + itr = next = m_inCombat.begin(); + for ( ; itr != m_inCombat.end(); itr = next) + { + next++; + Player* combatant = ObjectAccessor::Instance().GetPlayer(*who, itr->first); + if (!combatant) + { + m_inCombat.erase(itr); + next = m_inCombat.begin(); + continue; + } + if (who->GetMapId() != combatant->GetMapId()) + continue; + + if ( who->GetDistance2d(combatant) <= INCOMBAT_RANGE) + return true; + } + return false; +} + bool Group::_setAssistantFlag(const uint64 &guid, const bool &state) { member_witerator slot = _getMemberWSlot(guid); Index: Group.h =================================================================== --- Group.h (revision 5259) +++ Group.h (working copy) @@ -26,9 +26,10 @@ #include #include -#define MAXGROUPSIZE 5 -#define MAXRAIDSIZE 40 +#define MAXGROUPSIZE 5 +#define MAXRAIDSIZE 40 #define TARGETICONCOUNT 8 +#define INCOMBAT_RANGE 200 enum RollVote { @@ -101,6 +109,9 @@ //0, 1, 2, 3, 4, 5, 6, 7, 8, 9 static const uint8 GroupUpdateLength[GROUP_UPDATE_FLAGS_COUNT] = { 0, 1, 2, 2, 1, 2, 2, 2, 2, 4}; +typedef std::map CombatMap; +typedef CombatMap::iterator CombatMapItr; + class Roll : public LootValidatorRef { public: @@ -202,6 +213,10 @@ bool SameSubGroup(Player *member1, Player *member2) const; + bool IsInCombat() const { return !m_inCombat.empty(); } + + bool IsInCombatRange(Player* who); + MemberSlotList const& GetMemberSlots() const { return m_memberSlots; } GroupReference* GetFirstMember() { return m_memberMgr.getFirst(); } uint32 GetMembersCount() const { return m_memberSlots.size(); } @@ -251,7 +266,29 @@ SendUpdate(); } + void AddInCombat(const uint64& guid) + { + if (m_inCombat.find(guid) == m_inCombat.end()) + m_inCombat[guid] = 1; + else + m_inCombat[guid]++; + } + + void RemoveInCombat(const uint64& guid) + { + if (m_inCombat.find(guid) != m_inCombat.end()) + { + if (--m_inCombat[guid] == 0) + m_inCombat.erase(guid); + } + } + void SetTargetIcon(uint8 id, uint64 guid); // -no description- //void SendInit(WorldSession *session); @@ -332,11 +369,13 @@ uint64 m_mainTank; uint64 m_mainAssistant; GroupType m_groupType; BattleGround* m_bgGroup; uint64 m_targetIcons[TARGETICONCOUNT]; LootMethod m_lootMethod; ItemQualities m_lootThreshold; uint64 m_looterGuid; Rolls RollId; + CombatMap m_inCombat; ///< Members which are in combat }; #endif Index: Player.cpp =================================================================== --- Player.cpp (revision 5259) +++ Player.cpp (working copy) @@ -239,6 +238,7 @@ m_lastKillDate = 0; m_flushKills = false; m_saveKills = false; + m_groupCombatTimer = 1500; // Player summoning m_summon_expire = 0; @@ -902,6 +902,19 @@ { // Leave here so we don't forget this case // Not attacking or attacked + if (m_groupCombatTimer < p_time) + { + if (GetGroup() && isAlive()) + { + if (GetGroup()->IsInCombat() && GetGroup()->IsInCombatRange(this)) + SetInCombat(); + else + ClearInCombat(); + } + m_groupCombatTimer = 1500; + } + else + m_groupCombatTimer -= p_time; } if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) Index: Player.h =================================================================== --- Player.h (revision 5259) +++ Player.h (working copy) @@ -980,7 +980,23 @@ void Yell(const std::string text, const uint32 language); void TextEmote(const std::string text); void Whisper(const uint64 receiver, const std::string text, const uint32 language); + + virtual void _addAttacker(Unit *pAttacker) // must be called only from Unit::Attack(Unit*) + { + if (GetGroup() && pAttacker->GetTypeId() == TYPEID_UNIT) + GetGroup()->AddInCombat(GetGUID()); + Unit::_addAttacker(pAttacker); + } + + virtual void _removeAttacker(Unit *pAttacker) // must be called only from Unit::AttackStop() + { + if (GetGroup() && pAttacker->GetTypeId() == TYPEID_UNIT) + GetGroup()->RemoveInCombat(GetGUID()); + + Unit::_removeAttacker(pAttacker); + } + /*********************************************************/ /*** STORAGE SYSTEM ***/ /*********************************************************/ @@ -2032,6 +2056,8 @@ uint32 m_WeaponProficiency; uint32 m_ArmorProficiency; + + uint32 m_groupCombatTimer; bool m_canParry; bool m_canDualWield; float m_ammoDPS;