Initial pass at bounciness. To try it out, or lfBouncy on girder in uLandGraphics (search for the word graphically)
authornemo
Thu, 28 Nov 2013 21:13:49 -0500
changeset 9721 1833dadcebf0
parent 9720 453a1c29b7e4
child 9722 22dba2d8de93
Initial pass at bounciness. To try it out, or lfBouncy on girder in uLandGraphics (search for the word graphically)
hedgewars/uGearsHandlersMess.pas
hedgewars/uGearsList.pas
hedgewars/uLandObjects.pas
hedgewars/uVariables.pas
--- a/hedgewars/uGearsHandlersMess.pas	Thu Nov 28 00:41:35 2013 +0400
+++ b/hedgewars/uGearsHandlersMess.pas	Thu Nov 28 21:13:49 2013 -0500
@@ -282,7 +282,7 @@
     //tmp: QWord;
     tX, tdX, tdY: hwFloat;
     collV, collH: LongInt;
-    land: word;
+    land, xland: word;
 begin
     tX:= Gear^.X;
     if (Gear^.Kind <> gtGenericFaller) and WorldWrap(Gear) and (WorldEdge = weWrap) and (Gear^.AdvBounce <> 0) and
@@ -323,15 +323,20 @@
             begin
             collV := -1;
             if land and lfIce <> 0 then
-                Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1)
-            else
-                Gear^.dX := Gear^.dX * Gear^.Friction;
-
-            Gear^.dY := - Gear^.dY * Gear^.Elasticity;
-            Gear^.State := Gear^.State or gstCollision
+                 Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1)
+            else Gear^.dX := Gear^.dX * Gear^.Friction;
+            if land and lfBouncy = 0 then
+                 begin
+                 Gear^.dY := - Gear^.dY * Gear^.Elasticity;
+                 Gear^.State := Gear^.State or gstCollision
+                 end
+            else Gear^.dY := - Gear^.dY * cElastic
             end
-        else if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, 1) <> 0) then
-            collV := 1;
+        else if Gear^.AdvBounce = 1 then
+            begin
+            land:= TestCollisionYwithGear(Gear, 1);
+            if land <> 0 then collV := 1
+            end
         end
     else
         begin // Gear^.dY.isNegative is false
@@ -345,34 +350,62 @@
             else
                 Gear^.dX := Gear^.dX * Gear^.Friction;
 
-            Gear^.dY := - Gear^.dY * Gear^.Elasticity;
-            Gear^.State := Gear^.State or gstCollision
+            if land and lfBouncy = 0 then
+                 begin
+                 Gear^.dY := - Gear^.dY * Gear^.Elasticity;
+                 Gear^.State := Gear^.State or gstCollision
+                 end
+            else Gear^.dY := - Gear^.dY * cElastic
             end
         else
             begin
             isFalling := true;
-            if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, -1) <> 0) then
-                collV := -1
+            if Gear^.AdvBounce = 1 then
+                begin
+                land:= TestCollisionYwithGear(Gear, -1);
+                if land <> 0 then collV := -1
+                end
             end
         end;
 
 
-    if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then
+    xland:= TestCollisionXwithGear(Gear, hwSign(Gear^.dX));
+    if xland <> 0 then
         begin
         collH := hwSign(Gear^.dX);
-        Gear^.dX := - Gear^.dX * Gear^.Elasticity;
-        Gear^.dY :=   Gear^.dY * Gear^.Elasticity;
-        Gear^.State := Gear^.State or gstCollision
+        if xland and lfBouncy = 0 then
+            begin
+            Gear^.dX := - Gear^.dX * Gear^.Elasticity;
+            Gear^.dY :=   Gear^.dY * Gear^.Elasticity;
+            Gear^.State := Gear^.State or gstCollision
+            end
+        else
+            begin
+            Gear^.dX := - Gear^.dX * cElastic;
+            Gear^.dY :=   Gear^.dY * cElastic
+            end
         end
-    else if (Gear^.AdvBounce =1) and (TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)) <> 0) then
-        collH := -hwSign(Gear^.dX);
+    else if Gear^.AdvBounce = 1 then
+        begin
+        xland:= TestCollisionXwithGear(Gear, -hwSign(Gear^.dX));
+        if xland <> 0 then collH := -hwSign(Gear^.dX)
+        end;
     //if Gear^.AdvBounce and (collV <>0) and (collH <> 0) and (hwSqr(tdX) + hwSqr(tdY) > _0_08) then
-    if (Gear^.AdvBounce=1) and (collV <>0) and (collH <> 0) and ((collV=-1)
-    or ((tdX.QWordValue + tdY.QWordValue) > _0_2.QWordValue)) then
-        begin
-        Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction;
-        Gear^.dY := tdX*Gear^.Elasticity;
-        //*Gear^.Friction;
+    if (collV <> 0) and (collH <> 0) and 
+       (((Gear^.AdvBounce=1) and ((collV=-1) or ((tdX.QWordValue + tdY.QWordValue) > _0_2.QWordValue))) or
+        ((xland or land) and lfBouncy <> 0)) then
+        begin
+        if (xland or land) and lfBouncy = 0 then
+            begin
+            Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction;
+            Gear^.dY := tdX*Gear^.Elasticity
+            end
+        else
+            begin
+            Gear^.dX := tdY*cElastic*Gear^.Friction;
+            Gear^.dY := tdX*cElastic
+            end;
+
         Gear^.dY.isNegative := not tdY.isNegative;
         isFalling := false;
         Gear^.AdvBounce := 10;
@@ -397,7 +430,15 @@
     else
         Gear^.State := Gear^.State or gstMoving;
 
-    if (Gear^.nImpactSounds > 0) and
+    if ((xland or land) and lfBouncy <> 0) and (Gear^.dX.QWordValue < _0_1.QWordValue) and (Gear^.dY.QWordValue < _0_1.QWordValue) then
+        Gear^.State := Gear^.State or gstCollision;
+    
+    if ((xland or land) and lfBouncy <> 0) and
+        (((Gear^.Radius < 3) and (Gear^.dY < -_0_1)) or
+            ((Gear^.Radius >= 3) and
+                ((Gear^.dX.QWordValue > _0_1.QWordValue) or (Gear^.dY.QWordValue > _0_1.QWordValue)))) then
+        PlaySound(sndMelonImpact, true)
+    else if (Gear^.nImpactSounds > 0) and
         (Gear^.State and gstCollision <> 0) and
         (((Gear^.Kind <> gtMine) and (Gear^.Damage <> 0)) or (Gear^.State and gstMoving <> 0)) and
         (((Gear^.Radius < 3) and (Gear^.dY < -_0_1)) or
--- a/hedgewars/uGearsList.pas	Thu Nov 28 00:41:35 2013 +0400
+++ b/hedgewars/uGearsList.pas	Thu Nov 28 21:13:49 2013 -0500
@@ -236,16 +236,20 @@
                         gear^.Hedgehog^.Effects[heResurrectable] := 1;
                 end;
        gtShell: begin
+                gear^.Elasticity:= _0_8;
+                gear^.Friction:= _0_8;
                 gear^.Radius:= 4;
                 gear^.Density:= _1;
+                gear^.AdvBounce:= 1;
                 end;
        gtSnowball: begin
                 gear^.ImpactSound:= sndMudballImpact;
                 gear^.nImpactSounds:= 1;
                 gear^.Radius:= 4;
-                gear^.Elasticity:= _1;
-                gear^.Friction:= _1;
                 gear^.Density:= _0_5;
+                gear^.AdvBounce:= 1;
+                gear^.Elasticity:= _0_8;
+                gear^.Friction:= _0_8;
                 end;
 
      gtFlake: begin
@@ -327,9 +331,13 @@
                 gear^.Elasticity:= _0_55;
                 gear^.Friction:= _0_995;
                 gear^.Density:= _1_6;
+                gear^.AdvBounce:= 1;
                 if gear^.Timer = 0 then gear^.Timer:= 500;
                 end;
        gtKnife: begin
+                gear^.AdvBounce:= 1;
+                gear^.Elasticity:= _0_8;
+                gear^.Friction:= _0_8;
                 gear^.Density:= _4;
                 gear^.Radius:= 7
                 end;
@@ -341,6 +349,7 @@
                 if gear^.Timer = 0 then gear^.Timer:= 500
                 end;
   gtExplosives: begin
+                gear^.AdvBounce:= 1;
                 gear^.ImpactSound:= sndGrenadeImpact;
                 gear^.nImpactSounds:= 1;
                 gear^.Radius:= 16;
@@ -366,6 +375,9 @@
                 if gear^.Timer = 0 then gear^.Timer:= 5000;
                 end;
      gtCluster: begin
+                gear^.AdvBounce:= 1;
+                gear^.Elasticity:= _0_8;
+                gear^.Friction:= _0_8;
                 gear^.Radius:= 2;
                 gear^.Density:= _1_5;
                 gear^.RenderTimer:= true
@@ -409,6 +421,7 @@
                 gear^.Z:= cCurrHHZ+1;
                 end;
       gtMortar: begin
+                gear^.AdvBounce:= 1;
                 gear^.Radius:= 4;
                 gear^.Elasticity:= _0_2;
                 gear^.Friction:= _0_08;
@@ -443,6 +456,9 @@
                 if gear^.Timer = 0 then gear^.Timer:= 5000
                 end;
        gtDrill: begin
+                gear^.AdvBounce:= 1;
+                gear^.Elasticity:= _0_8;
+                gear^.Friction:= _0_8;
                 if gear^.Timer = 0 then
                     gear^.Timer:= 5000;
                 // Tag for drill strike. if 1 then first impact occured already
@@ -484,6 +500,7 @@
                 gear^.FlightTime := 2;
                 end;
          gtEgg: begin
+                gear^.AdvBounce:= 1;
                 gear^.Radius:= 4;
                 gear^.Elasticity:= _0_6;
                 gear^.Friction:= _0_96;
@@ -534,6 +551,9 @@
                 gear^.Tag := 47;
                 end;
   gtNapalmBomb: begin
+                gear^.AdvBounce:= 1;
+                gear^.Elasticity:= _0_8;
+                gear^.Friction:= _0_8;
                 if gear^.Timer = 0 then gear^.Timer:= 1000;
                 gear^.Radius:= 5;
                 gear^.Density:= _1_5;
--- a/hedgewars/uLandObjects.pas	Thu Nov 28 00:41:35 2013 +0400
+++ b/hedgewars/uLandObjects.pas	Thu Nov 28 21:13:49 2013 -0500
@@ -128,10 +128,7 @@
                     LandPixels[(cpY + y) div 2, (cpX + x) div 2]:= p^[x];
 
             if (Land[cpY + y, cpX + x] <= lfAllObjMask) and ((p^[x] and AMask) <> 0) then
-                begin
-                Land[cpY + y, cpX + x]:= lfObject;
-                Land[cpY + y, cpX + x]:= Land[cpY + y, cpX + x] or extraFlags
-                end;
+                Land[cpY + y, cpX + x]:= lfObject or extraFlags
             end;
     p:= @(p^[Image^.pitch shr 2])
     end;
@@ -280,7 +277,7 @@
     rr.x:= x1;
     while rr.x < x2 do
         begin
-        // For testing only. Intent is to flag this on objects with masks, or use it for an ice ray gun
+        // I should theme flag this. also snow...
         if (Theme = 'Snow') or (Theme = 'Christmas') then 
             BlitImageAndGenerateCollisionInfo(rr.x, y, min(x2 - rr.x, tmpsurf^.w), tmpsurf, lfIce)
         else
--- a/hedgewars/uVariables.pas	Thu Nov 28 00:41:35 2013 +0400
+++ b/hedgewars/uVariables.pas	Thu Nov 28 21:13:49 2013 -0500
@@ -161,6 +161,7 @@
     cMaxWindSpeed   : hwFloat;
     cWindSpeed      : hwFloat;
     cWindSpeedf     : real;
+    cElastic        : hwFloat;
     cGravity        : hwFloat;
     cGravityf       : real;
     cDamageModifier : hwFloat;
@@ -2434,6 +2435,7 @@
     cMaxWindSpeed.QWordValue:= 1073742;     // 0.00025
     cWindSpeed.QWordValue   := 0;           // 0.0
     cWindSpeedf             := 0.0;
+    cElastic                := _0_9;
     cGravity                := cMaxWindSpeed * 2;
     cGravityf               := 0.00025 * 2;
     cDamageModifier         := _1;