mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-22 18:15:31 +01:00
Core/Conditions: Added conditions for object visibility (#27565)
This commit is contained in:
@@ -82,7 +82,8 @@ char const* const ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX]
|
||||
"AreaTrigger",
|
||||
"ConversationLine",
|
||||
"AreaTrigger Client Triggered",
|
||||
"Trainer Spell"
|
||||
"Trainer Spell",
|
||||
"Object Visibility (by ID)"
|
||||
};
|
||||
|
||||
ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[CONDITION_MAX] =
|
||||
@@ -954,7 +955,8 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType)
|
||||
sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_PHASE ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_AREATRIGGER ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_TRAINER_SPELL);
|
||||
sourceType == CONDITION_SOURCE_TYPE_TRAINER_SPELL ||
|
||||
sourceType == CONDITION_SOURCE_TYPE_OBJECT_ID_VISIBILITY);
|
||||
}
|
||||
|
||||
bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType)
|
||||
@@ -1096,6 +1098,16 @@ bool ConditionMgr::IsObjectMeetingTrainerSpellConditions(uint32 trainerId, uint3
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConditionMgr::IsObjectMeetingVisibilityByObjectIdConditions(uint32 objectType, uint32 entry, WorldObject* seer) const
|
||||
{
|
||||
if (ConditionContainer const* conditions = Trinity::Containers::MapGetValuePtr(ObjectVisibilityConditionStore, { objectType, entry }))
|
||||
{
|
||||
TC_LOG_DEBUG("condition", "IsObjectMeetingVisibilityByObjectIdConditions: found conditions for objectType %u entry %u", objectType, entry);
|
||||
return IsObjectMeetToConditions(seer, *conditions);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ConditionMgr* ConditionMgr::instance()
|
||||
{
|
||||
static ConditionMgr instance;
|
||||
@@ -1348,6 +1360,13 @@ void ConditionMgr::LoadConditions(bool isReload)
|
||||
++count;
|
||||
continue;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_OBJECT_ID_VISIBILITY:
|
||||
{
|
||||
ObjectVisibilityConditionStore[{ cond->SourceGroup, uint32(cond->SourceEntry) }].push_back(cond);
|
||||
valid = true;
|
||||
++count;
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1992,6 +2011,37 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_OBJECT_ID_VISIBILITY:
|
||||
{
|
||||
if (cond->SourceGroup <= 0 || cond->SourceGroup >= NUM_CLIENT_OBJECT_TYPES)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, is no valid object type, ignoring.", cond->ToString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cond->SourceGroup == TYPEID_UNIT)
|
||||
{
|
||||
if (!sObjectMgr->GetCreatureTemplate(cond->SourceEntry))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (cond->SourceGroup == TYPEID_GAMEOBJECT)
|
||||
{
|
||||
if (!sObjectMgr->GetGameObjectTemplate(cond->SourceEntry))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `gameobject_template`, ignoring.", cond->ToString().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, uses unchecked type id, ignoring.", cond->ToString().c_str());
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
TC_LOG_ERROR("sql.sql", "%s Invalid ConditionSourceType in `condition` table, ignoring.", cond->ToString().c_str());
|
||||
return false;
|
||||
@@ -2585,6 +2635,12 @@ void ConditionMgr::Clean()
|
||||
|
||||
TrainerSpellConditionContainerStore.clear();
|
||||
|
||||
for (auto&& [_, conditions] : ObjectVisibilityConditionStore)
|
||||
for (Condition* condition : conditions)
|
||||
delete condition;
|
||||
|
||||
ObjectVisibilityConditionStore.clear();
|
||||
|
||||
// this is a BIG hack, feel free to fix it if you can figure out the ConditionMgr ;)
|
||||
for (std::vector<Condition*>::const_iterator itr = AllocatedMemoryStore.begin(); itr != AllocatedMemoryStore.end(); ++itr)
|
||||
delete *itr;
|
||||
|
||||
@@ -174,7 +174,8 @@ enum ConditionSourceType
|
||||
CONDITION_SOURCE_TYPE_CONVERSATION_LINE = 29,
|
||||
CONDITION_SOURCE_TYPE_AREATRIGGER_CLIENT_TRIGGERED = 30,
|
||||
CONDITION_SOURCE_TYPE_TRAINER_SPELL = 31,
|
||||
CONDITION_SOURCE_TYPE_MAX = 32 // MAX
|
||||
CONDITION_SOURCE_TYPE_OBJECT_ID_VISIBILITY = 32,
|
||||
CONDITION_SOURCE_TYPE_MAX = 33 // MAX
|
||||
};
|
||||
|
||||
enum RelationType
|
||||
@@ -298,6 +299,7 @@ class TC_GAME_API ConditionMgr
|
||||
|
||||
ConditionContainer const* GetConditionsForAreaTrigger(uint32 areaTriggerId, bool isServerSide) const;
|
||||
bool IsObjectMeetingTrainerSpellConditions(uint32 trainerId, uint32 spellId, Player* player) const;
|
||||
bool IsObjectMeetingVisibilityByObjectIdConditions(uint32 objectType, uint32 entry, WorldObject* seer) const;
|
||||
|
||||
static uint32 GetPlayerConditionLfgValue(Player const* player, PlayerConditionLfgStatus status);
|
||||
static bool IsPlayerMeetingCondition(Player const* player, PlayerConditionEntry const* condition);
|
||||
@@ -337,6 +339,7 @@ class TC_GAME_API ConditionMgr
|
||||
std::unordered_set<uint32> SpellsUsedInSpellClickConditions;
|
||||
ConditionEntriesByAreaTriggerIdMap AreaTriggerConditionContainerStore;
|
||||
ConditionEntriesByCreatureIdMap TrainerSpellConditionContainerStore;
|
||||
std::unordered_map<std::pair<uint32 /*object type*/, uint32 /*object id*/>, ConditionContainer> ObjectVisibilityConditionStore;
|
||||
};
|
||||
|
||||
#define sConditionMgr ConditionMgr::instance()
|
||||
|
||||
@@ -1404,6 +1404,9 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo
|
||||
if (!obj->CheckPrivateObjectOwnerVisibility(this))
|
||||
return false;
|
||||
|
||||
if (!sConditionMgr->IsObjectMeetingVisibilityByObjectIdConditions(obj->GetTypeId(), obj->GetEntry(), const_cast<WorldObject*>(this)))
|
||||
return false;
|
||||
|
||||
bool corpseVisibility = false;
|
||||
if (distanceCheck)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user