Core/Entities: Add new functions: Unit::GetReactionTo and Unit::GetFactionReactionTo for more direct reaction checks than Unit::IsFriendly/HostileTo (those functions have many duplicated code and have many checks unrelated to unit reaction).
This commit is contained in:
@@ -9239,6 +9239,122 @@ FactionTemplateEntry const* Unit::getFactionTemplateEntry() const
|
||||
return entry;
|
||||
}
|
||||
|
||||
ReputationRank Unit::GetReactionTo(Unit const* target) const
|
||||
{
|
||||
// always friendly to self
|
||||
if (this == target)
|
||||
return REP_FRIENDLY;
|
||||
|
||||
// always friendly to charmer or owner
|
||||
if (GetCharmerOrOwnerOrSelf() == target->GetCharmerOrOwnerOrSelf())
|
||||
return REP_FRIENDLY;
|
||||
|
||||
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE))
|
||||
{
|
||||
if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE))
|
||||
{
|
||||
Player const* selfPlayerOwner = GetAffectingPlayer();
|
||||
Player const* targetPlayerOwner = target->GetAffectingPlayer();
|
||||
|
||||
if (selfPlayerOwner && targetPlayerOwner)
|
||||
{
|
||||
// always friendly to other unit controlled by player, or to the player himself
|
||||
if (selfPlayerOwner == targetPlayerOwner)
|
||||
return REP_FRIENDLY;
|
||||
|
||||
// duel - always hostile to opponent
|
||||
if (selfPlayerOwner->duel && selfPlayerOwner->duel->opponent == targetPlayerOwner && selfPlayerOwner->duel->startTime != 0)
|
||||
return REP_HOSTILE;
|
||||
|
||||
// same group - checks dependant only on our faction - skip FFA_PVP for example
|
||||
if (selfPlayerOwner->IsInRaidWith(targetPlayerOwner))
|
||||
return GetFactionReactionTo(getFactionTemplateEntry(), target);
|
||||
}
|
||||
|
||||
// check FFA_PVP
|
||||
if (GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_FFA_PVP
|
||||
&& target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_FFA_PVP)
|
||||
return REP_HOSTILE;
|
||||
|
||||
if (selfPlayerOwner)
|
||||
{
|
||||
if (FactionTemplateEntry const* targetFactionTemplateEntry = target->getFactionTemplateEntry())
|
||||
{
|
||||
if (ReputationRank const* repRank = selfPlayerOwner->GetReputationMgr().GetForcedRankIfAny(targetFactionTemplateEntry))
|
||||
return *repRank;
|
||||
if (!selfPlayerOwner->HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_IGNORE_REPUTATION))
|
||||
{
|
||||
if (FactionEntry const* targetFactionEntry = sFactionStore.LookupEntry(targetFactionTemplateEntry->faction))
|
||||
{
|
||||
if (targetFactionEntry->CanHaveReputation())
|
||||
{
|
||||
// check contested flags
|
||||
if (targetFactionTemplateEntry->factionFlags & FACTION_TEMPLATE_FLAG_CONTESTED_GUARD
|
||||
&& selfPlayerOwner->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP))
|
||||
return REP_HOSTILE;
|
||||
|
||||
// if faction have reputation then hostile state dependent only from at_war state
|
||||
if (selfPlayerOwner->GetReputationMgr().IsAtWar(targetFactionEntry))
|
||||
return REP_HOSTILE;
|
||||
return REP_FRIENDLY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// do checks dependant only on our faction
|
||||
return GetFactionReactionTo(getFactionTemplateEntry(), target);
|
||||
}
|
||||
|
||||
ReputationRank Unit::GetFactionReactionTo(FactionTemplateEntry const* factionTemplateEntry, Unit const* target)
|
||||
{
|
||||
// always neutral when no template entry found
|
||||
if (!factionTemplateEntry)
|
||||
return REP_NEUTRAL;
|
||||
|
||||
FactionTemplateEntry const* targetFactionTemplateEntry = target->getFactionTemplateEntry();
|
||||
if (!targetFactionTemplateEntry)
|
||||
return REP_NEUTRAL;
|
||||
|
||||
if (Player const* targetPlayerOwner = target->GetAffectingPlayer())
|
||||
{
|
||||
// check contested flags
|
||||
if (factionTemplateEntry->factionFlags & FACTION_TEMPLATE_FLAG_CONTESTED_GUARD
|
||||
&& targetPlayerOwner->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP))
|
||||
return REP_HOSTILE;
|
||||
if (ReputationRank const* repRank = targetPlayerOwner->GetReputationMgr().GetForcedRankIfAny(factionTemplateEntry))
|
||||
return *repRank;
|
||||
if (!target->HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_IGNORE_REPUTATION))
|
||||
{
|
||||
if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionTemplateEntry->faction))
|
||||
{
|
||||
if (factionEntry->CanHaveReputation())
|
||||
{
|
||||
// CvP case - check reputation, don't allow state higher than neutral when at war
|
||||
ReputationRank repRank = targetPlayerOwner->GetReputationMgr().GetRank(factionEntry);
|
||||
if (targetPlayerOwner->GetReputationMgr().IsAtWar(factionEntry))
|
||||
repRank = std::min(REP_NEUTRAL, repRank);
|
||||
return repRank;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// common faction based check
|
||||
if (factionTemplateEntry->IsHostileTo(*targetFactionTemplateEntry))
|
||||
return REP_HOSTILE;
|
||||
if (factionTemplateEntry->IsFriendlyTo(*targetFactionTemplateEntry))
|
||||
return REP_FRIENDLY;
|
||||
if (targetFactionTemplateEntry->IsFriendlyTo(*factionTemplateEntry))
|
||||
return REP_FRIENDLY;
|
||||
if (factionTemplateEntry->factionFlags & FACTION_TEMPLATE_FLAG_HOSTILE_BY_DEFAULT)
|
||||
return REP_HOSTILE;
|
||||
// neutral by default
|
||||
return REP_NEUTRAL;
|
||||
}
|
||||
|
||||
bool Unit::IsHostileTo(Unit const* unit) const
|
||||
{
|
||||
if (!unit)
|
||||
@@ -9797,6 +9913,16 @@ Player* Unit::GetCharmerOrOwnerPlayerOrPlayerItself() const
|
||||
return GetTypeId() == TYPEID_PLAYER ? (Player*)this : NULL;
|
||||
}
|
||||
|
||||
Player* Unit::GetAffectingPlayer() const
|
||||
{
|
||||
if (!GetCharmerOrOwnerGUID())
|
||||
return GetTypeId() == TYPEID_PLAYER ? (Player*)this : NULL;
|
||||
|
||||
if (Unit* owner = GetCharmerOrOwner())
|
||||
return owner->GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Minion *Unit::GetFirstMinion() const
|
||||
{
|
||||
if (uint64 pet_guid = GetMinionGUID())
|
||||
|
||||
@@ -611,6 +611,7 @@ enum UnitFlags2
|
||||
{
|
||||
UNIT_FLAG2_FEIGN_DEATH = 0x00000001,
|
||||
UNIT_FLAG2_UNK1 = 0x00000002, // Hide unit model (show only player equip)
|
||||
UNIT_FLAG2_IGNORE_REPUTATION = 0x00000004,
|
||||
UNIT_FLAG2_COMPREHEND_LANG = 0x00000008,
|
||||
UNIT_FLAG2_MIRROR_IMAGE = 0x00000010,
|
||||
UNIT_FLAG2_FORCE_MOVE = 0x00000040,
|
||||
@@ -1386,6 +1387,10 @@ class Unit : public WorldObject
|
||||
uint32 getFaction() const { return GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE); }
|
||||
void setFaction(uint32 faction) { SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, faction); }
|
||||
FactionTemplateEntry const* getFactionTemplateEntry() const;
|
||||
|
||||
ReputationRank GetReactionTo(Unit const* target) const;
|
||||
ReputationRank static GetFactionReactionTo(FactionTemplateEntry const* factionTemplateEntry, Unit const* target);
|
||||
|
||||
bool IsHostileTo(Unit const* unit) const;
|
||||
bool IsHostileToPlayers() const;
|
||||
bool IsFriendlyTo(Unit const* unit) const;
|
||||
@@ -1662,6 +1667,7 @@ class Unit : public WorldObject
|
||||
return (Unit*)this;
|
||||
}
|
||||
Player* GetCharmerOrOwnerPlayerOrPlayerItself() const;
|
||||
Player* GetAffectingPlayer() const;
|
||||
|
||||
void SetMinion(Minion *minion, bool apply);
|
||||
void GetAllMinionsByEntry(std::list<Creature*>& Minions, uint32 entry);
|
||||
|
||||
Reference in New Issue
Block a user