mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 17:59:56 +00:00
Initial Lua bindings for ESM4 types; bindings for ESM4Door.
This commit is contained in:
parent
16845aa38e
commit
00beb06391
8 changed files with 196 additions and 14 deletions
|
@ -1,6 +1,7 @@
|
|||
#include "types.hpp"
|
||||
|
||||
#include <components/esm3/loaddoor.hpp>
|
||||
#include <components/esm4/loaddoor.hpp>
|
||||
#include <components/misc/resourcehelpers.hpp>
|
||||
#include <components/resource/resourcesystem.hpp>
|
||||
|
||||
|
@ -15,6 +16,11 @@ namespace sol
|
|||
struct is_automagical<ESM::Door> : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_automagical<ESM4::Door> : std::false_type
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
namespace MWLua
|
||||
|
@ -25,6 +31,11 @@ namespace MWLua
|
|||
return verifyType(ESM::REC_DOOR, o.ptr());
|
||||
}
|
||||
|
||||
static const MWWorld::Ptr& door4Ptr(const Object& o)
|
||||
{
|
||||
return verifyType(ESM::REC_DOOR4, o.ptr());
|
||||
}
|
||||
|
||||
void addDoorBindings(sol::table door, const Context& context)
|
||||
{
|
||||
door["isTeleport"] = [](const Object& o) { return doorPtr(o).getCellRef().getTeleport(); };
|
||||
|
@ -62,4 +73,34 @@ namespace MWLua
|
|||
[](const ESM::Door& rec) -> std::string { return rec.mCloseSound.serializeText(); });
|
||||
}
|
||||
|
||||
void addESM4DoorBindings(sol::table door, const Context& context)
|
||||
{
|
||||
door["isTeleport"] = [](const Object& o) { return door4Ptr(o).getCellRef().getTeleport(); };
|
||||
door["destPosition"]
|
||||
= [](const Object& o) -> osg::Vec3f { return door4Ptr(o).getCellRef().getDoorDest().asVec3(); };
|
||||
door["destRotation"]
|
||||
= [](const Object& o) -> osg::Vec3f { return door4Ptr(o).getCellRef().getDoorDest().asRotationVec3(); };
|
||||
door["destCell"] = [](sol::this_state lua, const Object& o) -> sol::object {
|
||||
const MWWorld::CellRef& cellRef = door4Ptr(o).getCellRef();
|
||||
if (!cellRef.getTeleport())
|
||||
return sol::nil;
|
||||
MWWorld::CellStore* cell = MWBase::Environment::get().getWorldModel()->getCell(cellRef.getDestCell());
|
||||
assert(cell);
|
||||
return o.getCell(lua, cell);
|
||||
};
|
||||
|
||||
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
||||
|
||||
addRecordFunctionBinding<ESM4::Door>(door, context, "ESM4Door");
|
||||
|
||||
sol::usertype<ESM4::Door> record = context.mLua->sol().new_usertype<ESM4::Door>("ESM4_Door");
|
||||
record[sol::meta_function::to_string]
|
||||
= [](const ESM4::Door& rec) -> std::string { return "ESM4_Door[" + rec.mId.toDebugString() + "]"; };
|
||||
record["id"]
|
||||
= sol::readonly_property([](const ESM4::Door& rec) -> std::string { return rec.mId.serializeText(); });
|
||||
record["name"] = sol::readonly_property([](const ESM4::Door& rec) -> std::string { return rec.mFullName; });
|
||||
record["model"] = sol::readonly_property([vfs](const ESM4::Door& rec) -> std::string {
|
||||
return Misc::ResourceHelpers::correctMeshPath(rec.mModel, vfs);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,20 @@ namespace MWLua
|
|||
constexpr std::string_view Probe = "Probe";
|
||||
constexpr std::string_view Repair = "Repair";
|
||||
constexpr std::string_view Marker = "Marker";
|
||||
|
||||
constexpr std::string_view ESM4Activator = "ESM4Activator";
|
||||
constexpr std::string_view ESM4Ammunition = "ESM4Ammunition";
|
||||
constexpr std::string_view ESM4Armor = "ESM4Armor";
|
||||
constexpr std::string_view ESM4Book = "ESM4Book";
|
||||
constexpr std::string_view ESM4Clothing = "ESM4Clothing";
|
||||
constexpr std::string_view ESM4Container = "ESM4Container";
|
||||
constexpr std::string_view ESM4Door = "ESM4Door";
|
||||
constexpr std::string_view ESM4Ingredient = "ESM4Ingredient";
|
||||
constexpr std::string_view ESM4Light = "ESM4Light";
|
||||
constexpr std::string_view ESM4MiscItem = "ESM4Miscellaneous";
|
||||
constexpr std::string_view ESM4Potion = "ESM4Potion";
|
||||
constexpr std::string_view ESM4Static = "ESM4Static";
|
||||
constexpr std::string_view ESM4Weapon = "ESM4Weapon";
|
||||
}
|
||||
|
||||
namespace
|
||||
|
@ -57,6 +71,20 @@ namespace MWLua
|
|||
{ ESM::REC_LOCK, ObjectTypeName::Lockpick },
|
||||
{ ESM::REC_PROB, ObjectTypeName::Probe },
|
||||
{ ESM::REC_REPA, ObjectTypeName::Repair },
|
||||
|
||||
{ ESM::REC_ACTI4, ObjectTypeName::ESM4Activator },
|
||||
{ ESM::REC_AMMO4, ObjectTypeName::ESM4Ammunition },
|
||||
{ ESM::REC_ARMO4, ObjectTypeName::ESM4Armor },
|
||||
{ ESM::REC_BOOK4, ObjectTypeName::ESM4Book },
|
||||
{ ESM::REC_CLOT4, ObjectTypeName::ESM4Clothing },
|
||||
{ ESM::REC_CONT4, ObjectTypeName::ESM4Container },
|
||||
{ ESM::REC_DOOR4, ObjectTypeName::ESM4Door },
|
||||
{ ESM::REC_INGR4, ObjectTypeName::ESM4Ingredient },
|
||||
{ ESM::REC_LIGH4, ObjectTypeName::ESM4Light },
|
||||
{ ESM::REC_MISC4, ObjectTypeName::ESM4MiscItem },
|
||||
{ ESM::REC_ALCH4, ObjectTypeName::ESM4Potion },
|
||||
{ ESM::REC_STAT4, ObjectTypeName::ESM4Static },
|
||||
{ ESM::REC_WEAP4, ObjectTypeName::ESM4Weapon },
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -175,6 +203,20 @@ namespace MWLua
|
|||
addDoorBindings(addType(ObjectTypeName::Door, { ESM::REC_DOOR }), context);
|
||||
addStaticBindings(addType(ObjectTypeName::Static, { ESM::REC_STAT }), context);
|
||||
|
||||
addType(ObjectTypeName::ESM4Activator, { ESM::REC_ACTI4 });
|
||||
addType(ObjectTypeName::ESM4Ammunition, { ESM::REC_AMMO4 });
|
||||
addType(ObjectTypeName::ESM4Armor, { ESM::REC_ARMO4 });
|
||||
addType(ObjectTypeName::ESM4Book, { ESM::REC_BOOK4 });
|
||||
addType(ObjectTypeName::ESM4Clothing, { ESM::REC_CLOT4 });
|
||||
addType(ObjectTypeName::ESM4Container, { ESM::REC_CONT4 });
|
||||
addESM4DoorBindings(addType(ObjectTypeName::ESM4Door, { ESM::REC_DOOR4 }), context);
|
||||
addType(ObjectTypeName::ESM4Ingredient, { ESM::REC_INGR4 });
|
||||
addType(ObjectTypeName::ESM4Light, { ESM::REC_LIGH4 });
|
||||
addType(ObjectTypeName::ESM4MiscItem, { ESM::REC_MISC4 });
|
||||
addType(ObjectTypeName::ESM4Potion, { ESM::REC_ALCH4 });
|
||||
addType(ObjectTypeName::ESM4Static, { ESM::REC_STAT4 });
|
||||
addType(ObjectTypeName::ESM4Weapon, { ESM::REC_WEAP4 });
|
||||
|
||||
sol::table typeToPackage = getTypeToPackageTable(context.mLua->sol());
|
||||
sol::table packageToType = getPackageToTypeTable(context.mLua->sol());
|
||||
for (const auto& [type, name] : luaObjectTypeInfo)
|
||||
|
|
|
@ -63,8 +63,11 @@ namespace MWLua
|
|||
void addStaticBindings(sol::table stat, const Context& context);
|
||||
void addLightBindings(sol::table light, const Context& context);
|
||||
|
||||
void addESM4DoorBindings(sol::table door, const Context& context);
|
||||
|
||||
template <class T>
|
||||
void addRecordFunctionBinding(sol::table table, const Context& context)
|
||||
void addRecordFunctionBinding(
|
||||
sol::table table, const Context& context, const std::string& recordName = std::string(T::getRecordType()))
|
||||
{
|
||||
const MWWorld::Store<T>& store = MWBase::Environment::get().getWorld()->getStore().get<T>();
|
||||
|
||||
|
@ -75,9 +78,9 @@ namespace MWLua
|
|||
// 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>(std::string(T::getRecordType()) + "WorldStore");
|
||||
storeT[sol::meta_function::to_string] = [](const StoreT& store) {
|
||||
return "{" + std::to_string(store.getSize()) + " " + std::string(T::getRecordType()) + " records}";
|
||||
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* {
|
||||
|
|
|
@ -3,10 +3,15 @@
|
|||
#include <cassert>
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/esm/refid.hpp>
|
||||
#include <components/esm3/loadcell.hpp>
|
||||
#include <components/esm3/objectstate.hpp>
|
||||
#include <components/esm4/loadrefr.hpp>
|
||||
|
||||
#include <apps/openmw/mwbase/environment.hpp>
|
||||
#include <apps/openmw/mwbase/world.hpp>
|
||||
#include <apps/openmw/mwworld/cellutils.hpp>
|
||||
#include <apps/openmw/mwworld/esmstore.hpp>
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
|
@ -90,13 +95,18 @@ namespace MWWorld
|
|||
return ESM::RefId::esm3ExteriorCell(index.x(), index.y());
|
||||
}
|
||||
};
|
||||
auto esm4Visit = [&](const ESM4::Reference& ref) -> ESM::RefId {
|
||||
if (ref.mDoor.destDoor.isZeroOrUnset())
|
||||
return ESM::RefId::sEmpty;
|
||||
const ESM4::Reference* refDest
|
||||
= MWBase::Environment::get().getWorld()->getStore().get<ESM4::Reference>().searchStatic(
|
||||
ESM::FormIdRefId(ref.mDoor.destDoor));
|
||||
if (refDest)
|
||||
return refDest->mParent;
|
||||
return ESM::RefId::sEmpty;
|
||||
};
|
||||
|
||||
return std::visit(
|
||||
ESM::VisitOverload{
|
||||
[&](const ESM4::Reference& ref) -> ESM::RefId { return ESM::RefId::sEmpty; },
|
||||
esm3Visit,
|
||||
},
|
||||
mCellRef.mVariant);
|
||||
return std::visit(ESM::VisitOverload{ esm3Visit, esm4Visit }, mCellRef.mVariant);
|
||||
}
|
||||
|
||||
void CellRef::setScale(float scale)
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace MWWorld
|
|||
struct Visitor
|
||||
{
|
||||
bool operator()(const ESM::CellRef& ref) { return ref.mTeleport; }
|
||||
bool operator()(const ESM4::Reference& ref) { return 0; }
|
||||
bool operator()(const ESM4::Reference& ref) { return !ref.mDoor.destDoor.isZeroOrUnset(); }
|
||||
};
|
||||
return std::visit(Visitor(), mCellRef.mVariant);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@ namespace ESM
|
|||
bool hasContentFile() const { return mContentFile >= 0; }
|
||||
bool isSet() const { return mIndex != 0 || mContentFile != -1; }
|
||||
|
||||
// Used in ESM4 as a null reference
|
||||
bool isZero() const { return mIndex == 0 && mContentFile == 0; }
|
||||
// Zero is used in ESM4 as a null reference
|
||||
bool isZeroOrUnset() const { return mIndex == 0 && (mContentFile == 0 || mContentFile == -1); }
|
||||
|
||||
std::string toString() const;
|
||||
FormId32 toUint32() const;
|
||||
|
|
|
@ -213,7 +213,7 @@ void ESM4::Land::load(ESM4::Reader& reader)
|
|||
bool missing = false;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
if (mTextures[i].base.formId.isZero())
|
||||
if (mTextures[i].base.formId.isZeroOrUnset())
|
||||
{
|
||||
// std::cout << "ESM4::LAND " << ESM4::formIdToString(mFormId) << " missing base, quad " << i << std::endl;
|
||||
// std::cout << "layers " << mTextures[i].layers.size() << std::endl;
|
||||
|
|
|
@ -1223,4 +1223,90 @@
|
|||
-- @field #string id Record id
|
||||
-- @field #string model VFS path to the model
|
||||
|
||||
--- Functions for @{#ESM4Activator} objects
|
||||
-- @field [parent=#types] #ESM4Activator ESM4Activator
|
||||
|
||||
--- Functions for @{#ESM4Ammunition} objects
|
||||
-- @field [parent=#types] #ESM4Ammunition ESM4Ammunition
|
||||
|
||||
--- Functions for @{#ESM4Armor} objects
|
||||
-- @field [parent=#types] #ESM4Armor ESM4Armor
|
||||
|
||||
--- Functions for @{#ESM4Book} objects
|
||||
-- @field [parent=#types] #ESM4Book ESM4Book
|
||||
|
||||
--- Functions for @{#ESM4Clothing} objects
|
||||
-- @field [parent=#types] #ESM4Clothing ESM4Clothing
|
||||
|
||||
--- Functions for @{#ESM4Door} objects
|
||||
-- @field [parent=#types] #ESM4Door ESM4Door
|
||||
|
||||
--- Functions for @{#ESM4Ingredient} objects
|
||||
-- @field [parent=#types] #ESM4Ingredient ESM4Ingredient
|
||||
|
||||
--- Functions for @{#ESM4Light} objects
|
||||
-- @field [parent=#types] #ESM4Light ESM4Light
|
||||
|
||||
--- Functions for @{#ESM4Miscellaneous} objects
|
||||
-- @field [parent=#types] #ESM4Miscellaneous ESM4Miscellaneous
|
||||
|
||||
--- Functions for @{#ESM4Potion} objects
|
||||
-- @field [parent=#types] #ESM4Potion ESM4Potion
|
||||
|
||||
--- Functions for @{#ESM4Static} objects
|
||||
-- @field [parent=#types] #ESM4Static ESM4Static
|
||||
|
||||
--- Functions for @{#ESM4Weapon} objects
|
||||
-- @field [parent=#types] #ESM4Weapon ESM4Weapon
|
||||
|
||||
---
|
||||
-- @type ESM4Door
|
||||
|
||||
---
|
||||
-- Whether the object is a ESM4Door.
|
||||
-- @function [parent=#ESM4Door] objectIsInstance
|
||||
-- @param openmw.core#GameObject object
|
||||
-- @return #boolean
|
||||
|
||||
---
|
||||
-- Whether the door is a teleport.
|
||||
-- @function [parent=#ESM4Door] isTeleport
|
||||
-- @param openmw.core#GameObject object
|
||||
-- @return #boolean
|
||||
|
||||
---
|
||||
-- Destination (only if a teleport door).
|
||||
-- @function [parent=#ESM4Door] destPosition
|
||||
-- @param openmw.core#GameObject object
|
||||
-- @return openmw.util#Vector3
|
||||
|
||||
---
|
||||
-- Destination rotation (only if a teleport door).
|
||||
-- @function [parent=#ESM4Door] destRotation
|
||||
-- @param openmw.core#GameObject object
|
||||
-- @return openmw.util#Vector3
|
||||
|
||||
---
|
||||
-- Destination cell (only if a teleport door).
|
||||
-- @function [parent=#ESM4Door] destCell
|
||||
-- @param openmw.core#GameObject object
|
||||
-- @return openmw.core#Cell
|
||||
|
||||
---
|
||||
-- Returns the read-only @{#ESM4DoorRecord} of a door
|
||||
-- @function [parent=#ESM4Door] record
|
||||
-- @param #any objectOrRecordId
|
||||
-- @return #ESM4DoorRecord
|
||||
|
||||
---
|
||||
-- Returns a read-only list of all @{#ESM4DoorRecord}s in the world database.
|
||||
-- @function [parent=#ESM4Door] records
|
||||
-- @return #list<#ESM4DoorRecord>
|
||||
|
||||
---
|
||||
-- @type ESM4DoorRecord
|
||||
-- @field #string id Record id
|
||||
-- @field #string name Human-readable name
|
||||
-- @field #string model VFS path to the model
|
||||
|
||||
return nil
|
||||
|
|
Loading…
Reference in a new issue