# HG changeset patch # User unc0rr # Date 1380486088 -14400 # Node ID 619920c6aea035191e11049ec9b2ac39b250011a # Parent 265e5997580e5271cb4836f74a1bbcc0652f364a# Parent a51a69094c24e03ccee5485bfd646810b96c3554 merge diff -r 265e5997580e -r 619920c6aea0 hedgewars/uGearsHandlersMess.pas --- 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); diff -r 265e5997580e -r 619920c6aea0 hedgewars/uGearsHandlersRope.pas --- 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); diff -r 265e5997580e -r 619920c6aea0 hedgewars/uGearsHedgehog.pas --- 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 diff -r 265e5997580e -r 619920c6aea0 hedgewars/uGearsUtils.pas --- 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. diff -r 265e5997580e -r 619920c6aea0 hedgewars/uTypes.pas --- 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; diff -r 265e5997580e -r 619920c6aea0 hedgewars/uVariables.pas --- 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; diff -r 265e5997580e -r 619920c6aea0 hedgewars/uWorld.pas --- 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;