diff --git a/apps/openmw/mwclass/activator.cpp b/apps/openmw/mwclass/activator.cpp index 525097f815..2c32fa33c8 100644 --- a/apps/openmw/mwclass/activator.cpp +++ b/apps/openmw/mwclass/activator.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 3abf2f6f57..85d831a544 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index dd8cef1d8a..c1734be946 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -3,6 +3,7 @@ #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 0ad6782011..fab3d35464 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -3,6 +3,7 @@ #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index b8bff50c27..a95c90d1b1 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 1be89c0c09..a3d6ce8212 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -5,6 +5,9 @@ #include #include #include +#include +#include +#include #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/magiceffects.hpp" diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index a990c1439a..3faa42b288 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include "../mwbase/environment.hpp" diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 0169e63950..0958c4e23a 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index e10273952a..1f076e6735 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 20092f936c..6e202a1c2f 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -1,6 +1,8 @@ #include "filter.hpp" #include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwdialogue/scripttest.cpp b/apps/openmw/mwdialogue/scripttest.cpp index 3692272484..3edcf077fc 100644 --- a/apps/openmw/mwdialogue/scripttest.cpp +++ b/apps/openmw/mwdialogue/scripttest.cpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include "filter.hpp" diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index b7fa3d71a9..67bee26710 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -7,6 +7,9 @@ #include #include +#include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index 6022a8bf89..6686678983 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -7,6 +7,8 @@ #include #include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index 682ea31a0e..a54435d67f 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "tooltips.hpp" #include "ustring.hpp" diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index 35b61f21e1..65ac17cea2 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -111,7 +111,7 @@ namespace MWGui for (MWWorld::ESMStore::iterator it = store.begin(); it != store.end(); ++it) { - it->second->listIdentifier (mNames); + (*it)->listIdentifier (mNames); } // exterior cell names aren't technically identifiers, but since the COC function accepts them, diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 78735540e0..03cd234fed 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 582aeded24..1e340b4a99 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -10,6 +10,8 @@ #include #include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index 028da083f5..d2a2b8f320 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index c661b59f17..c218d60726 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "../mwworld/inventorystore.hpp" #include "../mwworld/class.hpp" diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 0c59d1a938..f9d261a272 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -10,6 +10,9 @@ #include #include +#include +#include + #include "../mwworld/esmstore.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwgui/recharge.cpp b/apps/openmw/mwgui/recharge.cpp index cbebb0cc68..46fb64780e 100644 --- a/apps/openmw/mwgui/recharge.cpp +++ b/apps/openmw/mwgui/recharge.cpp @@ -6,6 +6,8 @@ #include +#include + #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index b0f35640f1..737efba65c 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -7,6 +7,10 @@ #include #include +#include +#include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" diff --git a/apps/openmw/mwgui/savegamedialog.cpp b/apps/openmw/mwgui/savegamedialog.cpp index acc220c751..8ea39429f5 100644 --- a/apps/openmw/mwgui/savegamedialog.cpp +++ b/apps/openmw/mwgui/savegamedialog.cpp @@ -21,6 +21,8 @@ #include +#include + #include "../mwbase/statemanager.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwgui/sortfilteritemmodel.cpp b/apps/openmw/mwgui/sortfilteritemmodel.cpp index 09ecdb54e5..f3239f0186 100644 --- a/apps/openmw/mwgui/sortfilteritemmodel.cpp +++ b/apps/openmw/mwgui/sortfilteritemmodel.cpp @@ -15,7 +15,7 @@ #include #include #include - +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index dae157f511..0894e9e1f2 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -6,6 +6,10 @@ #include +#include +#include + + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index a54c5c87f3..43024a3db3 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -9,6 +9,8 @@ #include #include +#include + #include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/environment.hpp" diff --git a/apps/openmw/mwgui/spellmodel.cpp b/apps/openmw/mwgui/spellmodel.cpp index 859410392d..a6972b90e4 100644 --- a/apps/openmw/mwgui/spellmodel.cpp +++ b/apps/openmw/mwgui/spellmodel.cpp @@ -3,6 +3,9 @@ #include #include +#include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index f41990ac41..f35d435f0c 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -5,6 +5,8 @@ #include #include +#include +#include #include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" diff --git a/apps/openmw/mwgui/statswatcher.cpp b/apps/openmw/mwgui/statswatcher.cpp index 883fd265cc..46be15542a 100644 --- a/apps/openmw/mwgui/statswatcher.cpp +++ b/apps/openmw/mwgui/statswatcher.cpp @@ -1,5 +1,8 @@ #include "statswatcher.hpp" +#include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index 1f7576d493..4856487686 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -9,6 +9,13 @@ #include #include +#include +#include +#include +#include +#include +#include + #include #include "../mwbase/environment.hpp" diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 94c4288ddf..e0da731d5d 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 24a4eb3607..1955a79426 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -16,6 +16,7 @@ #include "../mwmechanics/actorutil.hpp" #include +#include #include "tooltips.hpp" diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index f6671915f3..c8abf87fcb 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index 2a27a976ee..aa88d58c4f 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -9,6 +9,9 @@ #include #include +#include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwlua/stats.cpp b/apps/openmw/mwlua/stats.cpp index 3e1746dce8..83bce35cca 100644 --- a/apps/openmw/mwlua/stats.cpp +++ b/apps/openmw/mwlua/stats.cpp @@ -7,6 +7,7 @@ #include #include +#include #include "localscripts.hpp" #include "luamanagerimp.hpp" diff --git a/apps/openmw/mwlua/types/book.cpp b/apps/openmw/mwlua/types/book.cpp index fd646048f8..c439965f30 100644 --- a/apps/openmw/mwlua/types/book.cpp +++ b/apps/openmw/mwlua/types/book.cpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace sol { diff --git a/apps/openmw/mwlua/types/ingredient.cpp b/apps/openmw/mwlua/types/ingredient.cpp index e75453d776..3505633036 100644 --- a/apps/openmw/mwlua/types/ingredient.cpp +++ b/apps/openmw/mwlua/types/ingredient.cpp @@ -8,6 +8,7 @@ #include #include +#include namespace sol { diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index 040214848c..6d61b59553 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -10,6 +10,9 @@ #include #include +#include +#include +#include #include diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 2bc0a217c9..2c423cafd1 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -12,6 +12,10 @@ #include #include +#include +#include + + #include "../mwworld/esmstore.hpp" #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" diff --git a/apps/openmw/mwmechanics/autocalcspell.cpp b/apps/openmw/mwmechanics/autocalcspell.cpp index d82b8505f1..fd7bcd7d5e 100644 --- a/apps/openmw/mwmechanics/autocalcspell.cpp +++ b/apps/openmw/mwmechanics/autocalcspell.cpp @@ -2,6 +2,11 @@ #include +#include +#include +#include +#include + #include "../mwworld/esmstore.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 266ea5a9f5..7f14185ad2 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index 5ecbd78ad6..612f178d65 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -6,6 +6,10 @@ #include +#include +#include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/mechanicsmanager.hpp" diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index ae4ebbce49..97e30620da 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" diff --git a/apps/openmw/mwmechanics/disease.hpp b/apps/openmw/mwmechanics/disease.hpp index e182886059..fad9afd015 100644 --- a/apps/openmw/mwmechanics/disease.hpp +++ b/apps/openmw/mwmechanics/disease.hpp @@ -3,6 +3,7 @@ #include #include +#include #include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 256e1bd871..6540b405a0 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -2,6 +2,8 @@ #include #include +#include +#include #include "../mwworld/manualref.hpp" #include "../mwworld/class.hpp" diff --git a/apps/openmw/mwmechanics/levelledlist.hpp b/apps/openmw/mwmechanics/levelledlist.hpp index 57dca34cf0..35ad048a27 100644 --- a/apps/openmw/mwmechanics/levelledlist.hpp +++ b/apps/openmw/mwmechanics/levelledlist.hpp @@ -3,6 +3,7 @@ #include #include +#include #include "../mwworld/ptr.hpp" #include "../mwworld/esmstore.hpp" diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index bde5ad0225..1d69faaa8e 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -6,6 +6,9 @@ #include #include +#include +#include +#include #include diff --git a/apps/openmw/mwmechanics/recharge.cpp b/apps/openmw/mwmechanics/recharge.cpp index 315495ac67..d15b44d298 100644 --- a/apps/openmw/mwmechanics/recharge.cpp +++ b/apps/openmw/mwmechanics/recharge.cpp @@ -2,6 +2,8 @@ #include #include +#include +#include #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 06d504ef6c..c845cfab04 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" diff --git a/apps/openmw/mwmechanics/spelleffects.cpp b/apps/openmw/mwmechanics/spelleffects.cpp index d2909e87d6..fc2ed4bbc5 100644 --- a/apps/openmw/mwmechanics/spelleffects.cpp +++ b/apps/openmw/mwmechanics/spelleffects.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" diff --git a/apps/openmw/mwmechanics/spelllist.cpp b/apps/openmw/mwmechanics/spelllist.cpp index cbe95e7047..7c302f7861 100644 --- a/apps/openmw/mwmechanics/spelllist.cpp +++ b/apps/openmw/mwmechanics/spelllist.cpp @@ -3,6 +3,8 @@ #include #include +#include +#include #include "spells.hpp" diff --git a/apps/openmw/mwmechanics/spellpriority.cpp b/apps/openmw/mwmechanics/spellpriority.cpp index e22a8c4f75..52ad95f710 100644 --- a/apps/openmw/mwmechanics/spellpriority.cpp +++ b/apps/openmw/mwmechanics/spellpriority.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwmechanics/spellresistance.cpp b/apps/openmw/mwmechanics/spellresistance.cpp index bb39255b43..d865172875 100644 --- a/apps/openmw/mwmechanics/spellresistance.cpp +++ b/apps/openmw/mwmechanics/spellresistance.cpp @@ -2,6 +2,8 @@ #include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index 2f81be6d36..481d555c01 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -5,6 +5,8 @@ #include #include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwmechanics/spellutil.cpp b/apps/openmw/mwmechanics/spellutil.cpp index 7fa9687189..f8a9eb3b2e 100644 --- a/apps/openmw/mwmechanics/spellutil.cpp +++ b/apps/openmw/mwmechanics/spellutil.cpp @@ -2,6 +2,8 @@ #include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwmechanics/summoning.cpp b/apps/openmw/mwmechanics/summoning.cpp index f17b6773e8..20455e7350 100644 --- a/apps/openmw/mwmechanics/summoning.cpp +++ b/apps/openmw/mwmechanics/summoning.cpp @@ -2,6 +2,9 @@ #include #include +#include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwmechanics/weaponpriority.cpp b/apps/openmw/mwmechanics/weaponpriority.cpp index 024d837fe7..0beecae990 100644 --- a/apps/openmw/mwmechanics/weaponpriority.cpp +++ b/apps/openmw/mwmechanics/weaponpriority.cpp @@ -1,6 +1,8 @@ #include "weaponpriority.hpp" #include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 17ef53acd5..eee8bca234 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -28,6 +28,7 @@ #include #include #include // FindRecIndexVisitor +#include #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 9b9ad0f770..28dea789e5 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 421a7e622f..940b343792 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -21,7 +21,13 @@ #include #include #include - +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index adbf1a202b..1426a6d314 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -11,6 +11,11 @@ #include #include +#include +#include +#include +#include + #include #include #include diff --git a/apps/openmw/mwscript/compilercontext.cpp b/apps/openmw/mwscript/compilercontext.cpp index 53e93354fa..fcad0dd998 100644 --- a/apps/openmw/mwscript/compilercontext.cpp +++ b/apps/openmw/mwscript/compilercontext.cpp @@ -3,7 +3,8 @@ #include "../mwworld/esmstore.hpp" #include - +#include +#include #include #include "../mwbase/environment.hpp" diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index f3c04a7341..9f93e5853b 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -16,6 +16,8 @@ #include #include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwscript/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index 35a666234b..17742a0f84 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index 633bcf88a2..0ca1443656 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -4,6 +4,7 @@ #include #include +#include #include "../mwworld/esmstore.hpp" diff --git a/apps/openmw/mwscript/skyextensions.cpp b/apps/openmw/mwscript/skyextensions.cpp index ed65885906..6ade880c7e 100644 --- a/apps/openmw/mwscript/skyextensions.cpp +++ b/apps/openmw/mwscript/skyextensions.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index fa48ae7e99..7ce266111f 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -12,6 +12,9 @@ #include #include #include +#include + +#include #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" diff --git a/apps/openmw/mwsound/regionsoundselector.cpp b/apps/openmw/mwsound/regionsoundselector.cpp index 752c4a26b4..1553344913 100644 --- a/apps/openmw/mwsound/regionsoundselector.cpp +++ b/apps/openmw/mwsound/regionsoundselector.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include diff --git a/apps/openmw/mwsound/sound_buffer.cpp b/apps/openmw/mwsound/sound_buffer.cpp index e64e89d775..814e400305 100644 --- a/apps/openmw/mwsound/sound_buffer.cpp +++ b/apps/openmw/mwsound/sound_buffer.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index b6fb8c61e3..c21713ceca 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include diff --git a/apps/openmw/mwworld/actionread.cpp b/apps/openmw/mwworld/actionread.cpp index 58611f0af7..442078b18c 100644 --- a/apps/openmw/mwworld/actionread.cpp +++ b/apps/openmw/mwworld/actionread.cpp @@ -1,5 +1,8 @@ #include "actionread.hpp" +#include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwworld/actionsoulgem.cpp b/apps/openmw/mwworld/actionsoulgem.cpp index dae0a4503f..161d923358 100644 --- a/apps/openmw/mwworld/actionsoulgem.cpp +++ b/apps/openmw/mwworld/actionsoulgem.cpp @@ -1,6 +1,7 @@ #include "actionsoulgem.hpp" #include +#include #include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index fd4c6161e9..951b1ab6fe 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/luamanager.hpp" diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 93009c26cb..46c5bb81ab 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -3,6 +3,9 @@ #include #include +#include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 5f6df78b50..91b0c9e9cb 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 05f7509b60..6c784aade0 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -10,7 +11,10 @@ #include #include #include +#include + #include +#include #include "../mwmechanics/spelllist.hpp" @@ -129,17 +133,105 @@ namespace namespace MWWorld { + using IDMap = std::unordered_map; + + struct ESMStoreImp + { + ESMStore::StoreTuple mStores; + + std::map mRecNameToStore; + + // Lookup of all IDs. Makes looking up references faster. Just + // maps the id name to the record type. + IDMap mIds; + IDMap mStaticIds; + + template + static void assignStoreToIndex(ESMStore& stores, Store& store) + { + const std::size_t storeIndex = ESMStore::getTypeIndex(); + if (stores.mStores.size() <= storeIndex) + stores.mStores.resize(storeIndex + 1); + + assert(&store == &std::get>(stores.mStoreImp->mStores)); + + stores.mStores[storeIndex] = &store; + if constexpr (std::is_convertible_v*, DynamicStore*>) + { + stores.mDynamicStores.push_back(&store); + constexpr ESM::RecNameInts recName = T::sRecordId; + if constexpr (recName != ESM::REC_INTERNAL_PLAYER) + { + stores.mStoreImp->mRecNameToStore[recName] = &store; + } + } + } + }; + + + int ESMStore::find(const std::string_view id) const + { + IDMap::const_iterator it = mStoreImp->mIds.find(id); + if (it == mStoreImp->mIds.end()) { + return 0; + } + return it->second; + } + + int ESMStore::findStatic(const std::string_view id) const + { + IDMap::const_iterator it = mStoreImp-> mStaticIds.find(id); + if (it == mStoreImp->mStaticIds.end()) { + return 0; + } + return it->second; + } + + ESMStore::ESMStore() + { + mStoreImp = std::make_unique(); + std::apply([this](auto& ...x) {(ESMStoreImp::assignStoreToIndex(*this, x), ...); }, mStoreImp->mStores); + mDynamicCount = 0; + getWritable().setCells(getWritable()); + } + + ESMStore::~ESMStore() = default; + + void ESMStore::clearDynamic() + { + for (const auto& store : mDynamicStores) + store->clearDynamic(); + + movePlayerRecord(); + } static bool isCacheableRecord(int id) { - if (id == ESM::REC_ACTI || id == ESM::REC_ALCH || id == ESM::REC_APPA || id == ESM::REC_ARMO || - id == ESM::REC_BOOK || id == ESM::REC_CLOT || id == ESM::REC_CONT || id == ESM::REC_CREA || - id == ESM::REC_DOOR || id == ESM::REC_INGR || id == ESM::REC_LEVC || id == ESM::REC_LEVI || - id == ESM::REC_LIGH || id == ESM::REC_LOCK || id == ESM::REC_MISC || id == ESM::REC_NPC_ || - id == ESM::REC_PROB || id == ESM::REC_REPA || id == ESM::REC_STAT || id == ESM::REC_WEAP || - id == ESM::REC_BODY) + switch (id) { - return true; + case ESM::REC_ACTI: + case ESM::REC_ALCH: + case ESM::REC_APPA: + case ESM::REC_ARMO: + case ESM::REC_BOOK: + case ESM::REC_CLOT: + case ESM::REC_CONT: + case ESM::REC_CREA: + case ESM::REC_DOOR: + case ESM::REC_INGR: + case ESM::REC_LEVC: + case ESM::REC_LEVI: + case ESM::REC_LIGH: + case ESM::REC_LOCK: + case ESM::REC_MISC: + case ESM::REC_NPC_: + case ESM::REC_PROB: + case ESM::REC_REPA: + case ESM::REC_STAT: + case ESM::REC_WEAP: + case ESM::REC_BODY: + return true; + break; } return false; } @@ -152,7 +244,7 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener, ESM::Dialo // Land texture loading needs to use a separate internal store for each plugin. // We set the number of plugins here so we can properly verify if valid plugin // indices are being passed to the LandTexture Store retrieval methods. - mLandTextures.resize(esm.getIndex()+1); + getWritable().resize(esm.getIndex()+1); // Loop through all records while(esm.hasMoreRecs()) @@ -166,10 +258,11 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener, ESM::Dialo } // Look up the record type. - std::map::iterator it = mStores.find(n.toInt()); + ESM::RecNameInts recName = static_cast(n.toInt()); + const auto& it = mStoreImp->mRecNameToStore.find(recName); - if (it == mStores.end()) { - if (n.toInt() == ESM::REC_INFO) { + if (it == mStoreImp->mRecNameToStore.end()) { + if (recName == ESM::REC_INFO) { if (dialogue) { dialogue->readInfo(esm, esm.getIndex() != 0); @@ -180,9 +273,9 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener, ESM::Dialo esm.skipRecord(); } } else if (n.toInt() == ESM::REC_MGEF) { - mMagicEffects.load (esm); + getWritable().load (esm); } else if (n.toInt() == ESM::REC_SKIL) { - mSkills.load (esm); + getWritable().load (esm); } else if (n.toInt() == ESM::REC_FILT || n.toInt() == ESM::REC_DBGP) { @@ -208,7 +301,7 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener, ESM::Dialo } if (n.toInt() == ESM::REC_DIAL) { - dialogue = const_cast(mDialogs.find(id.mId)); + dialogue = const_cast(getWritable().find(id.mId)); } else { dialogue = nullptr; } @@ -218,6 +311,18 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener, ESM::Dialo } } +void ESMStore::setIdType(const std::string& id, ESM::RecNameInts type) +{ + mStoreImp->mIds[id] = type; +} + +static std::size_t sTypeIndexCounter = 0; + +std::size_t ESMStore::geNextTypeIndex() +{ + return sTypeIndexCounter++; +} + ESM::LuaScriptsCfg ESMStore::getLuaScriptsCfg() const { ESM::LuaScriptsCfg cfg; @@ -246,10 +351,10 @@ ESM::LuaScriptsCfg ESMStore::getLuaScriptsCfg() const void ESMStore::setUp() { - mIds.clear(); + mStoreImp->mIds.clear(); - std::map::iterator storeIt = mStores.begin(); - for (; storeIt != mStores.end(); ++storeIt) { + std::map::iterator storeIt = mStoreImp->mRecNameToStore.begin(); + for (; storeIt != mStoreImp->mRecNameToStore.end(); ++storeIt) { storeIt->second->setUp(); if (isCacheableRecord(storeIt->first)) @@ -258,18 +363,18 @@ void ESMStore::setUp() storeIt->second->listIdentifier(identifiers); for (std::vector::const_iterator record = identifiers.begin(); record != identifiers.end(); ++record) - mIds[*record] = storeIt->first; + mStoreImp->mIds[*record] = storeIt->first; } } - if (mStaticIds.empty()) - for (const auto& [k, v] : mIds) - mStaticIds.emplace(Misc::StringUtils::lowerCase(k), v); + if (mStoreImp->mStaticIds.empty()) + for (const auto& [k, v] : mStoreImp->mIds) + mStoreImp->mStaticIds.emplace(Misc::StringUtils::lowerCase(k), v); - mSkills.setUp(); - mMagicEffects.setUp(); - mAttributes.setUp(); - mDialogs.setUp(); + getWritable().setUp(); + getWritable().setUp();; + getWritable().setUp(); + getWritable().setUp(); } void ESMStore::validateRecords(ESM::ReadersCache& readers) @@ -286,9 +391,10 @@ void ESMStore::countAllCellRefs(ESM::ReadersCache& readers) return; std::vector refs; std::vector refIDs; - for(auto it = mCells.intBegin(); it != mCells.intEnd(); ++it) + Store Cells = getWritable < ESM::Cell>(); + for(auto it = Cells.intBegin(); it != Cells.intEnd(); ++it) readRefs(*it, refs, refIDs, readers); - for(auto it = mCells.extBegin(); it != mCells.extEnd(); ++it) + for(auto it = Cells.extBegin(); it != Cells.extEnd(); ++it) readRefs(*it, refs, refIDs, readers); const auto lessByRefNum = [] (const Ref& l, const Ref& r) { return l.mRefNum < r.mRefNum; }; std::stable_sort(refs.begin(), refs.end(), lessByRefNum); @@ -317,17 +423,19 @@ int ESMStore::getRefCount(std::string_view id) const void ESMStore::validate() { - std::vector npcsToReplace = getNPCsToReplace(mFactions, mClasses, mNpcs.mStatic); + auto& npcs = getWritable(); + std::vector npcsToReplace = getNPCsToReplace(getWritable(), getWritable(), npcs.mStatic); for (const ESM::NPC &npc : npcsToReplace) { - mNpcs.eraseStatic(npc.mId); - mNpcs.insertStatic(npc); + npcs.eraseStatic(npc.mId); + npcs.insertStatic(npc); } // Validate spell effects for invalid arguments std::vector spellsToReplace; - for (ESM::Spell spell : mSpells) + auto& spells = getWritable(); + for (ESM::Spell spell : spells) { if (spell.mEffects.mList.empty()) continue; @@ -336,7 +444,7 @@ void ESMStore::validate() auto iter = spell.mEffects.mList.begin(); while (iter != spell.mEffects.mList.end()) { - const ESM::MagicEffect* mgef = mMagicEffects.search(iter->mEffectID); + const ESM::MagicEffect* mgef = getWritable().search(iter->mEffectID); if (!mgef) { Log(Debug::Verbose) << "Spell '" << spell.mId << "' has an invalid effect (index " << iter->mEffectID << ") present. Dropping the effect."; @@ -383,25 +491,35 @@ void ESMStore::validate() for (const ESM::Spell &spell : spellsToReplace) { - mSpells.eraseStatic(spell.mId); - mSpells.insertStatic(spell); + spells.eraseStatic(spell.mId); + spells.insertStatic(spell); } } +void ESMStore::movePlayerRecord() +{ + auto& npcs = getWritable(); + auto player = npcs.find("player"); + npcs.insert(*player); +} + void ESMStore::validateDynamic() { - std::vector npcsToReplace = getNPCsToReplace(mFactions, mClasses, mNpcs.mDynamic); + auto& npcs = getWritable(); + auto& scripts = getWritable(); + + std::vector npcsToReplace = getNPCsToReplace(getWritable(), getWritable(), npcs.mDynamic); for (const ESM::NPC &npc : npcsToReplace) - mNpcs.insert(npc); + npcs.insert(npc); - removeMissingScripts(mScripts, mArmors.mDynamic); - removeMissingScripts(mScripts, mBooks.mDynamic); - removeMissingScripts(mScripts, mClothes.mDynamic); - removeMissingScripts(mScripts, mWeapons.mDynamic); + removeMissingScripts(scripts, getWritable().mDynamic); + removeMissingScripts(scripts, getWritable().mDynamic); + removeMissingScripts(scripts, getWritable().mDynamic); + removeMissingScripts(scripts, getWritable().mDynamic); - removeMissingObjects(mCreatureLists); - removeMissingObjects(mItemLists); + removeMissingObjects(getWritable()); + removeMissingObjects(getWritable()); } // Leveled lists can be modified by scripts. This removes items that no longer exist (presumably because the plugin was removed) from modified lists @@ -426,19 +544,20 @@ void ESMStore::removeMissingObjects(Store& store) int ESMStore::countSavedGameRecords() const { return 1 // DYNA (dynamic name counter) - +mPotions.getDynamicSize() - +mArmors.getDynamicSize() - +mBooks.getDynamicSize() - +mClasses.getDynamicSize() - +mClothes.getDynamicSize() - +mEnchants.getDynamicSize() - +mNpcs.getDynamicSize() - +mSpells.getDynamicSize() - +mWeapons.getDynamicSize() - +mCreatureLists.getDynamicSize() - +mItemLists.getDynamicSize() - +mCreatures.getDynamicSize() - +mContainers.getDynamicSize(); + + get().getDynamicSize() + + get().getDynamicSize() + + get().getDynamicSize() + + get().getDynamicSize() + + get().getDynamicSize() + + get().getDynamicSize() + + get().getDynamicSize() + + get().getDynamicSize() + + get().getDynamicSize() + + get().getDynamicSize() + + get().getDynamicSize() + + get().getDynamicSize() + + get().getDynamicSize(); + } void ESMStore::write (ESM::ESMWriter& writer, Loading::Listener& progress) const @@ -449,23 +568,24 @@ void ESMStore::removeMissingObjects(Store& store) writer.endRecord("COUN"); writer.endRecord(ESM::REC_DYNA); - mPotions.write (writer, progress); - mArmors.write (writer, progress); - mBooks.write (writer, progress); - mClasses.write (writer, progress); - mClothes.write (writer, progress); - mEnchants.write (writer, progress); - mSpells.write (writer, progress); - mWeapons.write (writer, progress); - mNpcs.write (writer, progress); - mItemLists.write (writer, progress); - mCreatureLists.write (writer, progress); - mCreatures.write (writer, progress); - mContainers.write (writer, progress); + get().write (writer, progress); + get().write (writer, progress); + get().write (writer, progress); + get().write (writer, progress); + get().write (writer, progress); + get().write (writer, progress); + get().write (writer, progress); + get().write (writer, progress); + get().write (writer, progress); + get().write (writer, progress); + get().write (writer, progress); + get().write (writer, progress); + get().write (writer, progress); } - bool ESMStore::readRecord (ESM::ESMReader& reader, uint32_t type) + bool ESMStore::readRecord (ESM::ESMReader& reader, uint32_t type_id) { + ESM::RecNameInts type = (ESM::RecNameInts)type_id; switch (type) { case ESM::REC_ALCH: @@ -478,12 +598,12 @@ void ESMStore::removeMissingObjects(Store& store) case ESM::REC_WEAP: case ESM::REC_LEVI: case ESM::REC_LEVC: - mStores[type]->read (reader); + mStoreImp->mRecNameToStore[type]->read (reader); return true; case ESM::REC_NPC_: case ESM::REC_CREA: case ESM::REC_CONT: - mStores[type]->read (reader, true); + mStoreImp->mRecNameToStore[type]->read (reader, true); return true; case ESM::REC_DYNA: @@ -501,10 +621,10 @@ void ESMStore::removeMissingObjects(Store& store) { setUp(); - const ESM::NPC *player = mNpcs.find ("player"); + const ESM::NPC *player = get().find ("player"); - if (!mRaces.find (player->mRace) || - !mClasses.find (player->mClass)) + if (!get().find (player->mRace) || + !get().find (player->mClass)) throw std::runtime_error ("Invalid player record (race or class unavailable"); } @@ -526,4 +646,34 @@ void ESMStore::removeMissingObjects(Store& store) } return {ptr, true}; } + + template <> + const ESM::Cell *ESMStore::insert(const ESM::Cell &cell) { + return getWritable().insert(cell); + } + + template <> + const ESM::NPC *ESMStore::insert(const ESM::NPC &npc) + { + + auto& npcs = getWritable(); + if (Misc::StringUtils::ciEqual(npc.mId, "player")) + { + return npcs.insert(npc); + } + const std::string id = "$dynamic" + std::to_string(mDynamicCount++); + if (npcs.search(id) != nullptr) + { + const std::string msg = "Try to override existing record '" + id + "'"; + throw std::runtime_error(msg); + } + ESM::NPC record = npc; + + record.mId = id; + + ESM::NPC *ptr = npcs.insert(record); + mStoreImp->mIds[ptr->mId] = ESM::REC_NPC_; + return ptr; + } + } // end namespace diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index b4df837936..48ba6ec81a 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -4,9 +4,11 @@ #include #include #include +#include #include -#include +#include + #include "store.hpp" namespace Loading @@ -22,75 +24,139 @@ namespace MWMechanics namespace ESM { class ReadersCache; + struct Activator; + struct Potion; + struct Apparatus; + struct Armor; + struct BodyPart; + struct Book; + struct BirthSign; + struct Class; + struct Clothing; + struct Container; + struct Creature; + struct Dialogue; + struct Door; + struct Enchantment; + struct Faction; + struct Global; + struct Ingredient; + struct CreatureLevList; + struct ItemLevList; + struct Light; + struct Lockpick; + struct Miscellaneous; + struct NPC; + struct Probe; + struct Race; + struct Region; + struct Repair; + struct SoundGenerator; + struct Sound; + struct Spell; + struct StartScript; + struct Static; + struct Weapon; + struct GameSetting; + class Script; + struct Cell; + struct Land; + struct LandTexture; + struct Pathgrid; + struct MagicEffect; + struct Skill; + struct Attribute; } namespace MWWorld { + struct ESMStoreImp; + class ESMStore { - Store mActivators; - Store mPotions; - Store mAppas; - Store mArmors; - Store mBodyParts; - Store mBooks; - Store mBirthSigns; - Store mClasses; - Store mClothes; - Store mContainers; - Store mCreatures; - Store mDialogs; - Store mDoors; - Store mEnchants; - Store mFactions; - Store mGlobals; - Store mIngreds; - Store mCreatureLists; - Store mItemLists; - Store mLights; - Store mLockpicks; - Store mMiscItems; - Store mNpcs; - Store mProbes; - Store mRaces; - Store mRegions; - Store mRepairs; - Store mSoundGens; - Store mSounds; - Store mSpells; - Store mStartScripts; - Store mStatics; - Store mWeapons; + friend struct ESMStoreImp; //This allows StoreImp to extend esmstore without beeing included everywhere - Store mGameSettings; - Store mScripts; + using StoreTuple = std::tuple < + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, + Store, - // Lists that need special rules - Store mCells; - Store mLands; - Store mLandTextures; - Store mPathgrids; + // Lists that need special rules + Store, + Store, + Store, + Store, - Store mMagicEffects; - Store mSkills; + Store, + Store, - // Special entry which is hardcoded and not loaded from an ESM - Store mAttributes; + // Special entry which is hardcoded and not loaded from an ESM + Store>; - // Lookup of all IDs. Makes looking up references faster. Just - // maps the id name to the record type. - using IDMap = std::unordered_map; - IDMap mIds; - std::unordered_map mStaticIds; + template + struct HasMember; + + template + struct HasMember ...>> { + static constexpr bool value = (std::is_same_v || ...); + }; + + static std::size_t geNextTypeIndex(); + + template + static std::size_t getTypeIndex() + { + static_assert(HasMember::value); + static std::size_t sIndex = geNextTypeIndex(); + return sIndex; + } + + std::unique_ptr mStoreImp; std::unordered_map mRefCount; - std::map mStores; + std::vector mStores; + std::vector mDynamicStores; unsigned int mDynamicCount; mutable std::unordered_map, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual> mSpellListCache; + template + Store& getWritable() {return static_cast&>(*mStores[getTypeIndex()]);} + /// Validate entries in store after setup void validate(); @@ -99,6 +165,8 @@ namespace MWWorld template void removeMissingObjects(Store& store); + void setIdType(const std::string& id, ESM::RecNameInts type); + using LuaContent = std::variant< ESM::LuaScriptsCfg, // data from an omwaddon std::string>; // path to an omwscripts file @@ -109,93 +177,28 @@ namespace MWWorld ESM::LuaScriptsCfg getLuaScriptsCfg() const; /// \todo replace with SharedIterator - typedef std::map::const_iterator iterator; + typedef std::vector::const_iterator iterator; iterator begin() const { - return mStores.begin(); + return mDynamicStores.begin(); } iterator end() const { - return mStores.end(); + return mDynamicStores.end(); } /// Look up the given ID in 'all'. Returns 0 if not found. - int find(std::string_view id) const - { - IDMap::const_iterator it = mIds.find(id); - if (it == mIds.end()) { - return 0; - } - return it->second; - } - int findStatic(const std::string &id) const - { - IDMap::const_iterator it = mStaticIds.find(id); - if (it == mStaticIds.end()) { - return 0; - } - return it->second; - } + int find(const std::string_view id) const; - ESMStore() - : mDynamicCount(0) - { - mStores[ESM::REC_ACTI] = &mActivators; - mStores[ESM::REC_ALCH] = &mPotions; - mStores[ESM::REC_APPA] = &mAppas; - mStores[ESM::REC_ARMO] = &mArmors; - mStores[ESM::REC_BODY] = &mBodyParts; - mStores[ESM::REC_BOOK] = &mBooks; - mStores[ESM::REC_BSGN] = &mBirthSigns; - mStores[ESM::REC_CELL] = &mCells; - mStores[ESM::REC_CLAS] = &mClasses; - mStores[ESM::REC_CLOT] = &mClothes; - mStores[ESM::REC_CONT] = &mContainers; - mStores[ESM::REC_CREA] = &mCreatures; - mStores[ESM::REC_DIAL] = &mDialogs; - mStores[ESM::REC_DOOR] = &mDoors; - mStores[ESM::REC_ENCH] = &mEnchants; - mStores[ESM::REC_FACT] = &mFactions; - mStores[ESM::REC_GLOB] = &mGlobals; - mStores[ESM::REC_GMST] = &mGameSettings; - mStores[ESM::REC_INGR] = &mIngreds; - mStores[ESM::REC_LAND] = &mLands; - mStores[ESM::REC_LEVC] = &mCreatureLists; - mStores[ESM::REC_LEVI] = &mItemLists; - mStores[ESM::REC_LIGH] = &mLights; - mStores[ESM::REC_LOCK] = &mLockpicks; - mStores[ESM::REC_LTEX] = &mLandTextures; - mStores[ESM::REC_MISC] = &mMiscItems; - mStores[ESM::REC_NPC_] = &mNpcs; - mStores[ESM::REC_PGRD] = &mPathgrids; - mStores[ESM::REC_PROB] = &mProbes; - mStores[ESM::REC_RACE] = &mRaces; - mStores[ESM::REC_REGN] = &mRegions; - mStores[ESM::REC_REPA] = &mRepairs; - mStores[ESM::REC_SCPT] = &mScripts; - mStores[ESM::REC_SNDG] = &mSoundGens; - mStores[ESM::REC_SOUN] = &mSounds; - mStores[ESM::REC_SPEL] = &mSpells; - mStores[ESM::REC_SSCR] = &mStartScripts; - mStores[ESM::REC_STAT] = &mStatics; - mStores[ESM::REC_WEAP] = &mWeapons; + int findStatic(const std::string_view id) const; - mPathgrids.setCells(mCells); - } - void clearDynamic () - { - for (std::map::iterator it = mStores.begin(); it != mStores.end(); ++it) - it->second->clearDynamic(); + ESMStore(); + ~ESMStore(); - movePlayerRecord(); - } + void clearDynamic(); - void movePlayerRecord () - { - auto player = mNpcs.find("player"); - mNpcs.insert(*player); - } + void movePlayerRecord(); /// Validate entries in store after loading a save void validateDynamic(); @@ -203,9 +206,7 @@ namespace MWWorld void load(ESM::ESMReader &esm, Loading::Listener* listener, ESM::Dialogue*& dialogue); template - const Store &get() const { - throw std::runtime_error("Storage for this type not exist"); - } + const Store& get() const {return static_cast&>(*mStores[getTypeIndex()]);} /// Insert a custom record (i.e. with a generated ID that will not clash will pre-existing records) template @@ -213,7 +214,7 @@ namespace MWWorld { const std::string id = "$dynamic" + std::to_string(mDynamicCount++); - Store &store = const_cast &>(get()); + Store &store = getWritable(); if (store.search(id) != nullptr) { const std::string msg = "Try to override existing record '" + id + "'"; @@ -224,10 +225,9 @@ namespace MWWorld record.mId = id; T *ptr = store.insert(record); - for (iterator it = mStores.begin(); it != mStores.end(); ++it) { - if (it->second == &store) { - mIds[ptr->mId] = it->first; - } + if constexpr (std::is_convertible_v*, DynamicStore*>) + { + setIdType(ptr->mId, T::sRecordId); } return ptr; } @@ -235,13 +235,12 @@ namespace MWWorld /// Insert a record with set ID, and allow it to override a pre-existing static record. template const T *overrideRecord(const T &x) { - Store &store = const_cast &>(get()); + Store &store = getWritable(); T *ptr = store.insert(x); - for (iterator it = mStores.begin(); it != mStores.end(); ++it) { - if (it->second == &store) { - mIds[ptr->mId] = it->first; - } + if constexpr (std::is_convertible_v*, DynamicStore*>) + { + setIdType(ptr->mId, T::sRecordId); } return ptr; } @@ -249,7 +248,7 @@ namespace MWWorld template const T *insertStatic(const T &x) { - Store &store = const_cast &>(get()); + Store& store = getWritable(); if (store.search(x.mId) != nullptr) { const std::string msg = "Try to override existing record '" + x.mId + "'"; @@ -257,10 +256,9 @@ namespace MWWorld } T *ptr = store.insertStatic(x); - for (iterator it = mStores.begin(); it != mStores.end(); ++it) { - if (it->second == &store) { - mIds[ptr->mId] = it->first; - } + if constexpr (std::is_convertible_v*, DynamicStore*>) + { + setIdType(ptr->mId, T::sRecordId); } return ptr; } @@ -286,245 +284,13 @@ namespace MWWorld /// Actors with the same ID share spells, abilities, etc. /// @return The shared spell list to use for this actor and whether or not it has already been initialized. std::pair, bool> getSpellList(const std::string& id) const; + }; + template <> + const ESM::Cell* ESMStore::insert(const ESM::Cell& cell); template <> - inline const ESM::Cell *ESMStore::insert(const ESM::Cell &cell) { - return mCells.insert(cell); - } - - template <> - inline const ESM::NPC *ESMStore::insert(const ESM::NPC &npc) - { - if (Misc::StringUtils::ciEqual(npc.mId, "player")) - { - return mNpcs.insert(npc); - } - - const std::string id = "$dynamic" + std::to_string(mDynamicCount++); - if (mNpcs.search(id) != nullptr) - { - const std::string msg = "Try to override existing record '" + id + "'"; - throw std::runtime_error(msg); - } - ESM::NPC record = npc; - - record.mId = id; - - ESM::NPC *ptr = mNpcs.insert(record); - mIds[ptr->mId] = ESM::REC_NPC_; - return ptr; - } - - template <> - inline const Store &ESMStore::get() const { - return mActivators; - } - - template <> - inline const Store &ESMStore::get() const { - return mPotions; - } - - template <> - inline const Store &ESMStore::get() const { - return mAppas; - } - - template <> - inline const Store &ESMStore::get() const { - return mArmors; - } - - template <> - inline const Store &ESMStore::get() const { - return mBodyParts; - } - - template <> - inline const Store &ESMStore::get() const { - return mBooks; - } - - template <> - inline const Store &ESMStore::get() const { - return mBirthSigns; - } - - template <> - inline const Store &ESMStore::get() const { - return mClasses; - } - - template <> - inline const Store &ESMStore::get() const { - return mClothes; - } - - template <> - inline const Store &ESMStore::get() const { - return mContainers; - } - - template <> - inline const Store &ESMStore::get() const { - return mCreatures; - } - - template <> - inline const Store &ESMStore::get() const { - return mDialogs; - } - - template <> - inline const Store &ESMStore::get() const { - return mDoors; - } - - template <> - inline const Store &ESMStore::get() const { - return mEnchants; - } - - template <> - inline const Store &ESMStore::get() const { - return mFactions; - } - - template <> - inline const Store &ESMStore::get() const { - return mGlobals; - } - - template <> - inline const Store &ESMStore::get() const { - return mIngreds; - } - - template <> - inline const Store &ESMStore::get() const { - return mCreatureLists; - } - - template <> - inline const Store &ESMStore::get() const { - return mItemLists; - } - - template <> - inline const Store &ESMStore::get() const { - return mLights; - } - - template <> - inline const Store &ESMStore::get() const { - return mLockpicks; - } - - template <> - inline const Store &ESMStore::get() const { - return mMiscItems; - } - - template <> - inline const Store &ESMStore::get() const { - return mNpcs; - } - - template <> - inline const Store &ESMStore::get() const { - return mProbes; - } - - template <> - inline const Store &ESMStore::get() const { - return mRaces; - } - - template <> - inline const Store &ESMStore::get() const { - return mRegions; - } - - template <> - inline const Store &ESMStore::get() const { - return mRepairs; - } - - template <> - inline const Store &ESMStore::get() const { - return mSoundGens; - } - - template <> - inline const Store &ESMStore::get() const { - return mSounds; - } - - template <> - inline const Store &ESMStore::get() const { - return mSpells; - } - - template <> - inline const Store &ESMStore::get() const { - return mStartScripts; - } - - template <> - inline const Store &ESMStore::get() const { - return mStatics; - } - - template <> - inline const Store &ESMStore::get() const { - return mWeapons; - } - - template <> - inline const Store &ESMStore::get() const { - return mGameSettings; - } - - template <> - inline const Store &ESMStore::get() const { - return mScripts; - } - - template <> - inline const Store &ESMStore::get() const { - return mCells; - } - - template <> - inline const Store &ESMStore::get() const { - return mLands; - } - - template <> - inline const Store &ESMStore::get() const { - return mLandTextures; - } - - template <> - inline const Store &ESMStore::get() const { - return mPathgrids; - } - - template <> - inline const Store &ESMStore::get() const { - return mMagicEffects; - } - - template <> - inline const Store &ESMStore::get() const { - return mSkills; - } - - template <> - inline const Store &ESMStore::get() const { - return mAttributes; - } + const ESM::NPC* ESMStore::insert(const ESM::NPC& npc); } #endif diff --git a/apps/openmw/mwworld/livecellref.cpp b/apps/openmw/mwworld/livecellref.cpp index 172ba9ca8d..d69f314ef3 100644 --- a/apps/openmw/mwworld/livecellref.cpp +++ b/apps/openmw/mwworld/livecellref.cpp @@ -4,6 +4,9 @@ #include #include +#include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwworld/localscripts.cpp b/apps/openmw/mwworld/localscripts.cpp index 9345a0cb9b..2cc9261fae 100644 --- a/apps/openmw/mwworld/localscripts.cpp +++ b/apps/openmw/mwworld/localscripts.cpp @@ -1,6 +1,7 @@ #include "localscripts.hpp" #include +#include #include "esmstore.hpp" #include "cellstore.hpp" diff --git a/apps/openmw/mwworld/magiceffects.cpp b/apps/openmw/mwworld/magiceffects.cpp index 5e8eb54138..e5e42b1a2d 100644 --- a/apps/openmw/mwworld/magiceffects.cpp +++ b/apps/openmw/mwworld/magiceffects.cpp @@ -2,6 +2,13 @@ #include "esmstore.hpp" #include +#include +#include +#include +#include +#include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwworld/manualref.cpp b/apps/openmw/mwworld/manualref.cpp index b809a81b3e..5c822483c5 100644 --- a/apps/openmw/mwworld/manualref.cpp +++ b/apps/openmw/mwworld/manualref.cpp @@ -1,4 +1,5 @@ #include "manualref.hpp" +#include #include "esmstore.hpp" diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index f6f7ac5e15..45ae53712b 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index b25d867542..d11cf47ce0 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -11,6 +11,9 @@ #include #include +#include +#include +#include #include #include diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 214d3b3a96..7d1defad94 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -43,10 +43,12 @@ namespace MWWorld RecordId(const std::string &id = {}, bool isDeleted = false); }; - class StoreBase + class StoreBase {}; //Empty interface to be parent of all store types + + class DynamicStore : public StoreBase { public: - virtual ~StoreBase() {} + virtual ~DynamicStore() {} virtual void setUp() {} @@ -67,7 +69,7 @@ namespace MWWorld }; template - class IndexedStore + class IndexedStore : public StoreBase { protected: typedef typename std::map Static; @@ -161,7 +163,7 @@ namespace MWWorld class ESMStore; template - class Store : public StoreBase + class Store : public DynamicStore { typedef std::unordered_map Static; Static mStatic; @@ -220,7 +222,7 @@ namespace MWWorld }; template <> - class Store : public StoreBase + class Store : public DynamicStore { // For multiple ESM/ESP files we need one list per file. typedef std::vector LandTextureList; @@ -248,7 +250,7 @@ namespace MWWorld }; template <> - class Store : public StoreBase + class Store : public DynamicStore { struct SpatialComparator { @@ -291,7 +293,7 @@ namespace MWWorld }; template <> - class Store : public StoreBase + class Store : public DynamicStore { struct DynamicExtCmp { @@ -366,7 +368,7 @@ namespace MWWorld }; template <> - class Store : public StoreBase + class Store : public DynamicStore { private: typedef std::unordered_map Interior; @@ -433,7 +435,7 @@ namespace MWWorld }; template <> - class Store : public StoreBase + class Store : public DynamicStore { std::map mStatic; @@ -459,7 +461,7 @@ namespace MWWorld }; template <> - class Store : public StoreBase + class Store : public DynamicStore { typedef std::unordered_map Static; Static mStatic; diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 38f1b340e8..4a3690daf7 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/soundmanager.hpp" diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 163df76106..fc90a14b25 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -16,6 +16,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include diff --git a/apps/openmw_test_suite/mwworld/test_store.cpp b/apps/openmw_test_suite/mwworld/test_store.cpp index 3f77aec498..88ea74c804 100644 --- a/apps/openmw_test_suite/mwworld/test_store.cpp +++ b/apps/openmw_test_suite/mwworld/test_store.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index f3e7e9506c..5063674aaa 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -2,11 +2,14 @@ #define OPENMW_ESM_DEFS_H #include +#include #include #include +#include + namespace ESM { @@ -86,10 +89,20 @@ bool inline operator!= (const Position& left, const Position& right) noexcept left.rot[2] != right.rot[2]; } -template -constexpr unsigned int fourCC(const char(&name)[len]) { - static_assert(len == 5, "Constant must be 4 characters long. (Plus null terminator)"); - return static_cast(name[0]) | (static_cast(name[1]) << 8) | (static_cast(name[2]) << 16) | (static_cast(name[3]) << 24); +constexpr unsigned int sEsm4RecnameFlag = 0x00800000; + +constexpr unsigned int esm3Recname(const char(&name)[5]) { + if ((fourCC(name) & sEsm4RecnameFlag) == 0) + return fourCC(name); + else + throw std::logic_error("there must be no collision between esm3 records and esm4 records");//The throw errors ensures at compile time that no collision between ESM4 and ESM3 is possible +} + +constexpr unsigned int esm4Recname(const ESM4::RecordTypes recType) { + if ((recType & sEsm4RecnameFlag) == 0) + return (recType | sEsm4RecnameFlag); + else + throw std::logic_error("there must be no collision between esm3 records and esm4 records");//The throw errors ensures at compile time that no collision between ESM4 and ESM3 is possible } enum RecNameInts : unsigned int @@ -100,87 +113,227 @@ enum RecNameInts : unsigned int REC_INTERNAL_MARKER = 1, // format 0 / legacy - REC_ACTI = fourCC("ACTI"), - REC_ALCH = fourCC("ALCH"), - REC_APPA = fourCC("APPA"), - REC_ARMO = fourCC("ARMO"), - REC_BODY = fourCC("BODY"), - REC_BOOK = fourCC("BOOK"), - REC_BSGN = fourCC("BSGN"), - REC_CELL = fourCC("CELL"), - REC_CLAS = fourCC("CLAS"), - REC_CLOT = fourCC("CLOT"), - REC_CNTC = fourCC("CNTC"), - REC_CONT = fourCC("CONT"), - REC_CREA = fourCC("CREA"), - REC_CREC = fourCC("CREC"), - REC_DIAL = fourCC("DIAL"), - REC_DOOR = fourCC("DOOR"), - REC_ENCH = fourCC("ENCH"), - REC_FACT = fourCC("FACT"), - REC_GLOB = fourCC("GLOB"), - REC_GMST = fourCC("GMST"), - REC_INFO = fourCC("INFO"), - REC_INGR = fourCC("INGR"), - REC_LAND = fourCC("LAND"), - REC_LEVC = fourCC("LEVC"), - REC_LEVI = fourCC("LEVI"), - REC_LIGH = fourCC("LIGH"), - REC_LOCK = fourCC("LOCK"), - REC_LTEX = fourCC("LTEX"), - REC_MGEF = fourCC("MGEF"), - REC_MISC = fourCC("MISC"), - REC_NPC_ = fourCC("NPC_"), - REC_NPCC = fourCC("NPCC"), - REC_PGRD = fourCC("PGRD"), - REC_PROB = fourCC("PROB"), - REC_RACE = fourCC("RACE"), - REC_REGN = fourCC("REGN"), - REC_REPA = fourCC("REPA"), - REC_SCPT = fourCC("SCPT"), - REC_SKIL = fourCC("SKIL"), - REC_SNDG = fourCC("SNDG"), - REC_SOUN = fourCC("SOUN"), - REC_SPEL = fourCC("SPEL"), - REC_SSCR = fourCC("SSCR"), - REC_STAT = fourCC("STAT"), - REC_WEAP = fourCC("WEAP"), + REC_ACTI = esm3Recname("ACTI"), + REC_ALCH = esm3Recname("ALCH"), + REC_APPA = esm3Recname("APPA"), + REC_ARMO = esm3Recname("ARMO"), + REC_BODY = esm3Recname("BODY"), + REC_BOOK = esm3Recname("BOOK"), + REC_BSGN = esm3Recname("BSGN"), + REC_CELL = esm3Recname("CELL"), + REC_CLAS = esm3Recname("CLAS"), + REC_CLOT = esm3Recname("CLOT"), + REC_CNTC = esm3Recname("CNTC"), + REC_CONT = esm3Recname("CONT"), + REC_CREA = esm3Recname("CREA"), + REC_CREC = esm3Recname("CREC"), + REC_DIAL = esm3Recname("DIAL"), + REC_DOOR = esm3Recname("DOOR"), + REC_ENCH = esm3Recname("ENCH"), + REC_FACT = esm3Recname("FACT"), + REC_GLOB = esm3Recname("GLOB"), + REC_GMST = esm3Recname("GMST"), + REC_INFO = esm3Recname("INFO"), + REC_INGR = esm3Recname("INGR"), + REC_LAND = esm3Recname("LAND"), + REC_LEVC = esm3Recname("LEVC"), + REC_LEVI = esm3Recname("LEVI"), + REC_LIGH = esm3Recname("LIGH"), + REC_LOCK = esm3Recname("LOCK"), + REC_LTEX = esm3Recname("LTEX"), + REC_MGEF = esm3Recname("MGEF"), + REC_MISC = esm3Recname("MISC"), + REC_NPC_ = esm3Recname("NPC_"), + REC_NPCC = esm3Recname("NPCC"), + REC_PGRD = esm3Recname("PGRD"), + REC_PROB = esm3Recname("PROB"), + REC_RACE = esm3Recname("RACE"), + REC_REGN = esm3Recname("REGN"), + REC_REPA = esm3Recname("REPA"), + REC_SCPT = esm3Recname("SCPT"), + REC_SKIL = esm3Recname("SKIL"), + REC_SNDG = esm3Recname("SNDG"), + REC_SOUN = esm3Recname("SOUN"), + REC_SPEL = esm3Recname("SPEL"), + REC_SSCR = esm3Recname("SSCR"), + REC_STAT = esm3Recname("STAT"), + REC_WEAP = esm3Recname("WEAP"), // format 0 - saved games - REC_SAVE = fourCC("SAVE"), - REC_JOUR_LEGACY = fourCC("\xa4UOR"), // "\xa4UOR", rather than "JOUR", little oversight when magic numbers were + REC_SAVE = esm3Recname("SAVE"), + REC_JOUR_LEGACY = esm3Recname("\xa4UOR"), // "\xa4UOR", rather than "JOUR", little oversight when magic numbers were // calculated by hand, needs to be supported for older files now - REC_JOUR = fourCC("JOUR"), - REC_QUES = fourCC("QUES"), - REC_GSCR = fourCC("GSCR"), - REC_PLAY = fourCC("PLAY"), - REC_CSTA = fourCC("CSTA"), - REC_GMAP = fourCC("GMAP"), - REC_DIAS = fourCC("DIAS"), - REC_WTHR = fourCC("WTHR"), - REC_KEYS = fourCC("KEYS"), - REC_DYNA = fourCC("DYNA"), - REC_ASPL = fourCC("ASPL"), - REC_ACTC = fourCC("ACTC"), - REC_MPRJ = fourCC("MPRJ"), - REC_PROJ = fourCC("PROJ"), - REC_DCOU = fourCC("DCOU"), - REC_MARK = fourCC("MARK"), - REC_ENAB = fourCC("ENAB"), - REC_CAM_ = fourCC("CAM_"), - REC_STLN = fourCC("STLN"), - REC_INPU = fourCC("INPU"), + REC_JOUR = esm3Recname("JOUR"), + REC_QUES = esm3Recname("QUES"), + REC_GSCR = esm3Recname("GSCR"), + REC_PLAY = esm3Recname("PLAY"), + REC_CSTA = esm3Recname("CSTA"), + REC_GMAP = esm3Recname("GMAP"), + REC_DIAS = esm3Recname("DIAS"), + REC_WTHR = esm3Recname("WTHR"), + REC_KEYS = esm3Recname("KEYS"), + REC_DYNA = esm3Recname("DYNA"), + REC_ASPL = esm3Recname("ASPL"), + REC_ACTC = esm3Recname("ACTC"), + REC_MPRJ = esm3Recname("MPRJ"), + REC_PROJ = esm3Recname("PROJ"), + REC_DCOU = esm3Recname("DCOU"), + REC_MARK = esm3Recname("MARK"), + REC_ENAB = esm3Recname("ENAB"), + REC_CAM_ = esm3Recname("CAM_"), + REC_STLN = esm3Recname("STLN"), + REC_INPU = esm3Recname("INPU"), // format 1 - REC_FILT = fourCC("FILT"), - REC_DBGP = fourCC("DBGP"), ///< only used in project files - REC_LUAL = fourCC("LUAL"), // LuaScriptsCfg (only in omwgame or omwaddon) + REC_FILT = esm3Recname("FILT"), + REC_DBGP = esm3Recname("DBGP"), ///< only used in project files + REC_LUAL = esm3Recname("LUAL"), // LuaScriptsCfg (only in omwgame or omwaddon) // format 16 - Lua scripts in saved games - REC_LUAM = fourCC("LUAM"), // LuaManager data + REC_LUAM = esm3Recname("LUAM"), // LuaManager data // format 21 - Random state in saved games. - REC_RAND = fourCC("RAND"), // Random state. + REC_RAND = esm3Recname("RAND"), // Random state. + + REC_AACT4 = esm4Recname(ESM4::REC_AACT), // Action + REC_ACHR4 = esm4Recname(ESM4::REC_ACHR), // Actor Reference + REC_ACTI4 = esm4Recname(ESM4::REC_ACTI), // Activator + REC_ADDN4 = esm4Recname(ESM4::REC_ADDN), // Addon Node + REC_ALCH4 = esm4Recname(ESM4::REC_ALCH), // Potion + REC_AMMO4 = esm4Recname(ESM4::REC_AMMO), // Ammo + REC_ANIO4 = esm4Recname(ESM4::REC_ANIO), // Animated Object + REC_APPA4 = esm4Recname(ESM4::REC_APPA), // Apparatus (probably unused) + REC_ARMA4 = esm4Recname(ESM4::REC_ARMA), // Armature (Model) + REC_ARMO4 = esm4Recname(ESM4::REC_ARMO), // Armor + REC_ARTO4 = esm4Recname(ESM4::REC_ARTO), // Art Object + REC_ASPC4 = esm4Recname(ESM4::REC_ASPC), // Acoustic Space + REC_ASTP4 = esm4Recname(ESM4::REC_ASTP), // Association Type + REC_AVIF4 = esm4Recname(ESM4::REC_AVIF), // Actor Values/Perk Tree Graphics + REC_BOOK4 = esm4Recname(ESM4::REC_BOOK), // Book + REC_BPTD4 = esm4Recname(ESM4::REC_BPTD), // Body Part Data + REC_CAMS4 = esm4Recname(ESM4::REC_CAMS), // Camera Shot + REC_CELL4 = esm4Recname(ESM4::REC_CELL), // Cell + REC_CLAS4 = esm4Recname(ESM4::REC_CLAS), // Class + REC_CLFM4 = esm4Recname(ESM4::REC_CLFM), // Color + REC_CLMT4 = esm4Recname(ESM4::REC_CLMT), // Climate + REC_CLOT4 = esm4Recname(ESM4::REC_CLOT), // Clothing + REC_COBJ4 = esm4Recname(ESM4::REC_COBJ), // Constructible Object (recipes) + REC_COLL4 = esm4Recname(ESM4::REC_COLL), // Collision Layer + REC_CONT4 = esm4Recname(ESM4::REC_CONT), // Container + REC_CPTH4 = esm4Recname(ESM4::REC_CPTH), // Camera Path + REC_CREA4 = esm4Recname(ESM4::REC_CREA), // Creature + REC_CSTY4 = esm4Recname(ESM4::REC_CSTY), // Combat Style + REC_DEBR4 = esm4Recname(ESM4::REC_DEBR), // Debris + REC_DIAL4 = esm4Recname(ESM4::REC_DIAL), // Dialog Topic + REC_DLBR4 = esm4Recname(ESM4::REC_DLBR), // Dialog Branch + REC_DLVW4 = esm4Recname(ESM4::REC_DLVW), // Dialog View + REC_DOBJ4 = esm4Recname(ESM4::REC_DOBJ), // Default Object Manager + REC_DOOR4 = esm4Recname(ESM4::REC_DOOR), // Door + REC_DUAL4 = esm4Recname(ESM4::REC_DUAL), // Dual Cast Data (possibly unused) + REC_ECZN4 = esm4Recname(ESM4::REC_ECZN), // Encounter Zone + REC_EFSH4 = esm4Recname(ESM4::REC_EFSH), // Effect Shader + REC_ENCH4 = esm4Recname(ESM4::REC_ENCH), // Enchantment + REC_EQUP4 = esm4Recname(ESM4::REC_EQUP), // Equip Slot (flag-type values) + REC_EXPL4 = esm4Recname(ESM4::REC_EXPL), // Explosion + REC_EYES4 = esm4Recname(ESM4::REC_EYES), // Eyes + REC_FACT4 = esm4Recname(ESM4::REC_FACT), // Faction + REC_FLOR4 = esm4Recname(ESM4::REC_FLOR), // Flora + REC_FLST4 = esm4Recname(ESM4::REC_FLST), // Form List (non-levelled list) + REC_FSTP4 = esm4Recname(ESM4::REC_FSTP), // Footstep + REC_FSTS4 = esm4Recname(ESM4::REC_FSTS), // Footstep Set + REC_FURN4 = esm4Recname(ESM4::REC_FURN), // Furniture + REC_GLOB4 = esm4Recname(ESM4::REC_GLOB), // Global Variable + REC_GMST4 = esm4Recname(ESM4::REC_GMST), // Game Setting + REC_GRAS4 = esm4Recname(ESM4::REC_GRAS), // Grass + REC_GRUP4 = esm4Recname(ESM4::REC_GRUP), // Form Group + REC_HAIR4 = esm4Recname(ESM4::REC_HAIR), // Hair + REC_HAZD4 = esm4Recname(ESM4::REC_HAZD), // Hazard + REC_HDPT4 = esm4Recname(ESM4::REC_HDPT), // Head Part + REC_IDLE4 = esm4Recname(ESM4::REC_IDLE), // Idle Animation + REC_IDLM4 = esm4Recname(ESM4::REC_IDLM), // Idle Marker + REC_IMAD4 = esm4Recname(ESM4::REC_IMAD), // Image Space Modifier + REC_IMGS4 = esm4Recname(ESM4::REC_IMGS), // Image Space + REC_INFO4 = esm4Recname(ESM4::REC_INFO), // Dialog Topic Info + REC_INGR4 = esm4Recname(ESM4::REC_INGR), // Ingredient + REC_IPCT4 = esm4Recname(ESM4::REC_IPCT), // Impact Data + REC_IPDS4 = esm4Recname(ESM4::REC_IPDS), // Impact Data Set + REC_KEYM4 = esm4Recname(ESM4::REC_KEYM), // Key + REC_KYWD4 = esm4Recname(ESM4::REC_KYWD), // Keyword + REC_LAND4 = esm4Recname(ESM4::REC_LAND), // Land + REC_LCRT4 = esm4Recname(ESM4::REC_LCRT), // Location Reference Type + REC_LCTN4 = esm4Recname(ESM4::REC_LCTN), // Location + REC_LGTM4 = esm4Recname(ESM4::REC_LGTM), // Lighting Template + REC_LIGH4 = esm4Recname(ESM4::REC_LIGH), // Light + REC_LSCR4 = esm4Recname(ESM4::REC_LSCR), // Load Screen + REC_LTEX4 = esm4Recname(ESM4::REC_LTEX), // Land Texture + REC_LVLC4 = esm4Recname(ESM4::REC_LVLC), // Leveled Creature + REC_LVLI4 = esm4Recname(ESM4::REC_LVLI), // Leveled Item + REC_LVLN4 = esm4Recname(ESM4::REC_LVLN), // Leveled Actor + REC_LVSP4 = esm4Recname(ESM4::REC_LVSP), // Leveled Spell + REC_MATO4 = esm4Recname(ESM4::REC_MATO), // Material Object + REC_MATT4 = esm4Recname(ESM4::REC_MATT), // Material Type + REC_MESG4 = esm4Recname(ESM4::REC_MESG), // Message + REC_MGEF4 = esm4Recname(ESM4::REC_MGEF), // Magic Effect + REC_MISC4 = esm4Recname(ESM4::REC_MISC), // Misc. Object + REC_MOVT4 = esm4Recname(ESM4::REC_MOVT), // Movement Type + REC_MSTT4 = esm4Recname(ESM4::REC_MSTT), // Movable Static + REC_MUSC4 = esm4Recname(ESM4::REC_MUSC), // Music Type + REC_MUST4 = esm4Recname(ESM4::REC_MUST), // Music Track + REC_NAVI4 = esm4Recname(ESM4::REC_NAVI), // Navigation (master data) + REC_NAVM4 = esm4Recname(ESM4::REC_NAVM), // Nav Mesh + REC_NOTE4 = esm4Recname(ESM4::REC_NOTE), // Note + REC_NPC_4 = esm4Recname(ESM4::REC_NPC_), // Actor (NPC, Creature) + REC_OTFT4 = esm4Recname(ESM4::REC_OTFT), // Outfit + REC_PACK4 = esm4Recname(ESM4::REC_PACK), // AI Package + REC_PERK4 = esm4Recname(ESM4::REC_PERK), // Perk + REC_PGRE4 = esm4Recname(ESM4::REC_PGRE), // Placed grenade + REC_PHZD4 = esm4Recname(ESM4::REC_PHZD), // Placed hazard + REC_PROJ4 = esm4Recname(ESM4::REC_PROJ), // Projectile + REC_QUST4 = esm4Recname(ESM4::REC_QUST), // Quest + REC_RACE4 = esm4Recname(ESM4::REC_RACE), // Race / Creature type + REC_REFR4 = esm4Recname(ESM4::REC_REFR), // Object Reference + REC_REGN4 = esm4Recname(ESM4::REC_REGN), // Region (Audio/Weather) + REC_RELA4 = esm4Recname(ESM4::REC_RELA), // Relationship + REC_REVB4 = esm4Recname(ESM4::REC_REVB), // Reverb Parameters + REC_RFCT4 = esm4Recname(ESM4::REC_RFCT), // Visual Effect + REC_SBSP4 = esm4Recname(ESM4::REC_SBSP), // Subspace (TES4 only?) + REC_SCEN4 = esm4Recname(ESM4::REC_SCEN), // Scene + REC_SCPT4 = esm4Recname(ESM4::REC_SCPT), // Script + REC_SCRL4 = esm4Recname(ESM4::REC_SCRL), // Scroll + REC_SGST4 = esm4Recname(ESM4::REC_SGST), // Sigil Stone + REC_SHOU4 = esm4Recname(ESM4::REC_SHOU), // Shout + REC_SLGM4 = esm4Recname(ESM4::REC_SLGM), // Soul Gem + REC_SMBN4 = esm4Recname(ESM4::REC_SMBN), // Story Manager Branch Node + REC_SMEN4 = esm4Recname(ESM4::REC_SMEN), // Story Manager Event Node + REC_SMQN4 = esm4Recname(ESM4::REC_SMQN), // Story Manager Quest Node + REC_SNCT4 = esm4Recname(ESM4::REC_SNCT), // Sound Category + REC_SNDR4 = esm4Recname(ESM4::REC_SNDR), // Sound Reference + REC_SOPM4 = esm4Recname(ESM4::REC_SOPM), // Sound Output Model + REC_SOUN4 = esm4Recname(ESM4::REC_SOUN), // Sound + REC_SPEL4 = esm4Recname(ESM4::REC_SPEL), // Spell + REC_SPGD4 = esm4Recname(ESM4::REC_SPGD), // Shader Particle Geometry + REC_STAT4 = esm4Recname(ESM4::REC_STAT), // Static + REC_TACT4 = esm4Recname(ESM4::REC_TACT), // Talking Activator + REC_TERM4 = esm4Recname(ESM4::REC_TERM), // Terminal + REC_TES44 = esm4Recname(ESM4::REC_TES4), // Plugin info + REC_TREE4 = esm4Recname(ESM4::REC_TREE), // Tree + REC_TXST4 = esm4Recname(ESM4::REC_TXST), // Texture Set + REC_VTYP4 = esm4Recname(ESM4::REC_VTYP), // Voice Type + REC_WATR4 = esm4Recname(ESM4::REC_WATR), // Water Type + REC_WEAP4 = esm4Recname(ESM4::REC_WEAP), // Weapon + REC_WOOP4 = esm4Recname(ESM4::REC_WOOP), // Word Of Power + REC_WRLD4 = esm4Recname(ESM4::REC_WRLD), // World Space + REC_WTHR4 = esm4Recname(ESM4::REC_WTHR), // Weather + REC_ACRE4 = esm4Recname(ESM4::REC_ACRE), // Placed Creature (TES4 only?) + REC_PGRD4 = esm4Recname(ESM4::REC_PGRD), // Pathgrid (TES4 only?) + REC_ROAD4 = esm4Recname(ESM4::REC_ROAD), // Road (TES4 only?) + REC_IMOD4 = esm4Recname(ESM4::REC_IMOD), // Item Mod + REC_PWAT4 = esm4Recname(ESM4::REC_PWAT), // Placeable Water + REC_SCOL4 = esm4Recname(ESM4::REC_SCOL), // Static Collection + REC_CCRD4 = esm4Recname(ESM4::REC_CCRD), // Caravan Card + REC_CMNY4 = esm4Recname(ESM4::REC_CMNY), // Caravan Money + REC_ALOC4 = esm4Recname(ESM4::REC_ALOC), // Audio Location Controller + REC_MSET4 = esm4Recname(ESM4::REC_MSET) // Media Set }; /// Common subrecords diff --git a/components/esm4/common.hpp b/components/esm4/common.hpp index 11286e4b03..ddfbefb002 100644 --- a/components/esm4/common.hpp +++ b/components/esm4/common.hpp @@ -30,10 +30,17 @@ #include #include -#include - #include "formid.hpp" +namespace ESM +{ + template + constexpr unsigned int fourCC(const char(&name)[len]) { + static_assert(len == 5, "Constant must be 4 characters long. (Plus null terminator)"); + return static_cast(name[0]) | (static_cast(name[1]) << 8) | (static_cast(name[2]) << 16) | (static_cast(name[3]) << 24); + } +} + namespace ESM4 { using ESM::fourCC;