Allure 0.4.8 → 0.4.9.0
raw patch · 36 files changed
+4061/−1418 lines, 36 filesdep +enummapset-thdep −ConfigFiledep −arraydep −binarydep ~LambdaHackdep ~textbinary-added
Dependencies added: enummapset-th
Dependencies removed: ConfigFile, array, binary, bytestring, deepseq, directory, enummapset, ghc-prim, hashable, keys, miniutter, mtl, old-time, random, stm, transformers, unordered-containers, zlib
Dependency ranges changed: LambdaHack, text
Files
- Allure.cabal +64/−46
- CHANGELOG.md +67/−0
- GameDefinition/Client/UI/Content/KeyKind.hs +183/−0
- GameDefinition/Content/CaveKind.hs +187/−0
- GameDefinition/Content/ItemKind.hs +756/−0
- GameDefinition/Content/ItemKindActor.hs +483/−0
- GameDefinition/Content/ItemKindOrgan.hs +259/−0
- GameDefinition/Content/ItemKindShrapnel.hs +261/−0
- GameDefinition/Content/ModeKind.hs +260/−0
- GameDefinition/Content/ModeKindPlayer.hs +149/−0
- GameDefinition/Content/PlaceKind.hs +316/−0
- GameDefinition/Content/RuleKind.hs +80/−0
- GameDefinition/Content/TileKind.hs +277/−0
- GameDefinition/Main.hs +18/−0
- GameDefinition/MainMenu.ascii +26/−0
- GameDefinition/PLAYING.md +262/−0
- GameDefinition/TieKnot.hs +41/−0
- GameDefinition/config.ui.default +33/−0
- GameDefinition/scores binary
- Makefile +279/−0
- PLAYING.md +0/−168
- README.md +54/−25
- config.rules.default +0/−53
- config.ui.default +0/−63
- scores binary
- src/Content/ActorKind.hs +0/−94
- src/Content/CaveKind.hs +0/−108
- src/Content/FactionKind.hs +0/−65
- src/Content/ItemKind.hs +0/−248
- src/Content/PlaceKind.hs +0/−149
- src/Content/RuleKind.hs +0/−98
- src/Content/StrategyKind.hs +0/−74
- src/Content/TileKind.hs +0/−163
- src/Main.hs +0/−49
- src/Multiline.hs +0/−15
- test/test.hs +6/−0
Allure.cabal view
@@ -1,26 +1,36 @@-name: Allure-version: 0.4.8-synopsis: Near-future roguelike game in very early and active development-description: This is an alpha release of Allure of the Stars,- a near-future Sci-Fi roguelike and tactical squad game.- The game is barely fun at this stage and not yet- really Sci-Fi. See the wiki for design notes and contribute.+name: Allure+-- The package version. See the Haskell package versioning policy (PVP)+-- for standards guiding when and how versions should be incremented.+-- http://www.haskell.org/haskellwiki/Package_versioning_policy+-- PVP summary: +-+------- breaking API changes+-- | | +----- non-breaking API additions+-- | | | +--- code changes with no API change+version: 0.4.9.0+synopsis: Near-future Sci-Fi roguelike and tactical squad game+description: Allure of the Stars+ is a near-future Sci-Fi roguelike and tactical squad game.+ See the wiki for design notes and contribute. .- New in this release are experimental multiplayer modes- and a lot of gameplay changes induced by the engine overhaul.- Long term goals are high replayability and auto-balancing- through procedural content generation and persistent content- modification based on player behaviour.+ <<https://raw.githubusercontent.com/AllureOfTheStars/media/master/screenshot/safari1.png>> .+ Please see the changelog file for recent improvements+ and the issue tracker for short-term plans. Long term goals+ are high replayability and auto-balancing through procedural+ content generation and persistent content modification+ based on player behaviour.+ . The game is written using the LambdaHack roguelike game engine available at <http://hackage.haskell.org/package/LambdaHack>.-homepage: http://github.com/Mikolaj/Allure-bug-reports: http://github.com/Mikolaj/Allure/issues+homepage: http://allureofthestars.com+bug-reports: http://github.com/AllureOfTheStars/Allure/issues license: OtherLicense license-file: LICENSE-tested-with: GHC == 7.4.2, GHC == 7.6.1-data-files: LICENSE, CREDITS, PLAYING.md, README.md,- config.rules.default, config.ui.default, scores+tested-with: GHC == 7.6.3, GHC == 7.8+data-files: GameDefinition/config.ui.default, GameDefinition/scores,+ GameDefinition/PLAYING.md, README.md, LICENSE, CREDITS,+ CHANGELOG.md+extra-source-files: GameDefinition/MainMenu.ascii, Makefile+-- extra-doc-files: GameDefinition/screenshot.png author: Andres Loeh, Mikolaj Konarski and others maintainer: Mikolaj Konarski <mikolaj.konarski@funktory.com> category: Game@@ -29,53 +39,61 @@ source-repository head type: git- location: git://github.com/Mikolaj/Allure.git+ location: git://github.com/AllureOfTheStars/Allure.git executable Allure- hs-source-dirs: src+ hs-source-dirs: GameDefinition main-is: Main.hs- other-modules: Content.ActorKind,+ other-modules: Client.UI.Content.KeyKind, Content.CaveKind,- Content.FactionKind, Content.ItemKind,+ Content.ItemKindActor,+ Content.ItemKindOrgan,+ Content.ItemKindShrapnel,+ Content.ModeKind,+ Content.ModeKindPlayer, Content.PlaceKind, Content.RuleKind,- Content.StrategyKind, Content.TileKind,- Multiline,+ TieKnot, Paths_Allure- build-depends: LambdaHack >= 0.2.8 && < 0.2.9,+ build-depends: LambdaHack >= 0.4.9.0 && < 0.5.1.0, template-haskell >= 2.6 && < 3, - ConfigFile >= 1.1.1 && < 2,- array >= 0.3.0.3 && < 1, base >= 4 && < 5,- binary >= 0.7 && < 1,- bytestring >= 0.9.2 && < 1, containers >= 0.5 && < 1,- deepseq >= 1.3 && < 2,- directory >= 1.1.0.1 && < 2,- enummapset >= 0.5.2 && < 1,+ enummapset-th >= 0.6.0.0 && < 1, filepath >= 1.2.0.1 && < 2,- ghc-prim >= 0.2,- hashable >= 1.2 && < 2,- keys >= 3 && < 4,- miniutter >= 0.4.1 && < 2,- mtl >= 2.0.1 && < 3,- old-time >= 1.0.0.7 && < 2,- random >= 1.0.1 && < 2,- stm >= 2.4 && < 3,- text >= 0.11.2.3 && < 1,- transformers >= 0.3 && < 1,- unordered-containers >= 0.2.3 && < 1,- zlib >= 0.5.3.1 && < 1+ text >= 0.11.2.3 && < 2 default-language: Haskell2010- default-extensions: MonoLocalBinds, ScopedTypeVariables,+ default-extensions: MonoLocalBinds, ScopedTypeVariables, OverloadedStrings BangPatterns, RecordWildCards, NamedFieldPuns- other-extensions: CPP, QuasiQuotes, OverloadedStrings+ other-extensions: TemplateHaskell ghc-options: -Wall -fwarn-orphans -fwarn-tabs -fwarn-incomplete-uni-patterns -fwarn-incomplete-record-updates -fwarn-monomorphism-restriction -fwarn-unrecognised-pragmas ghc-options: -fno-warn-auto-orphans -fno-warn-implicit-prelude ghc-options: -fno-ignore-asserts -funbox-strict-fields- ghc-options: -threaded -with-rtsopts=-C0.005+ ghc-options: -threaded -with-rtsopts=-C0.005 -rtsopts -- ghc-options: -with-rtsopts=-N -- eats all cores++test-suite test+ type: exitcode-stdio-1.0+ hs-source-dirs: GameDefinition, test+ main-is: test.hs+ build-depends: LambdaHack,+ template-haskell >= 2.6 && < 3,++ base >= 4 && < 5,+ containers >= 0.5 && < 1,+ enummapset-th >= 0.6.0.0 && < 1,+ filepath >= 1.2.0.1 && < 2,+ text >= 0.11.2.3 && < 2++ default-language: Haskell2010+ default-extensions: MonoLocalBinds, ScopedTypeVariables, OverloadedStrings+ BangPatterns, RecordWildCards, NamedFieldPuns+ other-extensions: TemplateHaskell+ ghc-options: -Wall -fwarn-orphans -fwarn-tabs -fwarn-incomplete-uni-patterns -fwarn-incomplete-record-updates -fwarn-monomorphism-restriction -fwarn-unrecognised-pragmas+ ghc-options: -fno-warn-auto-orphans -fno-warn-implicit-prelude+ ghc-options: -fno-ignore-asserts -funbox-strict-fields+ ghc-options: -threaded -with-rtsopts=-C0.005 -rtsopts
+ CHANGELOG.md view
@@ -0,0 +1,67 @@+## [v0.4.9.0, aka 'Player escapes through airlock'](https://github.com/LambdaHack/LambdaHack/compare/v0.4.14...v0.4.9.0)++- balance game content a bit (campaign still unbalanced)+- fix a bug where doors can't be closed+- assign AI tactics to players, in particular use follow-the-leader in safari+- specify monster spawn rate per-cave+- generally update content to the new v0.5.0.0 of LambdaHack content API++## [v0.4.14, aka 'Out of cosmic balance'](https://github.com/AllureOfTheStars/Allure/compare/v0.4.12...v0.4.14)++- add tons of new (unbalanced) items, actors and descriptions+- add a simple cabal test in addition to make-test and travis-test+- add items of Wonder and of Marvel+- add game mechanics, items and places to enable stealthy tactics+- add lots of shrapnel (explosions) and organs (body parts)+- expose a bit of the plot via new game modes and their order++## [v0.4.12](https://github.com/AllureOfTheStars/Allure/compare/v0.4.10...v0.4.12)++- make walls lit by default to simplify exploration+- improve and simplify dungeon generation+- simplify running and permit multi-actor runs+- let items explode and generate shrapnel projectiles+- add game difficulty setting (initial HP scaling right now)+- allow recording, playing back and looping commands+- implement pathfinding via per-actor BFS over the whole level+- extend setting targets for actors in UI tremendously+- implement autoexplore, go-to-target, etc., as macros+- let AI use pathfinding, switch leaders, pick levels to swarm to+- force level/leader changes on spawners (even when played by humans)+- extend and redesign UI bottom status lines++## [v0.4.10](https://github.com/AllureOfTheStars/Allure/compare/v0.4.8...v0.4.10)++- screensaver game modes (AI vs AI)+- improved AI (can now climbs stairs, etc.)+- multiple, multi-floor staircases+- multiple savefiles+- configurable framerate and combat animations++## [v0.4.8](https://github.com/AllureOfTheStars/Allure/compare/v0.4.6.5...v0.4.8)++- experimental multiplayer modes+- a lot of gameplay changes induced by the engine overhaul and in particular the client-server rewrite++## [v0.4.6.5](https://github.com/AllureOfTheStars/Allure/compare/v0.4.6...v0.4.6.5)++- this is a minor release, primarily intended to fix the broken compilation on Hackage+- changes since 0.4.6 are mostly unrelated to gameplay:+ - strictly typed config files split into UI and rules+ - a switch from Text to String throughout the codebase+ - use of the external library miniutter for English sentence generation++## [v0.4.6](https://github.com/AllureOfTheStars/Allure/compare/v0.4.4...v0.4.6)++- the Main Menu+- improved and configurable mode of squad combat++## [v0.4.4](https://github.com/AllureOfTheStars/Allure/compare/v0.4.3...v0.4.4)++- missiles flying for three turns (by an old kosmikus' idea)+- visual feedback for targeting+- animations of combat and individual monster moves++## [v0.4.3](https://github.com/AllureOfTheStars/Allure/compare/v0.4.2...v0.4.3)++- the Allure of the Stars game depends on the LambdaHack engine library
+ GameDefinition/Client/UI/Content/KeyKind.hs view
@@ -0,0 +1,183 @@+-- Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+-- This file is a part of the computer game Allure of the Stars+-- and is released under the terms of the GNU Affero General Public License.+-- For license and copyright information, see the file LICENSE.+--+-- | The default game key-command mapping to be used for UI. Can be overriden+-- via macros in the config file.+module Client.UI.Content.KeyKind ( standardKeys ) where++import Control.Arrow (first)++import qualified Game.LambdaHack.Client.Key as K+import Game.LambdaHack.Client.UI.Content.KeyKind+import Game.LambdaHack.Client.UI.HumanCmd+import qualified Game.LambdaHack.Common.Effect as Effect+import qualified Game.LambdaHack.Common.Feature as F+import Game.LambdaHack.Common.Misc++standardKeys :: KeyKind+standardKeys = KeyKind+ { rhumanCommands = map (first K.mkKM)+ -- All commands are defined here, except some movement and leader picking+ -- commands. All commands are shown on help screens except debug commands+ -- and macros with empty descriptions.+ -- The order below determines the order on the help screens.+ -- Remember to put commands that show information (e.g., enter targeting+ -- mode) first.++ -- Main Menu, which apart of these includes a few extra commands+ [ ("CTRL-x", ([CmdMenu], GameExit))+ , ("CTRL-u", ([CmdMenu], GameRestart "duel"))+ , ("CTRL-k", ([CmdMenu], GameRestart "skirmish"))+ , ("CTRL-m", ([CmdMenu], GameRestart "ambush"))+ , ("CTRL-b", ([CmdMenu], GameRestart "battle"))+ , ("CTRL-a", ([CmdMenu], GameRestart "campaign"))+ , ("CTRL-d", ([CmdMenu], GameDifficultyCycle))++ -- Movement and terrain alteration+ , ("less", ([CmdMove, CmdMinimal], TriggerTile+ [ TriggerFeature { verb = "ascend"+ , object = "a level"+ , feature = F.Cause (Effect.Ascend 1) }+ , TriggerFeature { verb = "escape"+ , object = "spaceship"+ , feature = F.Cause (Effect.Escape 1) } ]))+ , ("CTRL-less", ([CmdMove], TriggerTile+ [ TriggerFeature { verb = "ascend"+ , object = "10 levels"+ , feature = F.Cause (Effect.Ascend 10) } ]))+ , ("greater", ([CmdMove, CmdMinimal], TriggerTile+ [ TriggerFeature { verb = "descend"+ , object = "a level"+ , feature = F.Cause (Effect.Ascend (-1)) }+ , TriggerFeature { verb = "escape"+ , object = "spaceship"+ , feature = F.Cause (Effect.Escape (-1)) } ]))+ , ("CTRL-greater", ([CmdMove], TriggerTile+ [ TriggerFeature { verb = "descend"+ , object = "10 levels"+ , feature = F.Cause (Effect.Ascend (-10)) } ]))+ , ("semicolon", ([CmdMove], StepToTarget))+ , ("colon", ([CmdMove], Macro "go to target for 100 steps"+ ["semicolon", "V"]))+ , ("CTRL-colon", ([CmdMove], Macro "go to target for 10 steps"+ ["semicolon", "CTRL-V"]))+ , ("x", ([CmdMove], Macro "explore the closest unknown spot"+ [ "BackSpace"+ , "CTRL-question", "semicolon", "V" ]))+ , ("X", ([CmdMove], Macro "autoexplore 100 times"+ [ "BackSpace"+ , "'", "CTRL-question", "semicolon", "'"+ , "V" ]))+ , ("CTRL-X", ([CmdMove], Macro "autoexplore 10 times"+ [ "BackSpace"+ , "'", "CTRL-question", "semicolon", "'"+ , "CTRL-V" ]))+ , ("R", ([CmdMove], Macro "rest (wait 100 times)"+ ["KP_Begin", "V"]))+ , ("CTRL-R", ([CmdMove], Macro "rest (wait 10 times)"+ ["KP_Begin", "CTRL-V"]))+ , ("c", ([CmdMove], AlterDir+ [ AlterFeature { verb = "close"+ , object = "door"+ , feature = F.CloseTo "closed door" }+ ]))+ , ("period", ([CmdMove], Macro "" ["KP_Begin"]))+ , ("i", ([CmdMove], Macro "" ["KP_Begin"]))++ -- Item use+ --+ -- For later:+ -- ApplyItem {verb = "eat", object = "food", symbol = ','}+ -- ApplyItem {verb = "activate", object = "emitter", symbol = '_'}+ -- ApplyItem {verb = "use", object = "tool", symbol = '~'}+ --+ , ("E", ([CmdItem], DescribeItem CEqp))+ , ("P", ([CmdItem], DescribeItem CInv))+ , ("S", ([CmdItem], DescribeItem CSha))+ , ("G", ([CmdItem], DescribeItem CGround))+ , ("A", ([CmdItem], AllOwned))+ , ("g", ([CmdItem, CmdMinimal],+ MoveItem [CGround] CEqp "get" "an item" True))+ , ("d", ([CmdItem], MoveItem [CEqp, CInv, CSha] CGround+ "drop" "an item" False))+ , ("e", ([CmdItem], MoveItem [CInv, CSha] CEqp+ "equip" "an item" False))+ , ("p", ([CmdItem], MoveItem [CEqp, CSha] CInv+ "pack" "an item into inventory backpack"+ False))+ , ("s", ([CmdItem], MoveItem [CInv, CEqp] CSha+ "stash" "and share an item" False))+ , ("a", ([CmdItem, CmdMinimal], Apply+ [ ApplyItem { verb = "activate"+ , object = "applicable item"+ , symbol = ' ' }+ , ApplyItem { verb = "quaff"+ , object = "drink"+ , symbol = '!' }+ , ApplyItem { verb = "read"+ , object = "tablet"+ , symbol = '?' }+ ]))+ , ("q", ([CmdItem], Apply [ApplyItem { verb = "quaff"+ , object = "drink"+ , symbol = '!' }]))+ , ("r", ([CmdItem], Apply [ApplyItem { verb = "read"+ , object = "tablet"+ , symbol = '?' }]))+ , ("f", ([CmdItem, CmdMinimal], Project+ [ApplyItem { verb = "fling"+ , object = "projectable item"+ , symbol = ' ' }]))+ , ("t", ([CmdItem], Project [ ApplyItem { verb = "throw"+ , object = "missile"+ , symbol = '}' }+ , ApplyItem { verb = "throw"+ , object = "missile"+ , symbol = '{' } ]))+ , ("z", ([CmdItem], Project [ApplyItem { verb = "zap"+ , object = "mechanism"+ , symbol = '-' }]))++ -- Targeting+ , ("KP_Multiply", ([CmdTgt, CmdMinimal], TgtEnemy))+ , ("backslash", ([CmdTgt], Macro "" ["KP_Multiply"]))+ , ("slash", ([CmdTgt], TgtFloor))+ , ("plus", ([CmdTgt], EpsIncr True))+ , ("minus", ([CmdTgt], EpsIncr False))+ , ("BackSpace", ([CmdTgt], TgtClear))+ , ("CTRL-question", ([CmdTgt], TgtUnknown))+ , ("CTRL-I", ([CmdTgt], TgtItem))+ , ("CTRL-braceleft", ([CmdTgt], TgtStair True))+ , ("CTRL-braceright", ([CmdTgt], TgtStair False))++ -- Automation+ , ("equal", ([CmdAuto], SelectActor))+ , ("underscore", ([CmdAuto], SelectNone))+ , ("v", ([CmdAuto], Repeat 1))+ , ("V", ([CmdAuto], Repeat 100))+ , ("CTRL-v", ([CmdAuto], Repeat 1000))+ , ("CTRL-V", ([CmdAuto], Repeat 10))+ , ("apostrophe", ([CmdAuto], Record))+ , ("CTRL-T", ([CmdAuto], Tactic))+ , ("CTRL-A", ([CmdAuto], Automate))++ -- Assorted+ , ("question", ([CmdMeta], Help))+ , ("D", ([CmdMeta], History))+ , ("T", ([CmdMeta], MarkSuspect))+ , ("Z", ([CmdMeta], MarkVision))+ , ("C", ([CmdMeta], MarkSmell))+ , ("Tab", ([CmdMeta], MemberCycle))+ , ("ISO_Left_Tab", ([CmdMeta], MemberBack))+ , ("space", ([CmdMeta], Clear))+ , ("Escape", ([CmdMeta, CmdMinimal], Cancel))+ , ("Return", ([CmdMeta], Accept))++ -- Debug and others not to display in help screens+ , ("CTRL-s", ([CmdDebug], GameSave))+ , ("CTRL-f", ([CmdDebug], GameRestart "safari"))+ , ("CTRL-e", ([CmdDebug], GameRestart "defense"))+ ]+ }
+ GameDefinition/Content/CaveKind.hs view
@@ -0,0 +1,187 @@+-- Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+-- This file is a part of the computer game Allure of the Stars+-- and is released under the terms of the GNU Affero General Public License.+-- For license and copyright information, see the file LICENSE.+--+-- | Cave layouts.+module Content.CaveKind ( cdefs ) where++import Data.Ratio++import Game.LambdaHack.Common.ContentDef+import Game.LambdaHack.Common.Dice+import Game.LambdaHack.Common.Misc+import Game.LambdaHack.Content.CaveKind++cdefs :: ContentDef CaveKind+cdefs = ContentDef+ { getSymbol = csymbol+ , getName = cname+ , getFreq = cfreq+ , validateSingle = validateSingleCaveKind+ , validateAll = validateAllCaveKind+ , content =+ [rogue, arena, empty, noise, battle, skirmish, ambush, safari1, safari2, safari3]+ }+rogue, arena, empty, noise, battle, skirmish, ambush, safari1, safari2, safari3 :: CaveKind++rogue = CaveKind+ { csymbol = 'R'+ , cname = "Storage area"+ , cfreq = [("campaign random", 100), ("caveRogue", 1)]+ , cxsize = fst normalLevelBound + 1+ , cysize = snd normalLevelBound + 1+ , cgrid = DiceXY (3 * d 2) (d 2 + 2)+ , cminPlaceSize = DiceXY (2 * d 2 + 2) 4+ , cmaxPlaceSize = DiceXY 15 10+ , cdarkChance = d 54 + dl 20+ , cnightChance = 51+ , cauxConnects = 1%3+ , cmaxVoid = 1%6+ , cminStairDist = 30+ , cdoorChance = 1%2+ , copenChance = 1%10+ , chidden = 8+ , cactorCoeff = 20+ , cactorFreq = [("alien", 33), ("animal", 33), ("robot", 33)]+ , citemNum = 15 * d 2+ , citemFreq = [("useful", 50), ("treasure", 50)]+ , cplaceFreq = [("rogue", 100)]+ , cpassable = False+ , cdefTile = "fillerWall"+ , cdarkCorTile = "floorCorridorDark"+ , clitCorTile = "floorCorridorLit"+ , cfillerTile = "fillerWall"+ , couterFenceTile = "basic outer fence"+ , clegendDarkTile = "legendDark"+ , clegendLitTile = "legendLit"+ }+arena = rogue+ { csymbol = 'A'+ , cname = "Recreational deck"+ , cfreq = [("campaign random", 100), ("caveArena", 1)]+ , cgrid = DiceXY (2 * d 2) (2 * d 2)+ , cminPlaceSize = DiceXY (2 * d 2 + 3) 4+ , cdarkChance = d 80 + dl 60+ , cnightChance = 0+ , cmaxVoid = 1%4+ , chidden = 1000+ , cactorCoeff = 40+ , cactorFreq = [("alien", 15), ("animal", 80), ("robot", 5)]+ , citemNum = 11 * d 2 -- few rooms+ , cpassable = True+ , cdefTile = "arenaSet"+ , cdarkCorTile = "trailLit" -- let trails give off light+ , clitCorTile = "trailLit"+-- TODO: re-add when less rooms , couterFenceTile = "oriels fence"+ }+empty = rogue+ { csymbol = 'E'+ , cname = "Construction site"+ , cfreq = [("campaign random", 100), ("caveEmpty", 1)]+ , cgrid = DiceXY (d 2 + 1) 1+ , cminPlaceSize = DiceXY 10 10+ , cmaxPlaceSize = DiceXY 24 15+ , cdarkChance = d 80 + dl 80+ , cnightChance = 0+ , cauxConnects = 1+ , cmaxVoid = 1%2+ , cminStairDist = 50+ , chidden = 1000+ , cactorCoeff = 50+ , cactorFreq = [("alien", 5), ("animal", 15), ("robot", 80)]+ , citemNum = 9 * d 2 -- few rooms+ , cpassable = True+ , cdefTile = "emptySet"+ , cdarkCorTile = "floorArenaDark"+ , clitCorTile = "floorArenaLit"+ , couterFenceTile = "oriels fence"+ }+noise = rogue+ { csymbol = 'N'+ , cname = "Machine rooms"+ , cfreq = [("campaign random", 50), ("caveNoise", 1)]+ , cgrid = DiceXY (2 + d 2) 3+ , cminPlaceSize = DiceXY 12 5+ , cmaxPlaceSize = DiceXY 24 15+ , cnightChance = d 80 + dl 80+ , cauxConnects = 0+ , cmaxVoid = 0+ , chidden = 1000+ , cactorCoeff = 30+ , cactorFreq = [("alien", 80), ("animal", 5), ("robot", 15)]+ , citemNum = 16 * d 2 -- an incentive to explore the labyrinth+ , cpassable = True+ , cplaceFreq = [("noise", 100)]+ , cdefTile = "noiseSet"+ , cdarkCorTile = "floorArenaDark"+ , clitCorTile = "floorArenaLit"+ }+battle = rogue -- few lights and many solids, to help the less numerous heroes+ { csymbol = 'B'+ , cname = "Ravaged spaceport"+ , cfreq = [("caveBattle", 1)]+ , cgrid = DiceXY (2 * d 2 + 1) 3+ , cminPlaceSize = DiceXY 4 4+ , cmaxPlaceSize = DiceXY 9 7+ , cdarkChance = 0+ , cnightChance = 100+ , cmaxVoid = 0+ , cdoorChance = 2%10+ , copenChance = 9%10+ , chidden = 1000+ , cactorFreq = []+ , citemNum = 20 * d 2+ , citemFreq = [("useful", 100), ("light source", 200)]+ , cplaceFreq = [("battle", 50), ("rogue", 50)]+ , cpassable = True+ , cdefTile = "battleSet"+ , cdarkCorTile = "trailLit" -- let trails give off light+ , clitCorTile = "trailLit"+ }+skirmish = rogue -- many random solid tiles, to break LOS, since it's a day+ { csymbol = 'S'+ , cname = "Woodland biosphere"+ , cfreq = [("caveSkirmish", 1)]+ , cgrid = DiceXY (2 * d 2 + 2) (d 2 + 2)+ , cminPlaceSize = DiceXY 3 3+ , cmaxPlaceSize = DiceXY 7 5+ , cdarkChance = 100+ , cnightChance = 0+ , cdoorChance = 1+ , copenChance = 0+ , chidden = 1000+ , cactorFreq = []+ , citemNum = 20 * d 2+ , citemFreq = [("useful", 100)]+ , cplaceFreq = [("skirmish", 60), ("rogue", 40)]+ , cpassable = True+ , cdefTile = "skirmishSet"+ , cdarkCorTile = "floorArenaLit"+ , clitCorTile = "floorArenaLit"+ }+ambush = rogue -- lots of lights, to give a chance to snipe+ { csymbol = 'M'+ , cname = "Public garden"+ , cfreq = [("caveAmbush", 1)]+ , cgrid = DiceXY (2 * d 2 + 3) (d 2 + 2)+ , cminPlaceSize = DiceXY 3 3+ , cmaxPlaceSize = DiceXY 5 5+ , cdarkChance = 0+ , cnightChance = 100+ , cauxConnects = 1+ , cdoorChance = 1%10+ , copenChance = 9%10+ , chidden = 1000+ , cactorFreq = []+ , citemNum = 22 * d 2+ , citemFreq = [("useful", 100), ("light source", 200)]+ , cplaceFreq = [("ambush", 100)]+ , cpassable = True+ , cdefTile = "ambushSet"+ , cdarkCorTile = "trailLit" -- let trails give off light+ , clitCorTile = "trailLit"+ }+safari1 = ambush {cfreq = [("caveSafari1", 1)]}+safari2 = battle {cfreq = [("caveSafari2", 1)]}+safari3 = skirmish {cfreq = [("caveSafari3", 1)]}
+ GameDefinition/Content/ItemKind.hs view
@@ -0,0 +1,756 @@+-- Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+-- This file is a part of the computer game Allure of the Stars+-- and is released under the terms of the GNU Affero General Public License.+-- For license and copyright information, see the file LICENSE.+--+-- | Item and treasure definitions.+module Content.ItemKind ( cdefs ) where++import Data.List++import Content.ItemKindActor+import Content.ItemKindOrgan+import Content.ItemKindShrapnel+import Game.LambdaHack.Common.Color+import Game.LambdaHack.Common.ContentDef+import Game.LambdaHack.Common.Dice+import Game.LambdaHack.Common.Effect+import Game.LambdaHack.Common.Flavour+import Game.LambdaHack.Common.Misc+import Game.LambdaHack.Content.ItemKind++cdefs :: ContentDef ItemKind+cdefs = ContentDef+ { getSymbol = isymbol+ , getName = iname+ , getFreq = ifreq+ , validateSingle = validateSingleItemKind+ , validateAll = validateAllItemKind+ , content = items ++ organs ++ shrapnels ++ actors+ }++items :: [ItemKind]+items =+ [canOfGlue, crankSpotlight, buckler, dart, dart200, gem1, gem2, gem3, gloveFencing, gloveGauntlet, gloveJousting, currency, gorget, harpoon, jumpingPole, contactLens, necklace1, necklace2, necklace3, necklace4, necklace5, necklace6, necklace7, net, needle, oilLamp, potion1, potion2, potion3, potion4, potion5, potion6, potion7, potion8, potion9, potion10, potion11, ring1, ring2, ring3, ring4, ring5, scroll1, scroll2, scroll3, scroll4, scroll5, scroll6, scroll7, scroll8, scroll9, shield, dagger, hammer, sword, halberd, wand1, wand2, candle, armorLeather, armorMail, honingSteel, constructionHooter]++canOfGlue, crankSpotlight, buckler, dart, dart200, gem1, gem2, gem3, gloveFencing, gloveGauntlet, gloveJousting, currency, gorget, harpoon, jumpingPole, contactLens, necklace1, necklace2, necklace3, necklace4, necklace5, necklace6, necklace7, net, needle, oilLamp, potion1, potion2, potion3, potion4, potion5, potion6, potion7, ring1, potion8, potion9, potion10, potion11, ring2, ring3, ring4, ring5, scroll1, scroll2, scroll3, scroll4, scroll5, scroll6, scroll7, scroll8, scroll9, shield, dagger, hammer, sword, halberd, wand1, wand2, candle, armorLeather, armorMail, honingSteel, constructionHooter :: ItemKind++gem, necklace, potion, ring, scroll, wand :: ItemKind -- generic templates++{- Item group symbols (from Angband, only as an informal convention for now):++! potion, flask, concoction, bottle, jar, vial, canister+? scroll, book, note, tablet, remote+, food+- magical wand, magical rod, transmitter, pistol, rifle+_ magical staff, scanner+= ring+" necklace+$ currency, gem+~ light, tool+/ polearm+| edged weapon+\ hafted weapon+} launcher+{ projectile+( clothes+[ torso armour+] misc. armour+) shield++-}++-- * Thrown weapons++dart = ItemKind+ { isymbol = '{'+ , iname = "steak knife"+ , ifreq = [("useful", 100), ("any arrow", 100)]+ , iflavour = zipPlain [BrCyan]+ , icount = 3 * d 3+ , irarity = [(1, 20), (10, 10)]+ , iverbHit = "prick"+ , iweight = 100+ , iaspects = [AddHurtRanged ((d 6 + dl 6) |*| 10)]+ , ieffects = [Hurt (3 * d 1)]+ , ifeature = [toVelocity 75] -- no fins no special balance+ , idesc = "Not particularly well balanced, but with a laser-sharpened titanium tip and blade."+ , ikit = []+ }+dart200 = ItemKind+ { isymbol = '{'+ , iname = "billiard ball"+ , ifreq = [("useful", 100), ("any arrow", 50)] -- TODO: until arrows added+ , iflavour = zipPlain [BrWhite]+ , icount = 3 * d 3+ , irarity = [(4, 20), (10, 10)]+ , iverbHit = "strike"+ , iweight = 300+ , iaspects = [AddHurtRanged ((d 6 + dl 6) |*| 10)]+ , ieffects = [Hurt (2 * d 1)]+ , ifeature = [toVelocity 150]+ , idesc = "Ideal shape, size and weight for throwing."+ , ikit = []+ }++-- * Exotic thrown weapons++canOfGlue = ItemKind+ { isymbol = '{'+ , iname = "can of glue"+ , ifreq = [("useful", 100)]+ , iflavour = zipPlain [Magenta]+ , icount = dl 4+ , irarity = [(5, 5), (10, 20)]+ , iverbHit = "glue"+ , iweight = 1500+ , iaspects = []+ , ieffects = [Paralyze (5 + d 10)]+ , ifeature = [toVelocity 50] -- unwieldy+ , idesc = "A can of liquid, fast-setting, construction glue."+ , ikit = []+ }+harpoon = ItemKind+ { isymbol = '{'+ , iname = "harpoon"+ , ifreq = [("useful", 100)]+ , iflavour = zipPlain [Brown]+ , icount = dl 5+ , irarity = [(5, 5), (10, 5)]+ , iverbHit = "hook"+ , iweight = 4000+ , iaspects = [AddHurtRanged ((d 2 + 2 * dl 5) |*| 10)]+ , ieffects = [Hurt (4 * d 1), PullActor (ThrowMod 200 50)]+ , ifeature = []+ , idesc = "A display piece harking back to the Earth's oceanic tourism hayday. The cruel, barbed head lodges in its victim so painfully that the weakest tug of the thin line sends the victim flying."+ , ikit = []+ }+net = ItemKind+ { isymbol = '{'+ , iname = "net"+ , ifreq = [("useful", 100)]+ , iflavour = zipPlain [White]+ , icount = dl 3+ , irarity = [(3, 5), (10, 4)]+ , iverbHit = "entangle"+ , iweight = 1000+ , iaspects = []+ , ieffects = [ Paralyze (5 + d 5)+ , DropBestWeapon, DropEqp ')' False ]+ , ifeature = []+ , idesc = "A large synthetic fibre net with weights affixed along the edges. Entangles weapon and appendages alike."+ , ikit = []+ }+needle = ItemKind+ { isymbol = '{'+ , iname = "needle"+ , ifreq = []+ , iflavour = zipPlain [BrBlue]+ , icount = 9 * d 3+ , irarity = []+ , iverbHit = "prick"+ , iweight = 1+ , iaspects = [AddHurtRanged ((d 3 + dl 3) |*| 10)]+ , ieffects = [Hurt (1 * d 1)]+ , ifeature = [toVelocity 200, Fragile]+ , idesc = "The hypodermic needle part of a micro-syringe. Without the payload, it flies far and penetrates deeply, causing intense pain on movement."+ , ikit = []+ }++-- * Lights++candle = ItemKind+ { isymbol = '~'+ , iname = "candle"+ , ifreq = [("useful", 100), ("light source", 100)]+ , iflavour = zipPlain [Brown]+ , icount = 1+ , irarity = [(1, 8), (3, 6)]+ , iverbHit = "scorch"+ , iweight = 500+ , iaspects = [ AddLight 3+ , AddSight (-2) ]+ , ieffects = [Burn 3]+ , ifeature = [ toVelocity 50 -- easy to break when throwing+ , Fragile, EqpSlot EqpSlotAddLight "", Identified ]+ , idesc = "A smoking, thick candle with an unsteady fire."+ , ikit = []+ }+oilLamp = ItemKind+ { isymbol = '~'+ , iname = "oil lamp"+ , ifreq = [("useful", 100), ("light source", 100)]+ , iflavour = zipPlain [BrYellow]+ , icount = 1+ , irarity = [(5, 5), (10, 5)]+ , iverbHit = "burn"+ , iweight = 1000+ , iaspects = [AddLight 3, AddSight (-1)]+ , ieffects = [Burn 3, Paralyze 3, OnSmash (Explode "burning oil 3")]+ , ifeature = [ toVelocity 70 -- hard not to spill the oil while throwing+ , Fragile, EqpSlot EqpSlotAddLight "", Identified ]+ , idesc = "A sizable glass lamp filled with plant oil feeding a wick."+ , ikit = []+ }+crankSpotlight = ItemKind+ { isymbol = '~'+ , iname = "crank spotlight"+ , ifreq = [("useful", 100), ("light source", 100)]+ , iflavour = zipPlain [BrWhite]+ , icount = 1+ , irarity = [(10, 3)]+ , iverbHit = "snag"+ , iweight = 2400+ , iaspects = [AddLight 4, AddArmorRanged $ - d 3] -- noise and busy hands+ , ieffects = []+ , ifeature = [ EqpSlot EqpSlotAddLight "", Identified ]+ , idesc = "Powerful, wide-beam spotlight, powered by a hand-crank. Requires noisy two-handed recharging every few minutes."+ , ikit = []+ }++-- * Treasure++gem = ItemKind+ { isymbol = '*'+ , iname = "gem"+ , ifreq = [("treasure", 100)] -- x3, but rare on shallow levels+ , iflavour = zipPlain $ delete BrYellow brightCol -- natural, so not fancy+ , icount = 1+ , irarity = []+ , iverbHit = "tap"+ , iweight = 50+ , iaspects = [AddLight 1, AddSpeed (-1)] -- reflects strongly, distracts+ , ieffects = []+ , ifeature = [ Durable -- prevent destruction by evil monsters+ , Precious ]+ , idesc = "Precious, though useless. Worth around 100 gold grains."+ , ikit = []+ }+gem1 = gem+ { irarity = [(2, 0), (10, 10)]+ }+gem2 = gem+ { irarity = [(5, 0), (10, 10)]+ }+gem3 = gem+ { irarity = [(8, 0), (10, 10)]+ }+currency = ItemKind+ { isymbol = '$'+ , iname = "gold grain"+ , ifreq = [("treasure", 100), ("currency", 1)]+ , iflavour = zipPlain [BrYellow]+ , icount = 10 + d 20 + dl 20+ , irarity = [(1, 0), (2, 15), (5, 25), (10, 10)]+ , iverbHit = "tap"+ , iweight = 1+ , iaspects = []+ , ieffects = []+ , ifeature = [Durable, Identified, Precious]+ , idesc = "Reliably valuable in every civilized place."+ , ikit = []+ }++-- * Periodic jewelry++gorget = ItemKind+ { isymbol = '"'+ , iname = "gorget"+ , ifreq = [("useful", 100)]+ , iflavour = zipFancy [BrCyan]+ , irarity = [(4, 1), (10, 2)]+ , icount = 1+ , iverbHit = "whip"+ , iweight = 30+ , iaspects = [Periodic $ d 4 + dl 4, AddArmorMelee 1, AddArmorRanged 1]+ , ieffects = [RefillCalm 1]+ , ifeature = [ Precious, EqpSlot EqpSlotPeriodic "", Identified+ , toVelocity 50 ] -- not dense enough+ , idesc = "Highly ornamental, cold, large, steel medallion on a chain. Unlikely to offer much protection as an armor piece, but the old, worn engraving reassures you."+ , ikit = []+ }+necklace = ItemKind+ { isymbol = '"'+ , iname = "necklace"+ , ifreq = [("useful", 100)]+ , iflavour = zipFancy stdCol ++ zipPlain brightCol+ , irarity = [(10, 3)]+ , icount = 1+ , iverbHit = "whip"+ , iweight = 30+ , iaspects = []+ , ieffects = []+ , ifeature = [ Precious, EqpSlot EqpSlotPeriodic ""+ , toVelocity 50 ] -- not dense enough+ , idesc = "Tingling, rattling chain of flat encrusted links. Eccentric millionaires are known to hide their highly personalized body augmentation packs in such large jewelry pieces."+ , ikit = []+ }+necklace1 = necklace+ { iaspects = [Periodic $ d 2 + dl 2]+ , ieffects = [RefillHP 1]+ }+necklace2 = necklace+ { irarity = [(2, 0), (10, 1)]+ , iaspects = [Periodic $ d 4 + dl 2]+ , ieffects = [ Impress+ , Summon [("mobile animal", 1)] $ 1 + dl 2, Explode "waste" ]+ }+necklace3 = necklace+ { iaspects = [Periodic $ d 4 + dl 2]+ , ieffects = [Paralyze $ 5 + d 5 + dl 5, RefillCalm 999]+ }+necklace4 = necklace+ { iaspects = [Periodic $ 2 * d 10 + dl 10]+ , ieffects = [Teleport $ d 3 |*| 3]+ }+necklace5 = necklace+ { iaspects = [Periodic $ d 4 + dl 2]+ , ieffects = [Teleport $ 12 + d 3 |*| 3]+ }+necklace6 = necklace+ { iaspects = [Periodic $ 2 * d 5 + dl 5]+ , ieffects = [PushActor (ThrowMod 100 50)]+ }+necklace7 = necklace+ { irarity = [(4, 0), (10, 2)]+ , iaspects = [Periodic $ 2 * d 5 + dl 15]+ , ieffects = [InsertMove 1, RefillHP (-1)]+ , ifeature = ifeature necklace ++ [Durable]+ -- evil players would throw before death, to destroy+ -- TODO: teach AI to wear only for fight; prevent players from meleeing+ -- allies with that (Durable)+ }++-- * Non-periodic jewelry++contactLens = ItemKind+ { isymbol = '='+ , iname = "contact lens"+ , ifreq = [("useful", 100)]+ , iflavour = zipPlain [White]+ , icount = 1+ , irarity = [(5, 0), (10, 1)]+ , iverbHit = "rap"+ , iweight = 50+ , iaspects = [AddSight $ d 2, AddHurtMelee $ d 2 |*| 3]+ , ieffects = []+ , ifeature = [Precious, Identified, Durable, EqpSlot EqpSlotAddSight ""]+ , idesc = "Advanced design. Never needs to be taken off."+ , ikit = []+ }+ring = ItemKind+ { isymbol = '='+ , iname = "ring"+ , ifreq = [("useful", 100)]+ , iflavour = zipPlain stdCol ++ zipFancy darkCol+ , icount = 1+ , irarity = [(10, 3)]+ , iverbHit = "knock"+ , iweight = 15+ , iaspects = []+ , ieffects = []+ , ifeature = [Precious, Identified]+ , idesc = "A sturdy ring with a softly shining eye. If it contains a body booster unit, beware of the side-effects."+ , ikit = []+ }+ring1 = ring+ { irarity = [(2, 0), (10, 2)]+ , iaspects = [AddSpeed $ d 2, AddMaxHP $ dl 3 - 5 - d 3]+ , ifeature = ifeature ring ++ [Durable, EqpSlot EqpSlotAddSpeed ""]+ }+ring2 = ring+ { iaspects = [AddMaxHP $ 3 + dl 5, AddMaxCalm $ dl 6 - 15 - d 6]+ , ifeature = ifeature ring ++ [EqpSlot EqpSlotAddMaxHP ""]+ }+ring3 = ring+ { iaspects = [AddMaxCalm $ 10 + dl 10]+ , ifeature = ifeature ring ++ [EqpSlot EqpSlotAddMaxCalm ""]+ , idesc = "Cold, solid to the touch, perfectly round, engraved with solemn, strangely comforting, worn out words."+ }+ring4 = ring -- TODO: move to level-ups and to timed effects+ { irarity = [(3, 12), (10, 12)]+ , iaspects = [AddHurtMelee $ (d 5 + dl 5) |*| 3, AddMaxHP $ dl 3 - 4 - d 2]+ , ifeature = ifeature ring ++ [Durable, EqpSlot EqpSlotAddHurtMelee ""]+ }+ring5 = ring -- by the time it's found, probably no space in eqp+ { irarity = [(5, 0)]+ , iaspects = [AddLight $ d 2]+ , ifeature = ifeature ring ++ [EqpSlot EqpSlotAddLight ""]+ , idesc = "A sturdy ring with a large, shining stone."+ }++-- * Exploding consumables, often intended to be thrown++potion = ItemKind+ { isymbol = '!'+ , iname = "vial"+ , ifreq = [("useful", 100)]+ , iflavour = zipPlain stdCol ++ zipFancy brightCol+ , icount = 1+ , irarity = [(1, 15), (10, 12)]+ , iverbHit = "splash"+ , iweight = 200+ , iaspects = []+ , ieffects = []+ , ifeature = [ toVelocity 50 -- oily, bad grip+ , Applicable, Fragile ]+ , idesc = "A flask of bubbly, slightly oily liquid of a suspect color." -- purely natural; no nano, no alien tech -- TODO: move distortion to a special flask item or trigger when some precious high tech item is destroyed (jewelry?)?+ , ikit = []+ }+potion1 = potion+ { ieffects = [ NoEffect "of rose water", Impress+ , OnSmash (ApplyPerfume), OnSmash (Explode "fragrance") ]+ }+potion2 = potion+ { ifreq = [("useful", 1)] -- extremely rare+ , irarity = [(1, 1)]+ , ieffects = [ NoEffect "of musky concoction", Impress, DropBestWeapon+ , OnSmash (Explode "pheromone")]+ }+potion3 = potion+ { ieffects = [RefillHP 5, OnSmash (Explode "healing mist")]+ }+potion4 = potion -- TODO: a bit boring+ { irarity = [(1, 7)]+ , ieffects = [RefillHP (-5), OnSmash (Explode "wounding mist")]+ }+potion5 = potion+ { ieffects = [ Explode "explosion blast 10", Impress+ , PushActor (ThrowMod 200 75)+ , OnSmash (Explode "explosion blast 10") ]+ }+potion6 = potion+ { irarity = [(10, 2)]+ , ieffects = [ NoEffect "of distortion", Impress+ , OnSmash (Explode "distortion")]+ }+potion7 = potion+ { ieffects = [ NoEffect "of bait cocktail", Impress+ , OnSmash (Summon [("mobile animal", 1)] $ 1 + dl 2)+ , OnSmash (Explode "waste") ]+ }+potion8 = potion+ { ieffects = [ OneOf [Impress, DropBestWeapon, RefillHP 5, Burn 3]+ , OnSmash (OneOf [ Explode "healing mist"+ , Explode "wounding mist"+ , Explode "fragrance"+ , Explode "explosion blast 10" ]) ]+ }+potion9 = potion+ { irarity = [(3, 3), (10, 6)]+ , ieffects = [ OneOf [ Dominate, DropBestWeapon, RefillHP 20, Burn 9+ , InsertMove 2]+ , OnSmash (OneOf [ Explode "healing mist 2"+ , Explode "healing mist 2"+ , Explode "pheromone"+ , Explode "distortion"+ , Explode "explosion blast 20" ]) ]+ }+potion10 = potion -- used only as initial equipmnt; count betray identity+ { ifreq = [("useful", 100), ("potion of glue", 1)]+ , irarity = [(1, 1)]+ , icount = 1 + d 2+ , ieffects = [ NoEffect "of sticky foam", Paralyze (5 + d 5)+ , OnSmash (Explode "glue")]+ , ifeature = [Identified]+ }+potion11 = potion+ { irarity = [(10, 5)]+ , ieffects = [RefillHP 10, OnSmash (Explode "healing mist 2")]+ }++-- * Non-exploding consumables, not specifically designed for throwing++constructionHooter = scroll+ { iname = "construction hooter"+ , ifreq = [("useful", 1), ("construction hooter", 1)] -- extremely rare+ , iflavour = zipPlain [BrRed]+ , irarity = [(1, 1)]+ , iaspects = []+ , ieffects = [Summon [("construction robot", 1)] $ 1 + dl 2]+ , ifeature = ifeature scroll ++ [Identified]+ , idesc = "The single-use electronic overdrive hooter that construction robots use to warn about danger and call help in extreme emergency."+ , ikit = []+ }+scroll = ItemKind+ { isymbol = '?'+ , iname = "tablet"+ , ifreq = [("useful", 100), ("any scroll", 100)]+ , iflavour = zipFancy stdCol ++ zipPlain darkCol -- arcane and old+ , icount = 1+ , irarity = [(1, 15), (10, 12)]+ , iverbHit = "thump"+ , iweight = 700+ , iaspects = []+ , ieffects = []+ , ifeature = [ toVelocity 25 -- bad grip+ , Applicable ]+ , idesc = "A standard issue spaceship crew tablet displaying a fixed infographic and a big button. Some of these still contain a one-time password authorizing a particular spaceship's infrastructure transition. It is unknown how the infrastructure might respond after so many years."+ , ikit = []+ }+scroll1 = scroll+ { irarity = [(1, 2), (10, 3)]+ , ieffects = [CallFriend 1]+ }+scroll2 = scroll+ { irarity = [(1, 7), (10, 5)]+ , ieffects = [NoEffect "of fireworks", Explode "firecracker 7"]+ }+scroll3 = scroll+ { irarity = [(1, 5), (10, 3)]+ , ieffects = [Ascend 1]+ }+scroll4 = scroll+ { ieffects = [ OneOf [ Teleport $ d 3 |*| 3, RefillCalm 10, RefillCalm (-10)+ , InsertMove 4, Paralyze 10, Identify CGround ] ]+ }+scroll5 = scroll+ { irarity = [(3, 3), (10, 6)]+ , ieffects = [ OneOf [ Summon standardSummon $ d 2+ , CallFriend 1, Ascend (-1), Ascend 1+ , RefillCalm 30, RefillCalm (-30), CreateItem $ d 2+ , PolyItem CGround ] ]+ -- TODO: ask player: Escape 1+ }+scroll6 = scroll+ { ieffects = [Teleport $ d 3 |*| 3]+ }+scroll7 = scroll+ { irarity = [(10, 3)]+ , ieffects = [InsertMove $ d 2 + dl 2]+ }+scroll8 = scroll+ { irarity = [(3, 8), (10, 4)]+ , ieffects = [Identify CGround] -- TODO: ask player: AskPlayer cstore eff?+ }+scroll9 = scroll+ { irarity = [(10, 10)]+ , ieffects = [PolyItem CGround]+ }++standardSummon :: Freqs+standardSummon = [ ("alien", 20)+ , ("mobile animal", 50)+ , ("mobile robot", 30) ]++-- * Armor++armorLeather = ItemKind+ { isymbol = '['+ , iname = "spacesuit breastplate"+ , ifreq = [("useful", 100)]+ , iflavour = zipPlain [Brown]+ , icount = 1+ , irarity = [(3, 6), (10, 3)]+ , iverbHit = "thud"+ , iweight = 7000+ , iaspects = [ AddHurtMelee (-3)+ , AddArmorMelee $ (1 + dl 3) |*| 5+ , AddArmorRanged $ (1 + dl 3) |*| 5 ]+ , ieffects = []+ , ifeature = [ toVelocity 30 -- unwieldy to throw and blunt+ , Durable, EqpSlot EqpSlotAddArmorMelee "", Identified ]+ , idesc = "A hard-shell torso segment cut from a disposed off spacesuit."+ , ikit = []+ }+armorMail = armorLeather+ { iname = "bulletproof vest"+ , iflavour = zipPlain [Cyan]+ , irarity = [(6, 6), (10, 6)]+ , iweight = 12000+ , iaspects = [ AddHurtMelee (-3)+ , AddArmorMelee $ (2 + dl 4) |*| 5+ , AddArmorRanged $ (2 + dl 4) |*| 5 ]+ , idesc = "A civilian bulletproof vest. Discourages foes from attacking your torso, making it harder for them to land a blow."+ }+gloveFencing = ItemKind+ { isymbol = ']'+ , iname = "construction glove"+ , ifreq = [("useful", 100)]+ , iflavour = zipPlain [BrYellow]+ , icount = 1+ , irarity = [(5, 8), (10, 8)]+ , iverbHit = "flap"+ , iweight = 100+ , iaspects = [ AddHurtMelee $ (d 2 + dl 10) * 3+ , AddArmorRanged $ d 2 |*| 5 ]+ , ieffects = []+ , ifeature = [ toVelocity 30 -- flaps and flutters+ , Durable, EqpSlot EqpSlotAddArmorRanged "", Identified ]+ , idesc = "A flexible construction glove from rough leather ensuring a good grip. Also, quite effective in deflecting or even catching slow projectiles."+ , ikit = []+ }+gloveGauntlet = gloveFencing+ { iname = "spacesuit glove"+ , irarity = [(6, 12)]+ , iflavour = zipPlain [BrCyan]+ , iweight = 300+ , iaspects = [ AddArmorMelee $ (1 + dl 2) |*| 5+ , AddArmorRanged $ (1 + dl 2) |*| 5 ]+ , idesc = "A piece of a hull maintenance spacesuit, padded and reinforced with carbon fibre."+ }+gloveJousting = gloveFencing+ { iname = "welding handgear"+ , irarity = [(6, 6)]+ , iflavour = zipFancy [BrRed]+ , iweight = 500+ , iaspects = [ AddHurtMelee $ (dl 4 - 6) |*| 3+ , AddArmorMelee $ (2 + dl 2) |*| 5+ , AddArmorRanged $ (2 + dl 2) |*| 5 ]+ , idesc = "Rigid, bulky handgear embedding a welding equipment, complete with an affixed small shield and a darkened visor. Awe-inspiring."+ }+-- Shield doesn't protect against ranged attacks to prevent+-- micromanagement: walking with shield, melee without.+buckler = ItemKind+ { isymbol = ')'+ , iname = "buckler"+ , ifreq = [("useful", 100)]+ , iflavour = zipPlain [Blue]+ , icount = 1+ , irarity = [(4, 6)]+ , iverbHit = "bash"+ , iweight = 2000+ , iaspects = [AddArmorMelee 40, AddHurtMelee (-30)]+ , ieffects = []+ , ifeature = [ toVelocity 30 -- unwieldy to throw and blunt+ , Durable, EqpSlot EqpSlotAddArmorMelee "", Identified ]+ , idesc = "Heavy and unwieldy arm protection made from an outer airlock panel. Absorbs a percentage of melee damage, both dealt and sustained. Too small to intercept projectiles with."+ , ikit = []+ }+shield = buckler+ { iname = "shield"+ , irarity = [(7, 5)]+ , iflavour = zipPlain [Green]+ , iweight = 3000+ , iaspects = [AddArmorMelee 80, AddHurtMelee (-70)]+ , ifeature = [ toVelocity 20 -- unwieldy to throw and blunt+ , Durable, EqpSlot EqpSlotAddArmorMelee "", Identified ]+ , idesc = "Large and unwieldy rectangle made of anti-meteorite ceramic sheet. Absorbs a percentage of melee damage, both dealt and sustained. Too heavy to intercept projectiles with."+ }++-- * Weapons++dagger = ItemKind+ { isymbol = '|'+ , iname = "cleaver"+ , ifreq = [("useful", 100), ("starting weapon", 100)]+ , iflavour = zipPlain [BrCyan]+ , icount = 1+ , irarity = [(1, 12), (10, 4)]+ , iverbHit = "stab"+ , iweight = 1000+ , iaspects = [AddHurtMelee $ (d 3 + dl 3) |*| 3, AddArmorMelee $ d 2 |*| 5]+ , ieffects = [Hurt (6 * d 1)]+ , ifeature = [ toVelocity 40 -- ensuring it hits with the tip costs speed+ , Durable, EqpSlot EqpSlotWeapon "", Identified ]+ , idesc = "A heavy professional kitchen blade. Will do fine cutting any kind of meat and bone, as well as parrying blows. Does not penetrate deeply, but is hard to block. Especially useful in conjunction with a larger weapon."+ , ikit = []+ }+hammer = ItemKind+ { isymbol = '\\'+ , iname = "demolition hammer"+ , ifreq = [("useful", 100), ("starting weapon", 100)]+ , iflavour = zipPlain [BrMagenta]+ , icount = 1+ , irarity = [(4, 12), (10, 2)]+ , iverbHit = "club"+ , iweight = 1500+ , iaspects = [AddHurtMelee $ (d 2 + dl 2) |*| 3]+ , ieffects = [Hurt (8 * d 1)]+ , ifeature = [ toVelocity 20 -- ensuring it hits with the sharp tip costs+ , Durable, EqpSlot EqpSlotWeapon "", Identified ]+ , idesc = "A hammer on a long handle used for construction work. It may not cause grave wounds, but neither does it ricochet or glance off armor. Great sidearm for opportunistic blows against armored foes."+ , ikit = []+ }+sword = ItemKind+ { isymbol = '/'+ , iname = "sharpened pipe"+ , ifreq = [("useful", 100), ("starting weapon", 100)]+ , iflavour = zipPlain [BrBlue]+ , icount = 1+ , irarity = [(3, 1), (6, 16), (10, 8)]+ , iverbHit = "slash"+ , iweight = 2000+ , iaspects = []+ , ieffects = [Hurt (10 * d 1)]+ , ifeature = [ toVelocity 20 -- ensuring it hits with the tip costs speed+ , Durable, EqpSlot EqpSlotWeapon "", Identified ]+ , idesc = "A makeshift weapon of simple design, but great potential. Hard to master, though."+ , ikit = []+ }+halberd = ItemKind+ { isymbol = '/'+ , iname = "halberd"+ , ifreq = [("useful", 100), ("starting weapon", 1)]+ , iflavour = zipPlain [BrYellow]+ , icount = 1+ , irarity = [(7, 1), (10, 10)]+ , iverbHit = "impale"+ , iweight = 3000+ , iaspects = [AddArmorMelee $ (1 + dl 3) |*| 5]+ , ieffects = [Hurt (14 * d 1)]+ , ifeature = [ toVelocity 20 -- not balanced+ , Durable, EqpSlot EqpSlotWeapon "", Identified ]+ , idesc = "A perfect replica made for a reenactor troupe, missing only some sharpening. Versatile, with great reach and leverage. Foes are held at a distance."+ , ikit = []+ }++-- * Wands++wand = ItemKind+ { isymbol = '-'+ , iname = "injector"+ , ifreq = [("useful", 100)]+ , iflavour = zipFancy brightCol+ , icount = 1+ , irarity = [] -- TODO: add charges, etc.+ , iverbHit = "club"+ , iweight = 300+ , iaspects = [AddLight 1, AddSpeed (-1)] -- pulsing with power, distracts+ , ieffects = []+ , ifeature = [ toVelocity 125 -- sufficiently advanced tech+ , Applicable, Durable ]+ , idesc = "Buzzing with dazzling light that shines even through appendages that handle it."+ , ikit = []+ }+wand1 = wand+ { ieffects = [] -- TODO: emit a cone of sound shrapnel that makes enemy cover his ears and so drop '{'+ }+wand2 = wand+ { ieffects = []+ }++-- * Assorted tools++jumpingPole = ItemKind+ { isymbol = '~'+ , iname = "jumping pole"+ , ifreq = [("useful", 100)]+ , iflavour = zipPlain [White]+ , icount = 1+ , irarity = [(1, 4), (10, 2)]+ , iverbHit = "prod"+ , iweight = 10000+ , iaspects = []+ , ieffects = [InsertMove 2] -- TODO: implement with timed speed instead+ -- and then make Durable, freq 2, and just trade+ -- taken turn now for a free turn later+ , ifeature = [Applicable, Identified]+ , idesc = "Makes you vulnerable at take-off, but then you are free like a bird."+ , ikit = []+ }+honingSteel = ItemKind+ { isymbol = '~'+ , iname = "honing steel"+ , ifreq = [("useful", 100)]+ , iflavour = zipPlain [Blue]+ , icount = 1+ , irarity = [(10, 10)]+ , iverbHit = "smack"+ , iweight = 400+ , iaspects = [AddHurtMelee $ d 10 |*| 3]+ , ieffects = []+ , ifeature = [EqpSlot EqpSlotAddHurtMelee "", Identified]+ , idesc = "Originally used for realigning the bent or buckled edges of kitchen knives in the local bars. Now it saves lives by letting you fix your weapons between or even during fights, without the need to set up camp, fish out tools and assemble a proper sharpening workshop."+ , ikit = []+ }
+ GameDefinition/Content/ItemKindActor.hs view
@@ -0,0 +1,483 @@+-- Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+-- This file is a part of the computer game Allure of the Stars+-- and is released under the terms of the GNU Affero General Public License.+-- For license and copyright information, see the file LICENSE.+--+-- | Actor (or rather actor body trunk) definitions.+module Content.ItemKindActor ( actors ) where++import qualified Data.EnumMap.Strict as EM++import Game.LambdaHack.Common.Ability+import Game.LambdaHack.Common.Color+import Game.LambdaHack.Common.Effect+import Game.LambdaHack.Common.Flavour+import Game.LambdaHack.Common.Misc+import Game.LambdaHack.Content.ItemKind++actors :: [ItemKind]+actors =+ [warrior, pilot, engineer, doctor, soldier, clerk, hairdresser, lawyer, peddler, taxCollector, eye, fastEye, nose, elbow, armadillo, gilaMonster, komodoDragon, hyena, alligator, hornetSwarm, thornbush, razorwireFence, electricFence, activeFence, steamFaucet, biogasFaucet, shepherdDrone, huntingDrone, homeRobot, wasteRobot, lightRobot, heavyRobot]++warrior, pilot, engineer, doctor, soldier, clerk, hairdresser, lawyer, peddler, taxCollector, eye, fastEye, nose, elbow, armadillo, gilaMonster, komodoDragon, hyena, alligator, hornetSwarm, thornbush, razorwireFence, electricFence, activeFence, steamFaucet, biogasFaucet, shepherdDrone, huntingDrone, homeRobot, wasteRobot, lightRobot, heavyRobot :: ItemKind++-- * Hunams++warrior = ItemKind+ { isymbol = '@'+ , iname = "mercenary" -- modified if in hero faction+ , ifreq = [("hero", 100), ("civilian", 100)]+ , iflavour = zipPlain [BrBlack] -- modified if in hero faction+ , icount = 1+ , irarity = [(1, 5)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 50, AddMaxCalm 60, AddSpeed 20+ , AddSight 3 ] -- no via eyes, but feel, hearing, etc.+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = ""+ , ikit = [("fist", COrgan), ("foot", COrgan), ("eye 4", COrgan)]+ }+pilot = warrior+ { iname = "pilot" }+engineer = warrior+ { iname = "engineer" }+doctor = warrior+ { iname = "doctor" }++soldier = warrior+ { iname = "soldier"+ , ifreq = [("soldier", 100)]+ , ikit = ikit warrior ++ [("starting weapon", CEqp)]+ }++clerk = warrior+ { iname = "clerk"+ , ifreq = [("civilian", 100)] }+hairdresser = clerk+ { iname = "hairdresser" }+lawyer = clerk+ { iname = "lawyer" }+peddler = clerk+ { iname = "peddler" }+taxCollector = clerk+ { iname = "tax collector" }++-- * Aliens++eye = ItemKind+ { isymbol = 'w'+ , iname = "beckoning walker"+ , ifreq = [("alien", 100), ("horror", 100)]+ , iflavour = zipPlain [BrRed]+ , icount = 1+ , irarity = [(3, 1), (10, 9)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 20, AddMaxCalm 60, AddSpeed 20+ , AddSight 4 ] -- can shoot for as long as lives+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "Walks with a stately dignity. You read death in the slow beckoning gestures of its revolting upper appendages."+ , ikit = [ ("foot", COrgan)+ , ("tentacle", COrgan), ("tentacle", COrgan)+ , ("tentacle", COrgan)+ , ("eye 4", COrgan) ]+ }+fastEye = ItemKind+ { isymbol = 'b'+ , iname = "crawling biter"+ , ifreq = [("alien", 100), ("horror", 100)]+ , iflavour = zipPlain [BrBlue]+ , icount = 1+ , irarity = [(6, 1), (10, 7)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 6, AddMaxCalm 60, AddSpeed 30+ , AddSight 4 ] -- can shoot for as long as lives+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "It bites as blindingly fast as it runs. Or rolls? Or crawls? Also, cuts and pierces."+ , ikit = [ ("tentacle", COrgan), ("tentacle", COrgan)+ , ("tentacle", COrgan), ("tentacle", COrgan)+ , ("jaw", COrgan)+ , ("eye 4", COrgan), ("speed gland 10", COrgan) ]+ }+nose = ItemKind+ { isymbol = 'h'+ , iname = "tentacled horror"+ , ifreq = [("alien", 100), ("horror", 100)]+ , iflavour = zipPlain [BrGreen]+ , icount = 1+ , irarity = [(3, 1), (10, 9)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 40, AddMaxCalm 30, AddSpeed 18+ , AddSmell 3 ] -- depends solely on smell+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "A blind, slimy mass of clawing, stinging and burning. You'd think it's mindless, but as soon as it touches your trembling body, it's always one step ahead."+ , ikit = [ ("smallClaw", COrgan)+ , ("tentacle", COrgan), ("tentacle", COrgan)+ , ("tentacle", COrgan), ("tentacle", COrgan)+ , ("thorn", COrgan), ("sting", COrgan) ]+ }+elbow = ItemKind+ { isymbol = 's'+ , iname = "creepy shooter"+ , ifreq = [("alien", 100), ("horror", 100)]+ , iflavour = zipPlain [BrMagenta]+ , icount = 1+ , irarity = [(6, 1), (10, 5)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 15, AddMaxCalm 80, AddSpeed 26+ , AddSkills $ EM.singleton AbMelee (-1)+ , AddSight 15 ] -- can shoot for as long as lives+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "It moves in sudden jerks and never makes a noise. Speaks in hard objects hurled at deadly speeds."+ , ikit = [ ("speed gland 4", COrgan)+ , ("any arrow", CInv), ("any arrow", CInv)+ , ("any arrow", CInv), ("any arrow", CInv) ]+ }++-- * Animals++armadillo = ItemKind+ { isymbol = 'a'+ , iname = "giant armadillo"+ , ifreq = [("animal", 100), ("horror", 100), ("mobile animal", 100)]+ , iflavour = zipPlain [Brown]+ , icount = 1+ , irarity = [(1, 5)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 30, AddMaxCalm 30, AddSpeed 18+ , AddSkills $ EM.singleton AbAlter (-1)+ , AddSight 3 ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = ""+ , ikit = [ ("claw", COrgan), ("snout", COrgan), ("armored skin", COrgan)+ , ("nostril", COrgan) ]+ }+gilaMonster = ItemKind+ { isymbol = 'g'+ , iname = "Gila monster"+ , ifreq = [("animal", 100), ("horror", 100), ("mobile animal", 100)]+ , iflavour = zipPlain [Magenta]+ , icount = 1+ , irarity = [(2, 5), (10, 3)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 15, AddMaxCalm 60, AddSpeed 15+ , AddSkills $ EM.singleton AbAlter (-1)+ , AddSight 3 ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = ""+ , ikit = [ ("venom tooth", COrgan), ("small claw", COrgan)+ , ("eye 4", COrgan), ("nostril", COrgan) ]+ }+komodoDragon = ItemKind -- bad hearing+ { isymbol = 'k'+ , iname = "Komodo dragon"+ , ifreq = [("animal", 100), ("horror", 100), ("mobile animal", 100)]+ , iflavour = zipPlain [Blue]+ , icount = 1+ , irarity = [(5, 5), (10, 7)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 40, AddMaxCalm 60, AddSpeed 18+ , AddSight 3 ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = ""+ , ikit = [ ("large tail", COrgan), ("jaw", COrgan), ("small claw", COrgan)+ , ("speed gland 4", COrgan), ("armored skin", COrgan)+ , ("eye 2", COrgan), ("nostril", COrgan) ]+ }+hyena = ItemKind+ { isymbol = 'h'+ , iname = "spotted hyena"+ , ifreq = [("animal", 100), ("horror", 100), ("mobile animal", 100)]+ , iflavour = zipPlain [Red]+ , icount = 1+ , irarity = [(4, 6), (10, 6)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 30, AddMaxCalm 60, AddSpeed 35+ , AddSight 3 ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = ""+ , ikit = [("jaw", COrgan), ("eye 4", COrgan), ("nostril", COrgan)]+ }+alligator = ItemKind+ { isymbol = 'a'+ , iname = "alligator"+ , ifreq = [("animal", 100), ("horror", 100), ("mobile animal", 100)]+ , iflavour = zipPlain [Blue]+ , icount = 1+ , irarity = [(10, 8)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 30, AddMaxCalm 60, AddSpeed 17+ , AddArmorMelee 30, AddArmorRanged 30+ , AddSight 3 ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = ""+ , ikit = [ ("large jaw", COrgan), ("large tail", COrgan), ("claw", COrgan)+ , ("armored skin", COrgan), ("eye 4", COrgan) ]+ }++-- * Non-animal animals++hornetSwarm = ItemKind+ { isymbol = 'h'+ , iname = "hornet swarm"+ , ifreq = [("animal", 100), ("horror", 100), ("mobile animal", 100)]+ , iflavour = zipPlain [Magenta]+ , icount = 1+ , irarity = [(5, 1), (10, 5)]+ , iverbHit = "thud"+ , iweight = 1000+ , iaspects = [ AddMaxHP 5, AddMaxCalm 60, AddSpeed 30, AddSight 2+ , AddSkills $ EM.singleton AbAlter (-1)+ , AddArmorMelee 90, AddArmorRanged 90 ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = ""+ , ikit = [("sting", COrgan)]+ }+thornbush = ItemKind+ { isymbol = 'b'+ , iname = "rose bush"+ , ifreq = [("animal", 100)]+ , iflavour = zipPlain [Brown]+ , icount = 1+ , irarity = [(1, 1)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 20, AddMaxCalm 999, AddSpeed 20+ , AddSkills+ $ EM.fromDistinctAscList (zip [minBound..maxBound] [-1, -1..])+ `addSkills` EM.fromList (zip [AbWait, AbMelee] [1, 1..])+ , AddArmorMelee 30, AddArmorRanged 30 ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = ""+ , ikit = [("thorn", COrgan)]+ }++-- * Robots++razorwireFence = ItemKind+ { isymbol = 'f'+ , iname = "razorwire fence"+ , ifreq = [("robot", 100)]+ , iflavour = zipPlain [Cyan]+ , icount = 1+ , irarity = [(1, 1)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 30, AddMaxCalm 999, AddSpeed 20+ , AddSkills+ $ EM.fromDistinctAscList (zip [minBound..maxBound] [-1, -1..])+ `addSkills` EM.fromList (zip [AbWait, AbMelee] [1, 1..])+ , AddArmorMelee 50, AddArmorRanged 50 ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "Must have been bought by previous ship owners to contain the wild animal infestation."+ , ikit = [("razor", COrgan)]+ }+electricFence = ItemKind+ { isymbol = 'f'+ , iname = "electric fence"+ , ifreq = [("robot", 100)]+ , iflavour = zipPlain [Blue]+ , icount = 1+ , irarity = [(1, 1)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 10, AddMaxCalm 999, AddSpeed 50+ , AddSkills+ $ EM.fromDistinctAscList (zip [minBound..maxBound] [-1, -1..])+ `addSkills` EM.fromList (zip [AbWait, AbMelee] [1, 1..])+ , AddArmorMelee 50, AddArmorRanged 50 ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "Marginally intelligent electric shepherd. Originally used in the spaceship's dairy farm and the zoo level."+ , ikit = [("live wire", COrgan)]+ }+activeFence = ItemKind+ { isymbol = 'f'+ , iname = "active fence"+ , ifreq = [("robot", 100)]+ , iflavour = zipPlain [Red]+ , icount = 1+ , irarity = [(4, 0), (5, 1)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 30, AddMaxCalm 999, AddSpeed 20, AddSight 6+ , AddSkills+ $ EM.fromDistinctAscList (zip [minBound..maxBound] [-1, -1..])+ `addSkills` EM.fromList (zip [AbWait, AbProject]+ [1, 1..])+ , AddArmorMelee 50, AddArmorRanged 50 ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "Makeshift, mostly non-lethal, autonomous perimeter defense outpost."+ , ikit = [ ("needle", CInv), ("potion of glue", CInv)+ , ("potion of glue", CInv), ("potion of glue", CInv) ]+ }+steamFaucet = ItemKind+ { isymbol = 'f'+ , iname = "steam faucet"+ , ifreq = [("robot", 100)]+ , iflavour = zipPlain [BrWhite]+ , icount = 1+ , irarity = [(1, 1)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 100, AddMaxCalm 999, AddSpeed 5+ , AddSkills+ $ EM.fromDistinctAscList (zip [minBound..maxBound] [-1, -1..])+ `addSkills` EM.fromList (zip [AbWait, AbMelee] [1, 1..]) ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "A cracked valve on one of the superheated water pipes spreading radially outward from the tokamak level."+ , ikit = [("boiling vent", COrgan), ("fissure", COrgan)]+ }+biogasFaucet = ItemKind+ { isymbol = 'f'+ , iname = "biogas faucet"+ , ifreq = [("robot", 33)] -- very rare+ , iflavour = zipPlain [BrGreen]+ , icount = 1+ , irarity = [(3, 0), (4, 1)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 100, AddMaxCalm 999, AddSpeed 5+ , AddSkills+ $ EM.fromDistinctAscList (zip [minBound..maxBound] [-1, -1..])+ `addSkills` EM.fromList (zip [AbWait] [1, 1..]) ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "An emergency pressure-release vent on a liquefied biogas pipe."+ , ikit = [("explosion vent", COrgan)]+ }+shepherdDrone = ItemKind+ { isymbol = 'd'+ , iname = "shepherd drone"+ , ifreq = [("robot", 100), ("horror", 100), ("mobile robot", 100)]+ , iflavour = zipPlain [BrRed]+ , icount = 1+ , irarity = [(1, 2)]+ , iverbHit = "thud"+ , iweight = 1000+ , iaspects = [ AddMaxHP 2, AddMaxCalm 60, AddSpeed 30, AddSight 4+ , AddSkills+ $ EM.fromDistinctAscList+ $ zip [AbDisplace, AbMoveItem, AbProject] [-1, -1..]+ , AddArmorMelee 90, AddArmorRanged 90 ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "A shabby drone for bringing cows home."+ , ikit = [("eye2", COrgan), ("live wire", COrgan)]+ }+huntingDrone = ItemKind+ { isymbol = 'd'+ , iname = "hunting drone"+ , ifreq = [("robot", 100), ("horror", 100), ("mobile robot", 100)]+ , iflavour = zipPlain [Green]+ , icount = 1+ , irarity = [(4, 0), (5, 1), (10, 2)]+ , iverbHit = "thud"+ , iweight = 500+ , iaspects = [ AddMaxHP 2, AddMaxCalm 60, AddSpeed 40, AddSight 4+ , AddSkills+ $ EM.fromDistinctAscList+ $ zip [AbDisplace, AbMoveItem, AbMelee] [-1, -1..]+ , AddArmorMelee 90, AddArmorRanged 90 ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "Originally designed for hunting down and putting to sleep stray animals. The sleeping agent has long since dried up."+ , ikit = [("eye2", COrgan), ("needle", CInv)]+ }+homeRobot = ItemKind+ { isymbol = 'r'+ , iname = "feral home robot"+ -- TODO: name another 'deranged', tertiary imperative: survival+ , ifreq = [("robot", 100), ("horror", 100), ("mobile robot", 100)]+ , iflavour = zipPlain [Magenta]+ , icount = 1+ , irarity = [(1, 10), (10, 6)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 10, AddMaxCalm 60, AddSpeed 20+ , AddSmell 2 ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "Once a timid household robot, it magnificently adapted to the deadly environment."+ , ikit = [("fist", COrgan), ("eye2", COrgan)]+ }+wasteRobot = ItemKind+ { isymbol = 'r'+ , iname = "waste disposal robot"+ , ifreq = [ ("robot", 100), ("horror", 100), ("mobile robot", 100)+ , ("construction robot", 1) ]+ , iflavour = zipPlain [Green]+ , icount = 1+ , irarity = [(1, 10), (10, 6)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 20, AddMaxCalm 60, AddSpeed 15+ , AddSmell 2 ]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "You are not in its database, hence you are waste."+ , ikit = [ ("jaw", COrgan), ("tentacle", COrgan)+ , ("waste container", COrgan)+ , ("armored skin", COrgan), ("eye3", COrgan) ]+ }+lightRobot = ItemKind+ { isymbol = 'r'+ , iname = "decoration robot"+ , ifreq = [ ("robot", 100), ("horror", 100), ("mobile robot", 100)+ , ("construction robot", 1) ]+ , iflavour = zipPlain [BrYellow]+ , icount = 1+ , irarity = [(1, 8), (10, 8)]+ , iverbHit = "thud"+ , iweight = 80000+ , iaspects = [ AddMaxHP 20, AddMaxCalm 60, AddSpeed 30+ , AddSight 3, AddLight 3 ] -- light can't be turned off+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "Interior and exterior decoration robot. Strongly fancies deep reds recently."+ , ikit = [ ("claw", COrgan), ("tentacle", COrgan)+ , ("armored skin", COrgan), ("eye4", COrgan) ]+ }+heavyRobot = ItemKind+ { isymbol = 'r'+ , iname = "construction robot"+ , ifreq = [ ("robot", 100), ("horror", 100), ("mobile robot", 100)+ , ("construction robot", 100) ]+ , iflavour = zipPlain [BrRed]+ , icount = 1+ , irarity = [(1, 4), (10, 10)]+ , iverbHit = "thud"+ , iweight = 800000+ , iaspects = [ AddMaxHP 80, AddMaxCalm 60, AddSpeed 20+ , AddSight 3, AddLight 4 ] -- light can't be turned off+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = "Heavy multi-purpose construction robot. Excels at discharging, dismantling and demolition."+ , ikit = [ ("largeJaw", COrgan), ("claw", COrgan)+ , ("construction hooter", CInv)+ , ("armored skin", COrgan), ("eye3", COrgan) ]+ }
+ GameDefinition/Content/ItemKindOrgan.hs view
@@ -0,0 +1,259 @@+-- Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+-- This file is a part of the computer game Allure of the Stars+-- and is released under the terms of the GNU Affero General Public License.+-- For license and copyright information, see the file LICENSE.+--+-- | Organ definitions.+module Content.ItemKindOrgan ( organs ) where++import Game.LambdaHack.Common.Color+import Game.LambdaHack.Common.Dice+import Game.LambdaHack.Common.Effect+import Game.LambdaHack.Common.Flavour+import Game.LambdaHack.Common.Misc+import Game.LambdaHack.Common.Msg+import Game.LambdaHack.Content.ItemKind++organs :: [ItemKind]+organs =+ [fist, foot, tentacle, claw, smallClaw, snout, sting, venomTooth, venomFang, largeTail, jaw, largeJaw, armoredSkin, speedGland2, speedGland4, speedGland6, speedGland8, speedGland10, eye2, eye3, eye4, eye5, nostril, thorn, razor, liveWire, boilingVent, explosionVent, fissure, wasteContainer]++fist, foot, tentacle, claw, smallClaw, snout, sting, venomTooth, venomFang, largeTail, jaw, largeJaw, armoredSkin, speedGland2, speedGland4, speedGland6, speedGland8, speedGland10, eye2, eye3, eye4, eye5, nostril, thorn, razor, liveWire, boilingVent, explosionVent, fissure, wasteContainer :: ItemKind++-- * Parameterized organs++speedGland :: Int -> ItemKind+speedGland n = fist+ { iname = "speed gland"+ , ifreq = [(toGroupName $ "speed gland" <+> tshow n, 100)]+ , icount = 1+ , iverbHit = "spit at"+ , iaspects = [AddSpeed $ intToDice n, Periodic $ intToDice n]+ , ieffects = [RefillHP 1]+ , ifeature = [Durable, Identified]+ , idesc = ""+ }+speedGland2 = speedGland 2+speedGland4 = speedGland 4+speedGland6 = speedGland 6+speedGland8 = speedGland 8+speedGland10 = speedGland 10+eye :: Int -> ItemKind+eye n = fist+ { iname = "eye"+ , ifreq = [(toGroupName $ "eye" <+> tshow n, 100)]+ , icount = 2+ , iverbHit = "glare at"+ , iaspects = [AddSight (intToDice n)]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = ""+ }+eye2 = eye 2+eye3 = eye 3+eye4 = eye 4+eye5 = eye 5++-- * Human weapon organs++fist = ItemKind+ { isymbol = '%'+ , iname = "fist"+ , ifreq = [("fist", 100)]+ , iflavour = zipPlain [BrRed]+ , icount = 2+ , irarity = [(1, 1)]+ , iverbHit = "punch"+ , iweight = 2000+ , iaspects = []+ , ieffects = [Hurt (4 * d 1)]+ , ifeature = [Durable, EqpSlot EqpSlotWeapon "", Identified]+ , idesc = ""+ , ikit = []+ }+foot = fist+ { iname = "foot"+ , ifreq = [("foot", 50)]+ , icount = 2+ , iverbHit = "kick"+ , ieffects = [Hurt (4 * d 1)]+ , idesc = ""+ }++-- * Universal weapon organs++claw = fist+ { iname = "claw"+ , ifreq = [("claw", 50)]+ , icount = 2 -- even if more, only the fore claws used for fighting+ , iverbHit = "slash"+ , ieffects = [Hurt (6 * d 1)]+ , idesc = ""+ }+smallClaw = fist+ { iname = "small claw"+ , ifreq = [("small claw", 50)]+ , icount = 2+ , iverbHit = "slash"+ , ieffects = [Hurt (3 * d 1)]+ , idesc = ""+ }+snout = fist+ { iname = "snout"+ , ifreq = [("snout", 10)]+ , iverbHit = "bite"+ , ieffects = [Hurt (2 * d 1)]+ , idesc = ""+ }+jaw = fist+ { iname = "jaw"+ , ifreq = [("jaw", 20)]+ , icount = 1+ , iverbHit = "rip"+ , ieffects = [Hurt (5 * d 1)]+ , idesc = ""+ }+largeJaw = fist+ { iname = "large jaw"+ , ifreq = [("large jaw", 100)]+ , icount = 1+ , iverbHit = "crush"+ , ieffects = [Hurt (12 * d 1)]+ , idesc = ""+ }+tentacle = fist+ { iname = "tentacle"+ , ifreq = [("tentacle", 50)]+ , icount = 4+ , iverbHit = "slap"+ , ieffects = [Hurt (4 * d 1)]+ , idesc = ""+ }++-- * Special weapon organs++thorn = fist+ { iname = "thorn"+ , ifreq = [("thorn", 100)]+ , icount = 7+ , iverbHit = "impale"+ , ieffects = [Hurt (1 * d 1)]+ , idesc = ""+ }+razor = fist+ { iname = "razor"+ , ifreq = [("razor", 100)]+ , icount = 7+ , iverbHit = "slice"+ , ieffects = [Hurt (2 * d 1)]+ , idesc = ""+ }+fissure = fist+ { iname = "fissure"+ , ifreq = [("fissure", 100)]+ , icount = 2+ , iverbHit = "hiss at"+ , ieffects = [Burn 1]+ , idesc = ""+ }+sting = fist+ { iname = "sting"+ , ifreq = [("sting", 100)]+ , icount = 1+ , iverbHit = "sting"+ , ieffects = [Burn 1, Paralyze 2]+ , idesc = ""+ }+venomTooth = fist+ { iname = "venom tooth"+ , ifreq = [("venom tooth", 100)]+ , icount = 2+ , iverbHit = "bite"+ , ieffects = [Hurt (3 * d 1), Paralyze 3]+ , idesc = ""+ }+venomFang = fist+ { iname = "venom fang"+ , ifreq = [("venom fang", 100)]+ , icount = 2+ , iverbHit = "bite"+ , ieffects = [Hurt (3 * d 1)] -- TODO: +12 damage or poison effect+ , idesc = ""+ }+largeTail = fist+ { iname = "large tail"+ , ifreq = [("large tail", 50)]+ , icount = 1+ , iverbHit = "knock"+ , ieffects = [Hurt (8 * d 1), PushActor (ThrowMod 400 25)]+ , idesc = ""+ }+liveWire = fist+ { iname = "live wire"+ , ifreq = [("live wire", 100)]+ , icount = 4+ , iverbHit = "shock"+ , iaspects = []+ , ieffects = [Hurt (1 * d 1), Paralyze 1]+ , idesc = ""+ }++-- * Armor organs++armoredSkin = fist+ { iname = "armored skin"+ , ifreq = [("armored skin", 100)]+ , icount = 1+ , iverbHit = "bash"+ , iaspects = [AddArmorMelee 30, AddArmorRanged 30]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = ""+ }++-- * Sense organs++nostril = fist+ { iname = "nostril"+ , ifreq = [("nostril", 100)]+ , icount = 2+ , iverbHit = "snuff"+ , iaspects = [AddSmell 1]+ , ieffects = []+ , ifeature = [Durable, Identified]+ , idesc = ""+ }++-- * Assorted++boilingVent = fist+ { iname = "vent"+ , ifreq = [("boiling vent", 100)]+ , icount = 1+ , iverbHit = "menace"+ , iaspects = [Periodic $ 1 + d 2]+ , ieffects = [Explode "boiling water"]+ , ifeature = [Durable, Identified]+ , idesc = ""+ }+explosionVent = fist+ { iname = "vent"+ , ifreq = [("explosion vent", 100)]+ , icount = 1+ , iverbHit = "menace"+ , iaspects = [Periodic $ 2 + d 2]+ , ieffects = [Explode "explosion blast 20"]+ , ifeature = [Durable, Identified]+ , idesc = ""+ }+wasteContainer = fist+ { iname = "waste container"+ , ifreq = [("waste container", 100)]+ , icount = 1+ , iverbHit = "spill over"+ , iaspects = [Periodic 1]+ , ieffects = [ Summon [("mobile animal", 1)] $ 1 + dl 2, RefillHP 1+ , Explode "waste" ]+ , ifeature = [Durable, Identified]+ , idesc = ""+ }
+ GameDefinition/Content/ItemKindShrapnel.hs view
@@ -0,0 +1,261 @@+-- Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+-- This file is a part of the computer game Allure of the Stars+-- and is released under the terms of the GNU Affero General Public License.+-- For license and copyright information, see the file LICENSE.+--+-- | Shrapnel definitions.+module Content.ItemKindShrapnel ( shrapnels ) where++import Game.LambdaHack.Common.Color+import Game.LambdaHack.Common.Dice+import Game.LambdaHack.Common.Effect+import Game.LambdaHack.Common.Flavour+import Game.LambdaHack.Common.Misc+import Game.LambdaHack.Common.Msg+import Game.LambdaHack.Content.ItemKind++shrapnels :: [ItemKind]+shrapnels =+ [fragrance, pheromone, firecracker2, firecracker3, firecracker4, firecracker5, firecracker6, firecracker7, mistHealing, mistHealing2, mistWounding, distortion, waste, burningOil2, burningOil3, burningOil4, explosionBlast10, explosionBlast20, glassPiece, smoke, boilingWater, glue]++fragrance, pheromone, firecracker2, firecracker3, firecracker4, firecracker5, firecracker6, firecracker7, mistHealing, mistHealing2, mistWounding, distortion, waste, burningOil2, burningOil3, burningOil4, explosionBlast10, explosionBlast20, glassPiece, smoke, boilingWater, glue :: ItemKind++-- * Parameterized shrapnel++burningOil :: Int -> ItemKind+burningOil n = ItemKind+ { isymbol = '*'+ , iname = "burning oil"+ , ifreq = [(toGroupName $ "burning oil" <+> tshow n, 1)]+ , iflavour = zipFancy [BrYellow]+ , icount = intToDice (n * 4)+ , irarity = [(1, 1)]+ , iverbHit = "burn"+ , iweight = 1+ , iaspects = [AddLight 2]+ , ieffects = [ Burn (n `div` 2)+ , Paralyze (intToDice $ n `div` 2) ] -- tripping on oil+ , ifeature = [ toVelocity (min 100 $ n * 7)+ , Fragile, Identified ]+ , idesc = "Sticky oil, burning brightly."+ , ikit = []+ }+burningOil2 = burningOil 2+burningOil3 = burningOil 3+burningOil4 = burningOil 4+explosionBlast :: Int -> ItemKind+explosionBlast n = ItemKind+ { isymbol = '*'+ , iname = "explosion blast"+ , ifreq = [(toGroupName $ "explosion blast" <+> tshow n, 1)]+ , iflavour = zipPlain [BrRed]+ , icount = 12 -- strong, but few, so not always hits target+ , irarity = [(1, 1)]+ , iverbHit = "tear apart"+ , iweight = 1+ , iaspects = [AddLight $ intToDice n]+ , ieffects = [RefillHP (- n `div` 2), DropBestWeapon]+ , ifeature = [Fragile, toLinger 10, Identified]+ , idesc = ""+ , ikit = []+ }+explosionBlast10 = explosionBlast 10+explosionBlast20 = explosionBlast 20+firecracker :: Int -> ItemKind+firecracker n = ItemKind+ { isymbol = '*'+ , iname = "firecracker"+ , ifreq = [(toGroupName $ "firecracker" <+> tshow n, 1)]+ , iflavour = zipPlain [stdCol !! (n `mod` length stdCol)]+ , icount = intToDice $ 2 * n+ , irarity = [(1, 1)]+ , iverbHit = "crack"+ , iweight = 1+ , iaspects = [AddLight $ intToDice $ n `div` 2]+ , ieffects = [Burn 1, Explode $ toGroupName $ "firecracker" <+> tshow (n - 1)]+ , ifeature = [ ToThrow $ ThrowMod (n * 10) 20+ , Fragile, Identified ]+ , idesc = ""+ , ikit = []+ }+firecracker7 = firecracker 7+firecracker6 = firecracker 6+firecracker5 = firecracker 5+firecracker4 = firecracker 4+firecracker3 = firecracker 3+firecracker2 = firecracker 2++-- * Assorted++fragrance = ItemKind+ { isymbol = '\''+ , iname = "fragrance"+ , ifreq = [("fragrance", 1)]+ , iflavour = zipFancy [Magenta]+ , icount = 15+ , irarity = [(1, 1)]+ , iverbHit = "engulf"+ , iweight = 1+ , iaspects = []+ , ieffects = [Impress]+ , ifeature = [ toVelocity 13 -- the slowest that travels at least 2 steps+ , Fragile, Identified ]+ , idesc = ""+ , ikit = []+ }+pheromone = ItemKind+ { isymbol = '\''+ , iname = "musky whiff"+ , ifreq = [("pheromone", 1)]+ , iflavour = zipFancy [BrMagenta]+ , icount = 8+ , irarity = [(1, 1)]+ , iverbHit = "tempt"+ , iweight = 1+ , iaspects = []+ , ieffects = [Dominate]+ , ifeature = [ toVelocity 13 -- the slowest that travels at least 2 steps+ , Fragile, Identified ]+ , idesc = ""+ , ikit = []+ }+mistHealing = ItemKind+ { isymbol = '\''+ , iname = "mist"+ , ifreq = [("healing mist", 1)]+ , iflavour = zipFancy [White]+ , icount = 11+ , irarity = [(1, 1)]+ , iverbHit = "revitalize"+ , iweight = 1+ , iaspects = [AddLight 1]+ , ieffects = [RefillHP 2]+ , ifeature = [ toVelocity 7 -- the slowest that gets anywhere (1 step only)+ , Fragile, Identified ]+ , idesc = ""+ , ikit = []+ }+mistHealing2 = ItemKind+ { isymbol = '\''+ , iname = "mist"+ , ifreq = [("healing mist 2", 1)]+ , iflavour = zipFancy [White]+ , icount = 12+ , irarity = [(1, 1)]+ , iverbHit = "revitalize"+ , iweight = 1+ , iaspects = [AddLight 2]+ , ieffects = [RefillHP 4]+ , ifeature = [ toVelocity 7 -- the slowest that gets anywhere (1 step only)+ , Fragile, Identified ]+ , idesc = ""+ , ikit = []+ }+mistWounding = ItemKind+ { isymbol = '\''+ , iname = "mist"+ , ifreq = [("wounding mist", 1)]+ , iflavour = zipFancy [White]+ , icount = 13+ , irarity = [(1, 1)]+ , iverbHit = "devitalize"+ , iweight = 1+ , iaspects = []+ , ieffects = [RefillHP (-2)]+ , ifeature = [ toVelocity 7 -- the slowest that gets anywhere (1 step only)+ , Fragile, Identified ]+ , idesc = ""+ , ikit = []+ }+distortion = ItemKind+ { isymbol = 'v'+ , iname = "vortex"+ , ifreq = [("distortion", 1)]+ , iflavour = zipFancy [White]+ , icount = 4+ , irarity = [(1, 1)]+ , iverbHit = "engulf"+ , iweight = 1+ , iaspects = []+ , ieffects = [Teleport $ 15 + d 10]+ , ifeature = [ toVelocity 7 -- the slowest that gets anywhere (1 step only)+ , Fragile, Identified ]+ , idesc = ""+ , ikit = []+ }+waste = ItemKind+ { isymbol = '*'+ , iname = "waste"+ , ifreq = [("waste", 1)]+ , iflavour = zipPlain [Brown]+ , icount = 10+ , irarity = [(1, 1)]+ , iverbHit = "splosh"+ , iweight = 50+ , iaspects = []+ , ieffects = [RefillHP (-1)]+ , ifeature = [ ToThrow $ ThrowMod 28 50+ , Fragile, Identified ]+ , idesc = ""+ , ikit = []+ }+glassPiece = ItemKind -- when blowing up windows+ { isymbol = '*'+ , iname = "glass piece"+ , ifreq = [("glass piece", 1)]+ , iflavour = zipPlain [BrBlue]+ , icount = 17+ , irarity = [(1, 1)]+ , iverbHit = "cut"+ , iweight = 10+ , iaspects = []+ , ieffects = [Hurt (1 * d 1)]+ , ifeature = [toLinger 20, Fragile, Identified]+ , idesc = ""+ , ikit = []+ }+smoke = ItemKind -- when stuff burns out+ { isymbol = '\''+ , iname = "smoke"+ , ifreq = [("smoke", 1), ("firecracker 1", 1)]+ , iflavour = zipPlain [BrBlack]+ , icount = 19+ , irarity = [(1, 1)]+ , iverbHit = "choke"+ , iweight = 1+ , iaspects = []+ , ieffects = []+ , ifeature = [ toVelocity 21, Fragile, Identified ]+ , idesc = ""+ , ikit = []+ }+boilingWater = ItemKind+ { isymbol = '*'+ , iname = "boiling water"+ , ifreq = [("boiling water", 1)]+ , iflavour = zipPlain [BrWhite]+ , icount = 9+ , irarity = [(1, 1)]+ , iverbHit = "boil"+ , iweight = 5+ , iaspects = []+ , ieffects = [Burn 1]+ , ifeature = [toVelocity 50, Fragile, Identified]+ , idesc = ""+ , ikit = []+ }+glue = ItemKind+ { isymbol = '*'+ , iname = "sticky foam"+ , ifreq = [("glue", 1)]+ , iflavour = zipPlain [BrYellow]+ , icount = 14+ , irarity = [(1, 1)]+ , iverbHit = "glue"+ , iweight = 20+ , iaspects = []+ , ieffects = [Paralyze (3 + d 3)]+ , ifeature = [toVelocity 40, Fragile, Identified]+ , idesc = ""+ , ikit = []+ }
+ GameDefinition/Content/ModeKind.hs view
@@ -0,0 +1,260 @@+-- Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+-- This file is a part of the computer game Allure of the Stars+-- and is released under the terms of the GNU Affero General Public License.+-- For license and copyright information, see the file LICENSE.+--+-- | Game mode definitions.+module Content.ModeKind ( cdefs ) where++import qualified Data.IntMap.Strict as IM++import Content.ModeKindPlayer+import Game.LambdaHack.Common.ContentDef+import Game.LambdaHack.Content.ModeKind++cdefs :: ContentDef ModeKind+cdefs = ContentDef+ { getSymbol = msymbol+ , getName = mname+ , getFreq = mfreq+ , validateSingle = validateSingleModeKind+ , validateAll = validateAllModeKind+ , content =+ [campaign, duel, skirmish, ambush, battle, safari, pvp, coop, defense]+ }+campaign, duel, skirmish, ambush, battle, safari, pvp, coop, defense :: ModeKind++campaign = ModeKind+ { msymbol = 'a'+ , mname = "campaign"+ , mfreq = [("campaign", 1)]+ , mroster = rosterCampaign+ , mcaves = cavesCampaign+ , mdesc = "You got stranded looting a once luxurious cruise liner and your current plan is to fight through, gathering your spoils, to the bridge at the giant spaceship's opposite end."+ }++duel = ModeKind+ { msymbol = 'u'+ , mname = "duel"+ , mfreq = [("duel", 1)]+ , mroster = rosterDuel+ , mcaves = cavesSkirmish+ , mdesc = "Let's settle the argument about this noble lady outside, in the woody biosphere behind the saloon."+ }++skirmish = ModeKind+ { msymbol = 'k'+ , mname = "skirmish"+ , mfreq = [("skirmish", 1)]+ , mroster = rosterSkirmish+ , mcaves = cavesSkirmish+ , mdesc = "You owe restorative surgery to one of our crew: if we win, we take all you have; if you win, you take ours old giant spaceship (if you still want it when you see it)."+ }++ambush = ModeKind+ { msymbol = 'm'+ , mname = "ambush"+ , mfreq = [("ambush", 1)]+ , mroster = rosterAmbush+ , mcaves = cavesAmbush+ , mdesc = "Conveniently, on the path to the Triton's spaceport, passengers can relax in a shady park."+ }++battle = ModeKind+ { msymbol = 'b'+ , mname = "battle"+ , mfreq = [("battle", 1)]+ , mroster = rosterBattle+ , mcaves = cavesBattle+ , mdesc = "Not even the unexplained ruin of the largest and tightest security Neptune's moon spaceport will prevent you from claiming your prize."+ }++safari = ModeKind+ { msymbol = 'f'+ , mname = "safari"+ , mfreq = [("safari", 1)]+ , mroster = rosterSafari+ , mcaves = cavesSafari+ , mdesc = "In this simulation you'll discover the joys of hunting the most exquisite of Earth's flora and fauna, both animal and semi-intelligent (exit at the bottommost level)."+ }++pvp = ModeKind+ { msymbol = 'v'+ , mname = "PvP"+ , mfreq = [("PvP", 1)]+ , mroster = rosterPvP+ , mcaves = cavesSkirmish+ , mdesc = "(Not usable right now.) This is a fight to the death between two human-controlled teams."+ }++coop = ModeKind+ { msymbol = 'o'+ , mname = "Coop"+ , mfreq = [("Coop", 1)]+ , mroster = rosterCoop+ , mcaves = cavesCampaign+ , mdesc = "(This mode is intended solely for automated testing.)"+ }++defense = ModeKind+ { msymbol = 'e'+ , mname = "defense"+ , mfreq = [("defense", 1)]+ , mroster = rosterDefense+ , mcaves = cavesCampaign+ , mdesc = "Don't let the half-witted humans derail your operation and flee, like the puny, naked, tentacle-less beasts that they are!"+ }+++rosterCampaign, rosterDuel, rosterSkirmish, rosterAmbush, rosterBattle, rosterSafari, rosterPvP, rosterCoop, rosterDefense :: Roster++rosterCampaign = Roster+ { rosterList = [ playerHero+ , playerMonster+ , playerAnimal+ , playerRobot ]+ , rosterEnemy = [ ("Spacefarer Crew", "Alien Hierarchy")+ , ("Spacefarer Crew", "Animal Kingdom")+ , ("Spacefarer Crew", "Robot Anarchy") ]+ , rosterAlly = [ ("Alien Hierarchy", "Animal Kingdom")+ , ("Alien Hierarchy", "Robot Anarchy")+ , ("Robot Anarchy", "Animal Kingdom") ] }++rosterDuel = Roster+ { rosterList = [ playerHero { fname = "Spacefarer Crew"+ , fentryLevel = 3+ , finitialActors = 1 }+ , playerAntiHero { fname = "Red Collars"+ , fentryLevel = 3+ , finitialActors = 1 }+ , playerHorror ]+ , rosterEnemy = [ ("Spacefarer Crew", "Red Collars")+ , ("Spacefarer Crew", "Horror Den")+ , ("Red Collars", "Horror Den") ]+ , rosterAlly = [] }++rosterSkirmish = rosterDuel+ { rosterList = [ playerHero { fname = "Spacefarer Crew"+ , fentryLevel = 3 }+ , playerAntiHero { fname = "Red Collars"+ , fentryLevel = 3 }+ , playerHorror ] }++rosterAmbush = rosterDuel+ { rosterList = [ playerHero { fname = "Spacefarer Crew"+ , fentryLevel = 5 }+ , playerAntiHero { fname = "Red Collars"+ , fentryLevel = 5 }+ , playerHorror {fentryLevel = 5} ] }++rosterBattle = Roster+ { rosterList = [ playerSoldier { finitialActors = 5+ , fentryLevel = 5 }+ , playerMobileMonster { finitialActors = 30+ , fentryLevel = 5+ , fneverEmpty = True }+ , playerMobileAnimal { finitialActors = 10+ , fentryLevel = 5+ , fneverEmpty = True }+ , playerMobileRobot { finitialActors = 10+ , fentryLevel = 5+ , fneverEmpty = True } ]+ , rosterEnemy = [ ("Armed Spacefarer Crew", "Alien Hierarchy")+ , ("Armed Spacefarer Crew", "Animal Kingdom")+ , ("Armed Spacefarer Crew", "Robot Anarchy") ]+ , rosterAlly = [ ("Alien Hierarchy", "Animal Kingdom")+ , ("Alien Hierarchy", "Robot Anarchy")+ , ("Robot Anarchy", "Animal Kingdom") ] }++rosterSafari = Roster+ { rosterList = [ playerAntiMonster { fname = "Alien Tourist Office"+ , fcanEscape = True+ , fneverEmpty = True+ -- Follow-the-guide, as tourists do.+ , ftactic = TFollow+ , fentryLevel = 4+ , finitialActors = 15+ , fleaderMode =+ LeaderUI $ AutoLeader False False }+ , playerCivilian { fname = "Hunam Convict Pack"+ , fentryLevel = 4 }+ , playerMobileAnimal { fname =+ "Animal Magnificent Specimen Variety"+ , fneverEmpty = True+ , fentryLevel = 7+ , finitialActors = 10 }+ , playerMobileAnimal { fname =+ "Animal Exquisite Herds and Packs"+ , fneverEmpty = True+ , fentryLevel = 10+ , finitialActors = 25 } ]+ , rosterEnemy = [ ("Alien Tourist Office", "Hunam Convict Pack")+ , ("Alien Tourist Office",+ "Animal Magnificent Specimen Variety")+ , ("Alien Tourist Office",+ "Animal Exquisite Herds and Packs") ]+ , rosterAlly = [( "Animal Magnificent Specimen Variety"+ , "Animal Exquisite Herds and Packs" )] }++rosterPvP = Roster+ { rosterList = [ playerHero { fname = "Red"+ , fentryLevel = 3 }+ , playerHero { fname = "Blue"+ , fentryLevel = 3 }+ , playerHorror ]+ , rosterEnemy = [ ("Red", "Blue")+ , ("Red", "Horror Den")+ , ("Blue", "Horror Den") ]+ , rosterAlly = [] }++rosterCoop = Roster+ { rosterList = [ playerAntiHero { fname = "Coral" }+ , playerAntiHero { fname = "Amber"+ , fleaderMode = LeaderNull }+ , playerAntiHero { fname = "Green" }+ , playerAnimal { fhasUI = True }+ , playerMonster { fname = "Alien Hierarchy" }+ , playerMonster { fname = "Leaderless Alien Hierarchy"+ , fleaderMode = LeaderNull }+ , playerRobot ]+ , rosterEnemy = [ ("Coral", "Alien Hierarchy")+ , ("Amber", "Alien Hierarchy")+ , ("Animal Kingdom", "Leaderless Alien Hierarchy") ]+ , rosterAlly = [ ("Coral", "Amber")+ , ("Coral", "Green")+ , ("Amber", "Green")+ , ("Green", "Animal Kingdom")+ , ("Green", "Robot Anarchy")+ , ("Green", "Alien Hierarchy")+ , ("Green", "Leaderless Alien Hierarchy") ] }++rosterDefense = Roster+ { rosterList = [ playerAntiMonster { finitialActors = 1 }+ , playerAntiHero { fname = "Yellow"+ , finitialActors = 10 }+ , playerAnimal+ , playerRobot ]+ , rosterEnemy = [ ("Yellow", "Alien Hierarchy")+ , ("Yellow", "Animal Kingdom")+ , ("Yellow", "Robot Anarchy") ]+ , rosterAlly = [ ("Alien Hierarchy", "Animal Kingdom")+ , ("Alien Hierarchy", "Robot Anarchy")+ , ("Robot Anarchy", "Animal Kingdom") ] }+++cavesCampaign, cavesSkirmish, cavesAmbush, cavesBattle, cavesSafari :: Caves++cavesCampaign = IM.fromList+ $ [(1, ("caveRogue", Nothing))]+ ++ zip [2..11] (repeat ("campaign random", Nothing))+ ++ [(12, ("caveNoise", Just True))]++cavesSkirmish = IM.fromList [(3, ("caveSkirmish", Nothing))]++cavesAmbush = IM.fromList [(5, ("caveAmbush", Nothing))]++cavesBattle = IM.fromList [(5, ("caveBattle", Nothing))]++cavesSafari = IM.fromList [ (4, ("caveSafari1", Nothing))+ , (7, ("caveSafari2", Nothing))+ , (10, ("caveSafari3", Just False)) ]
+ GameDefinition/Content/ModeKindPlayer.hs view
@@ -0,0 +1,149 @@+-- Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+-- This file is a part of the computer game Allure of the Stars+-- and is released under the terms of the GNU Affero General Public License.+-- For license and copyright information, see the file LICENSE.+--+-- | Basic players definitions.+module Content.ModeKindPlayer+ ( playerHero, playerSoldier, playerAntiHero, playerCivilian, playerMonster+ , playerMobileMonster, playerAntiMonster, playerAnimal, playerMobileAnimal+ , playerRobot, playerMobileRobot, playerHorror+ ) where++import qualified Data.EnumMap.Strict as EM++import Game.LambdaHack.Common.Ability+import Game.LambdaHack.Content.ModeKind++playerHero, playerSoldier, playerAntiHero, playerCivilian, playerMonster, playerMobileMonster, playerAntiMonster, playerAnimal, playerMobileAnimal, playerRobot, playerMobileRobot, playerHorror :: Player++playerHero = Player+ { fname = "Spacefarer Crew"+ , fgroup = "hero"+ , fskillsOther = meleeAdjacent+ , fcanEscape = True+ , fneverEmpty = True+ , fhasNumbers = True+ , fhasGender = True+ , ftactic = TExplore+ , fentryLevel = 1+ , finitialActors = 3+ , fleaderMode = LeaderUI $ AutoLeader False False+ , fhasUI = True+ }++playerSoldier = playerHero+ { fname = "Armed Spacefarer Crew"+ , fgroup = "soldier"+ }++playerAntiHero = playerHero+ { fleaderMode = LeaderAI $ AutoLeader False False+ , fhasUI = False+ }++playerCivilian = Player+ { fname = "Civilian Crowd"+ , fgroup = "civilian"+ , fskillsOther = unitSkills -- not coordinated by any leadership+ , fcanEscape = False+ , fneverEmpty = True+ , fhasNumbers = False+ , fhasGender = True+ , ftactic = TPatrol+ , fentryLevel = 1+ , finitialActors = 3+ , fleaderMode = LeaderNull -- unorganized+ , fhasUI = False+ }++playerMonster = Player+ { fname = "Alien Hierarchy"+ , fgroup = "alien"+ , fskillsOther = unitSkills+ , fcanEscape = False+ , fneverEmpty = False+ , fhasNumbers = False+ , fhasGender = False+ , ftactic = TExplore+ , fentryLevel = 4+ , finitialActors = 3+ , fleaderMode = LeaderAI $ AutoLeader True False+ , fhasUI = False+ }++playerMobileMonster = playerMonster++playerAntiMonster = playerMonster+ { fhasUI = True+ }++playerAnimal = Player+ { fname = "Animal Kingdom"+ , fgroup = "animal"+ , fskillsOther = animalSkills+ , fcanEscape = False+ , fneverEmpty = False+ , fhasNumbers = False+ , fhasGender = False+ , ftactic = TRoam -- can't pick up, so no point exploring+ , fentryLevel = 2+ , finitialActors = 3+ , fleaderMode = LeaderNull+ , fhasUI = False+ }++playerMobileAnimal = playerAnimal+ { fgroup = "mobile animal" }++playerRobot = Player+ { fname = "Robot Anarchy"+ , fgroup = "robot"+ , fskillsOther = robotSkills+ , fcanEscape = False+ , fneverEmpty = False+ , fhasNumbers = False+ , fhasGender = False+ , ftactic = TFollow -- coordinated via net, follow alien leader (TODO)+ , fentryLevel = 3+ , finitialActors = 3+ , fleaderMode = LeaderNull+ , fhasUI = False+ }++playerMobileRobot = playerRobot+ { fgroup = "mobile robot" }++-- | A special player, for summoned actors that don't belong to any+-- of the main players of a given game. E.g., animals summoned during+-- a duel game between two hero players land in the horror faction.+-- In every game, either all factions for which summoning items exist+-- should be present or a horror player should be added to host them.+-- Actors that can be summoned should have "horror" in their @ifreq@ set.+playerHorror = Player+ { fname = "Horror Den"+ , fgroup = "horror"+ , fskillsOther = unitSkills+ , fcanEscape = False+ , fneverEmpty = False+ , fhasNumbers = False+ , fhasGender = False+ , ftactic = TPatrol -- disoriented+ , fentryLevel = 3+ , finitialActors = 0+ , fleaderMode = LeaderNull+ , fhasUI = False+ }+++meleeAdjacent, _meleeAndRanged, animalSkills, robotSkills :: Skills++meleeAdjacent = EM.fromList $ zip [AbWait, AbMelee] [1, 1..]++-- Melee and reaction fire.+_meleeAndRanged = EM.fromList $ zip [AbWait, AbMelee, AbProject] [1, 1..]++animalSkills =+ EM.fromList $ zip [AbMove, AbMelee, AbAlter, AbWait, AbTrigger] [1, 1..]++robotSkills = EM.delete AbApply unitSkills
+ GameDefinition/Content/PlaceKind.hs view
@@ -0,0 +1,316 @@+-- Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+-- This file is a part of the computer game Allure of the Stars+-- and is released under the terms of the GNU Affero General Public License.+-- For license and copyright information, see the file LICENSE.+--+-- | Room, hall and passage definitions.+module Content.PlaceKind ( cdefs ) where++import Game.LambdaHack.Common.ContentDef+import Game.LambdaHack.Content.PlaceKind++cdefs :: ContentDef PlaceKind+cdefs = ContentDef+ { getSymbol = psymbol+ , getName = pname+ , getFreq = pfreq+ , validateSingle = validateSinglePlaceKind+ , validateAll = validateAllPlaceKind+ , content =+ [rect, ruin, collapsed, collapsed2, collapsed3, collapsed4, pillar, pillar2, pillar3, pillar4, colonnade, colonnade2, colonnade3, colonnade4, colonnadeWide, lampPost, lampPost2, lampPost3, lampPost4, treeShade, treeShade2, treeShade3, oval, ovalFloor, ovalSquare, maze, maze2, maze3, mazeBig, mazeBig2, mazeBig3, cells]+ }+rect, ruin, collapsed, collapsed2, collapsed3, collapsed4, pillar, pillar2, pillar3, pillar4, colonnade, colonnade2, colonnade3, colonnade4, colonnadeWide, lampPost, lampPost2, lampPost3, lampPost4, treeShade, treeShade2, treeShade3, oval, ovalFloor, ovalSquare, maze, maze2, maze3, mazeBig, mazeBig2, mazeBig3, cells :: PlaceKind++rect = PlaceKind -- Valid for any nonempty area, hence low frequency.+ { psymbol = 'r'+ , pname = "room"+ , pfreq = [("rogue", 70), ("ambush", 8), ("noise", 40)]+ , prarity = [(1, 10), (10, 8)]+ , pcover = CStretch+ , pfence = FWall+ , ptopLeft = ["."]+ , poverride = []+ }+ruin = PlaceKind+ { psymbol = 'R'+ , pname = "ruin"+ , pfreq = [("ambush", 17), ("battle", 100), ("noise", 20)]+ , prarity = [(1, 10), (10, 20)]+ , pcover = CStretch+ , pfence = FWall+ , ptopLeft = ["X"]+ , poverride = []+ }+collapsed = PlaceKind+ { psymbol = 'c'+ , pname = "collapsed cavern"+ , pfreq = [("noise", 1)]+ , prarity = [(1, 10), (10, 10)]+ , pcover = CStretch+ , pfence = FNone+ , ptopLeft = ["#"]+ , poverride = [('#', "doorlessWallOver_#")]+ }+collapsed2 = collapsed+ { pfreq = [("noise", 100), ("battle", 50)]+ , ptopLeft = [ "XX#"+ , "X##"+ ]+ }+collapsed3 = collapsed+ { pfreq = [("noise", 200), ("battle", 50)]+ , ptopLeft = [ "XXX#"+ , "X###"+ ]+ }+collapsed4 = collapsed+ { pfreq = [("noise", 400), ("battle", 200)]+ , ptopLeft = [ "XXX#"+ , "XXX#"+ , "X###"+ ]+ }+pillar = PlaceKind+ { psymbol = 'p'+ , pname = "pillar room"+ , pfreq = [("rogue", 1000), ("noise", 50)]+ , prarity = [(1, 10), (10, 10)]+ , pcover = CStretch+ , pfence = FWall+ -- Larger rooms require support pillars.+ , ptopLeft = [ "...."+ , ".O.."+ , "...."+ , "...."+ ]+ , poverride = []+ }+pillar2 = pillar+ { prarity = [(1, 5), (10, 5)]+ , ptopLeft = [ ".#.."+ , "#..."+ , "...."+ , "...."+ ]+ }+pillar3 = pillar+ { prarity = [(1, 5), (10, 5)]+ , ptopLeft = [ "#..."+ , "..#."+ , ".#.."+ , "...."+ ]+ }+pillar4 = pillar+ { prarity = [(10, 7)]+ , ptopLeft = [ "&.#."+ , "...."+ , "#..."+ , "...."+ ]+ }+colonnade = PlaceKind+ { psymbol = 'c'+ , pname = "colonnade"+ , pfreq = [("rogue", 70), ("noise", 2000)]+ , prarity = [(1, 10), (10, 10)]+ , pcover = CAlternate+ , pfence = FFloor+ , ptopLeft = [ ".#"+ , "#."+ ]+ , poverride = []+ }+colonnade2 = colonnade+ { prarity = [(1, 2), (10, 4)]+ , pfence = FGround+ , ptopLeft = [ ".."+ , ".O"+ ]+ }+colonnade3 = colonnade+ { prarity = [(1, 4), (10, 6)]+ , ptopLeft = [ "#.."+ , "..#"+ ]+ }+colonnade4 = colonnade+ { ptopLeft = [ "#."+ , ".."+ , ".#"+ ]+ }+colonnadeWide = colonnade+ { prarity = [(1, 3), (10, 3)]+ , pfence = FWall+ , ptopLeft = [ ".."+ , ".#"+ ]+ }+lampPost = PlaceKind+ { psymbol = 'l'+ , pname = "lamp post"+ , pfreq = [("ambush", 30), ("battle", 10)]+ , prarity = [(1, 10), (10, 10)]+ , pcover = CVerbatim+ , pfence = FNone+ , ptopLeft = [ "X.X"+ , ".O."+ , "X.X"+ ]+ , poverride = [('O', "lampPostOver_O")]+ }+lampPost2 = lampPost+ { ptopLeft = [ "..."+ , ".O."+ , "..."+ ]+ }+lampPost3 = lampPost+ { ptopLeft = [ "XX.XX"+ , "X...X"+ , "..O.."+ , "X...X"+ , "XX.XX"+ ]+ }+lampPost4 = lampPost+ { ptopLeft = [ "X...X"+ , "....."+ , "..O.."+ , "....."+ , "X...X"+ ]+ }+treeShade = PlaceKind+ { psymbol = 't'+ , pname = "tree shade"+ , pfreq = [("skirmish", 100)]+ , prarity = [(1, 10), (10, 10)]+ , pcover = CVerbatim+ , pfence = FNone+ , ptopLeft = [ "sss"+ , "XOs"+ , "XXs"+ ]+ , poverride = [('O', "treeShadeOver_O"), ('s', "treeShadeOver_s")]+ }+treeShade2 = treeShade+ { ptopLeft = [ "sss"+ , "XOs"+ , "Xss"+ ]+ }+treeShade3 = treeShade+ { ptopLeft = [ "sss"+ , "sOs"+ , "XXs"+ ]+ }+oval = PlaceKind+ { psymbol = 'o'+ , pname = "oval room"+ , pfreq = [("rogue", 1000)]+ , prarity = [(1, 10), (10, 10)]+ , pcover = CStretch+ , pfence = FWall+ , ptopLeft = [ "####."+ , "##..."+ , "#...."+ , "#...."+ , "....."+ ]+ , poverride = []+ }+ovalFloor = oval -- Without outer solid fence, visible from outside.+ { pfreq = [("rogue", 10000)]+ , pfence = FGround+ , ptopLeft = [ "XXXX+#"+ , "XX###."+ , "X##..."+ , "X#...."+ , "+#...."+ , "#....."+ ]+ }+ovalSquare = ovalFloor+ { pfreq = [("rogue", 3000)]+ , ptopLeft = [ "X###+"+ , "##..."+ , "#...."+ , "#...."+ , "+...."+ ]+ }+maze = PlaceKind+ { psymbol = 'm'+ , pname = "maze"+ , pfreq = [("rogue", 20)]+ , prarity = [(1, 10), (10, 10)]+ , pcover = CStretch+ , pfence = FNone+ , ptopLeft = [ "#.#.##"+ , "##.#.."+ , "#.##.#"+ , "#.#.#."+ ]+ , poverride = []+ }+maze2 = maze+ { ptopLeft = [ "###.##"+ , ".###.."+ , "..#..#"+ , ".#..#."+ ]+ }+maze3 = maze+ { ptopLeft = [ "###.##"+ , ".##.#."+ , "..##.#"+ , ".#..#."+ ]+ }+mazeBig = maze+ { pfreq = [("rogue", 1000)]+ , ptopLeft = [ "#.#.##"+ , ".#.#.."+ , "#.&.##"+ , ".#.#.."+ , "#.#..#"+ , "#.#.#."+ ]+ }+mazeBig2 = mazeBig+ { ptopLeft = [ "##..##"+ , "#.##.."+ , ".#.###"+ , ".##.#."+ , "#.#&.#"+ , "#.#.#."+ ]+ }+mazeBig3 = mazeBig+ { ptopLeft = [ "##..##"+ , "#.###."+ , ".#...#"+ , ".#.##."+ , "##.#.#"+ , "#.#.#."+ ]+ }+cells = PlaceKind+ { psymbol = '#'+ , pname = "cells"+ , pfreq = [("rogue", 100), ("noise", 100)]+ , prarity = [(1, 10), (10, 10)]+ , pcover = CReflect+ , pfence = FWall+ , ptopLeft = [ "..#"+ , "..#"+ , "##."+ ]+ , poverride = []+ }+-- TODO: obtain all the rest as places nested within places.+-- 3 places are enough, with 1 or 2 tiles between places,+-- on all sides, only vertical, only horizontal,
+ GameDefinition/Content/RuleKind.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE TemplateHaskell #-}+-- Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+-- This file is a part of the computer game Allure of the Stars+-- and is released under the terms of the GNU Affero General Public License.+-- For license and copyright information, see the file LICENSE.+--+-- | Game rules and assorted game setup data.+module Content.RuleKind ( cdefs ) where++import Language.Haskell.TH.Syntax+import System.FilePath++-- Cabal+import qualified Paths_Allure as Self (getDataFileName, version)++import Game.LambdaHack.Common.ContentDef+import Game.LambdaHack.Content.RuleKind++cdefs :: ContentDef RuleKind+cdefs = ContentDef+ { getSymbol = rsymbol+ , getName = rname+ , getFreq = rfreq+ , validateSingle = validateSingleRuleKind+ , validateAll = validateAllRuleKind+ , content =+ [standard]+ }++standard :: RuleKind+standard = RuleKind+ { rsymbol = 's'+ , rname = "standard Allure of the Stars ruleset"+ , rfreq = [("standard", 100)]+ -- Check whether one position is accessible from another.+ -- Precondition: the two positions are next to each other+ -- and the target tile is walkable.+ -- TODO: in the future check flying for chasms, swimming for water, etc.+ , raccessible = Nothing+ , raccessibleDoor = Nothing+ , rtitle = "Allure of the Stars"+ , rpathsDataFile = Self.getDataFileName+ , rpathsVersion = Self.version+ -- The strings containing the default configuration file+ -- included from config.ui.default.+ , rcfgUIName = "config.ui"+ , rcfgUIDefault = $(do+ let path = "GameDefinition" </> "config.ui" <.> "default"+ qAddDependentFile path+ x <- qRunIO (readFile path)+ lift x)+ -- ASCII art for the Main Menu. Only pure 7-bit ASCII characters are+ -- allowed. The picture should be exactly 24 rows by 80 columns,+ -- plus an extra frame (of any characters) that is ignored.+ -- For a different screen size, the picture is centered and the outermost+ -- rows and columns cloned. When displayed in the Main Menu screen,+ -- it's overwritten with the game version string and keybinding strings.+ -- The game version string begins and ends with a space and is placed+ -- in the very bottom right corner. The keybindings overwrite places+ -- marked with 25 left curly brace signs '{' in a row. The sign is forbidden+ -- everywhere else. A specific number of such places with 25 left braces+ -- are required, at most one per row, and all are overwritten+ -- with text that is flushed left and padded with spaces.+ -- The Main Menu is displayed dull white on black.+ -- TODO: Show highlighted keybinding in inverse video or bright white on grey+ -- background. The spaces that pad keybindings are not highlighted.+ , rmainMenuArt = $(do+ let path = "GameDefinition/MainMenu.ascii"+ qAddDependentFile path+ x <- qRunIO (readFile path)+ lift x)+ , rfirstDeathEnds = False+ , rfovMode = Digital+ , rwriteSaveClips = 500+ , rleadLevelClips = 100+ , rscoresFile = "scores"+ , rsavePrefix = "save"+ , rsharedStash = True+ , rnearby = 10+ }
+ GameDefinition/Content/TileKind.hs view
@@ -0,0 +1,277 @@+-- Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+-- This file is a part of the computer game Allure of the Stars+-- and is released under the terms of the GNU Affero General Public License.+-- For license and copyright information, see the file LICENSE.+--+-- | Terrain tile definitions.+module Content.TileKind ( cdefs ) where++import Control.Arrow (first)+import Data.Maybe+import qualified Data.Text as T++import Game.LambdaHack.Common.Color+import Game.LambdaHack.Common.ContentDef+import qualified Game.LambdaHack.Common.Effect as Effect+import Game.LambdaHack.Common.Feature+import Game.LambdaHack.Common.Misc+import Game.LambdaHack.Common.Msg+import Game.LambdaHack.Content.TileKind++cdefs :: ContentDef TileKind+cdefs = ContentDef+ { getSymbol = tsymbol+ , getName = tname+ , getFreq = tfreq+ , validateSingle = validateSingleTileKind+ , validateAll = validateAllTileKind+ , content =+ [wall, wallCache, hardRock, doorlessWall, oriel, pillar, lampPost, burningBush, bush, tree, wallSuspect, doorClosed, doorOpen, stairsUp, stairsDown, escapeUp, escapeDown, liftUp, lift, liftDown, unknown, floorCorridorLit, floorActorLit, floorItemLit, floorActorItemLit, floorArenaShade, floorRedLit, floorBlueLit, floorGreenLit]+ ++ map makeDarkColor [floorCorridorLit, floorActorLit, floorItemLit, floorActorItemLit]+ }+wall, wallCache, hardRock, doorlessWall, oriel, pillar, lampPost, burningBush, bush, tree, wallSuspect, doorClosed, doorOpen, stairsUp, stairsDown, escapeUp, escapeDown, liftUp, lift, liftDown, unknown, floorCorridorLit, floorActorLit, floorItemLit, floorActorItemLit, floorArenaShade, floorRedLit, floorBlueLit, floorGreenLit :: TileKind++wall = TileKind+ { tsymbol = '#'+ , tname = "granite wall"+ , tfreq = [ ("fillerWall", 1), ("cachable", 70)+ , ("legendLit", 100), ("legendDark", 100)+ , ("noiseSet", 100), ("battleSet", 250) ]+ , tcolor = BrWhite+ , tcolor2 = defFG+ , tfeature = [HideAs "suspect wall"]+ }+wallCache = TileKind+ { tsymbol = '&'+ , tname = "cache"+ , tfreq = [ ("cachable", 30)+ , ("legendLit", 100), ("legendDark", 100) ]+ , tcolor = BrWhite+ , tcolor2 = defFG+ , tfeature = [Cause $ Effect.CreateItem 1, ChangeTo "cachable"]+ }+hardRock = TileKind+ { tsymbol = '#'+ , tname = "outer hull"+ , tfreq = [("basic outer fence", 100), ("oriels fence", 98)]+ , tcolor = BrBlack+ , tcolor2 = BrBlack+ , tfeature = [Impenetrable]+ }+doorlessWall = TileKind+ { tsymbol = '#'+ , tname = "granite wall"+ , tfreq = [("doorlessWallOver_#", 100)]+ , tcolor = BrWhite+ , tcolor2 = defFG+ , tfeature = []+ }+oriel = TileKind+ { tsymbol = '\''+ , tname = "oriel"+ , tfreq = [("oriels fence", 2)]+ , tcolor = White+ , tcolor2 = Black+ , tfeature = [Dark, Impenetrable]+ }+pillar = TileKind+ { tsymbol = 'O'+ , tname = "rock"+ , tfreq = [ ("legendLit", 100), ("legendDark", 100)+ , ("skirmishSet", 5) ]+ , tcolor = BrWhite+ , tcolor2 = defFG+ , tfeature = []+ }+lampPost = TileKind+ { tsymbol = 'O'+ , tname = "lamp post"+ , tfreq = [("lampPostOver_O", 90)]+ , tcolor = BrYellow+ , tcolor2 = Brown+ , tfeature = []+ }+burningBush = TileKind+ { tsymbol = 'O'+ , tname = "burning bush"+ , tfreq = [("lampPostOver_O", 10), ("ambushSet", 3), ("battleSet", 2)]+ , tcolor = BrRed+ , tcolor2 = Red+ , tfeature = []+ }+bush = TileKind+ { tsymbol = 'O'+ , tname = "bush"+ , tfreq = [("ambushSet", 100) ]+ , tcolor = Green+ , tcolor2 = BrBlack+ , tfeature = [Dark]+ }+tree = TileKind+ { tsymbol = 'O'+ , tname = "tree"+ , tfreq = [("skirmishSet", 14), ("battleSet", 20), ("treeShadeOver_O", 1)]+ , tcolor = BrGreen+ , tcolor2 = Green+ , tfeature = []+ }+wallSuspect = TileKind+ { tsymbol = '#'+ , tname = "moldy wall"+ , tfreq = [("suspect wall", 1)]+ , tcolor = BrWhite+ , tcolor2 = defFG+ , tfeature = [Suspect, RevealAs "closed door"]+ }+doorClosed = TileKind+ { tsymbol = '+'+ , tname = "closed door"+ , tfreq = [("legendLit", 100), ("legendDark", 100), ("closed door", 1)]+ , tcolor = Brown+ , tcolor2 = BrBlack+ , tfeature = [OpenTo "open door", HideAs "suspect wall"]+ }+doorOpen = TileKind+ { tsymbol = '\''+ , tname = "open door"+ , tfreq = [("legendLit", 100), ("legendDark", 100), ("open door", 1)]+ , tcolor = Brown+ , tcolor2 = BrBlack+ , tfeature = [Walkable, Clear, NoItem, NoActor, CloseTo "closed door"]+ }+stairsUp = TileKind+ { tsymbol = '<'+ , tname = "staircase up"+ , tfreq = [] -- TODO: [("legendLit", 100), ("legendDark", 100)]+ , tcolor = BrWhite+ , tcolor2 = defFG+ , tfeature = [Walkable, Clear, NoItem, NoActor, Cause $ Effect.Ascend 1]+ }+stairsDown = TileKind+ { tsymbol = '>'+ , tname = "staircase down"+ , tfreq = [] -- TODO: [("legendLit", 100), ("legendDark", 100)]+ , tcolor = BrWhite+ , tcolor2 = defFG+ , tfeature = [Walkable, Clear, NoItem, NoActor, Cause $ Effect.Ascend (-1)]+ }+escapeUp = TileKind+ { tsymbol = '<'+ , tname = "airlock to the shuttle"+ , tfreq = [("legendLit", 100), ("legendDark", 100)]+ , tcolor = BrYellow+ , tcolor2 = BrYellow+ , tfeature = [Walkable, Clear, NoItem, NoActor, Cause $ Effect.Escape 1]+ }+escapeDown = TileKind+ { tsymbol = '>'+ , tname = "airlock to the shuttle"+ , tfreq = [("legendLit", 100), ("legendDark", 100)]+ , tcolor = BrYellow+ , tcolor2 = BrYellow+ , tfeature = [Walkable, Clear, NoItem, NoActor, Cause $ Effect.Escape (-1)]+ }+liftUp = TileKind+ { tsymbol = '<'+ , tname = "lift up"+ , tfreq = [("legendLit", 100), ("legendDark", 100)]+ , tcolor = BrCyan+ , tcolor2 = BrCyan+ , tfeature = [Walkable, Clear, NoItem, NoActor, Cause $ Effect.Ascend 1]+ }+lift = TileKind+ { tsymbol = '<'+ , tname = "lift"+ , tfreq = [("legendLit", 100), ("legendDark", 100)]+ , tcolor = BrBlue+ , tcolor2 = BrBlue+ , tfeature = [ Walkable, Clear, NoItem, NoActor+ , Cause $ Effect.Ascend 1+ , Cause $ Effect.Ascend (-1) ]+ }+liftDown = TileKind+ { tsymbol = '>'+ , tname = "lift down"+ , tfreq = [("legendLit", 100), ("legendDark", 100)]+ , tcolor = BrCyan+ , tcolor2 = BrCyan+ , tfeature = [Walkable, Clear, NoItem, NoActor, Cause $ Effect.Ascend (-1)]+ }+unknown = TileKind+ { tsymbol = ' '+ , tname = "unknown space"+ , tfreq = [("unknown space", 1)]+ , tcolor = defFG+ , tcolor2 = defFG+ , tfeature = [Dark]+ }+floorCorridorLit = TileKind+ { tsymbol = '.'+ , tname = "floor"+ , tfreq = [ ("floorCorridorLit", 1), ("floorArenaLit", 1)+ , ("arenaSet", 1), ("emptySet", 1), ("noiseSet", 50)+ , ("battleSet", 1000), ("skirmishSet", 100)+ , ("ambushSet", 1000) ]+ , tcolor = BrWhite+ , tcolor2 = defFG+ , tfeature = [Walkable, Clear]+ }+floorActorLit = floorCorridorLit+ { tfreq = [("floorActorLit", 1)]+ , tfeature = OftenActor : tfeature floorCorridorLit+ }+floorItemLit = floorCorridorLit+ { tfreq = []+ , tfeature = OftenItem : tfeature floorCorridorLit+ }+floorActorItemLit = floorItemLit+ { tfreq = [("legendLit", 100)]+ , tfeature = OftenActor : tfeature floorItemLit+ }+floorArenaShade = floorActorLit+ { tname = "floor" -- TODO: "shaded ground"+ , tfreq = [("treeShadeOver_s", 1)]+ , tcolor2 = BrBlack+ , tfeature = Dark : tfeature floorActorLit -- no OftenItem+ }+floorRedLit = floorCorridorLit+ { tname = "emergency walkway"+ , tfreq = [("trailLit", 20)]+ , tcolor = BrRed+ , tcolor2 = Red+ , tfeature = Trail : tfeature floorCorridorLit+ }+floorBlueLit = floorRedLit+ { tname = "transport route"+ , tfreq = [("trailLit", 100)]+ , tcolor = BrBlue+ , tcolor2 = Blue+ }+floorGreenLit = floorRedLit+ { tname = "greenery trail"+ , tfreq = [("trailLit", 100)]+ , tcolor = BrGreen+ , tcolor2 = Green+ }+++makeDark :: TileKind -> TileKind+makeDark k = let darkText :: GroupName -> GroupName+ darkText t = maybe t (toGroupName . (<> "Dark"))+ $ T.stripSuffix "Lit" $ tshow t+ darkFrequency = map (first darkText) $ tfreq k+ darkFeat (OpenTo t) = Just $ OpenTo $ darkText t+ darkFeat (CloseTo t) = Just $ CloseTo $ darkText t+ darkFeat (ChangeTo t) = Just $ ChangeTo $ darkText t+ darkFeat (HideAs t) = Just $ HideAs $ darkText t+ darkFeat (RevealAs t) = Just $ RevealAs $ darkText t+ darkFeat OftenItem = Nothing -- items not common in the dark+ darkFeat feat = Just $ feat+ in k { tfreq = darkFrequency+ , tfeature = Dark : mapMaybe darkFeat (tfeature k)+ }++makeDarkColor :: TileKind -> TileKind+makeDarkColor k = (makeDark k) { tcolor = BrYellow+ , tcolor2 = BrBlack+ }
+ GameDefinition/Main.hs view
@@ -0,0 +1,18 @@+-- Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+-- This file is a part of the computer game Allure of the Stars+-- and is released under the terms of the GNU Affero General Public License.+-- For license and copyright information, see the file LICENSE.+--+-- | The main source code file of Allure of the Stars.+module Main ( main ) where++import System.Environment (getArgs)++import TieKnot++-- | Tie the LambdaHack engine client, server and frontend code+-- with the game-specific content definitions, and run the game.+main :: IO ()+main = do+ args <- getArgs+ tieKnot args
+ GameDefinition/MainMenu.ascii view
@@ -0,0 +1,26 @@+----------------------------------------------------------------------------------+| |+| >> Allure of the Stars << |+| |+| |+| {{{{{{{{{{{{{{{{{{{{{{{{{ |+| |+| {{{{{{{{{{{{{{{{{{{{{{{{{ |+| |+| {{{{{{{{{{{{{{{{{{{{{{{{{ |+| |+| {{{{{{{{{{{{{{{{{{{{{{{{{ |+| |+| {{{{{{{{{{{{{{{{{{{{{{{{{ |+| |+| {{{{{{{{{{{{{{{{{{{{{{{{{ |+| |+| {{{{{{{{{{{{{{{{{{{{{{{{{ |+| |+| {{{{{{{{{{{{{{{{{{{{{{{{{ |+| |+| {{{{{{{{{{{{{{{{{{{{{{{{{ |+| |+| |+| Version X.X.X (frontend: gtk, engine: LambdaHack X.X.X) |+----------------------------------------------------------------------------------
+ GameDefinition/PLAYING.md view
@@ -0,0 +1,262 @@+Playing Allure of the Stars+===========================++Your party of trusted crew-members is about to test their fortune+by exploring an abandoned Solar System passenger cruiser.+You are going to set up ambushes for it's feral denizens, hide in shadows,+cover tracks, bump into unspeakable horrors, hidden mechanisms+and astounding technical treasures and make creative use of it all.+The mysterious inhabitants of the gigantic spaceship are bound+to welcome intruders with bloody surprises of their own.+As soon as you turn your back in fear, expect to be chased tirelessly+throughout all the decks, by sight, sound and smell.++Once the few basic command keys and on-screen symbols are learned,+mastery and enjoyment of the game is the matter of tactical skill+and literary imagination. To be honest, a lot of imagination is required+at this stage, but the game is already playable and winnable.+Contributions are welcome.+++Heroes+------++The heroes are marked on the map with symbols `@` and `1` through `9`.+Their goal is to explore an old, warped, once luxurious, space liner,+battle the horrors within, gather as much gold and precious gems+as possible, and escape to tell the tale.++The currently chosen party leader is highlighted on the screen+and his attributes are displayed at the bottommost status line,+which in its most complex form may look as follows.++ *@12 Adventurer 4d1+5% Calm: 20/60 HP: 33/50 Target: basilisk [**___]++The line starts with the list of party members (unless only one member+resides on the currently displayed level) and the shortened name of the team.+Then comes the damage of the leader's weapon (but regardless of the figures,+each attack inflicts at least 1 damage), then his current and maximum+Calm (composure, focus, attentiveness), then his current and maximum+HP (hit points, health). At the end, the personal target of the leader+is described, in this case a basilisk monster, with hit points drawn as a bar.++The other status line describes the current location in relation to the party.++ 5 Lofty hall [33% seen] Cursor: exact spot (71,12) p15 l10++First comes the depth of the current level and its name.+Then the percentage of its explorable tiles already seen by the heroes.+The 'cursor' is the common target of the whole party,+directly manipulated with movement keys in the targeting mode.+At the end comes the length of the shortest path from the leader+to the cursor position and the straight-line distance between the two points.+++Spaceship+---------++The spaceship of the campaign mode game consists of decks on many levels+and each deck consists of a large number of tiles. The basic tile kinds+are as follows.++ terrain type on-screen symbol+ floor .+ wall #+ rock or tree O+ cache &+ stairs up <+ stairs down >+ open door '+ closed door +++The game world is persistent, i.e., every time the player visits a deck+during a single game, its layout is the same.+++Commands+--------++You move throughout the level using the numerical keypad (left diagram)+or its compact laptop replacement (middle) or Vi text editor keys+(right, also known as "Rogue-like keys", which have to be enabled+in config.ui.ini).++ 7 8 9 7 8 9 y k u+ \|/ \|/ \|/+ 4-5-6 u-i-o h-.-l+ /|\ /|\ /|\+ 1 2 3 j k l b j n++In targeting mode the keys above move the targeting cursor. In normal mode,+`SHIFT` (or `CTRL`) and a movement key make the current party leader+(and currently selected party members, if any) run in the indicated+direction, until anything of interest is spotted.+The '5', 'i' and '.' keys consume a turn and make you brace for combat,+which reduces any damage taken for a turn and makes it impossible+for foes to displace you. You displace enemies or friends by bumping+into them with SHIFT (or CTRL).++Melee, searching for secret doors, looting and opening closed doors+can be done by bumping into a monster, a wall and a door, respectively.+Few commands other than movement, 'g'etting an item from the floor,+'a'pplying an item and 'f'linging an item are necessary for casual play.+Some are provided only as specialized versions of more general commands+or as building blocks for more complex convenience commands,+e.g., the autoexplore command (key `X`) could be defined+by the player as a macro using `BACKSPACE`, `CTRL-?`, `;` and `V`.++Below are the remaining keys for terrain exploration and alteration.++ keys command+ < ascend a level+ CTRL-< ascend 10 levels+ > descend a level+ CTRL-> descend 10 levels+ ; make one step towards the target+ : go to target for 100 steps+ CTRL-: go to target for 10 steps+ x explore the closest unknown spot+ X autoexplore 100 times+ CTRL-X autoexplore 10 times+ R rest (wait 100 times)+ CTRL-R rest (wait 10 times)+ c close door++Item-use related keys are as follows.++ keys command+ E describe equipment of the leader+ P describe backpack inventory of the leader+ S describe the shared party stash+ G describe items on the ground+ A describe all owned items+ g and , get an item+ d drop an item+ e equip an item+ p pack an item into inventory backpack+ s stash and share an item+ a activate applicable item+ q quaff potion+ r read scroll+ f fling projectable item+ t throw missile+ z zap wand++To make a ranged attack, as in the last few commands above,+you need to set your target first (however, initial target is set+automatically as soon as a monster comes into view). Once in targeting mode,+you can move the targeting cursor with arrow keys and switch focus+among enemies with `*` (or among friends, projectiles and enemies, depending+on targeting mode set by `/`). The details of the shared cursor position+and of the personal target are described at the bottom of the screen.+All targeting keys are listed below.++ keys command+ KEYPAD_* and \ target enemy+ / cycle targeting mode+ + swerve targeting line+ - unswerve targeting line+ BACKSPACE clear target/cursor+ CTRL-? target the closest unknown spot+ CTRL-I target the closest item+ CTRL-{ target the closest stairs up+ CTRL-} target the closest stairs down++Here are the commands for automating the actions of one or more members+of the team.++ keys command+ = select (or deselect) a party member+ _ deselect (or select) all on the level+ v voice again the recorded commands+ V voice the recorded commands 100 times+ CTRL-v voice the recorded commands 1000 times+ CTRL-V voice the recorded commands 10 times+ ' start recording commands+ CTRL-T cycle tactic of non-leader team members (WIP)+ CTRL-A automate faction (ESC to retake control)++Assorted remaining keys and commands follow.++ keys command+ ? display help+ D display player diary+ T mark suspect terrain+ Z mark visible zone+ C mark smell clues+ TAB cycle among party members on the level+ SHIFT-TAB cycle among all party members+ SPACE clear messages+ ESC cancel action, open Main Menu+ RET accept choice+ 0--6 pick a new hero leader anywhere in the spaceship++Commands for saving and exiting the current game, starting a new game, etc.,+are listed in the Main Menu, brought up by the `ESC` key.+Game difficulty setting affects hitpoints at birth for any actors+of any UI-using faction. For a person new to roguelikes, the Duel game mode+offers a gentle introduction. The subsequent game modes gradually introduce+squad combat, stealth, asymmetric battles and more game elements.++ keys command+ CTRL-x save and exit+ CTRL-u new Duel game+ CTRL-k new Skirmish game+ CTRL-m new Ambush game+ CTRL-b new Battle game+ CTRL-a new Campaign game+ CTRL-d cycle next game difficulty++There are also some debug, testing and cheat options and game modes+that can be specified on the command line when starting the game server.+Use at your own peril! :) Of these, you may find the screensaver game modes+the least spoilery and the most fun, e.g.:++ Allure --savePrefix test --newGame --noMore --maxFps 60 --automateAll --gameMode campaign --difficulty 1++The `--automateAll` option strictly corresponds to the `CTRL-A` command,+but most of the debug options have no corresponding commands.+++Monsters+--------++Heroes are not alone in the spaceship. Monstrosities, natural+and out of this world, roam the dark halls and crawl from damp air-ducts+day and night. While heroes pay attention to all other party members+and take care to move one at a time, monsters don't care about each other+and all move at once, sometimes brutally colliding by accident.++When the hero bumps into a monster or a monster attacks the hero,+melee combat occurs. The best equipped weapon or the best fighting organ+of each opponent is taken into account for calculating damage.+The damage the current hero can potentially inflict is displayed+at the bottom of the screen, but the actual damage depends also+on the monster's armor. Heroes and monsters running into one another+(with the `SHIFT` key) do not inflict damage, but change places.+This gives the opponent a free blow, but can improve the tactical situation+or aid escape.++Slinging a missile at a target wounds it, consuming the weapon in the process.+You may propel any item in your equipment, inventory and on the ground+(press `?` to choose an item and press it again for a non-standard choice).+Only items of a few kinds inflict any damage, but some have other effects.+Whenever the monster's or hero's hit points reach zero, the combatant dies.+When the last hero dies, the game ends in defeat.+++On Winning and Dying+--------------------++You win the game if you escape the spaceship alive or, in game modes with+no exit opportunity, if you eliminate all opposition. In the former case,+your score is based on the gold and precious gems you've plundered,+plus a bonus based on the number of heroes you lost. In the latter case,+your score is based on the number of turns you spent overcoming your foes+and, as a bonus, the number of enemies you've subdued.++If all your heroes fall, you are awarded a score for your valiant deeds,+but no winning bonus. When, invariably, a new overconfident party+of adventurers storms the spaceship, they start from a new entrance,+with no experience and no equipment, and new, undaunted enemies+bar their way.
+ GameDefinition/TieKnot.hs view
@@ -0,0 +1,41 @@+-- Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+-- This file is a part of the computer game Allure of the Stars+-- and is released under the terms of the GNU Affero General Public License.+-- For license and copyright information, see the file LICENSE.+--+-- | Here the knot of engine code pieces and the game-specific+-- content definitions is tied, resulting in an executable game.+module TieKnot ( tieKnot ) where++import qualified Client.UI.Content.KeyKind as Content.KeyKind+import qualified Content.CaveKind+import qualified Content.ItemKind+import qualified Content.ModeKind+import qualified Content.PlaceKind+import qualified Content.RuleKind+import qualified Content.TileKind+import Game.LambdaHack.Client (exeFrontend)+import qualified Game.LambdaHack.Common.Kind as Kind+import Game.LambdaHack.SampleImplementation.SampleMonadClient (executorCli)+import Game.LambdaHack.SampleImplementation.SampleMonadServer (executorSer)+import Game.LambdaHack.Server (mainSer)++-- | Tie the LambdaHack engine client, server and frontend code+-- with the game-specific content definitions, and run the game.+tieKnot :: [String] -> IO ()+tieKnot args =+ let -- Common content operations, created from content definitions.+ copsServer = Kind.COps+ { cocave = Kind.createOps Content.CaveKind.cdefs+ , coitem = Kind.createOps Content.ItemKind.cdefs+ , comode = Kind.createOps Content.ModeKind.cdefs+ , coplace = Kind.createOps Content.PlaceKind.cdefs+ , corule = Kind.createOps Content.RuleKind.cdefs+ , cotile = Kind.createOps Content.TileKind.cdefs+ }+ -- Client content operations.+ copsClient = Content.KeyKind.standardKeys+ -- A single frontend is currently started by the server,+ -- instead of each client starting it's own.+ startupFrontend = exeFrontend executorCli executorCli copsClient+ in mainSer args copsServer executorSer startupFrontend
+ GameDefinition/config.ui.default view
@@ -0,0 +1,33 @@+; ; Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+; ; This file is a part of the computer game Allure of the Stars+; ; and is released under the terms of the GNU Affero General Public License.+; ; For license and copyright information, see the file LICENSE.+; ;+; ; This is a commented out copy of the default UI settings config file+; ; that is embedded in the binary.+; ; A user config file can overrides these options. The game looks for it at+; ; ~/.Allure/config.ui.ini (or a similar path, depending on the OS).+; ; Warning: options are case-sensitive and only ';' for comments is permitted.++; [extra_commands]+; ; A handy shorthand with Vi keys:+; Macro_1 = ("comma", ([CmdItem], Macro "" ["g"]))++; [hero_names]+; HeroName_0 = ("Haskell Alvin", "he")+; HeroName_1 = ("Alonzo Barkley", "he")+; HeroName_2 = ("Ines Galenti", "she")+; HeroName_3 = ("Ernst Abraham", "he")+; HeroName_4 = ("Samuel Saunders", "he")+; HeroName_5 = ("Roger Robin", "he")+; HeroName_6 = ("Christopher Flatt", "he")++; [ui]+; movementViKeys_hjklyubn = False+; movementLaptopKeys_uk8o79jl = True+; font = "Terminus,Monospace normal normal normal normal 12"+; historyMax = 5000+; maxFps = 15+; noAnim = False+; runStopMsgs = False+[dummy]
+ GameDefinition/scores view
binary file changed (absent → 335 bytes)
+ Makefile view
@@ -0,0 +1,279 @@+# Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski+# This file is a part of the computer game Allure of the Stars+# and is released under the terms of the GNU Affero General Public License.+# For license and copyright information, see the file LICENSE.+#++# All xc* tests assume a profiling build (for stack traces).+# See the install-debug target below or .travis.yml.prof.++install-debug:+ cabal install --enable-library-profiling --enable-executable-profiling --ghc-options="-fprof-auto-calls" --disable-optimization++configure-debug:+ cabal configure --enable-library-profiling --enable-executable-profiling --ghc-options="-fprof-auto-calls" --disable-optimization+++xcplay:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --dumpInitRngs++xcfrontendCampaign:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 60 --dumpInitRngs --automateAll --gameMode campaign --difficulty 1++xcfrontendSkirmish:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 60 --dumpInitRngs --automateAll --gameMode skirmish++xcfrontendAmbush:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 60 --dumpInitRngs --automateAll --gameMode ambush++xcfrontendBattle:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 60 --dumpInitRngs --automateAll --gameMode battle --difficulty 1++xcfrontendSafari:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 60 --dumpInitRngs --automateAll --gameMode safari --difficulty 1++xcfrontendDefense:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 60 --dumpInitRngs --automateAll --gameMode defense --difficulty 9++xcbenchCampaign:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendNull --benchmark --stopAfter 60 --automateAll --gameMode campaign --difficulty 1 --setDungeonRng 42 --setMainRng 42++xcbenchBattle:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendNull --benchmark --stopAfter 60 --automateAll --gameMode battle --difficulty 1 --setDungeonRng 42 --setMainRng 42++xcbenchFrontendCampaign:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 100000 --benchmark --stopAfter 60 --automateAll --gameMode campaign --difficulty 1 --setDungeonRng 42 --setMainRng 42++xcbenchFrontendBattle:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 100000 --benchmark --stopAfter 60 --automateAll --gameMode battle --difficulty 1 --setDungeonRng 42 --setMainRng 42++xcbenchNull: xcbenchCampaign xcbenchBattle++xcbench: xcbenchCampaign xcbenchFrontendCampaign xcbenchBattle xcbenchFrontendBattle+++xctest-travis-short: xctest-short xcbenchNull++xctest-travis: xctest-short xctest-medium xcbenchNull++xctest-travis-long: xctest-short xctest-long xcbenchNull++xctest: xctest-short xctest-medium xctest-long++xctest-short: xctest-short-new xctest-short-load++xctest-medium: xctestCampaign-medium xctestSkirmish-medium xctestAmbush-medium xctestBattle-medium xctestSafari-medium xctestPvP-medium xctestCoop-medium xctestDefense-medium++xctest-long: xctestCampaign-long xctestSkirmish-long xctestAmbush-long xctestBattle-long xctestSafari-long xctestPvP-long xctestCoop-long xctestDefense-long++xctestCampaign-long:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 400 --dumpInitRngs --automateAll --gameMode campaign --difficulty 1 > /tmp/stdtest.log++xctestCampaign-medium:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 250 --dumpInitRngs --automateAll --gameMode campaign --difficulty 1 > /tmp/stdtest.log++xctestSkirmish-long:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 100000 --frontendStd --benchmark --stopAfter 30 --dumpInitRngs --automateAll --gameMode skirmish > /tmp/stdtest.log++xctestSkirmish-medium:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 100000 --frontendStd --benchmark --stopAfter 30 --dumpInitRngs --automateAll --gameMode skirmish > /tmp/stdtest.log++xctestAmbush-long:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 30 --dumpInitRngs --automateAll --gameMode ambush > /tmp/stdtest.log++xctestAmbush-medium:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 30 --dumpInitRngs --automateAll --gameMode ambush > /tmp/stdtest.log++xctestBattle-long:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 400 --dumpInitRngs --automateAll --gameMode battle --difficulty 1 > /tmp/stdtest.log++xctestBattle-medium:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 250 --dumpInitRngs --automateAll --gameMode battle --difficulty 1 > /tmp/stdtest.log++xctestSafari-long:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 400 --dumpInitRngs --automateAll --gameMode safari --difficulty 1 > /tmp/stdtest.log++xctestSafari-medium:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 250 --dumpInitRngs --automateAll --gameMode safari --difficulty 1 > /tmp/stdtest.log++xctestPvP-long:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 30 --dumpInitRngs --automateAll --gameMode PvP > /tmp/stdtest.log++xctestPvP-medium:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 30 --dumpInitRngs --automateAll --gameMode PvP > /tmp/stdtest.log++xctestCoop-long:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 30 --dumpInitRngs --automateAll --gameMode Coop --difficulty 1 > /tmp/stdtest.log++xctestCoop-medium:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 250 --dumpInitRngs --automateAll --gameMode Coop --difficulty 1 > /tmp/stdtest.log++xctestDefense-long:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 400 --dumpInitRngs --automateAll --gameMode defense --difficulty 9 > /tmp/stdtest.log++xctestDefense-medium:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 250 --dumpInitRngs --automateAll --gameMode defense --difficulty 9 > /tmp/stdtest.log++xctest-short-new:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --newGame --noMore --savePrefix campaign --dumpInitRngs --automateAll --gameMode campaign --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --newGame --noMore --savePrefix skirmish --dumpInitRngs --automateAll --gameMode skirmish --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --newGame --noMore --savePrefix ambush --dumpInitRngs --automateAll --gameMode ambush --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --newGame --noMore --savePrefix battle --dumpInitRngs --automateAll --gameMode battle --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --newGame --noMore --savePrefix safari --dumpInitRngs --automateAll --gameMode safari --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --newGame --noMore --savePrefix PvP --dumpInitRngs --automateAll --gameMode PvP --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --newGame --noMore --savePrefix Coop --dumpInitRngs --automateAll --gameMode Coop --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --newGame --noMore --savePrefix defense --dumpInitRngs --automateAll --gameMode defense --frontendStd --stopAfter 2 > /tmp/stdtest.log++xctest-short-load:+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --noMore --savePrefix campaign --dumpInitRngs --automateAll --gameMode campaign --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --noMore --savePrefix skirmish --dumpInitRngs --automateAll --gameMode skirmish --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --noMore --savePrefix ambush --dumpInitRngs --automateAll --gameMode ambush --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --noMore --savePrefix battle --dumpInitRngs --automateAll --gameMode battle --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --noMore --savePrefix safari --dumpInitRngs --automateAll --gameMode safari --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --noMore --savePrefix PvP --dumpInitRngs --automateAll --gameMode PvP --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --noMore --savePrefix Coop --dumpInitRngs --automateAll --gameMode Coop --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure +RTS -xc -RTS --dbgMsgSer --noMore --savePrefix defense --dumpInitRngs --automateAll --gameMode defense --frontendStd --stopAfter 2 > /tmp/stdtest.log+++play:+ dist/build/Allure/Allure --dbgMsgSer --dumpInitRngs++frontendCampaign:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 60 --dumpInitRngs --automateAll --gameMode campaign --difficulty 1++frontendSkirmish:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 60 --dumpInitRngs --automateAll --gameMode skirmish++frontendAmbush:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 60 --dumpInitRngs --automateAll --gameMode ambush++frontendBattle:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 60 --dumpInitRngs --automateAll --gameMode battle --difficulty 1++frontendSafari:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 60 --dumpInitRngs --automateAll --gameMode safari --difficulty 1++frontendDefense:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 60 --dumpInitRngs --automateAll --gameMode defense --difficulty 9++benchCampaign:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendNull --benchmark --stopAfter 60 --automateAll --gameMode campaign --difficulty 1 --setDungeonRng 42 --setMainRng 42++benchBattle:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendNull --benchmark --stopAfter 60 --automateAll --gameMode battle --difficulty 1 --setDungeonRng 42 --setMainRng 42++benchFrontendCampaign:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 100000 --benchmark --stopAfter 60 --automateAll --gameMode campaign --difficulty 1 --setDungeonRng 42 --setMainRng 42++benchFrontendBattle:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 100000 --benchmark --stopAfter 60 --automateAll --gameMode battle --difficulty 1 --setDungeonRng 42 --setMainRng 42++benchNull: benchCampaign benchBattle++bench: benchCampaign benchFrontendCampaign benchBattle benchFrontendBattle+++test-travis-short: test-short benchNull++test-travis: test-short test-medium benchNull++test-travis-long: test-short test-long benchNull++test: test-short test-medium test-long++test-short: test-short-new test-short-load++test-medium: testCampaign-medium testSkirmish-medium testAmbush-medium testBattle-medium testSafari-medium testPvP-medium testCoop-medium testDefense-medium++test-long: testCampaign-long testSkirmish-long testAmbush-long testBattle-long testSafari-long testPvP-long testCoop-long testDefense-long++testCampaign-long:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 400 --dumpInitRngs --automateAll --gameMode campaign --difficulty 1 > /tmp/stdtest.log++testCampaign-medium:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 250 --dumpInitRngs --automateAll --gameMode campaign --difficulty 1 > /tmp/stdtest.log++testSkirmish-long:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 100000 --frontendStd --benchmark --stopAfter 30 --dumpInitRngs --automateAll --gameMode skirmish > /tmp/stdtest.log++testSkirmish-medium:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --maxFps 100000 --frontendStd --benchmark --stopAfter 30 --dumpInitRngs --automateAll --gameMode skirmish > /tmp/stdtest.log++testAmbush-long:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 30 --dumpInitRngs --automateAll --gameMode ambush > /tmp/stdtest.log++testAmbush-medium:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 30 --dumpInitRngs --automateAll --gameMode ambush > /tmp/stdtest.log++testBattle-long:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 400 --dumpInitRngs --automateAll --gameMode battle --difficulty 1 > /tmp/stdtest.log++testBattle-medium:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 250 --dumpInitRngs --automateAll --gameMode battle --difficulty 1 > /tmp/stdtest.log++testSafari-long:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 400 --dumpInitRngs --automateAll --gameMode safari --difficulty 1 > /tmp/stdtest.log++testSafari-medium:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 250 --dumpInitRngs --automateAll --gameMode safari --difficulty 1 > /tmp/stdtest.log++testPvP-long:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 30 --dumpInitRngs --automateAll --gameMode PvP > /tmp/stdtest.log++testPvP-medium:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 30 --dumpInitRngs --automateAll --gameMode PvP > /tmp/stdtest.log++testCoop-long:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 30 --dumpInitRngs --automateAll --gameMode Coop --difficulty 1 > /tmp/stdtest.log++testCoop-medium:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 250 --dumpInitRngs --automateAll --gameMode Coop --difficulty 1 > /tmp/stdtest.log++testDefense-long:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 400 --dumpInitRngs --automateAll --gameMode defense --difficulty 9 > /tmp/stdtest.log++testDefense-medium:+ dist/build/Allure/Allure --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendStd --benchmark --stopAfter 250 --dumpInitRngs --automateAll --gameMode defense --difficulty 9 > /tmp/stdtest.log++test-short-new:+ dist/build/Allure/Allure --dbgMsgSer --newGame --noMore --savePrefix campaign --dumpInitRngs --automateAll --gameMode campaign --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure --dbgMsgSer --newGame --noMore --savePrefix skirmish --dumpInitRngs --automateAll --gameMode skirmish --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure --dbgMsgSer --newGame --noMore --savePrefix ambush --dumpInitRngs --automateAll --gameMode ambush --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure --dbgMsgSer --newGame --noMore --savePrefix battle --dumpInitRngs --automateAll --gameMode battle --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure --dbgMsgSer --newGame --noMore --savePrefix safari --dumpInitRngs --automateAll --gameMode safari --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure --dbgMsgSer --newGame --noMore --savePrefix PvP --dumpInitRngs --automateAll --gameMode PvP --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure --dbgMsgSer --newGame --noMore --savePrefix Coop --dumpInitRngs --automateAll --gameMode Coop --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure --dbgMsgSer --newGame --noMore --savePrefix defense --dumpInitRngs --automateAll --gameMode defense --frontendStd --stopAfter 2 > /tmp/stdtest.log++test-short-load:+ dist/build/Allure/Allure --dbgMsgSer --noMore --savePrefix campaign --dumpInitRngs --automateAll --gameMode campaign --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure --dbgMsgSer --noMore --savePrefix skirmish --dumpInitRngs --automateAll --gameMode skirmish --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure --dbgMsgSer --noMore --savePrefix ambush --dumpInitRngs --automateAll --gameMode ambush --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure --dbgMsgSer --noMore --savePrefix battle --dumpInitRngs --automateAll --gameMode battle --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure --dbgMsgSer --noMore --savePrefix safari --dumpInitRngs --automateAll --gameMode safari --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure --dbgMsgSer --noMore --savePrefix PvP --dumpInitRngs --automateAll --gameMode PvP --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure --dbgMsgSer --noMore --savePrefix Coop --dumpInitRngs --automateAll --gameMode Coop --frontendStd --stopAfter 2 > /tmp/stdtest.log+ dist/build/Allure/Allure --dbgMsgSer --noMore --savePrefix defense --dumpInitRngs --automateAll --gameMode defense --frontendStd --stopAfter 2 > /tmp/stdtest.log+++build-binary:+ cabal configure --prefix=/usr/local+ cabal build Allure+ rm -rf /tmp/Allure+ cabal copy --destdir=/tmp/Allure+ tar -czf /tmp/Allure.tar.gz -C /tmp --exclude=Allure/usr/local/lib --exclude=Allure/usr/local/share/doc Allure+++# The rest of the makefile is unmaintained at the moment.++default : dist/setup-config+ runghc Setup build++dist/setup-config : Allure.cabal+ runghc Setup configure --user++clean :+ runghc Setup clean++ghci :+ ghci -XCPP -idist/build/autogen:GameDefinition
− PLAYING.md
@@ -1,168 +0,0 @@-Playing Allure of the Stars-===========================--Playing Allure of the Stars involves walking around an abandoned-Solar System space-ship, alone or in a party of trusted crew-members,-setting up ambushes, hiding in shadow, covering tracks,-breaking through to deeper spaceship decks, bumping into-hostile intruders, doors and walls, gathering technical resources-and making creative use of them. The bloodthirsty alien monsters-and their horrible minions do the same, intelligence allowing,-while tirelessly chasing the stranded heroes by smell and sight.--Once the few basic command keys and on-screen symbols are learned,-mastery and enjoyment of the game is the matter of tactical skill-and literary imagination. To be honest, a lot of imagination is required-at this stage, but the game is already playable and winnable.-The game also features multiplayer cooperative and competitive modes,-though only a shared-screen interface is provided at this time.-Contributions welcome.---Terrain----------The heroes are marked on the map with symbols '@' and '1' through '9'.-Their goal is to explore an old, gigantic, once luxurious space liner,-battle the horrors within, gather as much gold and precious gems-as possible, and escape to tell the tale. The spaceship, in the campaign-game mode, consists of many levels covered with varying terrain-of the following basic kinds:-- terrain type on-screen symbol- floor .- wall #- stairs up <- stairs down >- open door '- closed door +--The game world is persistent, i.e., every time the player visits a level-during a single game, the level layout is the same.---Keys-------You move throughout the level using the numerical keypad or-the vi text editor keys (also known as "Rogue-like keys").-- 7 8 9 y k u- \|/ \|/- 4-5-6 h-.-l- /|\ /|\- 1 2 3 b j n--SHIFT (or CTRL) and a movement key make the selected hero run in the indicated-direction, until anything of interest is spotted. The '5' and '.' keys take-a turn to brace for combat, which gives a chance to block blows next turn.-Melee, searching for secret doors and opening closed doors can be done-by bumping into a monster, a wall and a door, respectively.--Below are the default keys for major commands. The last four commands-are specialized versions of 'a' and 'p', offering narrower default item choice.-The commands that take player time are marked with a star.-- key command- < ascend a level*- > descend a level*- ? display help- I display inventory- a apply a consumable*- c close a door*- d drop an object*- g get an object*- o open a door*- p project a projectile*- q quaff a drink*- r read a tablet*- t throw a missile*- z zap a mechanism*--To make a ranged attack, you need to set your target first,-using targeting mode ('*' and '/' keys). The target, for the few-commands that require any, is indicated by the targeting cursor.-To avoid confusion, commands that take time are blocked when targeting-at a remote level (when the cursor is displayed on a different level-than the selected hero). The targeting commands and all the less used-commands are listed below. None of them takes hero time.-- key command- ESC cancel action or bring up the Main Menu- RET accept choice- TAB cycle among heroes on the level- SHIFT-TAB cycle among heroes in the dungeon- * target monster- + swerve targeting line- - unswerve targeting line- / target position- P display previous messages- S mark smell- T mark suspect terrain- V mark visible area- [ target next shallower level- ] target next deeper level- { target 10 levels shallower- } target 10 levels deeper- 0--9 select a hero anywhere in the dungeon--Commands for saving the current game, starting a new game, etc.,-are listed in the Main Menu, brough up by the ESC key.-Some of the game modes are multiplayer or feature multiple computer-players (allied or not). The setup of the modes can be modified-via a configuration file.-- key command- CTRL-s save game- CTRL-x save and exit- CTRL-r new campaign game- CTRL-k new skirmish game- CTRL-p new PvP game- CTRL-o new Coop game- CTRL-e new defense game--There are also some debug and cheat options that can be specified-on the command line when starting the game server. Use at your own peril!---Monsters-----------Heroes are not alone in the spaceship. Monsters roam the dark halls-and crawl from damp air-ducts day and night. While heroes pay attention-to all other party members and take care to move one at a time,-monsters don't care about each other and all move at once,-sometimes brutally colliding by accident.--When the hero bumps into a monster or a monster attacks the hero,-melee combat occurs. The best weapon carried by each opponent-is taken into account for calculating bonus damage. The total damage-the current hero can potentially inflict is displayed at the bottom-of the screen. The total damage potential of a monster may change-as it finds and picks up new weapons. Heroes and monsters running into-one another (with the Shift key) do not inflict damage, but change places.-This gives the opponent a free blow, but can improve the tactical situation-or aid escape.--Throwing weapons at targets wounds them, consuming the weapon in the process.-Target a monster with the '*' key from the top keyboard row or from keypad.-You may throw any object in your possession (press '?' to choose-an object and press it again for a non-standard choice) or on the floor-(press '-'). Only objects of a few kinds inflict any damage.-Whenever the monster's or hero's hit points reach zero, the combatant dies.-When the last hero dies, the game ends.---On Winning and Dying-----------------------You win the game if you escape the spaceship alive (or eliminate-all opposition, in some game modes). Your score is-the sum of all gold you've plundered plus 100 gold grains for each gem.-Only the loot in possession of the party members on the current level-counts (the rest of the party is considered MIA).--If all heroes die, your score is halved and only the treasure carried-by the last standing hero counts. You are free to start again-from a different entrance to the spaceship, but all your previous wealth-is gone and fresh, undaunted enemies bar your way.
README.md view
@@ -1,49 +1,75 @@-Allure of the Stars [](http://travis-ci.org/Mikolaj/Allure)+Allure of the Stars [](https://travis-ci.org/AllureOfTheStars/Allure)[](https://drone.io/github.com/AllureOfTheStars/Allure/latest) =================== -This is an alpha release of Allure of the Stars,-a near-future Sci-Fi [roguelike] [2] and tactical squad game.-Long-term goals are high replayability and auto-balancing-through procedural content generation and persistent content-modification based on player behaviour. The game is written in [Haskell] [1]-using the [LambdaHack] [5] roguelike game engine.+[Allure of the Stars] [8] is a near-future Sci-Fi [roguelike] [2]+and tactical squad game. Have a look at [PLAYING.md](GameDefinition/PLAYING.md)+or jump straight into the fray. + +The game is written in [Haskell] [1] using the [LambdaHack] [5]+roguelike game engine. Long-term goals of the project are high+replayability and auto-balancing through procedural content generation+and persistent content modification based on player behaviour.++ Compilation and installation ---------------------------- -The game is best compiled and installed via Cabal, which also takes care-of all dependencies. The latest official version of the game can be downloaded+The game is best compiled and installed via Cabal (already a part+of your OS distribution, or available within [The Haskell Platform] [7]),+which also takes care of all the dependencies. The latest official+version of the game can be downloaded, compiled and installed automatically by Cabal from [Hackage] [4] as follows + cabal install gtk2hs-buildtools cabal install Allure For a newer version, install a matching LambdaHack library snapshot from a development branch, download the game source from [github] [3]-and run 'cabal install' from the main directory.+and run `cabal install` from the main directory. +Some pre-compiled game binaries may be available from the [releases] [9] page. Compatibility notes ------------------- -The current code was tested with GHC 7.6, but should also work with-other GHC versions (see file .travis.yml for GHC 7.4 commands).+The current code was tested with GHC 7.6 and 7.8,+but should also work with other GHC versions. -If you are using the curses or vty frontends,-numerical keypad may not work correctly depending on the versions-of curses, terminfo and terminal emulators.-Selecting heroes via number keys or SHIFT-keypad keys is disabled-with curses, because CTRL-keypad for running does not work there,-so the numbers produced by the keypad have to be used. With vty on xterm,-CTRL-direction keys seem to work OK, but on rxvt they do not.-Vi keys (ykuhlbjn) should work everywhere regardless. Gtk works fine, too.+If you are using the terminal frontends, numerical keypad may not work+correctly depending on versions of the libraries, terminfo and terminal+emulators. The curses frontend is not fully supported due to the limitations+of the curses library. With the vty frontend run in an xterm,+CTRL-keypad keys for running seem to work OK, but on rxvt they do not.+Laptop (uk8o79jl) and Vi keys (hjklyubn, if enabled in config.ui.ini)+should work everywhere regardless. GTK works fine, too. +Testing and debugging+---------------------++The [Makefile](Makefile) contains many sample test commands.+All commands that use the screensaver game modes (AI vs. AI)+ and the dumb `stdout` frontend are gathered in `make test`.+Of these, travis runs `test-travis-*` on each push to the repo.+Test commands with prefix `frontend` start AI vs. AI games+with the standard, user-friendly frontend.++Run `Allure --help` to see a brief description of all debug options.+Of these, `--sniffIn` and `--sniffOut` are very useful (though verbose+and initially cryptic), for monitoring the traffic between clients+and the server. Some options in the config file may prove useful too,+though they mostly overlap with commandline options (and will be totally+merged at some point).++ Further information ------------------- For more information, visit the [wiki] [6]-and see the files PLAYING.md, CREDITS and LICENSE.+and see [PLAYING.md](GameDefinition/PLAYING.md), [CREDITS](CREDITS)+and [LICENSE](LICENSE). Have fun! @@ -51,7 +77,7 @@ Copyright --------- -Copyright (c) 2008--2011 Andres Loeh, 2010--2013 Mikolaj Konarski+Copyright (c) 2008--2011 Andres Loeh, 2010--2014 Mikolaj Konarski Allure of the Stars is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by@@ -71,7 +97,10 @@ [1]: http://www.haskell.org/ [2]: http://roguebasin.roguelikedevelopment.org/index.php?title=Berlin_Interpretation-[3]: http://github.com/Mikolaj/Allure+[3]: http://github.com/AllureOfTheStars/Allure [4]: http://hackage.haskell.org/package/Allure-[5]: http://github.com/kosmikus/LambdaHack-[6]: https://github.com/Mikolaj/Allure/wiki+[5]: http://github.com/LambdaHack/LambdaHack+[6]: https://github.com/AllureOfTheStars/Allure/wiki+[7]: http://www.haskell.org/platform+[8]: http://allureofthestars.com+[9]: https://github.com/AllureOfTheStars/Allure/releases
− config.rules.default
@@ -1,53 +0,0 @@-; ; Copyright (c) 2008--2011 Andres Loeh, 2010--2012 Mikolaj Konarski-; ; This file is a part of the computer game Allure of the Stars-; ; and is released under the terms of the GNU Affero General Public License.-; ; For license and copyright information, see the file LICENSE.-; ;-; ; This is a commented out copy of the default game rules config file-; ; that is embedded in the binary.-; ; A user config file can overrides these options. The game looks for it at-; ; ~/.LambdaHack/config.rules.ini (or a similar path, depending on the OS).-; ; Warning: options are case-sensitive and only ';' for comments is permitted.--; [caves]-; ; Cave "dng" means a random choice from caves that can randomly appear;-; ; this is the default and the lack of the Escape feature is the default.-; ; Fixed caves for the first levels, then randomly picked caves.-; campaign: [(1, ("caveRogue", False)), (12, ("caveNoise", True))]-; combat: [(3, ("caveCombat", False))]-; defense: [(1, ("dng", False)), (6, ("caveEmpty", True))]--; [engine]-; ;dungeonRandomGenerator: 42-; firstDeathEnds: False-; fovMode: Digital 12-; ;fovMode: Permissive-; ;fovMode: Shadow-; ;startingRandomGenerator: 42-; saveBkpClips: 100--; [file]-; ; Names of various game files. They reside in ~/.LambdaHack or similar.-; scoresFile: scores--; [heroName]-; HeroName_0: Haskell Alvin-; HeroName_1: Alonzo Barkley-; HeroName_2: Ines Galenti-; HeroName_3: Ernst Abraham-; HeroName_4: Samuel Saunders-; HeroName_5: Roger Robin--; [players]-; campaign: Players { playersHuman = [Player {playerName = "Spaceship Crew", playerKind = "hero", playerInitial = 1, playerEntry = LevelId 1}], playersComputer = [Player {playerName = "Alien Hierarchy", playerKind = "alien", playerInitial = 3, playerEntry = LevelId 5}, Player {playerName = "Animal Kingdom", playerKind = "animal", playerInitial = 3, playerEntry = LevelId 3}, Player {playerName = "Robotic Anarchy", playerKind = "robot", playerInitial = 3, playerEntry = LevelId 4}], playersEnemy = [("Spaceship Crew", "Alien Hierarchy"), ("Spaceship Crew", "Animal Kingdom"), ("Spaceship Crew", "Robotic Anarchy"), ("Animal Kingdom", "Alien Hierarchy"), ("Robotic Anarchy", "Alien Hierarchy"), ("Robotic Anarchy", "Animal Kingdom")], playersAlly = [] }-; skirmish: Players { playersHuman = [Player {playerName = "White", playerKind = "hero", playerInitial = 3, playerEntry = LevelId 1}], playersComputer = [Player {playerName = "Green", playerKind = "hero", playerInitial = 3, playerEntry = LevelId 1}, Player {playerName = "Horror Den", playerKind = "horror", playerInitial = 0, playerEntry = LevelId 1}], playersEnemy = [("White", "Green"), ("White", "Horror Den"), ("Green", "Horror Den")], playersAlly = [] }-; PvP: Players { playersHuman = [Player {playerName = "Red", playerKind = "hero", playerInitial = 3, playerEntry = LevelId 1}, Player {playerName = "Blue", playerKind = "hero", playerInitial = 3, playerEntry = LevelId 1}], playersComputer = [Player {playerName = "Horror Den", playerKind = "horror", playerInitial = 0, playerEntry = LevelId 1}], playersEnemy = [("Red", "Blue"), ("Red", "Horror Den"), ("Blue", "Horror Den")], playersAlly = [] }-; Coop: Players { playersHuman = [Player {playerName = "Coral", playerKind = "hero", playerInitial = 1, playerEntry = LevelId 1}, Player {playerName = "Amber", playerKind = "hero", playerInitial = 1, playerEntry = LevelId 1}], playersComputer = [Player {playerName = "Alien Hierarchy", playerKind = "alien", playerInitial = 3, playerEntry = LevelId 5}, Player {playerName = "Animal Kingdom", playerKind = "animal", playerInitial = 3, playerEntry = LevelId 3}, Player {playerName = "Robotic Anarchy", playerKind = "robot", playerInitial = 3, playerEntry = LevelId 4}], playersEnemy = [("Coral", "Alien Hierarchy"), ("Coral", "Animal Kingdom"), ("Coral", "Robotic Anarchy"), ("Amber", "Alien Hierarchy"), ("Amber", "Animal Kingdom"), ("Amber", "Robotic Anarchy"), ("Animal Kingdom", "Alien Hierarchy"), ("Robotic Anarchy", "Alien Hierarchy"), ("Robotic Anarchy", "Animal Kingdom")], playersAlly = [("Coral", "Amber")] }-; defense: Players { playersHuman = [Player {playerName = "Alien Hierarchy", playerKind = "alien", playerInitial = 1, playerEntry = LevelId 1}], playersComputer = [Player {playerName = "Green", playerKind = "hero", playerInitial = 1, playerEntry = LevelId 1}, Player {playerName = "Yellow", playerKind = "hero", playerInitial = 2, playerEntry = LevelId 1}, Player {playerName = "Cyan", playerKind = "hero", playerInitial = 3, playerEntry = LevelId 1}, Player {playerName = "Animal Kingdom", playerKind = "animal", playerInitial = 0, playerEntry = LevelId 1}, Player {playerName = "Robotic Anarchy", playerKind = "robot", playerInitial = 0, playerEntry = LevelId 1}], playersEnemy = [("Green", "Alien Hierarchy"), ("Green", "Animal Kingdom"), ("Green", "Robotic Anarchy"), ("Yellow", "Alien Hierarchy"), ("Yellow", "Animal Kingdom"), ("Yellow", "Robotic Anarchy"), ("Cyan", "Alien Hierarchy"), ("Cyan", "Animal Kingdom"), ("Cyan", "Robotic Anarchy"), ("Animal Kingdom", "Alien Hierarchy"), ("Robotic Anarchy", "Alien Hierarchy"), ("Robotic Anarchy", "Animal Kingdom")], playersAlly = [("Green", "Yellow"), ("Green", "Cyan"), ("Yellow", "Cyan")] }--; [scenario]-; campaign: Scenario { scenarioPlayers = "campaign", scenarioDungeon = "campaign" }-; skirmish: Scenario { scenarioPlayers = "skirmish", scenarioDungeon = "combat" }-; PvP: Scenario { scenarioPlayers = "PvP", scenarioDungeon = "combat" }-; Coop: Scenario { scenarioPlayers = "Coop", scenarioDungeon = "campaign" }-; defense: Scenario { scenarioPlayers = "defense", scenarioDungeon = "defense" }
− config.ui.default
@@ -1,63 +0,0 @@-; ; Copyright (c) 2008--2011 Andres Loeh, 2010--2012 Mikolaj Konarski-; ; This file is a part of the computer game Allure of the Stars-; ; and is released under the terms of the GNU Affero General Public License.-; ; For license and copyright information, see the file LICENSE.-; ;-; ; This is a commented out copy of the default UI settings config file-; ; that is embedded in the binary.-; ; A user config file can overrides these options. The game looks for it at-; ; ~/.LambdaHack/config.ui.ini (or a similar path, depending on the OS).-; ; Warning: options are case-sensitive and only ';' for comments is permitted.--; [commands]-; ; All commands are defined here, except movement, hero selection and debug.-; ;-; KP_Begin: Wait-; g: Pickup-; d: Drop-; p: Project [ApplyItem {verb = "project", object = "missile", symbol = ' '}, ApplyItem {verb = "throw", object = "projectile", symbol = '}'}, ApplyItem {verb = "throw", object = "projectile", symbol = '{'}, ApplyItem {verb = "zap", object = "mechanism", symbol = '-'}]-; t: Project [ApplyItem {verb = "throw", object = "projectile", symbol = '}'}, ApplyItem {verb = "throw", object = "projectile", symbol = '{'}]-; z: Project [ApplyItem {verb = "zap", object = "mechanism", symbol = '-'}]-; a: Apply [ApplyItem {verb = "apply", object = "consumable", symbol = ' '}, ApplyItem {verb = "eat", object = "food", symbol = ','}, ApplyItem {verb = "activate", object = "emitter", symbol = '_'}, ApplyItem {verb = "use", object = "tool", symbol = '~'}, ApplyItem {verb = "quaff", object = "drink", symbol = '!'}, ApplyItem {verb = "read", object = "tablet", symbol = '?'}]-; q: Apply [ApplyItem {verb = "quaff", object = "drink", symbol = '!'}]-; r: Apply [ApplyItem {verb = "read", object = "tablet", symbol = '?'}]-; c: TriggerDir [BumpFeature {verb = "close", object = "door", feature = Closable}]-; less: TriggerTile [BumpFeature {verb = "ascend", object = "level", feature = Cause (Ascend 1)}, BumpFeature {verb = "exit", object = "spaceship", feature = Cause Escape}]-; greater: TriggerTile [BumpFeature {verb = "descend", object = "level", feature = Cause (Descend 1)}, BumpFeature {verb = "exit", object = "spaceship", feature = Cause Escape}]-; CTRL-r: GameRestart "campaign"-; ; TODO: pick game modes via arrow keys, not special keys-; CTRL-k: GameRestart "skirmish"-; CTRL-p: GameRestart "PvP"-; CTRL-o: GameRestart "Coop"-; CTRL-e: GameRestart "defense"-; CTRL-x: GameExit-; CTRL-s: GameSave-; CTRL-d: CfgDump-; Tab: MemberCycle-; ISO_Left_Tab: MemberBack-; I: Inventory-; slash: TgtFloor-; asterisk: TgtEnemy-; bracketleft: TgtAscend 1-; bracketright: TgtAscend (-1)-; braceleft: TgtAscend 10-; braceright: TgtAscend (-10)-; plus: EpsIncr True-; minus: EpsIncr False-; Escape: Cancel-; Return: Accept-; space: Clear-; P: History-; V: MarkVision-; S: MarkSmell-; T: MarkSuspect-; question: Help--; [macros]-; ; Handy with Vi keys:-; comma: g-; period: KP_Begin--; [ui]-; font: Terminus,Monospace normal normal normal normal 12-; historyMax: 5000
− scores
binary file changed (277 → absent bytes)
− src/Content/ActorKind.hs
@@ -1,94 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--- Copyright (c) 2008--2011 Andres Loeh, 2010--2012 Mikolaj Konarski--- This file is a part of the computer game Allure of the Stars--- and is released under the terms of the GNU Affero General Public License.--- For license and copyright information, see the file LICENSE.------ | Monsters and heroes for Allure of the Stars.-module Content.ActorKind ( cdefs ) where--import Game.LambdaHack.Common.Ability-import Game.LambdaHack.Common.Color-import Game.LambdaHack.Common.ContentDef-import Game.LambdaHack.Common.Random-import Game.LambdaHack.Common.Time-import Game.LambdaHack.Content.ActorKind--cdefs :: ContentDef ActorKind-cdefs = ContentDef- { getSymbol = asymbol- , getName = aname- , getFreq = afreq- , validate = avalidate- , content =- [hero, projectile, eye, fastEye, nose]- }-hero, projectile, eye, fastEye, nose :: ActorKind--hero = ActorKind- { asymbol = '@'- , aname = "hero"- , afreq = [("hero", 1)]- , acolor = BrWhite -- modified if many hero factions- , ahp = RollDice 50 1- , aspeed = toSpeed 2- , asight = True- , asmell = False- , aiq = 16- , aregen = 500- , acanDo = [minBound..maxBound]- }--projectile = ActorKind -- includes homing missiles- { asymbol = '*'- , aname = "projectile"- , afreq = [("projectile", 1)] -- Does not appear randomly in the dungeon.- , acolor = BrWhite- , ahp = RollDice 0 0- , aspeed = toSpeed 0- , asight = False- , asmell = False- , aiq = 0- , aregen = maxBound- , acanDo = [Track]- }--eye = ActorKind- { asymbol = 'r'- , aname = "deranged household robot"- , afreq = [("robot", 60), ("horror", 60)]- , acolor = BrYellow- , ahp = RollDice 7 4- , aspeed = toSpeed 2- , asight = True- , asmell = False- , aiq = 8- , aregen = 100- , acanDo = [minBound..maxBound]- }-fastEye = ActorKind- { asymbol = 'm'- , aname = "deformed monkey"- , afreq = [("animal", 15), ("horror", 15)]- , acolor = BrMagenta- , ahp = RollDice 1 4- , aspeed = toSpeed 4- , asight = True- , asmell = False- , aiq = 12- , aregen = 5 -- Regenerates fast (at max HP most of the time!).- , acanDo = [minBound..maxBound]- }-nose = ActorKind- { asymbol = 'h'- , aname = "tentacled horror"- , afreq = [("alien", 20), ("horror", 20)]- , acolor = Green- , ahp = RollDice 17 2- , aspeed = toSpeed 1.8- , asight = False- , asmell = True- , aiq = 0- , aregen = 100- , acanDo = [minBound..maxBound]- }
− src/Content/CaveKind.hs
@@ -1,108 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--- Copyright (c) 2008--2011 Andres Loeh, 2010--2012 Mikolaj Konarski--- This file is a part of the computer game Allure of the Stars--- and is released under the terms of the GNU Affero General Public License.--- For license and copyright information, see the file LICENSE.------ | Cave layouts for Allure of the Stars.-module Content.CaveKind ( cdefs ) where--import Data.Ratio--import Game.LambdaHack.Common.ContentDef-import Game.LambdaHack.Common.Misc-import Game.LambdaHack.Common.Random as Random-import Game.LambdaHack.Content.CaveKind--cdefs :: ContentDef CaveKind-cdefs = ContentDef- { getSymbol = csymbol- , getName = cname- , getFreq = cfreq- , validate = cvalidate- , content =- [rogue, arena, empty, noise, combat]- }-rogue, arena, empty, noise, combat :: CaveKind--rogue = CaveKind- { csymbol = '$'- , cname = "Storage area"- , cfreq = [("dng", 100), ("caveRogue", 1)]- , cxsize = fst normalLevelBound + 1- , cysize = snd normalLevelBound + 1- , cgrid = RollDiceXY (RollDice 2 3, RollDice 2 2)- , cminPlaceSize = RollDiceXY (RollDice 2 2, RollDice 2 1)- , cdarkChance = (RollDice 1 54, RollDice 0 0)- , cauxConnects = 1%3- , cvoidChance = 1%4- , cnonVoidMin = 4- , cminStairDist = 30- , cdoorChance = 1%2- , copenChance = 1%10- , chidden = 8- , citemNum = RollDice 7 2- , cdefTile = "fillerWall"- , ccorridorTile = "darkCorridor"- , cfillerTile = "fillerWall"- , cdarkLegendTile = "darkLegend"- , clitLegendTile = "litLegend"- }-arena = rogue- { csymbol = 'A'- , cname = "Recreational deck"- , cfreq = [("dng", 100), ("caveArena", 1)]- , cgrid = RollDiceXY (RollDice 2 2, RollDice 2 2)- , cminPlaceSize = RollDiceXY (RollDice 3 2, RollDice 2 1)- , cdarkChance = (RollDice 1 80, RollDice 1 60)- , cvoidChance = 1%3- , cnonVoidMin = 2- , chidden = 9- , citemNum = RollDice 4 2 -- few rooms- , cdefTile = "floorArenaLit"- , ccorridorTile = "path"- }-empty = rogue- { csymbol = '.'- , cname = "Construction site"- , cfreq = [("dng", 100), ("caveEmpty", 1)]- , cgrid = RollDiceXY (RollDice 2 2, RollDice 1 2)- , cminPlaceSize = RollDiceXY (RollDice 4 3, RollDice 4 1)- , cdarkChance = (RollDice 1 80, RollDice 1 80)- , cauxConnects = 1- , cvoidChance = 3%4- , cnonVoidMin = 1- , cminStairDist = 50- , chidden = 10- , citemNum = RollDice 8 2 -- whole floor strewn with treasure- , cdefTile = "floorRoomLit"- , ccorridorTile = "floorRoomLit"- }-noise = rogue- { csymbol = '!'- , cname = "Machine rooms"- , cfreq = [("dng", 100), ("caveNoise", 1)]- , cgrid = RollDiceXY (RollDice 2 2, RollDice 1 2)- , cminPlaceSize = RollDiceXY (RollDice 4 2, RollDice 4 1)- , cdarkChance = (RollDice 1 80, RollDice 1 40)- , cvoidChance = 0- , cnonVoidMin = 0- , chidden = 6- , citemNum = RollDice 4 2 -- few rooms- , cdefTile = "noiseSet"- , ccorridorTile = "path"- }-combat = rogue- { csymbol = 'C'- , cname = "Combat arena"- , cfreq = [("caveCombat", 1)]- , cgrid = RollDiceXY (RollDice 5 2, RollDice 2 2)- , cminPlaceSize = RollDiceXY (RollDice 1 1, RollDice 1 1)- , cdarkChance = (RollDice 1 100, RollDice 1 100)- , cvoidChance = 1%10- , cnonVoidMin = 8- , chidden = 100- , citemNum = RollDice 12 2- , cdefTile = "combatSet"- , ccorridorTile = "path"- }
− src/Content/FactionKind.hs
@@ -1,65 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--- Copyright (c) 2008--2011 Andres Loeh, 2010--2012 Mikolaj Konarski--- This file is a part of the computer game Allure of the Stars--- and is released under the terms of the GNU Affero General Public License.--- For license and copyright information, see the file LICENSE.------ | The type of kinds of game factions (heroes, enemies, NPCs, etc.)--- for LambdaHack.-module Content.FactionKind ( cdefs ) where--import Game.LambdaHack.Common.ContentDef-import Game.LambdaHack.Content.FactionKind--cdefs :: ContentDef FactionKind-cdefs = ContentDef- { getSymbol = fsymbol- , getName = fname- , getFreq = ffreq- , validate = fvalidate- , content =- [hero, alien, animal, robot, horror]- }-hero, alien, animal, robot, horror :: FactionKind--hero = FactionKind- { fsymbol = '@'- , fname = "hero"- , ffreq = [("hero", 1)]- , fAiLeader = "fullAbility"- , fAiMember = "meleeAdjacent"- }---- Includes alien-operated robots, alien-conditioned animals and hybrids.-alien = FactionKind- { fsymbol = 'a'- , fname = "alien"- , ffreq = [("alien", 1), ("spawn", 20), ("summon", 20)]- , fAiLeader = "fullAbility"- , fAiMember = "fullAbility"- }--animal = FactionKind- { fsymbol = 'd'- , fname = "animal"- , ffreq = [("animal", 1), ("spawn", 50), ("summon", 50)]- , fAiLeader = "animalAbility"- , fAiMember = "animalAbility"- }---- Autonomous robots.-robot = FactionKind- { fsymbol = 'r'- , fname = "robot"- , ffreq = [("robot", 1), ("spawn", 10), ("summon", 10)]- , fAiLeader = "robotAbility"- , fAiMember = "robotAbility"- }--horror = FactionKind- { fsymbol = 'h'- , fname = "horror"- , ffreq = [("horror", 1), ("summon", 50)]- , fAiLeader = "fullAbility"- , fAiMember = "fullAbility"- }
− src/Content/ItemKind.hs
@@ -1,248 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--- Copyright (c) 2008--2011 Andres Loeh, 2010--2012 Mikolaj Konarski--- This file is a part of the computer game Allure of the Stars--- and is released under the terms of the GNU Affero General Public License.--- For license and copyright information, see the file LICENSE.------ | Weapons and treasure for Allure of the Stars.-module Content.ItemKind ( cdefs ) where--import qualified Data.List as L--import Game.LambdaHack.Common.Color-import Game.LambdaHack.Common.ContentDef-import Game.LambdaHack.Common.Effect-import Game.LambdaHack.Common.Flavour-import Game.LambdaHack.Common.Random-import Game.LambdaHack.Content.ItemKind--cdefs :: ContentDef ItemKind-cdefs = ContentDef- { getSymbol = isymbol- , getName = iname- , getFreq = ifreq- , validate = ivalidate- , content =- [necklace, dart, gem1, gem2, gem3, currency, javelin, kitchenKnife, potion1, potion2, potion3, ring, scroll1, scroll2, scroll3, sword, wand1, wand2, fist, foot, tentacle]- }-necklace, dart, gem1, gem2, gem3, currency, javelin, kitchenKnife, potion1, potion2, potion3, ring, scroll1, scroll2, scroll3, sword, wand1, wand2, fist, foot, tentacle :: ItemKind--gem, potion, scroll, wand :: ItemKind -- generic templates---- rollDeep (aDb, xDy) = rollDice aDb + lvl * rollDice xDy / depth--{- Item group symbols (from Angband, only as an informal convention for now):--! potion, flask, concoction, bottle, jar, vial, canister-? scroll, book, note, tablet, remote-, food-- magical wand, magical rod, transmitter, pistol, rifle-_ magical staff, scanner-= ring-" necklace-$ currency, gem-~ light, tool-/ polearm-| edged weapon-\ hafted weapon-} launcher-{ projectile-( clothes-[ torso armour-] misc. armour-) shield---}--necklace = ItemKind- { isymbol = '"'- , iname = "necklace"- , ifreq = [("dng", 6)]- , iflavour = zipFancy [BrGreen]- , ieffect = Regeneration (RollDice 2 3, RollDice 1 10)- , icount = intToDeep 1- , iverbApply = "tear down"- , iverbProject = "cast"- , iweight = 30- , itoThrow = -50 -- not dense enough- }-dart = ItemKind- { isymbol = '{'- , iname = "billiard ball"- , ifreq = [("dng", 30)]- , iflavour = zipPlain [BrWhite]- , ieffect = Hurt (RollDice 1 1) (RollDice 1 2, RollDice 1 2)- , icount = (RollDice 3 3, RollDice 0 0)- , iverbApply = "splinter"- , iverbProject = "hurl"- , iweight = 50- , itoThrow = 0 -- a cheap dart- }-gem = ItemKind- { isymbol = '*'- , iname = "precious gem"- , ifreq = [("dng", 20)] -- x3, but rare on shallow levels- , iflavour = zipPlain $ L.delete BrYellow brightCol -- natural, so not fancy- , ieffect = NoEffect- , icount = intToDeep 0- , iverbApply = "crush"- , iverbProject = "toss"- , iweight = 50- , itoThrow = 0- }-gem1 = gem- { icount = (RollDice 0 0, RollDice 1 1) -- appears on max depth- }-gem2 = gem- { icount = (RollDice 0 0, RollDice 1 2) -- appears halfway, doubled on max- }-gem3 = gem- { icount = (RollDice 0 0, RollDice 1 3)- }-currency = ItemKind- { isymbol = '$'- , iname = "gold grain"- , ifreq = [("dng", 50), ("currency", 1)]- , iflavour = zipPlain [BrYellow]- , ieffect = NoEffect- , icount = (RollDice 0 0, RollDice 10 10)- , iverbApply = "smear"- , iverbProject = "blow away"- , iweight = 1- , itoThrow = 0- }-javelin = ItemKind- { isymbol = '{'- , iname = "javelin"- , ifreq = [("dng", 30)]- , iflavour = zipPlain [Brown]- , ieffect = Hurt (RollDice 1 2) (RollDice 1 2, RollDice 2 2)- , icount = (RollDice 0 0, RollDice 1 1)- , iverbApply = "break up"- , iverbProject = "hurl"- , iweight = 2000- , itoThrow = 0 -- cheap but deadly- }-kitchenKnife = ItemKind- { isymbol = '{'- , iname = "kitchen knife"- , ifreq = [("dng", 30)]- , iflavour = zipPlain [BrCyan]- , ieffect = Hurt (RollDice 1 1) (RollDice 0 0, RollDice 1 2)- , icount = (RollDice 0 0, RollDice 1 2)- , iverbApply = "bend"- , iverbProject = "throw"- , iweight = 200- , itoThrow = -50 -- too flexible and the handle causes air resistance- }-potion = ItemKind- { isymbol = '!'- , iname = "vial"- , ifreq = [("dng", 15)]- , iflavour = zipFancy stdCol- , ieffect = NoEffect- , icount = intToDeep 1- , iverbApply = "gulp down"- , iverbProject = "lob"- , iweight = 200- , itoThrow = -50 -- oily, bad grip- }-potion1 = potion- { ifreq = [("dng", 5)]- , ieffect = ApplyPerfume- }-potion2 = potion- { ieffect = Heal 5- }-potion3 = potion- { ifreq = [("dng", 5)]- , ieffect = Heal (-5)- }-ring = ItemKind- { isymbol = '='- , iname = "ring"- , ifreq = [] -- [("dng", 10)] -- TODO: make it useful- , iflavour = zipPlain [White]- , ieffect = Searching (RollDice 1 6, RollDice 3 2)- , icount = intToDeep 1- , iverbApply = "squeeze down"- , iverbProject = "toss"- , iweight = 15- , itoThrow = 0- }-scroll = ItemKind- { isymbol = '?'- , iname = "tablet"- , ifreq = [("dng", 4)]- , iflavour = zipFancy darkCol -- arcane and old- , ieffect = NoEffect- , icount = intToDeep 1- , iverbApply = "dial"- , iverbProject = "lob"- , iweight = 700- , itoThrow = -25 -- bad grip- }-scroll1 = scroll- { ieffect = CallFriend 1- }-scroll2 = scroll- { ieffect = Summon 1- }-scroll3 = scroll- { ieffect = Descend 1- }-sword = ItemKind- { isymbol = '/'- , iname = "sharpened pipe"- , ifreq = [("dng", 40)]- , iflavour = zipPlain [Cyan]- , ieffect = Hurt (RollDice 3 1) (RollDice 1 2, RollDice 4 2)- , icount = intToDeep 1- , iverbApply = "hit"- , iverbProject = "heave"- , iweight = 3000- , itoThrow = -25 -- bad grip- }-wand = ItemKind- { isymbol = '-'- , iname = "injector"- , ifreq = [("dng", 15)]- , iflavour = zipFancy brightCol- , ieffect = NoEffect- , icount = intToDeep 1- , iverbApply = "snap"- , iverbProject = "zap"- , iweight = 300- , itoThrow = 25 -- jet- }-wand1 = wand- { ieffect = Dominate- }-wand2 = wand- { ifreq = [("dng", 3)]- , ieffect = Heal (-25)- }-fist = sword- { isymbol = '@'- , iname = "fist"- , ifreq = [("hth", 1), ("unarmed", 100)]- , ieffect = Hurt (RollDice 3 1) (intToDeep 0)- , iverbApply = "punch"- , iverbProject = "ERROR, please report: iverbProject fist"- }-foot = sword- { isymbol = '@'- , iname = "foot"- , ifreq = [("hth", 1), ("unarmed", 50)]- , ieffect = Hurt (RollDice 3 1) (intToDeep 0)- , iverbApply = "kick"- , iverbProject = "ERROR, please report: iverbProject foot"- }-tentacle = sword- { isymbol = 'S'- , iname = "tentacle"- , ifreq = [("hth", 1), ("monstrous", 100)]- , ieffect = Hurt (RollDice 3 1) (intToDeep 0)- , iverbApply = "hit"- , iverbProject = "ERROR, please report: iverbProject tentacle"- }
− src/Content/PlaceKind.hs
@@ -1,149 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--- Copyright (c) 2008--2011 Andres Loeh, 2010--2012 Mikolaj Konarski--- This file is a part of the computer game Allure of the Stars--- and is released under the terms of the GNU Affero General Public License.--- For license and copyright information, see the file LICENSE.------ | Rooms, halls and passages for Allure of the Stars.-module Content.PlaceKind ( cdefs ) where--import Game.LambdaHack.Common.ContentDef-import Game.LambdaHack.Content.PlaceKind--cdefs :: ContentDef PlaceKind-cdefs = ContentDef- { getSymbol = psymbol- , getName = pname- , getFreq = pfreq- , validate = pvalidate- , content =- [rect, oval, ovalFloor, ovalSquare, colonnade, colonnadeWide, maze, maze2, maze3, mazeBig, mazeBig2, mazeBig3, cells]- }-rect, oval, ovalFloor, ovalSquare, colonnade, colonnadeWide, maze, maze2, maze3, mazeBig, mazeBig2, mazeBig3, cells :: PlaceKind--rect = PlaceKind -- Valid for any nonempty area, hence low frequency.- { psymbol = 'r'- , pname = "room"- , pfreq = [("rogue", 100)]- , pcover = CStretch- , pfence = FWall- , ptopLeft = ["."]- }-oval = PlaceKind- { psymbol = 'o'- , pname = "oval room"- , pfreq = [("rogue", 1000)]- , pcover = CStretch- , pfence = FWall- , ptopLeft = [ "####.."- , "##...."- , "#....."- , "#....."- , "......"- , "......"- ]- }-ovalFloor = oval -- Without outer solid fence, visible from outside.- { pfreq = [("rogue", 10000)]- , pfence = FFloor- , ptopLeft = [ "XXXX+#"- , "XX###."- , "X##..."- , "X#...."- , "+#...."- , "#....."- ]- }-ovalSquare = ovalFloor- { ptopLeft = [ "X###+"- , "##..."- , "#...."- , "#...."- , "+...."- ]- }-colonnade = PlaceKind- { psymbol = 'c'- , pname = "colonnade"- , pfreq = [("rogue", 1000)]- , pcover = CAlternate- , pfence = FFloor- , ptopLeft = [ ".#"- , "#."- ]- }-colonnadeWide = colonnade- { pfreq = [("rogue", 50)]- , pfence = FWall- , ptopLeft = [ ".."- , ".#"- ]- }-maze = PlaceKind- { psymbol = 'm'- , pname = "maze"- , pfreq = [("rogue", 20)]- , pcover = CStretch- , pfence = FNone- , ptopLeft = [ "#.#.##"- , "##.#.."- , "#.##.#"- , "#.#.#."- ]- }-maze2 = maze- { ptopLeft = [ "###.##"- , ".###.."- , "..#..#"- , ".#..#."- ]- }-maze3 = maze- { ptopLeft = [ "###.##"- , ".##.#."- , "..##.#"- , ".#..#."- ]- }-mazeBig = maze- { pfreq = [("rogue", 1000)]- , ptopLeft = [ "#.#.##"- , ".#.#.."- , "#.#.##"- , ".#.#.."- , "#.#..#"- , "#.#.#."- ]- }-mazeBig2 = mazeBig- { ptopLeft = [ "##..##"- , "#.##.."- , ".#.###"- , ".##.#."- , "#.##.#"- , "#.#.#."- ]- }-mazeBig3 = mazeBig- { ptopLeft = [ "##..##"- , "#.###."- , ".#...#"- , ".#.##."- , "##.#.#"- , "#.#.#."- ]- }-cells = PlaceKind- { psymbol = '#'- , pname = "cells"- , pfreq = [("rogue", 30)]- , pcover = CReflect- , pfence = FWall- , ptopLeft = [ "..#"- , "..#"- , "##."- ]- }--- TODO: obtain all the reet as places nested within places.--- 3 places are enough, with 1 or 2 tiles between places,--- on all sides, only vertical, only horizontal,
− src/Content/RuleKind.hs
@@ -1,98 +0,0 @@-{-# LANGUAGE CPP, OverloadedStrings, QuasiQuotes #-}--- Copyright (c) 2008--2011 Andres Loeh, 2010--2012 Mikolaj Konarski--- This file is a part of the computer game Allure of the Stars--- and is released under the terms of the GNU Affero General Public License.--- For license and copyright information, see the file LICENSE.------ | Game rules and assorted game setup data for Allure of the Stars.-module Content.RuleKind ( cdefs ) where---- Cabal-import qualified Paths_Allure as Self (getDataFileName, version)--import Game.LambdaHack.Common.ContentDef-import qualified Game.LambdaHack.Common.Feature as F-import Game.LambdaHack.Content.RuleKind-import Game.LambdaHack.Content.TileKind-import Multiline--cdefs :: ContentDef RuleKind-cdefs = ContentDef- { getSymbol = rsymbol- , getName = rname- , getFreq = rfreq- , validate = ruvalidate- , content =- [standard]- }--standard :: RuleKind-standard = RuleKind- { rsymbol = 's'- , rname = "standard Allure of the Stars ruleset"- , rfreq = [("standard", 100)]- -- Check whether one position is accessible from another.- -- Precondition: the two positions are next to each other.- -- TODO: in the future check flying for chasms, swimming for water, etc.- , raccessible = \ _lxsize _spos _src _tpos tgt ->- F.Walkable `elem` tfeature tgt- , rtitle = "Allure of the Stars"- , rpathsDataFile = Self.getDataFileName- , rpathsVersion = Self.version- , ritemMelee = "/|\\"- , ritemProject = "!?,-~}{"- -- The strings containing the default configuration files,- -- included from files config.game.default and config.ui.default.- -- Warning: cabal does not detect that the config files are changed,- -- so touching them is needed to reinclude configs and recompile.- -- Note: consider code.haskell.org/~dons/code/compiled-constants- -- as soon as the config file grows very big.- , rcfgRulesDefault = [multiline|-#include "../../config.rules.default"-|]- , rcfgUIDefault = [multiline|-#include "../../config.ui.default"-|]- -- ASCII art for the Main Menu. Only pure 7-bit ASCII characters are- -- allowed. The picture should be exactly 24 rows by 80 columns,- -- plus an extra frame of any charecters that is ignored for all purposes.- -- For a different screen size, the picture is centered and the outermost- -- rows and columns cloned. When displayed in the Main Menu screen,- -- it's overwritten with the game version string and keybinding strings.- -- The game version string begins and ends with a space and is placed- -- in the very bottom right corner. The keybindings overwrite places- -- marked with 25 left curly brace signs '{' in a row. The sign is forbidden- -- everywhere else. Exactly five such places with 25 left braces- -- are required, at most one per row, and all are overwritten- -- with text that is flushed left and padded with spaces.- -- The Main Menu is displayed dull white on black.- -- TODO: Highlighted keybinding is in inverse video or bright white on grey- -- background. The spaces that pad keybindings are not highlighted.- , rmainMenuArt = [multiline|------------------------------------------------------------------------------------| |-| >> Allure of the Stars << |-| |-| {{{{{{{{{{{{{{{{{{{{{{{{{ |-| |-| {{{{{{{{{{{{{{{{{{{{{{{{{ |-| |-| {{{{{{{{{{{{{{{{{{{{{{{{{ |-| |-| {{{{{{{{{{{{{{{{{{{{{{{{{ |-| |-| {{{{{{{{{{{{{{{{{{{{{{{{{ |-| |-| {{{{{{{{{{{{{{{{{{{{{{{{{ |-| |-| {{{{{{{{{{{{{{{{{{{{{{{{{ |-| |-| {{{{{{{{{{{{{{{{{{{{{{{{{ |-| |-| {{{{{{{{{{{{{{{{{{{{{{{{{ |-| |-| |-| |-| Version X.X.X (frontend: gtk, engine: LambdaHack X.X.X) |------------------------------------------------------------------------------------|]}
− src/Content/StrategyKind.hs
@@ -1,74 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--- Copyright (c) 2008--2011 Andres Loeh, 2010--2012 Mikolaj Konarski--- This file is a part of the computer game Allure of the Stars--- and is released under the terms of the GNU Affero General Public License.--- For license and copyright information, see the file LICENSE.------ | AI strategies for Allure of the Stars.-module Content.StrategyKind ( cdefs ) where--import Data.List--import Game.LambdaHack.Common.Ability-import Game.LambdaHack.Common.ContentDef-import Game.LambdaHack.Content.StrategyKind--cdefs :: ContentDef StrategyKind-cdefs = ContentDef- { getSymbol = ssymbol- , getName = sname- , getFreq = sfreq- , validate = svalidate- , content =- [noAbility, onlyFollowTrack, meleeAdjacent, meleeAndRanged, animalAbility, robotAbility, fullAbility]- }-noAbility, onlyFollowTrack, meleeAdjacent, meleeAndRanged, animalAbility, robotAbility, fullAbility :: StrategyKind--noAbility = StrategyKind -- not even projectiles will fly- { ssymbol = '@'- , sname = "noAbility"- , sfreq = [("noAbility", 1)]- , sabilities = []- }--onlyFollowTrack = StrategyKind -- projectiles enabled- { ssymbol = '@'- , sname = "onlyFollowTrack"- , sfreq = [("onlyFollowTrack", 1)]- , sabilities = [Track]- }--meleeAdjacent = StrategyKind- { ssymbol = '@'- , sname = "meleeAdjacent"- , sfreq = [("meleeAdjacent", 1)]- , sabilities = [Track, Melee]- }--meleeAndRanged = StrategyKind -- melee and reaction fire- { ssymbol = '@'- , sname = "meleeAndRanged"- , sfreq = [("meleeAndRanged", 1)]- , sabilities = [Track, Melee, Ranged]- }--animalAbility = StrategyKind- { ssymbol = '@'- , sname = "animalAbility"- , sfreq = [("animalAbility", 1)]- , sabilities = [Track, Flee, Melee, Chase, Wander]- }--robotAbility = StrategyKind- { ssymbol = '@'- , sname = "robotAbility"- , sfreq = [("robotAbility", 1)]- , sabilities = delete Flee [minBound..maxBound]- }--fullAbility = StrategyKind- { ssymbol = '@'- , sname = "fullAbility"- , sfreq = [("fullAbility", 1)]- , sabilities = [minBound..maxBound]- }
− src/Content/TileKind.hs
@@ -1,163 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--- Copyright (c) 2008--2011 Andres Loeh, 2010--2012 Mikolaj Konarski--- This file is a part of the computer game Allure of the Stars--- and is released under the terms of the GNU Affero General Public License.--- For license and copyright information, see the file LICENSE.------ | Terrain tiles for Allure of the Stars.-module Content.TileKind ( cdefs ) where--import Game.LambdaHack.Common.Color-import Game.LambdaHack.Common.ContentDef-import qualified Game.LambdaHack.Common.Effect as Effect-import Game.LambdaHack.Common.Feature-import Game.LambdaHack.Content.TileKind--cdefs :: ContentDef TileKind-cdefs = ContentDef- { getSymbol = tsymbol- , getName = tname- , getFreq = tfreq- , validate = tvalidate- , content =- [wall, hardRock, pillar, wallSuspect, doorClosed, doorOpen, stairsUp, stairsDown, escapeUp, unknown, floorCorridorLit, floorCorridorDark, floorItemLit, floorItemDark, floorActorItemLit, floorActorItemDark, floorRed, floorBlue, floorGreen]- }-wall, hardRock, pillar, wallSuspect, doorClosed, doorOpen, stairsUp, stairsDown, escapeUp, unknown, floorCorridorLit, floorCorridorDark, floorItemLit, floorItemDark, floorActorItemLit, floorActorItemDark, floorRed, floorBlue, floorGreen :: TileKind--wall = TileKind- { tsymbol = '#'- , tname = "granite wall"- , tfreq = [ ("litLegend", 100), ("darkLegend", 100), ("fillerWall", 1)- , ("noiseSet", 55), ("combatSet", 5) ]- , tcolor = BrWhite- , tcolor2 = defFG- , tfeature = [HiddenAs "suspect wall"]- }-hardRock = TileKind- { tsymbol = '#'- , tname = "hard rock"- , tfreq = [("hard rock", 1)]- , tcolor = BrBlack- , tcolor2 = BrBlack- , tfeature = [Impenetrable]- }-pillar = TileKind- { tsymbol = 'O'- , tname = "pillar"- , tfreq = [("litLegend", 100), ("darkLegend", 100)]- , tcolor = BrWhite- , tcolor2 = defFG- , tfeature = []- }-wallSuspect = TileKind- { tsymbol = '#'- , tname = "moldy wall"- , tfreq = [("suspect wall", 1)]- , tcolor = BrWhite- , tcolor2 = defFG- , tfeature = [ Suspect- , ChangeTo "closed door" -- never triggered, hack 47- ]- }-doorClosed = TileKind- { tsymbol = '+'- , tname = "closed door"- , tfreq = [("litLegend", 100), ("darkLegend", 100), ("closed door", 1)]- , tcolor = Brown- , tcolor2 = BrBlack- , tfeature = [ Exit, Openable- , ChangeTo "open door"- , HiddenAs "suspect wall"- ]- }-doorOpen = TileKind- { tsymbol = '\''- , tname = "open door"- , tfreq = [("litLegend", 100), ("darkLegend", 100), ("open door", 1)]- , tcolor = Brown- , tcolor2 = BrBlack- , tfeature = [Walkable, Clear, Exit, Closable, ChangeTo "closed door"]- }-stairsUp = TileKind- { tsymbol = '<'- , tname = "staircase up"- , tfreq = [("litLegend", 100), ("darkLegend", 100)]- , tcolor = BrWhite- , tcolor2 = defFG- , tfeature = [ Walkable, Clear, Lit, Exit, Ascendable- , Cause $ Effect.Ascend 1 ]- }-stairsDown = TileKind- { tsymbol = '>'- , tname = "staircase down"- , tfreq = [("litLegend", 100), ("darkLegend", 100)]- , tcolor = BrWhite- , tcolor2 = defFG- , tfeature = [ Walkable, Clear, Lit, Exit, Descendable- , Cause $ Effect.Descend 1 ]- }-escapeUp = TileKind- { tsymbol = '<'- , tname = "exit airlock up"- , tfreq = [("litLegend", 100), ("darkLegend", 100)]- , tcolor = BrYellow- , tcolor2 = BrYellow- , tfeature = [ Walkable, Clear, Lit, Exit, Cause Effect.Escape ]- }-unknown = TileKind- { tsymbol = ' '- , tname = "unknown space"- , tfreq = [("unknown space", 1)]- , tcolor = defFG- , tcolor2 = BrWhite- , tfeature = []- }-floorCorridorLit = TileKind- { tsymbol = '.'- , tname = "floor"- , tfreq = [("floorArenaLit", 1), ("noiseSet", 100)]- , tcolor = BrWhite- , tcolor2 = defFG- , tfeature = [Walkable, Clear, Lit]- }-floorCorridorDark = floorCorridorLit- { tfreq = [("darkCorridor", 1)]- , tcolor = BrYellow- , tcolor2 = BrBlack- , tfeature = [Walkable, Clear]- }-floorItemLit = floorCorridorLit- { tfreq = [("combatSet", 100)]- , tfeature = CanItem : tfeature floorCorridorLit- }-floorItemDark = floorCorridorDark- { tfreq = []- , tfeature = CanItem : tfeature floorCorridorDark- }-floorActorItemLit = floorItemLit- { tfreq = [("litLegend", 100), ("floorRoomLit", 1)]- , tfeature = CanActor : tfeature floorItemLit- }-floorActorItemDark = floorItemDark- { tfreq = [("darkLegend", 100)]- , tfeature = CanActor : tfeature floorItemDark- }-floorRed = floorCorridorLit- { tname = "emergency walkway"- , tfreq = [("path", 20)]- , tcolor = BrRed- , tcolor2 = Red- , tfeature = Path : tfeature floorCorridorLit- }-floorBlue = floorRed- { tname = "transport route"- , tfreq = [("path", 100)]- , tcolor = BrBlue- , tcolor2 = Blue- }-floorGreen = floorRed- { tname = "greenery path"- , tfreq = [("path", 100)]- , tcolor = BrGreen- , tcolor2 = Green- }
− src/Main.hs
@@ -1,49 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}--- Copyright (c) 2008--2011 Andres Loeh, 2010--2012 Mikolaj Konarski--- This file is a part of the computer game Allure of the Stars--- and is released under the terms of the GNU Affero General Public License.--- For license and copyright information, see the file LICENSE.------ | The main code file of Allure of the Stairs. Here the knot of engine--- code pieces and the Allure-specific content defintions is tied,--- resulting in an executable game.-module Main ( main ) where--import qualified Content.ActorKind-import qualified Content.CaveKind-import qualified Content.FactionKind-import qualified Content.ItemKind-import qualified Content.PlaceKind-import qualified Content.RuleKind-import qualified Content.StrategyKind-import qualified Content.TileKind-import Game.LambdaHack.Client-import Game.LambdaHack.Client.Action.ActionType-import Game.LambdaHack.Common.Action (MonadAtomic (..))-import Game.LambdaHack.Common.AtomicCmd-import Game.LambdaHack.Common.AtomicSem-import qualified Game.LambdaHack.Common.Kind as Kind-import Game.LambdaHack.Server-import Game.LambdaHack.Server.Action.ActionType-import Game.LambdaHack.Server.AtomicSemSer--instance MonadAtomic ActionSer where- execAtomic = atomicSendSem--instance MonadAtomic (ActionCli c) where- execAtomic (CmdAtomic cmd) = cmdAtomicSem cmd- execAtomic (SfxAtomic _) = return ()--main :: IO ()-main =- let copsSlow = Kind.COps- { coactor = Kind.createOps Content.ActorKind.cdefs- , cocave = Kind.createOps Content.CaveKind.cdefs- , cofact = Kind.createOps Content.FactionKind.cdefs- , coitem = Kind.createOps Content.ItemKind.cdefs- , coplace = Kind.createOps Content.PlaceKind.cdefs- , corule = Kind.createOps Content.RuleKind.cdefs- , costrat = Kind.createOps Content.StrategyKind.cdefs- , cotile = Kind.createOps Content.TileKind.cdefs- }- in mainSer copsSlow executorSer $ exeFrontend executorCli executorCli
− src/Multiline.hs
@@ -1,15 +0,0 @@--- Copyright (c) 2008--2011 Andres Loeh, 2010--2012 Mikolaj Konarski--- This file is a part of the computer game Allure of the Stars--- and is released under the terms of the GNU Affero General Public License.--- For license and copyright information, see the file LICENSE.------ | Template Haskell machinery for quoting multiline strings.-module Multiline (multiline) where--import qualified Language.Haskell.TH as TH-import qualified Language.Haskell.TH.Quote as TQ---- | Handle multiline verbatim string expressions.-multiline :: TQ.QuasiQuoter-multiline = TQ.QuasiQuoter (\x -> (TH.litE . TH.stringL) x)- undefined undefined undefined
+ test/test.hs view
@@ -0,0 +1,6 @@+import TieKnot++main :: IO ()+main = do+ tieKnot $ tail $ words "dist/build/LambdaHack/LambdaHack --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendNull --benchmark --stopAfter 6 --automateAll --gameMode campaign --difficulty 1 --setDungeonRng 42 --setMainRng 42"+ -- tieKnot $ tail $ words "dist/build/LambdaHack/LambdaHack --dbgMsgSer --savePrefix test --newGame --noMore --noDelay --noAnim --maxFps 100000 --frontendNull --benchmark --stopAfter 6 --automateAll --gameMode battle --difficulty 1 --setDungeonRng 42 --setMainRng 42"