# HG changeset patch # User alfadur # Date 1484502627 18000 # Node ID 3374e0f67f397b7943903b899e89a3dd64f995cb # Parent 4f567f7a08e8d94c869ac064cfa96961b58f3f26 code changes to make the new bat animation work diff -r 4f567f7a08e8 -r 3374e0f67f39 hedgewars/uGearsHandlersMess.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; //////////////////////////////////////////////////////////////////////////////// diff -r 4f567f7a08e8 -r 3374e0f67f39 hedgewars/uGearsList.pas --- 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; diff -r 4f567f7a08e8 -r 3374e0f67f39 hedgewars/uGearsRender.pas --- 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; diff -r 4f567f7a08e8 -r 3374e0f67f39 hedgewars/uRender.pas --- 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 diff -r 4f567f7a08e8 -r 3374e0f67f39 hedgewars/uVariables.pas --- 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;