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 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
require "common"
local DebugEnabled = false
local function EchoDebug(inStr)
if DebugEnabled then
game:SendToConsole("RaiderBehaviour: " .. inStr)
end
end
local CMD_IDLEMODE = 145
local CMD_MOVE_STATE = 50
local MOVESTATE_ROAM = 2
function IsRaider(unit)
for i,name in ipairs(raiderList) do
if name == unit:Internal():Name() then
return true
end
end
return false
end
RaiderBehaviour = class(Behaviour)
function RaiderBehaviour:Init()
local mtype, network = ai.maphandler:MobilityOfUnit(self.unit:Internal())
self.mtype = mtype
self.name = self.unit:Internal():Name()
local utable = unitTable[self.name]
if self.mtype == "sub" then
self.range = utable.submergedRange
else
self.range = utable.groundRange
end
self.id = self.unit:Internal():ID()
self.disarmer = raiderDisarms[self.name]
if ai.raiderCount[mtype] == nil then
ai.raiderCount[mtype] = 1
else
ai.raiderCount[mtype] = ai.raiderCount[mtype] + 1
end
end
function RaiderBehaviour:UnitDead(unit)
if unit.engineID == self.unit.engineID then
-- game:SendToConsole("raider " .. self.name .. " died")
if self.target then
ai.targethandler:AddBadPosition(self.target, self.mtype)
end
ai.raidhandler:NeedLess(self.mtype)
ai.raiderCount[self.mtype] = ai.raiderCount[self.mtype] - 1
end
end
function RaiderBehaviour:UnitIdle(unit)
if unit.engineID == self.unit.engineID then
self.target = nil
self.evading = false
-- keep planes from landing (i'd rather set land state, but how?)
if self.mtype == "air" then
unit:Internal():Move(RandomAway(unit:Internal():GetPosition(), 500))
end
self.unit:ElectBehaviour()
end
end
function RaiderBehaviour:RaidCell(cell)
EchoDebug(self.name .. " raiding cell...")
if self.unit == nil then
EchoDebug("no raider unit to raid cell with!")
-- ai.raidhandler:RemoveRecruit(self)
elseif self.unit:Internal() == nil then
EchoDebug("no raider unit internal to raid cell with!")
-- ai.raidhandler:RemoveRecruit(self)
else
if self.buildingIDs ~= nil then
ai.raidhandler:IDsWeAreNotRaiding(self.buildingIDs)
end
ai.raidhandler:IDsWeAreRaiding(cell.buildingIDs, self.mtype)
self.buildingIDs = cell.buildingIDs
self.target = RandomAway(cell.pos, self.range * 0.5)
if self.mtype == "air" then
if self.disarmer then
self.unitTarget = cell.disarmTarget
else
self.unitTarget = cell.targets.air.ground
end
EchoDebug("air raid target: " .. tostring(self.unitTarget.unitName))
end
if self.active then
if self.mtype == "air" then
if self.unitTarget ~= nil then
CustomCommand(self.unit:Internal(), CMD_ATTACK, {self.unitTarget.unitID})
end
else
self.unit:Internal():Move(self.target)
end
end
self.unit:ElectBehaviour()
end
end
function RaiderBehaviour:Priority()
if not self.target then
-- revert to scouting
return 0
else
return 100
end
end
function RaiderBehaviour:Activate()
EchoDebug(self.name .. " active")
self.active = true
if self.target then
if self.mtype == "air" then
if self.unitTarget ~= nil then
CustomCommand(self.unit:Internal(), CMD_ATTACK, {self.unitTarget.unitID})
end
else
self.unit:Internal():Move(self.target)
end
end
end
function RaiderBehaviour:Deactivate()
EchoDebug(self.name .. " inactive")
self.active = false
self.target = nil
end
function RaiderBehaviour:Update()
local f = game:Frame()
if not self.active then
if math.mod(f, 89) == 0 then
local unit = self.unit:Internal()
local bestCell = ai.targethandler:GetBestRaidCell(unit)
ai.targethandler:RaiderHere(self)
EchoDebug(self.name .. " targetting...")
if bestCell then
EchoDebug(self.name .. " got target")
self:RaidCell(bestCell)
else
self.target = nil
self.unit:ElectBehaviour()
-- revert to scouting
end
end
else
if math.mod(f, 29) == 0 then
-- attack nearby vulnerables immediately
local unit = self.unit:Internal()
local attackTarget
if ai.targethandler:IsSafePosition(unit:GetPosition(), unit, 1) then
attackTarget = ai.targethandler:NearbyVulnerable(unit)
end
if attackTarget then
CustomCommand(unit, CMD_ATTACK, {attackTarget.unitID})
else
-- evade enemies on the way to the target, if possible
if self.target ~= nil then
local newPos, arrived = ai.targethandler:BestAdjacentPosition(unit, self.target)
ai.targethandler:RaiderHere(self)
if newPos then
EchoDebug(self.name .. " evading")
unit:Move(newPos)
self.evading = true
elseif arrived then
EchoDebug(self.name .. " arrived")
-- if we're at the target
self.evading = false
elseif self.evading then
EchoDebug(self.name .. " setting course to taget")
-- return to course to target after evading
if self.mtype == "air" then
if self.unitTarget ~= nil then
CustomCommand(self.unit:Internal(), CMD_ATTACK, {self.unitTarget.unitID})
end
else
self.unit:Internal():Move(self.target)
end
self.evading = false
end
end
end
end
end
end
-- set all raiders to roam
function RaiderBehaviour:SetMoveState()
local thisUnit = self.unit
if thisUnit then
local floats = api.vectorFloat()
floats:push_back(MOVESTATE_ROAM)
thisUnit:Internal():ExecuteCustomCommand(CMD_MOVE_STATE, floats)
if self.mtype == "air" then
local floats = api.vectorFloat()
floats:push_back(1)
thisUnit:Internal():ExecuteCustomCommand(CMD_IDLEMODE, floats)
end
end
end
|