mirror of
https://github.com/OpenMW/openmw.git
synced 2025-05-30 20:41:31 +00:00
A possibility to view actor controls from lua scripts without disabling AI.
This commit is contained in:
parent
7087eb1a4e
commit
a8f76260bc
6 changed files with 37 additions and 25 deletions
|
@ -34,6 +34,7 @@ namespace MWBase
|
||||||
virtual void keyPressed(const SDL_KeyboardEvent &arg) = 0;
|
virtual void keyPressed(const SDL_KeyboardEvent &arg) = 0;
|
||||||
|
|
||||||
struct ActorControls {
|
struct ActorControls {
|
||||||
|
bool disableAI;
|
||||||
bool controlledFromLua;
|
bool controlledFromLua;
|
||||||
|
|
||||||
bool jump;
|
bool jump;
|
||||||
|
@ -43,7 +44,7 @@ namespace MWBase
|
||||||
float turn;
|
float turn;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual const ActorControls* getActorControls(const MWWorld::Ptr&) const = 0;
|
virtual ActorControls* getActorControls(const MWWorld::Ptr&) const = 0;
|
||||||
|
|
||||||
virtual void clear() = 0;
|
virtual void clear() = 0;
|
||||||
virtual void setupPlayer(const MWWorld::Ptr&) = 0;
|
virtual void setupPlayer(const MWWorld::Ptr&) = 0;
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace MWLua
|
||||||
selfAPI["controls"] = sol::readonly_property([](SelfObject& self) { return &self.mControls; });
|
selfAPI["controls"] = sol::readonly_property([](SelfObject& self) { return &self.mControls; });
|
||||||
selfAPI["isActive"] = [](SelfObject& self) { return &self.mIsActive; };
|
selfAPI["isActive"] = [](SelfObject& self) { return &self.mIsActive; };
|
||||||
selfAPI["setDirectControl"] = [](SelfObject& self, bool v) { self.mControls.controlledFromLua = v; };
|
selfAPI["setDirectControl"] = [](SelfObject& self, bool v) { self.mControls.controlledFromLua = v; };
|
||||||
|
selfAPI["enableAI"] = [](SelfObject& self, bool v) { self.mControls.disableAI = !v; };
|
||||||
selfAPI["setEquipment"] = [manager=context.mLuaManager](const SelfObject& obj, sol::table equipment)
|
selfAPI["setEquipment"] = [manager=context.mLuaManager](const SelfObject& obj, sol::table equipment)
|
||||||
{
|
{
|
||||||
if (!obj.ptr().getClass().hasInventoryStore(obj.ptr()))
|
if (!obj.ptr().getClass().hasInventoryStore(obj.ptr()))
|
||||||
|
@ -87,6 +88,7 @@ namespace MWLua
|
||||||
: LuaUtil::ScriptsContainer(lua, "L" + idToString(obj.id())), mData(obj)
|
: LuaUtil::ScriptsContainer(lua, "L" + idToString(obj.id())), mData(obj)
|
||||||
{
|
{
|
||||||
mData.mControls.controlledFromLua = false;
|
mData.mControls.controlledFromLua = false;
|
||||||
|
mData.mControls.disableAI = false;
|
||||||
this->addPackage("openmw.self", sol::make_object(lua->sol(), &mData));
|
this->addPackage("openmw.self", sol::make_object(lua->sol(), &mData));
|
||||||
registerEngineHandlers({&mOnActiveHandlers, &mOnInactiveHandlers});
|
registerEngineHandlers({&mOnActiveHandlers, &mOnInactiveHandlers});
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace MWLua
|
||||||
static std::unique_ptr<LocalScripts> create(LuaUtil::LuaState* lua, const LObject& obj);
|
static std::unique_ptr<LocalScripts> create(LuaUtil::LuaState* lua, const LObject& obj);
|
||||||
static void initializeSelfPackage(const Context&);
|
static void initializeSelfPackage(const Context&);
|
||||||
|
|
||||||
const MWBase::LuaManager::ActorControls* getActorControls() const { return &mData.mControls; }
|
MWBase::LuaManager::ActorControls* getActorControls() { return &mData.mControls; }
|
||||||
|
|
||||||
struct SelfObject : public LObject
|
struct SelfObject : public LObject
|
||||||
{
|
{
|
||||||
|
|
|
@ -260,7 +260,7 @@ namespace MWLua
|
||||||
mKeyPressEvents.push_back(arg.keysym);
|
mKeyPressEvents.push_back(arg.keysym);
|
||||||
}
|
}
|
||||||
|
|
||||||
const MWBase::LuaManager::ActorControls* LuaManager::getActorControls(const MWWorld::Ptr& ptr) const
|
MWBase::LuaManager::ActorControls* LuaManager::getActorControls(const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
LocalScripts* localScripts = ptr.getRefData().getLuaScripts();
|
LocalScripts* localScripts = ptr.getRefData().getLuaScripts();
|
||||||
if (!localScripts)
|
if (!localScripts)
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace MWLua
|
||||||
void objectRemovedFromScene(const MWWorld::Ptr& ptr) override;
|
void objectRemovedFromScene(const MWWorld::Ptr& ptr) override;
|
||||||
void keyPressed(const SDL_KeyboardEvent &arg) override;
|
void keyPressed(const SDL_KeyboardEvent &arg) override;
|
||||||
|
|
||||||
const MWBase::LuaManager::ActorControls* getActorControls(const MWWorld::Ptr&) const override;
|
MWBase::LuaManager::ActorControls* getActorControls(const MWWorld::Ptr&) const override;
|
||||||
|
|
||||||
void clear() override; // should be called before loading game or starting a new game to reset internal state.
|
void clear() override; // should be called before loading game or starting a new game to reset internal state.
|
||||||
void setupPlayer(const MWWorld::Ptr& ptr) override; // Should be called once after each "clear".
|
void setupPlayer(const MWWorld::Ptr& ptr) override; // Should be called once after each "clear".
|
||||||
|
|
|
@ -1962,6 +1962,8 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
bool isPlayer = iter->first == player;
|
bool isPlayer = iter->first == player;
|
||||||
CharacterController* ctrl = iter->second->getCharacterController();
|
CharacterController* ctrl = iter->second->getCharacterController();
|
||||||
|
MWBase::LuaManager::ActorControls* luaControls =
|
||||||
|
MWBase::Environment::get().getLuaManager()->getActorControls(iter->first);
|
||||||
|
|
||||||
float distSqr = (playerPos - iter->first.getRefData().getPosition().asVec3()).length2();
|
float distSqr = (playerPos - iter->first.getRefData().getPosition().asVec3()).length2();
|
||||||
// AI processing is only done within given distance to the player.
|
// AI processing is only done within given distance to the player.
|
||||||
|
@ -2010,25 +2012,6 @@ namespace MWMechanics
|
||||||
return; // for now abort update of the old cell when cell changes by teleportation magic effect
|
return; // for now abort update of the old cell when cell changes by teleportation magic effect
|
||||||
// a better solution might be to apply cell changes at the end of the frame
|
// a better solution might be to apply cell changes at the end of the frame
|
||||||
}
|
}
|
||||||
bool controlledFromLua;
|
|
||||||
{
|
|
||||||
const MWBase::LuaManager::ActorControls* luaControls =
|
|
||||||
MWBase::Environment::get().getLuaManager()->getActorControls(iter->first);
|
|
||||||
controlledFromLua = luaControls && luaControls->controlledFromLua;
|
|
||||||
if (controlledFromLua && isConscious(iter->first))
|
|
||||||
{
|
|
||||||
Movement& mov = iter->first.getClass().getMovementSettings(iter->first);
|
|
||||||
mov.mPosition[0] = luaControls->sideMovement;
|
|
||||||
mov.mPosition[1] = luaControls->movement;
|
|
||||||
mov.mPosition[2] = luaControls->jump ? 1 : 0;
|
|
||||||
mov.mRotation[0] = mov.mRotation[1] = 0;
|
|
||||||
mov.mRotation[2] = luaControls->turn;
|
|
||||||
mov.mSpeedFactor = osg::Vec2(luaControls->movement, luaControls->sideMovement).length();
|
|
||||||
|
|
||||||
CreatureStats& stats = iter->first.getClass().getCreatureStats(iter->first);
|
|
||||||
stats.setMovementFlag(MWMechanics::CreatureStats::Flag_Run, luaControls->run);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (aiActive && inProcessingRange)
|
if (aiActive && inProcessingRange)
|
||||||
{
|
{
|
||||||
if (engageCombatTimerStatus == Misc::TimerStatus::Elapsed)
|
if (engageCombatTimerStatus == Misc::TimerStatus::Elapsed)
|
||||||
|
@ -2082,7 +2065,7 @@ namespace MWMechanics
|
||||||
if (iter->first != player)
|
if (iter->first != player)
|
||||||
{
|
{
|
||||||
CreatureStats &stats = iter->first.getClass().getCreatureStats(iter->first);
|
CreatureStats &stats = iter->first.getClass().getCreatureStats(iter->first);
|
||||||
if (isConscious(iter->first) && !controlledFromLua)
|
if (isConscious(iter->first) && !(luaControls && luaControls->disableAI))
|
||||||
{
|
{
|
||||||
stats.getAiSequence().execute(iter->first, *ctrl, duration);
|
stats.getAiSequence().execute(iter->first, *ctrl, duration);
|
||||||
updateGreetingState(iter->first, *iter->second, timerUpdateHello > 0);
|
updateGreetingState(iter->first, *iter->second, timerUpdateHello > 0);
|
||||||
|
@ -2091,7 +2074,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (aiActive && iter->first != player && isConscious(iter->first) && !controlledFromLua)
|
else if (aiActive && iter->first != player && isConscious(iter->first) && !(luaControls && luaControls->disableAI))
|
||||||
{
|
{
|
||||||
CreatureStats &stats = iter->first.getClass().getCreatureStats(iter->first);
|
CreatureStats &stats = iter->first.getClass().getCreatureStats(iter->first);
|
||||||
stats.getAiSequence().execute(iter->first, *ctrl, duration, /*outOfRange*/true);
|
stats.getAiSequence().execute(iter->first, *ctrl, duration, /*outOfRange*/true);
|
||||||
|
@ -2108,6 +2091,32 @@ namespace MWMechanics
|
||||||
if (timerUpdateEquippedLight == 0)
|
if (timerUpdateEquippedLight == 0)
|
||||||
updateEquippedLight(iter->first, updateEquippedLightInterval, showTorches);
|
updateEquippedLight(iter->first, updateEquippedLightInterval, showTorches);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (luaControls && isConscious(iter->first))
|
||||||
|
{
|
||||||
|
Movement& mov = iter->first.getClass().getMovementSettings(iter->first);
|
||||||
|
CreatureStats& stats = iter->first.getClass().getCreatureStats(iter->first);
|
||||||
|
float speedFactor = isPlayer ? 1.f : mov.mSpeedFactor;
|
||||||
|
osg::Vec2f movement = osg::Vec2f(mov.mPosition[0], mov.mPosition[1]) * speedFactor;
|
||||||
|
float rotationZ = mov.mRotation[2];
|
||||||
|
bool jump = mov.mPosition[2] == 1;
|
||||||
|
bool runFlag = stats.getMovementFlag(MWMechanics::CreatureStats::Flag_Run);
|
||||||
|
if (luaControls->controlledFromLua)
|
||||||
|
{
|
||||||
|
mov.mPosition[0] = luaControls->sideMovement;
|
||||||
|
mov.mPosition[1] = luaControls->movement;
|
||||||
|
mov.mPosition[2] = luaControls->jump ? 1 : 0;
|
||||||
|
mov.mRotation[1] = 0;
|
||||||
|
mov.mRotation[2] = luaControls->turn;
|
||||||
|
mov.mSpeedFactor = osg::Vec2(luaControls->movement, luaControls->sideMovement).length();
|
||||||
|
stats.setMovementFlag(MWMechanics::CreatureStats::Flag_Run, luaControls->run);
|
||||||
|
}
|
||||||
|
luaControls->sideMovement = movement.x();
|
||||||
|
luaControls->movement = movement.y();
|
||||||
|
luaControls->turn = rotationZ;
|
||||||
|
luaControls->jump = jump;
|
||||||
|
luaControls->run = runFlag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue