Esempio n. 1
0
/// 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();
	}
}
Esempio n. 2
0
// 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);
}
Esempio n. 3
0
/// 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());
	}
}
Esempio n. 4
0
// 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();
}
Esempio n. 5
0
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();
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
	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();
}
Esempio n. 8
0
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();
    }
}
Esempio n. 9
0
/// 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();
	}
}
Esempio n. 10
0
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();
}
Esempio n. 11
0
/// 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();
				}
			}
		}
	}
}
Esempio n. 12
0
/// 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();
				}
			}
		}
	}
}
Esempio n. 13
0
/// 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();
	}
}
Esempio n. 14
0
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();
			}
		}
	}
}
Esempio n. 15
0
/// 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();
	}
}
Esempio n. 16
0
/// 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) );
}
Esempio n. 17
0
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);
}
Esempio n. 18
0
void WorldSession::HandleLootMoneyOpcode( WorldPacket & recv_data )
{
	if(!_player->IsInWorld()) return;
	Loot * pLoot = NULL;
	uint64 lootguid=GetPlayer()->GetLootGUID();
	if(!lootguid)
		return;   // duno why this happens

	if(_player->isCasting())
		_player->InterruptSpell();

	WorldPacket pkt;	
	Unit * pt = 0;

	if(UINT32_LOPART(GUID_HIPART(lootguid)) == HIGHGUID_UNIT)
	{
		Creature* pCreature = _player->GetMapMgr()->GetCreature(lootguid);
		if(!pCreature)return;
		pLoot=&pCreature->loot;
		pt = pCreature;
	}
	else if(UINT32_LOPART(GUID_HIPART(lootguid)) == HIGHGUID_GAMEOBJECT)
	{
		GameObject* pGO = _player->GetMapMgr()->GetGameObject(lootguid);
		if(!pGO)return;
		pLoot=&pGO->loot;
	}
	else if(UINT32_LOPART(GUID_HIPART(lootguid)) == HIGHGUID_CORPSE)
	{
		Corpse *pCorpse = objmgr.GetCorpse((uint32)lootguid);
		if(!pCorpse)return;
		pLoot=&pCorpse->loot;
	}
	else if(UINT32_LOPART(GUID_HIPART(lootguid)) == HIGHGUID_PLAYER)
	{
		Player * pPlayer = _player->GetMapMgr()->GetPlayer(lootguid);
		if(!pPlayer) return;
		pLoot = &pPlayer->loot;
		pPlayer->bShouldHaveLootableOnCorpse = false;
		pt = pPlayer;
	}
	else if( (UINT32_LOPART(GUID_HIPART(lootguid)) == HIGHGUID_ITEM) )
	{
		Item *pItem = _player->GetItemInterface()->GetItemByGUID(lootguid);
		if(!pItem)
			return;
		pLoot = pItem->loot;
	}

	if (!pLoot)
	{
		//bitch about cheating maybe?
		return;
	}

	uint32 money = pLoot->gold;

	pLoot->gold=0;
	WorldPacket data(1);
	data.SetOpcode(SMSG_LOOT_CLEAR_MONEY);
	// send to all looters
	Player * plr;
	for(LooterSet::iterator itr = pLoot->looters.begin(); itr != pLoot->looters.end(); ++itr)
	{
		if((plr = _player->GetMapMgr()->GetPlayer(*itr)))
			plr->GetSession()->SendPacket(&data);
	}

	if(!_player->InGroup())
	{
		if(money)
		{
			GetPlayer()->ModUInt32Value( PLAYER_FIELD_COINAGE , money);
			sHookInterface.OnLoot(_player, pt, money, 0);
		}
	}
	else
	{
		//this code is wrong mustbe party not raid!
		Group* party = _player->GetGroup();
		if(party)
		{
			/*uint32 share = money/party->MemberCount();*/
			vector<Player*> targets;
			targets.reserve(party->MemberCount());

			GroupMembersSet::iterator itr;
			SubGroup * sgrp;
			for(uint32 i = 0; i < party->GetSubGroupCount(); i++)
			{
				sgrp = party->GetSubGroup(i);
				for(itr = sgrp->GetGroupMembersBegin(); itr != sgrp->GetGroupMembersEnd(); ++itr)
				{
					if((*itr)->GetZoneId() == _player->GetZoneId() && _player->GetInstanceID() == (*itr)->GetInstanceID())
						targets.push_back((*itr));
				}
			}

			if(!targets.size())
				return;

			uint32 share = money / targets.size();

			pkt.SetOpcode(SMSG_LOOT_MONEY_NOTIFY);
			pkt << share;

			for(vector<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
			{
				(*itr)->ModUInt32Value(PLAYER_FIELD_COINAGE, share);
				(*itr)->GetSession()->SendPacket(&pkt);
			}
		}
	}   
}
Esempio n. 19
0
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;
	}
}
Esempio n. 20
0
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);
				}
			}
		}
	}
}
Esempio n. 21
0
/// 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;
				}
			}
		}
	}
}
Esempio n. 22
0
void WorldSession::HandlePushQuestToPartyOpcode(WorldPacket &recv_data)
{
    if(!_player) return;
	if(!_player->IsInWorld()) return;
	uint32 questid, status;
	recv_data >> questid;

	sLog.outDetail( "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;
						if(_player->GetDistance2dSq(pPlayer) > 100)
						{
							response = QUEST_SHARE_MSG_TOO_FAR;
							continue;
						}
						QuestLogEntry *qst = pPlayer->GetQuestLogForEntry(questid);
						if(qst)
						{
							response = QUEST_SHARE_MSG_HAVE_QUEST;
							continue;
						}
						status = sQuestMgr.PlayerMeetsReqs(pPlayer, pQuest, false);
						if(status != QMGR_QUEST_AVAILABLE && status != QMGR_QUEST_CHAT)
						{
							response = QUEST_SHARE_MSG_CANT_TAKE_QUEST;
							continue;
						}
						if(pPlayer->HasFinishedQuest(questid))
						{
							response = QUEST_SHARE_MSG_FINISH_QUEST;
							continue;
						}
						if(pPlayer->GetOpenQuestSlot() == -1)
						{
							response = QUEST_SHARE_MSG_LOG_FULL;
							continue;
						}
						//Anything more?
						if(pPlayer->DuelingWith)
						{
							response = QUEST_SHARE_MSG_BUSY;
							continue;
						}
						if(response > 0)
							sQuestMgr.SendPushToPartyResponse(_player, pPlayer, response);

						data.clear();
						sQuestMgr.BuildQuestDetails(&data, pQuest, pPlayer, 1, pPlayer->GetSession()->language, _player);
						pPlayer->GetSession()->SendPacket(&data);
						pPlayer->SetQuestSharer(pguid);
					}
				}
				_player->GetGroup()->Unlock();
			}
		}
	}
}
Esempio n. 23
0
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);
}
Esempio n. 24
0
void WorldSession::HandlePushQuestToPartyOpcode(WorldPacket & recv_data)
{
	CHECK_INWORLD_RETURN

	uint32 questid;
	recv_data >> questid;

	LOG_DETAIL("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, 9);
						data << uint64(pPlayer->GetGUID());
						data << uint8(QUEST_SHARE_MSG_SHARING_QUEST);
						_player->GetSession()->SendPacket(&data);

						uint8 response = QUEST_SHARE_MSG_SHARING_QUEST;
						uint32 status = sQuestMgr.PlayerMeetsReqs(pPlayer, pQuest, false);

						// Checks if the player has the quest
						if(pPlayer->GetQuestLogForEntry(questid))
						{
							response = QUEST_SHARE_MSG_HAVE_QUEST;
						}
						// Checks if the player has finished the quest
						else if(pPlayer->HasFinishedQuest(questid))
						{
							response = QUEST_SHARE_MSG_FINISH_QUEST;
						}
						// Checks if the player is able to take the quest
						else if(status != QMGR_QUEST_AVAILABLE && status != QMGR_QUEST_CHAT)
						{
							response = QUEST_SHARE_MSG_CANT_TAKE_QUEST;
						}
						// Checks if the player has room in his/her questlog
						else if(pPlayer->GetOpenQuestSlot() == -1)
						{
							response = QUEST_SHARE_MSG_LOG_FULL;
						}
						// Checks if the player is dueling
						else if(pPlayer->DuelingWith)   // || pPlayer->GetQuestSharer() ) //VLack: A possible lock up can occur if we don't zero out questsharer, because sometimes the client does not send the reply packet.. This of course eliminates the check on it, so it is possible to spam group members with quest sharing, but hey, they are YOUR FRIENDS, and better than not being able to receive quest sharing requests at all!
						{
							response = QUEST_SHARE_MSG_BUSY;
						}

						//VLack: The quest giver player has to be visible for pPlayer, or else the client will show a non-functional "complete quest" panel instead of the "accept quest" one!
						//We could either push a full player create for pPlayer that would cause problems later (because they are still out of range and this would have to be handled somehow),
						//or create a fake bad response, as we no longer have an out of range response. I'll go with the latter option and send that the other player is busy...
						//Also, pPlayer's client can send a busy response automatically even if the players see each other, but they are still too far away.
						//But sometimes nothing happens on pPlayer's client (near the end of mutual visibility line), no quest window and no busy response either. This has to be solved later, maybe a distance check here...
						if(response == QUEST_SHARE_MSG_SHARING_QUEST && !pPlayer->IsVisible(_player->GetGUID()))
						{
							response = QUEST_SHARE_MSG_BUSY;
						}

						if(response != QUEST_SHARE_MSG_SHARING_QUEST)
						{
							sQuestMgr.SendPushToPartyResponse(_player, pPlayer, response);
							continue;
						}

						data.clear();
						sQuestMgr.BuildQuestDetails(&data, pQuest, _player, 1, pPlayer->GetSession()->language, pPlayer);
						pPlayer->SetQuestSharer(pguid); //VLack: better to set this _before_ sending out the packet, so no race conditions can happen on heavily loaded servers.
						pPlayer->GetSession()->SendPacket(&data);
					}
				}
				_player->GetGroup()->Unlock();
			}
		}
	}
}