hedgewars/uVisualGears.pas
changeset 4436 94c948a92759
parent 4422 5e8cfef25ccb
child 4443 d393b9ccd328
equal deleted inserted replaced
4366:d19adc635c99 4436:94c948a92759
    18 
    18 
    19 {$INCLUDE "options.inc"}
    19 {$INCLUDE "options.inc"}
    20 
    20 
    21 unit uVisualGears;
    21 unit uVisualGears;
    22 interface
    22 interface
    23 uses uConsts, uFloat, Math, GLunit;
    23 uses uConsts, uFloat, GLunit, uTypes;
    24 
       
    25 type PVisualGear = ^TVisualGear;
       
    26     TVGearStepProcedure = procedure (Gear: PVisualGear; Steps: Longword);
       
    27     TVisualGear = record
       
    28         NextGear, PrevGear: PVisualGear;
       
    29         Frame,
       
    30         FrameTicks: Longword;
       
    31         X : float;
       
    32         Y : float;
       
    33         dX: float;
       
    34         dY: float;
       
    35         tdX: float;
       
    36         tdY: float;
       
    37         State : Longword;
       
    38         Timer: Longword;
       
    39         Angle, dAngle: real;
       
    40         Kind: TVisualGearType;
       
    41         doStep: TVGearStepProcedure;
       
    42         Tex: PTexture;
       
    43         alpha, scale: GLfloat;
       
    44         Hedgehog: pointer;
       
    45         Text: shortstring;
       
    46         Tint: Longword;
       
    47         end;
       
    48 
    24 
    49 procedure initModule;
    25 procedure initModule;
    50 procedure freeModule;
    26 procedure freeModule;
    51 
    27 
    52 function  AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord = 0): PVisualGear;
    28 function  AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord = 0; Critical: Boolean = false): PVisualGear;
    53 procedure ProcessVisualGears(Steps: Longword);
    29 procedure ProcessVisualGears(Steps: Longword);
    54 procedure KickFlakes(Radius, X, Y: LongInt);
    30 procedure KickFlakes(Radius, X, Y: LongInt);
    55 procedure DrawVisualGears(Layer: LongWord);
    31 procedure DrawVisualGears(Layer: LongWord);
    56 procedure DeleteVisualGear(Gear: PVisualGear);
    32 procedure DeleteVisualGear(Gear: PVisualGear);
    57 procedure AddClouds;
    33 procedure AddClouds;
    58 procedure AddDamageTag(X, Y, Damage, Color: LongWord);
    34 procedure AddDamageTag(X, Y, Damage, Color: LongWord);
    59 
    35 
    60 var VisualGearsList: PVisualGear;
       
    61     vobFrameTicks, vobFramesCount, vobCount: Longword;
       
    62     vobVelocity, vobFallSpeed: LongInt;
       
    63 
       
    64 implementation
    36 implementation
    65 uses uWorld, uMisc, uStore, uTeams, uSound, uMobile;
    37 uses uSound, uMobile, uVariables, uTextures, uRender, Math, uRenderUtils;
       
    38 
    66 const cExplFrameTicks = 110;
    39 const cExplFrameTicks = 110;
    67 
    40 
    68 {$INCLUDE "VGSHandlers.inc"}
    41 {$INCLUDE "VGSHandlers.inc"}
    69 
    42 
    70 procedure AddDamageTag(X, Y, Damage, Color: LongWord);
    43 procedure AddDamageTag(X, Y, Damage, Color: LongWord);
   117             @doStepExplosion,
    90             @doStepExplosion,
   118             @doStepBigExplosion,
    91             @doStepBigExplosion,
   119             @doStepChunk,
    92             @doStepChunk,
   120             @doStepNote,
    93             @doStepNote,
   121             @doStepLineTrail,
    94             @doStepLineTrail,
   122             @doStepBulletHit
    95             @doStepBulletHit,
       
    96             @doStepCircle
   123         );
    97         );
   124 
    98 
   125 function  AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord = 0): PVisualGear;
    99 function  AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord = 0; Critical: Boolean = false): PVisualGear;
       
   100 const VGCounter: Longword = 0;
   126 var gear: PVisualGear;
   101 var gear: PVisualGear;
   127     t: Longword;
   102     t: Longword;
   128     sp: float;
   103     sp: real;
   129 begin
   104 begin
   130 if (GameType = gmtSave) or (fastUntilLag and (GameType = gmtNet)) then // we are scrolling now
   105 if (GameType = gmtSave) or (fastUntilLag and (GameType = gmtNet)) then // we are scrolling now
   131     if Kind <> vgtCloud then
   106     if (Kind <> vgtCloud) and not Critical then
   132         begin
   107         begin
   133         AddVisualGear:= nil;
   108         AddVisualGear:= nil;
   134         exit
   109         exit
   135         end;
   110         end;
   136 
   111 
   137 if ((cReducedQuality and rqFancyBoom) <> 0) and
   112 if ((cReducedQuality and rqFancyBoom) <> 0) and
       
   113    not Critical and
   138    not (Kind in
   114    not (Kind in
   139    [vgtTeamHealthSorter,
   115    [vgtTeamHealthSorter,
   140     vgtSmallDamageTag,
   116     vgtSmallDamageTag,
   141     vgtSpeechBubble,
   117     vgtSpeechBubble,
   142     vgtHealthTag,
   118     vgtHealthTag,
   147     begin
   123     begin
   148       AddVisualGear:= nil;
   124       AddVisualGear:= nil;
   149       exit
   125       exit
   150     end;
   126     end;
   151 
   127 
       
   128 inc(VGCounter);
   152 New(gear);
   129 New(gear);
   153 FillChar(gear^, sizeof(TVisualGear), 0);
   130 FillChar(gear^, sizeof(TVisualGear), 0);
   154 gear^.X:= float(X);
   131 gear^.X:= real(X);
   155 gear^.Y:= float(Y);
   132 gear^.Y:= real(Y);
   156 gear^.Kind := Kind;
   133 gear^.Kind := Kind;
   157 gear^.doStep:= doStepHandlers[Kind];
   134 gear^.doStep:= doStepHandlers[Kind];
   158 gear^.State:= 0;
   135 gear^.State:= 0;
   159 gear^.Tint:= $FFFFFFFF;
   136 gear^.Tint:= $FFFFFFFF;
       
   137 gear^.uid:= VGCounter;
   160 
   138 
   161 with gear^ do
   139 with gear^ do
   162     case Kind of
   140     case Kind of
   163     vgtFlake: begin
   141     vgtFlake: begin
   164                 Timer:= 0;
   142                 Timer:= 0;
   376       begin
   354       begin
   377       Gear:= t;
   355       Gear:= t;
   378       if Gear^.Kind = vgtFlake then
   356       if Gear^.Kind = vgtFlake then
   379           begin
   357           begin
   380           // Damage calc from doMakeExplosion
   358           // Damage calc from doMakeExplosion
   381           dmg:= min(101, Radius + cHHRadius div 2 - LongInt(abs(round(Gear^.X) - X) + abs(round(Gear^.Y) - Y)) div 5);
   359           dmg:= Min(101, Radius + cHHRadius div 2 - LongInt(abs(round(Gear^.X) - X) + abs(round(Gear^.Y) - Y)) div 5);
   382           if dmg > 1 then
   360           if dmg > 1 then
   383               begin
   361               begin
   384               Gear^.tdX:= 0.02 * dmg + 0.01;
   362               Gear^.tdX:= 0.02 * dmg + 0.01;
   385               if Gear^.X - X < 0 then Gear^.tdX := -Gear^.tdX;
   363               if Gear^.X - X < 0 then Gear^.tdX := -Gear^.tdX;
   386               Gear^.tdY:= 0.02 * dmg + 0.01;
   364               Gear^.tdY:= 0.02 * dmg + 0.01;
   434         begin
   412         begin
   435         Tint(Gear^.Tint);
   413         Tint(Gear^.Tint);
   436         case Gear^.Kind of
   414         case Gear^.Kind of
   437             vgtExplosion: DrawSprite(sprExplosion50, round(Gear^.X) - 32 + WorldDx, round(Gear^.Y) - 32 + WorldDy, Gear^.State);
   415             vgtExplosion: DrawSprite(sprExplosion50, round(Gear^.X) - 32 + WorldDx, round(Gear^.Y) - 32 + WorldDy, Gear^.State);
   438             vgtBigExplosion: begin
   416             vgtBigExplosion: begin
   439                              Tint($FF, $FF, $FF, floor($FF * (1 - power(Gear^.Timer / 250, 4))));
   417                              Tint($FF, $FF, $FF, round($FF * (1 - power(Gear^.Timer / 250, 4))));
   440                              DrawRotatedTextureF(SpritesData[sprBigExplosion].Texture, 0.85 * (-power(2, -10 * Int(Gear^.Timer)/250) + 1) + 0.4, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 385, 385, Gear^.Angle);
   418                              DrawRotatedTextureF(SpritesData[sprBigExplosion].Texture, 0.85 * (-power(2, -10 * Int(Gear^.Timer)/250) + 1) + 0.4, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 385, 385, Gear^.Angle);
   441                              end;
   419                              end;
   442             end;
   420             end;
   443         if (cReducedQuality and rqFancyBoom) = 0 then
   421         if (cReducedQuality and rqFancyBoom) = 0 then
   444             case Gear^.Kind of
   422             case Gear^.Kind of
   449                          else
   427                          else
   450                              DrawTextureF(SpritesData[sprFlame].Texture, Gear^.FrameTicks / 900, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, (RealTicks shr 7 + Gear^.Frame) mod 8, 1, 16, 16);
   428                              DrawTextureF(SpritesData[sprFlame].Texture, Gear^.FrameTicks / 900, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, (RealTicks shr 7 + Gear^.Frame) mod 8, 1, 16, 16);
   451                 vgtBubble: DrawSprite(sprBubbles, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, Gear^.Frame);//(RealTicks div 64 + Gear^.Frame) mod 8);
   429                 vgtBubble: DrawSprite(sprBubbles, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, Gear^.Frame);//(RealTicks div 64 + Gear^.Frame) mod 8);
   452                 vgtSteam: DrawSprite(sprSmokeWhite, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
   430                 vgtSteam: DrawSprite(sprSmokeWhite, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
   453                 vgtAmmo: begin
   431                 vgtAmmo: begin
   454                         Tint($FF, $FF, $FF, floor(Gear^.alpha * $FF));
   432                         Tint($FF, $FF, $FF, round(Gear^.alpha * $FF));
   455                         DrawTextureF(ropeIconTex, Gear^.scale, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 32, 32);
   433                         DrawTextureF(ropeIconTex, Gear^.scale, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 32, 32);
   456                         DrawTextureF(SpritesData[sprAMAmmos].Texture, Gear^.scale * 0.90, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame - 1, 1, 32, 32);
   434                         DrawTextureF(SpritesData[sprAMAmmos].Texture, Gear^.scale * 0.90, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame - 1, 1, 32, 32);
   457                         end;
   435                         end;
   458                 vgtHealth:  begin
   436                 vgtHealth:  begin
   459                             case Gear^.Frame div 10 of
   437                             case Gear^.Frame div 10 of
   460                                 0:Tint(0, $FF, 0, floor(Gear^.FrameTicks * $FF / 1000));
   438                                 0:Tint(0, $FF, 0, round(Gear^.FrameTicks * $FF / 1000));
   461                                 1:Tint($FF, 0, 0, floor(Gear^.FrameTicks * $FF / 1000));
   439                                 1:Tint($FF, 0, 0, round(Gear^.FrameTicks * $FF / 1000));
   462                             end;
   440                             end;
   463                             DrawSprite(sprHealth, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, 0);
   441                             DrawSprite(sprHealth, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, 0);
   464                             end;
   442                             end;
   465                 vgtShell: begin
   443                 vgtShell: begin
   466                             if Gear^.FrameTicks < $FF then
   444                             if Gear^.FrameTicks < $FF then
   480                             else
   458                             else
   481                                 Tint($FF, $FF, $FF, $80);
   459                                 Tint($FF, $FF, $FF, $80);
   482                             DrawRotatedF(sprBeeTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, (RealTicks shr 4) mod cMaxAngle);
   460                             DrawRotatedF(sprBeeTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, (RealTicks shr 4) mod cMaxAngle);
   483                             end;
   461                             end;
   484                 vgtSmokeRing: begin
   462                 vgtSmokeRing: begin
   485                             Tint($FF, $FF, $FF, floor(Gear^.alpha * $FF));
   463                             Tint($FF, $FF, $FF, round(Gear^.alpha * $FF));
   486                             DrawRotatedTextureF(SpritesData[sprSmokeRing].Texture, Gear^.scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 200, 200, Gear^.Angle);
   464                             DrawRotatedTextureF(SpritesData[sprSmokeRing].Texture, Gear^.scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 200, 200, Gear^.Angle);
   487                             end;
   465                             end;
   488                 vgtChunk: DrawRotatedF(sprChunk, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
   466                 vgtChunk: DrawRotatedF(sprChunk, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
   489                  vgtNote: DrawRotatedF(sprNote, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
   467                  vgtNote: DrawRotatedF(sprNote, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
   490                 vgtBulletHit: DrawRotatedF(sprBulletHit, round(Gear^.X) + WorldDx - 0, round(Gear^.Y) + WorldDy - 0, 7 - (Gear^.FrameTicks div 50), 1, Gear^.Angle);
   468                 vgtBulletHit: DrawRotatedF(sprBulletHit, round(Gear^.X) + WorldDx - 0, round(Gear^.Y) + WorldDy - 0, 7 - (Gear^.FrameTicks div 50), 1, Gear^.Angle);
   491             end;
   469             end;
   492         case Gear^.Kind of
   470         case Gear^.Kind of
   493             vgtSmallDamageTag: DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex);
   471             vgtSmallDamageTag: DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex);
   494             vgtSpeechBubble: if Gear^.Tex <> nil then DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex);
   472             vgtSpeechBubble: if Gear^.Tex <> nil then DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex);
   495             vgtHealthTag: if Gear^.Tex <> nil then DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex);
   473             vgtHealthTag: if Gear^.Tex <> nil then DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex);
       
   474             vgtCircle: DrawCircle(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.State, Gear^.Timer, 
       
   475                       ((Gear^.Tint shr 24) and $FF), ((Gear^.Tint shr 16) and $FF), ((Gear^.Tint shr 8) and $FF), Gear^.Tint and $FF); 
       
   476 // Consider adding a version of DrawCircle that does not set Tint internally, and just call it here...
   496         end;
   477         end;
   497         Gear:= Gear^.NextGear
   478         Gear:= Gear^.NextGear
   498         end
   479         end
   499     end
   480     end
   500 end;
   481 end;