From dc0bc5b68c474e40aeeb4a73ef4d0b4c48d3f3c9 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sat, 9 Jul 2016 02:16:47 +0200 Subject: [PATCH] Implement Face instruction (Feature #1424) --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwmechanics/aiface.cpp | 31 ++++++++++++++++++++++++++ apps/openmw/mwmechanics/aiface.hpp | 29 ++++++++++++++++++++++++ apps/openmw/mwmechanics/aipackage.hpp | 5 +++-- apps/openmw/mwmechanics/aisequence.cpp | 3 ++- apps/openmw/mwscript/aiextensions.cpp | 12 +++++++++- components/compiler/extensions0.cpp | 2 +- 7 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 apps/openmw/mwmechanics/aiface.cpp create mode 100644 apps/openmw/mwmechanics/aiface.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index f7a9fea3c..73f88bdb5 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -84,7 +84,7 @@ add_openmw_dir (mwmechanics drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiavoiddoor aiescort aiactivate aicombat repair enchanting pathfinding pathgrid security spellsuccess spellcasting disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction actor summoning - character actors objects aistate coordinateconverter trading + character actors objects aistate coordinateconverter trading aiface ) add_openmw_dir (mwstate diff --git a/apps/openmw/mwmechanics/aiface.cpp b/apps/openmw/mwmechanics/aiface.cpp new file mode 100644 index 000000000..7d15cabf2 --- /dev/null +++ b/apps/openmw/mwmechanics/aiface.cpp @@ -0,0 +1,31 @@ +#include "aiface.hpp" + +#include "../mwbase/world.hpp" + +#include "steering.hpp" + +MWMechanics::AiFace::AiFace(float targetX, float targetY) + : mTargetX(targetX), mTargetY(targetY) +{ +} + +MWMechanics::AiPackage *MWMechanics::AiFace::clone() const +{ + return new AiFace(*this); +} + +bool MWMechanics::AiFace::execute(const MWWorld::Ptr& actor, MWMechanics::CharacterController& /*characterController*/, MWMechanics::AiState& /*state*/, float /*duration*/) +{ + osg::Vec3f dir = osg::Vec3f(mTargetX, mTargetY, 0) - actor.getRefData().getPosition().asVec3(); + return zTurn(actor, std::atan2(dir.x(), dir.y()), osg::DegreesToRadians(3.f)); +} + +int MWMechanics::AiFace::getTypeId() const +{ + return AiPackage::TypeIdFace; +} + +unsigned int MWMechanics::AiFace::getPriority() const +{ + return 2; +} diff --git a/apps/openmw/mwmechanics/aiface.hpp b/apps/openmw/mwmechanics/aiface.hpp new file mode 100644 index 000000000..099e5d237 --- /dev/null +++ b/apps/openmw/mwmechanics/aiface.hpp @@ -0,0 +1,29 @@ +#ifndef GAME_MWMECHANICS_AIFACE_H +#define GAME_MWMECHANICS_AIFACE_H + +#include "aipackage.hpp" + +namespace MWMechanics +{ + /// AiPackage which makes an actor face a certain direction. + class AiFace : public AiPackage { + public: + AiFace(float targetX, float targetY); + + virtual AiPackage *clone() const; + + virtual bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration); + + virtual int getTypeId() const; + + virtual unsigned int getPriority() const; + + virtual bool canCancel() const { return false; } + virtual bool shouldCancelPreviousAi() const { return false; } + + private: + float mTargetX, mTargetY; + }; +} + +#endif diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp index 8f6ddb111..277629770 100644 --- a/apps/openmw/mwmechanics/aipackage.hpp +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -40,11 +40,12 @@ namespace MWMechanics TypeIdFollow = 3, TypeIdActivate = 4, - // These 3 are not really handled as Ai Packages in the MW engine + // These 4 are not really handled as Ai Packages in the MW engine // For compatibility do *not* return these in the getCurrentAiPackage script function.. TypeIdCombat = 5, TypeIdPursue = 6, - TypeIdAvoidDoor = 7 + TypeIdAvoidDoor = 7, + TypeIdFace = 8 }; ///Default constructor diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index ed9db102f..f05725cc2 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -159,7 +159,8 @@ bool isActualAiPackage(int packageTypeId) { return (packageTypeId != AiPackage::TypeIdCombat && packageTypeId != AiPackage::TypeIdPursue - && packageTypeId != AiPackage::TypeIdAvoidDoor); + && packageTypeId != AiPackage::TypeIdAvoidDoor + && packageTypeId != AiPackage::TypeIdFace); } void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index 12e323272..76130be24 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -19,6 +19,7 @@ #include "../mwmechanics/aifollow.hpp" #include "../mwmechanics/aitravel.hpp" #include "../mwmechanics/aiwander.hpp" +#include "../mwmechanics/aiface.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -483,7 +484,16 @@ namespace MWScript public: virtual void execute(Interpreter::Runtime& runtime) { - /// \todo implement + MWWorld::Ptr actor = R()(runtime); + + Interpreter::Type_Float x = runtime[0].mFloat; + runtime.pop(); + + Interpreter::Type_Float y = runtime[0].mFloat; + runtime.pop(); + + MWMechanics::AiFace facePackage(x, y); + actor.getClass().getCreatureStats(actor).getAiSequence().stack(facePackage, actor); } }; diff --git a/components/compiler/extensions0.cpp b/components/compiler/extensions0.cpp index f67e70522..353c35a0d 100644 --- a/components/compiler/extensions0.cpp +++ b/components/compiler/extensions0.cpp @@ -70,7 +70,7 @@ namespace Compiler extensions.registerFunction ("getlineofsight", 'l', "c", opcodeGetLineOfSight, opcodeGetLineOfSightExplicit); extensions.registerFunction ("getlos", 'l', "c", opcodeGetLineOfSight, opcodeGetLineOfSightExplicit); extensions.registerFunction("gettarget", 'l', "c", opcodeGetTarget, opcodeGetTargetExplicit); - extensions.registerInstruction("face", "llX", opcodeFace, opcodeFaceExplicit); + extensions.registerInstruction("face", "ffX", opcodeFace, opcodeFaceExplicit); } }