Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
alandtse committed Aug 22, 2023
2 parents 754dad7 + ff2afea commit 17065ba
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 9 deletions.
3 changes: 2 additions & 1 deletion include/RE/A/Actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ namespace RE
InventoryEntryData* GetAttackingWeapon();
const InventoryEntryData* GetAttackingWeapon() const;
bhkCharacterController* GetCharController() const;
uint32_t GetCollisionFilterInfo(uint32_t& a_outCollisionFilterInfo);
std::uint32_t GetCollisionFilterInfo(std::uint32_t& a_outCollisionFilterInfo);
NiPointer<Actor> GetCommandingActor() const;
TESFaction* GetCrimeFaction();
const TESFaction* GetCrimeFaction() const;
Expand Down Expand Up @@ -723,6 +723,7 @@ namespace RE
bool HasPerk(BGSPerk* a_perk) const;
bool HasShout(TESShout* a_shout) const;
bool HasSpell(SpellItem* a_spell) const;
void InitiateDoNothingPackage();
void InterruptCast(bool a_restoreMagicka) const;
bool IsAttacking() const;
bool IsAIEnabled() const;
Expand Down
11 changes: 10 additions & 1 deletion include/RE/T/TESForm.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ namespace RE
[[nodiscard]] const char* GetName() const;
[[nodiscard]] float GetWeight() const;
[[nodiscard]] bool HasKeywordInArray(const std::vector<BGSKeyword*>& a_keywords, bool a_matchAll) const;
[[nodiscard]] bool HasAnyKeywordByEditorID(const std::vector<std::string>& editorIDs) const;
[[nodiscard]] bool HasKeywordInList(BGSListForm* a_keywordList, bool a_matchAll) const;
[[nodiscard]] bool HasVMAD() const;
[[nodiscard]] bool HasWorldModel() const noexcept;
Expand All @@ -326,7 +327,15 @@ namespace RE
[[nodiscard]] bool IsInitialized() const noexcept { return (GetFormFlags() & RecordFlags::kInitialized) != 0; }
[[nodiscard]] bool IsKey() const noexcept { return Is(FormType::KeyMaster); }
[[nodiscard]] bool IsLockpick() const noexcept { return GetFormID() == 0x0000000A; }

/**
* @brief Checks if the Form represents Skooma.
*
* Determines whether the FormID matches one of the known form IDs for Skooma.
*
* @return True if the FormID is either 0x00057A7A or 0x0201391D, indicating that it is Skooma or RedWater Skooma.
*
*/
[[nodiscard]] bool IsSkooma() const noexcept { return (GetFormID() == 0x00057A7A || GetFormID() == 0x0201391D); }
[[nodiscard]] bool IsNot(FormType a_type) const noexcept { return !Is(a_type); }

template <class... Args>
Expand Down
7 changes: 7 additions & 0 deletions include/RE/T/TESObjectREFR.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "RE/B/BGSDefaultObjectManager.h"
#include "RE/B/BSFixedString.h"
#include "RE/B/BSHandleRefObject.h"
#include "RE/B/BSPointerHandle.h"
Expand Down Expand Up @@ -456,18 +457,23 @@ namespace RE
bool HasKeyword(const BGSKeyword* a_keyword) const;
bool HasKeywordInArray(const std::vector<BGSKeyword*>& a_keywords, bool a_matchAll) const;
bool HasKeywordInList(BGSListForm* a_keywordList, bool a_matchAll) const;
bool HasKeywordWithType(DEFAULT_OBJECT keywordType) const;
bool HasQuestObject() const;
void InitChildActivates(TESObjectREFR* a_actionRef);
bool InitInventoryIfRequired(bool a_ignoreContainerExtraData = false);
bool Is3DLoaded() const;
bool IsActivationBlocked() const;
bool IsAnimal() const;
bool IsAnOwner(const Actor* a_testOwner, bool a_useFaction, bool a_requiresOwner) const;
bool IsCrimeToActivate();
bool IsDisabled() const;
bool IsDragon() const;
bool IsEnchanted() const;
bool IsHorse() const;
bool IsHumanoid() const;
bool IsInitiallyDisabled() const;
bool IsInWater() const;
bool IsJewelry() const;
bool IsLocked() const;
bool IsMarkedForDeletion() const;
bool IsOffLimits();
Expand All @@ -477,6 +483,7 @@ namespace RE
void MoveTo(TESObjectREFR* a_target);
bool MoveToNode(TESObjectREFR* a_target, const BSFixedString& a_nodeName);
bool MoveToNode(TESObjectREFR* a_target, NiAVObject* a_node);
bool NameIncludes(std::string a_word);
NiPointer<TESObjectREFR> PlaceObjectAtMe(TESBoundObject* a_baseToPlace, bool a_forcePersist) const;
void PlayAnimation(stl::zstring a_from, stl::zstring a_to);
void PlayAnimation(NiControllerManager* a_manager, NiControllerSequence* a_toSeq, NiControllerSequence* a_fromSeq);
Expand Down
9 changes: 8 additions & 1 deletion include/RE/T/TESPackage.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,14 @@ namespace RE
kPickPocketWarning = 35,
kMovementBlocked = 36,
kVampireFeed = 37,
kCannibal = 38
kCannibal = 38,
kUnk39 = 39,
kUnk40 = 40,
kUnk41 = 41,
kUnk42 = 42,
kUnk43 = 43,
kUnk44 = 44,
kUnk45 = 45,
};

enum class PACK_EVENT_ACTION_TYPE
Expand Down
7 changes: 7 additions & 0 deletions src/RE/A/Actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,13 @@ namespace RE
return func(this, a_spell);
}

void Actor::InitiateDoNothingPackage()
{
using func_t = decltype(&Actor::InitiateDoNothingPackage);
REL::Relocation<func_t> func{ RELOCATION_ID(36408, 37402) };
return func(this);
}

void Actor::InterruptCast(bool a_restoreMagicka) const
{
using func_t = decltype(&Actor::InterruptCast);
Expand Down
28 changes: 28 additions & 0 deletions src/RE/T/TESForm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,34 @@ namespace RE
}
}

bool TESForm::HasAnyKeywordByEditorID(const std::vector<std::string>& editorIDs) const
{
// Try to cast to a keyword form interface
const auto keywordForm = As<BGSKeywordForm>();
if (!keywordForm) {
return false;
}

// Iterate through the keywords
for (std::uint32_t i = 0; i < keywordForm->GetNumKeywords(); ++i) {
auto keywordOpt = keywordForm->GetKeywordAt(i);
if (keywordOpt) {
auto keyword = *keywordOpt;
if (keyword) {
const char* keywordEditorID = keyword->GetFormEditorID();
if (keywordEditorID) {
// Check if the keywordEditorID is in the given editorIDs vector
if (std::find(editorIDs.begin(), editorIDs.end(), keywordEditorID) != editorIDs.end()) {
return true;
}
}
}
}
}

return false;
}

bool TESForm::HasKeywordInArray(const std::vector<BGSKeyword*>& a_keywords, bool a_matchAll) const
{
const auto keywordForm = As<BGSKeywordForm>();
Expand Down
45 changes: 39 additions & 6 deletions src/RE/T/TESObjectREFR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,17 @@ namespace RE
return hasKeyword;
}

bool TESObjectREFR::HasKeywordWithType(DEFAULT_OBJECT keywordType) const
{
auto dobj = BGSDefaultObjectManager::GetSingleton();
if (!dobj) {
return false;
}

auto keyword = dobj->GetObject<BGSKeyword>(keywordType);
return keyword ? HasKeyword(keyword) : false;
}

bool TESObjectREFR::HasQuestObject() const
{
using func_t = decltype(&TESObjectREFR::HasQuestObject);
Expand Down Expand Up @@ -615,6 +626,11 @@ namespace RE
return xFlags && xFlags->IsActivationBlocked();
}

bool TESObjectREFR::IsAnimal() const
{
return HasKeywordWithType(DEFAULT_OBJECT::kKeywordAnimal);
}

bool TESObjectREFR::IsAnOwner(const Actor* a_testOwner, bool a_useFaction, bool a_requiresOwner) const
{
using func_t = decltype(&TESObjectREFR::IsAnOwner);
Expand All @@ -634,6 +650,11 @@ namespace RE
return (GetFormFlags() & RecordFlags::kInitiallyDisabled) != 0;
}

bool TESObjectREFR::IsDragon() const
{
return HasKeywordWithType(DEFAULT_OBJECT::kKeywordDragon);
}

bool TESObjectREFR::IsEnchanted() const
{
auto xEnch = extraList.GetByType<ExtraEnchantment>();
Expand All @@ -654,20 +675,24 @@ namespace RE

bool TESObjectREFR::IsHorse() const
{
auto dobj = BGSDefaultObjectManager::GetSingleton();
if (!dobj) {
return false;
}
return HasKeywordWithType(DEFAULT_OBJECT::kKeywordHorse);
}

auto keyword = dobj->GetObject<BGSKeyword>(DEFAULT_OBJECT::kKeywordHorse);
return keyword ? HasKeyword(keyword) : false;
bool TESObjectREFR::IsHumanoid() const
{
return HasKeywordWithType(DEFAULT_OBJECT::kKeywordNPC);
}

bool TESObjectREFR::IsInitiallyDisabled() const
{
return (GetFormFlags() & RecordFlags::kInitiallyDisabled) != 0;
}

bool TESObjectREFR::IsJewelry() const
{
return HasKeywordWithType(DEFAULT_OBJECT::kKeywordJewelry);
}

bool TESObjectREFR::IsInWater() const
{
return GetWaterHeight() > GetPositionZ();
Expand Down Expand Up @@ -750,6 +775,14 @@ namespace RE
return true;
}

bool TESObjectREFR::NameIncludes(std::string a_word)
{
auto obj = GetObjectReference();
std::string name = obj ? obj->GetName() : "";

return name.find(a_word) != std::string::npos;
}

NiPointer<TESObjectREFR> TESObjectREFR::PlaceObjectAtMe(TESBoundObject* a_baseToPlace, bool a_forcePersist) const
{
const auto handle = TESDataHandler::GetSingleton()->CreateReferenceAtLocation(a_baseToPlace, GetPosition(), GetAngle(), GetParentCell(), GetWorldspace(), nullptr, nullptr, ObjectRefHandle(), a_forcePersist, true);
Expand Down

0 comments on commit 17065ba

Please sign in to comment.