mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-30 07:21:12 +00:00
Make loaded but inactive objects available in Lua scripts.
This commit is contained in:
parent
403d31313c
commit
1268597676
@ -31,6 +31,8 @@ namespace MWBase
|
|||||||
virtual void newGameStarted() = 0;
|
virtual void newGameStarted() = 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 registerObject(const MWWorld::Ptr& ptr) = 0;
|
||||||
|
virtual void deregisterObject(const MWWorld::Ptr& ptr) = 0;
|
||||||
virtual void keyPressed(const SDL_KeyboardEvent &arg) = 0;
|
virtual void keyPressed(const SDL_KeyboardEvent &arg) = 0;
|
||||||
|
|
||||||
struct ActorControls {
|
struct ActorControls {
|
||||||
|
@ -134,6 +134,7 @@ namespace MWLua
|
|||||||
scripts->processTimers(seconds, hours);
|
scripts->processTimers(seconds, hours);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Receive events
|
||||||
for (GlobalEvent& e : globalEvents)
|
for (GlobalEvent& e : globalEvents)
|
||||||
mGlobalScripts.receiveEvent(e.eventName, e.eventData);
|
mGlobalScripts.receiveEvent(e.eventName, e.eventData);
|
||||||
for (LocalEvent& e : localEvents)
|
for (LocalEvent& e : localEvents)
|
||||||
@ -147,12 +148,7 @@ namespace MWLua
|
|||||||
<< ". Object not found or has no attached scripts";
|
<< ". Object not found or has no attached scripts";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mPlayerChanged)
|
// Engine handlers in local scripts
|
||||||
{
|
|
||||||
mPlayerChanged = false;
|
|
||||||
mGlobalScripts.playerAdded(GObject(getId(mPlayer), mWorldView.getObjectRegistry()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mPlayerScripts)
|
if (mPlayerScripts)
|
||||||
{
|
{
|
||||||
for (const SDL_Keysym key : mKeyPressEvents)
|
for (const SDL_Keysym key : mKeyPressEvents)
|
||||||
@ -167,13 +163,21 @@ namespace MWLua
|
|||||||
mObjectActiveEvents.clear();
|
mObjectActiveEvents.clear();
|
||||||
mObjectInactiveEvents.clear();
|
mObjectInactiveEvents.clear();
|
||||||
|
|
||||||
|
for (LocalScripts* scripts : mActiveLocalScripts)
|
||||||
|
scripts->update(dt);
|
||||||
|
|
||||||
|
// Engine handlers in global scripts
|
||||||
|
if (mPlayerChanged)
|
||||||
|
{
|
||||||
|
mPlayerChanged = false;
|
||||||
|
mGlobalScripts.playerAdded(GObject(getId(mPlayer), mWorldView.getObjectRegistry()));
|
||||||
|
}
|
||||||
|
|
||||||
for (ObjectId id : mActorAddedEvents)
|
for (ObjectId id : mActorAddedEvents)
|
||||||
mGlobalScripts.actorActive(GObject(id, mWorldView.getObjectRegistry()));
|
mGlobalScripts.actorActive(GObject(id, mWorldView.getObjectRegistry()));
|
||||||
mActorAddedEvents.clear();
|
mActorAddedEvents.clear();
|
||||||
|
|
||||||
mGlobalScripts.update(dt);
|
mGlobalScripts.update(dt);
|
||||||
for (LocalScripts* scripts : mActiveLocalScripts)
|
|
||||||
scripts->update(dt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::applyQueuedChanges()
|
void LuaManager::applyQueuedChanges()
|
||||||
@ -212,6 +216,22 @@ namespace MWLua
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LuaManager::setupPlayer(const MWWorld::Ptr& ptr)
|
||||||
|
{
|
||||||
|
if (!mPlayer.isEmpty())
|
||||||
|
throw std::logic_error("Player is initialized twice");
|
||||||
|
mWorldView.objectAddedToScene(ptr);
|
||||||
|
mPlayer = ptr;
|
||||||
|
MWWorld::RefData& refData = ptr.getRefData();
|
||||||
|
if (!refData.getLuaScripts())
|
||||||
|
createLocalScripts(ptr);
|
||||||
|
if (!mPlayerScripts)
|
||||||
|
throw std::logic_error("mPlayerScripts not initialized");
|
||||||
|
mActiveLocalScripts.insert(mPlayerScripts);
|
||||||
|
mObjectActiveEvents.push_back(mPlayerScripts);
|
||||||
|
mPlayerChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
void LuaManager::objectAddedToScene(const MWWorld::Ptr& ptr)
|
void LuaManager::objectAddedToScene(const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
mWorldView.objectAddedToScene(ptr); // assigns generated RefNum if it is not set yet.
|
mWorldView.objectAddedToScene(ptr); // assigns generated RefNum if it is not set yet.
|
||||||
@ -227,21 +247,6 @@ namespace MWLua
|
|||||||
mActorAddedEvents.push_back(getId(ptr));
|
mActorAddedEvents.push_back(getId(ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::setupPlayer(const MWWorld::Ptr& ptr)
|
|
||||||
{
|
|
||||||
if (!mPlayer.isEmpty())
|
|
||||||
throw std::logic_error("Player is initialized twice");
|
|
||||||
mWorldView.objectAddedToScene(ptr);
|
|
||||||
mPlayer = ptr;
|
|
||||||
MWWorld::RefData& refData = ptr.getRefData();
|
|
||||||
if (!refData.getLuaScripts())
|
|
||||||
createLocalScripts(ptr);
|
|
||||||
if (!mPlayerScripts)
|
|
||||||
throw std::logic_error("mPlayerScripts not initialized");
|
|
||||||
mActiveLocalScripts.insert(mPlayerScripts);
|
|
||||||
mPlayerChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LuaManager::objectRemovedFromScene(const MWWorld::Ptr& ptr)
|
void LuaManager::objectRemovedFromScene(const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
mWorldView.objectRemovedFromScene(ptr);
|
mWorldView.objectRemovedFromScene(ptr);
|
||||||
@ -249,10 +254,19 @@ namespace MWLua
|
|||||||
if (localScripts)
|
if (localScripts)
|
||||||
{
|
{
|
||||||
mActiveLocalScripts.erase(localScripts);
|
mActiveLocalScripts.erase(localScripts);
|
||||||
mObjectInactiveEvents.push_back(localScripts);
|
if (!mWorldView.getObjectRegistry()->getPtr(getId(ptr), true).isEmpty())
|
||||||
|
mObjectInactiveEvents.push_back(localScripts);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: call mWorldView.objectUnloaded if object is unloaded from memory (does it ever happen?) and ptr becomes invalid.
|
void LuaManager::registerObject(const MWWorld::Ptr& ptr)
|
||||||
|
{
|
||||||
|
mWorldView.getObjectRegistry()->registerPtr(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaManager::deregisterObject(const MWWorld::Ptr& ptr)
|
||||||
|
{
|
||||||
|
mWorldView.getObjectRegistry()->deregisterPtr(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::keyPressed(const SDL_KeyboardEvent& arg)
|
void LuaManager::keyPressed(const SDL_KeyboardEvent& arg)
|
||||||
@ -349,6 +363,9 @@ namespace MWLua
|
|||||||
scripts->setSerializer(mLocalLoader.get());
|
scripts->setSerializer(mLocalLoader.get());
|
||||||
scripts->load(data, true);
|
scripts->load(data, true);
|
||||||
scripts->setSerializer(mLocalSerializer.get());
|
scripts->setSerializer(mLocalSerializer.get());
|
||||||
|
|
||||||
|
// LiveCellRef is usually copied after loading, so this Ptr will become invalid and should be deregistered.
|
||||||
|
mWorldView.getObjectRegistry()->deregisterPtr(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::reloadAllScripts()
|
void LuaManager::reloadAllScripts()
|
||||||
|
@ -40,6 +40,8 @@ namespace MWLua
|
|||||||
void newGameStarted() override { mGlobalScripts.newGameStarted(); }
|
void newGameStarted() override { mGlobalScripts.newGameStarted(); }
|
||||||
void objectAddedToScene(const MWWorld::Ptr& ptr) override;
|
void objectAddedToScene(const MWWorld::Ptr& ptr) override;
|
||||||
void objectRemovedFromScene(const MWWorld::Ptr& ptr) override;
|
void objectRemovedFromScene(const MWWorld::Ptr& ptr) override;
|
||||||
|
void registerObject(const MWWorld::Ptr& ptr) override;
|
||||||
|
void deregisterObject(const MWWorld::Ptr& ptr) override;
|
||||||
void keyPressed(const SDL_KeyboardEvent &arg) override;
|
void keyPressed(const SDL_KeyboardEvent &arg) override;
|
||||||
|
|
||||||
MWBase::LuaManager::ActorControls* getActorControls(const MWWorld::Ptr&) const override;
|
MWBase::LuaManager::ActorControls* getActorControls(const MWWorld::Ptr&) const override;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <components/esm/doorstate.hpp>
|
#include <components/esm/doorstate.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"
|
||||||
|
|
||||||
@ -195,6 +196,8 @@ namespace
|
|||||||
iter->mData.enable();
|
iter->mData.enable();
|
||||||
MWBase::Environment::get().getWorld()->disable(MWWorld::Ptr(&*iter, cellstore));
|
MWBase::Environment::get().getWorld()->disable(MWWorld::Ptr(&*iter, cellstore));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
MWBase::Environment::get().getLuaManager()->registerObject(MWWorld::Ptr(&*iter, cellstore));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,6 +209,9 @@ namespace
|
|||||||
MWWorld::LiveCellRef<T> ref (record);
|
MWWorld::LiveCellRef<T> ref (record);
|
||||||
ref.load (state);
|
ref.load (state);
|
||||||
collection.mList.push_back (ref);
|
collection.mList.push_back (ref);
|
||||||
|
|
||||||
|
MWWorld::LiveCellRefBase* base = &collection.mList.back();
|
||||||
|
MWBase::Environment::get().getLuaManager()->registerObject(MWWorld::Ptr(base, cellstore));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,16 +292,7 @@ namespace MWWorld
|
|||||||
if (searchViaRefNum(object.getCellRef().getRefNum()).isEmpty())
|
if (searchViaRefNum(object.getCellRef().getRefNum()).isEmpty())
|
||||||
throw std::runtime_error("moveTo: object is not in this cell");
|
throw std::runtime_error("moveTo: object is not in this cell");
|
||||||
|
|
||||||
|
MWBase::Environment::get().getLuaManager()->registerObject(MWWorld::Ptr(object.getBase(), cellToMoveTo));
|
||||||
// Objects with no refnum can't be handled correctly in the merging process that happens
|
|
||||||
// on a save/load, so do a simple copy & delete for these objects.
|
|
||||||
if (!object.getCellRef().getRefNum().hasContentFile())
|
|
||||||
{
|
|
||||||
MWWorld::Ptr copied = object.getClass().copyToCell(object, *cellToMoveTo, object.getRefData().getCount());
|
|
||||||
object.getRefData().setCount(0);
|
|
||||||
object.getRefData().setBaseNode(nullptr);
|
|
||||||
return copied;
|
|
||||||
}
|
|
||||||
|
|
||||||
MovedRefTracker::iterator found = mMovedHere.find(object.getBase());
|
MovedRefTracker::iterator found = mMovedHere.find(object.getBase());
|
||||||
if (found != mMovedHere.end())
|
if (found != mMovedHere.end())
|
||||||
|
@ -813,7 +813,8 @@ namespace MWWorld
|
|||||||
|
|
||||||
void World::enable (const Ptr& reference)
|
void World::enable (const Ptr& reference)
|
||||||
{
|
{
|
||||||
// enable is a no-op for items in containers
|
MWBase::Environment::get().getLuaManager()->registerObject(reference);
|
||||||
|
|
||||||
if (!reference.isInCell())
|
if (!reference.isInCell())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -864,6 +865,7 @@ namespace MWWorld
|
|||||||
if (reference == getPlayerPtr())
|
if (reference == getPlayerPtr())
|
||||||
throw std::runtime_error("can not disable player object");
|
throw std::runtime_error("can not disable player object");
|
||||||
|
|
||||||
|
MWBase::Environment::get().getLuaManager()->deregisterObject(reference);
|
||||||
reference.getRefData().disable();
|
reference.getRefData().disable();
|
||||||
|
|
||||||
if (reference.getCellRef().getRefNum().hasContentFile())
|
if (reference.getCellRef().getRefNum().hasContentFile())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user