84 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline; |
85 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline; |
85 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline; |
86 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline; |
86 function RealRateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; |
87 function RealRateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; |
87 function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; |
88 function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; |
88 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; |
89 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; |
|
90 function RateSeduction(Me: PGear): LongInt; |
89 function RateHammer(Me: PGear): LongInt; |
91 function RateHammer(Me: PGear): LongInt; |
90 |
92 |
91 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; |
93 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; |
92 function AIrndSign(num: LongInt): LongInt; inline; |
94 function AIrndSign(num: LongInt): LongInt; inline; |
93 function AIrndOffset(targ: TTarget; Level: LongWord): LongInt; inline; |
95 function AIrndOffset(targ: TTarget; Level: LongWord): LongInt; inline; |
537 hadSkips: boolean; |
539 hadSkips: boolean; |
538 begin |
540 begin |
539 x:= round(CheckWrap(real(x))); |
541 x:= round(CheckWrap(real(x))); |
540 fallDmg:= 0; |
542 fallDmg:= 0; |
541 rate:= 0; |
543 rate:= 0; |
542 // add our virtual position |
544 |
543 with Targets.ar[Targets.Count] do |
545 if (Flags and afIgnoreMe) = 0 then |
544 begin |
546 // add our virtual position |
545 Point.x:= hwRound(Me^.X); |
547 with Targets.ar[Targets.Count] do |
546 Point.y:= hwRound(Me^.Y); |
548 begin |
547 skip:= false; |
549 Point.x:= hwRound(Me^.X); |
548 matters:= true; |
550 Point.y:= hwRound(Me^.Y); |
549 Kind:= gtHedgehog; |
551 skip:= false; |
550 Density:= 1; |
552 matters:= true; |
551 Radius:= cHHRadius; |
553 Kind:= gtHedgehog; |
552 Score:= - ThinkingHH^.Health |
554 Density:= 1; |
553 end; |
555 Radius:= cHHRadius; |
|
556 Score:= - ThinkingHH^.Health |
|
557 end; |
|
558 |
554 // rate explosion |
559 // rate explosion |
555 |
|
556 if (Flags and afErasesLand <> 0) and (GameFlags and gfSolidLand = 0) then erasure:= r |
560 if (Flags and afErasesLand <> 0) and (GameFlags and gfSolidLand = 0) then erasure:= r |
557 else erasure:= 0; |
561 else erasure:= 0; |
558 |
562 |
559 hadSkips:= false; |
563 hadSkips:= false; |
560 |
564 |
561 for i:= 0 to Targets.Count do |
565 for i:= 0 to Targets.Count do |
562 if not Targets.ar[i].dead then |
566 if not Targets.ar[i].dead then |
563 with Targets.ar[i] do |
567 with Targets.ar[i] do |
564 if not matters then hadSkips:= true |
568 if not matters then |
565 else |
569 hadSkips:= true |
|
570 else |
566 begin |
571 begin |
567 dmg:= 0; |
572 dmg:= 0; |
568 dmgBase:= r + Radius div 2; |
573 dmgBase:= r + Radius div 2; |
569 if abs(Point.x - x) + abs(Point.y - y) < dmgBase then |
574 if abs(Point.x - x) + abs(Point.y - y) < dmgBase then |
570 dmg:= trunc(dmgMod * min((dmgBase - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)))) div 2, r)); |
575 dmg:= trunc(dmgMod * min((dmgBase - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)))) div 2, r)); |
830 else |
835 else |
831 RateShotgun:= rate * 1024; |
836 RateShotgun:= rate * 1024; |
832 ResetTargets; |
837 ResetTargets; |
833 end; |
838 end; |
834 |
839 |
|
840 function RateSeduction(Me: PGear): LongInt; |
|
841 var pX, pY, i, r, rate, subrate, fallDmg: LongInt; |
|
842 diffX, diffY: LongInt; |
|
843 meX, meY, dX, dY: hwFloat; |
|
844 pXr, pYr: real; |
|
845 hadSkips: boolean; |
|
846 begin |
|
847 meX:= Me^.X; |
|
848 meY:= Me^.Y; |
|
849 rate:= 0; |
|
850 for i:= 0 to Targets.Count do |
|
851 if not Targets.ar[i].dead then |
|
852 with Targets.ar[i] do |
|
853 begin |
|
854 pX:= Point.X; |
|
855 pY:= Point.Y; |
|
856 diffX:= pX - hwRound(meX); |
|
857 diffY:= pY - hwRound(meY); |
|
858 if (Me^.Hedgehog^.BotLevel < 4) and (abs(diffX) <= cHHRadius*2) and (diffY >= 0) and (diffY <= cHHRadius*2) then |
|
859 // Don't use seduction if too close to other hog. We could be |
|
860 // standing on it, so using seduction would remove the ground on |
|
861 // which we stand on, which is dangerous |
|
862 exit(BadTurn); |
|
863 |
|
864 if (not matters) then |
|
865 hadSkips:= true |
|
866 else if matters and (Kind = gtHedgehog) and (abs(pX - hwRound(meX)) + abs(pY - hwRound(meY)) < cSeductionDist) then |
|
867 begin |
|
868 r:= trunc(sqrt(sqr(abs(pX - hwRound(meX)))+sqr(abs(pY - hwRound(meY))))); |
|
869 if r < cSeductionDist then |
|
870 begin |
|
871 |
|
872 if (WorldEdge <> weWrap) or (not (hwAbs(meX - int2hwFloat(pX)) > int2hwFloat(cSeductionDist))) then |
|
873 dX:= _50 * cGravity * (meX - int2hwFloat(pX)) / _25 |
|
874 else if (not (hwAbs(meX + int2hwFloat((RightX-LeftX) - pX)) > int2hwFloat(cSeductionDist))) then |
|
875 dX:= _50 * cGravity * (meX + (int2hwFloat((RightX-LeftX) - pX))) / _25 |
|
876 else |
|
877 dX:= _50 * cGravity * (meX - (int2hwFloat((RightX-LeftX) - pX))) / _25; |
|
878 dY:= -_450 * cMaxWindSpeed * 2; |
|
879 |
|
880 |
|
881 pXr:= pX; |
|
882 pYr:= pY; |
|
883 fallDmg:= trunc(TraceShoveFall(pXr, pYr, hwFloat2Float(dX), hwFloat2Float(dY), Targets.ar[i]) * dmgMod); |
|
884 |
|
885 // rate damage |
|
886 if fallDmg < 0 then // drowning |
|
887 begin |
|
888 if Score > 0 then |
|
889 inc(rate, (KillScore + Score div 10) * 1024) // Add a bit of a bonus for bigger hog drownings |
|
890 else |
|
891 dec(rate, (KillScore * friendlyfactor div 100 - Score div 10) * 1024) // and more of a punishment for drowning bigger friendly hogs |
|
892 end |
|
893 else if (fallDmg) >= abs(Score) then // deadly fall damage |
|
894 begin |
|
895 dead:= true; |
|
896 Targets.reset:= true; |
|
897 if (hwFloat2Float(dX) < 0.035) then |
|
898 begin |
|
899 subrate:= RealRateExplosion(Me, round(pX), round(pY), 61, afErasesLand or afTrackFall); // hog explodes |
|
900 if abs(subrate) > 2000 then |
|
901 inc(rate, subrate) |
|
902 end; |
|
903 if Score > 0 then |
|
904 inc(rate, KillScore * 1024 + (fallDmg)) // tiny bonus for dealing more damage than needed to kill |
|
905 else |
|
906 dec(rate, KillScore * friendlyfactor div 100 * 1024) |
|
907 end |
|
908 else if (fallDmg <> 0) then // non-deadly fall damage |
|
909 if Score > 0 then |
|
910 inc(rate, fallDmg * 1024) |
|
911 else |
|
912 dec(rate, fallDmg * friendlyfactor div 100 * 1024) |
|
913 else // no damage, just shoved |
|
914 if (Score < 0) then |
|
915 dec(rate, 100); // small penalty for shoving friendly hogs as it might be dangerous |
|
916 end; |
|
917 end; |
|
918 end; |
|
919 |
|
920 if hadSkips and (rate <= 0) then |
|
921 RateSeduction:= BadTurn |
|
922 else |
|
923 RateSeduction:= rate * 1024; |
|
924 end; |
|
925 |
835 function RateHammer(Me: PGear): LongInt; |
926 function RateHammer(Me: PGear): LongInt; |
836 var x, y, i, r, rate: LongInt; |
927 var x, y, i, r, rate: LongInt; |
837 hadSkips: boolean; |
928 hadSkips: boolean; |
838 begin |
929 begin |
839 // hammer hit shift against attecker hog is 10 |
930 // hammer hit shift against attecker hog is 10 |