From 19292edd681d4fe68b1daa35390149586f52ae5d Mon Sep 17 00:00:00 2001
From: Allanis <allanis@saracraft.net>
Date: Wed, 22 Jan 2014 15:26:42 +0000
Subject: [PATCH] [Change] Improved AI's secondary weapon handling.

---
 scripts/ai/include/attack_bomber.lua  |  2 +-
 scripts/ai/include/attack_generic.lua |  9 ++-
 src/ai.c                              | 80 +++++++++++++--------------
 3 files changed, 46 insertions(+), 45 deletions(-)

diff --git a/scripts/ai/include/attack_bomber.lua b/scripts/ai/include/attack_bomber.lua
index bc7c17a..9e2c2a0 100644
--- a/scripts/ai/include/attack_bomber.lua
+++ b/scripts/ai/include/attack_bomber.lua
@@ -31,7 +31,7 @@ function atk_b()
   dist = ai.dist(ai.pos(target)) -- Get distance.
 
   -- Get bombing tool.
-  secondary, special = ai.secondary("Launcher")
+  secondary, special = ai.secondary("ranged")
   if secondary ~= "Launcher" or special == "Dumb" then -- No launcher, must melee.
     range = ai.getweaprange()
 
diff --git a/scripts/ai/include/attack_generic.lua b/scripts/ai/include/attack_generic.lua
index 6a65f60..d382598 100644
--- a/scripts/ai/include/attack_generic.lua
+++ b/scripts/ai/include/attack_generic.lua
@@ -66,10 +66,13 @@ end
 -- ]]
 function atk_g_ranged(target, dist)
   dir = ai.face(target) -- Normal face the target.
-  secondary, special, ammo = ai.secondary("Launcher")
+  secondary, special, ammo = ai.secondary("ranged")
+
+  -- Always use figher bay.
+  if secondary == "" then
 
   -- Shoot missiles if in range.
-  if secondary == "Launcher" and
+  elseif secondary == "Launcher" and
         dist < ai.getweaprange(1) then
     -- More lenient with aiming.
     if special == "Smart" and dir < 30 then
@@ -98,7 +101,7 @@ end
 --    Melee the target.
 --]]
 function atk_g_melee(target, dist)
-  secondary, special = ai.secondary("Beam Weapon")
+  secondary, special = ai.secondary("melee")
   dir = ai.aim(target) -- We aim instead of face.
 
   -- Fire non-smart secondary weapons.
diff --git a/src/ai.c b/src/ai.c
index d3ebca7..f85a63b 100644
--- a/src/ai.c
+++ b/src/ai.c
@@ -1260,27 +1260,49 @@ static int ai_settarget(lua_State* L) {
   LLUA_INVALID_PARAMETER();
 }
 
+static int outfit_isMelee(Pilot* p, PilotOutfit* o) {
+  (void)p;
+  if(outfit_isBolt(o->outfit) || outfit_isBeam(o->outfit))
+    return 1;
+  return 0;
+}
+
+static int outfit_isRanged(Pilot* p, PilotOutfit* o) {
+  if(outfit_isFighterBay(o->outfit) || outfit_isLauncher(o->outfit)) {
+    /* Must have ammo. */
+    if(pilot_getAmmo(p, o->outfit) <= 0)
+      return 0;
+    return 1;
+  }
+  return 0;
+}
+
 /* Set the secondary weapon. Biassed towards launchers.. */
 static int ai_secondary(lua_State* L) {
   PilotOutfit* co, *po;
-  int i;
-  char* type;
+  int i, melee;
+  char* str;
   const char* otype;
 
   po = NULL;
 
-  /* Search for a type. */
-  type = NULL;
-  if(lua_isstring(L, 1))
-    type = (char*) lua_tostring(L, 1);
+  /* Parse the parameters. */
+  if(lua_isstring(L, 1)) {
+    str = (char*)lua_tostring(L, 1);
+    if(strcmp(str, "melee")==0)
+      melee = 1;
+    else if(strcmp(str, "ranged")==0)
+      melee = 0;
+    else LLUA_INVALID_PARAMETER();
+  }
+  else LLUA_INVALID_PARAMETER();
 
   /* Pilot has secondary selected - use that. */
   if(cur_pilot->secondary != NULL) {
     co = cur_pilot->secondary;
-    otype = outfit_getTypeBroad(co->outfit);
-
-    /* If we aren't looking for a type or if it matches what we want. */
-    if((type == NULL) || (strcmp(otype, type) == 0))
+    if(melee && outfit_isMelee(cur_pilot, co))
+      po = co;
+    else if(!melee && outfit_isRanged(cur_pilot, co))
       po = co;
   }
 
@@ -1296,38 +1318,14 @@ static int ai_secondary(lua_State* L) {
           outfit_isAmmo(co->outfit))
         continue;
 
-
-      /* Must have ammo. */
-      if(outfit_isLauncher(co->outfit) && pilot_getAmmo(cur_pilot, co->outfit)==0)
-        continue;
-
-      /* Searching for type. */
-      if(type != NULL) {
-        otype = outfit_getTypeBroad(co->outfit);
-        if(strcmp(otype, type)==0) {
-          po = co;
-          break;
-        }
-
-        /* We'll grab the first weapon in case we don't find what we want. */
-        if((po == NULL) && (outfit_isWeapon(co->outfit) ||
-              outfit_isLauncher(co->outfit)))
-          po = co;
+      /* Get the first match. */
+      if(melee && outfit_isMelee(cur_pilot, co)) {
+        po = co;
+        break;
       }
-
-      /* Just grabbing best weapon. */
-      else {
-        /* Grab first weapon or launcher it finds. */
-        if((po == NULL) && (outfit_isBolt(co->outfit) ||
-              outfit_isBeam(co->outfit) ||
-              outfit_isLauncher(co->outfit)))
-          po = co;
-
-        /* Grab launcher over weapon by default. */
-        else if((po != NULL) && (outfit_isBolt(po->outfit) ||
-              outfit_isBeam(po->outfit)) &&
-            outfit_isLauncher(co->outfit))
-          po = co;
+      else if(!melee && outfit_isRanged(cur_pilot, co)) {
+        po = co;
+        break;
       }
     }
   }