123 dY:= dY + cGravity; |
123 dY:= dY + cGravity; |
124 dec(t) |
124 dec(t) |
125 until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t <= 0); |
125 until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t <= 0); |
126 EX:= hwRound(x); |
126 EX:= hwRound(x); |
127 EY:= hwRound(y); |
127 EY:= hwRound(y); |
128 Result:= RateExplosion(Me, EX, EY, 101); |
128 value:= RateExplosion(Me, EX, EY, 101); |
129 if Result = 0 then Result:= - Metric(Targ.X, Targ.Y, EX, EY) div 64; |
129 if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64; |
130 CheckTrace:= Result |
130 CheckTrace:= value; |
131 end; |
131 end; |
132 |
132 |
133 begin |
133 begin |
134 ap.Time:= 0; |
134 ap.Time:= 0; |
135 rTime:= 350; |
135 rTime:= 350; |
136 ap.ExplR:= 0; |
136 ap.ExplR:= 0; |
137 Result:= BadTurn; |
137 valueResult:= BadTurn; |
138 repeat |
138 repeat |
139 rTime:= rTime + 300 + Level * 50 + random(300); |
139 rTime:= rTime + 300 + Level * 50 + random(300); |
140 Vx:= - cWindSpeed * rTime * _0_5 + (int2hwFloat(Targ.X + AIrndSign(2)) - Me^.X) / int2hwFloat(rTime); |
140 Vx:= - cWindSpeed * rTime * _0_5 + (int2hwFloat(Targ.X + AIrndSign(2)) - Me^.X) / int2hwFloat(rTime); |
141 Vy:= cGravity * rTime * _0_5 - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(rTime); |
141 Vy:= cGravity * rTime * _0_5 - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(rTime); |
142 r:= Distance(Vx, Vy); |
142 r:= Distance(Vx, Vy); |
143 if not (r > _1) then |
143 if not (r > _1) then |
144 begin |
144 begin |
145 Score:= CheckTrace; |
145 Score:= CheckTrace; |
146 if Result <= Score then |
146 if valueResult <= Score then |
147 begin |
147 begin |
148 ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9)); |
148 ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9)); |
149 ap.Power:= hwRound(r * cMaxPower) - random((Level - 1) * 17 + 1); |
149 ap.Power:= hwRound(r * cMaxPower) - random((Level - 1) * 17 + 1); |
150 ap.ExplR:= 100; |
150 ap.ExplR:= 100; |
151 ap.ExplX:= EX; |
151 ap.ExplX:= EX; |
152 ap.ExplY:= EY; |
152 ap.ExplY:= EY; |
153 Result:= Score |
153 valueResult:= Score |
154 end; |
154 end; |
155 end |
155 end |
156 until (rTime > 4250); |
156 until (rTime > 4250); |
157 TestBazooka:= Result |
157 TestBazooka:= valueResult |
158 end; |
158 end; |
159 |
159 |
160 function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
160 function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
161 const tDelta = 24; |
161 const tDelta = 24; |
162 var Vx, Vy, r: hwFloat; |
162 var Vx, Vy, r: hwFloat; |
163 Score, EX, EY, Result: LongInt; |
163 Score, EX, EY, valueResult: LongInt; |
164 TestTime: Longword; |
164 TestTime: Longword; |
165 |
165 |
166 function CheckTrace: LongInt; |
166 function CheckTrace: LongInt; |
167 var x, y, dY: hwFloat; |
167 var x, y, dY: hwFloat; |
168 t: LongInt; |
168 t: LongInt; |
182 if t < 50 then CheckTrace:= RateExplosion(Me, EX, EY, 101) |
182 if t < 50 then CheckTrace:= RateExplosion(Me, EX, EY, 101) |
183 else CheckTrace:= BadTurn |
183 else CheckTrace:= BadTurn |
184 end; |
184 end; |
185 |
185 |
186 begin |
186 begin |
187 Result:= BadTurn; |
187 valueResult:= BadTurn; |
188 TestTime:= 0; |
188 TestTime:= 0; |
189 ap.ExplR:= 0; |
189 ap.ExplR:= 0; |
190 repeat |
190 repeat |
191 inc(TestTime, 1000); |
191 inc(TestTime, 1000); |
192 Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime + tDelta); |
192 Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime + tDelta); |
193 Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime + tDelta); |
193 Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime + tDelta); |
194 r:= Distance(Vx, Vy); |
194 r:= Distance(Vx, Vy); |
195 if not (r > _1) then |
195 if not (r > _1) then |
196 begin |
196 begin |
197 Score:= CheckTrace; |
197 Score:= CheckTrace; |
198 if Result < Score then |
198 if valueResult < Score then |
199 begin |
199 begin |
200 ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); |
200 ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); |
201 ap.Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15); |
201 ap.Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15); |
202 ap.Time:= TestTime; |
202 ap.Time:= TestTime; |
203 ap.ExplR:= 100; |
203 ap.ExplR:= 100; |
204 ap.ExplX:= EX; |
204 ap.ExplX:= EX; |
205 ap.ExplY:= EY; |
205 ap.ExplY:= EY; |
206 Result:= Score |
206 valueResult:= Score |
207 end; |
207 end; |
208 end |
208 end |
209 until (TestTime = 4000); |
209 until (TestTime = 4000); |
210 TestGrenade:= Result |
210 TestGrenade:= valueResult |
211 end; |
211 end; |
212 |
212 |
213 function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
213 function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
214 const tDelta = 24; |
214 const tDelta = 24; |
215 var Vx, Vy: hwFloat; |
215 var Vx, Vy: hwFloat; |
216 Score, EX, EY, Result: LongInt; |
216 Score, EX, EY, valueResult: LongInt; |
217 TestTime: Longword; |
217 TestTime: Longword; |
218 |
218 |
219 function CheckTrace: LongInt; |
219 function CheckTrace: LongInt; |
220 var x, y, dY: hwFloat; |
220 var x, y, dY: hwFloat; |
221 Result: LongInt; |
221 value: LongInt; |
222 begin |
222 begin |
223 x:= Me^.X; |
223 x:= Me^.X; |
224 y:= Me^.Y; |
224 y:= Me^.Y; |
225 dY:= -Vy; |
225 dY:= -Vy; |
226 |
226 |
232 EY:= hwRound(y); |
232 EY:= hwRound(y); |
233 until TestCollExcludingMe(Me, EX, EY, 5) or (EY > 1000); |
233 until TestCollExcludingMe(Me, EX, EY, 5) or (EY > 1000); |
234 |
234 |
235 if (EY < 1000) and not dY.isNegative then |
235 if (EY < 1000) and not dY.isNegative then |
236 begin |
236 begin |
237 Result:= RateExplosion(Me, EX, EY, 91); |
237 value:= RateExplosion(Me, EX, EY, 91); |
238 if (Result = 0) then |
238 if (value = 0) then |
239 if (dY > _0_15) then |
239 if (dY > _0_15) then |
240 Result:= - abs(Targ.Y - EY) div 32 |
240 value:= - abs(Targ.Y - EY) div 32 |
241 else |
241 else |
242 Result:= BadTurn |
242 value:= BadTurn |
243 else if (Result < 0) then Result:= BadTurn |
243 else if (value < 0) then value:= BadTurn |
244 end |
244 end |
245 else |
245 else |
246 Result:= BadTurn; |
246 value:= BadTurn; |
247 |
247 |
248 CheckTrace:= Result |
248 CheckTrace:= value; |
249 end; |
249 end; |
250 |
250 |
251 function Solve: LongWord; |
251 function Solve: LongWord; |
252 var A, B, D, T: hwFloat; |
252 var A, B, D, T: hwFloat; |
253 C: LongInt; |
253 C: LongInt; |
279 |
279 |
280 Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime); |
280 Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime); |
281 Vy:= cGravity * (TestTime div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime); |
281 Vy:= cGravity * (TestTime div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime); |
282 |
282 |
283 Score:= CheckTrace; |
283 Score:= CheckTrace; |
284 if Result < Score then |
284 if valueResult < Score then |
285 begin |
285 begin |
286 ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); |
286 ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); |
287 ap.Power:= 1; |
287 ap.Power:= 1; |
288 ap.ExplR:= 100; |
288 ap.ExplR:= 100; |
289 ap.ExplX:= EX; |
289 ap.ExplX:= EX; |
290 ap.ExplY:= EY; |
290 ap.ExplY:= EY; |
291 Result:= Score |
291 valueResult:= Score |
292 end; |
292 end; |
293 |
293 |
294 TestMortar:= Result |
294 TestMortar:= valueResult; |
295 end; |
295 end; |
296 |
296 |
297 function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
297 function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
298 const |
298 const |
299 MIN_RANGE = 80; |
299 MIN_RANGE = 80; |
300 MAX_RANGE = 400; |
300 MAX_RANGE = 400; |
301 var Vx, Vy, x, y: hwFloat; |
301 var Vx, Vy, x, y: hwFloat; |
302 rx, ry, Result: LongInt; |
302 rx, ry, valueResult: LongInt; |
303 range: integer; |
303 range: integer; |
304 begin |
304 begin |
305 ap.ExplR:= 0; |
305 ap.ExplR:= 0; |
306 ap.Time:= 0; |
306 ap.Time:= 0; |
307 ap.Power:= 1; |
307 ap.Power:= 1; |
319 ry:= hwRound(y); |
319 ry:= hwRound(y); |
320 if TestCollExcludingMe(Me, rx, ry, 2) then |
320 if TestCollExcludingMe(Me, rx, ry, 2) then |
321 begin |
321 begin |
322 x:= x + vX * 8; |
322 x:= x + vX * 8; |
323 y:= y + vY * 8; |
323 y:= y + vY * 8; |
324 Result:= RateShotgun(Me, rx, ry) * 2; |
324 valueResult:= RateShotgun(Me, rx, ry) * 2; |
325 if Result = 0 then Result:= - Metric(Targ.X, Targ.Y, rx, ry) div 64 |
325 if valueResult = 0 then valueResult:= - Metric(Targ.X, Targ.Y, rx, ry) div 64 |
326 else dec(Result, Level * 4000); |
326 else dec(valueResult, Level * 4000); |
327 exit(Result) |
327 exit(valueResult) |
328 end |
328 end |
329 until (Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 4) or (x.isNegative) or (y.isNegative) or (x.Round > LAND_WIDTH) or (y.Round > LAND_HEIGHT); |
329 until (Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 4) or (x.isNegative) or (y.isNegative) or (x.Round > LAND_WIDTH) or (y.Round > LAND_HEIGHT); |
330 TestShotgun:= BadTurn |
330 TestShotgun:= BadTurn |
331 end; |
331 end; |
332 |
332 |
333 function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
333 function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
334 var Vx, Vy, x, y, t: hwFloat; |
334 var Vx, Vy, x, y, t: hwFloat; |
335 d: Longword; |
335 d: Longword; |
336 Result: LongInt; |
336 valueResult: LongInt; |
337 begin |
337 begin |
338 ap.ExplR:= 0; |
338 ap.ExplR:= 0; |
339 ap.Time:= 0; |
339 ap.Time:= 0; |
340 ap.Power:= 1; |
340 ap.Power:= 1; |
341 if Abs(hwRound(Me^.X) - Targ.X) + Abs(hwRound(Me^.Y) - Targ.Y) < 80 then |
341 if Abs(hwRound(Me^.X) - Targ.X) + Abs(hwRound(Me^.Y) - Targ.Y) < 80 then |
353 y:= y + vY; |
353 y:= y + vY; |
354 if ((hwRound(x) and LAND_WIDTH_MASK) = 0)and((hwRound(y) and LAND_HEIGHT_MASK) = 0) |
354 if ((hwRound(x) and LAND_WIDTH_MASK) = 0)and((hwRound(y) and LAND_HEIGHT_MASK) = 0) |
355 and (Land[hwRound(y), hwRound(x)] <> 0) then inc(d); |
355 and (Land[hwRound(y), hwRound(x)] <> 0) then inc(d); |
356 until (Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 4) or (x.isNegative) or (y.isNegative) or (x.Round > LAND_WIDTH) or (y.Round > LAND_HEIGHT) or (d > 200); |
356 until (Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 4) or (x.isNegative) or (y.isNegative) or (x.Round > LAND_WIDTH) or (y.Round > LAND_HEIGHT) or (d > 200); |
357 |
357 |
358 if Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 3 then Result:= max(0, (4 - d div 50) * 7 * 1024) |
358 if Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 3 then valueResult:= max(0, (4 - d div 50) * 7 * 1024) |
359 else Result:= BadTurn; |
359 else valueResult:= BadTurn; |
360 TestDesertEagle:= Result |
360 TestDesertEagle:= valueResult |
361 end; |
361 end; |
362 |
362 |
363 function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
363 function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
364 var Result: LongInt; |
364 var valueResult: LongInt; |
365 begin |
365 begin |
366 ap.ExplR:= 0; |
366 ap.ExplR:= 0; |
367 if (Level > 2) or (Abs(hwRound(Me^.X) - Targ.X) + Abs(hwRound(Me^.Y) - Targ.Y) > 25) then |
367 if (Level > 2) or (Abs(hwRound(Me^.X) - Targ.X) + Abs(hwRound(Me^.Y) - Targ.Y) > 25) then |
368 exit(BadTurn); |
368 exit(BadTurn); |
369 |
369 |
370 ap.Time:= 0; |
370 ap.Time:= 0; |
371 ap.Power:= 1; |
371 ap.Power:= 1; |
372 if (Targ.X) - hwRound(Me^.X) >= 0 then ap.Angle:= cMaxAngle div 4 |
372 if (Targ.X) - hwRound(Me^.X) >= 0 then ap.Angle:= cMaxAngle div 4 |
373 else ap.Angle:= - cMaxAngle div 4; |
373 else ap.Angle:= - cMaxAngle div 4; |
374 Result:= RateShove(Me, hwRound(Me^.X) + 10 * hwSign(int2hwFloat(Targ.X) - Me^.X), hwRound(Me^.Y), 15, 30); |
374 valueResult:= RateShove(Me, hwRound(Me^.X) + 10 * hwSign(int2hwFloat(Targ.X) - Me^.X), hwRound(Me^.Y), 15, 30); |
375 if Result <= 0 then Result:= BadTurn else inc(Result); |
375 if valueResult <= 0 then valueResult:= BadTurn else inc(valueResult); |
376 TestBaseballBat:= Result |
376 TestBaseballBat:= valueResult; |
377 end; |
377 end; |
378 |
378 |
379 function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
379 function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
380 var i, Result: LongInt; |
380 var i, valueResult: LongInt; |
381 begin |
381 begin |
382 ap.ExplR:= 0; |
382 ap.ExplR:= 0; |
383 ap.Time:= 0; |
383 ap.Time:= 0; |
384 ap.Power:= 1; |
384 ap.Power:= 1; |
385 ap.Angle:= 0; |
385 ap.Angle:= 0; |
386 if (Abs(hwRound(Me^.X) - Targ.X) > 25) |
386 if (Abs(hwRound(Me^.X) - Targ.X) > 25) |
387 or (Abs(hwRound(Me^.Y) - 50 - Targ.Y) > 50) then |
387 or (Abs(hwRound(Me^.Y) - 50 - Targ.Y) > 50) then |
388 begin |
388 begin |
389 if TestColl(hwRound(Me^.Y), hwRound(Me^.Y) - 16, 6) |
389 if TestColl(hwRound(Me^.Y), hwRound(Me^.Y) - 16, 6) |
390 and (RateShove(Me, hwRound(Me^.X) + 10 * hwSign(Me^.dX), hwRound(Me^.Y) - 40, 30, 30) = 0) then |
390 and (RateShove(Me, hwRound(Me^.X) + 10 * hwSign(Me^.dX), hwRound(Me^.Y) - 40, 30, 30) = 0) then |
391 Result:= Succ(BadTurn) |
391 valueResult:= Succ(BadTurn) |
392 else |
392 else |
393 Result:= BadTurn; |
393 valueResult:= BadTurn; |
394 exit(Result) |
394 exit(valueResult) |
395 end; |
395 end; |
396 |
396 |
397 Result:= 0; |
397 valueResult:= 0; |
398 for i:= 0 to 4 do |
398 for i:= 0 to 4 do |
399 Result:= Result + RateShove(Me, hwRound(Me^.X) + 10 * hwSign(int2hwFloat(Targ.X) - Me^.X), |
399 valueResult:= valueResult + RateShove(Me, hwRound(Me^.X) + 10 * hwSign(int2hwFloat(Targ.X) - Me^.X), |
400 hwRound(Me^.Y) - 20 * i - 5, 10, 30); |
400 hwRound(Me^.Y) - 20 * i - 5, 10, 30); |
401 if Result <= 0 then |
401 if valueResult <= 0 then |
402 Result:= BadTurn |
402 valueResult:= BadTurn |
403 else |
403 else |
404 inc(Result); |
404 inc(valueResult); |
405 |
405 |
406 TestFirePunch:= Result |
406 TestFirePunch:= valueResult; |
407 end; |
407 end; |
408 |
408 |
409 function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
409 function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
410 const cShift = 4; |
410 const cShift = 4; |
411 var X, Y, dY: hwFloat; |
411 var X, Y, dY: hwFloat; |
412 b: array[0..9] of boolean; |
412 b: array[0..9] of boolean; |
413 dmg: array[0..9] of LongInt; |
413 dmg: array[0..9] of LongInt; |
414 fexit: boolean; |
414 fexit: boolean; |
415 i, t, Result: LongInt; |
415 i, t, valueResult: LongInt; |
416 begin |
416 begin |
417 ap.ExplR:= 0; |
417 ap.ExplR:= 0; |
418 ap.Time:= 0; |
418 ap.Time:= 0; |
419 if (Level > 3) then exit(BadTurn); |
419 if (Level > 3) then exit(BadTurn); |
420 |
420 |