1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
--[[
-- Attack utilitiesGeneric attack functions
--]]
--[[
--Attempts to maintain a constant distance from nearby things
--This modulates the distance between the current pilot and its nearest neighbor
--]]
function _atk_keep_distance()
--anticipate this will be added to eliminate potentially silly behavior if it becomes a problem
--local flight_offset = ai.drift_facing()
--find nearest thing
local neighbor = ai.nearestpilot()
if not neighbor or not neighbor:exists() then
return
end
--find the distance based on the direction I'm travelling
local perp_distance = ai.flyby_dist(neighbor)
-- adjust my direction of flight to account for this
-- if pilot is too close, turn away
if perp_distance < 0 and perp_distance > -50 then
ai.turn(1)
elseif perp_distance > 0 and perp_distance < 50 then
ai.turn(-1)
end
end
--[[
-- Tests if the target is seeable (even fuzzy). If no, try to go where it was last seen
-- This is not supra-clean as we are not supposed to know [target:pos()]
-- But the clean way would require to have stored the target position into memory
-- This test should be put in any subtask of the attack task.
--]]
function _atk_check_seeable()
local self = ai.pilot()
local target = ai.target()
-- Pilot still sees the target: continue attack
if self:inrange( target ) then
return true
end
-- Pilots on manual control (in missions or events) never loose target
-- /!\ This is not necessary desirable all the time /!\
-- TODO: there should probably be a flag settable to allow to outwit pilots under manual control
if self:flags().manualcontrol then
return true
end
ai.settarget(self) -- Un-target
ai.poptask()
ai.pushtask("goto", target:pos() )
return false
end
--[[
-- Decides if zigzag is a good option
--]]
function _atk_decide_zz()
-- The situation is the following: we're out of range, facing the target,
-- going towards the target, and someone is shooting on us.
local target = ai.target()
local pilot = ai.pilot()
local range = ai.getweaprange(3)
local dir = ai.idir(target)
local dist = ai.dist( target )
local m, d1 = vec2.polar( pilot:vel() )
local m, d2 = vec2.polar( target:pos() - pilot:pos() )
local d = d1-d2
return ( (dist > (1.1*range)) and (ai.hasprojectile())
and (dir < 10) and (dir > -10) and (d < 10) and (d > -10) )
end
--[[
-- Zig zags towards the target
--]]
function _atk_zigzag()
local target = ai.target()
local range = ai.getweaprange(3)
if (not target:exists()) then
ai.poptask()
return
end
-- See if the enemy is still seeable
if not _atk_check_seeable() then return end
-- Is there something to dodge?
if (not ai.hasprojectile()) then
ai.popsubtask()
return
end
local dist = ai.dist( target )
-- Are we ready to shoot?
if dist < (1.1*range) then
ai.popsubtask()
return
end
local dir = ai.dir(ai.target())
__zigzag(dir, 30)
end
--[[
-- Common control stuff
--]]
function _atk_com_think ()
local target = ai.target()
-- make sure pilot exists
if not target:exists() then
ai.poptask()
return
end
-- Check if is bribed by target
if ai.isbribed(target) then
ai.poptask()
return
end
-- Check if we want to board
if mem.atk_board and ai.canboard(target) then
ai.pushtask("board", target );
return
end
-- Check to see if target is disabled
if not mem.atk_kill and target:flags().disabled then
ai.poptask()
return
end
return target
end
|