mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-30 03:32:36 +00:00
Lua: Add missing light flags, allow creating light record via world.createRecord
This commit is contained in:
parent
f595015ffc
commit
c63c1e69cf
@ -15,6 +15,65 @@ namespace sol
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void setRecordFlag(const sol::table& rec, const std::string& key, int flag, ESM::Light& record)
|
||||||
|
{
|
||||||
|
if (auto luaFlag = rec[key]; luaFlag != sol::nil)
|
||||||
|
{
|
||||||
|
if (luaFlag)
|
||||||
|
{
|
||||||
|
record.mData.mFlags |= flag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
record.mData.mFlags &= ~flag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Populates a light struct from a Lua table.
|
||||||
|
ESM::Light tableToLight(const sol::table& rec)
|
||||||
|
{
|
||||||
|
ESM::Light light;
|
||||||
|
if (rec["template"] != sol::nil)
|
||||||
|
light = LuaUtil::cast<ESM::Light>(rec["template"]);
|
||||||
|
else
|
||||||
|
light.blank();
|
||||||
|
if (rec["name"] != sol::nil)
|
||||||
|
light.mName = rec["name"];
|
||||||
|
if (rec["model"] != sol::nil)
|
||||||
|
light.mModel = Misc::ResourceHelpers::meshPathForESM3(rec["model"].get<std::string_view>());
|
||||||
|
if (rec["icon"] != sol::nil)
|
||||||
|
light.mIcon = rec["icon"];
|
||||||
|
if (rec["mwscript"] != sol::nil)
|
||||||
|
{
|
||||||
|
std::string_view scriptId = rec["mwscript"].get<std::string_view>();
|
||||||
|
light.mScript = ESM::RefId::deserializeText(scriptId);
|
||||||
|
}
|
||||||
|
if (rec["weight"] != sol::nil)
|
||||||
|
light.mData.mWeight = rec["weight"];
|
||||||
|
if (rec["value"] != sol::nil)
|
||||||
|
light.mData.mValue = rec["value"];
|
||||||
|
if (rec["duration"] != sol::nil)
|
||||||
|
light.mData.mTime = rec["duration"];
|
||||||
|
if (rec["radius"] != sol::nil)
|
||||||
|
light.mData.mRadius = rec["radius"];
|
||||||
|
if (rec["color"] != sol::nil)
|
||||||
|
light.mData.mColor = rec["color"];
|
||||||
|
setRecordFlag(rec, "isCarriable", ESM::Light::Carry, light);
|
||||||
|
setRecordFlag(rec, "isDynamic", ESM::Light::Dynamic, light);
|
||||||
|
setRecordFlag(rec, "isFire", ESM::Light::Fire, light);
|
||||||
|
setRecordFlag(rec, "isFlicker", ESM::Light::Flicker, light);
|
||||||
|
setRecordFlag(rec, "isFlickerSlow", ESM::Light::FlickerSlow, light);
|
||||||
|
setRecordFlag(rec, "isNegative", ESM::Light::Negative, light);
|
||||||
|
setRecordFlag(rec, "isOffByDefault", ESM::Light::OffDefault, light);
|
||||||
|
setRecordFlag(rec, "isPulse", ESM::Light::Pulse, light);
|
||||||
|
setRecordFlag(rec, "isPulseSlow", ESM::Light::PulseSlow, light);
|
||||||
|
|
||||||
|
return light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
void addLightBindings(sol::table light, const Context& context)
|
void addLightBindings(sol::table light, const Context& context)
|
||||||
@ -22,6 +81,7 @@ namespace MWLua
|
|||||||
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM::Light>(light, context);
|
addRecordFunctionBinding<ESM::Light>(light, context);
|
||||||
|
light["createRecordDraft"] = tableToLight;
|
||||||
|
|
||||||
sol::usertype<ESM::Light> record = context.mLua->sol().new_usertype<ESM::Light>("ESM3_Light");
|
sol::usertype<ESM::Light> record = context.mLua->sol().new_usertype<ESM::Light>("ESM3_Light");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
@ -45,5 +105,21 @@ namespace MWLua
|
|||||||
record["color"] = sol::readonly_property([](const ESM::Light& rec) -> int { return rec.mData.mColor; });
|
record["color"] = sol::readonly_property([](const ESM::Light& rec) -> int { return rec.mData.mColor; });
|
||||||
record["isCarriable"] = sol::readonly_property(
|
record["isCarriable"] = sol::readonly_property(
|
||||||
[](const ESM::Light& rec) -> bool { return rec.mData.mFlags & ESM::Light::Carry; });
|
[](const ESM::Light& rec) -> bool { return rec.mData.mFlags & ESM::Light::Carry; });
|
||||||
|
record["isDynamic"] = sol::readonly_property(
|
||||||
|
[](const ESM::Light& rec) -> bool { return rec.mData.mFlags & ESM::Light::Dynamic; });
|
||||||
|
record["isFire"]
|
||||||
|
= sol::readonly_property([](const ESM::Light& rec) -> bool { return rec.mData.mFlags & ESM::Light::Fire; });
|
||||||
|
record["isFlicker"] = sol::readonly_property(
|
||||||
|
[](const ESM::Light& rec) -> bool { return rec.mData.mFlags & ESM::Light::Flicker; });
|
||||||
|
record["isFlickerSlow"] = sol::readonly_property(
|
||||||
|
[](const ESM::Light& rec) -> bool { return rec.mData.mFlags & ESM::Light::FlickerSlow; });
|
||||||
|
record["isNegative"] = sol::readonly_property(
|
||||||
|
[](const ESM::Light& rec) -> bool { return rec.mData.mFlags & ESM::Light::Negative; });
|
||||||
|
record["isOffByDefault"] = sol::readonly_property(
|
||||||
|
[](const ESM::Light& rec) -> bool { return rec.mData.mFlags & ESM::Light::OffDefault; });
|
||||||
|
record["isPulse"] = sol::readonly_property(
|
||||||
|
[](const ESM::Light& rec) -> bool { return rec.mData.mFlags & ESM::Light::Pulse; });
|
||||||
|
record["isPulseSlow"] = sol::readonly_property(
|
||||||
|
[](const ESM::Light& rec) -> bool { return rec.mData.mFlags & ESM::Light::PulseSlow; });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <components/esm3/loadarmo.hpp>
|
#include <components/esm3/loadarmo.hpp>
|
||||||
#include <components/esm3/loadbook.hpp>
|
#include <components/esm3/loadbook.hpp>
|
||||||
#include <components/esm3/loadclot.hpp>
|
#include <components/esm3/loadclot.hpp>
|
||||||
|
#include <components/esm3/loadligh.hpp>
|
||||||
#include <components/esm3/loadmisc.hpp>
|
#include <components/esm3/loadmisc.hpp>
|
||||||
#include <components/esm3/loadskil.hpp>
|
#include <components/esm3/loadskil.hpp>
|
||||||
#include <components/esm3/loadweap.hpp>
|
#include <components/esm3/loadweap.hpp>
|
||||||
@ -181,6 +182,10 @@ namespace MWLua
|
|||||||
[lua = context.mLua](const ESM::Weapon& weapon) -> const ESM::Weapon* {
|
[lua = context.mLua](const ESM::Weapon& weapon) -> const ESM::Weapon* {
|
||||||
checkGameInitialized(lua);
|
checkGameInitialized(lua);
|
||||||
return MWBase::Environment::get().getESMStore()->insert(weapon);
|
return MWBase::Environment::get().getESMStore()->insert(weapon);
|
||||||
|
},
|
||||||
|
[lua = context.mLua](const ESM::Light& light) -> const ESM::Light* {
|
||||||
|
checkGameInitialized(lua);
|
||||||
|
return MWBase::Environment::get().getESMStore()->insert(light);
|
||||||
});
|
});
|
||||||
|
|
||||||
api["_runStandardActivationAction"] = [context](const GObject& object, const GObject& actor) {
|
api["_runStandardActivationAction"] = [context](const GObject& object, const GObject& actor) {
|
||||||
|
@ -540,6 +540,7 @@ void MWState::StateManager::loadGame(const Character* character, const std::file
|
|||||||
case ESM::REC_ENAB:
|
case ESM::REC_ENAB:
|
||||||
case ESM::REC_LEVC:
|
case ESM::REC_LEVC:
|
||||||
case ESM::REC_LEVI:
|
case ESM::REC_LEVI:
|
||||||
|
case ESM::REC_LIGH:
|
||||||
case ESM::REC_CREA:
|
case ESM::REC_CREA:
|
||||||
case ESM::REC_CONT:
|
case ESM::REC_CONT:
|
||||||
case ESM::REC_RAND:
|
case ESM::REC_RAND:
|
||||||
|
@ -689,7 +689,7 @@ namespace MWWorld
|
|||||||
+ get<ESM::Activator>().getDynamicSize() + get<ESM::Miscellaneous>().getDynamicSize()
|
+ get<ESM::Activator>().getDynamicSize() + get<ESM::Miscellaneous>().getDynamicSize()
|
||||||
+ get<ESM::Weapon>().getDynamicSize() + get<ESM::CreatureLevList>().getDynamicSize()
|
+ get<ESM::Weapon>().getDynamicSize() + get<ESM::CreatureLevList>().getDynamicSize()
|
||||||
+ get<ESM::ItemLevList>().getDynamicSize() + get<ESM::Creature>().getDynamicSize()
|
+ get<ESM::ItemLevList>().getDynamicSize() + get<ESM::Creature>().getDynamicSize()
|
||||||
+ get<ESM::Container>().getDynamicSize();
|
+ get<ESM::Container>().getDynamicSize() + get<ESM::Light>().getDynamicSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESMStore::write(ESM::ESMWriter& writer, Loading::Listener& progress) const
|
void ESMStore::write(ESM::ESMWriter& writer, Loading::Listener& progress) const
|
||||||
@ -715,6 +715,7 @@ namespace MWWorld
|
|||||||
get<ESM::ItemLevList>().write(writer, progress);
|
get<ESM::ItemLevList>().write(writer, progress);
|
||||||
get<ESM::Creature>().write(writer, progress);
|
get<ESM::Creature>().write(writer, progress);
|
||||||
get<ESM::Container>().write(writer, progress);
|
get<ESM::Container>().write(writer, progress);
|
||||||
|
get<ESM::Light>().write(writer, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ESMStore::readRecord(ESM::ESMReader& reader, uint32_t type_id)
|
bool ESMStore::readRecord(ESM::ESMReader& reader, uint32_t type_id)
|
||||||
@ -734,6 +735,7 @@ namespace MWWorld
|
|||||||
case ESM::REC_WEAP:
|
case ESM::REC_WEAP:
|
||||||
case ESM::REC_LEVI:
|
case ESM::REC_LEVI:
|
||||||
case ESM::REC_LEVC:
|
case ESM::REC_LEVC:
|
||||||
|
case ESM::REC_LIGH:
|
||||||
mStoreImp->mRecNameToStore[type]->read(reader);
|
mStoreImp->mRecNameToStore[type]->read(reader);
|
||||||
return true;
|
return true;
|
||||||
case ESM::REC_NPC_:
|
case ESM::REC_NPC_:
|
||||||
|
@ -1589,6 +1589,13 @@
|
|||||||
-- @param openmw.core#GameObject object
|
-- @param openmw.core#GameObject object
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
|
|
||||||
|
---
|
||||||
|
-- Creates a @{#LightRecord} without adding it to the world database.
|
||||||
|
-- Use @{openmw_world#(world).createRecord} to add the record to the world.
|
||||||
|
-- @function [parent=#Light] createRecordDraft
|
||||||
|
-- @param #LightRecord light A Lua table with the fields of a LightRecord, with an optional field `template` that accepts a @{#LightRecord} as a base.
|
||||||
|
-- @return #LightRecord A strongly typed Light record.
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Returns the read-only @{#LightRecord} of a Light
|
-- Returns the read-only @{#LightRecord} of a Light
|
||||||
-- @function [parent=#Light] record
|
-- @function [parent=#Light] record
|
||||||
@ -1608,7 +1615,15 @@
|
|||||||
-- @field #number duration
|
-- @field #number duration
|
||||||
-- @field #number radius
|
-- @field #number radius
|
||||||
-- @field #number color
|
-- @field #number color
|
||||||
-- @field #boolean isCarriable
|
-- @field #boolean isCarriable True if the light can be carried by actors and appears up in their inventory.
|
||||||
|
-- @field #boolean isDynamic If true, the light will apply to actors and other moving objects
|
||||||
|
-- @field #boolean isFire True if the light acts like a fire.
|
||||||
|
-- @field #boolean isFlicker
|
||||||
|
-- @field #boolean isFlickerSlow
|
||||||
|
-- @field #boolean isNegative If true, the light will reduce light instead of increasing it.
|
||||||
|
-- @field #boolean isOffByDefault If true, the light will not emit any light or sound while placed in the world. It will still work in the inventory.
|
||||||
|
-- @field #boolean isPulse
|
||||||
|
-- @field #boolean isPulseSlow
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,7 +172,8 @@
|
|||||||
-- * @{openmw.types#MiscellaneousRecord},
|
-- * @{openmw.types#MiscellaneousRecord},
|
||||||
-- * @{openmw.types#ClothingRecord},
|
-- * @{openmw.types#ClothingRecord},
|
||||||
-- * @{openmw.types#WeaponRecord},
|
-- * @{openmw.types#WeaponRecord},
|
||||||
-- * @{openmw.types#ActivatorRecord}
|
-- * @{openmw.types#ActivatorRecord},
|
||||||
|
-- * @{openmw.types#LightRecord}
|
||||||
-- @function [parent=#world] createRecord
|
-- @function [parent=#world] createRecord
|
||||||
-- @param #any record A record to be registered in the database. Must be one of the supported types.
|
-- @param #any record A record to be registered in the database. Must be one of the supported types.
|
||||||
-- @return #any A new record added to the database. The type is the same as the input's.
|
-- @return #any A new record added to the database. The type is the same as the input's.
|
||||||
|
@ -126,7 +126,30 @@ local function testRecordStores()
|
|||||||
testRecordStore(types.NPC.races,"races")
|
testRecordStore(types.NPC.races,"races")
|
||||||
testRecordStore(types.Player.birthSigns,"birthSigns")
|
testRecordStore(types.Player.birthSigns,"birthSigns")
|
||||||
end
|
end
|
||||||
|
local function testRecordCreation()
|
||||||
|
local newLight = {
|
||||||
|
isCarriable = true,
|
||||||
|
isDynamic = true,
|
||||||
|
isFire =false,
|
||||||
|
isFlicker = false,
|
||||||
|
isFlickerSlow = false,
|
||||||
|
isNegative = false,
|
||||||
|
isOffByDefault = false,
|
||||||
|
isPulse = false,
|
||||||
|
weight = 1,
|
||||||
|
value = 10,
|
||||||
|
duration = 12,
|
||||||
|
radius = 30,
|
||||||
|
color = 5,
|
||||||
|
name = "TestLight",
|
||||||
|
model = "meshes\\marker_door.dae"
|
||||||
|
}
|
||||||
|
local draft = types.Light.createRecordDraft(newLight)
|
||||||
|
local record = world.createRecord(draft)
|
||||||
|
for key, value in pairs(newLight) do
|
||||||
|
testing.expectEqual(record[key],value)
|
||||||
|
end
|
||||||
|
end
|
||||||
local function initPlayer()
|
local function initPlayer()
|
||||||
player:teleport('', util.vector3(4096, 4096, 867.237), util.transform.identity)
|
player:teleport('', util.vector3(4096, 4096, 867.237), util.transform.identity)
|
||||||
coroutine.yield()
|
coroutine.yield()
|
||||||
@ -165,6 +188,7 @@ tests = {
|
|||||||
{'teleport', testTeleport},
|
{'teleport', testTeleport},
|
||||||
{'getGMST', testGetGMST},
|
{'getGMST', testGetGMST},
|
||||||
{'recordStores', testRecordStores},
|
{'recordStores', testRecordStores},
|
||||||
|
{'recordCreation', testRecordCreation},
|
||||||
{'mwscript', testMWScript},
|
{'mwscript', testMWScript},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user