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;