2709 tdX,tdY, f: HWFloat; |
2709 tdX,tdY, f: HWFloat; |
2710 landPixel: Word; |
2710 landPixel: Word; |
2711 begin |
2711 begin |
2712 WorldWrap(Gear); |
2712 WorldWrap(Gear); |
2713 if Gear^.FlightTime > 0 then dec(Gear^.FlightTime); |
2713 if Gear^.FlightTime > 0 then dec(Gear^.FlightTime); |
|
2714 // There are 2 flame types: normal and sticky |
2714 sticky:= (Gear^.State and gsttmpFlag) <> 0; |
2715 sticky:= (Gear^.State and gsttmpFlag) <> 0; |
2715 if not sticky then AllInactive := false; |
2716 if not sticky then AllInactive := false; |
2716 |
2717 |
2717 landPixel:= TestCollisionYwithGear(Gear, 1); |
2718 landPixel:= TestCollisionYwithGear(Gear, 1); |
|
2719 // Flame is in mid-air |
2718 if landPixel = 0 then |
2720 if landPixel = 0 then |
2719 begin |
2721 begin |
2720 AllInactive := false; |
2722 AllInactive := false; |
2721 |
2723 |
|
2724 // Deals damage in mid-air if FlightTime = 0. |
|
2725 // Otherwise, flame is harmless in mid-air. |
|
2726 // Intended for use with scripts. |
2722 if (GameTicks and $F = 0) and (Gear^.FlightTime = 0) then |
2727 if (GameTicks and $F = 0) and (Gear^.FlightTime = 0) then |
2723 begin |
2728 begin |
2724 Gear^.Radius := 7; |
2729 Gear^.Radius := 7; |
2725 tdX:= Gear^.dX; |
2730 tdX:= Gear^.dX; |
2726 tdY:= Gear^.dY; |
2731 tdY:= Gear^.dY; |
2753 f:= _1_9 / Distance(Gear^.dX, Gear^.dY); |
2758 f:= _1_9 / Distance(Gear^.dX, Gear^.dY); |
2754 Gear^.dX:= Gear^.dX * f; |
2759 Gear^.dX:= Gear^.dX * f; |
2755 Gear^.dY:= Gear^.dY * f; |
2760 Gear^.dY:= Gear^.dY * f; |
2756 end |
2761 end |
2757 else begin |
2762 else begin |
|
2763 // Gravity and wind |
2758 if Gear^.dX.QWordValue > _0_01.QWordValue then |
2764 if Gear^.dX.QWordValue > _0_01.QWordValue then |
2759 Gear^.dX := Gear^.dX * _0_995; |
2765 Gear^.dX := Gear^.dX * _0_995; |
2760 |
2766 |
2761 Gear^.dY := Gear^.dY + cGravity; |
2767 Gear^.dY := Gear^.dY + cGravity; |
2762 |
2768 |
2768 end; |
2774 end; |
2769 |
2775 |
2770 gX := hwRound(Gear^.X); |
2776 gX := hwRound(Gear^.X); |
2771 gY := hwRound(Gear^.Y); |
2777 gY := hwRound(Gear^.Y); |
2772 |
2778 |
|
2779 // Extinguish in water |
2773 if CheckCoordInWater(gX, gY) then |
2780 if CheckCoordInWater(gX, gY) then |
2774 begin |
2781 begin |
2775 for i:= 0 to 3 do |
2782 for i:= 0 to 3 do |
2776 AddVisualGear(gX - 8 + Random(16), gY - 8 + Random(16), vgtSteam); |
2783 AddVisualGear(gX - 8 + Random(16), gY - 8 + Random(16), vgtSteam); |
2777 PlaySound(sndVaporize); |
2784 PlaySound(sndVaporize); |
2778 DeleteGear(Gear); |
2785 DeleteGear(Gear); |
2779 exit |
2786 exit |
2780 end |
2787 end |
2781 end |
2788 end |
|
2789 // Flame is on terrain |
2782 else |
2790 else |
2783 begin |
2791 begin |
2784 if (Gear^.Timer = 1) and (GameTicks and $3 = 0) then |
2792 if (Gear^.Timer = 1) and (GameTicks and $3 = 0) then |
2785 begin |
2793 begin |
2786 Gear^.Y:= Gear^.Y+_6; |
2794 Gear^.Y:= Gear^.Y+_6; |
|
2795 // Extinguish on ice |
2787 if (landPixel and lfIce <> 0) or (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then |
2796 if (landPixel and lfIce <> 0) or (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then |
2788 begin |
2797 begin |
2789 gX := hwRound(Gear^.X); |
2798 gX := hwRound(Gear^.X); |
2790 gY := hwRound(Gear^.Y) - 6; |
2799 gY := hwRound(Gear^.Y) - 6; |
2791 doMakeExplosion(gX, gY, 4, Gear^.Hedgehog, EXPLNoDamage or EXPLDoNotTouchAny or EXPLNoGfx); |
2800 doMakeExplosion(gX, gY, 4, Gear^.Hedgehog, EXPLNoDamage or EXPLDoNotTouchAny or EXPLNoGfx); |
2841 |
2853 |
2842 if ((GameTicks and $7) = 0) and (Random(2) = 0) then |
2854 if ((GameTicks and $7) = 0) and (Random(2) = 0) then |
2843 for i:= Random(2) downto 0 do |
2855 for i:= Random(2) downto 0 do |
2844 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2856 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2845 |
2857 |
|
2858 // Flame burn-out due to time |
2846 if Gear^.Health > 0 then |
2859 if Gear^.Health > 0 then |
2847 dec(Gear^.Health); |
2860 dec(Gear^.Health); |
|
2861 |
|
2862 // Calculate time for next flame update with a bit of random jitter |
2848 Gear^.Timer := 450 - Gear^.Tag * 8 + LongInt(GetRandom(2)) |
2863 Gear^.Timer := 450 - Gear^.Tag * 8 + LongInt(GetRandom(2)) |
2849 end |
2864 end |
|
2865 // Sticky flame: Burns down slowly and persists between turns |
2850 else |
2866 else |
2851 begin |
2867 begin |
2852 // Modified fire |
2868 // Destroy land very slowly (low chance this gets called) |
2853 if ((GameTicks and $7FF) = 0) and ((GameFlags and gfSolidLand) = 0) then |
2869 if ((GameTicks and $7FF) = 0) and ((GameFlags and gfSolidLand) = 0) then |
2854 begin |
2870 begin |
2855 doMakeExplosion(gX, gY, 4, Gear^.Hedgehog, EXPLNoDamage or EXPLDoNotTouchAny or EXPLNoGfx); |
2871 doMakeExplosion(gX, gY, 4, Gear^.Hedgehog, EXPLNoDamage or EXPLDoNotTouchAny or EXPLNoGfx); |
2856 |
2872 |
2857 for i:= Random(3) downto 0 do |
2873 for i:= Random(3) downto 0 do |
2858 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2874 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2859 end; |
2875 end; |
2860 |
2876 |
2861 // This one is interesting. I think I understand the purpose, but I wonder if a bit more fuzzy of kicking could be done with getrandom. |
2877 // Calculate time for next flame update with a bit of random jitter |
2862 Gear^.Timer := 100 - Gear^.Tag * 3 + LongInt(GetRandom(2)); |
2878 Gear^.Timer := 100 - Gear^.Tag * 3 + LongInt(GetRandom(2)); |
|
2879 |
|
2880 // Flame burn-out due to time |
2863 if (Gear^.Damage > 3000+Gear^.Tag*1500) then |
2881 if (Gear^.Damage > 3000+Gear^.Tag*1500) then |
2864 Gear^.Health := 0 |
2882 Gear^.Health := 0 |
2865 end |
2883 end |
2866 end |
2884 end |
2867 end; |
2885 end; |
|
2886 // This kills the flame |
2868 if Gear^.Health = 0 then |
2887 if Gear^.Health = 0 then |
2869 begin |
2888 begin |
2870 gX := hwRound(Gear^.X); |
2889 gX := hwRound(Gear^.X); |
2871 gY := hwRound(Gear^.Y); |
2890 gY := hwRound(Gear^.Y); |
2872 if not sticky then |
2891 if not sticky then |