branch | webgl |
changeset 9127 | e350500c4edb |
parent 8839 | caa57115d7ea |
parent 9080 | 9b42757d7e71 |
child 9136 | 78f087fd3e5b |
8860:bde641cf53c8 | 9127:e350500c4edb |
---|---|
1 (* |
1 (* |
2 * Hedgewars, a free turn based strategy game |
2 * Hedgewars, a free turn based strategy game |
3 * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com> |
3 * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com> |
4 * |
4 * |
5 * This program is free software; you can redistribute it and/or modify |
5 * This program is free software; you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License as published by |
6 * it under the terms of the GNU General Public License as published by |
7 * the Free Software Foundation; version 2 of the License |
7 * the Free Software Foundation; version 2 of the License |
8 * |
8 * |
18 |
18 |
19 {$INCLUDE "options.inc"} |
19 {$INCLUDE "options.inc"} |
20 |
20 |
21 unit uAIAmmoTests; |
21 unit uAIAmmoTests; |
22 interface |
22 interface |
23 uses SDLh, uConsts, uFloat, uTypes; |
23 uses SDLh, uConsts, uFloat, uTypes, uAIMisc; |
24 const |
24 const |
25 amtest_Rare = $00000001; // check only several positions |
25 amtest_Rare = $00000001; // check only several positions |
26 amtest_NoTarget = $00000002; // each pos, but no targetting |
26 amtest_NoTarget = $00000002; // each pos, but no targetting |
27 |
27 |
28 var windSpeed: real; |
28 var windSpeed: real; |
32 Angle, Power: LongInt; |
32 Angle, Power: LongInt; |
33 ExplX, ExplY, ExplR: LongInt; |
33 ExplX, ExplY, ExplR: LongInt; |
34 AttackPutX, AttackPutY: LongInt; |
34 AttackPutX, AttackPutY: LongInt; |
35 end; |
35 end; |
36 |
36 |
37 function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
37 function TestBazooka(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
38 function TestSnowball(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
38 function TestSnowball(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
39 function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
39 function TestGrenade(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
40 function TestMolotov(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
40 function TestMolotov(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
41 function TestClusterBomb(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
41 function TestClusterBomb(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
42 function TestWatermelon(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
42 function TestWatermelon(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
43 function TestDrillRocket(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
43 function TestDrillRocket(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
44 function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
44 function TestMortar(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
45 function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
45 function TestShotgun(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
46 function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
46 function TestDesertEagle(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
47 function TestSniperRifle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
47 function TestSniperRifle(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
48 function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
48 function TestBaseballBat(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
49 function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
49 function TestFirePunch(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
50 function TestWhip(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
50 function TestWhip(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
51 function TestKamikaze(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
51 function TestKamikaze(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
52 function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
52 function TestAirAttack(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
53 function TestTeleport(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
53 function TestTeleport(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
54 function TestHammer(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
54 function TestHammer(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
55 function TestCake(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
55 function TestCake(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
56 |
56 |
57 type TAmmoTestProc = function (Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
57 type TAmmoTestProc = function (Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
58 TAmmoTest = record |
58 TAmmoTest = record |
59 proc: TAmmoTestProc; |
59 proc: TAmmoTestProc; |
60 flags: Longword; |
60 flags: Longword; |
61 end; |
61 end; |
62 |
62 |
121 (proc: nil; flags: 0), // amIceGun |
121 (proc: nil; flags: 0), // amIceGun |
122 (proc: nil; flags: 0) // amKnife |
122 (proc: nil; flags: 0) // amKnife |
123 ); |
123 ); |
124 |
124 |
125 implementation |
125 implementation |
126 uses uAIMisc, uVariables, uUtils, uGearsHandlers; |
126 uses uVariables, uUtils, uGearsHandlers; |
127 |
127 |
128 function Metric(x1, y1, x2, y2: LongInt): LongInt; inline; |
128 function Metric(x1, y1, x2, y2: LongInt): LongInt; inline; |
129 begin |
129 begin |
130 Metric:= abs(x1 - x2) + abs(y1 - y2) |
130 Metric:= abs(x1 - x2) + abs(y1 - y2) |
131 end; |
131 end; |
132 |
132 |
133 function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
133 function TestBazooka(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
134 var Vx, Vy, r, mX, mY: real; |
134 var Vx, Vy, r, mX, mY: real; |
135 rTime: LongInt; |
135 rTime: LongInt; |
136 EX, EY: LongInt; |
136 EX, EY: LongInt; |
137 valueResult: LongInt; |
137 valueResult: LongInt; |
138 x, y, dX, dY: real; |
138 x, y, dX, dY: real; |
145 rTime:= 350; |
145 rTime:= 350; |
146 ap.ExplR:= 0; |
146 ap.ExplR:= 0; |
147 valueResult:= BadTurn; |
147 valueResult:= BadTurn; |
148 repeat |
148 repeat |
149 rTime:= rTime + 300 + Level * 50 + random(300); |
149 rTime:= rTime + 300 + Level * 50 + random(300); |
150 Vx:= - windSpeed * rTime * 0.5 + (Targ.X + AIrndSign(2) - mX) / rTime; |
150 Vx:= - windSpeed * rTime * 0.5 + (Targ.Point.X + AIrndSign(2) - mX) / rTime; |
151 Vy:= cGravityf * rTime * 0.5 - (Targ.Y + 1 - mY) / rTime; |
151 Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y + 1 - mY) / rTime; |
152 r:= sqr(Vx) + sqr(Vy); |
152 r:= sqr(Vx) + sqr(Vy); |
153 if not (r > 1) then |
153 if not (r > 1) then |
154 begin |
154 begin |
155 x:= mX; |
155 x:= mX; |
156 y:= mY; |
156 y:= mY; |
162 y:= y + dY; |
162 y:= y + dY; |
163 dX:= dX + windSpeed; |
163 dX:= dX + windSpeed; |
164 dY:= dY + cGravityf; |
164 dY:= dY + cGravityf; |
165 dec(t) |
165 dec(t) |
166 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
166 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
167 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t <= 0); |
167 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t <= 0); |
168 |
168 |
169 EX:= trunc(x); |
169 EX:= trunc(x); |
170 EY:= trunc(y); |
170 EY:= trunc(y); |
171 if Level = 1 then |
171 if Level = 1 then |
172 value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand) |
172 value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand) |
173 else value:= RateExplosion(Me, EX, EY, 101); |
173 else value:= RateExplosion(Me, EX, EY, 101); |
174 if value = 0 then |
174 if (value = 0) and (Targ.Kind = gtHedgehog) and (Targ.Score > 0) then |
175 value:= 1024 - Metric(Targ.X, Targ.Y, EX, EY) div 64; |
175 value:= 1024 - Metric(Targ.Point.X, Targ.Point.Y, EX, EY) div 64; |
176 if valueResult <= value then |
176 if valueResult <= value then |
177 begin |
177 begin |
178 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random((Level - 1) * 9)); |
178 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random((Level - 1) * 9)); |
179 ap.Power:= trunc(sqrt(r) * cMaxPower) - random((Level - 1) * 17 + 1); |
179 ap.Power:= trunc(sqrt(r) * cMaxPower) - random((Level - 1) * 17 + 1); |
180 ap.ExplR:= 100; |
180 ap.ExplR:= 100; |
182 ap.ExplY:= EY; |
182 ap.ExplY:= EY; |
183 valueResult:= value |
183 valueResult:= value |
184 end; |
184 end; |
185 end |
185 end |
186 //until (value > 204800) or (rTime > 4250); not so useful since adding score to the drowning |
186 //until (value > 204800) or (rTime > 4250); not so useful since adding score to the drowning |
187 until rTime > 4250; |
187 until rTime > 5050 - Level * 800; |
188 TestBazooka:= valueResult |
188 TestBazooka:= valueResult |
189 end; |
189 end; |
190 |
190 |
191 |
191 |
192 function TestDrillRocket(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
192 function TestDrillRocket(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
193 var Vx, Vy, r, mX, mY: real; |
193 var Vx, Vy, r, mX, mY: real; |
194 rTime: LongInt; |
194 rTime: LongInt; |
195 EX, EY: LongInt; |
195 EX, EY: LongInt; |
196 valueResult: LongInt; |
196 valueResult: LongInt; |
197 x, y, dX, dY: real; |
197 x, y, dX, dY: real; |
208 rTime:= 350; |
208 rTime:= 350; |
209 ap.ExplR:= 0; |
209 ap.ExplR:= 0; |
210 valueResult:= BadTurn; |
210 valueResult:= BadTurn; |
211 repeat |
211 repeat |
212 rTime:= rTime + 300 + Level * 50 + random(300); |
212 rTime:= rTime + 300 + Level * 50 + random(300); |
213 Vx:= - windSpeed * rTime * 0.5 + (Targ.X + AIrndSign(2) - mX) / rTime; |
213 Vx:= - windSpeed * rTime * 0.5 + (Targ.Point.X + AIrndSign(2) - mX) / rTime; |
214 Vy:= cGravityf * rTime * 0.5 - (Targ.Y - 35 - mY) / rTime; |
214 Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y - 35 - mY) / rTime; |
215 r:= sqr(Vx) + sqr(Vy); |
215 r:= sqr(Vx) + sqr(Vy); |
216 if not (r > 1) then |
216 if not (r > 1) then |
217 begin |
217 begin |
218 x:= mX; |
218 x:= mX; |
219 y:= mY; |
219 y:= mY; |
225 y:= y + dY; |
225 y:= y + dY; |
226 dX:= dX + windSpeed; |
226 dX:= dX + windSpeed; |
227 dY:= dY + cGravityf; |
227 dY:= dY + cGravityf; |
228 dec(t) |
228 dec(t) |
229 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
229 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
230 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (y > cWaterLine); |
230 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (y > cWaterLine); |
231 |
231 |
232 if TestCollWithLand(trunc(x), trunc(y), 5) and (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) > 21) then |
232 if TestCollExcludingObjects(trunc(x), trunc(y), 5) and (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) > 21) then |
233 begin |
233 begin |
234 timer := 500; |
234 timer := 500; |
235 t2 := 0.5 / sqrt(sqr(dX) + sqr(dY)); |
235 t2 := 0.5 / sqrt(sqr(dX) + sqr(dY)); |
236 dX := dX * t2; |
236 dX := dX * t2; |
237 dY := dY * t2; |
237 dY := dY * t2; |
238 repeat |
238 repeat |
239 x:= x + dX; |
239 x:= x + dX; |
240 y:= y + dY; |
240 y:= y + dY; |
241 dec(timer); |
241 dec(timer); |
242 until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 22) |
242 until (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 22) |
243 or (x < 0) |
243 or (x < 0) |
244 or (y < 0) |
244 or (y < 0) |
245 or (trunc(x) > LAND_WIDTH) |
245 or (trunc(x) > LAND_WIDTH) |
246 or (trunc(y) > LAND_HEIGHT) |
246 or (trunc(y) > LAND_HEIGHT) |
247 or (not TestCollWithLand(trunc(x), trunc(y), 5)) |
247 or not TestCollExcludingObjects(trunc(x), trunc(y), 5) |
248 or (timer = 0) |
248 or (timer = 0) |
249 end; |
249 end; |
250 EX:= trunc(x); |
250 EX:= trunc(x); |
251 EY:= trunc(y); |
251 EY:= trunc(y); |
252 // Try to prevent AI from thinking firing into water will cause a drowning |
|
253 if (EY < cWaterLine-5) and (Timer > 0) and (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) > 21) then exit(BadTurn); |
|
252 if Level = 1 then |
254 if Level = 1 then |
253 value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand) |
255 value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand) |
254 else value:= RateExplosion(Me, EX, EY, 101); |
256 else value:= RateExplosion(Me, EX, EY, 101); |
255 if valueResult <= value then |
257 if valueResult <= value then |
256 begin |
258 begin |
260 ap.ExplX:= EX; |
262 ap.ExplX:= EX; |
261 ap.ExplY:= EY; |
263 ap.ExplY:= EY; |
262 valueResult:= value-2500 // trying to make it slightly less attractive than a bazooka, to prevent waste. AI could use awareness of weapon count |
264 valueResult:= value-2500 // trying to make it slightly less attractive than a bazooka, to prevent waste. AI could use awareness of weapon count |
263 end; |
265 end; |
264 end |
266 end |
265 until rTime > 4250; |
267 until rTime > 5050 - Level * 800; |
266 TestDrillRocket:= valueResult |
268 TestDrillRocket:= valueResult |
267 end; |
269 end; |
268 |
270 |
269 |
271 |
270 function TestSnowball(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
272 function TestSnowball(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
271 var Vx, Vy, r: real; |
273 var Vx, Vy, r: real; |
272 rTime: LongInt; |
274 rTime: LongInt; |
273 EX, EY: LongInt; |
275 EX, EY: LongInt; |
274 valueResult: LongInt; |
276 valueResult: LongInt; |
275 x, y, dX, dY, meX, meY: real; |
277 x, y, dX, dY, meX, meY: real; |
283 rTime:= 350; |
285 rTime:= 350; |
284 ap.ExplR:= 0; |
286 ap.ExplR:= 0; |
285 valueResult:= BadTurn; |
287 valueResult:= BadTurn; |
286 repeat |
288 repeat |
287 rTime:= rTime + 300 + Level * 50 + random(1000); |
289 rTime:= rTime + 300 + Level * 50 + random(1000); |
288 Vx:= - windSpeed * rTime * 0.5 + ((Targ.X + AIrndSign(2)) - meX) / rTime; |
290 Vx:= - windSpeed * rTime * 0.5 + ((Targ.Point.X + AIrndSign(2)) - meX) / rTime; |
289 Vy:= cGravityf * rTime * 0.5 - (Targ.Y - meY) / rTime; |
291 Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y - meY) / rTime; |
290 r:= sqr(Vx) + sqr(Vy); |
292 r:= sqr(Vx) + sqr(Vy); |
291 if not (r > 1) then |
293 if not (r > 1) then |
292 begin |
294 begin |
293 x:= meX; |
295 x:= meX; |
294 y:= meY; |
296 y:= meY; |
300 y:= y + dY; |
302 y:= y + dY; |
301 dX:= dX + windSpeed; |
303 dX:= dX + windSpeed; |
302 dY:= dY + cGravityf; |
304 dY:= dY + cGravityf; |
303 dec(t) |
305 dec(t) |
304 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
306 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
305 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t <= 0); |
307 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t <= 0); |
306 EX:= trunc(x); |
308 EX:= trunc(x); |
307 EY:= trunc(y); |
309 EY:= trunc(y); |
308 |
310 |
309 value:= RateShove(trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, afTrackFall); |
311 value:= RateShove(Me, trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, afTrackFall); |
310 // LOL copypasta: this is score for digging with... snowball |
312 // LOL copypasta: this is score for digging with... snowball |
311 //if value = 0 then |
313 //if value = 0 then |
312 // value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64; |
314 // value:= - Metric(Targ.Point.X, Targ.Point.Y, EX, EY) div 64; |
313 |
315 |
314 if valueResult <= value then |
316 if valueResult <= value then |
315 begin |
317 begin |
316 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random((Level - 1) * 9)); |
318 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random((Level - 1) * 9)); |
317 ap.Power:= trunc(sqrt(r) * cMaxPower) - random((Level - 1) * 17 + 1); |
319 ap.Power:= trunc(sqrt(r) * cMaxPower) - random((Level - 1) * 17 + 1); |
319 ap.ExplX:= EX; |
321 ap.ExplX:= EX; |
320 ap.ExplY:= EY; |
322 ap.ExplY:= EY; |
321 valueResult:= value |
323 valueResult:= value |
322 end; |
324 end; |
323 end |
325 end |
324 until (rTime > 4250); |
326 until (rTime > 5050 - Level * 800); |
325 TestSnowball:= valueResult |
327 TestSnowball:= valueResult |
326 end; |
328 end; |
327 |
329 |
328 function TestMolotov(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
330 function TestMolotov(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
329 var Vx, Vy, r: real; |
331 var Vx, Vy, r: real; |
330 Score, EX, EY, valueResult: LongInt; |
332 Score, EX, EY, valueResult: LongInt; |
331 TestTime: Longword; |
333 TestTime: Longword; |
332 x, y, dY, meX, meY: real; |
334 x, y, dY, meX, meY: real; |
333 t: LongInt; |
335 t: LongInt; |
337 valueResult:= BadTurn; |
339 valueResult:= BadTurn; |
338 TestTime:= 0; |
340 TestTime:= 0; |
339 ap.ExplR:= 0; |
341 ap.ExplR:= 0; |
340 repeat |
342 repeat |
341 inc(TestTime, 300); |
343 inc(TestTime, 300); |
342 Vx:= (Targ.X - meX) / TestTime; |
344 Vx:= (Targ.Point.X - meX) / TestTime; |
343 Vy:= cGravityf * (TestTime div 2) - Targ.Y - meY / TestTime; |
345 Vy:= cGravityf * (TestTime div 2) - Targ.Point.Y - meY / TestTime; |
344 r:= sqr(Vx) + sqr(Vy); |
346 r:= sqr(Vx) + sqr(Vy); |
345 if not (r > 1) then |
347 if not (r > 1) then |
346 begin |
348 begin |
347 x:= meX; |
349 x:= meX; |
348 y:= meY; |
350 y:= meY; |
352 x:= x + Vx; |
354 x:= x + Vx; |
353 y:= y + dY; |
355 y:= y + dY; |
354 dY:= dY + cGravityf; |
356 dY:= dY + cGravityf; |
355 dec(t) |
357 dec(t) |
356 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or |
358 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or |
357 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 6))) or (t = 0); |
359 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 6))) or (t = 0); |
358 EX:= trunc(x); |
360 EX:= trunc(x); |
359 EY:= trunc(y); |
361 EY:= trunc(y); |
360 if t < 50 then |
362 if t < 50 then |
361 Score:= RateExplosion(Me, EX, EY, 97) // average of 17 attempts, most good, but some failing spectacularly |
363 Score:= RateExplosion(Me, EX, EY, 97) // average of 17 attempts, most good, but some failing spectacularly |
362 else |
364 else |
370 ap.ExplX:= EX; |
372 ap.ExplX:= EX; |
371 ap.ExplY:= EY; |
373 ap.ExplY:= EY; |
372 valueResult:= Score |
374 valueResult:= Score |
373 end; |
375 end; |
374 end |
376 end |
375 until (TestTime > 4250); |
377 until (TestTime > 5050 - Level * 800); |
376 TestMolotov:= valueResult |
378 TestMolotov:= valueResult |
377 end; |
379 end; |
378 |
380 |
379 function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
381 function TestGrenade(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
380 const tDelta = 24; |
382 const tDelta = 24; |
381 var Vx, Vy, r: real; |
383 var Vx, Vy, r: real; |
382 Score, EX, EY, valueResult: LongInt; |
384 Score, EX, EY, valueResult: LongInt; |
383 TestTime: Longword; |
385 TestTime: Longword; |
384 x, y, meX, meY, dY: real; |
386 x, y, meX, meY, dY: real; |
389 ap.ExplR:= 0; |
391 ap.ExplR:= 0; |
390 meX:= hwFloat2Float(Me^.X); |
392 meX:= hwFloat2Float(Me^.X); |
391 meY:= hwFloat2Float(Me^.Y); |
393 meY:= hwFloat2Float(Me^.Y); |
392 repeat |
394 repeat |
393 inc(TestTime, 1000); |
395 inc(TestTime, 1000); |
394 Vx:= (Targ.X - meX) / (TestTime + tDelta); |
396 Vx:= (Targ.Point.X - meX) / (TestTime + tDelta); |
395 Vy:= cGravityf * ((TestTime + tDelta) div 2) - (Targ.Y - meY) / (TestTime + tDelta); |
397 Vy:= cGravityf * ((TestTime + tDelta) div 2) - (Targ.Point.Y - meY) / (TestTime + tDelta); |
396 r:= sqr(Vx) + sqr(Vy); |
398 r:= sqr(Vx) + sqr(Vy); |
397 if not (r > 1) then |
399 if not (r > 1) then |
398 begin |
400 begin |
399 x:= meX; |
401 x:= meX; |
400 y:= meY; |
402 y:= meY; |
404 x:= x + Vx; |
406 x:= x + Vx; |
405 y:= y + dY; |
407 y:= y + dY; |
406 dY:= dY + cGravityf; |
408 dY:= dY + cGravityf; |
407 dec(t) |
409 dec(t) |
408 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
410 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
409 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t = 0); |
411 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t = 0); |
410 EX:= trunc(x); |
412 EX:= trunc(x); |
411 EY:= trunc(y); |
413 EY:= trunc(y); |
412 if t < 50 then |
414 if t < 50 then |
413 if Level = 1 then |
415 if Level = 1 then |
414 Score:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand) |
416 Score:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand) |
416 else |
418 else |
417 Score:= BadTurn; |
419 Score:= BadTurn; |
418 |
420 |
419 if (valueResult < Score) and (Score > 0) then |
421 if (valueResult < Score) and (Score > 0) then |
420 begin |
422 begin |
421 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); |
423 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level * 3)); |
422 ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15); |
424 ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 20); |
423 ap.Time:= TestTime; |
425 ap.Time:= TestTime; |
424 ap.ExplR:= 100; |
426 ap.ExplR:= 100; |
425 ap.ExplX:= EX; |
427 ap.ExplX:= EX; |
426 ap.ExplY:= EY; |
428 ap.ExplY:= EY; |
427 valueResult:= Score |
429 valueResult:= Score |
428 end; |
430 end; |
429 end |
431 end |
430 //until (Score > 204800) or (TestTime > 4000); |
432 //until (Score > 204800) or (TestTime > 4000); |
431 until TestTime > 4000; |
433 until TestTime > 4500 - Level * 512; |
432 TestGrenade:= valueResult |
434 TestGrenade:= valueResult |
433 end; |
435 end; |
434 |
436 |
435 function TestClusterBomb(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
437 function TestClusterBomb(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
436 const tDelta = 24; |
438 const tDelta = 24; |
437 var Vx, Vy, r: real; |
439 var Vx, Vy, r: real; |
438 Score, EX, EY, valueResult: LongInt; |
440 Score, EX, EY, valueResult: LongInt; |
439 TestTime: Longword; |
441 TestTime: Longword; |
440 x, y, dY, meX, meY: real; |
442 x, y, dY, meX, meY: real; |
446 meX:= hwFloat2Float(Me^.X); |
448 meX:= hwFloat2Float(Me^.X); |
447 meY:= hwFloat2Float(Me^.Y); |
449 meY:= hwFloat2Float(Me^.Y); |
448 repeat |
450 repeat |
449 inc(TestTime, 900); |
451 inc(TestTime, 900); |
450 // Try to overshoot slightly, seems to pay slightly better dividends in terms of hitting cluster |
452 // Try to overshoot slightly, seems to pay slightly better dividends in terms of hitting cluster |
451 if meX<Targ.X then |
453 if meX<Targ.Point.X then |
452 Vx:= ((Targ.X+10) - meX) / (TestTime + tDelta) |
454 Vx:= ((Targ.Point.X+10) - meX) / (TestTime + tDelta) |
453 else |
455 else |
454 Vx:= ((Targ.X-10) - meX) / (TestTime + tDelta); |
456 Vx:= ((Targ.Point.X-10) - meX) / (TestTime + tDelta); |
455 Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Y-50) - meY) / (TestTime + tDelta); |
457 Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Point.Y-50) - meY) / (TestTime + tDelta); |
456 r:= sqr(Vx)+sqr(Vy); |
458 r:= sqr(Vx)+sqr(Vy); |
457 if not (r > 1) then |
459 if not (r > 1) then |
458 begin |
460 begin |
459 x:= meX; |
461 x:= meX; |
460 y:= meY; |
462 y:= meY; |
464 x:= x + Vx; |
466 x:= x + Vx; |
465 y:= y + dY; |
467 y:= y + dY; |
466 dY:= dY + cGravityf; |
468 dY:= dY + cGravityf; |
467 dec(t) |
469 dec(t) |
468 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
470 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
469 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t = 0); |
471 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t = 0); |
470 EX:= trunc(x); |
472 EX:= trunc(x); |
471 EY:= trunc(y); |
473 EY:= trunc(y); |
472 if t < 50 then |
474 if t < 50 then |
473 Score:= RateExplosion(Me, EX, EY, 41) |
475 Score:= RateExplosion(Me, EX, EY, 41) |
474 else |
476 else |
475 Score:= BadTurn; |
477 Score:= BadTurn; |
476 |
478 |
477 if valueResult < Score then |
479 if Score > 0 then |
478 begin |
480 begin |
479 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); |
481 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level * 2)); |
480 ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15); |
482 ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15); |
481 ap.Time:= TestTime div 1000 * 1000; |
483 ap.Time:= TestTime div 1000 * 1000; |
482 ap.ExplR:= 90; |
484 ap.ExplR:= 90; |
483 ap.ExplX:= EX; |
485 ap.ExplX:= EX; |
484 ap.ExplY:= EY; |
486 ap.ExplY:= EY; |
487 end |
489 end |
488 until (TestTime = 4100); |
490 until (TestTime = 4100); |
489 TestClusterBomb:= valueResult |
491 TestClusterBomb:= valueResult |
490 end; |
492 end; |
491 |
493 |
492 function TestWatermelon(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
494 function TestWatermelon(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
493 const tDelta = 24; |
495 const tDelta = 24; |
494 var Vx, Vy, r: real; |
496 var Vx, Vy, r: real; |
495 Score, EX, EY, valueResult: LongInt; |
497 Score, EX, EY, valueResult: LongInt; |
496 TestTime: Longword; |
498 TestTime: Longword; |
497 x, y, dY, meX, meY: real; |
499 x, y, dY, meX, meY: real; |
502 ap.ExplR:= 0; |
504 ap.ExplR:= 0; |
503 meX:= hwFloat2Float(Me^.X); |
505 meX:= hwFloat2Float(Me^.X); |
504 meY:= hwFloat2Float(Me^.Y); |
506 meY:= hwFloat2Float(Me^.Y); |
505 repeat |
507 repeat |
506 inc(TestTime, 900); |
508 inc(TestTime, 900); |
507 Vx:= (Targ.X - meX) / (TestTime + tDelta); |
509 Vx:= (Targ.Point.X - meX) / (TestTime + tDelta); |
508 Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Y-50) - meY) / (TestTime + tDelta); |
510 Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Point.Y-50) - meY) / (TestTime + tDelta); |
509 r:= sqr(Vx)+sqr(Vy); |
511 r:= sqr(Vx)+sqr(Vy); |
510 if not (r > 1) then |
512 if not (r > 1) then |
511 begin |
513 begin |
512 x:= meX; |
514 x:= meX; |
513 y:= meY; |
515 y:= meY; |
517 x:= x + Vx; |
519 x:= x + Vx; |
518 y:= y + dY; |
520 y:= y + dY; |
519 dY:= dY + cGravityf; |
521 dY:= dY + cGravityf; |
520 dec(t) |
522 dec(t) |
521 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or |
523 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or |
522 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 6))) or (t = 0); |
524 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 6))) or (t = 0); |
523 |
525 |
524 EX:= trunc(x); |
526 EX:= trunc(x); |
525 EY:= trunc(y); |
527 EY:= trunc(y); |
526 if t < 50 then |
528 if t < 50 then |
527 Score:= RateExplosion(Me, EX, EY, 200) + RateExplosion(Me, EX, EY + 120, 200) |
529 Score:= RateExplosion(Me, EX, EY, 200) + RateExplosion(Me, EX, EY + 120, 200) |
563 end |
565 end |
564 else |
566 else |
565 Solve:= 0 |
567 Solve:= 0 |
566 end; |
568 end; |
567 |
569 |
568 function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
570 function TestMortar(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
569 //const tDelta = 24; |
571 //const tDelta = 24; |
570 var Vx, Vy: real; |
572 var Vx, Vy: real; |
571 Score, EX, EY: LongInt; |
573 Score, EX, EY: LongInt; |
572 TestTime: Longword; |
574 TestTime: Longword; |
573 x, y, dY, meX, meY: real; |
575 x, y, dY, meX, meY: real; |
579 meY:= hwFloat2Float(Me^.Y); |
581 meY:= hwFloat2Float(Me^.Y); |
580 |
582 |
581 if (Level > 2) then |
583 if (Level > 2) then |
582 exit(BadTurn); |
584 exit(BadTurn); |
583 |
585 |
584 TestTime:= Solve(Targ.X, Targ.Y, trunc(meX), trunc(meY)); |
586 TestTime:= Solve(Targ.Point.X, Targ.Point.Y, trunc(meX), trunc(meY)); |
585 |
587 |
586 if TestTime = 0 then |
588 if TestTime = 0 then |
587 exit(BadTurn); |
589 exit(BadTurn); |
588 |
590 |
589 Vx:= (Targ.X - meX) / TestTime; |
591 Vx:= (Targ.Point.X - meX) / TestTime; |
590 Vy:= cGravityf * (TestTime div 2) - (Targ.Y - meY) / TestTime; |
592 Vy:= cGravityf * (TestTime div 2) - (Targ.Point.Y - meY) / TestTime; |
591 |
593 |
592 x:= meX; |
594 x:= meX; |
593 y:= meY; |
595 y:= meY; |
594 dY:= -Vy; |
596 dY:= -Vy; |
595 |
597 |
598 y:= y + dY; |
600 y:= y + dY; |
599 dY:= dY + cGravityf; |
601 dY:= dY + cGravityf; |
600 EX:= trunc(x); |
602 EX:= trunc(x); |
601 EY:= trunc(y); |
603 EY:= trunc(y); |
602 until (((Me = CurrentHedgehog^.Gear) and TestColl(EX, EY, 4)) or |
604 until (((Me = CurrentHedgehog^.Gear) and TestColl(EX, EY, 4)) or |
603 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, EX, EY, 4))) or (EY > cWaterLine); |
605 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, EX, EY, 4))) or (EY > cWaterLine); |
604 |
606 |
605 if (EY < cWaterLine) and (dY >= 0) then |
607 if (EY < cWaterLine) and (dY >= 0) then |
606 begin |
608 begin |
607 Score:= RateExplosion(Me, EX, EY, 91); |
609 Score:= RateExplosion(Me, EX, EY, 91); |
608 if (Score = 0) then |
610 if (Score = 0) then |
609 if (dY > 0.15) then |
611 if (dY > 0.15) and (Targ.Kind = gtHedgehog) and (Targ.Score > 0) then |
610 Score:= - abs(Targ.Y - EY) div 32 |
612 Score:= - abs(Targ.Point.Y - EY) div 32 |
611 else |
613 else |
612 Score:= BadTurn |
614 Score:= BadTurn |
613 else if (Score < 0) then |
615 else if (Score < 0) then |
614 Score:= BadTurn |
616 Score:= BadTurn |
615 end |
617 end |
616 else |
618 else |
617 Score:= BadTurn; |
619 Score:= BadTurn; |
618 |
620 |
619 if BadTurn < Score then |
621 if Score > 0 then |
620 begin |
622 begin |
621 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); |
623 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); |
622 ap.Power:= 1; |
624 ap.Power:= 1; |
623 ap.ExplR:= 100; |
625 ap.ExplR:= 100; |
624 ap.ExplX:= EX; |
626 ap.ExplX:= EX; |
625 ap.ExplY:= EY; |
627 ap.ExplY:= EY; |
626 TestMortar:= Score |
628 TestMortar:= Score |
627 end; |
629 end; |
628 end; |
630 end; |
629 |
631 |
630 function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
632 function TestShotgun(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
631 const |
633 const |
632 MIN_RANGE = 80; |
634 MIN_RANGE = 80; |
633 MAX_RANGE = 400; |
635 MAX_RANGE = 400; |
634 var Vx, Vy, x, y: real; |
636 var Vx, Vy, x, y: real; |
635 rx, ry, valueResult: LongInt; |
637 rx, ry, valueResult: LongInt; |
639 ap.ExplR:= 0; |
641 ap.ExplR:= 0; |
640 ap.Time:= 0; |
642 ap.Time:= 0; |
641 ap.Power:= 1; |
643 ap.Power:= 1; |
642 x:= hwFloat2Float(Me^.X); |
644 x:= hwFloat2Float(Me^.X); |
643 y:= hwFloat2Float(Me^.Y); |
645 y:= hwFloat2Float(Me^.Y); |
644 range:= Metric(trunc(x), trunc(y), Targ.X, Targ.Y); |
646 range:= Metric(trunc(x), trunc(y), Targ.Point.X, Targ.Point.Y); |
645 if ( range < MIN_RANGE ) or ( range > MAX_RANGE ) then |
647 if ( range < MIN_RANGE ) or ( range > MAX_RANGE ) then |
646 exit(BadTurn); |
648 exit(BadTurn); |
647 |
649 |
648 Vx:= (Targ.X - x) * 1 / 1024; |
650 Vx:= (Targ.Point.X - x) * 1 / 1024; |
649 Vy:= (Targ.Y - y) * 1 / 1024; |
651 Vy:= (Targ.Point.Y - y) * 1 / 1024; |
650 ap.Angle:= DxDy2AttackAnglef(Vx, -Vy); |
652 ap.Angle:= DxDy2AttackAnglef(Vx, -Vy); |
651 repeat |
653 repeat |
652 x:= x + vX; |
654 x:= x + vX; |
653 y:= y + vY; |
655 y:= y + vY; |
654 rx:= trunc(x); |
656 rx:= trunc(x); |
655 ry:= trunc(y); |
657 ry:= trunc(y); |
656 if ((Me = CurrentHedgehog^.Gear) and TestColl(rx, ry, 2)) or |
658 if ((Me = CurrentHedgehog^.Gear) and TestColl(rx, ry, 2)) or |
657 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, rx, ry, 2)) then |
659 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, rx, ry, 2)) then |
658 begin |
660 begin |
659 x:= x + vX * 8; |
661 x:= x + vX * 8; |
660 y:= y + vY * 8; |
662 y:= y + vY * 8; |
661 valueResult:= RateShotgun(Me, vX, vY, rx, ry); |
663 valueResult:= RateShotgun(Me, vX, vY, rx, ry); |
662 |
664 |
663 if valueResult = 0 then |
665 if (valueResult = 0) and (Targ.Kind = gtHedgehog) and (Targ.Score > 0) then |
664 valueResult:= 1024 - Metric(Targ.X, Targ.Y, rx, ry) div 64 |
666 valueResult:= 1024 - Metric(Targ.Point.X, Targ.Point.Y, rx, ry) div 64 |
665 else |
667 else |
666 dec(valueResult, Level * 4000); |
668 dec(valueResult, Level * 4000); |
667 // 27/20 is reuse bonus |
669 // 27/20 is reuse bonus |
668 exit(valueResult * 27 div 20) |
670 exit(valueResult * 27 div 20) |
669 end |
671 end |
670 until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4) |
672 until (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 4) |
671 or (x < 0) |
673 or (x < 0) |
672 or (y < 0) |
674 or (y < 0) |
673 or (trunc(x) > LAND_WIDTH) |
675 or (trunc(x) > LAND_WIDTH) |
674 or (trunc(y) > LAND_HEIGHT); |
676 or (trunc(y) > LAND_HEIGHT); |
675 |
677 |
676 TestShotgun:= BadTurn |
678 TestShotgun:= BadTurn |
677 end; |
679 end; |
678 |
680 |
679 function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
681 function TestDesertEagle(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
680 var Vx, Vy, x, y, t, dmgMod: real; |
682 var Vx, Vy, x, y, t: real; |
681 d: Longword; |
683 d: Longword; |
682 fallDmg, valueResult: LongInt; |
684 fallDmg, valueResult: LongInt; |
683 begin |
685 begin |
684 if Level > 4 then exit(BadTurn); |
686 if (Level > 4) or (Targ.Score < 0) or (Targ.Kind <> gtHedgehog) then exit(BadTurn); |
685 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent; |
|
686 Level:= Level; // avoid compiler hint |
687 Level:= Level; // avoid compiler hint |
687 ap.ExplR:= 0; |
688 ap.ExplR:= 1; |
688 ap.Time:= 0; |
689 ap.Time:= 0; |
689 ap.Power:= 1; |
690 ap.Power:= 1; |
690 |
691 |
691 x:= hwFloat2Float(Me^.X); |
692 x:= hwFloat2Float(Me^.X); |
692 y:= hwFloat2Float(Me^.Y); |
693 y:= hwFloat2Float(Me^.Y); |
693 |
694 |
694 if Abs(trunc(x) - Targ.X) + Abs(trunc(y) - Targ.Y) < 20 then |
695 if Abs(trunc(x) - Targ.Point.X) + Abs(trunc(y) - Targ.Point.Y) < 20 then |
695 exit(BadTurn); |
696 exit(BadTurn); |
696 |
697 |
697 t:= 2 / sqrt(sqr(Targ.X - x)+sqr(Targ.Y-y)); |
698 t:= 2 / sqrt(sqr(Targ.Point.X - x)+sqr(Targ.Point.Y-y)); |
698 Vx:= (Targ.X - x) * t; |
699 Vx:= (Targ.Point.X - x) * t; |
699 Vy:= (Targ.Y - y) * t; |
700 Vy:= (Targ.Point.Y - y) * t; |
700 ap.Angle:= DxDy2AttackAnglef(Vx, -Vy); |
701 ap.Angle:= DxDy2AttackAnglef(Vx, -Vy); |
701 d:= 0; |
702 d:= 0; |
702 |
703 |
703 repeat |
704 repeat |
704 x:= x + vX; |
705 x:= x + vX; |
705 y:= y + vY; |
706 y:= y + vY; |
706 if ((trunc(x) and LAND_WIDTH_MASK) = 0)and((trunc(y) and LAND_HEIGHT_MASK) = 0) |
707 if ((trunc(x) and LAND_WIDTH_MASK) = 0)and((trunc(y) and LAND_HEIGHT_MASK) = 0) |
707 and (Land[trunc(y), trunc(x)] <> 0) then |
708 and (Land[trunc(y), trunc(x)] <> 0) then |
708 inc(d); |
709 inc(d); |
709 until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 5) |
710 until (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 5) |
710 or (x < 0) |
711 or (x < 0) |
711 or (y < 0) |
712 or (y < 0) |
712 or (trunc(x) > LAND_WIDTH) |
713 or (trunc(x) > LAND_WIDTH) |
713 or (trunc(y) > LAND_HEIGHT) |
714 or (trunc(y) > LAND_HEIGHT) |
714 or (d > 48); |
715 or (d > 48); |
715 |
716 |
716 if Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 5 then |
717 if Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 5 then |
717 begin |
718 valueResult:= RateShove(Me, Targ.Point.X, Targ.Point.Y, 1, 7, 20, vX*0.125, vY*0.125, afTrackFall) |
718 fallDmg:= TraceShoveFall(Targ.X, Targ.Y, vX * 0.00125 * 20, vY * 0.00125 * 20); |
719 else valueResult:= BadTurn; |
719 if fallDmg < 0 then |
|
720 valueResult:= 204800 |
|
721 else valueResult:= Max(0, (4 - d div 12) * trunc((7 + fallDmg) * dmgMod) * 1024) |
|
722 end |
|
723 else |
|
724 valueResult:= BadTurn; |
|
725 TestDesertEagle:= valueResult |
720 TestDesertEagle:= valueResult |
726 end; |
721 end; |
727 |
722 |
728 |
723 |
729 function TestSniperRifle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
724 function TestSniperRifle(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
730 var Vx, Vy, x, y, t, dmg, dmgMod: real; |
725 var Vx, Vy, x, y, t, dmg: real; |
731 d: Longword; |
726 d: Longword; |
732 fallDmg: LongInt; |
727 fallDmg: LongInt; |
733 begin |
728 begin |
734 if Level > 3 then exit(BadTurn); |
729 if (Level > 3) or (Targ.Score < 0) or (Targ.Kind <> gtHedgehog) then exit(BadTurn); |
735 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent; |
|
736 Level:= Level; // avoid compiler hint |
730 Level:= Level; // avoid compiler hint |
737 ap.ExplR:= 0; |
731 ap.ExplR:= 0; |
738 ap.Time:= 0; |
732 ap.Time:= 0; |
739 ap.Power:= 1; |
733 ap.Power:= 1; |
740 x:= hwFloat2Float(Me^.X); |
734 x:= hwFloat2Float(Me^.X); |
741 y:= hwFloat2Float(Me^.Y); |
735 y:= hwFloat2Float(Me^.Y); |
742 if Abs(trunc(x) - Targ.X) + Abs(trunc(y) - Targ.Y) < 40 then |
736 if Abs(trunc(x) - Targ.Point.X) + Abs(trunc(y) - Targ.Point.Y) < 40 then |
743 exit(BadTurn); |
737 exit(BadTurn); |
744 |
738 |
745 dmg:= sqrt(sqr(Targ.X - x)+sqr(Targ.Y-y)); |
739 dmg:= sqrt(sqr(Targ.Point.X - x)+sqr(Targ.Point.Y-y)); |
746 t:= 1.5 / dmg; |
740 t:= 1.5 / dmg; |
747 dmg:= dmg * 0.025; // div 40 |
741 dmg:= dmg * 0.025; // div 40 |
748 Vx:= (Targ.X - x) * t; |
742 Vx:= (Targ.Point.X - x) * t; |
749 Vy:= (Targ.Y - y) * t; |
743 Vy:= (Targ.Point.Y - y) * t; |
750 ap.Angle:= DxDy2AttackAnglef(Vx, -Vy); |
744 ap.Angle:= DxDy2AttackAnglef(Vx, -Vy); |
751 d:= 0; |
745 d:= 0; |
752 |
746 |
753 repeat |
747 repeat |
754 x:= x + vX; |
748 x:= x + vX; |
755 y:= y + vY; |
749 y:= y + vY; |
756 if ((trunc(x) and LAND_WIDTH_MASK) = 0)and((trunc(y) and LAND_HEIGHT_MASK) = 0) |
750 if ((trunc(x) and LAND_WIDTH_MASK) = 0)and((trunc(y) and LAND_HEIGHT_MASK) = 0) |
757 and (Land[trunc(y), trunc(x)] <> 0) then |
751 and (Land[trunc(y), trunc(x)] <> 0) then |
758 inc(d); |
752 inc(d); |
759 until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4) |
753 until (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 4) |
760 or (x < 0) |
754 or (x < 0) |
761 or (y < 0) |
755 or (y < 0) |
762 or (trunc(x) > LAND_WIDTH) |
756 or (trunc(x) > LAND_WIDTH) |
763 or (trunc(y) > LAND_HEIGHT) |
757 or (trunc(y) > LAND_HEIGHT) |
764 or (d > 22); |
758 or (d > 22); |
765 |
759 |
766 if Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4 then |
760 if Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 4 then |
767 begin |
761 TestSniperRifle:= RateShove(Me, Targ.Point.X, Targ.Point.Y, 1, trunc(dmg), 20, vX*0.166, vY*0.166, afTrackFall) |
768 fallDmg:= TraceShoveFall(Targ.X, Targ.Y, vX * 0.00166 * dmg, vY * 0.00166 * dmg); |
762 else TestSniperRifle:= BadTurn; |
769 if fallDmg < 0 then |
763 end; |
770 TestSniperRifle:= BadTurn |
764 |
771 else |
765 |
772 TestSniperRifle:= Max(0, trunc((dmg + fallDmg) * dmgMod) * 1024) |
766 function TestBaseballBat(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
773 end |
|
774 else |
|
775 TestSniperRifle:= BadTurn |
|
776 end; |
|
777 |
|
778 |
|
779 function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
|
780 var valueResult, a, v1, v2: LongInt; |
767 var valueResult, a, v1, v2: LongInt; |
781 x, y, trackFall: LongInt; |
768 x, y, trackFall: LongInt; |
782 dx, dy: real; |
769 dx, dy: real; |
783 begin |
770 begin |
784 Targ:= Targ; // avoid compiler hint |
771 Targ:= Targ; // avoid compiler hint |
798 while a >= 0 do |
785 while a >= 0 do |
799 begin |
786 begin |
800 dx:= sin(a / cMaxAngle * pi) * 0.5; |
787 dx:= sin(a / cMaxAngle * pi) * 0.5; |
801 dy:= cos(a / cMaxAngle * pi) * 0.5; |
788 dy:= cos(a / cMaxAngle * pi) * 0.5; |
802 |
789 |
803 v1:= RateShove(x - 10, y + 2 |
790 v1:= RateShove(Me, x - 10, y + 2 |
804 , 32, 30, 115 |
791 , 32, 30, 115 |
805 , -dx, -dy, trackFall); |
792 , -dx, -dy, trackFall); |
806 v2:= RateShove(x + 10, y + 2 |
793 v2:= RateShove(Me, x + 10, y + 2 |
807 , 32, 30, 115 |
794 , 32, 30, 115 |
808 , dx, -dy, trackFall); |
795 , dx, -dy, trackFall); |
809 if (v1 > valueResult) or (v2 > valueResult) then |
796 if (v1 > valueResult) or (v2 > valueResult) then |
810 if (v2 > v1) |
797 if (v2 > v1) |
811 or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then |
798 or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then |
826 valueResult:= BadTurn; |
813 valueResult:= BadTurn; |
827 |
814 |
828 TestBaseballBat:= valueResult; |
815 TestBaseballBat:= valueResult; |
829 end; |
816 end; |
830 |
817 |
831 function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
818 function TestFirePunch(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
832 var valueResult, v1, v2, i: LongInt; |
819 var valueResult, v1, v2, i: LongInt; |
833 x, y, trackFall: LongInt; |
820 x, y, trackFall: LongInt; |
834 begin |
821 begin |
835 Targ:= Targ; // avoid compiler hint |
822 Targ:= Targ; // avoid compiler hint |
836 |
823 |
844 y:= hwRound(Me^.Y) + 4; |
831 y:= hwRound(Me^.Y) + 4; |
845 |
832 |
846 v1:= 0; |
833 v1:= 0; |
847 for i:= 0 to 8 do |
834 for i:= 0 to 8 do |
848 begin |
835 begin |
849 v1:= v1 + RateShove(x - 5, y - 10 * i |
836 v1:= v1 + RateShove(Me, x - 5, y - 10 * i |
850 , 19, 30, 40 |
837 , 19, 30, 40 |
851 , -0.45, -0.9, trackFall or afSetSkip); |
838 , -0.45, -0.9, trackFall or afSetSkip); |
852 end; |
839 end; |
853 v1:= v1 + RateShove(x - 5, y - 90 |
840 v1:= v1 + RateShove(Me, x - 5, y - 90 |
854 , 19, 30, 40 |
841 , 19, 30, 40 |
855 , -0.45, -0.9, trackFall); |
842 , -0.45, -0.9, trackFall); |
856 |
843 |
857 |
844 |
858 // now try opposite direction |
845 // now try opposite direction |
859 v2:= 0; |
846 v2:= 0; |
860 for i:= 0 to 8 do |
847 for i:= 0 to 8 do |
861 begin |
848 begin |
862 v2:= v2 + RateShove(x + 5, y - 10 * i |
849 v2:= v2 + RateShove(Me, x + 5, y - 10 * i |
863 , 19, 30, 40 |
850 , 19, 30, 40 |
864 , 0.45, -0.9, trackFall or afSetSkip); |
851 , 0.45, -0.9, trackFall or afSetSkip); |
865 end; |
852 end; |
866 v2:= v2 + RateShove(x + 5, y - 90 |
853 v2:= v2 + RateShove(Me, x + 5, y - 90 |
867 , 19, 30, 40 |
854 , 19, 30, 40 |
868 , 0.45, -0.9, trackFall); |
855 , 0.45, -0.9, trackFall); |
869 |
856 |
870 if (v2 > v1) |
857 if (v2 > v1) |
871 or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then |
858 or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then |
884 |
871 |
885 TestFirePunch:= valueResult; |
872 TestFirePunch:= valueResult; |
886 end; |
873 end; |
887 |
874 |
888 |
875 |
889 function TestWhip(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
876 function TestWhip(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
890 var valueResult, v1, v2: LongInt; |
877 var valueResult, v1, v2: LongInt; |
891 x, y, trackFall: LongInt; |
878 x, y, trackFall: LongInt; |
892 begin |
879 begin |
893 Targ:= Targ; // avoid compiler hint |
880 Targ:= Targ; // avoid compiler hint |
894 |
881 |
903 |
890 |
904 // check left direction |
891 // check left direction |
905 {first RateShove checks farthermost of two whip's AmmoShove attacks |
892 {first RateShove checks farthermost of two whip's AmmoShove attacks |
906 to encourage distant attacks (damaged hog is excluded from view of second |
893 to encourage distant attacks (damaged hog is excluded from view of second |
907 RateShove call)} |
894 RateShove call)} |
908 v1:= RateShove(x - 13, y |
895 v1:= RateShove(Me, x - 13, y |
909 , 30, 30, 25 |
896 , 30, 30, 25 |
910 , -1, -0.8, trackFall or afSetSkip); |
897 , -1, -0.8, trackFall or afSetSkip); |
911 v1:= v1 + |
898 v1:= v1 + |
912 RateShove(x - 2, y |
899 RateShove(Me, x - 2, y |
913 , 30, 30, 25 |
900 , 30, 30, 25 |
914 , -1, -0.8, trackFall); |
901 , -1, -0.8, trackFall); |
915 // now try opposite direction |
902 // now try opposite direction |
916 v2:= RateShove(x + 13, y |
903 v2:= RateShove(Me, x + 13, y |
917 , 30, 30, 25 |
904 , 30, 30, 25 |
918 , 1, -0.8, trackFall or afSetSkip); |
905 , 1, -0.8, trackFall or afSetSkip); |
919 v2:= v2 + |
906 v2:= v2 + |
920 RateShove(x + 2, y |
907 RateShove(Me, x + 2, y |
921 , 30, 30, 25 |
908 , 30, 30, 25 |
922 , 1, -0.8, trackFall); |
909 , 1, -0.8, trackFall); |
923 |
910 |
924 if (v2 > v1) |
911 if (v2 > v1) |
925 or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then |
912 or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then |
939 inc(valueResult); |
926 inc(valueResult); |
940 |
927 |
941 TestWhip:= valueResult; |
928 TestWhip:= valueResult; |
942 end; |
929 end; |
943 |
930 |
944 function TestKamikaze(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
931 function TestKamikaze(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
945 const step = 8; |
932 const step = 8; |
946 var valueResult, i, v, tx: LongInt; |
933 var valueResult, i, v, tx: LongInt; |
947 trackFall: LongInt; |
934 trackFall: LongInt; |
948 t, d, x, y, dx, dy, cx: real; |
935 t, d, x, y, dx, dy, cx: real; |
949 begin |
936 begin |
961 valueResult:= 0; |
948 valueResult:= 0; |
962 v:= 0; |
949 v:= 0; |
963 |
950 |
964 x:= hwFloat2Float(Me^.X); |
951 x:= hwFloat2Float(Me^.X); |
965 y:= hwFloat2Float(Me^.Y); |
952 y:= hwFloat2Float(Me^.Y); |
966 d:= sqrt(sqr(Targ.X - x) + sqr(Targ.Y - y)); |
953 d:= sqrt(sqr(Targ.Point.X - x) + sqr(Targ.Point.Y - y)); |
967 if d < 10 then |
954 if d < 10 then |
968 begin |
955 begin |
969 dx:= 0; |
956 dx:= 0; |
970 dy:= 8; |
957 dy:= 8; |
971 ap.Angle:= 2048 |
958 ap.Angle:= 2048 |
972 end |
959 end |
973 else |
960 else |
974 begin |
961 begin |
975 t:= step / d; |
962 t:= step / d; |
976 dx:= (Targ.X - x) * t; |
963 dx:= (Targ.Point.X - x) * t; |
977 dy:= (Targ.Y - y) * t; |
964 dy:= (Targ.Point.Y - y) * t; |
978 |
965 |
979 ap.Angle:= DxDy2AttackAnglef(dx, -dy) |
966 ap.Angle:= DxDy2AttackAnglef(dx, -dy) |
980 end; |
967 end; |
981 |
968 |
982 if dx >= 0 then cx:= 0.45 else cx:= -0.45; |
969 if dx >= 0 then cx:= 0.45 else cx:= -0.45; |
983 |
970 |
984 for i:= 0 to 512 div step - 2 do |
971 for i:= 0 to 512 div step - 2 do |
985 begin |
972 begin |
986 valueResult:= valueResult + |
973 valueResult:= valueResult + |
987 RateShove(trunc(x), trunc(y) |
974 RateShove(Me, trunc(x), trunc(y) |
988 , 30, 30, 25 |
975 , 30, 30, 25 |
989 , cx, -0.9, trackFall or afSetSkip); |
976 , cx, -0.9, trackFall or afSetSkip); |
990 |
977 |
991 x:= x + dx; |
978 x:= x + dx; |
992 y:= y + dy; |
979 y:= y + dy; |
994 if dx = 0 then |
981 if dx = 0 then |
995 begin |
982 begin |
996 x:= hwFloat2Float(Me^.X); |
983 x:= hwFloat2Float(Me^.X); |
997 y:= hwFloat2Float(Me^.Y); |
984 y:= hwFloat2Float(Me^.Y); |
998 tx:= trunc(x); |
985 tx:= trunc(x); |
999 v:= RateShove(tx, trunc(y) |
986 v:= RateShove(Me, tx, trunc(y) |
1000 , 30, 30, 25 |
987 , 30, 30, 25 |
1001 , -cx, -0.9, trackFall); |
988 , -cx, -0.9, trackFall); |
1002 for i:= 1 to 512 div step - 2 do |
989 for i:= 1 to 512 div step - 2 do |
1003 begin |
990 begin |
1004 y:= y + dy; |
991 y:= y + dy; |
1005 v:= v + |
992 v:= v + |
1006 RateShove(tx, trunc(y) |
993 RateShove(Me, tx, trunc(y) |
1007 , 30, 30, 25 |
994 , 30, 30, 25 |
1008 , -cx, -0.9, trackFall or afSetSkip); |
995 , -cx, -0.9, trackFall or afSetSkip); |
1009 end |
996 end |
1010 end; |
997 end; |
1011 if v > valueResult then |
998 if v > valueResult then |
1012 begin |
999 begin |
1013 ap.Angle:= -2048; |
1000 ap.Angle:= -2048; |
1014 valueResult:= v |
1001 valueResult:= v |
1015 end; |
1002 end; |
1016 |
1003 |
1017 v:= RateShove(trunc(x), trunc(y) |
1004 v:= RateShove(Me, trunc(x), trunc(y) |
1018 , 30, 30, 25 |
1005 , 30, 30, 25 |
1019 , cx, -0.9, trackFall); |
1006 , cx, -0.9, trackFall); |
1020 valueResult:= valueResult + v - KillScore * friendlyfactor div 100 * 1024; |
1007 valueResult:= valueResult + v - KillScore * friendlyfactor div 100 * 1024; |
1021 |
1008 |
1022 if v < 65536 then |
1009 if v < 65536 then |
1023 inc(valueResult, RateExplosion(Me, trunc(x), trunc(y), 30)); |
1010 inc(valueResult, RateExplosion(Me, trunc(x), trunc(y), 30)); |
1024 |
1011 |
1025 TestKamikaze:= valueResult; |
1012 TestKamikaze:= valueResult; |
1026 end; |
1013 end; |
1027 |
1014 |
1028 function TestHammer(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
1015 function TestHammer(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
1029 var rate: LongInt; |
1016 var rate: LongInt; |
1030 begin |
1017 begin |
1031 Level:= Level; // avoid compiler hint |
1018 Level:= Level; // avoid compiler hint |
1032 Targ:= Targ; |
1019 Targ:= Targ; |
1033 |
1020 |
1040 if rate = 0 then |
1027 if rate = 0 then |
1041 rate:= BadTurn; |
1028 rate:= BadTurn; |
1042 TestHammer:= rate; |
1029 TestHammer:= rate; |
1043 end; |
1030 end; |
1044 |
1031 |
1045 function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
1032 function TestAirAttack(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
1046 const cShift = 4; |
1033 const cShift = 4; |
1047 var bombsSpeed, X, Y, dY: real; |
1034 var bombsSpeed, X, Y, dY: real; |
1048 b: array[0..9] of boolean; |
1035 b: array[0..9] of boolean; |
1049 dmg: array[0..9] of LongInt; |
1036 dmg: array[0..9] of LongInt; |
1050 fexit: boolean; |
1037 fexit: boolean; |
1054 ap.Time:= 0; |
1041 ap.Time:= 0; |
1055 if (Level > 3) then |
1042 if (Level > 3) then |
1056 exit(BadTurn); |
1043 exit(BadTurn); |
1057 |
1044 |
1058 ap.Angle:= 0; |
1045 ap.Angle:= 0; |
1059 ap.AttackPutX:= Targ.X; |
1046 ap.AttackPutX:= Targ.Point.X; |
1060 ap.AttackPutY:= Targ.Y; |
1047 ap.AttackPutY:= Targ.Point.Y; |
1061 |
1048 |
1062 bombsSpeed:= hwFloat2Float(cBombsSpeed); |
1049 bombsSpeed:= hwFloat2Float(cBombsSpeed); |
1063 X:= Targ.X - 135 - cShift; // hh center - cShift |
1050 X:= Targ.Point.X - 135 - cShift; // hh center - cShift |
1064 X:= X - bombsSpeed * sqrt(((Targ.Y + 128) * 2) / cGravityf); |
1051 X:= X - bombsSpeed * sqrt(((Targ.Point.Y + 128) * 2) / cGravityf); |
1065 Y:= -128; |
1052 Y:= -128; |
1066 dY:= 0; |
1053 dY:= 0; |
1067 |
1054 |
1068 for i:= 0 to 9 do |
1055 for i:= 0 to 9 do |
1069 begin |
1056 begin |
1091 end; |
1078 end; |
1092 until fexit or (Y > cWaterLine); |
1079 until fexit or (Y > cWaterLine); |
1093 |
1080 |
1094 for i:= 0 to 5 do inc(valueResult, dmg[i]); |
1081 for i:= 0 to 5 do inc(valueResult, dmg[i]); |
1095 t:= valueResult; |
1082 t:= valueResult; |
1096 ap.AttackPutX:= Targ.X - 60; |
1083 ap.AttackPutX:= Targ.Point.X - 60; |
1097 |
1084 |
1098 for i:= 0 to 3 do |
1085 for i:= 0 to 3 do |
1099 begin |
1086 begin |
1100 dec(t, dmg[i]); |
1087 dec(t, dmg[i]); |
1101 inc(t, dmg[i + 6]); |
1088 inc(t, dmg[i + 6]); |
1102 if t > valueResult then |
1089 if t > valueResult then |
1103 begin |
1090 begin |
1104 valueResult:= t; |
1091 valueResult:= t; |
1105 ap.AttackPutX:= Targ.X - 30 - cShift + i * 30 |
1092 ap.AttackPutX:= Targ.Point.X - 30 - cShift + i * 30 |
1106 end |
1093 end |
1107 end; |
1094 end; |
1108 |
1095 |
1109 if valueResult <= 0 then |
1096 if valueResult <= 0 then |
1110 valueResult:= BadTurn; |
1097 valueResult:= BadTurn; |
1111 TestAirAttack:= valueResult; |
1098 TestAirAttack:= valueResult; |
1112 end; |
1099 end; |
1113 |
1100 |
1114 |
1101 |
1115 function TestTeleport(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
1102 function TestTeleport(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
1116 var |
1103 var |
1117 i, failNum: longword; |
1104 i, failNum: longword; |
1118 maxTop: longword; |
1105 maxTop: longword; |
1119 begin |
1106 begin |
1120 TestTeleport := BadTurn; |
1107 TestTeleport := BadTurn; |
1123 //FillBonuses(true, [gtCase]); |
1110 //FillBonuses(true, [gtCase]); |
1124 if bonuses.Count = 0 then |
1111 if bonuses.Count = 0 then |
1125 begin |
1112 begin |
1126 if Me^.Health <= 100 then |
1113 if Me^.Health <= 100 then |
1127 begin |
1114 begin |
1128 maxTop := Targ.Y - cHHRadius * 2; |
1115 maxTop := Targ.Point.Y - cHHRadius * 2; |
1129 |
1116 |
1130 while (not TestColl(Targ.X, maxTop, cHHRadius)) and (maxTop > topY + cHHRadius * 2 + 1) do |
1117 while not TestColl(Targ.Point.X, maxTop, cHHRadius) and (maxTop > topY + cHHRadius * 2 + 1) do |
1131 dec(maxTop, cHHRadius*2); |
1118 dec(maxTop, cHHRadius*2); |
1132 if not TestColl(Targ.X, maxTop + cHHRadius, cHHRadius) then |
1119 if not TestColl(Targ.Point.X, maxTop + cHHRadius, cHHRadius) then |
1133 begin |
1120 begin |
1134 ap.AttackPutX := Targ.X; |
1121 ap.AttackPutX := Targ.Point.X; |
1135 ap.AttackPutY := maxTop + cHHRadius; |
1122 ap.AttackPutY := maxTop + cHHRadius; |
1136 TestTeleport := Targ.Y - maxTop; |
1123 TestTeleport := Targ.Point.Y - maxTop; |
1137 end; |
1124 end; |
1138 end; |
1125 end; |
1139 end |
1126 end |
1140 else |
1127 else |
1141 begin |
1128 begin |
1174 ap.Power:= v |
1161 ap.Power:= v |
1175 end |
1162 end |
1176 end; |
1163 end; |
1177 end; |
1164 end; |
1178 |
1165 |
1179 function TestCake(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
1166 function TestCake(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt; |
1180 var valueResult, v1, v2: LongInt; |
1167 var valueResult, v1, v2: LongInt; |
1181 cake: TGear; |
1168 cake: TGear; |
1182 begin |
1169 begin |
1183 Targ:= Targ; // avoid compiler hint |
1170 Targ:= Targ; // avoid compiler hint |
1184 |
1171 |