diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 96d4c7c2796..12b94461259 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -1177,6 +1177,7 @@ void Battleground::AddOrSetPlayerToCorrectBgGroup(Player* player, uint32 team) { group->ChangeLeader(playerGuid); group->SendUpdate(); + group->SendRaidMarkerUpdateToPlayer(playerGuid); } } } diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index fb54ed06301..4bf1eda4097 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -429,6 +429,7 @@ bool Group::AddMember(Player* player) } SendUpdate(); + SendRaidMarkerUpdateToPlayer(player->GetGUID()); sScriptMgr->OnGroupAddMember(this, player->GetGUID()); if (!IsLeader(player->GetGUID()) && !isBGGroup() && !isBFGroup()) @@ -632,6 +633,8 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R SendUpdate(); + SendRaidMarkerUpdateToPlayer(guid, true); + if (isLFGGroup() && GetMembersCount() == 1) { Player* leader = ObjectAccessor::FindConnectedPlayer(GetLeaderGUID()); @@ -813,7 +816,14 @@ void Group::Disband(bool hideDestroy /* = false */) } _homebindIfInstance(player); + } + + SetGroupMarkerMask(0x20); + SendRaidMarkerUpdate(); + RemoveMarker(); + RemoveAllMarkerFromList(); + RollId.clear(); m_memberSlots.clear(); diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 3911ba207eb..8bbc191c4ed 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -284,6 +284,7 @@ class TC_GAME_API Group // -no description- //void SendInit(WorldSession* session); void SendTargetIconList(WorldSession* session); + void SendRaidMarkerUpdateToPlayer(uint64 playerGUID, bool remove = false); void SendUpdate(); void SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot = NULL); void UpdatePlayerOutOfRange(Player* player); @@ -360,6 +361,7 @@ class TC_GAME_API Group ObjectGuid m_leaderGuid; std::string m_leaderName; GroupType m_groupType; + uint32 m_markerMask; Difficulty m_dungeonDifficulty; Difficulty m_raidDifficulty; Battleground* m_bgGroup; @@ -376,5 +378,8 @@ class TC_GAME_API Group uint32 m_counter; // used only in SMSG_GROUP_LIST uint32 m_maxEnchantingLevel; uint32 m_dbStoreId; // Represents the ID used in database (Can be reused by other groups if group was disbanded) + + typedef std::list DynObjectList; + DynObjectList m_dynObj; }; #endif diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 27e58bc7c0c..a7407ce58f0 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1008,6 +1008,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) { //pCurrChar->groupInfo.group->SendInit(this); // useless group->SendUpdate(); + group->SendRaidMarkerUpdateToPlayer(playerGuid); group->ResetMaxEnchantingLevel(); } diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index 6c6d7c1d184..154f5f1091e 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -366,7 +366,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) caster = _player; } - if (caster->GetTypeId() == TYPEID_PLAYER && !caster->ToPlayer()->HasActiveSpell(spellInfo->Id)) + if (caster->GetTypeId() == TYPEID_PLAYER && !caster->ToPlayer()->HasActiveSpell(spellInfo->Id) && !spellInfo->IsRaidMarker()) { // not have spell in spellbook recvPacket.rfinish(); // prevent spam at ignore packet diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 2d6cc4655e3..25c106afd61 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -281,6 +281,8 @@ class TC_GAME_API Spell void EffectHealMaxHealth(SpellEffIndex effIndex); void EffectInterruptCast(SpellEffIndex effIndex); void EffectSummonObjectWild(SpellEffIndex effIndex); + void EffectSummonRaidMarker(SpellEffIndex effIndex); + void EffectSummonDynObj(SpellEffIndex effIndex); void EffectScriptEffect(SpellEffIndex effIndex); void EffectSanctuary(SpellEffIndex effIndex); void EffectAddComboPoints(SpellEffIndex effIndex); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 7e8f46a7d3a..6b39e1eae96 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -166,7 +166,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectReputation, //103 SPELL_EFFECT_REPUTATION &Spell::EffectSummonObject, //104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1 &Spell::EffectSummonObject, //105 SPELL_EFFECT_SUMMON_OBJECT_SLOT2 - &Spell::EffectSummonObject, //106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3 + &Spell::EffectSummonRaidMarker, //106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3 &Spell::EffectSummonObject, //107 SPELL_EFFECT_SUMMON_OBJECT_SLOT4 &Spell::EffectDispelMechanic, //108 SPELL_EFFECT_DISPEL_MECHANIC &Spell::EffectResurrectPet, //109 SPELL_EFFECT_RESURRECT_PET @@ -4178,6 +4178,58 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex) m_caster->m_ObjectSlot[slot] = go->GetGUID(); } +void Spell::EffectSummonDynObj(SpellEffIndex effIndex) +{ + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + + Player* player = m_caster->ToPlayer(); + if (!player) + return; + + float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); + DynamicObject* dynObj = new DynamicObject(false); + if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo, *destTarget, radius, DYNAMIC_OBJECT_RAID_MARKER)) + { + delete dynObj; + return; + } + + int32 duration = m_spellInfo->GetDuration(); + dynObj->SetDuration(duration); +} + +void Spell::EffectSummonRaidMarker(SpellEffIndex effIndex) +{ + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + + Player* player = m_caster->ToPlayer(); + if (!player) + return; + + Group* group = player->GetGroup(); + if (!group) + return; + + uint32 slotMask = 1 << m_spellInfo->Effects[effIndex].BasePoints; + + float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); + DynamicObject* dynObj = new DynamicObject(false); + if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo, *destTarget, radius, DYNAMIC_OBJECT_RAID_MARKER)) + { + delete dynObj; + return; + } + + group->AddMarkerToList(dynObj->GetGUID()); + group->AddGroupMarkerMask(slotMask); + group->SendRaidMarkerUpdate(); + + int32 duration = m_spellInfo->GetDuration(); + dynObj->SetDuration(duration); +} + void Spell::EffectResurrect(SpellEffIndex effIndex) { if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index ef44fbf8d8a..5a6545d6752 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1225,6 +1225,11 @@ bool SpellInfo::IsPassive() const return HasAttribute(SPELL_ATTR0_PASSIVE); } +bool SpellInfo::IsRaidMarker() const +{ + return AttributesEx8 & SPELL_ATTR8_RAID_MARKER; +} + bool SpellInfo::IsAutocastable() const { if (IsPassive()) diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 3ca73cf11f6..9f8859fa97d 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -471,6 +471,7 @@ public: bool NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) const; bool IsPassive() const; + bool IsRaidMarker() const; bool IsAutocastable() const; bool IsStackableWithRanks() const; bool IsPassiveStackableWithRanks() const;