diff --git a/dat/fleet.xml b/dat/fleet.xml
index aac64d7..c53636f 100644
--- a/dat/fleet.xml
+++ b/dat/fleet.xml
@@ -1,12 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Fleets>
- <fleet name="Militia Lancelot">
-  <ai>militia</ai>
-  <faction>Militia</faction>
-  <pilots>
-   <pilot chance="100">Lancelot</pilot>
-  </pilots>
- </fleet>
  <fleet name="Goddard Goddard">
   <ai>militia</ai>
   <faction>Goddard</faction>
@@ -15,21 +8,21 @@
   </pilots>
  </fleet>
  <fleet name="Trader Llama">
-  <ai>merchant</ai>
+  <ai>trader</ai>
   <faction>Trader</faction>
   <pilots>
    <pilot chance="100">Llama</pilot>
   </pilots>
  </fleet>
  <fleet name="Trader Mule">
-  <ai>merchant</ai>
+  <ai>trader</ai>
   <faction>Trader</faction>
   <pilots>
    <pilot chance="100">Mule</pilot>
   </pilots>
  </fleet>
  <fleet name="Sml Trader Convoy">
-  <ai>merchant</ai>
+  <ai>trader</ai>
   <faction>Trader</faction>
   <pilots>
    <pilot chance="80">Llama</pilot>
diff --git a/scripts/ai/collective.lua b/scripts/ai/collective.lua
index 341e06a..dde8eb7 100644
--- a/scripts/ai/collective.lua
+++ b/scripts/ai/collective.lua
@@ -1,42 +1,7 @@
-include("../scripts/ai/include/basic.lua")
+include("../scripts/ai/tpl/generic.lua")
 
--- Required control rate.
-control_rate = 0.5
-
-function control()
-  local task = ai.taskname()
-
-  -- Think function for attack.
-  if task == "attack" then
-    attack_think()
-
-  elseif task == "none" then
-    local enemy = ai.getenemy()
-
-  if enemey ~= 0 then
-   ai.pushtask(0, "attack", enemy)
-  else
-    ai.pushtask(0, "hyperspace")
-  end
-  elseif task == "hyperspace" then
-    ai.hyperspace()
- end
-end
-
--- Required "attacked" function.
-function attacked(attacker)
- task = ai.taskname()
- if task ~= "attack" then
-  -- Now pilot fights back.
-  ai.pushtask(0, "attack", attacker)
- 
- elseif task == "attack" then
-  if ai.targetid() ~= attacker then
-   ai.pushtask(0, "attack", attacker)
-  end
- end
-end
-
-function create()
-end
+-- Settings.
+control_rate  = 0.5 -- Lower control rate.
+aggressive    = true
+land_planet   = false
 
diff --git a/scripts/ai/draktharr.lua b/scripts/ai/draktharr.lua
index 027dd3c..fc92d4f 100644
--- a/scripts/ai/draktharr.lua
+++ b/scripts/ai/draktharr.lua
@@ -1,46 +1,15 @@
-include("../scripts/ai/include/basic.lua")
+include("../scripts/ai/tpl/generic.lua")
 
--- Required control rate
-control_rate = 2
+-- Settings.
+aggressive = true
 
--- Required "control" function.
-function control()
- task = ai.taskname()
-
- enemy = ai.getenemy()
- if task ~= "attack" and enemy ~= nil then
-   ai.hostile(enemy)
-  ai.pushtask(0, "attack", enemy)
- elseif task == "none" then
-  planet = ai.landplanet()
-  -- Planet needs to exist..
-  if planet == nil then
-   ai.pushtask(0, "hyperspace")
-  else
-    ai.pushtask(0, "hyperspace")
-    ai.pushtask(0, "land", planet)
-  end
- end
-end
-
-function attacked(attacker)
- task = ai.taskname()
- if task ~= "attack" and task ~= "runaway" then
-  taunt(attacker)
-
-  ai.pushtask(0, "attack", attacker)
- elseif task == "attack" then
-  if ai.targetid() ~= attacker then
-   ai.pushtask(0, "attack", attacker)
-  end
- end
-end
 
 function create()
-  ai.setcredits(rnd.int(1000, ai.shipprice()/100))
+  ai.setcredits(rnd.int(1000, ai.shipprice()/200))
 end
 
-function taunt(target)
+function taunt(target, offense)
+  -- Offense is not actually used.
   taunts = {
     "Prepare for annihilation!",
     "I shall wash my hull with your blood!",
@@ -49,33 +18,3 @@ function taunt(target)
   ai.comm(target, taunts[rnd.int(1, #taunts)])
 end
 
-function go()
- target = ai.target()
- dir = ai.face(target)
- dist = ai.dist(target)
- bdist = ai.minbrakedist()
- if dir < 10 and dist > bdist then
-  ai.accel()
- elseif dir < 10 and dist < bdist then
-  ai.poptask()
-  ai.pushtask(0, "stop")
- end
-end
-
-function stop()
- if ai.isstopped() then
-  ai.stop()
-  ai.poptask()
-  ai.settimer(0, rnd.int(8000, 15000))
-  ai.pushtask(0, "land")
- else
-  ai.brake()
- end
-end
-
-function land()
- if ai.timeup(0) then
-  ai.pushtask(0, "hyperspace")
- end
-end
-
diff --git a/scripts/ai/empire.lua b/scripts/ai/empire.lua
index 0d3aef9..c7901f1 100644
--- a/scripts/ai/empire.lua
+++ b/scripts/ai/empire.lua
@@ -1,55 +1,12 @@
-include("../scripts/ai/include/basic.lua")
+include("../scripts/ai/tpl/generic.lua")
 
--- Required control rate
-control_rate = 2
-
--- Required "control" function.
-function control()
-  local task = ai.taskname()
-  local enemy = ai.getenemy()
-
-  -- Think for attacking.
-  if task == "attack" then
-    attack_think()
-
-  -- Enemy sighted.
-  elseif enemy ~= nil then
-   ai.pushtask(0, "attack", enemy)
-
- -- Enter hyperspace if possible.
- elseif task == "hyperspace" then
-   ai.hyperspace() -- Try to hyperspace.
-
- -- Get new task.
- else
-  planet = ai.landplanet()
-  -- Planet needs to exist..
-  if planet == nil then
-   ai.pushtask(0, "hyperspace")
-  else
-    ai.pushtask(0, "hyperspace")
-    ai.pushtask(0, "land", planet)
-  end
- end
-end
-
-function attacked(attacker)
- task = ai.taskname()
- if task ~= "attack" and task ~= "runaway" then
-  taunt(attacker)
-
-  ai.pushtask(0, "attack", attacker)
- elseif task == "attack" then
-  if ai.targetid() ~= attacker then
-   ai.pushtask(0, "attack", attacker)
-  end
- end
-end
+-- Settings.
+armour_run    = 40
+armour_return = 70
+aggressive    = true
 
 function create()
- if rnd.int(0,2)==0 then -- More money, but less often.
   ai.setcredits(rnd.int(1000, ai.shipprice()/70))
- end
  if rnd.int(0,2)==0 then
   ai.broadcast("The Empire is watching")
  end
@@ -65,33 +22,3 @@ function taunt(target)
   ai.comm(target, taunts[rnd.int(1, #taunts)])
 end
 
-function go()
- target = ai.target()
- dir = ai.face(target)
- dist = ai.dist(target)
- bdist = ai.minbrakedist()
- if dir < 10 and dist > bdist then
-  ai.accel()
- elseif dir < 10 and dist < bdist then
-  ai.poptask()
-  ai.pushtask(0, "stop")
- end
-end
-
-function stop()
- if ai.isstopped() then
-  ai.stop()
-  ai.poptask()
-  ai.settimer(0, rnd.int(8000, 15000))
-  ai.pushtask(0, "land")
- else
-  ai.brake()
- end
-end
-
-function land()
- if ai.timeup(0) then
-  ai.pushtask(0, "hyperspace")
- end
-end
-
diff --git a/scripts/ai/goddard.lua b/scripts/ai/goddard.lua
new file mode 100644
index 0000000..0350f76
--- /dev/null
+++ b/scripts/ai/goddard.lua
@@ -0,0 +1,19 @@
+include("../scripts/ai/tpl/generic.lua")
+
+-- Settings.
+aggressive = true
+
+function create()
+  ai.setcredits(rnd.int(300, ai.shipprice()/70))
+end
+
+function taunt(target, offense)
+  -- Offence is not actually used.
+  taunts = {
+    "Prepare to face annihilation!",
+    "I shall wash my hull in your blood!",
+    "Your head will make a great trophy!"
+  }
+  ai.comm(target, taunts[rnd.int(1, #taunts)])
+end
+
diff --git a/scripts/ai/include/attack.lua b/scripts/ai/include/attack.lua
new file mode 100644
index 0000000..fb9f99f
--- /dev/null
+++ b/scripts/ai/include/attack.lua
@@ -0,0 +1,68 @@
+--[[
+--  Generic attack functions.
+--]]
+
+function attack_think()
+
+end
+
+--[[
+--  Generic "brute force" attack. Doesn't really do anything interesting.
+--]]
+function attack()
+  target = ai.targetid()
+  ai.hostile(target) -- Mark as hostile.
+
+  -- Make sure pilot exists.
+  if not ai.exists(target) then
+    ai.poptask()
+    return
+  end
+  ai.settarget(target)
+
+  -- Get stats about enemy.
+  dist = ai.dist(ai.pos(target)) -- Get distance.
+  range = ai.getweaprange()
+
+  if dist > range then
+    dir = ai.face(target) -- Normal face the target.
+
+    secondary, special, ammo = ai.secondary("Launcher")
+
+    -- Shoot missiles if in range.
+    if secondary == "Launcher" and
+        dist < ai.getweaprange(1) then
+      -- More lenient with aiming.
+      if special == "Smart" and dir < 30 then
+        ai.shoot(2)
+
+      -- Non-smart miss more.
+      elseif dir < 10 then
+        ai.shoot(2)
+      end
+    end
+
+    -- Approach for melee.
+    if dir < 10 then
+      ai.accel()
+    end
+
+  -- Close enough to melee.
+  else
+    secondary, special = ai.secondary("Beam Weapon")
+    dir = ai.aim(target) -- We aim instead of face.
+
+    -- Fire non-smart secondary weapons.
+    if(secondary == "Launcher" and special ~= "Smart") or
+        secondary == "Beam Weapon" then
+      if dir < 10 or special == "Turret" then -- Need good accuracy.
+        ai.shoot(2)
+      end
+    end
+
+    if dir < 10 or ai.hasturrets() then
+      ai.shoot()
+    end
+  end
+end
+
diff --git a/scripts/ai/include/attack_bomber.lua b/scripts/ai/include/attack_bomber.lua
new file mode 100644
index 0000000..224e03e
--- /dev/null
+++ b/scripts/ai/include/attack_bomber.lua
@@ -0,0 +1,106 @@
+--[[
+--  Attack functions for bombers.
+--]]
+
+--[[
+--  Bombers don't really thing, they lock on until target is dead.
+--]]
+function attack_think()
+  -- No thinking atm.
+end
+
+--[[
+--  Attack the current target, task pops when target is dead.
+--
+--  Specialized for bomber type craft. AI will try to shoot missiles and such
+--  until out and then they will melee.
+--]]
+function attack()
+  target = ai.targetid()
+  ai.hostile(target) -- Mark as hostile.
+
+  -- Make sure pilot exists.
+  if not ai.exists(target) then
+    ai.poptask()
+    return
+  end
+
+  ai.settarget(target)
+
+  -- Get stats about enemy.
+  dist = ai.dist(ai.pos(target)) -- Get distance.
+
+  -- Get bombing tool.
+  secondary, special = ai.secondary("Launcher")
+  if secondary ~= "Launcher" or special == "Dumb" then -- No launcher, must melee.
+    range = ai.getweaprange()
+
+    -- Must approach.
+    if dist > range then
+      dir = ai.face(target)
+      if dir < 10 then
+        ai.accel()
+      end
+
+    -- Time to shoot!
+    else
+      dir = ai.aim(target) -- We aim instead of face.
+
+      -- Fire secondary.
+      if dir < 10 or special == "Turret" then
+        ai.shoot(1)
+      end
+
+      -- Fire primary.
+      if dir < 10 or ai.hasturrets() then
+        ai.shoot()
+      end
+    end
+    return -- No need to do ranged attack calculations.
+  end
+
+  -- Get ranges relative to bombing weapon of choice.
+  bombrange = ai.getweaprange(1)
+  backoff = bombrange / 4
+
+  if dist > bombrange then
+    dir = ai.face(target)
+    if dir < 10 then
+      ai.accel()
+    end
+
+  -- In bombing range.
+  elseif dist > backoff then
+    dir = ai.face(target)
+
+    -- Shoot missiles if in range.
+    if secondary == "Launcher" and
+      dist < ai.getweaprange(1) then
+
+      -- More lenient with aiming.
+      if special == "Smart" and dir < 30 then
+        ai.shoot(2)
+
+      -- Non-smart miss more.
+      elseif dir < 10 then
+        ai.shoot(2)
+      end
+    end
+
+    -- We don't apprauch, we try to stay away from melee.
+
+  -- Time to break attack and get back to bomb.
+  else
+    range = ai.getweaprange()
+
+    -- Flee
+    ai.face(target, true)
+    ai.accel()
+
+    -- Fire turret if being chased.
+    if dist < range and ai.hasturrets() then
+      ai.shoot()
+    end
+  end
+end
+
diff --git a/scripts/ai/include/basic.lua b/scripts/ai/include/basic.lua
index a314a59..c1d3bb5 100644
--- a/scripts/ai/include/basic.lua
+++ b/scripts/ai/include/basic.lua
@@ -5,104 +5,14 @@
 --  functions and such for each AI.
 --]]
 
---[[
---  Should be run when the pilot is in attack mode, something like:
---  if task == "attack" then attack_think() end
---  in control().
---]]
-function attack_think()
-  local enemy = ai.getenemy()
-  local target = ai.targetid()
-
-  -- Get new target if it's closer.
-  if enemy ~= target then
-    local dist = ai.dist(ai.pos(target))
-    local range = ai.getweaprange()
-
-    -- Shouldn't switch targets if close.
-    if dist > range * 1.3 then
-      ai.poptask()
-      ai.pushtask(0, "attack", enemy)
-    end
-  end
-end
-
---[[
---  Attacks the current target, task pops when target is dead.
---]]
-function attack_default()
-  local target = ai.targetid()
-  ai.hostile(target) -- Mark as hostile.
-
-  -- Make sure pilot exists.
-  if not ai.exists(target) then
-    ai.poptask()
-    return
-  end
-
-  ai.settarget(target)
-
-  -- Get stats about enemy.
-  local dist = ai.dist(ai.pos(target))   -- Get distance.
-  local range = ai.getweaprange()
-
-  -- We first bias towards range.
-  if dist > range then 
-    local dir = ai.face(target) -- Normal face the target.
-
-    local secondary, special = ai.secondary("Launcher")
-
-    -- Shoot missiles if in range.
-    if secondary == "Launcher" and
-        dist < ai.getweaprange(1) then
-      -- More lenient with aiming.
-      if special == "Smart" and dir < 30 then
-        ai.shoot(2)
-
-      -- Non-smart miss more.
-      elseif dir < 10 then
-        ai.shoot(2)
-      end
-    end
-
-    if dir < 10 then
-      ai.accel()
-    end
-
-  -- Close enough to melee.
-  else
-    local secondary, special = ai.secondary("Weapon")
-    local dir = ai.aim(target) -- we aim instead of face.
-
-    -- Fire non-smart secondary weapons.
-    if(secondary == "Launcher" and special ~= "Smart") or
-        secondary == "Beam Weapon" then
-      if dir < 10 or special == "Turret" then -- Need good acuracy.
-        ai.shoot(2)
-      end
-    end
-
-    if dir < 10 or ai.hasturrets() then
-      ai.shoot()
-    end
-  end
-end
-
---[[
---  Set attack function to be default. If you want to override use:
---  attack = attack_<type>
---  Right after including this file.
---]]
-attack = attack_default
-
 --[[
 --  Attempt to land on a planet.
 --]]
 function land()
-  local target = ai.target()
-  local dir = ai.face(target)
-  local dist = ai.dist(target)
-  local bdist = ai.minbrakedist()
+  target = ai.target()
+  dir = ai.face(target)
+  dist = ai.dist(target)
+  bdist = ai.minbrakedist()
 
   -- Need to get closer.
   if dir < 10 and dist > bdist then
@@ -118,7 +28,7 @@ function landstop()
   ai.brake()
 
   if ai.isstopped() then
-    local target = ai.target()
+    target = ai.target()
     ai.stop() -- Will stop the pilot if below err vel.
     ai.settime(0, rnd.int(8000, 15000)) -- We wait during a while.
     ai.poptask()
@@ -127,8 +37,8 @@ function landstop()
 end
 
 function landwait()
-  local target = ai.target()
-  local dist = ai.dist(target)
+  target = ai.target()
+  dist = ai.dist(target)
   
   -- In case for some reason landed far away..
   if dist > 50 then
@@ -144,14 +54,14 @@ end
 --  Attempts to run from the target.
 --]]
 function runaway()
-  local target = ai.targetid()
+  target = ai.targetid()
 
   if not ai.exists(target) then
     ai.poptask()
     return
   end
 
-  local dir = ai.face(target, 1)
+  dir = ai.face(target, 1)
   ai.accel()
 
   --[[
@@ -174,13 +84,13 @@ end
 --
 -- Will need the following in control() to work:
 --
--- local task = ai.taskname()
+-- task = ai.taskname()
 -- if task == "hyperspace" then
 --   ai.hyperspace() -- Try to hyperspace.
 -- end
 --]]
 function hyperspace()
-  local dir = ai.face(-1) -- Face away from (0,0).
+  dir = ai.face(-1) -- Face away from (0,0).
   if(dir < 10) then
     ai.accel()
   end
diff --git a/scripts/ai/militia.lua b/scripts/ai/militia.lua
deleted file mode 100644
index 9674470..0000000
--- a/scripts/ai/militia.lua
+++ /dev/null
@@ -1,68 +0,0 @@
-include("../scripts/ai/include/basic.lua")
-
--- Required control rate
-control_rate = 2
-
--- Required "control" function.
-function control()
- task = ai.taskname()
-
- enemy = ai.getenemy()
- if task ~= "attack" and enemy ~= nil then
-   ai.hostile(enemy)
-  ai.pushtask(0, "attack", enemy)
- elseif ai.taskname() == "none" then
-  ai.pushtask(0, "scan", ai.rndpilot())
- end
-end
-
--- Required "attacked" function
-function attacked(attacker)
- task = ai.taskname()
- if task ~= "attack" and task ~= "runaway" then
-  -- Some taunting.
-  taunt(attacker)
-
-  -- Now pilot fights back!
-  ai.pushtask(0, "attack", attacker)
-
- elseif task == "attack" then
-  if ai.targetid() ~= attaker then
-   ai.pushtack(0, "attack", attacker)
-  end
- end
-end
-
-function create()
- ai.setcredits(rnd.int(1000, ai.shipprice()/200))
- if rnd.int(0, 2)==0 then
-  ai.broadcast("This area is under militia survellance.")
-  end
-end
-
--- Taunts
-function taunt(target)
-  taunts = {
-    "How dare you attack me!?",
-    "YOU! ARE NOT! PREPARED!",
-    "Won't you just die already!?",
-    "You won't survive!"
-  }
-  ai.comm(target, taunts[rnd.int(1, #taunts)])
-end
-
-function scan()
- target = ai.targetid()
- if not ai.exists(target) then
-  ai.poptask()
-  return
- end
- dir = ai.face(target)
- dist = ai.dist(ai.pos(target))
- if dir < 10 and dist > 300 then
-  ai.accel()
- elseif dist < 300 then -- Scan the target.
-  ai.poptask()
- end
-end
-
diff --git a/scripts/ai/pirate.lua b/scripts/ai/pirate.lua
index 2593b55..38a30de 100644
--- a/scripts/ai/pirate.lua
+++ b/scripts/ai/pirate.lua
@@ -1,69 +1,17 @@
-include("../scripts/ai/include/basic.lua")
+include("../scripts/ai/tpl/generic.lua")
 
---Required control rate.
-control_rate = 2
-
--- Required "control" function.
-function control()
-  task = ai.taskname()
-
-  if task == "attack" then
-    if ai.parmour() < 80 then
-      ai.pushtask(0, "runaway", ai.targetid())
-    else
-      attack_think()
-    end
-
-  elseif task == "hyperspace" then
-    ai.hyperspace() -- Try to hyperspace.
-
-  -- Running pilot has healed up some.
-  elseif task == "runaway" then
-    if ai.parmour() == 100 then
-      -- "attack" should be called after "runaway".
-      ai.poptask()
-  elseif ai.dist(ai.pos(ai.targetid())) > 300 then
-   ai.hyperspace()
-  end
-
-  -- Nothing to do.
-  else
-    -- If getenemy() is 0, there is no enemy around.
-    enemy = ai.getenemy()
-    if ai.parmour() == 100 and enemy ~= 0 then
-      taunt(enemy, true)
-      ai.pushtask(0, "attack", enemy) -- Begin the attack.
-    -- Nothing to attack.
-    else
-      ai.pushtask(0, "hyperspace")
-    end
-  end
-end
-
--- Required "attacked" function
-function attacked(attacker)
-  task = ai.taskname()
-
-  -- Pirate isn't fighting or fleeing already.
-  if task ~= "attack" and task ~= "runaway" then
-    taunt(attacker, false)
-    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 ai.targetid() ~= attacker then
-      ai.pushtask(0, "attack", attacker)
-    end
-  end
-end
+-- Settings.
+aggressive      = true
+safe_distance   = 500
+armour_run      = 80
+armour_return   = 100
 
 function create()
- if rnd.int(0,5) ~= 0 then
-  ai.setcredits(0, ai.shipprice()/100)
- end
+  ai.setcredits(ai.shipprice()/1000, ai.shipprice()/100)
 end
 
 function taunt(target, offense)
-  -- Only 50$ of actually taunting.
+  -- Only 50% of actually taunting.
   if rnd.int(0,1) == 0 then
     return
   end
diff --git a/scripts/ai/tpl/bomber.lua b/scripts/ai/tpl/bomber.lua
new file mode 100644
index 0000000..c8dfd3b
--- /dev/null
+++ b/scripts/ai/tpl/bomber.lua
@@ -0,0 +1,5 @@
+include("../scripts/ai/tpl/generic.lua")
+include("../scripts/ai/include/attack_bomber.lua") -- Will override default attack functions.
+
+aggressive = true -- Bombers have to be f*cking aggressive by nature! RIGHT?!
+
diff --git a/scripts/ai/tpl/generic.lua b/scripts/ai/tpl/generic.lua
new file mode 100644
index 0000000..0a432a3
--- /dev/null
+++ b/scripts/ai/tpl/generic.lua
@@ -0,0 +1,92 @@
+include("../scripts/ai/include/basic.lua")
+include("../scripts/ai/include/attack.lua")
+
+--[[
+--  Variables to adjust AI.
+--
+--  These variables can be used to adjust the generic AI to suit other roles.
+--]]
+
+armour_run      = 0     -- At which damage to run at.
+armour_return   = 0     -- At which armour to return to combat.
+shield_run      = 0     -- At which shield to run.
+shield_return   = 0     -- At which shield to return to combat.
+aggressive      = false -- Should pilot actively attack enemies?
+safe_distance   = 300   -- Safe distance from enemies to jump.
+land_planet     = true  -- Should land on planets?
+
+control_rate = 2
+
+function control()
+  task = ai.taskname()
+  enemy = ai.getenemy()
+
+  -- Think for attacking.
+  if task == "attack" then
+    -- 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())
+
+    -- Think like normal.
+    else
+      attack_think()
+    end
+
+  -- Enemy sighted.
+  elseif enemy ~= nil and aggressive then
+    taunt(enemy, true)
+    ai.pushtask(0, "attack", enemy)
+
+  -- Pilot is running away.
+  elseif task == "runaway" then
+    dist = ai.dist(ai.pos(ai.targetid()))
+
+    if aggressive and((shield_return > 0 and ai.pshield() >= shield_return) or
+        (armour_return > 0 and ai.parmour() >= armour_return)) then
+      ai.poptask() -- "attack" should be above "runaway"
+
+    -- Try to jump now.
+    elseif dist > safe_distance then
+      ai.hyperspace()
+    end
+
+  -- Enter hyperspace if possible.
+  elseif task == "hyperspace" then
+    ai.hyperspace() -- Try to hyperspace.
+  else -- Get new task.
+    planet = ai.landplanet()
+    -- Planet must exist.
+    if planet == nil or land_planet == false then
+      ai.pushtask(0, "hyperspace")
+    else
+      ai.pushtask(0, "hyperspace")
+      ai.pushtask(0, "land", planet)
+    end
+  end
+end
+
+function attacked(attacker)
+  task = ai.taskname()
+  if task ~= "attack" and task ~= "runaway" then
+    -- Some taunting
+    taunt(attacker, false)
+
+    -- Now pilot fights back.
+    ai.pushtask(0, "attack", attacker)
+
+  elseif task == "attack" then
+    if ai.targetid() ~= attacker then
+      ai.pushtask(0, "attack", attacker)
+    end
+  end
+end
+
+function create()
+  -- Empty stub.
+end
+
+function taunt(target, offensive)
+  -- Empty stub.
+end
+
diff --git a/scripts/ai/tpl/merchant.lua b/scripts/ai/tpl/merchant.lua
new file mode 100644
index 0000000..e113d8e
--- /dev/null
+++ b/scripts/ai/tpl/merchant.lua
@@ -0,0 +1,59 @@
+include("../scripts/ai/include/basic.lua")
+
+-- Variables.
+enemy_close = 500 -- Distance enemy is too close for comfort.
+
+-- Required control rate.
+control_rate = 2
+
+function control()
+  task = ai.taskname()
+  enemy = ai.getenemy()
+
+  -- Runaway if enemy is near.
+  if task ~= "runaway" and enemy ~= nil and ai.dist(enemy) < enemy_close then
+    if task ~= "none" then
+      ai.poptask()
+    end
+    ai.pushtask(0, "runaway", enemy)
+  elseif task == "hyperspace" then
+    ai.hyperspace() -- Try to hyperspace.
+
+  -- Try to jump when far enough away.
+  elseif task == "runaway" then
+    if ai.dist(ai.pos(ai.targetid())) > 400 then
+      ai.hyperspace()
+    end
+
+  -- Find something to do.
+  elseif task == "none" then
+    planet = ai.landplanet()
+    -- Planet must exist.
+    if planet == nil then
+      ai.pushtask(0, "hyperspace")
+    else
+      ai.pushtask(0, "hyperspace")
+      ai.pushtask(0, "land", planet)
+    end
+  end
+end
+
+function sos()
+
+end
+
+function attacked(attacker)
+  if ai.taskname() ~= "runaway" then
+    sos()
+    -- Sir Robin bravely ran away!!
+    ai.pushtask(0, "runaway", attacker)
+  else
+    ai.poptask()
+    ai.pushtask(0, "runaway", attacker)
+  end
+end
+
+function create()
+
+end
+
diff --git a/scripts/ai/scout.lua b/scripts/ai/tpl/scout.lua
similarity index 94%
rename from scripts/ai/scout.lua
rename to scripts/ai/tpl/scout.lua
index 471081b..45299e3 100644
--- a/scripts/ai/scout.lua
+++ b/scripts/ai/tpl/scout.lua
@@ -1,6 +1,6 @@
 include("../scripts/ai/include/basic.lua")
 
--- Some vars.
+-- Variables.
 planet_dist = 1000  -- Distance to keep from planets.
 enemy_dist  = 700   -- Distance to keep from enemies.
 
@@ -15,7 +15,6 @@ function control()
 
     -- There is an enemy.
     if enemy ~= 0 then
-      -- Make hostile to the enemy (mainly for player).
       if ai.dist(enemy) < enemy_dist or ai.haslockon() then
         ai.pushtask(0, "runaway", enemy)
         return
@@ -63,10 +62,14 @@ end
 -- Required "attacked" function.
 function attacked(attaker)
   task = ai.taskname()
+
+  -- Start running away
   if task ~= "runaway" then
     ai.pushtask(0, "runaway", attacker)
   elseif task == "runaway" then
     if ai.targetid() ~= attacker then
+      -- Runaway from the new guy.
+      ai.poptask()
       ai.pushtask(0, "runaway", attacker)
     end
   end
@@ -87,7 +90,7 @@ end
 -- Approaches the target.
 function approach()
   target = ai.target()
-  dir = ai.face(target)
+  ai.face(target)
   ai.accel()
 end
 
diff --git a/src/ai.c b/src/ai.c
index d0ed28e..3faf700 100644
--- a/src/ai.c
+++ b/src/ai.c
@@ -1,25 +1,3 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-#include <math.h>
-
-#include "lephisto.h"
-#include "log.h"
-#include "pilot.h"
-#include "player.h"
-#include "physics.h"
-#include "pack.h"
-#include "rng.h"
-#include "space.h"
-#include "faction.h"
-#include "llua.h"
-#include "lluadef.h"
-#include "ai.h"
-
 /**
  * @file ai.c
  *
@@ -54,8 +32,35 @@
  *  -- "control" task is also run at a set rate (depending on
  *      Lua global "control_rate") to choose optimal behaviour
  *      (task).
+ *
+ * @todo Clean up most of the code, it was written as one of the first
+ * subsystems and is pretty lacking in quite a few aspects. Notably
+ * removing the entire lightuserdata and actually go with full userdata.
  */
 
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+#include <math.h>
+
+#include "lephisto.h"
+#include "log.h"
+#include "pilot.h"
+#include "player.h"
+#include "physics.h"
+#include "pack.h"
+#include "rng.h"
+#include "space.h"
+#include "faction.h"
+#include "llua.h"
+#include "lluadef.h"
+#include "ai.h"
+
+
 /**
  * @def lua_regnumber(l, s, n)
  *
@@ -782,9 +787,10 @@ static int ai_face(lua_State* L) {
   Vec2* v, sv, tv; /* Grab the position to face. */
   Pilot* p;
   double mod, diff;
-  int invert = 0;
-  int n = -2;
+  int n;
 
+  /* Get first parameter, aka what to face. */
+  n = -2;
   if(lua_isnumber(L, 1))
     n = (int)lua_tonumber(L, 1);
 
@@ -797,8 +803,12 @@ static int ai_face(lua_State* L) {
   else if(lua_islightuserdata(L,1)) v = (Vec2*)lua_topointer(L,1);
 
   mod = 10;
-  if(lua_gettop(L) > 1 && lua_isnumber(L,2)) invert = (int)lua_tonumber(L,2);
-  if(invert) mod *= -1;
+
+  /* Check if must invert. */
+  if(lua_gettop(L) > 1) {
+    if(lua_isboolean(L, 2) && lua_toboolean(L, 2))
+      mod *= -1;
+  }
 
   vect_cset(&sv, VX(cur_pilot->solid->pos), VY(cur_pilot->solid->pos));
 
@@ -813,10 +823,11 @@ static int ai_face(lua_State* L) {
                       (n==-1) ? VANGLE(cur_pilot->solid->pos) :
                                 vect_angle(&cur_pilot->solid->pos, v));
 
+  /* Make pilot turn. */
   pilot_turn = mod*diff;
 
+  /* Return angle in degrees away from target. */
   lua_pushnumber(L, ABS(diff*180./M_PI));
-
   return 1;
 }
 
@@ -1152,7 +1163,10 @@ static int ai_getweaprange(lua_State* L) {
       else
         range = outfit_range(cur_pilot->secondary->outfit);
 
-      if(range < 0.) return 0; /* Secondary doesn't have range. */
+      if(range < 0.) {
+        lua_pushnumber(L, 0.); /* Secondary doesn't have range. */
+        return 1;
+      }
 
       /* Secondary does have range. */
       lua_pushnumber(L, range);
diff --git a/src/pilot.c b/src/pilot.c
index e6c7dd3..3cfede1 100644
--- a/src/pilot.c
+++ b/src/pilot.c
@@ -99,7 +99,8 @@ unsigned int pilot_getNearestEnemy(const Pilot* p) {
   double d, td;
 
   for(tp = 0, d = 0., i = 0; i < pilot_nstack; i++)
-    if(areEnemies(p->faction, pilot_stack[i]->faction)) {
+    if(areEnemies(p->faction, pilot_stack[i]->faction) ||
+        ((pilot_stack[i]->id == PLAYER_ID) && (pilot_isFlag(p, PILOT_HOSTILE)))) {
       td = vect_dist(&pilot_stack[i]->solid->pos, &p->solid->pos);
       if(!pilot_isDisabled(pilot_stack[i]) && ((!tp) || (td < d))) {
         d = td;