1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-10-17 18:16:39 +00:00

Add region bindings

This commit is contained in:
SkyHasACat 2025-07-05 07:25:56 -05:00 committed by Evil Eye
parent 32e463945e
commit d58545ca39
5 changed files with 138 additions and 1 deletions

View file

@ -63,7 +63,7 @@ add_openmw_dir (mwlua
context menuscripts globalscripts localscripts playerscripts luabindings objectbindings cellbindings coremwscriptbindings
mwscriptbindings camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings dialoguebindings
postprocessingbindings stats recordstore debugbindings corebindings worldbindings worker landbindings magicbindings factionbindings
classbindings itemdata inputprocessor animationbindings birthsignbindings racebindings markupbindings weatherbindings
classbindings itemdata inputprocessor animationbindings birthsignbindings racebindings markupbindings weatherbindings regionbindings
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
types/potion types/ingredient types/misc types/repair types/armor types/light types/static

View file

@ -27,6 +27,7 @@
#include "luaevents.hpp"
#include "magicbindings.hpp"
#include "soundbindings.hpp"
#include "regionbindings.hpp"
#include "stats.hpp"
#include "weatherbindings.hpp"
@ -111,6 +112,8 @@ namespace MWLua
api["factions"]
= context.cachePackage("openmw_core_factions", [context]() { return initCoreFactionBindings(context); });
api["regions"]
= context.cachePackage("openmw_core_regions", [context]() { return initCoreRegionBindings(context); });
api["dialogue"]
= context.cachePackage("openmw_core_dialogue", [context]() { return initCoreDialogueBindings(context); });
api["l10n"] = context.cachePackage("openmw_core_l10n",

View file

@ -0,0 +1,92 @@
#include "regionbindings.hpp"
#include "recordstore.hpp"
#include <components/esm3/loadregn.hpp>
#include <components/lua/luastate.hpp>
#include <components/lua/util.hpp>
#include <components/misc/color.hpp>
#include "idcollectionbindings.hpp"
namespace
{
struct RegionSoundRef
{
ESM::RefId mSoundId;
uint8_t mChance;
RegionSoundRef(const ESM::Region::SoundRef& ref)
: mSoundId(ref.mSound)
, mChance(ref.mChance)
{
}
};
}
namespace sol
{
template <>
struct is_automagical<ESM::Region> : std::false_type
{
};
template <>
struct is_automagical<MWWorld::Store<RegionSoundRef>> : std::false_type
{
};
}
namespace MWLua
{
sol::table initCoreRegionBindings(const Context& context)
{
sol::state_view lua = context.sol();
sol::table regions(lua, sol::create);
addRecordFunctionBinding<ESM::Region>(regions, context);
// Region record
auto regionT = lua.new_usertype<ESM::Region>("ESM3_Region");
regionT[sol::meta_function::to_string]
= [](const ESM::Region& rec) -> std::string { return "ESM3_Region[" + rec.mId.toDebugString() + "]"; };
regionT["id"] = sol::readonly_property([](const ESM::Region& rec) { return rec.mId.serializeText(); });
regionT["name"] = sol::readonly_property([](const ESM::Region& rec) -> std::string_view { return rec.mName; });
regionT["mapColor"] = sol::readonly_property([](const ESM::Region& rec) -> Misc::Color {
uint32_t c = rec.mMapColor;
float r = ((c >> 16) & 0xFF) / 255.f;
float g = ((c >> 8) & 0xFF) / 255.f;
float b = (c & 0xFF) / 255.f;
return Misc::Color(r, g, b, 1.f); // assume alpha = 1.0
});
regionT["sleepList"]
= sol::readonly_property([](const ESM::Region& rec) { return rec.mSleepList.serializeText(); });
regionT["weatherProbabilities"] = sol::readonly_property([lua = lua.lua_state()](const ESM::Region& rec) {
static const std::array<const char*, 10> WeatherNames
= { "clear", "cloudy", "foggy", "overcast", "rain", "thunder", "ash", "blight", "snow", "blizzard" };
sol::table res(lua, sol::create);
for (size_t i = 0; i < rec.mData.mProbabilities.size(); ++i)
{
res[i + 1] = rec.mData.mProbabilities[i]; // Numeric index (Lua-style 1-based)
res[WeatherNames[i]] = rec.mData.mProbabilities[i]; // Named index
}
return res;
});
regionT["sounds"] = sol::readonly_property([lua = lua.lua_state()](const ESM::Region& rec) {
sol::table res(lua, sol::create);
for (const auto& soundRef : rec.mSoundList)
res.add(RegionSoundRef(soundRef));
return res;
});
auto soundRefT = lua.new_usertype<RegionSoundRef>("ESM3_RegionSoundRef");
soundRefT[sol::meta_function::to_string] = [](const RegionSoundRef& ref) -> std::string {
return "ESM3_RegionSoundRef[" + ref.mSoundId.toDebugString() + "]";
};
soundRefT["soundId"]
= sol::readonly_property([](const RegionSoundRef& ref) { return ref.mSoundId.serializeText(); });
soundRefT["chance"] = sol::readonly_property([](const RegionSoundRef& ref) { return ref.mChance; });
return LuaUtil::makeReadOnly(regions);
}
}

View file

@ -0,0 +1,13 @@
#ifndef MWLUA_REGIONBINDINGS_H
#define MWLUA_REGIONBINDINGS_H
#include <sol/forward.hpp>
#include "context.hpp"
namespace MWLua
{
sol::table initCoreRegionBindings(const Context& context);
}
#endif // MWLUA_REGIONBINDINGS_H

View file

@ -1159,6 +1159,35 @@
-- Always nil for journal records or if there is no value set.
-- @field [parent=#DialogueRecordInfo] #string resultScript
--- @{#Regions}: Regions
-- @field [parent=#core] #Regions regions
---
-- A read-only list of all @{#RegionRecord}s in the world database.
-- @field [parent=#Regions] #list<#RegionRecord> records
-- @usage local record = core.regions.records['bitter coast region']
-- @usage local record = core.regions.records[1]
---
-- Region data record
-- @type RegionRecord
-- @field #string id Region ID
-- @field #string name Region display name
-- @field openmw.util#Color mapColor Map color for this region.
-- @field #string sleepList A list of leveled creature list used when sleeping outdoors in this region
-- @field #list<#RegionSoundRef> sounds A read-only list of ambient sounds played randomly in this region
-- @field #table weatherProbabilities A table mapping weather types to their probability (0100), should sum to 100.
-- Supports both numeric indices (110) and string keys:
-- `"clear"`, `"cloudy"`, `"foggy"`, `"overcast"`, `"rain"`, `"thunder"`, `"ash"`, `"blight"`, `"snow"`, `"blizzard"`
-- @usage print(region.weatherProbabilities[1]) -- access by index
-- @usage print(region.weatherProbabilities["rain"]) -- access by name
---
-- Region sound reference
-- @type RegionSoundRef
-- @field #string soundId Sound record ID
-- @field #number chance Probability that this sound plays periodically in the region
--- @{#Factions}: Factions
-- @field [parent=#core] #Factions factions