-
Notifications
You must be signed in to change notification settings - Fork 38
/
attackerbehaviour.lua
167 lines (151 loc) · 4.54 KB
/
attackerbehaviour.lua
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
shard_include( "attackers" )
local SpGetUnitNearestEnemy = Spring.GetUnitNearestEnemy
function IsAttacker(unit)
for i,name in ipairs(attackerlist) do
if name == unit:Internal():Name() then
return true
end
end
return false
end
AttackerBehaviour = class(Behaviour)
function AttackerBehaviour:Init()
--self.ai.game:SendToConsole("attacker!")
--self.game:AddMarker({ x = startPosx, y = startPosy, z = startPosz }, "my start position")
CMD.MOVE_STATE = 50
end
function AttackerBehaviour:Update()
local unitID = self.unit:Internal().id
-- Spring.Echo(unitID)
local myRange = Spring.GetUnitMaxRange(unitID)
local closestUnit = Spring.GetUnitNearestEnemy(unitID, myRange)
local allyTeamID = self.ai.allyId
if Spring.GetGameFrame() % 15 == 4 then
if closestUnit and (Spring.IsUnitInLos(closestUnit, allyTeamID)) then
local enemyRange = Spring.GetUnitMaxRange(closestUnit)
if myRange > enemyRange then
local ex,ey,ez = Spring.GetUnitPosition(closestUnit)
local ux,uy,uz = Spring.GetUnitPosition(unitID)
local pointDis = Spring.GetUnitSeparation(unitID,closestUnit)
local dis = 120
local f = dis/pointDis
if (pointDis+dis > Spring.GetUnitMaxRange(unitID)) then
f = (Spring.GetUnitMaxRange(unitID)-pointDis)/pointDis
end
local cx = ux+(ux-ex)*f
local cy = uy
local cz = uz+(uz-ez)*f
self.unit:Internal():ExecuteCustomCommand(CMD.MOVE, {cx, cy, cz})
end
end
end
end
function AttackerBehaviour:OwnerBuilt()
self.ai.attackhandler:AddRecruit(self)
self.unit:Internal():ExecuteCustomCommand(CMD.MOVE_STATE, { 2 }, {})
self.attacking = true
self.active = true
end
function AttackerBehaviour:OwnerDead()
self.ai.attackhandler:RemoveRecruit(self)
end
function AttackerBehaviour:OwnerIdle()
self.attacking = true
self.active = true
self.ai.attackhandler:AddRecruit(self)
end
function AttackerBehaviour:AttackCell(cell)
local unit = self.unit:Internal()
local unitID = unit.id
local teamID = ai.id
local r = math.random(0,1000)
if r == 0 then
local ec = Spring.GetTeamResources(ai.id, "energy")
if ec > 100 then
Spring.GiveOrderToUnit(unitID, 31337, {}, {})
end
end
--attack
if unitID%60 == Spring.GetGameFrame()%60 then
local currenthealth = unit:GetHealth()
local maxhealth = unit:GetMaxHealth()
local startPosx, startPosy, startPosz = Spring.GetTeamStartPosition(self.ai.id)
local startBoxMinX, startBoxMinZ, startBoxMaxX, startBoxMaxZ = Spring.GetAllyTeamStartBox(self.ai.allyId)
local ec, es = Spring.GetTeamResources(ai.id, "energy")
local closestUnit = Spring.GetUnitNearestEnemy(unitID, 50000, false)
local ex,ey,ez = Spring.GetUnitPosition(closestUnit)
local enemyDis = Spring.GetUnitSeparation(unitID,closestUnit)
if (currenthealth >= maxhealth or currenthealth > 3000) and closestUnit then
if enemyDis < 1500 then
Spring.GiveOrderToUnit(unitID, CMD.CLOAK, { 1 }, {})
else
Spring.GiveOrderToUnit(unitID, CMD.CLOAK, { 0 }, {})
end
p = api.Position()
p.x = ex
p.z = ez
p.y = ey
self.target = p
self.attacking = true
self.ai.attackhandler:AddRecruit(self)
if self.active then
self.unit:Internal():MoveAndFire(self.target)
else
self.unit:ElectBehaviour()
end
--retreat
else
local nanotcx, nanotcy, nanotcz = GG.GetClosestNanoTC(unitID)
if enemyDis < 1500 then
Spring.GiveOrderToUnit(unitID, CMD.CLOAK, { 1 }, {})
else
Spring.GiveOrderToUnit(unitID, CMD.CLOAK, { 0 }, {})
end
if nanotcx and nanotcy and nanotcz then
p = api.Position()
p.x, p.y, p.z = nanotcx, nanotcy, nanotcz
elseif startBoxMinX == 0 and startBoxMinZ == 0 and startBoxMaxZ == Game.mapSizeZ and startBoxMaxX == Game.mapSizeX then
p = api.Position()
p.x = startPosx
p.z = startPosz
p.y = 0
else
p = api.Position()
p.x = math.random(startBoxMinX, startBoxMaxX)
p.z = math.random(startBoxMinZ, startBoxMaxZ)
p.y = 0
end
self.target = p
self.attacking = false
self.ai.attackhandler:AddRecruit(self)
if self.active then
self.unit:Internal():Move(self.target)
else
self.unit:ElectBehaviour()
end
end
end
end
function AttackerBehaviour:Priority()
if not self.attacking then
return 0
else
return 100
end
end
function AttackerBehaviour:Activate()
self.active = true
if self.target then
self.unit:Internal():MoveAndFire(self.target)
self.target = nil
self.ai.attackhandler:AddRecruit(self)
else
self.ai.attackhandler:AddRecruit(self)
end
end
function AttackerBehaviour:OwnerDied()
self.ai.attackhandler:RemoveRecruit(self)
self.attacking = nil
self.active = nil
self.unit = nil
end