64 |
65 |
65 function RatePlace(Gear: PGear): LongInt; |
66 function RatePlace(Gear: PGear): LongInt; |
66 function TestColl(x, y, r: LongInt): boolean; inline; |
67 function TestColl(x, y, r: LongInt): boolean; inline; |
67 function TestCollExcludingObjects(x, y, r: LongInt): boolean; inline; |
68 function TestCollExcludingObjects(x, y, r: LongInt): boolean; inline; |
68 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline; |
69 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline; |
69 function TraceShoveFall(x, y, dX, dY: Real): LongInt; |
70 function TraceShoveFall(x, y, dX, dY: Real; Kind: TGearType): LongInt; |
70 |
71 |
71 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline; |
72 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline; |
72 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline; |
73 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline; |
73 function RealRateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; |
74 function RealRateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; |
74 function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; |
75 function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; |
142 matters:= (iter^.AIHints and aihDoesntMatter) = 0; |
143 matters:= (iter^.AIHints and aihDoesntMatter) = 0; |
143 |
144 |
144 Point.X:= hwRound(iter^.X); |
145 Point.X:= hwRound(iter^.X); |
145 Point.Y:= hwRound(iter^.Y); |
146 Point.Y:= hwRound(iter^.Y); |
146 if (iter^.Kind = gtHedgehog) then |
147 if (iter^.Kind = gtHedgehog) then |
|
148 begin |
147 if (iter^.Hedgehog^.Team^.Clan = CurrentTeam^.Clan) then |
149 if (iter^.Hedgehog^.Team^.Clan = CurrentTeam^.Clan) then |
148 begin |
150 begin |
149 Score:= iter^.Damage - iter^.Health; |
151 Score:= iter^.Damage - iter^.Health; |
150 inc(f) |
152 inc(f) |
151 end |
153 end |
152 else |
154 else |
153 begin |
155 begin |
154 Score:= iter^.Health - iter^.Damage; |
156 Score:= iter^.Health - iter^.Damage; |
155 inc(e) |
157 inc(e) |
156 end |
158 end; |
157 else if iter^.Kind = gtExplosives then Score:= iter^.Health - iter^.Damage |
159 Density:= 1; |
158 else if iter^.Kind = gtMine then Score:= max(0,35-iter^.Damage) |
160 end |
|
161 else if iter^.Kind = gtExplosives then |
|
162 begin |
|
163 Score:= iter^.Health - iter^.Damage; |
|
164 Density:= 2 |
|
165 end |
|
166 else if iter^.Kind = gtMine then |
|
167 begin |
|
168 Score:= max(0,35-iter^.Damage); |
|
169 Density:= 1/3 |
|
170 end |
159 end; |
171 end; |
160 inc(Targets.Count) |
172 inc(Targets.Count) |
161 end; |
173 end; |
162 iter:= iter^.NextGear |
174 iter:= iter^.NextGear |
163 end; |
175 end; |
349 TestCollExcludingMe:= TestCollWithEverything(x, y, r) |
361 TestCollExcludingMe:= TestCollWithEverything(x, y, r) |
350 end; |
362 end; |
351 |
363 |
352 |
364 |
353 |
365 |
354 function TraceFall(eX, eY: LongInt; var x, y: Real; dX, dY: Real; r: LongWord): LongInt; |
366 function TraceFall(eX, eY: LongInt; var x, y: Real; dX, dY: Real; r: LongWord; Kind: TGearType): LongInt; |
355 var skipLandCheck: boolean; |
367 var skipLandCheck: boolean; |
356 rCorner: real; |
368 rCorner: real; |
357 dmg: LongInt; |
369 dmg, radius: LongInt; |
358 begin |
370 begin |
359 skipLandCheck:= true; |
371 skipLandCheck:= true; |
360 if x - eX < 0 then dX:= -dX; |
372 if x - eX < 0 then dX:= -dX; |
361 if y - eY < 0 then dY:= -dY; |
373 if y - eY < 0 then dY:= -dY; |
362 // ok. attempt approximate search for an unbroken trajectory into water. if it continues far enough, assume out of map |
374 // ok. attempt approximate search for an unbroken trajectory into water. if it continues far enough, assume out of map |
|
375 if Kind = gtHedgehog then |
|
376 radius:= cHHRadius |
|
377 else if Kind = gtExplosives then |
|
378 radius:= 16 |
|
379 else if Kind = gtMine then |
|
380 radius:= 2; |
363 rCorner:= r * 0.75; |
381 rCorner:= r * 0.75; |
364 while true do |
382 while true do |
365 begin |
383 begin |
366 x:= x + dX; |
384 x:= x + dX; |
367 y:= y + dY; |
385 y:= y + dY; |
368 dY:= dY + cGravityf; |
386 dY:= dY + cGravityf; |
369 skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner)); |
387 skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner)); |
370 if not skipLandCheck and TestCollExcludingObjects(trunc(x), trunc(y), cHHRadius) then |
388 if not skipLandCheck and TestCollExcludingObjects(trunc(x), trunc(y), radius) then |
371 begin |
389 begin |
372 if 0.4 < dY then |
390 if (Kind = gtHedgehog) and (0.4 < dY) then |
373 begin |
391 begin |
374 dmg := 1 + trunc((abs(dY) - 0.4) * 70); |
392 dmg := 1 + trunc((abs(dY) - 0.4) * 70); |
375 if dmg >= 1 then |
393 if dmg >= 1 then exit(dmg) |
376 exit(dmg); |
394 end |
377 end; |
395 // so. the problem w/ explosives is it only uses dX or dY depending on impact, and we don't know which we hit. Maybe we didn't even hit, given TestColl check corners. |
|
396 else |
|
397 begin |
|
398 if ((dY > 0.2) and (Land[trunc(y)+radius, trunc(x)] > lfAllObjMask)) or |
|
399 ((dY < -0.2) and (Land[trunc(y)-radius, trunc(x)] > lfAllObjMask)) then |
|
400 begin |
|
401 dmg := 1 + trunc(abs(dY) * 70); |
|
402 if dmg >= 1 then exit(dmg) |
|
403 end |
|
404 // so we don't know at present if a barrel is already rolling. Would need to add that to target info I guess |
|
405 else if ((Kind = gtMine) or (abs(dX) > 0.15) or ((abs(dY) > 0.15) and (abs(dX) > 0.02))) and |
|
406 (((dX > 0.2) and (Land[trunc(y), trunc(x)+radius] > lfAllObjMask)) or |
|
407 ((dX < -0.2) and (Land[trunc(y), trunc(x)-radius] > lfAllObjMask))) then |
|
408 begin |
|
409 dmg := 1 + trunc(abs(dX) * 70); |
|
410 if dmg >= 1 then exit(dmg) |
|
411 end |
|
412 end; |
378 exit(0) |
413 exit(0) |
379 end; |
414 end; |
380 if (y > cWaterLine) or (x > 4096) or (x < 0) then |
415 if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(-1) |
381 exit(-1); |
416 end |
382 end; |
417 end; |
383 end; |
418 |
384 |
419 function TraceShoveFall(x, y, dX, dY: Real; Kind: TGearType): LongInt; |
385 function TraceShoveFall(x, y, dX, dY: Real): LongInt; |
|
386 var dmg: LongInt; |
420 var dmg: LongInt; |
387 begin |
421 begin |
388 //v:= random($FFFFFFFF); |
422 //v:= random($FFFFFFFF); |
389 while true do |
423 while true do |
390 begin |
424 begin |
465 begin |
499 begin |
466 pX:= Point.x; |
500 pX:= Point.x; |
467 pY:= Point.y; |
501 pY:= Point.y; |
468 if (Flags and afTrackFall <> 0) and (dmg < abs(Score)) then |
502 if (Flags and afTrackFall <> 0) and (dmg < abs(Score)) then |
469 begin |
503 begin |
470 dX:= 0.005 * dmg + 0.01; |
504 dX:= 0.005 * dmg + 0.01 * Density; |
471 dY:= dX; |
505 dY:= dX; |
472 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and |
506 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and |
473 (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then |
507 (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then |
474 fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0) * dmgMod) |
508 fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0, Kind) * dmgMod) |
475 else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure) * dmgMod) |
509 else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure, Kind) * dmgMod) |
476 end; |
510 end; |
477 if Kind = gtHedgehog then |
511 if Kind = gtHedgehog then |
478 begin |
512 begin |
479 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
513 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
480 begin |
514 begin |
544 begin |
578 begin |
545 pX:= Point.x; |
579 pX:= Point.x; |
546 pY:= Point.y; |
580 pY:= Point.y; |
547 if (Flags and afSetSkip <> 0) then skip:= true; |
581 if (Flags and afSetSkip <> 0) then skip:= true; |
548 if (Flags and afTrackFall <> 0) and (Score > 0) then |
582 if (Flags and afTrackFall <> 0) and (Score > 0) then |
549 fallDmg:= trunc(TraceShoveFall(pX, pY - 2, dX, dY) * dmgMod); |
583 fallDmg:= trunc(TraceShoveFall(pX, pY - 2, dX, dY, Kind) * dmgMod); |
550 if Kind = gtHedgehog then |
584 if Kind = gtHedgehog then |
551 begin |
585 begin |
552 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
586 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
553 begin |
587 begin |
554 if Score > 0 then |
588 if Score > 0 then |
632 end; |
666 end; |
633 if dmg > 0 then |
667 if dmg > 0 then |
634 begin |
668 begin |
635 pX:= Point.x; |
669 pX:= Point.x; |
636 pY:= Point.y; |
670 pY:= Point.y; |
637 dX:= gdX * dmg; |
671 dX:= gdX * dmg * Density; |
638 dY:= gdY * dmg; |
672 dY:= gdY * dmg * Density; |
639 if dX < 0 then dX:= dX - 0.01 |
673 if dX < 0 then dX:= dX - 0.01 |
640 else dX:= dX + 0.01; |
674 else dX:= dX + 0.01; |
641 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and |
675 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and |
642 (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then |
676 (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then |
643 fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0) * dmgMod) |
677 fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0, Kind) * dmgMod) |
644 else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure) * dmgMod); |
678 else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure, Kind) * dmgMod); |
645 if Kind = gtHedgehog then |
679 if Kind = gtHedgehog then |
646 begin |
680 begin |
647 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
681 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
648 begin |
682 begin |
649 if Score > 0 then |
683 if Score > 0 then |