[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:
parent
db18dd0516
commit
5a87b2da77
@ -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>
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
19
scripts/ai/goddard.lua
Normal 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
|
||||
|
68
scripts/ai/include/attack.lua
Normal file
68
scripts/ai/include/attack.lua
Normal 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
|
||||
|
106
scripts/ai/include/attack_bomber.lua
Normal file
106
scripts/ai/include/attack_bomber.lua
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
5
scripts/ai/tpl/bomber.lua
Normal file
5
scripts/ai/tpl/bomber.lua
Normal 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?!
|
||||
|
92
scripts/ai/tpl/generic.lua
Normal file
92
scripts/ai/tpl/generic.lua
Normal 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
|
||||
|
59
scripts/ai/tpl/merchant.lua
Normal file
59
scripts/ai/tpl/merchant.lua
Normal 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
|
||||
|
@ -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
|
||||
|
70
src/ai.c
70
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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user