[Change] MAJOR AI rehaul, split all the lua stuff into generic templates.

[Add] Bomber attack routines.
[Fix] Bug with AI forgetting about you if another enemy attacks.
This commit is contained in:
Allanis 2013-11-10 05:03:59 +00:00
parent db18dd0516
commit 5a87b2da77
16 changed files with 437 additions and 456 deletions

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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

19
scripts/ai/goddard.lua Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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?!

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;