--- a/hedgewars/uAIMisc.pas Sat Jul 05 18:51:45 2014 +0200
+++ b/hedgewars/uAIMisc.pas Sat Jul 05 20:15:56 2014 +0200
@@ -445,7 +445,7 @@
end;
exit(0)
end;
- if (y > cWaterLine) or (x > rightX) or (x < leftX) then exit(-1)
+ if CheckCoordInWater(round(x), round(y)) then exit(-1)
end
end;
@@ -497,7 +497,7 @@
end;
exit(0)
end;
- if (y > cWaterLine) or (x > rightX) or (x < leftX) then
+ if CheckCoordInWater(round(x), round(y)) then
// returning -1 for drowning so it can be considered in the Rate routine
exit(-1)
end;
@@ -876,7 +876,7 @@
UpdateLandTexture(hwRound(Gear^.X), 1, hwRound(Gear^.Y), 1, true);
end;}
- if not (hwRound(Gear^.Y) + cHHRadius < cWaterLine) then
+ if CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y) + cHHRadius) then
exit(false);
if (Gear^.State and gstMoving) <> 0 then
begin
@@ -941,7 +941,7 @@
pX:= hwRound(Gear^.X);
pY:= hwRound(Gear^.Y);
- if pY + cHHRadius >= cWaterLine then
+ if CheckCoordInWater(pX, pY + cHHRadius) then
begin
if AltGear^.Hedgehog^.BotLevel < 4 then
AddWalkBonus(pX, tY, 250, -40);
--- a/hedgewars/uCollisions.pas Sat Jul 05 18:51:45 2014 +0200
+++ b/hedgewars/uCollisions.pas Sat Jul 05 20:15:56 2014 +0200
@@ -54,6 +54,8 @@
function TestRectancleForObstacle(x1, y1, x2, y2: LongInt; landOnly: boolean): boolean;
+function CheckCoordInWater(X, Y: LongInt): boolean; inline;
+
// returns: negative sign if going downhill to left, value is steepness (noslope/error = _0, 45 = _0_5)
function CalcSlopeBelowGear(Gear: PGear): hwFloat;
function CalcSlopeNearGear(Gear: PGear; dirX, dirY: LongInt): hwFloat;
@@ -112,6 +114,12 @@
end;
end;
+function CheckCoordInWater(X, Y: LongInt): boolean; inline;
+begin
+ CheckCoordInWater:= (Y > cWaterLine)
+ or ((WorldEdge = weSea) and ((X < leftX) or (X > rightX)));
+end;
+
function CheckGearsCollision(Gear: PGear): PGearArray;
var mx, my, tr: LongInt;
i: Longword;
--- a/hedgewars/uConsts.pas Sat Jul 05 18:51:45 2014 +0200
+++ b/hedgewars/uConsts.pas Sat Jul 05 20:15:56 2014 +0200
@@ -314,6 +314,8 @@
kSystemSoundID_Vibrate = $00000FFF;
+ cMinPlayWidth = 200;
+
implementation
end.
--- a/hedgewars/uGearsHandlersMess.pas Sat Jul 05 18:51:45 2014 +0200
+++ b/hedgewars/uGearsHandlersMess.pas Sat Jul 05 20:15:56 2014 +0200
@@ -259,9 +259,33 @@
////////////////////////////////////////////////////////////////////////////////
procedure doStepDrowningGear(Gear: PGear);
begin
- AllInactive := false;
+ if Gear^.Timer = 0 then
+ begin
+ if (FollowGear = Gear) and (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) then
+ FollowGear:= CurrentHedgehog^.Gear;
+ end
+ else if Gear^.Timer > 0 then
+ begin
+ AllInactive := false;
+ dec(Gear^.Timer);
+ end;
+
Gear^.Y := Gear^.Y + cDrownSpeed;
- Gear^.X := Gear^.X + Gear^.dX * cDrownSpeed;
+
+ if cWaterLine > hwRound(Gear^.Y) + Gear^.Radius then
+ begin
+ if leftX > hwRound(Gear^.X) - Gear^.Radius then
+ Gear^.X := Gear^.X - cDrownSpeed
+ else
+ Gear^.X := Gear^.X + cDrownSpeed;
+ end
+ else
+ Gear^.X := Gear^.X + Gear^.dX * cDrownSpeed;
+
+ if cWaterLine < hwRound(Gear^.Y) + Gear^.Radius then
+ else
+ Gear^.Y := Gear^.Y + Gear^.dY * cDrownSpeed;
+
// Create some bubbles (0.5% might be better but causes too few bubbles sometimes)
if ((not SuddenDeathDmg and (WaterOpacity < $FF))
or (SuddenDeathDmg and (SDWaterOpacity < $FF))) and ((GameTicks and $1F) = 0) then
@@ -301,7 +325,7 @@
if Gear^.dY.Round > 1 then
Gear^.dY.QWordValue:= 8589934592;
- if (Gear^.State and gstSubmersible <> 0) and (gY > cWaterLine) then
+ if (Gear^.State and gstSubmersible <> 0) and CheckCoordInWater(gX, gY) then
begin
Gear^.dX:= Gear^.dX * _0_999;
Gear^.dY:= Gear^.dY * _0_999
@@ -787,7 +811,7 @@
end;
*)
// move back to cloud layer
- if yy > cWaterLine then
+ if CheckCoordInWater(xx, yy) then
move:= true
else if (xx > snowRight) or (xx < snowLeft) then
move:=true
@@ -956,16 +980,19 @@
gX := hwRound(Gear^.X);
gY := hwRound(Gear^.Y);
uw := (Gear^.Tag <> 0); // was bee underwater last tick?
- nuw := (cWaterLine < gy + Gear^.Radius); // is bee underwater now?
+ nuw := CheckCoordInWater(gx, gy + Gear^.Radius); // is bee underwater now?
// if water entered or left
if nuw <> uw then
begin
- AddVisualGear(gX, cWaterLine, vgtSplash);
- AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
- AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
- AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
- AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
+ if (gX > leftX) and (gY < rightX) then
+ begin
+ AddVisualGear(gX, cWaterLine, vgtSplash);
+ AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
+ AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
+ AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
+ AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
+ end;
StopSoundChan(Gear^.SoundChannel);
if nuw then
begin
@@ -1178,7 +1205,7 @@
if (hwRound(Bullet^.X) and LAND_WIDTH_MASK <> 0)
or (hwRound(Bullet^.Y) and LAND_HEIGHT_MASK <> 0) then
// only extend if not under water
- if hwRound(Bullet^.Y) < cWaterLine then
+ if not CheckCoordInWater(hwRound(Bullet^.X), hwRound(Bullet^.Y)) then
begin
VGear^.dX := VGear^.dX + max(LAND_WIDTH,4096) * (VGear^.dX - VGear^.X);
VGear^.dY := VGear^.dY + max(LAND_WIDTH,4096) * (VGear^.dY - VGear^.Y);
@@ -2153,11 +2180,13 @@
Gear^.X := Gear^.X + Gear^.dX + cWindSpeed * 640;
Gear^.Y := Gear^.Y + Gear^.dY;
- if (hwRound(Gear^.Y) > cWaterLine) then
+ gX := hwRound(Gear^.X);
+ gY := hwRound(Gear^.Y);
+
+ if CheckCoordInWater(gX, gY) then
begin
- gX := hwRound(Gear^.X);
for i:= 0 to 3 do
- AddVisualGear(gX - 16 + Random(32), cWaterLine - 16 + Random(16), vgtSteam);
+ AddVisualGear(gX - 8 + Random(16), gY - 8 + Random(16), vgtSteam);
PlaySound(sndVaporize);
DeleteGear(Gear);
exit
@@ -2170,8 +2199,7 @@
Gear^.Y:= Gear^.Y+_6;
if (landPixel and lfIce <> 0) or (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
begin
- gX := hwRound(Gear^.X);
- gY := hwRound(Gear^.Y)-6;
+ gY := gy-6;
DrawExplosion(gX, gY, 4);
PlaySound(sndVaporize);
AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSteam);
@@ -2201,8 +2229,6 @@
end
else
begin
- gX := hwRound(Gear^.X);
- gY := hwRound(Gear^.Y);
// Standard fire
if not sticky then
begin
@@ -2252,8 +2278,6 @@
end;
if Gear^.Health = 0 then
begin
- gX := hwRound(Gear^.X);
- gY := hwRound(Gear^.Y);
if not sticky then
begin
if ((GameTicks and $3) = 0) and (Random(1) = 0) then
@@ -2799,6 +2823,14 @@
HHGear^.X := Gear^.X;
HHGear^.Y := Gear^.Y;
+ // check for drowning
+ if CheckGearDrowning(HHGear) then
+ begin
+ AfterAttack;
+ DeleteGear(Gear);
+ exit;
+ end;
+
inc(Gear^.Damage, 2);
// if TestCollisionXwithGear(HHGear, hwSign(Gear^.dX))
@@ -3167,6 +3199,18 @@
else
exit;
+ if playWidth > cMinPlayWidth then
+ begin
+ inc(leftX);
+ dec(rightX);
+ dec(playWidth, 2);
+ for i:= 0 to LAND_HEIGHT - 1 do
+ begin
+ Land[i, leftX] := 0;
+ Land[i, rightX] := 0;
+ end;
+ end;
+
if cWaterLine > 0 then
begin
dec(cWaterLine);
@@ -3508,7 +3552,7 @@
isUnderwater: Boolean;
bubble: PVisualGear;
begin
- isUnderwater:= cWaterLine < hwRound(Gear^.Y) + Gear^.Radius;
+ isUnderwater:= CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y) + Gear^.Radius);
if Gear^.Pos > 0 then
dec(Gear^.Pos);
AllInactive := false;
@@ -3614,6 +3658,7 @@
if // (Gear^.Health = 0)
(HHGear^.Damage <> 0)
//or CheckGearDrowning(HHGear)
+ // drown if too deep under water
or (cWaterLine + cVisibleWater * 4 < hwRound(HHGear^.Y))
or (TurnTimeLeft = 0)
// allow brief ground touches - to be fair on this, might need another counter
@@ -3929,7 +3974,7 @@
if (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] <= lfAllObjMask)
or (Gear^.Timer < 1)
or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team)
- or (hwRound(Gear^.Y) > cWaterLine) then
+ or CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y)) then
begin
deleteGear(Gear);
EXIT;
@@ -4318,7 +4363,7 @@
loadNewPortalBall(Gear, true);
end
- else if (y > cWaterLine)
+ else if CheckCoordInWater(x, y)
or (y < -max(LAND_WIDTH,4096))
or (x > 2*max(LAND_WIDTH,4096))
or (x < -max(LAND_WIDTH,4096)) then
@@ -4558,7 +4603,7 @@
end
else
begin
- if (rY <= cWaterLine) or (y <= cWaterLine) then
+ if CheckCoordInWater(rX, rY) or CheckCoordInWater(x, y) then
begin
if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0)
and (Land[y, x] <> 0) then
@@ -4945,7 +4990,7 @@
begin
//Gear^.dY := Gear^.dY + cGravity;
//Gear^.Y := Gear^.Y + Gear^.dY;
- if hwRound(Gear^.Y) > cWaterLine then
+ if CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y)) then
Gear^.Timer := 1
end;
--- a/hedgewars/uGearsHedgehog.pas Sat Jul 05 18:51:45 2014 +0200
+++ b/hedgewars/uGearsHedgehog.pas Sat Jul 05 20:15:56 2014 +0200
@@ -423,7 +423,7 @@
newGear^.dY:= newDY / newGear^.Density
end;
if (CurAmmoGear <> nil) and (CurAmmoGear^.AmmoType = amJetpack) and
- (Gear^.Message and gmPrecise <> 0) and (hwRound(Y) > cWaterLine) then
+ (Gear^.Message and gmPrecise <> 0) and CheckCoordInWater(hwRound(X), hwRound(Y)) then
newGear^.State:= newGear^.State or gstSubmersible;
case CurAmmoType of
@@ -548,7 +548,7 @@
begin
if TagTurnTimeLeft = 0 then
TagTurnTimeLeft:= TurnTimeLeft;
- if (CurAmmoGear <> nil) and (CurAmmoGear^.State and gstSubmersible <> 0) and (hwRound(CurAmmoGear^.Y) > cWaterLine) then
+ if (CurAmmoGear <> nil) and (CurAmmoGear^.State and gstSubmersible <> 0) and CheckCoordInWater(hwRound(CurAmmoGear^.X), hwRound(CurAmmoGear^.Y)) then
TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 25
else TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100;
end;
@@ -864,7 +864,7 @@
land: Word;
begin
land:= 0;
-isUnderwater:= cWaterLine < hwRound(Gear^.Y) + Gear^.Radius;
+isUnderwater:= CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y) + Gear^.Radius);
if Gear^.dX.QWordValue > 8160437862 then
Gear^.dX.QWordValue:= 8160437862;
if Gear^.dY.QWordValue > 8160437862 then
--- a/hedgewars/uGearsList.pas Sat Jul 05 18:51:45 2014 +0200
+++ b/hedgewars/uGearsList.pas Sat Jul 05 20:15:56 2014 +0200
@@ -649,12 +649,11 @@
begin
if (Gear <> CurrentHedgehog^.Gear) or (CurAmmoGear = nil) or (CurAmmoGear^.Kind <> gtKamikaze) then
Gear^.Hedgehog^.Team^.Clan^.Flawless:= false;
- if (hwRound(Gear^.Y) >= cWaterLine) then
+ if CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y)) then
begin
t:= max(Gear^.Damage, Gear^.Health);
Gear^.Damage:= t;
- if (((not SuddenDeathDmg) and (WaterOpacity < $FF)) or (SuddenDeathDmg and (WaterOpacity < $FF)))
- and (hwRound(Gear^.Y) < cWaterLine + 256) then
+ if (((not SuddenDeathDmg) and (WaterOpacity < $FF)) or (SuddenDeathDmg and (SDWaterOpacity < $FF))) then
spawnHealthTagForHH(Gear, t);
end;
--- a/hedgewars/uGearsUtils.pas Sat Jul 05 18:51:45 2014 +0200
+++ b/hedgewars/uGearsUtils.pas Sat Jul 05 20:15:56 2014 +0200
@@ -357,19 +357,40 @@
Gear^.DirAngle := Gear^.DirAngle - 360
end;
+procedure DrownGear(Gear: PGear);
+begin
+Gear^.doStep := @doStepDrowningGear;
+
+Gear^.Timer := 5000; // how long game should wait
+end;
+
function CheckGearDrowning(var Gear: PGear): boolean;
var
- skipSpeed, skipAngle, skipDecay: hwFloat;
- i, maxDrops, X, Y: LongInt;
- vdX, vdY: real;
+ skipSpeed, skipAngle, skipDecay, hwTmp: hwFloat;
+ i, maxDrops, X, Y, dist2Water: LongInt;
+ vdX, vdY, tmp: real;
particle, splash: PVisualGear;
- isSubmersible: boolean;
+ isSubmersible, isImpactH, isImpactRight, isLeaving: boolean;
s: ansistring;
begin
// probably needs tweaking. might need to be in a case statement based upon gear type
+ X:= hwRound(Gear^.X);
Y:= hwRound(Gear^.Y);
- if cWaterLine < Y + Gear^.Radius then
+
+ dist2Water:= cWaterLine - (Y + Gear^.Radius);
+ isImpactH:= false;
+
+ if WorldEdge = weSea then
begin
+ i:= dist2Water;
+ dist2Water:= min(dist2Water, min(X - Gear^.Radius - leftX, rightX - (X + Gear^.Radius)));
+ isImpactH:= i <> dist2Water;
+ end;
+
+ if dist2Water < 0 then
+ begin
+ // invisible gears will just be deleted
+ // unless they are generic fallers, then they will be "respawned"
if Gear^.State and gstInvisible <> 0 then
begin
if Gear^.Kind = gtGenericFaller then
@@ -386,20 +407,33 @@
skipSpeed := _0_25;
skipAngle := _1_9;
skipDecay := _0_87;
- X:= hwRound(Gear^.X);
- vdX:= hwFloat2Float(Gear^.dX);
- vdY:= hwFloat2Float(Gear^.dY);
- // this could perhaps be a tiny bit higher.
- if (cWaterLine + 64 + Gear^.Radius > Y) and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed)
- and (hwAbs(Gear^.dX) > skipAngle * hwAbs(Gear^.dY)) then
+ vdX:= abs(hwFloat2Float(Gear^.dX));
+ vdY:= abs(hwFloat2Float(Gear^.dY));
+
+ // skipping
+
+ // check for -1 depth because if deeper, then it already had its chance of skipping
+ if (dist2Water = -1) and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed)
+ and ( ((not isImpactH) and (hwAbs(Gear^.dX) > skipAngle * hwAbs(Gear^.dY)))
+ or (isImpactH and (hwAbs(Gear^.dY) > skipAngle * hwAbs(Gear^.dX))) ) then
begin
- Gear^.dY.isNegative := true;
+ // if skipping we move the gear out of water
+ if isImpactH then
+ begin
+ Gear^.dX.isNegative := (not Gear^.dX.isNegative);
+ Gear^.X:= Gear^.X + Gear^.dX;
+ end
+ else
+ begin
+ Gear^.dY.isNegative := (not Gear^.dY.isNegative);
+ Gear^.Y:= Gear^.Y + Gear^.dY;
+ end;
Gear^.dY := Gear^.dY * skipDecay;
Gear^.dX := Gear^.dX * skipDecay;
CheckGearDrowning := false;
PlaySound(sndSkip)
end
- else
+ else // not skipping
begin
if not isSubmersible then
begin
@@ -418,58 +452,110 @@
end
else
begin
- Gear^.doStep := @doStepDrowningGear;
+ DrownGear(Gear);
Gear^.State := Gear^.State and (not gstHHDriven);
s:= ansistring(Gear^.Hedgehog^.Name);
AddCaption(FormatA(GetEventString(eidDrowned), s), cWhiteColor, capgrpMessage);
end
end
else
- Gear^.doStep := @doStepDrowningGear;
- if Gear^.Kind = gtFlake then
- exit(true) // skip splashes
+ DrownGear(Gear);
+ if Gear^.Kind = gtFlake then
+ exit(true); // skip splashes
end
+ // drown submersible grears if far below map
else if (Y > cWaterLine + cVisibleWater*4) and
((Gear <> CurrentHedgehog^.Gear) or (CurAmmoGear = nil) or (CurAmmoGear^.State and gstSubmersible = 0)) then
- Gear^.doStep:= @doStepDrowningGear;
- if ((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius))
- or (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and (Gear = CurAmmoGear) and ((CurAmmoGear^.Pos = 0)
- and (CurAmmoGear^.dY < _0_01))) then
- if Gear^.Density * Gear^.dY > _1 then
+ DrownGear(Gear);
+
+ isImpactRight:= isImpactH and (abs(X - leftX) > abs(rightX - X));
+ isLeaving:= (isSubmersible and (dist2Water = -2 * Gear^.Radius) and (Gear = CurAmmoGear) and (CurAmmoGear^.Pos = 0)
+ and (((not isImpactH) and CurAmmoGear^.dY.isNegative) or (isImpactH and (isImpactRight = CurAmmoGear^.dX.isNegative))));
+
+ // splash sound
+
+ if ((not isSubmersible) and (dist2Water = -1))
+ or isLeaving then
+ begin
+ // adjust water impact sound on gear speed and density
+ if isImpactH then
+ hwTmp:= hwAbs(Gear^.Density * Gear^.dX)
+ else
+ hwTmp:= hwAbs(Gear^.Density * Gear^.dY);
+
+ if hwTmp > _1 then
PlaySound(sndSplash)
- else if Gear^.Density * Gear^.dY > _0_5 then
+ else if hwTmp > _0_5 then
PlaySound(sndSkip)
else
PlaySound(sndDroplet2);
+ end;
end;
+ // splash animation
+
if ((cReducedQuality and rqPlainSplash) = 0)
- and (((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius))
- or (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and (Gear = CurAmmoGear) and ((CurAmmoGear^.Pos = 0)
- and (CurAmmoGear^.dY < _0_01)))) then
+ and (((not isSubmersible) and (dist2Water = -1))
+ or isLeaving) then
begin
- splash:= AddVisualGear(X, cWaterLine, vgtSplash);
+ splash:= AddVisualGear(X, Y, vgtSplash);
if splash <> nil then
- with splash^ do
begin
- Scale:= hwFloat2Float(Gear^.Density / _3 * Gear^.dY);
- if Scale > 1 then Scale:= power(Scale,0.3333)
- else Scale:= Scale + ((1-Scale) / 2);
- if Scale > 1 then Timer:= round(min(Scale*0.0005/cGravityf,4))
- else Timer:= 1;
- // Low Gravity
- FrameTicks:= FrameTicks*Timer;
+ if isImpactH then
+ begin
+ splash^.Scale:= abs(hwFloat2Float((Gear^.Density / _3) * Gear^.dX));
+ if isImpactRight then
+ splash^.Angle:= -90
+ else
+ splash^.Angle:= 90;
+ end
+ else
+ splash^.Scale:= abs(hwFloat2Float(Gear^.Density / _3 * Gear^.dY));
+ with splash^ do
+ begin
+ if Scale > 1 then Scale:= power(Scale,0.3333)
+ else Scale:= Scale + ((1-Scale) / 2);
+ if Scale > 1 then Timer:= round(min(Scale*0.0005/cGravityf,4))
+ else Timer:= 1;
+ // Low Gravity
+ FrameTicks:= FrameTicks*Timer;
+ end;
end;
+ // eject water drops
+
maxDrops := (hwRound(Gear^.Density) * 3) div 2 + round(vdX * hwRound(Gear^.Density) * 6) + round(vdY * hwRound(Gear^.Density) * 6);
for i:= max(maxDrops div 3, min(32, Random(maxDrops))) downto 0 do
begin
- particle := AddVisualGear(X - 3 + Random(7), cWaterLine, vgtDroplet);
+ if isImpactH then
+ begin
+ if isImpactRight then
+ particle := AddVisualGear(RightX, Y - 3 + Random(7), vgtDroplet)
+ else
+ particle := AddVisualGear(LeftX, Y - 3 + Random(7), vgtDroplet)
+ end
+ else
+ particle := AddVisualGear(X - 3 + Random(7), cWaterLine, vgtDroplet);
+
if particle <> nil then
with particle^ do
begin
- dX := dX - vdX / 10;
- dY := dY - vdY / 5;
+ // dX and dY were initialized to have a random value on creation (see uVisualGearsList)
+ if isImpactH then
+ begin
+ tmp:= dX;
+ if isImpactRight then
+ dX:= dY - vdX / 5
+ else
+ dX:= -dy + vdX / 5;
+ dY:= tmp * (1 + vdY / 10);
+ end
+ else
+ begin
+ dX:= dX * (1 + vdX / 10);
+ dY:= dY - vdY / 5;
+ end;
+
if splash <> nil then
begin
if splash^.Scale > 1 then
@@ -482,7 +568,7 @@
dX:= dX * splash^.Scale;
dY:= dY * splash^.Scale
end
- end
+ end;
end
end
end;
@@ -1250,7 +1336,7 @@
Trying to make the checks a little broader than on first pass to catch things that don't move normally.
*)
function WorldWrap(var Gear: PGear): boolean;
-var tdx: hwFloat;
+//var tdx: hwFloat;
begin
WorldWrap:= false;
if WorldEdge = weNone then exit(false);
@@ -1281,7 +1367,7 @@
end;
if (Gear^.Radius > 2) and (Gear^.dX.QWordValue > _0_001.QWordValue) then
PlaySound(sndMelonImpact)
- end
+ end{
else if WorldEdge = weSea then
begin
if (hwRound(Gear^.Y) > cWaterLine) and (Gear^.State and gstSubmersible <> 0) then
@@ -1296,7 +1382,7 @@
Gear^.dY:= tdx;
Gear^.dY.isNegative:= true
end
- end;
+ end};
(*
* Window in the sky (Gear moved high into the sky, Y is used to determine X) [unfortunately, not a safe thing to do. shame, I thought aerial bombardment would be kinda neat
This one would be really easy to freeze game unless it was flagged unfortunately.
--- a/hedgewars/uRender.pas Sat Jul 05 18:51:45 2014 +0200
+++ b/hedgewars/uRender.pas Sat Jul 05 20:15:56 2014 +0200
@@ -847,7 +847,6 @@
procedure DrawTextureRotatedF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real);
var ft, fb, fl, fr: GLfloat;
hw, hh, nx, ny: LongInt;
- VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
begin
// note: not taking scale into account
@@ -1520,7 +1519,6 @@
lw, nWaves, shift: GLfloat;
sprite: TSprite;
begin
-
// note: spriteHeight is the Height of the wave sprite while
// cWaveHeight describes how many pixels of it will be above waterline
--- a/hedgewars/uVisualGears.pas Sat Jul 05 18:51:45 2014 +0200
+++ b/hedgewars/uVisualGears.pas Sat Jul 05 20:15:56 2014 +0200
@@ -205,11 +205,25 @@
else
DrawTextureF(SpritesData[sprFlame].Texture, Gear^.FrameTicks / 900, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, (RealTicks shr 7 + Gear^.Frame) mod 8, 1, 16, 16);
vgtSplash: if SuddenDeathDmg then
+ begin
+ if Gear^.Angle <> 0 then
+ begin
+ DrawTextureRotatedF(SpritesData[sprSDSplash].Texture, Gear^.scale, 0, 0, round(Gear^.X + WorldDx + (((SpritesData[sprSDSplash].Height+8)*Gear^.Scale)/2) * (Gear^.Angle / abs(Gear^.Angle))), round(Gear^.Y + WorldDy), 19 - (Gear^.FrameTicks div Gear^.Timer div 37), 1, SpritesData[sprSDSplash].Width, SpritesData[sprSDSplash].Height, Gear^.Angle);
+ end
+ else
//DrawSprite(sprSDSplash, round(Gear^.X) + WorldDx - 40, round(Gear^.Y) + WorldDy - 58, 19 - (Gear^.FrameTicks div 37))
- DrawTextureF(SpritesData[sprSDSplash].Texture, Gear^.scale, round(Gear^.X + WorldDx), round(Gear^.Y + WorldDy - ((SpritesData[sprSDSplash].Height+8)*Gear^.Scale)/2), 19 - (Gear^.FrameTicks div Gear^.Timer div 37), 1, SpritesData[sprSDSplash].Width, SpritesData[sprSDSplash].Height)
+ DrawTextureF(SpritesData[sprSDSplash].Texture, Gear^.scale, round(Gear^.X + WorldDx), round(Gear^.Y + WorldDy - ((SpritesData[sprSDSplash].Height+8)*Gear^.Scale)/2), 19 - (Gear^.FrameTicks div Gear^.Timer div 37), 1, SpritesData[sprSDSplash].Width, SpritesData[sprSDSplash].Height);
+ end
else
+ begin
+ if Gear^.Angle <> 0 then
+ begin
+ DrawTextureRotatedF(SpritesData[sprSplash].Texture, Gear^.scale, 0, 0, round(Gear^.X + WorldDx + (((SpritesData[sprSplash].Height+8)*Gear^.Scale)/2) * (Gear^.Angle / abs(Gear^.Angle))), round(Gear^.Y + WorldDy), 19 - (Gear^.FrameTicks div Gear^.Timer div 37), 1, SpritesData[sprSplash].Width, SpritesData[sprSplash].Height, Gear^.Angle);
+ end
+ else
//DrawSprite(sprSplash, round(Gear^.X) + WorldDx - 40, round(Gear^.Y) + WorldDy - 58, 19 - (Gear^.FrameTicks div 37));
- DrawTextureF(SpritesData[sprSplash].Texture, Gear^.scale, round(Gear^.X + WorldDx), round(Gear^.Y + WorldDy - ((SpritesData[sprSplash].Height+8)*Gear^.Scale)/2), 19 - (Gear^.FrameTicks div Gear^.Timer div 37), 1, SpritesData[sprSplash].Width, SpritesData[sprSplash].Height);
+ DrawTextureF(SpritesData[sprSplash].Texture, Gear^.scale, round(Gear^.X + WorldDx), round(Gear^.Y + WorldDy - ((SpritesData[sprSplash].Height+8)*Gear^.Scale)/2), 19 - (Gear^.FrameTicks div Gear^.Timer div 37), 1, SpritesData[sprSplash].Width, SpritesData[sprSplash].Height);
+ end;
vgtDroplet: if SuddenDeathDmg then
DrawSprite(sprSDDroplet, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, Gear^.Frame)
else
--- a/hedgewars/uVisualGearsHandlers.pas Sat Jul 05 18:51:45 2014 +0200
+++ b/hedgewars/uVisualGearsHandlers.pas Sat Jul 05 20:15:56 2014 +0200
@@ -75,7 +75,7 @@
procedure initModule;
implementation
-uses uVariables, Math, uConsts, uVisualGearsList, uFloat, uSound, uRenderUtils, uWorld;
+uses uCollisions, uVariables, Math, uConsts, uVisualGearsList, uFloat, uSound, uRenderUtils, uWorld;
procedure doStepFlake(Gear: PVisualGear; Steps: Longword);
var sign: real;
@@ -345,7 +345,7 @@
Gear^.dX := Gear^.dX / (1.001 * Steps);
Gear^.dY := Gear^.dY / (1.001 * Steps);
-if (Gear^.FrameTicks <= Steps) or (round(Gear^.Y) < cWaterLine) then
+if (Gear^.FrameTicks <= Steps) or not CheckCoordInWater(round(Gear^.X), round(Gear^.Y)) then
DeleteVisualGear(Gear)
else
dec(Gear^.FrameTicks, Steps)
@@ -354,7 +354,9 @@
////////////////////////////////////////////////////////////////////////////////
procedure doStepSteam(Gear: PVisualGear; Steps: Longword);
begin
-Gear^.X:= Gear^.X + (cWindSpeedf * 100 + Gear^.dX) * Steps;
+if ((cWindSpeedf > 0) and ( leftX > Gear^.X))
+or ((cWindSpeedf < 0) and (rightX < Gear^.X)) then
+ Gear^.X:= Gear^.X + (cWindSpeedf * 100 + Gear^.dX) * Steps;
Gear^.Y:= Gear^.Y - cDrownSpeedf * Steps;
if Gear^.FrameTicks <= Steps then
--- a/hedgewars/uVisualGearsList.pas Sat Jul 05 18:51:45 2014 +0200
+++ b/hedgewars/uVisualGearsList.pas Sat Jul 05 20:15:56 2014 +0200
@@ -36,12 +36,12 @@
VisualGearLayers: array[0..6] of PVisualGear;
implementation
-uses uFloat, uVariables, uConsts, uTextures, uVisualGearsHandlers;
+uses uCollisions, uFloat, uVariables, uConsts, uTextures, uVisualGearsHandlers;
function AddVisualGear(X, Y: LongInt; Kind: TVisualGearType): PVisualGear; inline;
begin
// adjust some visual gear types if underwater
- if (Y > cWaterLine) and ((Kind = vgtBeeTrace) or (Kind = vgtSmokeTrace) or (Kind = vgtEvilTrace)) then
+ if CheckCoordInWater(X, Y) and ((Kind = vgtBeeTrace) or (Kind = vgtSmokeTrace) or (Kind = vgtEvilTrace)) then
Kind:= vgtBubble;
AddVisualGear:= AddVisualGear(X, Y, Kind, 0, false, -1);