51 procedure FillBonuses(isAfterAttack: boolean; filter: TGearsType = []); |
51 procedure FillBonuses(isAfterAttack: boolean; filter: TGearsType = []); |
52 procedure AwareOfExplosion(x, y, r: LongInt); inline; |
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; inline; |
54 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline; |
55 function TestColl(x, y, r: LongInt): boolean; inline; |
55 function TestColl(x, y, r: LongInt): boolean; inline; |
56 function TraceShoveDrown(Me: PGear; x, y, dX, dY: Real): boolean; |
56 function TraceShoveFall(Me: PGear; x, y, dX, dY: Real): LongInt; |
57 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt; |
57 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt; |
58 function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; |
58 function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; |
59 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; |
59 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; |
60 function RateHammer(Me: PGear): LongInt; |
60 function RateHammer(Me: PGear): LongInt; |
61 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; |
61 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; |
258 exit(true); |
258 exit(true); |
259 |
259 |
260 TestCollWithLand:=(((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > 255) |
260 TestCollWithLand:=(((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > 255) |
261 end; |
261 end; |
262 |
262 |
263 function TraceDrown(eX, eY: LongInt; x, y, dX, dY: Real; r: LongWord): boolean; |
263 function TraceFall(eX, eY: LongInt; x, y, dX, dY: Real; r: LongWord): LongInt; |
264 var skipLandCheck: boolean; |
264 var skipLandCheck: boolean; |
265 rCorner: real; |
265 rCorner: real; |
|
266 dmg: LongInt; |
266 begin |
267 begin |
267 skipLandCheck:= true; |
268 skipLandCheck:= true; |
268 if x - eX < 0 then dX:= -dX; |
269 if x - eX < 0 then dX:= -dX; |
269 if y - eY < 0 then dY:= -dY; |
270 if y - eY < 0 then dY:= -dY; |
270 // ok. attempt approximate search for an unbroken trajectory into water. if it continues far enough, assume out of map |
271 // ok. attempt approximate search for an unbroken trajectory into water. if it continues far enough, assume out of map |
273 begin |
274 begin |
274 x:= x + dX; |
275 x:= x + dX; |
275 y:= y + dY; |
276 y:= y + dY; |
276 dY:= dY + cGravityf; |
277 dY:= dY + cGravityf; |
277 skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner)); |
278 skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner)); |
278 // consider adding dX/dY calc here for fall damage |
279 if not skipLandCheck and TestCollWithLand(trunc(x), trunc(y), cHHRadius) then |
279 if not skipLandCheck and TestCollWithLand(trunc(x), trunc(y), cHHRadius) then exit(false); |
280 begin |
280 if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(true); |
281 if 0.4 < dY then |
281 end; |
282 begin |
282 end; |
283 dmg := 1 + trunc((abs(dY) - 0.4) * 70); |
283 |
284 if dmg >= 1 then exit(dmg) |
284 function TraceShoveDrown(Me: PGear; x, y, dX, dY: Real): boolean; |
285 end; |
|
286 exit(0) |
|
287 end; |
|
288 if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(-1); // returning -1 for drowning so it can be considered in the Rate routine |
|
289 end; |
|
290 end; |
|
291 |
|
292 function TraceShoveFall(Me: PGear; x, y, dX, dY: Real): LongInt; |
|
293 var dmg: LongInt; |
285 begin |
294 begin |
286 while true do |
295 while true do |
287 begin |
296 begin |
288 x:= x + dX; |
297 x:= x + dX; |
289 y:= y + dY; |
298 y:= y + dY; |
290 dY:= dY + cGravityf; |
299 dY:= dY + cGravityf; |
291 // consider adding dX/dY calc here for fall damage |
300 // consider adding dX/dY calc here for fall damage |
292 if TestCollExcludingMe(Me, trunc(x), trunc(y), cHHRadius) then exit(false); |
301 if TestCollExcludingMe(Me, trunc(x), trunc(y), cHHRadius) then |
293 if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(true); |
302 begin |
|
303 if 0.4 < dY then |
|
304 begin |
|
305 dmg := 1 + trunc((abs(dY) - 0.4) * 70); |
|
306 if dmg >= 1 then exit(dmg) |
|
307 end; |
|
308 exit(0) |
|
309 end; |
|
310 if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(-1); // returning -1 for drowning so it can be considered in the Rate routine |
294 end; |
311 end; |
295 end; |
312 end; |
296 |
313 |
297 // Flags are not defined yet but 1 for checking drowning and 2 for assuming land erasure. |
314 // Flags are not defined yet but 1 for checking drowning and 2 for assuming land erasure. |
298 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt; |
315 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt; |
299 var i, dmg, dmgBase, rate, erasure: LongInt; |
316 var i, fallDmg, dmg, dmgBase, rate, erasure: LongInt; |
300 dX, dY, dmgMod: real; |
317 dX, dY, dmgMod: real; |
301 begin |
318 begin |
|
319 fallDmg:= 0; |
302 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent; |
320 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent; |
303 rate:= 0; |
321 rate:= 0; |
304 // add our virtual position |
322 // add our virtual position |
305 with Targets.ar[Targets.Count] do |
323 with Targets.ar[Targets.Count] do |
306 begin |
324 begin |
323 begin |
341 begin |
324 if Flags and 1 <> 0 then |
342 if Flags and 1 <> 0 then |
325 begin |
343 begin |
326 dX:= 0.005 * dmg + 0.01; |
344 dX:= 0.005 * dmg + 0.01; |
327 dY:= dX; |
345 dY:= dX; |
|
346 fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod); |
328 end; |
347 end; |
329 if (Flags and 1 <> 0) and TraceDrown(x, y, Point.x, Point.y, dX, dY, erasure) then |
348 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
330 if Score > 0 then |
349 if Score > 0 then |
331 inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings |
350 inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings |
332 else |
351 else |
333 dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs |
352 dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs |
334 else if dmg >= abs(Score) then |
353 else if (dmg+fallDmg) >= abs(Score) then |
335 if Score > 0 then |
354 if Score > 0 then |
336 inc(rate, KillScore) |
355 inc(rate, KillScore) |
337 else |
356 else |
338 dec(rate, KillScore * friendlyfactor div 100) |
357 dec(rate, KillScore * friendlyfactor div 100) |
339 else |
358 else |
340 if Score > 0 then |
359 if Score > 0 then |
341 inc(rate, dmg) |
360 inc(rate, dmg+fallDmg) |
342 else |
361 else |
343 dec(rate, dmg * friendlyfactor div 100) |
362 dec(rate, (dmg+fallDmg) * friendlyfactor div 100) |
344 end; |
363 end; |
345 end; |
364 end; |
346 RateExplosion:= rate * 1024; |
365 RateExplosion:= rate * 1024; |
347 end; |
366 end; |
348 |
367 |
349 function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; |
368 function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; |
350 var i, dmg, rate: LongInt; |
369 var i, fallDmg, dmg, rate: LongInt; |
351 dX, dY, dmgMod: real; |
370 dX, dY, dmgMod: real; |
352 begin |
371 begin |
|
372 fallDmg:= 0; |
353 dX:= gdX * 0.005 * kick; |
373 dX:= gdX * 0.005 * kick; |
354 dY:= gdY * 0.005 * kick; |
374 dY:= gdY * 0.005 * kick; |
355 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent; |
375 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent; |
356 rate:= 0; |
376 rate:= 0; |
357 for i:= 0 to Pred(Targets.Count) do |
377 for i:= 0 to Pred(Targets.Count) do |
363 dmg:= r - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y))); |
383 dmg:= r - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y))); |
364 dmg:= trunc(dmg * dmgMod); |
384 dmg:= trunc(dmg * dmgMod); |
365 end; |
385 end; |
366 if dmg > 0 then |
386 if dmg > 0 then |
367 begin |
387 begin |
368 if (Flags and 1 <> 0) and TraceShoveDrown(Me, Point.x, Point.y-2, dX, dY) then |
388 if (Flags and 1 <> 0) then |
|
389 fallDmg:= trunc(TraceShoveFall(Me, Point.x, Point.y-2, dX, dY) * dmgMod); |
|
390 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
369 if Score > 0 then |
391 if Score > 0 then |
370 inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings |
392 inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings |
371 else |
393 else |
372 dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs |
394 dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs |
373 else if power >= abs(Score) then |
395 else if power+fallDmg >= abs(Score) then |
374 if Score > 0 then |
396 if Score > 0 then |
375 inc(rate, KillScore) |
397 inc(rate, KillScore) |
376 else |
398 else |
377 dec(rate, KillScore * friendlyfactor div 100) |
399 dec(rate, KillScore * friendlyfactor div 100) |
378 else |
400 else |
379 if Score > 0 then |
401 if Score > 0 then |
380 inc(rate, power) |
402 inc(rate, power+fallDmg) |
381 else |
403 else |
382 dec(rate, power * friendlyfactor div 100) |
404 dec(rate, (power+fallDmg) * friendlyfactor div 100) |
383 end; |
405 end; |
384 end; |
406 end; |
385 RateShove:= rate * 1024 |
407 RateShove:= rate * 1024 |
386 end; |
408 end; |
387 |
409 |
388 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; |
410 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; |
389 var i, dmg, baseDmg, rate, erasure: LongInt; |
411 var i, dmg, fallDmg, baseDmg, rate, erasure: LongInt; |
390 dX, dY, dmgMod: real; |
412 dX, dY, dmgMod: real; |
391 begin |
413 begin |
392 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent; |
414 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent; |
393 rate:= 0; |
415 rate:= 0; |
394 gdX:= gdX * 0.01; |
416 gdX:= gdX * 0.01; |
417 begin |
439 begin |
418 dX:= gdX * dmg; |
440 dX:= gdX * dmg; |
419 dY:= gdY * dmg; |
441 dY:= gdY * dmg; |
420 if dX < 0 then dX:= dX - 0.01 |
442 if dX < 0 then dX:= dX - 0.01 |
421 else dX:= dX + 0.01; |
443 else dX:= dX + 0.01; |
422 if TraceDrown(x, y, Point.x, Point.y, dX, dY, erasure) then |
444 fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod); |
|
445 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
423 if Score > 0 then |
446 if Score > 0 then |
424 inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings |
447 inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings |
425 else |
448 else |
426 dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs |
449 dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs |
427 else if dmg >= abs(Score) then |
450 else if (dmg+fallDmg) >= abs(Score) then |
428 dmg := KillScore; |
451 if Score > 0 then |
429 if Score > 0 then |
452 inc(rate, KillScore) |
430 inc(rate, dmg) |
453 else |
|
454 dec(rate, KillScore * friendlyfactor div 100) |
431 else |
455 else |
432 dec(rate, dmg * friendlyfactor div 100); |
456 if Score > 0 then |
|
457 inc(rate, dmg+fallDmg) |
|
458 else |
|
459 dec(rate, (dmg+fallDmg) * friendlyfactor div 100) |
433 end; |
460 end; |
434 end; |
461 end; |
435 RateShotgun:= rate * 1024; |
462 RateShotgun:= rate * 1024; |
436 end; |
463 end; |
437 |
464 |