mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-30 07:15:34 +00:00
Add LocalScripts::LocalEngineEvent. Add OnConsume
engine handler.
This commit is contained in:
parent
1268597676
commit
b1a6441c23
8 changed files with 90 additions and 43 deletions
|
@ -29,11 +29,16 @@ namespace MWBase
|
|||
virtual ~LuaManager() = default;
|
||||
|
||||
virtual void newGameStarted() = 0;
|
||||
virtual void objectAddedToScene(const MWWorld::Ptr& ptr) = 0;
|
||||
virtual void objectRemovedFromScene(const MWWorld::Ptr& ptr) = 0;
|
||||
virtual void keyPressed(const SDL_KeyboardEvent &arg) = 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 objectAddedToScene(const MWWorld::Ptr& ptr) = 0;
|
||||
virtual void objectRemovedFromScene(const MWWorld::Ptr& ptr) = 0;
|
||||
virtual void appliedToObject(const MWWorld::Ptr& toPtr, std::string_view recordId, const MWWorld::Ptr& fromPtr) = 0;
|
||||
// TODO: notify LuaManager about other events
|
||||
// virtual void objectOnHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object,
|
||||
// const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) = 0;
|
||||
|
||||
struct ActorControls {
|
||||
bool disableAI;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/dialoguemanager.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
#include "../mwbase/luamanager.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
@ -1095,6 +1096,7 @@ namespace MWClass
|
|||
bool Npc::apply (const MWWorld::Ptr& ptr, const std::string& id,
|
||||
const MWWorld::Ptr& actor) const
|
||||
{
|
||||
MWBase::Environment::get().getLuaManager()->appliedToObject(ptr, id, actor);
|
||||
MWMechanics::CastSpell cast(ptr, ptr);
|
||||
return cast.cast(id);
|
||||
}
|
||||
|
|
|
@ -14,10 +14,10 @@ namespace MWLua
|
|||
template <typename Event>
|
||||
void saveEvent(ESM::ESMWriter& esm, const ObjectId& dest, const Event& event)
|
||||
{
|
||||
esm.writeHNString("LUAE", event.eventName);
|
||||
esm.writeHNString("LUAE", event.mEventName);
|
||||
dest.save(esm, true);
|
||||
if (!event.eventData.empty())
|
||||
saveLuaBinaryData(esm, event.eventData);
|
||||
if (!event.mEventData.empty())
|
||||
saveLuaBinaryData(esm, event.mEventData);
|
||||
}
|
||||
|
||||
void loadEvents(sol::state& lua, ESM::ESMReader& esm, GlobalEventQueue& globalEvents, LocalEventQueue& localEvents,
|
||||
|
@ -57,7 +57,7 @@ namespace MWLua
|
|||
for (const GlobalEvent& e : globalEvents)
|
||||
saveEvent(esm, globalId, e);
|
||||
for (const LocalEvent& e : localEvents)
|
||||
saveEvent(esm, e.dest, e);
|
||||
saveEvent(esm, e.mDest, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,14 +23,14 @@ namespace MWLua
|
|||
{
|
||||
struct GlobalEvent
|
||||
{
|
||||
std::string eventName;
|
||||
std::string eventData;
|
||||
std::string mEventName;
|
||||
std::string mEventData;
|
||||
};
|
||||
struct LocalEvent
|
||||
{
|
||||
ObjectId dest;
|
||||
std::string eventName;
|
||||
std::string eventData;
|
||||
ObjectId mDest;
|
||||
std::string mEventName;
|
||||
std::string mEventData;
|
||||
};
|
||||
using GlobalEventQueue = std::vector<GlobalEvent>;
|
||||
using LocalEventQueue = std::vector<LocalEvent>;
|
||||
|
|
|
@ -90,18 +90,30 @@ namespace MWLua
|
|||
mData.mControls.controlledFromLua = false;
|
||||
mData.mControls.disableAI = false;
|
||||
this->addPackage("openmw.self", sol::make_object(lua->sol(), &mData));
|
||||
registerEngineHandlers({&mOnActiveHandlers, &mOnInactiveHandlers});
|
||||
registerEngineHandlers({&mOnActiveHandlers, &mOnInactiveHandlers, &mOnConsumeHandlers});
|
||||
}
|
||||
|
||||
void LocalScripts::becomeActive()
|
||||
void LocalScripts::receiveEngineEvent(const EngineEvent& event, ObjectRegistry*)
|
||||
{
|
||||
mData.mIsActive = true;
|
||||
callEngineHandlers(mOnActiveHandlers);
|
||||
}
|
||||
void LocalScripts::becomeInactive()
|
||||
{
|
||||
mData.mIsActive = false;
|
||||
callEngineHandlers(mOnInactiveHandlers);
|
||||
std::visit([this](auto&& arg)
|
||||
{
|
||||
using EventT = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<EventT, OnActive>)
|
||||
{
|
||||
mData.mIsActive = true;
|
||||
callEngineHandlers(mOnActiveHandlers);
|
||||
}
|
||||
else if constexpr (std::is_same_v<EventT, OnInactive>)
|
||||
{
|
||||
mData.mIsActive = false;
|
||||
callEngineHandlers(mOnInactiveHandlers);
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(std::is_same_v<EventT, OnConsume>);
|
||||
callEngineHandlers(mOnConsumeHandlers, arg.mRecordId);
|
||||
}
|
||||
}, event);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,14 +31,23 @@ namespace MWLua
|
|||
bool mIsActive;
|
||||
};
|
||||
|
||||
void becomeActive();
|
||||
void becomeInactive();
|
||||
struct OnActive {};
|
||||
struct OnInactive {};
|
||||
struct OnConsume
|
||||
{
|
||||
std::string mRecordId;
|
||||
};
|
||||
using EngineEvent = std::variant<OnActive, OnInactive, OnConsume>;
|
||||
|
||||
void receiveEngineEvent(const EngineEvent&, ObjectRegistry*);
|
||||
|
||||
protected:
|
||||
LocalScripts(LuaUtil::LuaState* lua, const LObject& obj);
|
||||
SelfObject mData;
|
||||
private:
|
||||
EngineHandlerList mOnActiveHandlers{"onActive"};
|
||||
EngineHandlerList mOnInactiveHandlers{"onInactive"};
|
||||
EngineHandlerList mOnConsumeHandlers{"onConsume"};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -100,6 +100,8 @@ namespace MWLua
|
|||
|
||||
void LuaManager::update(bool paused, float dt)
|
||||
{
|
||||
ObjectRegistry* objectRegistry = mWorldView.getObjectRegistry();
|
||||
|
||||
if (!mPlayer.isEmpty())
|
||||
{
|
||||
MWWorld::Ptr newPlayerPtr = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
|
@ -108,7 +110,7 @@ namespace MWLua
|
|||
if (!mPlayer.isInCell() || !newPlayerPtr.isInCell() || mPlayer.getCell() != newPlayerPtr.getCell())
|
||||
{
|
||||
mPlayer = newPlayerPtr;
|
||||
mWorldView.getObjectRegistry()->registerPtr(mPlayer);
|
||||
objectRegistry->registerPtr(mPlayer);
|
||||
}
|
||||
}
|
||||
mWorldView.update();
|
||||
|
@ -136,15 +138,15 @@ namespace MWLua
|
|||
|
||||
// Receive events
|
||||
for (GlobalEvent& e : globalEvents)
|
||||
mGlobalScripts.receiveEvent(e.eventName, e.eventData);
|
||||
mGlobalScripts.receiveEvent(e.mEventName, e.mEventData);
|
||||
for (LocalEvent& e : localEvents)
|
||||
{
|
||||
LObject obj(e.dest, mWorldView.getObjectRegistry());
|
||||
LObject obj(e.mDest, objectRegistry);
|
||||
LocalScripts* scripts = obj.isValid() ? obj.ptr().getRefData().getLuaScripts() : nullptr;
|
||||
if (scripts)
|
||||
scripts->receiveEvent(e.eventName, e.eventData);
|
||||
scripts->receiveEvent(e.mEventName, e.mEventData);
|
||||
else
|
||||
Log(Debug::Debug) << "Ignored event " << e.eventName << " to L" << idToString(e.dest)
|
||||
Log(Debug::Debug) << "Ignored event " << e.mEventName << " to L" << idToString(e.mDest)
|
||||
<< ". Object not found or has no attached scripts";
|
||||
}
|
||||
|
||||
|
@ -156,12 +158,19 @@ namespace MWLua
|
|||
}
|
||||
mKeyPressEvents.clear();
|
||||
|
||||
for (LocalScripts* localScripts : mObjectInactiveEvents)
|
||||
localScripts->becomeInactive();
|
||||
for (LocalScripts* localScripts : mObjectActiveEvents)
|
||||
localScripts->becomeActive();
|
||||
mObjectActiveEvents.clear();
|
||||
mObjectInactiveEvents.clear();
|
||||
for (const LocalEngineEvent& e : mLocalEngineEvents)
|
||||
{
|
||||
LObject obj(e.mDest, objectRegistry);
|
||||
if (!obj.isValid())
|
||||
{
|
||||
Log(Debug::Verbose) << "Can not call engine handlers: object" << idToString(e.mDest) << " is not found";
|
||||
continue;
|
||||
}
|
||||
LocalScripts* scripts = obj.ptr().getRefData().getLuaScripts();
|
||||
if (scripts)
|
||||
scripts->receiveEngineEvent(e.mEvent, objectRegistry);
|
||||
}
|
||||
mLocalEngineEvents.clear();
|
||||
|
||||
for (LocalScripts* scripts : mActiveLocalScripts)
|
||||
scripts->update(dt);
|
||||
|
@ -170,11 +179,11 @@ namespace MWLua
|
|||
if (mPlayerChanged)
|
||||
{
|
||||
mPlayerChanged = false;
|
||||
mGlobalScripts.playerAdded(GObject(getId(mPlayer), mWorldView.getObjectRegistry()));
|
||||
mGlobalScripts.playerAdded(GObject(getId(mPlayer), objectRegistry));
|
||||
}
|
||||
|
||||
for (ObjectId id : mActorAddedEvents)
|
||||
mGlobalScripts.actorActive(GObject(id, mWorldView.getObjectRegistry()));
|
||||
mGlobalScripts.actorActive(GObject(id, objectRegistry));
|
||||
mActorAddedEvents.clear();
|
||||
|
||||
mGlobalScripts.update(dt);
|
||||
|
@ -203,8 +212,7 @@ namespace MWLua
|
|||
mGlobalEvents.clear();
|
||||
mKeyPressEvents.clear();
|
||||
mActorAddedEvents.clear();
|
||||
mObjectActiveEvents.clear();
|
||||
mObjectInactiveEvents.clear();
|
||||
mLocalEngineEvents.clear();
|
||||
mPlayerChanged = false;
|
||||
mPlayerScripts = nullptr;
|
||||
mWorldView.clear();
|
||||
|
@ -228,7 +236,7 @@ namespace MWLua
|
|||
if (!mPlayerScripts)
|
||||
throw std::logic_error("mPlayerScripts not initialized");
|
||||
mActiveLocalScripts.insert(mPlayerScripts);
|
||||
mObjectActiveEvents.push_back(mPlayerScripts);
|
||||
mLocalEngineEvents.push_back({getId(ptr), LocalScripts::OnActive{}});
|
||||
mPlayerChanged = true;
|
||||
}
|
||||
|
||||
|
@ -240,7 +248,7 @@ namespace MWLua
|
|||
if (localScripts)
|
||||
{
|
||||
mActiveLocalScripts.insert(localScripts);
|
||||
mObjectActiveEvents.push_back(localScripts);
|
||||
mLocalEngineEvents.push_back({getId(ptr), LocalScripts::OnActive{}});
|
||||
}
|
||||
|
||||
if (ptr.getClass().isActor() && ptr != mPlayer)
|
||||
|
@ -255,7 +263,7 @@ namespace MWLua
|
|||
{
|
||||
mActiveLocalScripts.erase(localScripts);
|
||||
if (!mWorldView.getObjectRegistry()->getPtr(getId(ptr), true).isEmpty())
|
||||
mObjectInactiveEvents.push_back(localScripts);
|
||||
mLocalEngineEvents.push_back({getId(ptr), LocalScripts::OnInactive{}});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,6 +282,11 @@ namespace MWLua
|
|||
mKeyPressEvents.push_back(arg.keysym);
|
||||
}
|
||||
|
||||
void LuaManager::appliedToObject(const MWWorld::Ptr& toPtr, std::string_view recordId, const MWWorld::Ptr& fromPtr)
|
||||
{
|
||||
mLocalEngineEvents.push_back({getId(toPtr), LocalScripts::OnConsume{std::string(recordId)}});
|
||||
}
|
||||
|
||||
MWBase::LuaManager::ActorControls* LuaManager::getActorControls(const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
LocalScripts* localScripts = ptr.getRefData().getLuaScripts();
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace MWLua
|
|||
void registerObject(const MWWorld::Ptr& ptr) override;
|
||||
void deregisterObject(const MWWorld::Ptr& ptr) override;
|
||||
void keyPressed(const SDL_KeyboardEvent &arg) override;
|
||||
void appliedToObject(const MWWorld::Ptr& toPtr, std::string_view recordId, const MWWorld::Ptr& fromPtr) override;
|
||||
|
||||
MWBase::LuaManager::ActorControls* getActorControls(const MWWorld::Ptr&) const override;
|
||||
|
||||
|
@ -96,8 +97,13 @@ namespace MWLua
|
|||
|
||||
std::vector<SDL_Keysym> mKeyPressEvents;
|
||||
std::vector<ObjectId> mActorAddedEvents;
|
||||
std::vector<LocalScripts*> mObjectActiveEvents;
|
||||
std::vector<LocalScripts*> mObjectInactiveEvents;
|
||||
|
||||
struct LocalEngineEvent
|
||||
{
|
||||
ObjectId mDest;
|
||||
LocalScripts::EngineEvent mEvent;
|
||||
};
|
||||
std::vector<LocalEngineEvent> mLocalEngineEvents;
|
||||
|
||||
// Queued actions that should be done in main thread. Processed by applyQueuedChanges().
|
||||
std::vector<std::unique_ptr<Action>> mActionQueue;
|
||||
|
|
Loading…
Reference in a new issue