diff --git a/scripts/ai/include/attack_bomber.lua b/scripts/ai/include/attack_bomber.lua
index 25f16b7..bc7c17a 100644
--- a/scripts/ai/include/attack_bomber.lua
+++ b/scripts/ai/include/attack_bomber.lua
@@ -16,7 +16,7 @@ end
 --  until out and then they will melee.
 --]]
 function atk_b()
-  target = ai.targetid()
+  target = ai.target()
   ai.hostile(target) -- Mark as hostile.
 
   -- Make sure pilot exists.
diff --git a/scripts/ai/include/attack_generic.lua b/scripts/ai/include/attack_generic.lua
index 829e9e5..51129b1 100644
--- a/scripts/ai/include/attack_generic.lua
+++ b/scripts/ai/include/attack_generic.lua
@@ -7,7 +7,7 @@
 --]]
 function atk_g_think()
   enemy = ai.getenemy()
-  target = ai.targetid()
+  target = ai.target()
 
   -- Get new target if it's closer.
   if enemy ~= target then
@@ -26,7 +26,7 @@ end
 --  Generic "brute force" attack. Doesn't really do anything interesting.
 --]]
 function atk_g()
-  target = ai.targetid()
+  target = ai.target()
   ai.hostile(target) -- Mark as hostile.
 
   -- Make sure pilot exists.
diff --git a/scripts/ai/include/basic.lua b/scripts/ai/include/basic.lua
index 83b3335..30c8eee 100644
--- a/scripts/ai/include/basic.lua
+++ b/scripts/ai/include/basic.lua
@@ -53,7 +53,7 @@ end
 --  Attempts to run from the target.
 --]]
 function runaway()
-  target = ai.targetid()
+  target = ai.target()
 
   if not ai.exists(target) then
     ai.poptask()
diff --git a/scripts/ai/tpl/generic.lua b/scripts/ai/tpl/generic.lua
index d85a88e..dfe8403 100644
--- a/scripts/ai/tpl/generic.lua
+++ b/scripts/ai/tpl/generic.lua
@@ -30,7 +30,7 @@ function control()
     -- Runaway if needed.
     if(shield_run > 0 and ai.pshield() < shield_run) or
         (armour_run > 0 and ai.parmour() < armour_run) then
-      ai.pushtask(0, "runaway", ai.targetid())
+      ai.pushtask(0, "runaway", ai.target())
 
     -- Think like normal.
     else
@@ -39,7 +39,7 @@ function control()
 
   -- Pilot is running away.
   elseif task == "runaway" then
-    dist = ai.dist(ai.pos(ai.targetid()))
+    dist = ai.dist(ai.pos(ai.target()))
 
     if aggressive and((shield_return > 0 and ai.pshield() >= shield_return) or
         (armour_return > 0 and ai.parmour() >= armour_return)) then
@@ -71,7 +71,7 @@ function attacked(attacker)
     ai.pushtask(0, "attack", attacker)
 
   elseif task == "attack" then
-    if ai.targetid() ~= attacker then
+    if ai.target() ~= attacker then
       ai.pushtask(0, "attack", attacker)
     end
   end
diff --git a/scripts/ai/tpl/merchant.lua b/scripts/ai/tpl/merchant.lua
index 26b6a71..14f845c 100644
--- a/scripts/ai/tpl/merchant.lua
+++ b/scripts/ai/tpl/merchant.lua
@@ -21,7 +21,7 @@ function control()
 
   -- Try to jump when far enough away.
   elseif task == "runaway" then
-    if ai.dist(ai.pos(ai.targetid())) > 400 then
+    if ai.dist(ai.pos(ai.target())) > 400 then
       ai.hyperspace()
     end
 
diff --git a/scripts/ai/tpl/scout.lua b/scripts/ai/tpl/scout.lua
index 0156971..8ed888a 100644
--- a/scripts/ai/tpl/scout.lua
+++ b/scripts/ai/tpl/scout.lua
@@ -51,7 +51,7 @@ function control()
 
     -- Check if we need to run more.
   elseif task == "runaway" then
-    enemy = ai.targetid()
+    enemy = ai.target()
 
     if ai.dist(enemy) > enemy_dist and ai.haslockon() == false then
       ai.poptask()
@@ -68,7 +68,7 @@ function attacked(attaker)
   if task ~= "runaway" then
     ai.pushtask(0, "runaway", attacker)
   elseif task == "runaway" then
-    if ai.targetid() ~= attacker then
+    if ai.target() ~= attacker then
       -- Runaway from the new guy.
       ai.poptask()
       ai.pushtask(0, "runaway", attacker)
diff --git a/src/ai.c b/src/ai.c
index b07ef5c..7dafe70 100644
--- a/src/ai.c
+++ b/src/ai.c
@@ -120,7 +120,6 @@ static int ai_taskname(lua_State* L);           /* Number taskname. */
 /* Consult values. */
 static int ai_getplayer(lua_State* L);          /* number getPlayer() */
 static int ai_gettarget(lua_State* L);          /* Pointer gettarget() */
-static int ai_gettargetid(lua_State* L);        /* Number gettargetis() */
 static int ai_getrndpilot(lua_State* L);        /* Number getrndpilot() */
 static int ai_armour(lua_State* L);             /* armour() */
 static int ai_shield(lua_State* L);             /* shield() */
@@ -193,7 +192,6 @@ static const luaL_Reg ai_methods[] = {
   /* Get. */
   { "getPlayer",            ai_getplayer        },
   { "target",               ai_gettarget        },
-  { "targetid",             ai_gettargetid      },
   { "rndpilot",             ai_getrndpilot      },
   { "armour",               ai_armour           },
   { "shield",               ai_shield           },
@@ -368,6 +366,7 @@ void ai_destroy(Pilot* p) {
   /* Clean up tasks. */
   if(p->task)
     ai_freetask(p->task);
+  p->task = NULL;
 }
 
 /**
@@ -614,10 +613,12 @@ static void ai_create(Pilot* pilot, char* param) {
 
 /* Free the task. */
 static void ai_freetask(Task* t) {
-  if(t->next) ai_freetask(t->next); /* Woot, recursive freeing! */
+  if(t->next != NULL) {
+    ai_freetask(t->next); /* Woot, recursive freeing! */
+    t->next = NULL;
+  }
 
-  if(t->name)               free(t->name);
-  if(t->dtype == TYPE_PTR)  free(t->dat.target);
+  if(t->name) free(t->name);
   free(t);
 }
 
@@ -644,39 +645,32 @@ static void ai_freetask(Task* t) {
  *        is currently supported.
  */
 static int ai_pushtask(lua_State* L) {
+  LLUA_MIN_ARGS(2);
   int pos;
-  if(lua_isnumber(L, 1)) pos = (int) lua_tonumber(L, 1);
-  else return 0; /* Invalid param. */
+  char* func;
+  Task* t, *pointer;
 
-  Task* t = MALLOC_L(Task);
-  t->name = (lua_isstring(L, 2)) ? strdup((char*) lua_tostring(L, 2)) : NULL;
+  /* Parse basic parameters. */
+  if(lua_isnumber(L, 1)) pos = (int) lua_tonumber(L, 1);
+  else LLUA_INVALID_PARAMETER();
+  if(lua_isstring(L, 2)) func = (char*)lua_tostring(L, 1);
+  else LLUA_INVALID_PARAMETER();
+
+  t = MALLOC_L(Task);
   t->next = NULL;
-  t->dat.target = NULL;
+  t->name = strdup(func);
+  t->dtype = TYPE_NULL;
 
   if(lua_gettop(L) > 2) {
     if(lua_isnumber(L, 3)) {
       t->dtype = TYPE_INT;
-      t->dat.ID = (unsigned int) lua_tonumber(L, 3);
+      t->dat.num = (unsigned int)lua_tonumber(L,3);
     }
-    else if(lua_islightuserdata(L, 3)) {
-      /* Only pointer valid is Vec2* in Lua. */
-      t->dtype = TYPE_PTR;
-      t->dat.target = MALLOC_L(Vec2);
-      /* No idea why vectcpy doesn't work here.. */
-      ((Vec2*)t->dat.target)->x     = ((Vec2*)lua_topointer(L,3))->x;
-      ((Vec2*)t->dat.target)->y     = ((Vec2*)lua_topointer(L,3))->y;
-      ((Vec2*)t->dat.target)->mod   = ((Vec2*)lua_topointer(L,3))->mod;
-      ((Vec2*)t->dat.target)->angle = ((Vec2*)lua_topointer(L,3))->angle;
-    } else
-      t->dtype = TYPE_NULL;
+    else LLUA_INVALID_PARAMETER();
   }
 
-  if(cur_pilot->task == NULL) /* No other tasks. */
-    cur_pilot->task = t;
-  else if(pos == 1) {
-    /* Put at the end. */
-    Task* pointer;
-    for(pointer = cur_pilot->task; pointer->next; pointer = pointer->next);
+  if(pos == 1) { /* Put at the end. */
+    for(pointer = cur_pilot->task; pointer->next != NULL; pointer = pointer->next);
     pointer->next = t;
   } else {
     /* Default put at the beginning. */
@@ -696,13 +690,15 @@ static int ai_pushtask(lua_State* L) {
 static int ai_poptask(lua_State* L) {
   (void)L; /* Just a hack to avoid -W -Wall warnings. */
   Task* t = cur_pilot->task;
-  if(t != NULL) {
-    cur_pilot->task = t->next;
-    t->next = NULL;
-  } else {
+
+  /* Tasks must exist. */
+  if(t == NULL) {
     LLUA_DEBUG("Trying to pop task when there are no tasks in stack");
     return 0;
   }
+
+  cur_pilot->task = t->next;
+  t->next = NULL;
   ai_freetask(t);
   return 0;
 }
@@ -719,22 +715,15 @@ static int ai_getplayer(lua_State* L) {
   return 1;
 }
 
-/* Grab the target pointer. */
+/* Grab the target. */
 static int ai_gettarget(lua_State* L) {
-  if(cur_pilot->task->dtype == TYPE_PTR) {
-    lua_pushlightuserdata(L, cur_pilot->task->dat.target);
-    return 1;
+  switch(cur_pilot->task->dtype) {
+    case TYPE_INT:
+      lua_pushnumber(L, cur_pilot->task->dat.num);
+      return 1;
+    default:
+      return 0;
   }
-  return 0;
-}
-
-/* Get the ID. */
-static int ai_gettargetid(lua_State* L) {
-  if(cur_pilot->task->dtype == TYPE_INT) {
-    lua_pushnumber(L, cur_pilot->task->dat.ID);
-    return 1;
-  }
-  return 0;
 }
 
 static int ai_getrndpilot(lua_State* L) {
diff --git a/src/ai.h b/src/ai.h
index fcfc6e8..0bd6af7 100644
--- a/src/ai.h
+++ b/src/ai.h
@@ -10,7 +10,7 @@
 /* Max number of AI timers. */
 #define MAX_AI_TIMERS 2           /**< Max amount of AI timers. */
 
-typedef enum TaskData_ { TYPE_NULL, TYPE_INT, TYPE_PTR } TaskData;
+typedef enum TaskData_ { TYPE_NULL, TYPE_INT } TaskData;
 
 /**
  * @struct Task
@@ -23,8 +23,7 @@ typedef struct Task_ {
 
   TaskData dtype;       /**< Data type. */
   union {
-    void* target;       /**< Vec2 etc. */
-    unsigned int ID;    /**< Pilot ID etc. */
+    unsigned int num;   /**< Pilot ID, etc... */
   } dat; /**< Stores the data. */
 } Task;