mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-06 06:15:32 +00:00
Make loaded but inactive objects available in Lua scripts.
This commit is contained in:
parent
403d31313c
commit
1268597676
5 changed files with 56 additions and 36 deletions
|
@ -31,6 +31,8 @@ namespace MWBase
|
|||
virtual void newGameStarted() = 0;
|
||||
virtual void objectAddedToScene(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;
|
||||
|
||||
struct ActorControls {
|
||||
|
|
|
@ -134,6 +134,7 @@ namespace MWLua
|
|||
scripts->processTimers(seconds, hours);
|
||||
}
|
||||
|
||||
// Receive events
|
||||
for (GlobalEvent& e : globalEvents)
|
||||
mGlobalScripts.receiveEvent(e.eventName, e.eventData);
|
||||
for (LocalEvent& e : localEvents)
|
||||
|
@ -147,12 +148,7 @@ namespace MWLua
|
|||
<< ". Object not found or has no attached scripts";
|
||||
}
|
||||
|
||||
if (mPlayerChanged)
|
||||
{
|
||||
mPlayerChanged = false;
|
||||
mGlobalScripts.playerAdded(GObject(getId(mPlayer), mWorldView.getObjectRegistry()));
|
||||
}
|
||||
|
||||
// Engine handlers in local scripts
|
||||
if (mPlayerScripts)
|
||||
{
|
||||
for (const SDL_Keysym key : mKeyPressEvents)
|
||||
|
@ -167,13 +163,21 @@ namespace MWLua
|
|||
mObjectActiveEvents.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)
|
||||
mGlobalScripts.actorActive(GObject(id, mWorldView.getObjectRegistry()));
|
||||
mActorAddedEvents.clear();
|
||||
|
||||
mGlobalScripts.update(dt);
|
||||
for (LocalScripts* scripts : mActiveLocalScripts)
|
||||
scripts->update(dt);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
mWorldView.objectAddedToScene(ptr); // assigns generated RefNum if it is not set yet.
|
||||
|
@ -227,21 +247,6 @@ namespace MWLua
|
|||
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)
|
||||
{
|
||||
mWorldView.objectRemovedFromScene(ptr);
|
||||
|
@ -249,10 +254,19 @@ namespace MWLua
|
|||
if (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)
|
||||
|
@ -349,6 +363,9 @@ namespace MWLua
|
|||
scripts->setSerializer(mLocalLoader.get());
|
||||
scripts->load(data, true);
|
||||
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()
|
||||
|
|
|
@ -40,6 +40,8 @@ namespace MWLua
|
|||
void newGameStarted() override { mGlobalScripts.newGameStarted(); }
|
||||
void objectAddedToScene(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;
|
||||
|
||||
MWBase::LuaManager::ActorControls* getActorControls(const MWWorld::Ptr&) const override;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <components/esm/doorstate.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/luamanager.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
|
@ -195,6 +196,8 @@ namespace
|
|||
iter->mData.enable();
|
||||
MWBase::Environment::get().getWorld()->disable(MWWorld::Ptr(&*iter, cellstore));
|
||||
}
|
||||
else
|
||||
MWBase::Environment::get().getLuaManager()->registerObject(MWWorld::Ptr(&*iter, cellstore));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -206,6 +209,9 @@ namespace
|
|||
MWWorld::LiveCellRef<T> ref (record);
|
||||
ref.load (state);
|
||||
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())
|
||||
throw std::runtime_error("moveTo: object is not in this cell");
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
MWBase::Environment::get().getLuaManager()->registerObject(MWWorld::Ptr(object.getBase(), cellToMoveTo));
|
||||
|
||||
MovedRefTracker::iterator found = mMovedHere.find(object.getBase());
|
||||
if (found != mMovedHere.end())
|
||||
|
|
|
@ -813,7 +813,8 @@ namespace MWWorld
|
|||
|
||||
void World::enable (const Ptr& reference)
|
||||
{
|
||||
// enable is a no-op for items in containers
|
||||
MWBase::Environment::get().getLuaManager()->registerObject(reference);
|
||||
|
||||
if (!reference.isInCell())
|
||||
return;
|
||||
|
||||
|
@ -864,6 +865,7 @@ namespace MWWorld
|
|||
if (reference == getPlayerPtr())
|
||||
throw std::runtime_error("can not disable player object");
|
||||
|
||||
MWBase::Environment::get().getLuaManager()->deregisterObject(reference);
|
||||
reference.getRefData().disable();
|
||||
|
||||
if (reference.getCellRef().getRefNum().hasContentFile())
|
||||
|
|
Loading…
Reference in a new issue