aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorQAston <qaston@gmail.com>2011-09-15 17:44:03 +0200
committerQAston <qaston@gmail.com>2011-09-15 17:44:03 +0200
commite07535c3e3b9df05c894557b675ccf95bf7a622b (patch)
tree69af39ede1eb45c822abd0a293b281192208962b /src/server
parentaf05915b9e36497eda8f2f061c29ffee0c8042b6 (diff)
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).
Diffstat (limited to 'src/server')
-rwxr-xr-xsrc/server/game/DataStores/DBCEnums.h1
-rwxr-xr-xsrc/server/game/DataStores/DBCStructure.h10
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp126
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h6
-rwxr-xr-xsrc/server/game/Reputation/ReputationMgr.cpp23
-rwxr-xr-xsrc/server/game/Reputation/ReputationMgr.h5
6 files changed, 166 insertions, 5 deletions
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 0a4c6b70b9f..dcdc2b2ea0a 100755
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -307,6 +307,7 @@ enum FactionTemplateFlags
{
FACTION_TEMPLATE_FLAG_PVP = 0x00000800, // flagged for PvP
FACTION_TEMPLATE_FLAG_CONTESTED_GUARD = 0x00001000, // faction will attack players that were involved in PvP combats
+ FACTION_TEMPLATE_FLAG_HOSTILE_BY_DEFAULT= 0x00002000,
};
enum FactionMasks
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index ff91964230a..431e803fa87 100755
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -870,6 +870,12 @@ struct FactionEntry
// 39 string flags
//char* description[16]; // 40-55 m_description_lang
// 56 string flags
+
+ // helpers
+ bool CanHaveReputation() const
+ {
+ return reputationListID >=0;
+ }
};
#define MAX_FACTION_RELATIONS 4
@@ -889,8 +895,6 @@ struct FactionTemplateEntry
// helpers
bool IsFriendlyTo(FactionTemplateEntry const& entry) const
{
- if (ID == entry.ID)
- return true;
if (entry.faction)
{
for (int i = 0; i < MAX_FACTION_RELATIONS; ++i)
@@ -904,8 +908,6 @@ struct FactionTemplateEntry
}
bool IsHostileTo(FactionTemplateEntry const& entry) const
{
- if (ID == entry.ID)
- return false;
if (entry.faction)
{
for (int i = 0; i < MAX_FACTION_RELATIONS; ++i)
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 29df2c20442..01410c19f99 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -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())
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 19fa017e37c..a1566f14434 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -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);
diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp
index 0aaa3da0a38..a82764c62f9 100755
--- a/src/server/game/Reputation/ReputationMgr.cpp
+++ b/src/server/game/Reputation/ReputationMgr.cpp
@@ -39,6 +39,29 @@ ReputationRank ReputationMgr::ReputationToRank(int32 standing)
return MIN_REPUTATION_RANK;
}
+bool ReputationMgr::IsAtWar(uint32 faction_id) const
+{
+ FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id);
+
+ if (!factionEntry)
+ {
+ sLog->outError("ReputationMgr::IsAtWar: Can't get AtWat flag of %s for unknown faction (faction id) #%u.", m_player->GetName(), faction_id);
+ return 0;
+ }
+
+ return IsAtWar(factionEntry);
+}
+
+bool ReputationMgr::IsAtWar(FactionEntry const* factionEntry) const
+{
+ if (!factionEntry)
+ return false;
+
+ if (FactionState const* factionState = GetState(factionEntry))
+ return (factionState->Flags & FACTION_FLAG_AT_WAR);
+ return false;
+}
+
int32 ReputationMgr::GetReputation(uint32 faction_id) const
{
FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id);
diff --git a/src/server/game/Reputation/ReputationMgr.h b/src/server/game/Reputation/ReputationMgr.h
index bb22f46585a..59ec826f0c5 100755
--- a/src/server/game/Reputation/ReputationMgr.h
+++ b/src/server/game/Reputation/ReputationMgr.h
@@ -86,7 +86,7 @@ class ReputationMgr
FactionState const* GetState(FactionEntry const* factionEntry) const
{
- return factionEntry->reputationListID >= 0 ? GetState(factionEntry->reputationListID) : NULL;
+ return factionEntry->CanHaveReputation() ? GetState(factionEntry->reputationListID) : NULL;
}
FactionState const* GetState(RepListID id) const
@@ -95,6 +95,9 @@ class ReputationMgr
return repItr != m_factions.end() ? &repItr->second : NULL;
}
+ bool IsAtWar(uint32 faction_id) const;
+ bool IsAtWar(FactionEntry const* factionEntry) const;
+
int32 GetReputation(uint32 faction_id) const;
int32 GetReputation(FactionEntry const* factionEntry) const;
int32 GetBaseReputation(FactionEntry const* factionEntry) const;