mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-26 19:41:34 +00:00
Merge branch 'teleporting' into 'master'
A few Lua changes related to teleporting See merge request OpenMW/openmw!3246
This commit is contained in:
commit
3032b340a2
13 changed files with 55 additions and 12 deletions
|
@ -47,6 +47,7 @@ namespace MWBase
|
||||||
virtual void gameLoaded() = 0;
|
virtual void gameLoaded() = 0;
|
||||||
virtual void objectAddedToScene(const MWWorld::Ptr& ptr) = 0;
|
virtual void objectAddedToScene(const MWWorld::Ptr& ptr) = 0;
|
||||||
virtual void objectRemovedFromScene(const MWWorld::Ptr& ptr) = 0;
|
virtual void objectRemovedFromScene(const MWWorld::Ptr& ptr) = 0;
|
||||||
|
virtual void objectTeleported(const MWWorld::Ptr& ptr) = 0;
|
||||||
virtual void itemConsumed(const MWWorld::Ptr& consumable, const MWWorld::Ptr& actor) = 0;
|
virtual void itemConsumed(const MWWorld::Ptr& consumable, const MWWorld::Ptr& actor) = 0;
|
||||||
virtual void objectActivated(const MWWorld::Ptr& object, const MWWorld::Ptr& actor) = 0;
|
virtual void objectActivated(const MWWorld::Ptr& object, const MWWorld::Ptr& actor) = 0;
|
||||||
virtual void exteriorCreated(MWWorld::CellStore& cell) = 0;
|
virtual void exteriorCreated(MWWorld::CellStore& cell) = 0;
|
||||||
|
|
|
@ -22,8 +22,6 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(const OnNewGame&) const { mGlobalScripts.newGameStarted(); }
|
|
||||||
|
|
||||||
void operator()(const OnActive& event) const
|
void operator()(const OnActive& event) const
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = getPtr(event.mObject);
|
MWWorld::Ptr ptr = getPtr(event.mObject);
|
||||||
|
@ -50,6 +48,12 @@ namespace MWLua
|
||||||
scripts->setActive(false);
|
scripts->setActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void operator()(const OnTeleported& event) const
|
||||||
|
{
|
||||||
|
if (auto* scripts = getLocalScripts(event.mObject))
|
||||||
|
scripts->onTeleported();
|
||||||
|
}
|
||||||
|
|
||||||
void operator()(const OnActivate& event) const
|
void operator()(const OnActivate& event) const
|
||||||
{
|
{
|
||||||
MWWorld::Ptr obj = getPtr(event.mObject);
|
MWWorld::Ptr obj = getPtr(event.mObject);
|
||||||
|
|
|
@ -19,9 +19,6 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OnNewGame
|
|
||||||
{
|
|
||||||
};
|
|
||||||
struct OnActive
|
struct OnActive
|
||||||
{
|
{
|
||||||
ESM::RefNum mObject;
|
ESM::RefNum mObject;
|
||||||
|
@ -30,6 +27,10 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
ESM::RefNum mObject;
|
ESM::RefNum mObject;
|
||||||
};
|
};
|
||||||
|
struct OnTeleported
|
||||||
|
{
|
||||||
|
ESM::RefNum mObject;
|
||||||
|
};
|
||||||
struct OnActivate
|
struct OnActivate
|
||||||
{
|
{
|
||||||
ESM::RefNum mActor;
|
ESM::RefNum mActor;
|
||||||
|
@ -44,7 +45,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
MWWorld::CellStore& mCell;
|
MWWorld::CellStore& mCell;
|
||||||
};
|
};
|
||||||
using Event = std::variant<OnNewGame, OnActive, OnInactive, OnConsume, OnActivate, OnNewExterior>;
|
using Event = std::variant<OnActive, OnInactive, OnConsume, OnActivate, OnNewExterior, OnTeleported>;
|
||||||
|
|
||||||
void clear() { mQueue.clear(); }
|
void clear() { mQueue.clear(); }
|
||||||
void addToQueue(Event e) { mQueue.push_back(std::move(e)); }
|
void addToQueue(Event e) { mQueue.push_back(std::move(e)); }
|
||||||
|
|
|
@ -169,8 +169,8 @@ namespace MWLua
|
||||||
, mData(obj)
|
, mData(obj)
|
||||||
{
|
{
|
||||||
this->addPackage("openmw.self", sol::make_object(lua->sol(), &mData));
|
this->addPackage("openmw.self", sol::make_object(lua->sol(), &mData));
|
||||||
registerEngineHandlers(
|
registerEngineHandlers({ &mOnActiveHandlers, &mOnInactiveHandlers, &mOnConsumeHandlers, &mOnActivatedHandlers,
|
||||||
{ &mOnActiveHandlers, &mOnInactiveHandlers, &mOnConsumeHandlers, &mOnActivatedHandlers });
|
&mOnTeleportedHandlers });
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalScripts::setActive(bool active)
|
void LocalScripts::setActive(bool active)
|
||||||
|
|
|
@ -70,6 +70,7 @@ namespace MWLua
|
||||||
void setActive(bool active);
|
void setActive(bool active);
|
||||||
void onConsume(const LObject& consumable) { callEngineHandlers(mOnConsumeHandlers, consumable); }
|
void onConsume(const LObject& consumable) { callEngineHandlers(mOnConsumeHandlers, consumable); }
|
||||||
void onActivated(const LObject& actor) { callEngineHandlers(mOnActivatedHandlers, actor); }
|
void onActivated(const LObject& actor) { callEngineHandlers(mOnActivatedHandlers, actor); }
|
||||||
|
void onTeleported() { callEngineHandlers(mOnTeleportedHandlers); }
|
||||||
|
|
||||||
void applyStatsCache();
|
void applyStatsCache();
|
||||||
|
|
||||||
|
@ -81,6 +82,7 @@ namespace MWLua
|
||||||
EngineHandlerList mOnInactiveHandlers{ "onInactive" };
|
EngineHandlerList mOnInactiveHandlers{ "onInactive" };
|
||||||
EngineHandlerList mOnConsumeHandlers{ "onConsume" };
|
EngineHandlerList mOnConsumeHandlers{ "onConsume" };
|
||||||
EngineHandlerList mOnActivatedHandlers{ "onActivated" };
|
EngineHandlerList mOnActivatedHandlers{ "onActivated" };
|
||||||
|
EngineHandlerList mOnTeleportedHandlers{ "onTeleported" };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,6 +178,20 @@ namespace MWLua
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LuaManager::objectTeleported(const MWWorld::Ptr& ptr)
|
||||||
|
{
|
||||||
|
if (ptr == mPlayer)
|
||||||
|
{
|
||||||
|
// For player run the onTeleported handler immediately,
|
||||||
|
// so it can adjust camera position after teleporting.
|
||||||
|
PlayerScripts* playerScripts = dynamic_cast<PlayerScripts*>(mPlayer.getRefData().getLuaScripts());
|
||||||
|
if (playerScripts)
|
||||||
|
playerScripts->onTeleported();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mEngineEvents.addToQueue(EngineEvents::OnTeleported{ getId(ptr) });
|
||||||
|
}
|
||||||
|
|
||||||
void LuaManager::questUpdated(const ESM::RefId& questId, int stage)
|
void LuaManager::questUpdated(const ESM::RefId& questId, int stage)
|
||||||
{
|
{
|
||||||
if (mPlayer.isEmpty())
|
if (mPlayer.isEmpty())
|
||||||
|
@ -194,6 +208,14 @@ namespace MWLua
|
||||||
if (mPlayer.isEmpty())
|
if (mPlayer.isEmpty())
|
||||||
return; // The game is not started yet.
|
return; // The game is not started yet.
|
||||||
|
|
||||||
|
if (mNewGameStarted)
|
||||||
|
{
|
||||||
|
mNewGameStarted = false;
|
||||||
|
// Run onNewGame handler in synchronizedUpdate (at the beginning of the frame), so it
|
||||||
|
// can teleport the player to the starting location before the first frame is rendered.
|
||||||
|
mGlobalScripts.newGameStarted();
|
||||||
|
}
|
||||||
|
|
||||||
// We apply input events in `synchronizedUpdate` rather than in `update` in order to reduce input latency.
|
// We apply input events in `synchronizedUpdate` rather than in `update` in order to reduce input latency.
|
||||||
mProcessingInputEvents = true;
|
mProcessingInputEvents = true;
|
||||||
PlayerScripts* playerScripts = dynamic_cast<PlayerScripts*>(mPlayer.getRefData().getLuaScripts());
|
PlayerScripts* playerScripts = dynamic_cast<PlayerScripts*>(mPlayer.getRefData().getLuaScripts());
|
||||||
|
@ -237,6 +259,7 @@ namespace MWLua
|
||||||
mWorldView.clear();
|
mWorldView.clear();
|
||||||
mGlobalScripts.removeAllScripts();
|
mGlobalScripts.removeAllScripts();
|
||||||
mGlobalScriptsStarted = false;
|
mGlobalScriptsStarted = false;
|
||||||
|
mNewGameStarted = false;
|
||||||
if (!mPlayer.isEmpty())
|
if (!mPlayer.isEmpty())
|
||||||
{
|
{
|
||||||
mPlayer.getCellRef().unsetRefNum();
|
mPlayer.getCellRef().unsetRefNum();
|
||||||
|
@ -273,7 +296,7 @@ namespace MWLua
|
||||||
mInputEvents.clear();
|
mInputEvents.clear();
|
||||||
mGlobalScripts.addAutoStartedScripts();
|
mGlobalScripts.addAutoStartedScripts();
|
||||||
mGlobalScriptsStarted = true;
|
mGlobalScriptsStarted = true;
|
||||||
mEngineEvents.addToQueue(EngineEvents::OnNewGame{});
|
mNewGameStarted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::gameLoaded()
|
void LuaManager::gameLoaded()
|
||||||
|
|
|
@ -75,6 +75,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
mEngineEvents.addToQueue(EngineEvents::OnNewExterior{ cell });
|
mEngineEvents.addToQueue(EngineEvents::OnNewExterior{ cell });
|
||||||
}
|
}
|
||||||
|
void objectTeleported(const MWWorld::Ptr& ptr) override;
|
||||||
void questUpdated(const ESM::RefId& questId, int stage) override;
|
void questUpdated(const ESM::RefId& questId, int stage) override;
|
||||||
|
|
||||||
MWBase::LuaManager::ActorControls* getActorControls(const MWWorld::Ptr&) const override;
|
MWBase::LuaManager::ActorControls* getActorControls(const MWWorld::Ptr&) const override;
|
||||||
|
@ -141,6 +142,7 @@ namespace MWLua
|
||||||
bool mInitialized = false;
|
bool mInitialized = false;
|
||||||
bool mGlobalScriptsStarted = false;
|
bool mGlobalScriptsStarted = false;
|
||||||
bool mProcessingInputEvents = false;
|
bool mProcessingInputEvents = false;
|
||||||
|
bool mNewGameStarted = false;
|
||||||
LuaUtil::ScriptsConfiguration mConfiguration;
|
LuaUtil::ScriptsConfiguration mConfiguration;
|
||||||
LuaUtil::LuaState mLua;
|
LuaUtil::LuaState mLua;
|
||||||
LuaUi::ResourceManager mUiResourceManager;
|
LuaUi::ResourceManager mUiResourceManager;
|
||||||
|
|
|
@ -95,6 +95,7 @@ namespace MWLua
|
||||||
world->rotateObject(newPtr, rot);
|
world->rotateObject(newPtr, rot);
|
||||||
if (placeOnGround)
|
if (placeOnGround)
|
||||||
world->adjustPosition(newPtr, true);
|
world->adjustPosition(newPtr, true);
|
||||||
|
MWBase::Environment::get().getLuaManager()->objectTeleported(newPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void teleportNotPlayer(const MWWorld::Ptr& ptr, MWWorld::CellStore* destCell, const osg::Vec3f& pos,
|
void teleportNotPlayer(const MWWorld::Ptr& ptr, MWWorld::CellStore* destCell, const osg::Vec3f& pos,
|
||||||
|
@ -119,6 +120,7 @@ namespace MWLua
|
||||||
}
|
}
|
||||||
if (!newPtr.getRefData().isEnabled())
|
if (!newPtr.getRefData().isEnabled())
|
||||||
world->enable(newPtr);
|
world->enable(newPtr);
|
||||||
|
MWBase::Environment::get().getLuaManager()->objectTeleported(newPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ObjT>
|
template <typename ObjT>
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <components/interpreter/runtime.hpp>
|
#include <components/interpreter/runtime.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/luamanager.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
|
@ -436,6 +437,7 @@ namespace MWScript
|
||||||
|
|
||||||
bool cellActive = MWBase::Environment::get().getWorldScene()->isCellActive(*ptr.getCell());
|
bool cellActive = MWBase::Environment::get().getWorldScene()->isCellActive(*ptr.getCell());
|
||||||
ptr.getClass().adjustPosition(ptr, isPlayer || !cellActive);
|
ptr.getClass().adjustPosition(ptr, isPlayer || !cellActive);
|
||||||
|
MWBase::Environment::get().getLuaManager()->objectTeleported(ptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -492,6 +494,7 @@ namespace MWScript
|
||||||
world->rotateObject(ptr, rot);
|
world->rotateObject(ptr, rot);
|
||||||
bool cellActive = MWBase::Environment::get().getWorldScene()->isCellActive(*ptr.getCell());
|
bool cellActive = MWBase::Environment::get().getWorldScene()->isCellActive(*ptr.getCell());
|
||||||
ptr.getClass().adjustPosition(ptr, isPlayer || !cellActive);
|
ptr.getClass().adjustPosition(ptr, isPlayer || !cellActive);
|
||||||
|
MWBase::Environment::get().getLuaManager()->objectTeleported(ptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <components/esm3/loadmgef.hpp>
|
#include <components/esm3/loadmgef.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/luamanager.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
|
@ -65,7 +66,6 @@ namespace MWWorld
|
||||||
actor.getClass().getCreatureStats(actor).getAiSequence().stopCombat();
|
actor.getClass().getCreatureStats(actor).getAiSequence().stopCombat();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
teleported = world->moveObject(actor, &worldModel->getCell(mCellId), mPosition.asVec3(), true, true);
|
teleported = world->moveObject(actor, &worldModel->getCell(mCellId), mPosition.asVec3(), true, true);
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,8 @@ namespace MWWorld
|
||||||
.getCreatureStats(teleported)
|
.getCreatureStats(teleported)
|
||||||
.getActiveSpells()
|
.getActiveSpells()
|
||||||
.purgeEffect(actor, ESM::MagicEffect::WaterWalking);
|
.purgeEffect(actor, ESM::MagicEffect::WaterWalking);
|
||||||
|
|
||||||
|
MWBase::Environment::get().getLuaManager()->objectTeleported(teleported);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionTeleport::getFollowers(
|
void ActionTeleport::getFollowers(
|
||||||
|
|
|
@ -974,7 +974,6 @@ namespace MWWorld
|
||||||
removeContainerScripts(getPlayerPtr());
|
removeContainerScripts(getPlayerPtr());
|
||||||
mWorldScene->changeToInteriorCell(cellName, position, adjustPlayerPos, changeEvent);
|
mWorldScene->changeToInteriorCell(cellName, position, adjustPlayerPos, changeEvent);
|
||||||
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
|
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
|
||||||
mRendering->getCamera()->instantTransition();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::changeToCell(
|
void World::changeToCell(
|
||||||
|
@ -999,7 +998,6 @@ namespace MWWorld
|
||||||
else
|
else
|
||||||
mWorldScene->changeToInteriorCell(destinationCell->getNameId(), position, adjustPlayerPos, changeEvent);
|
mWorldScene->changeToInteriorCell(destinationCell->getNameId(), position, adjustPlayerPos, changeEvent);
|
||||||
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
|
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
|
||||||
mRendering->getCamera()->instantTransition();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float World::getMaxActivationDistance() const
|
float World::getMaxActivationDistance() const
|
||||||
|
|
|
@ -64,6 +64,8 @@ Engine handler is a function defined by a script, that can be called by the engi
|
||||||
- | Object became inactive. Since it is inactive the handler
|
- | Object became inactive. Since it is inactive the handler
|
||||||
| can not access anything nearby, but it is possible to send
|
| can not access anything nearby, but it is possible to send
|
||||||
| an event to global scripts.
|
| an event to global scripts.
|
||||||
|
* - onTeleported()
|
||||||
|
- Object was teleported.
|
||||||
* - onActivated(actor)
|
* - onActivated(actor)
|
||||||
- | Called on an object when an actor activates it. Note that picking
|
- | Called on an object when an actor activates it. Note that picking
|
||||||
| up an item is also an activation and works this way: (1) a copy of
|
| up an item is also an activation and works this way: (1) a copy of
|
||||||
|
|
|
@ -281,6 +281,9 @@ return {
|
||||||
end
|
end
|
||||||
move360.onInputAction(action)
|
move360.onInputAction(action)
|
||||||
end,
|
end,
|
||||||
|
onTeleported = function()
|
||||||
|
camera.instantTransition()
|
||||||
|
end,
|
||||||
onActive = init,
|
onActive = init,
|
||||||
onLoad = function(data)
|
onLoad = function(data)
|
||||||
if data and data.distance then third_person.baseDistance = data.distance end
|
if data and data.distance then third_person.baseDistance = data.distance end
|
||||||
|
|
Loading…
Reference in a new issue