427 |
428 |
428 doStepFallingGear(Gear); |
429 doStepFallingGear(Gear); |
429 CalcRotationDirAngle(Gear); |
430 CalcRotationDirAngle(Gear); |
430 |
431 |
431 // let's add some smoke depending on speed |
432 // let's add some smoke depending on speed |
432 s:= max(32,152 - hwRound(Distance(Gear^.dX,Gear^.dY)*120))+random(10); |
433 s:= max(32,152 - round((abs(hwFloat2FLoat(Gear^.dX))+abs(hwFloat2Float(Gear^.dY)))*120))+random(10); |
433 if (GameTicks mod s) = 0 then |
434 if (GameTicks mod s) = 0 then |
434 begin |
435 begin |
435 // adjust angle to match the texture |
436 // adjust angle to match the texture |
436 if Gear^.dX.isNegative then |
437 if Gear^.dX.isNegative then |
437 i:= 130 |
438 i:= 130 |
438 else |
439 else i:= 50; |
439 i:= 50; |
|
440 |
440 |
441 smoke:= AddVisualGear(hwRound(Gear^.X)-round(cos((Gear^.DirAngle+i) * pi / 180)*20), hwRound(Gear^.Y)-round(sin((Gear^.DirAngle+i) * pi / 180)*20), vgtSmoke); |
441 smoke:= AddVisualGear(hwRound(Gear^.X)-round(cos((Gear^.DirAngle+i) * pi / 180)*20), hwRound(Gear^.Y)-round(sin((Gear^.DirAngle+i) * pi / 180)*20), vgtSmoke); |
442 if smoke <> nil then |
442 if smoke <> nil then |
443 smoke^.Scale:= 0.75; |
443 smoke^.Scale:= 0.75; |
444 end; |
444 end; |
502 |
502 |
503 if (Gear^.Kind = gtMelonPiece) |
503 if (Gear^.Kind = gtMelonPiece) |
504 or (Gear^.Kind = gtBall) then |
504 or (Gear^.Kind = gtBall) then |
505 CalcRotationDirAngle(Gear) |
505 CalcRotationDirAngle(Gear) |
506 else if (GameTicks and $1F) = 0 then |
506 else if (GameTicks and $1F) = 0 then |
507 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
507 begin |
|
508 if hwRound(Gear^.Y) > cWaterLine then |
|
509 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble) |
|
510 else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
|
511 end |
508 end; |
512 end; |
509 |
513 |
510 //////////////////////////////////////////////////////////////////////////////// |
514 //////////////////////////////////////////////////////////////////////////////// |
511 procedure doStepShell(Gear: PGear); |
515 procedure doStepShell(Gear: PGear); |
512 begin |
516 begin |
519 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
523 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
520 DeleteGear(Gear); |
524 DeleteGear(Gear); |
521 exit |
525 exit |
522 end; |
526 end; |
523 if (GameTicks and $3F) = 0 then |
527 if (GameTicks and $3F) = 0 then |
524 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); |
528 begin |
|
529 if hwRound(Gear^.Y) > cWaterLine then |
|
530 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble) |
|
531 else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
|
532 end |
525 end; |
533 end; |
526 |
534 |
527 //////////////////////////////////////////////////////////////////////////////// |
535 //////////////////////////////////////////////////////////////////////////////// |
528 procedure doStepSnowball(Gear: PGear); |
536 procedure doStepSnowball(Gear: PGear); |
529 var kick, i: LongInt; |
537 var kick, i: LongInt; |
530 particle: PVisualGear; |
538 particle: PVisualGear; |
|
539 gdX, gdY: hwFloat; |
531 begin |
540 begin |
532 AllInactive := false; |
541 AllInactive := false; |
533 if (GameFlags and gfMoreWind) = 0 then |
542 if (GameFlags and gfMoreWind) = 0 then |
534 Gear^.dX := Gear^.dX + cWindSpeed; |
543 Gear^.dX := Gear^.dX + cWindSpeed; |
|
544 gdX := Gear^.dX; |
|
545 gdY := Gear^.dY; |
535 doStepFallingGear(Gear); |
546 doStepFallingGear(Gear); |
536 CalcRotationDirAngle(Gear); |
547 CalcRotationDirAngle(Gear); |
537 if (Gear^.State and gstCollision) <> 0 then |
548 if (Gear^.State and gstCollision) <> 0 then |
538 begin |
549 begin |
539 kick:= hwRound((hwAbs(Gear^.dX)+hwAbs(Gear^.dY)) * _20); |
550 kick:= hwRound((hwAbs(gdX)+hwAbs(gdY)) * _20); |
540 Gear^.dY.isNegative:= (not Gear^.dY.isNegative); |
551 Gear^.dX:= gdX; |
541 Gear^.dX.isNegative:= (not Gear^.dX.isNegative); |
552 Gear^.dY:= gdY; |
542 AmmoShove(Gear, 0, kick); |
553 AmmoShove(Gear, 0, kick); |
543 for i:= 15 + kick div 10 downto 0 do |
554 for i:= 15 + kick div 10 downto 0 do |
544 begin |
555 begin |
545 particle := AddVisualGear(hwRound(Gear^.X) + Random(25), hwRound(Gear^.Y) + Random(25), vgtDust); |
556 particle := AddVisualGear(hwRound(Gear^.X) + Random(25), hwRound(Gear^.Y) + Random(25), vgtDust); |
546 if particle <> nil then |
557 if particle <> nil then |
1434 end |
1447 end |
1435 else if (GameTicks and $3F) = 25 then |
1448 else if (GameTicks and $3F) = 25 then |
1436 doStepFallingGear(Gear); |
1449 doStepFallingGear(Gear); |
1437 if (Gear^.Health = 0) then |
1450 if (Gear^.Health = 0) then |
1438 begin |
1451 begin |
1439 if (not Gear^.dY.isNegative) and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
1452 if (dxdy > _0_4) and (Gear^.State and gstCollision <> 0) then |
1440 inc(Gear^.Damage, hwRound(Gear^.dY * _70)) |
1453 inc(Gear^.Damage, hwRound(dxdy * _50)); |
1441 else if (not Gear^.dX.isNegative) and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then |
|
1442 inc(Gear^.Damage, hwRound(Gear^.dX * _70)) |
|
1443 else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then |
|
1444 inc(Gear^.Damage, hwRound(Gear^.dY * -_70)) |
|
1445 else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then |
|
1446 inc(Gear^.Damage, hwRound(Gear^.dX * -_70)); |
|
1447 |
1454 |
1448 if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then |
1455 if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then |
1449 begin |
1456 begin |
1450 vg:= AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke); |
1457 vg:= AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke); |
1451 if vg <> nil then |
1458 if vg <> nil then |
1575 dec(Gear^.Timer); |
1582 dec(Gear^.Timer); |
1576 end; |
1583 end; |
1577 |
1584 |
1578 /////////////////////////////////////////////////////////////////////////////// |
1585 /////////////////////////////////////////////////////////////////////////////// |
1579 |
1586 |
1580 (* |
|
1581 TODO |
|
1582 Increase damage as barrel smokes? |
|
1583 Try tweaking friction some more |
|
1584 *) |
|
1585 procedure doStepRollingBarrel(Gear: PGear); |
1587 procedure doStepRollingBarrel(Gear: PGear); |
1586 var |
1588 var |
1587 i: LongInt; |
1589 i: LongInt; |
1588 particle: PVisualGear; |
1590 particle: PVisualGear; |
|
1591 dxdy: hwFloat; |
1589 begin |
1592 begin |
1590 if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then |
1593 if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then |
1591 SetLittle(Gear^.dY); |
1594 SetLittle(Gear^.dY); |
1592 Gear^.State := Gear^.State or gstAnimation; |
1595 Gear^.State := Gear^.State or gstAnimation; |
|
1596 if Gear^.Health < cBarrelHealth then Gear^.State:= Gear^.State and not gstFrozen; |
1593 |
1597 |
1594 if ((Gear^.dX.QWordValue <> 0) |
1598 if ((Gear^.dX.QWordValue <> 0) |
1595 or (Gear^.dY.QWordValue <> 0)) then |
1599 or (Gear^.dY.QWordValue <> 0)) then |
1596 begin |
1600 begin |
1597 DeleteCI(Gear); |
1601 DeleteCI(Gear); |
1598 AllInactive := false; |
1602 AllInactive := false; |
1599 if (not Gear^.dY.isNegative) and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
1603 dxdy:= hwAbs(Gear^.dX)+hwAbs(Gear^.dY); |
1600 begin |
1604 doStepFallingGear(Gear); |
1601 Gear^.State := Gear^.State or gsttmpFlag; |
1605 if (Gear^.State and gstCollision <> 0) and(dxdy > _0_4) then |
1602 inc(Gear^.Damage, hwRound(Gear^.dY * _70)); |
1606 begin |
1603 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do |
1607 if (TestCollisionYwithGear(Gear, 1) <> 0) then |
1604 begin |
1608 begin |
1605 particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12,vgtDust); |
1609 Gear^.State := Gear^.State or gsttmpFlag; |
1606 if particle <> nil then |
1610 for i:= min(12, hwRound(dxdy*_10)) downto 0 do |
1607 particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480) |
1611 begin |
1608 end |
1612 particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12,vgtDust); |
1609 end |
1613 if particle <> nil then |
1610 else if (not Gear^.dX.isNegative) and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then |
1614 particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480) |
1611 inc(Gear^.Damage, hwRound(Gear^.dX * _70)) |
1615 end |
1612 |
1616 end; |
1613 else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then |
1617 inc(Gear^.Damage, hwRound(dxdy * _50)) |
1614 inc(Gear^.Damage, hwRound(Gear^.dY * -_70)) |
1618 end; |
1615 |
|
1616 else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then |
|
1617 inc(Gear^.Damage, hwRound(Gear^.dX * -_70)); |
|
1618 |
|
1619 doStepFallingGear(Gear); |
|
1620 CalcRotationDirAngle(Gear); |
1619 CalcRotationDirAngle(Gear); |
1621 //CheckGearDrowning(Gear) |
1620 //CheckGearDrowning(Gear) |
1622 end |
1621 end |
1623 else |
1622 else |
1624 begin |
1623 begin |
1682 with CurrentHedgehog^ do |
1677 with CurrentHedgehog^ do |
1683 if Gear <> nil then |
1678 if Gear <> nil then |
1684 Gear^.Message := Gear^.Message and (not (gmLJump or gmHJump)); |
1679 Gear^.Message := Gear^.Message and (not (gmLJump or gmHJump)); |
1685 exit |
1680 exit |
1686 end; |
1681 end; |
1687 |
1682 if (k = gtExplosives) and (Gear^.Health < cBarrelHealth) then Gear^.State:= Gear^.State and not gstFrozen; |
1688 if k = gtExplosives then |
1683 |
1689 begin |
1684 if ((k <> gtExplosives) and (Gear^.Damage > 0)) or ((k = gtExplosives) and (Gear^.Health<=0)) then |
1690 //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation; |
|
1691 if (hwAbs(Gear^.dX) > _0_15) or ((hwAbs(Gear^.dY) > _0_15) and (hwAbs(Gear^.dX) > _0_02)) then |
|
1692 Gear^.doStep := @doStepRollingBarrel; |
|
1693 |
|
1694 if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then |
|
1695 if (cBarrelHealth div Gear^.Health) > 2 then |
|
1696 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke) |
|
1697 else |
|
1698 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite); |
|
1699 dec(Gear^.Health, Gear^.Damage); |
|
1700 Gear^.Damage := 0; |
|
1701 if Gear^.Health <= 0 then |
|
1702 exBoom := true; |
|
1703 end |
|
1704 else |
|
1705 begin |
|
1706 if (Gear^.Pos <> posCaseHealth) and (GameTicks and $1FFF = 0) then // stir 'em up periodically |
|
1707 begin |
|
1708 gi := GearsList; |
|
1709 while gi <> nil do |
|
1710 begin |
|
1711 if gi^.Kind = gtGenericFaller then |
|
1712 begin |
|
1713 gi^.Active:= true; |
|
1714 gi^.X:= int2hwFloat(GetRandom(rightX-leftX)+leftX); |
|
1715 gi^.Y:= int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY); |
|
1716 gi^.dX:= _90-(GetRandomf*_360); |
|
1717 gi^.dY:= _90-(GetRandomf*_360) |
|
1718 end; |
|
1719 gi := gi^.NextGear |
|
1720 end |
|
1721 end; |
|
1722 |
|
1723 if Gear^.Timer = 500 then |
|
1724 begin |
|
1725 (* Can't make sparkles team coloured without working out what the next team is going to be. This should be solved, really, since it also screws up |
|
1726 voices. Reinforcements voices is heard for active team, not team-to-be. Either that or change crate spawn from end of turn to start, although that |
|
1727 has its own complexities. *) |
|
1728 // Abuse a couple of gear values to track origin |
|
1729 Gear^.Angle:= hwRound(Gear^.Y); |
|
1730 Gear^.Tag:= random(2); |
|
1731 inc(Gear^.Timer) |
|
1732 end; |
|
1733 if Gear^.Timer < 1833 then inc(Gear^.Timer); |
|
1734 if Gear^.Timer = 1000 then |
|
1735 begin |
|
1736 sparkles:= AddVisualGear(hwRound(Gear^.X), Gear^.Angle, vgtDust, 1); |
|
1737 if sparkles <> nil then |
|
1738 begin |
|
1739 sparkles^.dX:= 0; |
|
1740 sparkles^.dY:= 0; |
|
1741 sparkles^.Angle:= 270; |
|
1742 if Gear^.Tag = 1 then |
|
1743 sparkles^.Tint:= $3744D7FF |
|
1744 else sparkles^.Tint:= $FAB22CFF |
|
1745 end; |
|
1746 end; |
|
1747 if Gear^.Timer < 1000 then |
|
1748 begin |
|
1749 AllInactive:= false; |
|
1750 exit |
|
1751 end |
|
1752 end; |
|
1753 |
|
1754 if (Gear^.Damage > 0) or exBoom then |
|
1755 begin |
1685 begin |
1756 x := hwRound(Gear^.X); |
1686 x := hwRound(Gear^.X); |
1757 y := hwRound(Gear^.Y); |
1687 y := hwRound(Gear^.Y); |
1758 hog:= Gear^.Hedgehog; |
1688 hog:= Gear^.Hedgehog; |
1759 |
1689 |
1777 AddGear(x, y, gtFlame, gstTmpFlag, -dX, -dY, 0); |
1707 AddGear(x, y, gtFlame, gstTmpFlag, -dX, -dY, 0); |
1778 end |
1708 end |
1779 end; |
1709 end; |
1780 exit |
1710 exit |
1781 end; |
1711 end; |
|
1712 |
|
1713 if k = gtExplosives then |
|
1714 begin |
|
1715 //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation; |
|
1716 if (hwAbs(Gear^.dX) > _0_15) or ((hwAbs(Gear^.dY) > _0_15) and (hwAbs(Gear^.dX) > _0_02)) then |
|
1717 begin |
|
1718 Gear^.doStep := @doStepRollingBarrel; |
|
1719 exit; |
|
1720 end |
|
1721 else Gear^.dX:= _0; |
|
1722 |
|
1723 if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then |
|
1724 if (cBarrelHealth div Gear^.Health) > 2 then |
|
1725 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke) |
|
1726 else |
|
1727 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite); |
|
1728 dec(Gear^.Health, Gear^.Damage); |
|
1729 Gear^.Damage := 0; |
|
1730 end |
|
1731 else |
|
1732 begin |
|
1733 if (Gear^.Pos <> posCaseHealth) and (GameTicks and $1FFF = 0) then // stir 'em up periodically |
|
1734 begin |
|
1735 gi := GearsList; |
|
1736 while gi <> nil do |
|
1737 begin |
|
1738 if gi^.Kind = gtGenericFaller then |
|
1739 begin |
|
1740 gi^.Active:= true; |
|
1741 gi^.X:= int2hwFloat(GetRandom(rightX-leftX)+leftX); |
|
1742 gi^.Y:= int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY); |
|
1743 gi^.dX:= _90-(GetRandomf*_360); |
|
1744 gi^.dY:= _90-(GetRandomf*_360) |
|
1745 end; |
|
1746 gi := gi^.NextGear |
|
1747 end |
|
1748 end; |
|
1749 |
|
1750 if Gear^.Timer = 500 then |
|
1751 begin |
|
1752 (* Can't make sparkles team coloured without working out what the next team is going to be. This should be solved, really, since it also screws up |
|
1753 voices. Reinforcements voices is heard for active team, not team-to-be. Either that or change crate spawn from end of turn to start, although that |
|
1754 has its own complexities. *) |
|
1755 // Abuse a couple of gear values to track origin |
|
1756 Gear^.Angle:= hwRound(Gear^.Y); |
|
1757 Gear^.Tag:= random(2); |
|
1758 inc(Gear^.Timer) |
|
1759 end; |
|
1760 if Gear^.Timer < 1833 then inc(Gear^.Timer); |
|
1761 if Gear^.Timer = 1000 then |
|
1762 begin |
|
1763 sparkles:= AddVisualGear(hwRound(Gear^.X), Gear^.Angle, vgtDust, 1); |
|
1764 if sparkles <> nil then |
|
1765 begin |
|
1766 sparkles^.dX:= 0; |
|
1767 sparkles^.dY:= 0; |
|
1768 sparkles^.Angle:= 270; |
|
1769 if Gear^.Tag = 1 then |
|
1770 sparkles^.Tint:= $3744D7FF |
|
1771 else sparkles^.Tint:= $FAB22CFF |
|
1772 end; |
|
1773 end; |
|
1774 if Gear^.Timer < 1000 then |
|
1775 begin |
|
1776 AllInactive:= false; |
|
1777 exit |
|
1778 end |
|
1779 end; |
|
1780 |
1782 |
1781 |
1783 if (Gear^.dY.QWordValue <> 0) |
1782 if (Gear^.dY.QWordValue <> 0) |
1784 or (TestCollisionYwithGear(Gear, 1) = 0) then |
1783 or (TestCollisionYwithGear(Gear, 1) = 0) then |
1785 begin |
1784 begin |
1786 AllInactive := false; |
1785 AllInactive := false; |
2430 //////////////////////////////////////////////////////////////////////////////// |
2429 //////////////////////////////////////////////////////////////////////////////// |
2431 procedure doStepMortar(Gear: PGear); |
2430 procedure doStepMortar(Gear: PGear); |
2432 var |
2431 var |
2433 dX, dY, gdX, gdY: hwFloat; |
2432 dX, dY, gdX, gdY: hwFloat; |
2434 i: LongInt; |
2433 i: LongInt; |
2435 dxn, dyn: boolean; |
|
2436 begin |
2434 begin |
2437 AllInactive := false; |
2435 AllInactive := false; |
2438 dxn := Gear^.dX.isNegative; |
2436 gdX := Gear^.dX; |
2439 dyn := Gear^.dY.isNegative; |
2437 gdY := Gear^.dY; |
2440 |
2438 |
2441 doStepFallingGear(Gear); |
2439 doStepFallingGear(Gear); |
2442 if (Gear^.State and gstCollision) <> 0 then |
2440 if (Gear^.State and gstCollision) <> 0 then |
2443 begin |
2441 begin |
2444 gdX := Gear^.dX; |
|
2445 gdY := Gear^.dY; |
|
2446 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLAutoSound); |
2442 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLAutoSound); |
2447 |
2443 gdX.isNegative := not gdX.isNegative; |
2448 gdX.isNegative := not dxn; |
2444 gdY.isNegative := not gdY.isNegative; |
2449 gdY.isNegative := not dyn; |
2445 gdX:= gdX*_0_2; |
|
2446 gdY:= gdY*_0_2; |
|
2447 |
2450 for i:= 0 to 4 do |
2448 for i:= 0 to 4 do |
2451 begin |
2449 begin |
2452 dX := gdX + (GetRandomf - _0_5) * _0_03; |
2450 dX := gdX + rndSign(GetRandomf) * _0_03; |
2453 dY := gdY + (GetRandomf - _0_5) * _0_03; |
2451 dY := gdY + rndSign(GetRandomf) * _0_03; |
2454 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25); |
2452 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25); |
2455 end; |
2453 end; |
2456 |
2454 |
2457 DeleteGear(Gear); |
2455 DeleteGear(Gear); |
2458 exit |
2456 exit |
2459 end; |
2457 end; |
2460 |
2458 |
2461 if (GameTicks and $3F) = 0 then |
2459 if (GameTicks and $3F) = 0 then |
2462 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
2460 begin |
|
2461 if hwRound(Gear^.Y) > cWaterLine then |
|
2462 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble) |
|
2463 else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
|
2464 end |
2463 end; |
2465 end; |
2464 |
2466 |
2465 //////////////////////////////////////////////////////////////////////////////// |
2467 //////////////////////////////////////////////////////////////////////////////// |
2466 procedure doStepKamikazeWork(Gear: PGear); |
2468 procedure doStepKamikazeWork(Gear: PGear); |
2467 var |
2469 var |
3278 //AddCaption('Fuel: '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate); |
3284 //AddCaption('Fuel: '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate); |
3279 FreeTexture(Gear^.Tex); |
3285 FreeTexture(Gear^.Tex); |
3280 Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) + '%', cWhiteColor, fntSmall) |
3286 Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) + '%', cWhiteColor, fntSmall) |
3281 end; |
3287 end; |
3282 |
3288 |
3283 if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then |
3289 if (HHGear^.Message and (gmAttack or gmUp or gmLeft or gmRight) <> 0) and |
|
3290 (HHGear^.Message and gmPrecise = 0) then |
3284 Gear^.State := Gear^.State and (not gsttmpFlag); |
3291 Gear^.State := Gear^.State and (not gsttmpFlag); |
3285 |
3292 |
3286 HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight)); |
3293 if HHGear^.Message and gmPrecise = 0 then |
|
3294 HHGear^.Message := HHGear^.Message and (not (gmUp or gmLeft or gmRight)); |
3287 HHGear^.State := HHGear^.State or gstMoving; |
3295 HHGear^.State := HHGear^.State or gstMoving; |
3288 |
3296 |
3289 Gear^.X := HHGear^.X; |
3297 Gear^.X := HHGear^.X; |
3290 Gear^.Y := HHGear^.Y; |
3298 Gear^.Y := HHGear^.Y; |
3291 |
3299 |
3298 doStepHedgehogMoving(HHGear); |
3306 doStepHedgehogMoving(HHGear); |
3299 |
3307 |
3300 if // (Gear^.Health = 0) |
3308 if // (Gear^.Health = 0) |
3301 (HHGear^.Damage <> 0) |
3309 (HHGear^.Damage <> 0) |
3302 //or CheckGearDrowning(HHGear) |
3310 //or CheckGearDrowning(HHGear) |
3303 or (cWaterLine + 512 < hwRound(HHGear^.Y)) |
3311 or (cWaterLine + cVisibleWater * 4 < hwRound(HHGear^.Y)) |
3304 or (TurnTimeLeft = 0) |
3312 or (TurnTimeLeft = 0) |
3305 // allow brief ground touches - to be fair on this, might need another counter |
3313 // allow brief ground touches - to be fair on this, might need another counter |
3306 or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0)) |
3314 or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0)) |
3307 or ((Gear^.Message and gmAttack) <> 0) then |
3315 or ((Gear^.Message and gmAttack) <> 0) then |
3308 begin |
3316 begin |
5091 Gear^.Damage:= t; |
5101 Gear^.Damage:= t; |
5092 FreeTexture(Gear^.Tex); |
5102 FreeTexture(Gear^.Tex); |
5093 Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(t) + |
5103 Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(t) + |
5094 '%', cWhiteColor, fntSmall) |
5104 '%', cWhiteColor, fntSmall) |
5095 end; |
5105 end; |
5096 if GameTicks mod 10 = 0 then dec(Gear^.Health); |
5106 if Gear^.Message and (gmUp or gmDown) <> 0 then |
|
5107 begin |
|
5108 StopSoundChan(Gear^.SoundChannel); |
|
5109 Gear^.SoundChannel:= -1; |
|
5110 if GameTicks mod 40 = 0 then dec(Gear^.Health) |
|
5111 end |
|
5112 else |
|
5113 begin |
|
5114 if Gear^.SoundChannel = -1 then |
|
5115 Gear^.SoundChannel := LoopSound(sndIceBeam); |
|
5116 if GameTicks mod 10 = 0 then dec(Gear^.Health) |
|
5117 end |
5097 end; |
5118 end; |
5098 |
5119 |
5099 |
5120 |
5100 procedure updateTarget(Gear:PGear; newX, newY:HWFloat); |
5121 procedure updateTarget(Gear:PGear; newX, newY:HWFloat); |
5101 // var |
5122 // var |
5133 //const waterFreezingTime:Longint = 500; |
5143 //const waterFreezingTime:Longint = 500; |
5134 const groundFreezingTime:Longint = 1000; |
5144 const groundFreezingTime:Longint = 1000; |
5135 const iceRadius = 32; |
5145 const iceRadius = 32; |
5136 const iceHeight = 40; |
5146 const iceHeight = 40; |
5137 var |
5147 var |
5138 HHGear: PGear; |
5148 HHGear, iter: PGear; |
5139 landRect: TSDL_Rect; |
5149 landRect: TSDL_Rect; |
5140 ndX, ndY: hwFloat; |
5150 ndX, ndY: hwFloat; |
5141 i, t, gX, gY: LongInt; |
5151 i, j, t, gX, gY: LongInt; |
5142 hogs: PGearArrayS; |
5152 hogs: PGearArrayS; |
5143 len: Integer; |
5153 vg: PVisualGear; |
5144 begin |
5154 begin |
5145 HHGear := Gear^.Hedgehog^.Gear; |
5155 HHGear := Gear^.Hedgehog^.Gear; |
5146 if (Gear^.Message and gmAttack <> 0) or (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) then |
5156 if (Gear^.Message and gmAttack <> 0) or (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) or (HHGear^.dX.QWordValue > 4294967) then |
5147 begin |
5157 begin |
|
5158 StopSoundChan(Gear^.SoundChannel); |
5148 DeleteGear(Gear); |
5159 DeleteGear(Gear); |
5149 AfterAttack; |
5160 AfterAttack; |
5150 exit |
5161 exit |
5151 end |
5162 end; |
5152 else if Gear^.Message and (gmUp or gmDown) = 0 then updateFuel(Gear); |
5163 updateFuel(Gear); |
5153 |
5164 |
5154 with Gear^ do |
5165 with Gear^ do |
5155 begin |
5166 begin |
5156 HedgehogChAngle(HHGear); |
5167 HedgehogChAngle(HHGear); |
5157 ndX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _4; |
5168 ndX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _4; |
5203 landRect.x := min(max(target.x - iceRadius, 0), LAND_WIDTH - 1); |
5214 landRect.x := min(max(target.x - iceRadius, 0), LAND_WIDTH - 1); |
5204 landRect.y := min(max(target.y - iceRadius, 0), LAND_HEIGHT - 1); |
5215 landRect.y := min(max(target.y - iceRadius, 0), LAND_HEIGHT - 1); |
5205 landRect.w := min(2*iceRadius, LAND_WIDTH - landRect.x - 1); |
5216 landRect.w := min(2*iceRadius, LAND_WIDTH - landRect.x - 1); |
5206 landRect.h := min(2*iceRadius, LAND_HEIGHT - landRect.y - 1); |
5217 landRect.h := min(2*iceRadius, LAND_HEIGHT - landRect.y - 1); |
5207 UpdateLandTexture(landRect.x, landRect.w, landRect.y, landRect.h, true); |
5218 UpdateLandTexture(landRect.x, landRect.w, landRect.y, landRect.h, true); |
|
5219 |
|
5220 // Freeze nearby mines/explosives/cases too |
|
5221 iter := GearsList; |
|
5222 while iter <> nil do |
|
5223 begin |
|
5224 if (iter^.State and gstFrozen = 0) and |
|
5225 ((iter^.Kind = gtExplosives) or (iter^.Kind = gtCase) or (iter^.Kind = gtMine)) and |
|
5226 (abs(iter^.X.Round-target.x)+abs(iter^.Y.Round-target.y)+2<2*iceRadius) and (Distance(iter^.X-int2hwFloat(target.x),iter^.Y-int2hwFloat(target.y))<int2hwFloat(iceRadius*2)) then |
|
5227 begin |
|
5228 for t:= 0 to 5 do |
|
5229 begin |
|
5230 vg:= AddVisualGear(hwRound(iter^.X)+random(4)-8, hwRound(iter^.Y)+random(8), vgtDust, 1); |
|
5231 if vg <> nil then |
|
5232 begin |
|
5233 i:= random(100) + 155; |
|
5234 vg^.Tint:= i shl 24 or i shl 16 or $FF shl 8 or Longword(random(200) + 55); |
|
5235 vg^.Angle:= random(360); |
|
5236 vg^.dx:= 0.001 * random(80); |
|
5237 vg^.dy:= 0.001 * random(80) |
|
5238 end |
|
5239 end; |
|
5240 PlaySound(sndHogFreeze); |
|
5241 iter^.State:= iter^.State or gstFrozen; |
|
5242 if iter^.Kind = gtMine then // dud mine block |
|
5243 begin |
|
5244 vg:= AddVisualGear(hwRound(iter^.X) - 4 + Random(8), hwRound(iter^.Y) - 4 - Random(4), vgtSmoke); |
|
5245 if vg <> nil then |
|
5246 vg^.Scale:= 0.5; |
|
5247 PlaySound(sndVaporize); |
|
5248 iter^.Health := 0; |
|
5249 iter^.Damage := 0; |
|
5250 iter^.State := iter^.State and (not gstAttacking) |
|
5251 end |
|
5252 else if iter^.Kind = gtCase then |
|
5253 begin |
|
5254 DeleteCI(iter); |
|
5255 AddGearCI(iter) |
|
5256 end |
|
5257 else // gtExplosives |
|
5258 iter^.Health:= iter^.Health + cBarrelHealth |
|
5259 end; |
|
5260 iter:= iter^.NextGear |
|
5261 end; |
5208 |
5262 |
5209 // FillRoundInLandWithIce(Target.X, Target.Y, iceRadius); |
5263 // FillRoundInLandWithIce(Target.X, Target.Y, iceRadius); |
5210 SetAllHHToActive(true); |
5264 SetAllHHToActive(true); |
5211 Timer := iceWaitCollision; |
5265 Timer := iceWaitCollision; |
5212 end; |
5266 end; |
5213 |
5267 |
5214 if (Timer = iceCollideWithWater) and ((GameTicks - Power) > groundFreezingTime) then |
5268 if (Timer = iceCollideWithWater) and ((GameTicks - Power) > groundFreezingTime) then |
5215 begin |
5269 begin |
|
5270 PlaySound(sndHogFreeze); |
5216 DrawIceBreak(Target.X, cWaterLine - iceHeight, iceRadius, iceHeight); |
5271 DrawIceBreak(Target.X, cWaterLine - iceHeight, iceRadius, iceHeight); |
5217 SetAllHHToActive(true); |
5272 SetAllHHToActive(true); |
5218 Timer := iceWaitCollision; |
5273 Timer := iceWaitCollision; |
5219 end; |
5274 end; |
|
5275 (* |
|
5276 Any ideas for something that would look good here? |
|
5277 if (Target.X <> NoPointX) and ((Timer = iceCollideWithGround) or (Timer = iceCollideWithWater)) and (GameTicks mod max((groundFreezingTime-((GameTicks - Power)*2)),2) = 0) then //and CheckLandValue(Target.X, Target.Y, lfIce) then |
|
5278 begin |
|
5279 vg:= AddVisualGear(Target.X+random(20)-10, Target.Y+random(40)-10, vgtDust, 1); |
|
5280 if vg <> nil then |
|
5281 begin |
|
5282 i:= random(100) + 155; |
|
5283 vg^.Tint:= IceColor or $FF; |
|
5284 vg^.Angle:= random(360); |
|
5285 vg^.dx:= 0.001 * random(80); |
|
5286 vg^.dy:= 0.001 * random(80) |
|
5287 end |
|
5288 end; |
|
5289 *) |
5220 |
5290 |
5221 // freeze nearby hogs |
5291 // freeze nearby hogs |
5222 hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2); |
5292 hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2); |
5223 if hogs.size > 0 then |
5293 if hogs.size > 0 then |
5224 for i:= 0 to hogs.size - 1 do |
5294 for i:= 0 to hogs.size - 1 do |