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());
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");
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);
}
}
@ -123,10 +123,11 @@ namespace MWLua
}
// Engine handlers in local scripts
if (mPlayerScripts)
PlayerScripts* playerScripts = dynamic_cast<PlayerScripts*>(mPlayer.getRefData().getLuaScripts());
if (playerScripts)
{
for (const SDL_Keysym& key : mKeyPressEvents)
mPlayerScripts->keyPress(key);
playerScripts->keyPress(key);
}
mKeyPressEvents.clear();
@ -186,7 +187,6 @@ namespace MWLua
mActorAddedEvents.clear();
mLocalEngineEvents.clear();
mPlayerChanged = false;
mPlayerScripts = nullptr;
mWorldView.clear();
if (!mPlayer.isEmpty())
{
@ -202,12 +202,10 @@ namespace MWLua
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);
LocalScripts* localScripts = ptr.getRefData().getLuaScripts();
if (!localScripts)
localScripts = createLocalScripts(ptr);
mActiveLocalScripts.insert(localScripts);
mLocalEngineEvents.push_back({getId(ptr), LocalScripts::OnActive{}});
mPlayerChanged = true;
}
@ -269,10 +267,14 @@ namespace MWLua
void LuaManager::addLocalScript(const MWWorld::Ptr& ptr, const std::string& scriptPath)
{
MWWorld::RefData& refData = ptr.getRefData();
if (!refData.getLuaScripts())
mActiveLocalScripts.insert(createLocalScripts(ptr));
refData.getLuaScripts()->addNewScript(scriptPath);
LocalScripts* localScripts = ptr.getRefData().getLuaScripts();
if (!localScripts)
{
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)
@ -282,8 +284,7 @@ namespace MWLua
// so we can't just check ptr == mPlayer here.
if (*ptr.getCellRef().getRefIdPtr() == "player")
{
mPlayerScripts = new PlayerScripts(&mLua, LObject(getId(ptr), mWorldView.getObjectRegistry()));
scripts = std::shared_ptr<LocalScripts>(mPlayerScripts);
scripts = std::make_shared<PlayerScripts>(&mLua, LObject(getId(ptr), mWorldView.getObjectRegistry()));
scripts->addPackage("openmw.ui", mUserInterfacePackage);
scripts->addPackage("openmw.camera", mCameraPackage);
}

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

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

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

@ -52,6 +52,9 @@ Global 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.
.. note::
Currently scripts on objects in a container or an inventory are considered inactive. Probably later this behaviour will be changed.
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).

Loading…
Cancel
Save