You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/components/esm4/loadnpc.hpp

240 lines
8.8 KiB
C++

/*
Copyright (C) 2016, 2018-2021 cc9cii
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
cc9cii cc9c@iinet.net.au
Much of the information on the data structures are based on the information
from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
trial & error. See http://en.uesp.net/wiki for details.
*/
#ifndef ESM4_NPC__H
#define ESM4_NPC__H
#include <cstdint>
#include <string>
#include <vector>
#include <components/esm/defs.hpp>
#include <components/esm/formid.hpp>
#include "actor.hpp"
#include "inventory.hpp"
namespace ESM4
{
class Reader;
class Writer;
struct Npc
{
enum ACBS_TES4
{
TES4_Female = 0x000001,
TES4_Essential = 0x000002,
TES4_Respawn = 0x000008,
TES4_AutoCalcStats = 0x000010,
TES4_PCLevelOffset = 0x000080,
TES4_NoLowLevelProc = 0x000200,
TES4_NoRumors = 0x002000,
TES4_Summonable = 0x004000,
TES4_NoPersuasion = 0x008000, // different meaning to crea
TES4_CanCorpseCheck = 0x100000 // opposite of crea
};
enum ACBS_FO3
{
FO3_Female = 0x00000001,
FO3_Essential = 0x00000002,
FO3_PresetFace = 0x00000004, // Is CharGen Face Preset
FO3_Respawn = 0x00000008,
FO3_AutoCalcStats = 0x00000010,
FO3_PCLevelMult = 0x00000080,
FO3_UseTemplate = 0x00000100,
FO3_NoLowLevelProc = 0x00000200,
FO3_NoBloodSpray = 0x00000800,
FO3_NoBloodDecal = 0x00001000,
FO3_NoVATSMelee = 0x00100000,
FO3_AnyRace = 0x00400000,
FO3_AutoCalcServ = 0x00800000,
FO3_NoKnockdown = 0x04000000,
FO3_NotPushable = 0x08000000,
FO3_NoRotateHead = 0x40000000
};
// In FO4 flags seem to be the same.
enum ACBS_TES5
{
TES5_Female = 0x00000001,
TES5_Essential = 0x00000002,
TES5_PresetFace = 0x00000004, // Is CharGen Face Preset
TES5_Respawn = 0x00000008,
TES5_AutoCalcStats = 0x00000010,
TES5_Unique = 0x00000020,
TES5_NoStealth = 0x00000040, // Doesn't affect stealth meter
TES5_PCLevelMult = 0x00000080,
// TES5_Unknown = 0x00000100, // Audio template?
TES5_Protected = 0x00000800,
TES5_Summonable = 0x00004000,
TES5_NoBleeding = 0x00010000,
TES5_Owned = 0x00040000, // owned/follow? (Horses, Atronachs, NOT Shadowmere)
TES5_GenderAnim = 0x00080000, // Opposite Gender Anims
TES5_SimpleActor = 0x00100000,
TES5_LoopedScript = 0x00200000, // AAvenicci, Arcadia, Silvia, Afflicted, TortureVictims
TES5_LoopedAudio = 0x10000000, // AAvenicci, Arcadia, Silvia, DA02 Cultists, Afflicted, TortureVictims
TES5_IsGhost = 0x20000000, // Ghost/non-interactable (Ghosts, Nocturnal)
TES5_Invulnerable = 0x80000000
};
// All FO3+ games.
enum Template_Flags
{
Template_UseTraits = 0x0001, // Destructible Object; Traits tab, including race, gender, height, weight,
// voice type, death item; Sounds tab; Animation tab; Character Gen tabs
Template_UseStats = 0x0002, // Stats tab, including level, autocalc, skills, health/magicka/stamina,
// speed, bleedout, class
Template_UseFactions = 0x0004, // both factions and assigned crime faction
Template_UseSpellList = 0x0008, // both spells and perks
Template_UseAIData = 0x0010, // AI Data tab, including aggression/confidence/morality, combat style and
// gift filter
Template_UseAIPackage = 0x0020, // only the basic Packages listed on the AI Packages tab;
// rest of tab controlled by Def Pack List
Template_UseModel = 0x0040, // FO3, FONV; probably not used in TES5+
Template_UseBaseData = 0x0080, // including name and short name, and flags for Essential, Protected,
// Respawn, Summonable, Simple Actor, and Doesn't affect stealth meter
Template_UseInventory = 0x0100, // Inventory tab, including all outfits and geared-up item,
// but not death item
Template_UseScript = 0x0200,
// The following flags were added in TES5+:
Template_UseDefined = 0x0400, // Def Pack List (the dropdown-selected package lists on the AI Packages tab)
Template_UseAtkData = 0x0800, // Attack Data tab, including override from behavior graph race,
// events, and data)
Template_UseKeywords = 0x1000
};
#pragma pack(push, 1)
struct SkillValues
{
std::uint8_t armorer;
std::uint8_t athletics;
std::uint8_t blade;
std::uint8_t block;
std::uint8_t blunt;
std::uint8_t handToHand;
std::uint8_t heavyArmor;
std::uint8_t alchemy;
std::uint8_t alteration;
std::uint8_t conjuration;
std::uint8_t destruction;
std::uint8_t illusion;
std::uint8_t mysticism;
std::uint8_t restoration;
std::uint8_t acrobatics;
std::uint8_t lightArmor;
std::uint8_t marksman;
std::uint8_t mercantile;
std::uint8_t security;
std::uint8_t sneak;
std::uint8_t speechcraft;
};
struct HairColour
{
std::uint8_t red;
std::uint8_t green;
std::uint8_t blue;
std::uint8_t custom; // alpha?
};
struct Data
{
SkillValues skills;
std::uint32_t health;
AttributeValues attribs;
};
#pragma pack(pop)
ESM::FormId mId; // from the header
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
bool mIsTES4;
bool mIsFONV;
bool mIsFO4 = false;
std::string mEditorId;
std::string mFullName;
std::string mModel; // skeleton model (can be a marker in FO3/FONV)
ESM::FormId mRace;
ESM::FormId mClass;
ESM::FormId mHair; // not for TES5, see mHeadParts
ESM::FormId mEyes;
std::vector<ESM::FormId> mHeadParts; // FO3/FONV/TES5
float mHairLength;
HairColour mHairColour; // TES4/FO3/FONV
ESM::FormId mHairColourId; // TES5
ESM::FormId mBeardColourId; // FO4
ESM::FormId mDeathItem;
std::vector<ESM::FormId> mSpell;
ESM::FormId mScriptId;
AIData mAIData;
std::vector<ESM::FormId> mAIPackages; // seems to be in priority order, 0 = highest priority
ActorBaseConfig mBaseConfig; // union
ActorFaction mFaction;
Data mData;
ESM::FormId mCombatStyle;
ESM::FormId mSoundBase;
ESM::FormId mSound;
std::uint8_t mSoundChance;
float mFootWeight;
float mBoundRadius;
std::vector<std::string> mKf; // filenames only, get directory path from mModel
std::vector<InventoryItem> mInventory;
ESM::FormId mBaseTemplate; // FO3/FONV/TES5
ESM::FormId mWornArmor; // TES5 only?
ESM::FormId mDefaultOutfit; // TES5 OTFT
ESM::FormId mSleepOutfit; // TES5 OTFT
ESM::FormId mDefaultPkg;
std::vector<float> mSymShapeModeCoefficients; // size 0 or 50
std::vector<float> mAsymShapeModeCoefficients; // size 0 or 30
std::vector<float> mSymTextureModeCoefficients; // size 0 or 50
std::int16_t mFgRace;
void load(ESM4::Reader& reader);
// void save(ESM4::Writer& writer) const;
// void blank();
static constexpr ESM::RecNameInts sRecordId = ESM::RecNameInts::REC_NPC_4;
};
}
#endif // ESM4_NPC__H