From 5841d23f54995b3937249d2cc18f4a8548103310 Mon Sep 17 00:00:00 2001
From: Allanis <allanis@saracraft.net>
Date: Sat, 23 Feb 2013 17:53:31 +0000
Subject: [PATCH] [Change] Sanitized lua ai api a little.

---
 scripts/ai/merchant.lua |  51 +++++++++---------
 scripts/ai/pirate.lua   |  68 +++++++++++------------
 scripts/ai/test.lua     |  60 ++++++++++-----------
 src/ai.c                | 116 ++++++++++++++++++++--------------------
 src/ai.h                |   2 +-
 5 files changed, 149 insertions(+), 148 deletions(-)

diff --git a/scripts/ai/merchant.lua b/scripts/ai/merchant.lua
index 1459aa6..46c2403 100644
--- a/scripts/ai/merchant.lua
+++ b/scripts/ai/merchant.lua
@@ -3,63 +3,66 @@ control_rate = 2
 
 -- Required "control" function.
 function control()
-  if taskname() == "none" then
-    planet = getrndplanet()
-    pushtask(0, "go", planet)
+  if ai.taskname() == "none" then
+    planet = ai.rndplanet()
+    ai.pushtask(0, "go", planet)
   end
 end
 
 -- Required "attacked" function.
 function attacked(attacker)
-  if taskname() ~= "runaway" then
+  if ai.taskname() ~= "runaway" then
     -- Let's have some messages.
-    num = rng(0,3)
+    num = ai.rnd(0,3)
     if num == 0 then msg = "Mayday! We are under attack!"
     elseif num == 1 then msg = "Requesting assistance! Some scoundral is attacking us!"
     elseif num == 2 then msg = "Merchant vessle under attack here! HALP!"
     end
-    if msg then broadcast(msg) end
+    if msg then ai.broadcast(msg) end
 
     -- So bravely run away!
-    pushtask(0, "runaway", attacker)
+    ai.pushtask(0, "runaway", attacker)
   end
 end
 
 -- Runs away.
 function runaway()
-  target = gettargetid()
-  dir = face(target, 1)
-  accel()
+  target = ai.targetid()
+  dir = ai.face(target, 1)
+  ai.accel()
 end
 
 -- Fly to the target.
 function go()
-  target = gettarget()
-  dir = face(target)
-  dist = getdist(target)
-  bdist = minbrakedist()
+  target = ai.target()
+  dir = ai.face(target)
+  dist = ai.dist(target)
+  bdist = ai.minbrakedist()
   if dir < 10 and dist > bdist then
-    accel()
+    ai.accel()
   elseif dir < 10 and dist < bdist then
-    poptask()
-    pushtask(0, "stop")
+    ai.poptask()
+    ai.pushtask(0, "stop")
   end
 end
 
 -- Backthrust.
 function stop()
-  brake()
-  if isstopped() then
-    poptask()
-    settimer(0, rng(8000, 15000))
-    pushtask(0, "land")
+  ai.brake()
+  if ai.isstopped() then
+		ai.stop()
+    ai.poptask()
+    ai.settimer(0, ai.rnd(8000, 15000))
+    ai.pushtask(0, "land")
+	else
+		ai.brake()
   end
 end
 
 --Waits.
 function land()
-  if timeup(0) then
-    pushtask(0, "runaway", player)
+  if ai.timeup(0) then
+    ai.pushtask(0, "runaway", player)
   end
 end
 
diff --git a/scripts/ai/pirate.lua b/scripts/ai/pirate.lua
index abfd37c..a13117d 100644
--- a/scripts/ai/pirate.lua
+++ b/scripts/ai/pirate.lua
@@ -3,112 +3,112 @@ control_rate = 2
 
 -- Required "control" function.
 function control()
-  task = taskname()
+  task = ai.taskname()
 
   -- Running pilot has healed up some.
   if task == "runaway" then
-    if parmour() == 100 then
+    if ai.parmour() == 100 then
       -- "attack" should be called after "runaway".
-      poptask()
+      ai.poptask()
     end
 
     -- Nothing to do.
   elseif task ~= "attack" and task ~= "runaway" then
     -- If getenemy() is 0, there is no enemy around.
-    enemy = getenemy()
-    if parmour() == 100 and enemy ~= 0 then
+    enemy = ai.getenemy()
+    if ai.parmour() == 100 and enemy ~= 0 then
       -- Taunts.
-      num = rng(0,4)
+      num = ai.rnd(0,4)
       if num == 0 then msg "Prepare to be boarded!"
       elseif num == 1 then msg = "Whoa! Lookie what we found here!"
       elseif num == 2 then msg = "What's a ship like you doing in a place like this?"
       end
-      comm(enemy,msg)
+      ai.comm(enemy,msg)
 
       -- Make hostile to the enemy (mainly, player! YOU!).
-      hostile(enemy)
+      ai.hostile(enemy)
 
       -- Go ahead and attack.
-      combat() -- Set to be in combat.
-      pushtask(0, "attack", enemy) -- Begin the attack.
+      ai.combat() -- Set to be in combat.
+      ai.pushtask(0, "attack", enemy) -- Begin the attack.
     -- Nothing to attack.
     else
-      pushtask(0, "fly")
+      ai.pushtask(0, "fly")
     end
   end
 end
 
 -- Required "attacked" function
 function attacked(attacker)
-  task = taskname()
+  task = ai.taskname()
 
   -- Pirate isn't fighting or fleeing already.
   if task ~= "attack" and task ~= "runaway" then
     taunt(attacker)
-    pushtask(0, "attack", attacker)
+    ai.pushtask(0, "attack", attacker)
   -- Pirate is fighting bit switches to new target (doesn't forget the old on though).
   elseif task == "attack" then
-    if gettargetid() ~= attacker then
-      pushtask(0, "attack", attacker)
+    if ai.targetid() ~= attacker then
+      ai.pushtask(0, "attack", attacker)
     end
   end
 end
 
 function taunt(target)
-  num = rng(0,4)
+  num = ai.rnd(0,4)
   if num == 0 then msg = "How dare you attack me?!"
   elseif num == 1 then msg = "Aha! You think you can best ME?!"
   elseif num == 2 then msg = "JUST! DIE!"
   elseif num == 3 then msg = "Ohh, You're not going to enjoy this!"
   end
-  if msg then comm(target, msg) end
+  if msg then ai.comm(target, msg) end
 end
 
 -- Run away from the target.
 function runaway()
-  target = gettargerid()
+  target = ai.targerid()
 
   -- Ensure target exists.
-  if not exists(targe) then
-    poptask()
+  if not ai.exists(target) then
+    ai.poptask()
     return
   end
 
-  dir = face(target, 1)
-  accel()
+  dir = ai.face(target, 1)
+  ai.accel()
 end
 
 -- Attack the target.
 function attack()
-  target = gettargetid()
+  target = ai.targetid()
 
   -- Ensure target exists.
-  if not exists(target) then
-    poptask()
+  if not ai.exists(target) then
+    ai.poptask()
     return
   end
 
-  dir = face(target)
-  dist = getdist(getpos(target))
+  dir = ai.face(target)
+  dist = ai.dist(ai.pos(target))
 
   -- We need to know when to run away.
-  if parmour() < 70 then
-    pushtask(0, "runaway", target)
+  if ai.parmour() < 70 then
+    ai.pushtask(0, "runaway", target)
   -- Try to obliterate the target.
   elseif dir < 10 and dist > 300 then
-    accel()
+    ai.accel()
   elseif dir < 10 and dist < 300 then
-    shoot()
+    ai.shoot()
   end
 end
 
 -- Fly to the player. Pointless until hyperspace is implemented.
 function fly()
   target = player
-  dir = face(target)
-  dist = getdist(getpos(target))
+  dir = ai.face(target)
+  dist = ai.dist(ai.pos(target))
   if dir < 10 and dist > 300 then
-    accel()
+    ai.accel()
   end
 end
 
diff --git a/scripts/ai/test.lua b/scripts/ai/test.lua
index c8a26f5..0e36b60 100644
--- a/scripts/ai/test.lua
+++ b/scripts/ai/test.lua
@@ -3,88 +3,88 @@ control_rate = 2
 
 -- Required "control" function.
 function control()
-  if taskname() == "none" then
-    pushtask(0, "fly")
+  if ai.taskname() == "none" then
+    ai.pushtask(0, "fly")
   end
 end
 
 -- Required "attacked" function.
 function attacked(attacker)
-  task = taskname()
+  task = ai.taskname()
   if task ~= "attack" and task ~= "runaway" then
     -- Let's have some taunts.
     taunt(attacker)
 
     -- Now pilot fights back.
-    pushtask(0, "attack", attacker)
+    ai.pushtask(0, "attack", attacker)
   elseif task == "attack" then
-    if gettargetid() ~= attacker then
-      pushtask(0, "attack", attacker)
+    if ai.targetid() ~= attacker then
+      ai.pushtask(0, "attack", attacker)
     end
   end
 end
 
 -- Taunts.
 function taunt(target)
-  num = rng(0,4)
+  num = ai.rnd(0,4)
   if num == 0 then msg = "You will never kill me!"
   elseif num == 1 then msg = "DIE!"
   elseif num == 2 then msg = "You won't survive!"
   elseif num == 3 then msg = "I hate you!"
   end
-  if msg then comm(attacker, msg) end
+  if msg then ai.comm(attacker, msg) end
 end
 
 -- Runs away.
 function runaway()
-  target = gettargetid()
+  target = ai.targetid()
 
   -- Make sure pilot exists.
-  if not exists(target) then
-    poptask()
+  if not ai.exists(target) then
+    ai.poptask()
     return
   end
 
-  dir = face(target, 1)
-  accel()
+  dir = ai.face(target, 1)
+  ai.accel()
 end
 
 -- Attack
 function attack()
-  target = gettargetid()
+  target = ai.targetid()
 
   -- Make sure target exists.
-  if not exists(target) then
-    poptask()
+  if not ai.exists(target) then
+    ai.poptask()
     return
   end
 
-  dir = face(target)
-  dist = getdist(getpos(target))
-  second = secondary()
+  dir = ai.face(target)
+  dist = ai.dist(ai.pos(target))
+  second = ai.secondary()
 
-  if secondary() == "Launcher" then
-    settarget(target)
-    shoot(2)
+  if ai.secondary() == "Launcher" then
+    ai.settarget(target)
+    ai.shoot(2)
   end
 
-  if parmour() < 70 then
-    poptask()
-    pushtask(0, "runaway", target)
+  if ai.parmour() < 70 then
+    ai.poptask()
+    ai.pushtask(0, "runaway", target)
   elseif dir < 10 and dist > 300 then
-    accel()
+    ai.accel()
   elseif dir < 10 and dist < 300 then
-    shoot()
+    ai.shoot()
   end
 end
 
 -- Fly to the player.
 function fly()
   target = player
-  dir = face(target)
-  dist = getdist(getpos(target))
+  dir = ai.face(target)
+  dist = ai.dist(ai.pos(target))
   if dir < 10 and dist > 300 then
-    accel()
+    ai.accel()
   end
 end
 
diff --git a/src/ai.c b/src/ai.c
index 9d39d40..bed3140 100644
--- a/src/ai.c
+++ b/src/ai.c
@@ -46,6 +46,10 @@
 //      (task).
 // ============================================================
 
+// FUCK LUA!!!
+#define luaL_register(L,n,l) (luaL_openlib(L, (n),(l), 0))
+// Creates a new lua table.
+#define newtable(L)						(lua_newtable(L), lua_gettop(L))
 // Call the AI function with name f.
 #define AI_LCALL(f)           (lua_getglobal(L, f), lua_pcall(L, 0, 0, 0))
 // Register a number constant n to name s (syntax is just like lua_regfunc).
@@ -117,6 +121,7 @@ static int ai_brake(lua_State* L);              // Brake()
 static int ai_getnearestplanet(lua_State* L);   // pointer getnearestplanet()
 static int ai_getrndplanet(lua_State* L);       // pointer getrndplanet()
 static int ai_hyperspace(lua_State* L);         // [number] hyperspace()
+static int ai_stop(lua_State* L);								// stop()
 // Combat.
 static int ai_combat(lua_State* L);             // combat(number)
 static int ai_settarget(lua_State* L);          // settarget(number)
@@ -128,11 +133,51 @@ static int ai_hostile(lua_State* L);            // hostile(number).
 static int ai_settimer(lua_State* L);           // settimer(number, number)
 static int ai_timeup(lua_State* L);             // boolean timeup(number)
 // Misc.
-static int ai_createvect(lua_State* L);         // createvect(number, number)
 static int ai_comm(lua_State* L);               // comm(string)
 static int ai_broadcast(lua_State* L);          // broadcast(string)
 static int ai_rng(lua_State* L);                // rng(number, number)
 
+static const luaL_Reg ai_methods[] = {
+	{ "pushtask", 						ai_pushtask 				},
+	{ "poptask", 							ai_poptask  				},
+	{ "taskname",							ai_taskname 				},
+	{ "exists",								ai_exists						},
+	{ "ismaxvel",							ai_ismaxvel					},
+	{ "isstopped",						ai_isstopped				},
+	{ "isenemy",							ai_isenemy					},
+	{ "isally",								ai_isally						},
+	{ "incombat",							ai_incombat					},
+	{ "target",								ai_gettarget				},
+	{ "targetid",							ai_gettargetid			},
+	{ "armour",								ai_armour						},
+	{ "shield",								ai_shield						},
+	{ "parmour", 							ai_parmour					},
+	{ "pshield",							ai_pshield					},
+	{ "dist",									ai_getdistance			},
+	{ "pos",									ai_getpos						},
+	{ "minbrakedist",					ai_minbrakedist			},
+	{ "nearestplanet",				ai_getnearestplanet	},
+	{ "rndplanet",						ai_getrndplanet			},
+	{ "accel",								ai_accel						},
+	{ "turn",									ai_turn							},
+	{ "face",									ai_face							},
+	{ "brake",								ai_brake						},
+	{ "stop", 								ai_stop							},
+	{ "hyperspace",						ai_hyperspace				},
+	{ "combat",								ai_combat						},
+	{ "settarget",						ai_settarget				},
+	{ "secondary",						ai_secondary				},
+	{ "shoot",								ai_shoot						},
+	{ "getenemy",							ai_getenemy					},
+	{ "hostile",							ai_hostile					},
+	{ "settime",							ai_settimer					},
+	{ "timeup",								ai_timeup						},
+	{	"comm", 								ai_comm							},
+	{ "broadcast",						ai_broadcast				},
+	{ "rnd",									ai_rng							},
+	{ 0, 0 } // End.
+};
+
 // Current pilot "thinking" and assorted variables.
 static Pilot* cur_pilot     = NULL;
 static double pilot_acc     = 0.;
@@ -197,51 +242,7 @@ static int ai_loadProfile(char* filename) {
   lua_regnumber(L, "player", PLAYER_ID); // Player id.
 
   // Register C funstions in Lua.
-  // Tasks.
-  lua_regfunc(L, "pushtask",           ai_pushtask);
-  lua_regfunc(L, "poptask",            ai_poptask);
-  lua_regfunc(L, "taskname",           ai_taskname);
-  // Consult.
-  lua_regfunc(L, "gettarget",          ai_gettarget);
-  lua_regfunc(L, "gettargetid",        ai_gettargetid);
-  lua_regfunc(L, "armour",             ai_armour);
-  lua_regfunc(L, "shield",             ai_shield);
-  lua_regfunc(L, "parmour",            ai_parmour);
-  lua_regfunc(L, "pshield",            ai_pshield);
-  lua_regfunc(L, "getdist",            ai_getdistance);
-  lua_regfunc(L, "getpos",             ai_getpos);
-  lua_regfunc(L, "minbrakedist",       ai_minbrakedist);
-  // Boolean.
-  lua_regfunc(L, "exists",             ai_exists);
-  lua_regfunc(L, "ismaxvel",           ai_ismaxvel);
-  lua_regfunc(L, "isstopped",          ai_isstopped);
-  lua_regfunc(L, "isenemy",            ai_isenemy);
-  lua_regfunc(L, "isally",             ai_isally);
-  lua_regfunc(L, "incombat",           ai_incombat);
-  // Movement.
-  lua_regfunc(L, "accel",              ai_accel);
-  lua_regfunc(L, "turn",               ai_turn);
-  lua_regfunc(L, "face",               ai_face);
-  lua_regfunc(L, "brake",              ai_brake);
-  lua_regfunc(L, "getnearestplanet",   ai_getnearestplanet);
-  lua_regfunc(L, "getrndplanet",       ai_getrndplanet);
-  lua_regfunc(L, "hyperspace",         ai_hyperspace);
-  // Combat.
-  lua_regfunc(L, "combat",             ai_combat);
-  lua_regfunc(L, "settarget",          ai_settarget);
-  lua_regfunc(L, "secondary",          ai_secondary);
-  lua_regfunc(L, "shoot",              ai_shoot);
-  lua_regfunc(L, "getenemy",           ai_getenemy);
-  lua_regfunc(L, "hostile",            ai_hostile);
-  // Timers.
-  lua_regfunc(L, "settimer",           ai_settimer);
-  lua_regfunc(L, "timeup",             ai_timeup);
-  // Misc.
-  lua_regfunc(L, "createvect",         ai_createvect);
-  lua_regfunc(L, "comm",               ai_comm);
-  lua_regfunc(L, "broadcast",          ai_broadcast);
-  lua_regfunc(L, "rng",                ai_rng);
-
+	luaL_register(L, "ai", ai_methods);
 
   // Now load the file, since all the functions have been previously loaded.
   buf = pack_readfile(DATA, filename, &bufsize);
@@ -676,6 +677,16 @@ static int ai_hyperspace(lua_State* L) {
   return 1;
 }
 
+// Completely stop the pilot if it is below minimum vel error. (No instant stops.)
+static int ai_stop(lua_State* L) {
+	(void)L; // Just avoid a gcc warning.
+
+	if(VMOD(cur_pilot->solid->vel) < MIN_VEL_ERR)
+		vect_pset(&cur_pilot->solid->vel, 0., 0.);
+	
+	return 0;
+}
+
 // Toggle combat flag. Default is on.
 static int ai_combat(lua_State* L) {
   int i;
@@ -774,19 +785,6 @@ static int ai_timeup(lua_State* L) {
   return 1;
 }
 
-// Create a vector.
-static int ai_createvect(lua_State* L) {
-  MIN_ARGS(2);
-  Vec2* v = MALLOC_L(Vec2);
-  double x = (lua_isnumber(L, 1)) ? (double)lua_tonumber(L,1) : 0.;
-  double y = (lua_isnumber(L, 2)) ? (double)lua_tonumber(L,2) : 0.;
-
-  vect_cset(v, x, y);
-
-  lua_pushlightuserdata(L, v);
-  return 1;
-}
-
 // Have the pilot say something to player.
 static int ai_comm(lua_State* L) {
   MIN_ARGS(2);
diff --git a/src/ai.h b/src/ai.h
index 0ba1fdf..1e70c68 100644
--- a/src/ai.h
+++ b/src/ai.h
@@ -3,7 +3,7 @@
 
 #define MIN_DIR_ERR 1.0*M_PI/180.
 #define MAX_DIR_ERR 0.1*M_PI/180.
-#define MIN_VEL_ERR 0.5
+#define MIN_VEL_ERR 1.0
 
 
 // Max number of AI timers.