From 7079b9062f66250fa9b0790c75bfd76533cbd814 Mon Sep 17 00:00:00 2001 From: rpopovici <rpopovici@github.com> Date: Fri, 30 Nov 2012 02:16:16 +0200 Subject: [PATCH 1/2] add AI script functions --- apps/openmw/mwmechanics/aiescort.cpp | 6 + apps/openmw/mwmechanics/aiescort.hpp | 5 + apps/openmw/mwmechanics/aifollow.cpp | 5 + apps/openmw/mwmechanics/aifollow.hpp | 4 +- apps/openmw/mwscript/aiextensions.cpp | 239 +++++++++++++++++++++++-- apps/openmw/mwscript/docs/vmformat.txt | 16 +- 6 files changed, 262 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index 27cd9095dc..ebbea55b0e 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -5,6 +5,12 @@ MWMechanics::AiEscort::AiEscort(const std::string &actorId,int duration, float x : mActorId(actorId), mX(x), mY(y), mZ(z), mDuration(duration) { } + +MWMechanics::AiEscort::AiEscort(const std::string &actorId,const std::string &cellId,int duration, float x, float y, float z) +: mActorId(actorId), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration) +{ +} + MWMechanics::AiEscort *MWMechanics::AiEscort::clone() const { diff --git a/apps/openmw/mwmechanics/aiescort.hpp b/apps/openmw/mwmechanics/aiescort.hpp index fef70f508e..d89a9586ce 100644 --- a/apps/openmw/mwmechanics/aiescort.hpp +++ b/apps/openmw/mwmechanics/aiescort.hpp @@ -10,6 +10,10 @@ namespace MWMechanics { public: AiEscort(const std::string &actorId,int duration, float x, float y, float z); + ///< \implement AiEscort + AiEscort(const std::string &actorId,const std::string &cellId,int duration, float x, float y, float z); + ///< \implement AiEscortCell + virtual AiEscort *clone() const; virtual bool execute (const MWWorld::Ptr& actor); @@ -19,6 +23,7 @@ namespace MWMechanics private: std::string mActorId; + std::string mCellId; float mX; float mY; float mZ; diff --git a/apps/openmw/mwmechanics/aifollow.cpp b/apps/openmw/mwmechanics/aifollow.cpp index 3fee6d98c3..dab9e02839 100644 --- a/apps/openmw/mwmechanics/aifollow.cpp +++ b/apps/openmw/mwmechanics/aifollow.cpp @@ -5,6 +5,11 @@ MWMechanics::AiFollow::AiFollow(const std::string &actorId,float duration, float : mDuration(duration), mX(x), mY(y), mZ(z), mActorId(actorId) { } +MWMechanics::AiFollow::AiFollow(const std::string &actorId,const std::string &cellId,float duration, float x, float y, float z) +: mDuration(duration), mX(x), mY(y), mZ(z), mActorId(actorId), mCellId(cellId) +{ +} + MWMechanics::AiFollow *MWMechanics::AiFollow::clone() const { return new AiFollow(*this); diff --git a/apps/openmw/mwmechanics/aifollow.hpp b/apps/openmw/mwmechanics/aifollow.hpp index ded13d7800..0b37b0a2d9 100644 --- a/apps/openmw/mwmechanics/aifollow.hpp +++ b/apps/openmw/mwmechanics/aifollow.hpp @@ -11,6 +11,7 @@ namespace MWMechanics { public: AiFollow(const std::string &ActorId,float duration, float X, float Y, float Z); + AiFollow(const std::string &ActorId,const std::string &CellId,float duration, float X, float Y, float Z); virtual AiFollow *clone() const; virtual bool execute (const MWWorld::Ptr& actor); ///< \return Package completed? @@ -21,7 +22,8 @@ namespace MWMechanics float mX; float mY; float mZ; - std::string mActorId; + std::string mActorId; + std::string mCellId; }; } #endif diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index 787962ad1e..a4108c17e4 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -10,6 +10,11 @@ #include "../mwworld/class.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/aiactivate.hpp" +#include "../mwmechanics/aiescort.hpp" +#include "../mwmechanics/aifollow.hpp" +#include "../mwmechanics/aitravel.hpp" +#include "../mwmechanics/aiwander.hpp" #include "interpretercontext.hpp" #include "ref.hpp" @@ -20,6 +25,27 @@ namespace MWScript { namespace Ai { + template<class R> + class OpAiActivate : public Interpreter::Opcode1 + { + public: + + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string objectID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + // discard additional arguments (reset), because we have no idea what they mean. + for (unsigned int i=0; i<arg0; ++i) runtime.pop(); + + MWMechanics::AiActivate activatePackage(objectID); + MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(activatePackage); + std::cout << "AiActivate" << std::endl; + } + }; + template<class R> class OpAiTravel : public Interpreter::Opcode1 { @@ -41,6 +67,9 @@ namespace MWScript // discard additional arguments (reset), because we have no idea what they mean. for (unsigned int i=0; i<arg0; ++i) runtime.pop(); + MWMechanics::AiTravel travelPackage(x, y, z); + MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(travelPackage); + std::cout << "AiTravel: " << x << ", " << y << ", " << z << std::endl; } }; @@ -54,7 +83,7 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - std::string actor = runtime.getStringLiteral (runtime[0].mInteger); + std::string actorID = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); Interpreter::Type_Float duration = runtime[0].mFloat; @@ -72,6 +101,47 @@ namespace MWScript // discard additional arguments (reset), because we have no idea what they mean. for (unsigned int i=0; i<arg0; ++i) runtime.pop(); + MWMechanics::AiEscort escortPackage(actorID, duration, x, y, z); + MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(escortPackage); + + std::cout << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration + << std::endl; + } + }; + + template<class R> + class OpAiEscortCell : public Interpreter::Opcode1 + { + public: + + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string actorID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + std::string cellID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Float duration = runtime[0].mFloat; + runtime.pop(); + + Interpreter::Type_Float x = runtime[0].mFloat; + runtime.pop(); + + Interpreter::Type_Float y = runtime[0].mFloat; + runtime.pop(); + + Interpreter::Type_Float z = runtime[0].mFloat; + runtime.pop(); + + // discard additional arguments (reset), because we have no idea what they mean. + for (unsigned int i=0; i<arg0; ++i) runtime.pop(); + + MWMechanics::AiEscort escortPackage(actorID, cellID, duration, x, y, z); + MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(escortPackage); + std::cout << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration << std::endl; } @@ -86,7 +156,7 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = 0; + Interpreter::Type_Integer value = MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().isPackageDone(); runtime.push (value); } @@ -101,19 +171,28 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); -// Interpreter::Type_Float range = runtime[0].mFloat; + Interpreter::Type_Integer range = runtime[0].mFloat; runtime.pop(); -// Interpreter::Type_Float duration = runtime[0].mFloat; + Interpreter::Type_Integer duration = runtime[0].mFloat; runtime.pop(); -// Interpreter::Type_Float time = runtime[0].mFloat; + Interpreter::Type_Integer time = runtime[0].mFloat; runtime.pop(); - // discard additional idle arguments for now + std::vector<int> idleList; + for (unsigned int i=0; i<arg0; ++i) { + Interpreter::Type_Integer idleValue = runtime[0].mFloat; + idleList.push_back(idleValue); + runtime.pop(); + } + // discard additional arguments (reset), because we have no idea what they mean. for (unsigned int i=0; i<arg0; ++i) runtime.pop(); + MWMechanics::AiWander wanderPackage(range, duration, time, idleList); + MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(wanderPackage); + std::cout << "AiWanter" << std::endl; } }; @@ -182,6 +261,113 @@ namespace MWScript } }; + template<class R> + class OpAiFollow : public Interpreter::Opcode1 + { + public: + + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string actorID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Float duration = runtime[0].mFloat; + runtime.pop(); + + Interpreter::Type_Float x = runtime[0].mFloat; + runtime.pop(); + + Interpreter::Type_Float y = runtime[0].mFloat; + runtime.pop(); + + Interpreter::Type_Float z = runtime[0].mFloat; + runtime.pop(); + + // discard additional arguments (reset), because we have no idea what they mean. + for (unsigned int i=0; i<arg0; ++i) runtime.pop(); + + MWMechanics::AiFollow followPackage(actorID, duration, x, y ,z); + MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(followPackage); + + std::cout << "AiFollow: " << actorID << ", " << x << ", " << y << ", " << z << ", " << duration + << std::endl; + } + }; + + template<class R> + class OpAiFollowCell : public Interpreter::Opcode1 + { + public: + + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string actorID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + std::string cellID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Float duration = runtime[0].mFloat; + runtime.pop(); + + Interpreter::Type_Float x = runtime[0].mFloat; + runtime.pop(); + + Interpreter::Type_Float y = runtime[0].mFloat; + runtime.pop(); + + Interpreter::Type_Float z = runtime[0].mFloat; + runtime.pop(); + + // discard additional arguments (reset), because we have no idea what they mean. + for (unsigned int i=0; i<arg0; ++i) runtime.pop(); + + MWMechanics::AiFollow followPackage(actorID, cellID, duration, x, y ,z); + MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().stack(followPackage); + std::cout << "AiFollow: " << actorID << ", " << x << ", " << y << ", " << z << ", " << duration + << std::endl; + } + }; + + template<class R> + class OpGetCurrentAIPackage : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + + Interpreter::Type_Integer value = MWWorld::Class::get (ptr).getCreatureStats (ptr).getAiSequence().getTypeId (); + + runtime.push (value); + } + }; + + template<class R> + class OpGetDetected : public Interpreter::Opcode1 + { + public: + + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string actorID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Integer value = false; // TODO replace with implementation + + std::cout << "AiGetDetected: " << actorID << ", " << value << std::endl; + + runtime.push (value); + } + }; + const int opcodeAiTravel = 0x20000; const int opcodeAiTravelExplicit = 0x20001; @@ -189,8 +375,20 @@ namespace MWScript const int opcodeAiEscortExplicit = 0x20003; const int opcodeGetAiPackageDone = 0x200007c; const int opcodeGetAiPackageDoneExplicit = 0x200007d; + const int opcodeGetCurrentAiPackage = 0x20001b1; + const int opcodeGetCurrentAiPackageExplicit = 0x20001b2; + const int opcodeGetDetected = 0x20001b3; + const int opcodeGetDetectedExplicit = 0x20001b4; const int opcodeAiWander = 0x20010; const int opcodeAiWanderExplicit = 0x20011; + const int opcodeAIActivate = 0x20018; + const int opcodeAIActivateExplicit = 0x20019; + const int opcodeAiEscortCell = 0x2001a; + const int opcodeAiEscortCellExplicit = 0x2001b; + const int opcodeAiFollow = 0x2001c; + const int opcodeAiFollowExplicit = 0x2001d; + const int opcodeAiFollowCell = 0x2001e; + const int opcodeAiFollowCellExplicit = 0x2001f; const int opcodeSetHello = 0x200015e; const int opcodeSetHelloExplicit = 0x200015d; const int opcodeSetFight = 0x200015e; @@ -202,16 +400,26 @@ namespace MWScript void registerExtensions (Compiler::Extensions& extensions) { + extensions.registerInstruction ("aiactivate", "c/l", opcodeAIActivate, + opcodeAIActivateExplicit); extensions.registerInstruction ("aitravel", "fff/l", opcodeAiTravel, opcodeAiTravelExplicit); extensions.registerInstruction ("aiescort", "cffff/l", opcodeAiEscort, opcodeAiEscortExplicit); + extensions.registerInstruction ("aiescortcell", "ccffff/l", opcodeAiEscortCell, + opcodeAiEscortCellExplicit); extensions.registerInstruction ("aiwander", "fff/llllllllll", opcodeAiWander, opcodeAiWanderExplicit); - + extensions.registerInstruction ("aifollow", "cffff/l", opcodeAiFollow, + opcodeAiFollowExplicit); + extensions.registerInstruction ("aifollowcell", "ccffff/l", opcodeAiFollowCell, + opcodeAiFollowCellExplicit); extensions.registerFunction ("getaipackagedone", 'l', "", opcodeGetAiPackageDone, opcodeGetAiPackageDoneExplicit); - + extensions.registerFunction ("getcurrentaipackage", 'l', "", opcodeGetCurrentAiPackage, + opcodeGetAiPackageDoneExplicit); + extensions.registerFunction ("getdetected", 'l', "c", opcodeGetDetected, + opcodeGetDetectedExplicit); extensions.registerInstruction ("sethello", "l", opcodeSetHello, opcodeSetHelloExplicit); extensions.registerInstruction ("setfight", "l", opcodeSetFight, opcodeSetFightExplicit); extensions.registerInstruction ("setflee", "l", opcodeSetFlee, opcodeSetFleeExplicit); @@ -220,15 +428,26 @@ namespace MWScript void installOpcodes (Interpreter::Interpreter& interpreter) { + interpreter.installSegment3 (opcodeAIActivate, new OpAiActivate<ImplicitRef>); + interpreter.installSegment3 (opcodeAIActivateExplicit, new OpAiActivate<ExplicitRef>); interpreter.installSegment3 (opcodeAiTravel, new OpAiTravel<ImplicitRef>); interpreter.installSegment3 (opcodeAiTravelExplicit, new OpAiTravel<ExplicitRef>); interpreter.installSegment3 (opcodeAiEscort, new OpAiEscort<ImplicitRef>); interpreter.installSegment3 (opcodeAiEscortExplicit, new OpAiEscort<ExplicitRef>); + interpreter.installSegment3 (opcodeAiEscortCell, new OpAiEscortCell<ImplicitRef>); + interpreter.installSegment3 (opcodeAiEscortCellExplicit, new OpAiEscortCell<ExplicitRef>); interpreter.installSegment3 (opcodeAiWander, new OpAiWander<ImplicitRef>); interpreter.installSegment3 (opcodeAiWanderExplicit, new OpAiWander<ExplicitRef>); + interpreter.installSegment3 (opcodeAiFollow, new OpAiFollow<ImplicitRef>); + interpreter.installSegment3 (opcodeAiFollowExplicit, new OpAiFollow<ExplicitRef>); + interpreter.installSegment3 (opcodeAiFollowCell, new OpAiFollowCell<ImplicitRef>); + interpreter.installSegment3 (opcodeAiFollowCellExplicit, new OpAiFollowCell<ExplicitRef>); interpreter.installSegment5 (opcodeGetAiPackageDone, new OpGetAiPackageDone<ImplicitRef>); - interpreter.installSegment5 (opcodeGetAiPackageDoneExplicit, - new OpGetAiPackageDone<ExplicitRef>); + interpreter.installSegment5 (opcodeGetAiPackageDoneExplicit, new OpGetAiPackageDone<ExplicitRef>); + interpreter.installSegment5 (opcodeGetCurrentAiPackage, new OpGetCurrentAIPackage<ImplicitRef>); + interpreter.installSegment5 (opcodeGetCurrentAiPackageExplicit, new OpGetCurrentAIPackage<ExplicitRef>); + interpreter.installSegment3 (opcodeGetDetected, new OpGetDetected<ImplicitRef>); + interpreter.installSegment3 (opcodeGetDetectedExplicit, new OpGetDetected<ExplicitRef>); interpreter.installSegment5 (opcodeSetHello, new OpSetHello<ImplicitRef>); interpreter.installSegment5 (opcodeSetHelloExplicit, new OpSetHello<ExplicitRef>); interpreter.installSegment5 (opcodeSetFight, new OpSetFight<ImplicitRef>); diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index b130aa9547..19517ac8d3 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -37,7 +37,15 @@ op 0x20014: SetPCFacRep op 0x20015: SetPCFacRep, explicit reference op 0x20016: ModPCFacRep op 0x20017: ModPCFacRep, explicit reference -op s 0x20018-0x3ffff unused +op 0x20018: AIActivate +op 0x20019: AIActivate, explicit reference +op 0x2001a: AiEscortCell +op 0x2001b: AiEscortCell, explicit reference +op 0x2001c: AiFollow +op 0x2001d: AiFollow, explicit reference +op 0x2001e: AiFollowCell +op 0x2001f: AiFollowCell, explicit reference +op s 0x20020-0x3ffff unused Segment 4: (not implemented yet) @@ -226,5 +234,9 @@ op 0x20001ad: SetReputation op 0x20001ae: ModReputation op 0x20001af: SetReputation, explicit op 0x20001b0: ModReputation, explicit -opcodes 0x20001b1-0x3ffffff unused +op 0x20001b1: GetCurrentAIPackage +op 0x20001b2: GetCurrentAIPackage, explicit reference +op 0x20001b3: GetDetected +op 0x20001b4: GetDetected, explicit reference +opcodes 0x20001b5-0x3ffffff unused From 42e0501c671b2034f5d6f8a7c90dc85f34d1dd51 Mon Sep 17 00:00:00 2001 From: scrawl <scrawl@baseoftrash.de> Date: Thu, 3 Jan 2013 02:40:21 +0100 Subject: [PATCH 2/2] fix typo --- apps/openmw/mwscript/docs/vmformat.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 8a09135179..89cacf65cb 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -4,7 +4,7 @@ Segment 0: (not implemented yet) opcodes 0x20-0x3f unused -Segment 1:< +Segment 1: (not implemented yet) opcodes 0x20-0x3f unused