-
Notifications
You must be signed in to change notification settings - Fork 0
/
repair.nim
94 lines (89 loc) · 3.27 KB
/
repair.nim
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
from fieldbehavior import FieldBehavior
proc initRepair*(): FieldBehavior
from analyze import WorldState
from clusterization import clusterize
from formation_info import FormationInfo
from pf import FieldGrid, applyRepairFields, PointField, gridFromPoint
from vehicles import maxHealthRange, resolve
from model.vehicle_type import VehicleType
from borders import obtainCenter
from fastset import `-`, empty, card, `*`
from tables import `[]`
from utils import Point, debug
proc initRepair(): FieldBehavior =
result.apply = proc (f: var FieldGrid, ws: WorldState, fi: FormationInfo) =
let v = ws.vehicles
let damaged = v.byGroup[fi.group] - v.byHealth[maxHealthRange]
debug("FH: " & $card(v.byHealth[maxHealthRange]))
if damaged.empty and not empty(v.all - v.mine):
return
let arrvs = v.clusterize(v.byType[VehicleType.ARRV] * v.mine)
var healPoints = newSeq[PointField](arrvs.len)
let damagedlen = card(damaged) + 1
let fulllen = fi.units.len()
debug($fi.group & ": " & $damagedlen & " of " & $fulllen &
" damaged units detected!")
var unitscounter = newSeq[int](arrvs.len)
var maxunits = 0
for i, arrv in arrvs.pairs():
let units = v.resolve(arrv)
if maxunits < units.len:
maxunits = units.len
unitscounter[i] = units.len
let center = obtainCenter(units)
healPoints[i].point = center.gridFromPoint()
healPoints[i].power = max(-5.0, min(-2.0, -3*damagedlen/fulllen))
for i, ul in unitscounter.pairs:
healPoints[i].power *= ul/maxunits
f.applyRepairFields(healPoints)
from behavior import Behavior, BehaviorStatus
from model.move import Move
from model.action_type import ActionType
proc initRepairBh*(): Behavior =
var tgridx = -1
var tgridy = -1
var target: Point
proc doreset() =
tgridx = -1
tgridy = -1
result.reset = doreset
result.tick = proc (ws: WorldState, fi: FormationInfo): BehaviorStatus =
let v = ws.vehicles
let damaged = v.byGroup[fi.group] - v.byHealth[maxHealthRange]
debug("FH: " & $card(v.byHealth[maxHealthRange]))
if damaged.empty:
doreset()
return BehaviorStatus.inactive
elif damaged.card/fi.units.len > 0.8:
let arrvs = v.clusterize(v.byType[VehicleType.ARRV] * v.mine)
#let damagedlen = card(damaged)
#let fulllen = fi.units.len()
var maxunits = 0
for i, arrv in arrvs.pairs():
let units = v.resolve(arrv)
let center = obtainCenter(units)
if maxunits < units.len():
maxunits = units.len()
target = center
if maxunits > 0:
let gridx = int(target.x / 16)
let gridy = int(target.y / 16)
let mgridx = int(fi.center.x / 16)
let mgridy = int(fi.center.y / 16)
if mgridx == tgridx and mgridy == tgridy:
return BehaviorStatus.inactive
elif gridx != tgridx or gridy != tgridy:
tgridx = gridx
tgridy = gridy
return BehaviorStatus.act
else:
return BehaviorStatus.hold
else:
doreset()
return BehaviorStatus.inactive
result.action = proc(ws: WorldState, fi: FormationInfo, m: var Move) =
m.action = ActionType.MOVE
m.x = target.x - fi.center.x
m.y = target.y - fi.center.y
tgridx = int(target.x / 16)
tgridy = int(target.y / 16)