Refactoring and minor fixes related to active/inactive object state

dont-compose-content
Petr Mikheev 4 years ago
parent 43b7e6964a
commit 85c441ec9a

@ -41,7 +41,6 @@ namespace MWLua
{ {
MWWorld::Ptr newObj = world->moveObject(obj, cell, mPos.x(), mPos.y(), mPos.z()); MWWorld::Ptr newObj = world->moveObject(obj, cell, mPos.x(), mPos.y(), mPos.z());
world->rotateObject(newObj, mRot.x(), mRot.y(), mRot.z()); world->rotateObject(newObj, mRot.x(), mRot.y(), mRot.z());
worldView.getObjectRegistry()->registerPtr(newObj);
} }
} }

@ -81,7 +81,7 @@ namespace MWLua
throw std::logic_error("Player Refnum was changed unexpectedly"); throw std::logic_error("Player Refnum was changed unexpectedly");
if (!mPlayer.isInCell() || !newPlayerPtr.isInCell() || mPlayer.getCell() != newPlayerPtr.getCell()) if (!mPlayer.isInCell() || !newPlayerPtr.isInCell() || mPlayer.getCell() != newPlayerPtr.getCell())
{ {
mPlayer = newPlayerPtr; mPlayer = newPlayerPtr; // player was moved to another cell, update ptr in registry
objectRegistry->registerPtr(mPlayer); objectRegistry->registerPtr(mPlayer);
} }
} }
@ -123,10 +123,11 @@ namespace MWLua
} }
// Engine handlers in local scripts // Engine handlers in local scripts
if (mPlayerScripts) PlayerScripts* playerScripts = dynamic_cast<PlayerScripts*>(mPlayer.getRefData().getLuaScripts());
if (playerScripts)
{ {
for (const SDL_Keysym& key : mKeyPressEvents) for (const SDL_Keysym& key : mKeyPressEvents)
mPlayerScripts->keyPress(key); playerScripts->keyPress(key);
} }
mKeyPressEvents.clear(); mKeyPressEvents.clear();
@ -186,7 +187,6 @@ namespace MWLua
mActorAddedEvents.clear(); mActorAddedEvents.clear();
mLocalEngineEvents.clear(); mLocalEngineEvents.clear();
mPlayerChanged = false; mPlayerChanged = false;
mPlayerScripts = nullptr;
mWorldView.clear(); mWorldView.clear();
if (!mPlayer.isEmpty()) if (!mPlayer.isEmpty())
{ {
@ -202,12 +202,10 @@ namespace MWLua
throw std::logic_error("Player is initialized twice"); throw std::logic_error("Player is initialized twice");
mWorldView.objectAddedToScene(ptr); mWorldView.objectAddedToScene(ptr);
mPlayer = ptr; mPlayer = ptr;
MWWorld::RefData& refData = ptr.getRefData(); LocalScripts* localScripts = ptr.getRefData().getLuaScripts();
if (!refData.getLuaScripts()) if (!localScripts)
createLocalScripts(ptr); localScripts = createLocalScripts(ptr);
if (!mPlayerScripts) mActiveLocalScripts.insert(localScripts);
throw std::logic_error("mPlayerScripts not initialized");
mActiveLocalScripts.insert(mPlayerScripts);
mLocalEngineEvents.push_back({getId(ptr), LocalScripts::OnActive{}}); mLocalEngineEvents.push_back({getId(ptr), LocalScripts::OnActive{}});
mPlayerChanged = true; mPlayerChanged = true;
} }
@ -269,10 +267,14 @@ namespace MWLua
void LuaManager::addLocalScript(const MWWorld::Ptr& ptr, const std::string& scriptPath) void LuaManager::addLocalScript(const MWWorld::Ptr& ptr, const std::string& scriptPath)
{ {
MWWorld::RefData& refData = ptr.getRefData(); LocalScripts* localScripts = ptr.getRefData().getLuaScripts();
if (!refData.getLuaScripts()) if (!localScripts)
mActiveLocalScripts.insert(createLocalScripts(ptr)); {
refData.getLuaScripts()->addNewScript(scriptPath); localScripts = createLocalScripts(ptr);
if (ptr.isInCell() && MWBase::Environment::get().getWorld()->isCellActive(ptr.getCell()))
mActiveLocalScripts.insert(localScripts);
}
localScripts->addNewScript(scriptPath);
} }
LocalScripts* LuaManager::createLocalScripts(const MWWorld::Ptr& ptr) LocalScripts* LuaManager::createLocalScripts(const MWWorld::Ptr& ptr)
@ -282,8 +284,7 @@ namespace MWLua
// so we can't just check ptr == mPlayer here. // so we can't just check ptr == mPlayer here.
if (*ptr.getCellRef().getRefIdPtr() == "player") if (*ptr.getCellRef().getRefIdPtr() == "player")
{ {
mPlayerScripts = new PlayerScripts(&mLua, LObject(getId(ptr), mWorldView.getObjectRegistry())); scripts = std::make_shared<PlayerScripts>(&mLua, LObject(getId(ptr), mWorldView.getObjectRegistry()));
scripts = std::shared_ptr<LocalScripts>(mPlayerScripts);
scripts->addPackage("openmw.ui", mUserInterfacePackage); scripts->addPackage("openmw.ui", mUserInterfacePackage);
scripts->addPackage("openmw.camera", mCameraPackage); scripts->addPackage("openmw.camera", mCameraPackage);
} }

@ -82,7 +82,6 @@ namespace MWLua
bool mPlayerChanged = false; bool mPlayerChanged = false;
MWWorld::Ptr mPlayer; MWWorld::Ptr mPlayer;
PlayerScripts* mPlayerScripts = nullptr;
GlobalEventQueue mGlobalEvents; GlobalEventQueue mGlobalEvents;
LocalEventQueue mLocalEvents; LocalEventQueue mLocalEvents;

@ -118,16 +118,16 @@ namespace MWLua
mLastAssignedId.unset(); mLastAssignedId.unset();
} }
MWWorld::Ptr ObjectRegistry::getPtr(ObjectId id, bool onlyActive) MWWorld::Ptr ObjectRegistry::getPtr(ObjectId id, bool local)
{ {
MWWorld::Ptr ptr; MWWorld::Ptr ptr;
auto it = mObjectMapping.find(id); auto it = mObjectMapping.find(id);
if (it != mObjectMapping.end()) if (it != mObjectMapping.end())
ptr = it->second; ptr = it->second;
if (onlyActive) if (local)
{ {
// TODO: add flag `isActive` to LiveCellRefBase. Return empty Ptr if the flag is not set. // TODO: Return ptr only if it is active or was active in the previous frame, otherwise return empty.
// Needed because in multiplayer mode inactive objects will not be synchronized, so will likely be out of date. // Needed because in multiplayer inactive objects will not be synchronized, so an be out of date.
} }
else else
{ {

@ -35,10 +35,9 @@ namespace MWLua
ObjectId deregisterPtr(const MWWorld::Ptr& ptr); ObjectId deregisterPtr(const MWWorld::Ptr& ptr);
// Returns Ptr by id. If object is not found, returns empty Ptr. // Returns Ptr by id. If object is not found, returns empty Ptr.
// If onlyActive = true, returns non-empty ptr only if it is registered and is in an active cell. // If local = true, returns non-empty ptr only if it can be used in local scripts
// If onlyActive = false, tries to load and register the object if it is not loaded yet. // (i.e. is active or was active in the previous frame).
// NOTE: `onlyActive` logic is not yet implemented. MWWorld::Ptr getPtr(ObjectId id, bool local);
MWWorld::Ptr getPtr(ObjectId id, bool onlyActive);
// Needed only for saving/loading. // Needed only for saving/loading.
const ObjectId& getLastAssignedId() const { return mLastAssignedId; } const ObjectId& getLastAssignedId() const { return mLastAssignedId; }
@ -46,8 +45,6 @@ namespace MWLua
private: private:
friend class Object; friend class Object;
friend class GObject;
friend class LObject;
friend class LuaManager; friend class LuaManager;
bool mChanged = false; bool mChanged = false;

@ -52,6 +52,9 @@ Global scripts
Local scripts Local scripts
Lua scripts that are attached to some game object. A local script is active only if the object it is attached to is in an active cell. There are no limitations to the number of local scripts on one object. Local scripts can be attached to (or detached from) any object at any moment by a global script. In some cases inactive local scripts still can run code (for example during saving and loading), but while inactive they can not see nearby objects. Lua scripts that are attached to some game object. A local script is active only if the object it is attached to is in an active cell. There are no limitations to the number of local scripts on one object. Local scripts can be attached to (or detached from) any object at any moment by a global script. In some cases inactive local scripts still can run code (for example during saving and loading), but while inactive they can not see nearby objects.
.. note::
Currently scripts on objects in a container or an inventory are considered inactive. Probably later this behaviour will be changed.
Player scripts Player scripts
A specific kind of local scripts; *player script* is a local script that is attached to a player. It can do everything that a normal local script can do, plus some player-specific functionality (e.g. control UI and camera). A specific kind of local scripts; *player script* is a local script that is attached to a player. It can do everything that a normal local script can do, plus some player-specific functionality (e.g. control UI and camera).

Loading…
Cancel
Save