-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.mnd
202 lines (188 loc) · 6.27 KB
/
main.mnd
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
#set target = ML7AS; // Mindcode Logic version 7 (revision A) standard processors
#set remarks = active; // Remarks (///) are included in the compiled code and are executed
param unit = @vela; /// Possible units: @vela, @quasar, @pulsar and @nova
param repAppr = 4; /// Approach distance to repair turret
param vaultAppr = 6; /// Approach distance to vault during bomb loading
param idleAppr = 30; /// Approach distance to vault when logic is idle
param angleChange = 30; /// Angle change in carousel logic (more is faster)
do
ubind(unit);
maxHp = @unit.@maxHealth;
maxSpeed = @unit.@speed;
UNITRANGE = @unit.@range;
unitCap = @unit.@itemCapacity;
isDead = @unit.@dead;
loop while isDead == 1; /// Check if the unit is alive to make sure the variable values are correct
minRepHp = maxHp * 0.55; /// Minimum health for repair
maxRepHp = maxHp * 0.98; /// Maximum health for repair
maxRepDist = maxSpeed * 60; /// Maximum distance to repair turret
dangEnemy = maxHp * 0.068; /// Minimum health of a dangerous enemy
defDist = vaultAppr + 10; /// Defense range during repairs and bomb loading
defDistIdle = idleAppr + 5; /// Defense range during idle
enUnitAppr = UNITRANGE * 0.9; /// Approach distance for attacking enemy units
enBuildDist = UNITRANGE * 1.5; /// Attack range to enemy buildings
while true do
ubind(unit);
// Repair logic
unitFlag = @unit.@flag;
if unitFlag == 0 then
hp = @unit.@health;
if hp < maxRepHp then
repTurr = ulocate(building, repair, false, out repX, out repY);
repPower = repTurr.@totalPower;
if repPower > 0 then
isNear = within(repX, repY, defDist);
if isNear == 1 then
approach(repX, repY, repAppr);
autoDef();
continue;
elsif hp <= minRepHp then
isRepNear = within(repX, repY, maxRepDist);
if isRepNear == 1 then
approach(repX, repY, repAppr);
boost(1);
continue;
end;
end;
end;
end;
end;
// Bomb loading logic
items = @unit.@totalItems;
if items < unitCap then
bombType = sorter1.@config;
if bombType != null then
if vault1 != null then
vaultX = vault1.@x;
vaultY = vault1.@y;
approach(vaultX, vaultY, vaultAppr);
isNear = within(vaultX, vaultY, defDist);
if isNear == 1 then
itemTake(vault1, bombType, unitCap);
autoDef();
else
boost(1);
end;
continue;
end;
end;
end;
flag(0); // Reset flag
// Idle logic
isEnabled = switch1.@enabled;
if isEnabled == 0 then
if vault1 == null then // If there is no vault, approach to this processor
idleX = @this.@x;
idleY = @this.@y;
else
idleX = vault1.@x;
idleY = vault1.@y;
end;
isNear = within(idleX, idleY, defDistIdle);
if isNear == 1 then
autoDef();
// Carousel logic
unitX = @unit.@x;
unitY = @unit.@y;
vectorX = unitX - idleX;
vectorY = unitY - idleY;
angle = angle(vectorX, vectorY);
angle += angleChange;
moveX = cos(angle);
moveY = sin(angle);
moveX *= idleAppr;
moveY *= idleAppr;
moveX += idleX;
moveY += idleY;
pathfind(moveX, moveY);
else
approach(idleX, idleY, vaultAppr);
boost(1);
end;
continue;
end;
// Manual control logic
controlled = arc1.@controlled;
if controlled == 2 then
arcX = arc1.@shootX;
arcY = arc1.@shootY;
isNear = within(arcX, arcY, enBuildDist);
if isNear == 1 then
isShooting = arc1.@shooting;
if isShooting == 1 then
attackBuilding(arcX, arcY);
continue;
end;
end;
move(arcX, arcY);
boost(1);
continue;
end;
// Attack logic
enUnit = uradar(enemy, any, any, maxHealth, 1);
if enUnit != null then
enMaxHp = enUnit.@maxHealth;
if enMaxHp >= dangEnemy then
boost(0);
targetp(enUnit, 1);
enemyX = enUnit.@x;
enemyY = enUnit.@y;
approach(enemyX, enemyY, enUnitAppr);
continue;
end;
end;
ulocate(building, turret, true, out turretX, out turretY, out enTurr);
if enTurr == 1 then
isNear = within(turretX, turretY, enBuildDist);
if isNear == 1 then
attackBuilding(turretX, turretY);
continue;
end;
end;
ulocate(building, core, true, out coreX, out coreY);
isNear = within(coreX, coreY, enBuildDist);
if isNear == 1 then
attackBuilding(coreX, coreY);
continue;
end;
ulocate(building, generator, true, out genX, out genY, out enGener);
if enGener == 1 then
isNear = within(genX, genY, enBuildDist);
if isNear == 1 then
attackBuilding(genX, genY);
continue;
end;
end;
// Fly to the nearest enemy base
autoPathfind();
boost(1);
end;
// Automatic defense against enemy units and repair of neighboring allied buildings
void autoDef()
enUnit = uradar(enemy, any, any, distance, 1);
if enUnit != null then
boost(0);
targetp(enUnit, 1);
else
ulocate(damaged, out outX, out outY);
isNear = within(outX, outY, UNITRANGE);
if isNear == 1 then
boost(0);
target(outX, outY, 1);
else
boost(1); // If there are no targets nearby, fly instead of swim
end;
end;
end;
// Attack the enemy building
void attackBuilding(outX, outY)
boost(0);
target(outX, outY, 1);
isBoosted = @unit.@boosting;
if isBoosted == 1 then // Kamikaze attack if can't land
move(outX, outY);
flag(1);
else
approach(outX, outY, UNITRANGE);
end;
end;