64 function TestSeduction(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
64 function TestSeduction(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
65 function TestDynamite(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
65 function TestDynamite(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
66 function TestMine(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
66 function TestMine(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
67 function TestKnife(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
67 function TestKnife(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
68 function TestAirMine(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
68 function TestAirMine(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
|
69 function TestMinigun(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
69 |
70 |
70 type TAmmoTestProc = function (Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
71 type TAmmoTestProc = function (Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
71 TAmmoTest = record |
72 TAmmoTest = record |
72 proc: TAmmoTestProc; |
73 proc: TAmmoTestProc; |
73 flags: Longword; |
74 flags: Longword; |
133 (proc: nil; flags: 0), // amIceGun |
134 (proc: nil; flags: 0), // amIceGun |
134 (proc: @TestKnife; flags: 0), // amKnife |
135 (proc: @TestKnife; flags: 0), // amKnife |
135 (proc: nil; flags: 0), // amRubber |
136 (proc: nil; flags: 0), // amRubber |
136 (proc: @TestAirMine; flags: 0), // amAirMine |
137 (proc: @TestAirMine; flags: 0), // amAirMine |
137 (proc: nil; flags: 0), // amCreeper |
138 (proc: nil; flags: 0), // amCreeper |
138 (proc: @TestShotgun; flags: 0) // amMinigun |
139 (proc: @TestMinigun; flags: 0) // amMinigun |
139 ); |
140 ); |
140 |
141 |
141 implementation |
142 implementation |
142 uses uVariables, uUtils, uGearsHandlers; |
143 uses uVariables, uUtils, uGearsHandlers; |
143 |
144 |
2167 or (trunc(y) > LAND_HEIGHT); |
2168 or (trunc(y) > LAND_HEIGHT); |
2168 |
2169 |
2169 TestAirMine := BadTurn |
2170 TestAirMine := BadTurn |
2170 end; |
2171 end; |
2171 |
2172 |
|
2173 function TestMinigun(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
|
2174 const |
|
2175 MAX_RANGE = 400; |
|
2176 var Vx, Vy, x, y: real; |
|
2177 rx, ry, valueResult: LongInt; |
|
2178 range: integer; |
|
2179 begin |
|
2180 // This code is still very similar to TestShotgun, |
|
2181 // but it's a good simple estimate. |
|
2182 // TODO: Simulate random bullets |
|
2183 // TODO: Replace RateShotgun with something else |
|
2184 // TODO: Teach AI to move aim during shooting |
|
2185 Flags:= Flags; // avoid compiler hint |
|
2186 TestMinigun:= BadTurn; |
|
2187 ap.ExplR:= 0; |
|
2188 ap.Time:= 0; |
|
2189 ap.Power:= 1; |
|
2190 x:= hwFloat2Float(Me^.X); |
|
2191 y:= hwFloat2Float(Me^.Y); |
|
2192 range:= Metric(trunc(x), trunc(y), Targ.Point.X, Targ.Point.Y); |
|
2193 if ( range > MAX_RANGE ) then |
|
2194 exit(BadTurn); |
|
2195 |
|
2196 Vx:= (Targ.Point.X - x) * 1 / 1024; |
|
2197 Vy:= (Targ.Point.Y - y) * 1 / 1024; |
|
2198 ap.Angle:= DxDy2AttackAnglef(Vx, -Vy); |
|
2199 // Minigun angle is limited |
|
2200 if (ap.Angle < Ammoz[amMinigun].minAngle) or (ap.Angle > Ammoz[amMinigun].maxAngle) then |
|
2201 exit(BadTurn); |
|
2202 |
|
2203 // Apply inaccuracy |
|
2204 if (not cLaserSighting) then |
|
2205 inc(ap.Angle, + AIrndSign(random((Level - 1) * 10))); |
|
2206 repeat |
|
2207 x:= x + vX; |
|
2208 y:= y + vY; |
|
2209 rx:= trunc(x); |
|
2210 ry:= trunc(y); |
|
2211 if ((Me = CurrentHedgehog^.Gear) and TestColl(rx, ry, 1)) or |
|
2212 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, rx, ry, 1)) then |
|
2213 begin |
|
2214 x:= x + vX * 8; |
|
2215 y:= y + vY * 8; |
|
2216 // TODO: Use different rating function |
|
2217 valueResult:= RateShotgun(Me, vX, vY, rx, ry); |
|
2218 |
|
2219 if (valueResult = 0) and (Targ.Kind = gtHedgehog) and (Targ.Score > 0) then |
|
2220 begin |
|
2221 if GameFlags and gfSolidLand = 0 then |
|
2222 valueResult:= 1024 - Metric(Targ.Point.X, Targ.Point.Y, rx, ry) div 64 |
|
2223 else valueResult := BadTurn |
|
2224 end |
|
2225 else |
|
2226 dec(valueResult, Level * 4000); |
|
2227 exit(valueResult) |
|
2228 end |
|
2229 until (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 4) |
|
2230 or (x < 0) |
|
2231 or (y < 0) |
|
2232 or (trunc(x) > LAND_WIDTH) |
|
2233 or (trunc(y) > LAND_HEIGHT); |
|
2234 |
|
2235 TestMinigun:= BadTurn |
|
2236 end; |
2172 |
2237 |
2173 end. |
2238 end. |