hedgewars/uGearsRender.pas
branchui-scaling
changeset 15288 c4fd2813b127
parent 15242 5c91c5191085
child 15313 01bd0a087163
equal deleted inserted replaced
13395:0135e64c6c66 15288:c4fd2813b127
     4  *
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation; version 2 of the License
     7  * the Free Software Foundation; version 2 of the License
     8  *
     8  *
     9 	 * This program is distributed in the hope that it will be useful,
     9      * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    12  * GNU General Public License for more details.
    13  *
    13  *
    14  * You should have received a copy of the GNU General Public License
    14  * You should have received a copy of the GNU General Public License
    35             ar        : array[0..MAXROPEPOINTS] of Tar;
    35             ar        : array[0..MAXROPEPOINTS] of Tar;
    36             rounded   : array[0..MAXROPEPOINTS + 2] of TVertex2f;
    36             rounded   : array[0..MAXROPEPOINTS + 2] of TVertex2f;
    37          end;
    37          end;
    38 procedure RenderGear(Gear: PGear; x, y: LongInt);
    38 procedure RenderGear(Gear: PGear; x, y: LongInt);
    39 procedure RenderGearTimer(Gear: PGear; x, y: LongInt);
    39 procedure RenderGearTimer(Gear: PGear; x, y: LongInt);
       
    40 procedure RenderGearHealth(Gear: PGear; x, y: LongInt);
       
    41 procedure RenderHHGuiExtras(Gear: PGear; ox, oy: LongInt);
       
    42 procedure RenderAirMineGuiExtras(Gear: PGear; ox, oy: LongInt);
    40 procedure DrawHHOrder();
    43 procedure DrawHHOrder();
    41 
    44 
    42 var RopePoints: record
    45 var RopePoints: record
    43                 Count: Longword;
    46                 Count: Longword;
    44                 HookAngle: GLfloat;
    47                 HookAngle: GLfloat;
    50                                 end;
    53                                 end;
    51                 rounded: array[0..MAXROPEPOINTS + 2] of TVertex2f;
    54                 rounded: array[0..MAXROPEPOINTS + 2] of TVertex2f;
    52                 end;
    55                 end;
    53 
    56 
    54 implementation
    57 implementation
    55 uses uRender, uUtils, uVariables, uAmmos, Math, uVisualGearsList;
    58 uses uRender, uRenderUtils, uGearsUtils, uUtils, uVariables, uAmmos, Math, uVisualGearsList;
    56 
    59 
    57 procedure DrawRopeLinesRQ(Gear: PGear);
    60 procedure DrawRopeLinesRQ(Gear: PGear);
    58 var n: LongInt;
    61 var n: LongInt;
    59 begin
    62 begin
    60 with RopePoints do
    63 with RopePoints do
    66     end;
    69     end;
    67 
    70 
    68 if (RopePoints.Count > 0) or (Gear^.Elasticity.QWordValue > 0) then
    71 if (RopePoints.Count > 0) or (Gear^.Elasticity.QWordValue > 0) then
    69     begin
    72     begin
    70     EnableTexture(false);
    73     EnableTexture(false);
    71     //glEnable(GL_LINE_SMOOTH);
       
    72 
       
    73     
    74     
    74     Tint(Gear^.Tint shr 24 div 3, Gear^.Tint shr 16 and $FF div 3, Gear^.Tint shr 8 and $FF div 3, Gear^.Tint and $FF);
    75     Tint(Gear^.Tint shr 24 div 3, Gear^.Tint shr 16 and $FF div 3, Gear^.Tint shr 8 and $FF div 3, Gear^.Tint and $FF);
    75 
    76 
    76     n:= RopePoints.Count + 2;
    77     n:= RopePoints.Count + 2;
    77 
    78 
    89     untint;
    90     untint;
    90 
    91 
    91     openglPopMatrix();
    92     openglPopMatrix();
    92 
    93 
    93     EnableTexture(true);
    94     EnableTexture(true);
    94     //glDisable(GL_LINE_SMOOTH)
       
    95     end
    95     end
    96 end;
    96 end;
    97 
    97 
    98 
    98 
    99 function DrawRopeLine(X1, Y1, X2, Y2, roplen: LongInt): LongInt;
    99 procedure DrawRopeLine(X1, Y1, X2, Y2: Real; LayerIndex: Longword; var linesLength, ropeLength: Real);
   100 var  eX, eY, dX, dY: LongInt;
   100 var dX, dY, angle, lineLength: Real;
   101     i, sX, sY, x, y, d: LongInt;
   101     FrameIndex: LongWord;
   102     b: boolean;
       
   103 begin
   102 begin
   104     if (X1 = X2) and (Y1 = Y2) then
   103     if (X1 = X2) and (Y1 = Y2) then
   105         begin
   104         exit;
   106         //OutError('WARNING: zero length rope line!', false);
   105 
   107         DrawRopeLine:= 0;
       
   108         exit
       
   109         end;
       
   110     eX:= 0;
       
   111     eY:= 0;
       
   112     dX:= X2 - X1;
   106     dX:= X2 - X1;
   113     dY:= Y2 - Y1;
   107     dY:= Y2 - Y1;
   114 
   108     lineLength:= sqrt(sqr(dX) + sqr(dY));
   115     if (dX > 0) then
   109     angle:= arctan2(dY, dX) * 180 / PI - 90;
   116         sX:= 1
   110 
       
   111     dX:= dX / lineLength;
       
   112     dY:= dY / lineLength;
       
   113 
       
   114     while (ropeLength - linesLength) <= lineLength do
       
   115     begin
       
   116         FrameIndex:= round(ropeLength / cRopeNodeStep);
       
   117         if (FrameIndex mod cRopeLayers) = LayerIndex then
       
   118             DrawSpriteRotatedFReal(sprRopeNode,
       
   119                 X1 + (ropeLength - linesLength) * dX,
       
   120                 Y1 + (ropeLength - linesLength) * dY,
       
   121                 FrameIndex, 1, angle);
       
   122         ropeLength:= ropeLength + cRopeNodeStep;
       
   123     end;
       
   124     linesLength:= linesLength + lineLength
       
   125 end;
       
   126 
       
   127 procedure DrawRopeLayer(Gear: PGear; LayerIndex: LongWord);
       
   128 var i: LongInt;
       
   129     linesLength, ropeLength: Real;
       
   130 begin
       
   131     linesLength:= 0;
       
   132     ropeLength:= cRopeNodeStep;
       
   133     if RopePoints.Count > 0 then
       
   134     begin
       
   135         i:= 0;
       
   136         while i < Pred(RopePoints.Count) do
       
   137         begin
       
   138             DrawRopeLine(hwFloat2Float(RopePoints.ar[i].X) + WorldDx, hwFloat2Float(RopePoints.ar[i].Y) + WorldDy,
       
   139                          hwFloat2Float(RopePoints.ar[Succ(i)].X) + WorldDx, hwFloat2Float(RopePoints.ar[Succ(i)].Y) + WorldDy,
       
   140                          LayerIndex, linesLength, ropeLength);
       
   141             inc(i)
       
   142         end;
       
   143 
       
   144         DrawRopeLine(hwFloat2Float(RopePoints.ar[i].X) + WorldDx, hwFloat2Float(RopePoints.ar[i].Y) + WorldDy,
       
   145                      hwFloat2Float(Gear^.X) + WorldDx, hwFloat2Float(Gear^.Y) + WorldDy,
       
   146                      LayerIndex, linesLength, ropeLength);
       
   147 
       
   148         DrawRopeLine(hwFloat2Float(Gear^.X) + WorldDx, hwFloat2Float(Gear^.Y) + WorldDy,
       
   149                      hwFloat2Float(Gear^.Hedgehog^.Gear^.X) + WorldDx, hwFloat2Float(Gear^.Hedgehog^.Gear^.Y) + WorldDy,
       
   150                      LayerIndex, linesLength, ropeLength);
       
   151     end
   117     else
   152     else
   118         if (dX < 0) then
   153         if Gear^.Elasticity.QWordValue > 0 then
   119             begin
   154             DrawRopeLine(hwFloat2Float(Gear^.X) + WorldDx, hwFloat2Float(Gear^.Y) + WorldDy,
   120             sX:= -1;
   155                          hwFloat2Float(Gear^.Hedgehog^.Gear^.X) + WorldDx, hwFloat2Float(Gear^.Hedgehog^.Gear^.Y) + WorldDy,
   121             dX:= -dX
   156                          LayerIndex, linesLength, ropeLength);
   122             end
       
   123         else sX:= dX;
       
   124 
       
   125     if (dY > 0) then
       
   126         sY:= 1
       
   127     else
       
   128         if (dY < 0) then
       
   129             begin
       
   130             sY:= -1;
       
   131             dY:= -dY
       
   132             end
       
   133         else
       
   134             sY:= dY;
       
   135 
       
   136     if (dX > dY) then
       
   137         d:= dX
       
   138     else
       
   139         d:= dY;
       
   140 
       
   141     x:= X1;
       
   142     y:= Y1;
       
   143 
       
   144     for i:= 0 to d do
       
   145         begin
       
   146         inc(eX, dX);
       
   147         inc(eY, dY);
       
   148         b:= false;
       
   149         if (eX > d) then
       
   150             begin
       
   151             dec(eX, d);
       
   152             inc(x, sX);
       
   153             b:= true
       
   154             end;
       
   155         if (eY > d) then
       
   156             begin
       
   157             dec(eY, d);
       
   158             inc(y, sY);
       
   159             b:= true
       
   160             end;
       
   161         if b then
       
   162             begin
       
   163             inc(roplen);
       
   164             if (roplen mod 4) = 0 then
       
   165                 DrawSprite(sprRopeNode, x - 2, y - 2, 0)
       
   166             end
       
   167     end;
       
   168     DrawRopeLine:= roplen;
       
   169 end;
   157 end;
   170 
   158 
   171 procedure DrawRope(Gear: PGear);
   159 procedure DrawRope(Gear: PGear);
   172 var roplen, i: LongInt;
   160 var i: LongInt;
   173 begin
   161 begin
   174     if Gear^.Hedgehog^.Gear = nil then exit;
   162     if Gear^.Hedgehog^.Gear = nil then exit;
   175     if (Gear^.Tag = 1) or ((cReducedQuality and rqSimpleRope) <> 0) then
   163     if (Gear^.Tag = 1) or ((cReducedQuality and rqSimpleRope) <> 0) then
   176         DrawRopeLinesRQ(Gear)
   164         DrawRopeLinesRQ(Gear)
   177     else
   165     else
   178         begin
   166         for i := 0 to cRopeLayers - 1 do
   179         roplen:= 0;
   167             DrawRopeLayer(Gear, i);
   180         if RopePoints.Count > 0 then
       
   181             begin
       
   182             i:= 0;
       
   183             while i < Pred(RopePoints.Count) do
       
   184                     begin
       
   185                     roplen:= DrawRopeLine(hwRound(RopePoints.ar[i].X) + WorldDx, hwRound(RopePoints.ar[i].Y) + WorldDy,
       
   186                                 hwRound(RopePoints.ar[Succ(i)].X) + WorldDx, hwRound(RopePoints.ar[Succ(i)].Y) + WorldDy, roplen);
       
   187                     inc(i)
       
   188                     end;
       
   189             roplen:= DrawRopeLine(hwRound(RopePoints.ar[i].X) + WorldDx, hwRound(RopePoints.ar[i].Y) + WorldDy,
       
   190                         hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, roplen);
       
   191             roplen:= DrawRopeLine(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy,
       
   192                         hwRound(Gear^.Hedgehog^.Gear^.X) + WorldDx, hwRound(Gear^.Hedgehog^.Gear^.Y) + WorldDy, roplen);
       
   193             end
       
   194         else
       
   195             if Gear^.Elasticity.QWordValue > 0 then
       
   196             roplen:= DrawRopeLine(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy,
       
   197                         hwRound(Gear^.Hedgehog^.Gear^.X) + WorldDx, hwRound(Gear^.Hedgehog^.Gear^.Y) + WorldDy, roplen);
       
   198         end;
       
   199 
       
   200 
   168 
   201 if RopePoints.Count > 0 then
   169 if RopePoints.Count > 0 then
   202     DrawSpriteRotated(sprRopeHook, hwRound(RopePoints.ar[0].X) + WorldDx, hwRound(RopePoints.ar[0].Y) + WorldDy, 1, RopePoints.HookAngle)
   170     DrawSpriteRotated(sprRopeHook, hwRound(RopePoints.ar[0].X) + WorldDx, hwRound(RopePoints.ar[0].Y) + WorldDy, 1, RopePoints.HookAngle)
   203 else
   171 else
   204     if Gear^.Elasticity.QWordValue > 0 then
   172     if Gear^.Elasticity.QWordValue > 0 then
   205         DrawSpriteRotated(sprRopeHook, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
   173         DrawSpriteRotated(sprRopeHook, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
   206 end;
   174 end;
   207 
   175 
   208 
   176 
   209 procedure DrawAltWeapon(Gear: PGear; sx, sy: LongInt);
   177 procedure DrawSelectedWeapon(Gear: PGear; sx, sy: LongInt; isAltWeapon: boolean);
   210 begin
   178 begin
   211 with Gear^.Hedgehog^ do
   179 with Gear^.Hedgehog^ do
   212     begin
   180     begin
   213     if not (((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) and ((Gear^.State and gstAttacked) = 0)) then
   181     if ((Gear^.State and gstAttacked) <> 0) then
   214         exit;
   182         exit;
       
   183     if (isAltWeapon and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0)) then
       
   184         exit;
       
   185     if (not isAltWeapon) and (((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_ShowSelIcon) = 0) or (
       
   186             (((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) = 0) and ((Gear^.State and gstMoving) <> 0)))) then
       
   187         exit;
       
   188     if (not isAltWeapon) then
       
   189         begin
       
   190         sy:= sy - 64;
       
   191         if (IsHogFacingLeft(Gear)) then
       
   192             sx:= sx - 61;
       
   193         end;
   215     DrawTexture(sx + 16, sy + 16, ropeIconTex);
   194     DrawTexture(sx + 16, sy + 16, ropeIconTex);
   216     DrawTextureF(SpritesData[sprAMAmmos].Texture, 0.75, sx + 30, sy + 30, ord(CurAmmoType) - 1, 1, 32, 32);
   195     DrawTextureF(SpritesData[sprAMAmmos].Texture, 0.75, sx + 30, sy + 30, ord(CurAmmoType) - 1, 1, 32, 32);
   217     end;
   196     end;
   218 end;
   197 end;
   219 
   198 
   240     i:= 0;
   219     i:= 0;
   241     c:= 0;
   220     c:= 0;
   242         repeat
   221         repeat
   243         hh:= @TeamsArray[t]^.Hedgehogs[i];
   222         hh:= @TeamsArray[t]^.Hedgehogs[i];
   244         inc(i);
   223         inc(i);
   245         if (hh <> nil) and (hh^.Gear <> nil) then
   224         if (hh <> nil) and (hh^.Gear <> nil) and (not hh^.Unplaced) then
   246             begin
   225             begin
   247             inc(c);
   226             inc(c);
   248             HHGear:= hh^.Gear;
   227             HHGear:= hh^.Gear;
   249             x:= hwRound(HHGear^.X) + WorldDx;
   228             x:= hwRound(HHGear^.X) + WorldDx;
   250             y:= hwRound(HHGear^.Y) + WorldDy - 2;
   229             y:= hwRound(HHGear^.Y) + WorldDy - 2;
   257         until (i > cMaxHHIndex);
   236         until (i > cMaxHHIndex);
   258     end
   237     end
   259 
   238 
   260 end;
   239 end;
   261 
   240 
       
   241 // Render some informational GUI next to hedgehog, like fuel and alternate weapon
       
   242 procedure RenderHHGuiExtras(Gear: PGear; ox, oy: LongInt);
       
   243 var HH: PHedgehog;
       
   244     sx, sy, tx, ty, t, hogLR: LongInt;
       
   245     dAngle: real;
       
   246 begin
       
   247     HH:= Gear^.Hedgehog;
       
   248     sx:= ox + 1; // this offset is very common
       
   249     sy:= oy - 3;
       
   250     if HH^.Unplaced then
       
   251         exit;
       
   252     if (Gear^.State and gstHHDeath) <> 0 then
       
   253         exit;
       
   254     if (Gear^.State and gstHHGone) <> 0 then
       
   255         exit;
       
   256     if (CinematicScript) then
       
   257         exit;
       
   258 
       
   259     // render finger (pointing arrow)
       
   260     if bShowFinger and ((Gear^.State and gstHHDriven) <> 0) then
       
   261         begin
       
   262         ty := oy - 32;
       
   263         // move finger higher up if tags are above hog
       
   264         if (cTagsMask and htTeamName) <> 0 then
       
   265             ty := ty - HH^.Team^.NameTagTex^.h - 2;
       
   266         if (cTagsMask and htName) <> 0 then
       
   267             ty := ty - HH^.NameTagTex^.h - 2;
       
   268         if (cTagsMask and htHealth) <> 0 then
       
   269             ty := ty - HH^.HealthTagTex^.h - 2;
       
   270         tx := ox;
       
   271 
       
   272         // don't go offscreen
       
   273         t:= 32;
       
   274         tx := min(max(tx, ViewLeftX + t), ViewRightX - t);
       
   275         ty := min(ty, ViewBottomY - 96);
       
   276         // don't overlap with HH or HH tags
       
   277         if ty < ViewTopY + t then
       
   278             begin
       
   279             if abs(tx - ox) < abs(ty - oy)  then
       
   280                 ty:= max(ViewTopY + t, oy + t)
       
   281             else
       
   282                 ty:= max(ViewTopY + t, ty);
       
   283             end;
       
   284 
       
   285         dAngle := DxDy2Angle(int2hwfloat(ty - oy), int2hwfloat(tx - ox)) + 90;
       
   286 
       
   287         if (IsTooDarkToRead(HH^.Team^.Clan^.Color)) then
       
   288             DrawSpriteRotatedF(sprFingerBackInv, tx, ty, RealTicks div 32 mod 16, 1, dAngle)
       
   289         else
       
   290             DrawSpriteRotatedF(sprFingerBack, tx, ty, RealTicks div 32 mod 16, 1, dAngle);
       
   291         Tint(HH^.Team^.Clan^.Color shl 8 or $FF);
       
   292         DrawSpriteRotatedF(sprFinger, tx, ty, RealTicks div 32 mod 16, 1, dAngle);
       
   293         untint;
       
   294         end;
       
   295 
       
   296     // render crosshair
       
   297     if (CrosshairGear <> nil) and (Gear = CrosshairGear) then
       
   298         begin
       
   299         hogLR:= 1;
       
   300         if IsHogFacingLeft(Gear) then
       
   301             hogLR:= -1;
       
   302         setTintAdd(true);
       
   303         Tint(HH^.Team^.Clan^.Color shl 8 or $FF);
       
   304         DrawTextureRotated(CrosshairTexture,
       
   305                 12, 12, CrosshairX + WorldDx, CrosshairY + WorldDy, 0,
       
   306                 hogLR * (Gear^.Angle * 180.0) / cMaxAngle);
       
   307         untint;
       
   308         setTintAdd(false);
       
   309         end;
       
   310 
       
   311     // render gear-related extras: alt weapon, fuel, other
       
   312     if ((Gear^.State and gstHHDriven) <> 0) and (CurAmmoGear <> nil) then
       
   313         begin
       
   314         case CurAmmoGear^.Kind of
       
   315             gtJetpack:      begin
       
   316                             // render jetpack contour if underwater
       
   317                             if (((not SuddenDeathDmg) and (WaterOpacity > cGearContourThreshold)) or (SuddenDeathDmg and (SDWaterOpacity > cGearContourThreshold))) and
       
   318                                     ((cWaterLine < (hwRound(Gear^.Y) + Gear^.Radius - 16)) or
       
   319                                     ((WorldEdge = weSea) and ((hwRound(Gear^.X) < LeftX) or (hwRound(Gear^.X) > RightX)))) then
       
   320                                 DrawSprite(sprJetpack, sx-32, sy-32, 4);
       
   321                             if CurAmmoGear^.Tex <> nil then
       
   322                                 DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex);
       
   323                             DrawSelectedWeapon(Gear, sx, sy, true);
       
   324                             end;
       
   325             gtRope:         DrawSelectedWeapon(Gear, sx, sy, true);
       
   326             gtParachute:    DrawSelectedWeapon(Gear, sx, sy, true);
       
   327             gtLandGun:      if CurAmmoGear^.Tex <> nil then
       
   328                                 DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex);
       
   329             gtFlamethrower: if CurAmmoGear^.Tex <> nil then
       
   330                                 DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex);
       
   331             gtIceGun:       if CurAmmoGear^.Tex <> nil then
       
   332                                 DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex);
       
   333         end;
       
   334         end
       
   335     else if ((Gear^.State and gstHHDriven) <> 0) then
       
   336         begin
       
   337         DrawSelectedWeapon(Gear, sx, sy, false);
       
   338         end
       
   339 end;
       
   340 
       
   341 procedure RenderAirMineGuiExtras(Gear: PGear; ox, oy: LongInt);
       
   342 var tinted: boolean;
       
   343 begin
       
   344 // render air mine contour, if underwater
       
   345     if (((not SuddenDeathDmg) and (WaterOpacity > cGearContourThreshold)) or (SuddenDeathDmg and (SDWaterOpacity > cGearContourThreshold))) and
       
   346         ((cWaterLine < (hwRound(Gear^.Y) + Gear^.Radius + 16)) or
       
   347         ((WorldEdge = weSea) and ((hwRound(Gear^.X) < LeftX + 24) or (hwRound(Gear^.X) > RightX - 24)))) then
       
   348         begin
       
   349         tinted:= true;
       
   350         // tint contour based on air mine state:
       
   351         // not seeking or chasing (frozen, stunned or just launched)
       
   352         if ((Gear^.State and gstFrozen) <> 0) or ((Gear^.State and gstTmpFlag) = 0) or (Gear^.Tag <> 0) then
       
   353             // more transparent
       
   354             Tint($FF, $FF, $FF, $80)
       
   355         // chasing hog
       
   356         else if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.Gear <> nil) then
       
   357             // reddish
       
   358             Tint($FF, $30, $30, $FF)
       
   359         // not seeking or chasing (no target)
       
   360         else if (Gear^.State and gstChooseTarget) = 0 then
       
   361             // more transparent
       
   362             Tint($FF, $FF, $FF, $80)
       
   363         // seeking
       
   364         else
       
   365             // default color
       
   366             tinted:= false;
       
   367         DrawSprite(sprAirMine, ox-16, oy-16, 32);
       
   368         if tinted then
       
   369             untint;
       
   370         end;
       
   371 end;
   262 
   372 
   263 procedure DrawHH(Gear: PGear; ox, oy: LongInt);
   373 procedure DrawHH(Gear: PGear; ox, oy: LongInt);
   264 var i, t: LongInt;
   374 var i, t: LongInt;
   265     amt: TAmmoType;
   375     amt: TAmmoType;
   266     sign, hx, hy, tx, ty, sx, sy, m: LongInt;  // hedgehog, crosshair, temp, sprite, direction
   376     sign, hx, hy, tx, ty, sx, sy, hogLR: LongInt;  // hedgehog, crosshair, temp, sprite, direction
   267     dx, dy, ax, ay, aAngle, dAngle, hAngle, lx, ly: real;  // laser, change
   377     dx, dy, ax, ay, aAngle, dAngle, hAngle, lx, ly: real;  // laser, change
   268     defaultPos, HatVisible: boolean;
   378     wraps: LongWord; // numbe of wraps for laser in world wrap
       
   379     defaultPos, HatVisible, inWorldBounds: boolean;
   269     HH: PHedgehog;
   380     HH: PHedgehog;
   270     CurWeapon: PAmmo;
   381     CurWeapon: PAmmo;
   271     iceOffset:Longint;
   382     iceOffset:Longint;
   272     r:TSDL_Rect;
   383     r:TSDL_Rect;
   273     curhat: PTexture;
   384     curhat: PTexture;
   274 begin
   385 begin
   275     HH:= Gear^.Hedgehog;
   386     HH:= Gear^.Hedgehog;
       
   387     CrosshairGear:= nil;
   276     if HH^.Unplaced then
   388     if HH^.Unplaced then
   277         exit;
   389         exit;
   278     if (HH^.CurAmmoType = amKnife) and (HH = CurrentHedgehog) then
   390     if (HH^.CurAmmoType = amKnife) and (HH = CurrentHedgehog) then
   279          curhat:= ChefHatTexture
   391          curhat:= ChefHatTexture
   280     else curhat:= HH^.HatTex;
   392     else curhat:= HH^.HatTex;
   281     m:= 1;
       
   282     if ((Gear^.State and gstHHHJump) <> 0) and (HH^.Effects[heArtillery] = 0) then
       
   283         m:= -1;
       
   284     sx:= ox + 1; // this offset is very common
   393     sx:= ox + 1; // this offset is very common
   285     sy:= oy - 3;
   394     sy:= oy - 3;
   286     sign:= hwSign(Gear^.dX);
   395     sign:= hwSign(Gear^.dX);
       
   396     if IsHogFacingLeft(Gear) then
       
   397         hogLR:= -1
       
   398     else
       
   399         hogLR:= 1;
   287 
   400 
   288     if (Gear^.State and gstHHDeath) <> 0 then
   401     if (Gear^.State and gstHHDeath) <> 0 then
   289         begin
   402         begin
   290         DrawSprite(sprHHDeath, ox - 16, oy - 26, Gear^.Pos);
   403         DrawSprite(sprHHDeath, ox - 16, oy - 26, Gear^.Pos);
   291         Tint(HH^.Team^.Clan^.Color shl 8 or $FF);
   404         Tint(HH^.Team^.Clan^.Color shl 8 or $FF);
   366 
   479 
   367     if (Gear^.State and gstHHDriven) <> 0 then
   480     if (Gear^.State and gstHHDriven) <> 0 then
   368         begin
   481         begin
   369         if ((Gear^.State and (gstHHThinking or gstAnimation)) = 0) and
   482         if ((Gear^.State and (gstHHThinking or gstAnimation)) = 0) and
   370 /// If current ammo is active, and current ammo has alt attack and uses a crosshair  (rope, basically, right now, with no crosshair for parachute/saucer
   483 /// If current ammo is active, and current ammo has alt attack and uses a crosshair  (rope, basically, right now, with no crosshair for parachute/saucer
   371             (((CurAmmoGear <> nil) and //((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) and
   484             (((CurAmmoGear <> nil) and
   372             // don't render crosshair/laser during kamikaze
   485             // don't render crosshair/laser during kamikaze
   373             ((CurAmmoGear^.AmmoType <> amKamikaze) or ((Gear^.State and gstAttacking) = 0)) and
   486             ((CurAmmoGear^.AmmoType <> amKamikaze) or ((Gear^.State and gstAttacking) = 0)) and
   374              ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_NoCrossHair) = 0)) or
   487              ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_NoCrossHair) = 0)) or
   375 /// If no current ammo is active, and the selected ammo uses a crosshair
   488 /// If no current ammo is active, and the selected ammo uses a crosshair
   376             ((CurAmmoGear = nil) and ((Ammoz[HH^.CurAmmoType].Ammo.Propz and ammoprop_NoCrosshair) = 0) and ((Gear^.State and gstAttacked) = 0))) then
   489             ((CurAmmoGear = nil) and ((Ammoz[HH^.CurAmmoType].Ammo.Propz and ammoprop_NoCrosshair) = 0) and ((Gear^.State and gstAttacked) = 0))) then
   379     1: I need to draw the laser from weapon origin to nearest land
   492     1: I need to draw the laser from weapon origin to nearest land
   380     2: I need to start the beam outside the hedgie for attractiveness.
   493     2: I need to start the beam outside the hedgie for attractiveness.
   381     3: I need to extend the beam beyond land.
   494     3: I need to extend the beam beyond land.
   382     This routine perhaps should be pushed into uStore or somesuch instead of continuuing the increase in size of this function.
   495     This routine perhaps should be pushed into uStore or somesuch instead of continuuing the increase in size of this function.
   383     *)
   496     *)
   384             dx:= sign * m * Sin(Gear^.Angle * pi / cMaxAngle);
   497             dx:= hogLR * Sin(Gear^.Angle * pi / cMaxAngle);
   385             dy:= -Cos(Gear^.Angle * pi / cMaxAngle);
   498             dy:= -Cos(Gear^.Angle * pi / cMaxAngle);
   386             if cLaserSighting or cLaserSightingSniper then
   499             if cLaserSighting or cLaserSightingSniper then
   387                 begin
   500                 begin
   388                 lx:= GetLaunchX(HH^.CurAmmoType, sign * m, Gear^.Angle);
   501                 lx:= GetLaunchX(HH^.CurAmmoType, hogLR, Gear^.Angle);
   389                 ly:= GetLaunchY(HH^.CurAmmoType, Gear^.Angle);
   502                 ly:= GetLaunchY(HH^.CurAmmoType, Gear^.Angle);
   390 
   503 
   391                 // ensure we start outside the hedgehog (he's solid after all)
   504                 // ensure we start outside the hedgehog (he's solid after all)
   392                 while abs(lx * lx + ly * ly) < (Gear^.radius * Gear^.radius) do
   505                 while abs(lx * lx + ly * ly) < (Gear^.radius * Gear^.radius) do
   393                     begin
   506                     begin
   405 
   518 
   406                 tx:= round(lx);
   519                 tx:= round(lx);
   407                 ty:= round(ly);
   520                 ty:= round(ly);
   408                 hx:= tx;
   521                 hx:= tx;
   409                 hy:= ty;
   522                 hy:= ty;
   410                 while ((ty and LAND_HEIGHT_MASK) = 0) and
   523                 wraps:= 0;
   411                     ((tx and LAND_WIDTH_MASK) = 0) and
   524                 inWorldBounds := ((ty and LAND_HEIGHT_MASK) or (tx and LAND_WIDTH_MASK)) = 0;
   412                     (Land[ty, tx] = 0) do // TODO: check for constant variable instead
   525                 while (inWorldBounds and ((Land[ty, tx] and lfAll) = 0)) or (not inWorldBounds) do
   413                     begin
   526                     begin
       
   527                     if wraps > cMaxLaserSightWraps then
       
   528                         break;
   414                     lx:= lx + ax;
   529                     lx:= lx + ax;
   415                     ly:= ly + ay;
   530                     ly:= ly + ay;
   416                     tx:= round(lx);
   531                     tx:= round(lx);
   417                     ty:= round(ly)
   532                     ty:= round(ly);
   418                     end;
   533                     // reached edge of land.
   419                 // reached edge of land. assume infinite beam. Extend it way out past camera
   534                     if ((ty and LAND_HEIGHT_MASK) <> 0) and (((ty < LAND_HEIGHT) and (ay < 0)) or ((ty >= TopY) and (ay > 0))) then
   420                 if ((ty and LAND_HEIGHT_MASK) <> 0) or ((tx and LAND_WIDTH_MASK) <> 0) then
   535                         begin
   421                     begin
   536                         // assume infinite beam. Extend it way out past camera
   422                     tx:= round(lx + ax * (max(LAND_WIDTH,4096) div 2));
   537                         tx:= round(lx + ax * (max(LAND_WIDTH,4096) div 2));
   423                     ty:= round(ly + ay * (max(LAND_WIDTH,4096) div 2));
   538                         ty:= round(ly + ay * (max(LAND_WIDTH,4096) div 2));
   424                     end;
   539                         break;
   425 
   540                         end;
   426                 //if (abs(lx-tx)>8) or (abs(ly-ty)>8) then
   541 
   427                     begin
   542                     if ((hogLR < 0) and (tx < LeftX)) or ((hogLR > 0) and (tx >= RightX)) then
   428                     DrawLine(hx, hy, tx, ty, 1.0, $FF, $00, $00, $C0);
   543                         if (WorldEdge = weWrap) then
   429                     end;
   544                             // wrap beam
       
   545                             begin
       
   546                             if hogLR < 0 then
       
   547                                 lx:= RightX - (ax - (lx - LeftX))
       
   548                             else
       
   549                                 lx:= LeftX + (ax - (RightX - lx));
       
   550                             tx:= round(lx);
       
   551                             inc(wraps);
       
   552                             end
       
   553                         else if (WorldEdge = weBounce) then
       
   554                             // just stop
       
   555                             break;
       
   556 
       
   557                     if ((tx and LAND_WIDTH_MASK) <> 0) and (((ax > 0) and (tx >= RightX)) or ((ax < 0) and (tx <= LeftX))) then
       
   558                         begin
       
   559                         if (WorldEdge <> weWrap) and (WorldEdge <> weBounce) then
       
   560                             // assume infinite beam. Extend it way out past camera
       
   561                             begin
       
   562                             tx:= round(lx + ax * (max(LAND_WIDTH,4096) div 2));
       
   563                             ty:= round(ly + ay * (max(LAND_WIDTH,4096) div 2));
       
   564                             end;
       
   565                         break;
       
   566                         end;
       
   567                     inWorldBounds := ((ty and LAND_HEIGHT_MASK) or (tx and LAND_WIDTH_MASK)) = 0;
       
   568                     end;
       
   569 
       
   570                 DrawLineWrapped(hx, hy, tx, ty, 1.0, hogLR < 0, wraps, $FF, $00, $00, $C0);
   430                 end;
   571                 end;
   431             // draw crosshair
   572 
   432             CrosshairX := Round(hwRound(Gear^.X) + dx * 80 + GetLaunchX(HH^.CurAmmoType, sign * m, Gear^.Angle));
   573             // calculate crosshair position
       
   574             CrosshairX := Round(hwRound(Gear^.X) + dx * 80 + GetLaunchX(HH^.CurAmmoType, hogLR, Gear^.Angle));
   433             CrosshairY := Round(hwRound(Gear^.Y) + dy * 80 + GetLaunchY(HH^.CurAmmoType, Gear^.Angle));
   575             CrosshairY := Round(hwRound(Gear^.Y) + dy * 80 + GetLaunchY(HH^.CurAmmoType, Gear^.Angle));
   434 
   576             // crosshair will be rendered in RenderHHGuiExtras
   435             setTintAdd(true);
   577             CrosshairGear := Gear;
   436             Tint(HH^.Team^.Clan^.Color shl 8 or $FF);
       
   437             DrawTextureRotated(CrosshairTexture,
       
   438                     12, 12, CrosshairX + WorldDx, CrosshairY + WorldDy, 0,
       
   439                     sign * m * (Gear^.Angle * 180.0) / cMaxAngle);
       
   440             untint;
       
   441             setTintAdd(false);
       
   442             end;
   578             end;
   443 
   579 
   444         hx:= ox + 8 * sign;
   580         hx:= ox + 8 * sign;
   445         hy:= oy - 2;
   581         hy:= oy - 2;
   446         aangle:= Gear^.Angle * 180 / cMaxAngle - 90;
   582         aangle:= Gear^.Angle * 180 / cMaxAngle - 90;
   460                         else
   596                         else
   461                             DrawSpriteRotatedF(sprSniperRifle, hx, hy, 0, sign, aangle)
   597                             DrawSpriteRotatedF(sprSniperRifle, hx, hy, 0, sign, aangle)
   462                     end;
   598                     end;
   463                 gtBallgun: DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle);
   599                 gtBallgun: DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle);
   464                 gtRCPlane: begin
   600                 gtRCPlane: begin
   465                     DrawSpriteRotated(sprHandPlane, hx, hy, sign, 0);
   601                     DrawSpriteRotated(sprHandPlane, hx + 1, hy, sign, 0);
   466                     defaultPos:= false
   602                     defaultPos:= false
   467                     end;
   603                     end;
   468                 gtRope: begin
   604                 gtRope: begin
   469                     if Gear^.X < CurAmmoGear^.X then
   605                     if Gear^.X < CurAmmoGear^.X then
   470                         begin
   606                         begin
   501                                         i*DxDy2Angle(CurAmmoGear^.dY, CurAmmoGear^.dX) + hAngle);
   637                                         i*DxDy2Angle(CurAmmoGear^.dY, CurAmmoGear^.dX) + hAngle);
   502                                     untint
   638                                     untint
   503                                     end
   639                                     end
   504                                 end
   640                                 end
   505                     end;
   641                     end;
   506                     DrawAltWeapon(Gear, ox, oy);
       
   507                     defaultPos:= false
   642                     defaultPos:= false
   508                     end;
   643                     end;
   509                 gtBlowTorch:
   644                 gtBlowTorch:
   510                     begin
   645                     begin
   511                     DrawSpriteRotated(sprBlowTorch, hx, hy, sign, aangle);
   646                     DrawSpriteRotated(sprBlowTorch, hx, hy, sign, aangle);
   558                     begin
   693                     begin
   559                     defaultPos:= false;
   694                     defaultPos:= false;
   560                     dec(sy,20);
   695                     dec(sy,20);
   561                     end;
   696                     end;
   562                 gtTeleport: defaultPos:= false;
   697                 gtTeleport: defaultPos:= false;
       
   698                 gtParachute:
       
   699                     begin
       
   700                     DrawSpriteRotatedF(sprHHIdle,
       
   701                             sx,
       
   702                             sy,
       
   703                             0,
       
   704                             CurAmmoGear^.Tag,
       
   705                             0);
       
   706                     HatVisible:= true;
       
   707                     defaultPos:= false;
       
   708                     end;
   563                 gtWhip:
   709                 gtWhip:
   564                     begin
   710                     begin
   565                     DrawSpriteRotatedF(sprWhip,
   711                     DrawSpriteRotatedF(sprWhip,
   566                             sx,
   712                             sx,
   567                             sy,
   713                             sy,
   616                                 CurAmmoGear^.Pos,
   762                                 CurAmmoGear^.Pos,
   617                                 sign,
   763                                 sign,
   618                                 0);
   764                                 0);
   619                         // sprCensored contains English text, so only show it for English locales
   765                         // sprCensored contains English text, so only show it for English locales
   620                         // TODO: Make text translatable. But how?
   766                         // TODO: Make text translatable. But how?
   621                         if Copy(cLocale, 1, 2) = 'en' then
   767                         if Copy(cLanguage, 1, 2) = 'en' then
   622                             DrawSprite(sprCensored, ox - 32, oy - 20, 0);
   768                             DrawSprite(sprCensored, ox - 32, oy - 20, 0);
   623                         end;
   769                         end;
   624                     defaultPos:= false
   770                     defaultPos:= false
   625                     end;
   771                     end;
   626                 gtFlamethrower:
   772                 gtFlamethrower: DrawSpriteRotatedF(sprHandFlamethrower, hx, hy, (RealTicks div 125) mod 4, sign, aangle);
   627                     begin
   773                 gtLandGun: DrawSpriteRotated(sprHandLandGun, hx, hy, sign, aangle);
   628                     DrawSpriteRotatedF(sprHandFlamethrower, hx, hy, (RealTicks div 125) mod 4, sign, aangle);
   774                 gtIceGun: DrawSpriteRotated(sprIceGun, hx, hy, sign, aangle);
   629                     if CurAmmoGear^.Tex <> nil then
       
   630                         DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex)
       
   631                     end;
       
   632                 gtLandGun:
       
   633                     begin DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle);
       
   634                     if CurAmmoGear^.Tex <> nil then
       
   635                         DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex)
       
   636                     end;
       
   637                 gtIceGun:
       
   638                     begin DrawSpriteRotated(sprIceGun, hx, hy, sign, aangle);
       
   639                     if CurAmmoGear^.Tex <> nil then
       
   640                         DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex)
       
   641                     end;
       
   642             end;
   775             end;
   643 
   776 
   644             case CurAmmoGear^.Kind of
   777             case CurAmmoGear^.Kind of
   645                 gtShotgunShot,
   778                 gtShotgunShot,
   646                 gtDEagleShot,
   779                 gtDEagleShot,
   660         end else
   793         end else
   661 
   794 
   662         if ((Gear^.State and gstHHJumping) <> 0) then
   795         if ((Gear^.State and gstHHJumping) <> 0) then
   663         begin
   796         begin
   664         DrawHedgehog(sx, sy,
   797         DrawHedgehog(sx, sy,
   665             sign*m,
   798             hogLR,
   666             1,
   799             1,
   667             1,
   800             1,
   668             0);
   801             0);
   669         HatVisible:= true;
   802         HatVisible:= true;
   670         defaultPos:= false
   803         defaultPos:= false
   739                 amGrenade: DrawSpriteRotated(sprHandGrenade, hx, hy, sign, aangle);
   872                 amGrenade: DrawSpriteRotated(sprHandGrenade, hx, hy, sign, aangle);
   740                 amWatermelon: DrawSpriteRotated(sprHandMelon, hx, hy, sign, aangle);
   873                 amWatermelon: DrawSpriteRotated(sprHandMelon, hx, hy, sign, aangle);
   741                 amSkip: DrawSpriteRotated(sprHandSkip, hx, hy, sign, aangle);
   874                 amSkip: DrawSpriteRotated(sprHandSkip, hx, hy, sign, aangle);
   742                 amClusterBomb: DrawSpriteRotated(sprHandCluster, hx, hy, sign, aangle);
   875                 amClusterBomb: DrawSpriteRotated(sprHandCluster, hx, hy, sign, aangle);
   743                 amDynamite: DrawSpriteRotated(sprHandDynamite, hx, hy, sign, aangle);
   876                 amDynamite: DrawSpriteRotated(sprHandDynamite, hx, hy, sign, aangle);
   744                 amDuck: DrawSpriteRotatedF(sprHandDuck, hx, hy, 0, sign, aangle);
   877                 amCreeper: DrawSpriteRotatedF(sprHandCreeper, hx, hy, 0, sign, aangle);
   745                 amHellishBomb: DrawSpriteRotated(sprHandHellish, hx, hy, sign, aangle);
   878                 amHellishBomb: DrawSpriteRotated(sprHandHellish, hx, hy, sign, aangle);
   746                 amGasBomb: DrawSpriteRotated(sprHandCheese, hx, hy, sign, aangle);
   879                 amGasBomb: DrawSpriteRotated(sprHandCheese, hx, hy, sign, aangle);
   747                 amMine: DrawSpriteRotated(sprHandMine, hx, hy, sign, aangle);
   880                 amMine: DrawSpriteRotated(sprHandMine, hx, hy, sign, aangle);
   748                 amAirMine: DrawSpriteRotated(sprHandAirMine, hx, hy, sign, aangle);
   881                 amAirMine: DrawSpriteRotated(sprHandAirMine, hx, hy, sign, aangle);
   749                 amSMine: DrawSpriteRotated(sprHandSMine, hx, hy, sign, aangle);
   882                 amSMine: DrawSpriteRotated(sprHandSMine, hx, hy, sign, aangle);
   750                 amKnife: DrawSpriteRotatedF(sprHandKnife, hx, hy, 0, sign, aangle);
   883                 amKnife: DrawSpriteRotatedF(sprHandKnife, hx, hy, 0, sign, aangle);
   751                 amSeduction: begin
   884                 amSeduction: if ((Gear^.State and gstMoving) = 0) then
       
   885                              begin
   752                              DrawSpriteRotated(sprHandSeduction, hx, hy, sign, aangle);
   886                              DrawSpriteRotated(sprHandSeduction, hx, hy, sign, aangle);
   753                              DrawCircle(ox, oy, 248, 4, $FF, $00, $00, $AA);
   887                              DrawCircle(ox, oy, cSeductionDist - 2, 4, $FF, $00, $00, $AA);
   754                              //Tint($FF, $0, $0, $AA);
       
   755                              //DrawTexture(ox - 240, oy - 240, SpritesData[sprVampiric].Texture, 10);
       
   756                              //untint;
       
   757                              end;
   888                              end;
   758                 amVampiric: DrawSpriteRotatedF(sprHandVamp, hx, hy, (RealTicks div 125) mod 4, sign, aangle);
   889                 amVampiric: DrawSpriteRotatedF(sprHandVamp, hx, hy, (RealTicks div 125) mod 4, sign, aangle);
   759                 amRCPlane: begin
       
   760                     DrawSpriteRotated(sprHandPlane, hx, hy, sign, 0);
       
   761                     defaultPos:= false
       
   762                     end;
       
   763                 amRubber,
   890                 amRubber,
   764                 amGirder: begin
   891                 amGirder: if ((Gear^.State and gstMoving) = 0) then
       
   892                     begin
   765                     DrawSpriteRotated(sprHandConstruction, hx, hy, sign, aangle);
   893                     DrawSpriteRotated(sprHandConstruction, hx, hy, sign, aangle);
   766                     if cBuildMaxDist = cDefaultBuildMaxDist then
   894                     if cBuildMaxDist = cDefaultBuildMaxDist then
   767                         begin
   895                         begin
   768                         if WorldEdge = weWrap then
   896                         if WorldEdge = weWrap then
   769                             begin
   897                             begin
   770                             if hwRound(Gear^.X) < LongInt(leftX) + 256 then
   898                             if hwRound(Gear^.X) < leftX + 256 then
   771                                 DrawSpriteClipped(sprGirder,
   899                                 DrawSpriteClipped(sprGirder,
   772                                                 rightX+(ox-leftX)-256,
   900                                                 rightX+(ox-leftX)-256,
   773                                                 oy-256,
   901                                                 oy-256,
   774                                                 LongInt(topY)+WorldDy,
   902                                                 topY+WorldDy,
   775                                                 LongInt(rightX)+WorldDx,
   903                                                 rightX+WorldDx,
   776                                                 cWaterLine+WorldDy,
   904                                                 cWaterLine+WorldDy,
   777                                                 LongInt(leftX)+WorldDx);
   905                                                 leftX+WorldDx);
   778                             if hwRound(Gear^.X) > LongInt(rightX) - 256 then
   906                             if hwRound(Gear^.X) > rightX - 256 then
   779                                 DrawSpriteClipped(sprGirder,
   907                                 DrawSpriteClipped(sprGirder,
   780                                                 leftX-(rightX-ox)-256,
   908                                                 leftX-(rightX-ox)-256,
   781                                                 oy-256,
   909                                                 oy-256,
   782                                                 LongInt(topY)+WorldDy,
   910                                                 topY+WorldDy,
   783                                                 LongInt(rightX)+WorldDx,
   911                                                 rightX+WorldDx,
   784                                                 cWaterLine+WorldDy,
   912                                                 cWaterLine+WorldDy,
   785                                                 LongInt(leftX)+WorldDx)
   913                                                 leftX+WorldDx)
   786                             end;
   914                             end;
   787                         DrawSpriteClipped(sprGirder,
   915                         DrawSpriteClipped(sprGirder,
   788                                         ox-256,
   916                                         ox-256,
   789                                         oy-256,
   917                                         oy-256,
   790                                         LongInt(topY)+WorldDy,
   918                                         topY+WorldDy,
   791                                         LongInt(rightX)+WorldDx,
   919                                         rightX+WorldDx,
   792                                         cWaterLine+WorldDy,
   920                                         cWaterLine+WorldDy,
   793                                         LongInt(leftX)+WorldDx)
   921                                         leftX+WorldDx)
   794                         end
   922                         end
   795                     else if cBuildMaxDist > 0 then
   923                     else if cBuildMaxDist > 0 then
   796                         begin
   924                         begin
   797                             DrawCircle(hx, hy, cBuildMaxDist, 3, $FF, 0, 0, $80);
   925                             DrawCircle(hx, hy, cBuildMaxDist, 3, $FF, 0, 0, $80);
   798                         end;
   926                         end;
   799                     end;
   927                     end;
   800                 amBee: DrawSpriteRotatedF(sprHandBee, hx, hy, (RealTicks div 125) mod 4, sign, aangle);
   928                 amBee: DrawSpriteRotatedF(sprHandBee, hx, hy, (RealTicks div 125) mod 4, sign, aangle);
   801                 amFlamethrower: DrawSpriteRotatedF(sprHandFlamethrower, hx, hy, (RealTicks div 125) mod 4, sign, aangle);
   929                 amFlamethrower: DrawSpriteRotatedF(sprHandFlamethrower, hx, hy, (RealTicks div 125) mod 4, sign, aangle);
   802                 amLandGun: DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle);
   930                 amLandGun: DrawSpriteRotated(sprHandLandGun, hx, hy, sign, aangle);
   803                 amIceGun: DrawSpriteRotated(sprIceGun, hx, hy, sign, aangle);
   931                 amIceGun: DrawSpriteRotated(sprIceGun, hx, hy, sign, aangle);
   804                 amResurrector: DrawCircle(ox, oy, 98, 4, $F5, $DB, $35, $AA); // I'd rather not like to hardcode 100 here
   932                 amResurrector: if ((Gear^.State and gstMoving) = 0) then
       
   933                     DrawCircle(ox, oy, cResurrectorDist - 2, 4, $F5, $DB, $35, $AA);
       
   934                 amFirePunch: DrawSpriteRotatedF(sprFirePunch, hx + 6 * sign + 1, hy - 5, (RealTicks div 50) mod 16, sign, 0);
   805             end;
   935             end;
   806 
   936 
   807             case amt of
   937             case amt of
   808                 amAirAttack,
   938                 amAirAttack,
   809                 amNapalm,
   939                 amNapalm,
   826                             sy,
   956                             sy,
   827                             0,
   957                             0,
   828                             sign,
   958                             sign,
   829                             0);
   959                             0);
   830                 amHammer: DrawSpriteRotatedF(sprHammer,
   960                 amHammer: DrawSpriteRotatedF(sprHammer,
   831                             sx,
   961                             sx + sign,
   832                             sy,
   962                             sy,
   833                             0,
   963                             0,
   834                             sign,
   964                             sign,
   835                             0);
   965                             0);
       
   966                 amRCPlane:
       
   967                     begin
       
   968                     DrawSpriteRotated(sprHandPlane, hx + 1, hy, sign, 0);
       
   969                     defaultPos:= false
       
   970                     end;
   836                 amBaseballBat, amMinigun:
   971                 amBaseballBat, amMinigun:
   837                     begin
   972                     begin
   838                     HatVisible:= true;
   973                     HatVisible:= true;
   839                     DrawHedgehog(sx, sy,
   974                     DrawHedgehog(sx, sy,
   840                             sign,
   975                             sign,
   841                             0,
   976                             0,
   842                             5,
   977                             5,
   843                             0);
   978                             0);
   844                     end
   979                     end
   845             else
   980             else
   846                 DrawHedgehog(sx, sy,
   981                 // Special hog sprite that makes hog "look" towards the selection icon.
   847                     sign,
   982                 // Only works without hat for now since it would look weird/creepy for many hats.
   848                     0,
   983                 if ((HH^.Hat = 'NoHat') or (HH^.HatTex = nil)) and ((Gear^.State and (gstMoving or gstAttacking)) = 0) and ((Ammoz[amt].Ammo.Propz and ammoprop_ShowSelIcon) <> 0) then
   849                     4,
   984                     DrawHedgehog(sx, sy,
   850                     0);
   985                         sign,
   851 
   986                         0,
   852                 HatVisible:= true;
   987                         6,
   853                 (* with HH^ do
   988                         0)
   854                     if (HatTex <> nil)
   989                 // Default idle hedgehog
   855                     and (HatVisibility > 0) then
   990                 else
   856                         DrawTextureF(HatTex,
   991                     begin
   857                             HatVisibility,
   992                     DrawHedgehog(sx, sy,
   858                             sx,
   993                         sign,
   859                             sy - 5,
   994                         0,
   860                             0,
   995                         4,
   861                             sign,
   996                         0);
   862                             32,
   997                     HatVisible:= true;
   863                             32); *)
   998                     end;
   864             end;
   999             end;
   865 
  1000 
   866             defaultPos:= false
  1001             defaultPos:= false
   867         end;
  1002         end;
   868 
  1003 
   902 
  1037 
   903 
  1038 
   904         if ((Gear^.State and gstHHJumping) <> 0) then
  1039         if ((Gear^.State and gstHHJumping) <> 0) then
   905             begin
  1040             begin
   906             DrawHedgehog(sx, sy,
  1041             DrawHedgehog(sx, sy,
   907                 sign*m,
  1042                 hogLR,
   908                 1,
  1043                 1,
   909                 1,
  1044                 1,
   910                 0);
  1045                 0);
   911             defaultPos:= false
  1046             defaultPos:= false
   912             end;
  1047             end;
  1006                 DrawTextureF(curhat,
  1141                 DrawTextureF(curhat,
  1007                     HatVisibility,
  1142                     HatVisibility,
  1008                     sx,
  1143                     sx,
  1009                     sy - 5,
  1144                     sy - 5,
  1010                     0,
  1145                     0,
  1011                     sign*m,
  1146                     hogLR,
  1012                     32,
  1147                     32,
  1013                     32);
  1148                     32);
  1014                 if (curhat^.w > 64) or ((curhat^.w = 64) and (curhat^.h = 32)) then
  1149                 if (curhat^.w > 64) or ((curhat^.w = 64) and (curhat^.h = 32)) then
  1015                     begin
  1150                     begin
  1016                     if ((curhat^.w = 64) and (curhat^.h = 32)) then
  1151                     if ((curhat^.w = 64) and (curhat^.h = 32)) then
  1021                     DrawTextureF(curhat,
  1156                     DrawTextureF(curhat,
  1022                         HatVisibility,
  1157                         HatVisibility,
  1023                         sx,
  1158                         sx,
  1024                         sy - 5,
  1159                         sy - 5,
  1025                         tx,
  1160                         tx,
  1026                         sign*m,
  1161                         hogLR,
  1027                         32,
  1162                         32,
  1028                         32);
  1163                         32);
  1029                     untint
  1164                     untint
  1030                     end
  1165                     end
  1031                 end
  1166                 end
  1032         end;
  1167         end;
  1033 
  1168 
  1034     if (Gear^.State and gstHHDriven) <> 0 then
  1169     if (Gear^.State and gstHHDriven) <> 0 then
  1035         begin
  1170         begin
  1036     (*    if (CurAmmoGear = nil) then
       
  1037             begin
       
  1038             amt:= CurrentHedgehog^.CurAmmoType;
       
  1039             case amt of
       
  1040                 amJetpack: DrawSprite(sprJetpack, sx-32, sy-32, 0);
       
  1041                 end
       
  1042             end; *)
       
  1043         if (CurAmmoGear = nil) then
  1171         if (CurAmmoGear = nil) then
  1044             begin
  1172             begin
  1045                 if ((Gear^.State and (gstAttacked or gstAnimation or gstHHJumping)) = 0)
  1173             if ((Gear^.State and (gstAttacked or gstAnimation or gstHHJumping)) = 0)
  1046                 and (Gear^.Message and (gmLeft or gmRight) = 0) then
  1174             and (Gear^.Message and (gmLeft or gmRight) = 0) then
  1047                 begin
  1175                 begin
  1048                 amt:= CurrentHedgehog^.CurAmmoType;
  1176                 amt:= CurrentHedgehog^.CurAmmoType;
  1049                     case amt of
  1177                 case amt of
  1050                         amBaseballBat: DrawSpritePivotedF(sprHandBaseball,
  1178                     amBaseballBat: DrawSpritePivotedF(sprHandBaseball,
  1051                             sx + 9 * sign, sy + 2, 0, sign, -8, 1, aangle);
  1179                         sx + 9 * sign, sy + 2, 0, sign, -8, 1, aangle);
  1052                         amMinigun: DrawSpritePivotedF(sprMinigun,
  1180                     amMinigun: DrawSpritePivotedF(sprMinigun,
  1053                             sx + 20 * sign, sy + 4, 0, sign, -18, -2, aangle);
  1181                         sx + 20 * sign, sy + 4, 0, sign, -18, -2, aangle);
  1054                     end;
  1182                     end;
  1055                 end;
  1183                 end;
  1056             end
  1184             end
  1057         else
  1185         else
  1058             begin
  1186             begin
  1067                             if (CurAmmoGear^.MsgParam and gmLeft) <> 0 then
  1195                             if (CurAmmoGear^.MsgParam and gmLeft) <> 0 then
  1068                                 DrawSprite(sprJetpack, sx-28, sy-28, 2);
  1196                                 DrawSprite(sprJetpack, sx-28, sy-28, 2);
  1069                             if (CurAmmoGear^.MsgParam and gmRight) <> 0 then
  1197                             if (CurAmmoGear^.MsgParam and gmRight) <> 0 then
  1070                                 DrawSprite(sprJetpack, sx-36, sy-28, 3)
  1198                                 DrawSprite(sprJetpack, sx-36, sy-28, 3)
  1071                             end;
  1199                             end;
  1072                         if CurAmmoGear^.Tex <> nil then
       
  1073                             DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex);
       
  1074                         DrawAltWeapon(Gear, sx, sy)
       
  1075                         end;
  1200                         end;
  1076                 gtShover: DrawSpritePivotedF(sprHandBaseball,
  1201                 gtShover: DrawSpritePivotedF(sprHandBaseball,
  1077                     sx + 9 * sign, sy + 2, CurAmmoGear^.Tag, sign, -8, 1, aangle);
  1202                     sx + 9 * sign, sy + 2, CurAmmoGear^.Tag, sign, -8, 1, aangle);
  1078                 gtMinigun: DrawSpritePivotedF(sprMinigun,
  1203                 gtMinigun: DrawSpritePivotedF(sprMinigun,
  1079                     sx + 20 * sign, sy + 4, CurAmmoGear^.Tag, sign, -18, -2, aangle);
  1204                     sx + 20 * sign, sy + 4, CurAmmoGear^.Tag, sign, -18, -2, aangle);
  1111         if (Gear^.State and gstHHDriven) <> 0 then // Current hedgehog
  1236         if (Gear^.State and gstHHDriven) <> 0 then // Current hedgehog
  1112             begin
  1237             begin
  1113             if (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtResurrector) then
  1238             if (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtResurrector) then
  1114                 DrawTextureCentered(ox, sy - cHHRadius - 7 - HealthTagTex^.h, HealthTagTex);
  1239                 DrawTextureCentered(ox, sy - cHHRadius - 7 - HealthTagTex^.h, HealthTagTex);
  1115 
  1240 
  1116             if bShowFinger and ((Gear^.State and gstHHDriven) <> 0) then
       
  1117                 begin
       
  1118                 ty := oy - 32;
       
  1119                 // move finger higher up if tags are above hog
       
  1120                 if (cTagsMask and htTeamName) <> 0 then
       
  1121                     ty := ty - Team^.NameTagTex^.h - 2;
       
  1122                 if (cTagsMask and htName) <> 0 then
       
  1123                     ty := ty - NameTagTex^.h - 2;
       
  1124                 if (cTagsMask and htHealth) <> 0 then
       
  1125                     ty := ty - HealthTagTex^.h - 2;
       
  1126                 tx := ox;
       
  1127 
       
  1128                 // don't go offscreen
       
  1129                 //tx := round(max(((-cScreenWidth + 16) / cScaleFactor) + SpritesData[sprFinger].Width div 2, min(((cScreenWidth - 16) / cScaleFactor) - SpritesData[sprFinger].Width div 2, tx)));
       
  1130                 //ty := round(max(cScreenHeight div 2 - ((cScreenHeight - 16) / cScaleFactor) + SpritesData[sprFinger].Height div 2, min(cScreenHeight div 2 - ((-cScreenHeight + SpritesData[sprFinger].Height) / (cScaleFactor)) - SpritesData[sprFinger].Width div 2 - 96, ty)));
       
  1131                 t:= 32;//trunc((SpritesData[sprFinger].Width + t) / cScaleFactor);
       
  1132                 tx := min(max(tx, ViewLeftX + t), ViewRightX  - t);
       
  1133                 t:= 32;//trunc((SpritesData[sprFinger].Height + t) / cScaleFactor);
       
  1134                 ty := min(ty, ViewBottomY - 96);
       
  1135                 // don't overlap with HH or HH tags
       
  1136                 if ty < ViewTopY + t then
       
  1137                     begin
       
  1138                     if abs(tx - ox) < abs(ty - oy)  then
       
  1139                         ty:= max(ViewTopY + t, oy + t)
       
  1140                     else
       
  1141                         ty:= max(ViewTopY + t, ty);
       
  1142                     end;
       
  1143 
       
  1144                 dAngle := DxDy2Angle(int2hwfloat(ty - oy), int2hwfloat(tx - ox)) + 90;
       
  1145 
       
  1146                 DrawSpriteRotatedF(sprFinger, tx, ty, RealTicks div 32 mod 16, 1, dAngle);
       
  1147                 end;
       
  1148 
       
  1149 
       
  1150             if (Gear^.State and gstDrowning) = 0 then
  1241             if (Gear^.State and gstDrowning) = 0 then
  1151                 if (Gear^.State and gstHHThinking) <> 0 then
  1242                 if ((Gear^.State and gstHHThinking) <> 0) and (not CinematicScript) then
  1152                     DrawSprite(sprQuestion, ox - 10, oy - cHHRadius - 34, (RealTicks shr 9) mod 8)
  1243                     DrawSprite(sprQuestion, ox - 10, oy - cHHRadius - 34, (RealTicks shr 9) mod 8)
  1153             end
  1244             end
  1154         end;
  1245         end;
  1155 
  1246 
  1156     if HH^.Effects[hePoisoned] <> 0 then
  1247     if HH^.Effects[hePoisoned] <> 0 then
  1205     vg: PVisualGear;
  1296     vg: PVisualGear;
  1206     i: Longword;
  1297     i: Longword;
  1207     aAngle: real;
  1298     aAngle: real;
  1208     startX, endX, startY, endY: LongInt;
  1299     startX, endX, startY, endY: LongInt;
  1209 begin
  1300 begin
  1210     if Gear^.State and gstFrozen <> 0 then Tint($A0, $A0, $FF, $FF);
  1301     // airmine has its own sprite
  1211     //if Gear^.State and gstFrozen <> 0 then Tint(IceColor or $FF);
  1302     if (Gear^.State and gstFrozen <> 0) and (Gear^.Kind <> gtAirMine) then Tint($A0, $A0, $FF, $FF);
  1212     if Gear^.Target.X <> NoPointX then
  1303     if Gear^.Target.X <> NoPointX then
  1213         if Gear^.AmmoType = amBee then
  1304         if Gear^.AmmoType = amBee then
  1214             DrawSpriteRotatedF(sprTargetBee, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360)
  1305             DrawSpriteRotatedF(sprTargetBee, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360)
  1215     else if Gear^.AmmoType = amIceGun then
  1306     else if Gear^.AmmoType = amIceGun then
  1216         //DrawSprite(sprSnowDust, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, (RealTicks shr 2) mod 8)
       
  1217         //DrawTextureRotatedF(SpritesData[sprSnowDust].Texture, 1, 0, 0, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, (RealTicks shr 2) mod 8, 1, 22, 22, (RealTicks shr 3) mod 360)
       
  1218         DrawTextureRotatedF(SpritesData[sprSnowDust].Texture, 1/(1+(RealTicks shr 8) mod 5), 0, 0, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, (RealTicks shr 2) mod 8, 1, 22, 22, (RealTicks shr 3) mod 360)
  1307         DrawTextureRotatedF(SpritesData[sprSnowDust].Texture, 1/(1+(RealTicks shr 8) mod 5), 0, 0, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, (RealTicks shr 2) mod 8, 1, 22, 22, (RealTicks shr 3) mod 360)
  1219     else
  1308     else
       
  1309         begin
       
  1310         if CurrentHedgehog <> nil then
       
  1311             begin
       
  1312             if (IsTooDarkToRead(CurrentHedgehog^.Team^.Clan^.Color)) then
       
  1313                 DrawSpriteRotatedF(sprTargetPBackInv, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360)
       
  1314             else
       
  1315                 DrawSpriteRotatedF(sprTargetPBack, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360);
       
  1316             Tint(CurrentHedgehog^.Team^.Clan^.Color shl 8 or $FF);
       
  1317             end;
  1220         DrawSpriteRotatedF(sprTargetP, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360);
  1318         DrawSpriteRotatedF(sprTargetP, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360);
       
  1319         if CurrentHedgehog <> nil then
       
  1320             untint;
       
  1321         end;
  1221 
  1322 
  1222     case Gear^.Kind of
  1323     case Gear^.Kind of
  1223           gtGrenade: DrawSpriteRotated(sprBomb, x, y, 0, Gear^.DirAngle);
  1324           gtGrenade: DrawSpriteRotated(sprBomb, x, y, 0, Gear^.DirAngle);
  1224       gtSnowball: DrawSpriteRotated(sprSnowball, x, y, 0, Gear^.DirAngle);
  1325       gtSnowball: DrawSpriteRotated(sprSnowball, x, y, 0, Gear^.DirAngle);
  1225        gtGasBomb: DrawSpriteRotated(sprCheese, x, y, 0, Gear^.DirAngle);
  1326        gtGasBomb: DrawSpriteRotated(sprCheese, x, y, 0, Gear^.DirAngle);
  1256                          else if Gear^.Tag = 2 then
  1357                          else if Gear^.Tag = 2 then
  1257                              vg^.Tint:= $364df7b0;
  1358                              vg^.Tint:= $364df7b0;
  1258                      end;
  1359                      end;
  1259                  end;
  1360                  end;
  1260 
  1361 
  1261            gtDrill: if (Gear^.State and gsttmpFlag) <> 0 then
  1362            gtDrill: begin
  1262                         DrawSpriteRotated(sprAirDrill, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX))
  1363                     if (Gear^.Pos = 1) then
       
  1364                         i:= (RealTicks shr 5 + Gear^.uid) mod 4
  1263                     else
  1365                     else
  1264                         DrawSpriteRotated(sprDrill, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
  1366                         i:= Gear^.uid mod 4;
  1265 
  1367                     if (Gear^.State and gsttmpFlag) <> 0 then
       
  1368                         DrawTextureRotatedF(SpritesData[sprAirDrill].texture, 0.5, 0, 0, x, y, i, 0, 64, 64, DxDy2Angle(Gear^.dY, Gear^.dX))
       
  1369                     else
       
  1370                         DrawTextureRotatedF(SpritesData[sprDrill].texture, 0.5, 0, 0, x, y, i, 0, 64, 64, DxDy2Angle(Gear^.dY, Gear^.dX));
       
  1371                     end;
  1266         gtHedgehog: DrawHH(Gear, x, y);
  1372         gtHedgehog: DrawHH(Gear, x, y);
  1267 
  1373 
  1268            gtShell: DrawSpriteRotated(sprBazookaShell, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
  1374            gtShell: DrawSpriteRotated(sprBazookaShell, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
  1269 
  1375 
  1270            gtGrave: begin
  1376            gtGrave: begin
  1271                     DrawTextureF(Gear^.Hedgehog^.Team^.GraveTex, 1, x, y, (RealTicks shr 7+Gear^.uid) and 15, 1, 32, 32);
  1377                     DrawTextureF(Gear^.Hedgehog^.Team^.GraveTex, 1, x, y, (RealTicks shr 7+Gear^.uid) and 15, 1, 32, 32);
  1272                     if Gear^.Health > 0 then
  1378                     if Gear^.Health > 0 then
  1273                         begin
  1379                         begin
  1274                         //Tint($33, $33, $FF, max($40, round($FF * abs(1 - (GameTicks mod (6000 div Gear^.Health)) / 750))));
       
  1275                         Tint($f5, $db, $35, max($40, round($FF * abs(1 - (RealTicks mod 1500) / (750 + Gear^.Health)))));
  1380                         Tint($f5, $db, $35, max($40, round($FF * abs(1 - (RealTicks mod 1500) / (750 + Gear^.Health)))));
  1276                         //Tint($FF, $FF, $FF, max($40, round($FF * abs(1 - (RealTicks mod 1500) / 750))));
       
  1277                         DrawSprite(sprVampiric, x - 24, y - 24, 0);
  1381                         DrawSprite(sprVampiric, x - 24, y - 24, 0);
  1278                         untint
  1382                         untint
  1279                         end
  1383                         end
  1280                     end;
  1384                     end;
  1281              gtBee: DrawSpriteRotatedF(sprBee, x, y, (RealTicks shr 5) mod 2, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
  1385              gtBee: DrawSpriteRotatedF(sprBee, x, y, (RealTicks shr 5) mod 2, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
  1287                            DrawSpriteRotated(sprMineOff, x, y, 0, Gear^.DirAngle)
  1391                            DrawSpriteRotated(sprMineOff, x, y, 0, Gear^.DirAngle)
  1288                     else if Gear^.Health <> 0 then
  1392                     else if Gear^.Health <> 0 then
  1289                        DrawSpriteRotated(sprMineOn, x, y, 0, Gear^.DirAngle)
  1393                        DrawSpriteRotated(sprMineOn, x, y, 0, Gear^.DirAngle)
  1290                     else DrawSpriteRotated(sprMineDead, x, y, 0, Gear^.DirAngle);
  1394                     else DrawSpriteRotated(sprMineDead, x, y, 0, Gear^.DirAngle);
  1291                     end;
  1395                     end;
  1292          gtAirMine: if Gear^.State and gstTmpFlag = 0 then                // mine is inactive
  1396          gtAirMine: 
  1293                         begin
  1397                     // render air mine based on its state:
       
  1398                     // frozen
       
  1399                     if (Gear^.State and gstFrozen <> 0) then
       
  1400                         // frozen air mine sprite
       
  1401                         DrawSprite(sprFrozenAirMine, x-16, y-16, 0)
       
  1402                     // stunned (after being shot)
       
  1403                     else if (Gear^.Tag <> 0) then
       
  1404                         // sparks animation
       
  1405                         DrawSprite(sprAirMine, x-16, y-16, 16 + ((RealTicks div 50 + Gear^.Uid) mod 16))
       
  1406                     // inactive / initialization phase (shortly after launched by hog)
       
  1407                     else if (Gear^.State and gstTmpFlag = 0) then
       
  1408                         begin
       
  1409                         // dark air mine, signal lamp off
  1294                         Tint(150,150,150,255);
  1410                         Tint(150,150,150,255);
  1295                         DrawSprite(sprAirMine, x-16, y-16, 15);
  1411                         DrawSprite(sprAirMine, x-16, y-16, 15);
  1296                         untint
  1412                         untint
  1297                         end
  1413                         end
  1298                     else if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.Gear <> nil) then  // mine is chasing a hog
  1414                     // actively chasing a hog
  1299                          DrawSprite(sprAirMine, x-16, y-16, (RealTicks div 25) mod 16)
  1415                     else if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.Gear <> nil) then
  1300                     else if Gear^.State and gstChooseTarget <> 0 then   // mine is seeking for hogs
  1416                          // signal lamp rapidly flashes
  1301                          DrawSprite(sprAirMine, x-16, y-16, (RealTicks div 125) mod 16)
  1417                          DrawSprite(sprAirMine, x-16, y-16, (RealTicks div 25 + Gear^.Uid) mod 16)
       
  1418                     // seeking for hogs
       
  1419                     else if Gear^.State and gstChooseTarget <> 0 then
       
  1420                          // signal lamp on
       
  1421                          DrawSprite(sprAirMine, x-16, y-16, 3)
       
  1422                     // active, but not seeking for hogs
  1302                     else
  1423                     else
  1303                          DrawSprite(sprAirMine, x-16, y-16, 4);           // mine is active but not seeking
  1424                          // signal lamp off
       
  1425                          DrawSprite(sprAirMine, x-16, y-16, 15);
  1304 
  1426 
  1305            gtSMine: if (((Gear^.State and gstAttacking) = 0)or((Gear^.Timer and $3FF) < 420)) and (Gear^.Health <> 0) then
  1427            gtSMine: if (((Gear^.State and gstAttacking) = 0)or((Gear^.Timer and $3FF) < 420)) and (Gear^.Health <> 0) then
  1306                            DrawSpriteRotated(sprSMineOff, x, y, 0, Gear^.DirAngle)
  1428                            DrawSpriteRotated(sprSMineOff, x, y, 0, Gear^.DirAngle)
  1307                        else if Gear^.Health <> 0 then
  1429                        else if Gear^.Health <> 0 then
  1308                            DrawSpriteRotated(sprSMineOn, x, y, 0, Gear^.DirAngle)
  1430                            DrawSpriteRotated(sprSMineOn, x, y, 0, Gear^.DirAngle)
  1396            gtFlame: if Gear^.Tag and 1 = 0 then
  1518            gtFlame: if Gear^.Tag and 1 = 0 then
  1397                          DrawTextureF(SpritesData[sprFlame].Texture, 2 / (Gear^.Tag mod 3 + 2), x, y, (RealTicks shr 7 + LongWord(Gear^.Tag)) mod 8, 1, 16, 16)
  1519                          DrawTextureF(SpritesData[sprFlame].Texture, 2 / (Gear^.Tag mod 3 + 2), x, y, (RealTicks shr 7 + LongWord(Gear^.Tag)) mod 8, 1, 16, 16)
  1398                     else DrawTextureF(SpritesData[sprFlame].Texture, 2 / (Gear^.Tag mod 3 + 2), x, y, (RealTicks shr 7 + LongWord(Gear^.Tag)) mod 8, -1, 16, 16);
  1520                     else DrawTextureF(SpritesData[sprFlame].Texture, 2 / (Gear^.Tag mod 3 + 2), x, y, (RealTicks shr 7 + LongWord(Gear^.Tag)) mod 8, -1, 16, 16);
  1399        gtParachute: begin
  1521        gtParachute: begin
  1400                     DrawSprite(sprParachute, x - 24, y - 48, 0);
  1522                     DrawSprite(sprParachute, x - 24, y - 48, 0);
  1401                     DrawAltWeapon(Gear, x + 1, y - 3)
       
  1402                     end;
  1523                     end;
  1403        gtAirAttack: begin
  1524        gtAirAttack: begin
  1404                     Tint(Gear^.Tint);
  1525                     Tint(Gear^.Tint);
  1405                     DrawSpriteRotatedF(sprAirplane, x, y, 0, Gear^.Tag, 0);
  1526                     DrawSpriteRotatedF(sprAirplane, x, y, 0, Gear^.Tag, 0);
  1406                     untint;
  1527                     untint;
  1407                     DrawSpriteRotatedF(sprAirplane, x, y, 1, Gear^.Tag, 0);
  1528                     DrawSpriteRotatedF(sprAirplane, x, y, 1, Gear^.Tag, 0);
       
  1529                     if WorldEdge <> weSea then
       
  1530                         DrawSpriteRotatedF(sprAirplane, x, y, 2, Gear^.Tag, 0)
       
  1531                     else
       
  1532                         DrawSpriteRotatedF(sprAirplane, x, y, 3, Gear^.Tag, 0);
  1408                     end;
  1533                     end;
  1409          gtAirBomb: DrawSpriteRotated(sprAirBomb, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
  1534          gtAirBomb: DrawSpriteRotated(sprAirBomb, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
  1410         gtTeleport: begin
  1535         gtTeleport: begin
  1411                     HHGear:= Gear^.Hedgehog^.Gear;
  1536                     HHGear:= Gear^.Hedgehog^.Gear;
  1412                     if HHGear <> nil then
  1537                     if HHGear <> nil then
  1414                         if ((Gear^.State and gstAnimation) <> 0) then
  1539                         if ((Gear^.State and gstAnimation) <> 0) then
  1415                             DrawSpriteRotatedF(sprTeleport, x + 1, y - 3, Gear^.Pos, hwSign(Gear^.dX), 0);
  1540                             DrawSpriteRotatedF(sprTeleport, x + 1, y - 3, Gear^.Pos, hwSign(Gear^.dX), 0);
  1416                         DrawSpriteRotatedF(sprTeleport, hwRound(HHGear^.X) + 1 + WorldDx, hwRound(HHGear^.Y) - 3 + WorldDy, 11 - Gear^.Pos, hwSign(HHGear^.dX), 0)
  1541                         DrawSpriteRotatedF(sprTeleport, hwRound(HHGear^.X) + 1 + WorldDx, hwRound(HHGear^.Y) - 3 + WorldDy, 11 - Gear^.Pos, hwSign(HHGear^.dX), 0)
  1417                         end
  1542                         end
  1418                     end;
  1543                     end;
  1419         gtSwitcher: DrawSprite(sprSwitch, x - 16, y - 56, (RealTicks shr 6) mod 12);
  1544         gtSwitcher: begin
       
  1545                     setTintAdd(true);
       
  1546                     Tint(Gear^.Hedgehog^.Team^.Clan^.Color shl 8 or $FF);
       
  1547                     DrawSprite(sprSwitch, x - 16, y - 56, (RealTicks shr 6) mod 12);
       
  1548                     untint;
       
  1549                     setTintAdd(false);
       
  1550                     end;
  1420           gtTarget: begin
  1551           gtTarget: begin
  1421                     Tint($FF, $FF, $FF, round($FF * Gear^.Timer / 1000));
  1552                     Tint($FF, $FF, $FF, round($FF * Gear^.Timer / 1000));
  1422                     DrawSprite(sprTarget, x - 16, y - 16, 0);
  1553                     DrawSprite(sprTarget, x - 16, y - 16, 0);
  1423                     untint;
  1554                     untint;
  1424                     end;
  1555                     end;
  1498            gtFlake: if Gear^.State and (gstDrowning or gstTmpFlag) <> 0  then
  1629            gtFlake: if Gear^.State and (gstDrowning or gstTmpFlag) <> 0  then
  1499                         begin
  1630                         begin
  1500                         Tint(Gear^.Tint);
  1631                         Tint(Gear^.Tint);
  1501                         // Needs a nicer white texture to tint
  1632                         // Needs a nicer white texture to tint
  1502                         DrawTextureRotatedF(SpritesData[sprSnowDust].Texture, 1, 0, 0, x, y, 0, 1, 8, 8, Gear^.DirAngle);
  1633                         DrawTextureRotatedF(SpritesData[sprSnowDust].Texture, 1, 0, 0, x, y, 0, 1, 8, 8, Gear^.DirAngle);
  1503                         //DrawSpriteRotated(sprSnowDust, x, y, 0, Gear^.DirAngle);
       
  1504                         //DrawTexture(x, y, SpritesData[sprVampiric].Texture, 0.1);
       
  1505                         untint;
  1634                         untint;
  1506                         end
  1635                         end
  1507                     else //if not isInLag then
  1636                     else //if not isInLag then
  1508                         begin
  1637                         begin
  1509                         if isInLag and (Gear^.FlightTime < 256) then
  1638                         if isInLag and (Gear^.FlightTime < 256) then
  1514                             Tint($FF, $FF, $FF, $FF-min(255,Gear^.FlightTime));
  1643                             Tint($FF, $FF, $FF, $FF-min(255,Gear^.FlightTime));
  1515                         if vobVelocity = 0 then
  1644                         if vobVelocity = 0 then
  1516                             DrawSprite(sprFlake, x, y, Gear^.Timer)
  1645                             DrawSprite(sprFlake, x, y, Gear^.Timer)
  1517                         else
  1646                         else
  1518                             DrawSpriteRotatedF(sprFlake, x, y, Gear^.Timer, 1, Gear^.DirAngle);
  1647                             DrawSpriteRotatedF(sprFlake, x, y, Gear^.Timer, 1, Gear^.DirAngle);
  1519 //DrawSprite(sprFlake, x-SpritesData[sprFlake].Width div 2, y-SpritesData[sprFlake].Height div 2, Gear^.Timer)
       
  1520 //DrawSpriteRotatedF(sprFlake, x-SpritesData[sprFlake].Width div 2, y-SpritesData[sprFlake].Height div 2, Gear^.Timer, 1, Gear^.DirAngle);
       
  1521                         if Gear^.FlightTime > 0 then
  1648                         if Gear^.FlightTime > 0 then
  1522                             untint;
  1649                             untint;
  1523                         end;
  1650                         end;
  1524        //gtStructure: DrawSprite(sprTarget, x - 16, y - 16, 0);
       
  1525           gtTardis: if Gear^.Pos <> 4 then
  1651           gtTardis: if Gear^.Pos <> 4 then
  1526                         begin
  1652                         begin
  1527                         if Gear^.Pos = 2 then
  1653                         if Gear^.Pos = 2 then
  1528                             Tint(Gear^.Hedgehog^.Team^.Clan^.Color shl 8 or $FF)
  1654                             Tint(Gear^.Hedgehog^.Team^.Clan^.Color shl 8 or $FF)
  1529                         else
  1655                         else
  1534                         else
  1660                         else
  1535                             Tint($FF,$FF,$FF,max($00, round(Gear^.Power * (1-abs(0.5 - (GameTicks mod 2000) / 2000)))));
  1661                             Tint($FF,$FF,$FF,max($00, round(Gear^.Power * (1-abs(0.5 - (GameTicks mod 2000) / 2000)))));
  1536                         DrawSprite(sprTardis, x-25, y-64,1);
  1662                         DrawSprite(sprTardis, x-25, y-64,1);
  1537                         if Gear^.Pos <> 2 then
  1663                         if Gear^.Pos <> 2 then
  1538                             untint
  1664                             untint
  1539 (*
       
  1540                         Tint(Gear^.Hedgehog^.Team^.Clan^.Color shl 8 or max($00, round(Gear^.Power * abs(1 - (RealTicks mod 500) / 250))));
       
  1541                         DrawTexture(x-6, y-70, SpritesData[sprVampiric].Texture, 0.25);
       
  1542                         untint
       
  1543 *)
       
  1544                         end;
  1665                         end;
  1545             gtIceGun: begin
  1666             gtIceGun: begin
  1546                       HHGear := Gear^.Hedgehog^.Gear;
  1667                       HHGear := Gear^.Hedgehog^.Gear;
  1547                       if HHGear <> nil then
  1668                       if HHGear <> nil then
  1548                           begin
  1669                           begin
  1562                           if RealTicks mod 2 = 0 then
  1683                           if RealTicks mod 2 = 0 then
  1563                                 begin
  1684                                 begin
  1564                                 i:= random(100)+100;
  1685                                 i:= random(100)+100;
  1565                                 if Gear^.Target.X <> NoPointX then
  1686                                 if Gear^.Target.X <> NoPointX then
  1566                                     begin
  1687                                     begin
  1567                                     DrawLine(Gear^.Target.X, Gear^.Target.Y, hwRound(HHGear^.X), hwRound(HHGear^.Y), 4.0, i, i, $FF, $40);
  1688                                     DrawLineWrapped(hwRound(HHGear^.X), hwRound(HHGear^.Y), Gear^.Target.X, Gear^.Target.Y, 4.0, hwSign(HHGear^.dX) < 0, Gear^.FlightTime, i, i, $FF, $40);
  1568                                     end
  1689                                     end
  1569                                 else
  1690                                 else
  1570                                     begin
  1691                                     begin
  1571                                     DrawLine(hwRound(HHGear^.X), hwRound(HHGear^.Y), hwRound(Gear^.X), hwRound(Gear^.Y), 4.0, i, i, $FF, $40);
  1692                                     DrawLineWrapped(hwRound(HHGear^.X), hwRound(HHGear^.Y), hwRound(Gear^.X), hwRound(Gear^.Y), 4.0, hwSign(HHGear^.dX) < 0, Gear^.FlightTime, i, i, $FF, $40);
  1572                                     end;
  1693                                     end;
  1573                                 end
  1694                                 end
  1574                           end
  1695                           end
  1575                       end;
  1696                       end;
  1576             gtDuck: DrawSpriteRotatedF(sprDuck, x, y, 1, Gear^.Tag, 
  1697             gtCreeper: if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.Gear <> nil) then
  1577                     // replace with something based on dx/dy?
  1698                          DrawSpriteRotatedF(sprCreeper, x, y, 1, hwRound(SignAs(_1,Gear^.Hedgehog^.Gear^.X-Gear^.X)), 0)
  1578                     Gear^.DirAngle + 10-round(20 * abs(1 - (RealTicks mod round(0.1/max(0.00005,cWindSpeedf))) / round(0.05/max(0.00005,cWindSpeedf))) ));
  1699                     else DrawSpriteRotatedF(sprCreeper, x, y, 1, hwRound(SignAs(_1,Gear^.dX)), 0);
       
  1700 
  1579             gtGenericFaller: begin
  1701             gtGenericFaller: begin
  1580                              // DEBUG: draw gtGenericFaller
  1702                              // DEBUG: draw gtGenericFaller
  1581                              if Gear^.Tag <> 0 then
  1703                              if Gear^.Tag <> 0 then
  1582                                  DrawCircle(x, y, max(3, Gear^.Radius), 3, $FF, $00, $00, $FF)
  1704                                  DrawCircle(x, y, max(3, Gear^.Radius), 3, $FF, $00, $00, $FF)
  1583                              else
  1705                              else
  1587     if Gear^.State and gstFrozen <> 0 then untint
  1709     if Gear^.State and gstFrozen <> 0 then untint
  1588 end;
  1710 end;
  1589 
  1711 
  1590 procedure RenderGearTimer(Gear: PGear; x, y: LongInt);
  1712 procedure RenderGearTimer(Gear: PGear; x, y: LongInt);
  1591 begin
  1713 begin
  1592 if Gear^.RenderTimer and (Gear^.Tex <> nil) then
  1714 if Gear^.RenderTimer and (Gear^.Tex <> nil) and (isShowGearInfo or (not (Gear^.Kind in [gtMine, gtSMine, gtAirMine]))) then
  1593     DrawTextureCentered(x + 8, y + 8, Gear^.Tex);
  1715     DrawTextureCentered(x + 8, y + 8, Gear^.Tex);
  1594 end;
  1716 end;
  1595 
  1717 
       
  1718 procedure RenderGearHealth(Gear: PGear; x, y: LongInt);
       
  1719 begin
       
  1720 if isShowGearInfo and (Gear^.RenderHealth) and (Gear^.Tex <> nil) then
       
  1721     begin
       
  1722     if (Gear^.Kind = gtCase) and ((Gear^.Pos and posCaseHealth) <> 0) then
       
  1723         DrawTextureCentered(x, y - 38, Gear^.Tex);
       
  1724     if (Gear^.Kind = gtExplosives) then
       
  1725         DrawTextureCentered(x, y - 38, Gear^.Tex);
       
  1726     end;
       
  1727 end;
       
  1728 
  1596 end.
  1729 end.