--- a/hedgewars/uGearsHandlersMess.pas Mon Sep 30 00:20:58 2013 +0400
+++ b/hedgewars/uGearsHandlersMess.pas Mon Sep 30 00:21:28 2013 +0400
@@ -284,6 +284,8 @@
collV, collH: LongInt;
land: word;
begin
+ WorldWrap(Gear);
+
// clip velocity at 2 - over 1 per pixel, but really shouldn't cause many actual problems.
if Gear^.dX.Round > 2 then
Gear^.dX.QWordValue:= 8589934592;
@@ -302,8 +304,6 @@
tdX := Gear^.dX;
tdY := Gear^.dY;
-
-
// might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips)
if (hwRound(Gear^.X) < min(LAND_WIDTH div -2, -2048))
or (hwRound(Gear^.X) > max(LAND_WIDTH * 3 div 2, 6144)) then
@@ -889,6 +889,7 @@
flower: PVisualGear;
begin
+ WorldWrap(Gear);
AllInactive := false;
gX := hwRound(Gear^.X);
gY := hwRound(Gear^.Y);
@@ -4637,6 +4638,7 @@
////////////////////////////////////////////////////////////////////////////////
procedure doStepPoisonCloud(Gear: PGear);
begin
+ WorldWrap(Gear);
if Gear^.Timer = 0 then
begin
DeleteGear(Gear);
--- a/hedgewars/uGearsHandlersRope.pas Mon Sep 30 00:20:58 2013 +0400
+++ b/hedgewars/uGearsHandlersRope.pas Mon Sep 30 00:21:28 2013 +0400
@@ -33,6 +33,7 @@
HHGear: PGear;
begin
HHGear := Gear^.Hedgehog^.Gear;
+ WorldWrap(HHGear);
if (HHGear^.Hedgehog^.CurAmmoType = amParachute) and (HHGear^.dY > _0_39) then
begin
DeleteGear(Gear);
@@ -116,7 +117,7 @@
HHGear := Gear^.Hedgehog^.Gear;
- if ((HHGear^.State and gstHHDriven) = 0)
+ if ((HHGear^.State and gstHHDriven) = 0) or WorldWrap(HHGear)
or (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then
begin
PlaySound(sndRopeRelease);
--- a/hedgewars/uGearsHedgehog.pas Mon Sep 30 00:20:58 2013 +0400
+++ b/hedgewars/uGearsHedgehog.pas Mon Sep 30 00:21:28 2013 +0400
@@ -828,6 +828,7 @@
var isFalling, isUnderwater: boolean;
land: Word;
begin
+WorldWrap(Gear);
land:= 0;
isUnderwater:= cWaterLine < hwRound(Gear^.Y) + Gear^.Radius;
if Gear^.dX.QWordValue > 8160437862 then
--- a/hedgewars/uGearsUtils.pas Mon Sep 30 00:20:58 2013 +0400
+++ b/hedgewars/uGearsUtils.pas Mon Sep 30 00:21:28 2013 +0400
@@ -53,6 +53,8 @@
function GetAmmo(Hedgehog: PHedgehog): TAmmoType;
function GetUtility(Hedgehog: PHedgehog): TAmmoType;
+function WorldWrap(var Gear: PGear): boolean;
+
function MakeHedgehogsStep(Gear: PGear) : boolean;
@@ -486,7 +488,10 @@
CurAmmoGear^.Pos := 1000
end
else
- CheckGearDrowning := false;
+ begin
+ if Gear^.Kind = gtHedgehog then Gear^.State:= Gear^.State and not gstSubmersible;
+ CheckGearDrowning := false
+ end
end;
@@ -1198,5 +1203,75 @@
GetUtility:= i
end;
+(*
+Intended to check Gear X/Y against the map left/right edges and apply one of the world modes
+* Normal - infinite world, do nothing
+* Wrap (entering left edge exits at same height on right edge)
+* Bounce (striking edge is treated as a 100% elasticity bounce)
+* From the depths (same as from sky, but from sea, with submersible flag set)
+
+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;
+begin
+WorldWrap:= false;
+// for playing around since it isn't hooked up yet
+//WorldEdge:= weBounce;
+if WorldEdge = weNone then exit(false);
+if (hwRound(Gear^.X)-Gear^.Radius < leftX) or
+ (hwRound(Gear^.X)+Gear^.Radius > rightX) then
+ begin
+ if WorldEdge = weWrap then
+ begin
+ if (hwRound(Gear^.X)-Gear^.Radius < leftX) then
+ Gear^.X:= int2hwfloat(rightX-Gear^.Radius)
+ else Gear^.X:= int2hwfloat(leftX+Gear^.Radius)
+ end
+ else if WorldEdge = weBounce then
+ begin
+ if (hwRound(Gear^.X)-Gear^.Radius < leftX) then
+ begin
+ Gear^.dX.isNegative:= false;
+ Gear^.X:= int2hwfloat(leftX+Gear^.Radius)
+ end
+ else
+ begin
+ Gear^.dX.isNegative:= true;
+ Gear^.X:= int2hwfloat(rightX-Gear^.Radius)
+ end
+ end
+ else if WorldEdge = weSea then
+ begin
+ if (hwRound(Gear^.Y) > cWaterLine) and (Gear^.State and gstSubmersible <> 0) then
+ Gear^.State:= Gear^.State and not gstSubmersible
+ else
+ begin
+ Gear^.State:= Gear^.State or gstSubmersible;
+ Gear^.X:= int2hwFloat(PlayWidth)*int2hwFloat(min(max(0,hwRound(Gear^.Y)),PlayHeight))/PlayHeight;
+ Gear^.Y:= int2hwFloat(cWaterLine+cVisibleWater+Gear^.Radius*2);
+ tdx:= Gear^.dX;
+ Gear^.dX:= Gear^.dY;
+ Gear^.dY:= tdx;
+ Gear^.dY.isNegative:= true
+ 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.
+
+ else
+ begin
+ Gear^.X:= int2hwFloat(PlayWidth)*int2hwFloat(min(max(0,hwRound(Gear^.Y)),PlayHeight))/PlayHeight;
+ Gear^.Y:= -_2048-_256-_256;
+ tdx:= Gear^.dX;
+ Gear^.dX:= Gear^.dY;
+ Gear^.dY:= tdx;
+ Gear^.dY.isNegative:= false
+ end
+*)
+ WorldWrap:= true
+ end;
+end;
end.
--- a/hedgewars/uTypes.pas Mon Sep 30 00:20:58 2013 +0400
+++ b/hedgewars/uTypes.pas Mon Sep 30 00:21:28 2013 +0400
@@ -173,6 +173,8 @@
TRenderMode = (rmDefault, rmLeftEye, rmRightEye);
TStereoMode = (smNone, smRedCyan, smCyanRed, smRedBlue, smBlueRed, smRedGreen, smGreenRed, smHorizontal, smVertical);
+ TWorldEdge = (weNone, weWrap, weBounce, weSea, weSky);
+
THHFont = record
Handle: PTTF_Font;
Height: LongInt;
--- a/hedgewars/uVariables.pas Mon Sep 30 00:20:58 2013 +0400
+++ b/hedgewars/uVariables.pas Mon Sep 30 00:21:28 2013 +0400
@@ -82,6 +82,7 @@
GameType : TGameType;
InputMask : LongWord;
GameFlags : Longword;
+ WorldEdge : TWorldEdge;
TurnTimeLeft : Longword;
TagTurnTimeLeft : Longword;
ReadyTimeLeft : Longword;
@@ -2446,6 +2447,7 @@
InputMask := $FFFFFFFF;
GameFlags := 0;
+ WorldEdge := weNone;
TurnTimeLeft := 0;
TagTurnTimeLeft := 0;
cSuddenDTurns := 15;
--- a/hedgewars/uWorld.pas Mon Sep 30 00:20:58 2013 +0400
+++ b/hedgewars/uWorld.pas Mon Sep 30 00:21:28 2013 +0400
@@ -1235,6 +1235,13 @@
end;
{$WARNINGS ON}
+if WorldEdge <> weNone then
+ begin
+(* I think for a bounded world, will fill the left and right areas with black or something. Also will probably want various border effects/animations based on border type. Prob also, say, trigger a border animation timer on an impact. *)
+ DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 3.0, $FF, $00, $FF, $FF);
+ DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 3.0, $FF, $00, $FF, $FF)
+ end;
+
// this scale is used to keep the various widgets at the same dimension at all zoom levels
SetScale(cDefaultZoomLevel);
@@ -1631,7 +1638,7 @@
DrawSprite(sprArrow, TargetCursorPoint.X, cScreenHeight - TargetCursorPoint.Y, (RealTicks shr 6) mod 8)
end
end;
-isFirstFrame:= false
+isFirstFrame:= false;
end;
var PrevSentPointTime: LongWord = 0;