Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow scrolling the world map unless scrollable: false is set #1109

Merged
merged 1 commit into from
Feb 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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