47 procedure initModule; |
47 procedure initModule; |
48 procedure freeModule; |
48 procedure freeModule; |
49 |
49 |
50 procedure FillTargets; |
50 procedure FillTargets; |
51 procedure FillBonuses(isAfterAttack: boolean; filter: TGearsType = []); |
51 procedure FillBonuses(isAfterAttack: boolean; filter: TGearsType = []); |
52 procedure AwareOfExplosion(x, y, r: LongInt); |
52 procedure AwareOfExplosion(x, y, r: LongInt); inline; |
53 function RatePlace(Gear: PGear): LongInt; |
53 function RatePlace(Gear: PGear): LongInt; |
54 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; |
54 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline; |
55 function TestColl(x, y, r: LongInt): boolean; |
55 function TestColl(x, y, r: LongInt): boolean; inline; |
56 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; |
56 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt; |
57 function RateShove(Me: PGear; x, y, r, power: LongInt): LongInt; |
57 function RateShove(Me: PGear; x, y, r, power: LongInt): LongInt; |
58 function RateShotgun(Me: PGear; x, y: LongInt): LongInt; |
58 function RateShotgun(Me: PGear; x, y: LongInt): LongInt; |
59 function RateHammer(Me: PGear): LongInt; |
59 function RateHammer(Me: PGear): LongInt; |
60 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; |
60 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; |
61 function AIrndSign(num: LongInt): LongInt; |
61 function AIrndSign(num: LongInt): LongInt; |
113 |
113 |
114 if e > f then friendlyfactor:= 300 + (e - f) * 30 |
114 if e > f then friendlyfactor:= 300 + (e - f) * 30 |
115 else friendlyfactor:= max(30, 300 - f * 80 div max(1,e)) |
115 else friendlyfactor:= max(30, 300 - f * 80 div max(1,e)) |
116 end; |
116 end; |
117 |
117 |
118 procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt); |
118 procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt); inline; |
119 begin |
119 begin |
120 bonuses.ar[bonuses.Count].x:= x; |
120 bonuses.ar[bonuses.Count].x:= x; |
121 bonuses.ar[bonuses.Count].y:= y; |
121 bonuses.ar[bonuses.Count].y:= y; |
122 bonuses.ar[bonuses.Count].Radius:= r; |
122 bonuses.ar[bonuses.Count].Radius:= r; |
123 bonuses.ar[bonuses.Count].Score:= s; |
123 bonuses.ar[bonuses.Count].Score:= s; |
232 exit(true); |
232 exit(true); |
233 |
233 |
234 TestColl:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] <> 0) |
234 TestColl:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] <> 0) |
235 end; |
235 end; |
236 |
236 |
237 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; |
237 function TestCollWithLand(x, y, r: LongInt): boolean; inline; |
238 var i, dmg, dmgBase, rate: LongInt; |
238 var b: boolean; |
|
239 begin |
|
240 b:= (((x-r) and LAND_WIDTH_MASK) = 0)and(((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] > 255); |
|
241 if b then |
|
242 exit(true); |
|
243 |
|
244 b:=(((x-r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] > 255); |
|
245 if b then |
|
246 exit(true); |
|
247 |
|
248 b:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] > 255); |
|
249 if b then |
|
250 exit(true); |
|
251 |
|
252 TestCollWithLand:=(((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > 255) |
|
253 end; |
|
254 |
|
255 function TraceDrown(eX, eY: LongInt; x, y, dX, dY: Real; r: LongWord): boolean; |
|
256 var skipLandCheck: boolean; |
|
257 rCorner: real; |
|
258 begin |
|
259 if x - eX < 0 then dX*=-1; |
|
260 if y - eY < 0 then dY*=-1; |
|
261 // ok. attempt approximate search for an unbroken trajectory into water. if it continues far enough, assume out of map |
|
262 rCorner:= r * 0.75; |
|
263 while true do |
|
264 begin |
|
265 x:= x + dX; |
|
266 y:= y + dY + cGravityf; |
|
267 skipLandCheck:= (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner)); |
|
268 if not skipLandCheck and TestCollWithLand(trunc(x), trunc(y), cHHRadius) then exit(false); |
|
269 if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(true); |
|
270 end; |
|
271 end; |
|
272 |
|
273 // Flags are not defined yet but 1 for checking drowning and 2 for assuming land erasure. |
|
274 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt; |
|
275 var i, dmg, dmgBase, rate, erasure: LongInt; |
|
276 dX, dY: real; |
239 begin |
277 begin |
240 rate:= 0; |
278 rate:= 0; |
241 // add our virtual position |
279 // add our virtual position |
242 with Targets.ar[Targets.Count] do |
280 with Targets.ar[Targets.Count] do |
243 begin |
281 begin |
245 Point.y:= hwRound(Me^.Y); |
283 Point.y:= hwRound(Me^.Y); |
246 Score:= - ThinkingHH^.Health |
284 Score:= - ThinkingHH^.Health |
247 end; |
285 end; |
248 // rate explosion |
286 // rate explosion |
249 dmgBase:= r + cHHRadius div 2; |
287 dmgBase:= r + cHHRadius div 2; |
|
288 if (Flags and 2 <> 0) and (GameFlags and gfSolidLand = 0) then erasure:= r |
|
289 else erasure:= 0; |
250 for i:= 0 to Targets.Count do |
290 for i:= 0 to Targets.Count do |
251 with Targets.ar[i] do |
291 with Targets.ar[i] do |
252 begin |
292 begin |
253 dmg:= 0; |
293 dmg:= 0; |
254 if abs(Point.x - x) + abs(Point.y - y) < dmgBase then |
294 if abs(Point.x - x) + abs(Point.y - y) < dmgBase then |
255 dmg:= hwRound(_0_01 * cDamageModifier * min((dmgBase - LongInt(DistanceI(Point.x - x, Point.y - y).Round)) div 2, r) * cDamagePercent); |
295 dmg:= hwRound(_0_01 * cDamageModifier * min((dmgBase - LongInt(DistanceI(Point.x - x, Point.y - y).Round)) div 2, r) * cDamagePercent); |
256 |
296 |
257 if dmg > 0 then |
297 if dmg > 0 then |
258 begin |
298 begin |
259 if dmg >= abs(Score) then |
299 if Flags and 1 <> 0 then |
|
300 begin |
|
301 dX:= 0.005 * dmg + 0.01; |
|
302 dY:= dX; |
|
303 end; |
|
304 if (Flags and 1 <> 0) and TraceDrown(x, y, Point.x, Point.y, dX, dY, erasure) then |
|
305 if Score > 0 then |
|
306 begin |
|
307 inc(rate, KillScore) |
|
308 end |
|
309 else |
|
310 dec(rate, KillScore * friendlyfactor div 100) |
|
311 else if dmg >= abs(Score) then |
260 if Score > 0 then |
312 if Score > 0 then |
261 inc(rate, KillScore) |
313 inc(rate, KillScore) |
262 else |
314 else |
263 dec(rate, KillScore * friendlyfactor div 100) |
315 dec(rate, KillScore * friendlyfactor div 100) |
264 else |
316 else |