Lua: Standardize record stores

fix-osga-rotate-wildly
Zackhasacat 1 month ago committed by psi29a
parent 38eb741bfd
commit 6d529835ae

@ -63,7 +63,7 @@ add_openmw_dir (mwlua
luamanagerimp object objectlists userdataserializer luaevents engineevents objectvariant
context menuscripts globalscripts localscripts playerscripts luabindings objectbindings cellbindings
mwscriptbindings camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings
postprocessingbindings stats debugbindings corebindings worldbindings worker magicbindings factionbindings
postprocessingbindings stats recordstore debugbindings corebindings worldbindings worker magicbindings factionbindings
classbindings itemdata inputprocessor animationbindings birthsignbindings racebindings markupbindings
types/types types/door types/item types/actor types/container types/lockable types/weapon types/npc
types/creature types/player types/activator types/book types/lockpick types/probe types/apparatus

@ -97,8 +97,7 @@ namespace MWLua
api["magic"] = initCoreMagicBindings(context);
api["stats"] = initCoreStatsBindings(context);
initCoreFactionBindings(context);
api["factions"] = &MWBase::Environment::get().getESMStore()->get<ESM::Faction>();
api["factions"] = initCoreFactionBindings(context);
api["l10n"] = LuaUtil::initL10nLoader(lua->sol(), MWBase::Environment::get().getL10nManager());
const MWWorld::Store<ESM::GameSetting>* gmstStore

@ -1,4 +1,5 @@
#include "factionbindings.hpp"
#include "recordstore.hpp"
#include <components/esm3/loadfact.hpp>
#include <components/lua/luastate.hpp>
@ -32,10 +33,6 @@ namespace sol
{
};
template <>
struct is_automagical<MWWorld::Store<ESM::Faction>> : std::false_type
{
};
template <>
struct is_automagical<MWWorld::Store<FactionRank>> : std::false_type
{
};
@ -43,27 +40,11 @@ namespace sol
namespace MWLua
{
using FactionStore = MWWorld::Store<ESM::Faction>;
void initCoreFactionBindings(const Context& context)
sol::table initCoreFactionBindings(const Context& context)
{
sol::state_view& lua = context.mLua->sol();
sol::usertype<FactionStore> factionStoreT = lua.new_usertype<FactionStore>("ESM3_FactionStore");
factionStoreT[sol::meta_function::to_string] = [](const FactionStore& store) {
return "ESM3_FactionStore{" + std::to_string(store.getSize()) + " factions}";
};
factionStoreT[sol::meta_function::length] = [](const FactionStore& store) { return store.getSize(); };
factionStoreT[sol::meta_function::index] = sol::overload(
[](const FactionStore& store, size_t index) -> const ESM::Faction* {
if (index == 0 || index > store.getSize())
return nullptr;
return store.at(index - 1);
},
[](const FactionStore& store, std::string_view factionId) -> const ESM::Faction* {
return store.search(ESM::RefId::deserializeText(factionId));
});
factionStoreT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
factionStoreT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>();
sol::table factions(lua, sol::create);
addRecordFunctionBinding<ESM::Faction>(factions, context);
// Faction record
auto factionT = lua.new_usertype<ESM::Faction>("ESM3_Faction");
factionT[sol::meta_function::to_string]
@ -113,5 +94,6 @@ namespace MWLua
res.add(rec.mAttribute2);
return res;
});
return LuaUtil::makeReadOnly(factions);
}
}

@ -7,7 +7,7 @@
namespace MWLua
{
void initCoreFactionBindings(const Context& context);
sol::table initCoreFactionBindings(const Context& context);
}
#endif // MWLUA_FACTIONBINDINGS_H

@ -31,6 +31,7 @@
#include "luamanagerimp.hpp"
#include "object.hpp"
#include "objectvariant.hpp"
#include "recordstore.hpp"
namespace MWLua
{
@ -135,10 +136,6 @@ namespace MWLua
namespace sol
{
template <typename T>
struct is_automagical<typename MWWorld::Store<T>> : std::false_type
{
};
template <>
struct is_automagical<ESM::Spell> : std::false_type
{
@ -228,50 +225,18 @@ namespace MWLua
}
// Spell store
using SpellStore = MWWorld::Store<ESM::Spell>;
const SpellStore* spellStore = &MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>();
sol::usertype<SpellStore> spellStoreT = lua.new_usertype<SpellStore>("ESM3_SpellStore");
spellStoreT[sol::meta_function::to_string]
= [](const SpellStore& store) { return "ESM3_SpellStore{" + std::to_string(store.getSize()) + " spells}"; };
spellStoreT[sol::meta_function::length] = [](const SpellStore& store) { return store.getSize(); };
spellStoreT[sol::meta_function::index] = sol::overload(
[](const SpellStore& store, size_t index) -> const ESM::Spell* {
if (index == 0 || index > store.getSize())
return nullptr;
return store.at(index - 1);
},
[](const SpellStore& store, std::string_view spellId) -> const ESM::Spell* {
return store.search(ESM::RefId::deserializeText(spellId));
});
spellStoreT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
spellStoreT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>();
magicApi["spells"] = spellStore;
sol::table spells(lua, sol::create);
addRecordFunctionBinding<ESM::Spell>(spells, context);
magicApi["spells"] = LuaUtil::makeReadOnly(spells);
// Enchantment store
using EnchantmentStore = MWWorld::Store<ESM::Enchantment>;
const EnchantmentStore* enchantmentStore
= &MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>();
sol::usertype<EnchantmentStore> enchantmentStoreT = lua.new_usertype<EnchantmentStore>("ESM3_EnchantmentStore");
enchantmentStoreT[sol::meta_function::to_string] = [](const EnchantmentStore& store) {
return "ESM3_EnchantmentStore{" + std::to_string(store.getSize()) + " enchantments}";
};
enchantmentStoreT[sol::meta_function::length] = [](const EnchantmentStore& store) { return store.getSize(); };
enchantmentStoreT[sol::meta_function::index] = sol::overload(
[](const EnchantmentStore& store, size_t index) -> const ESM::Enchantment* {
if (index == 0 || index > store.getSize())
return nullptr;
return store.at(index - 1);
},
[](const EnchantmentStore& store, std::string_view enchantmentId) -> const ESM::Enchantment* {
return store.search(ESM::RefId::deserializeText(enchantmentId));
});
enchantmentStoreT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
enchantmentStoreT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>();
magicApi["enchantments"] = enchantmentStore;
sol::table enchantments(lua, sol::create);
addRecordFunctionBinding<ESM::Enchantment>(enchantments, context);
magicApi["enchantments"] = LuaUtil::makeReadOnly(enchantments);
// MagicEffect store
sol::table magicEffects(lua, sol::create);
magicApi["effects"] = LuaUtil::makeReadOnly(magicEffects);
using MagicEffectStore = MWWorld::Store<ESM::MagicEffect>;
const MagicEffectStore* magicEffectStore
= &MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>();
@ -303,8 +268,10 @@ namespace MWLua
};
magicEffectStoreT[sol::meta_function::pairs]
= [iter = sol::make_object(lua, magicEffectsIter)] { return iter; };
magicEffectStoreT[sol::meta_function::ipairs]
= [iter = sol::make_object(lua, magicEffectsIter)] { return iter; };
magicApi["effects"] = magicEffectStore;
magicEffects["records"] = magicEffectStore;
// Spell record
auto spellT = lua.new_usertype<ESM::Spell>("ESM3_Spell");

@ -0,0 +1,63 @@
#ifndef MWLUA_RECORDSTORE_H
#define MWLUA_RECORDSTORE_H
#include <sol/sol.hpp>
#include <components/esm/defs.hpp>
#include <components/lua/luastate.hpp>
#include "apps/openmw/mwbase/environment.hpp"
#include "apps/openmw/mwbase/world.hpp"
#include "apps/openmw/mwworld/esmstore.hpp"
#include "apps/openmw/mwworld/store.hpp"
#include "context.hpp"
#include "object.hpp"
namespace sol
{
// Ensure sol does not try to create the automatic Container or usertype bindings for Store.
// They include write operations and we want the store to be read-only.
template <typename T>
struct is_automagical<typename MWWorld::Store<T>> : std::false_type
{
};
}
namespace MWLua
{
template <class T>
void addRecordFunctionBinding(
sol::table& table, const Context& context, const std::string& recordName = std::string(T::getRecordType()))
{
const MWWorld::Store<T>& store = MWBase::Environment::get().getESMStore()->get<T>();
table["record"] = sol::overload([](const Object& obj) -> const T* { return obj.ptr().get<T>()->mBase; },
[&store](std::string_view id) -> const T* { return store.search(ESM::RefId::deserializeText(id)); });
// Define a custom user type for the store.
// Provide the interface of a read-only array.
using StoreT = MWWorld::Store<T>;
sol::state_view& lua = context.mLua->sol();
sol::usertype<StoreT> storeT = lua.new_usertype<StoreT>(recordName + "WorldStore");
storeT[sol::meta_function::to_string] = [recordName](const StoreT& store) {
return "{" + std::to_string(store.getSize()) + " " + recordName + " records}";
};
storeT[sol::meta_function::length] = [](const StoreT& store) { return store.getSize(); };
storeT[sol::meta_function::index] = sol::overload(
[](const StoreT& store, size_t index) -> const T* {
if (index == 0 || index > store.getSize())
return nullptr;
return store.at(index - 1); // Translate from Lua's 1-based indexing.
},
[](const StoreT& store, std::string_view id) -> const T* {
return store.search(ESM::RefId::deserializeText(id));
});
storeT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>();
storeT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
// Provide access to the store.
table["records"] = &store;
}
}
#endif // MWLUA_RECORDSTORE_H

@ -1,4 +1,5 @@
#include "soundbindings.hpp"
#include "recordstore.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp"
@ -196,24 +197,7 @@ namespace MWLua
},
[]() { return MWBase::Environment::get().getSoundManager()->sayActive(MWWorld::ConstPtr()); });
using SoundStore = MWWorld::Store<ESM::Sound>;
sol::usertype<SoundStore> soundStoreT = lua.new_usertype<SoundStore>("ESM3_SoundStore");
soundStoreT[sol::meta_function::to_string]
= [](const SoundStore& store) { return "ESM3_SoundStore{" + std::to_string(store.getSize()) + " sounds}"; };
soundStoreT[sol::meta_function::length] = [](const SoundStore& store) { return store.getSize(); };
soundStoreT[sol::meta_function::index] = sol::overload(
[](const SoundStore& store, size_t index) -> const ESM::Sound* {
if (index == 0 || index > store.getSize())
return nullptr;
return store.at(index - 1);
},
[](const SoundStore& store, std::string_view soundId) -> const ESM::Sound* {
return store.search(ESM::RefId::deserializeText(soundId));
});
soundStoreT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
soundStoreT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>();
api["sounds"] = &MWBase::Environment::get().getWorld()->getStore().get<ESM::Sound>();
addRecordFunctionBinding<ESM::Sound>(api, context);
// Sound record
auto soundT = lua.new_usertype<ESM::Sound>("ESM3_Sound");

@ -22,7 +22,7 @@
#include "../mwworld/esmstore.hpp"
#include "objectvariant.hpp"
#include "types/types.hpp"
#include "recordstore.hpp"
namespace
{

@ -6,22 +6,8 @@
#include <components/esm/defs.hpp>
#include <components/lua/luastate.hpp>
#include "apps/openmw/mwbase/environment.hpp"
#include "apps/openmw/mwworld/esmstore.hpp"
#include "apps/openmw/mwworld/store.hpp"
#include "../context.hpp"
#include "../object.hpp"
namespace sol
{
// Ensure sol does not try to create the automatic Container or usertype bindings for Store.
// They include write operations and we want the store to be read-only.
template <typename T>
struct is_automagical<typename MWWorld::Store<T>> : std::false_type
{
};
}
#include "../recordstore.hpp"
namespace MWLua
{
@ -68,36 +54,6 @@ namespace MWLua
void addESM4DoorBindings(sol::table door, const Context& context);
void addESM4TerminalBindings(sol::table term, const Context& context);
template <class T>
void addRecordFunctionBinding(
sol::table& table, const Context& context, const std::string& recordName = std::string(T::getRecordType()))
{
const MWWorld::Store<T>& store = MWBase::Environment::get().getESMStore()->get<T>();
table["record"] = sol::overload([](const Object& obj) -> const T* { return obj.ptr().get<T>()->mBase; },
[&store](std::string_view id) -> const T* { return store.search(ESM::RefId::deserializeText(id)); });
// Define a custom user type for the store.
// Provide the interface of a read-only array.
using StoreT = MWWorld::Store<T>;
sol::state_view& lua = context.mLua->sol();
sol::usertype<StoreT> storeT = lua.new_usertype<StoreT>(recordName + "WorldStore");
storeT[sol::meta_function::to_string] = [recordName](const StoreT& store) {
return "{" + std::to_string(store.getSize()) + " " + recordName + " records}";
};
storeT[sol::meta_function::length] = [](const StoreT& store) { return store.getSize(); };
storeT[sol::meta_function::index] = [](const StoreT& store, size_t index) -> const T* {
if (index == 0 || index > store.getSize())
return nullptr;
return store.at(index - 1); // Translate from Lua's 1-based indexing.
};
storeT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
storeT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>();
// Provide access to the store.
table["records"] = &store;
}
}
#endif // MWLUA_TYPES_H

@ -10,10 +10,6 @@
-- The revision of OpenMW Lua API. It is an integer that is incremented every time the API is changed. See the actual value at the top of the page.
-- @field [parent=#core] #number API_REVISION
---
-- A read-only list of all @{#FactionRecord}s in the world database.
-- @field [parent=#core] #list<#FactionRecord> factions
---
-- Terminates the game and quits to the OS. Should be used only for testing purposes.
-- @function [parent=#core] quit
@ -622,41 +618,52 @@
-- @field #number Curse Curse
-- @field #number Power Power, can be used once a day
--- @{#Spells}: Spells
-- @field [parent=#Magic] #Spells spells
--- List of all @{#Spell}s.
-- @field [parent=#Magic] #list<#Spell> spells
-- @usage local spell = core.magic.spells['thunder fist'] -- get by id
-- @usage local spell = core.magic.spells[1] -- get by index
-- @field [parent=#Spells] #list<#Spell> records A read-only list of all @{#Spell} records in the world database, may be indexed by recordId.
-- Implements [iterables#List](iterables.html#List) of #Spell.
-- @usage local spell = core.magic.spells.records['thunder fist'] -- get by id
-- @usage local spell = core.magic.spells.records[1] -- get by index
-- @usage -- Print all powers
-- for _, spell in pairs(core.magic.spells) do
-- for _, spell in pairs(core.magic.spells.records) do
-- if spell.types == core.magic.SPELL_TYPE.Power then
-- print(spell.name)
-- end
-- end
--- @{#Effects}: Magic Effects
-- @field [parent=#Magic] #Effects effects
--- Map from @{#MagicEffectId} to @{#MagicEffect}
-- @field [parent=#Magic] #map<#number, #MagicEffect> effects
-- @field [parent=#Effects] #map<#number, #MagicEffect> records
-- @usage -- Print all harmful effects
-- for _, effect in pairs(core.magic.effects) do
-- for _, effect in pairs(core.magic.effects.records) do
-- if effect.harmful then
-- print(effect.name)
-- end
-- end
-- @usage -- Look up the record of a specific effect and print its icon
-- local mgef = core.magic.effects[core.magic.EFFECT_TYPE.Reflect]
-- local mgef = core.magic.effects.records[core.magic.EFFECT_TYPE.Reflect]
-- print('Reflect Icon: '..tostring(mgef.icon))
--- List of all @{#Enchantment}s.
-- @field [parent=#Magic] #list<#Enchantment> enchantments
-- @usage local enchantment = core.magic.enchantments['marara's boon'] -- get by id
-- @usage local enchantment = core.magic.enchantments[1] -- get by index
--- @{#Enchantments}: Enchantments
-- @field [parent=#Magic] #Enchantments enchantments
--- A read-only list of all @{#Enchantment} records in the world database, may be indexed by recordId.
-- Implements [iterables#List](iterables.html#List) and [iterables#Map](iterables.html#map-iterable) of #Enchantment.
-- @field [parent=#Enchantments] #list<#Enchantment> records
-- @usage local enchantment = core.magic.enchantments.records['marara's boon'] -- get by id
-- @usage local enchantment = core.magic.enchantments.records[1] -- get by index
-- @usage -- Print all enchantments with constant effect
-- for _, ench in pairs(core.magic.enchantments) do
-- for _, ench in pairs(core.magic.enchantments.records) do
-- if ench.type == core.magic.ENCHANTMENT_TYPE.ConstantEffect then
-- print(ench.id)
-- end
-- end
---
-- @type Spell
-- @field #string id Spell id
@ -827,11 +834,12 @@
-- @field #number maxRange Raw maximal range value, from 0 to 255
--- List of all @{#SoundRecord}s.
-- @field [parent=#Sound] #list<#SoundRecord> sounds
-- @usage local sound = core.sound.sounds['Ashstorm'] -- get by id
-- @usage local sound = core.sound.sounds[1] -- get by index
-- @field [parent=#Sound] #list<#SoundRecord> records A read-only list of all @{#SoundRecord}s in the world database, may be indexed by recordId.
-- Implements [iterables#List](iterables.html#List) of #SoundRecord.
-- @usage local sound = core.sound.records['Ashstorm'] -- get by id
-- @usage local sound = core.sound.records[1] -- get by index
-- @usage -- Print all sound files paths
-- for _, sound in pairs(core.sound.sounds) do
-- for _, sound in pairs(core.sound.records) do
-- print(sound.fileName)
-- end
@ -844,7 +852,10 @@
--- `core.stats.Attribute`
-- @type Attribute
-- @field #list<#AttributeRecord> records A read-only list of all @{#AttributeRecord}s in the world database.
-- @field #list<#AttributeRecord> records A read-only list of all @{#AttributeRecord}s in the world database, may be indexed by recordId.
-- Implements [iterables#List](iterables.html#List) of #AttributeRecord.
-- @usage local record = core.stats.Attribute.records['example_recordid']
-- @usage local record = core.stats.Attribute.records[1]
---
-- Returns a read-only @{#AttributeRecord}
@ -857,7 +868,10 @@
--- `core.stats.Skill`
-- @type Skill
-- @field #list<#SkillRecord> records A read-only list of all @{#SkillRecord}s in the world database.
-- @field #list<#SkillRecord> records A read-only list of all @{#SkillRecord}s in the world database, may be indexed by recordId.
-- Implements [iterables#List](iterables.html#List) of #SkillRecord.
-- @usage local record = core.stats.Skill.records['example_recordid']
-- @usage local record = core.stats.Skill.records[1]
---
-- Returns a read-only @{#SkillRecord}
@ -892,6 +906,15 @@
-- @field #string failureSound VFS path to the failure sound
-- @field #string hitSound VFS path to the hit sound
--- @{#Factions}: Factions
-- @field [parent=#core] #Factions factions
---
-- A read-only list of all @{#FactionRecord}s in the world database.
-- @field [parent=#Factions] #list<#FactionRecord> records
-- @usage local record = core.factions.records['example_recordid']
-- @usage local record = core.factions.records[1]
---
-- Faction data record
-- @type FactionRecord

@ -718,7 +718,13 @@
-- @type Creature
-- @extends #Actor
-- @field #Actor baseType @{#Actor}
-- @field #list<#CreatureRecord> records A read-only list of all @{#CreatureRecord}s in the world database.
---
-- A read-only list of all @{#CreatureRecord}s in the world database, may be indexed by recordId.
-- Implements [iterables#List](iterables.html#List) of #CreatureRecord.
-- @field [parent=#Creature] #list<#CreatureRecord> records
-- @usage local record = types.NPC.classes['example_recordid']
-- @usage local record = types.NPC.classes[1]
---
-- Whether the object is a creature.
@ -772,7 +778,13 @@
-- @extends #Actor
-- @field #Actor baseType @{#Actor}
-- @field [parent=#NPC] #NpcStats stats
-- @field #list<#NpcRecord> records A read-only list of all @{#NpcRecord}s in the world database.
---
-- A read-only list of all @{#NpcRecord}s in the world database, may be indexed by recordId.
-- Implements [iterables#List](iterables.html#List) of #NpcRecord.
-- @field [parent=#NPC] #map<#NpcRecord> records
-- @usage local record = types.NPC.classes['example_recordid']
-- @usage local record = types.NPC.classes[1]
---
-- Whether the object is an NPC or a Player.
@ -925,8 +937,11 @@
-- @field [parent=#NPC] #Classes classes
---
-- A read-only list of all @{#ClassRecord}s in the world database.
-- A read-only list of all @{#ClassRecord}s in the world database, may be indexed by recordId.
-- Implements [iterables#List](iterables.html#List) of #ClassRecord.
-- @field [parent=#Classes] #list<#ClassRecord> records
-- @usage local record = types.NPC.classes['example_recordid']
-- @usage local record = types.NPC.classes[1]
---
-- Returns a read-only @{#ClassRecord}
@ -963,7 +978,10 @@
---
-- A read-only list of all @{#RaceRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #RaceRecord.
-- @field [parent=#Races] #list<#RaceRecord> records
-- @usage local record = types.NPC.classes['example_recordid']
-- @usage local record = types.NPC.classes[1]
---
-- Returns a read-only @{#RaceRecord}
@ -1120,7 +1138,10 @@
---
-- A read-only list of all @{#BirthSignRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #BirthSignRecord.
-- @field [parent=#BirthSigns] #list<#BirthSignRecord> records
-- @usage local record = types.NPC.classes['example_recordid']
-- @usage local record = types.NPC.classes[1]
---
-- Returns a read-only @{#BirthSignRecord}
@ -1152,7 +1173,6 @@
-- @type Armor
-- @extends #Item
-- @field #Item baseType @{#Item}
-- @field #list<#ArmorRecord> records A read-only list of all @{#ArmorRecord}s in the world database.
---
-- Whether the object is an Armor.
@ -1174,6 +1194,13 @@
-- @field #number LBracer
-- @field #number RBracer
---
-- A read-only list of all @{#ArmorRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #ArmorRecord.
-- @field [parent=#Armor] #list<#ArmorRecord> records
-- @usage local record = types.Armor.records['example_recordid']
-- @usage local record = types.Armor.records[1]
--- @{#ArmorTYPE}
-- @field [parent=#Armor] #ArmorTYPE TYPE
@ -1219,7 +1246,13 @@
-- @type Book
-- @extends #Item
-- @field #Item baseType @{#Item}
-- @field #list<#BookRecord> records A read-only list of all @{#BookRecord}s in the world database.
---
-- A read-only list of all @{#BookRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #BookRecord.
-- @field [parent=#Book] #list<#BookRecord> records
-- @usage local record = types.Book.records['example_recordid']
-- @usage local record = types.Book.records[1]
---
-- Whether the object is a Book.
@ -1295,7 +1328,13 @@
-- @type Clothing
-- @extends #Item
-- @field #Item baseType @{#Item}
-- @field #list<#ClothingRecord> records A read-only list of all @{#ClothingRecord}s in the world database.
---
-- A read-only list of all @{#ClothingRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #ClothingRecord.
-- @field [parent=#Clothing] #list<#ClothingRecord> records
-- @usage local record = types.Clothing.records['example_recordid']
-- @usage local record = types.Clothing.records[1]
---
-- Whether the object is a Clothing.
@ -1361,7 +1400,13 @@
-- @type Ingredient
-- @extends #Item
-- @field #Item baseType @{#Item}
-- @field #list<#IngredientRecord> records A read-only list of all @{#IngredientRecord}s in the world database.
---
-- A read-only list of all @{#IngredientRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #IngredientRecord.
-- @field [parent=#Ingredient] #list<#IngredientRecord> records
-- @usage local record = types.Ingredient.records['example_recordid']
-- @usage local record = types.Ingredient.records[1]
---
-- Whether the object is an Ingredient.
@ -1448,7 +1493,13 @@
-- @type Light
-- @extends #Item
-- @field #Item baseType @{#Item}
-- @field #list<#LightRecord> records A read-only list of all @{#LightRecord}s in the world database.
---
-- A read-only list of all @{#LightRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #LightRecord.
-- @field [parent=#Light] #list<#LightRecord> records
-- @usage local record = types.Light.records['example_recordid']
-- @usage local record = types.Light.records[1]
---
-- Whether the object is a Light.
@ -1486,7 +1537,13 @@
-- @type Miscellaneous
-- @extends #Item
-- @field #Item baseType @{#Item}
-- @field #list<#MiscellaneousRecord> records A read-only list of all @{#MiscellaneousRecord}s in the world database.
---
-- A read-only list of all @{#MiscellaneousRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #MiscellaneousRecord.
-- @field [parent=#Miscellaneous] #list<#MiscellaneousRecord> records
-- @usage local record = types.Miscellaneous.records['example_recordid']
-- @usage local record = types.Miscellaneous.records[1]
---
-- Whether the object is a Miscellaneous.
@ -1537,7 +1594,13 @@
-- @type Potion
-- @extends #Item
-- @field #Item baseType @{#Item}
-- @field #list<#PotionRecord> records A read-only list of all @{#PotionRecord}s in the world database.
---
-- A read-only list of all @{#PotionRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #PotionRecord.
-- @field [parent=#Potion] #list<#PotionRecord> records
-- @usage local record = types.Potion.records['example_recordid']
-- @usage local record = types.Potion.records[1]
---
-- Whether the object is a Potion.
@ -1578,7 +1641,13 @@
-- @type Weapon
-- @extends #Item
-- @field #Item baseType @{#Item}
-- @field #list<#WeaponRecord> records A read-only list of all @{#WeaponRecord}s in the world database.
---
-- A read-only list of all @{#WeaponRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #WeaponRecord.
-- @field [parent=#Weapon] #list<#WeaponRecord> records
-- @usage local record = types.Weapon.records['example_recordid']
-- @usage local record = types.Weapon.records[1]
---
-- Whether the object is a Weapon.
@ -1650,7 +1719,14 @@
-- @type Apparatus
-- @extends #Item
-- @field #Item baseType @{#Item}
-- @field #list<#ApparatusRecord> records A read-only list of all @{#ApparatusRecord}s in the world database.
---
-- A read-only list of all @{#ApparatusRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #ApparatusRecord.
-- @field [parent=#Apparatus] #list<#ApparatusRecord> records
-- @usage local record = types.Apparatus.records['example_recordid']
-- @usage local record = types.Apparatus.records[1]
---
-- Whether the object is an Apparatus.
@ -1693,7 +1769,13 @@
-- @type Lockpick
-- @extends #Item
-- @field #Item baseType @{#Item}
-- @field #list<#LockpickRecord> records A read-only list of all @{#LockpickRecord}s in the world database.
---
-- A read-only list of all @{#LockpickRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #LockpickRecord.
-- @field [parent=#Lockpick] #list<#LockpickRecord> records
-- @usage local record = types.Lockpick.records['example_recordid']
-- @usage local record = types.Lockpick.records[1]
---
-- Whether the object is a Lockpick.
@ -1726,7 +1808,13 @@
-- @type Probe
-- @extends #Item
-- @field #Item baseType @{#Item}
-- @field #list<#ProbeRecord> records A read-only list of all @{#ProbeRecord}s in the world database.
---
-- A read-only list of all @{#ProbeRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #ProbeRecord.
-- @field [parent=#Probe] #list<#ProbeRecord> records
-- @usage local record = types.Probe.records['example_recordid']
-- @usage local record = types.Probe.records[1]
---
-- Whether the object is a Probe.
@ -1759,7 +1847,13 @@
-- @type Repair
-- @extends #Item
-- @field #Item baseType @{#Item}
-- @field #list<#RepairRecord> records A read-only list of all @{#RepairRecord}s in the world database.
---
-- A read-only list of all @{#RepairRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #RepairRecord.
-- @field [parent=#Repair] #list<#RepairRecord> records
-- @usage local record = types.Repair.records['example_recordid']
-- @usage local record = types.Repair.records[1]
---
-- Whether the object is a Repair.
@ -1790,7 +1884,13 @@
---
-- @type Activator
-- @field #list<#ActivatorRecord> records A read-only list of all @{#ActivatorRecord}s in the world database.
---
-- A read-only list of all @{#ActivatorRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #ActivatorRecord.
-- @field [parent=#Activator] #list<#ActivatorRecord> records
-- @usage local record = types.Activator.records['example_recordid']
-- @usage local record = types.Activator.records[1]
---
-- Whether the object is an Activator.
@ -1827,7 +1927,13 @@
-- @type Container
-- @extends #Lockable
-- @field #Lockable baseType @{#Lockable}
-- @field #list<#ContainerRecord> records A read-only list of all @{#ContainerRecord}s in the world database.
---
-- A read-only list of all @{#ContainerRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #ContainerRecord.
-- @field [parent=#Container] #list<#ContainerRecord> records
-- @usage local record = types.Container.records['example_recordid']
-- @usage local record = types.Container.records[1]
---
-- Container content.
@ -1882,7 +1988,13 @@
-- @type Door
-- @extends #Lockable
-- @field #Lockable baseType @{#Lockable}
-- @field #list<#DoorRecord> records A read-only list of all @{#DoorRecord}s in the world database.
---
-- A read-only list of all @{#DoorRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #DoorRecord.
-- @field [parent=#Door] #list<#DoorRecord> records
-- @usage local record = types.Door.records['example_recordid']
-- @usage local record = types.Door.records[1]
---
-- Whether the object is a Door.
@ -1936,7 +2048,13 @@
---
-- @type Static
-- @field #list<#StaticRecord> records A read-only list of all @{#StaticRecord}s in the world database.
---
-- A read-only list of all @{#StaticRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #StaticRecord.
-- @field [parent=#Static] #list<#StaticRecord> records
-- @usage local record = types.Static.records['example_recordid']
-- @usage local record = types.Static.records[1]
---
-- Whether the object is a Static.
@ -1961,7 +2079,13 @@
---
-- @type CreatureLevelledList
-- @field #list<#CreatureLevelledListRecord> records A read-only list of all @{#CreatureLevelledListRecord}s in the world database.
---
-- A read-only list of all @{#CreatureLevelledListRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #CreatureLevelledListRecord.
-- @field [parent=#CreatureLevelledList] #list<#CreatureLevelledListRecord> records
-- @usage local record = types.CreatureLevelledList.records['example_recordid']
-- @usage local record = types.CreatureLevelledList.records[1]
---
-- Whether the object is a CreatureLevelledList.
@ -2045,7 +2169,13 @@
---
-- @type ESM4Terminal
-- @field #list<#ESM4TerminalRecord> records A read-only list of all @{#ESM4TerminalRecord}s in the world database.
---
-- A read-only list of all @{#ESM4TerminalRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #ESM4TerminalRecord.
-- @field [parent=#ESM4Terminal] #list<#ESM4TerminalRecord> records
-- @usage local record = types.ESM4Terminal.records['example_recordid']
-- @usage local record = types.ESM4Terminal.records[1]
---
-- Whether the object is a ESM4Terminal.
@ -2110,9 +2240,11 @@
-- @return #ESM4DoorRecord
---
-- Returns a read-only list of all @{#ESM4DoorRecord}s in the world database.
-- @function [parent=#ESM4Door] records
-- @return #list<#ESM4DoorRecord>
-- A read-only list of all @{#ESM4DoorRecord}s in the world database.
-- Implements [iterables#List](iterables.html#List) of #ESM4DoorRecord.
-- @field [parent=#ESM4Door] #list<#ESM4DoorRecord> records
-- @usage local record = types.ESM4Door.records['example_recordid']
-- @usage local record = types.ESM4Door.records[1]
---
-- @type ESM4DoorRecord

@ -2,6 +2,7 @@ local testing = require('testing_util')
local core = require('openmw.core')
local async = require('openmw.async')
local util = require('openmw.util')
local types = require('openmw.types')
local world = require('openmw.world')
local function testTimers()
@ -87,6 +88,45 @@ local function testMWScript()
testing.expectEqual(variableStoreCount, indexCheck)
end
local function testRecordStore(store,storeName,skipPairs)
testing.expect(store.records)
local firstRecord = store.records[1]
if not firstRecord then return end
testing.expectEqual(firstRecord.id,store.records[firstRecord.id].id)
local status, _ = pcall(function()
for index, value in ipairs(store.records) do
if value.id == firstRecord.id then
testing.expectEqual(index,1,storeName)
break
end
end
end)
testing.expectEqual(status,true,storeName)
end
local function testRecordStores()
for key, type in pairs(types) do
if type.records then
testRecordStore(type,key)
end
end
testRecordStore(core.magic.enchantments,"enchantments")
testRecordStore(core.magic.effects,"effects",true)
testRecordStore(core.magic.spells,"spells")
testRecordStore(core.stats.Attribute,"Attribute")
testRecordStore(core.stats.Skill,"Skill")
testRecordStore(core.sound,"sound")
testRecordStore(core.factions,"factions")
testRecordStore(types.NPC.classes,"classes")
testRecordStore(types.NPC.races,"races")
testRecordStore(types.Player.birthSigns,"birthSigns")
end
local function initPlayer()
player:teleport('', util.vector3(4096, 4096, 867.237), util.transform.identity)
coroutine.yield()
@ -124,6 +164,7 @@ tests = {
end},
{'teleport', testTeleport},
{'getGMST', testGetGMST},
{'recordStores', testRecordStores},
{'mwscript', testMWScript},
}

Loading…
Cancel
Save