# HG changeset patch # User Wuzzy # Date 1593429258 -7200 # Node ID 85d2afe34116a4a0d17a9613c1a3040bd4e07e94 # Parent b4ec4a8a8b09ad7703eaed36093040ed2bca1ed3 Enforce camera limits regardless of zoom level Previously, when you zoomed out, you could move the camera further out to the left, right and up. diff -r b4ec4a8a8b09 -r 85d2afe34116 hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Mon Jun 29 00:15:37 2020 +0300 +++ b/hedgewars/uConsts.pas Mon Jun 29 13:14:18 2020 +0200 @@ -233,6 +233,12 @@ // do not change this value cDefaultZoomLevel = 2.0; // 100% zoom + // Maximum camera positions, values are "pixels outside the mainland" + cCamLimitX = 0; // X (left/right) camera limit, no border. Note: Influences sndFlyAway + cCamLimitY = 2048; // Top Y camera limit, no border + cCamLimitBorderX = 2048; // X (left/right) camera limit, with border + cCamLimitBorderY = 2048; // Top Y camera limit, with border + // game flags gfAny = $FFFFFFFF; // mask for all possible gameflags gfOneClanMode = $00000001; // Game does not end if there's only one clan in play. For missions diff -r b4ec4a8a8b09 -r 85d2afe34116 hedgewars/uGearsHedgehog.pas --- a/hedgewars/uGearsHedgehog.pas Mon Jun 29 00:15:37 2020 +0300 +++ b/hedgewars/uGearsHedgehog.pas Mon Jun 29 13:14:18 2020 +0200 @@ -1281,7 +1281,7 @@ uStats.hedgehogFlight(Gear, Gear^.FlightTime); Gear^.FlightTime:= 0; end; -if (WorldEdge = weNone) and (not Gear^.Hedgehog^.FlownOffMap) and (not isZero(Gear^.dX)) and (not isUnderwater) and ((Gear^.State and gstHHDriven) = 0) and (hwRound(Gear^.Y) < cWaterLine-300) and ((hwRound(Gear^.X) < leftX-2048) or (hwRound(Gear^.X) > rightX+2048)) then +if (WorldEdge = weNone) and (not hasBorder) and (not Gear^.Hedgehog^.FlownOffMap) and (not isZero(Gear^.dX)) and (not isUnderwater) and ((Gear^.State and gstHHDriven) = 0) and (hwRound(Gear^.Y) < cWaterLine-300) and ((hwRound(Gear^.X) < -cCamLimitX) or (hwRound(Gear^.X) > LAND_WIDTH+cCamLimitX)) then begin PlaySoundV(sndFlyAway, Gear^.Hedgehog^.Team^.voicepack); Gear^.Hedgehog^.FlownOffMap:= true; diff -r b4ec4a8a8b09 -r 85d2afe34116 hedgewars/uWorld.pas --- a/hedgewars/uWorld.pas Mon Jun 29 00:15:37 2020 +0300 +++ b/hedgewars/uWorld.pas Mon Jun 29 13:14:18 2020 +0200 @@ -877,12 +877,42 @@ end end; -// Force the lower camera boundary to never be lower than a few pixels below the water line -function LowerCameraBound: LongInt; +// Force camera to stay within a certain area +procedure CameraBounds; +var lowBound: LongInt; begin -LowerCameraBound:= trunc(cScreenHeight / cScaleFactor) + cScreenHeight div 2 - cWaterLine - (cVisibleWater + trunc(CinematicBarH / (cScaleFactor / 2.0))); -if WorldDy < LowerCameraBound then - WorldDy:= LowerCameraBound; +if (not hasBorder) then + begin + if WorldDy > (-(cScreenHeight / cScaleFactor) + cScreenHeight div 2 - TopY + cCamLimitY) then + WorldDy:= (-trunc(cScreenHeight / cScaleFactor) + cScreenHeight div 2 - TopY + cCamLimitY); + if (RightX - LeftX + cCamLimitX * 2) div 2 < cScreenWidth / cScaleFactor then + WorldDx:= -((LeftX + RightX) div 2) + else + begin + if WorldDx < -LAND_WIDTH - cCamLimitX + (cScreenWidth / cScaleFactor) then + WorldDx:= -LAND_WIDTH - cCamLimitX + trunc(cScreenWidth / cScaleFactor); + if WorldDx > cCamLimitX - (cScreenWidth / cScaleFactor) then + WorldDx:= cCamLimitX - trunc(cScreenWidth / cScaleFactor); + end; + end +else + begin + if WorldDy > (-(cScreenHeight / cScaleFactor) + cScreenHeight div 2 - TopY + cCamLimitBorderY) then + WorldDy:= (-trunc(cScreenHeight / cScaleFactor) + cScreenHeight div 2 - TopY + cCamLimitBorderY); + if (RightX - LeftX + cCamLimitBorderX * 2) div 2 < cScreenWidth / cScaleFactor then + WorldDx:= -((LeftX + RightX) div 2) + else + begin + if WorldDx > -LeftX + cCamLimitBorderX - (cScreenWidth / cScaleFactor) then + WorldDx:= -LeftX + cCamLimitBorderX - trunc(cScreenWidth / cScaleFactor); + if WorldDx < -RightX - cCamLimitBorderX + (cScreenWidth / cScaleFactor) then + WorldDx:= -RightX - cCamLimitBorderX + trunc(cScreenWidth / cScaleFactor); + end; + end; + +lowBound:= trunc(cScreenHeight / cScaleFactor) + cScreenHeight div 2 - cWaterLine - (cVisibleWater + trunc(CinematicBarH / (cScaleFactor / 2.0))); +if WorldDy < lowBound then + WorldDy:= lowBound; end; procedure DrawWorld(Lag: LongInt); @@ -906,7 +936,7 @@ if (not isPaused) and (not isAFK) and (GameType <> gmtRecord) then MoveCamera else if (isPaused) then - LowerCameraBound; + CameraBounds; if cStereoMode = smNone then begin @@ -1902,7 +1932,7 @@ var PrevSentPointTime: LongWord = 0; procedure MoveCamera; -var EdgesDist, wdy, shs,z, dstX: LongInt; +var EdgesDist, shs,z, dstX: LongInt; inbtwnTrgtAttks: Boolean; begin {$IFNDEF MOBILE} @@ -1950,10 +1980,11 @@ WorldDx:= WorldDx + rightX - leftX; end; -wdy:= LowerCameraBound; - if ((CursorPoint.X = prevPoint.X) and (CursorPoint.Y = prevpoint.Y)) then + begin + CameraBounds; exit; + end; if (AMState = AMShowingUp) or (AMState = AMShowing) then begin @@ -1966,6 +1997,7 @@ if CursorPoint.Y < cScreenHeight - (AmmoRect.y + AmmoRect.h - AMSlotSize - 5) then//check bottom CursorPoint.Y:= cScreenHeight - (AmmoRect.y + AmmoRect.h - AMSlotSize - 5); prevPoint:= CursorPoint; + CameraBounds; exit end; @@ -2021,14 +2053,10 @@ // this moves the camera according to CursorPoint X and Y prevPoint:= CursorPoint; -if WorldDy > LAND_HEIGHT + 1024 then - WorldDy:= LAND_HEIGHT + 1024; -if WorldDy < wdy then - WorldDy:= wdy; -if WorldDx < - LAND_WIDTH - 1024 then - WorldDx:= - LAND_WIDTH - 1024; -if WorldDx > 1024 then - WorldDx:= 1024; + +// enforce camera bounds +CameraBounds(); + end; procedure ShowMission(caption, subcaption, text: ansistring; icon, time : LongInt);