mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-30 15:11:38 +00:00
put land bindings in a table in openmw.core
This commit is contained in:
parent
336275292e
commit
8917103bf3
4 changed files with 168 additions and 11 deletions
|
@ -62,7 +62,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 dialoguebindings
|
||||
postprocessingbindings stats recordstore debugbindings corebindings worldbindings worker magicbindings factionbindings
|
||||
postprocessingbindings stats recordstore debugbindings corebindings worldbindings worker landbindings 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
|
||||
|
|
|
@ -2,20 +2,10 @@
|
|||
|
||||
#include <chrono>
|
||||
#include <stdexcept>
|
||||
#include <tuple>
|
||||
|
||||
#include <sol/object.hpp>
|
||||
|
||||
#include <apps/openmw/mwlua/object.hpp>
|
||||
#include <apps/openmw/mwworld/cellstore.hpp>
|
||||
#include <apps/openmw/mwworld/worldmodel.hpp>
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/esm3/landrecorddata.hpp>
|
||||
#include <components/esm3/loadfact.hpp>
|
||||
#include <components/esm3/loadland.hpp>
|
||||
#include <components/esm3/loadltex.hpp>
|
||||
#include <components/esmterrain/storage.hpp>
|
||||
#include <components/lua/l10n.hpp>
|
||||
#include <components/lua/luastate.hpp>
|
||||
#include <components/lua/serialization.hpp>
|
||||
|
@ -32,6 +22,7 @@
|
|||
|
||||
#include "dialoguebindings.hpp"
|
||||
#include "factionbindings.hpp"
|
||||
#include "landbindings.hpp"
|
||||
#include "luaevents.hpp"
|
||||
#include "magicbindings.hpp"
|
||||
#include "soundbindings.hpp"
|
||||
|
@ -108,6 +99,8 @@ namespace MWLua
|
|||
api["stats"]
|
||||
= context.cachePackage("openmw_core_stats", [context]() { return initCoreStatsBindings(context); });
|
||||
|
||||
api["land"] = context.cachePackage("openmw_core_land", [context]() { return initCoreLandBindings(context); });
|
||||
|
||||
api["factions"]
|
||||
= context.cachePackage("openmw_core_factions", [context]() { return initCoreFactionBindings(context); });
|
||||
api["dialogue"]
|
||||
|
|
153
apps/openmw/mwlua/landbindings.cpp
Normal file
153
apps/openmw/mwlua/landbindings.cpp
Normal file
|
@ -0,0 +1,153 @@
|
|||
#include "landbindings.hpp"
|
||||
|
||||
#include <apps/openmw/mwlua/object.hpp>
|
||||
#include <apps/openmw/mwworld/cellstore.hpp>
|
||||
#include <apps/openmw/mwworld/worldmodel.hpp>
|
||||
|
||||
#include <components/esmterrain/storage.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
|
||||
namespace MWLua
|
||||
{
|
||||
sol::table initCoreLandBindings(const Context& context)
|
||||
{
|
||||
sol::state_view& lua = context.mLua->sol();
|
||||
sol::table landApi(lua, sol::create);
|
||||
|
||||
// Constants
|
||||
landApi["RANGE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, ESM::RangeType>({
|
||||
{ "Self", ESM::RT_Self },
|
||||
{ "Touch", ESM::RT_Touch },
|
||||
{ "Target", ESM::RT_Target },
|
||||
}));
|
||||
|
||||
landApi["getHeightAt"] = [](const osg::Vec3f& pos, sol::object cellOrName) {
|
||||
ESM::RefId worldspace;
|
||||
if (cellOrName.is<GCell>())
|
||||
worldspace = cellOrName.as<GCell>().mStore->getCell()->getWorldSpace();
|
||||
else if (cellOrName.is<std::string_view>() && !cellOrName.as<std::string_view>().empty())
|
||||
worldspace = MWBase::Environment::get()
|
||||
.getWorldModel()
|
||||
->getCell(cellOrName.as<std::string_view>())
|
||||
.getCell()
|
||||
->getWorldSpace();
|
||||
else
|
||||
worldspace = ESM::Cell::sDefaultWorldspaceId;
|
||||
|
||||
const float cellSize = ESM::getCellSize(worldspace);
|
||||
int cellX = static_cast<int>(std::floor(pos.x() / cellSize));
|
||||
int cellY = static_cast<int>(std::floor(pos.y() / cellSize));
|
||||
|
||||
auto store = MWBase::Environment::get().getESMStore();
|
||||
auto landStore = store->get<ESM::Land>();
|
||||
auto land = landStore.search(cellX, cellY);
|
||||
const ESM::Land::LandData* landData = nullptr;
|
||||
if (land != nullptr)
|
||||
{
|
||||
landData = land->getLandData(ESM::Land::DATA_VHGT);
|
||||
if (landData != nullptr)
|
||||
{
|
||||
// Ensure data is loaded if necessary
|
||||
land->loadData(ESM::Land::DATA_VHGT);
|
||||
landData = land->getLandData(ESM::Land::DATA_VHGT);
|
||||
}
|
||||
}
|
||||
if (landData == nullptr)
|
||||
{
|
||||
// If we failed to load data, return the default height
|
||||
return static_cast<float>(ESM::Land::DEFAULT_HEIGHT);
|
||||
}
|
||||
return ESMTerrain::Storage::getHeightAt(landData->mHeights, landData->sLandSize, pos, cellSize);
|
||||
};
|
||||
|
||||
landApi["getLandTextureAt"] = [lua = context.mLua](const osg::Vec3f& pos, sol::object cellOrName) {
|
||||
sol::variadic_results values;
|
||||
ESM::RefId worldspace;
|
||||
if (cellOrName.is<GCell>())
|
||||
worldspace = cellOrName.as<GCell>().mStore->getCell()->getWorldSpace();
|
||||
else if (cellOrName.is<std::string_view>() && !cellOrName.as<std::string_view>().empty())
|
||||
worldspace = MWBase::Environment::get()
|
||||
.getWorldModel()
|
||||
->getCell(cellOrName.as<std::string_view>())
|
||||
.getCell()
|
||||
->getWorldSpace();
|
||||
else
|
||||
worldspace = ESM::Cell::sDefaultWorldspaceId;
|
||||
|
||||
const float cellSize = ESM::getCellSize(worldspace);
|
||||
|
||||
int cellX = static_cast<int>(std::floor(pos.x() / cellSize));
|
||||
int cellY = static_cast<int>(std::floor(pos.y() / cellSize));
|
||||
|
||||
auto store = MWBase::Environment::get().getESMStore();
|
||||
// We need to read land twice. Once to get the amount of texture samples per cell edge, and the second time
|
||||
// to get the actual data
|
||||
auto landStore = store->get<ESM::Land>();
|
||||
auto land = landStore.search(cellX, cellY);
|
||||
const ESM::Land::LandData* landData = nullptr;
|
||||
if (land != nullptr)
|
||||
{
|
||||
landData = land->getLandData(ESM::Land::DATA_VTEX);
|
||||
if (landData != nullptr)
|
||||
{
|
||||
// Ensure data is loaded if necessary
|
||||
land->loadData(ESM::Land::DATA_VTEX);
|
||||
landData = land->getLandData(ESM::Land::DATA_VTEX);
|
||||
}
|
||||
}
|
||||
if (landData == nullptr)
|
||||
{
|
||||
// If we fail to preload land data, return, we need to be able to get *any* land to know how to correct
|
||||
// the position used to sample terrain
|
||||
return values;
|
||||
}
|
||||
|
||||
const osg::Vec3f correctedPos
|
||||
= ESMTerrain::Storage::getTextureCorrectedWorldPos(pos, landData->sLandTextureSize, cellSize);
|
||||
int correctedCellX = static_cast<int>(std::floor(correctedPos.x() / cellSize));
|
||||
int correctedCellY = static_cast<int>(std::floor(correctedPos.y() / cellSize));
|
||||
auto correctedLand = landStore.search(correctedCellX, correctedCellY);
|
||||
const ESM::Land::LandData* correctedLandData = nullptr;
|
||||
if (correctedLand != nullptr)
|
||||
{
|
||||
correctedLandData = correctedLand->getLandData(ESM::Land::DATA_VTEX);
|
||||
if (correctedLandData != nullptr)
|
||||
{
|
||||
// Ensure data is loaded if necessary
|
||||
land->loadData(ESM::Land::DATA_VTEX);
|
||||
correctedLandData = correctedLand->getLandData(ESM::Land::DATA_VTEX);
|
||||
}
|
||||
}
|
||||
if (correctedLandData == nullptr)
|
||||
{
|
||||
return values;
|
||||
}
|
||||
|
||||
// We're passing in sLandTextureSize, NOT sLandSize like with getHeightAt
|
||||
const ESMTerrain::UniqueTextureId textureId
|
||||
= ESMTerrain::Storage::getLandTextureAt(correctedLandData->mTextures, correctedLand->getPlugin(),
|
||||
correctedLandData->sLandTextureSize, correctedPos, cellSize);
|
||||
|
||||
// Need to check for 0, 0 so that we can safely subtract 1 later, as per documentation on UniqueTextureId
|
||||
if (textureId.first != 0)
|
||||
{
|
||||
values.push_back(sol::make_object<uint16_t>(lua->sol(), textureId.first - 1));
|
||||
values.push_back(sol::make_object<int>(lua->sol(), textureId.second));
|
||||
|
||||
auto textureStore = store->get<ESM::LandTexture>();
|
||||
const std::string* textureString = textureStore.search(textureId.first - 1, textureId.second);
|
||||
if (textureString)
|
||||
{
|
||||
values.push_back(sol::make_object<std::string>(lua->sol(), *textureString));
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
};
|
||||
|
||||
return LuaUtil::makeReadOnly(landApi);
|
||||
}
|
||||
}
|
11
apps/openmw/mwlua/landbindings.hpp
Normal file
11
apps/openmw/mwlua/landbindings.hpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef MWLUA_LANDBINDINGS_H
|
||||
#define MWLUA_LANDBINDINGS_H
|
||||
|
||||
#include "context.hpp"
|
||||
|
||||
namespace MWLua
|
||||
{
|
||||
sol::table initCoreLandBindings(const Context& context);
|
||||
}
|
||||
|
||||
#endif // MWLUA_LANDBINDINGS_H
|
Loading…
Reference in a new issue