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; }
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 } }
/// 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; }