Core/Objects: Allow more specific checks to include or exclude feign death units in CreatureWithOptionsInObjectRangeCheck::IsAlive check (#30361)

* this also extends SMART_TARGET_CLOSEST_CREATURE dead param
This commit is contained in:
ModoX
2024-12-22 12:59:57 +01:00
committed by GitHub
parent 76d16440dc
commit 92efc2523b
5 changed files with 53 additions and 7 deletions
@@ -2966,7 +2966,7 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
Creature* target = ref->FindNearestCreatureWithOptions(float(e.target.unitClosest.dist ? e.target.unitClosest.dist : 100), {
.CreatureId = e.target.unitClosest.entry,
.StringId = !e.target.param_string.empty() ? Optional<std::string_view>(e.target.param_string) : Optional<std::string_view>(),
.IsAlive = !e.target.unitClosest.dead
.IsAlive = (FindCreatureAliveState)e.target.unitClosest.findCreatureAliveState
});
if (target)
@@ -594,8 +594,14 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e)
TC_SAI_IS_BOOLEAN_VALID(e, e.target.farthest.isInLos);
break;
case SMART_TARGET_CLOSEST_CREATURE:
TC_SAI_IS_BOOLEAN_VALID(e, e.target.unitClosest.dead);
{
if (e.target.unitClosest.findCreatureAliveState < (uint32)FindCreatureAliveState::Alive || e.target.unitClosest.findCreatureAliveState >= (uint32)FindCreatureAliveState::Max)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} has invalid alive state {}", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType(), e.target.unitClosest.findCreatureAliveState);
return false;
}
break;
}
case SMART_TARGET_CLOSEST_ENEMY:
TC_SAI_IS_BOOLEAN_VALID(e, e.target.closestAttackable.playerOnly);
break;
@@ -1289,7 +1289,7 @@ enum SMARTAI_TARGETS
SMART_TARGET_INVOKER_PARTY = 16, // invoker's party members
SMART_TARGET_PLAYER_RANGE = 17, // min, max
SMART_TARGET_PLAYER_DISTANCE = 18, // maxDist
SMART_TARGET_CLOSEST_CREATURE = 19, // CreatureEntry(0any), maxDist, dead?, StringId
SMART_TARGET_CLOSEST_CREATURE = 19, // CreatureEntry(0any), maxDist, findCreatureAliveState, StringId
SMART_TARGET_CLOSEST_GAMEOBJECT = 20, // entry(0any), maxDist, StringId
SMART_TARGET_CLOSEST_PLAYER = 21, // maxDist
SMART_TARGET_ACTION_INVOKER_VEHICLE = 22, // Unit's vehicle who caused this Event to occur
@@ -1399,7 +1399,7 @@ struct SmartTarget
{
uint32 entry;
uint32 dist;
SAIBool dead;
uint32 findCreatureAliveState;
} unitClosest;
struct
+11 -1
View File
@@ -563,12 +563,22 @@ class FlaggedValuesArray32
T_FLAGS m_flags;
};
enum class FindCreatureAliveState : uint8
{
Alive = 0, // includes feign death
Dead = 1, // excludes feign death
EffectivelyAlive = 2, // excludes feign death
EffectivelyDead = 3, // includes feign death
Max
};
struct FindCreatureOptions
{
Optional<uint32> CreatureId;
Optional<std::string_view> StringId;
Optional<bool> IsAlive;
Optional<FindCreatureAliveState> IsAlive;
Optional<bool> IsInCombat;
Optional<bool> IsSummon;
@@ -1435,8 +1435,38 @@ namespace Trinity
if (i_args.StringId && !u->HasStringId(*i_args.StringId))
return false;
if (i_args.IsAlive.has_value() && u->IsAlive() != i_args.IsAlive)
return false;
if (i_args.IsAlive.has_value())
{
switch (*i_args.IsAlive)
{
case FindCreatureAliveState::Alive:
{
if (!u->IsAlive())
return false;
break;
}
case FindCreatureAliveState::Dead:
{
if (u->IsAlive())
return false;
break;
}
case FindCreatureAliveState::EffectivelyAlive:
{
if (!u->IsAlive() || u->HasUnitFlag2(UNIT_FLAG2_FEIGN_DEATH))
return false;
break;
}
case FindCreatureAliveState::EffectivelyDead:
{
if (u->IsAlive() && !u->HasUnitFlag2(UNIT_FLAG2_FEIGN_DEATH))
return false;
break;
}
default:
break;
}
}
if (i_args.IsSummon.has_value() && u->IsSummon() != i_args.IsSummon)
return false;