/// Spell Target Handling for type 37: all Members of the targets party void Spell::SpellTargetPartyMember(uint32 i, uint32 j) { if(!m_caster->IsInWorld()) return; TargetsList* tmpMap=&m_targetUnits[i]; // if no group target self Player * Target = m_caster->GetMapMgr()->GetPlayer((uint32)m_targets.m_unitTarget); if(!Target) return; SubGroup * subgroup = Target->GetGroup() ? Target->GetGroup()->GetSubGroup(Target->GetSubGroup()) : 0; float rsqr = GetRadius( i ); if( rsqr == 0 ) rsqr = 40*40;//kinda like a bug. 0 range to target a party member ? Highly impossible else rsqr *= rsqr; if(subgroup) { Target->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = subgroup->GetGroupMembersBegin(); itr != subgroup->GetGroupMembersEnd(); ++itr) //if you are picky you could also check if on same map. Let's face it you won't similar positions on different maps if((*itr)->m_loggedInPlayer && IsInrange(Target,(*itr)->m_loggedInPlayer, rsqr) ) SafeAddTarget(tmpMap,(*itr)->m_loggedInPlayer->GetGUID()); Target->GetGroup()->Unlock(); } else { SafeAddTarget(tmpMap,Target->GetGUID()); } }
// Spell Target Handling for type 37: all Members of the targets party void Spell::SpellTargetPartyMember(uint32 i, uint32 j) { if(!m_caster->IsInWorld()) return; // if no group target self Player* Target = m_caster->GetMapMgr()->GetPlayer((uint32)m_targets.m_unitTarget); if(!Target) return; SubGroup * subgroup = Target->GetGroup() ? Target->GetGroup()->GetSubGroup(Target->GetSubGroup()) : 0; if(subgroup) { Target->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = subgroup->GetGroupMembersBegin(); itr != subgroup->GetGroupMembersEnd(); itr++) { if((*itr)->m_loggedInPlayer) _AddTargetForced( (*itr)->m_loggedInPlayer->GetGUID(), i ); } Target->GetGroup()->Unlock(); } else _AddTargetForced(Target->GetGUID(), i); }
bool Group::AddMember(Player* pPlayer) { if(!IsFull()) { SubGroup* subgroup = FindFreeSubGroup(); if(subgroup == NULL) { // weird shit.. sLog.outDebug("GROUP: Tried to add member %s but FindFreeSubGroup returned NULL!", pPlayer->GetName()); return false; } subgroup->AddPlayer(pPlayer); pPlayer->SetGroup(this); if(m_MemberCount == 1) { // We're the only member? Set us to the leader. SetLeader(pPlayer); } UpdateAllOutOfRangePlayersFor(pPlayer); Update(); // Send group update return true; } else { return false; } }
void Group::Disband() { m_groupLock.Acquire(); m_updateblock = true; if(m_isqueued) { m_isqueued=false; WorldPacket * data = sChatHandler.FillSystemMessageData("A change was made to your group. Removing the arena queue."); SendPacketToAll(data); delete data; BattlegroundManager.RemoveGroupFromQueues(this); } uint32 i = 0; for(i = 0; i < m_SubGroupCount; i++) { SubGroup *sg = m_SubGroups[i]; sg->Disband(); } m_groupLock.Release(); CharacterDatabase.Execute("DELETE FROM groups WHERE group_id = %u", m_Id); sInstanceMgr.OnGroupDestruction(this); delete this; // destroy ourselves, the destructor removes from eventmgr and objectmgr. }
// Spell Target Handling for type 56: Target all raid members. (WotLK) void Spell::SpellTargetAllRaid( uint32 i, uint32 j ) { if( !m_caster->IsInWorld() || !m_caster->IsUnit() ) return; TargetsList* tmpMap = &m_targetUnits[i]; SafeAddTarget( tmpMap, m_caster->GetGUID() ); Group * group = static_cast< Unit* >( m_caster )->GetGroup(); if( group == NULL ) return; uint32 count = group->GetSubGroupCount(); // Loop through each raid group. group->Lock(); for( uint8 k = 0; k < count; k++ ) { SubGroup * subgroup = group->GetSubGroup( k ); if( subgroup ) { for( GroupMembersSet::iterator itr = subgroup->GetGroupMembersBegin(); itr != subgroup->GetGroupMembersEnd(); ++itr ) { if( (*itr)->m_loggedInPlayer && (*itr)->m_loggedInPlayer != m_caster) SafeAddTarget( tmpMap,(*itr)->m_loggedInPlayer->GetGUID() ); } } } group->Unlock(); }
/// Spell Target Handling for type 61: targets with the same group/raid and the same class void Spell::SpellTargetSameGroupSameClass(uint32 i, uint32 j) { TargetsList* tmpMap=&m_targetUnits[i]; if(!m_caster->IsInWorld()) return; Player * Target = m_caster->GetMapMgr()->GetPlayer((uint32)m_targets.m_unitTarget); if(!Target) return; SubGroup * subgroup = Target->GetGroup() ? Target->GetGroup()->GetSubGroup(Target->GetSubGroup()) : 0; if(subgroup) { Target->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = subgroup->GetGroupMembersBegin(); itr != subgroup->GetGroupMembersEnd(); ++itr) { if(!(*itr)->m_loggedInPlayer || Target->getClass() != (*itr)->m_loggedInPlayer->getClass()) continue; SafeAddTarget(tmpMap,(*itr)->m_loggedInPlayer->GetGUID()); } Target->GetGroup()->Unlock(); } }
bool Group::AddMember(PlayerInfo * info, int32 subgroupid/* =-1 */) { m_groupLock.Acquire(); Player * pPlayer = info->m_loggedInPlayer; if( m_isqueued ) { m_isqueued = false; BattlegroundManager.RemoveGroupFromQueues(this); } if( !IsFull() ) { SubGroup* subgroup = (subgroupid>0) ? m_SubGroups[subgroupid] : FindFreeSubGroup(); if(subgroup == NULL) { m_groupLock.Release(); return false; } if( subgroup->AddPlayer( info ) ) { if( pPlayer != NULL ) sEventMgr.AddEvent( pPlayer,&Player::EventGroupFullUpdate, EVENT_PLAYER_UPDATE, 1500, 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT ); if( info->m_Group && info->m_Group != this ) info->m_Group->RemovePlayer( info ); if( m_Leader == NULL && info->m_loggedInPlayer ) m_Leader = info; info->m_Group = this; info->subGroup = (int8)subgroup->GetID(); ++m_MemberCount; m_dirty = true; Update(); // Send group update m_groupLock.Release(); return true; } else { m_groupLock.Release(); info->m_Group = NULL; info->subGroup = -1; return false; } } else { info->m_Group = NULL; info->subGroup = -1; m_groupLock.Release(); return false; } }
void Group::SendLootUpdates( Object *o ){ // Build the actual update. ByteBuffer buf( 500 ); uint32 Flags = o->GetUInt32Value( UNIT_DYNAMIC_FLAGS ); Flags |= U_DYN_FLAG_LOOTABLE; Flags |= U_DYN_FLAG_TAPPED_BY_PLAYER; o->BuildFieldUpdatePacket( &buf, UNIT_DYNAMIC_FLAGS, Flags ); Lock(); switch( m_LootMethod ){ case PARTY_LOOT_RR: case PARTY_LOOT_FFA: case PARTY_LOOT_GROUP: case PARTY_LOOT_NBG:{ SubGroup *sGrp = NULL; GroupMembersSet::iterator itr2; for( uint32 Index = 0; Index < GetSubGroupCount(); ++Index ){ sGrp = GetSubGroup( Index ); itr2 = sGrp->GetGroupMembersBegin(); for( ; itr2 != sGrp->GetGroupMembersEnd(); ++itr2 ){ PlayerInfo *p = *itr2; if( p->m_loggedInPlayer != NULL && p->m_loggedInPlayer->IsVisible( o->GetGUID() ) ) // Save updates for non-existent creatures p->m_loggedInPlayer->PushUpdateData( &buf, 1 ); } } break;} case PARTY_LOOT_MASTER:{ Player * pLooter = GetLooter() ? GetLooter()->m_loggedInPlayer : NULL; if( pLooter == NULL ) pLooter = GetLeader()->m_loggedInPlayer; if( pLooter->IsVisible( o->GetGUID() ) ){ Unit *victim = static_cast< Unit* >( o ); victim->Tag( pLooter->GetGUID() ); pLooter->PushUpdateData( &buf, 1 ); } break;} } Unlock(); }
void Group::Disband() { uint32 i = 0; for(i = 0; i < m_SubGroupCount; i++) { SubGroup *sg = m_SubGroups[i]; sg->Disband(true); } delete this; // destroy ourselves, the destructor removes from eventmgr and objectmgr. }
void WorldSession::HandleLootOpcode( WorldPacket & recv_data ) { if(!_player->IsInWorld()) return; uint64 guid; recv_data >> guid; if(_player->isCasting()) _player->InterruptSpell(); if(_player->InGroup() && !_player->m_bgInBattleground) { Group * party = _player->GetGroup(); if(party) { if(party->GetMethod() == PARTY_LOOT_MASTER) { WorldPacket data(SMSG_LOOT_MASTER_LIST, 330); // wont be any larger data << (uint8)party->MemberCount(); uint32 real_count = 0; SubGroup *s; GroupMembersSet::iterator itr; for(uint32 i = 0; i < party->GetSubGroupCount(); ++i) { s = party->GetSubGroup(i); for(itr = s->GetGroupMembersBegin(); itr != s->GetGroupMembersEnd(); ++itr) { if(_player->GetZoneId() == (*itr)->GetZoneId()) { data << (*itr)->GetGUID(); ++real_count; } } } *(uint8*)&data.contents()[0] = real_count; party->SendPacketToAll(&data); } /* //this commented code is not used because it was never tested and finished ! else if(party->GetMethod() == PARTY_LOOT_RR) { Creature *target=GetPlayer()->GetMapMgr()->GetCreature(guid); //maybe we should extend this to other object types too if(target) { if(target->TaggerGuid==GetPlayer()->GetGUID()) GetPlayer()->SendLoot(guid,1); else return; } }*/ } } GetPlayer()->SendLoot(guid,1); }
void Group::MovePlayer(Player *pPlayer, uint8 subgroup) { ASSERT(subgroup < m_SubGroupCount); SubGroup *sgr = GetSubGroup(pPlayer->GetSubGroup()); sgr->RemovePlayer(pPlayer); // Grab the new group, and insert sgr = m_SubGroups[subgroup]; sgr->AddPlayer(pPlayer); Update(); }
void Group::MovePlayer(PlayerInfo *info, uint8 subgroup) { if( subgroup >= m_SubGroupCount ) return; if( m_SubGroups[subgroup]->IsFull() ) return; m_groupLock.Acquire(); SubGroup *sg = NULL; if( info->subGroup > 0 && info->subGroup <= 8 ) sg = m_SubGroups[info->subGroup]; if( sg == NULL || sg->m_GroupMembers.find(info) == sg->m_GroupMembers.end() ) { for( uint8 i = 0; i < m_SubGroupCount; ++i ) { if( m_SubGroups[i] != NULL ) { if( m_SubGroups[i]->m_GroupMembers.find(info) != m_SubGroups[i]->m_GroupMembers.end() ) { sg = m_SubGroups[i]; break; } } } } if( sg == NULL ) { m_groupLock.Release(); return; } sg->RemovePlayer( info ); // Grab the new group, and insert sg = m_SubGroups[subgroup]; if( !sg->AddPlayer( info ) ) { RemovePlayer( info ); } else { info->subGroup = (int8)sg->GetID(); } Update(); m_groupLock.Release(); }
void Group::SetSubGroupLeader(Player *pPlayer, uint8 subgroup) { sLog.outString("Set subgroup %d leader to %s", (uint32)subgroup, pPlayer->GetName()); ASSERT(subgroup < m_SubGroupCount); SubGroup *group = m_SubGroups[subgroup]; if(group->GetID() != pPlayer->GetSubGroup()) { sLog.outString("GROUP: Tried to set leader of subgroup %d and player %s is not in that group", group->GetID(), pPlayer->GetName()); return; } group->m_SubGroupLeader = pPlayer; Update(); }
void Group::SendPacketToAllInRange(Player* plr, WorldPacket* packet) { Lock(); for(uint8 i = 0; i < GetSubGroupCount(); ++i) { SubGroup* sg = GetSubGroup(i); for(GroupMembersSet::iterator itr = sg->GetGroupMembersBegin(); itr != sg->GetGroupMembersEnd(); ++itr) { if((*itr)->m_loggedInPlayer && (*itr)->m_loggedInPlayer->GetDistance2dSq(plr) < 80.0f) (*itr)->m_loggedInPlayer->GetSession()->SendPacket(packet); } } Unlock(); }
void GenericBattleground::OnKillPlayer(Player * pPlayer, Player * pVictim) { if( pPlayer == NULL || pVictim == NULL || pPlayer != pVictim ) return; Group * pGroup = pPlayer->GetGroup(); if( pGroup == NULL ) { pPlayer->BroadcastMessage("You've been awarded 10 gold for slaying %s", pVictim->GetName()); pPlayer->ModUnsigned32Value(PLAYER_FIELD_COINAGE, 100000); } else { std::vector<Player*> GroupMembers; std::set<Player*> PotentialHealers; pPlayer->GetGroup()->Lock(); for(uint8 i = 0; i < pPlayer->GetGroup()->GetSubGroupCount(); i++) { SubGroup * pSubGroup = pPlayer->GetGroup()->GetSubGroup(i); if(!pSubGroup) continue; GroupMembersSet::iterator itr = pSubGroup->GetGroupMembersBegin(); for(; itr != pSubGroup->GetGroupMembersEnd(); itr++) { PlayerInfo * pi = *itr; if(!pi) continue; Player * tPlr = pi->m_loggedInPlayer; if(!tPlr) continue; // Ineligible due to distance. if(tPlr->GetDistance2dSq(pPlayer) > 80.0f && tPlr != pPlayer) continue; GroupMembers.push_back(pi->m_loggedInPlayer); } } // Pick a number, any number! if(GroupMembers.size() > 0) { uint32 reward = RandomUInt(GroupMembers.size() - 1); GroupMembers[reward]->ModUnsigned32Value(PLAYER_FIELD_COINAGE, 100000); GroupMembers[reward]->BroadcastMessage("You've been awarded 10 gold for slaying %s.", pVictim->GetName()); } pPlayer->GetGroup()->Unlock(); } }
/// Spell Target Handling for type 18: All Party Members around the Caster in given range NOT RAID void Spell::SpellTargetAllPartyMembersRangeNR(uint32 i, uint32 j) { TargetsList* tmpMap = &m_targetUnits[i]; Player* p = p_caster; if( p == NULL ) { if( static_cast< Creature* >( u_caster)->IsTotem() ) p = static_cast< Player* >( static_cast< Creature* >( u_caster )->GetTotemOwner() ); else if( u_caster->IsPet() && static_cast< Pet* >( u_caster )->GetPetOwner() ) p = static_cast< Pet* >( u_caster )->GetPetOwner(); else if( u_caster->GetUInt64Value( UNIT_FIELD_CREATEDBY ) ) { Unit *t = u_caster->GetMapMgr()->GetUnit( u_caster->GetUInt64Value( UNIT_FIELD_CREATEDBY ) ); if ( t && t->IsPlayer() ) p = static_cast< Player* >( t ); } } if( p == NULL ) return; float r = GetRadius(i); r *= r; if( IsInrange( m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(), p, r ) ) SafeAddTarget( tmpMap, p->GetGUID() ); SubGroup* subgroup = p->GetGroup() ? p->GetGroup()->GetSubGroup( p->GetSubGroup() ) : 0; if( subgroup != NULL ) { p->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = subgroup->GetGroupMembersBegin(); itr != subgroup->GetGroupMembersEnd(); ++itr) { if(!(*itr)->m_loggedInPlayer || m_caster == (*itr)->m_loggedInPlayer) continue; if(IsInrange(m_caster->GetPositionX(),m_caster->GetPositionY(),m_caster->GetPositionZ(),(*itr)->m_loggedInPlayer,r)) SafeAddTarget(tmpMap,(*itr)->m_loggedInPlayer->GetGUID()); } p->GetGroup()->Unlock(); } }
void Group::UpdateAchievementCriteriaForInrange( Object *o, AchievementCriteriaTypes type, int32 miscvalue1, int32 miscvalue2, uint32 time ){ Lock(); SubGroup *sGrp = NULL; GroupMembersSet::iterator itr2; for( uint32 Index = 0; Index < GetSubGroupCount(); ++Index ){ sGrp = GetSubGroup( Index ); itr2 = sGrp->GetGroupMembersBegin(); for( ; itr2 != sGrp->GetGroupMembersEnd(); ++itr2 ){ PlayerInfo *p = *itr2; if( p->m_loggedInPlayer != NULL && p->m_loggedInPlayer->IsVisible( o->GetGUID() ) ) p->m_loggedInPlayer->GetAchievementMgr().UpdateAchievementCriteria( type, miscvalue1, miscvalue2, time ); } } Unlock(); }
/// Spell Target Handling for type 33: Party members of totem, inside given range void Spell::SpellTargetNearbyPartyMembers(uint32 i, uint32 j) { TargetsList* tmpMap=&m_targetUnits[i]; // this implementation is wrong.... this one is for totems if( u_caster != NULL ) { if( u_caster->GetTypeId()==TYPEID_UNIT) { if( static_cast< Creature* >( u_caster )->IsTotem() ) { float r = GetRadius(i); r *= r; Player* p = static_cast< Player* >( static_cast< Creature* >( u_caster )->GetTotemOwner() ); if( p == NULL) return; if(IsInrange(m_caster->GetPositionX(),m_caster->GetPositionY(),m_caster->GetPositionZ(),p,r)) SafeAddTarget(tmpMap,p->GetGUID()); SubGroup * pGroup = p->GetGroup() ? p->GetGroup()->GetSubGroup(p->GetSubGroup()) : 0; if(pGroup) { p->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = pGroup->GetGroupMembersBegin(); itr != pGroup->GetGroupMembersEnd(); ++itr) { if(!(*itr)->m_loggedInPlayer || p == (*itr)->m_loggedInPlayer) continue; if(IsInrange(m_caster->GetPositionX(),m_caster->GetPositionY(),m_caster->GetPositionZ(),(*itr)->m_loggedInPlayer,r)) SafeAddTarget(tmpMap,(*itr)->m_loggedInPlayer->GetGUID()); } p->GetGroup()->Unlock(); } } } } }
/// Spell Target Handling for type 33: Party members of totem, inside given range void Spell::SpellTargetNearbyPartyMembers(uint32 i, uint32 j) { // this implementation is wrong.... this one is for totems if( u_caster != NULL ) { if( u_caster->GetTypeId()==TYPEID_UNIT) { if( TO_CREATURE( u_caster )->IsTotem() ) { float r = GetDBCCastTime(i); r *= r; Player* p = TO_PLAYER( TO_CREATURE(u_caster)->GetSummonOwner()); if( p == NULL) return; if(IsInrange(m_caster->GetPositionX(),m_caster->GetPositionY(),m_caster->GetPositionZ(),p,r)) _AddTargetForced(p->GetGUID(), i); SubGroup * pGroup = p->GetGroup() ? p->GetGroup()->GetSubGroup(p->GetSubGroup()) : 0; if(pGroup) { p->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = pGroup->GetGroupMembersBegin(); itr != pGroup->GetGroupMembersEnd(); itr++) { if(!(*itr)->m_loggedInPlayer || p == (*itr)->m_loggedInPlayer) continue; if(IsInrange(m_caster->GetPositionX(),m_caster->GetPositionY(),m_caster->GetPositionZ(),(*itr)->m_loggedInPlayer,r)) _AddTargetForced((*itr)->m_loggedInPlayer->GetGUID(), i); } p->GetGroup()->Unlock(); } } } } }
void Group::RemovePlayer(Player* pPlayer) { WorldPacket data; SubGroup *sg = GetSubGroup(pPlayer->GetSubGroup()); ASSERT(sg); // something wrong here if that isn't right sg->RemovePlayer(pPlayer); pPlayer->SetGroup(NULL); if(pPlayer->GetSession() != NULL) { SendNullUpdate(pPlayer); //pPlayer->RemoveAllAreaAuras(); data.SetOpcode(SMSG_GROUP_DESTROYED); pPlayer->GetSession()->SendPacket(&data); data.Initialize(SMSG_PARTY_COMMAND_RESULT); data << uint32(2) << uint8(0) << uint32(0); // you leave the group pPlayer->GetSession()->SendPacket(&data); } if(m_MemberCount < 2) { Disband(); return; } Player *newPlayer = FindFirstPlayer(); if(m_Looter == pPlayer) m_Looter = newPlayer; if(m_Leader == pPlayer) SetLeader(newPlayer); else Update(); }
/// Spell Target Handling for type 18: All Party Members around the Caster in given range NOT RAID void Spell::SpellTargetAllPartyMembersRangeNR(uint32 i, uint32 j) { Player* p = p_caster; if( p == NULL ) { if( TO_CREATURE( u_caster)->IsTotem() ) p = TO_PLAYER( TO_CREATURE(u_caster)->GetSummonOwner()); else if( u_caster->IsPet() && TO_PET( u_caster )->GetPetOwner() ) p = TO_PET( u_caster )->GetPetOwner(); } if( p == NULL ) return; float r = GetDBCCastTime(i); r *= r; if( IsInrange( m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(), p, r ) ) _AddTargetForced(p->GetGUID(), i); SubGroup* subgroup = p->GetGroup() ? p->GetGroup()->GetSubGroup( p->GetSubGroup() ) : 0; if( subgroup != NULL ) { p->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = subgroup->GetGroupMembersBegin(); itr != subgroup->GetGroupMembersEnd(); itr++) { if(!(*itr)->m_loggedInPlayer || m_caster == (*itr)->m_loggedInPlayer) continue; if(IsInrange(m_caster->GetPositionX(),m_caster->GetPositionY(),m_caster->GetPositionZ(),(*itr)->m_loggedInPlayer,r)) _AddTargetForced( (*itr)->m_loggedInPlayer->GetGUID(), i ); } p->GetGroup()->Unlock(); } }
void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data, 9); WorldPacket *data; if(!_player->IsInWorld()) return; uint32 type; int32 lang; const char * pMisc = 0; const char * pMsg = 0; recv_data >> type; recv_data >> lang; if( lang >= NUM_LANGUAGES ) return; if(GetPlayer()->IsBanned()) { GetPlayer()->BroadcastMessage("You cannot do that when banned."); return; } if(lang != -1 && !GetPermissionCount() && sWorld.flood_lines) { /* flood detection, wheeee! */ if(UNIXTIME >= floodTime) { floodLines = 0; floodTime = UNIXTIME + sWorld.flood_seconds; } if((++floodLines) > sWorld.flood_lines) { if(sWorld.flood_message) _player->BroadcastMessage("Your message has triggered serverside flood protection. You can speak again in %u seconds.", floodTime - UNIXTIME); return; } } std::stringstream irctext; irctext.rdbuf()->str(""); std::string msg; msg.reserve(256); //arghhh STFU. I'm not giving you gold or items NOOB switch(type) { case CHAT_MSG_EMOTE: case CHAT_MSG_SAY: case CHAT_MSG_YELL: case CHAT_MSG_WHISPER: case CHAT_MSG_CHANNEL: { if( m_muted && m_muted >= (uint32)UNIXTIME ) { SystemMessage("Your voice is currently muted by a moderator."); return; } }break; } switch(type) { case CHAT_MSG_EMOTE: { recv_data >> msg; if(GetPlayer()->m_modlanguage >=0) data = sChatHandler.FillMessageData( CHAT_MSG_EMOTE, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); else data = sChatHandler.FillMessageData( CHAT_MSG_EMOTE, CanUseCommand('c') ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); GetPlayer()->SendMessageToSet( data, true ,true ); //sLog.outString("[emote] %s: %s", _player->GetName(), msg.c_str()); delete data; pMsg=msg.c_str(); pMisc=0; }break; case CHAT_MSG_SAY: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->m_modlanguage >=0) { data = sChatHandler.FillMessageData( CHAT_MSG_SAY, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); GetPlayer()->SendMessageToSet( data, true ); } else { if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false) return; if(lang==0 && !CanUseCommand('c')) return; data = sChatHandler.FillMessageData( CHAT_MSG_SAY, lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); SendChatPacket(data, 1, lang, this); for(set<Player*>::iterator itr = _player->m_inRangePlayers.begin(); itr != _player->m_inRangePlayers.end(); ++itr) { (*itr)->GetSession()->SendChatPacket(data, 1, lang, this); } } //sLog.outString("[say] %s: %s", _player->GetName(), msg.c_str()); delete data; pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_PARTY: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } Group *pGroup = _player->GetGroup(); if(pGroup == NULL) break; if(GetPlayer()->m_modlanguage >=0) data=sChatHandler.FillMessageData( type, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); else data=sChatHandler.FillMessageData( type, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0); if(type == CHAT_MSG_PARTY && pGroup->GetGroupType() == GROUP_TYPE_RAID) { // only send to that subgroup SubGroup * sgr = _player->GetGroup() ? _player->GetGroup()->GetSubGroup(_player->GetSubGroup()) : 0; if(sgr) { _player->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr) { if((*itr)->m_loggedInPlayer) (*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this); } _player->GetGroup()->Unlock(); } } else { SubGroup * sgr; for(uint32 i = 0; i < _player->GetGroup()->GetSubGroupCount(); ++i) { sgr = _player->GetGroup()->GetSubGroup(i); _player->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr) { if((*itr)->m_loggedInPlayer) (*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this); } _player->GetGroup()->Unlock(); } } //sLog.outString("[party] %s: %s", _player->GetName(), msg.c_str()); delete data; pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_GUILD: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) { break; } if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_playerInfo->guild) _player->m_playerInfo->guild->GuildChat(msg.c_str(), this, lang); pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_OFFICER: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_playerInfo->guild) _player->m_playerInfo->guild->OfficerChat(msg.c_str(), this, lang); pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_YELL: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false) return; if(lang==0 && !CanUseCommand('c')) return; if(GetPlayer()->m_modlanguage >=0) data = sChatHandler.FillMessageData( CHAT_MSG_YELL, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); else data = sChatHandler.FillMessageData( CHAT_MSG_YELL, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); //SendPacket(data); //sWorld.SendZoneMessage(data, GetPlayer()->GetZoneId(), this); _player->GetMapMgr()->SendChatMessageToCellPlayers(_player, data, 2, 1, lang, this); delete data; //sLog.outString("[yell] %s: %s", _player->GetName(), msg.c_str()); pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_WHISPER: { std::string to = "",tmp; recv_data >> to >> msg; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } Player *player = objmgr.GetPlayer(to.c_str(), false); if(!player) { data = new WorldPacket(SMSG_CHAT_PLAYER_NOT_FOUND, to.length() + 1); *data << to; SendPacket(data); delete data; break; } // Check that the player isn't a gm with his status on if(!_player->GetSession()->GetPermissionCount() && player->bGMTagOn && player->gmTargets.count(_player) == 0) { // Send CHAT_MSG_WHISPER_INFORM packet WorldPacket *data2; data2 = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL,msg.c_str(), player->GetGUID(), 0); SendPacket(data2); delete data2; // Build automated reply string Reply = "This Game Master does not currently have an open ticket from you and did not receive your whisper. Please submit a new GM Ticket request if you need to speak to a GM. This is an automatic message."; data = sChatHandler.FillMessageData( CHAT_MSG_WHISPER, LANG_UNIVERSAL, Reply.c_str(), player->GetGUID(), 4); SendPacket(data); delete data; break; } if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false) return; if(lang==0 && !CanUseCommand('c')) return; if( player->Social_IsIgnoring( _player->GetLowGUID() ) ) { data = sChatHandler.FillMessageData( CHAT_MSG_IGNORED, LANG_UNIVERSAL, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); SendPacket(data); delete data; } else { if(GetPlayer()->m_modlanguage >=0) data = sChatHandler.FillMessageData( CHAT_MSG_WHISPER, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); else data = sChatHandler.FillMessageData( CHAT_MSG_WHISPER, ((CanUseCommand('c') || player->GetSession()->CanUseCommand('c')) && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); player->GetSession()->SendPacket(data); delete data; } //Sent the to Users id as the channel, this should be fine as it's not used for wisper data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL,msg.c_str(), player->GetGUID(), 0 ); SendPacket(data); delete data; if(player->HasFlag(PLAYER_FLAGS, 0x02)) { // Has AFK flag, autorespond. data = sChatHandler.FillMessageData(CHAT_MSG_AFK, LANG_UNIVERSAL, player->m_afk_reason.c_str(),player->GetGUID(), _player->bGMTagOn ? 4 : 0); SendPacket(data); delete data; } else if(player->HasFlag(PLAYER_FLAGS, 0x04)) { // Has DND flag, autorespond. data = sChatHandler.FillMessageData(CHAT_MSG_DND, LANG_UNIVERSAL, player->m_afk_reason.c_str(),player->GetGUID(), _player->bGMTagOn ? 4 : 0); SendPacket(data); delete data; } //sLog.outString("[whisper] %s to %s: %s", _player->GetName(), to.c_str(), msg.c_str()); pMsg=msg.c_str(); pMisc=to.c_str(); } break; case CHAT_MSG_CHANNEL: { std::string channel = ""; recv_data >> channel; recv_data >> msg; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; Channel *chn = channelmgr.GetChannel(channel.c_str(),GetPlayer()); if(chn) chn->Say(GetPlayer(),msg.c_str(), NULL, false); //sLog.outString("[%s] %s: %s", channel.c_str(), _player->GetName(), msg.c_str()); pMsg=msg.c_str(); pMisc=channel.c_str(); } break; case CHAT_MSG_AFK: { std::string reason; recv_data >> reason; GetPlayer()->SetAFKReason(reason); if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } /* WorldPacket *data, WorldSession* session, uint32 type, uint32 language, const char *channelName, const char *message*/ if(GetPlayer()->HasFlag(PLAYER_FLAGS, 0x02)) { GetPlayer()->RemoveFlag(PLAYER_FLAGS, 0x02); if(sWorld.GetKickAFKPlayerTime()) sEventMgr.RemoveEvents(GetPlayer(),EVENT_PLAYER_SOFT_DISCONNECT); } else { GetPlayer()->SetFlag(PLAYER_FLAGS, 0x02); if(sWorld.GetKickAFKPlayerTime()) sEventMgr.AddEvent(GetPlayer(),&Player::SoftDisconnect,EVENT_PLAYER_SOFT_DISCONNECT,sWorld.GetKickAFKPlayerTime(),1,0); } } break; case CHAT_MSG_DND: { std::string reason; recv_data >> reason; GetPlayer()->SetAFKReason(reason); if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->HasFlag(PLAYER_FLAGS, 0x04)) GetPlayer()->RemoveFlag(PLAYER_FLAGS, 0x04); else { GetPlayer()->SetFlag(PLAYER_FLAGS, 0x04); } } break; default: sLog.outError("CHAT: unknown msg type %u, lang: %u", type, lang); } if(pMsg) sHookInterface.OnChat(_player, type, lang, pMsg, pMisc); }
void Group::RemovePlayer(PlayerInfo * info) { WorldPacket data(50); Player * pPlayer = info->m_loggedInPlayer; m_groupLock.Acquire(); if(m_isqueued) { m_isqueued = false; BattlegroundManager.RemoveGroupFromQueues(this); } SubGroup *sg = NULL; if( info->subGroup >= 0 && info->subGroup <= 8 ) sg = m_SubGroups[info->subGroup]; if( sg == NULL || sg->m_GroupMembers.find(info) == sg->m_GroupMembers.end() ) { for( uint8 i = 0; i < m_SubGroupCount; ++i ) { if( m_SubGroups[i] != NULL ) { if( m_SubGroups[i]->m_GroupMembers.find(info) != m_SubGroups[i]->m_GroupMembers.end() ) { sg = m_SubGroups[i]; break; } } } } info->m_Group = NULL; info->subGroup = -1; if(sg == NULL) { m_groupLock.Release(); return; } m_dirty = true; sg->RemovePlayer( info ); --m_MemberCount; // remove team member from the instance if( info->m_loggedInPlayer != NULL ) { sInstanceMgr.PlayerLeftGroup( this, info->m_loggedInPlayer ); } if( pPlayer != NULL ) { if( pPlayer->GetSession() != NULL ) { SendNullUpdate( pPlayer ); data.SetOpcode( SMSG_GROUP_DESTROYED ); pPlayer->GetSession()->SendPacket( &data ); data.Initialize( SMSG_PARTY_COMMAND_RESULT ); data << uint32(2) << uint8(0) << uint32(0); // you leave the group pPlayer->GetSession()->SendPacket( &data ); } //Remove some party auras. for (uint32 i=MAX_POSITIVE_AURAS_EXTEDED_START;i<MAX_POSITIVE_AURAS_EXTEDED_END;i++) { if (pPlayer->m_auras[i] && pPlayer->m_auras[i]->m_areaAura) { Player * caster = pPlayer->m_auras[i]->GetPlayerCaster(); if( caster != NULL && pPlayer->GetLowGUID() != caster->GetLowGUID() ) pPlayer->m_auras[i]->Remove(); } } } if( m_MemberCount < 2 ) { if( m_disbandOnNoMembers ) { m_groupLock.Release(); Disband(); return; } } /* eek! ;P */ Player *newPlayer = NULL; if(m_Looter == info) { newPlayer = FindFirstPlayer(); if( newPlayer != NULL ) m_Looter = newPlayer->getPlayerInfo(); else m_Looter = NULL; } if(m_Leader == info) { if( newPlayer== NULL ) newPlayer=FindFirstPlayer(); if( newPlayer != NULL ) SetLeader(newPlayer, false); else m_Leader = NULL; } Update(); m_groupLock.Release(); }
void LfgMgr::SendLfgList(Player* plr, uint32 Dungeon) { if (plr == NULL) return; if (Dungeon >= MAX_DUNGEONS) return; LfgPlayerList::iterator itr; GroupMembersSet::iterator it2; uint32 count = 0; Player * pl; uint32 i; uint64 tguid; SubGroup * sgrp; m_lock.Acquire(); WorldPacket data(MSG_LOOKING_FOR_GROUP, ((m_lookingForGroup[Dungeon].size() + m_lookingForMore[Dungeon].size()) * 20) + 20); data << LfgDungeonTypes[Dungeon]; data << Dungeon; data << uint32(m_lookingForGroup[Dungeon].size()); data << uint32(m_lookingForGroup[Dungeon].size()); for (itr = m_lookingForGroup[Dungeon].begin(); itr != m_lookingForGroup[Dungeon].end(); ++itr) { pl = *itr; if (pl->GetTeam() != plr->GetTeam() || pl == plr) continue; ++count; data << pl->GetNewGUID(); data << pl->getLevel(); data << pl->GetZoneId(); data << uint8(0); // 1=LFG? for (i = 0; i < MAX_LFG_QUEUE_ID; ++i) data << pl->LfgDungeonId[i] << uint8(0) << pl->LfgType[i]; data << pl->Lfgcomment; // LFG members are never in parties. data << uint32(0); } for (itr = m_lookingForMore[Dungeon].begin(); itr != m_lookingForMore[Dungeon].end(); ++itr) { pl = *itr; if (pl->GetTeam() != plr->GetTeam() || pl == plr) continue; ++count; data << pl->GetNewGUID(); data << pl->getLevel(); data << pl->GetZoneId(); data << uint8(1); // 1=LFM? for (i = 0; i < MAX_LFG_QUEUE_ID; ++i) data << pl->LfgDungeonId[i] << uint8(0) << pl->LfgType[i]; data << pl->Lfgcomment; if (pl->GetGroup() && pl->GetGroup()->GetGroupType() == GROUP_TYPE_PARTY) { pl->GetGroup()->Lock(); sgrp = pl->GetGroup()->GetSubGroup(0); data << uint32(sgrp->GetMemberCount() - 1); for (it2 = sgrp->GetGroupMembersBegin(); it2 != sgrp->GetGroupMembersEnd(); ++it2) { if ((*it2)->m_loggedInPlayer) data << (*it2)->m_loggedInPlayer->GetNewGUID(); else { tguid = (*it2)->guid; FastGUIDPack(data, tguid); } } pl->GetGroup()->Unlock(); } else data << uint32(0); } m_lock.Release(); //*(uint32*)(data.contents()[8]) = count; //*(uint32*)(data.contents()[12]) = count; data.put(8, count); data.put(12, count); plr->GetSession()->SendPacket(&data); }
void WorldSession::HandleMessagechatOpcode(WorldPacket & recv_data) { CHECK_INWORLD_RETURN CHECK_PACKET_SIZE(recv_data, 9); WorldPacket* data = NULL; uint32 type; int32 lang; const char* pMisc = NULL; const char* pMsg = NULL; recv_data >> type; recv_data >> lang; if(lang >= NUM_LANGUAGES) return; if(GetPlayer()->IsBanned()) { GetPlayer()->BroadcastMessage("You cannot do that when banned."); return; } // Flood protection if(lang != -1 && !GetPermissionCount() && sWorld.flood_lines != 0) { /* flood detection, wheeee! */ if(UNIXTIME >= floodTime) { floodLines = 0; floodTime = UNIXTIME + sWorld.flood_seconds; } if((++floodLines) > sWorld.flood_lines) { if(sWorld.flood_message) _player->BroadcastMessage("Your message has triggered serverside flood protection. You can speak again in %u seconds.", floodTime - UNIXTIME); return; } } switch(type) { case CHAT_MSG_EMOTE: case CHAT_MSG_SAY: case CHAT_MSG_YELL: case CHAT_MSG_WHISPER: case CHAT_MSG_CHANNEL: { if(m_muted && m_muted >= (uint32)UNIXTIME) { SystemMessage("Your voice is currently muted by a moderator."); return; } } break; } std::string msg, to = "", channel = "", tmp; msg.reserve(256); // Process packet switch(type) { case CHAT_MSG_SAY: case CHAT_MSG_EMOTE: case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: case CHAT_MSG_YELL: recv_data >> msg; pMsg = msg.c_str(); //g_chatFilter->ParseEscapeCodes((char*)pMsg,true); pMisc = 0; break; case CHAT_MSG_WHISPER: recv_data >> to >> msg; pMsg = msg.c_str(); pMisc = to.c_str(); break; case CHAT_MSG_CHANNEL: recv_data >> channel; recv_data >> msg; pMsg = msg.c_str(); pMisc = channel.c_str(); break; case CHAT_MSG_AFK: case CHAT_MSG_DND: break; case CHAT_MSG_BATTLEGROUND: case CHAT_MSG_BATTLEGROUND_LEADER: recv_data >> msg; pMsg = msg.c_str(); break; default: LOG_ERROR("CHAT: unknown msg type %u, lang: %u", type, lang); } if(int(msg.find("|T")) > -1) { GetPlayer()->BroadcastMessage("Don't even THINK about doing that again"); return; } // HookInterface OnChat event if(pMsg && !sHookInterface.OnChat(_player, type, lang, pMsg, pMisc)) return; Channel* chn = NULL; // Main chat message processing switch(type) { case CHAT_MSG_EMOTE: { if(sWorld.interfaction_chat && lang > 0) lang = 0; if(g_chatFilter->Parse(msg)) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->m_modlanguage >= 0) data = sChatHandler.FillMessageData(CHAT_MSG_EMOTE, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else if(lang == 0 && sWorld.interfaction_chat) data = sChatHandler.FillMessageData(CHAT_MSG_EMOTE, CanUseCommand('0') ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else data = sChatHandler.FillMessageData(CHAT_MSG_EMOTE, CanUseCommand('c') ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); GetPlayer()->SendMessageToSet(data, true, ! sWorld.interfaction_chat); //sLog.outString("[emote] %s: %s", _player->GetName(), msg.c_str()); delete data; } break; case CHAT_MSG_SAY: { if(sWorld.interfaction_chat && lang > 0) lang = 0; if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg)) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->m_modlanguage >= 0) { data = sChatHandler.FillMessageData(CHAT_MSG_SAY, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); GetPlayer()->SendMessageToSet(data, true); } else { if(lang > 0 && LanguageSkills[lang] && ! _player->_HasSkillLine(LanguageSkills[lang])) return; if(lang == 0 && ! CanUseCommand('c') && ! sWorld.interfaction_chat) return; data = sChatHandler.FillMessageData(CHAT_MSG_SAY, lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); GetPlayer()->SendMessageToSet(data, true); } delete data; } break; case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: { if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(sWorld.interfaction_chat && lang > 0) lang = 0; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } Group* pGroup = _player->GetGroup(); if(pGroup == NULL) break; if(GetPlayer()->m_modlanguage >= 0) data = sChatHandler.FillMessageData(type, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else if(lang == 0 && sWorld.interfaction_chat) data = sChatHandler.FillMessageData(type, (CanUseCommand('0') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else data = sChatHandler.FillMessageData(type, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); if(type == CHAT_MSG_PARTY && pGroup->GetGroupType() == GROUP_TYPE_RAID) { // only send to that subgroup SubGroup* sgr = _player->GetGroup() ? _player->GetGroup()->GetSubGroup(_player->GetSubGroup()) : 0; if(sgr) { _player->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr) { if((*itr)->m_loggedInPlayer) (*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this); } _player->GetGroup()->Unlock(); } } else { SubGroup* sgr; for(uint32 i = 0; i < _player->GetGroup()->GetSubGroupCount(); ++i) { sgr = _player->GetGroup()->GetSubGroup(i); _player->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr) { if((*itr)->m_loggedInPlayer) (*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this); } _player->GetGroup()->Unlock(); } } //sLog.outString("[party] %s: %s", _player->GetName(), msg.c_str()); delete data; } break; case CHAT_MSG_GUILD: { if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) { break; } if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_playerInfo->guild) _player->m_playerInfo->guild->GuildChat(msg.c_str(), this, lang); } break; case CHAT_MSG_OFFICER: { if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_playerInfo->guild) _player->m_playerInfo->guild->OfficerChat(msg.c_str(), this, lang); } break; case CHAT_MSG_YELL: { if(sWorld.interfaction_chat && lang > 0) lang = 0; if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false) return; if(lang == 0 && sWorld.interfaction_chat) data = sChatHandler.FillMessageData(CHAT_MSG_YELL, (CanUseCommand('0') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else if(lang == 0 && !CanUseCommand('c')) { if(data != NULL) delete data; return; } else if(GetPlayer()->m_modlanguage >= 0) data = sChatHandler.FillMessageData(CHAT_MSG_YELL, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else data = sChatHandler.FillMessageData(CHAT_MSG_YELL, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); _player->GetMapMgr()->SendChatMessageToCellPlayers(_player, data, 2, 1, lang, this); delete data; } break; case CHAT_MSG_WHISPER: { if(lang != -1) lang = LANG_UNIVERSAL; //All whispers are universal if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } PlayerCache* playercache = objmgr.GetPlayerCache(to.c_str(), false); if(playercache == NULL) { data = new WorldPacket(SMSG_CHAT_PLAYER_NOT_FOUND, to.length() + 1); *data << to; SendPacket(data); delete data; break; } if(_player->GetTeamInitial() != playercache->GetUInt32Value(CACHE_PLAYER_INITIALTEAM) && !sWorld.interfaction_chat && !playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) && !_player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM)) { WorldPacket response(SMSG_CHAT_PLAYER_NOT_FOUND, to.length() + 1); response << to; SendPacket(&response); playercache->DecRef(); break; } // Check that the player isn't a gm with his status on // TODO: Game Master's on retail are able to have block whispers after they close the ticket with the current packet. // When a Game Master is visible to your player it says "This player is unavailable for whisper" I need to figure out how this done. if(!HasPermissions() && playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) && playercache->CountValue64(CACHE_GM_TARGETS, _player->GetGUID()) == 0) { // Build automated reply string Reply = "SYSTEM: This Game Master does not currently have an open ticket from you and did not receive your whisper. Please submit a new GM Ticket request if you need to speak to a GM. This is an automatic message."; data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL, Reply.c_str(), playercache->GetGUID(), 4); SendPacket(data); delete data; playercache->DecRef(); break; } if(playercache->CountValue64(CACHE_SOCIAL_IGNORELIST, _player->GetLowGUID()) > 0) { data = sChatHandler.FillMessageData(CHAT_MSG_IGNORED, LANG_UNIVERSAL, msg.c_str(), playercache->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); SendPacket(data); delete data; playercache->DecRef(); break; } else { data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER, lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); playercache->SendPacket(data); } //Sent the to Users id as the channel, this should be fine as it's not used for whisper if(lang != -1) //DO NOT SEND if its an addon message! { data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL, msg.c_str(), playercache->GetGUID(), playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); SendPacket(data); delete data; } if(playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_AFK)) { // Has AFK flag, autorespond. std::string reason; playercache->GetStringValue(CACHE_AFK_DND_REASON, reason); data = sChatHandler.FillMessageData(CHAT_MSG_AFK, LANG_UNIVERSAL, reason.c_str(), playercache->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); SendPacket(data); delete data; } else if(playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_DND)) { // Has DND flag, autorespond. std::string reason; playercache->GetStringValue(CACHE_AFK_DND_REASON, reason); data = sChatHandler.FillMessageData(CHAT_MSG_DND, LANG_UNIVERSAL, reason.c_str(), playercache->GetGUID(), playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); SendPacket(data); delete data; } playercache->DecRef(); } break; case CHAT_MSG_CHANNEL: { if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; chn = channelmgr.GetChannel(channel.c_str(), GetPlayer()); if(chn) { //g_chatFilter->ParseEscapeCodes((char*)pMsg, (chn->m_flags & CHANNEL_PACKET_ALLOWLINKS)>0 ); chn->Say(GetPlayer(), msg.c_str(), NULL, false); } } break; case CHAT_MSG_AFK: { std::string reason = ""; recv_data >> reason; GetPlayer()->SetAFKReason(reason); if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } /* WorldPacket *data, WorldSession* session, uint32 type, uint32 language, const char *channelName, const char *message*/ if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_AFK)) { GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAG_AFK); if(sWorld.GetKickAFKPlayerTime()) sEventMgr.RemoveEvents(GetPlayer(), EVENT_PLAYER_SOFT_DISCONNECT); } else { GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_AFK); if(GetPlayer()->m_bg) GetPlayer()->m_bg->RemovePlayer(GetPlayer(), false); if(sWorld.GetKickAFKPlayerTime()) sEventMgr.AddEvent(GetPlayer(), &Player::SoftDisconnect, EVENT_PLAYER_SOFT_DISCONNECT, sWorld.GetKickAFKPlayerTime(), 1, 0); } } break; case CHAT_MSG_DND: { std::string reason; recv_data >> reason; GetPlayer()->SetAFKReason(reason); if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_DND)) GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAG_DND); else { GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_DND); } } break; case CHAT_MSG_BATTLEGROUND: case CHAT_MSG_BATTLEGROUND_LEADER: { if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_bg != NULL) { data = sChatHandler.FillMessageData(type, lang, msg.c_str(), _player->GetGUID()); _player->m_bg->DistributePacketToTeam(data, _player->GetTeam()); delete data; } } break; } }
void HonorHandler::OnPlayerKilledUnit( Player *pPlayer, Unit* pVictim ) { if( pVictim == NULL || pPlayer == NULL ) return; if( pPlayer->GetTypeId() != TYPEID_PLAYER || !pVictim->IsUnit() ) return; if( !pVictim->IsPlayer() || static_cast< Player* >( pVictim )->m_honorless ) return; if( pVictim->IsPlayer() ) { if( pPlayer->m_bg ) { if( static_cast< Player* >( pVictim )->m_bgTeam == pPlayer->m_bgTeam ) return; // patch 2.4, players killed >50 times in battlegrounds won't be worth honor for the rest of that bg if( static_cast<Player*>(pVictim)->m_bgScore.Deaths >= 50 ) return; } else { if( pPlayer->GetTeam() == static_cast< Player* >( pVictim )->GetTeam() ) return; } } // Calculate points int32 Points = 0; if(pVictim->IsPlayer() && pPlayer != pVictim) Points = CalculateHonorPointsForKill( pPlayer->getLevel(), pVictim->getLevel() ); if( Points > 0 ) { if( pPlayer->m_bg ) { // hackfix for battlegrounds (since the groups there are disabled, we need to do this manually) vector<Player*> toadd; uint32 t = pPlayer->m_bgTeam; toadd.reserve(15); // shouldn't have more than this pPlayer->m_bg->Lock(); set<Player*> * s = &pPlayer->m_bg->m_players[t]; for(set<Player*>::iterator itr = s->begin(); itr != s->end(); ++itr) { // Also check that the player is in range, and the player is alive. if((*itr) == pPlayer || ((*itr)->isAlive() && (*itr)->isInRange(pPlayer,100.0f))) toadd.push_back(*itr); } if( toadd.size() > 0 ) { uint32 pts = Points / (uint32)toadd.size(); for(vector<Player*>::iterator vtr = toadd.begin(); vtr != toadd.end(); ++vtr) { AddHonorPointsToPlayer(*vtr, pts); (*vtr)->m_killsToday++; (*vtr)->m_killsLifetime++; pPlayer->m_bg->HookOnHK(*vtr); if(pVictim) { // Send PVP credit WorldPacket data(SMSG_PVP_CREDIT, 12); uint32 pvppoints = pts * 10; data << pvppoints << pVictim->GetGUID() << uint32(static_cast< Player* >(pVictim)->GetPVPRank()); (*vtr)->GetSession()->SendPacket(&data); } } } pPlayer->m_bg->Unlock(); } else { set<Player*> contributors; // First loop: Get all the people in the attackermap. pVictim->UpdateOppFactionSet(); for(std::set<Object*>::iterator itr = pVictim->GetInRangeOppFactsSetBegin(); itr != pVictim->GetInRangeOppFactsSetEnd(); itr++) { if(!(*itr)->IsPlayer()) continue; bool added = false; Player * plr = (Player*)(*itr); if(pVictim->CombatStatus.m_attackers.find(plr->GetGUID()) != pVictim->CombatStatus.m_attackers.end()) { added = true; contributors.insert(plr); } if(added && plr->GetGroup()) { Group * pGroup = plr->GetGroup(); uint32 groups = pGroup->GetSubGroupCount(); for(uint32 i = 0; i < groups; i++) { SubGroup * sg = pGroup->GetSubGroup(i); if(!sg) continue; for(GroupMembersSet::iterator itr2 = sg->GetGroupMembersBegin(); itr2 != sg->GetGroupMembersEnd(); itr2++) { PlayerInfo * pi = (*itr2); Player * gm = objmgr.GetPlayer(pi->guid); if(!gm) continue; if(gm->isInRange(pVictim, 100.0f)) contributors.insert(gm); } } } } for(set<Player*>::iterator itr = contributors.begin(); itr != contributors.end(); itr++) { Player * pAffectedPlayer = (*itr); if(!pAffectedPlayer) continue; pAffectedPlayer->m_killsToday++; pAffectedPlayer->m_killsLifetime++; if(pAffectedPlayer->m_bg) pAffectedPlayer->m_bg->HookOnHK(pAffectedPlayer); int32 contributorpts = Points / (int32)contributors.size(); AddHonorPointsToPlayer(pAffectedPlayer, contributorpts); if(pVictim->IsPlayer()) { sHookInterface.OnHonorableKill(pAffectedPlayer, (Player*)pVictim); WorldPacket data(SMSG_PVP_CREDIT, 12); uint32 pvppoints = contributorpts * 10; // Why *10? data << pvppoints << pVictim->GetGUID() << uint32(static_cast< Player* >(pVictim)->GetPVPRank()); pAffectedPlayer->GetSession()->SendPacket(&data); } int PvPToken = 0; Config.OptionalConfig.GetInt("Extra", "PvPToken", &PvPToken); if( PvPToken > 0 ) { int PvPTokenID = 0; Config.OptionalConfig.GetInt("Extra", "PvPTokenID", &PvPTokenID); if( PvPTokenID > 0 ) { Item * PvPTokenItem = objmgr.CreateItem(PvPTokenID, pAffectedPlayer); if( PvPTokenItem ) { PvPTokenItem->SoulBind(); pAffectedPlayer->GetItemInterface()->AddItemToFreeSlot( PvPTokenItem ); } } } if(pAffectedPlayer->GetZoneId() == 3518) { // Add Halaa Battle Token SpellEntry * pvp_token_spell = dbcSpell.LookupEntry(pAffectedPlayer->GetTeam()? 33004 : 33005); pAffectedPlayer->CastSpell(pAffectedPlayer, pvp_token_spell, true); } // If we are in Hellfire Peninsula <http://www.wowwiki.com/Hellfire_Peninsula#World_PvP_-_Hellfire_Fortifications> if(pAffectedPlayer->GetZoneId() == 3483) { // Hellfire Horde Controlled Towers /*if(pAffectedPlayer->GetMapMgr()->GetWorldState(2478) != 3 && pAffectedPlayer->GetTeam() == 1) return; // Hellfire Alliance Controlled Towers if(pAffectedPlayer->GetMapMgr()->GetWorldState(2476) != 3 && pAffectedPlayer->GetTeam() == 0) return; */ // Add Mark of Thrallmar/Honor Hold SpellEntry * pvp_token_spell = dbcSpell.LookupEntry(pAffectedPlayer->GetTeam()? 32158 : 32155); pAffectedPlayer->CastSpell(pAffectedPlayer, pvp_token_spell, true); } } } } }
void WorldSession::HandlePushQuestToPartyOpcode(WorldPacket &recv_data) { CHECK_INWORLD_RETURN; uint32 questid, status; recv_data >> questid; DEBUG_LOG( "WORLD"," Received CMSG_PUSHQUESTTOPARTY quest = %u", questid ); Quest *pQuest = QuestStorage.LookupEntry(questid); if(pQuest) { Group *pGroup = _player->GetGroup(); if(pGroup) { uint32 pguid = _player->GetLowGUID(); SubGroup * sgr = _player->GetGroup() ? _player->GetGroup()->GetSubGroup(_player->GetSubGroup()) : 0; if(sgr) { _player->GetGroup()->Lock(); GroupMembersSet::iterator itr; for(itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); itr++) { Player* pPlayer = (*itr)->m_loggedInPlayer; if(pPlayer && pPlayer->GetGUID() != pguid) { WorldPacket data( MSG_QUEST_PUSH_RESULT, 13 ); data << pPlayer->GetGUID(); data << uint32(QUEST_SHARE_MSG_SHARING_QUEST); data << uint8(0); _player->GetSession()->SendPacket(&data); uint32 response = 0; //CHECKS IF CAN TAKE THE QUEST status = sQuestMgr.PlayerMeetsReqs(pPlayer, pQuest, false); if(status != QMGR_QUEST_AVAILABLE && status != QMGR_QUEST_CHAT) { response = QUEST_SHARE_MSG_CANT_TAKE_QUEST; } //CHECKS IF QUESTLOG ISN'T FULL if(pPlayer->GetOpenQuestSlot() == -1) { response = QUEST_SHARE_MSG_LOG_FULL; } //CHEQUEA SI TIENE LA QUEST EN EL QUESTLOG | CHEKS IF HAVE ALREADY THE QUEST IN QUESTLOG QuestLogEntry *qst = pPlayer->GetQuestLogForEntry(questid); if(qst) { response = QUEST_SHARE_MSG_HAVE_QUEST; } //CHECKS IF ALREADY HAVE COMPLETED THE QUEST if(pPlayer->HasFinishedQuest(questid)) { response = QUEST_SHARE_MSG_FINISH_QUEST; } //CHECKS IF ALREADY HAVE COMPLETED THE DAILY QUEST if(pPlayer->HasFinishedDailyQuest(questid)) { response = QUEST_SHARE_MSG_CANT_SHARE_TODAY; } //CHECKS IF IS IN THE PARTY if(!pGroup) { response = QUEST_SHARE_MSG_NOT_IN_PARTY; } //CHECKS IF IS BUSY if(pPlayer->DuelingWith != NULL) { response = QUEST_SHARE_MSG_BUSY; } if(response > 0) { sQuestMgr.SendPushToPartyResponse(_player, pPlayer, response); continue; } data.clear(); sQuestMgr.BuildQuestDetails(&data, pQuest, pPlayer, 1, pPlayer->GetSession()->language, _player); pPlayer->GetSession()->SendPacket(&data); pPlayer->SetQuestSharer(pguid); } } _player->GetGroup()->Unlock(); } } } }
/// Spell Target Handling for type 45: Chain,!!only for healing!! for chain lightning =6 void Spell::SpellTargetChainTargeting(uint32 i, uint32 j) { if( !m_caster->IsInWorld() ) return; TargetsList* tmpMap=&m_targetUnits[i]; //if selected target is party member, then jumps on party Unit* firstTarget; bool PartyOnly = false; float range = GetMaxRange(dbcSpellRange.LookupEntry(m_spellInfo->rangeIndex));//this is probably wrong, //this is cast distance, not searching distance range *= range; firstTarget = m_caster->GetMapMgr()->GetPlayer((uint32)m_targets.m_unitTarget); if( firstTarget && p_caster != NULL ) { if( p_caster->InGroup() ) if( p_caster->GetSubGroup() == static_cast< Player* >( firstTarget )->GetSubGroup() ) PartyOnly=true; } else { firstTarget = m_caster->GetMapMgr()->GetUnit(m_targets.m_unitTarget); if(!firstTarget) return; } uint32 jumps=m_spellInfo->EffectChainTarget[i]; if(m_spellInfo->SpellGroupType && u_caster) { SM_FIValue(u_caster->SM_FAdditionalTargets,(int32*)&jumps,m_spellInfo->SpellGroupType); } SafeAddTarget(tmpMap,firstTarget->GetGUID()); if(!jumps) return; jumps--; if(PartyOnly) { GroupMembersSet::iterator itr; SubGroup * pGroup = p_caster->GetGroup() ? p_caster->GetGroup()->GetSubGroup(p_caster->GetSubGroup()) : 0; if(pGroup) { p_caster->GetGroup()->Lock(); for(itr = pGroup->GetGroupMembersBegin(); itr != pGroup->GetGroupMembersEnd(); ++itr) { if(!(*itr)->m_loggedInPlayer || (*itr)->m_loggedInPlayer==u_caster || !(*itr)->m_loggedInPlayer->isAlive() ) continue; //we target stuff that has no full health. No idea if we must fill target list or not :( if( (*itr)->m_loggedInPlayer->GetUInt32Value( UNIT_FIELD_HEALTH ) == (*itr)->m_loggedInPlayer->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) ) continue; if( sWorld.Collision && u_caster != NULL ) { if (u_caster->GetMapId() == (*itr)->m_loggedInPlayer->GetMapId() && !CollideInterface.CheckLOS(u_caster->GetMapId(),u_caster->GetPositionNC(),(*itr)->m_loggedInPlayer->GetPositionNC())) continue; } if( IsInrange(u_caster,(*itr)->m_loggedInPlayer, range) ) { SafeAddTarget(tmpMap,(*itr)->m_loggedInPlayer->GetGUID()); if(!--jumps) { p_caster->GetGroup()->Unlock(); return; } } } p_caster->GetGroup()->Unlock(); } }//find nearby friendly target else { std::set<Object*>::iterator itr; firstTarget->AquireInrangeLock(); //make sure to release lock before exit function ! for( itr = firstTarget->GetInRangeSetBegin(); itr != firstTarget->GetInRangeSetEnd(); itr++ ) { if( !(*itr)->IsUnit() || !((Unit*)(*itr))->isAlive()) continue; //we target stuff that has no full health. No idea if we must fill target list or not :( if( (*itr)->GetUInt32Value( UNIT_FIELD_HEALTH ) == (*itr)->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) ) continue; if (sWorld.Collision) { if (u_caster->GetMapId() == (*itr)->GetMapId() && !CollideInterface.CheckLOS(u_caster->GetMapId(),u_caster->GetPositionNC(),(*itr)->GetPositionNC())) continue; } if(IsInrange(firstTarget,*itr, range)) { if(!isAttackable(u_caster,(Unit*)(*itr))) { SafeAddTarget(tmpMap,(*itr)->GetGUID()); if(!--jumps) { firstTarget->ReleaseInrangeLock(); return; } } } } firstTarget->ReleaseInrangeLock(); } }
/// Spell Target Handling for type 31: related to scripted effects void Spell::SpellTargetScriptedEffects( uint32 i, uint32 j ) { // Circle of healing or Wild Growth // - target top 5 hp deficient raid members around target. if( GetProto()->NameHash == SPELL_HASH_CIRCLE_OF_HEALING || GetProto()->NameHash == SPELL_HASH_WILD_GROWTH ) { if( p_caster == NULL || !p_caster->IsInWorld() ) return; TargetsList* tmpMap = &m_targetUnits[i]; Unit * pTarget = p_caster->GetMapMgr()->GetUnit( m_targets.m_unitTarget ); if( !pTarget ) return; if( p_caster == pTarget || IsInrange( p_caster->GetPositionX(), p_caster->GetPositionY(), p_caster->GetPositionZ(), pTarget, GetMaxRange( dbcSpellRange.LookupEntry( GetProto()->rangeIndex ) ) ) ) SafeAddTarget( tmpMap, pTarget->GetGUID() ); else { cancastresult = SPELL_FAILED_OUT_OF_RANGE; return; // No point targeting others if the target is not in casting range. } Group * group = p_caster->GetGroup(); if( group == NULL ) return; std::vector<Player*> raidList; std::vector<Player*>::iterator itr; uint32 count = group->GetSubGroupCount(); group->Lock(); for( uint32 k = 0; k < count; k++ ) { SubGroup * subgroup = group->GetSubGroup( k ); if( subgroup ) { for( GroupMembersSet::iterator itr = subgroup->GetGroupMembersBegin(); itr != subgroup->GetGroupMembersEnd(); ++itr ) { if( (*itr)->m_loggedInPlayer && m_caster != (*itr)->m_loggedInPlayer && IsInrange( pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), (*itr)->m_loggedInPlayer, GetRadius(i) ) ) raidList.push_back( (*itr)->m_loggedInPlayer ); } } } group->Unlock(); std::sort( raidList.begin(), raidList.end(), hpLessThan ); uint32 maxTargets = 4; if( GetProto()->NameHash == SPELL_HASH_CIRCLE_OF_HEALING && p_caster->HasSpell( 55675 ) ) // Glyph of circle of healing maxTargets++; for( itr = raidList.begin(); itr != raidList.end() && maxTargets > 0; ++itr, maxTargets-- ) { SafeAddTarget( tmpMap, (*itr)->GetGUID() ); } } else FillAllTargetsInArea( i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, GetRadius(i) ); }
/// Spell Target Handling for type 45: Chain,!!only for healing!! for chain lightning =6 void Spell::SpellTargetChainTargeting(uint32 i, uint32 j) { if( !m_caster->IsInWorld() ) return; //if selected target is party member, then jumps on party Unit* firstTarget; bool PartyOnly = false; float range = GetMaxRange(dbcSpellRange.LookupEntry(m_spellInfo->rangeIndex));//this is probably wrong, //this is cast distance, not searching distance range *= range; firstTarget = m_caster->GetMapMgr()->GetPlayer((uint32)m_targets.m_unitTarget); if( firstTarget && p_caster != NULL ) { if( p_caster->InGroup() ) if( p_caster->GetSubGroup() == TO_PLAYER( firstTarget )->GetSubGroup() ) PartyOnly=true; } else { firstTarget = m_caster->GetMapMgr()->GetUnit(m_targets.m_unitTarget); if(!firstTarget) return; } uint32 jumps=m_spellInfo->EffectChainTarget[i]; if(m_spellInfo->SpellGroupType && u_caster) { SM_FIValue(u_caster->SM[SMT_ADDITIONAL_TARGET][0],(int32*)&jumps,m_spellInfo->SpellGroupType); } _AddTargetForced(firstTarget->GetGUID(), i); if(!jumps) return; jumps--; if(PartyOnly) { GroupMembersSet::iterator itr; SubGroup * pGroup = p_caster->GetGroup() ? p_caster->GetGroup()->GetSubGroup(p_caster->GetSubGroup()) : 0; if(pGroup) { p_caster->GetGroup()->Lock(); for(itr = pGroup->GetGroupMembersBegin(); itr != pGroup->GetGroupMembersEnd(); itr++) { if(!(*itr)->m_loggedInPlayer || (*itr)->m_loggedInPlayer == u_caster || (*itr)->m_loggedInPlayer->GetUInt32Value(UNIT_FIELD_HEALTH) == (*itr)->m_loggedInPlayer->GetUInt32Value(UNIT_FIELD_MAXHEALTH)) continue; if(IsInrange(u_caster->GetPositionX(),u_caster->GetPositionY(),u_caster->GetPositionZ(),(*itr)->m_loggedInPlayer, range)) { _AddTargetForced((*itr)->m_loggedInPlayer->GetGUID(), i); if(!--jumps) { p_caster->GetGroup()->Unlock(); return; } } } p_caster->GetGroup()->Unlock(); } }//find nearby friendly target else { unordered_set<Object*>::iterator itr; for( itr = firstTarget->GetInRangeSetBegin(); itr != firstTarget->GetInRangeSetEnd(); ++itr ) { if( !(*itr)->IsUnit() || !TO_UNIT(*itr)->isAlive()) continue; if(IsInrange(firstTarget->GetPositionX(),firstTarget->GetPositionY(),firstTarget->GetPositionZ(),*itr, range)) { if(!isAttackable(u_caster,TO_UNIT(*itr)) && (*itr)->GetUInt32Value(UNIT_FIELD_HEALTH) != (*itr)->GetUInt32Value(UNIT_FIELD_MAXHEALTH)) { _AddTargetForced((*itr)->GetGUID(), i); if(!--jumps) return; } } } } }