Initial pass at bounciness. To try it out, or lfBouncy on girder in uLandGraphics (search for the word graphically)
--- 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;