bool isHostile(Object* objA, Object* objB) // B is hostile for A? { bool hostile = false; // can't attack self.. this causes problems with buffs if we dont have it :p if(!objA || !objB || (objA == objB)) return false; // can't attack corpses neither... if(objA->GetTypeId() == TYPEID_CORPSE || objB->GetTypeId() == TYPEID_CORPSE) return false; if( objA->m_faction == NULL || objB->m_faction == NULL || objA->m_factionDBC == NULL || objB->m_factionDBC == NULL ) return true; uint32 faction = objB->m_faction->Mask; uint32 host = objA->m_faction->HostileMask; if(faction & host) 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 Player* player_objA = GetPlayerFromObject(objA); Player* player_objB = GetPlayerFromObject(objB); // BG or PVP? if( player_objA && player_objB ) { if( player_objA->m_bg != NULL ) { if( player_objA->m_bgTeam != player_objB->m_bgTeam ) return true; } if( hostile && player_objA->IsPvPFlagged()&& player_objB->IsPvPFlagged() ) return true; else return false; } // Reputation System Checks if(player_objA && !player_objB) // PvE { if(objB->m_factionDBC->RepListId >= 0) hostile = player_objA->IsHostileBasedOnReputation( objB->m_factionDBC ); } if(player_objB && !player_objA) // PvE { if(objA->m_factionDBC->RepListId >= 0) hostile = player_objB->IsHostileBasedOnReputation( objA->m_factionDBC ); } if( objA->IsPlayer() && objB->IsPlayer() && TO_PLAYER(objA)->m_bg != NULL ) { if( TO_PLAYER(objA)->m_bgTeam != TO_PLAYER(objB)->m_bgTeam ) return true; } return hostile; }
// 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? { // can't attack self.. this causes problems with buffs if we don't have it :p if( !objA || !objB || objA == objB ) return false; // can't attack corpses neither... if( objA->GetTypeId() == TYPEID_CORPSE || objB->GetTypeId() == TYPEID_CORPSE ) return false; // We do need all factiondata for this if( objB->m_factionDBC == NULL || objA->m_factionDBC == NULL || objB->m_faction == NULL || objA->m_faction == NULL ) return false; // Checks for untouchable, unattackable if( objA->IsUnit() && objA->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_9 | UNIT_FLAG_MOUNTED_TAXI | UNIT_FLAG_NOT_SELECTABLE)) return false; if( objB->IsUnit() && objB->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_9 | UNIT_FLAG_MOUNTED_TAXI | UNIT_FLAG_NOT_SELECTABLE)) return false; // we cannot attack sheathed units. Maybe checked in other places too ? // !! warning, this presumes that objA is attacking ObjB if( CheckStealth && objB->IsUnit() && TO_UNIT(objB)->InStealth() ) return false; // Get players (or owners of pets/totems) Player* player_objA = GetPlayerFromObject(objA); Player* player_objB = GetPlayerFromObject(objB); if( player_objA && player_objB ) { // Handle duels if( player_objA->DuelingWith == player_objB && player_objA->GetDuelState() == DUEL_STATE_STARTED ) return true; // These area's are sanctuaries for(uint32 i = 0; i < NUM_SANCTUARIES ; ++i) { if( player_objA->GetAreaID() == SANCTUARY_ZONES[i] || player_objB->GetAreaID() == SANCTUARY_ZONES[i]) return false; } // Players with feign death flags can't be attacked // But they can be attacked by another players. -- Dvlpr // WARNING: This presumes, that objA attacks objb!!! if( (objA->HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH) || objB->HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH)) && !objA->IsPlayer() ) return false; // do not let people attack each other in sanctuary // We know they aren't dueling AreaTable *atA = NULL; AreaTable *atB = NULL; atA = dbcArea.LookupEntry( player_objA->GetAreaID() ); atB = dbcArea.LookupEntry( player_objB->GetAreaID() ); if ( atA && atB && (atA->AreaFlags & AREA_SANCTUARY || atB->AreaFlags & AREA_SANCTUARY) ) return false; // Handle BG's if( player_objA->m_bg != NULL) { // Handle ffa_PVP if( player_objA->HasFlag(PLAYER_FLAGS,PLAYER_FLAG_FREE_FOR_ALL_PVP) && player_objA->HasFlag(PLAYER_FLAGS,PLAYER_FLAG_FREE_FOR_ALL_PVP)) { if( player_objA->GetGroup() == player_objB->GetGroup() ) return false; else return true; } // Handle Arenas if( player_objA->GetTeam() != player_objB->GetTeam() ) return true; } if(player_objA->IsFFAPvPFlagged() && player_objB->IsFFAPvPFlagged()) { if( player_objA->GetGroup() && player_objA->GetGroup() == player_objB->GetGroup() ) return false; if( player_objA == player_objB ) // Totems... return false; return true; // can hurt each other in FFA pvp } if( player_objA->GetAreaDBC() != NULL ) { if( player_objA->GetAreaDBC()->AreaFlags & 0x800 ) return false; } } // same faction can't kill each other. if(objA->m_faction == objB->m_faction) return false; // moved this from IsHostile(); // by doing so we skip a hell of a lot redundant checks, which we already passed in this routine. uint32 faction = objB->m_faction->Mask; uint32 host = objA->m_faction->HostileMask; bool hostile = false; if(faction & host) { 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; if(objA->m_faction->FriendlyFactions[i] == objB->m_faction->Faction) hostile = false; } } // Reputation System Checks if(player_objA && !player_objB) // PvE { if(objB->m_factionDBC->RepListId >= 0) hostile = player_objA->IsHostileBasedOnReputation( objB->m_factionDBC ); } if(player_objB && !player_objA) // PvE { if(objA->m_factionDBC->RepListId >= 0) hostile = player_objB->IsHostileBasedOnReputation( objA->m_factionDBC ); } // Neutral Creature Check if(player_objA) { if(objB->m_factionDBC->RepListId == -1 && objB->m_faction->HostileMask == 0 && objB->m_faction->FriendlyMask == 0) hostile = true; } else if(player_objB) { if(objA->m_factionDBC->RepListId == -1 && objA->m_faction->HostileMask == 0 && objA->m_faction->FriendlyMask == 0) hostile = true; } return hostile; }
/// Where we check if we object A can attack object B. This is used in many feature's /// Including the spell class, the player class, and the AI interface class. int intisAttackable(Object* objA, Object* objB, bool CheckStealth)// A can attack B? { // can't attack self.. this causes problems with buffs if we don't have it :p if( !objA || !objB || objA == objB ) return 0; // can't attack corpses neither... if( objA->GetTypeId() == TYPEID_CORPSE || objB->GetTypeId() == TYPEID_CORPSE ) return 0; // Dead people can't attack anything. if( (objA->IsUnit() && !TO_UNIT(objA)->isAlive()) || (objB->IsUnit() && !TO_UNIT(objB)->isAlive()) ) return 0; // Checks for untouchable, unattackable if( objA->IsUnit() && (objA->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_9) || objA->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNTED_TAXI) || objA->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))) return 0; if( objB->IsUnit() && (objB->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_9) || objB->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNTED_TAXI) || objB->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))) return 0; if(!objA->PhasedCanInteract(objB)) return 0; // we cannot attack sheathed units. Maybe checked in other places too ? // !! warning, this presumes that objA is attacking ObjB if( CheckStealth && objB->IsUnit() && TO_UNIT(objB)->InStealth() ) return 0; // Get players (or owners of pets/totems) Player* player_objA = GetPlayerFromObject(objA); Player* player_objB = GetPlayerFromObject(objB); if(objA->IsUnit() && objB->IsVehicle()) if(TO_VEHICLE(objB)->GetPassengerSlot(TO_UNIT(objA)) != -1) return 0; else if(objB->IsUnit() && objA->IsVehicle()) if(TO_VEHICLE(objA)->GetPassengerSlot(TO_UNIT(objB)) != -1) return 0; // Disable GM attacking. if(player_objA && player_objB && player_objA->bGMTagOn) return -1; // Disable GM attacking. if(player_objA && !player_objB && player_objA->bGMTagOn) return -1; // Don't allow players to attack GMs if(player_objA && player_objB && player_objB->bGMTagOn) return -1; // Creatures cannot attack a GM with tag on. if(!player_objA && player_objB && player_objB->bGMTagOn) return -1; if(objA->IsCreature() && isTargetDummy(objA->GetEntry())) return 0; // Bwahahaha if( player_objA && player_objB ) { if(player_objA->DuelingWith == player_objB && player_objA->GetDuelState() == DUEL_STATE_STARTED ) return 1; } else if(player_objA) { if(objB->IsPet() && TO_PET(objB)->GetOwner() == player_objA && player_objA->DuelingWith == player_objB) return 1; } else if(player_objB) { if(objA->IsPet() && TO_PET(objA)->GetOwner() == player_objB && player_objB->DuelingWith == player_objA) return 1; } else if(player_objA == NULL && player_objB == NULL) // Ignore players, we have critters in sanctuaries { // Do not let units attack each other in sanctuary // We know they aren't dueling if( (objA->GetAreaID() && sWorld.IsSanctuaryArea(objA->GetAreaID())) || objB->GetAreaID() && sWorld.IsSanctuaryArea(objB->GetAreaID())) return 0; if(sWorld.FunServerMall != -1 && (objA->GetAreaID() == (uint32)sWorld.FunServerMall || objB->GetAreaID() == (uint32)sWorld.FunServerMall)) return 0; } if(objA->IsCreature()) { if(objA->IsPet()) { if(player_objB) { if(TO_PET(objA)->GetOwner()) { if(TO_PET(objA)->GetOwner()->IsPvPFlagged() && !player_objB->IsPvPFlagged()) return 0; if(!TO_PET(objA)->GetOwner()->IsPvPFlagged() && !player_objB->IsPvPFlagged()) return 0; // the target is PvP, its okay. } else return 0; } } else if(TO_CREATURE(objA)->IsTotem()) { if(player_objB) { if(TO_CREATURE(objA)->GetSummonOwner()) { if(TO_PET(objA)->GetSummonOwner()->IsPvPFlagged() && !player_objB->IsPvPFlagged()) return 0; if(!TO_PET(objA)->GetSummonOwner()->IsPvPFlagged() && !player_objB->IsPvPFlagged()) return 0; // the target is PvP, its okay. } else return 0; } } } // We do need all factiondata for this if( objB->m_factionDBC == NULL || objA->m_factionDBC == NULL || objB->m_faction == NULL || objA->m_faction == NULL || (((objA->IsPlayer() && !TO_PLAYER(objA)->IsFFAPvPFlagged()) ? true : false) && ((objB->IsPlayer() && !TO_PLAYER(objB)->IsFFAPvPFlagged()) ? true : false) && (objB->m_factionDBC == objA->m_factionDBC || objB->m_faction == objA->m_faction))) return 0; if( player_objA && player_objB ) { if(sWorld.FunServerMall != -1 && (player_objA->GetAreaID() == (uint32)sWorld.FunServerMall || player_objB->GetAreaID() == (uint32)sWorld.FunServerMall)) return 0; if(player_objA->IsPvPFlagged() && !player_objB->IsPvPFlagged() && player_objA->DuelingWith != player_objB) return 0; if(!player_objA->IsPvPFlagged() && !player_objB->IsPvPFlagged() && player_objA->DuelingWith != player_objB) return 0; //These area's are sanctuaries if( sWorld.IsSanctuaryArea(player_objA->GetPlayerAreaID()) || sWorld.IsSanctuaryArea(player_objB->GetPlayerAreaID()) ) return 0; // Players with feign death flags can't be attacked // But they can be attacked by another players. -- Dvlpr // WARNING: This presumes, that objA attacks objb!!! if( (objA->HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH) || objB->HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH)) && !objA->IsPlayer() ) return 0; //Handle BG's if( player_objA->m_bg != NULL) { //Handle ffa_PVP if( player_objA->HasFlag(PLAYER_FLAGS,PLAYER_FLAG_FREE_FOR_ALL_PVP) && player_objA->HasFlag(PLAYER_FLAGS,PLAYER_FLAG_FREE_FOR_ALL_PVP)) { if( player_objA->GetGroup() == player_objB->GetGroup() ) return 0; else return 1; } //Handle Arenas if( player_objA->GetTeam() != player_objB->GetTeam() ) return 1; } if(player_objA->IsFFAPvPFlagged() && player_objB->IsFFAPvPFlagged()) { if( player_objA->GetGroup() && player_objA->GetGroup() == player_objB->GetGroup() ) return 0; if( player_objA == player_objB ) // Totems... return 0; return 1; // can hurt each other in FFA pvp } if( player_objA->GetAreaDBC() != NULL ) { if( player_objA->GetAreaDBC()->AreaFlags & 0x800 ) return 0; } return 1; // Skip the rest of this, it's all faction shit. } // same faction can't kill each other. if(objA->m_faction == objB->m_faction) return 0; // moved this from IsHostile(); // by doing so we skip a hell of a lot redundant checks, which we already passed in this routine. uint32 faction = objB->m_faction->Mask; uint32 host = objA->m_faction->HostileMask; bool hostile = false; if(faction & host) { 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; if(objA->m_faction->FriendlyFactions[i] == objB->m_faction->Faction) hostile = false; } } // Reputation System Checks if(player_objA) { if(objB->m_factionDBC->RepListId >= 0) hostile = player_objA->IsHostileBasedOnReputation( objB->m_factionDBC ); if(hostile == false) { if(objB->m_factionDBC->RepListId == -1 && objB->m_faction->HostileMask == 0 && objB->m_faction->FriendlyMask == 0) hostile = true; if(player_objA->bGMTagOn) hostile = true; } } else if(player_objB) { if(objA->m_factionDBC->RepListId >= 0) hostile = player_objB->IsHostileBasedOnReputation( objA->m_factionDBC ); if(hostile == false) if(objA->m_factionDBC->RepListId == -1 && objA->m_faction->HostileMask == 0 && objA->m_faction->FriendlyMask == 0) hostile = true; } return (hostile ? 1 : 0); }