Skip to content

Commit

Permalink
fix: handle NPCs with leveled items
Browse files Browse the repository at this point in the history
  • Loading branch information
RobbeBryssinck committed Mar 31, 2024
1 parent 4a3cbf4 commit ca4476a
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 9 deletions.
12 changes: 5 additions & 7 deletions Code/client/Games/Skyrim/Actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <Components/TESActorBaseData.h>
#include <ExtraData/ExtraFactionChanges.h>
#include <Games/Memory.h>
#include <Forms/TESLevItem.h>

#include <Events/HealthChangeEvent.h>
#include <Events/InventoryChangeEvent.h>
Expand Down Expand Up @@ -216,22 +217,19 @@ bool Actor::ShouldWearBodyPiece() const noexcept
pArmor = Cast<TESObjectARMO>(pItem);
else if (pItem->formType == FormType::LeveledItem)
{
// TODO: leveled items can probably also be handled but afaik,
// the naked npc bug mostly occurs to town NPCs.
// Since this is a bit more complex and possibly error prone, leave out for now.
#if 0
TESLevItem* pLevItem = Cast<TESLevItem>(pItem);
if (!pLevItem)
if (!pLevItem || !pLevItem->pLeveledListA || !pLevItem->pLeveledListA->pForm)
continue;
#endif

pArmor = Cast<TESObjectARMO>(pLevItem->pLeveledListA->pForm);
}
else
continue;

if (!pArmor)
continue;

if (pArmor->slotType & 0x4) // 0x4 is flag for body piece
if (pArmor->IsBodyPiece())
return true;
}

Expand Down
7 changes: 5 additions & 2 deletions Code/client/Games/Skyrim/Forms/TESLevItem.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#pragma once

struct TESLevItem : BaseFormComponent
{
#include "TESLeveledList.h"

struct TESLevItem : TESBoundObject, TESLeveledList
{
};

static_assert(sizeof(TESLevItem) == 0x58);
18 changes: 18 additions & 0 deletions Code/client/Games/Skyrim/Forms/TESLeveledList.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

struct TESLeveledList : BaseFormComponent
{
struct LEVELED_OBJECT
{
TESForm* pForm;
uint16_t count;
uint16_t level;
uint32_t padC;
void* pItemExtra;
};

LEVELED_OBJECT* pLeveledListA; // this array has count at offset -8
uint8_t unk10[0x28 - 0x10];
};

static_assert(sizeof(TESLeveledList) == 0x28);
5 changes: 5 additions & 0 deletions Code/client/Games/Skyrim/Forms/TESObjectARMO.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

struct TESObjectARMO : TESForm
{
[[nodiscard]] bool IsBodyPiece() const noexcept
{
return (slotType & 0x4) != 0; // 0x4 is flag for body piece
}

uint8_t unk20[0x1B8 - sizeof(TESForm)];
uint32_t slotType;
};

0 comments on commit ca4476a

Please sign in to comment.