1472 TestAirAttack:= valueResult; |
1473 TestAirAttack:= valueResult; |
1473 end; |
1474 end; |
1474 |
1475 |
1475 function TestDrillStrike(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
1476 function TestDrillStrike(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; |
1476 const cShift = 4; |
1477 const cShift = 4; |
|
1478 Density : real = 1.0; |
1477 var bombsSpeed, X, Y, dX, dY, drillX, drillY: real; |
1479 var bombsSpeed, X, Y, dX, dY, drillX, drillY: real; |
1478 t2: real; |
1480 t2: real; |
1479 b: array[0..9] of boolean; |
|
1480 dmg: array[0..9] of LongInt; |
1481 dmg: array[0..9] of LongInt; |
1481 fexit, collided: boolean; |
1482 collided, drilling, timerRuns: boolean; |
1482 i, t, value, valueResult, attackTime, drillTimer, targetX: LongInt; |
1483 i, t, value, valueResult, attackTime, drillTimer, targetX: LongInt; |
1483 begin |
1484 begin |
1484 Flags:= Flags; // avoid compiler hint |
1485 Flags:= Flags; // avoid compiler hint |
1485 ap.ExplR:= 0; |
1486 ap.ExplR:= 0; |
1486 // TODO: Add support for More Wind |
1487 if (Level > 3) or (cGravityf = 0) then |
1487 if (Level > 3) or (cGravityf = 0) or ((GameFlags and gfMoreWind) <> 0) then |
|
1488 exit(BadTurn); |
1488 exit(BadTurn); |
1489 |
1489 |
1490 ap.Angle:= 0; |
1490 ap.Angle:= 0; |
1491 targetX:= Targ.Point.X; |
1491 targetX:= Targ.Point.X; |
1492 ap.AttackPutY:= Targ.Point.Y; |
1492 ap.AttackPutY:= Targ.Point.Y; |
1493 |
1493 |
1494 bombsSpeed:= hwFloat2Float(cBombsSpeed); |
1494 bombsSpeed:= hwFloat2Float(cBombsSpeed); |
1495 X:= Targ.Point.X - 135 - cShift; // hh center - cShift |
1495 X:= Targ.Point.X - 135 - cShift; // hh center - cShift |
1496 X:= X - bombsSpeed * sqrt(((Targ.Point.Y + 128) * 2) / cGravityf); |
1496 X:= X - bombsSpeed * sqrt(((Targ.Point.Y + 128) * 2) / cGravityf); |
1497 Y:= -128; |
1497 Y:= -128; |
1498 dX:= bombsSpeed; |
|
1499 dY:= 0; |
|
1500 |
1498 |
1501 valueResult:= 0; |
1499 valueResult:= 0; |
1502 |
1500 |
1503 attackTime:= 0; |
1501 attackTime:= 6000; |
1504 while attackTime <= 4000 do |
1502 while attackTime >= 0 do |
1505 begin |
1503 begin |
1506 inc(attackTime, 1000); |
1504 dec(attackTime, 1000); |
1507 value:= 0; |
1505 value:= 0; |
1508 for i:= 0 to 9 do |
1506 for i:= 0 to 9 do |
1509 begin |
1507 begin |
1510 b[i]:= true; |
1508 dmg[i]:= 0; |
1511 dmg[i]:= 0 |
1509 drillX:= trunc(X) + LongWord(i * 30); |
|
1510 drillY:= trunc(Y); |
|
1511 dX:= bombsSpeed; |
|
1512 dY:= 0; |
|
1513 collided:= false; |
|
1514 drilling:= false; |
|
1515 timerRuns:= false; |
|
1516 drillTimer := attackTime; |
|
1517 |
|
1518 repeat |
|
1519 // Simulate in-air movement |
|
1520 drillX:= drillX + dX; |
|
1521 drillY:= drillY + dY; |
|
1522 if (GameFlags and gfMoreWind) <> 0 then |
|
1523 dX:= dX + windSpeed / Density; |
|
1524 dY:= dY + cGravityf; |
|
1525 |
|
1526 if timerRuns then |
|
1527 dec(drillTimer); |
|
1528 |
|
1529 // Collided with land ... simulate drilling |
|
1530 if (drillTimer > 0) and TestCollExcludingObjects(trunc(drillX), trunc(drillY), 4) and |
|
1531 (Abs(Targ.Point.X - trunc(drillX)) + Abs(Targ.Point.Y - trunc(drillY)) > 21) then |
|
1532 begin |
|
1533 drilling := true; |
|
1534 timerRuns := true; |
|
1535 t2 := 0.5 / sqrt(sqr(dX) + sqr(dY)); |
|
1536 dX := dX * t2; |
|
1537 dY := dY * t2; |
|
1538 repeat |
|
1539 drillX:= drillX + dX; |
|
1540 drillY:= drillY + dY; |
|
1541 dec(drillTimer, 10); |
|
1542 if (Abs(Targ.Point.X - drillX) + Abs(Targ.Point.Y - drillY) < 22) |
|
1543 or (drillX < -32) |
|
1544 or (drillY < -32) |
|
1545 or (trunc(drillX) > LAND_WIDTH + 32) |
|
1546 or (trunc(drillY) > cWaterLine) |
|
1547 or (drillTimer <= 0) then |
|
1548 collided:= true |
|
1549 else if not TestCollExcludingObjects(trunc(drillX), trunc(drillY), 4) then |
|
1550 drilling:= false; |
|
1551 until (collided or (not drilling)); |
|
1552 end |
|
1553 // Collided with something else ... record collision |
|
1554 else if (drillTimer <= 0) or TestColl(trunc(drillX), trunc(drillY), 4) then |
|
1555 collided:= true; |
|
1556 |
|
1557 // Simulate explosion |
|
1558 if collided then |
|
1559 dmg[i]:= RateExplosion(Me, trunc(drillX), trunc(drillY), 58); |
|
1560 // 58 (instead of 60) for better prediction (hh moves after explosion of one of the rockets) |
|
1561 until collided or (drillY > cWaterLine); |
1512 end; |
1562 end; |
1513 |
1563 |
1514 repeat |
1564 // calculate score |
1515 X:= X + dX; |
|
1516 Y:= Y + dY; |
|
1517 dY:= dY + cGravityf; |
|
1518 fexit:= true; |
|
1519 |
|
1520 for i:= 0 to 9 do |
|
1521 if b[i] then |
|
1522 begin |
|
1523 fexit:= false; |
|
1524 collided:= false; |
|
1525 drillX:= trunc(X) + LongWord(i * 30); |
|
1526 drillY:= trunc(Y); |
|
1527 // Collided with land ... simulate drilling |
|
1528 if TestCollExcludingObjects(trunc(drillX), trunc(drillY), 4) and |
|
1529 (Abs(Targ.Point.X - trunc(X)) + Abs(Targ.Point.Y - trunc(Y)) > 21) then |
|
1530 begin |
|
1531 drillTimer := attackTime; |
|
1532 t2 := 0.5 / sqrt(sqr(dX) + sqr(dY)); |
|
1533 dX := dX * t2; |
|
1534 dY := dY * t2; |
|
1535 repeat |
|
1536 drillX:= drillX + dX; |
|
1537 drillY:= drillY + dY; |
|
1538 dec(drillTimer, 10); |
|
1539 until (Abs(Targ.Point.X - drillX) + Abs(Targ.Point.Y - drillY) < 22) |
|
1540 or (drillX < 0) |
|
1541 or (drillY < 0) |
|
1542 or (trunc(drillX) > LAND_WIDTH) |
|
1543 or (trunc(drillY) > LAND_HEIGHT) |
|
1544 // TODO: Simulate falling again when rocket has left terrain again |
|
1545 or (drillTimer <= 0); |
|
1546 collided:= true; |
|
1547 end |
|
1548 // Collided with something else ... record collision |
|
1549 else if TestColl(trunc(drillX), trunc(drillY), 4) then |
|
1550 collided:= true; |
|
1551 |
|
1552 // Simulate explosion |
|
1553 if collided then |
|
1554 begin |
|
1555 b[i]:= false; |
|
1556 dmg[i]:= RateExplosion(Me, trunc(drillX), trunc(drillY), 58); |
|
1557 // 58 (instead of 60) for better prediction (hh moves after explosion of one of the rockets) |
|
1558 end; |
|
1559 end; |
|
1560 until fexit or (Y > cWaterLine); |
|
1561 |
|
1562 for i:= 0 to 5 do |
1565 for i:= 0 to 5 do |
1563 if dmg[i] <> BadTurn then |
1566 if dmg[i] <> BadTurn then |
1564 inc(value, dmg[i]); |
1567 inc(value, dmg[i]); |
1565 t:= value; |
1568 t:= value; |
1566 targetX:= Targ.Point.X - 60; |
1569 targetX:= Targ.Point.X - 60; |