예제 #1
0
bool isHostile(Object* objA, Object* objB)// B is hostile for A?
{
	if(!objA || !objB)
		return false;
	bool hostile = false;

  if ( !objA->IsInWorld() || !objB->IsInWorld() )  // pending or ...?
    return false;

	if(objA == objB)
		return false;   // can't attack self.. this causes problems with buffs if we don't have it :p

	if(objA->GetTypeId() == TYPEID_CORPSE)
		return false;

	if(objB->GetTypeId() == TYPEID_CORPSE)
		return false;

	if( !(objA->m_phase & objB->m_phase) ) //What you can't see, can't be hostile!
		return false;

	if( objA->IsPlayer() && objA->HasFlag( PLAYER_FLAGS, 0x100) && objB->IsCreature() && static_cast<Unit*>(objB)->GetAIInterface()->m_isNeutralGuard )
		return true;
	if( objB->IsPlayer() && objB->HasFlag( PLAYER_FLAGS, 0x100) && objA->IsCreature() && static_cast<Unit*>(objA)->GetAIInterface()->m_isNeutralGuard )
		return true;

    if( objB->IsUnit() && objB->HasFlag( UNIT_FIELD_FLAGS, 2 | 128 | 256 | 65536 ) )
        return false;

	int ret = isBgEnemy(objA, objB);
	if (ret != -1) return ret == 1;

	uint32 faction = objB->m_faction->Mask;
	uint32 host = objA->m_faction->HostileMask;

	/*if( faction != 0 )
	{*/
		if(faction & host)
		{
			hostile = true;
		}
	/*}
	else
	{
		// default to true
		hostile = true;
	}*/

		// anyway, this place won't fight
	AreaTable *atA = NULL;
	AreaTable *atB = NULL;

	if( objA->IsPlayer() )
		atA = dbcArea.LookupEntry( static_cast< Player* >( objA )->GetAreaID() );

	if( objB->IsPlayer() )
		atB = dbcArea.LookupEntry( static_cast< Player* >( objB )->GetAreaID() );

	if( ( atA && atA->AreaFlags & 0x800) || (atB && atB->AreaFlags & 0x800) ) // cebernic: fix older logic error
		return false;

	// check friend/enemy list
	for(uint32 i = 0; i < 4; i++)
	{
		if(objA->m_faction->EnemyFactions[i] == objB->m_faction->Faction)
		{
			hostile = true;
			break;
		}
		if(objA->m_faction->FriendlyFactions[i] == objB->m_faction->Faction)
		{
			hostile = false;
			break;
		}
	}

	// PvP Flag System Checks
	// We check this after the normal isHostile test, that way if we're
	// on the opposite team we'll already know :p
    

//////////////////////////////////////////// PvP checks /////////////////////////////////
    {
        Player *A = GetPlayerOwner( objA );
        Player *B = GetPlayerOwner( objB );

        if( hostile && A != NULL && B != NULL ){
			if( !B->IsSanctuaryFlagged() && ( B->IsPvPFlagged() || B->IsFFAPvPFlagged() ) )
                return true;
            else
                return false;
        }

    }
/////////////////////////////////////////////////////////////////////////////////////////

	// Reputation System Checks
	if(objA->IsPlayer() && !objB->IsPlayer())	   // PvE
	{
		if(objB->m_factionDBC->RepListId >= 0)
			hostile = static_cast< Player* >( objA )->IsHostileBasedOnReputation( objB->m_factionDBC );
	}
	
	if(objB->IsPlayer() && !objA->IsPlayer())	   // PvE
	{
		if(objA->m_factionDBC->RepListId >= 0)
			hostile = static_cast< Player* >( objB )->IsHostileBasedOnReputation( objA->m_factionDBC );
	}

	if( objA->IsPlayer() && objB->IsPlayer() && static_cast<Player*>(objA)->m_bg != NULL )
	{
		if( static_cast<Player*>(objA)->m_bgTeam != static_cast<Player*>(objB)->m_bgTeam )
			return true;
	}

	return hostile;
}
예제 #2
0
파일: faction.cpp 프로젝트: Chero/abcwow
bool isHostile(Object* objA, Object* objB)// B is hostile for A?
{
	if(!objA || !objB)
		return false;
	bool hostile = false;

//	if(objB->m_faction == NULL || objA->m_faction == NULL)
//		return true;

	if(objA == objB)
		return false;   // can't attack self.. this causes problems with buffs if we dont have it :p

	if(objA->GetTypeId() == TYPEID_CORPSE)
		return false;

	if(objB->GetTypeId() == TYPEID_CORPSE)
		return false;

	int ret = isBgEnemy(objA, objB);
	if (ret != -1) return ret == 1;

	uint32 faction = objB->m_faction->Mask;
	uint32 host = objA->m_faction->HostileMask;

	/*if( faction != 0 )
	{*/
		if(faction & host)
		{
			hostile = true;
		}
	/*}
	else
	{
		// default to true
		hostile = true;
	}*/

	// check friend/enemy list
	for(uint32 i = 0; i < 4; i++)
	{
		if(objA->m_faction->EnemyFactions[i] == objB->m_faction->Faction)
		{
			hostile = true;
			break;
		}
		if(objA->m_faction->FriendlyFactions[i] == objB->m_faction->Faction)
		{
			hostile = false;
			break;
		}
	}

	// PvP Flag System Checks
	// We check this after the normal isHostile test, that way if we're
	// on the opposite team we'll already know :p

	if( hostile && ( objA->IsPlayer() || objA->IsPet() || ( objA->IsUnit() && !objA->IsPlayer() && static_cast< Creature* >( objA )->IsTotem() && static_cast< Creature* >( objA )->GetTotemOwner()->IsPvPFlagged() ) ) )
	{
		if( objB->IsPlayer() )
		{
			// Check PvP Flags.
			if( static_cast< Player* >( objB )->IsPvPFlagged() )
				return true;
			else
				return false;
		}
		if( objB->IsPet() )
		{
#if defined(WIN32) && defined(HACKY_CRASH_FIXES)
			__try {
				// Check PvP Flags.
				if( static_cast< Pet* >( objB )->GetPetOwner() != NULL && static_cast< Pet* >( objB )->GetPetOwner()->GetMapMgr() == objB->GetMapMgr() && static_cast< Pet* >( objB )->GetPetOwner()->IsPvPFlagged() )
					return true;
				else
					return false;
			} __except(EXCEPTION_EXECUTE_HANDLER)
			{
				static_cast<Pet*>(objB)->ClearPetOwner();
				static_cast<Pet*>(objB)->SafeDelete();
			}
#else
			// Check PvP Flags.
			if( static_cast< Pet* >( objB )->GetPetOwner() != NULL && static_cast< Pet* >( objB )->GetPetOwner()->GetMapMgr() == objB->GetMapMgr() && static_cast< Pet* >( objB )->GetPetOwner()->IsPvPFlagged() )
				return true;
			else
				return false;
#endif
		}
	}
예제 #3
0
/// Where we check if we object A can attack object B. This is used in many feature's
/// Including the spell class and the player class.
bool isAttackable(Object* objA, Object* objB, bool CheckStealth)// A can attack B?
{
	if(!objA || !objB )
		return false;

	if ( !objA->IsInWorld() || !objB->IsInWorld() )  // pending or ...?
		return false;

	if(objA == objB)
		return false;   // can't attack self.. this causes problems with buffs if we don't have it :p

	if( !(objA->m_phase & objB->m_phase) ) //What you can't see, you can't attack either...
		return false;

	if(objA->GetTypeId() == TYPEID_CORPSE)
		return false;

	if(objB->GetTypeId() == TYPEID_CORPSE)
		return false;

	// Players in feign death flags can't be attacked (where did you get this information from?)
	// Changed by Supa: Creatures cannot attack players with feign death flags.
	/*if(!objA->IsPlayer())
		if(objA->HasFlag(UNIT_FIELD_FLAGS_2, 0x00000001))
			return false;
	if(!objB->IsPlayer())
		if(objB->HasFlag(UNIT_FIELD_FLAGS_2, 0x00000001))
			return false;*/

	// Checks for untouchable, unattackable
	if(objA->IsUnit() && objA->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNTED_TAXI | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_DEAD))
		return false;
	if(objB->IsUnit())
	{
		if(objB->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNTED_TAXI | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_DEAD))
			return false;

		/// added by Zack : 
        /// we cannot attack shealthed units. Maybe checked in other places too ?
		/// !! warning, this presumes that objA is attacking ObjB
        /// Capt: Added the possibility to disregard this (regarding the spell class)
		if(static_cast<Unit *>(objB)->IsStealth() && CheckStealth)
			return false;
	}

	int ret = isBgEnemy(objA, objB);
	if (ret != -1) return ret == 1;

	if(objA->IsPlayer() && objB->IsPlayer())
	{
		if(
			static_cast< Player* >( objA )->DuelingWith == static_cast< Player* >(objB) && 
			static_cast< Player* >( objA )->GetDuelState() == DUEL_STATE_STARTED
			)
		return true;

		//players in same group should not attack each other. Required for arenas with mixed groups
		if( static_cast< Player* >( objA )->GetGroup() && static_cast< Player* >( objA )->GetGroup() == static_cast< Player* >( objB )->GetGroup() )
			return false;

		if(objA->HasFlag(PLAYER_FLAGS,PLAYER_FLAG_FREE_FOR_ALL_PVP) && objB->HasFlag(PLAYER_FLAGS,PLAYER_FLAG_FREE_FOR_ALL_PVP))
		{
			if(static_cast< Player* >( objA )->m_bg != NULL && static_cast< Player* >( objB )->m_bg != NULL)
				if(static_cast< Player* >( objA )->m_bgTeam == static_cast< Player* >( objB )->m_bgTeam)
					return false;

			if( static_cast< Player* >( objA )->m_bg != NULL )
				if( static_cast< Player* >( objA )->GetGroup() == static_cast< Player* >( objB )->GetGroup() )
					return false;

			return true;		// can hurt each other in FFA pvp
		}
	}
	
	// handle for pets in duel
	if(objA->IsPet())
	{
		if(objB->IsPlayer())
		{
			if(
				static_cast<Pet *>(objA)->GetPetOwner() )
			{
				if(	static_cast<Pet *>(objA)->GetPetOwner()->DuelingWith == static_cast< Player* >(objB) && 
					static_cast<Pet *>(objA)->GetPetOwner()->GetDuelState() == DUEL_STATE_STARTED )
					return true;
				if(	static_cast<Pet *>(objA)->GetPetOwner()->m_bg &&
					static_cast<Pet *>(objA)->GetPetOwner()->m_bgTeam != static_cast< Player* >(objB)->m_bgTeam	)
					return true;
				//players in same group should not attack each other. Required for arenas with mixed groups
				if( static_cast<Player *>(objB)->GetGroup() && 
					static_cast<Pet *>(objA)->GetGroup() == static_cast< Player* >( objB )->GetGroup() )
					return false;
			}
		}
		else if(objB->IsPet())
		{
			if(static_cast<Pet *>(objA)->GetPetOwner() && static_cast<Pet *>(objB)->GetPetOwner())
			{
				if(	static_cast<Pet *>(objA)->GetPetOwner()->DuelingWith == static_cast<Pet *>(objB)->GetPetOwner() && 
				static_cast<Pet *>(objA)->GetPetOwner()->GetDuelState() == DUEL_STATE_STARTED
				)
					return true;
				if(	static_cast<Pet *>(objA)->GetPetOwner()->m_bg &&
					static_cast<Pet *>(objA)->GetPetOwner()->m_bgTeam != static_cast<Pet *>(objB)->GetPetOwner()->m_bgTeam )
					return true;
				//players in same group should not attack each other. Required for arenas with mixed groups
				if( static_cast<Pet *>(objA)->GetGroup() && 
					static_cast<Pet *>(objA)->GetGroup() == static_cast<Pet *>(objB)->GetGroup() )
					return false;
			}
		}
	}
	if(objB->IsPet())
	{
		if(objA->IsPlayer())
		{
			if( static_cast<Pet*>(objB)->GetPetOwner() )
			{
				if(	static_cast<Pet *>(objB)->GetPetOwner()->DuelingWith == static_cast< Player* >(objA) && 
					static_cast<Pet *>(objB)->GetPetOwner()->GetDuelState() == DUEL_STATE_STARTED )
				return true;
				//players in same group should not attack each other. Required for arenas with mixed groups
				if( static_cast<Player *>(objA)->GetGroup() && 
					static_cast<Pet *>(objB)->GetGroup() == static_cast< Player* >( objA )->GetGroup() )
					return false;
			}
		}
		//we already made this check a few lines before : if A -> B
/*		else if(objA->IsPet())
		{
			if(static_cast<Pet*>(objA)->GetPetOwner() && static_cast<Pet *>(objB)->GetPetOwner() &&
				static_cast<Pet*>(objB)->GetPetOwner() &&
				static_cast<Pet *>(objB)->GetPetOwner()->DuelingWith == static_cast<Pet *>(objA)->GetPetOwner() && 
				static_cast<Pet *>(objB)->GetPetOwner()->GetDuelState() == DUEL_STATE_STARTED
				)
				return true;
		}*/
	}

	// handle for totems
	if( objA->IsCreature() && static_cast<Creature *>(objA)->IsTotem() ) 
	{
		if(objB->IsPlayer())
		{
			if( static_cast<Creature *>(objA)->GetTotemOwner() &&
				static_cast<Creature *>(objA)->GetTotemOwner()->DuelingWith == static_cast< Player* >(objB) && 
				static_cast<Creature *>(objA)->GetTotemOwner()->GetDuelState() == DUEL_STATE_STARTED
				)
				return true;
			if( static_cast<Creature *>(objA)->GetTotemOwner()->m_bg &&
				static_cast<Creature *>(objA)->GetTotemOwner()->m_bgTeam != static_cast< Player* >(objB)->m_bgTeam )
				return true;
			//players in same group should not attack each other. Required for arenas with mixed groups
			if( static_cast<Player *>(objB)->GetGroup() && 
				static_cast<Creature *>(objA)->GetGroup() == static_cast< Player* >( objB )->GetGroup() )
				return false;
		}
		if( static_cast<Creature *>(objA)->GetTotemOwner() )
		{
			if( objB->IsPet() )
			{
				if(	static_cast<Creature *>(objA)->GetTotemOwner()->DuelingWith == static_cast<Pet *>(objB)->GetPetOwner() && 
					static_cast<Creature *>(objA)->GetTotemOwner()->GetDuelState() == DUEL_STATE_STARTED
					)
					return true;
				//players in same group should not attack each other. Required for arenas with mixed groups
				if( static_cast<Pet *>(objB)->GetGroup() && 
					static_cast<Creature *>(objA)->GetGroup() == static_cast<Pet *>(objB)->GetGroup() )
					return false;
			}
			else if( objB->IsCreature() && static_cast<Creature *>(objB)->IsTotem() )
			{
				if(	static_cast<Creature *>(objA)->GetTotemOwner()->DuelingWith == static_cast<Creature *>(objB)->GetTotemOwner() && 
					static_cast<Creature *>(objA)->GetTotemOwner()->GetDuelState() == DUEL_STATE_STARTED
					)
					return true;
				//players in same group should not attack each other. Required for arenas with mixed groups
				if( static_cast<Creature *>(objA)->GetGroup() && 
					static_cast<Creature *>(objA)->GetGroup() == static_cast<Creature *>(objB)->GetGroup() )
					return false;
			}
		}
		
	}
	if( objB->IsCreature() && static_cast<Creature *>(objB)->IsTotem() ) // must be creature
	{
		if(objA->IsPlayer() && static_cast<Creature *>(objB)->GetTotemOwner())
		{
			if( static_cast<Creature *>(objB)->GetTotemOwner()->DuelingWith == static_cast< Player* >(objA) && 
				static_cast<Creature *>(objB)->GetTotemOwner()->GetDuelState() == DUEL_STATE_STARTED )
				return true;
			//players in same group should not attack each other. Required for arenas with mixed groups
			if( static_cast<Player *>(objA)->GetGroup() && 
				static_cast<Creature *>(objB)->GetGroup() == static_cast< Player* >( objA )->GetGroup() )
				return false;
		}
		if(objA->IsPet() && static_cast<Creature *>(objB)->GetTotemOwner() )
		{
			if( static_cast<Creature *>(objB)->GetTotemOwner()->DuelingWith == static_cast<Pet *>(objA)->GetPetOwner() && 
			static_cast<Creature *>(objB)->GetTotemOwner()->GetDuelState() == DUEL_STATE_STARTED
			)
				return true;
			//players in same group should not attack each other. Required for arenas with mixed groups
			if( static_cast<Creature *>(objB)->GetGroup() && 
				static_cast<Creature *>(objB)->GetGroup() == static_cast< Pet* >( objA )->GetGroup() )
				return false;
		}
	}

	// do not let people attack each other in sanctuary
	// Dueling is already catered for
	AreaTable *atA = NULL;
	AreaTable *atB = NULL;

	// cebernic: don't forget totem

	if ( objA->IsCreature() )
	{
		if( static_cast<Creature *>(objA)->IsTotem() && static_cast< Creature* >( objA )->GetTotemOwner() )
			atA = dbcArea.LookupEntry( static_cast< Creature* >( objA )->GetTotemOwner()->GetAreaID() );
		else
		if( objA->IsPet() && static_cast< Pet* >( objA )->GetPetOwner() )
			atA = dbcArea.LookupEntry( static_cast< Pet* >( objA )->GetPetOwner()->GetAreaID() );
	}
	
	if ( objB->IsCreature() )
	{
		if( static_cast<Creature *>(objB)->IsTotem() && static_cast< Creature* >( objB )->GetTotemOwner() )
			atB = dbcArea.LookupEntry( static_cast< Creature* >( objB )->GetTotemOwner()->GetAreaID() );
		else if( objB->IsPet() && static_cast< Pet* >( objB )->GetPetOwner() )
			atB = dbcArea.LookupEntry( static_cast< Pet* >( objB )->GetPetOwner()->GetAreaID() );
/*		if ( atB== NULL ) {
			Unit *_creator = objB->GetMapMgr()->GetUnit( objB->GetUInt64Value( UNIT_FIELD_CREATEDBY ) );
			if( _creator!= NULL && _creator->IsCreature() && _creator->GetMapMgr() ){
//				printf("%s\n",__ansi(static_cast< Creature* >( _creator )->GetCreatureInfo()->Name ));
				atB = dbcArea.LookupEntry( _creator->GetMapMgr()->GetAreaID(_creator->GetPositionX(),_creator->GetPositionY())  );	
			}*/
//		}
	}			
		
	if( objA->IsPlayer() )
		atA = dbcArea.LookupEntry( static_cast< Player* >( objA )->GetAreaID() );

	if( objB->IsPlayer() )
		atB = dbcArea.LookupEntry( static_cast< Player* >( objB )->GetAreaID() );

	// We have the area codes
	// We know they aren't dueling
	if( ( atA && atA->AreaFlags & 0x800) || (atB && atB->AreaFlags & 0x800) ) // cebernic: fix older logic error
		return false;

	if(objA->m_faction == objB->m_faction)  // same faction can't kill each other unless in ffa pvp/duel
		return false;

	bool attackable = isHostile(objA, objB); // B is attackable if its hostile for A
	/*if((objA->m_faction->HostileMask & 8) && (objB->m_factionDBC->RepListId != 0) && 
		(objB->GetTypeId() != TYPEID_PLAYER) && objB->m_faction->Faction != 31) // B is attackable if its a neutral Creature*/

	// Neutral Creature Check
	if(objA->IsPlayer() || objA->IsPet())
	{
		if(objB->m_factionDBC->RepListId == -1 && objB->m_faction->HostileMask == 0 && objB->m_faction->FriendlyMask == 0)
		{
			attackable = true;
		}
	}
	else if(objB->IsPlayer() || objB->IsPet())
	{
		if(objA->m_factionDBC->RepListId == -1 && objA->m_faction->HostileMask == 0 && objA->m_faction->FriendlyMask == 0)
		{
			attackable = true;
		}
	}

	return attackable;
}