19 const auto base = a_actor->GetActorBase();
23 const uint32_t perk_count = base->perkCount;
24 for (uint32_t i = 0; i < perk_count; i++)
26 RE::BGSPerk* perk = base->perks[i].perk;
29 perks.push_back(perk);
40 const auto proc = actor->currentProcess;
44 for (
auto& [
object, slot] : proc->equippedForms)
48 if (
const auto armor = object->As<RE::TESObjectARMO>())
50 if (armor->IsHeavyArmor())
66 const auto proc = actor->currentProcess;
70 for (
auto& [
object, slot] : proc->equippedForms)
74 if (
const auto armor = object->As<RE::TESObjectARMO>())
76 if (!armor->IsHeavyArmor())
93 victim->actorState1.sitSleepState == RE::SIT_SLEEP_STATE::kIsSitting ||
94 victim->actorState1.sitSleepState == RE::SIT_SLEEP_STATE::kIsSleeping ||
95 (victim->GetHeadingAngle(attacker->GetPosition(),
false) <= -135 ||
96 victim->GetHeadingAngle(attacker->GetPosition(),
false) >= 135) ||
108 if (
const auto *rightHandItem = actor->GetEquippedEntryData(
false))
110 if (rightHandItem->IsQuestObject())
116 if (
const auto *leftHandItem = actor->GetEquippedEntryData(
true))
118 if (leftHandItem->IsQuestObject())
132 if (a_ref->HasKeywordWithType(RE::DEFAULT_OBJECT::kKeywordVampire))
144 if (a_ref->HasKeywordWithType(RE::DEFAULT_OBJECT::kKeywordUndead))
157 if (a_actor->HasKeywordWithType(RE::DEFAULT_OBJECT::kKeywordDragon))
161 const auto key = RE::TESForm::LookupByEditorID<RE::BGSKeyword>(
"ActorTypeDragon");
164 return a_actor->HasKeyword(key);
172 const auto player = RE::PlayerCharacter::GetSingleton();
174 auto cell = player->GetParentCell();
177 cell = player->GetSaveParentCell();
190 const auto process = a_actor->GetHighProcess();
191 return process ? process->lightLevel : 0.0f;
198 const auto player = RE::PlayerCharacter::GetSingleton();
208 static void TryStagger(RE::Actor* a_target,
float a_staggerMult, RE::Actor* a_aggressor) {
210 static REL::Relocation<func_t> func{ RELOCATION_ID(36700, 37710) };
211 func(a_target, a_staggerMult, a_aggressor);
221 return actor && (actor->formFlags & RE::Actor::RecordFlags::kStartsDead);
232 return a_actor->GetActorValueModifier(RE::ACTOR_VALUE_MODIFIER::kTemporary, RE::ActorValue::kHealth) +
233 a_actor->GetPermanentActorValue(RE::ActorValue::kHealth);
241 return actor->GetActorValueModifier(RE::ACTOR_VALUE_MODIFIER::kTemporary, RE::ActorValue::kStamina) +
242 actor->GetPermanentActorValue(RE::ActorValue::kStamina);
250 return actor->GetActorValueModifier(RE::ACTOR_VALUE_MODIFIER::kTemporary, RE::ActorValue::kMagicka) +
251 actor->GetPermanentActorValue(RE::ActorValue::kMagicka);
258 a_actor->RestoreActorValue(RE::ActorValue::kHealth,
GetMaxHealth(a_actor));
259 a_actor->RestoreActorValue(RE::ActorValue::kStamina,
GetMaxStamina(a_actor));
260 a_actor->RestoreActorValue(RE::ActorValue::kMagicka,
GetMaxMagicka(a_actor));
272 const auto& activeEffects = a_actor->GetActiveEffectList();
276 return std::ranges::any_of(*activeEffects, [a_type](
const RE::ActiveEffect* effect) ->
bool
278 if (!effect || effect->flags.any(RE::ActiveEffect::Flag::kInactive))
return false;
279 const auto base = effect->GetBaseObject();
280 return base && base->HasArchetype(a_type);
290 if (!a_actor || a_keyword.empty() || !a_actor->Is3DLoaded())
294 const auto& activeEffects = a_actor->GetActiveEffectList();
298 if (
const auto key = RE::TESForm::LookupByEditorID<RE::BGSKeyword>(a_keyword)) {
299 return std::ranges::any_of(*activeEffects, [key](
const RE::ActiveEffect* effect) ->
bool {
300 if (!effect || effect->flags.any(RE::ActiveEffect::Flag::kInactive))
return false;
301 const auto base = effect->GetBaseObject();
302 return base && base->HasKeyword(key);
305 return std::ranges::any_of(*activeEffects, [a_keyword](
const RE::ActiveEffect* effect) ->
bool {
306 if (!effect || effect->flags.any(RE::ActiveEffect::Flag::kInactive))
return false;
307 const auto base = effect->GetBaseObject();
308 return base && base->HasKeywordString(a_keyword);
317 static bool IsEffectActive(RE::Actor *a_actor,
const RE::EffectSetting *a_effect)
319 if (!a_actor || !a_effect)
323 const auto& activeEffects = a_actor->GetActiveEffectList();
327 return std::ranges::any_of(*activeEffects, [a_effect](
const RE::ActiveEffect* effect) ->
bool
329 if (!effect || effect->flags.any(RE::ActiveEffect::Flag::kInactive))
331 const auto base = effect->GetBaseObject();
332 return base == a_effect;
342 static void AddItem(RE::Actor *a_actor, RE::TESBoundObject *a_item, RE::ExtraDataList *a_extraList,
int a_count,
343 RE::TESObjectREFR *a_fromRefr)
345 using func_t =
decltype(
AddItem);
346 static REL::Relocation<func_t> func{RELOCATION_ID(36525,37525)};
347 return func(a_actor, a_item, a_extraList, a_count, a_fromRefr);
355 return AddItem(RE::PlayerCharacter::GetSingleton(), a_item,
nullptr, a_count,
nullptr);
365 static REL::Relocation<func_t> func{RELOCATION_ID(16564, 16919)};
366 return func(item, count);
377 const auto& inv = actor->GetInventory();
378 const auto it = inv.find(item);
379 return it != inv.end() && it->second.first > 0;
388 if (
const auto weapon = a_actor->GetAttackingWeapon())
390 const auto obj = weapon->object;
391 return obj ? obj->As<RE::TESObjectWEAP>() :
nullptr;
393 if (
const auto rhs = a_actor->GetEquippedObject(
false); rhs && rhs->IsWeapon())
395 return rhs->As<RE::TESObjectWEAP>();
397 if (
const auto lhs = a_actor->GetEquippedObject(
true); lhs && lhs->IsWeapon())
399 return lhs->As<RE::TESObjectWEAP>();
409 RE::NiPointer<RE::Actor> currentMount;
410 if ( RE::PlayerCharacter::GetSingleton()->GetMount(currentMount)) {
411 return currentMount.get();
421 const auto high = actor->GetHighProcess();
425 const auto &attackData = high->attackData;
429 return attackData->data.flags.any(RE::AttackData::AttackFlag::kPowerAttack);
437 const auto high = actor->GetHighProcess();
442 if (actor->GetAttackState() == RE::ATTACK_STATE_ENUM::kNone)
445 const auto& attackData = high->attackData;
449 return attackData->data.flags.any(RE::AttackData::AttackFlag::kBashAttack);
459 static std::vector<RE::Actor*>
GetNearbyActors(
const RE::TESObjectREFR* a_ref,
const float a_radius,
const bool a_ignorePlayer)
461 std::vector<RE::Actor*> result;
462 const auto processLists = RE::ProcessLists::GetSingleton();
466 if (a_ignorePlayer && processLists->numberHighActors == 0)
469 const auto squaredRadius = a_radius * a_radius;
470 const auto originPos = a_ref->GetPosition();
472 result.reserve(processLists->numberHighActors);
474 const auto get_actor_within_radius = [&](RE::Actor* a_actor) {
475 if (a_actor && a_actor != a_ref && originPos.GetSquaredDistance(a_actor->GetPosition()) <= squaredRadius) {
476 result.emplace_back(a_actor);
479 for (
auto& actorHandle : processLists->highActorHandles) {
480 const auto actor = actorHandle.get();
481 get_actor_within_radius(actor.get());
484 if (!a_ignorePlayer) {
485 get_actor_within_radius(RE::PlayerCharacter::GetSingleton());
498 std::erase_if(actors, [](
const RE::Actor* a) {
return a->IsPlayerTeammate(); });
507 static bool IsGuardNearby(
const RE::TESObjectREFR* a_ref,
const float a_radius)
509 return std::ranges::any_of(
GetNearbyActors(a_ref, a_radius,
false), [](
const RE::Actor* a) {
510 return a && a->IsGuard();
518 static RE::Actor*
GetClosestActor(
const RE::TESObjectREFR* a_ref,
const float a_radius)
551 static REL::Relocation<func_t> func{ RELOCATION_ID(0, 37337) };
552 return func(a_actor, a_av);
562 if (actors.empty())
return nullptr;
563 const auto originPos = a_ref->GetPosition();
564 const auto it = std::ranges::min_element(actors, [&](RE::Actor* a, RE::Actor* b) {
565 return originPos.GetSquaredDistance(a->GetPosition()) < originPos.GetSquaredDistance(b->GetPosition());
567 return it != actors.end() ? *it :
nullptr;
static void AddItemPlayer(RE::TESBoundObject *a_item, const int a_count)
Helper function to add an item to the player.
Definition st-actor.h:353
static float GetMaxHealth(RE::Actor *a_actor)
Get maximum Health of an actor.
Definition st-actor.h:230
static bool HasEffectWithKeywordActive(RE::Actor *a_actor, const std::string_view a_keyword)
Check if an actor has an effect active with a specific keyword.
Definition st-actor.h:288
static bool StartsDead(const RE::Actor *actor)
Check if actor is supposed to spawn dead.
Definition st-actor.h:219
static bool ActorHasEquippedHeavyArmor(RE::Actor *actor)
Check if an actor has any heavy armor equipped. It returning false does not mean the actor has light ...
Definition st-actor.h:36
static RE::Actor * GetClosestActor(const RE::TESObjectREFR *a_ref, const float a_radius)
Get the closest actor within a radius.
Definition st-actor.h:518
static RE::Actor * GetClosestFromVector(const RE::TESObjectREFR *a_ref, const std::vector< RE::Actor * > &actors)
Helper function to get the closest actor from a vector.
Definition st-actor.h:560
static std::vector< RE::Actor * > GetNearbyNonPlayerTeammates(const RE::TESObjectREFR *a_ref, const float a_radius)
Search all non-teammates within a certain radius.
Definition st-actor.h:495
static bool IsGuardNearby(const RE::TESObjectREFR *a_ref, const float a_radius)
Check if any actor within a certain radius is a guard.
Definition st-actor.h:507
static bool IsVampire(RE::Actor *a_ref)
Check if actor is vampire.
Definition st-actor.h:130
static bool IsBashing(const RE::Actor *actor)
Check if an actor is shield bashing.
Definition st-actor.h:435
static RE::Actor * GetClosestNonPlayerTeammate(const RE::TESObjectREFR *a_ref, const float a_radius)
Get the closest non-player teammate within a radius of a reference.
Definition st-actor.h:528
static bool IsInOpportunityState(RE::Actor *victim, const RE::Actor *attacker)
Very specific function used to see if an Actor is in a state an attack of opportunity should be possi...
Definition st-actor.h:90
static bool ActorHasItem(RE::Actor *actor, RE::TESBoundObject *item)
Check if actor has the specified item in the inventory.
Definition st-actor.h:373
static RE::TESObjectWEAP * GetWieldingWeapon(RE::Actor *a_actor)
Get the weapon a character is currently wielding.
Definition st-actor.h:386
static float GetCurrentLightLevelPlayer()
Get the light level the player is standing in.
Definition st-actor.h:196
static float GetMaxMagicka(RE::Actor *actor)
Get maximum Magicka of an actor.
Definition st-actor.h:248
static int RemoveItemPlayer(RE::TESBoundObject *item, int count)
Remove item from the player.
Definition st-actor.h:362
static void SetNPCLevel(RE::Actor *actor, uint16_t level)
Runs the console command SetLevel to set an actor's level to the amount.
Definition st-actor.h:538
static std::vector< RE::Actor * > GetNearbyActors(const RE::TESObjectREFR *a_ref, const float a_radius, const bool a_ignorePlayer)
Get all nearby actors.
Definition st-actor.h:459
static void AddItem(RE::Actor *a_actor, RE::TESBoundObject *a_item, RE::ExtraDataList *a_extraList, int a_count, RE::TESObjectREFR *a_fromRefr)
Add item to actor.
Definition st-actor.h:342
static bool ActorHasEquippedLightArmor(const RE::Actor *actor)
Check if an actor has any light armor equipped. It returning false does not mean the actor has heavy ...
Definition st-actor.h:62
static bool IsDragon(const RE::Actor *a_actor)
Check if actor is a dragon.
Definition st-actor.h:155
static void FullyHealActor(RE::Actor *a_actor)
Fully heals all 3 attributes of an actor.
Definition st-actor.h:256
static RE::Actor * GetPlayerMount()
Get the player mount.
Definition st-actor.h:407
static float GetMaxStamina(RE::Actor *actor)
Get maximum Stamina of an actor.
Definition st-actor.h:239
static void TryStagger(RE::Actor *a_target, float a_staggerMult, RE::Actor *a_aggressor)
Try to stagger a target.
Definition st-actor.h:208
static bool ActorHasQuestObjectInHand(RE::Actor *actor)
Check if actor has Quest item as weapon.
Definition st-actor.h:104
static float GetActorValuePercentage(RE::Actor *a_actor, RE::ActorValue a_av)
Get the actor value percentage of an actor.
Definition st-actor.h:548
static bool IsUndead(RE::Actor *a_ref)
Check if actor is undead.
Definition st-actor.h:142
static bool ActorHasEffectOfTypeActive(RE::Actor *a_actor, RE::EffectArchetypes::ArchetypeID a_type)
Check if actor has an effect of a specific type active.
Definition st-actor.h:267
static float GetCurrentLightLevel(const RE::Actor *a_actor)
Get the current light level the actor is standing in.
Definition st-actor.h:185
static RE::TESObjectCELL * GetPlayerCell()
Get the current cell the player is in.
Definition st-actor.h:170
static void GetPerksFromBaseActor(RE::Actor *a_actor, std::vector< RE::BGSPerk * > &perks)
Fills a vector<RE::BGSPerk*> reference with all the perks an actor inherits from the actor base.
Definition st-actor.h:14
static bool IsEffectActive(RE::Actor *a_actor, const RE::EffectSetting *a_effect)
Check if an actor has a specific effect active.
Definition st-actor.h:317
static bool IsPowerAttacking(const RE::Actor *actor)
Check if an actor is power attacking.
Definition st-actor.h:419
static void RunConsoleCommandOnRef(RE::TESObjectREFR *a_target, const std::string_view a_command)
Run console command on reference.
Definition st-misc.h:114