LambdaHack 0.9.4.1 → 0.9.5.0
raw patch · 37 files changed
+321/−176 lines, 37 filesdep ~randomPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: random
API changes (from Hackage documentation)
+ Game.LambdaHack.Client.UI: [swasAutomated] :: SessionUI -> Bool
+ Game.LambdaHack.Client.UI.HandleHumanGlobalM: automateBackHuman :: MonadClientUI m => m (Either MError ReqUI)
+ Game.LambdaHack.Client.UI.HandleHumanGlobalM: automateToggleHuman :: MonadClientUI m => m (FailOrCmd ReqUI)
+ Game.LambdaHack.Client.UI.HandleHumanGlobalM: gameQuitHuman :: MonadClientUI m => m (FailOrCmd ReqUI)
+ Game.LambdaHack.Client.UI.HandleHumanGlobalM: mainMenuAutoOffHuman :: MonadClientUI m => (HumanCmd -> m (Either MError ReqUI)) -> m (Either MError ReqUI)
+ Game.LambdaHack.Client.UI.HandleHumanGlobalM: mainMenuAutoOnHuman :: MonadClientUI m => (HumanCmd -> m (Either MError ReqUI)) -> m (Either MError ReqUI)
+ Game.LambdaHack.Client.UI.HumanCmd: AutomateBack :: HumanCmd
+ Game.LambdaHack.Client.UI.HumanCmd: AutomateToggle :: HumanCmd
+ Game.LambdaHack.Client.UI.HumanCmd: GameQuit :: HumanCmd
+ Game.LambdaHack.Client.UI.HumanCmd: MainMenuAutoOff :: HumanCmd
+ Game.LambdaHack.Client.UI.HumanCmd: MainMenuAutoOn :: HumanCmd
+ Game.LambdaHack.Client.UI.Key: ControlShift :: Modifier
+ Game.LambdaHack.Client.UI.Key: middleButtonReleaseKM :: KM
+ Game.LambdaHack.Client.UI.SessionUI: [swasAutomated] :: SessionUI -> Bool
+ Game.LambdaHack.Definition.Color: HighlightNoneCursor :: Highlight
- Game.LambdaHack.Client.UI: SessionUI :: Maybe Target -> ActorDictUI -> ItemDictUI -> ItemSlots -> Maybe (CStore, CStore) -> ChanFrontend -> CCUI -> UIOptions -> Maybe AimMode -> Bool -> Maybe (ItemId, CStore, Bool) -> EnumSet ActorId -> Maybe RunParams -> History -> Point -> LastRecord -> [KM] -> EnumSet ActorId -> Int -> Bool -> Bool -> Map String Int -> Bool -> HintMode -> Bool -> POSIXTime -> POSIXTime -> Time -> Int -> Int -> SessionUI
+ Game.LambdaHack.Client.UI: SessionUI :: Maybe Target -> ActorDictUI -> ItemDictUI -> ItemSlots -> Maybe (CStore, CStore) -> ChanFrontend -> CCUI -> UIOptions -> Maybe AimMode -> Bool -> Maybe (ItemId, CStore, Bool) -> EnumSet ActorId -> Maybe RunParams -> History -> Point -> LastRecord -> [KM] -> EnumSet ActorId -> Int -> Bool -> Bool -> Bool -> Map String Int -> Bool -> HintMode -> Bool -> POSIXTime -> POSIXTime -> Time -> Int -> Int -> SessionUI
- Game.LambdaHack.Client.UI.SessionUI: SessionUI :: Maybe Target -> ActorDictUI -> ItemDictUI -> ItemSlots -> Maybe (CStore, CStore) -> ChanFrontend -> CCUI -> UIOptions -> Maybe AimMode -> Bool -> Maybe (ItemId, CStore, Bool) -> EnumSet ActorId -> Maybe RunParams -> History -> Point -> LastRecord -> [KM] -> EnumSet ActorId -> Int -> Bool -> Bool -> Map String Int -> Bool -> HintMode -> Bool -> POSIXTime -> POSIXTime -> Time -> Int -> Int -> SessionUI
+ Game.LambdaHack.Client.UI.SessionUI: SessionUI :: Maybe Target -> ActorDictUI -> ItemDictUI -> ItemSlots -> Maybe (CStore, CStore) -> ChanFrontend -> CCUI -> UIOptions -> Maybe AimMode -> Bool -> Maybe (ItemId, CStore, Bool) -> EnumSet ActorId -> Maybe RunParams -> History -> Point -> LastRecord -> [KM] -> EnumSet ActorId -> Int -> Bool -> Bool -> Bool -> Map String Int -> Bool -> HintMode -> Bool -> POSIXTime -> POSIXTime -> Time -> Int -> Int -> SessionUI
Files
- CHANGELOG.md +17/−0
- GameDefinition/Content/ModeKind.hs +22/−22
- GameDefinition/InGameHelp.txt +14/−10
- GameDefinition/MainMenu.ascii +24/−24
- GameDefinition/MoveKeys.txt +3/−3
- GameDefinition/PLAYING.md +10/−8
- GameDefinition/config.ui.default +7/−6
- GameDefinition/game-src/Client/UI/Content/Input.hs +19/−11
- LambdaHack.cabal +4/−2
- Makefile +3/−3
- README.md +9/−14
- definition-src/Game/LambdaHack/Content/ModeKind.hs +1/−1
- definition-src/Game/LambdaHack/Definition/Color.hs +2/−0
- engine-src/Game/LambdaHack/Client/State.hs +2/−2
- engine-src/Game/LambdaHack/Client/UI.hs +3/−3
- engine-src/Game/LambdaHack/Client/UI/Content/Input.hs +1/−1
- engine-src/Game/LambdaHack/Client/UI/DisplayAtomicM.hs +5/−7
- engine-src/Game/LambdaHack/Client/UI/FrameM.hs +6/−3
- engine-src/Game/LambdaHack/Client/UI/Frontend/Common.hs +1/−0
- engine-src/Game/LambdaHack/Client/UI/Frontend/Curses.hs +2/−1
- engine-src/Game/LambdaHack/Client/UI/Frontend/Dom.hs +7/−5
- engine-src/Game/LambdaHack/Client/UI/Frontend/Gtk.hs +6/−3
- engine-src/Game/LambdaHack/Client/UI/Frontend/Sdl.hs +4/−2
- engine-src/Game/LambdaHack/Client/UI/Frontend/Vty.hs +1/−0
- engine-src/Game/LambdaHack/Client/UI/HandleHumanGlobalM.hs +89/−27
- engine-src/Game/LambdaHack/Client/UI/HandleHumanM.hs +5/−0
- engine-src/Game/LambdaHack/Client/UI/HumanCmd.hs +5/−0
- engine-src/Game/LambdaHack/Client/UI/Key.hs +13/−2
- engine-src/Game/LambdaHack/Client/UI/KeyBindings.hs +6/−6
- engine-src/Game/LambdaHack/Client/UI/MonadClientUI.hs +3/−3
- engine-src/Game/LambdaHack/Client/UI/MsgM.hs +6/−0
- engine-src/Game/LambdaHack/Client/UI/SessionUI.hs +4/−1
- engine-src/Game/LambdaHack/Client/UI/SlideshowM.hs +10/−1
- engine-src/Game/LambdaHack/Common/Save.hs +2/−1
- engine-src/Game/LambdaHack/Server/LoopM.hs +3/−2
- engine-src/Game/LambdaHack/Server/MonadServer.hs +1/−1
- engine-src/Game/LambdaHack/Server/StartM.hs +1/−1
CHANGELOG.md view
@@ -1,3 +1,20 @@+## [v0.9.5.0](https://github.com/LambdaHack/LambdaHack/compare/v0.9.4.0...v0.9.5.0)++- Fix NumLock disabled in the browser+- In screen reader frontend, highlight active menu line with the cursor+- Clone the main main menu commands as map mode commands+- Add C-RMB and C-S-LMB as alternatives of MMB+- Announce prominently MMB binding for describing map positions+- Clean up the default config file, keeping compatibility+- Make scenario names longer and slighlty more informative+- Make Vi movement keys the default in addition to keypad and mouse+- Fix a bug where death prompt when autoplaying was capturing a keypress+- Let ESC from main menu return to insert coin mode, if applicable+- Make various small UI tweaks, especially to main menu and its submenu+- Let main menu lines have 35, not 30, characters+- Make the main menu ASCII art less intrusive (and easier for screen readers)+- Don't invalidate the score file due to game minor (only) version bump+ ## [v0.9.4.0](https://github.com/LambdaHack/LambdaHack/compare/v0.9.3.0...v0.9.4.0) - In vty frontend highlight actors more
GameDefinition/Content/ModeKind.hs view
@@ -34,11 +34,11 @@ raid = ModeKind -- mini-crawl { msymbol = 'r'- , mname = "raid (1)"- , mfreq = [("raid", 1), ("campaign scenario", 1)]+ , mname = "solo raid (1)"+ , mfreq = [("solo", 1), ("raid", 1), ("campaign scenario", 1)] , mroster = rosterRaid , mcaves = cavesRaid- , mendMsg = [ (Killed, "This expedition has gone wrong. However, scientific mind does not despair, but analyzes and corrects. Did you perchance awake one animal too many? Did you remember to try using all consumables at your disposal for your immediate survival? Did you choose a challenge with difficulty level within your means? Answer honestly, ponder wisely, experiment methodically.")+ , mendMsg = [ (Killed, "This expedition has gone wrong. However, scientific mind does not despair, but analyzes and corrects. Did you perchance awake one animal too many? Did you remember to try using all consumables at your disposal for your immediate survival? Did you choose a challenge with difficulty level within your means? Answer honestly, ponder wisely, experiment methodically.") , (Defeated, "Regrettably, the other team snatched the grant, while you were busy contemplating natural phenomena. Science is a competitive sport, as sad as it sounds. It's not enough to make a discovery, you have to get there first.") , (Escape, "You've got hold of the machine! Think of the hours of fun taking it apart and putting it back together again! That's a great first step on your quest to solve the typing problems of the world.") ] , mdesc = "An incredibly advanced typing machine worth 100 gold is buried at the exit of this maze. Be the first to find it and fund a research team that makes typing accurate and dependable forever."@@ -46,8 +46,8 @@ brawl = ModeKind -- sparse melee in daylight, with shade for melee ambush { msymbol = 'k'- , mname = "brawl (2)"- , mfreq = [("brawl", 1), ("campaign scenario", 1)]+ , mname = "melee brawl (2)"+ , mfreq = [("melee", 1), ("brawl", 1), ("campaign scenario", 1)] , mroster = rosterBrawl , mcaves = cavesBrawl , mendMsg = []@@ -64,8 +64,8 @@ -- and that's their only role, so a small party makes sense. shootout = ModeKind -- sparse ranged in daylight { msymbol = 's'- , mname = "shootout (3)"- , mfreq = [("shootout", 1), ("campaign scenario", 1)]+ , mname = "foggy shootout (3)"+ , mfreq = [("foggy", 1), ("shootout", 1), ("campaign scenario", 1)] , mroster = rosterShootout , mcaves = cavesShootout , mendMsg = []@@ -74,8 +74,8 @@ hunt = ModeKind -- melee vs ranged with reaction fire in daylight { msymbol = 'h'- , mname = "hunt (4)"- , mfreq = [("hunt", 1), ("campaign scenario", 1)]+ , mname = "perilous hunt (4)"+ , mfreq = [("perilous", 1), ("hunt", 1), ("campaign scenario", 1)] , mroster = rosterHunt , mcaves = cavesHunt , mendMsg = []@@ -84,8 +84,8 @@ escape = ModeKind -- asymmetric ranged and stealth race at night { msymbol = 'e'- , mname = "escape (5)"- , mfreq = [("escape", 1), ("campaign scenario", 1)]+ , mname = "night escape (5)"+ , mfreq = [("night", 1), ("escape", 1), ("campaign scenario", 1)] , mroster = rosterEscape , mcaves = cavesEscape , mendMsg = []@@ -94,8 +94,8 @@ zoo = ModeKind -- asymmetric crowd melee at night { msymbol = 'b'- , mname = "zoo (6)"- , mfreq = [("zoo", 1), ("campaign scenario", 1)]+ , mname = "burning zoo (6)"+ , mfreq = [("burning", 1), ("zoo", 1), ("campaign scenario", 1)] , mroster = rosterZoo , mcaves = cavesZoo , mendMsg = []@@ -112,8 +112,8 @@ -- shoots (and often also scouts) and others just gather ammo. ambush = ModeKind -- dense ranged with reaction fire vs melee at night { msymbol = 'm'- , mname = "ambush (7)"- , mfreq = [("ambush", 1), ("campaign scenario", 1)]+ , mname = "ranged ambush (7)"+ , mfreq = [("ranged", 1), ("ambush", 1), ("campaign scenario", 1)] , mroster = rosterAmbush , mcaves = cavesAmbush , mendMsg = []@@ -122,8 +122,8 @@ crawl = ModeKind { msymbol = 'c'- , mname = "crawl (long)"- , mfreq = [("crawl", 1), ("campaign scenario", 1)]+ , mname = "deep crawl (long)"+ , mfreq = [("deep", 1), ("crawl", 1), ("campaign scenario", 1)] , mroster = rosterCrawl , mcaves = cavesCrawl , mendMsg = [ (Killed, "To think that followers of science and agents of enlightenment would earn death as their reward! Where did we err in our ways? Perhaps nature should not have been disturbed so brashly and the fell beasts woken up from their slumber so eagerly? Perhaps the gathered items should have been used for scientific experiments on the spot rather than hoarded as if of base covetousness? Or perhaps the challenge, chosen freely but without the foreknowledge of the grisly difficulty, was insurmountable and forlorn from the start, despite the enormous power of educated reason at out disposal?")@@ -254,7 +254,7 @@ screensaverRaid = raid { mname = "auto-raid (1)"- , mfreq = [("starting", 1), ("no confirms", 1)]+ , mfreq = [("insert coin", 1), ("no confirms", 1)] , mroster = screensave (AutoLeader False False) rosterRaid } @@ -266,19 +266,19 @@ screensaverShootout = shootout { mname = "auto-shootout (3)"- , mfreq = [("starting", 1), ("no confirms", 1)]+ , mfreq = [("insert coin", 1), ("no confirms", 1)] , mroster = screensave (AutoLeader False False) rosterShootout } screensaverHunt = hunt { mname = "auto-hunt (4)"- , mfreq = [("starting", 1), ("no confirms", 1)]+ , mfreq = [("insert coin", 1), ("no confirms", 1)] , mroster = screensave (AutoLeader False False) rosterHunt } screensaverEscape = escape { mname = "auto-escape (5)"- , mfreq = [("starting", 1), ("no confirms", 1)]+ , mfreq = [("insert coin", 1), ("no confirms", 1)] , mroster = screensave (AutoLeader False False) rosterEscape } @@ -302,7 +302,7 @@ screensaverSafari = safari { mname = "auto-safari"- , mfreq = [("starting", 1), ("no confirms", 1)]+ , mfreq = [("insert coin", 1), ("no confirms", 1)] , mroster = -- changing leader by client needed, because of TFollow screensave (AutoLeader False True) rosterSafari }
GameDefinition/InGameHelp.txt view
@@ -5,9 +5,9 @@ Minimal cheat sheet for casual play. - Walk throughout a level with mouse or numeric keypad (left diagram below),- or with its compact laptop replacement (middle) or the Vi editor keys (right)- selectable in config.ui.ini. Run until disturbed with Shift or Control.+ Walk throughout a level with mouse or numeric keypad (left diagram below)+ or the Vi editor keys (right) or with a compact laptop setup (middle) that+ requires enabling in config.ui.ini. Run until disturbed with Shift or Control. Go-to with LMB (left mouse button). Run collectively via S-LMB (holding Shift). 7 8 9 7 8 9 y k u@@ -128,7 +128,8 @@ The list includes not only left and right buttons, but also the optional middle mouse button (MMB) and the mouse wheel, which is also used over menus, to page-scroll them.- (For mice without RMB, one can use Control key with LMB.)+ (For mice without RMB, one can use Control key with LMB and for mice+ without MMB, one can use C-RMB or C-S-LMB.) Next we show mouse button effects per screen area, in exploration mode and (if different) in aiming mode. @@ -136,13 +137,11 @@ LMB go to pointer for 25 steps/fling at enemy S-LMB run to pointer collectively for 25 steps/fling at enemy RMB or C-LMB start aiming at enemy under pointer- C-RMB open or close or alter at pointer- MMB snap x-hair to floor under pointer+ S-RMB open or close or alter at pointer+ MMB or C-RMB snap x-hair to floor under pointer WHEEL-UP swerve the aiming line WHEEL-DN unswerve the aiming line -Mouse in exploration and aiming modes.- exploration LMB (left mouse button) RMB (right mouse button) message line clear messages and show history display help leader on map grab item(s) drop item(s)@@ -167,9 +166,15 @@ keys command SPACE clear messages and show history- F12 open dashboard+ % yell/yawn+ C-s start new game+ C-x save and exit to desktop+ C-t toggle autoplay (insert coin)+ C-q quit game and start autoplay+ C-c exit to desktop without saving ? display help F1 display help immediately+ F12 open dashboard v voice again the recorded commands V voice recorded commands 100 times C-v voice recorded commands 1000 times@@ -177,4 +182,3 @@ ' start recording commands C-S save game backup C-P print screen- % yell/yawn
GameDefinition/MainMenu.ascii view
@@ -1,24 +1,24 @@-fffffjjjjtti,:Lft: tDEGLLGEKEK; . . . . .iEDEGL.;iiij ...-fLLLLfffjjjti;.fL . GDDLfGDEDEf . . . . ;LDWEGi,;iit ..-LD#WWELfffjjtt;.if.: .DEGLLGEDLti, . . . . . ,tLKDG ,;itt.-fK#WWW#DLffjjtt;:;j... tDEGfLDEDGtK. . LambdaHack itLEG::;itt.-;K#WWWWW Lfffjjti:.t... tDEGfLDEDL, . tDGj.;itt. - EWWWWKW GLffjjti: t, tDEGLGEEDj; <lambdahack.github.io> tLDLi,ittj- EKWWWEWG GLffjjti: tt .tDEGGDEDGi, ;fEG :iitj- LEWWWKKK GLfffjti: tt tDDLGDEDGf. {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ;jGG :iitj- DWWWKDWL DLffjjti: jt.DDLGDEDLD {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ,jDG .ittj- LEWWWEDKj DLffjjti: jj.LGDEDLE {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ,jDG ittj- DKKWKDEKf GLffjjti::ff.EEDLE {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ,fGG ittj- GWKWEDEEt GLffjjji :fL.ELE {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ :tGL ittf- EEWKKDGDEjt..DLfftjji.,fG:K, {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ,fGj,.tjjf- EfKGKDLGDDDGDGLffiiti ttf:. {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ .LG;i,;itt- ..EDKEKEGjiLDDfGLLfijtii;fL: {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ jLj ,;tjtL- . . KLEEKKDGLLLGLGLfffjji,;LL:,. {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{,tfL.fijffL- .......jDKEEKKKKKEDGLffffji;;LL:... {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{j fGii tjff-..........KtGDKEDEEDGLGLfffjti,;Lf:::: {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{iDf j:jffL.-..........::,E,tjjifL,,LLfffjji.;fL.,: {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{fiififffL .- ......::,;tjLGGGGGLfji;LLfffjjt.,jft. ;t;i:jfff .- ..:::::,;;;,iiiiiiii;;;;LLfffjjt,,;LL: ... ,iiijjfffL ..-..:::::,,;;;;;;;;;;;;;;;;;GLffffjt;j,jff,:::, ;ifLjjijifffL ..-.......::,,,,;;;;,,,,,,,,,:GLffffjjt:::tLiL LLLLGj;i,ffLLL ...-. ..:::::,,,,,,,,,,, Version X.X.X (frontend: xxx, engine: LambdaHack X.X.X).+ffjjjjtti,:Lft: tDEGLLfGEKEDKP .iEDEGL.;iiij ...+LLfffjjjti;.fL . GDDLfGDEDEtf ;LDWEGi,;iit ..+WWELfffjjtt;.if.: .DEGLLGEDLti, ,tLKDG ,;itt.+WWW#DLffjjtt;:;j... tDEGfLDEDGtK. LambdaHack itLEG::;itt.+WWWWW Lfffjjti:.t... tDEGfLDEDL, tDGj.;itt.+WWWKW GLffjjti: t, tDEGLGEEDj; <lambdahack.github.io> tLDLi,ittj+WWWEWG GLffjjti: tt .tDEGGDEDG: ;fEG :iitj+WWWKKK GLfffjti: tt tDDLGDEDGf {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ;jGG :iitj+WWWKDWL DLffjjti: jt.DDLGDEDLD {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ,jDG .ittj+EWWWEDKj DLffjjti: jj.LGDEDLE {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ,jDG ittj+DKKWKDEKf GLffjjti::ff.EEDLE {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ,fGG ittj+ GWKWEDEEt GLffjjji :fL.ELE {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ :tGL ittf+ EEWKKDGDEjt..DLfftjji.,fG:K, {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ,fGj,.tjjf+ EfKGKDLGDDDGDGLffiiti ttf:. {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ .LG;i,;itt+ ..EDKEKEGjiLDDfGLLfijtii;fL: {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ jLj ,;tjtL+. . KLEEKKDGLLLGLGLfffjji,;LL:, {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ tfL.fijffL+......jDKEEKKKKKEDGLffffji;;LL:. {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ EfGii tjff+.......KtGDKEDEEDGLGLfffjti,;Lf: {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{:Df j:jffL.+.......::,E,tjjifL,,LLfffjji.;fL. {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{;iififffL .+....::,;tjLGGGGGLfji;LLfffjjt.,jf.{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{j;i:jfff .+:::::,;;;,iiiiiiii;;;;LLfffjjt,,;LL: ,iiijjfffL ..+::::,,;;;;;;;;;;;;;;;;;GLffffjt;j,jff,:: ;ifLjjijifffL ..+....::,,,,;;;;,,,,,,,,,:GLffffjjt:::tLiL;::. .;LLLLGj;i,ffLLL ...+ ..:::::,,,,,,,,,,,,,, Version X.X.X (frontend: xxx, engine: LambdaHack X.X.X).
GameDefinition/MoveKeys.txt view
@@ -1,6 +1,6 @@-Walk throughout a level with mouse or numeric keypad (left diagram below),-or with its compact laptop replacement (middle) or the Vi editor keys (right)-selectable in config.ui.ini. Run until disturbed with Shift or Control.+Walk throughout a level with mouse or numeric keypad (left diagram below)+or the Vi editor keys (right) or with a compact laptop setup (middle) that+requires enabling in config.ui.ini. Run until disturbed with Shift or Control. Go-to with LMB (left mouse button). Run collectively via S-LMB (holding Shift). 7 8 9 7 8 9 y k u
GameDefinition/PLAYING.md view
@@ -52,7 +52,8 @@ In case of doubt, one of the aiming commands (keypad `/`, with default keybinding) cycles through all visible and remembered items on the level and another (keypad `*`, with default keybinding) through all foes.-The basic terrain kinds are as follows.+Also, pointing at a map position with `MMB` (middle mouse button) displays+a short description of its contents. The basic terrain kinds are as follows. terrain type on-screen symbol wall (horizontal and vertical) - and |@@ -168,9 +169,9 @@ A text snapshot of the complete in-game help is in [InGameHelp.txt](InGameHelp.txt). -Walk throughout a level with mouse or numeric keypad (left diagram below),-or with its compact laptop replacement (middle) or the Vi editor keys (right)-selectable in config.ui.ini. Run until disturbed with Shift or Control.+Walk throughout a level with mouse or numeric keypad (left diagram below)+or the Vi editor keys (right) or with a compact laptop setup (middle) that+requires enabling in config.ui.ini. Run until disturbed with Shift or Control. Go-to with LMB (left mouse button). Run collectively via S-LMB (holding Shift). 7 8 9 7 8 9 y k u@@ -214,14 +215,15 @@ The list includes not only left and right buttons, but also the optional middle mouse button (MMB) and the mouse wheel, which is also used over menus, to page-scroll them.-(For mice without RMB, one can use Control key with LMB.)+(For mice without RMB, one can use Control key with LMB and for mice+without MMB, one can use C-RMB or C-S-LMB.) keys command LMB go to pointer for 25 steps/fling at enemy S-LMB run to pointer collectively for 25 steps/fling at enemy RMB or C-LMB start aiming at enemy under pointer- C-RMB open or close or alter at pointer- MMB snap x-hair to floor under pointer+ S-RMB open or close or alter at pointer+ MMB or C-RMB snap x-hair to floor under pointer WHEEL-UP swerve the aiming line WHEEL-DN unswerve the aiming line @@ -240,7 +242,7 @@ to more than one enemy, setting his target makes him melee a particular foe. You can enter the aiming mode with the `*` keypad key that selects-enemies or the `/` keypad key that cycles among items on the floor+enemies or the `/` key that cycles among items on the floor and marks a tile underneath an item. You can move x-hair with direction keys and assign a personal target to the leader with a `RET` key (Return, Enter). The details of the shared x-hair mark
GameDefinition/config.ui.default view
@@ -26,26 +26,27 @@ HeroName_6 = ("Christopher Flatt", "he") [ui]-movementViKeys_hjklyubn = False+; These two are mutually exclusive:+movementViKeys_hjklyubn = True movementLaptopKeys_uk8o79jl = False-; Monospace fonts that have fixed size regardless of boldness (on some OSes at least)-gtkFontFamily = "DejaVu Sans Mono,Consolas,Courier New,Liberation Mono,Courier,FreeMono,Monospace"+; The font to use for scaling SDL2 display (best by multiples or 0.5): ;sdlFontFile = "16x16xw.woff" scalableFontSize = 16 sdlScalableSizeAdd = 0 sdlFontFile = "16x16xw.bdf" sdlBitmapSizeAdd = 0-;sdlFonSizeAdd is now ignored ;sdlFontFile = "8x8xb.fnt"-;sdlBitmapSizeAdd = 2 ;sdlFontFile = "8x8x.fnt" ;sdlBitmapSizeAdd = 2 ; New historyMax takes effect after removal of savefiles. historyMax = 5000 maxFps = 24 noAnim = False-; runStopMsgs is now ignored hpWarningPercent = 20 ; Uncomment to make all messages white. ; messageColors = [] overrideCmdline = ""+; Legacy: monospace fonts that have fixed size regardless of boldness (on some OSes at least)+gtkFontFamily = "DejaVu Sans Mono,Consolas,Courier New,Liberation Mono,Courier,FreeMono,Monospace"+; sdlFonSizeAdd is now ignored+; runStopMsgs is now ignored
GameDefinition/game-src/Client/UI/Content/Input.hs view
@@ -33,12 +33,12 @@ -- Main menu [ ("e", ([CmdMainMenu], "enter challenges menu>", ChallengesMenu)) , ("s", ([CmdMainMenu], "start new game", GameRestart))- , ("x", ([CmdMainMenu], "exit to desktop", GameExit))+ , ("x", ([CmdMainMenu], "save and exit to desktop", GameExit)) , ("v", ([CmdMainMenu], "visit settings menu>", SettingsMenu))- , ("a", ([CmdMainMenu], "automate faction", Automate))+ , ("t", ([CmdMainMenu], "toggle autoplay (insert coin)", AutomateToggle)) , ("?", ([CmdMainMenu], "see command help", Help))- , ("F12", ([CmdMainMenu], "go to dashboard", Dashboard))- , ("Escape", ([CmdMainMenu], "back to playing", Cancel))+ , ("F12", ([CmdMainMenu], "switch to dashboard", Dashboard))+ , ("Escape", ([CmdMainMenu], "back to playing", AutomateBack)) -- Minimal command set, in the desired presentation order. -- A lot of these are not necessary, but may be familiar to new players.@@ -48,9 +48,10 @@ , ("g", addCmdCategory CmdMinimal $ grabItems "grab item(s)") , ("Escape", ( [CmdMinimal, CmdAim] , "open main menu/finish aiming"- , ByAimMode AimModeCmd { exploration = ExecuteIfClear MainMenu+ , ByAimMode AimModeCmd { exploration =+ ExecuteIfClear MainMenuAutoOff , aiming = Cancel } ))- , ("C-Escape", ([CmdNoHelp], "", MainMenu))+ , ("C-Escape", ([CmdNoHelp], "", MainMenuAutoOn)) -- required by frontends; not shown , ("Return", ( [CmdMinimal, CmdAim] , "open dashboard/accept target"@@ -185,17 +186,21 @@ , "clear chosen item and x-hair" , ComposeUnlessError ClearTargetIfItemClear ItemClear)) - -- Assorted- , ("F12", ([CmdMeta], "open dashboard", Dashboard))+ -- Assorted (first few cloned from main menu)+ , ("C-s", ([CmdMeta], "start new game", GameRestart))+ , ("C-x", ([CmdMeta], "save and exit to desktop", GameExit))+ , ("C-t", ([CmdMeta], "toggle autoplay (insert coin)", Automate))+ , ("C-q", ([CmdMeta], "quit game and start autoplay", GameQuit))+ , ("C-c", ([CmdMeta], "exit to desktop without saving", GameDrop)) , ("?", ([CmdMeta], "display help", Hint)) , ("F1", ([CmdMeta, CmdDashboard], "display help immediately", Help))+ , ("F12", ([CmdMeta], "open dashboard", Dashboard)) , ("v", ([CmdMeta], "voice again the recorded commands", Repeat 1)) , ("V", repeatTriple 100) , ("C-v", repeatTriple 1000) , ("C-V", repeatTriple 25) , ("'", ([CmdMeta], "start recording commands", Record)) , ("C-S", ([CmdMeta], "save game backup", GameSave))- , ("C-c", ([CmdMeta], "exit without saving", GameDrop)) , ("C-P", ([CmdMeta], "print screen", PrintScreen)) -- Dashboard, in addition to commands marked above@@ -210,9 +215,12 @@ "run to pointer collectively for 25 steps/fling at enemy" ) , ("RightButtonRelease", mouseRMB) , ("C-LeftButtonRelease", replaceDesc "" mouseRMB) -- Mac convention- , ( "C-RightButtonRelease"+ , ( "S-RightButtonRelease" , ([CmdMouse], "open or close or alter at pointer", AlterWithPointer []) ) , ("MiddleButtonRelease", mouseMMB)+ , ("C-RightButtonRelease", replaceDesc "" mouseMMB)+ , ( "C-S-LeftButtonRelease",+ addCmdCategory CmdNoHelp $ replaceDesc "" mouseMMB ) , ("WheelNorth", ([CmdMouse], "swerve the aiming line", Macro ["+"])) , ("WheelSouth", ([CmdMouse], "unswerve the aiming line", Macro ["-"])) @@ -247,7 +255,7 @@ , aimFlingCmd )) , ("safe7", ( [CmdInternal, CmdDashboard] , "open main menu"- , MainMenu ))+ , MainMenuAutoOff )) , ("safe8", ( [CmdInternal] , "cancel aiming" , Cancel ))
LambdaHack.cabal view
@@ -6,7 +6,7 @@ -- PVP summary:+-+------- breaking API changes -- | | +----- minor or non-breaking API additions -- | | | +--- code changes with no API change-version: 0.9.4.1+version: 0.9.5.0 synopsis: A game engine library for tactical squad ASCII roguelike dungeon crawlers description: LambdaHack is a Haskell game engine library for ASCII roguelike games of arbitrary theme, size and complexity, with optional@@ -61,12 +61,14 @@ GameDefinition/fonts/Fix15Mono-Bold.woff, GameDefinition/fonts/LICENSE.Fix15Mono-Bold, GameDefinition/InGameHelp.txt,+ GameDefinition/PLAYING.md, README.md, CHANGELOG.md, LICENSE, COPYLEFT, CREDITS-extra-source-files: GameDefinition/MainMenu.ascii,+extra-source-files: GameDefinition/config.ui.default,+ GameDefinition/MainMenu.ascii, GameDefinition/MoveKeys.txt, GameDefinition/PLAYING.md, Makefile
Makefile view
@@ -29,10 +29,10 @@ google-chrome --no-sandbox --js-flags="--logfile=%t.log --prof" ../lambdahack.github.io/index.html minific:- npx google-closure-compiler dist-newstyle/build/x86_64-linux/ghcjs-8.6.0.1/LambdaHack-0.9.4.0/x/LambdaHack/build/LambdaHack/LambdaHack.jsexe/all.js --compilation_level=ADVANCED_OPTIMIZATIONS --isolation_mode=IIFE --assume_function_wrapper --externs=dist-newstyle/build/x86_64-linux/ghcjs-8.6.0.1/LambdaHack-0.9.4.0/x/LambdaHack/build/LambdaHack/LambdaHack.jsexe/all.js.externs --jscomp_off="*" > ../lambdahack.github.io/lambdahack.all.js+ npx google-closure-compiler dist-newstyle/build/x86_64-linux/ghcjs-8.6.0.1/LambdaHack-0.9.5.0/x/LambdaHack/build/LambdaHack/LambdaHack.jsexe/all.js --compilation_level=ADVANCED_OPTIMIZATIONS --isolation_mode=IIFE --assume_function_wrapper --externs=dist-newstyle/build/x86_64-linux/ghcjs-8.6.0.1/LambdaHack-0.9.5.0/x/LambdaHack/build/LambdaHack/LambdaHack.jsexe/all.js.externs --jscomp_off="*" > ../lambdahack.github.io/lambdahack.all.js minificForNode:- npx google-closure-compiler dist-newstyle/build/x86_64-linux/ghcjs-8.6.0.1/LambdaHack-0.9.4.0/x/LambdaHack/build/LambdaHack/LambdaHack.jsexe/all.js --compilation_level=ADVANCED_OPTIMIZATIONS --isolation_mode=IIFE --assume_function_wrapper --externs=dist-newstyle/build/x86_64-linux/ghcjs-8.6.0.1/LambdaHack-0.9.4.0/x/LambdaHack/build/LambdaHack/LambdaHack.jsexe/all.js.externs --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/assert.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/child_process.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/crypto.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/dns.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/events.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/globals.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/https.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/os.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/punycode.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/readline.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/stream.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/tls.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/url.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/vm.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/buffer.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/cluster.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/dgram.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/domain.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/fs.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/http.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/net.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/path.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/querystring.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/repl.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/string_decoder.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/tty.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/util.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/zlib.js --jscomp_off="*" > ../lambdahack.github.io/lambdahack.all.js+ npx google-closure-compiler dist-newstyle/build/x86_64-linux/ghcjs-8.6.0.1/LambdaHack-0.9.5.0/x/LambdaHack/build/LambdaHack/LambdaHack.jsexe/all.js --compilation_level=ADVANCED_OPTIMIZATIONS --isolation_mode=IIFE --assume_function_wrapper --externs=dist-newstyle/build/x86_64-linux/ghcjs-8.6.0.1/LambdaHack-0.9.5.0/x/LambdaHack/build/LambdaHack/LambdaHack.jsexe/all.js.externs --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/assert.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/child_process.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/crypto.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/dns.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/events.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/globals.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/https.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/os.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/punycode.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/readline.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/stream.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/tls.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/url.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/vm.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/buffer.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/cluster.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/dgram.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/domain.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/fs.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/http.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/net.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/path.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/querystring.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/repl.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/string_decoder.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/tty.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/util.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/zlib.js --jscomp_off="*" > ../lambdahack.github.io/lambdahack.all.js # Low delay to display animations swiftly and not bore the public too much. # Delay can't be lower than 2, because browsers sometimes treat delay 1@@ -259,8 +259,8 @@ cp GameDefinition/fonts/LICENSE.16x16x LambdaHackTheGame/GameDefinition/fonts cp GameDefinition/fonts/Fix15Mono-Bold.woff LambdaHackTheGame/GameDefinition/fonts cp GameDefinition/fonts/LICENSE.Fix15Mono-Bold LambdaHackTheGame/GameDefinition/fonts- cp GameDefinition/PLAYING.md LambdaHackTheGame/GameDefinition cp GameDefinition/InGameHelp.txt LambdaHackTheGame/GameDefinition+ cp GameDefinition/PLAYING.md LambdaHackTheGame/GameDefinition cp README.md LambdaHackTheGame cp CHANGELOG.md LambdaHackTheGame cp LICENSE LambdaHackTheGame
README.md view
@@ -83,19 +83,14 @@ (which takes a long time). Hence, after trying out the game, you may prefer to use a native binary for your architecture, if it exists. -Pre-compiled game binaries are available through the release page[11].+Pre-compiled game binaries are available through the release page[11]+(and, for Windows, dev versions continuously from AppVeyor[18]). To use a pre-compiled binary archive, unpack it and run the executable in the unpacked directory or use program shortcuts from the installer,-if available.--On Linux, make sure you have the SDL2 libraries installed on your system-(e.g., libsdl2-2.0-0 and libsdl2-ttf-2.0-0 on Ubuntu).-On Mac OS X, you need SDL2 installed, e.g.,-from [libsdlorg](https://www.libsdl.org/download-2.0.php).-For Windows, the SDL2 and all other needed libraries are already-contained in the game's binary archive.-Note that Windows binaries no longer work on Windows XP, since Cygwin-and MSYS2 dropped support for XP.+if available. On Linux, make sure you have the SDL2 libraries installed+on your system (e.g., libsdl2-2.0-0 and libsdl2-ttf-2.0-0 on Ubuntu).+For Windows (XP no longer supported), the SDL2 and all other needed libraries+are already contained in the game's binary archive. Screen and keyboard configuration@@ -122,9 +117,9 @@ With `scalableFontSize = 16` it should look almost the same as the pixel-perfect `16x16xw.bdf`. -If you don't have a numeric keypad, you can use mouse for movement-or you can enable the compact laptop keys (uk8o79jl) or the Vi keys-(aka roguelike keys) in the config file. If numeric keypad doesn't work,+If you don't have a numeric keypad, you can use the Vi editor keys+(aka roguelike keys) or mouse for movement or you can enable the compact+laptop keys (uk8o79jl) in the config file. If numeric keypad doesn't work, toggling the Num Lock key sometimes helps. If running with the Shift key and keypad keys doesn't work, try Control key instead. The game is fully playable with mouse only, as well as with keyboard only,
definition-src/Game/LambdaHack/Content/ModeKind.hs view
@@ -227,7 +227,7 @@ | not $ null hardwiredAbsent ] hardwiredModeGroups :: [GroupName ModeKind]-hardwiredModeGroups = ["campaign scenario", "starting"]+hardwiredModeGroups = ["campaign scenario", "insert coin"] makeData :: ContentData CaveKind -> ContentData ItemKind
definition-src/Game/LambdaHack/Definition/Color.hs view
@@ -133,6 +133,7 @@ | HighlightYellow | HighlightYellowAim | HighlightRedAim+ | HighlightNoneCursor deriving (Show, Eq, Ord, Enum, Bounded, Generic) highlightToColor :: Highlight -> Color@@ -147,6 +148,7 @@ HighlightYellow -> BrYellow -- obscures, but mostly used around bright white HighlightYellowAim -> BrYellow HighlightRedAim -> Red+ HighlightNoneCursor -> Black -- | Text attributes: foreground color and highlight. data Attr = Attr
engine-src/Game/LambdaHack/Client/State.hs view
@@ -26,12 +26,12 @@ import Game.LambdaHack.Common.Faction import Game.LambdaHack.Common.Item import Game.LambdaHack.Common.Perception+import Game.LambdaHack.Common.Point+import qualified Game.LambdaHack.Common.PointArray as PointArray import Game.LambdaHack.Common.State import Game.LambdaHack.Common.Types import Game.LambdaHack.Common.Vector import Game.LambdaHack.Content.ModeKind (ModeKind)-import Game.LambdaHack.Common.Point-import qualified Game.LambdaHack.Common.PointArray as PointArray import Game.LambdaHack.Definition.Defs -- | Client state, belonging to a single faction.
engine-src/Game/LambdaHack/Client/UI.hs view
@@ -66,8 +66,8 @@ recordHistory keyPressed <- anyKeyPressed if keyPressed && fleaderMode (gplayer fact) /= LeaderNull then do+ -- Menu is entered in @displayRespUpdAtomicUI@ at @UpdAutoFaction@. discardPressedKey- addPressedControlEsc -- Regaining control of faction cancels --stopAfter*. modifyClient $ \cli -> cli {soptions = (soptions cli) { sstopAfterSeconds = Nothing@@ -124,8 +124,8 @@ report <- getsSession $ newReport . shistory hintMode <- getsSession shintMode -- Hints are not considered non-empty reports.- modifySession $ \sess -> sess {sreportNull =- nullReport report || hintMode == HintShown}+ modifySession $ \sess -> sess+ {sreportNull = nullReport report || hintMode == HintShown} case hintMode of HintAbsent -> return () HintShown -> modifySession $ \sess -> sess {shintMode = HintWiped}
engine-src/Game/LambdaHack/Client/UI/Content/Input.hs view
@@ -157,7 +157,7 @@ [ (CaMapLeader, dropCmd) , (CaMapParty, SelectWithPointer) , (CaMap, AimPointerEnemy)- , (CaArenaName, MainMenu)+ , (CaArenaName, MainMenuAutoOff) , (CaPercentSeen, autoexplore25Cmd) ] , aiming = ByArea $ common ++ [ (CaMap, XhairPointerEnemy) -- hack; same effect, but matches LMB
engine-src/Game/LambdaHack/Client/UI/DisplayAtomicM.hs view
@@ -300,7 +300,9 @@ side <- getsClient sside lidV <- viewedLevelUI markDisplayNeeded lidV- when (fid == side) $ setFrontAutoYes b+ when (fid == side) $ do+ unless b $ addPressedControlEsc -- sets @swasAutomated@, enters main menu+ setFrontAutoYes b -- now can stop auto-accepting prompts UpdRecordKill{} -> return () -- Alter map. UpdAlterTile lid p fromTile toTile -> do@@ -437,12 +439,8 @@ unless (T.null desc) $ do msgAdd MsgPromptFocus "You remember your surroundings." msgAdd MsgPrompt desc- msgAdd MsgAlert "Are you up for the challenge?"- slides <- reportToSlideshow [K.spaceKM, K.escKM]- km <- getConfirms ColorFull [K.spaceKM, K.escKM] slides- if km == K.escKM- then addPressedControlEsc- else promptAdd0 "Prove yourself!"+ displayMore ColorFull "Are you up for the challenge?"+ promptAdd0 "Prove yourself!" UpdResumeServer{} -> return () UpdKillExit{} -> frontendShutdown UpdWriteSave -> msgAdd MsgSpam "Saving backup."
engine-src/Game/LambdaHack/Client/UI/FrameM.hs view
@@ -97,9 +97,12 @@ -- at the nearest @stopPlayBack@, etc. modifySession $ \sess -> sess {srunning = Nothing} frontKeyFrame <- drawOverlay dm onBlank ov lidV- when (dm /= ColorFull)- -- Forget the furious keypresses just before a special event.- resetPressedKeys+ when (dm /= ColorFull) $ do+ side <- getsClient sside+ fact <- getsState $ (EM.! side) . sfactionD+ unless (isAIFact fact) $ -- don't forget special autoplay keypresses+ -- Forget the furious keypresses just before a special event.+ resetPressedKeys recordHistory connFrontendFrontKey frontKeyKeys frontKeyFrame LastRecord seqCurrent seqPrevious k <- getsSession slastRecord
engine-src/Game/LambdaHack/Client/UI/Frontend/Common.hs view
@@ -86,6 +86,7 @@ -- | Translates modifiers to our own encoding. modifierTranslate :: Bool -> Bool -> Bool -> Bool -> K.Modifier modifierTranslate modCtrl modShift modAlt modMeta+ | modCtrl && modShift = K.ControlShift | modCtrl = K.Control | modAlt || modMeta = K.Alt | modShift = K.Shift
engine-src/Game/LambdaHack/Client/UI/Frontend/Curses.hs view
@@ -111,7 +111,8 @@ Color.HighlightRedAim -> if fg /= Color.Red then (fg, Color.Red)- else (fg, Color.defFG) ]+ else (fg, Color.defFG)+ Color.HighlightNoneCursor -> (fg, Color.Black) ] C.refresh keyTranslate :: C.Key -> K.KM
engine-src/Game/LambdaHack/Client/UI/Frontend/Dom.hs view
@@ -104,8 +104,7 @@ modAlt <- ask >>= getAltKey modMeta <- ask >>= getMetaKey modAltG <- ask >>= getAltGraphKey- return $! modifierTranslate- modCtrl modShift (modAlt || modAltG) modMeta+ return $! modifierTranslate modCtrl modShift (modAlt || modAltG) modMeta void $ doc `on` keyDown $ do keyId <- ask >>= getKey modifier <- readMod@@ -115,8 +114,10 @@ -- 3 {-KEY_LOCATION_NUMPAD-} -> True -- _ -> False let key = K.keyTranslateWeb keyId (modifier == K.Shift)- modifierNoShift = -- to prevent S-!, etc.- if modifier == K.Shift then K.NoModifier else modifier+ modifierNoShift = case modifier of -- to prevent S-!, etc.+ K.Shift -> K.NoModifier+ K.ControlShift -> K.Control+ _ -> modifier -- IO.liftIO $ do -- putStrLn $ "keyId: " ++ keyId -- putStrLn $ "key: " ++ K.showKey key@@ -126,7 +127,8 @@ -- Pass through C-+ and others, but disable special behaviour on Tab, etc. let browserKeys = "+-0tTnNdxcv" unless (modifier == K.Alt- || modifier == K.Control && key `elem` map K.Char browserKeys) $ do+ || modifier == K.Control && key `elem` map K.Char browserKeys+ || key == K.DeadKey) $ do -- NumLock in particular preventDefault stopPropagation -- Handle mouseclicks, per-cell.
engine-src/Game/LambdaHack/Client/UI/Frontend/Gtk.hs view
@@ -75,6 +75,7 @@ if fg /= Color.Red then (fg, Color.Red) else (fg, Color.defFG)+ Color.HighlightNoneCursor -> (fg, Color.Black) ttt <- textTagTableNew stags <- IM.fromDistinctAscList <$> mapM (\ak -> do@@ -105,9 +106,11 @@ n <- eventKeyName mods <- eventModifier let key = K.keyTranslate $ T.unpack n- modifier =- let md = modTranslate mods- in if md == K.Shift then K.NoModifier else md+ md = modTranslate mods+ modifier = case modifier of -- to prevent S-!, etc.+ K.Shift -> K.NoModifier+ K.ControlShift -> K.Control+ _ -> modifier pointer = originPoint when (key == K.Esc) $ IO.liftIO $ resetChanKey (fchanKey rf) IO.liftIO $ saveKMP rf modifier key pointer
engine-src/Game/LambdaHack/Client/UI/Frontend/Sdl.hs view
@@ -218,8 +218,10 @@ || SDL.keyModifierRightShift ksm key = keyTranslate shiftPressed $ SDL.keysymKeycode sym modifier = modTranslate ksm- modifierNoShift = -- to prevent S-!, etc.- if modifier == K.Shift then K.NoModifier else modifier+ modifierNoShift = case modifier of -- to prevent S-!, etc.+ K.Shift -> K.NoModifier+ K.ControlShift -> K.Control+ _ -> modifier p <- SDL.getAbsoluteMouseLocation when (key == K.Esc) $ resetChanKey (fchanKey rf) saveKMP rf modifierNoShift key (pointTranslate p)
engine-src/Game/LambdaHack/Client/UI/Frontend/Vty.hs view
@@ -139,6 +139,7 @@ if fg /= Color.Red then (fg, Color.Red) else (fg, Color.defFG)+ Color.HighlightNoneCursor -> (fg, Color.Black) in hack fg1 $ hack bg1 $ defAttr { attrForeColor = SetTo (aToc fg1) , attrBackColor = SetTo (aToc bg1) }
engine-src/Game/LambdaHack/Client/UI/HandleHumanGlobalM.hs view
@@ -16,11 +16,12 @@ , moveItemHuman, projectHuman, applyHuman , alterDirHuman, alterWithPointerHuman , helpHuman, hintHuman, dashboardHuman, itemMenuHuman, chooseItemMenuHuman- , mainMenuHuman, settingsMenuHuman, challengesMenuHuman+ , mainMenuHuman, mainMenuAutoOnHuman, mainMenuAutoOffHuman+ , settingsMenuHuman, challengesMenuHuman , gameScenarioIncr, gameDifficultyIncr, gameWolfToggle, gameFishToggle -- * Global commands that never take time- , gameRestartHuman, gameDropHuman, gameExitHuman, gameSaveHuman- , tacticHuman, automateHuman+ , gameRestartHuman, gameQuitHuman, gameDropHuman, gameExitHuman, gameSaveHuman+ , tacticHuman, automateHuman, automateToggleHuman, automateBackHuman #ifdef EXPOSE_INTERNAL -- * Internal operations , areaToRectangles, meleeAid, displaceAid, moveSearchAlter, goToXhair@@ -1325,14 +1326,15 @@ -> m (Either MError ReqUI) generateMenu cmdAction kds gameInfo menuName = do art <- artWithVersion- let bindingLen = 30+ let bindingLen = 35 emptyInfo = repeat $ replicate bindingLen ' ' bindings = -- key bindings to display let fmt (k, (d, _)) = ( Just k , T.unpack $ T.justifyLeft bindingLen ' '- $ T.justifyLeft 3 ' ' (T.pack $ K.showKM k) <> " " <> d )+ $ " " <> T.justifyLeft 4 ' ' (T.pack $ K.showKM k)+ <> " " <> d ) in map fmt kds overwrite :: [(Int, String)] -> [(String, Maybe KYX)] overwrite = -- overwrite the art with key bindings and other lines@@ -1379,15 +1381,35 @@ kds = (K.mkKM "p", (tnextScenario, GameScenarioIncr)) : [ (km, (desc, cmd)) | (km, ([CmdMainMenu], desc, cmd)) <- bcmdList ]- bindingLen = 30+ bindingLen = 35 gameName = mname gameMode gameInfo = map T.unpack [ T.justifyLeft bindingLen ' ' "" , T.justifyLeft bindingLen ' '- $ "Now playing:" <+> gameName+ $ " Now playing:" <+> gameName , T.justifyLeft bindingLen ' ' "" ] generateMenu cmdAction kds gameInfo "main" +-- * MainMenuAutoOn++-- | Display the main menu and set @swasAutomated@.+mainMenuAutoOnHuman :: MonadClientUI m+ => (HumanCmd -> m (Either MError ReqUI))+ -> m (Either MError ReqUI)+mainMenuAutoOnHuman cmdAction = do+ modifySession $ \sess -> sess {swasAutomated = True}+ mainMenuHuman cmdAction++-- * MainMenuAutoOff++-- | Display the main menu and unset @swasAutomated@.+mainMenuAutoOffHuman :: MonadClientUI m+ => (HumanCmd -> m (Either MError ReqUI))+ -> m (Either MError ReqUI)+mainMenuAutoOffHuman cmdAction = do+ modifySession $ \sess -> sess {swasAutomated = False}+ mainMenuHuman cmdAction+ -- * SettingsMenu -- | Display the settings menu.@@ -1402,24 +1424,24 @@ factTactic <- getsState $ ftactic . gplayer . (EM.! side) . sfactionD let offOn b = if b then "on" else "off" offOnAll n = case n of- 0 -> "low"- 1 -> "medium"- 2 -> "high"+ 0 -> "none"+ 1 -> "untried"+ 2 -> "all" _ -> error $ "" `showFailure` n- tsuspect = "suspect terrain:" <+> offOnAll markSuspect- tvisible = "visible zone:" <+> offOn markVision- tsmell = "smell clues:" <+> offOn markSmell- thenchmen = "tactic:" <+> Ability.nameTactic factTactic+ tsuspect = "mark suspect terrain:" <+> offOnAll markSuspect+ tvisible = "show visible zone:" <+> offOn markVision+ tsmell = "display smell clues:" <+> offOn markSmell+ thenchmen = "henchmen tactic:" <+> Ability.nameTactic factTactic -- Key-description-command tuples. kds = [ (K.mkKM "s", (tsuspect, MarkSuspect)) , (K.mkKM "v", (tvisible, MarkVision)) , (K.mkKM "c", (tsmell, MarkSmell)) , (K.mkKM "t", (thenchmen, Tactic)) , (K.mkKM "Escape", ("back to main menu", MainMenu)) ]- bindingLen = 30+ bindingLen = 35 gameInfo = map T.unpack [ T.justifyLeft bindingLen ' ' ""- , T.justifyLeft bindingLen ' ' "Convenience settings:"+ , T.justifyLeft bindingLen ' ' " Convenience settings:" , T.justifyLeft bindingLen ' ' "" ] generateMenu cmdAction kds gameInfo "settings" @@ -1433,30 +1455,30 @@ curChal <- getsClient scurChal nxtChal <- getsClient snxtChal let offOn b = if b then "on" else "off"- tcurDiff = "* difficulty:" <+> tshow (cdiff curChal)- tnextDiff = "difficulty:" <+> tshow (cdiff nxtChal)- tcurWolf = "* lone wolf:"+ tcurDiff = " * difficulty:" <+> tshow (cdiff curChal)+ tnextDiff = "difficulty (lower easier):" <+> tshow (cdiff nxtChal)+ tcurWolf = " * lone wolf:" <+> offOn (cwolf curChal)- tnextWolf = "lone wolf:"+ tnextWolf = "lone wolf (very hard):" <+> offOn (cwolf nxtChal)- tcurFish = "* cold fish:"+ tcurFish = " * cold fish:" <+> offOn (cfish curChal)- tnextFish = "cold fish:"+ tnextFish = "cold fish (hard):" <+> offOn (cfish nxtChal) -- Key-description-command tuples. kds = [ (K.mkKM "d", (tnextDiff, GameDifficultyIncr)) , (K.mkKM "w", (tnextWolf, GameWolfToggle)) , (K.mkKM "f", (tnextFish, GameFishToggle)) , (K.mkKM "Escape", ("back to main menu", MainMenu)) ]- bindingLen = 30+ bindingLen = 35 gameInfo = map T.unpack- [ T.justifyLeft bindingLen ' ' "Current challenges:"+ [ T.justifyLeft bindingLen ' ' " Current challenges:" , T.justifyLeft bindingLen ' ' "" , T.justifyLeft bindingLen ' ' tcurDiff , T.justifyLeft bindingLen ' ' tcurWolf , T.justifyLeft bindingLen ' ' tcurFish , T.justifyLeft bindingLen ' ' ""- , T.justifyLeft bindingLen ' ' "Next game challenges:"+ , T.justifyLeft bindingLen ' ' " Next game challenges:" , T.justifyLeft bindingLen ' ' "" ] generateMenu cmdAction kds gameInfo "challenge" @@ -1471,7 +1493,7 @@ gameDifficultyIncr :: MonadClient m => m () gameDifficultyIncr = do nxtDiff <- getsClient $ cdiff . snxtChal- let delta = 1+ let delta = -1 d | nxtDiff + delta > difficultyBound = 1 | nxtDiff + delta < 1 = difficultyBound | otherwise = nxtDiff + delta@@ -1526,6 +1548,28 @@ campaignModes = ofoldlGroup' comode "campaign scenario" f [] in campaignModes !! (snxtScenario `mod` length campaignModes) +-- * GameQuit++-- TODO: deduplicate with gameRestartHuman+gameQuitHuman :: MonadClientUI m => m (FailOrCmd ReqUI)+gameQuitHuman = do+ isNoConfirms <- isNoConfirmsGame+ gameMode <- getGameMode+ b <- if isNoConfirms+ then return True+ else displayYesNo ColorBW+ $ "If you quit, the progress of the ongoing" <+> mname gameMode+ <+> "game will be lost! Are you sure?"+ if b+ then do+ snxtChal <- getsClient snxtChal+ return $ Right $ ReqUIGameRestart "insert coin" snxtChal+ else do+ msg2 <- rndToActionForget $ oneOf+ [ "yea, would be a pity to leave them to die"+ , "yea, a shame to get your team stranded" ]+ failWith msg2+ -- * GameDrop gameDropHuman :: MonadClientUI m => m ReqUI@@ -1580,7 +1624,25 @@ automateHuman = do clearAimMode go <- displaySpaceEsc ColorBW- "Ceding control to AI (press ESC to regain)."+ "Ceding control to AI (press SPACE to confirm, ESC to cancel)." if not go then failWith "automation canceled" else return $ Right ReqUIAutomate++-- * AutomateToggle++automateToggleHuman :: MonadClientUI m => m (FailOrCmd ReqUI)+automateToggleHuman = do+ swasAutomated <- getsSession swasAutomated+ if swasAutomated+ then failWith "automation canceled"+ else automateHuman++-- * AutomateBack++automateBackHuman :: MonadClientUI m => m (Either MError ReqUI)+automateBackHuman = do+ swasAutomated <- getsSession swasAutomated+ return $! if swasAutomated+ then Right ReqUIAutomate+ else Left Nothing
engine-src/Game/LambdaHack/Client/UI/HandleHumanM.hs view
@@ -95,6 +95,8 @@ ItemMenu -> itemMenuHuman cmdAction ChooseItemMenu dialogMode -> chooseItemMenuHuman cmdAction dialogMode MainMenu -> mainMenuHuman cmdAction+ MainMenuAutoOn -> mainMenuAutoOnHuman cmdAction+ MainMenuAutoOff -> mainMenuAutoOffHuman cmdAction Dashboard -> dashboardHuman cmdAction GameDifficultyIncr -> gameDifficultyIncr >> challengesMenuHuman cmdAction GameWolfToggle -> gameWolfToggle >> challengesMenuHuman cmdAction@@ -102,11 +104,14 @@ GameScenarioIncr -> gameScenarioIncr >> mainMenuHuman cmdAction GameRestart -> weaveJust <$> gameRestartHuman+ GameQuit -> weaveJust <$> gameQuitHuman GameDrop -> weaveJust <$> fmap Right gameDropHuman GameExit -> weaveJust <$> fmap Right gameExitHuman GameSave -> weaveJust <$> fmap Right gameSaveHuman Tactic -> weaveJust <$> tacticHuman Automate -> weaveJust <$> automateHuman+ AutomateToggle -> weaveJust <$> automateToggleHuman+ AutomateBack -> automateBackHuman ChooseItem dialogMode -> Left <$> chooseItemHuman dialogMode ChooseItemProject ts -> Left <$> chooseItemProjectHuman ts
engine-src/Game/LambdaHack/Client/UI/HumanCmd.hs view
@@ -130,6 +130,8 @@ | Hint | ItemMenu | MainMenu+ | MainMenuAutoOn+ | MainMenuAutoOff | Dashboard -- Below this line, commands do not take time. | GameDifficultyIncr@@ -137,11 +139,14 @@ | GameFishToggle | GameScenarioIncr | GameRestart+ | GameQuit | GameDrop | GameExit | GameSave | Tactic | Automate+ | AutomateToggle+ | AutomateBack -- Local. Below this line, commands do not notify the server. | ChooseItem ItemDialogMode | ChooseItemMenu ItemDialogMode
engine-src/Game/LambdaHack/Client/UI/Key.hs view
@@ -7,7 +7,7 @@ , pgupKM, pgdnKM, wheelNorthKM, wheelSouthKM , upKM, downKM, leftKM, rightKM , homeKM, endKM, backspaceKM, controlP- , leftButtonReleaseKM, rightButtonReleaseKM+ , leftButtonReleaseKM, middleButtonReleaseKM, rightButtonReleaseKM , dirAllKey, handleDir, moveBinding, mkKM, mkChar, mkKP , keyTranslate, keyTranslateWeb #ifdef EXPOSE_INTERNAL@@ -73,6 +73,7 @@ -- | Our own encoding of modifiers. data Modifier = NoModifier+ | ControlShift | Shift | Control | Alt@@ -134,10 +135,11 @@ -- | Show a key with a modifier, if any. showKM :: KM -> String+showKM KM{modifier=NoModifier, key} = showKey key+showKM KM{modifier=ControlShift, key} = "C-S-" ++ showKey key showKM KM{modifier=Shift, key} = "S-" ++ showKey key showKM KM{modifier=Control, key} = "C-" ++ showKey key showKM KM{modifier=Alt, key} = "A-" ++ showKey key-showKM KM{modifier=NoModifier, key} = showKey key escKM :: KM escKM = KM NoModifier Esc@@ -196,6 +198,9 @@ leftButtonReleaseKM :: KM leftButtonReleaseKM = KM NoModifier LeftButtonRelease +middleButtonReleaseKM :: KM+middleButtonReleaseKM = KM NoModifier MiddleButtonRelease+ rightButtonReleaseKM :: KM rightButtonReleaseKM = KM NoModifier RightButtonRelease @@ -277,6 +282,8 @@ Unknown _ -> error $ "unknown key" `showFailure` s key -> key in case s of+ 'C':'-':'S':'-':rest -> KM ControlShift (mkKey rest)+ 'S':'-':'C':'-':rest -> KM ControlShift (mkKey rest) 'S':'-':rest -> KM Shift (mkKey rest) 'C':'-':rest -> KM Control (mkKey rest) 'A':'-':rest -> KM Alt (mkKey rest)@@ -429,7 +436,9 @@ keyTranslate "ISO_Level2_Latch" = DeadKey keyTranslate "ISO_Level3_Latch" = DeadKey keyTranslate "Num_Lock" = DeadKey+keyTranslate "NumLock" = DeadKey keyTranslate "Caps_Lock" = DeadKey+keyTranslate "CapsLock" = DeadKey keyTranslate "VoidSymbol" = DeadKey -- numeric keypad keyTranslate ['K','P','_',c] = KP c@@ -519,6 +528,8 @@ keyTranslateWeb "Alt" _ = DeadKey keyTranslateWeb "AltGraph" _ = DeadKey keyTranslateWeb "Num_Lock" _ = DeadKey+keyTranslateWeb "NumLock" _ = DeadKey+keyTranslateWeb "Caps_Lock" _ = DeadKey keyTranslateWeb "CapsLock" _ = DeadKey keyTranslateWeb "Win" _ = DeadKey -- browser quirks
engine-src/Game/LambdaHack/Client/UI/KeyBindings.hs view
@@ -39,7 +39,7 @@ : map T.pack rintroScreen ++ [ ""- , "Press SPACE for help or ESC to see the map again."+ , "Press SPACE or PGDN for help and ESC to see the map again." ] movBlurb = map T.pack rmoveKeysScreen movBlurbEnd =@@ -101,7 +101,8 @@ , "The list includes not only left and right buttons, but also" , "the optional middle mouse button (MMB) and the mouse wheel," , "which is also used over menus, to page-scroll them."- , "(For mice without RMB, one can use Control key with LMB.)"+ , "(For mice without RMB, one can use Control key with LMB and for mice"+ , "without MMB, one can use C-RMB or C-S-LMB.)" , "Next we show mouse button effects per screen area," , "in exploration mode and (if different) in aiming mode." , ""@@ -112,9 +113,8 @@ ] lastHelpEnding = [ ""- , "For more playing instructions see file PLAYING.md."- , "Press PGUP or scroll the mouse wheel to return to previous pages"- , "and press SPACE or ESC to see the map again."+ , "For more playing instructions see file PLAYING.md. Press PGUP or scroll"+ , "mouse wheel for previous pages and press SPACE or ESC to see the map again." ] keyL = 12 pickLeaderDescription =@@ -203,7 +203,7 @@ else [ ( casualDescription <> "." , okxs CmdMinimal- (movText ++ ["", ""] ++ minimalText ++ [keyCaption])+ (movText ++ [""] ++ minimalText ++ [keyCaption]) casualEnd ) ] , if catLength CmdItemMenu + catLength CmdItem + 9 > rheight then
engine-src/Game/LambdaHack/Client/UI/MonadClientUI.hs view
@@ -66,14 +66,14 @@ import Game.LambdaHack.Common.Kind import Game.LambdaHack.Common.Misc import Game.LambdaHack.Common.MonadStateRead+import Game.LambdaHack.Common.Point+import qualified Game.LambdaHack.Common.PointArray as PointArray import qualified Game.LambdaHack.Common.Save as Save import Game.LambdaHack.Common.State import Game.LambdaHack.Common.Time import Game.LambdaHack.Common.Types import Game.LambdaHack.Content.ModeKind import Game.LambdaHack.Content.RuleKind-import Game.LambdaHack.Common.Point-import qualified Game.LambdaHack.Common.PointArray as PointArray import qualified Game.LambdaHack.Definition.Ability as Ability import Game.LambdaHack.Definition.Defs @@ -193,7 +193,7 @@ fact <- getsState $ (EM.! side) . sfactionD let underAI = isAIFact fact mem = EM.fromList <$> uMessageColors sUIOptions- promptAI = toMsg mem MsgPrompt "[press ESC for main menu]"+ promptAI = toMsg mem MsgPrompt "[press any key for main menu]" return $! if underAI then consReport promptAI report else report getLeaderUI :: MonadClientUI m => m ActorId
engine-src/Game/LambdaHack/Client/UI/MsgM.hs view
@@ -64,6 +64,7 @@ kmItemEqp = revCmd K.undefinedKM (HumanCmd.MoveItem [CGround, CInv, CSha] CEqp Nothing False)+ kmXhairPointerFloor = revCmd K.undefinedKM HumanCmd.XhairPointerFloor saimMode <- getsSession saimMode UIOptions{uVi, uLaptop} <- getsSession sUIOptions xhair <- getsSession sxhair@@ -76,14 +77,19 @@ keepTab = if manyTeammates then "Keep TAB of teammates (S-TAB for other levels)." else ""+ describePos = if mmbIsNormal+ then "Describe map position with MMB."+ else "" viewEquip = if eqpKeysAreNormal then "View (E)quipment and (e)quip items." else "" moreHelp = "Press" <+> tshow kmHelp <+> "for help."+ mmbIsNormal = kmXhairPointerFloor == K.middleButtonReleaseKM eqpKeysAreNormal = kmViewEqp == K.mkChar 'E' && kmItemEqp == K.mkChar 'e' keys | isNothing saimMode = "Explore with" <+> moveKeys <+> "keys or mouse."+ <+> describePos <+> viewEquip <+> keepTab <+> moreHelp
engine-src/Game/LambdaHack/Client/UI/SessionUI.hs view
@@ -24,10 +24,10 @@ import qualified Game.LambdaHack.Client.UI.Key as K import Game.LambdaHack.Client.UI.Msg import Game.LambdaHack.Client.UI.UIOptions-import Game.LambdaHack.Definition.Defs import Game.LambdaHack.Common.Point import Game.LambdaHack.Common.Time import Game.LambdaHack.Common.Types+import Game.LambdaHack.Definition.Defs -- | The information that is used across a client playing session, -- including many consecutive games in a single session.@@ -59,6 +59,7 @@ , slastLost :: ES.EnumSet ActorId -- ^ actors that just got out of sight , swaitTimes :: Int -- ^ player just waited this many times+ , swasAutomated :: Bool -- ^ the player just exited AI automation , smarkVision :: Bool -- ^ mark leader and party FOV , smarkSmell :: Bool -- ^ mark smell, if the leader can smell , smenuIxMap :: M.Map String Int@@ -130,6 +131,7 @@ , slastPlay = [] , slastLost = ES.empty , swaitTimes = 0+ , swasAutomated = False , smarkVision = False , smarkSmell = True , smenuIxMap = M.singleton "main" (2 - 9) -- subtracting @initIx@@@ -193,6 +195,7 @@ slastPlay = [] slastLost = ES.empty swaitTimes = 0+ swasAutomated = False smenuIxMap = M.singleton "main" (2 - 9) -- subtracting @initIx@ sreportNull = True shintMode = HintAbsent
engine-src/Game/LambdaHack/Client/UI/SlideshowM.hs view
@@ -140,13 +140,22 @@ highAttr x | Color.acAttr x `notElem` highableAttrs = x highAttr x = x {Color.acAttr = (Color.acAttr x) {Color.fg = Color.BrWhite}}+ cursorAttr x = x {Color.acAttr =+ (Color.acAttr x)+ {Color.bg = Color.HighlightNoneCursor}} drawHighlight xs = let (xs1, xsRest) = splitAt x1 xs (xs2, xs3) = splitAt (x2 - x1) xsRest highW32 = Color.attrCharToW32 . highAttr . Color.attrCharFromW32- in xs1 ++ map highW32 xs2 ++ xs3+ cursorW32 = Color.attrCharToW32+ . cursorAttr+ . Color.attrCharFromW32+ xs2High = case map highW32 xs2 of+ [] -> []+ xh : xhrest -> cursorW32 xh : xhrest+ in xs1 ++ xs2High ++ xs3 ov1 = updateLines y drawHighlight ov ignoreKey = page pointer pageLen = length kyxs
engine-src/Game/LambdaHack/Common/Save.hs view
@@ -1,9 +1,10 @@ -- | Saving and restoring game state, used by both server and clients. module Game.LambdaHack.Common.Save ( ChanSave, saveToChan, wrapInSaves, restoreGame, saveNameCli, saveNameSer+ , compatibleVersion #ifdef EXPOSE_INTERNAL -- * Internal operations- , loopSave, compatibleVersion, delayPrint+ , loopSave, delayPrint #endif ) where
engine-src/Game/LambdaHack/Server/LoopM.hs view
@@ -584,11 +584,10 @@ mainUIactor = fhasUI (gplayer fact) && (aidIsLeader || fleaderMode (gplayer fact) == LeaderNull)- -- Checking squit, to avoid doubly setting faction status to Camping+ -- Checking @breakLoop@, to avoid doubly setting faction status to Camping -- in case AI-controlled UI client asks to exit game at exactly -- the same moment as natural game over was detected. mainUIunderAI = mainUIactor && isAIFact fact && not breakLoop- doQueryAI = not mainUIactor || isAIFact fact when mainUIunderAI $ do cmdS <- sendQueryUI side aid case fst cmdS of@@ -597,6 +596,8 @@ ReqUIGameDropAndExit -> reqGameDropAndExit aid ReqUIGameSaveAndExit -> reqGameSaveAndExit aid _ -> error $ "" `showFailure` cmdS+ factNew <- getsState $ (EM.! side) . sfactionD+ let doQueryAI = not mainUIactor || isAIFact factNew breakASAP <- getsServer sbreakASAP -- If breaking out of the game loop, pretend there was a non-wait move. -- we don't need additionally to check @sbreakLoop@, because it occurs alone
engine-src/Game/LambdaHack/Server/MonadServer.hs view
@@ -130,7 +130,7 @@ res <- liftIO $ Ex.try $ if configExists then do (vlib2, s) <- strictDecodeEOF (path "")- if vlib2 == Self.version+ if Save.compatibleVersion vlib2 Self.version then return $ Just s else do let msg = "High score file from old version of game detected."
engine-src/Game/LambdaHack/Server/StartM.hs view
@@ -263,7 +263,7 @@ factionDold <- getsState sfactionD gameModeIdOld <- getsState sgameModeId curChalSer <- getsServer $ scurChalSer . soptions- let startingModeGroup = "starting"+ let startingModeGroup = "insert coin" gameMode = fromMaybe startingModeGroup $ mGameMode `mplus` sgameMode serverOptions rnd :: Rnd (FactionDict, FlavourMap, DiscoveryKind, DiscoveryKindRev,