52 |
52 |
53 procedure initModule; |
53 procedure initModule; |
54 procedure freeModule; |
54 procedure freeModule; |
55 |
55 |
56 procedure FillTargets; |
56 procedure FillTargets; |
|
57 procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt); inline; |
57 procedure FillBonuses(isAfterAttack: boolean); |
58 procedure FillBonuses(isAfterAttack: boolean); |
58 procedure AwareOfExplosion(x, y, r: LongInt); inline; |
59 procedure AwareOfExplosion(x, y, r: LongInt); inline; |
59 |
60 |
60 function RatePlace(Gear: PGear): LongInt; |
61 function RatePlace(Gear: PGear): LongInt; |
61 function TestColl(x, y, r: LongInt): boolean; inline; |
62 function TestColl(x, y, r: LongInt): boolean; inline; |
138 bonuses.ar[bonuses.Count].Score:= s; |
144 bonuses.ar[bonuses.Count].Score:= s; |
139 inc(bonuses.Count); |
145 inc(bonuses.Count); |
140 end; |
146 end; |
141 end; |
147 end; |
142 |
148 |
|
149 procedure AddWalkBonus(x, y: LongInt; r: Longword; s: LongInt); inline; |
|
150 begin |
|
151 if(walkbonuses.Count < MAXBONUS div 8) then |
|
152 begin |
|
153 walkbonuses.ar[walkbonuses.Count].x:= x; |
|
154 walkbonuses.ar[walkbonuses.Count].y:= y; |
|
155 walkbonuses.ar[walkbonuses.Count].Radius:= r; |
|
156 walkbonuses.ar[walkbonuses.Count].Score:= s; |
|
157 inc(walkbonuses.Count); |
|
158 end; |
|
159 end; |
|
160 |
143 procedure FillBonuses(isAfterAttack: boolean); |
161 procedure FillBonuses(isAfterAttack: boolean); |
144 var Gear: PGear; |
162 var Gear: PGear; |
145 MyClan: PClan; |
163 MyClan: PClan; |
|
164 i: Longint; |
146 begin |
165 begin |
147 bonuses.Count:= 0; |
166 bonuses.Count:= 0; |
148 MyClan:= ThinkingHH^.Hedgehog^.Team^.Clan; |
167 MyClan:= ThinkingHH^.Hedgehog^.Team^.Clan; |
149 Gear:= GearsList; |
168 Gear:= GearsList; |
150 while Gear <> nil do |
169 while Gear <> nil do |
151 begin |
170 begin |
152 case Gear^.Kind of |
171 case Gear^.Kind of |
153 gtCase: |
172 gtCase: |
154 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 33, 25); |
173 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y) + 3, 37, 25); |
155 gtFlame: |
174 gtFlame: |
156 if (Gear^.State and gsttmpFlag) <> 0 then |
175 if (Gear^.State and gsttmpFlag) <> 0 then |
157 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 20, -50); |
176 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 20, -50); |
158 // avoid mines unless they are very likely to be duds, or are duds. also avoid if they are about to blow |
177 // avoid mines unless they are very likely to be duds, or are duds. also avoid if they are about to blow |
159 gtMine: |
178 gtMine: |
176 gtHedgehog: |
195 gtHedgehog: |
177 begin |
196 begin |
178 if Gear^.Damage >= Gear^.Health then |
197 if Gear^.Damage >= Gear^.Health then |
179 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 60, -25) |
198 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 60, -25) |
180 else |
199 else |
181 if isAfterAttack and (ThinkingHH^.Hedgehog <> Gear^.Hedgehog) then |
200 if isAfterAttack |
|
201 and (ThinkingHH^.Hedgehog <> Gear^.Hedgehog) |
|
202 and ((hwAbs(Gear^.dX) + hwAbs(Gear^.dY)) < _0_1) then |
182 if (ClansCount > 2) or (MyClan = Gear^.Hedgehog^.Team^.Clan) then |
203 if (ClansCount > 2) or (MyClan = Gear^.Hedgehog^.Team^.Clan) then |
183 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 150, -3) // hedgehog-friend |
204 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 150, -3) // hedgehog-friend |
184 else |
205 else |
185 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 100, 3) |
206 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 100, 3) |
186 end; |
207 end; |
188 Gear:= Gear^.NextGear |
209 Gear:= Gear^.NextGear |
189 end; |
210 end; |
190 if isAfterAttack and (KnownExplosion.Radius > 0) then |
211 if isAfterAttack and (KnownExplosion.Radius > 0) then |
191 with KnownExplosion do |
212 with KnownExplosion do |
192 AddBonus(X, Y, Radius + 10, -Radius); |
213 AddBonus(X, Y, Radius + 10, -Radius); |
|
214 if isAfterAttack then |
|
215 begin |
|
216 for i:= 0 to Pred(walkbonuses.Count) do |
|
217 with walkbonuses.ar[i] do |
|
218 AddBonus(X, Y, Radius, Score); |
|
219 walkbonuses.Count:= 0 |
|
220 end; |
193 end; |
221 end; |
194 |
222 |
195 procedure AwareOfExplosion(x, y, r: LongInt); inline; |
223 procedure AwareOfExplosion(x, y, r: LongInt); inline; |
196 begin |
224 begin |
197 KnownExplosion.X:= x; |
225 KnownExplosion.X:= x; |
341 while true do |
369 while true do |
342 begin |
370 begin |
343 x:= x + dX; |
371 x:= x + dX; |
344 y:= y + dY; |
372 y:= y + dY; |
345 dY:= dY + cGravityf; |
373 dY:= dY + cGravityf; |
346 (* |
374 |
347 if ((trunc(y) and LAND_HEIGHT_MASK) = 0) and ((trunc(x) and LAND_WIDTH_MASK) = 0) then |
375 { if ((trunc(y) and LAND_HEIGHT_MASK) = 0) and ((trunc(x) and LAND_WIDTH_MASK) = 0) then |
348 begin |
376 begin |
349 LandPixels[trunc(y), trunc(x)]:= v; |
377 LandPixels[trunc(y), trunc(x)]:= v; |
350 UpdateLandTexture(trunc(X), 1, trunc(Y), 1, true); |
378 UpdateLandTexture(trunc(X), 1, trunc(Y), 1, true); |
351 end; |
379 end;} |
352 *) |
380 |
353 |
381 |
354 // consider adding dX/dY calc here for fall damage |
382 // consider adding dX/dY calc here for fall damage |
355 if TestCollExcludingObjects(trunc(x), trunc(y), cHHRadius) then |
383 if TestCollExcludingObjects(trunc(x), trunc(y), cHHRadius) then |
356 begin |
384 begin |
357 if 0.4 < dY then |
385 if 0.4 < dY then |
402 begin |
430 begin |
403 if Flags and afTrackFall <> 0 then |
431 if Flags and afTrackFall <> 0 then |
404 begin |
432 begin |
405 dX:= 0.005 * dmg + 0.01; |
433 dX:= 0.005 * dmg + 0.01; |
406 dY:= dX; |
434 dY:= dX; |
407 fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod); |
435 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and |
|
436 (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then |
|
437 fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, 0) * dmgMod) |
|
438 else fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod) |
408 end; |
439 end; |
409 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
440 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
410 if Score > 0 then |
441 if Score > 0 then |
411 inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings |
442 inc(rate, (KillScore + Score div 10) * 1024) // Add a bit of a bonus for bigger hog drownings |
412 else |
443 else |
413 dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs |
444 dec(rate, (KillScore * friendlyfactor div 100 - Score div 10) * 1024) // and more of a punishment for drowning bigger friendly hogs |
414 else if (dmg+fallDmg) >= abs(Score) then |
445 else if (dmg+fallDmg) >= abs(Score) then |
415 if Score > 0 then |
446 if Score > 0 then |
416 inc(rate, KillScore) |
447 inc(rate, KillScore * 1024 + (dmg + fallDmg)) // tiny bonus for dealing more damage than needed to kill |
417 else |
448 else |
418 dec(rate, KillScore * friendlyfactor div 100) |
449 dec(rate, KillScore * friendlyfactor div 100 * 1024) |
419 else |
450 else |
420 if Score > 0 then |
451 if Score > 0 then |
421 inc(rate, dmg+fallDmg) |
452 inc(rate, (dmg + fallDmg) * 1024) |
422 else dec(rate, (dmg+fallDmg) * friendlyfactor div 100) |
453 else dec(rate, (dmg + fallDmg) * friendlyfactor div 100 * 1024) |
423 end; |
454 end; |
424 end; |
455 end; |
425 RateExplosion:= rate * 1024; |
456 RateExplosion:= rate; |
426 end; |
457 end; |
427 |
458 |
428 function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; |
459 function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; |
429 var i, fallDmg, dmg, rate: LongInt; |
460 var i, fallDmg, dmg, rate: LongInt; |
430 dX, dY, dmgMod: real; |
461 dX, dY, dmgMod: real; |
501 begin |
532 begin |
502 dX:= gdX * dmg; |
533 dX:= gdX * dmg; |
503 dY:= gdY * dmg; |
534 dY:= gdY * dmg; |
504 if dX < 0 then dX:= dX - 0.01 |
535 if dX < 0 then dX:= dX - 0.01 |
505 else dX:= dX + 0.01; |
536 else dX:= dX + 0.01; |
506 fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod); |
537 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and |
|
538 (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then |
|
539 fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, 0) * dmgMod) |
|
540 else fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod); |
507 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
541 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
508 if Score > 0 then |
542 if Score > 0 then |
509 inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings |
543 inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings |
510 else |
544 else |
511 dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs |
545 dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs |
609 if (Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, -1) <> 0) then |
649 if (Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, -1) <> 0) then |
610 Gear^.dY:= _0; |
650 Gear^.dY:= _0; |
611 Gear^.Y:= Gear^.Y + Gear^.dY; |
651 Gear^.Y:= Gear^.Y + Gear^.dY; |
612 if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
652 if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
613 begin |
653 begin |
614 Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); |
654 Gear^.State:= Gear^.State and (not (gstMoving or gstHHJumping)); |
615 Gear^.dY:= _0; |
655 Gear^.dY:= _0; |
616 case JumpType of |
656 case JumpType of |
617 jmpHJump: |
657 jmpHJump: |
618 if bY - hwRound(Gear^.Y) > 5 then |
658 if bY - hwRound(Gear^.Y) > 5 then |
619 begin |
659 begin |
634 end; |
674 end; |
635 until false |
675 until false |
636 end; |
676 end; |
637 |
677 |
638 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; |
678 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; |
639 var pX, pY: LongInt; |
679 var pX, pY, tY: LongInt; |
640 begin |
680 begin |
641 HHGo:= false; |
681 HHGo:= false; |
|
682 Gear^.CollisionMask:= $FF7F; |
642 AltGear^:= Gear^; |
683 AltGear^:= Gear^; |
643 |
684 |
644 GoInfo.Ticks:= 0; |
685 GoInfo.Ticks:= 0; |
645 GoInfo.FallPix:= 0; |
686 GoInfo.FallPix:= 0; |
646 GoInfo.JumpType:= jmpNone; |
687 GoInfo.JumpType:= jmpNone; |
647 |
688 tY:= hwRound(Gear^.Y); |
648 repeat |
689 repeat |
|
690 {if ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) then |
|
691 begin |
|
692 LandPixels[hwRound(Gear^.Y), hwRound(Gear^.X)]:= random($FFFFFFFF);//Gear^.Hedgehog^.Team^.Clan^.Color; |
|
693 UpdateLandTexture(hwRound(Gear^.X), 1, hwRound(Gear^.Y), 1, true); |
|
694 end;} |
|
695 |
649 pX:= hwRound(Gear^.X); |
696 pX:= hwRound(Gear^.X); |
650 pY:= hwRound(Gear^.Y); |
697 pY:= hwRound(Gear^.Y); |
651 if pY + cHHRadius >= cWaterLine then |
698 if pY + cHHRadius >= cWaterLine then |
652 exit(false); |
699 begin |
|
700 if AltGear^.Hedgehog^.BotLevel < 4 then |
|
701 AddWalkBonus(pX, tY, 250, -40); |
|
702 exit(false) |
|
703 end; |
653 |
704 |
654 // hog is falling |
705 // hog is falling |
655 if (Gear^.State and gstMoving) <> 0 then |
706 if (Gear^.State and gstMoving) <> 0 then |
656 begin |
707 begin |
657 inc(GoInfo.Ticks); |
708 inc(GoInfo.Ticks); |
658 Gear^.dY:= Gear^.dY + cGravity; |
709 Gear^.dY:= Gear^.dY + cGravity; |
659 if Gear^.dY > _0_4 then |
710 if Gear^.dY > _0_4 then |
660 begin |
711 begin |
661 Goinfo.FallPix:= 0; |
712 GoInfo.FallPix:= 0; |
662 // try ljump instead of fall with damage |
713 // try ljump instead of fall with damage |
663 HHJump(AltGear, jmpLJump, GoInfo); |
714 HHJump(AltGear, jmpLJump, GoInfo); |
|
715 if AltGear^.Hedgehog^.BotLevel < 4 then |
|
716 AddWalkBonus(pX, tY, 175, -20); |
664 exit(false) |
717 exit(false) |
665 end; |
718 end; |
666 Gear^.Y:= Gear^.Y + Gear^.dY; |
719 Gear^.Y:= Gear^.Y + Gear^.dY; |
667 if hwRound(Gear^.Y) > pY then |
720 if hwRound(Gear^.Y) > pY then |
668 inc(GoInfo.FallPix); |
721 inc(GoInfo.FallPix); |
669 if TestCollisionYwithGear(Gear, 1) <> 0 then |
722 if TestCollisionYwithGear(Gear, 1) <> 0 then |
670 begin |
723 begin |
671 inc(GoInfo.Ticks, 410); |
724 inc(GoInfo.Ticks, 410); |
672 Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); |
725 Gear^.State:= Gear^.State and (not (gstMoving or gstHHJumping)); |
673 Gear^.dY:= _0; |
726 Gear^.dY:= _0; |
674 // try ljump instead of fall |
727 // try ljump instead of fall |
675 HHJump(AltGear, jmpLJump, GoInfo); |
728 HHJump(AltGear, jmpLJump, GoInfo); |
676 exit(true) |
729 exit(true) |
677 end; |
730 end; |