# HG changeset patch # User sheepluva # Date 1273183376 0 # Node ID dee31c5149e02a2f3ad8ebc50a4f8a66b9587913 # Parent a98984e4f458b708c1832c2ebd86e543dd831e23 * gtHealthTag, gtSmokeTrace, gtEvilTrace, gtExplosion and gtBigExplosion are visual gears now (vgt*) * moved virtual gear steps into new file diff -r a98984e4f458 -r dee31c5149e0 hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Thu May 06 20:59:15 2010 +0000 +++ b/hedgewars/GSHandlers.inc Thu May 06 22:02:56 2010 +0000 @@ -343,7 +343,7 @@ if (GameTicks and $3F) = 0 then if (Gear^.State and gstCollision) = 0 then - AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtEvilTrace, 0, _0, _0, 0); + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace); end; end; //////////////////////////////////////////////////////////////////////////////// @@ -400,7 +400,7 @@ CalcRotationDirAngle(Gear) else if (GameTicks and $1F) = 0 then - AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0) + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) end; //////////////////////////////////////////////////////////////////////////////// @@ -416,51 +416,7 @@ exit end; if (GameTicks and $3F) = 0 then - AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0) -end; - -//////////////////////////////////////////////////////////////////////////////// -procedure doStepHealthTagWork(Gear: PGear); -begin -if Gear^.Kind = gtHealthTag then - AllInactive:= false; - -dec(Gear^.Timer); -Gear^.Y:= Gear^.Y + Gear^.dY; - -if Gear^.Timer = 0 then - begin - if (Gear^.Kind = gtHealthTag) and (PHedgehog(Gear^.Hedgehog)^.Gear <> nil) then - PHedgehog(Gear^.Hedgehog)^.Gear^.Active:= true; // to let current hh die - DeleteGear(Gear) - end -end; - -procedure doStepHealthTagWorkUnderWater(Gear: PGear); -begin -AllInactive:= false; - -Gear^.Y:= Gear^.Y - _0_08; - -if hwRound(Gear^.Y) < cWaterLine + 10 then - DeleteGear(Gear) -end; - -procedure doStepHealthTag(Gear: PGear); -var s: shortstring; -begin -AllInactive:= false; -Gear^.dY:= -_0_08; - -str(Gear^.State, s); -Gear^.Tex:= RenderStringTex(s, PHedgehog(Gear^.Hedgehog)^.Team^.Clan^.Color, fnt16); - -if hwRound(Gear^.Y) < cWaterLine then - Gear^.doStep:= @doStepHealthTagWork -else - Gear^.doStep:= @doStepHealthTagWorkUnderWater; - -Gear^.Y:= Gear^.Y - int2hwFloat(Gear^.Tex^.h) + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) end; //////////////////////////////////////////////////////////////////////////////// @@ -1292,41 +1248,6 @@ end; //////////////////////////////////////////////////////////////////////////////// -procedure doStepSmokeTrace(Gear: PGear); -begin -inc(Gear^.Timer); -if Gear^.Timer > 64 then - begin - Gear^.Timer:= 0; - dec(Gear^.State) - end; -Gear^.dX:= Gear^.dX + cWindSpeed; -Gear^.X:= Gear^.X + Gear^.dX; -if Gear^.State = 0 then DeleteGear(Gear) -end; - -//////////////////////////////////////////////////////////////////////////////// -procedure doStepExplosionWork(Gear: PGear); -begin -inc(Gear^.Timer); -if Gear^.Timer > 75 then - begin - inc(Gear^.State); - Gear^.Timer:= 0; - if Gear^.State > 5 then DeleteGear(Gear) - end; -end; - -procedure doStepExplosion(Gear: PGear); -var i: LongWord; -begin -for i:= 0 to 31 do AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFire); -for i:= 0 to 8 do AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtExplPart); -for i:= 0 to 8 do AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtExplPart2); -Gear^.doStep:= @doStepExplosionWork -end; - -//////////////////////////////////////////////////////////////////////////////// procedure doStepMine(Gear: PGear); begin if (Gear^.State and gstMoving) <> 0 then @@ -1862,7 +1783,7 @@ end; if (GameTicks and $3F) = 0 then - AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0); + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); if (hwRound(Gear^.X) > (LAND_WIDTH+1024)) or (hwRound(Gear^.X) < -1024) then DeleteGear(Gear) end; @@ -1905,7 +1826,7 @@ exit end; if (GameTicks and $3F) = 0 then - AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0) + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) end; //////////////////////////////////////////////////////////////////////////////// @@ -2103,7 +2024,7 @@ end; if (GameTicks and $3F) = 0 then - AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0) + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) end; //////////////////////////////////////////////////////////////////////////////// @@ -2492,7 +2413,7 @@ doStepFallingGear(Gear); if (GameTicks and $3F) = 0 then - AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0); + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); if ((Gear^.State and gstCollision) <> 0) then begin //hit Gear^.dX:= oldDx; @@ -2616,9 +2537,9 @@ begin if (GameTicks and $FF) = 0 then if Gear^.Timer < 3500 then - AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtEvilTrace, 0, _0, _0, 0) + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace) else - AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0); + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); if ((HHGear^.Message and gm_Attack) <> 0) and (Gear^.Health <> 0) then begin @@ -2643,7 +2564,7 @@ else begin if (GameTicks and $FF) = 0 then - AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0); + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); // pickup targets t:= CheckGearNear(Gear, gtTarget, 36, 36); @@ -2985,32 +2906,6 @@ end; //////////////////////////////////////////////////////////////////////////////// -procedure doStepBigExplosionWork(Gear: PGear); -var maxMovement: LongInt; -begin -inc(Gear^.Timer); -if (Gear^.Timer and 5) = 0 then - begin - maxMovement := max(1, 13 - ((Gear^.Timer * 15) div 250)); - ShakeCamera(maxMovement); - end; -if Gear^.Timer > 250 then DeleteGear(Gear); -end; - -procedure doStepBigExplosion(Gear: PGear); -var i: LongWord; -gX,gY: LongInt; -begin -gX:= hwRound(Gear^.X); -gY:= hwRound(Gear^.Y); -AddVisualGear(gX, gY, vgtSmokeRing); -for i:= 0 to 46 do AddVisualGear(gX, gY, vgtFire); -for i:= 0 to 15 do AddVisualGear(gX, gY, vgtExplPart); -for i:= 0 to 15 do AddVisualGear(gX, gY, vgtExplPart2); -Gear^.doStep:= @doStepBigExplosionWork -end; - -//////////////////////////////////////////////////////////////////////////////// procedure doStepEggWork(Gear: PGear); var vg: PVisualGear; i: LongInt; @@ -3106,8 +3001,7 @@ // don't port portals or other gear that wouldn't make sense if (iterator^.Kind = gtPortal) - or (iterator^.Kind = gtRope) - or (iterator^.Kind = gtHealthTag) then + or (iterator^.Kind = gtRope) then continue; // don't port hogs on rope @@ -3461,7 +3355,7 @@ end; if getRandom(100) = 0 then - AddGear(x, y, gtSmokeTrace, 0, _0, _0, 0); + AddVisualGear(x, y, vgtSmokeTrace); end // if underwater get additional damage diff -r a98984e4f458 -r dee31c5149e0 hedgewars/GearDrawing.inc --- a/hedgewars/GearDrawing.inc Thu May 06 20:59:15 2010 +0000 +++ b/hedgewars/GearDrawing.inc Thu May 06 22:02:56 2010 +0000 @@ -614,16 +614,12 @@ gtAmmo_Grenade: DrawRotated(sprGrenade, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); - gtHealthTag: if Gear^.Tex <> nil then DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex); - gtGrave: DrawTextureF(PHedgehog(Gear^.Hedgehog)^.Team^.GraveTex, 1, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, (GameTicks shr 7+Gear^.uid) and 7, 1, 32, 32); gtBee: DrawRotatedF(sprBee, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, (GameTicks shr 5) mod 2, 0, DxDy2Angle(Gear^.dY, Gear^.dX)); gtPickHammer: DrawSprite(sprPHammer, hwRound(Gear^.X) - 16 + WorldDx, hwRound(Gear^.Y) - 50 + LongInt(((GameTicks shr 5) and 1) * 2) + WorldDy, 0); gtRope: DrawRope(Gear); - gtSmokeTrace: if Gear^.State < 8 then DrawSprite(sprSmokeTrace, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.State); - gtExplosion: DrawSprite(sprExplosion50, hwRound(Gear^.X) - 32 + WorldDx, hwRound(Gear^.Y) - 32 + WorldDy, Gear^.State); gtMine: if (((Gear^.State and gstAttacking) = 0)or((Gear^.Timer and $3FF) < 420)) and (Gear^.Health <> 0) then DrawRotated(sprMineOff, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, Gear^.DirAngle) else if Gear^.Health <> 0 then DrawRotated(sprMineOn, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, Gear^.DirAngle) @@ -691,7 +687,6 @@ gtWatermelon: DrawRotatedf(sprWatermelon, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, 0, Gear^.DirAngle); gtMelonPiece: DrawRotatedf(sprWatermelon, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 1, 0, Gear^.DirAngle); gtHellishBomb: DrawRotated(sprHellishBomb, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, Gear^.DirAngle); - gtEvilTrace: if Gear^.State < 8 then DrawSprite(sprEvilTrace, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.State); gtBirdy: begin if Gear^.State and gstAnimation = gstAnimation then begin @@ -721,11 +716,6 @@ else DrawTextureF(SpritesData[sprBirdy].Texture, 1, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, ((Gear^.Pos shr 6) or (RealTicks shr 8)) mod 2, Gear^.Tag, 75, 75); end; - gtBigExplosion: begin - Tint($FF, $FF, $FF, floor($FF * (1 - power(Gear^.Timer / 250, 4)))); - DrawRotatedTextureF(SpritesData[sprBigExplosion].Texture, 0.85 * (-power(2, -10 * Int(Gear^.Timer)/250) + 1) + 0.4, 0, 0, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, 1, 385, 385, Gear^.Angle); - Tint($FF, $FF, $FF, $FF); - end; gtEgg: DrawRotatedTextureF(SpritesData[sprEgg].Texture, 1, 0, 0, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, 1, 16, 16, Gear^.DirAngle); gtPiano: begin if (Gear^.State and gstDrowning) = 0 then diff -r a98984e4f458 -r dee31c5149e0 hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Thu May 06 20:59:15 2010 +0000 +++ b/hedgewars/uConsts.pas Thu May 06 22:02:56 2010 +0000 @@ -76,24 +76,24 @@ ); // Gears that interact with other Gears and/or Land - TGearType = (gtAmmo_Bomb, gtHedgehog, gtAmmo_Grenade, gtHealthTag, // 3 - gtGrave, gtBee, gtShotgunShot, gtPickHammer, gtRope, // 8 - gtSmokeTrace, gtExplosion, gtMine, gtCase, gtDEagleShot, gtDynamite, // 14 - gtClusterBomb, gtCluster, gtShover, gtFlame, // 18 - gtFirePunch, gtATStartGame, gtATSmoothWindCh, gtATFinishGame, // 24 - gtParachute, gtAirAttack, gtAirBomb, gtBlowTorch, gtGirder, // 27 - gtTeleport, gtSwitcher, gtTarget, gtMortar, // 31 - gtWhip, gtKamikaze, gtCake, gtSeduction, gtWatermelon, gtMelonPiece, // 37 - gtHellishBomb, gtEvilTrace, gtWaterUp, gtDrill, gtBallGun, gtBall, gtRCPlane, // 44 - gtSniperRifleShot, gtJetpack, gtMolotov, gtExplosives, gtBirdy, // 49 - gtBigExplosion, gtEgg, gtPortal, gtPiano, gtGasBomb, gtSineGunShot); // 55 + TGearType = (gtAmmo_Bomb, gtHedgehog, gtAmmo_Grenade, gtGrave, gtBee, // 4 + gtShotgunShot, gtPickHammer, gtRope, gtMine, gtCase, // 9 + gtDEagleShot, gtDynamite, gtClusterBomb, gtCluster, gtShover, // 14 + gtFlame, gtFirePunch, gtATStartGame, gtATSmoothWindCh, // 18 + gtATFinishGame, gtParachute, gtAirAttack, gtAirBomb, gtBlowTorch, // 23 + gtGirder, gtTeleport, gtSwitcher, gtTarget, gtMortar, // 28 + gtWhip, gtKamikaze, gtCake, gtSeduction, gtWatermelon, gtMelonPiece, // 34 + gtHellishBomb, gtWaterUp, gtDrill, gtBallGun, gtBall, gtRCPlane, // 40 + gtSniperRifleShot, gtJetpack, gtMolotov, gtExplosives, gtBirdy, // 45 + gtEgg, gtPortal, gtPiano, gtGasBomb, gtSineGunShot); // 50 // Gears that are _only_ of visual nature (e.g. background stuff, visual effects, speechbubbles, etc.) TVisualGearType = (vgtFlake, vgtCloud, vgtExplPart, vgtExplPart2, vgtFire, vgtSmallDamageTag, vgtTeamHealthSorter, vgtSpeechBubble, vgtBubble, vgtSteam, vgtAmmo, vgtSmoke, vgtSmokeWhite, vgtHealth, vgtShell, vgtDust, vgtSplash, vgtDroplet, vgtSmokeRing, vgtBeeTrace, vgtEgg, - vgtFeather); + vgtFeather, vgtHealthTag, vgtSmokeTrace, vgtEvilTrace, vgtExplosion, + vgtBigExplosion); TGearsType = set of TGearType; diff -r a98984e4f458 -r dee31c5149e0 hedgewars/uGears.pas --- a/hedgewars/uGears.pas Thu May 06 20:59:15 2010 +0000 +++ b/hedgewars/uGears.pas Thu May 06 22:02:56 2010 +0000 @@ -134,14 +134,11 @@ @doStepBomb, @doStepHedgehog, @doStepGrenade, - @doStepHealthTag, @doStepGrave, @doStepBee, @doStepShotgunShot, @doStepPickHammer, @doStepRope, - @doStepSmokeTrace, - @doStepExplosion, @doStepMine, @doStepCase, @doStepDEagleShot, @@ -170,7 +167,6 @@ @doStepWatermelon, @doStepCluster, @doStepBomb, - @doStepSmokeTrace, @doStepWaterUp, @doStepDrill, @doStepBallgun, @@ -181,7 +177,6 @@ @doStepMolotov, @doStepCase, @doStepBirdy, - @doStepBigExplosion, @doStepEggWork, @doStepPortalShot, @doStepPiano, @@ -291,10 +286,6 @@ gtAmmo_Grenade: begin // bazooka gear^.Radius:= 4; end; - gtHealthTag: begin - gear^.Timer:= 1500; - gear^.Z:= 2002; - end; gtGrave: begin gear^.ImpactSound:= sndGraveImpact; gear^.nImpactSounds:= 1; @@ -316,13 +307,6 @@ gear^.Radius:= 10; gear^.Timer:= 4000 end; - gtSmokeTrace, - gtEvilTrace: begin - gear^.X:= gear^.X - _16; - gear^.Y:= gear^.Y - _16; - gear^.State:= 8; - gear^.Z:= cSmokeZ - end; gtRope: begin gear^.Radius:= 3; gear^.Friction:= _450; @@ -464,9 +448,6 @@ gear^.Health := 2000; gear^.FlightTime := 2; end; -gtBigExplosion: begin - gear^.Angle:= random(360); - end; gtEgg: begin gear^.Radius:= 4; gear^.Elasticity:= _0_6; @@ -533,7 +514,7 @@ t:= max(Gear^.Damage, Gear^.Health); Gear^.Damage:= t; if (cWaterOpacity < $FF) and (hwRound(Gear^.Y) < cWaterLine + 256) then - AddGear(hwRound(Gear^.X), min(hwRound(Gear^.Y),cWaterLine+cVisibleWater+32), gtHealthTag, t, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog; + AddVisualGear(hwRound(Gear^.X), min(hwRound(Gear^.Y),cWaterLine+cVisibleWater+32), vgtHealthTag, t)^.Hedgehog:= Gear^.Hedgehog; uStats.HedgehogDamaged(Gear) end; @@ -594,8 +575,8 @@ not SuddenDeathDmg then Gear^.State:= Gear^.State or gstLoser; - AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) - cHHRadius - 12, - gtHealthTag, dmg, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog; + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y) - cHHRadius - 12, + vgtHealthTag, dmg)^.Hedgehog:= Gear^.Hedgehog; RenderHealth(PHedgehog(Gear^.Hedgehog)^); RecountTeamHealth(PHedgehog(Gear^.Hedgehog)^.Team); @@ -915,9 +896,9 @@ not CurrentHedgehog^.Gear^.Invulnerable then begin // this cannot just use Damage or it interrupts shotgun and gets you called stupid inc(CurrentHedgehog^.Gear^.Karma, tmpDmg); - AddGear(hwRound(CurrentHedgehog^.Gear^.X), + AddVisualGear(hwRound(CurrentHedgehog^.Gear^.X), hwRound(CurrentHedgehog^.Gear^.Y), - gtHealthTag, tmpDmg, _0, _0, 0)^.Hedgehog:= CurrentHedgehog; + vgtHealthTag, tmpDmg)^.Hedgehog:= CurrentHedgehog; end; end; end; @@ -1169,8 +1150,8 @@ if ((Mask and EXPLNoGfx) = 0) then begin - if Radius > 50 then AddGear(X, Y, gtBigExplosion, 0, _0, _0, 0) - else if Radius > 10 then AddGear(X, Y, gtExplosion, 0, _0, _0, 0); + if Radius > 50 then AddVisualGear(X, Y, vgtBigExplosion) + else if Radius > 10 then AddVIsualGear(X, Y, vgtExplosion); end; if (Mask and EXPLAutoSound) <> 0 then PlaySound(sndExplosion); diff -r a98984e4f458 -r dee31c5149e0 hedgewars/uVisualGears.pas --- a/hedgewars/uVisualGears.pas Thu May 06 20:59:15 2010 +0000 +++ b/hedgewars/uVisualGears.pas Thu May 06 22:02:56 2010 +0000 @@ -35,6 +35,7 @@ tdX: hwFloat; tdY: hwFloat; mdY: QWord; + State : Longword; Timer: Longword; Angle, dAngle: real; Kind: TVisualGearType; @@ -48,7 +49,7 @@ procedure initModule; procedure freeModule; -function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear; +function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord = 0): PVisualGear; procedure ProcessVisualGears(Steps: Longword); procedure KickFlakes(Radius, X, Y: LongInt); procedure DrawVisualGears(Layer: LongWord); @@ -65,6 +66,8 @@ uses uWorld, uMisc, uStore, uTeams, uSound; const cExplFrameTicks = 110; +{$INCLUDE "VGSHandlers.inc"} + procedure AddDamageTag(X, Y, Damage, Color: LongWord); var s: shortstring; Gear: PVisualGear; @@ -83,398 +86,6 @@ // ================================================================== -procedure doStepFlake(Gear: PVisualGear; Steps: Longword); -var sign: hwFloat; -begin -sign:= _1; -with Gear^ do - begin - inc(FrameTicks, Steps); - if FrameTicks > vobFrameTicks then - begin - dec(FrameTicks, vobFrameTicks); - inc(Frame); - if Frame = vobFramesCount then Frame:= 0 - end; - X:= X + (cWindSpeed * 200 + dX + tdX) * Steps; - Y:= Y + (dY + tdY + cGravity * vobFallSpeed) * Steps; - Angle:= Angle + dAngle * Steps; - - if (hwRound(X) >= -cScreenWidth - 64) and - (hwRound(X) <= cScreenWidth + LAND_WIDTH) and - (hwRound(Y) <= (LAND_HEIGHT + 75)) and - (Timer > 0) and (Timer-Steps > 0) then - begin - sign.isNegative:=tdX.isNegative; - tdX:= tdX - _0_005*Steps*sign; - if (sign.isNegative and (tdX > _0)) or (not sign.isNegative and (tdX < _0)) then tdX:= _0; - sign.isNegative:=tdY.isNegative; - tdY:= tdY - _0_005*Steps*sign; - if (sign.isNegative and (tdY > _0)) or (not sign.isNegative and (tdY < _0)) then tdY:= _0; - dec(Timer, Steps) - end - else - begin - if hwRound(X) < -cScreenWidth - 64 then X:= int2hwFloat(cScreenWidth + LAND_WIDTH) else - if hwRound(X) > cScreenWidth + LAND_WIDTH then X:= int2hwFloat(-cScreenWidth - 64); - // if hwRound(Y) < (LAND_HEIGHT - 1024 - 75) then Y:= Y + int2hwFloat(25); // For if flag is set for flakes rising upwards? - if hwRound(Y) > (LAND_HEIGHT + 75) then Y:= Y - int2hwFloat(1024 + 150); // TODO - configure in theme (jellies for example could use limited range) - Timer:= 0; - tdX:= _0; - tdY:= _0 - end; - end; - -end; - -procedure doStepBeeTrace(Gear: PVisualGear; Steps: Longword); -begin -if Gear^.FrameTicks > Steps then - dec(Gear^.FrameTicks, Steps) -else - DeleteVisualGear(Gear); -end; - -procedure doStepCloud(Gear: PVisualGear; Steps: Longword); -var i: Longword; -begin -Gear^.X:= Gear^.X + (cWindSpeed * 200 + Gear^.dX) * Steps; - -for i:= 0 to Steps - 1 do - begin - if hwRound(Gear^.Y) > LAND_HEIGHT-1184 then // TODO - configure in theme - Gear^.dY:= Gear^.dY - _1div50000 - else - Gear^.dY:= Gear^.dY + _1div50000; - - Gear^.Y:= Gear^.Y + Gear^.dY - end; - -if hwRound(Gear^.X) < -cScreenWidth - 256 then Gear^.X:= int2hwFloat(cScreenWidth + LAND_WIDTH) else -if hwRound(Gear^.X) > cScreenWidth + LAND_WIDTH then Gear^.X:= int2hwFloat(-cScreenWidth - 256) -end; - -procedure doStepExpl(Gear: PVisualGear; Steps: Longword); -begin -Gear^.X:= Gear^.X + Gear^.dX * Steps; - -Gear^.Y:= Gear^.Y + Gear^.dY * Steps; -//Gear^.dY:= Gear^.dY + cGravity; - -if Gear^.FrameTicks <= Steps then - if Gear^.Frame = 0 then DeleteVisualGear(Gear) - else - begin - dec(Gear^.Frame); - Gear^.FrameTicks:= cExplFrameTicks - end - else dec(Gear^.FrameTicks, Steps) -end; - -procedure doStepEgg(Gear: PVisualGear; Steps: Longword); -begin -Gear^.X:= Gear^.X + Gear^.dX * Steps; - -Gear^.Y:= Gear^.Y + Gear^.dY * Steps; -Gear^.dY:= Gear^.dY + cGravity * Steps; - -Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle; - -if Gear^.FrameTicks <= Steps then - DeleteVisualGear(Gear) -else - dec(Gear^.FrameTicks, Steps) -end; - -procedure doStepFire(Gear: PVisualGear; Steps: Longword); -begin -Gear^.X:= Gear^.X + Gear^.dX * Steps; - -Gear^.Y:= Gear^.Y + Gear^.dY * Steps;// + cGravity * (Steps * Steps); -Gear^.dY:= Gear^.dY + cGravity * Steps; - -if Gear^.FrameTicks <= Steps then - DeleteVisualGear(Gear) -else - dec(Gear^.FrameTicks, Steps) -end; - -procedure doStepShell(Gear: PVisualGear; Steps: Longword); -begin -Gear^.X:= Gear^.X + Gear^.dX * Steps; - -Gear^.Y:= Gear^.Y + Gear^.dY * Steps; -Gear^.dY:= Gear^.dY + cGravity * Steps; - -Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle; - -if Gear^.FrameTicks <= Steps then - DeleteVisualGear(Gear) -else - dec(Gear^.FrameTicks, Steps) -end; - -procedure doStepSmallDamage(Gear: PVisualGear; Steps: Longword); -begin -Gear^.Y:= Gear^.Y - _0_02 * Steps; - -if Gear^.FrameTicks <= Steps then - DeleteVisualGear(Gear) -else - dec(Gear^.FrameTicks, Steps) -end; - -procedure doStepBubble(Gear: PVisualGear; Steps: Longword); -begin - Gear^.X:= Gear^.X + (cWindSpeed * 100 + Gear^.dX) * Steps; - Gear^.Y:= Gear^.Y - cDrownSpeed * Steps; - - if (Gear^.FrameTicks <= Steps) or (hwRound(Gear^.Y) < cWaterLine) then - DeleteVisualGear(Gear) - else - dec(Gear^.FrameTicks, Steps) -end; - -procedure doStepHealth(Gear: PVisualGear; Steps: Longword); -begin -Gear^.X:= Gear^.X + Gear^.dX * Steps; -Gear^.Y:= Gear^.Y - Gear^.dY * Steps; - -if Gear^.FrameTicks <= Steps then - DeleteVisualGear(Gear) -else - dec(Gear^.FrameTicks, Steps); -end; - -procedure doStepSteam(Gear: PVisualGear; Steps: Longword); -begin - Gear^.X:= Gear^.X + (cWindSpeed * 100 + Gear^.dX) * Steps; - Gear^.Y:= Gear^.Y - cDrownSpeed * Steps; - - if Gear^.FrameTicks <= Steps then - if Gear^.Frame = 0 then DeleteVisualGear(Gear) - else - begin - if Random(2) = 0 then dec(Gear^.Frame); - Gear^.FrameTicks:= cExplFrameTicks - end - else dec(Gear^.FrameTicks, Steps) -end; - -procedure doStepAmmo(Gear: PVisualGear; Steps: Longword); -begin - Gear^.Y:= Gear^.Y - cDrownSpeed * Steps; - - Gear^.scale:= Gear^.scale + 0.0025 * Steps; - Gear^.alpha:= Gear^.alpha - 0.0015 * Steps; - - if Gear^.alpha < 0 then DeleteVisualGear(Gear) -end; - -procedure doStepSmoke(Gear: PVisualGear; Steps: Longword); -begin - Gear^.X:= Gear^.X + (cWindSpeed + Gear^.dX) * Steps; - Gear^.Y:= Gear^.Y - (cDrownSpeed + Gear^.dY) * Steps; - - Gear^.dX := Gear^.dX + (cWindSpeed * _0_3 * Steps); - //Gear^.dY := Gear^.dY - (cDrownSpeed * _0_995); - - if Gear^.FrameTicks <= Steps then - if Gear^.Frame = 0 then DeleteVisualGear(Gear) - else - begin - if Random(2) = 0 then dec(Gear^.Frame); - Gear^.FrameTicks:= cExplFrameTicks - end - else dec(Gear^.FrameTicks, Steps) -end; - -procedure doStepDust(Gear: PVisualGear; Steps: Longword); -begin - Gear^.X:= Gear^.X + (cWindSpeed + (cWindSpeed * _0_03 * Steps) + Gear^.dX) * Steps; - Gear^.Y:= Gear^.Y - (Gear^.dY) * Steps; - - Gear^.dX := Gear^.dX - (Gear^.dX * _0_005 * Steps); - Gear^.dY := Gear^.dY - (cDrownSpeed * _0_001 * Steps); - - if Gear^.FrameTicks <= Steps then - if Gear^.Frame = 0 then DeleteVisualGear(Gear) - else - begin - dec(Gear^.Frame); - Gear^.FrameTicks:= cExplFrameTicks - end - else dec(Gear^.FrameTicks, Steps) -end; - -procedure doStepSplash(Gear: PVisualGear; Steps: Longword); -begin - if Gear^.FrameTicks <= Steps then - DeleteVisualGear(Gear) - else - dec(Gear^.FrameTicks, Steps); -end; - -procedure doStepDroplet(Gear: PVisualGear; Steps: Longword); -begin - Gear^.X:= Gear^.X + Gear^.dX * Steps; - - Gear^.Y:= Gear^.Y + Gear^.dY * Steps; - Gear^.dY:= Gear^.dY + cGravity * Steps; - - if hwRound(Gear^.Y) > cWaterLine then begin - DeleteVisualGear(Gear); - PlaySound(TSound(ord(sndDroplet1) + Random(3))); - end; -end; - -procedure doStepSmokeRing(Gear: PVisualGear; Steps: Longword); -begin -inc(Gear^.Timer, Steps); -if Gear^.Timer >= Gear^.FrameTicks then DeleteVisualGear(Gear) -else - begin - Gear^.scale := 1.25 * (-power(2, -10 * Int(Gear^.Timer)/Gear^.FrameTicks) + 1) + 0.4; - Gear^.alpha := 1 - power(Gear^.Timer / 350, 4); - if Gear^.alpha < 0 then Gear^.alpha:= 0; - end; -end; - -procedure doStepFeather(Gear: PVisualGear; Steps: Longword); -begin -Gear^.X:= Gear^.X + Gear^.dX * Steps; - -Gear^.Y:= Gear^.Y + Gear^.dY * Steps; -Gear^.dY:= Gear^.dY + cGravity * Steps; - -Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle; - -if Gear^.FrameTicks <= Steps then - DeleteVisualGear(Gear) -else - dec(Gear^.FrameTicks, Steps) -end; -//////////////////////////////////////////////////////////////////////////////// -const cSorterWorkTime = 640; -var thexchar: array[0..cMaxTeams] of - record - dy, ny, dw: LongInt; - team: PTeam; - SortFactor: QWord; - end; - currsorter: PVisualGear = nil; - -procedure doStepTeamHealthSorterWork(Gear: PVisualGear; Steps: Longword); -var i, t: LongInt; -begin -for t:= 1 to Steps do - begin - dec(Gear^.Timer); - if (Gear^.Timer and 15) = 0 then - for i:= 0 to Pred(TeamsCount) do - with thexchar[i] do - begin - {$WARNINGS OFF} - team^.DrawHealthY:= ny + dy * LongInt(Gear^.Timer) div 640; - team^.TeamHealthBarWidth:= team^.NewTeamHealthBarWidth + dw * LongInt(Gear^.Timer) div cSorterWorkTime; - {$WARNINGS ON} - end; - - if (Gear^.Timer = 0) or (currsorter <> Gear) then - begin - if currsorter = Gear then currsorter:= nil; - DeleteVisualGear(Gear); - exit - end - end -end; - -procedure doStepTeamHealthSorter(Gear: PVisualGear; Steps: Longword); -var i: Longword; - b: boolean; - t: LongInt; -begin -Steps:= Steps; // avoid compiler hint -for t:= 0 to Pred(TeamsCount) do - with thexchar[t] do - begin - dy:= TeamsArray[t]^.DrawHealthY; - dw:= TeamsArray[t]^.TeamHealthBarWidth - TeamsArray[t]^.NewTeamHealthBarWidth; - team:= TeamsArray[t]; - SortFactor:= TeamsArray[t]^.Clan^.ClanHealth; - SortFactor:= (SortFactor shl 3) + TeamsArray[t]^.Clan^.ClanIndex; - SortFactor:= (SortFactor shl 30) + TeamsArray[t]^.TeamHealth; - end; - -if TeamsCount > 1 then - repeat - b:= true; - for t:= 0 to TeamsCount - 2 do - if (thexchar[t].SortFactor > thexchar[Succ(t)].SortFactor) then - begin - thexchar[cMaxTeams]:= thexchar[t]; - thexchar[t]:= thexchar[Succ(t)]; - thexchar[Succ(t)]:= thexchar[cMaxTeams]; - b:= false - end - until b; - -t:= - 4; -for i:= 0 to Pred(TeamsCount) do - with thexchar[i] do - begin - dec(t, team^.HealthTex^.h + 2); - ny:= t; - dy:= dy - ny - end; - -Gear^.Timer:= cSorterWorkTime; -Gear^.doStep:= @doStepTeamHealthSorterWork; -currsorter:= Gear; -//doStepTeamHealthSorterWork(Gear, Steps) -end; - -procedure doStepSpeechBubbleWork(Gear: PVisualGear; Steps: Longword); -begin -if Gear^.Timer > Steps then dec(Gear^.Timer, Steps) else Gear^.Timer:= 0; - -if (PHedgehog(Gear^.Hedgehog)^.Gear <> nil) then - begin - Gear^.X:= PHedgehog(Gear^.Hedgehog)^.Gear^.X + int2hwFloat(Gear^.Tex^.w div 2 - Gear^.FrameTicks); - Gear^.Y:= PHedgehog(Gear^.Hedgehog)^.Gear^.Y - int2hwFloat(16 + Gear^.Tex^.h); - end; - -if Gear^.Timer = 0 then - begin - if PHedgehog(Gear^.Hedgehog)^.SpeechGear = Gear then - PHedgehog(Gear^.Hedgehog)^.SpeechGear:= nil; - DeleteVisualGear(Gear) - end; -end; - -procedure doStepSpeechBubble(Gear: PVisualGear; Steps: Longword); -begin -Steps:= Steps; // avoid compiler hint - -with PHedgehog(Gear^.Hedgehog)^ do - if SpeechGear <> nil then SpeechGear^.Timer:= 0; - -PHedgehog(Gear^.Hedgehog)^.SpeechGear:= Gear; - -Gear^.Timer:= max(Length(Gear^.Text) * 150, 3000); - -Gear^.Tex:= RenderSpeechBubbleTex(Gear^.Text, Gear^.FrameTicks, fnt16); - -case Gear^.FrameTicks of - 1: Gear^.FrameTicks:= SpritesData[sprSpeechTail].Width-28; - 2: Gear^.FrameTicks:= SpritesData[sprThoughtTail].Width-20; - 3: Gear^.FrameTicks:= SpritesData[sprShoutTail].Width-10; - end; - -Gear^.doStep:= @doStepSpeechBubbleWork; - -Gear^.Y:= Gear^.Y - int2hwFloat(Gear^.Tex^.h) -end; // ================================================================== const doStepHandlers: array[TVisualGearType] of TVGearStepProcedure = @@ -500,10 +111,15 @@ @doStepSmokeRing, @doStepBeeTrace, @doStepEgg, - @doStepFeather + @doStepFeather, + @doStepHealthTag, + @doStepSmokeTrace, + @doStepSmokeTrace, + @doStepExplosion, + @doStepBigExplosion ); -function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear; +function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord = 0): PVisualGear; var gear: PVisualGear; t: Longword; sp: hwFloat; @@ -530,6 +146,7 @@ gear^.Y:= int2hwFloat(Y); gear^.Kind := Kind; gear^.doStep:= doStepHandlers[Kind]; +gear^.State:= 0; with gear^ do case Kind of @@ -673,8 +290,24 @@ FrameTicks:= 650 + random(250); Frame:= 1 end; + vgtHealthTag: begin + gear^.Timer:= 1500; + //gear^.Z:= 2002; + end; + vgtSmokeTrace, + vgtEvilTrace: begin + gear^.X:= gear^.X - _16; + gear^.Y:= gear^.Y - _16; + gear^.State:= 8; + //gear^.Z:= cSmokeZ + end; +vgtBigExplosion: begin + gear^.Angle:= random(360); + end; end; +if State <> 0 then gear^.State:= State; + if VisualGearsList <> nil then begin VisualGearsList^.PrevGear:= gear; @@ -766,6 +399,16 @@ Tint($FF, $FF, $FF, $FF); end; end; + case Gear^.Kind of + vgtSmokeTrace: if Gear^.State < 8 then DrawSprite(sprSmokeTrace, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.State); + vgtEvilTrace: if Gear^.State < 8 then DrawSprite(sprEvilTrace, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.State); + vgtExplosion: DrawSprite(sprExplosion50, hwRound(Gear^.X) - 32 + WorldDx, hwRound(Gear^.Y) - 32 + WorldDy, Gear^.State); + vgtBigExplosion: begin + Tint($FF, $FF, $FF, floor($FF * (1 - power(Gear^.Timer / 250, 4)))); + DrawRotatedTextureF(SpritesData[sprBigExplosion].Texture, 0.85 * (-power(2, -10 * Int(Gear^.Timer)/250) + 1) + 0.4, 0, 0, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 0, 1, 385, 385, Gear^.Angle); + Tint($FF, $FF, $FF, $FF); + end; + end; Gear:= Gear^.NextGear end; 2: while Gear <> nil do @@ -824,6 +467,7 @@ case Gear^.Kind of vgtSmallDamageTag: DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex); vgtSpeechBubble: if Gear^.Tex <> nil then DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex); + vgtHealthTag: if Gear^.Tex <> nil then DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Tex); end; Gear:= Gear^.NextGear end