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

@@ -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"
}
]
}
]