mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-09-22 11:23:27 -04:00
Merge branch 'new_cont_crea' into 'master'
Add record creation for containers, creatures See merge request OpenMW/openmw!4869
This commit is contained in:
commit
937703cb22
@ -18,6 +18,53 @@ namespace sol
|
||||
};
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
ESM::Container tableToContainer(const sol::table& rec)
|
||||
{
|
||||
ESM::Container cont;
|
||||
|
||||
// Start from template if provided
|
||||
if (rec["template"] != sol::nil)
|
||||
cont = LuaUtil::cast<ESM::Container>(rec["template"]);
|
||||
else
|
||||
cont.blank();
|
||||
|
||||
cont.mId = {};
|
||||
|
||||
// Basic fields
|
||||
if (rec["name"] != sol::nil)
|
||||
cont.mName = rec["name"];
|
||||
if (rec["model"] != sol::nil)
|
||||
cont.mModel = Misc::ResourceHelpers::meshPathForESM3(rec["model"].get<std::string_view>());
|
||||
if (rec["mwscript"] != sol::nil)
|
||||
cont.mScript = ESM::RefId::deserializeText(rec["mwscript"].get<std::string_view>());
|
||||
if (rec["weight"] != sol::nil)
|
||||
cont.mWeight = rec["weight"].get<float>();
|
||||
|
||||
// Flags
|
||||
if (rec["isOrganic"] != sol::nil)
|
||||
{
|
||||
bool isOrganic = rec["isOrganic"];
|
||||
if (isOrganic)
|
||||
cont.mFlags |= ESM::Container::Organic;
|
||||
else
|
||||
cont.mFlags &= ~ESM::Container::Organic;
|
||||
}
|
||||
|
||||
if (rec["isRespawning"] != sol::nil)
|
||||
{
|
||||
bool isRespawning = rec["isRespawning"];
|
||||
if (isRespawning)
|
||||
cont.mFlags |= ESM::Container::Respawn;
|
||||
else
|
||||
cont.mFlags &= ~ESM::Container::Respawn;
|
||||
}
|
||||
|
||||
return cont;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWLua
|
||||
{
|
||||
|
||||
@ -35,6 +82,7 @@ namespace MWLua
|
||||
const MWWorld::Ptr& ptr = containerPtr(obj);
|
||||
return ptr.getClass().getEncumbrance(ptr);
|
||||
};
|
||||
container["createRecordDraft"] = tableToContainer;
|
||||
container["encumbrance"] = container["getEncumbrance"]; // for compatibility; should be removed later
|
||||
container["getCapacity"] = [](const Object& obj) -> float {
|
||||
const MWWorld::Ptr& ptr = containerPtr(obj);
|
||||
|
@ -10,6 +10,138 @@
|
||||
#include <components/misc/resourcehelpers.hpp>
|
||||
#include <components/resource/resourcesystem.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
ESM::Creature tableToCreature(const sol::table& rec)
|
||||
{
|
||||
ESM::Creature crea;
|
||||
|
||||
// Start from template if provided
|
||||
if (rec["template"] != sol::nil)
|
||||
crea = LuaUtil::cast<ESM::Creature>(rec["template"]);
|
||||
else
|
||||
crea.blank();
|
||||
|
||||
crea.mId = {};
|
||||
|
||||
// Basic fields
|
||||
if (rec["name"] != sol::nil)
|
||||
crea.mName = rec["name"];
|
||||
if (rec["model"] != sol::nil)
|
||||
crea.mModel = Misc::ResourceHelpers::meshPathForESM3(rec["model"].get<std::string_view>());
|
||||
if (rec["mwscript"] != sol::nil)
|
||||
crea.mScript = ESM::RefId::deserializeText(rec["mwscript"].get<std::string_view>());
|
||||
if (rec["baseCreature"] != sol::nil)
|
||||
crea.mOriginal = ESM::RefId::deserializeText(rec["baseCreature"].get<std::string_view>());
|
||||
|
||||
if (rec["soulValue"] != sol::nil)
|
||||
crea.mData.mSoul = rec["soulValue"].get<int>();
|
||||
if (rec["type"] != sol::nil)
|
||||
crea.mData.mType
|
||||
= rec["type"].get<int>();
|
||||
if (rec["baseGold"] != sol::nil)
|
||||
crea.mData.mGold = rec["baseGold"].get<int>();
|
||||
if (rec["combatSkill"] != sol::nil)
|
||||
crea.mData.mCombat = rec["combatSkill"].get<int>();
|
||||
if (rec["magicSkill"] != sol::nil)
|
||||
crea.mData.mMagic = rec["magicSkill"].get<int>();
|
||||
if (rec["stealthSkill"] != sol::nil)
|
||||
crea.mData.mStealth = rec["stealthSkill"].get<int>();
|
||||
|
||||
if (rec["attack"] != sol::nil)
|
||||
{
|
||||
const sol::table atk = rec["attack"];
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
sol::object v = atk[i + 1];
|
||||
if (v != sol::nil)
|
||||
crea.mData.mAttack[i] = v.as<int>();
|
||||
}
|
||||
}
|
||||
|
||||
if (rec["canFly"] != sol::nil)
|
||||
{
|
||||
bool canFly = rec["canFly"];
|
||||
if (canFly)
|
||||
crea.mFlags |= ESM::Creature::Flies;
|
||||
else
|
||||
crea.mFlags &= ~ESM::Creature::Flies;
|
||||
}
|
||||
|
||||
if (rec["canSwim"] != sol::nil)
|
||||
{
|
||||
bool canSwim = rec["canSwim"];
|
||||
if (canSwim)
|
||||
crea.mFlags |= ESM::Creature::Swims;
|
||||
else
|
||||
crea.mFlags &= ~ESM::Creature::Swims;
|
||||
}
|
||||
|
||||
if (rec["canUseWeapons"] != sol::nil)
|
||||
{
|
||||
bool canUseWeapons = rec["canUseWeapons"];
|
||||
if (canUseWeapons)
|
||||
crea.mFlags |= ESM::Creature::Weapon;
|
||||
else
|
||||
crea.mFlags &= ~ESM::Creature::Weapon;
|
||||
}
|
||||
|
||||
if (rec["canWalk"] != sol::nil)
|
||||
{
|
||||
bool canWalk = rec["canWalk"];
|
||||
if (canWalk)
|
||||
crea.mFlags |= ESM::Creature::Walks;
|
||||
else
|
||||
crea.mFlags &= ~ESM::Creature::Walks;
|
||||
}
|
||||
|
||||
if (rec["isBiped"] != sol::nil)
|
||||
{
|
||||
bool isBiped = rec["isBiped"];
|
||||
if (isBiped)
|
||||
crea.mFlags |= ESM::Creature::Bipedal;
|
||||
else
|
||||
crea.mFlags &= ~ESM::Creature::Bipedal;
|
||||
}
|
||||
|
||||
if (rec["isEssential"] != sol::nil)
|
||||
{
|
||||
bool isEssential = rec["isEssential"];
|
||||
if (isEssential)
|
||||
crea.mFlags |= ESM::Creature::Essential;
|
||||
else
|
||||
crea.mFlags &= ~ESM::Creature::Essential;
|
||||
}
|
||||
|
||||
if (rec["isRespawning"] != sol::nil)
|
||||
{
|
||||
bool isRespawning = rec["isRespawning"];
|
||||
if (isRespawning)
|
||||
crea.mFlags |= ESM::Creature::Respawn;
|
||||
else
|
||||
crea.mFlags &= ~ESM::Creature::Respawn;
|
||||
}
|
||||
|
||||
if (rec["bloodType"] != sol::nil)
|
||||
crea.mBloodType = rec["bloodType"].get<int>();
|
||||
|
||||
if (rec["servicesOffered"] != sol::nil)
|
||||
{
|
||||
const sol::table services = rec["servicesOffered"];
|
||||
int flags = 0;
|
||||
for (const auto& [mask, key] : MWLua::ServiceNames)
|
||||
{
|
||||
sol::object value = services[key];
|
||||
if (value != sol::nil && value.as<bool>())
|
||||
flags |= mask;
|
||||
}
|
||||
crea.mAiData.mServices = flags;
|
||||
}
|
||||
|
||||
return crea;
|
||||
}
|
||||
}
|
||||
|
||||
namespace sol
|
||||
{
|
||||
template <>
|
||||
@ -30,6 +162,7 @@ namespace MWLua
|
||||
{ "Undead", ESM::Creature::Undead },
|
||||
{ "Humanoid", ESM::Creature::Humanoid },
|
||||
}));
|
||||
creature["createRecordDraft"] = tableToCreature;
|
||||
|
||||
addRecordFunctionBinding<ESM::Creature>(creature, context);
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <components/esm3/loadarmo.hpp>
|
||||
#include <components/esm3/loadbook.hpp>
|
||||
#include <components/esm3/loadclot.hpp>
|
||||
#include <components/esm3/loadcrea.hpp>
|
||||
#include <components/esm3/loadcont.hpp>
|
||||
#include <components/esm3/loadligh.hpp>
|
||||
#include <components/esm3/loadmisc.hpp>
|
||||
#include <components/esm3/loadnpc.hpp>
|
||||
@ -197,6 +199,22 @@ namespace MWLua
|
||||
copy.mId = {};
|
||||
return MWBase::Environment::get().getESMStore()->insert(copy);
|
||||
},
|
||||
[lua = context.mLua](const ESM::Creature& crea) -> const ESM::Creature* {
|
||||
checkGameInitialized(lua);
|
||||
if (crea.mId.empty())
|
||||
return MWBase::Environment::get().getESMStore()->insert(crea);
|
||||
ESM::Creature copy = crea;
|
||||
copy.mId = {};
|
||||
return MWBase::Environment::get().getESMStore()->insert(copy);
|
||||
},
|
||||
[lua = context.mLua](const ESM::Container& cont) -> const ESM::Container* {
|
||||
checkGameInitialized(lua);
|
||||
if (cont.mId.empty())
|
||||
return MWBase::Environment::get().getESMStore()->insert(cont);
|
||||
ESM::Container copy = cont;
|
||||
copy.mId = {};
|
||||
return MWBase::Environment::get().getESMStore()->insert(copy);
|
||||
},
|
||||
[lua = context.mLua](const ESM::Weapon& weapon) -> const ESM::Weapon* {
|
||||
checkGameInitialized(lua);
|
||||
return MWBase::Environment::get().getESMStore()->insert(weapon);
|
||||
|
@ -806,6 +806,18 @@
|
||||
-- @extends #Actor
|
||||
-- @field #Actor baseType @{#Actor}
|
||||
|
||||
---
|
||||
-- Creates a @{#CreatureRecord} without adding it to the world database.
|
||||
-- Use @{openmw_world#(world).createRecord} to add the record to the world.
|
||||
-- @function [parent=#Creature] createRecordDraft
|
||||
-- @param #CreatureRecord creature A Lua table with the fields of a CreatureRecord, with an additional field `template` that accepts a @{#CreatureRecord} as a base.
|
||||
-- @return #CreatureRecord A strongly typed Creature record.
|
||||
-- @usage local creatureTemplate = types.Creature.records['mudcrab']
|
||||
-- local creatureTable = {name = "Epic Mudcrab", template = creatureTemplate, soulValue = 500, isEssential = true}
|
||||
-- local recordDraft = types.Creature.createRecordDraft(creatureTable)
|
||||
-- local newRecord = world.createRecord(recordDraft)
|
||||
-- world.createObject(newRecord.id):teleport(playerCell, playerPosition)
|
||||
|
||||
---
|
||||
-- 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.
|
||||
@ -2194,6 +2206,18 @@
|
||||
-- @param openmw.core#GameObject object
|
||||
-- @return openmw.core#Inventory
|
||||
|
||||
---
|
||||
-- Creates a @{#ContainerRecord} without adding it to the world database.
|
||||
-- Use @{openmw_world#(world).createRecord} to add the record to the world.
|
||||
-- @function [parent=#Container] createRecordDraft
|
||||
-- @param #ContainerRecord container A Lua table with the fields of a ContainerRecord, with an additional field `template` that accepts a @{#ContainerRecord} as a base.
|
||||
-- @return #ContainerRecord A strongly typed Container record.
|
||||
-- @usage local chestTemplate = types.Container.records['chest_small_01']
|
||||
-- local containerTable = {name = "Respawning Treasure Chest", template = chestTemplate, isRespawning = true, weight = 150.0}
|
||||
-- local recordDraft = types.Container.createRecordDraft(containerTable)
|
||||
-- local newRecord = world.createRecord(recordDraft)
|
||||
-- world.createObject(newRecord.id):moveInto(playerCell)
|
||||
|
||||
---
|
||||
-- Container content (same as `Container.content`, added for consistency with `Actor.inventory`).
|
||||
-- @function [parent=#Container] inventory
|
||||
|
@ -177,7 +177,10 @@
|
||||
-- * @{openmw.types#ClothingRecord},
|
||||
-- * @{openmw.types#WeaponRecord},
|
||||
-- * @{openmw.types#ActivatorRecord},
|
||||
-- * @{openmw.types#LightRecord}
|
||||
-- * @{openmw.types#LightRecord},
|
||||
-- * @{openmw.types#NpcRecord},
|
||||
-- * @{openmw.types#ContainerRecord},
|
||||
-- * @{openmw.types#CreatureRecord}
|
||||
-- @function [parent=#world] createRecord
|
||||
-- @param #any record A record to be registered in the database. Must be one of the supported types. The id field is not used, one will be generated for you.
|
||||
-- @return #any A new record added to the database. The type is the same as the input's.
|
||||
|
Loading…
x
Reference in New Issue
Block a user