Implemented LUT codegen, untested.

This commit is contained in:
2022-10-24 15:49:07 +11:00
parent 018fe5a743
commit ab6eae3d1c
11 changed files with 2573 additions and 481 deletions

View File

@@ -38,14 +38,18 @@ enum class GroupType : int32_t {
};
enum class RecordType {
None,
AACT, ACHR, ACTI, ADDN, ALCH, AMMO, ANIO, APPA, ARMA, ARMO, ARTO, ASPC, ASTP, AVIF, BOOK, BPTD, CAMS, CELL, CLAS, CLDC, CLFM,
CLMT, COBJ, COLL, CONT, CPTH, CSTY, DEBR, DIAL, DLBR, DLVW, DOBJ, DOOR, DUAL, ECZN, EFSH, ENCH, EQUP, EXPL, EYES, FACT, FLOR,
FLST, FSTP, FSTS, FURN, GLOB, GMST, GRAS, GRUP, HAIR, HAZD, HDPT, IDLE, IDLM, IMAD, IMGS, INFO, INGR, IPCT, IPDS, KEYM, KYWD,
LAND, LCRT, LCTN, LENS, LGTM, LIGH, LSCR, LTEX, LVLI, LVLN, LVSP, MATO, MATT, MESG, MGEF, MISC, MOVT, MSTT, MUSC, MUST, NAVI,
NAVM, NOTE, NPC_, OTFT, PACK, PARW, PBAR, PBEA, PCON, PERK, PFLA, PGRE, PHZD, PLYR, PMIS, PROJ, PWAT, QUST, RACE, REFR, REGN,
RELA, REVB, RFCT, RGDL, SCEN, SCOL, SCOL, SCPT, SCRL, SHOU, SLGM, SMBN, SMEN, SMQN, SNCT, SNDR, SOPM, SOUN, SPEL, SPGD, STAT,
TACT, TES4, TREE, TXST, VOLI, VTYP, WATR, WEAP, WOOP, WRLD, WTHR
AACT, ACHR, ACTI, ADDN, ALCH, AMMO, ANIO, APPA, ARMA, ARMO, ARTO, ASPC,
ASTP, AVIF, BOOK, BPTD, CAMS, CELL, CLAS, CLDC, CLFM, CLMT, COBJ, COLL,
CONT, CPTH, CSTY, DEBR, DIAL, DLBR, DLVW, DOBJ, DOOR, DUAL, ECZN, EFSH,
ENCH, EQUP, EXPL, EYES, FACT, FLOR, FLST, FSTP, FSTS, FURN, GLOB, GMST,
GRAS, GRUP, HAIR, HAZD, HDPT, IDLE, IDLM, IMAD, IMGS, INFO, INGR, IPCT,
IPDS, KEYM, KYWD, LAND, LCRT, LCTN, LENS, LGTM, LIGH, LSCR, LTEX, LVLI,
LVLN, LVSP, MATO, MATT, MESG, MGEF, MISC, MOVT, MSTT, MUSC, MUST, NAVI,
NAVM, NOTE, NPC_, OTFT, PACK, PARW, PBAR, PBEA, PCON, PERK, PFLA, PGRE,
PHZD, PLYR, PMIS, PROJ, PWAT, QUST, RACE, REFR, REGN, RELA, REVB, RFCT,
RGDL, SCEN, SCOL, SCPT, SCRL, SHOU, SLGM, SMBN, SMEN, SMQN, SNCT, SNDR,
SOPM, SOUN, SPEL, SPGD, STAT, TACT, TES4, TREE, TXST, VOLI, VTYP, WATR,
WEAP, WOOP, WRLD, WTHR,
};
//
@@ -58,9 +62,9 @@ using Node = std::variant<GroupNode, RecordNode>;
// Aggregate types
//
struct FourCC : utility::Store<std::array<char, 4>> {
struct FourCC : utility::Store<uint32_t> {
constexpr FourCC() noexcept = default;
explicit constexpr FourCC(const char (&str)[5]) noexcept : Store{ utility::literal_to_array(str) } { }
explicit constexpr FourCC(const char (&str)[5]) noexcept : Store{ utility::fourcc_lit_to_val(str) } { }
};
static_assert(std::is_trivial_v<FourCC>);
@@ -68,6 +72,16 @@ struct FormID : utility::Store<uint32_t> { };
struct Timestamp : utility::Store<uint16_t> { };
struct VCInfo : utility::Store<uint16_t> { };
struct Flag {
RecordType type;
unsigned bit;
};
struct RefrFlag {
RecordType refr_type;
unsigned bit;
};
struct GroupHeader {
struct Coord {
int16_t y, x;
@@ -138,5 +152,12 @@ private:
// Free functions
//
[[nodiscard]] constexpr std::optional<std::string_view> esxr_lut::group_type_to_name(GroupType group_type) noexcept;
[[nodiscard]] constexpr std::optional<FourCC> esxr_lut::record_type_to_fourcc(RecordType record_type) noexcept;
[[nodiscard]] constexpr std::optional<RecordType> esxr_lut::fourcc_to_record_type(FourCC fourcc) noexcept;
[[nodiscard]] constexpr std::optional<std::string_view> esxr_lut::record_type_to_name(RecordType record_type) noexcept;
[[nodiscard]] constexpr std::optional<std::string_view> esxr_lut::flag_to_description(Flag flag) noexcept;
[[nodiscard]] constexpr std::optional<std::string_view> esxr_lut::refr_flag_to_description(RefrFlag refr_flag) noexcept;
}
#endif

View File

@@ -4,287 +4,7 @@ using namespace esxr;
namespace esxr_lut {
static constexpr std::pair<RecordType, std::string_view> record_type_name_map[] = {
{RecordType::AACT, "Action"},
{RecordType::ACHR, "Placed NPC"},
{RecordType::ACTI, "Activator"},
{RecordType::ADDN, "Addon Node"},
{RecordType::ALCH, "Ingestible"},
{RecordType::AMMO, "Ammunition"},
{RecordType::ANIO, "Animated Object"},
{RecordType::APPA, "Alchemical Apparatus"},
{RecordType::ARMA, "Armor Addon"},
{RecordType::ARMO, "Armor"},
{RecordType::ARTO, "Art Object"},
{RecordType::ASPC, "Acoustic Space"},
{RecordType::ASTP, "Association Type"},
{RecordType::AVIF, "Actor Value Information"},
{RecordType::BOOK, "Book"},
{RecordType::BPTD, "Body Part Data"},
{RecordType::CAMS, "Camera Shot"},
{RecordType::CELL, "Cell"},
{RecordType::CLAS, "Class"},
{RecordType::CLDC, "CLDC"},
{RecordType::CLFM, "Color"},
{RecordType::CLMT, "Climate"},
{RecordType::COBJ, "Constructible Object"},
{RecordType::COLL, "Collision Layer"},
{RecordType::CONT, "Container"},
{RecordType::CPTH, "Camera Path"},
{RecordType::CSTY, "Combat Style"},
{RecordType::DEBR, "Debris"},
{RecordType::DIAL, "Dialog Topic"},
{RecordType::DLBR, "Dialog Branch"},
{RecordType::DLVW, "Dialog View"},
{RecordType::DOBJ, "Default Object Manager"},
{RecordType::DOOR, "Door"},
{RecordType::DUAL, "Dual Cast Data"},
{RecordType::ECZN, "Encounter Zone"},
{RecordType::EFSH, "Effect Shader"},
{RecordType::ENCH, "Object Effect"},
{RecordType::EQUP, "Equip Type"},
{RecordType::EXPL, "Explosion"},
{RecordType::EYES, "Eyes"},
{RecordType::FACT, "Faction"},
{RecordType::FLOR, "Flora"},
{RecordType::FLST, "FormID List"},
{RecordType::FSTP, "Footstep"},
{RecordType::FSTS, "Footstep Set"},
{RecordType::FURN, "Furniture"},
{RecordType::GLOB, "Global"},
{RecordType::GMST, "Game Setting"},
{RecordType::GRAS, "Grass"},
{RecordType::GRUP, "Internal File Structure Group"},
{RecordType::HAIR, "HAIR"},
{RecordType::HAZD, "Hazard"},
{RecordType::HDPT, "Head Part"},
{RecordType::IDLE, "Idle Animation"},
{RecordType::IDLM, "Idle Marker"},
{RecordType::IMAD, "Image Space Adapter"},
{RecordType::IMGS, "Image Space"},
{RecordType::INFO, "Dialog response"},
{RecordType::INGR, "Ingredient"},
{RecordType::IPCT, "Impact"},
{RecordType::IPDS, "Impact Data Set"},
{RecordType::KEYM, "Key"},
{RecordType::KYWD, "Keyword"},
{RecordType::LAND, "Landscape"},
{RecordType::LCRT, "Location Reference Type"},
{RecordType::LCTN, "Location"},
{RecordType::LENS, "Lens Flare"},
{RecordType::LGTM, "Lighting Template"},
{RecordType::LIGH, "Light"},
{RecordType::LSCR, "Load Screen"},
{RecordType::LTEX, "Landscape Texture"},
{RecordType::LVLI, "Leveled Item"},
{RecordType::LVLN, "Leveled NPC"},
{RecordType::LVSP, "Leveled Spell"},
{RecordType::MATO, "Material Object"},
{RecordType::MATT, "Material Type"},
{RecordType::MESG, "Message"},
{RecordType::MGEF, "Magic Effect"},
{RecordType::MISC, "Misc.Item"},
{RecordType::MOVT, "Movement Type"},
{RecordType::MSTT, "Moveable Static"},
{RecordType::MUSC, "Music Type"},
{RecordType::MUST, "Music Track"},
{RecordType::NAVI, "Navigation Mesh Info Map"},
{RecordType::NAVM, "Navigation Mesh"},
{RecordType::NOTE, "NOTE"},
{RecordType::NPC_, "Non - Player Character(Actor)"},
{RecordType::OTFT, "Outfit"},
{RecordType::PACK, "Package"},
{RecordType::PARW, "Placed Arrow"},
{RecordType::PBAR, "Placed Barrier"},
{RecordType::PBEA, "Placed Beam"},
{RecordType::PCON, "Placed Cone / Voice"},
{RecordType::PERK, "Perk"},
{RecordType::PFLA, "Placed Flame"},
{RecordType::PGRE, "Placed Projectile"},
{RecordType::PHZD, "Placed Hazard"},
{RecordType::PLYR, "Player Reference"},
{RecordType::PMIS, "Placed Missile"},
{RecordType::PROJ, "Projectile"},
{RecordType::PWAT, "PWAT"},
{RecordType::QUST, "Quest"},
{RecordType::RACE, "Race"},
{RecordType::REFR, "Placed Object"},
{RecordType::REGN, "Region"},
{RecordType::RELA, "Relationship"},
{RecordType::REVB, "Reverb Parameters"},
{RecordType::RFCT, "Visual Effect"},
{RecordType::RGDL, "RGDL"},
{RecordType::SCEN, "Scene"},
{RecordType::SCOL, "SCOL"},
{RecordType::SCOL, "Static Collection"},
{RecordType::SCPT, "SCPT"},
{RecordType::SCRL, "Scroll"},
{RecordType::SHOU, "Shout"},
{RecordType::SLGM, "Soul Gem"},
{RecordType::SMBN, "Story Manager Branch Node"},
{RecordType::SMEN, "Story Manager Event Node"},
{RecordType::SMQN, "Story Manager Quest Node"},
{RecordType::SNCT, "Sound Category"},
{RecordType::SNDR, "Sound Descriptor"},
{RecordType::SOPM, "Sound Output Model"},
{RecordType::SOUN, "Sound Marker"},
{RecordType::SPEL, "Spell"},
{RecordType::SPGD, "Shader Particle Geometry"},
{RecordType::STAT, "Static"},
{RecordType::TACT, "Talking Activator"},
{RecordType::TES4, "Main File Header"},
{RecordType::TREE, "Tree"},
{RecordType::TXST, "Texture Set"},
{RecordType::VOLI, "Volumetric Lighting"},
{RecordType::VTYP, "Voice Type"},
{RecordType::WATR, "Water"},
{RecordType::WEAP, "Weapon"},
{RecordType::WOOP, "Word of Power"},
{RecordType::WRLD, "Worldspace"},
{RecordType::WTHR, "Weather"}
};
static constexpr std::pair<RecordType, FourCC> record_type_fourcc_map[] = {
{RecordType::AACT, FourCC("AACT")},
{RecordType::ACHR, FourCC("ACHR")},
{RecordType::ACTI, FourCC("ACTI")},
{RecordType::ADDN, FourCC("ADDN")},
{RecordType::ALCH, FourCC("ALCH")},
{RecordType::AMMO, FourCC("AMMO")},
{RecordType::ANIO, FourCC("ANIO")},
{RecordType::APPA, FourCC("APPA")},
{RecordType::ARMA, FourCC("ARMA")},
{RecordType::ARMO, FourCC("ARMO")},
{RecordType::ARTO, FourCC("ARTO")},
{RecordType::ASPC, FourCC("ASPC")},
{RecordType::ASTP, FourCC("ASTP")},
{RecordType::AVIF, FourCC("AVIF")},
{RecordType::BOOK, FourCC("BOOK")},
{RecordType::BPTD, FourCC("BPTD")},
{RecordType::CAMS, FourCC("CAMS")},
{RecordType::CELL, FourCC("CELL")},
{RecordType::CLAS, FourCC("CLAS")},
{RecordType::CLDC, FourCC("CLDC")},
{RecordType::CLFM, FourCC("CLFM")},
{RecordType::CLMT, FourCC("CLMT")},
{RecordType::COBJ, FourCC("COBJ")},
{RecordType::COLL, FourCC("COLL")},
{RecordType::CONT, FourCC("CONT")},
{RecordType::CPTH, FourCC("CPTH")},
{RecordType::CSTY, FourCC("CSTY")},
{RecordType::DEBR, FourCC("DEBR")},
{RecordType::DIAL, FourCC("DIAL")},
{RecordType::DLBR, FourCC("DLBR")},
{RecordType::DLVW, FourCC("DLVW")},
{RecordType::DOBJ, FourCC("DOBJ")},
{RecordType::DOOR, FourCC("DOOR")},
{RecordType::DUAL, FourCC("DUAL")},
{RecordType::ECZN, FourCC("ECZN")},
{RecordType::EFSH, FourCC("EFSH")},
{RecordType::ENCH, FourCC("ENCH")},
{RecordType::EQUP, FourCC("EQUP")},
{RecordType::EXPL, FourCC("EXPL")},
{RecordType::EYES, FourCC("EYES")},
{RecordType::FACT, FourCC("FACT")},
{RecordType::FLOR, FourCC("FLOR")},
{RecordType::FLST, FourCC("FLST")},
{RecordType::FSTP, FourCC("FSTP")},
{RecordType::FSTS, FourCC("FSTS")},
{RecordType::FURN, FourCC("FURN")},
{RecordType::GLOB, FourCC("GLOB")},
{RecordType::GMST, FourCC("GMST")},
{RecordType::GRAS, FourCC("GRAS")},
{RecordType::GRUP, FourCC("GRUP")},
{RecordType::HAIR, FourCC("HAIR")},
{RecordType::HAZD, FourCC("HAZD")},
{RecordType::HDPT, FourCC("HDPT")},
{RecordType::IDLE, FourCC("IDLE")},
{RecordType::IDLM, FourCC("IDLM")},
{RecordType::IMAD, FourCC("IMAD")},
{RecordType::IMGS, FourCC("IMGS")},
{RecordType::INFO, FourCC("INFO")},
{RecordType::INGR, FourCC("INGR")},
{RecordType::IPCT, FourCC("IPCT")},
{RecordType::IPDS, FourCC("IPDS")},
{RecordType::KEYM, FourCC("KEYM")},
{RecordType::KYWD, FourCC("KYWD")},
{RecordType::LAND, FourCC("LAND")},
{RecordType::LCRT, FourCC("LCRT")},
{RecordType::LCTN, FourCC("LCTN")},
{RecordType::LENS, FourCC("LENS")},
{RecordType::LGTM, FourCC("LGTM")},
{RecordType::LIGH, FourCC("LIGH")},
{RecordType::LSCR, FourCC("LSCR")},
{RecordType::LTEX, FourCC("LTEX")},
{RecordType::LVLI, FourCC("LVLI")},
{RecordType::LVLN, FourCC("LVLN")},
{RecordType::LVSP, FourCC("LVSP")},
{RecordType::MATO, FourCC("MATO")},
{RecordType::MATT, FourCC("MATT")},
{RecordType::MESG, FourCC("MESG")},
{RecordType::MGEF, FourCC("MGEF")},
{RecordType::MISC, FourCC("MISC")},
{RecordType::MOVT, FourCC("MOVT")},
{RecordType::MSTT, FourCC("MSTT")},
{RecordType::MUSC, FourCC("MUSC")},
{RecordType::MUST, FourCC("MUST")},
{RecordType::NAVI, FourCC("NAVI")},
{RecordType::NAVM, FourCC("NAVM")},
{RecordType::NOTE, FourCC("NOTE")},
{RecordType::NPC_, FourCC("NPC_")},
{RecordType::OTFT, FourCC("OTFT")},
{RecordType::PACK, FourCC("PACK")},
{RecordType::PARW, FourCC("PARW")},
{RecordType::PBAR, FourCC("PBAR")},
{RecordType::PBEA, FourCC("PBEA")},
{RecordType::PCON, FourCC("PCON")},
{RecordType::PERK, FourCC("PERK")},
{RecordType::PFLA, FourCC("PFLA")},
{RecordType::PGRE, FourCC("PGRE")},
{RecordType::PHZD, FourCC("PHZD")},
{RecordType::PLYR, FourCC("PLYR")},
{RecordType::PMIS, FourCC("PMIS")},
{RecordType::PROJ, FourCC("PROJ")},
{RecordType::PWAT, FourCC("PWAT")},
{RecordType::QUST, FourCC("QUST")},
{RecordType::RACE, FourCC("RACE")},
{RecordType::REFR, FourCC("REFR")},
{RecordType::REGN, FourCC("REGN")},
{RecordType::RELA, FourCC("RELA")},
{RecordType::REVB, FourCC("REVB")},
{RecordType::RFCT, FourCC("RFCT")},
{RecordType::RGDL, FourCC("RGDL")},
{RecordType::SCEN, FourCC("SCEN")},
{RecordType::SCOL, FourCC("SCOL")},
{RecordType::SCOL, FourCC("SCOL")},
{RecordType::SCPT, FourCC("SCPT")},
{RecordType::SCRL, FourCC("SCRL")},
{RecordType::SHOU, FourCC("SHOU")},
{RecordType::SLGM, FourCC("SLGM")},
{RecordType::SMBN, FourCC("SMBN")},
{RecordType::SMEN, FourCC("SMEN")},
{RecordType::SMQN, FourCC("SMQN")},
{RecordType::SNCT, FourCC("SNCT")},
{RecordType::SNDR, FourCC("SNDR")},
{RecordType::SOPM, FourCC("SOPM")},
{RecordType::SOUN, FourCC("SOUN")},
{RecordType::SPEL, FourCC("SPEL")},
{RecordType::SPGD, FourCC("SPGD")},
{RecordType::STAT, FourCC("STAT")},
{RecordType::TACT, FourCC("TACT")},
{RecordType::TES4, FourCC("TES4")},
{RecordType::TREE, FourCC("TREE")},
{RecordType::TXST, FourCC("TXST")},
{RecordType::VOLI, FourCC("VOLI")},
{RecordType::VTYP, FourCC("VTYP")},
{RecordType::WATR, FourCC("WATR")},
{RecordType::WEAP, FourCC("WEAP")},
{RecordType::WOOP, FourCC("WOOP")},
{RecordType::WRLD, FourCC("WRLD")},
{RecordType::WTHR, FourCC("WTHR")},
};
static constexpr std::pair<GroupType, std::string_view> group_type_names_map[] = {
static constexpr std::pair<GroupType, std::string_view> group_type_name_map_builtin[] {
{GroupType::Top , "Top Type" },
{GroupType::WorldChildren , "World Children" },
{GroupType::InteriorCellBlock , "Interior Cell Block" },
@@ -296,23 +16,599 @@ static constexpr std::pair<GroupType, std::string_view> group_type_names_map[] =
{GroupType::CellPersistentChildren, "Cell Persistent Children"},
{GroupType::CellTemporaryChildren , "Cell Temporary Children" },
};
static constexpr auto group_type_name_map_std = utility::array_builtin_to_std(group_type_name_map_builtin);
static constexpr auto group_type_name_map = utility::map_to_soa(group_type_name_map_std);
[[nodiscard]] constexpr std::optional<std::string_view> group_type_to_name(GroupType group_type) noexcept
{
return utility::soa_first_to_second(group_type_name_map, group_type);
}
struct flag {
RecordType type;
unsigned bit;
static constexpr std::pair<RecordType, FourCC> record_type_fourcc_map_builtin[] {
{RecordType::AACT, FourCC("AACT")}, {RecordType::ACHR, FourCC("ACHR")},
{RecordType::ACTI, FourCC("ACTI")}, {RecordType::ADDN, FourCC("ADDN")},
{RecordType::ALCH, FourCC("ALCH")}, {RecordType::AMMO, FourCC("AMMO")},
{RecordType::ANIO, FourCC("ANIO")}, {RecordType::APPA, FourCC("APPA")},
{RecordType::ARMA, FourCC("ARMA")}, {RecordType::ARMO, FourCC("ARMO")},
{RecordType::ARTO, FourCC("ARTO")}, {RecordType::ASPC, FourCC("ASPC")},
{RecordType::ASTP, FourCC("ASTP")}, {RecordType::AVIF, FourCC("AVIF")},
{RecordType::BOOK, FourCC("BOOK")}, {RecordType::BPTD, FourCC("BPTD")},
{RecordType::CAMS, FourCC("CAMS")}, {RecordType::CELL, FourCC("CELL")},
{RecordType::CLAS, FourCC("CLAS")}, {RecordType::CLDC, FourCC("CLDC")},
{RecordType::CLFM, FourCC("CLFM")}, {RecordType::CLMT, FourCC("CLMT")},
{RecordType::COBJ, FourCC("COBJ")}, {RecordType::COLL, FourCC("COLL")},
{RecordType::CONT, FourCC("CONT")}, {RecordType::CPTH, FourCC("CPTH")},
{RecordType::CSTY, FourCC("CSTY")}, {RecordType::DEBR, FourCC("DEBR")},
{RecordType::DIAL, FourCC("DIAL")}, {RecordType::DLBR, FourCC("DLBR")},
{RecordType::DLVW, FourCC("DLVW")}, {RecordType::DOBJ, FourCC("DOBJ")},
{RecordType::DOOR, FourCC("DOOR")}, {RecordType::DUAL, FourCC("DUAL")},
{RecordType::ECZN, FourCC("ECZN")}, {RecordType::EFSH, FourCC("EFSH")},
{RecordType::ENCH, FourCC("ENCH")}, {RecordType::EQUP, FourCC("EQUP")},
{RecordType::EXPL, FourCC("EXPL")}, {RecordType::EYES, FourCC("EYES")},
{RecordType::FACT, FourCC("FACT")}, {RecordType::FLOR, FourCC("FLOR")},
{RecordType::FLST, FourCC("FLST")}, {RecordType::FSTP, FourCC("FSTP")},
{RecordType::FSTS, FourCC("FSTS")}, {RecordType::FURN, FourCC("FURN")},
{RecordType::GLOB, FourCC("GLOB")}, {RecordType::GMST, FourCC("GMST")},
{RecordType::GRAS, FourCC("GRAS")}, {RecordType::GRUP, FourCC("GRUP")},
{RecordType::HAIR, FourCC("HAIR")}, {RecordType::HAZD, FourCC("HAZD")},
{RecordType::HDPT, FourCC("HDPT")}, {RecordType::IDLE, FourCC("IDLE")},
{RecordType::IDLM, FourCC("IDLM")}, {RecordType::IMAD, FourCC("IMAD")},
{RecordType::IMGS, FourCC("IMGS")}, {RecordType::INFO, FourCC("INFO")},
{RecordType::INGR, FourCC("INGR")}, {RecordType::IPCT, FourCC("IPCT")},
{RecordType::IPDS, FourCC("IPDS")}, {RecordType::KEYM, FourCC("KEYM")},
{RecordType::KYWD, FourCC("KYWD")}, {RecordType::LAND, FourCC("LAND")},
{RecordType::LCRT, FourCC("LCRT")}, {RecordType::LCTN, FourCC("LCTN")},
{RecordType::LENS, FourCC("LENS")}, {RecordType::LGTM, FourCC("LGTM")},
{RecordType::LIGH, FourCC("LIGH")}, {RecordType::LSCR, FourCC("LSCR")},
{RecordType::LTEX, FourCC("LTEX")}, {RecordType::LVLI, FourCC("LVLI")},
{RecordType::LVLN, FourCC("LVLN")}, {RecordType::LVSP, FourCC("LVSP")},
{RecordType::MATO, FourCC("MATO")}, {RecordType::MATT, FourCC("MATT")},
{RecordType::MESG, FourCC("MESG")}, {RecordType::MGEF, FourCC("MGEF")},
{RecordType::MISC, FourCC("MISC")}, {RecordType::MOVT, FourCC("MOVT")},
{RecordType::MSTT, FourCC("MSTT")}, {RecordType::MUSC, FourCC("MUSC")},
{RecordType::MUST, FourCC("MUST")}, {RecordType::NAVI, FourCC("NAVI")},
{RecordType::NAVM, FourCC("NAVM")}, {RecordType::NOTE, FourCC("NOTE")},
{RecordType::NPC_, FourCC("NPC_")}, {RecordType::OTFT, FourCC("OTFT")},
{RecordType::PACK, FourCC("PACK")}, {RecordType::PARW, FourCC("PARW")},
{RecordType::PBAR, FourCC("PBAR")}, {RecordType::PBEA, FourCC("PBEA")},
{RecordType::PCON, FourCC("PCON")}, {RecordType::PERK, FourCC("PERK")},
{RecordType::PFLA, FourCC("PFLA")}, {RecordType::PGRE, FourCC("PGRE")},
{RecordType::PHZD, FourCC("PHZD")}, {RecordType::PLYR, FourCC("PLYR")},
{RecordType::PMIS, FourCC("PMIS")}, {RecordType::PROJ, FourCC("PROJ")},
{RecordType::PWAT, FourCC("PWAT")}, {RecordType::QUST, FourCC("QUST")},
{RecordType::RACE, FourCC("RACE")}, {RecordType::REFR, FourCC("REFR")},
{RecordType::REGN, FourCC("REGN")}, {RecordType::RELA, FourCC("RELA")},
{RecordType::REVB, FourCC("REVB")}, {RecordType::RFCT, FourCC("RFCT")},
{RecordType::RGDL, FourCC("RGDL")}, {RecordType::SCEN, FourCC("SCEN")},
{RecordType::SCOL, FourCC("SCOL")}, {RecordType::SCPT, FourCC("SCPT")},
{RecordType::SCRL, FourCC("SCRL")}, {RecordType::SHOU, FourCC("SHOU")},
{RecordType::SLGM, FourCC("SLGM")}, {RecordType::SMBN, FourCC("SMBN")},
{RecordType::SMEN, FourCC("SMEN")}, {RecordType::SMQN, FourCC("SMQN")},
{RecordType::SNCT, FourCC("SNCT")}, {RecordType::SNDR, FourCC("SNDR")},
{RecordType::SOPM, FourCC("SOPM")}, {RecordType::SOUN, FourCC("SOUN")},
{RecordType::SPEL, FourCC("SPEL")}, {RecordType::SPGD, FourCC("SPGD")},
{RecordType::STAT, FourCC("STAT")}, {RecordType::TACT, FourCC("TACT")},
{RecordType::TES4, FourCC("TES4")}, {RecordType::TREE, FourCC("TREE")},
{RecordType::TXST, FourCC("TXST")}, {RecordType::VOLI, FourCC("VOLI")},
{RecordType::VTYP, FourCC("VTYP")}, {RecordType::WATR, FourCC("WATR")},
{RecordType::WEAP, FourCC("WEAP")}, {RecordType::WOOP, FourCC("WOOP")},
{RecordType::WRLD, FourCC("WRLD")}, {RecordType::WTHR, FourCC("WTHR")},
};
static constexpr auto record_type_fourcc_map_std = utility::array_builtin_to_std(record_type_fourcc_map_builtin);
static constexpr auto record_type_fourcc_map = utility::map_to_soa(record_type_fourcc_map_std);
[[nodiscard]] constexpr std::optional<FourCC> record_type_to_fourcc(RecordType record_type) noexcept
{
return utility::soa_first_to_second(record_type_fourcc_map, record_type);
}
[[nodiscard]] constexpr std::optional<RecordType> fourcc_to_record_type(FourCC fourcc) noexcept
{
return utility::soa_second_to_first(record_type_fourcc_map, fourcc);
}
static constexpr std::pair<flag, std::string_view> flag_strings_map[]{
{{RecordType::ACHR, 9}, "Starts Dead"},
static constexpr std::pair<RecordType, std::string_view> record_type_name_map_builtin[] {
{RecordType::AACT, "Action" },
{RecordType::ACHR, "Placed NPC" },
{RecordType::ACTI, "Activator" },
{RecordType::ADDN, "Addon Node" },
{RecordType::ALCH, "Ingestible" },
{RecordType::AMMO, "Ammunition" },
{RecordType::ANIO, "Animated Object" },
{RecordType::APPA, "Alchemical Apparatus" },
{RecordType::ARMA, "Armor Addon" },
{RecordType::ARMO, "Armor" },
{RecordType::ARTO, "Art Object" },
{RecordType::ASPC, "Acoustic Space" },
{RecordType::ASTP, "Association Type" },
{RecordType::AVIF, "Actor Value Information" },
{RecordType::BOOK, "Book" },
{RecordType::BPTD, "Body Part Data" },
{RecordType::CAMS, "Camera Shot" },
{RecordType::CELL, "Cell" },
{RecordType::CLAS, "Class" },
{RecordType::CLDC, "CLDC" },
{RecordType::CLFM, "Color" },
{RecordType::CLMT, "Climate" },
{RecordType::COBJ, "Constructible Object" },
{RecordType::COLL, "Collision Layer" },
{RecordType::CONT, "Container" },
{RecordType::CPTH, "Camera Path" },
{RecordType::CSTY, "Combat Style" },
{RecordType::DEBR, "Debris" },
{RecordType::DIAL, "Dialog Topic" },
{RecordType::DLBR, "Dialog Branch" },
{RecordType::DLVW, "Dialog View" },
{RecordType::DOBJ, "Default Object Manager" },
{RecordType::DOOR, "Door" },
{RecordType::DUAL, "Dual Cast Data" },
{RecordType::ECZN, "Encounter Zone" },
{RecordType::EFSH, "Effect Shader" },
{RecordType::ENCH, "Object Effect" },
{RecordType::EQUP, "Equip Type" },
{RecordType::EXPL, "Explosion" },
{RecordType::EYES, "Eyes" },
{RecordType::FACT, "Faction" },
{RecordType::FLOR, "Flora" },
{RecordType::FLST, "FormID List" },
{RecordType::FSTP, "Footstep" },
{RecordType::FSTS, "Footstep Set" },
{RecordType::FURN, "Furniture" },
{RecordType::GLOB, "Global" },
{RecordType::GMST, "Game Setting" },
{RecordType::GRAS, "Grass" },
{RecordType::GRUP, "Group" },
{RecordType::HAIR, "HAIR" },
{RecordType::HAZD, "Hazard" },
{RecordType::HDPT, "Head Part" },
{RecordType::IDLE, "Idle Animation" },
{RecordType::IDLM, "Idle Marker" },
{RecordType::IMAD, "Image Space Adapter" },
{RecordType::IMGS, "Image Space" },
{RecordType::INFO, "Dialog response" },
{RecordType::INGR, "Ingredient" },
{RecordType::IPCT, "Impact" },
{RecordType::IPDS, "Impact Data Set" },
{RecordType::KEYM, "Key" },
{RecordType::KYWD, "Keyword" },
{RecordType::LAND, "Landscape" },
{RecordType::LCRT, "Location Reference Type" },
{RecordType::LCTN, "Location" },
{RecordType::LENS, "Lens Flare" },
{RecordType::LGTM, "Lighting Template" },
{RecordType::LIGH, "Light" },
{RecordType::LSCR, "Load Screen" },
{RecordType::LTEX, "Landscape Texture" },
{RecordType::LVLI, "Leveled Item" },
{RecordType::LVLN, "Leveled NPC" },
{RecordType::LVSP, "Leveled Spell" },
{RecordType::MATO, "Material Object" },
{RecordType::MATT, "Material Type" },
{RecordType::MESG, "Message" },
{RecordType::MGEF, "Magic Effect" },
{RecordType::MISC, "Misc. Item" },
{RecordType::MOVT, "Movement Type" },
{RecordType::MSTT, "Moveable Static" },
{RecordType::MUSC, "Music Type" },
{RecordType::MUST, "Music Track" },
{RecordType::NAVI, "Navigation Mesh Info Map" },
{RecordType::NAVM, "Navigation Mesh" },
{RecordType::NOTE, "Note" },
{RecordType::NPC_, "Non-Player Character (Actor)"},
{RecordType::OTFT, "Outfit" },
{RecordType::PACK, "Package" },
{RecordType::PARW, "Placed Arrow" },
{RecordType::PBAR, "Placed Barrier" },
{RecordType::PBEA, "Placed Beam" },
{RecordType::PCON, "Placed Cone/Voice" },
{RecordType::PERK, "Perk" },
{RecordType::PFLA, "Placed Flame" },
{RecordType::PGRE, "Placed Projectile" },
{RecordType::PHZD, "Placed Hazard" },
{RecordType::PLYR, "Player Reference" },
{RecordType::PMIS, "Placed Missile" },
{RecordType::PROJ, "Projectile" },
{RecordType::PWAT, "PWAT" },
{RecordType::QUST, "Quest" },
{RecordType::RACE, "Race" },
{RecordType::REFR, "Placed Object" },
{RecordType::REGN, "Region" },
{RecordType::RELA, "Relationship" },
{RecordType::REVB, "Reverb Parameters" },
{RecordType::RFCT, "Visual Effect" },
{RecordType::RGDL, "RGDL" },
{RecordType::SCEN, "Scene" },
{RecordType::SCOL, "Static Collection" },
{RecordType::SCPT, "SCPT" },
{RecordType::SCRL, "Scroll" },
{RecordType::SHOU, "Shout" },
{RecordType::SLGM, "Soul Gem" },
{RecordType::SMBN, "Story Manager Branch Node" },
{RecordType::SMEN, "Story Manager Event Node" },
{RecordType::SMQN, "Story Manager Quest Node" },
{RecordType::SNCT, "Sound Category" },
{RecordType::SNDR, "Sound Descriptor" },
{RecordType::SOPM, "Sound Output Model" },
{RecordType::SOUN, "Sound Marker" },
{RecordType::SPEL, "Spell" },
{RecordType::SPGD, "Shader Particle Geometry" },
{RecordType::STAT, "Static" },
{RecordType::TACT, "Talking Activator" },
{RecordType::TES4, "Main File Header" },
{RecordType::TREE, "Tree" },
{RecordType::TXST, "Texture Set" },
{RecordType::VOLI, "Volumetric Lighting" },
{RecordType::VTYP, "Voice Type" },
{RecordType::WATR, "Water" },
{RecordType::WEAP, "Weapon" },
{RecordType::WOOP, "Word of Power" },
{RecordType::WRLD, "Worldspace" },
{RecordType::WTHR, "Weather" },
};
static constexpr auto record_type_name_map_std = utility::array_builtin_to_std(record_type_name_map_builtin);
static constexpr auto record_type_name_map = utility::map_to_soa(record_type_name_map_std);
[[nodiscard]] constexpr std::optional<std::string_view> record_type_to_name(RecordType record_type) noexcept
{
return utility::soa_first_to_second(record_type_name_map, record_type);
}
struct refr_flag {
RecordType refr_type;
unsigned bit;
static constexpr std::pair<Flag, std::string_view> flag_description_map_builtin[] {
{{RecordType::ACHR, 9}, "Starts Dead" },
{{RecordType::ACHR, 10}, "Persistent" },
{{RecordType::ACHR, 11}, "Initially Disabled" },
{{RecordType::ACHR, 25}, "No AI Acquire" },
{{RecordType::ACHR, 29}, "Don't Havok Settle" },
{{RecordType::ACTI, 6}, "Has Tree LOD" },
{{RecordType::ACTI, 8}, "Must Update Anims" },
{{RecordType::ACTI, 9}, "Hidden From Local Map" },
{{RecordType::ACTI, 15}, "Has Distant LOD" },
{{RecordType::ACTI, 16}, "Random Anim Start" },
{{RecordType::ACTI, 17}, "Dangerous" },
{{RecordType::ACTI, 20}, "Ignore Object Interaction" },
{{RecordType::ACTI, 23}, "Is Marker" },
{{RecordType::ACTI, 25}, "Obstacle" },
{{RecordType::ACTI, 26}, "NavMesh Generation - Filter" },
{{RecordType::ACTI, 27}, "NavMesh Generation - Bounding Box"},
{{RecordType::ACTI, 29}, "Child Can Use" },
{{RecordType::ACTI, 30}, "NavMesh Generation - Ground" },
{{RecordType::ALCH, 29}, "Medicine" },
{{RecordType::AMMO, 2}, "Non-Playable" },
{{RecordType::ANIO, 9}, "Unknown 9" },
{{RecordType::ARMO, 2}, "Non-Playable" },
{{RecordType::ARMO, 6}, "Shield" },
{{RecordType::ARMO, 10}, "Unknown 10" },
{{RecordType::ARMO, 15}, "Unknown 15" },
{{RecordType::CELL, 10}, "Persistent" },
{{RecordType::CELL, 17}, "Off Limits" },
{{RecordType::CELL, 18}, "Compressed" },
{{RecordType::CELL, 19}, "Can't Wait" },
{{RecordType::CLFM, 2}, "Non-Playable" },
{{RecordType::CONT, 15}, "Has Distant LOD" },
{{RecordType::CONT, 16}, "Random Anim Start" },
{{RecordType::CONT, 25}, "Obstacle" },
{{RecordType::CONT, 26}, "NavMesh Generation - Filter" },
{{RecordType::CONT, 27}, "NavMesh Generation - Bounding Box"},
{{RecordType::CONT, 30}, "NavMesh Generation - Ground" },
{{RecordType::CSTY, 19}, "Allow Dual Wielding" },
{{RecordType::DOOR, 15}, "Has Distant LOD" },
{{RecordType::DOOR, 16}, "Random Anim Start" },
{{RecordType::DOOR, 23}, "Is Marker" },
{{RecordType::EYES, 2}, "Non-Playable" },
{{RecordType::FURN, 7}, "Is Perch" },
{{RecordType::FURN, 15}, "Has Distant LOD" },
{{RecordType::FURN, 16}, "Random Anim Start" },
{{RecordType::FURN, 23}, "Is Marker" },
{{RecordType::FURN, 28}, "Must Exit To Talk" },
{{RecordType::FURN, 29}, "Child Can Use" },
{{RecordType::GLOB, 6}, "Constant" },
{{RecordType::HDPT, 2}, "Non-Playable" },
{{RecordType::IDLM, 29}, "Child Can Use" },
{{RecordType::INFO, 13}, "Actor Changed" },
{{RecordType::KEYM, 2}, "Non-Playable" },
{{RecordType::LAND, 18}, "Compressed" },
{{RecordType::LIGH, 16}, "Random Anim Start" },
{{RecordType::LIGH, 17}, "Portal-strict" },
{{RecordType::LIGH, 25}, "Obstacle" },
{{RecordType::LSCR, 10}, "Displays In Main Menu" },
{{RecordType::MISC, 2}, "Non-Playable" },
{{RecordType::MSTT, 8}, "Must Update Anims" },
{{RecordType::MSTT, 9}, "Hidden From Local Map" },
{{RecordType::MSTT, 15}, "Has Distant LOD" },
{{RecordType::MSTT, 16}, "Random Anim Start" },
{{RecordType::MSTT, 19}, "Has Currents" },
{{RecordType::MSTT, 25}, "Obstacle" },
{{RecordType::MSTT, 26}, "NavMesh Generation - Filter" },
{{RecordType::MSTT, 27}, "NavMesh Generation - Bounding Box"},
{{RecordType::MSTT, 30}, "NavMesh Generation - Ground" },
{{RecordType::NAVM, 18}, "Compressed" },
{{RecordType::NAVM, 26}, "AutoGen" },
{{RecordType::NAVM, 31}, "NavmeshGenCell" },
{{RecordType::NPC_, 10}, "Unknown 10" },
{{RecordType::NPC_, 18}, "Compressed" },
{{RecordType::NPC_, 19}, "Unknown 19" },
{{RecordType::NPC_, 29}, "Bleedout Override" },
{{RecordType::PARW, 7}, "Turn Off Fire" },
{{RecordType::PARW, 10}, "Persistent" },
{{RecordType::PARW, 11}, "Initially Disabled" },
{{RecordType::PARW, 28}, "Reflected By Auto Water" },
{{RecordType::PARW, 29}, "Don't Havok Settle" },
{{RecordType::PARW, 30}, "No Respawn" },
{{RecordType::PBAR, 7}, "Turn Off Fire" },
{{RecordType::PBAR, 10}, "Persistent" },
{{RecordType::PBAR, 11}, "Initially Disabled" },
{{RecordType::PBAR, 28}, "Reflected By Auto Water" },
{{RecordType::PBAR, 29}, "Don't Havok Settle" },
{{RecordType::PBAR, 30}, "No Respawn" },
{{RecordType::PBEA, 7}, "Turn Off Fire" },
{{RecordType::PBEA, 10}, "Persistent" },
{{RecordType::PBEA, 11}, "Initially Disabled" },
{{RecordType::PBEA, 28}, "Reflected By Auto Water" },
{{RecordType::PBEA, 29}, "Don't Havok Settle" },
{{RecordType::PBEA, 30}, "No Respawn" },
{{RecordType::PCON, 7}, "Turn Off Fire" },
{{RecordType::PCON, 10}, "Persistent" },
{{RecordType::PCON, 11}, "Initially Disabled" },
{{RecordType::PCON, 28}, "Reflected By Auto Water" },
{{RecordType::PCON, 29}, "Don't Havok Settle" },
{{RecordType::PCON, 30}, "No Respawn" },
{{RecordType::PERK, 2}, "Non-Playable" },
{{RecordType::PFLA, 7}, "Turn Off Fire" },
{{RecordType::PFLA, 10}, "Persistent" },
{{RecordType::PFLA, 11}, "Initially Disabled" },
{{RecordType::PFLA, 28}, "Reflected By Auto Water" },
{{RecordType::PFLA, 29}, "Don't Havok Settle" },
{{RecordType::PFLA, 30}, "No Respawn" },
{{RecordType::PGRE, 7}, "Turn Off Fire" },
{{RecordType::PGRE, 10}, "Persistent" },
{{RecordType::PGRE, 11}, "Initially Disabled" },
{{RecordType::PGRE, 28}, "Reflected By Auto Water" },
{{RecordType::PGRE, 29}, "Don't Havok Settle" },
{{RecordType::PGRE, 30}, "No Respawn" },
{{RecordType::PHZD, 7}, "Turn Off Fire" },
{{RecordType::PHZD, 10}, "Persistent" },
{{RecordType::PHZD, 11}, "Initially Disabled" },
{{RecordType::PHZD, 28}, "Reflected By Auto Water" },
{{RecordType::PHZD, 29}, "Don't Havok Settle" },
{{RecordType::PHZD, 30}, "No Respawn" },
{{RecordType::PMIS, 7}, "Turn Off Fire" },
{{RecordType::PMIS, 10}, "Persistent" },
{{RecordType::PMIS, 11}, "Initially Disabled" },
{{RecordType::PMIS, 28}, "Reflected By Auto Water" },
{{RecordType::PMIS, 29}, "Don't Havok Settle" },
{{RecordType::PMIS, 30}, "No Respawn" },
{{RecordType::RACE, 19}, "Critter?" },
{{RecordType::REFR, 10}, "Persistent" },
{{RecordType::REFR, 11}, "Initially Disabled" },
{{RecordType::REFR, 16}, "Is Full LOD" },
{{RecordType::REFR, 26}, "Filter (Collision Geometry)" },
{{RecordType::REFR, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::REFR, 28}, "Reflected By Auto Water" },
{{RecordType::REFR, 30}, "Ground" },
{{RecordType::REFR, 31}, "Multibound" },
{{RecordType::REGN, 6}, "Border Region" },
{{RecordType::RELA, 6}, "Secret" },
{{RecordType::SHOU, 7}, "Treat spells as powers" },
{{RecordType::SLGM, 17}, "Can Hold NPC Soul" },
{{RecordType::STAT, 2}, "Never Fades" },
{{RecordType::STAT, 5}, "Deleted" },
{{RecordType::STAT, 6}, "Has Tree LOD" },
{{RecordType::STAT, 7}, "Add-On LOD Object" },
{{RecordType::STAT, 9}, "Hidden From Local Map" },
{{RecordType::STAT, 11}, "Unknown 11" },
{{RecordType::STAT, 15}, "Has Distant LOD" },
{{RecordType::STAT, 16}, "Unknown 16" },
{{RecordType::STAT, 17}, "Uses HD LOD Texture" },
{{RecordType::STAT, 19}, "Has Currents" },
{{RecordType::STAT, 23}, "Is Marker" },
{{RecordType::STAT, 25}, "Obstacle" },
{{RecordType::STAT, 26}, "NavMesh Generation - Filter" },
{{RecordType::STAT, 27}, "NavMesh Generation - Bounding Box"},
{{RecordType::STAT, 28}, "Show In World Map" },
{{RecordType::STAT, 30}, "NavMesh Generation - Ground" },
{{RecordType::TACT, 9}, "Hidden From Local Map" },
{{RecordType::TACT, 16}, "Random Anim Start" },
{{RecordType::TACT, 17}, "Radio Station" },
{{RecordType::TES4, 0}, "ESM" },
{{RecordType::TES4, 1}, "Altered" },
{{RecordType::TES4, 2}, "Checked" },
{{RecordType::TES4, 3}, "Active" },
{{RecordType::TES4, 4}, "Optimized File" },
{{RecordType::TES4, 5}, "Temp ID Owner" },
{{RecordType::TES4, 7}, "Localized" },
{{RecordType::TES4, 8}, "Precalc Data Only" },
{{RecordType::TES4, 9}, "ESL" },
{{RecordType::TREE, 15}, "Has Distant LOD" },
{{RecordType::WEAP, 2}, "Non-Playable" },
{{RecordType::WRLD, 19}, "Can't Wait" },
};
static constexpr auto flag_description_map_std = utility::array_builtin_to_std(flag_description_map_builtin);
static constexpr auto flag_description_map = utility::map_to_soa(flag_description_map_std);
[[nodiscard]] constexpr std::optional<std::string_view> flag_to_description(Flag flag) noexcept
{
return utility::soa_first_to_second(flag_description_map, flag);
}
static constexpr std::pair<flag, std::string_view> refr_flag_strings_map[]{
{{RecordType::ACHR, 9}, "Hidden From Local Map"},
static constexpr std::pair<RefrFlag, std::string_view> refr_flag_description_map_builtin[] {
{{RecordType::ACTI, 9}, "Hidden From Local Map" },
{{RecordType::ACTI, 10}, "Persistent" },
{{RecordType::ACTI, 11}, "Initially Disabled" },
{{RecordType::ACTI, 13}, "Sky Marker" },
{{RecordType::ACTI, 15}, "Visible when distant" },
{{RecordType::ACTI, 16}, "Is Full LOD" },
{{RecordType::ACTI, 26}, "Filter (Collision Geometry)" },
{{RecordType::ACTI, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::ACTI, 28}, "Reflected By Auto Water" },
{{RecordType::ACTI, 29}, "Don''t Havok Settle" },
{{RecordType::ACTI, 30}, "No Respawn" },
{{RecordType::ACTI, 31}, "Multibound" },
{{RecordType::ADDN, 10}, "Persistent" },
{{RecordType::ADDN, 11}, "Initially Disabled" },
{{RecordType::ADDN, 16}, "Is Full LOD" },
{{RecordType::ADDN, 28}, "Reflected By Auto Water" },
{{RecordType::ADDN, 29}, "Don''t Havok Settle" },
{{RecordType::ADDN, 30}, "No Respawn" },
{{RecordType::ADDN, 31}, "Multibound" },
{{RecordType::ALCH, 10}, "Persistent" },
{{RecordType::ALCH, 11}, "Initially Disabled" },
{{RecordType::ALCH, 16}, "Is Full LOD" },
{{RecordType::ALCH, 25}, "No AI Acquire" },
{{RecordType::ALCH, 28}, "Reflected By Auto Water" },
{{RecordType::ALCH, 29}, "Don''t Havok Settle" },
{{RecordType::ALCH, 30}, "No Respawn" },
{{RecordType::ALCH, 31}, "Multibound" },
{{RecordType::AMMO, 10}, "Persistent" },
{{RecordType::AMMO, 11}, "Initially Disabled" },
{{RecordType::AMMO, 16}, "Is Full LOD" },
{{RecordType::AMMO, 25}, "No AI Acquire" },
{{RecordType::AMMO, 28}, "Reflected By Auto Water" },
{{RecordType::AMMO, 29}, "Don''t Havok Settle" },
{{RecordType::AMMO, 30}, "No Respawn" },
{{RecordType::AMMO, 31}, "Multibound" },
{{RecordType::ARMO, 10}, "Persistent" },
{{RecordType::ARMO, 11}, "Initially Disabled" },
{{RecordType::ARMO, 16}, "Is Full LOD" },
{{RecordType::ARMO, 25}, "No AI Acquire" },
{{RecordType::ARMO, 28}, "Reflected By Auto Water" },
{{RecordType::ARMO, 29}, "Don''t Havok Settle" },
{{RecordType::ARMO, 30}, "No Respawn" },
{{RecordType::ARMO, 31}, "Multibound" },
{{RecordType::BOOK, 10}, "Persistent" },
{{RecordType::BOOK, 11}, "Initially Disabled" },
{{RecordType::BOOK, 16}, "Is Full LOD" },
{{RecordType::BOOK, 25}, "No AI Acquire" },
{{RecordType::BOOK, 28}, "Reflected By Auto Water" },
{{RecordType::BOOK, 29}, "Don''t Havok Settle" },
{{RecordType::BOOK, 30}, "No Respawn" },
{{RecordType::BOOK, 31}, "Multibound" },
{{RecordType::CONT, 10}, "Persistent" },
{{RecordType::CONT, 11}, "Initially Disabled" },
{{RecordType::CONT, 16}, "Is Full LOD" },
{{RecordType::CONT, 25}, "No AI Acquire" },
{{RecordType::CONT, 26}, "Filter (Collision Geometry)" },
{{RecordType::CONT, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::CONT, 28}, "Reflected By Auto Water" },
{{RecordType::CONT, 29}, "Don''t Havok Settle" },
{{RecordType::CONT, 30}, "Ground" },
{{RecordType::CONT, 31}, "Multibound" },
{{RecordType::DOOR, 6}, "Hidden From Local Map" },
{{RecordType::DOOR, 8}, "Inaccessible" },
{{RecordType::DOOR, 10}, "Persistent" },
{{RecordType::DOOR, 11}, "Initially Disabled" },
{{RecordType::DOOR, 16}, "Is Full LOD" },
{{RecordType::DOOR, 26}, "Filter (Collision Geometry)" },
{{RecordType::DOOR, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::DOOR, 28}, "Reflected By Auto Water" },
{{RecordType::DOOR, 29}, "Don''t Havok Settle" },
{{RecordType::DOOR, 30}, "No Respawn" },
{{RecordType::DOOR, 31}, "Multibound" },
{{RecordType::FLOR, 9}, "Hidden From Local Map" },
{{RecordType::FLOR, 10}, "Persistent" },
{{RecordType::FLOR, 11}, "Initially Disabled" },
{{RecordType::FLOR, 13}, "Sky Marker" },
{{RecordType::FLOR, 15}, "Visible when distant" },
{{RecordType::FLOR, 16}, "Is Full LOD" },
{{RecordType::FLOR, 26}, "Filter (Collision Geometry)" },
{{RecordType::FLOR, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::FLOR, 28}, "Reflected By Auto Water" },
{{RecordType::FLOR, 29}, "Don''t Havok Settle" },
{{RecordType::FLOR, 30}, "No Respawn" },
{{RecordType::FLOR, 31}, "Multibound" },
{{RecordType::INGR, 10}, "Persistent" },
{{RecordType::INGR, 11}, "Initially Disabled" },
{{RecordType::INGR, 16}, "Is Full LOD" },
{{RecordType::INGR, 25}, "No AI Acquire" },
{{RecordType::INGR, 28}, "Reflected By Auto Water" },
{{RecordType::INGR, 29}, "Don''t Havok Settle" },
{{RecordType::INGR, 30}, "No Respawn" },
{{RecordType::INGR, 31}, "Multibound" },
{{RecordType::KEYM, 10}, "Persistent" },
{{RecordType::KEYM, 11}, "Initially Disabled" },
{{RecordType::KEYM, 16}, "Is Full LOD" },
{{RecordType::KEYM, 25}, "No AI Acquire" },
{{RecordType::KEYM, 28}, "Reflected By Auto Water" },
{{RecordType::KEYM, 29}, "Don''t Havok Settle" },
{{RecordType::KEYM, 30}, "No Respawn" },
{{RecordType::KEYM, 31}, "Multibound" },
{{RecordType::LIGH, 8}, "Doesn''t Light Water" },
{{RecordType::LIGH, 9}, "Casts Shadows" },
{{RecordType::LIGH, 10}, "Persistent" },
{{RecordType::LIGH, 11}, "Initially Disabled" },
{{RecordType::LIGH, 16}, "Never Fades" },
{{RecordType::LIGH, 17}, "Doesn''t Light Landscape" },
{{RecordType::LIGH, 25}, "No AI Acquire" },
{{RecordType::LIGH, 28}, "Reflected By Auto Water" },
{{RecordType::LIGH, 29}, "Don''t Havok Settle" },
{{RecordType::LIGH, 30}, "No Respawn" },
{{RecordType::LIGH, 31}, "Multibound" },
{{RecordType::MISC, 10}, "Persistent" },
{{RecordType::MISC, 11}, "Initially Disabled" },
{{RecordType::MISC, 16}, "Is Full LOD" },
{{RecordType::MISC, 25}, "No AI Acquire" },
{{RecordType::MISC, 28}, "Reflected By Auto Water" },
{{RecordType::MISC, 29}, "Don''t Havok Settle" },
{{RecordType::MISC, 30}, "No Respawn" },
{{RecordType::MISC, 31}, "Multibound" },
{{RecordType::MSTT, 9}, "Motion Blur" },
{{RecordType::MSTT, 10}, "Persistent" },
{{RecordType::MSTT, 11}, "Initially Disabled" },
{{RecordType::MSTT, 16}, "Is Full LOD" },
{{RecordType::MSTT, 26}, "Filter (Collision Geometry)" },
{{RecordType::MSTT, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::MSTT, 28}, "Reflected By Auto Water" },
{{RecordType::MSTT, 29}, "Don''t Havok Settle" },
{{RecordType::MSTT, 30}, "No Respawn" },
{{RecordType::MSTT, 31}, "Multibound" },
{{RecordType::SCRL, 10}, "Persistent" },
{{RecordType::SCRL, 11}, "Initially Disabled" },
{{RecordType::SCRL, 16}, "Is Full LOD" },
{{RecordType::SCRL, 25}, "No AI Acquire" },
{{RecordType::SCRL, 28}, "Reflected By Auto Water" },
{{RecordType::SCRL, 29}, "Don''t Havok Settle" },
{{RecordType::SCRL, 30}, "No Respawn" },
{{RecordType::SCRL, 31}, "Multibound" },
{{RecordType::SLGM, 10}, "Persistent" },
{{RecordType::SLGM, 11}, "Initially Disabled" },
{{RecordType::SLGM, 16}, "Is Full LOD" },
{{RecordType::SLGM, 25}, "No AI Acquire" },
{{RecordType::SLGM, 28}, "Reflected By Auto Water" },
{{RecordType::SLGM, 29}, "Don''t Havok Settle" },
{{RecordType::SLGM, 30}, "No Respawn" },
{{RecordType::SLGM, 31}, "Multibound" },
{{RecordType::STAT, 9}, "Hidden From Local Map" },
{{RecordType::STAT, 10}, "Persistent" },
{{RecordType::STAT, 11}, "Initially Disabled" },
{{RecordType::STAT, 13}, "Sky Marker" },
{{RecordType::STAT, 15}, "Visible when distant" },
{{RecordType::STAT, 16}, "Is Full LOD" },
{{RecordType::STAT, 26}, "Filter (Collision Geometry)" },
{{RecordType::STAT, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::STAT, 28}, "Reflected By Auto Water" },
{{RecordType::STAT, 29}, "Don''t Havok Settle" },
{{RecordType::STAT, 30}, "No Respawn" },
{{RecordType::STAT, 31}, "Multibound" },
{{RecordType::TREE, 9}, "Hidden From Local Map" },
{{RecordType::TREE, 10}, "Persistent" },
{{RecordType::TREE, 11}, "Initially Disabled" },
{{RecordType::TREE, 13}, "Sky Marker" },
{{RecordType::TREE, 15}, "Visible when distant" },
{{RecordType::TREE, 16}, "Is Full LOD" },
{{RecordType::TREE, 26}, "Filter (Collision Geometry)" },
{{RecordType::TREE, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::TREE, 28}, "Reflected By Auto Water" },
{{RecordType::TREE, 29}, "Don''t Havok Settle" },
{{RecordType::TREE, 30}, "No Respawn" },
{{RecordType::TREE, 31}, "Multibound" },
{{RecordType::WEAP, 10}, "Persistent" },
{{RecordType::WEAP, 11}, "Initially Disabled" },
{{RecordType::WEAP, 16}, "Is Full LOD" },
{{RecordType::WEAP, 25}, "No AI Acquire" },
{{RecordType::WEAP, 28}, "Reflected By Auto Water" },
{{RecordType::WEAP, 29}, "Don''t Havok Settle" },
{{RecordType::WEAP, 30}, "No Respawn" },
{{RecordType::WEAP, 31}, "Multibound" },
};
static constexpr auto refr_flag_description_map_std = utility::array_builtin_to_std(refr_flag_description_map_builtin);
static constexpr auto refr_flag_description_map = utility::map_to_soa(refr_flag_description_map_std);
[[nodiscard]] constexpr std::optional<std::string_view> refr_flag_to_description(RefrFlag refr_flag) noexcept
{
return utility::soa_first_to_second(refr_flag_description_map, refr_flag);
}
}

View File

@@ -1,23 +1,67 @@
#pragma once
#include <array>
#include <optional>
#include <bit>
namespace utility {
// Converts a string literal to a std::array<char>, from https://stackoverflow.com/a/33484394
template <std::size_t N, std::size_t ... Is>
constexpr std::array<char, N - 1>
literal_to_array(const char(&a)[N], std::index_sequence<Is...>)
// This is a base class for a generic store for some value that can be represented by
// type T but should not be type checked as type T, but rather some more constrained class.
template <class T>
struct Store {
static_assert(std::is_trivial_v<T>);
T value;
friend constexpr auto operator<=>(const Store &, const Store &) noexcept = default;
};
// Convert a fourcc literal (e.g. "LITR" to a uint32_t)
constexpr uint32_t fourcc_lit_to_val(const char(&a)[5]) noexcept
{
return { {a[Is]...} };
char temp[4] = { a[0], a[1], a[2], a[3] };
return std::bit_cast<uint32_t, char[4]>(temp);
}
template <std::size_t N>
constexpr std::array<char, N - 1> literal_to_array(const char(&a)[N])
// Convert a builtin array to a std::array
template <typename T, std::size_t N>
constexpr std::array<T, N> array_builtin_to_std(const T(&builtin)[N]) noexcept
{
return literal_to_array(a, std::make_index_sequence<N - 1>());
std::array<T, N> array;
std::copy(std::cbegin(builtin), std::cend(builtin), array.begin());
return array;
}
template <typename First, typename Second, std::size_t N>
constexpr std::pair<std::array<First, N>, std::array<Second, N>> map_to_soa(std::array<std::pair<First, Second>, N> map) noexcept
{
std::array<First, N> first;
std::array<Second, N> second;
for (std::size_t i = 0; i != N; ++i) {
first[i] = map[i].first;
second[i] = map[i].second;
}
return std::make_pair(first, second);
}
template <typename First, typename Second, std::size_t N>
constexpr std::optional<Second> soa_first_to_second(const std::pair<std::array<First, N>, std::array<Second, N>> &soa, const First &first) noexcept
{
auto lhs = std::find(soa.first.cbegin(), soa.first.cend(), first);
if (lhs == soa.first.cend())
return {};
auto index = std::distance(soa.first.cbegin(), lhs);
return { soa.second[index] };
}
template <typename First, typename Second, std::size_t N>
constexpr std::optional<First> soa_second_to_first(const std::pair<std::array<First, N>, std::array<Second, N>> &soa, const Second &second) noexcept
{
auto lhs = std::find(soa.second.cbegin(), soa.second.cend(), second);
if (lhs == soa.second.cend())
return {};
auto index = std::distance(soa.second.cbegin(), lhs);
return { soa.first[index] };
}
// Used to inspect type sizes and values at compile time. Example:
//
@@ -32,15 +76,5 @@ class TS;
template<typename T>
class TD;
// This is a base class for a generic store for some value that can be represented by
// type T but should not be type checked as type T, but rather some more constrained class.
template <class T>
struct Store {
static_assert(std::is_trivial_v<T>);
T value;
friend constexpr auto operator<=>(const Store &, const Store &) noexcept = default;
};
}

View File

@@ -0,0 +1,19 @@
enum class RecordType {
AACT, ACHR, ACTI, ADDN, ALCH, AMMO, ANIO, APPA, ARMA, ARMO, ARTO, ASPC,
ASTP, AVIF, BOOK, BPTD, CAMS, CELL, CLAS, CLDC, CLFM, CLMT, COBJ, COLL,
CONT, CPTH, CSTY, DEBR, DIAL, DLBR, DLVW, DOBJ, DOOR, DUAL, ECZN, EFSH,
ENCH, EQUP, EXPL, EYES, FACT, FLOR, FLST, FSTP, FSTS, FURN, GLOB, GMST,
GRAS, GRUP, HAIR, HAZD, HDPT, IDLE, IDLM, IMAD, IMGS, INFO, INGR, IPCT,
IPDS, KEYM, KYWD, LAND, LCRT, LCTN, LENS, LGTM, LIGH, LSCR, LTEX, LVLI,
LVLN, LVSP, MATO, MATT, MESG, MGEF, MISC, MOVT, MSTT, MUSC, MUST, NAVI,
NAVM, NOTE, NPC_, OTFT, PACK, PARW, PBAR, PBEA, PCON, PERK, PFLA, PGRE,
PHZD, PLYR, PMIS, PROJ, PWAT, QUST, RACE, REFR, REGN, RELA, REVB, RFCT,
RGDL, SCEN, SCOL, SCPT, SCRL, SHOU, SLGM, SMBN, SMEN, SMQN, SNCT, SNDR,
SOPM, SOUN, SPEL, SPGD, STAT, TACT, TES4, TREE, TXST, VOLI, VTYP, WATR,
WEAP, WOOP, WRLD, WTHR, };
[[nodiscard]] constexpr std::optional<std::string_view> group_type_to_name(GroupType group_type) noexcept;
[[nodiscard]] constexpr std::optional<FourCC> record_type_to_fourcc(RecordType record_type) noexcept;
[[nodiscard]] constexpr std::optional<RecordType> fourcc_to_record_type(FourCC fourcc) noexcept;
[[nodiscard]] constexpr std::optional<std::string_view> record_type_to_name(RecordType record_type) noexcept;
[[nodiscard]] constexpr std::optional<std::string_view> flag_to_description(Flag flag) noexcept;
[[nodiscard]] constexpr std::optional<std::string_view> refr_flag_to_description(RefrFlag refr_flag) noexcept;

View File

@@ -0,0 +1,614 @@
#include "esx_reader.hpp"
using namespace esxr;
namespace esxr_lut {
static constexpr std::pair<GroupType, std::string_view> group_type_name_map_builtin[] {
{GroupType::Top , "Top Type" },
{GroupType::WorldChildren , "World Children" },
{GroupType::InteriorCellBlock , "Interior Cell Block" },
{GroupType::InteriorCellSubBlock , "Interior Cell Sub-Block" },
{GroupType::ExteriorCellBlock , "Exterior Cell" },
{GroupType::ExteriorCellSubBlock , "Exterior Cell Sub-Block" },
{GroupType::CellChildren , "Cell Children" },
{GroupType::TopicChildren , "Topic Children" },
{GroupType::CellPersistentChildren, "Cell Persistent Children"},
{GroupType::CellTemporaryChildren , "Cell Temporary Children" },
};
static constexpr auto group_type_name_map_std = utility::array_builtin_to_std(group_type_name_map_builtin);
static constexpr auto group_type_name_map = utility::map_to_soa(group_type_name_map_std);
[[nodiscard]] constexpr std::optional<std::string_view> group_type_to_name(GroupType group_type) noexcept
{
return utility::soa_first_to_second(group_type_name_map, group_type);
}
static constexpr std::pair<RecordType, FourCC> record_type_fourcc_map_builtin[] {
{RecordType::AACT, FourCC("AACT")}, {RecordType::ACHR, FourCC("ACHR")},
{RecordType::ACTI, FourCC("ACTI")}, {RecordType::ADDN, FourCC("ADDN")},
{RecordType::ALCH, FourCC("ALCH")}, {RecordType::AMMO, FourCC("AMMO")},
{RecordType::ANIO, FourCC("ANIO")}, {RecordType::APPA, FourCC("APPA")},
{RecordType::ARMA, FourCC("ARMA")}, {RecordType::ARMO, FourCC("ARMO")},
{RecordType::ARTO, FourCC("ARTO")}, {RecordType::ASPC, FourCC("ASPC")},
{RecordType::ASTP, FourCC("ASTP")}, {RecordType::AVIF, FourCC("AVIF")},
{RecordType::BOOK, FourCC("BOOK")}, {RecordType::BPTD, FourCC("BPTD")},
{RecordType::CAMS, FourCC("CAMS")}, {RecordType::CELL, FourCC("CELL")},
{RecordType::CLAS, FourCC("CLAS")}, {RecordType::CLDC, FourCC("CLDC")},
{RecordType::CLFM, FourCC("CLFM")}, {RecordType::CLMT, FourCC("CLMT")},
{RecordType::COBJ, FourCC("COBJ")}, {RecordType::COLL, FourCC("COLL")},
{RecordType::CONT, FourCC("CONT")}, {RecordType::CPTH, FourCC("CPTH")},
{RecordType::CSTY, FourCC("CSTY")}, {RecordType::DEBR, FourCC("DEBR")},
{RecordType::DIAL, FourCC("DIAL")}, {RecordType::DLBR, FourCC("DLBR")},
{RecordType::DLVW, FourCC("DLVW")}, {RecordType::DOBJ, FourCC("DOBJ")},
{RecordType::DOOR, FourCC("DOOR")}, {RecordType::DUAL, FourCC("DUAL")},
{RecordType::ECZN, FourCC("ECZN")}, {RecordType::EFSH, FourCC("EFSH")},
{RecordType::ENCH, FourCC("ENCH")}, {RecordType::EQUP, FourCC("EQUP")},
{RecordType::EXPL, FourCC("EXPL")}, {RecordType::EYES, FourCC("EYES")},
{RecordType::FACT, FourCC("FACT")}, {RecordType::FLOR, FourCC("FLOR")},
{RecordType::FLST, FourCC("FLST")}, {RecordType::FSTP, FourCC("FSTP")},
{RecordType::FSTS, FourCC("FSTS")}, {RecordType::FURN, FourCC("FURN")},
{RecordType::GLOB, FourCC("GLOB")}, {RecordType::GMST, FourCC("GMST")},
{RecordType::GRAS, FourCC("GRAS")}, {RecordType::GRUP, FourCC("GRUP")},
{RecordType::HAIR, FourCC("HAIR")}, {RecordType::HAZD, FourCC("HAZD")},
{RecordType::HDPT, FourCC("HDPT")}, {RecordType::IDLE, FourCC("IDLE")},
{RecordType::IDLM, FourCC("IDLM")}, {RecordType::IMAD, FourCC("IMAD")},
{RecordType::IMGS, FourCC("IMGS")}, {RecordType::INFO, FourCC("INFO")},
{RecordType::INGR, FourCC("INGR")}, {RecordType::IPCT, FourCC("IPCT")},
{RecordType::IPDS, FourCC("IPDS")}, {RecordType::KEYM, FourCC("KEYM")},
{RecordType::KYWD, FourCC("KYWD")}, {RecordType::LAND, FourCC("LAND")},
{RecordType::LCRT, FourCC("LCRT")}, {RecordType::LCTN, FourCC("LCTN")},
{RecordType::LENS, FourCC("LENS")}, {RecordType::LGTM, FourCC("LGTM")},
{RecordType::LIGH, FourCC("LIGH")}, {RecordType::LSCR, FourCC("LSCR")},
{RecordType::LTEX, FourCC("LTEX")}, {RecordType::LVLI, FourCC("LVLI")},
{RecordType::LVLN, FourCC("LVLN")}, {RecordType::LVSP, FourCC("LVSP")},
{RecordType::MATO, FourCC("MATO")}, {RecordType::MATT, FourCC("MATT")},
{RecordType::MESG, FourCC("MESG")}, {RecordType::MGEF, FourCC("MGEF")},
{RecordType::MISC, FourCC("MISC")}, {RecordType::MOVT, FourCC("MOVT")},
{RecordType::MSTT, FourCC("MSTT")}, {RecordType::MUSC, FourCC("MUSC")},
{RecordType::MUST, FourCC("MUST")}, {RecordType::NAVI, FourCC("NAVI")},
{RecordType::NAVM, FourCC("NAVM")}, {RecordType::NOTE, FourCC("NOTE")},
{RecordType::NPC_, FourCC("NPC_")}, {RecordType::OTFT, FourCC("OTFT")},
{RecordType::PACK, FourCC("PACK")}, {RecordType::PARW, FourCC("PARW")},
{RecordType::PBAR, FourCC("PBAR")}, {RecordType::PBEA, FourCC("PBEA")},
{RecordType::PCON, FourCC("PCON")}, {RecordType::PERK, FourCC("PERK")},
{RecordType::PFLA, FourCC("PFLA")}, {RecordType::PGRE, FourCC("PGRE")},
{RecordType::PHZD, FourCC("PHZD")}, {RecordType::PLYR, FourCC("PLYR")},
{RecordType::PMIS, FourCC("PMIS")}, {RecordType::PROJ, FourCC("PROJ")},
{RecordType::PWAT, FourCC("PWAT")}, {RecordType::QUST, FourCC("QUST")},
{RecordType::RACE, FourCC("RACE")}, {RecordType::REFR, FourCC("REFR")},
{RecordType::REGN, FourCC("REGN")}, {RecordType::RELA, FourCC("RELA")},
{RecordType::REVB, FourCC("REVB")}, {RecordType::RFCT, FourCC("RFCT")},
{RecordType::RGDL, FourCC("RGDL")}, {RecordType::SCEN, FourCC("SCEN")},
{RecordType::SCOL, FourCC("SCOL")}, {RecordType::SCPT, FourCC("SCPT")},
{RecordType::SCRL, FourCC("SCRL")}, {RecordType::SHOU, FourCC("SHOU")},
{RecordType::SLGM, FourCC("SLGM")}, {RecordType::SMBN, FourCC("SMBN")},
{RecordType::SMEN, FourCC("SMEN")}, {RecordType::SMQN, FourCC("SMQN")},
{RecordType::SNCT, FourCC("SNCT")}, {RecordType::SNDR, FourCC("SNDR")},
{RecordType::SOPM, FourCC("SOPM")}, {RecordType::SOUN, FourCC("SOUN")},
{RecordType::SPEL, FourCC("SPEL")}, {RecordType::SPGD, FourCC("SPGD")},
{RecordType::STAT, FourCC("STAT")}, {RecordType::TACT, FourCC("TACT")},
{RecordType::TES4, FourCC("TES4")}, {RecordType::TREE, FourCC("TREE")},
{RecordType::TXST, FourCC("TXST")}, {RecordType::VOLI, FourCC("VOLI")},
{RecordType::VTYP, FourCC("VTYP")}, {RecordType::WATR, FourCC("WATR")},
{RecordType::WEAP, FourCC("WEAP")}, {RecordType::WOOP, FourCC("WOOP")},
{RecordType::WRLD, FourCC("WRLD")}, {RecordType::WTHR, FourCC("WTHR")},
};
static constexpr auto record_type_fourcc_map_std = utility::array_builtin_to_std(record_type_fourcc_map_builtin);
static constexpr auto record_type_fourcc_map = utility::map_to_soa(record_type_fourcc_map_std);
[[nodiscard]] constexpr std::optional<FourCC> record_type_to_fourcc(RecordType record_type) noexcept
{
return utility::soa_first_to_second(record_type_fourcc_map, record_type);
}
[[nodiscard]] constexpr std::optional<RecordType> fourcc_to_record_type(FourCC fourcc) noexcept
{
return utility::soa_second_to_first(record_type_fourcc_map, fourcc);
}
static constexpr std::pair<RecordType, std::string_view> record_type_name_map_builtin[] {
{RecordType::AACT, "Action" },
{RecordType::ACHR, "Placed NPC" },
{RecordType::ACTI, "Activator" },
{RecordType::ADDN, "Addon Node" },
{RecordType::ALCH, "Ingestible" },
{RecordType::AMMO, "Ammunition" },
{RecordType::ANIO, "Animated Object" },
{RecordType::APPA, "Alchemical Apparatus" },
{RecordType::ARMA, "Armor Addon" },
{RecordType::ARMO, "Armor" },
{RecordType::ARTO, "Art Object" },
{RecordType::ASPC, "Acoustic Space" },
{RecordType::ASTP, "Association Type" },
{RecordType::AVIF, "Actor Value Information" },
{RecordType::BOOK, "Book" },
{RecordType::BPTD, "Body Part Data" },
{RecordType::CAMS, "Camera Shot" },
{RecordType::CELL, "Cell" },
{RecordType::CLAS, "Class" },
{RecordType::CLDC, "CLDC" },
{RecordType::CLFM, "Color" },
{RecordType::CLMT, "Climate" },
{RecordType::COBJ, "Constructible Object" },
{RecordType::COLL, "Collision Layer" },
{RecordType::CONT, "Container" },
{RecordType::CPTH, "Camera Path" },
{RecordType::CSTY, "Combat Style" },
{RecordType::DEBR, "Debris" },
{RecordType::DIAL, "Dialog Topic" },
{RecordType::DLBR, "Dialog Branch" },
{RecordType::DLVW, "Dialog View" },
{RecordType::DOBJ, "Default Object Manager" },
{RecordType::DOOR, "Door" },
{RecordType::DUAL, "Dual Cast Data" },
{RecordType::ECZN, "Encounter Zone" },
{RecordType::EFSH, "Effect Shader" },
{RecordType::ENCH, "Object Effect" },
{RecordType::EQUP, "Equip Type" },
{RecordType::EXPL, "Explosion" },
{RecordType::EYES, "Eyes" },
{RecordType::FACT, "Faction" },
{RecordType::FLOR, "Flora" },
{RecordType::FLST, "FormID List" },
{RecordType::FSTP, "Footstep" },
{RecordType::FSTS, "Footstep Set" },
{RecordType::FURN, "Furniture" },
{RecordType::GLOB, "Global" },
{RecordType::GMST, "Game Setting" },
{RecordType::GRAS, "Grass" },
{RecordType::GRUP, "Group" },
{RecordType::HAIR, "HAIR" },
{RecordType::HAZD, "Hazard" },
{RecordType::HDPT, "Head Part" },
{RecordType::IDLE, "Idle Animation" },
{RecordType::IDLM, "Idle Marker" },
{RecordType::IMAD, "Image Space Adapter" },
{RecordType::IMGS, "Image Space" },
{RecordType::INFO, "Dialog response" },
{RecordType::INGR, "Ingredient" },
{RecordType::IPCT, "Impact" },
{RecordType::IPDS, "Impact Data Set" },
{RecordType::KEYM, "Key" },
{RecordType::KYWD, "Keyword" },
{RecordType::LAND, "Landscape" },
{RecordType::LCRT, "Location Reference Type" },
{RecordType::LCTN, "Location" },
{RecordType::LENS, "Lens Flare" },
{RecordType::LGTM, "Lighting Template" },
{RecordType::LIGH, "Light" },
{RecordType::LSCR, "Load Screen" },
{RecordType::LTEX, "Landscape Texture" },
{RecordType::LVLI, "Leveled Item" },
{RecordType::LVLN, "Leveled NPC" },
{RecordType::LVSP, "Leveled Spell" },
{RecordType::MATO, "Material Object" },
{RecordType::MATT, "Material Type" },
{RecordType::MESG, "Message" },
{RecordType::MGEF, "Magic Effect" },
{RecordType::MISC, "Misc. Item" },
{RecordType::MOVT, "Movement Type" },
{RecordType::MSTT, "Moveable Static" },
{RecordType::MUSC, "Music Type" },
{RecordType::MUST, "Music Track" },
{RecordType::NAVI, "Navigation Mesh Info Map" },
{RecordType::NAVM, "Navigation Mesh" },
{RecordType::NOTE, "Note" },
{RecordType::NPC_, "Non-Player Character (Actor)"},
{RecordType::OTFT, "Outfit" },
{RecordType::PACK, "Package" },
{RecordType::PARW, "Placed Arrow" },
{RecordType::PBAR, "Placed Barrier" },
{RecordType::PBEA, "Placed Beam" },
{RecordType::PCON, "Placed Cone/Voice" },
{RecordType::PERK, "Perk" },
{RecordType::PFLA, "Placed Flame" },
{RecordType::PGRE, "Placed Projectile" },
{RecordType::PHZD, "Placed Hazard" },
{RecordType::PLYR, "Player Reference" },
{RecordType::PMIS, "Placed Missile" },
{RecordType::PROJ, "Projectile" },
{RecordType::PWAT, "PWAT" },
{RecordType::QUST, "Quest" },
{RecordType::RACE, "Race" },
{RecordType::REFR, "Placed Object" },
{RecordType::REGN, "Region" },
{RecordType::RELA, "Relationship" },
{RecordType::REVB, "Reverb Parameters" },
{RecordType::RFCT, "Visual Effect" },
{RecordType::RGDL, "RGDL" },
{RecordType::SCEN, "Scene" },
{RecordType::SCOL, "Static Collection" },
{RecordType::SCPT, "SCPT" },
{RecordType::SCRL, "Scroll" },
{RecordType::SHOU, "Shout" },
{RecordType::SLGM, "Soul Gem" },
{RecordType::SMBN, "Story Manager Branch Node" },
{RecordType::SMEN, "Story Manager Event Node" },
{RecordType::SMQN, "Story Manager Quest Node" },
{RecordType::SNCT, "Sound Category" },
{RecordType::SNDR, "Sound Descriptor" },
{RecordType::SOPM, "Sound Output Model" },
{RecordType::SOUN, "Sound Marker" },
{RecordType::SPEL, "Spell" },
{RecordType::SPGD, "Shader Particle Geometry" },
{RecordType::STAT, "Static" },
{RecordType::TACT, "Talking Activator" },
{RecordType::TES4, "Main File Header" },
{RecordType::TREE, "Tree" },
{RecordType::TXST, "Texture Set" },
{RecordType::VOLI, "Volumetric Lighting" },
{RecordType::VTYP, "Voice Type" },
{RecordType::WATR, "Water" },
{RecordType::WEAP, "Weapon" },
{RecordType::WOOP, "Word of Power" },
{RecordType::WRLD, "Worldspace" },
{RecordType::WTHR, "Weather" },
};
static constexpr auto record_type_name_map_std = utility::array_builtin_to_std(record_type_name_map_builtin);
static constexpr auto record_type_name_map = utility::map_to_soa(record_type_name_map_std);
[[nodiscard]] constexpr std::optional<std::string_view> record_type_to_name(RecordType record_type) noexcept
{
return utility::soa_first_to_second(record_type_name_map, record_type);
}
static constexpr std::pair<Flag, std::string_view> flag_description_map_builtin[] {
{{RecordType::ACHR, 9}, "Starts Dead" },
{{RecordType::ACHR, 10}, "Persistent" },
{{RecordType::ACHR, 11}, "Initially Disabled" },
{{RecordType::ACHR, 25}, "No AI Acquire" },
{{RecordType::ACHR, 29}, "Don't Havok Settle" },
{{RecordType::ACTI, 6}, "Has Tree LOD" },
{{RecordType::ACTI, 8}, "Must Update Anims" },
{{RecordType::ACTI, 9}, "Hidden From Local Map" },
{{RecordType::ACTI, 15}, "Has Distant LOD" },
{{RecordType::ACTI, 16}, "Random Anim Start" },
{{RecordType::ACTI, 17}, "Dangerous" },
{{RecordType::ACTI, 20}, "Ignore Object Interaction" },
{{RecordType::ACTI, 23}, "Is Marker" },
{{RecordType::ACTI, 25}, "Obstacle" },
{{RecordType::ACTI, 26}, "NavMesh Generation - Filter" },
{{RecordType::ACTI, 27}, "NavMesh Generation - Bounding Box"},
{{RecordType::ACTI, 29}, "Child Can Use" },
{{RecordType::ACTI, 30}, "NavMesh Generation - Ground" },
{{RecordType::ALCH, 29}, "Medicine" },
{{RecordType::AMMO, 2}, "Non-Playable" },
{{RecordType::ANIO, 9}, "Unknown 9" },
{{RecordType::ARMO, 2}, "Non-Playable" },
{{RecordType::ARMO, 6}, "Shield" },
{{RecordType::ARMO, 10}, "Unknown 10" },
{{RecordType::ARMO, 15}, "Unknown 15" },
{{RecordType::CELL, 10}, "Persistent" },
{{RecordType::CELL, 17}, "Off Limits" },
{{RecordType::CELL, 18}, "Compressed" },
{{RecordType::CELL, 19}, "Can't Wait" },
{{RecordType::CLFM, 2}, "Non-Playable" },
{{RecordType::CONT, 15}, "Has Distant LOD" },
{{RecordType::CONT, 16}, "Random Anim Start" },
{{RecordType::CONT, 25}, "Obstacle" },
{{RecordType::CONT, 26}, "NavMesh Generation - Filter" },
{{RecordType::CONT, 27}, "NavMesh Generation - Bounding Box"},
{{RecordType::CONT, 30}, "NavMesh Generation - Ground" },
{{RecordType::CSTY, 19}, "Allow Dual Wielding" },
{{RecordType::DOOR, 15}, "Has Distant LOD" },
{{RecordType::DOOR, 16}, "Random Anim Start" },
{{RecordType::DOOR, 23}, "Is Marker" },
{{RecordType::EYES, 2}, "Non-Playable" },
{{RecordType::FURN, 7}, "Is Perch" },
{{RecordType::FURN, 15}, "Has Distant LOD" },
{{RecordType::FURN, 16}, "Random Anim Start" },
{{RecordType::FURN, 23}, "Is Marker" },
{{RecordType::FURN, 28}, "Must Exit To Talk" },
{{RecordType::FURN, 29}, "Child Can Use" },
{{RecordType::GLOB, 6}, "Constant" },
{{RecordType::HDPT, 2}, "Non-Playable" },
{{RecordType::IDLM, 29}, "Child Can Use" },
{{RecordType::INFO, 13}, "Actor Changed" },
{{RecordType::KEYM, 2}, "Non-Playable" },
{{RecordType::LAND, 18}, "Compressed" },
{{RecordType::LIGH, 16}, "Random Anim Start" },
{{RecordType::LIGH, 17}, "Portal-strict" },
{{RecordType::LIGH, 25}, "Obstacle" },
{{RecordType::LSCR, 10}, "Displays In Main Menu" },
{{RecordType::MISC, 2}, "Non-Playable" },
{{RecordType::MSTT, 8}, "Must Update Anims" },
{{RecordType::MSTT, 9}, "Hidden From Local Map" },
{{RecordType::MSTT, 15}, "Has Distant LOD" },
{{RecordType::MSTT, 16}, "Random Anim Start" },
{{RecordType::MSTT, 19}, "Has Currents" },
{{RecordType::MSTT, 25}, "Obstacle" },
{{RecordType::MSTT, 26}, "NavMesh Generation - Filter" },
{{RecordType::MSTT, 27}, "NavMesh Generation - Bounding Box"},
{{RecordType::MSTT, 30}, "NavMesh Generation - Ground" },
{{RecordType::NAVM, 18}, "Compressed" },
{{RecordType::NAVM, 26}, "AutoGen" },
{{RecordType::NAVM, 31}, "NavmeshGenCell" },
{{RecordType::NPC_, 10}, "Unknown 10" },
{{RecordType::NPC_, 18}, "Compressed" },
{{RecordType::NPC_, 19}, "Unknown 19" },
{{RecordType::NPC_, 29}, "Bleedout Override" },
{{RecordType::PARW, 7}, "Turn Off Fire" },
{{RecordType::PARW, 10}, "Persistent" },
{{RecordType::PARW, 11}, "Initially Disabled" },
{{RecordType::PARW, 28}, "Reflected By Auto Water" },
{{RecordType::PARW, 29}, "Don't Havok Settle" },
{{RecordType::PARW, 30}, "No Respawn" },
{{RecordType::PBAR, 7}, "Turn Off Fire" },
{{RecordType::PBAR, 10}, "Persistent" },
{{RecordType::PBAR, 11}, "Initially Disabled" },
{{RecordType::PBAR, 28}, "Reflected By Auto Water" },
{{RecordType::PBAR, 29}, "Don't Havok Settle" },
{{RecordType::PBAR, 30}, "No Respawn" },
{{RecordType::PBEA, 7}, "Turn Off Fire" },
{{RecordType::PBEA, 10}, "Persistent" },
{{RecordType::PBEA, 11}, "Initially Disabled" },
{{RecordType::PBEA, 28}, "Reflected By Auto Water" },
{{RecordType::PBEA, 29}, "Don't Havok Settle" },
{{RecordType::PBEA, 30}, "No Respawn" },
{{RecordType::PCON, 7}, "Turn Off Fire" },
{{RecordType::PCON, 10}, "Persistent" },
{{RecordType::PCON, 11}, "Initially Disabled" },
{{RecordType::PCON, 28}, "Reflected By Auto Water" },
{{RecordType::PCON, 29}, "Don't Havok Settle" },
{{RecordType::PCON, 30}, "No Respawn" },
{{RecordType::PERK, 2}, "Non-Playable" },
{{RecordType::PFLA, 7}, "Turn Off Fire" },
{{RecordType::PFLA, 10}, "Persistent" },
{{RecordType::PFLA, 11}, "Initially Disabled" },
{{RecordType::PFLA, 28}, "Reflected By Auto Water" },
{{RecordType::PFLA, 29}, "Don't Havok Settle" },
{{RecordType::PFLA, 30}, "No Respawn" },
{{RecordType::PGRE, 7}, "Turn Off Fire" },
{{RecordType::PGRE, 10}, "Persistent" },
{{RecordType::PGRE, 11}, "Initially Disabled" },
{{RecordType::PGRE, 28}, "Reflected By Auto Water" },
{{RecordType::PGRE, 29}, "Don't Havok Settle" },
{{RecordType::PGRE, 30}, "No Respawn" },
{{RecordType::PHZD, 7}, "Turn Off Fire" },
{{RecordType::PHZD, 10}, "Persistent" },
{{RecordType::PHZD, 11}, "Initially Disabled" },
{{RecordType::PHZD, 28}, "Reflected By Auto Water" },
{{RecordType::PHZD, 29}, "Don't Havok Settle" },
{{RecordType::PHZD, 30}, "No Respawn" },
{{RecordType::PMIS, 7}, "Turn Off Fire" },
{{RecordType::PMIS, 10}, "Persistent" },
{{RecordType::PMIS, 11}, "Initially Disabled" },
{{RecordType::PMIS, 28}, "Reflected By Auto Water" },
{{RecordType::PMIS, 29}, "Don't Havok Settle" },
{{RecordType::PMIS, 30}, "No Respawn" },
{{RecordType::RACE, 19}, "Critter?" },
{{RecordType::REFR, 10}, "Persistent" },
{{RecordType::REFR, 11}, "Initially Disabled" },
{{RecordType::REFR, 16}, "Is Full LOD" },
{{RecordType::REFR, 26}, "Filter (Collision Geometry)" },
{{RecordType::REFR, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::REFR, 28}, "Reflected By Auto Water" },
{{RecordType::REFR, 30}, "Ground" },
{{RecordType::REFR, 31}, "Multibound" },
{{RecordType::REGN, 6}, "Border Region" },
{{RecordType::RELA, 6}, "Secret" },
{{RecordType::SHOU, 7}, "Treat spells as powers" },
{{RecordType::SLGM, 17}, "Can Hold NPC Soul" },
{{RecordType::STAT, 2}, "Never Fades" },
{{RecordType::STAT, 5}, "Deleted" },
{{RecordType::STAT, 6}, "Has Tree LOD" },
{{RecordType::STAT, 7}, "Add-On LOD Object" },
{{RecordType::STAT, 9}, "Hidden From Local Map" },
{{RecordType::STAT, 11}, "Unknown 11" },
{{RecordType::STAT, 15}, "Has Distant LOD" },
{{RecordType::STAT, 16}, "Unknown 16" },
{{RecordType::STAT, 17}, "Uses HD LOD Texture" },
{{RecordType::STAT, 19}, "Has Currents" },
{{RecordType::STAT, 23}, "Is Marker" },
{{RecordType::STAT, 25}, "Obstacle" },
{{RecordType::STAT, 26}, "NavMesh Generation - Filter" },
{{RecordType::STAT, 27}, "NavMesh Generation - Bounding Box"},
{{RecordType::STAT, 28}, "Show In World Map" },
{{RecordType::STAT, 30}, "NavMesh Generation - Ground" },
{{RecordType::TACT, 9}, "Hidden From Local Map" },
{{RecordType::TACT, 16}, "Random Anim Start" },
{{RecordType::TACT, 17}, "Radio Station" },
{{RecordType::TES4, 0}, "ESM" },
{{RecordType::TES4, 1}, "Altered" },
{{RecordType::TES4, 2}, "Checked" },
{{RecordType::TES4, 3}, "Active" },
{{RecordType::TES4, 4}, "Optimized File" },
{{RecordType::TES4, 5}, "Temp ID Owner" },
{{RecordType::TES4, 7}, "Localized" },
{{RecordType::TES4, 8}, "Precalc Data Only" },
{{RecordType::TES4, 9}, "ESL" },
{{RecordType::TREE, 15}, "Has Distant LOD" },
{{RecordType::WEAP, 2}, "Non-Playable" },
{{RecordType::WRLD, 19}, "Can't Wait" },
};
static constexpr auto flag_description_map_std = utility::array_builtin_to_std(flag_description_map_builtin);
static constexpr auto flag_description_map = utility::map_to_soa(flag_description_map_std);
[[nodiscard]] constexpr std::optional<std::string_view> flag_to_description(Flag flag) noexcept
{
return utility::soa_first_to_second(flag_description_map, flag);
}
static constexpr std::pair<RefrFlag, std::string_view> refr_flag_description_map_builtin[] {
{{RecordType::ACTI, 9}, "Hidden From Local Map" },
{{RecordType::ACTI, 10}, "Persistent" },
{{RecordType::ACTI, 11}, "Initially Disabled" },
{{RecordType::ACTI, 13}, "Sky Marker" },
{{RecordType::ACTI, 15}, "Visible when distant" },
{{RecordType::ACTI, 16}, "Is Full LOD" },
{{RecordType::ACTI, 26}, "Filter (Collision Geometry)" },
{{RecordType::ACTI, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::ACTI, 28}, "Reflected By Auto Water" },
{{RecordType::ACTI, 29}, "Don''t Havok Settle" },
{{RecordType::ACTI, 30}, "No Respawn" },
{{RecordType::ACTI, 31}, "Multibound" },
{{RecordType::ADDN, 10}, "Persistent" },
{{RecordType::ADDN, 11}, "Initially Disabled" },
{{RecordType::ADDN, 16}, "Is Full LOD" },
{{RecordType::ADDN, 28}, "Reflected By Auto Water" },
{{RecordType::ADDN, 29}, "Don''t Havok Settle" },
{{RecordType::ADDN, 30}, "No Respawn" },
{{RecordType::ADDN, 31}, "Multibound" },
{{RecordType::ALCH, 10}, "Persistent" },
{{RecordType::ALCH, 11}, "Initially Disabled" },
{{RecordType::ALCH, 16}, "Is Full LOD" },
{{RecordType::ALCH, 25}, "No AI Acquire" },
{{RecordType::ALCH, 28}, "Reflected By Auto Water" },
{{RecordType::ALCH, 29}, "Don''t Havok Settle" },
{{RecordType::ALCH, 30}, "No Respawn" },
{{RecordType::ALCH, 31}, "Multibound" },
{{RecordType::AMMO, 10}, "Persistent" },
{{RecordType::AMMO, 11}, "Initially Disabled" },
{{RecordType::AMMO, 16}, "Is Full LOD" },
{{RecordType::AMMO, 25}, "No AI Acquire" },
{{RecordType::AMMO, 28}, "Reflected By Auto Water" },
{{RecordType::AMMO, 29}, "Don''t Havok Settle" },
{{RecordType::AMMO, 30}, "No Respawn" },
{{RecordType::AMMO, 31}, "Multibound" },
{{RecordType::ARMO, 10}, "Persistent" },
{{RecordType::ARMO, 11}, "Initially Disabled" },
{{RecordType::ARMO, 16}, "Is Full LOD" },
{{RecordType::ARMO, 25}, "No AI Acquire" },
{{RecordType::ARMO, 28}, "Reflected By Auto Water" },
{{RecordType::ARMO, 29}, "Don''t Havok Settle" },
{{RecordType::ARMO, 30}, "No Respawn" },
{{RecordType::ARMO, 31}, "Multibound" },
{{RecordType::BOOK, 10}, "Persistent" },
{{RecordType::BOOK, 11}, "Initially Disabled" },
{{RecordType::BOOK, 16}, "Is Full LOD" },
{{RecordType::BOOK, 25}, "No AI Acquire" },
{{RecordType::BOOK, 28}, "Reflected By Auto Water" },
{{RecordType::BOOK, 29}, "Don''t Havok Settle" },
{{RecordType::BOOK, 30}, "No Respawn" },
{{RecordType::BOOK, 31}, "Multibound" },
{{RecordType::CONT, 10}, "Persistent" },
{{RecordType::CONT, 11}, "Initially Disabled" },
{{RecordType::CONT, 16}, "Is Full LOD" },
{{RecordType::CONT, 25}, "No AI Acquire" },
{{RecordType::CONT, 26}, "Filter (Collision Geometry)" },
{{RecordType::CONT, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::CONT, 28}, "Reflected By Auto Water" },
{{RecordType::CONT, 29}, "Don''t Havok Settle" },
{{RecordType::CONT, 30}, "Ground" },
{{RecordType::CONT, 31}, "Multibound" },
{{RecordType::DOOR, 6}, "Hidden From Local Map" },
{{RecordType::DOOR, 8}, "Inaccessible" },
{{RecordType::DOOR, 10}, "Persistent" },
{{RecordType::DOOR, 11}, "Initially Disabled" },
{{RecordType::DOOR, 16}, "Is Full LOD" },
{{RecordType::DOOR, 26}, "Filter (Collision Geometry)" },
{{RecordType::DOOR, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::DOOR, 28}, "Reflected By Auto Water" },
{{RecordType::DOOR, 29}, "Don''t Havok Settle" },
{{RecordType::DOOR, 30}, "No Respawn" },
{{RecordType::DOOR, 31}, "Multibound" },
{{RecordType::FLOR, 9}, "Hidden From Local Map" },
{{RecordType::FLOR, 10}, "Persistent" },
{{RecordType::FLOR, 11}, "Initially Disabled" },
{{RecordType::FLOR, 13}, "Sky Marker" },
{{RecordType::FLOR, 15}, "Visible when distant" },
{{RecordType::FLOR, 16}, "Is Full LOD" },
{{RecordType::FLOR, 26}, "Filter (Collision Geometry)" },
{{RecordType::FLOR, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::FLOR, 28}, "Reflected By Auto Water" },
{{RecordType::FLOR, 29}, "Don''t Havok Settle" },
{{RecordType::FLOR, 30}, "No Respawn" },
{{RecordType::FLOR, 31}, "Multibound" },
{{RecordType::INGR, 10}, "Persistent" },
{{RecordType::INGR, 11}, "Initially Disabled" },
{{RecordType::INGR, 16}, "Is Full LOD" },
{{RecordType::INGR, 25}, "No AI Acquire" },
{{RecordType::INGR, 28}, "Reflected By Auto Water" },
{{RecordType::INGR, 29}, "Don''t Havok Settle" },
{{RecordType::INGR, 30}, "No Respawn" },
{{RecordType::INGR, 31}, "Multibound" },
{{RecordType::KEYM, 10}, "Persistent" },
{{RecordType::KEYM, 11}, "Initially Disabled" },
{{RecordType::KEYM, 16}, "Is Full LOD" },
{{RecordType::KEYM, 25}, "No AI Acquire" },
{{RecordType::KEYM, 28}, "Reflected By Auto Water" },
{{RecordType::KEYM, 29}, "Don''t Havok Settle" },
{{RecordType::KEYM, 30}, "No Respawn" },
{{RecordType::KEYM, 31}, "Multibound" },
{{RecordType::LIGH, 8}, "Doesn''t Light Water" },
{{RecordType::LIGH, 9}, "Casts Shadows" },
{{RecordType::LIGH, 10}, "Persistent" },
{{RecordType::LIGH, 11}, "Initially Disabled" },
{{RecordType::LIGH, 16}, "Never Fades" },
{{RecordType::LIGH, 17}, "Doesn''t Light Landscape" },
{{RecordType::LIGH, 25}, "No AI Acquire" },
{{RecordType::LIGH, 28}, "Reflected By Auto Water" },
{{RecordType::LIGH, 29}, "Don''t Havok Settle" },
{{RecordType::LIGH, 30}, "No Respawn" },
{{RecordType::LIGH, 31}, "Multibound" },
{{RecordType::MISC, 10}, "Persistent" },
{{RecordType::MISC, 11}, "Initially Disabled" },
{{RecordType::MISC, 16}, "Is Full LOD" },
{{RecordType::MISC, 25}, "No AI Acquire" },
{{RecordType::MISC, 28}, "Reflected By Auto Water" },
{{RecordType::MISC, 29}, "Don''t Havok Settle" },
{{RecordType::MISC, 30}, "No Respawn" },
{{RecordType::MISC, 31}, "Multibound" },
{{RecordType::MSTT, 9}, "Motion Blur" },
{{RecordType::MSTT, 10}, "Persistent" },
{{RecordType::MSTT, 11}, "Initially Disabled" },
{{RecordType::MSTT, 16}, "Is Full LOD" },
{{RecordType::MSTT, 26}, "Filter (Collision Geometry)" },
{{RecordType::MSTT, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::MSTT, 28}, "Reflected By Auto Water" },
{{RecordType::MSTT, 29}, "Don''t Havok Settle" },
{{RecordType::MSTT, 30}, "No Respawn" },
{{RecordType::MSTT, 31}, "Multibound" },
{{RecordType::SCRL, 10}, "Persistent" },
{{RecordType::SCRL, 11}, "Initially Disabled" },
{{RecordType::SCRL, 16}, "Is Full LOD" },
{{RecordType::SCRL, 25}, "No AI Acquire" },
{{RecordType::SCRL, 28}, "Reflected By Auto Water" },
{{RecordType::SCRL, 29}, "Don''t Havok Settle" },
{{RecordType::SCRL, 30}, "No Respawn" },
{{RecordType::SCRL, 31}, "Multibound" },
{{RecordType::SLGM, 10}, "Persistent" },
{{RecordType::SLGM, 11}, "Initially Disabled" },
{{RecordType::SLGM, 16}, "Is Full LOD" },
{{RecordType::SLGM, 25}, "No AI Acquire" },
{{RecordType::SLGM, 28}, "Reflected By Auto Water" },
{{RecordType::SLGM, 29}, "Don''t Havok Settle" },
{{RecordType::SLGM, 30}, "No Respawn" },
{{RecordType::SLGM, 31}, "Multibound" },
{{RecordType::STAT, 9}, "Hidden From Local Map" },
{{RecordType::STAT, 10}, "Persistent" },
{{RecordType::STAT, 11}, "Initially Disabled" },
{{RecordType::STAT, 13}, "Sky Marker" },
{{RecordType::STAT, 15}, "Visible when distant" },
{{RecordType::STAT, 16}, "Is Full LOD" },
{{RecordType::STAT, 26}, "Filter (Collision Geometry)" },
{{RecordType::STAT, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::STAT, 28}, "Reflected By Auto Water" },
{{RecordType::STAT, 29}, "Don''t Havok Settle" },
{{RecordType::STAT, 30}, "No Respawn" },
{{RecordType::STAT, 31}, "Multibound" },
{{RecordType::TREE, 9}, "Hidden From Local Map" },
{{RecordType::TREE, 10}, "Persistent" },
{{RecordType::TREE, 11}, "Initially Disabled" },
{{RecordType::TREE, 13}, "Sky Marker" },
{{RecordType::TREE, 15}, "Visible when distant" },
{{RecordType::TREE, 16}, "Is Full LOD" },
{{RecordType::TREE, 26}, "Filter (Collision Geometry)" },
{{RecordType::TREE, 27}, "Bounding Box (Collision Geometry)"},
{{RecordType::TREE, 28}, "Reflected By Auto Water" },
{{RecordType::TREE, 29}, "Don''t Havok Settle" },
{{RecordType::TREE, 30}, "No Respawn" },
{{RecordType::TREE, 31}, "Multibound" },
{{RecordType::WEAP, 10}, "Persistent" },
{{RecordType::WEAP, 11}, "Initially Disabled" },
{{RecordType::WEAP, 16}, "Is Full LOD" },
{{RecordType::WEAP, 25}, "No AI Acquire" },
{{RecordType::WEAP, 28}, "Reflected By Auto Water" },
{{RecordType::WEAP, 29}, "Don''t Havok Settle" },
{{RecordType::WEAP, 30}, "No Respawn" },
{{RecordType::WEAP, 31}, "Multibound" },
};
static constexpr auto refr_flag_description_map_std = utility::array_builtin_to_std(refr_flag_description_map_builtin);
static constexpr auto refr_flag_description_map = utility::map_to_soa(refr_flag_description_map_std);
[[nodiscard]] constexpr std::optional<std::string_view> refr_flag_to_description(RefrFlag refr_flag) noexcept
{
return utility::soa_first_to_second(refr_flag_description_map, refr_flag);
}
}

42
reference/group_type.json Normal file
View File

@@ -0,0 +1,42 @@
[
{
"type": "Top",
"name": "Top Type"
},
{
"type": "WorldChildren",
"name": "World Children"
},
{
"type": "InteriorCellBlock",
"name": "Interior Cell Block"
},
{
"type": "InteriorCellSubBlock",
"name": "Interior Cell Sub-Block"
},
{
"type": "ExteriorCellBlock",
"name": "Exterior Cell"
},
{
"type": "ExteriorCellSubBlock",
"name": "Exterior Cell Sub-Block"
},
{
"type": "CellChildren",
"name": "Cell Children"
},
{
"type": "TopicChildren",
"name": "Topic Children"
},
{
"type": "CellPersistentChildren",
"name": "Cell Persistent Children"
},
{
"type": "CellTemporaryChildren",
"name": "Cell Temporary Children"
}
]

179
reference/record_codegen.py Normal file
View File

@@ -0,0 +1,179 @@
import json
import os
from dataclasses import dataclass
INDENT = 8
WIDTH = 80
LAST = "};"
SV = "std::string_view"
PREAMBLE = """#include "esx_reader.hpp"
using namespace esxr;
namespace esxr_lut {"""
POSTAMBLE = "}\n"
def transpose(seq):
return list(zip(*seq))
def clean(seq):
return [x for x in seq if x is not None]
def indented_block(items):
lines = []
line = ""
for item in items:
if len(line) + len(item) + 1 > WIDTH:
lines += [line[:-1]]
line = ""
if not line:
line = " " * INDENT
line += item + ", "
if line.strip():
lines += [line]
return "\n".join(lines)
def indented_list(items):
return ",\n".join([" " * INDENT + x for x in items])
def max_length(list):
return max(map(lambda x: len(x), list))
def wrap_bracket(list):
return ["{" + string + "}" for string in list]
def padded_join(lists):
maximums = [max_length(x) for x in lists]
padded = []
for max, l in zip(maximums, lists):
padded += [[x + " " * (max - len(x)) for x in l]]
padded_transposed = transpose(padded)
return ["".join(x) for x in padded_transposed]
@dataclass
class Map:
first_type: str
second_type: str
first_name: str
second_name: str
formats: list[str]
F_DECL = "static constexpr std::pair<{0}, {1}> {2}_builtin[] {{"
F_SOA = """static constexpr auto {0}_std = utility::array_builtin_to_std({0}_builtin);
static constexpr auto {0} = utility::map_to_soa({0}_std);"""
F_FUNC_DECL = "[[nodiscard]] constexpr std::optional<{0}> {1}_to_{2}({3} {1}) noexcept"
F_FUNC_BODY_FORWARD = " return utility::soa_first_to_second({0}, {1});"
F_FUNC_BODY_REVERSE = " return utility::soa_second_to_first({0}, {1});"
@property
def name(self):
return self.first_name + "_" + self.second_name + "_map"
@property
def decl(self):
return Map.F_DECL.format(self.first_type, self.second_type, self.name)
@property
def to_soa(self):
return Map.F_SOA.format(self.name)
@property
def forward_decl(self):
return Map.F_FUNC_DECL.format(self.second_type, self.first_name, self.second_name, self.first_type)
@property
def reverse_decl(self):
return Map.F_FUNC_DECL.format(self.first_type, self.second_name, self.first_name, self.second_type)
@property
def forward_func(self):
return self.forward_decl + "\n{\n" + Map.F_FUNC_BODY_FORWARD.format(self.name, self.first_name) + "\n}"
@property
def reverse_func(self):
return self.reverse_decl + "\n{\n" + Map.F_FUNC_BODY_REVERSE.format(self.name, self.second_name) + "\n}"
def data_to_list(self, data):
parts = []
for format in self.formats:
parts += [[format.format(*x) for x in data]]
return indented_block(wrap_bracket(padded_join(parts)))
def code(self, data, reverse = False):
parts = [self.decl, self.data_to_list(data), LAST, self.to_soa, self.forward_func]
decls = [self.forward_decl]
if reverse:
parts += [self.reverse_func]
decls += [self.reverse_decl]
return ["\n".join(parts), "\n".join([x + ';' for x in decls])]
def add_extra(data):
grup = {"fourcc": "GRUP", "name": "Group", "flags": []}
note = {"fourcc": "NOTE", "name": "Note", "flags": []}
data += [grup, note]
data.sort(key=lambda x: x["fourcc"])
def gen_enum(data):
# generate sorted list of signatures
sigs = [r["fourcc"] for r in data]
string = "enum class RecordType {\n" + indented_block(sigs) + LAST
return [None, string]
def gen_group_type(data):
map = Map("GroupType", SV, "group_type", "name", ["GroupType::{0}", ", \"{1}\""])
data = [(x['type'], x['name']) for x in data]
return map.code(data)
def gen_names(data):
map = Map("RecordType", SV, "record_type", "name", ["RecordType::{0}", ", \"{1}\""])
data = [(x['fourcc'], x['name']) for x in data]
return map.code(data)
def gen_fourcc(data):
map = Map("RecordType", "FourCC", "record_type", "fourcc", ["RecordType::{0}", ", FourCC(\"{0}\")"])
data = [(x['fourcc'], ) for x in data]
return map.code(data, reverse = True)
def gen_flags(data):
map = Map("Flag", SV, "flag", "description", ["{{RecordType::{0}, {1:>2}}}", ", \"{2}\""])
data = [(x['fourcc'], y['bit'], y['description']) for x in data for y in x['flags']]
return map.code(data)
def gen_refr_flags(data):
map = Map("RefrFlag", SV, "refr_flag", "description", ["{{RecordType::{0}, {1:>2}}}", ", \"{2}\""])
data = [(x['fourcc'], y['bit'], y['description']) for x in data for y in x['flags']]
return map.code(data)
def main():
fdir = os.path.dirname(__file__)
with open(os.path.join(fdir, "records.json"), "r") as f:
data = json.load(f)
with open(os.path.join(fdir, "refr_flags.json"), "r") as f:
refr_data = json.load(f)
with open(os.path.join(fdir, "group_type.json"), "r") as f:
gt_data = json.load(f)
add_extra(data)
code = []
code += [gen_enum(data)]
code += [gen_group_type(gt_data)]
code += [gen_fourcc(data)]
code += [gen_names(data)]
code += [gen_flags(data)]
code += [gen_refr_flags(refr_data)]
code = transpose(code)
lut = [PREAMBLE] + clean(code[0]) + [POSTAMBLE]
lut = "\n\n".join(lut)
header = clean(code[1])
header = "\n".join(header)
with open(os.path.join(fdir, "esx_reader_lut.cpp"), "w") as f:
f.write(lut)
with open(os.path.join(fdir, "esx_reader.hpp.fragment"), "w") as f:
f.write(header)
if __name__ == "__main__":
main()

View File

@@ -63,7 +63,7 @@ for string in all:
bit, desc = re_flag_line.match(line).groups()
# fix '' pascal escape and ESL special case
desc = desc.replace("''", "'").replace("', '", "")
flags += [Flag(bit, desc)]
flags += [Flag(int(bit), desc)]
# handle STAT special case
elif sig == "STAT":
flags_string = re.match(".*?\n.*?wbFlags\(.*?\n(?:.*?\n){32}.*?\]", string).group(0)
@@ -78,9 +78,6 @@ for string in all:
rdict = {r.fourcc: r for r in records}
records = list(rdict.values())
# add in the apparently supported NOTE
records += [Record("NOTE", "Note", [])]
# sort the records by signature
records = sorted(records, key=lambda x: x.fourcc)
@@ -92,6 +89,6 @@ class Encoder(json.JSONEncoder):
else:
return json.JSONEncoder.default(self, obj)
with open(os.path.join(fdir, "flags.json"), "w") as f:
with open(os.path.join(fdir, "records.json"), "w") as f:
json.dump(records, f, cls=Encoder, indent=4)

View File

@@ -9,23 +9,23 @@
"name": "Placed NPC",
"flags": [
{
"bit": "9",
"bit": 9,
"description": "Starts Dead"
},
{
"bit": "10",
"bit": 10,
"description": "Persistent"
},
{
"bit": "11",
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": "25",
"bit": 25,
"description": "No AI Acquire"
},
{
"bit": "29",
"bit": 29,
"description": "Don't Havok Settle"
}
]
@@ -35,55 +35,55 @@
"name": "Activator",
"flags": [
{
"bit": "6",
"bit": 6,
"description": "Has Tree LOD"
},
{
"bit": "8",
"bit": 8,
"description": "Must Update Anims"
},
{
"bit": "9",
"bit": 9,
"description": "Hidden From Local Map"
},
{
"bit": "15",
"bit": 15,
"description": "Has Distant LOD"
},
{
"bit": "16",
"bit": 16,
"description": "Random Anim Start"
},
{
"bit": "17",
"bit": 17,
"description": "Dangerous"
},
{
"bit": "20",
"bit": 20,
"description": "Ignore Object Interaction"
},
{
"bit": "23",
"bit": 23,
"description": "Is Marker"
},
{
"bit": "25",
"bit": 25,
"description": "Obstacle"
},
{
"bit": "26",
"bit": 26,
"description": "NavMesh Generation - Filter"
},
{
"bit": "27",
"bit": 27,
"description": "NavMesh Generation - Bounding Box"
},
{
"bit": "29",
"bit": 29,
"description": "Child Can Use"
},
{
"bit": "30",
"bit": 30,
"description": "NavMesh Generation - Ground"
}
]
@@ -98,7 +98,7 @@
"name": "Ingestible",
"flags": [
{
"bit": "29",
"bit": 29,
"description": "Medicine"
}
]
@@ -108,7 +108,7 @@
"name": "Ammunition",
"flags": [
{
"bit": "2",
"bit": 2,
"description": "Non-Playable"
}
]
@@ -118,7 +118,7 @@
"name": "Animated Object",
"flags": [
{
"bit": "9",
"bit": 9,
"description": "Unknown 9"
}
]
@@ -138,19 +138,19 @@
"name": "Armor",
"flags": [
{
"bit": "2",
"bit": 2,
"description": "Non-Playable"
},
{
"bit": "6",
"bit": 6,
"description": "Shield"
},
{
"bit": "10",
"bit": 10,
"description": "Unknown 10"
},
{
"bit": "15",
"bit": 15,
"description": "Unknown 15"
}
]
@@ -195,19 +195,19 @@
"name": "Cell",
"flags": [
{
"bit": "10",
"bit": 10,
"description": "Persistent"
},
{
"bit": "17",
"bit": 17,
"description": "Off Limits"
},
{
"bit": "18",
"bit": 18,
"description": "Compressed"
},
{
"bit": "19",
"bit": 19,
"description": "Can't Wait"
}
]
@@ -227,7 +227,7 @@
"name": "Color",
"flags": [
{
"bit": "2",
"bit": 2,
"description": "Non-Playable"
}
]
@@ -252,27 +252,27 @@
"name": "Container",
"flags": [
{
"bit": "15",
"bit": 15,
"description": "Has Distant LOD"
},
{
"bit": "16",
"bit": 16,
"description": "Random Anim Start"
},
{
"bit": "25",
"bit": 25,
"description": "Obstacle"
},
{
"bit": "26",
"bit": 26,
"description": "NavMesh Generation - Filter"
},
{
"bit": "27",
"bit": 27,
"description": "NavMesh Generation - Bounding Box"
},
{
"bit": "30",
"bit": 30,
"description": "NavMesh Generation - Ground"
}
]
@@ -287,7 +287,7 @@
"name": "Combat Style",
"flags": [
{
"bit": "19",
"bit": 19,
"description": "Allow Dual Wielding"
}
]
@@ -322,15 +322,15 @@
"name": "Door",
"flags": [
{
"bit": "15",
"bit": 15,
"description": "Has Distant LOD"
},
{
"bit": "16",
"bit": 16,
"description": "Random Anim Start"
},
{
"bit": "23",
"bit": 23,
"description": "Is Marker"
}
]
@@ -370,7 +370,7 @@
"name": "Eyes",
"flags": [
{
"bit": "2",
"bit": 2,
"description": "Non-Playable"
}
]
@@ -405,27 +405,27 @@
"name": "Furniture",
"flags": [
{
"bit": "7",
"bit": 7,
"description": "Is Perch"
},
{
"bit": "15",
"bit": 15,
"description": "Has Distant LOD"
},
{
"bit": "16",
"bit": 16,
"description": "Random Anim Start"
},
{
"bit": "23",
"bit": 23,
"description": "Is Marker"
},
{
"bit": "28",
"bit": 28,
"description": "Must Exit To Talk"
},
{
"bit": "29",
"bit": 29,
"description": "Child Can Use"
}
]
@@ -435,7 +435,7 @@
"name": "Global",
"flags": [
{
"bit": "6",
"bit": 6,
"description": "Constant"
}
]
@@ -465,7 +465,7 @@
"name": "Head Part",
"flags": [
{
"bit": "2",
"bit": 2,
"description": "Non-Playable"
}
]
@@ -480,7 +480,7 @@
"name": "Idle Marker",
"flags": [
{
"bit": "29",
"bit": 29,
"description": "Child Can Use"
}
]
@@ -500,7 +500,7 @@
"name": "Dialog response",
"flags": [
{
"bit": "13",
"bit": 13,
"description": "Actor Changed"
}
]
@@ -525,7 +525,7 @@
"name": "Key",
"flags": [
{
"bit": "2",
"bit": 2,
"description": "Non-Playable"
}
]
@@ -540,7 +540,7 @@
"name": "Landscape",
"flags": [
{
"bit": "18",
"bit": 18,
"description": "Compressed"
}
]
@@ -570,15 +570,15 @@
"name": "Light",
"flags": [
{
"bit": "16",
"bit": 16,
"description": "Random Anim Start"
},
{
"bit": "17",
"bit": 17,
"description": "Portal-strict"
},
{
"bit": "25",
"bit": 25,
"description": "Obstacle"
}
]
@@ -588,7 +588,7 @@
"name": "Load Screen",
"flags": [
{
"bit": "10",
"bit": 10,
"description": "Displays In Main Menu"
}
]
@@ -638,7 +638,7 @@
"name": "Misc. Item",
"flags": [
{
"bit": "2",
"bit": 2,
"description": "Non-Playable"
}
]
@@ -653,39 +653,39 @@
"name": "Moveable Static",
"flags": [
{
"bit": "8",
"bit": 8,
"description": "Must Update Anims"
},
{
"bit": "9",
"bit": 9,
"description": "Hidden From Local Map"
},
{
"bit": "15",
"bit": 15,
"description": "Has Distant LOD"
},
{
"bit": "16",
"bit": 16,
"description": "Random Anim Start"
},
{
"bit": "19",
"bit": 19,
"description": "Has Currents"
},
{
"bit": "25",
"bit": 25,
"description": "Obstacle"
},
{
"bit": "26",
"bit": 26,
"description": "NavMesh Generation - Filter"
},
{
"bit": "27",
"bit": 27,
"description": "NavMesh Generation - Bounding Box"
},
{
"bit": "30",
"bit": 30,
"description": "NavMesh Generation - Ground"
}
]
@@ -710,42 +710,37 @@
"name": "Navigation Mesh",
"flags": [
{
"bit": "18",
"bit": 18,
"description": "Compressed"
},
{
"bit": "26",
"bit": 26,
"description": "AutoGen"
},
{
"bit": "31",
"bit": 31,
"description": "NavmeshGenCell"
}
]
},
{
"fourcc": "NOTE",
"name": "Note",
"flags": []
},
{
"fourcc": "NPC_",
"name": "Non-Player Character (Actor)",
"flags": [
{
"bit": "10",
"bit": 10,
"description": "Unknown 10"
},
{
"bit": "18",
"bit": 18,
"description": "Compressed"
},
{
"bit": "19",
"bit": 19,
"description": "Unknown 19"
},
{
"bit": "29",
"bit": 29,
"description": "Bleedout Override"
}
]
@@ -765,27 +760,27 @@
"name": "Placed Arrow",
"flags": [
{
"bit": "7",
"bit": 7,
"description": "Turn Off Fire"
},
{
"bit": "10",
"bit": 10,
"description": "Persistent"
},
{
"bit": "11",
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": "28",
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": "29",
"bit": 29,
"description": "Don't Havok Settle"
},
{
"bit": "30",
"bit": 30,
"description": "No Respawn"
}
]
@@ -795,27 +790,27 @@
"name": "Placed Barrier",
"flags": [
{
"bit": "7",
"bit": 7,
"description": "Turn Off Fire"
},
{
"bit": "10",
"bit": 10,
"description": "Persistent"
},
{
"bit": "11",
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": "28",
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": "29",
"bit": 29,
"description": "Don't Havok Settle"
},
{
"bit": "30",
"bit": 30,
"description": "No Respawn"
}
]
@@ -825,27 +820,27 @@
"name": "Placed Beam",
"flags": [
{
"bit": "7",
"bit": 7,
"description": "Turn Off Fire"
},
{
"bit": "10",
"bit": 10,
"description": "Persistent"
},
{
"bit": "11",
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": "28",
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": "29",
"bit": 29,
"description": "Don't Havok Settle"
},
{
"bit": "30",
"bit": 30,
"description": "No Respawn"
}
]
@@ -855,27 +850,27 @@
"name": "Placed Cone/Voice",
"flags": [
{
"bit": "7",
"bit": 7,
"description": "Turn Off Fire"
},
{
"bit": "10",
"bit": 10,
"description": "Persistent"
},
{
"bit": "11",
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": "28",
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": "29",
"bit": 29,
"description": "Don't Havok Settle"
},
{
"bit": "30",
"bit": 30,
"description": "No Respawn"
}
]
@@ -885,7 +880,7 @@
"name": "Perk",
"flags": [
{
"bit": "2",
"bit": 2,
"description": "Non-Playable"
}
]
@@ -895,27 +890,27 @@
"name": "Placed Flame",
"flags": [
{
"bit": "7",
"bit": 7,
"description": "Turn Off Fire"
},
{
"bit": "10",
"bit": 10,
"description": "Persistent"
},
{
"bit": "11",
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": "28",
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": "29",
"bit": 29,
"description": "Don't Havok Settle"
},
{
"bit": "30",
"bit": 30,
"description": "No Respawn"
}
]
@@ -925,27 +920,27 @@
"name": "Placed Projectile",
"flags": [
{
"bit": "7",
"bit": 7,
"description": "Turn Off Fire"
},
{
"bit": "10",
"bit": 10,
"description": "Persistent"
},
{
"bit": "11",
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": "28",
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": "29",
"bit": 29,
"description": "Don't Havok Settle"
},
{
"bit": "30",
"bit": 30,
"description": "No Respawn"
}
]
@@ -955,27 +950,27 @@
"name": "Placed Hazard",
"flags": [
{
"bit": "7",
"bit": 7,
"description": "Turn Off Fire"
},
{
"bit": "10",
"bit": 10,
"description": "Persistent"
},
{
"bit": "11",
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": "28",
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": "29",
"bit": 29,
"description": "Don't Havok Settle"
},
{
"bit": "30",
"bit": 30,
"description": "No Respawn"
}
]
@@ -990,27 +985,27 @@
"name": "Placed Missile",
"flags": [
{
"bit": "7",
"bit": 7,
"description": "Turn Off Fire"
},
{
"bit": "10",
"bit": 10,
"description": "Persistent"
},
{
"bit": "11",
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": "28",
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": "29",
"bit": 29,
"description": "Don't Havok Settle"
},
{
"bit": "30",
"bit": 30,
"description": "No Respawn"
}
]
@@ -1035,7 +1030,7 @@
"name": "Race",
"flags": [
{
"bit": "19",
"bit": 19,
"description": "Critter?"
}
]
@@ -1045,35 +1040,35 @@
"name": "Placed Object",
"flags": [
{
"bit": "10",
"bit": 10,
"description": "Persistent"
},
{
"bit": "11",
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": "16",
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": "26",
"bit": 26,
"description": "Filter (Collision Geometry)"
},
{
"bit": "27",
"bit": 27,
"description": "Bounding Box (Collision Geometry)"
},
{
"bit": "28",
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": "30",
"bit": 30,
"description": "Ground"
},
{
"bit": "31",
"bit": 31,
"description": "Multibound"
}
]
@@ -1083,7 +1078,7 @@
"name": "Region",
"flags": [
{
"bit": "6",
"bit": 6,
"description": "Border Region"
}
]
@@ -1093,7 +1088,7 @@
"name": "Relationship",
"flags": [
{
"bit": "6",
"bit": 6,
"description": "Secret"
}
]
@@ -1138,7 +1133,7 @@
"name": "Shout",
"flags": [
{
"bit": "7",
"bit": 7,
"description": "Treat spells as powers"
}
]
@@ -1148,7 +1143,7 @@
"name": "Soul Gem",
"flags": [
{
"bit": "17",
"bit": 17,
"description": "Can Hold NPC Soul"
}
]
@@ -1273,15 +1268,15 @@
"name": "Talking Activator",
"flags": [
{
"bit": "9",
"bit": 9,
"description": "Hidden From Local Map"
},
{
"bit": "16",
"bit": 16,
"description": "Random Anim Start"
},
{
"bit": "17",
"bit": 17,
"description": "Radio Station"
}
]
@@ -1291,39 +1286,39 @@
"name": "Main File Header",
"flags": [
{
"bit": "0",
"bit": 0,
"description": "ESM"
},
{
"bit": "1",
"bit": 1,
"description": "Altered"
},
{
"bit": "2",
"bit": 2,
"description": "Checked"
},
{
"bit": "3",
"bit": 3,
"description": "Active"
},
{
"bit": "4",
"bit": 4,
"description": "Optimized File"
},
{
"bit": "5",
"bit": 5,
"description": "Temp ID Owner"
},
{
"bit": "7",
"bit": 7,
"description": "Localized"
},
{
"bit": "8",
"bit": 8,
"description": "Precalc Data Only"
},
{
"bit": "9",
"bit": 9,
"description": "ESL"
}
]
@@ -1333,7 +1328,7 @@
"name": "Tree",
"flags": [
{
"bit": "15",
"bit": 15,
"description": "Has Distant LOD"
}
]
@@ -1363,7 +1358,7 @@
"name": "Weapon",
"flags": [
{
"bit": "2",
"bit": 2,
"description": "Non-Playable"
}
]
@@ -1378,7 +1373,7 @@
"name": "Worldspace",
"flags": [
{
"bit": "19",
"bit": 19,
"description": "Can't Wait"
}
]

View File

@@ -0,0 +1,90 @@
import os
import re
import json
from dataclasses import dataclass
# helper used when dumping the records to JSON
class Jsonify:
def encode(self, value=None):
if not value:
value = self.__dict__
return value
# Record model
@dataclass
class Flag(Jsonify):
bit: int
description: str
@dataclass
class Record(Jsonify):
fourcc: str
flags: list[Flag]
# open and read the records from xEdit source
fdir = os.path.dirname(__file__)
with open(os.path.join(fdir, "TES5Edit/Core/wbDefinitionsTES5.pas"), "r") as f:
inp = f.read()
# find the REFR flags decider
decider = re.findall("function wbREFRRecordFlagsDecider.*?\n(?:.*?\n)+?end;", inp)
assert len(decider) == 1, "Could not uniquely match wbREFRRecordFlagsDecider."
decider = decider[0]
# get decider sections
sections = re.findall("if\s*?[\\(]?MainRecord.Signature.*?then\s*?Result.*?\n", decider, flags = re.DOTALL)
# for each section get signatures and index
sig_to_index = {}
index_re = re.compile("Result := (\d.*?)")
sig_re = re.compile("MainRecord.Signature = (\w{4})")
for s in sections:
index = index_re.findall(s)
assert len(index) == 1, "Could not parse REFR decider index"
index = int(index[0]) - 1
sigs = sig_re.findall(s)
for sig in sigs:
sig_to_index[sig] = index
# get the REFR record
refr = re.findall("wbRefRecord\((REFR.*?\n(?:.*?\n)*?.*?)\);", inp)
assert len(refr) == 1, "Could not find REFR record"
refr = refr[0]
# get all of the flag lists
flag_lists = re.findall("wbFlagsList\\(\\[.*?\n((?:.*?\n)*?).*?\\]", refr)[1:]
assert len(flag_lists) - 1 == max(sig_to_index.values()), "Could not match decider indices with flag lists."
# process flag lists into flags
index_to_flag_list = {}
re_flag_line = re.compile(".*?(\d+?),.*?'(.*)'")
for index, flist in enumerate(flag_lists):
flags = []
for line in flist.strip().split('\n'):
match = re_flag_line.match(line).groups()
assert len(match) == 2, "Could not parse flag line."
flags += [Flag(int(match[0]), match[1])]
index_to_flag_list[index] = flags
# create list of records
records = []
for sig, index in sig_to_index.items():
records += [Record(sig, index_to_flag_list[index])]
# sort the records by signature
records = sorted(records, key=lambda x: x.fourcc)
# write the records out to a JSON file
class Encoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Jsonify):
return obj.encode()
else:
return json.JSONEncoder.default(self, obj)
with open(os.path.join(fdir, "refr_flags.json"), "w") as f:
json.dump(records, f, cls=Encoder, indent=4)

805
reference/refr_flags.json Normal file
View File

@@ -0,0 +1,805 @@
[
{
"fourcc": "ACTI",
"flags": [
{
"bit": 9,
"description": "Hidden From Local Map"
},
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 13,
"description": "Sky Marker"
},
{
"bit": 15,
"description": "Visible when distant"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 26,
"description": "Filter (Collision Geometry)"
},
{
"bit": 27,
"description": "Bounding Box (Collision Geometry)"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "ADDN",
"flags": [
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "ALCH",
"flags": [
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 25,
"description": "No AI Acquire"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "AMMO",
"flags": [
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 25,
"description": "No AI Acquire"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "ARMO",
"flags": [
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 25,
"description": "No AI Acquire"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "BOOK",
"flags": [
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 25,
"description": "No AI Acquire"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "CONT",
"flags": [
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 25,
"description": "No AI Acquire"
},
{
"bit": 26,
"description": "Filter (Collision Geometry)"
},
{
"bit": 27,
"description": "Bounding Box (Collision Geometry)"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "Ground"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "DOOR",
"flags": [
{
"bit": 6,
"description": "Hidden From Local Map"
},
{
"bit": 8,
"description": "Inaccessible"
},
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 26,
"description": "Filter (Collision Geometry)"
},
{
"bit": 27,
"description": "Bounding Box (Collision Geometry)"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "FLOR",
"flags": [
{
"bit": 9,
"description": "Hidden From Local Map"
},
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 13,
"description": "Sky Marker"
},
{
"bit": 15,
"description": "Visible when distant"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 26,
"description": "Filter (Collision Geometry)"
},
{
"bit": 27,
"description": "Bounding Box (Collision Geometry)"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "INGR",
"flags": [
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 25,
"description": "No AI Acquire"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "KEYM",
"flags": [
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 25,
"description": "No AI Acquire"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "LIGH",
"flags": [
{
"bit": 8,
"description": "Doesn''t Light Water"
},
{
"bit": 9,
"description": "Casts Shadows"
},
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Never Fades"
},
{
"bit": 17,
"description": "Doesn''t Light Landscape"
},
{
"bit": 25,
"description": "No AI Acquire"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "MISC",
"flags": [
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 25,
"description": "No AI Acquire"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "MSTT",
"flags": [
{
"bit": 9,
"description": "Motion Blur"
},
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 26,
"description": "Filter (Collision Geometry)"
},
{
"bit": 27,
"description": "Bounding Box (Collision Geometry)"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "SCRL",
"flags": [
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 25,
"description": "No AI Acquire"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "SLGM",
"flags": [
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 25,
"description": "No AI Acquire"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "STAT",
"flags": [
{
"bit": 9,
"description": "Hidden From Local Map"
},
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 13,
"description": "Sky Marker"
},
{
"bit": 15,
"description": "Visible when distant"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 26,
"description": "Filter (Collision Geometry)"
},
{
"bit": 27,
"description": "Bounding Box (Collision Geometry)"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "TREE",
"flags": [
{
"bit": 9,
"description": "Hidden From Local Map"
},
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 13,
"description": "Sky Marker"
},
{
"bit": 15,
"description": "Visible when distant"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 26,
"description": "Filter (Collision Geometry)"
},
{
"bit": 27,
"description": "Bounding Box (Collision Geometry)"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
},
{
"fourcc": "WEAP",
"flags": [
{
"bit": 10,
"description": "Persistent"
},
{
"bit": 11,
"description": "Initially Disabled"
},
{
"bit": 16,
"description": "Is Full LOD"
},
{
"bit": 25,
"description": "No AI Acquire"
},
{
"bit": 28,
"description": "Reflected By Auto Water"
},
{
"bit": 29,
"description": "Don''t Havok Settle"
},
{
"bit": 30,
"description": "No Respawn"
},
{
"bit": 31,
"description": "Multibound"
}
]
}
]