hedgewars/uGearsHandlersMess.pas
changeset 14993 fd29c23ff95e
parent 14976 8c1a8673843f
child 15028 20c80919d97d
equal deleted inserted replaced
14992:b35a036d6b97 14993:fd29c23ff95e
  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);
  2794                 DeleteGear(Gear);
  2803                 DeleteGear(Gear);
  2795                 exit
  2804                 exit
  2796                 end;
  2805                 end;
  2797             Gear^.Y:= Gear^.Y-_6
  2806             Gear^.Y:= Gear^.Y-_6
  2798             end;
  2807             end;
       
  2808         // Sticky flame damage
  2799         if sticky and (GameTicks and $F = 0) then
  2809         if sticky and (GameTicks and $F = 0) then
  2800             begin
  2810             begin
  2801             Gear^.Radius := 7;
  2811             Gear^.Radius := 7;
  2802             tdX:= Gear^.dX;
  2812             tdX:= Gear^.dX;
  2803             tdY:= Gear^.dY;
  2813             tdY:= Gear^.dY;
  2814             begin
  2824             begin
  2815             dec(Gear^.Timer);
  2825             dec(Gear^.Timer);
  2816             inc(Gear^.Damage)
  2826             inc(Gear^.Damage)
  2817             end
  2827             end
  2818         else
  2828         else
       
  2829             // Flame burn-down handling
  2819             begin
  2830             begin
  2820             gX := hwRound(Gear^.X);
  2831             gX := hwRound(Gear^.X);
  2821             gY := hwRound(Gear^.Y);
  2832             gY := hwRound(Gear^.Y);
  2822             // Standard fire
  2833             // Normal flame: Burns down quickly and must be destroyed before the turn ends
  2823             if not sticky then
  2834             if not sticky then
  2824                 begin
  2835                 begin
       
  2836                 // Deal damage
  2825                 if ((GameTicks and $1) = 0) then
  2837                 if ((GameTicks and $1) = 0) then
  2826                     begin
  2838                     begin
  2827                     Gear^.Radius := 7;
  2839                     Gear^.Radius := 7;
  2828                     tdX:= Gear^.dX;
  2840                     tdX:= Gear^.dX;
  2829                     tdY:= Gear^.dY;
  2841                     tdY:= Gear^.dY;
  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