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