Skip to content

Commit

Permalink
Allow scrolling the world map unless scrollable: false is set (#1109)
Browse files Browse the repository at this point in the history
Adds a new boolean key `scrollable` to the world description in scenario files, with a default value of true.

Closes #1108.
  • Loading branch information
byorgey committed Feb 15, 2023
1 parent 42abf59 commit 0ef8fc7
Show file tree
Hide file tree
Showing 10 changed files with 33 additions and 10 deletions.
15 changes: 8 additions & 7 deletions data/scenarios/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,13 +220,14 @@ The top-level `world` field contains a key-value mapping describing the
world, that is, a description of the terrain and entities that exist
at various locations.

| Key | Default? | Type | Description |
|-------------|----------|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `default` | `null` | `string list` | A tuple representing the contents of a default cell (see [Cells](#cells), except that the default cell may not contain a robot). If this key is present, it means that the whole world besides the part specified with the `map` will be filled with this default cell. If omitted, the world besides the part specified with the `map` will be procedurally generated. |
| `offset` | `False` | `boolean` | Whether the `base` robot's position should be moved to the nearest "good" location, currently defined as a location near a tree, in a 16x16 patch which contains at least one each of `tree`, `copper ore`, `bit (0)`, `bit (1)`, `rock`, `lambda`, `water`, and `sand`. The `classic` scenario uses `offset: True` to make sure that the it is not unreasonably difficult to obtain necessary resources in the early game. See https://github.com/swarm-game/swarm/blob/main/src/Swarm/Game/WorldGen.hs#L204 . |
| `palette` | `{}` | `object` | The `palette` maps single character keys to tuples representing contents of cells in the world, so that a world containing entities and robots can be drawn graphically. See [Cells](#cells) for the contents of the tuples representing a cell. |
| `map` | `""` | `string` | A rectangular string, using characters from the `palette`, exactly specifying the contents of a rectangular portion of the world. Leading spaces are ignored. The rest of the world is either filled by the `default` cell, or by procedural generation otherwise. Note that this is optional; if omitted, the world will simply be filled with the `default` cell or procedurally generated. |
| `upperleft` | `[0,0]` | `int × int` | A 2-tuple of `int` values specifying the (x,y) coordinates of the upper left corner of the `map`. |
| Key | Default? | Type | Description |
|--------------|----------|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `default` | `null` | `string list` | A tuple representing the contents of a default cell (see [Cells](#cells), except that the default cell may not contain a robot). If this key is present, it means that the whole world besides the part specified with the `map` will be filled with this default cell. If omitted, the world besides the part specified with the `map` will be procedurally generated. |
| `offset` | `False` | `boolean` | Whether the `base` robot's position should be moved to the nearest "good" location, currently defined as a location near a tree, in a 16x16 patch which contains at least one each of `tree`, `copper ore`, `bit (0)`, `bit (1)`, `rock`, `lambda`, `water`, and `sand`. The `classic` scenario uses `offset: True` to make sure that the it is not unreasonably difficult to obtain necessary resources in the early game. See https://github.com/swarm-game/swarm/blob/main/src/Swarm/Game/WorldGen.hs#L204 . |
| `scrollable` | `True` | `boolean` | Whether players are allowed to scroll the world map. |
| `palette` | `{}` | `object` | The `palette` maps single character keys to tuples representing contents of cells in the world, so that a world containing entities and robots can be drawn graphically. See [Cells](#cells) for the contents of the tuples representing a cell. |
| `map` | `""` | `string` | A rectangular string, using characters from the `palette`, exactly specifying the contents of a rectangular portion of the world. Leading spaces are ignored. The rest of the world is either filled by the `default` cell, or by procedural generation otherwise. Note that this is optional; if omitted, the world will simply be filled with the `default` cell or procedurally generated. |
| `upperleft` | `[0,0]` | `int × int` | A 2-tuple of `int` values specifying the (x,y) coordinates of the upper left corner of the `map`. |

#### Cells

Expand Down
1 change: 1 addition & 0 deletions data/scenarios/Tutorials/backstory.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,4 @@ robots:
seed: 0
world:
offset: true
scrollable: false
1 change: 1 addition & 0 deletions data/scenarios/Tutorials/farming.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,4 @@ robots:
seed: 0
world:
offset: true
scrollable: false
1 change: 1 addition & 0 deletions data/scenarios/Tutorials/world101.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,4 @@ robots:
seed: 0
world:
offset: true
scrollable: false
1 change: 1 addition & 0 deletions data/scenarios/classic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ robots:
world:
seed: null
offset: true
scrollable: false
5 changes: 5 additions & 0 deletions data/schema/world.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
"type": "boolean",
"description": "Whether the base robot's position should be moved to the nearest \"good\" location, currently defined as a location near a tree, in a 16x16 patch which contains at least one each of tree, copper ore, bit (0), bit (1), rock, lambda, water, and sand. The classic scenario uses offset: True to make sure that the it is not unreasonably difficult to obtain necessary resources in the early game. See https://github.com/swarm-game/swarm/blob/main/src/Swarm/Game/WorldGen.hs#L204 ."
},
"scrollable": {
"default": true,
"type": "boolean",
"description": "Whether players are allowed to scroll the world map."
},
"palette": {
"default": {},
"type": "object",
Expand Down
2 changes: 2 additions & 0 deletions src/Swarm/Game/Scenario/WorldDescription.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ instance FromJSONE (EntityMap, RobotMap) (WorldPalette Entity) where
data PWorldDescription e = WorldDescription
{ defaultTerrain :: Maybe (PCell e)
, offsetOrigin :: Bool
, scrollable :: Bool
, palette :: WorldPalette e
, ul :: Location
, area :: [[PCell e]]
Expand All @@ -48,6 +49,7 @@ instance FromJSONE (EntityMap, RobotMap) WorldDescription where
WorldDescription
<$> v ..:? "default"
<*> liftE (v .:? "offset" .!= False)
<*> liftE (v .:? "scrollable" .!= True)
<*> pure pal
<*> liftE (v .:? "upperleft" .!= origin)
<*> liftE ((v .:? "map" .!= "") >>= paintMap pal)
Expand Down
7 changes: 7 additions & 0 deletions src/Swarm/Game/State.hs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ module Swarm.Game.State (
currentScenarioPath,
knownEntities,
world,
worldScrollable,
viewCenterRule,
viewCenter,
needsRedraw,
Expand Down Expand Up @@ -342,6 +343,7 @@ data GameState = GameState
, _currentScenarioPath :: Maybe FilePath
, _knownEntities :: [Text]
, _world :: W.World Int Entity
, _worldScrollable :: Bool
, _viewCenterRule :: ViewCenterRule
, _viewCenter :: Location
, _needsRedraw :: Bool
Expand Down Expand Up @@ -506,6 +508,9 @@ knownEntities :: Lens' GameState [Text]
-- unboxed tile arrays.
world :: Lens' GameState (W.World Int Entity)

-- | Whether the world map is supposed to be scrollable or not.
worldScrollable :: Lens' GameState Bool

-- | The current center of the world view. Note that this cannot be
-- modified directly, since it is calculated automatically from the
-- 'viewCenterRule'. To modify the view center, either set the
Expand Down Expand Up @@ -794,6 +799,7 @@ initGameState = do
, _currentScenarioPath = Nothing
, _knownEntities = []
, _world = W.emptyWorld (fromEnum StoneT)
, _worldScrollable = True
, _viewCenterRule = VCRobot 0
, _viewCenter = origin
, _needsRedraw = False
Expand Down Expand Up @@ -842,6 +848,7 @@ scenarioToGameState scenario userSeed toRun g = do
, _recipesReq = addRecipesWith reqRecipeMap recipesReq
, _knownEntities = scenario ^. scenarioKnown
, _world = theWorld theSeed
, _worldScrollable = scenario ^. scenarioWorld . to scrollable
, _viewCenterRule = VCRobot baseID
, _viewCenter = origin
, _needsRedraw = False
Expand Down
7 changes: 5 additions & 2 deletions src/Swarm/TUI/Controller.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1124,9 +1124,12 @@ onlyCreative a = do

-- | Handle a user input event in the world view panel.
handleWorldEvent :: BrickEvent Name AppEvent -> EventM Name AppState ()
-- scrolling the world view in Creative mode
handleWorldEvent = \case
Key k | k `elem` moveKeys -> onlyCreative $ scrollView (.+^ (worldScrollDist *^ keyToDir k))
Key k
| k `elem` moveKeys -> do
c <- use $ gameState . creativeMode
s <- use $ gameState . worldScrollable
when (c || s) $ scrollView (.+^ (worldScrollDist *^ keyToDir k))
CharKey 'c' -> do
invalidateCacheEntry WorldCache
gameState . viewCenterRule .= VCRobot 0
Expand Down
3 changes: 2 additions & 1 deletion src/Swarm/TUI/View.hs
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,7 @@ drawKeyMenu s =
showZero = s ^. uiState . uiShowZero
inventorySort = s ^. uiState . uiInventorySort
ctrlMode = s ^. uiState . uiREPL . replControlMode
canScroll = creative || (s ^. gameState . worldScrollable)

renderControlModeSwitch :: ReplControlMode -> T.Text
renderControlModeSwitch = \case
Expand Down Expand Up @@ -792,7 +793,7 @@ drawKeyMenu s =
++ [("^c", "cancel") | isReplWorking]
++ [("M-p", renderControlModeSwitch ctrlMode) | creative]
keyCmdsFor (Just (FocusablePanel WorldPanel)) =
[ ("←↓↑→ / hjkl", "scroll") | creative
[ ("←↓↑→ / hjkl", "scroll") | canScroll
]
++ [("c", "recenter") | not viewingBase]
++ [("f", "FPS")]
Expand Down

0 comments on commit 0ef8fc7

Please sign in to comment.