code changes to make the new bat animation work
authoralfadur
Sun, 15 Jan 2017 12:50:27 -0500
changeset 12119 3374e0f67f39
parent 12118 4f567f7a08e8
child 12120 1aae30470fa3
code changes to make the new bat animation work
hedgewars/uGearsHandlersMess.pas
hedgewars/uGearsList.pas
hedgewars/uGearsRender.pas
hedgewars/uRender.pas
hedgewars/uVariables.pas
--- a/hedgewars/uGearsHandlersMess.pas	Sun Jan 15 12:49:26 2017 -0500
+++ b/hedgewars/uGearsHandlersMess.pas	Sun Jan 15 12:50:27 2017 -0500
@@ -2301,15 +2301,25 @@
 var
     HHGear: PGear;
 begin
-    HHGear := Gear^.Hedgehog^.Gear;
-    HHGear^.State := HHGear^.State or gstNoDamage;
-    DeleteCI(HHGear);
-
-    AmmoShove(Gear, Gear^.Boom, 115);
-
-    HHGear^.State := (HHGear^.State and (not gstNoDamage)) or gstMoving;
-    Gear^.Timer := 250;
-    Gear^.doStep := @doStepIdle
+    dec(Gear^.Timer);
+    if Gear^.Timer = 0 then
+        begin
+        inc(Gear^.Tag);
+        Gear^.Timer := 100
+        end;
+
+    if Gear^.Tag = 5 then
+        begin
+        HHGear := Gear^.Hedgehog^.Gear;
+        HHGear^.State := HHGear^.State or gstNoDamage;
+        DeleteCI(HHGear);
+
+        AmmoShove(Gear, Gear^.Boom, 115);
+
+        HHGear^.State := (HHGear^.State and (not gstNoDamage)) or gstMoving;
+        Gear^.Timer := 250;
+        Gear^.doStep := @doStepIdle
+        end
 end;
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/hedgewars/uGearsList.pas	Sun Jan 15 12:49:26 2017 -0500
+++ b/hedgewars/uGearsList.pas	Sun Jan 15 12:50:27 2017 -0500
@@ -508,7 +508,11 @@
                 gear^.Density:= _1_5;
                 gear^.RenderTimer:= true
                 end;
-      gtShover: gear^.Radius:= 20;
+      gtShover: begin
+                gear^.Radius:= 20;
+                gear^.Tag:= 0;
+                gear^.Timer:= 100;
+                end;
        gtFlame: begin
                 gear^.Tag:= GetRandom(32);
                 gear^.Radius:= 1;
--- a/hedgewars/uGearsRender.pas	Sun Jan 15 12:49:26 2017 -0500
+++ b/hedgewars/uGearsRender.pas	Sun Jan 15 12:50:27 2017 -0500
@@ -536,7 +536,6 @@
                             end;
                     defaultPos:= false
                     end;
-                gtShover: DrawSpriteRotated(sprHandBaseball, hx, hy, sign, aangle + 180);
                 gtFirePunch:
                     begin
                     DrawHedgehog(sx, sy,
@@ -633,13 +632,18 @@
             case CurAmmoGear^.Kind of
                 gtShotgunShot,
                 gtDEagleShot,
-                gtSniperRifleShot,
-                gtShover:
+                gtSniperRifleShot:
                     begin
                     DrawHedgehog(sx, sy, sign, 0, 4, 0);
                     defaultPos:= false;
                     HatVisible:= true
-                end
+                    end;
+                gtShover:
+                    begin
+                    DrawHedgehog(sx, sy, sign, 0, 5, 0);
+                    defaultPos:= false;
+                    HatVisible:= true
+                    end
             end
         end else
 
@@ -814,6 +818,11 @@
                             0,
                             sign,
                             0);
+                amBaseballBat: DrawHedgehog(sx, sy,
+                            sign,
+                            0,
+                            5,
+                            0);
             else
                 DrawHedgehog(sx, sy,
                     sign,
@@ -836,9 +845,9 @@
             end;
 
             case amt of
-                amBaseballBat: DrawSpriteRotated(sprHandBaseball,
-                        sx - 4 * sign,
-                        sy + 9, sign, aangle);
+                amBaseballBat: DrawSpritePivotedF(sprHandBaseball,
+                        sx + 9 * sign,
+                        sy - 6, 0, sign, -8, 9, aangle);
             end;
 
             defaultPos:= false
@@ -1019,6 +1028,7 @@
             end; *)
         if CurAmmoGear <> nil then
             begin
+            aangle:= Gear^.Angle * 180 / cMaxAngle - 90;
             case CurAmmoGear^.Kind of
                 gtJetpack: begin
                         DrawSprite(sprJetpack, sx-32, sy-32, 0);
@@ -1035,6 +1045,7 @@
                             DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex);
                         DrawAltWeapon(Gear, sx, sy)
                         end;
+                gtShover: DrawSpritePivotedF(sprHandBaseball, sx + 9 * sign, sy - 6, CurAmmoGear^.Tag, sign, -8, 9, aangle);
                 end;
             end
         end;
--- a/hedgewars/uRender.pas	Sun Jan 15 12:49:26 2017 -0500
+++ b/hedgewars/uRender.pas	Sun Jan 15 12:50:27 2017 -0500
@@ -34,6 +34,7 @@
 procedure DrawSpriteClipped     (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
 procedure DrawSpriteRotated     (Sprite: TSprite; X, Y, Dir: LongInt; Angle: real);
 procedure DrawSpriteRotatedF    (Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real);
+procedure DrawSpritePivotedF(Sprite: TSprite; X, Y, Frame, Dir, PivotX, PivotY: LongInt; Angle: real);
 
 procedure DrawTexture           (X, Y: LongInt; Texture: PTexture); inline;
 procedure DrawTexture           (X, Y: LongInt; Texture: PTexture; Scale: GLfloat);
@@ -73,6 +74,7 @@
 procedure FinishRender();
 
 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline;
+function isCircleOffscreen(X, Y, RadiusSquared: LongInt): boolean; inline;
 
 // 0 => not offscreen, <0 => left/top of screen >0 => right/below of screen
 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline;
@@ -147,6 +149,20 @@
     isAreaOffscreen:= (isDxAreaOffscreen(X, Width) <> 0) or (isDyAreaOffscreen(Y, Height) <> 0);
 end;
 
+function isCircleOffscreen(X, Y, RadiusSquared: LongInt): boolean; inline;
+var dRightX, dBottomY, dLeftX, dTopY: LongInt;
+begin
+    dRightX:= (X - ViewRightX);
+    dBottomY:= (Y - ViewBottomY);
+    dLeftX:= (ViewLeftX - X);
+    dTopY:= (ViewTopY - Y);
+    isCircleOffscreen:= 
+        ((dRightX > 0) and (sqr(dRightX) > RadiusSquared)) or
+        ((dBottomY > 0) and (sqr(dBottomY) > RadiusSquared)) or
+        ((dLeftX > 0) and (sqr(dLeftX) > RadiusSquared)) or
+        ((dTopY > 0) and (sqr(dTopY) > RadiusSquared))
+end;
+
 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline;
 begin
     if X > ViewRightX then exit(1);
@@ -1131,11 +1147,8 @@
 
 if Angle <> 0  then
     begin
-    // sized doubled because the sprite might occupy up to 1.4 * of it's
-    // original size in each dimension, because it is rotated
-    if isDxAreaOffscreen(X - SpritesData[Sprite].Width, 2 * SpritesData[Sprite].Width) <> 0 then
-        exit;
-    if isDYAreaOffscreen(Y - SpritesData[Sprite].Height, 2 * SpritesData[Sprite].Height) <> 0 then
+    // Check the bounding circle 
+    if isCircleOffscreen(X, Y, sqr(SpritesData[Sprite].Width) + sqr(SpritesData[Sprite].Height)) then
         exit;
     end
 else
@@ -1164,6 +1177,43 @@
 
 end;
 
+procedure DrawSpritePivotedF(Sprite: TSprite; X, Y, Frame, Dir, PivotX, PivotY: LongInt; Angle: real);
+begin
+if Angle <> 0  then
+    begin
+    // Check the bounding circle 
+    // Assuming the pivot point is inside the sprite's rectangle, the farthest possible point is 3/2 of its diagonal away from the center
+    if isCircleOffscreen(X, Y, 9 * (sqr(SpritesData[Sprite].Width) + sqr(SpritesData[Sprite].Height)) div 4) then
+        exit;
+    end
+else
+    begin
+    if isDxAreaOffscreen(X - SpritesData[Sprite].Width div 2, SpritesData[Sprite].Width) <> 0 then
+        exit;
+    if isDYAreaOffscreen(Y - SpritesData[Sprite].Height div 2 , SpritesData[Sprite].Height) <> 0 then
+        exit;
+    end;
+
+openglPushMatrix;
+openglTranslatef(X, Y, 0);
+
+// mirror
+if Dir < 0 then
+    openglScalef(-1.0, 1.0, 1.0);
+
+// apply rotation around the pivot after (conditional) mirroring
+if Angle <> 0  then
+    begin
+    openglTranslatef(PivotX, PivotY, 0);
+    openglRotatef(Angle, 0, 0, 1);
+    openglTranslatef(-PivotX, -PivotY, 0);
+    end;
+
+DrawSprite(Sprite, -SpritesData[Sprite].Width div 2, -SpritesData[Sprite].Height div 2, Frame);
+
+openglPopMatrix;
+end;
+
 procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real);
 begin
 
--- a/hedgewars/uVariables.pas	Sun Jan 15 12:49:26 2017 -0500
+++ b/hedgewars/uVariables.pas	Sun Jan 15 12:50:27 2017 -0500
@@ -473,7 +473,7 @@
             (FileName:'amAirAttack'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
             Width:  32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprHandAirAttack
             (FileName: 'amBaseball'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
-            Width:  32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprHandBaseball
+            Width:  64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprHandBaseball
             (FileName:     'Hammer'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
             Width:  32; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprPHammer
             (FileName: 'amBTorch_i'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;