Allure-0.9.5.0/0000755000000000000000000000000007346545000011300 5ustar0000000000000000Allure-0.9.5.0/Allure.cabal0000644000000000000000000001672107346545000013517 0ustar0000000000000000cabal-version: 2.2 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 -- | | +----- minor or non-breaking API additions -- | | | +--- code changes with no API change version: 0.9.5.0 synopsis: Near-future Sci-Fi roguelike and tactical squad combat game description: Allure of the Stars is a near-future Sci-Fi roguelike and tactical squad combat game. Binaries and the game manual are available at the homepage, where you can also try the game out in the browser: . (It runs fastest on Chrome. Keyboard commands and savefiles are supported only on recent enough versions of browsers. Mouse should work everywhere.) . Not a single picture in this game. You have to imagine everything yourself, like with a book (a grown-up book, without pictures). Once you learn to imagine things, though, you can keep exploring and mastering the world and making up stories for a long time. . The game is written in Haskell using the LambdaHack roguelike game engine . 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. Contributions are welcome. . This is a workaround .cabal file, flattened to eliminated internal libraries until generating haddocks for them is fixed. The original .cabal file is stored in the github repo. homepage: http://allureofthestars.com bug-reports: http://github.com/AllureOfTheStars/Allure/issues license: AGPL-3.0-or-later license-file: COPYLEFT tested-with: GHC==8.2.2, GHC==8.4.4, GHC==8.6.5 data-files: GameDefinition/config.ui.default, GameDefinition/fonts/16x16xw.woff, GameDefinition/fonts/16x16xw.bdf, GameDefinition/fonts/16x16x.fnt, GameDefinition/fonts/8x8xb.fnt, GameDefinition/fonts/8x8x.fnt, GameDefinition/fonts/LICENSE.16x16x, GameDefinition/fonts/Fix15Mono-Bold.woff, GameDefinition/fonts/LICENSE.Fix15Mono-Bold, GameDefinition/InGameHelp.txt, GameDefinition/PLAYING.md, README.md, CHANGELOG.md, LICENSE, COPYLEFT, CREDITS extra-source-files: GameDefinition/config.ui.default, GameDefinition/MainMenu.ascii, GameDefinition/MoveKeys.txt, GameDefinition/PLAYING.md, Makefile author: Andres Loeh, Mikolaj Konarski and others maintainer: Mikolaj Konarski category: Game build-type: Simple source-repository head type: git location: git://github.com/AllureOfTheStars/Allure.git flag supportNodeJS description: compile so that the JS blob works in terminal with NodeJS default: True manual: True common options default-language: Haskell2010 default-extensions: MonoLocalBinds, ScopedTypeVariables, OverloadedStrings BangPatterns, RecordWildCards, NamedFieldPuns, MultiWayIf, LambdaCase, DefaultSignatures, InstanceSigs, MonadFailDesugaring, StrictData, CPP other-extensions: TemplateHaskell, MultiParamTypeClasses, RankNTypes, TypeFamilies, FlexibleContexts, FlexibleInstances, DeriveFunctor, FunctionalDependencies, GeneralizedNewtypeDeriving, TupleSections, DeriveFoldable, DeriveTraversable, ExistentialQuantification, GADTs, StandaloneDeriving, DataKinds, KindSignatures, DeriveGeneric ghc-options: -Wall -Wcompat -Worphans -Wincomplete-uni-patterns -Wincomplete-record-updates -Wimplicit-prelude -Wmissing-home-modules -Widentities -Wredundant-constraints -Wmissing-export-lists -Wpartial-fields ghc-options: -Wall-missed-specialisations ghc-options: -fno-ignore-asserts -fexpose-all-unfoldings -fspecialise-aggressively -fsimpl-tick-factor=200 cpp-options: -DEXPOSE_INTERNAL ghcjs-options: -DUSE_JSFILE common exe-options ghc-options: -threaded -rtsopts -- (Ignored by GHCJS) Minimize median lag at the cost of occasional bigger -- GC lag, which fortunately sometimes fits into idle time between turns): -- (Ignored by GHCJS) Avoid frequent GCs. Only idle-GC during a break in -- gameplay (5s), not between slow keystrokes. ghc-options: "-with-rtsopts=-A99m -I5" -- Haskell GC in GHCJS every 10s. ghcjs-options: -DGHCJS_GC_INTERVAL=10000 -- This is the largest GHCJS_BUSY_YIELD value that does not cause dropped frames -- on my machine with default --maxFps. ghcjs-options: -DGHCJS_BUSY_YIELD=50 ghcjs-options: -dedupe if !flag(supportNodeJS) ghcjs-options: -DGHCJS_BROWSER library import: options hs-source-dirs: GameDefinition, GameDefinition/game-src exposed-modules: Content.CaveKind Content.ItemKind Content.ItemKindEmbed Content.ItemKindActor Content.ItemKindOrgan Content.ItemKindBlast Content.ItemKindTemporary Content.ModeKind Content.ModeKindPlayer Content.PlaceKind Content.RuleKind Content.TileKind TieKnot Client.UI.Content.Input Client.UI.Content.Screen Implementation.MonadClientImplementation Implementation.MonadServerImplementation other-modules: Paths_Allure autogen-modules: Paths_Allure build-depends: ,LambdaHack >= 0.9.5.0 && < 0.9.6.0 ,async ,base >= 4.10 && < 99 ,enummapset ,filepath ,ghc-compact ,optparse-applicative ,primitive ,random ,template-haskell >= 2.6 ,text ,transformers executable Allure import: options, exe-options main-is: GameDefinition/Main.hs build-depends: ,LambdaHack ,Allure ,async ,base ,filepath ,optparse-applicative test-suite test import: options, exe-options type: exitcode-stdio-1.0 main-is: test/test.hs build-depends: ,LambdaHack ,Allure ,async ,base ,filepath ,optparse-applicative Allure-0.9.5.0/CHANGELOG.md0000644000000000000000000006537207346545000013126 0ustar0000000000000000## [v0.9.5.0](https://github.com/LambdaHack/LambdaHack/compare/v0.9.4.0...v0.9.5.0) - Fix NumLock disabled in the browser - In screen reader frontend, highlight active menu line with the cursor - Fix commited debug value of rwriteSaveClips - Clone the main main menu commands as map mode commands - Add C-RMB and C-S-LMB as alternatives of MMB - Announce prominently MMB binding for describing map positions - Break the misleading alignment of movement key help paragraphs and pictures - Clean up the default config file, keeping compatibility - Make scenario names longer and slighlty more informative - Make Vi movement keys the default in addition to keypad and mouse - Fix a bug where death prompt when autoplaying was capturing a keypress - Let ESC from main menu return to insert coin mode, if applicable - Make various small UI tweaks, especially to main menu and its submenu - Let main menu lines have 35, not 30, characters - Make the main menu ASCII art less intrusive (and easier for screen readers) - Don't invalidate the score file due to game minor (only) version bump ## [v0.9.4.0](https://github.com/AllureOfTheStars/Allure/compare/v0.9.3.0...v0.9.4.0) - Tweak razor organs - In vty frontend highlight actors more - Clean up actor highlighting - Add yell/yawn to minimal command set, remove swerving the aiming line - Invoke yell/yawn exclusively with '%', due tor Windows and terminal woes - Move C-c command to C, not to mask C-c on console frontends - Tweak and fix vty console frontends, for screen-readers - React specially at gameover under certain special circumstances - Simpliy assignSlot now that slots are auto-sorted - Get rid of explicit item sorting; let lore and menu slots agree - Make DetectExit non-modal - Mark in a game end confirmation message that more treasure can be found - Add a description to the escape embedded item - Reword gameover text for raid scenario - Be more verbose when confirming escape from the game - Don't claim to summon, when not possible on this level - Fix missing 'no longer poisoned' when applying antidote - Don't ask confirmation for neutral (e.g., not IDed) items - Fix 'you fall down; you stand on a sword' - Prevent selecting regions via mouse down in web frontend - Deselect item if player declines to apply or fling - Hand-hold the player, warning if flung item is beneficial - Hand-hold the player, warning if applied item is harmful - Rewrite the condition in UI applyItem check - Improve the lobable item skill failure message - Let mouse buttons describe tiles, etc. - Unblock S-MouseButton in SDL2 frontend - Always describe things under mouse button - Make the message when hitting dead foe more varied ## [v0.9.3.0, aka 'Double of everything'](https://github.com/AllureOfTheStars/Allure/compare/v0.8.3.0...v0.9.3.0) - Make maximal level size twice higher - Extend the spaceship to 15 decks - Expand game content to fill the more numerous and often twice larger levels - Vary size and position of levels - Adjust help screens to twice higher display size - Introduce message classes with configurable behaviour - Create a new 16x16 font and use it everywhere; tweak smaller fonts - Lock some levels or otherwise make ascending tricky - Add cooldown to most melee weapons, display that in HUD, adjust AI - Add per-scenario and per-outcome end-game messages in content - Add duplicate and reroll item effects in preparation for crafting - Add actor and item analytics as a preparation for XP gain quests - Implement piercing projectiles that may share a tile with a big actor - Increase the spawn speed now that monsters sleep a lot - Introduce actors falling asleep and yelling - Allow any level size and position - Mention places when looking at tiles and add place lore menu - Expand all kinds of content and rebalance - Create and rework all item, cave and plot prose (Dan Keefe @Peritract) - Make explosives in cramped spaces twice weaker - Tweak player fling command - Tweak equipping when equipment overfull - Start cycling stores at equipment since that's the one mentioned in help - Overhaul CI scripts - Restructure and clean up codebase - Extend balance debugging tools, using item and actor analytics, places, etc. - Drop the gameplay option that first death means defeat - Avoid idle-GC between slow keystrokes - Put content data into a compact region to limit GC - Remove the border around web frontend game screen; seems unneeded now - Don't draw aiming line nor path in vty frontend - Highlight xhair by cursor in vty frontend - Highlight player by cursor in vty frontend - Switch the default FPS to 24 for tradition's sake - Highlight current high score - Remove most stopPlayBack, now spurious, because message classes used - Overhaul cabal file: define common options, split into internal libraries - Fix confusion of nub and uniq - Rename short wait to lurk and many lurks to heed - Show a red message when HP or Calm dip too low or when foe appears - Lose Calm and so alert AI even at weakest non-zero HP draining attacks - Enable screenshots while in menus - Rename config options related to fonts - Recolour aiming line not to clash with the red crosshair - Exchange the functions of yellow and red highlight - Tweak all colours, in particular to differentiate blues/cyans - Cap bright colours at 85 CIELAB Lightness at D65 - Normalize dark colours to be between 42 and 57 CIELAB Lightness at D65 - Get rid of colorIsBold option; KISS - Tint white in alternating lines with different hue for long text readability - Don't split lines at articles - Set xhair to currently meleed foe to see his HP - Display speed on HUD; tweak status lines in other ways - Don't show description of leader target in HUD; TMI - Help AI flee in a consistent direction over many turns - Expose the save backup command, for browser games - Don't display target info when item selected - Let AI actors spawn even quite far from the player - Auto-select all new team members, to help new players - Replace O by zero on the map display; make zero distinct from O in all fonts - Flesh out the initial ? prompt - Add 'I' alias for pack-related commands, unless laptop key-scheme used - Turn off movementLaptopKeys by default not to confuse new players - Make sure AI attacks bosses even if distant and fleeing or non-moving - Lower bonus HP at extreme difficulty - Add a separate frame for each projectiles start - Don't go modal at the frequent and weak hidden tile detection effect - Make AI pick closest stairs more often - Let apply-unskilled actors activate embedded items - Don't boost damage by speed unless actor is projectile - If everything else fails, let AI flee by opening doors - Help AI actor prevent being dominated - Make computing gameplay benefit to items more accurate - Rename, clone and fine-tune effect Temporary - Simplify code and content by getting rid of Recharging effect - Let applying periodic items only produce the first effect - Tweak item detection to help in skipping boring level portions and in stealth - Invoke and display embedded items in the order specified in tile definitions - Let lit trails illuminate colonnades - Prevent an exploit for avoiding self-invoked firecrackers - Don't let AI attempt summoning if not enough Calm - Improve item label bracket codes in menus - Pick randomly destination stairs if teleporting level - Display the number of items in store - Summarize value of player loot in shared stash menu's header - Start history menu at the close-up of the last message - Make fast-dying insects aggressive - Overhaul game score DSL and particular scoring definitions in content - Add and extend messages, e.g., tell if victim blocks and with what armor - Extend and rework menu manipulation keys - Remove specialized quaff, read and throw commands; KISS - Split walls of text into more paragraphs and/or make them narrower - Extend and update help and manual - Don't let AI waste time looting distant lone projectiles - Make Enum instances of Point and Vector contiguous, hackily - Make dominated actor drop all his items, for ID and in case he defects ASAP - Try to find a non-waiting action, if better AI leader can't be found - Prevent summoning OoD actors - Let animals eat food and add several foods - Make Domination effect harder to activate - Let only actors and items with SkOdor property leave smell and add perfumes - Let spawning rate level out after a few dozen spawns - Describe smell, if present in an inspected tile - Let pushed actor fly after crashing a door open - Show passing time and heard events even if no actors in the UI faction - When movement impossible, describe the tile with SHIFT-direction - Catch and steal projectiles when braced instead of when weaponless - Let actors that are pushed perform any action in addition to movement - Improve deduplication of messages - When describing actor on map, tell if it has loot - Represent being braced as having an organ; also add other pseudo-organs - Overhaul hearing to facilitate triangulation based on sound cues - Prefer to spawn aquatic actors on aquatic tiles - Add swimming and flying skills and shallow water tile features - Boost/drain skills via many new items - Rework and extend skills and their effects as a preparation for XP rewards - Enable specifying each side of outer cave fence separately - Make definition of caves of a scenario more precise - Specify more properties of levels in content - Extend content validation - Improve placement and fitting stairs and rooms on levels - Don't hardwire level size - Simplify game rules content - Change the format of game client content - Fix an arbitrary delay in killing dying actors - Fix arbitrary branch of a corridor chosen when running - Fix bush patches blocking off a level's corner - Fix config file ignored at game reinit - Fix running disturbed by flavours of walls - Fix splitting lines one character too early - Fix Calm drain from nearby foes occurring only every other turn - Fix some AI looping movement, in particular when fleeing - Fix running into own periodic explosions, e.g., from necklaces - Fix 'she painfullies collide' - Fix AI with vector targets unwilling to change them - Fix crash when attempting to fling at a target on remote level - Fix wrong timestamps in history - Fix, again, various kinds of frames intruding between fadeout and fadein - Fix wrong pluralization of some item names, compound and exceptions - Fix disabled items benefit recalculation after item kind learned - Fix in many ways too close initial faction and item positions - Fix performance in many ways and places, particularly for JS translation - Fix missing perception updates, causing missed AI actions concerning us - Fix uninitialized sarenas, which was probably causing resume to change state - Fix weak AI actors fleeing even if enemy can't melee - Fix and optimize sifting free tiles for spawn/summon location - Fix various cases of excessive summoning - Fix recording of item first seen level - Fix many problems with item descriptions and other messages - Fix reporting of reduction and elimination of actor conditions - Fix reading and interpreting old format config files - Fix synced initial item timeouts and actor times, leading to artificial feel - Fix actors erratically following their leader - Fix lifts continuing as stars and the other way around - Fix various 32bit overflows - Fix other errors, probably not present or not visible in previous version ## [v0.8.3.0](https://github.com/AllureOfTheStars/Allure/compare/v0.8.1.2...v0.8.3.0) - Add a hack to run SDL2 on the main thread, fixing the OS X crash - Warn visually when impressed and Calm running low, risking domination - Display actor as red when low Calm and impressed or when low HP - Fix, complete and fine tune UI, AI and server skill and weapon checks - Fix a bug where item aspects look different to clients than to the server - Change the requirements for the main menu ASCII art - Tweak loot and terrain a tiny bit ## [v0.8.1.2](https://github.com/AllureOfTheStars/Allure/compare/v0.8.1.1...v0.8.1.2) - Fix typos detected by lintian - Fix the code that runs in case of old async (bug introduced in v0.8.1.1) ## [v0.8.1.1](https://github.com/AllureOfTheStars/Allure/v0.8.1.0...v0.8.1.1) - no player-visible changes - make it possible to compile with old async package - rewrite copyright information according to Debian format - make github display the correct main license ## [v0.8.1.0](https://github.com/AllureOfTheStars/Allure/v0.8.0.0...v0.8.1.0) - no player-visible changes - significantly reduce RAM usage when compiling library - update and extend CI ## [v0.8.0.0, aka 'Explosive dashboard'](https://github.com/AllureOfTheStars/Allure/compare/v0.7.1.0...v0.8.0.0) - display initial bits of backstory as a help screen and in-game - rework greying out menu items and permitting item application and projection - rework history collection; merge message repetitions more aggressively - display HP in red when below (configurable) warning threshold - tweak AI: actors remember they are fleeing; better leader choice, etc. - add to content specialized explosive projectiles; tune the effects - calculate loot score component based on fraction of dungeon loot collected - don't hardwire item price, but let it be specified in content - let all valuables glitter in the dark to avoid complete level exploration - teach AI to cure ailments and shake off impressions - rework detection effects; add detection of items embedded in tiles - automatically identify stolen items that only have minor effects - let projectiles hit each other if fragile and substantial enough - rework item kind identification code; change the way it's defined in content - make more item kinds (including some traps) secret - protect paralyzed actors with a stasis condition to avoid infinite paralysis - implement dumping screenshots in SDL2 and create animated GIFs in Makefile - generate most common consumables less often, but in depth-scaled bunches - make pushed actors alter tiles and trigger effects of embedded items - validate and cross-validate more content; reduce content creation boilerplate - make summoning more varied and prevent chain-summoning - add many ways to conditionally sequence effects - create large, merged rooms more often - generalize the terrain altering player command (C-c, mouse) - let RET, SPACE and ESC clear pending messages, if any - add dashboard with links to all menus and info screens - scale some organ and trap power with level depth - simplify level-scaled dice roll semantics - change scaled dice notation 'dl' to 'dL' for readability in-game - rebalance items and decrease dice variety to unclutter backpack - colour-code beneficial and harmful conditions in menu and in HUD - display item lore (also for organs, embedded items, explosions, etc.) - display embedded item descriptions as if they were tile descriptions - tweak blast visuals, lower particle counts, beautify their spread - tweak projectile visuals, e.g., display an extra frame when projectile dies - add intro screen and work on other ways to convey story - simplify a lot of code, including a bit of game rules - fix some bugs, tweak content, speed up some AI bottlenecks ## [v0.7.1.0, aka 'Ancient troubles'](https://github.com/AllureOfTheStars/Allure/compare/v0.7.0.0...v0.7.1.0) - add amazing cave and item (actor, blast, organ) descriptions - package for Windows as an installer and also as zip archives - fix a crash from SDL frontend under some OpenGL drivers (no thread-safety) - add WWW address to the Main Menu, for other sites that may run our JS blob ## [v0.7.0.0, aka 'The dice are cast'](https://github.com/AllureOfTheStars/Allure/compare/v0.6.2.0...v0.7.0.0) - decouple tile searching from tile alteration - refrain from identifying items that are not randomized - switch away from incapacitated leader to let others revive him - make rescue easier by not going into negative HP the first time - fix crowd of friends on another level slowing even actors that melee - fix missing report about items underneath an actor when changing levels - API breakage: change the syntax of dice in content - API addition: introduce cave descriptions - keep all client states in the server and optimize communication with clients - improve item choice for identification and item polymorphing - reset embedded items when altering tile - replace atomic command filtering with exception catching - reimplement dice as symbolic expressions inducing multiple RNG calls - switch to optparse-applicative and rewrite cli handling - add stack and cabal new-build project files - improve haddocks across the codebase ## [v0.6.2.0, aka 'Zoom out'](https://github.com/AllureOfTheStars/Allure/compare/v0.6.1.0...v0.6.2.0) - make fireworks slower and so easier to spot - make rattlesnake deeper but more common - announce no effect of activation - describe original and current faction of an actor - highlight dominated actors - mark organs with comma instead of percent and gems with dollar - make the healing cave dangerous to prevent camping - slightly balance various content - by default move item the same as last time - often spawn between heroes and stairs going deeper - fix totalUsefulness computation for negative effects - fix abandoning distant enemy target despite no alternatives - fix slow pushing of actors - fix a crash when many actors run towards stairs - hotfix: Pass zoom keys through to the browser - help players find the info about changing the font size - depend on GHC >= 8.0 and new vector ## [v0.6.1.0, aka 'Breaking one rule at a time'](https://github.com/AllureOfTheStars/Allure/compare/v0.6.0.0...v0.6.1.0) - major engine bugfix: fix redrawing after window minimized and restored - major engine bugfix: hack around vanishing texture on Windows - major engine bugfix: hack around SDL backends not thread-safe on Windows - update wrt the only breaking API change: specify font dir in game rules content - let the game use its own fonts, not fonts from the sample game in library - tweak some item creation to occur in character's pack, not on the ground - slightly balance various content - make sure the 'resolution' effect is not a drawback - make artifact weapon rarities more regular - avoid creating lit, open dungeon at the bottom, where foes have ranged weapons - number scenarios in user descriptions ## [v0.6.0.0, aka 'Too much to tell'](https://github.com/AllureOfTheStars/Allure/compare/v0.5.0.0...v0.6.0.0) - add and modify a lot of content: items, tiles, embedded items, scenarios - improve AI: targeting, stealth, moving in groups, item use, fleeing, etc. - make monsters more aggressive than animals - tie scenarios into a loose, optional storyline - add more level generators and more variety to room placement - make stairs not walkable and use them by bumping - align stair position on the levels they pass through - introduce noctovision - increase human vision to 12 so that normal speed missiles can be sidestepped - tweak and document weapon damage calculation - derive projectile damage mostly from their speed - make heavy projectiles better vs armor but easier to sidestep - improve hearing of unseen actions, actors and missiles impacts - let some missiles lit up on impact - make torches reusable flares and add blankets for dousing dynamic light - add detection effects and use them in items and tiles - make it possible to catch missiles, if not using weapons - make it possible to wait 0.1 of a turn, at the cost of no bracing - improve pathfinding, prefer less unknown, alterable and dark tiles on paths - slow down actors when acting at the same time, for speed with large factions - don't halve Calm at serious damage any more - eliminate alternative FOV modes, for speed - stop actors blocking FOV, for speed - let actor move diagonally to and from doors, for speed - improve blast (explosion) shapes visually and gameplay-wise - add SDL2 frontend and deprecate GTK frontend - add specialized square bitmap fonts and hack a scalable font - use middle dot instead of period on the map (except in teletype frontend) - add a browser frontend based on DOM, using ghcjs - improve targeting UI, e.g., cycle among items on the map - show an animation when actor teleports - add character stats menu and stat description texts - add item lore and organ lore menus - add a command to sort item slots and perform the sort at startup - add a single item manipulation menu and let it mark an item for later - make history display a menu and improve display of individual messages - display highscore dates according to the local timezone - make the help screen a menu, execute actions directly from it - rework the Main Menu - rework special positions highlight in all frontends - mark leader's target on the map (grey highlight) - visually mark currently chosen menu item and grey out impossible items - define mouse commands based on UI mode and screen area - let the game be fully playable only with mouse, use mouse wheel - pick menu items with mouse and with arrow keys - add more sanity checks for content - reorganize content in files to make rebasing on changed content easier - rework keybinding definition machinery - let clients, not the server, start frontends - version savefiles and move them aside if versions don't match - lots of bug fixes internal improvements and minor visual and text tweaks ## [v0.5.0.0, aka 'Halfway through space'](https://github.com/AllureOfTheStars/Allure/compare/v0.4.101.0...v0.5.0.0) - let AI put excess items in shared stash and use them out of shared stash - let UI multiple items pickup routine put items that don't fit into equipment into shared stash, if possible, not into inventory pack - re-enable the ability to hear close, invisible foes - add a few more AI and autonomous henchmen tactics (CTRL-T) - keep difficulty setting over session restart - change some game start keybindings - replace the Duel game mode with the Raid game mode - various bugfixes, minor improvements and balancing ## [v0.4.101.1, aka 'Officially fun'](https://github.com/AllureOfTheStars/Allure/compare/v0.4.100.0...v0.4.101.1) - the game is now officially fun to play, with a seal of the Galactic Council - introduce unique boss monsters and unique artifact items - add robots that heal the player, in particular as a mid-game reset for HP - move spaceship airlock to level 10 and beef up spaceship crew - let AI gang up, attempt stealth and react to player aggressiveness - spawn actors fast, close to the enemy and in large numbers - spawn actors less and less often on a given level, but with growing depth - prefer weapons with effects, if recharged - make the bracing melee bonus additive, not multiplicative - let explosions buffet actors around - make braced actors immune to translocation effects - make actor domination yet less common and deadly - use mouse for movement, actor selection, aiming - don't run straight with selected actors, but go-to cross-hair with them - speed up default frame rate, slow down projectiles visually - rework item manipulation UI - you can pick up many items at once and it costs only one turn - allow actors to apply and project from the shared stash - reverse messages shown in player diary - display actor organs and stats - split highscore tables wrt game modes - move score calculation formula to content - don't keep the default/example config file commented out; was misleading - update vs the naughtily changed v0.5.0.0 of LambdaHack content API ## [v0.4.100.0, aka 'The last interstellar thaw'](https://github.com/AllureOfTheStars/Allure/compare/v0.4.99.0...v0.4.100.0) - update vs the unexpectedly thawed v0.5.0.0 of LambdaHack content API - unexpectedly add items with timeouts and temporary effects - start campaign on level 3 and don't spawn aliens until level 4 - rebalance campaign (probably still too hard) - tweak skills of some factions and actors - rename tablets to chips to make their vanishing easier to understand - make colorful characters bold (if it resizes your fonts, turn off via colorIsBold = False in config file or --noColorIsBold on commandline) - start the game with a screensaver safari mode - improve keyboard handling on Windows - add i386 Linux and Windows compilation targets to Makefile ## [v0.4.99.0, aka 'Player escapes through airlock'](https://github.com/AllureOfTheStars/Allure/compare/v0.4.14...v0.4.99.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 Allure-0.9.5.0/COPYLEFT0000644000000000000000000012027507346545000012457 0ustar0000000000000000Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Allure Upstream-Contact: Mikolaj Konarski Source: https://hackage.haskell.org/package/Allure Files: * Copyright: 2008-2011 Andres Loeh 2010-2019 Mikolaj Konarski and others (see git history) License: AGPL-3.0-or-later Files: GameDefinition/fonts/{*.fnt,*.bdf,16x16xw.woff} Copyright: 1997-2016 Leon Marrick 1997-2016 Sheldon Simms III 1997-2016 Nick McConnell 2016-2019 Mikolaj Konarski License: GPL-2.0-or-later Files: GameDefinition/fonts/Fix15Mono-Bold.woff Copyright: 2012-2015 The Mozilla Foundation and Telefonica S.A 2016-2019 Mikolaj Konarski License: OFL-1.1 Files: debian/* Copyright: held by the contributors mentioned in debian/changelog License: AGPL-3.0-or-later License: AGPL-3.0-or-later GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 . Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. . Preamble . The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. . The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. . When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. . Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. . A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. . The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. . An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. . The precise terms and conditions for copying, distribution and modification follow. . TERMS AND CONDITIONS . 0. Definitions. . "This License" refers to version 3 of the GNU Affero General Public License. . "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. . "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. . To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. . A "covered work" means either the unmodified Program or a work based on the Program. . To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. . To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. . An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. . 1. Source Code. . The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. . A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. . The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. . The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. . The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. . The Corresponding Source for a work in source code form is that same work. . 2. Basic Permissions. . All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. . You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. . Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. . 3. Protecting Users' Legal Rights From Anti-Circumvention Law. . No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. . When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. . 4. Conveying Verbatim Copies. . You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. . You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. . 5. Conveying Modified Source Versions. . You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: . a) The work must carry prominent notices stating that you modified it, and giving a relevant date. . b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". . c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. . d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. . A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. . 6. Conveying Non-Source Forms. . You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: . a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. . b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. . c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. . d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. . e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. . A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. . A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. . "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. . If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). . The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. . Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. . 7. Additional Terms. . "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. . When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. . Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: . a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or . b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or . c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or . d) Limiting the use for publicity purposes of names of licensors or authors of the material; or . e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or . f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. . All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. . If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. . Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. . 8. Termination. . You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). . However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. . Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. . Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. . 9. Acceptance Not Required for Having Copies. . You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. . 10. Automatic Licensing of Downstream Recipients. . Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. . An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. . You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. . 11. Patents. . A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". . A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. . Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. . In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. . If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. . If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. . A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. . Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. . 12. No Surrender of Others' Freedom. . If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. . 13. Remote Network Interaction; Use with the GNU General Public License. . Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. . Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License. . 14. Revised Versions of this License. . The Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. . Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation. . If the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. . Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. . 15. Disclaimer of Warranty. . THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. . 16. Limitation of Liability. . IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. . 17. Interpretation of Sections 15 and 16. . If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. . END OF TERMS AND CONDITIONS . How to Apply These Terms to Your New Programs . If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. . To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. . Copyright (C) . This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. . This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. . You should have received a copy of the GNU Affero General Public License along with this program. If not, see . . Also add information on how to contact you by electronic and paper mail. . If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. . You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . License: GPL-2.0-or-later This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation . This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this package; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA . On Debian systems, the full text of the GNU General Public License version 2 can be found in the file `/usr/share/common-licenses/GPL-2'. License: OFL-1.1 SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 . PREAMBLE The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. . The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. . DEFINITIONS Font Software refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. . Reserved Font Name refers to any names specified as such after the copyright statement(s). . Original Version refers to the collection of Font Software components as distributed by the Copyright Holder(s). . Modified Version refers to any derivative made by adding to, deleting, or substituting in part or in whole any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. . Author refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. . PERMISSION & CONDITIONS Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: . 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. . 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. . 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. . 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. . 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. . TERMINATION This license becomes null and void if any of the above conditions are not met. . DISCLAIMER THE FONT SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Allure-0.9.5.0/CREDITS0000644000000000000000000000466307346545000012331 0ustar0000000000000000All kinds of contributions to Allure of the Stars are gratefully welcome! Some of the contributors are listed below, in chronological order. Andres Loeh Mikolaj Konarski Krzysztof PÅ‚awski Daniel Keefe Pablo Reszczynski Simon Michael Fonts 16x16xw.woff, 16x16xw.bdf, 16x16x.fnt, 8x8x.fnt and 8x8xb.fnt are are derived from fonts taken from https://github.com/angband/angband, copyrighted by Leon Marrick, Sheldon Simms III and Nick McConnell and released by them under GNU GPL, version 2 or any later version (confirmed at http://www.thangorodrim.net/development/opensource.html). Any further modifications by authors of LambdaHack are also released under GNU GPL version 2. The licence file is at GameDefinition/fonts/LICENSE.16x16x in the source code tree. Font 16x16xw.bdf is derived from 16x16x.fon by changing all but a few glyphs, converting to BDF format, extending character set and hacking the font file with bdftopcf and pcf2bdf to include full bitmaps, not only non-zero portions, for otherwise SDL2-ttf was not able to display the glyphs. Font 16x16xw.woff was derived from 16x16xw.bdf by changing format to TTF with bitsnpicas, faking descendent offsets to be 1 point lower to prevent freetype from adding an extra pixel to the descendent, tweaking with fontforge glyps 3 5 6 8 A a S s b d h to prevent antialiasing of their vital parts when zoomed out, auto-hinting, manually simplifying hints in some glyphs and converting to WOFF format. Font Fix15Mono-Bold.woff is a modified version of https://github.com/mozilla/Fira/blob/master/ttf/FiraMono-Bold.ttf that is copyright 2012-2015, The Mozilla Foundation and Telefonica S.A. The modified font is released under the SIL Open Font License, as seen in GameDefinition/fonts/LICENSE.Fix15Mono-Bold in the source code tree. Modifications were performed with font editor FontForge and are as follows: * straighten and enlarge #, enlarge %, &, ', +, \,, -, :, ;, O, _, ` * centre a few other glyphs * create a small 0x22c5 * shrink 0xb7 a bit * extend all fonts by 150% and 150% (the extension resulted in an artifact in letter 'n', which was gleefully kept, and many other artifacts and distortions that should be fixed at some point) * set width of space, nbsp and # glyphs to 1170 (this is a hack to make DOM create square table cells) * copy O to 0 (zero) and add the middle dot from the original zero * randomly fix various errors and simplify with fontforge * auto-generate hints with fontforge Allure-0.9.5.0/GameDefinition/Content/0000755000000000000000000000000007346545000015574 5ustar0000000000000000Allure-0.9.5.0/GameDefinition/Content/CaveKind.hs0000644000000000000000000007543707346545000017634 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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 properties. module Content.CaveKind ( content ) where import Prelude () import Game.LambdaHack.Core.Prelude import Data.Ratio import Game.LambdaHack.Content.CaveKind import Game.LambdaHack.Core.Dice content :: [CaveKind] content = [rogue, residential, arena, casino, museum, laboratory, noise, power, empty, exit, outermost, bridge, shallowRogue, raid, brawl, shootout, hunt, escape, zoo, ambush, battle, safari1, safari2, safari3] rogue, residential, arena, casino, museum, laboratory, noise, power, empty, exit, outermost, bridge, shallowRogue, raid, brawl, shootout, hunt, escape, zoo, ambush, battle, safari1, safari2, safari3 :: CaveKind -- * On-ship "caves", that is, decks, most of mediocre height and size rogue = CaveKind { csymbol = 'R' , cname = "Maintenance and storage" , cfreq = [("default random", 100), ("caveRogue", 1)] , cXminSize = 80 , cYminSize = 42 , ccellSize = DiceXY (2 `d` 4 + 10) (1 `d` 3 + 6) , cminPlaceSize = DiceXY (2 `d` 2 + 4) (1 `d` 2 + 5) -- sometimes merge vert. , cmaxPlaceSize = DiceXY 16 40 -- often maximize vertically , cdarkOdds = 1 `d` 54 + 1 `dL` 20 -- most rooms lit, to compensate for dark corridors , cnightOdds = 51 -- always night , cauxConnects = 1%2 , cmaxVoid = 1%8 , cminStairDist = 30 , cextraStairs = 1 `d` 2 , cdoorChance = 3%4 , copenChance = 1%5 , chidden = 7 , cactorCoeff = 50 -- the maze requires time to explore , cactorFreq = [("monster", 50), ("animal", 20), ("robot", 30)] , citemNum = 8 `d` 4 + 20 - 20 `dL` 1 -- deep down quality over quantity , citemFreq = [ ("common item", 40), ("treasure", 60) , ("curious item", 10) ] , cplaceFreq = [("rogue", 1)] , cpassable = False , labyrinth = False , cdefTile = "rogueSet" , cdarkCorTile = "floorCorridorDark" , clitCorTile = "floorCorridorLit" , cwallTile = "trappableWall" , ccornerTile = "fillerWall" , cfenceTileN = "basic outer fence" , cfenceTileE = "habitat containment wall" , cfenceTileS = "basic outer fence" , cfenceTileW = "habitat containment wall" , cfenceApart = False , clegendDarkTile = "legendDark" , clegendLitTile = "legendLit" , cescapeFreq = [] , cstairFreq = [ ("walled lift", 50), ("open lift", 50) , ("tiny lift", 1) ] , cstairAllowed = [ ("walled staircase", 50), ("open staircase", 50) , ("tiny staircase", 1) ] , cdesc = "Winding tunnels stretch into the dark. A few areas are passable but the remainder is packed with tanks and cells of raw materials and machinery." } residential = rogue { cfreq = [("default random", 50), ("caveResidential", 1)] , cname = "Residential area" , cmaxPlaceSize = DiceXY 14 20 -- fewer big rooms , cdarkOdds = 51 -- all rooms dark , cnightOdds = 0 -- always day , cauxConnects = 1%10 -- differentiate; bare skeleton feel; long span paths , cmaxVoid = 1%4 , cextraStairs = 1 + 1 `d` 2 , cdefTile = "fillerWall" , cstairFreq = [ ("walled staircase", 50), ("open staircase", 50) , ("tiny staircase", 1) ] , cstairAllowed = [ ("walled lift", 50), ("open lift", 50) , ("tiny lift", 1) ] , cdesc = "The area has been powered down, except for emergency corridors. Many suites are depressurized and sealed." } arena = rogue { csymbol = 'A' , cname = "Recreational deck" , cfreq = [("caveArena", 1)] , cXminSize = 80 , cYminSize = 25 , ccellSize = DiceXY (3 `d` 3 + 17) (1 `d` 3 + 5) , cminPlaceSize = DiceXY 10 15 -- merge vertically , cmaxPlaceSize = DiceXY 25 40 -- often maximize vertically , cdarkOdds = 49 + 1 `d` 10 -- almost all rooms dark (1 in 10 lit) -- Light is not too deadly, because not many obstructions and so -- foes visible from far away and few foes have ranged combat -- at shallow depth. , cnightOdds = 0 -- always day , cauxConnects = 1 , cmaxVoid = 1%20 , cminStairDist = 20 , cextraStairs = 1 `d` 2 , chidden = 0 , cactorCoeff = 40 -- smallish level, but easy to view and plan , cactorFreq = [ ("monster", 50), ("animal", 70), ("robot", 5) , ("aquatic", 10) ] , citemNum = 7 `d` 4 -- few rooms , citemFreq = [ ("common item", 20), ("treasure", 40), ("any scroll", 40) , ("explosive", 40), ("curious item", 20) ] , cplaceFreq = [("arena", 1)] , cpassable = True , cdefTile = "arenaSetLit" , cdarkCorTile = "trailLit" -- let trails give off light , clitCorTile = "trailLit" -- may be rolled different than the above , cwallTile = "openableWall" , cstairFreq = [ ("walled lift", 20), ("closed lift", 80) , ("tiny lift", 1) ] , cstairAllowed = [ ("walled staircase", 20), ("closed staircase", 80) , ("tiny staircase", 1) ] , cdesc = "Debris litters the wide streets and all the stalls have their shutters down." } casino = arena { cname = "Casino" , cfreq = [("caveCasino", 1)] , cXminSize = 21 , cYminSize = 21 , cdarkOdds = 41 + 1 `d` 10 -- almost all rooms lit (1 in 10 dark) -- Trails provide enough light for fun stealth, though level too small. , cnightOdds = 51 -- always night , cminStairDist = 10 , cactorCoeff = 70 -- cramped, don't overcrowd , cactorFreq = [("monster", 50), ("animal", 25), ("robot", 50)] , citemNum = 7 `d` 3 -- rare, so make it exciting, by keeping many items , citemFreq = [ ("common item", 20) , ("treasure", 80) -- lives up to the name , ("curious item", 40) ] , cdefTile = "arenaSetDark" , cfenceTileN = "habitat containment wall" -- small cave , cfenceTileE = "habitat containment wall" , cfenceTileS = "habitat containment wall" , cfenceTileW = "habitat containment wall" , cdesc = "The establishment is no longer filled with hollow-eyed gamblers; more dangerous things now lurk in the dark." } museum = arena { cname = "Museum" , cfreq = [("caveMuseum", 1)] , cXminSize = 25 , cYminSize = 25 , cdarkOdds = 41 + 1 `d` 10 -- almost all rooms lit (1 in 10 dark) -- Trails provide enough light for fun stealth, though level too small. , cnightOdds = 51 -- always night , cminStairDist = 10 , cactorCoeff = 70 -- cramped, don't overcrowd , cactorFreq = [("monster", 100), ("animal", 25), ("robot", 25)] , citemNum = 7 `d` 4 -- rare, so make it exciting , citemFreq = [ ("common item", 20) , ("treasure", 40) , ("curious item", 40) , ("museum", 100) ] -- lives up to the name , cplaceFreq = [("museum", 1)] , cdefTile = "museumSetDark" , cfenceTileN = "habitat containment wall" -- small cave , cfenceTileE = "habitat containment wall" , cfenceTileS = "habitat containment wall" , cfenceTileW = "habitat containment wall" , cdesc = "History has shown that museal treasures are safer in space than anywhere on Earth. Also, cruise passengers eagerly visit exhibitions, even if over the weeks of the journey they become increasingly a captive audience. That rarely applies to spaceship crew and yet museum security has a particularly keen eye for the working men visiting their establishments. Quite often a museum is the only place within millions of kilometers to house a desperately needed tool, old but sturdy beyond anything a 3D printer could produce." } laboratory = rogue { csymbol = 'L' , cname = "Laboratory" , cfreq = [("caveLaboratory", 1)] , cXminSize = 60 , cYminSize = 42 , ccellSize = DiceXY (1 `d` 2 + 5) (1 `d` 2 + 7) , cminPlaceSize = DiceXY 6 8 -- merge, usually vertically , cmaxPlaceSize = DiceXY 12 40 -- often maximize vertically , cnightOdds = 0 -- always day so that the corridor smoke is lit , cauxConnects = 1%5 , cmaxVoid = 1%10 , cminStairDist = 25 , cextraStairs = 1 `d` 2 , cdoorChance = 1 , copenChance = 1%2 , cactorFreq = [ ("monster", 50), ("animal", 70), ("robot", 5) , ("aquatic", 10) ] , citemNum = 7 `d` 5 -- reward difficulty , citemFreq = [ ("common item", 20), ("treasure", 40), ("potion", 40) , ("curious item", 40) ] , cplaceFreq = [("laboratory", 1)] , cdefTile = "fillerWall" , cdarkCorTile = "labTrailLit" -- let lab smoke give off light always , clitCorTile = "labTrailLit" , cstairFreq = [ ("decontaminating walled staircase", 50) , ("decontaminating open staircase", 50) , ("decontaminating tiny staircase", 1) ] -- In lone wolf challenge, the player better summoned or dominated -- any helpers by this point. If not, good luck fighting bare-handed. , cstairAllowed = [ ("decontaminating walled lift", 50) , ("decontaminating open lift", 50) , ("decontaminating tiny lift", 1) ] , cdesc = "Shattered glassware and the sharp scent of spilt chemicals show that something terrible happened here." } noise = rogue { csymbol = 'N' , cname = "Computing hardware hub" , cfreq = [("caveNoise", 1)] , cXminSize = 21 , cYminSize = 42 , ccellSize = DiceXY (3 `d` 5 + 12) 8 , cminPlaceSize = DiceXY 8 7 -- often merge vertically , cmaxPlaceSize = DiceXY 20 20 , cdarkOdds = 51 -- Light is deadly, because nowhere to hide and pillars enable spawning -- very close to heroes. , cnightOdds = 0 -- harder variant, but looks cheerful , cauxConnects = 1%10 , cmaxVoid = 1%100 , cminStairDist = 15 , cextraStairs = 1 , cdoorChance = 1 -- to enable the doorlessWall hack , chidden = 0 , cactorCoeff = 70 -- the maze requires time to explore; also, small , cactorFreq = [("monster", 100), ("animal", 5), ("robot", 25)] , citemNum = 8 `d` 5 -- an incentive to explore the labyrinth , citemFreq = [ ("common item", 20), ("treasure", 60), ("explosive", 20) , ("curious item", 30) ] , cpassable = True , labyrinth = True , cplaceFreq = [("noise", 1)] , cdefTile = "noiseSetLit" , cwallTile = "openableWall" , cfenceApart = True -- ensures no cut-off parts from collapsed , cdarkCorTile = "damp floor Dark" , clitCorTile = "damp floor Lit" , cstairFreq = [ ("closed staircase", 50), ("open staircase", 50) , ("tiny staircase", 1) ] , cstairAllowed = [ ("closed lift", 50), ("open lift", 50) , ("tiny lift", 1) ] , cdesc = "Several machines still function, processors whirring through routines scheduled by dead men." } power = noise { cname = "Power distribution hub" , cfreq = [("cavePower", 1)] , cXminSize = 32 , cYminSize = 42 , cnightOdds = 51 -- easier variant, but looks sinister , cextraStairs = 2 , citemNum = 8 `d` 5 -- an incentive to explore the final labyrinth , citemFreq = [ ("common item", 20), ("gem", 80), ("curious item", 30) ] -- can't be "valuable" or template items generated , cdefTile = "powerSetDark" , cdarkCorTile = "oily floor Dark" , clitCorTile = "oily floor Lit" , cstairFreq = [ ("gated closed staircase", 50) , ("gated open staircase", 50) , ("gated tiny staircase", 1) ] , cstairAllowed = [ ("gated closed lift", 50) , ("gated open lift", 50) , ("gated tiny lift", 1) ] , cdesc = "A trickle of energy flows through a hub that could power a city. The air is warm and carries organic stench. Once in a while a young animal scurries across a lit patch of ground, pouncing in low gravity." } empty = rogue { csymbol = 'E' , cname = "Construction site" , cfreq = [] , ccellSize = DiceXY (2 `d` 8 + 14) 16 , cminPlaceSize = DiceXY 9 9 -- normally don't merge , cmaxPlaceSize = DiceXY 50 20 -- often maximize horizontally , cdarkOdds = 1 `d` 100 + 1 `dL` 100 , cnightOdds = 0 -- always day , cauxConnects = 3%2 , cmaxVoid = 0 -- too few rooms to have void and fog common anyway , cminStairDist = 40 , cextraStairs = 1 , cdoorChance = 1 -- to enable the doorlessWall hack , chidden = 0 , cactorCoeff = 40 -- easy to view and plan , cactorFreq = [("monster", 10), ("animal", 5), ("robot", 85)] , citemNum = 7 `d` 4 -- few rooms , cplaceFreq = [("empty", 1)] , cpassable = True , cdefTile = "emptySetLit" , cdarkCorTile = "floorArenaDark" , clitCorTile = "floorArenaLit" , cwallTile = "openableWall" , cfenceApart = True -- ensures no cut-off border airlocks and tanks , cstairFreq = [ ("walled lift", 20), ("closed lift", 80) , ("tiny lift", 1) ] , cstairAllowed = [ ("walled staircase", 20), ("closed staircase", 80) , ("tiny staircase", 1) ] , cdesc = "Not much to see here yet." } exit = empty { cname = "Shuttle servicing level" , cfreq = [("caveExit", 1)] , ccellSize = DiceXY (1 `d` 2 + 20) 16 , cmaxPlaceSize = DiceXY 25 20 , cdarkOdds = 51 -- all dark to compensate for the always lit shuttles , cextraStairs = 2 , cplaceFreq = [("exit", 1)] , cdefTile = "exitSetLit" , cdarkCorTile = "transport route" , clitCorTile = "transport route" , cfenceTileN = "basic outer fence" , cfenceTileE = "habitat containment wall" , cfenceTileS = "airlock fence" , cfenceTileW = "habitat containment wall" , cescapeFreq = [("escape spaceship down", 1)] , cstairFreq = [("walled lift", 20), ("tiny lift", 1)] , cstairAllowed = [("walled staircase", 20), ("tiny staircase", 1)] , cdesc = "Empty husks and strewn entrails of small craft litter the hangar among cranes and welding machines. The distant main fusion thruster array can be seen to the rear of the spaceship through oriels and airlocks of all sizes." -- E and W sides are borders with other level sections, so no oriels. -- The meteor shield towards N is not punctured here, because -- the cargo bay is too thick here, near the axis of the ship. } outermost = empty { cname = "Outermost deck" , cfreq = [("caveOutermost", 100)] , cactorCoeff = 5 -- shallower than LH, so fewer immediate actors, so boost , cactorFreq = [ ("animal", 3), ("robot", 1) , ("immobile robot", 90), ("immobile animal", 2) , ("aquatic animal", 2) ] -- ("aquatic robot", 2) -- The medbot faucets on lvl 1 act like HP resets. Needed to avoid -- cascading failure, if the particular starting conditions were -- very hard. Items are not reset, even if they are bad, which provides -- enough of a continuity. The faucets on lvl 1 are not OP and can't be -- abused, because they spawn less and less often and also HP doesn't -- effectively accumulate over max. , citemFreq = ("starting weapon", 20) : filter ((/= "treasure") . fst) (citemFreq empty) , cfenceTileN = "oriels fence" , cfenceTileE = "habitat containment wall" , cfenceTileS = "empty airlock fence" , cfenceTileW = "habitat containment wall" , cdesc = "The black sky outside sucks light through the oriel and airlock glass in the walls and floor of this outermost level. Each minute, the dusky melancholic light of the distant Sun attempts for a few seconds to squeeze in but is repelled by artificial lighting. The mucky floor looks misleadingly straight, its curvature noticeable only across the whole extent of the hull section. Overflowing water treatment basins and series of hanging and stacked tanks double as radiation shields. Hoses writhe on the ground and dangle in thick knots from the ceiling. This deck is the main pressurized cargo bay and storage, with the only other docking hub for small craft somewhere among the giant spaceship's upper levels. You recognize an inner airlock door smeared with guano, but you can't see the shuttle you left engaged to the airlock clamps outside. " -- E and W sides are borders with other level sections, so no oriels. } bridge = rogue { csymbol = 'B' , cname = "Captain's bridge" , cfreq = [("caveBridge", 1)] , cXminSize = 30 , cYminSize = 30 , ccellSize = DiceXY (2 `d` 4 + 5) (1 `d` 2 + 5) , cminPlaceSize = DiceXY (2 `d` 2 + 3) (1 `d` 2 + 4) -- sometimes merge all , cmaxPlaceSize = DiceXY 16 20 , cminStairDist = 10 , cdarkOdds = 0 -- all rooms lit, for a gentle start , cauxConnects = 2 -- few rooms, so many corridors , cextraStairs = 1 , cactorCoeff = 300 -- it's quite deep already, so spawn slowly; -- initially best for sleeping, then all catch up , cactorFreq = [("animal", 100)] , citemNum = 8 `d` 3 -- lure them in with loot , citemFreq = filter ((`notElem` ["treasure", "curious item"]) . fst) $ citemFreq rogue , cdefTile = "fillerWall" , cfenceTileN = "habitat containment wall" -- cave isolated for safety , cfenceTileE = "habitat containment wall" , cfenceTileS = "habitat containment wall" , cfenceTileW = "habitat containment wall" , cstairFreq = [ ("welded walled lift", 50) , ("welded open lift", 50) , ("welded tiny lift", 1) ] , cstairAllowed = [ ("welded walled staircase", 50) , ("welded open staircase", 50) , ("welded tiny staircase", 1) ] , cdesc = "The bridge is gutted out and nonoperational. There are animal cries down below and ominous silence up above." } shallowRogue = rogue { cfreq = [("caveShallowRogue", 100)] , cXminSize = 60 , cYminSize = 37 , cextraStairs = 2 , cactorCoeff = 40 -- more difficult , cactorFreq = filter ((/= "monster") . fst) $ cactorFreq rogue , citemNum = 8 `d` 4 , citemFreq = ("starting weapon", 20) : filter ((/= "treasure") . fst) (citemFreq rogue) , cdesc = "This close to the outermost deck, residence is not permitted and walls and doors are sturdier, to contain a theoretically possible micro-meteorite breach. The entry is not closed off, though, because some passengers can't live without a regular pilgrimage to 'look outside'. Apparently, gazing at the sharp pin-points of stars and planets through the reinforced oriel glass is incomparable to watching the same through the thin polymer of wall displays. Animals appear to share the fascination of outer decks, perhaps attracted by the increased gravity, nearly Earth-like, unlike elsewhere on the ship." } -- * "Caves" on various celestial bodies (including, but not limited to, moons, -- with virtually no story-wise limits wrt height and size raid = rogue { csymbol = 'S' , cname = "Triton City sewers" , cfreq = [("caveRaid", 1)] , cXminSize = 50 , cYminSize = 21 , ccellSize = DiceXY (2 `d` 2 + 7) 6 , cminPlaceSize = DiceXY (2 `d` 2 + 4) 5 -- sometimes merge all , cmaxPlaceSize = DiceXY 16 20 , cdarkOdds = 0 -- all rooms lit, for a gentle start , cmaxVoid = 1%10 , cdefTile = "fillerWall" , cextraStairs = 0 , cactorCoeff = 250 -- deep level with no kit, so slow spawning , cactorFreq = [("animal", 50), ("robot", 50)] , citemNum = 6 `d` 6 -- just one level, hard enemies, treasure , citemFreq = [("common item", 100), ("currency", 500)] , cescapeFreq = [("escape up", 1)] , cstairFreq = [] , cstairAllowed = [] , cdesc = "Mold spreads across the walls and scuttling sounds can be heard in the distance." } brawl = rogue -- many random solid tiles, to break LOS, since it's a day -- and this scenario is not focused on ranged combat; -- also, sanctuaries against missiles in shadow under trees { csymbol = 'S' , cname = "Woodland biosphere" , cfreq = [("caveBrawl", 1)] , cXminSize = 60 , cYminSize = 30 , ccellSize = DiceXY (2 `d` 5 + 5) 7 , cminPlaceSize = DiceXY 3 3 -- rarely merge vertically , cmaxPlaceSize = DiceXY 7 5 , cdarkOdds = 51 , cnightOdds = 0 , cdoorChance = 1 , copenChance = 0 , cextraStairs = 0 , chidden = 0 , cactorFreq = [] , citemNum = 5 `d` 6 , citemFreq = [("common item", 100)] , cplaceFreq = [("brawl", 1)] , cpassable = True , cdefTile = "brawlSetLit" , cdarkCorTile = "dirt Lit" , clitCorTile = "dirt Lit" , cwallTile = "openableWall" , cstairFreq = [] , cstairAllowed = [] , cdesc = "Shadows pool under the trees and leaves crunch underfoot." } shootout = rogue -- a scenario with strong missiles; -- few solid tiles, but only translucent tiles or walkable -- opaque tiles, to make scouting and sniping more interesting -- and to avoid obstructing view too much, since this -- scenario is about ranged combat at long range { csymbol = 'S' , cname = "Hydroponic farm" -- still a neutral, official wording , cfreq = [("caveShootout", 1)] , ccellSize = DiceXY (1 `d` 2 + 5) 6 , cminPlaceSize = DiceXY 3 3 -- rarely merge vertically , cmaxPlaceSize = DiceXY 5 5 , cdarkOdds = 51 , cnightOdds = 0 , cauxConnects = 1%10 , cdoorChance = 1 , copenChance = 0 , cextraStairs = 0 , chidden = 0 , cactorFreq = [] , citemNum = 5 `d` 16 -- less items in inventory, more to be picked up, -- to reward explorer and aggressor and punish camper , citemFreq = [ ("common item", 30) , ("any arrow", 400), ("harpoon", 300), ("explosive", 50) ] -- Many consumable buffs are needed in symmetric maps -- so that aggressor prepares them in advance and camper -- needs to waste initial turns to buff for the defence. , cplaceFreq = [("shootout", 1)] , cpassable = True , cdefTile = "shootoutSetLit" , cdarkCorTile = "dirt Lit" , clitCorTile = "dirt Lit" , cwallTile = "openableWall" , cstairFreq = [] , cstairAllowed = [] , cdesc = "Once so carefully curated, the planting beds are now overgrown and choked with weeds." -- when we know what fits the plot, suggest it here; e.g., there are better way to earn money, shortage of manpower, dangerous area of the city, mismanagement by the city council } hunt = rogue -- a scenario with strong missiles for ranged and shade for melee { csymbol = 'H' , cname = "Swamp biosphere" , cfreq = [("caveHunt", 1)] , ccellSize = DiceXY (1 `d` 2 + 5) 6 , cminPlaceSize = DiceXY 3 3 -- rarely merge vertically , cmaxPlaceSize = DiceXY 5 5 , cdarkOdds = 51 , cnightOdds = 0 , cauxConnects = 1%10 , cdoorChance = 1 , copenChance = 0 , cextraStairs = 0 , chidden = 0 , cactorFreq = [] , citemNum = 5 `d` 10 , citemFreq = [ ("common item", 30) , ("any arrow", 400), ("harpoon", 300), ("explosive", 50) ] , cplaceFreq = [("brawl", 50), ("shootout", 100)] , cpassable = True , cdefTile = "huntSetLit" -- much more water than in shootoutSetLit , cdarkCorTile = "dirt Lit" , clitCorTile = "dirt Lit" , cwallTile = "openableWall" , cstairFreq = [] , cstairAllowed = [] , cdesc = "Mangrove trees and murky water, inspired by a habitat now eradicated from Earth." } escape = rogue -- a scenario with weak missiles, because heroes don't depend -- on them; dark, so solid obstacles are to hide from missiles, -- not view; obstacles are not lit, to frustrate the AI; -- lots of small lights to cross, to have some risks { csymbol = 'E' , cname = "Red Collar Bros den" -- tension rises; non-official name , cfreq = [("caveEscape", 1)] , ccellSize = DiceXY (1 `d` 3 + 6) 7 , cminPlaceSize = DiceXY 5 4 -- rarely merge , cmaxPlaceSize = DiceXY 9 9 -- bias towards larger lamp areas , cdarkOdds = 0 , cnightOdds = 51 -- always night , cauxConnects = 2 -- many lit trails, so easy to aim , cmaxVoid = 1%100 , cextraStairs = 0 , chidden = 0 , cactorFreq = [] , citemNum = 6 `d` 8 , citemFreq = [ ("common item", 30), ("gem", 150) , ("weak arrow", 500), ("harpoon", 400) , ("explosive", 100) ] , cplaceFreq = [("escape", 1)] , cpassable = True , cdefTile = "escapeSetDark" , cdarkCorTile = "safeTrailLit" -- let trails give off light , clitCorTile = "safeTrailLit" , cwallTile = "openableWall" , cescapeFreq = [("escape outdoor down", 1)] , cstairFreq = [] , cstairAllowed = [] , cdesc = "Graffiti scrawls across the walls and the heavy scents of stimulants hang in the air." } zoo = rogue -- few lights and many solids, to help the less numerous heroes { csymbol = 'Z' , cname = "Municipal zoo in flames" -- non-official adjective , cfreq = [("caveZoo", 1)] , ccellSize = DiceXY (1 `d` 4 + 7) 8 , cminPlaceSize = DiceXY 4 4 -- don't merge , cmaxPlaceSize = DiceXY 14 7 , cdarkOdds = 0 , cnightOdds = 51 -- always night , cauxConnects = 1%4 , cmaxVoid = 1%20 , cdoorChance = 7%10 , copenChance = 9%10 , cextraStairs = 0 , chidden = 0 , cactorFreq = [] , citemNum = 7 `d` 8 , citemFreq = [ ("common item", 100), ("light source", 1000) , ("starting weapon", 1000) ] , cplaceFreq = [("zoo", 1)] , cpassable = True , cdefTile = "zooSetDark" , cdarkCorTile = "safeTrailLit" -- let trails give off light , clitCorTile = "safeTrailLit" , cwallTile = "openableWall" , cstairFreq = [] , cstairAllowed = [] , cdesc = "Leaping flames illuminate the cages; not all are empty." } ambush = rogue -- a scenario with strong missiles; -- dark, so solid obstacles are to hide from missiles, -- not view, and they are all lit, because stopped missiles -- are frustrating, while a few LOS-only obstacles are not lit; -- few small lights to cross, giving a chance to snipe; -- crucial difference wrt shootout and hunt is that trajectories -- of missiles are usually not seen, so enemy can't be guessed; -- camping doesn't pay off, because enemies can sneak and only -- active scouting, throwing flares and shooting discovers them -- and the level is big enough for all that { csymbol = 'M' , cname = "Ravaged spaceport" -- non-official adjective , cfreq = [("caveAmbush", 1)] , ccellSize = DiceXY 11 6 , cminPlaceSize = DiceXY 9 10 -- merge vertically , cmaxPlaceSize = DiceXY 40 30 -- allow hangars and shuttles , cdarkOdds = 0 , cnightOdds = 51 -- always night , cauxConnects = 1%10 -- few lit trails, so hard to aim , cextraStairs = 0 , chidden = 0 , cactorFreq = [] , citemNum = 5 `d` 8 , citemFreq = [ ("common item", 30) , ("any arrow", 400), ("harpoon", 300), ("explosive", 50) ] , cplaceFreq = [("ambush", 1)] , cpassable = True , cdefTile = "ambushSetDark" , cdarkCorTile = "trailLit" -- let trails give off light , clitCorTile = "trailLit" , cwallTile = "openableWall" , cstairFreq = [] , cstairAllowed = [] , cdesc = "Scarred walls and ransacked lockers show the total breakdown of order." -- seems related to the abandoned farm; perhaps distantly to the existence of the gangs; more closely to the mystery of the lost and found space cruiser and various parties interested in it } -- * Other caves; testing, Easter egg, future work battle = rogue -- few lights and many solids, to help the less numerous heroes { csymbol = 'B' , cname = "Old industrial plant" , cfreq = [("caveBattle", 1)] , ccellSize = DiceXY (5 `d` 3 + 11) 7 , cminPlaceSize = DiceXY 4 4 , cmaxPlaceSize = DiceXY 9 7 , cdarkOdds = 0 , cnightOdds = 51 -- always night , cauxConnects = 1%4 , cmaxVoid = 1%20 , cdoorChance = 2%10 , copenChance = 9%10 , cextraStairs = 0 , chidden = 0 , cactorFreq = [] , citemNum = 5 `d` 8 , citemFreq = [("common item", 100), ("light source", 200)] , cplaceFreq = [("battle", 50), ("rogue", 50)] , cpassable = True , cdefTile = "battleSetDark" , cdarkCorTile = "safeTrailLit" -- let trails give off light , clitCorTile = "safeTrailLit" , cwallTile = "openableWall" , cfenceApart = True -- ensures no cut-off parts from collapsed , cstairFreq = [] , cstairAllowed = [] , cdesc = "Huge machines stand silent and powerless in the dark." } safari1 = brawl { cname = "Hunam habitat" , cfreq = [("caveSafari1", 1)] , cminPlaceSize = DiceXY 5 3 , cextraStairs = 1 , cstairFreq = [ ("outdoor walled staircase", 20) , ("outdoor closed staircase", 80) , ("outdoor tiny staircase", 1) ] , cstairAllowed = [] , cdesc = "\"DLC 1. Hunams scavenge in a forest in their usual disgusting way.\"" } safari2 = escape -- lamps instead of trees, but ok, it's only a simulation { cname = "Deep into the jungle" , cfreq = [("caveSafari2", 1)] , cextraStairs = 1 , cescapeFreq = [] , cstairFreq = [ ("outdoor walled staircase", 20) , ("outdoor closed staircase", 80) , ("outdoor tiny staircase", 1) ] , cstairAllowed = [] , cdesc = "\"DLC 2. In the dark pure heart of the jungle noble animals roam freely.\"" } safari3 = zoo -- glass rooms, but ok, it's only a simulation { cname = "Jungle in flames" , cfreq = [("caveSafari3", 1)] , cminPlaceSize = DiceXY 5 4 , cescapeFreq = [("escape outdoor down", 1)] , cextraStairs = 1 , cstairFreq = [ ("outdoor walled staircase", 20) , ("outdoor closed staircase", 80) , ("outdoor tiny staircase", 1) ] , cstairAllowed = [] , cdesc = "\"DLC 3. Jealous hunams set jungle on fire and flee.\"" } Allure-0.9.5.0/GameDefinition/Content/ItemKind.hs0000644000000000000000000024304507346545000017644 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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 definitions. module Content.ItemKind ( content, items, otherItemContent ) where import Prelude () import Game.LambdaHack.Core.Prelude import Content.ItemKindActor import Content.ItemKindBlast import Content.ItemKindEmbed import Content.ItemKindOrgan import Content.ItemKindTemporary import Content.RuleKind import Game.LambdaHack.Content.ItemKind import Game.LambdaHack.Content.RuleKind import Game.LambdaHack.Core.Dice import Game.LambdaHack.Definition.Ability import Game.LambdaHack.Definition.Color import Game.LambdaHack.Definition.Defs import Game.LambdaHack.Definition.Flavour content :: [ItemKind] content = items ++ otherItemContent otherItemContent :: [ItemKind] otherItemContent = embeds ++ actors ++ organs ++ blasts ++ temporaries items :: [ItemKind] items = [sandstoneRock, dart, spike, spike2, slingStone, slingBullet, paralizingProj, harpoon, harpoon2, net, light1, light2, light3, blanket, flaskTemplate, flask1, flask2, flask3, flask4, flask5, flask6, flask7, flask8, flask9, flask10, flask11, flask12, flask13, flask14, flask15, flask16, flask17, potionTemplate, potion1, potion2, potion3, potion4, potion5, potion6, potion7, potion8, potion9, potion10, potion11, potion12, fragmentationBomb, concussionBomb, flashBomb, firecrackerBomb, ediblePlantTemplate, ediblePlant1, ediblePlant2, ediblePlant3, ediblePlant4, ediblePlant5, ediblePlant6, ediblePlant7, scrollTemplate, scroll1, scroll2, scroll3, scroll4, scroll5, scroll6, scroll7, scroll8, scroll9, scroll10, scroll11, scroll12, scroll13, jumpingPole, sharpeningTool, seeingItem, motionScanner, gorget, necklaceTemplate, necklace1, necklace3, necklace4, necklace5, necklace6, necklace7, necklace8, necklace9, necklace10, imageItensifier, sightSharpening, ringTemplate, ring1, ring2, ring3, ring4, ring5, ring6, ring7, ring8, armorLeather, armorLeather2, armorMail, gloveFencing, gloveGauntlet, gloveJousting, hatUshanka, capReinforced, helmArmored, buckler, shield, shield2, shield3, dagger, daggerDropBestWeapon, hammerTemplate, hammer1, hammer2, hammer3, hammerParalyze, hammerSpark, sword, swordImpress, swordNullify, halberd, halberd2, halberdPushActor, wandTemplate, wand1, gemTemplate, gem1, gem2, gem3, gem4, gem5, currencyTemplate, currency] -- Allure-specific ++ [needle, needleSleep, constructionHooter, wasteContainer, spotlight, scrollAd1, blowtorch] sandstoneRock, dart, spike, spike2, slingStone, slingBullet, paralizingProj, harpoon, harpoon2, net, light1, light2, light3, blanket, flaskTemplate, flask1, flask2, flask3, flask4, flask5, flask6, flask7, flask8, flask9, flask10, flask11, flask12, flask13, flask14, flask15, flask16, flask17, potionTemplate, potion1, potion2, potion3, potion4, potion5, potion6, potion7, potion8, potion9, potion10, potion11, potion12, fragmentationBomb, concussionBomb, flashBomb, firecrackerBomb, ediblePlantTemplate, ediblePlant1, ediblePlant2, ediblePlant3, ediblePlant4, ediblePlant5, ediblePlant6, ediblePlant7, scrollTemplate, scroll1, scroll2, scroll3, scroll4, scroll5, scroll6, scroll7, scroll8, scroll9, scroll10, scroll11, scroll12, scroll13, jumpingPole, sharpeningTool, seeingItem, motionScanner, gorget, necklaceTemplate, necklace1, necklace3, necklace4, necklace5, necklace6, necklace7, necklace8, necklace9, necklace10, imageItensifier, sightSharpening, ringTemplate, ring1, ring2, ring3, ring4, ring5, ring6, ring7, ring8, armorLeather, armorLeather2, armorMail, gloveFencing, gloveGauntlet, gloveJousting, hatUshanka, capReinforced, helmArmored, buckler, shield, shield2, shield3, dagger, daggerDropBestWeapon, hammerTemplate, hammer1, hammer2, hammer3, hammerParalyze, hammerSpark, sword, swordImpress, swordNullify, halberd, halberd2, halberdPushActor, wandTemplate, wand1, gemTemplate, gem1, gem2, gem3, gem4, gem5, currencyTemplate, currency :: ItemKind -- Allure-specific needle, needleSleep, constructionHooter, wasteContainer, spotlight, scrollAd1, blowtorch :: ItemKind -- Keep the dice rolls and sides in aspects small so that not too many -- distinct items are generated (for display in item lore and for narrative -- impact ("oh, I found the more powerful of the two variants of the item!", -- instead of "hmm, I found one of the countless variants, a decent one"). -- In particular, for unique items, unless they inherit aspects from -- a standard item, permit only a couple possible variants. -- This is especially important if an item kind has multiple random aspects. -- Instead multiply dice results, e.g., (1 `d` 3) * 5 instead of 1 `d` 15. -- -- Beware of non-periodic non-weapon durable items with beneficial effects -- and low timeout -- AI will starve applying such an item incessantly. -- * Item group symbols, from Angband and variants symbolProjectile, _symbolLauncher, symbolLight, symbolTool, symbolSpecial, symbolGold, symbolNecklace, symbolRing, symbolPotion, symbolFlask, symbolScroll, symbolTorsoArmor, symbolMiscArmor, _symbolClothes, symbolShield, symbolPolearm, symbolEdged, symbolHafted, symbolWand, _symbolStaff, symbolFood :: Char symbolProjectile = rsymbolProjectile standardRules -- '{' _symbolLauncher = '}' symbolLight = '(' symbolTool = ')' symbolSpecial = '*' -- don't overuse, because it clashes with projectiles symbolGold = '$' -- also gems symbolNecklace = '"' symbolRing = '=' symbolPotion = '!' -- concoction, bottle, jar, vial, canister symbolFlask = '!' symbolScroll = '?' -- book, note, tablet, remote, chip, card symbolTorsoArmor = '[' symbolMiscArmor = '[' _symbolClothes = '[' symbolShield = ']' symbolPolearm = '/' symbolEdged = '|' symbolHafted = '\\' symbolWand = '-' -- magical rod, transmitter, pistol, rifle, instrument _symbolStaff = '_' -- scanner symbolFood = ',' -- also body part; distinct from floor: not middle dot -- * Generic items, for any epoch (some may be removed for Allure) -- ** Thrown weapons sandstoneRock = ItemKind { isymbol = symbolProjectile , iname = "ceramic foam splinter" , ifreq = [ ("sandstone rock", 1) , ("unreported inventory", 1) ] -- too weak to spam , iflavour = zipPlain [Green] , icount = 1 + 1 `d` 2 -- > 1, to let AI ignore sole pieces , irarity = [(1, 50), (10, 1)] , iverbHit = "swat" , iweight = 300 , idamage = 1 `d` 1 , iaspects = [ AddSkill SkHurtMelee $ -16 * 5 , SetFlag Fragile , toVelocity 70 ] -- not dense, irregular , ieffects = [] , idesc = "A light, irregular lump of ceramic foam used in construction." , ikit = [] } dart = ItemKind { isymbol = symbolProjectile , iname = "billiard ball" , ifreq = [("common item", 100), ("any arrow", 50), ("weak arrow", 50)] , iflavour = zipPlain [White] , icount = 1 + 4 `dL` 5 , irarity = [(1, 15), (10, 5)] , iverbHit = "strike" , iweight = 170 , idamage = 1 `d` 1 , iaspects = [AddSkill SkHurtMelee $ (-15 + 1 `d` 2 + 1 `dL` 3) * 5] -- only good against leather , ieffects = [] , idesc = "Ideal shape, size and weight for throwing." , ikit = [] } spike = ItemKind { isymbol = symbolProjectile , iname = "steak knife" , ifreq = [("common item", 100), ("any arrow", 50), ("weak arrow", 50)] , iflavour = zipPlain [Cyan] , icount = 1 + 4 `dL` 5 , irarity = [(1, 10), (10, 10)] , iverbHit = "nick" , iweight = 100 , idamage = 2 `d` 1 , iaspects = [ AddSkill SkHurtMelee $ (-10 + 1 `d` 2 + 1 `dL` 3) * 5 -- heavy vs armor , SetFlag MinorEffects , toVelocity 70 ] -- hitting with tip costs speed , ieffects = [ Explode "single spark" -- when hitting enemy , OnSmash (Explode "single spark") ] -- at wall hit -- this results in a wordy item synopsis, but it's OK, the spark really -- is useful in some situations, not just a flavour , idesc = "Not particularly well balanced, but with a laser-sharpened titanium alloy tip and blade." , ikit = [] } spike2 = spike { iname = "heavy steak knife" , ifreq = [("common item", 2), ("any arrow", 1), ("weak arrow", 1)] , icount = 6 `dL` 5 , iverbHit = "penetrate" , iweight = 150 , idamage = 4 `d` 1 , iaspects = [ AddSkill SkHurtMelee $ (-10 + 1 `d` 2 + 1 `dL` 3) * 5 , SetFlag MinorEffects , Odds (10 * 1 `dL` 10) [] [toVelocity 70] ] -- at deep levels sometimes even don't limit velocity , idesc = "Old, slightly discoloured, probably from a genuine steel. A heavy and surprisingly well balanced prop from a posh restaurant." -- the theme of pre-modern things being more solid and intimidating } slingStone = ItemKind { isymbol = symbolProjectile , iname = "steel hex nut" , ifreq = [("common item", 5), ("any arrow", 100)] , iflavour = zipPlain [Blue] , icount = 1 + 3 `dL` 4 , irarity = [(1, 1), (10, 20)] , iverbHit = "clobber" , iweight = 200 , idamage = 1 `d` 1 , iaspects = [ AddSkill SkHurtMelee $ (-10 + 1 `d` 2 + 1 `dL` 3) * 5 -- heavy, to bludgeon through armor , SetFlag MinorEffects , toVelocity 150 ] , ieffects = [ Explode "single spark" -- when hitting enemy , OnSmash (Explode "single spark") ] -- at wall hit , idesc = "A large hexagonal fastening nut; due to its angular shape, securely lodging in the pouch of a makeshift string and cloth sling." , ikit = [] } slingBullet = ItemKind { isymbol = symbolProjectile , iname = "bearing ball" , ifreq = [("common item", 5), ("any arrow", 100)] , iflavour = zipPlain [BrBlack] , icount = 1 + 6 `dL` 4 , irarity = [(1, 1), (10, 15)] , iverbHit = "slug" , iweight = 28 , idamage = 1 `d` 1 , iaspects = [ AddSkill SkHurtMelee $ (-17 + 1 `d` 2 + 1 `dL` 3) * 5 -- not too good against armor , ToThrow $ ThrowMod 200 100 2 ] -- piercing , ieffects = [] , idesc = "Small but heavy bearing ball. Thanks to its size and shape, it doesn't snag when released from the makeshift sling's pouch. Minimal friction enable it to pierce through flesh when fast enough initially." -- we lie, it doesn't slow down in our model; but it stops piercing alright , ikit = [] } -- ** Exotic thrown weapons -- Identified, because shape (and name) says it all. Detailed aspects id by use. -- This is an extremely large value for @Paralyze@. Normally for such values -- we should instead use condition that disables (almost) all stats, -- except @SkWait@, so that the player can switch leader and not be -- helpless nor experience instadeath (unless his party is 1-person -- or the actor is isolated, but that's usually player's fault). paralizingProj = ItemKind { isymbol = symbolProjectile , iname = "can" , ifreq = [("common item", 100), ("can of sticky foam", 1)] , iflavour = zipPlain [Magenta] , icount = 1 `dL` 4 , irarity = [(5, 5), (10, 20)] , iverbHit = "glue" , iweight = 1000 , idamage = 1 `d` 1 , iaspects = [ ELabel "of sticky foam" , AddSkill SkHurtMelee $ -14 * 5 , SetFlag Lobable, SetFlag Fragile , toVelocity 70 ] -- unwieldy , ieffects = [Paralyze 15, OnSmash (Explode "glue") ] , idesc = "A can of liquid, fast-setting construction foam." , ikit = [] } harpoon = ItemKind { isymbol = symbolProjectile , iname = "harpoon" , ifreq = [("curious item", 100), ("harpoon", 100), ("museum", 100)] , iflavour = zipPlain [Brown] , icount = 1 `dL` 5 , irarity = [(7, 5), (10, 5)] , iverbHit = "hook" , iweight = 750 , idamage = 5 `d` 1 , iaspects = [AddSkill SkHurtMelee $ (-10 + 1 `d` 2 + 1 `dL` 3) * 5] , ieffects = [ PullActor (ThrowMod 200 50 1) -- 1 step, fast , Yell ] -- yell, because brutal , idesc = "A display piece harking back to the Earth's oceanic tourism heyday. The cruel, barbed head lodges in its victim so painfully that the weakest tug of the thin line sends the victim flying." , ikit = [] } harpoon2 = harpoon { iname = "heavy harpoon" , ifreq = [("curious item", 5), ("harpoon", 2)] , icount = 2 `dL` 5 , iweight = 1000 , idamage = 10 `d` 1 , idesc = "A sharpened cargo-hook with high-tension cord." -- could use some explanation of why it breaks when thrown, especially that's it's not apparent } net = ItemKind { isymbol = symbolProjectile , iname = "net" , ifreq = [("common item", 100)] , iflavour = zipPlain [BrGreen] , icount = 1 `dL` 3 , irarity = [(5, 5), (10, 7)] , iverbHit = "entangle" , iweight = 1000 , idamage = 2 `d` 1 , iaspects = [AddSkill SkHurtMelee $ -14 * 5] , ieffects = [ toOrganBad "slowed" (3 + 1 `d` 3) , DropItem maxBound 1 CEqp "torso armor" -- only one of each kind is dropped, because no rubbish -- in this group and so no risk of exploit , SendFlying (ThrowMod 100 50 1) ] -- 1 step; painful , idesc = "A large synthetic fibre net with weights affixed along the edges. Entangles armor and restricts movement." , ikit = [] } -- ** Lights light1 = ItemKind { isymbol = symbolLight , iname = "torch" , ifreq = [ ("common item", 100), ("light source", 100) , ("wooden torch", 1) ] , iflavour = zipPlain [Brown] , icount = 1 `dL` 4 , irarity = [(1, 30), (4, 1)] , iverbHit = "scorch" , iweight = 1000 , idamage = 0 , iaspects = [ AddSkill SkShine 3, AddSkill SkSight (-2) -- not only flashes, but also sparks, -- so unused by AI due to the mixed blessing , SetFlag Lobable, SetFlag Equipable , EqpSlot EqpSlotShine ] -- not Fragile; reusable flare , ieffects = [Burn 1] , idesc = "A puttering torch improvised with polymer sheets soaked in lubricant on a stick." , ikit = [] } light2 = ItemKind { isymbol = symbolLight , iname = "oil lamp" , ifreq = [("common item", 100), ("light source", 100)] , iflavour = zipPlain [BrYellow] , icount = 1 `dL` 2 , irarity = [(6, 10)] , iverbHit = "burn" , iweight = 1500 , idamage = 1 `d` 1 , iaspects = [ AddSkill SkShine 3, AddSkill SkSight (-1) , SetFlag Lobable, SetFlag Fragile, SetFlag Equipable , EqpSlot EqpSlotShine ] , ieffects = [ Burn 1 , toOrganBad "pacified" (2 + 1 `d` 2) , OnSmash (Explode "burning oil 2") ] , idesc = "A restaurant table glass lamp filled with plant oil feeding a slender wick." , ikit = [] } light3 = ItemKind { isymbol = symbolLight , iname = "brass lantern" , ifreq = [("common item", 100), ("museum", 100), ("light source", 20)] , iflavour = zipPlain [Red] , icount = 1 , irarity = [(6, 1), (10, 4)] , iverbHit = "burn" , iweight = 3000 , idamage = 2 `d` 1 , iaspects = [ AddSkill SkShine 4, AddSkill SkSight (-1) , SetFlag Lobable, SetFlag Fragile, SetFlag Equipable , EqpSlot EqpSlotShine ] , ieffects = [ Burn 1 , toOrganBad "pacified" (4 + 1 `d` 2) , OnSmash (Explode "burning oil 4") ] , idesc = "Very old, very bright and very heavy lantern made of hand-polished brass." , ikit = [] } blanket = ItemKind { isymbol = symbolLight , iname = "mineral fibre blanket" , ifreq = [("common item", 100), ("light source", 100), ("blanket", 1)] , iflavour = zipPlain [BrBlack] , icount = 1 , irarity = [(1, 1)] -- not every playthrough needs one , iverbHit = "swoosh" , iweight = 1000 , idamage = 0 , iaspects = [ AddSkill SkShine (-10) , AddSkill SkArmorMelee 2, AddSkill SkMaxCalm 5 , SetFlag Lobable, SetFlag Equipable ] -- not Fragile; reusable douse implement; -- douses torch, lamp and lantern in one action, -- both in equipment and when thrown at the floor , ieffects = [] , idesc = "Flame-retardant synthetic fibres." , ikit = [] } -- ** Exploding consumables, often intended to be thrown. -- Not identified, because they are perfect for the id-by-use fun, -- due to effects. They are fragile and upon hitting the ground explode -- for effects roughly corresponding to their normal effects. -- Whether to hit with them or explode them close to the target -- is intended to be an interesting tactical decision. -- -- Flasks are often not natural; maths, magic, distillery. -- In fact, they just cover all conditions, except those for stats. -- -- There is no flask nor condition of Calm depletion, -- because Calm reduced often via combat, etc. flaskTemplate = ItemKind { isymbol = symbolFlask , iname = "flask" , ifreq = [("flask unknown", 1)] , iflavour = zipGlassPlain darkCol ++ zipGlassFancy darkCol ++ zipLiquid darkCol -- ++ zipPlain darkCol ++ zipFancy darkCol , icount = 1 `dL` 3 , irarity = [(1, 7), (10, 3)] , iverbHit = "splash" , iweight = 500 , idamage = 0 , iaspects = [ HideAs "flask unknown", SetFlag Lobable, SetFlag Fragile , toVelocity 50 ] -- oily, bad grip , ieffects = [] , idesc = "A flask of oily liquid of a suspect color. Something seems to be moving inside. Double dose causes twice longer effect." , ikit = [] } flask1 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , icount = 1 `dL` 5 , irarity = [(10, 10)] , iaspects = ELabel "of strength renewal brew" : iaspects flaskTemplate , ieffects = [ toOrganGood "strengthened" (20 + 1 `d` 5) , toOrganNoTimer "regenerating" , OnSmash (Explode "dense shower") ] } flask2 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , iaspects = ELabel "of weakness brew" : iaspects flaskTemplate , ieffects = [ toOrganBad "weakened" (20 + 1 `d` 5) , OnSmash (Explode "sparse shower") ] } flask3 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , iaspects = ELabel "of melee protective balm" : iaspects flaskTemplate , ieffects = [ toOrganGood "protected from melee" (20 + 1 `d` 5) , OnSmash (Explode "melee protective balm") ] } flask4 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , iaspects = ELabel "of ranged protective balm" : iaspects flaskTemplate , ieffects = [ toOrganGood "protected from ranged" (20 + 1 `d` 5) , OnSmash (Explode "ranged protective balm") ] } flask5 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , iaspects = ELabel "of fluorescent paint" : iaspects flaskTemplate , ieffects = [ toOrganBad "painted" (20 + 1 `d` 5) , OnSmash (Explode "fluorescent paint") ] } flask6 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , irarity = [(1, 1)] -- not every playthrough needs one , iaspects = ELabel "of resolution" : iaspects flaskTemplate , ieffects = [ toOrganGood "resolute" (500 + 1 `d` 200) -- long, for scouting , RefillCalm 60 -- not to make it a drawback, via @calmEnough@ , OnSmash (Explode "resolution dust") ] } flask7 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , icount = 1 -- too powerful en masse , iaspects = ELabel "of haste brew" : iaspects flaskTemplate , ieffects = [ toOrganGood "hasted" (20 + 1 `d` 5) , OnSmash (Explode "haste spray") ] } flask8 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , iaspects = ELabel "of eye drops" : iaspects flaskTemplate , ieffects = [ toOrganGood "far-sighted" (40 + 1 `d` 10) , OnSmash (Explode "eye drop") ] } flask9 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , irarity = [(10, 2)] -- not very useful right now , iaspects = ELabel "of smelly concoction" : iaspects flaskTemplate , ieffects = [ toOrganGood "keen-smelling" (40 + 1 `d` 10) , Detect DetectActor 10 -- make it at least slightly useful , OnSmash (Explode "smelly droplet") ] } flask10 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , irarity = [(10, 2)] -- not very useful right now , iaspects = ELabel "of cat tears" : iaspects flaskTemplate , ieffects = [ toOrganGood "shiny-eyed" (40 + 1 `d` 10) , OnSmash (Explode "eye shine") ] } flask11 = flaskTemplate { iname = "bottle" , ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , icount = 1 `d` 3 -- the only one sometimes giving away its identity , iaspects = ELabel "of whiskey" : iaspects flaskTemplate , ieffects = [ toOrganGood "drunk" (20 + 1 `d` 5) , Burn 1, RefillHP 3, Yell , OnSmash (Explode "whiskey spray") ] } flask12 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , icount = 1 , iaspects = ELabel "of bait cocktail" : iaspects flaskTemplate , ieffects = [ toOrganGood "drunk" (20 + 1 `d` 5) , Burn 1, RefillHP 3 -- risky exploit possible, good , Summon "mobile animal" 1 , OnSmash (Summon "mobile animal" 1) , OnSmash Impress -- mildly useful when thrown , OnSmash (Explode "waste") ] } -- The player has full control over throwing the flask at his party, -- so he can milk the explosion, so it has to be much weaker, so a weak -- healing effect is enough. OTOH, throwing a harmful flask at many enemies -- at once is not easy to arrange, so these explosions can stay powerful. flask13 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , irarity = [(1, 2), (10, 12)] , iaspects = ELabel "of regeneration brew" : iaspects flaskTemplate , ieffects = [ toOrganGood "rose-smelling" (80 + 1 `d` 20) , toOrganNoTimer "regenerating" , toOrganNoTimer "regenerating" -- x2 , OnSmash (Explode "youth sprinkle") ] } flask14 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , iaspects = ELabel "of poison" : iaspects flaskTemplate , ieffects = [ toOrganNoTimer "poisoned", toOrganNoTimer "poisoned" -- x2 , OnSmash (Explode "poison cloud") ] } flask15 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , irarity = [(10, 4)] , iaspects = ELabel "of slow resistance" : iaspects flaskTemplate , ieffects = [ toOrganNoTimer "slow resistant" , OnSmash (Explode "anti-slow mist") ] } flask16 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , irarity = [(10, 4)] , iaspects = ELabel "of poison resistance" : iaspects flaskTemplate , ieffects = [ toOrganNoTimer "poison resistant" , OnSmash (Explode "antidote mist") ] } flask17 = flaskTemplate { ifreq = [("common item", 100), ("explosive", 100), ("any vial", 100)] , iaspects = ELabel "of calamity" : iaspects flaskTemplate , ieffects = [ toOrganNoTimer "poisoned" , toOrganBad "weakened" (20 + 1 `d` 5) , toOrganBad "painted" (20 + 1 `d` 5) , OnSmash (Explode "glass hail") ] -- enough glass to cause that } -- Potions are often natural, including natural stats. -- They appear deeper than most flasks. Various configurations of effects. -- A different class of effects is on scrolls and mechanical items. -- Some are shared. potionTemplate = ItemKind { isymbol = symbolPotion , iname = "vial" , ifreq = [("potion unknown", 1)] , iflavour = zipLiquid brightCol ++ zipPlain brightCol ++ zipFancy brightCol , icount = 1 `dL` 3 , irarity = [(1, 10), (10, 6)] , iverbHit = "splash" , iweight = 200 , idamage = 0 , iaspects = [ HideAs "potion unknown", SetFlag Lobable, SetFlag Fragile , toVelocity 50 ] -- oily, bad grip , ieffects = [] , idesc = "A vial of bright, frothing concoction. The best that nature has to offer." , ikit = [] } potion1 = potionTemplate { ifreq = [("common item", 100), ("potion", 100), ("any vial", 100)] , icount = 3 `dL` 1 -- very useful, despite appearances , iaspects = ELabel "of rose water" : iaspects potionTemplate , ieffects = [ Impress, toOrganGood "rose-smelling" (80 + 1 `d` 20) , OnSmash ApplyPerfume, OnSmash (Explode "fragrance") ] } potion2 = potionTemplate { ifreq = [("curious item", 100), ("any vial", 100)] , icount = 1 , irarity = [(5, 8), (10, 8)] , iaspects = [ SetFlag Unique, ELabel "of Attraction" , SetFlag Precious, SetFlag Lobable, SetFlag Fragile , toVelocity 50 ] -- identified , ieffects = [ Dominate , toOrganGood "hasted" (20 + 1 `d` 5) , OnSmash (Explode "pheromone") , OnSmash (Explode "haste spray") ] , idesc = "The liquid fizzes with energy." } potion3 = potionTemplate { ifreq = [("common item", 100), ("potion", 100), ("any vial", 100)] , ieffects = [ RefillHP 5, DropItem 1 maxBound COrgan "poisoned" , OnSmash (Explode "healing mist") ] } potion4 = potionTemplate { ifreq = [("common item", 100), ("potion", 100), ("any vial", 100)] , irarity = [(1, 6), (10, 10)] , ieffects = [ RefillHP 10, DropItem maxBound maxBound COrgan "condition" , OnSmash (Explode "healing mist 2") ] } potion5 = potionTemplate -- needs to be common to show at least a portion of effects { ifreq = [("common item", 100), ("potion", 100), ("any vial", 100)] , icount = 3 `dL` 1 -- always as many as possible on this level -- without giving away potion identity , irarity = [(1, 12)] , ieffects = [ OneOf [ RefillHP 10, RefillHP 5, Burn 5 , DropItem 1 maxBound COrgan "poisoned" , toOrganGood "strengthened" (20 + 1 `d` 5) ] , OnSmash (OneOf [ Explode "dense shower" , Explode "sparse shower" , Explode "melee protective balm" , Explode "ranged protective balm" , Explode "fluorescent paint" ]) ] } potion6 = potionTemplate -- needs to be common to show at least a portion of effects { ifreq = [("common item", 100), ("potion", 100), ("any vial", 100)] , icount = 3 `dL` 1 , irarity = [(10, 10)] , ieffects = [ Impress , OneOf [ RefillHP 20, RefillHP 10, Burn 10 , DropItem 1 maxBound COrgan "poisoned" , toOrganGood "hasted" (20 + 1 `d` 5) , toOrganBad "impatient" (2 + 1 `d` 2) ] , OnSmash (OneOf [ Explode "healing mist 2" , Explode "wounding mist" , Explode "distressing odor" , Explode "impatient mist" , Explode "haste spray" , Explode "slowness mist" , Explode "fragrance" , Explode "violent flash" ]) ] } potion7 = potionTemplate { iname = "ampoule" -- filled with semi-stabilized high explosive liquid , ifreq = [("common item", 100), ("potion", 100), ("any vial", 100)] , icount = 3 `dL` 1 , ieffects = [ DropItem 1 maxBound COrgan "condition" , OnSmash (Explode "violent concussion") ] -- not fragmentation nor glass hail, because not enough glass } potion8 = potionTemplate { ifreq = [("curious item", 100), ("any vial", 100)] , icount = 1 , irarity = [(10, 5)] , iaspects = [ SetFlag Unique, ELabel "of Love" , SetFlag Precious, SetFlag Lobable, SetFlag Fragile , toVelocity 50 ] -- identified , ieffects = [ RefillHP 60, RefillCalm (-60) , toOrganGood "rose-smelling" (80 + 1 `d` 20) , OnSmash (Explode "healing mist 2") , OnSmash (Explode "distressing odor") ] , idesc = "Perplexing swirls of intense, compelling colour." } potion9 = potionTemplate { ifreq = [("common item", 100), ("potion", 100), ("any vial", 100)] , irarity = [(10, 5)] , iaspects = ELabel "of grenadier focus" : iaspects potionTemplate , ieffects = [ toOrganGood "more projecting" (40 + 1 `d` 10) , toOrganBad "pacified" (5 + 1 `d` 3) -- the malus has to be weak, or would be too good -- when thrown at foes , OnSmash (Explode "more projecting dew") , OnSmash (Explode "pacified mist") ] , idesc = "Thick, sluggish fluid with violently-bursting bubbles." } potion10 = potionTemplate { ifreq = [("common item", 100), ("potion", 100), ("any vial", 100)] , irarity = [(10, 8)] , iaspects = ELabel "of frenzy" : iaspects potionTemplate , ieffects = [ Yell , toOrganGood "strengthened" (20 + 1 `d` 5) , toOrganBad "retaining" (5 + 1 `d` 3) , toOrganBad "frenzied" (40 + 1 `d` 10) , OnSmash (Explode "dense shower") , OnSmash (Explode "retaining mist") , OnSmash (Explode "retaining mist") ] } potion11 = potionTemplate { ifreq = [("common item", 100), ("potion", 100), ("any vial", 100)] , irarity = [(10, 8)] , iaspects = ELabel "of panic" : iaspects potionTemplate , ieffects = [ RefillCalm (-30) , toOrganGood "hasted" (20 + 1 `d` 5) , toOrganBad "weakened" (20 + 1 `d` 5) , toOrganBad "withholding" (10 + 1 `d` 5) , OnSmash (Explode "haste spray") , OnSmash (Explode "sparse shower") , OnSmash (Explode "withholding mist") ] } potion12 = potionTemplate { ifreq = [("common item", 100), ("potion", 100), ("any vial", 100)] , irarity = [(10, 8)] , iaspects = ELabel "of quicksilver" : iaspects potionTemplate , ieffects = [ toOrganGood "hasted" (20 + 1 `d` 5) , toOrganBad "blind" (10 + 1 `d` 5) , toOrganBad "immobile" (5 + 1 `d` 5) , OnSmash (Explode "haste spray") , OnSmash (Explode "iron filing") , OnSmash (Explode "immobile mist") ] } -- ** Explosives, with the only effect being @Explode@ fragmentationBomb = ItemKind { isymbol = symbolProjectile , iname = "hand bomb" -- improvised bomb filled with iron pellets, nuts, cut nails; -- deflagration, not detonation, so large mass and hard container -- required not to burn harmlessly; improvised short fuze; -- can't be more powerful or would fracture the spaceship's hull , ifreq = [("common item", 100), ("explosive", 200)] , iflavour = zipPlain [Red] , icount = 1 `dL` 5 -- many, because not very intricate , irarity = [(5, 8), (10, 5)] , iverbHit = "thud" , iweight = 3000 -- low velocity due to weight , idamage = 1 `d` 1 -- heavy and hard , iaspects = [SetFlag Lobable, SetFlag Fragile] , ieffects = [ Explode "focused fragmentation" , OnSmash (Explode "violent fragmentation") ] , idesc = "Shards of brittle metal packed around an explosive core." , ikit = [] } concussionBomb = fragmentationBomb { iname = "canister" -- slightly stabilized liquid explosive in a soft container, hence -- no fragmentation, but huge shock wave despite small size and lack -- of strong container to build up pressure; indoors help the shock wave; -- unstable enough that no fuze required (or simple electric fuse?); -- that's the most potent explosive (a detonating one) to be found -- and only in small quantities, due to depressurization hazard , iflavour = zipPlain [Magenta] , iverbHit = "bonk" , iweight = 400 , idamage = 0 , iaspects = [ SetFlag Lobable, SetFlag Fragile , toVelocity 70 ] -- flappy and so slow , ieffects = [ Explode "focused concussion" , OnSmash (Explode "violent concussion") ] , idesc = "Avoid sudden movements." } -- Not flashbang, because powerful bang without fragmentation is harder -- to manufacture (requires an oxidizer and steel canister with holes). -- The bang would also paralyze and/or lower the movement skill -- (out of balance due to ear trauma). flashBomb = fragmentationBomb { iname = "powder tube" -- filled with magnesium flash powder , iflavour = zipPlain [BrYellow] -- avoid @BrWhite@; looks wrong in dark , iverbHit = "flash" , iweight = 400 , idamage = 0 , iaspects = [ SetFlag Lobable, SetFlag Fragile , toVelocity 70 ] -- bad shape for throwing , ieffects = [Explode "focused flash", OnSmash (Explode "violent flash")] , idesc = "For dramatic entrances and urgent exits." } firecrackerBomb = fragmentationBomb { iname = "roll" -- not fireworks, as they require outdoors , iflavour = zipPlain [BrMagenta] , irarity = [(1, 5), (5, 6)] -- a toy, if deadly , iverbHit = "crack" -- a pun, matches the verb from "ItemKindBlast" , iweight = 1000 , idamage = 0 , iaspects = [SetFlag Lobable, SetFlag Fragile] , ieffects = [Explode "firecracker", OnSmash (Explode "firecracker")] , idesc = "String and paper, concealing a deadly surprise." } -- ** Non-exploding consumables, not specifically designed for throwing -- Foods require only minimal apply skill to consume. Many animals can eat them. ediblePlantTemplate = ItemKind { isymbol = symbolFood , iname = "edible plant" , ifreq = [("edible plant unknown", 1)] , iflavour = zipPlain stdCol , icount = 1 `dL` 5 , irarity = [(1, 12), (10, 6)] -- let's feed the animals , iverbHit = "thump" , iweight = 50 , idamage = 0 , iaspects = [ HideAs "edible plant unknown" , toVelocity 30 ] -- low density, often falling apart , ieffects = [] , idesc = "Withered but fragrant bits of a colorful plant. Taste tolerably and break down easily, but only eating may reveal the full effects." , ikit = [] } ediblePlant1 = ediblePlantTemplate { iname = "enhanced berry" , ifreq = [("common item", 100), ("edible plant", 100)] , ieffects = [RefillHP 1, toOrganBad "immobile" (5 + 1 `d` 5)] } ediblePlant2 = ediblePlantTemplate { iname = "frayed fungus" , ifreq = [("common item", 100), ("edible plant", 100)] , ieffects = [toOrganNoTimer "poisoned"] } ediblePlant3 = ediblePlantTemplate { iname = "thick leaf" , ifreq = [("common item", 100), ("edible plant", 100)] , ieffects = [DropItem 1 maxBound COrgan "poisoned"] } ediblePlant4 = ediblePlantTemplate { iname = "reconfigured fruit" , ifreq = [("common item", 100), ("edible plant", 100)] , ieffects = [toOrganBad "blind" (10 + 1 `d` 10)] } ediblePlant5 = ediblePlantTemplate { iname = "fragrant herb" , ifreq = [("common item", 100), ("edible plant", 100)] , icount = 1 `dL` 9 , irarity = [(1, 12), (10, 5)] , iaspects = ELabel "of lethargy" : iaspects ediblePlantTemplate , ieffects = [ toOrganBad "slowed" (20 + 1 `d` 5) , toOrganNoTimer "regenerating" , toOrganNoTimer "regenerating" -- x2 , RefillCalm 5 ] } ediblePlant6 = ediblePlantTemplate { iname = "dull flower" , ifreq = [("common item", 100), ("edible plant", 100)] , ieffects = [PutToSleep] } ediblePlant7 = ediblePlantTemplate { iname = "spicy bark" , ifreq = [("common item", 100), ("edible plant", 100)] , ieffects = [InsertMove 20, toOrganBad "frenzied" (40 + 1 `d` 10)] } -- These require high apply skill to consume. scrollTemplate = ItemKind { isymbol = symbolScroll , iname = "chip" , ifreq = [("scroll unknown", 1)] , iflavour = zipFancy stdCol ++ zipPlain stdCol , icount = 1 `dL` 3 , irarity = [(1, 14), (10, 7)] , iverbHit = "thump" , iweight = 20 , idamage = 0 , iaspects = [ HideAs "scroll unknown" , toVelocity 30 ] -- too small , ieffects = [] , idesc = "A generic, disposable chip, capable of a one-time holo-display. Some of these also contain a one-time password authorizing a particular spaceship's infrastructure transition. Nobody knows how the infrastructure might respond after so many years." , ikit = [] } scroll1 = scrollTemplate { ifreq = [("curious item", 100), ("any scroll", 100)] , icount = 1 , irarity = [(5, 9), (10, 9)] -- mixed blessing, so found early for a unique , iaspects = [SetFlag Unique, ELabel "of Reckless Beacon"] ++ iaspects scrollTemplate , ieffects = [Summon "hero" 1, Summon "mobile animal" (2 + 1 `d` 2)] , idesc = "This industrial, wide-spectrum alarm broadcaster, if over-amped for a single powerful blast, should be able to cut through the interference and reach any lost crew members, giving them enough positional information to locate us." } scroll2 = scrollTemplate { ifreq = [("curious item", 100), ("any scroll", 100)] , irarity = [(1, 6), (10, 2)] , ieffects = [Ascend True] } scroll3 = scrollTemplate -- needs to be common to show at least a portion of effects { ifreq = [("common item", 100), ("any scroll", 100)] , icount = 3 `dL` 1 , irarity = [(1, 14)] , ieffects = [OneOf [ Teleport 5, Paralyze 10, InsertMove 30 , Detect DetectEmbed 12, Detect DetectHidden 20 ]] } scroll4 = scrollTemplate -- needs to be common to show at least a portion of effects { ifreq = [("common item", 100), ("any scroll", 100)] , icount = 3 `dL` 1 , irarity = [(10, 14)] , ieffects = [ Impress , OneOf [ Teleport 20, Ascend False, Ascend True , Summon "hero" 1, Summon "mobile animal" $ 1 `d` 2 , Detect DetectLoot 20 -- the most useful of detections , CreateItem CGround "common item" timerNone ] ] } scroll5 = scrollTemplate { ifreq = [("common item", 100), ("any scroll", 100)] , irarity = [(1, 6)] -- powerful, but low counts at the depths it appears on , ieffects = [InsertMove $ 20 + 1 `dL` 20] } scroll6 = scrollTemplate { ifreq = [("common item", 100), ("any scroll", 100)] , icount = 3 `dL` 1 , irarity = [(1, 20)] -- uncommon deep down, where all is known , iaspects = ELabel "of scientific explanation" : iaspects scrollTemplate , ieffects = [Composite [Identify, RefillCalm 10]] , idesc = "The most pressing existential concerns are met with a deeply satisfying scientific answer." } scroll7 = scrollTemplate { ifreq = [("common item", 100), ("any scroll", 100)] , irarity = [(10, 20)] -- at endgame a crucial item may be missing , iaspects = ELabel "of molecular reconfiguration" : iaspects scrollTemplate , ieffects = [Composite [PolyItem, Explode "firecracker"]] } scroll8 = scrollTemplate { ifreq = [("curious item", 100), ("any scroll", 100)] , icount = 1 , irarity = [(10, 12)] , iaspects = [SetFlag Unique, ELabel "of Skeleton Key"] ++ iaspects scrollTemplate , ieffects = [Summon "hero" 1] , idesc = "This is a security lock chip that opens all doors in the area, including the hatch to a nearby closet, bulging from the blows of one of our lost crew members." } scroll9 = scrollTemplate { ifreq = [("common item", 100), ("any scroll", 100)] , irarity = [(10, 4)] -- powerful, even if not ideal; scares newbies , ieffects = [Detect DetectAll 20] } scroll10 = scrollTemplate { ifreq = [("common item", 100), ("any scroll", 100)] , iaspects = ELabel "of cue interpretation" : iaspects scrollTemplate , ieffects = [Detect DetectActor 20] } scroll11 = scrollTemplate { ifreq = [("common item", 100), ("any scroll", 100)] , irarity = [(10, 11)] , ieffects = [PushActor (ThrowMod 400 200 1)] -- 8 steps, 4 turns } scroll12 = scrollTemplate { ifreq = [("common item", 100), ("any scroll", 100)] , irarity = [(10, 15)] , iaspects = ELabel "of molecular duplication" : iaspects scrollTemplate , ieffects = [DupItem] } scroll13 = scrollTemplate { ifreq = [("common item", 100), ("any scroll", 100)] , irarity = [(10, 15)] , iaspects = ELabel "of surface reconfiguration" : iaspects scrollTemplate , ieffects = [RerollItem] } -- ** Assorted tools jumpingPole = ItemKind { isymbol = symbolWand , iname = "jumping pole" , ifreq = [("common item", 100)] , iflavour = zipPlain [White] , icount = 1 , irarity = [(1, 3)] , iverbHit = "prod" , iweight = 10000 , idamage = 0 , iaspects = [ Timeout $ (2 + 1 `d` 2 - 1 `dL` 2) * 5 , SetFlag Durable ] , ieffects = [toOrganGood "hasted" 1] -- safe for AI, because it speeds up, so when AI applies it -- again and again, it gets its time back and is not stuck; -- in total, the explorations speed is unchanged, -- but it's useful when fleeing in the dark to make distance -- and when initiating combat, so it's OK that AI uses it , idesc = "Makes you vulnerable at take-off, but then you are free like a bird." , ikit = [] } sharpeningTool = ItemKind { isymbol = symbolTool , iname = "honing steel" , ifreq = [("common item", 100)] , iflavour = zipPlain [Blue] , icount = 1 , irarity = [(10, 10)] , iverbHit = "smack" , iweight = 400 , idamage = 0 , iaspects = [ AddSkill SkHurtMelee $ (1 `dL` 7) * 5 , SetFlag Equipable, EqpSlot EqpSlotHurtMelee ] , ieffects = [] , idesc = "Originally used for realigning and sharpening dulled edges of kitchen knives in the local restaurants. Now it saves lives by keeping your melee weapons keen and true before each skirmish." , ikit = [] } seeingItem = ItemKind { isymbol = symbolFood , iname = "visual sensor" , ifreq = [("common item", 100)] , iflavour = zipPlain [Red] , icount = 1 , irarity = [(1, 2)] , iverbHit = "gaze at" , iweight = 500 , idamage = 0 , iaspects = [ Timeout 3 , AddSkill SkSight 10 -- a spyglass for quick wields , AddSkill SkMaxCalm 30 -- to diminish clipping sight by Calm , AddSkill SkShine 2 -- to lit corridors when flying , SetFlag Periodic ] , ieffects = [ Detect DetectActor 20 -- rare enough , Explode "single spark" , toOrganNoTimer "poisoned" -- really can't be worn , Summon "mobile robot" 1 ] , idesc = "An oversize visual sensor freshly torn out of some unfortunate robot. It still sends a clear picture to unidentified receivers, even though the coolant liquid seeps from the seized servos and many internal contacts spark loose." , ikit = [] } motionScanner = ItemKind { isymbol = symbolTool , iname = "handheld sonar" , ifreq = [("common item", 100), ("add nocto 1", 20)] , iflavour = zipPlain [Green] , icount = 1 , irarity = [(5, 2)] , iverbHit = "ping" , iweight = 1000 , idamage = 0 , iaspects = [ AddSkill SkNocto 1 , AddSkill SkArmorMelee (-15 + (1 `dL` 3) * 5) , AddSkill SkArmorRanged (-15 + (1 `dL` 3) * 5) , SetFlag Equipable, EqpSlot EqpSlotMiscBonus ] , ieffects = [] , idesc = "Portable underwater echolocator overdriven to scan dark corridors at the cost of emitting loud pings." , ikit = [] } -- ** Periodic jewelry -- Morally these are the aspects, but we also need to add a fake @Timeout@, -- to let clients know that the not identified item is periodic jewelry. iaspects_necklaceTemplate :: [Aspect] iaspects_necklaceTemplate = [ HideAs "necklace unknown" , SetFlag Periodic, SetFlag Precious, SetFlag Equipable , toVelocity 50 ] -- not dense enough gorget = necklaceTemplate { iname = "Old Gorget" , ifreq = [("common item", 25), ("treasure", 25), ("museum", 100)] , iflavour = zipFancy [BrCyan] -- looks exactly the same as one of necklaces, -- but it's OK, it's an artifact , iaspects = [ SetFlag Unique , Timeout $ 5 - 1 `dL` 4 , AddSkill SkArmorMelee 3, AddSkill SkArmorRanged 2 , SetFlag Durable ] ++ iaspects_necklaceTemplate , ieffects = [RefillCalm 1] , 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 the wearer." } -- Not identified, because id by use, e.g., via periodic activations. Fun. necklaceTemplate = ItemKind { isymbol = symbolNecklace , iname = "necklace" , ifreq = [("necklace unknown", 1)] , iflavour = zipFancy stdCol ++ zipPlain brightCol , icount = 1 , irarity = [(4, 3), (10, 4)] , iverbHit = "whip" , iweight = 30 , idamage = 0 , iaspects = Timeout 1000000 -- fake, needed to display "charging"; the timeout itself -- won't be displayed thanks to periodic; as a side-effect, -- it can't be activated until identified, which is better -- than letting the player try to activate before the real -- cooldown is over and waste turn : iaspects_necklaceTemplate , ieffects = [] , idesc = "Tingling, rattling chain of flat encrusted links. Eccentric millionaires are known to hide their highly personalized body augmentation packs in bulky jewelry pieces such as these." , ikit = [] } necklace1 = necklaceTemplate { ifreq = [("curious item", 100), ("any jewelry", 100)] , irarity = [(3 * 10/15, 0), (4 * 10/15, 1), (10, 3)] -- prevents camping on lvl 3 , iaspects = [ SetFlag Unique, ELabel "of Spur Life" , Timeout $ (4 - 1 `dL` 3) * 10 -- priceless, so worth the long wait , SetFlag Durable ] ++ iaspects_necklaceTemplate , ieffects = [RefillHP 1, RefillCalm (-5)] , idesc = "This awkward chain, when worn on bare skin, frequently emits mild but highly annoying electric shocks, which apparently stimulate tissue regeneration even in distant parts of the body. A part of the surprising effectiveness of this unique artifact may stem from the desperation of the patients to be quickly healed enough to take it off." } -- no necklace2 of Live Bait, wasteContainer too similar necklace3 = necklaceTemplate { ifreq = [("common item", 100), ("any jewelry", 100)] , iaspects = [ ELabel "of fearful listening" , Timeout ((1 + 1 `d` 2) * 10) , AddSkill SkHearing 2 ] ++ iaspects_necklaceTemplate , ieffects = [ Detect DetectActor 10 -- can be applied; destroys the item , RefillCalm (-40) ] } necklace4 = necklaceTemplate { ifreq = [("common item", 100), ("any jewelry", 100)] , iaspects = Timeout ((3 + 1 `d` 3 - 1 `dL` 3) * 2) : iaspects_necklaceTemplate , ieffects = [Teleport $ 3 `d` 2] } necklace5 = necklaceTemplate { ifreq = [("common item", 100), ("any jewelry", 100)] , iaspects = [ ELabel "of escape" , Timeout $ (7 - 1 `dL` 5) * 10 ] ++ iaspects_necklaceTemplate , ieffects = [ Teleport $ 14 + 3 `d` 3 -- can be applied; destroys the item , Detect DetectExit 20 , Yell ] -- drawback when used for quick exploring , idesc = "A supple chain that slips through your fingers." } necklace6 = necklaceTemplate { ifreq = [("common item", 100), ("any jewelry", 100)] , iaspects = Timeout (1 + (1 `d` 3) * 2) : iaspects_necklaceTemplate , ieffects = [PushActor (ThrowMod 100 50 1)] -- 1 step, slow -- the @50@ is only for the case of very light actor, etc. } necklace7 = necklaceTemplate { ifreq = [("curious item", 100), ("any jewelry", 100)] , irarity = [(10, 1)] -- powerful and determines tactics for one actor , iaspects = [ SetFlag Unique, ELabel "of Overdrive" , Timeout 10 , AddSkill SkMaxHP 10 -- good effects vanish when taken off , AddSkill SkSpeed 10 , SetFlag Durable ] ++ iaspects_necklaceTemplate , ieffects = [ RefillCalm (-2) -- don't spam , toOrganBad "pacified" 10] -- The same duration as timeout, to avoid spurious messages -- as well as unlimited accumulation of the duration. -- Timeout lessens temptation to frequently wear and take off, -- to engage in melee, which would lead to micromanagement. , idesc = "This whirring augmentation pack stimulates its host beyond any medically advisable or, surely, even legally admissible levels. It can be only speculated what kind of activity it was designed for, but clearly the steady handling of melee weapons was not one of them." } necklace8 = necklaceTemplate { ifreq = [("common item", 100), ("any jewelry", 100)] , irarity = [(4, 3)] -- entirely optional , iaspects = Timeout ((1 + 1 `d` 3) * 5) : iaspects_necklaceTemplate , ieffects = [Explode "spark"] } necklace9 = necklaceTemplate { ifreq = [("common item", 100), ("any jewelry", 100)] , iaspects = Timeout ((1 + 1 `d` 3) * 5) : iaspects_necklaceTemplate , ieffects = [Explode "fragrance"] } necklace10 = necklaceTemplate { ifreq = [("common item", 100), ("any jewelry", 100)] , iaspects = [ ELabel "of greed" , Timeout ((2 + 1 `d` 3) * 10) ] ++ iaspects_necklaceTemplate , ieffects = [ Detect DetectLoot 20 , Teleport 40 -- risky , toOrganBad "parsimonious" (5 + 1 `d` 3) ] -- hard to flee } -- ** Non-periodic jewelry imageItensifier = ItemKind { isymbol = symbolRing , iname = "noctovisor" , ifreq = [("treasure", 100), ("add nocto 1", 80), ("museum", 100)] , iflavour = zipFancy [BrGreen] , icount = 1 , irarity = [(5, 2)] , iverbHit = "rattle" , iweight = 700 , idamage = 0 , iaspects = [ AddSkill SkNocto 1, AddSkill SkSight (-1) , AddSkill SkArmorMelee $ (-1 + 1 `dL` 6) * 3 , SetFlag Precious, SetFlag Equipable , EqpSlot EqpSlotMiscBonus ] , ieffects = [] , idesc = "Sturdy antique night vision goggles of unknown origin. Wired to run on modern micro-cells." , ikit = [] } sightSharpening = ringTemplate -- small and round, so mistaken for a ring { iname = "Autozoom Contact Lens" , ifreq = [("treasure", 20), ("add sight", 1)] -- it's has to be very rare, because it's powerful and not unique, -- and also because it looks exactly as one of necklaces, so it would -- be misleading when seen on the map , irarity = [(7, 1), (10, 12)] -- low @ifreq@ , iweight = 50 -- heavier that it looks, due to glass , iaspects = [ AddSkill SkSight $ 1 + 1 `dL` 2 , AddSkill SkHurtMelee $ (-1 + 1 `d` 3) * 3 , EqpSlot EqpSlotSight ] ++ iaspects ringTemplate , idesc = "Zooms on any movement, distant or close. Requires some getting used to. Never needs to be taken off." } -- Don't add standard effects to rings, because they go in and out -- of eqp and so activating them would require UI tedium: looking for -- them in eqp and inv or even activating a wrong item by mistake. -- -- By general mechanisms, due to not having effects that could identify -- them by observing the effect, rings are identified on pickup. -- That's unlike necklaces, which provide the fun of id-by-use, because they -- have effects and when the effects are triggered, they get identified. ringTemplate = ItemKind { isymbol = symbolRing , iname = "ring" , ifreq = [("ring unknown", 1)] , iflavour = zipPlain stdCol ++ zipFancy darkCol , icount = 1 , irarity = [(10, 2)] -- the default very low , iverbHit = "knock" , iweight = 15 , idamage = 0 , iaspects = [HideAs "ring unknown", SetFlag Precious, SetFlag Equipable] , ieffects = [] , idesc = "A sturdy ring with a softly shining eye. If it contains a body booster unit, beware of the side-effects." , ikit = [] } ring1 = ringTemplate { ifreq = [("common item", 100), ("any jewelry", 100)] , irarity = [(8, 4)] , iaspects = [ AddSkill SkSpeed $ 1 `dL` 3, AddSkill SkMaxHP (-10) , EqpSlot EqpSlotSpeed ] ++ iaspects ringTemplate } ring2 = ringTemplate { ifreq = [("curious item", 100), ("any jewelry", 100)] , iaspects = [ SetFlag Unique, ELabel "of Rush" , AddSkill SkSpeed $ (1 + 1 `dL` 2) * 2 , AddSkill SkMaxCalm (-40), AddSkill SkMaxHP (-20) , SetFlag Durable, EqpSlot EqpSlotSpeed ] ++ iaspects ringTemplate , idesc = "There creator of this dangerous artifact didn't find time to document its operation. And now it's too late." } ring3 = ringTemplate { ifreq = [("common item", 100), ("any jewelry", 100)] , irarity = [(10, 8)] , iaspects = [ AddSkill SkMaxHP $ 5 + (1 `d` 2 + 1 `dL` 2) * 5 , AddSkill SkMaxCalm $ -30 + (1 `dL` 3) * 5 , EqpSlot EqpSlotMaxHP ] ++ iaspects ringTemplate } ring4 = ringTemplate { ifreq = [("common item", 100), ("any jewelry", 100), ("museum", 100)] , irarity = [(5, 1), (10, 9)] -- needed after other rings drop Calm , iaspects = [ AddSkill SkMaxCalm $ 20 + (1 `dL` 4) * 5 , EqpSlot EqpSlotMiscBonus ] ++ iaspects ringTemplate , idesc = "Cold, solid to the touch, perfectly round, engraved with solemn, strangely comforting, worn out words." } ring5 = ringTemplate { ifreq = [("common item", 100), ("any jewelry", 100)] , irarity = [(3, 4), (10, 8)] , iaspects = [ AddSkill SkHurtMelee $ (2 + 1 `d` 2 + (1 `dL` 2) * 2 ) * 3 , AddSkill SkMaxHP $ (-3 + 1 `dL` 3) * 10 , EqpSlot EqpSlotHurtMelee ] ++ iaspects ringTemplate } ring6 = ringTemplate -- weak skill per eqp slot, so can be without drawbacks { ifreq = [("common item", 100), ("any jewelry", 100), ("museum", 100)] , irarity = [(10, 3)] , iaspects = [ AddSkill SkShine 1 , EqpSlot EqpSlotShine ] ++ iaspects ringTemplate , idesc = "A sturdy ring with a large, shining stone." } ring7 = ringTemplate { ifreq = [("common item", 10), ("ring of opportunity sniper", 1)] , irarity = [(10, 5)] -- low @ifreq@ , iaspects = [ ELabel "of opportunity sniper" , AddSkill SkProject 8 , EqpSlot EqpSlotProject ] ++ iaspects ringTemplate } ring8 = ringTemplate { ifreq = [("treasure", 100), ("any jewelry", 100)] , iaspects = [ SetFlag Unique, ELabel "of Overwatch" , AddSkill SkProject 8 -- TODO: 11, but let player control -- potion throwing; see capReinforced , AddSkill SkMaxHP (-20) , SetFlag Durable, EqpSlot EqpSlotProject ] ++ iaspects ringTemplate , idesc = "This exceptional medical contraption constantly transforms and re-injects minuscule amounts of blood serum, synthesizing powerful drugs that greatly enhance spacial awareness and focus, at the cost of weakening bodily resilience and recovery." } -- ** Armor armorLeather = ItemKind { isymbol = symbolTorsoArmor , iname = "spacesuit breastplate" , ifreq = [("common item", 100), ("torso armor", 1)] , iflavour = zipPlain [Brown] , icount = 1 , irarity = [(1, 4), (10, 2)] , iverbHit = "thud" , iweight = 7000 , idamage = 0 , iaspects = [ AddSkill SkHurtMelee (-2) , AddSkill SkArmorMelee $ (2 + 1 `dL` 4) * 5 , AddSkill SkArmorRanged $ (1 + 1 `dL` 2) * 3 , SetFlag Durable, SetFlag Equipable , EqpSlot EqpSlotArmorMelee ] , ieffects = [] , idesc = "A hard-shell torso segment cut from a disposed off spacesuit. Well ventilated." , ikit = [] } armorLeather2 = armorLeather -- for now, purely flavour, for better messages { isymbol = symbolMiscArmor , iname = "pair" , ifreq = [("common item", 100)] , iaspects = ELabel "of spacesuit trousers" : iaspects armorLeather , idesc = "Segmented trousers for open space work, with the hermetically sealed boots cut off. Surprisingly flexible and airy, yet micro-meteorite-proof." } armorMail = armorLeather { iname = "bulletproof vest" , ifreq = [("common item", 100), ("torso armor", 1), ("armor ranged", 50)] , iflavour = zipPlain [Cyan] , irarity = [(6, 9), (10, 3)] , iweight = 12000 , idamage = 0 , iaspects = [ AddSkill SkHurtMelee (-3) , AddSkill SkArmorMelee $ (2 + 1 `dL` 4) * 5 , AddSkill SkArmorRanged $ (4 + 1 `dL` 2) * 3 , AddSkill SkOdor 2 , SetFlag Durable, SetFlag Equipable , EqpSlot EqpSlotArmorRanged ] , ieffects = [] , idesc = "A civilian bulletproof vest. Discourages foes from attacking your torso, making it harder for them to land a blow. Really hard to wash due to thickness." } gloveFencing = ItemKind { isymbol = symbolMiscArmor , iname = "construction glove" , ifreq = [("common item", 100), ("misc armor", 1), ("armor ranged", 50)] , iflavour = zipPlain [White] , icount = 1 , irarity = [(5, 9), (10, 9)] , iverbHit = "flap" , iweight = 100 , idamage = 1 `d` 1 , iaspects = [ AddSkill SkHurtMelee $ (2 + 1 `d` 2 + 1 `dL` 2) * 3 , AddSkill SkArmorRanged $ (1 `dL` 2) * 3 , SetFlag Durable, SetFlag Equipable , EqpSlot EqpSlotHurtMelee , toVelocity 50 ] -- flaps and flutters , ieffects = [] , 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" , ifreq = [("common item", 100), ("misc armor", 1)] , iflavour = zipPlain [BrCyan] , irarity = [(1, 9), (10, 3)] , iweight = 300 , idamage = 2 `d` 1 , iaspects = [ AddSkill SkArmorMelee $ (1 + 1 `dL` 4) * 5 , SetFlag Durable, SetFlag Equipable , EqpSlot EqpSlotArmorMelee , toVelocity 50 ] -- flaps and flutters , idesc = "A piece of a hull maintenance spacesuit, padded and reinforced with carbon fibre." } gloveJousting = gloveFencing { iname = "Welding Handgear" , ifreq = [("common item", 100), ("misc armor", 1)] , iflavour = zipFancy [BrRed] , irarity = [(1, 3), (10, 3)] , iverbHit = "rasp" , iweight = 3000 , idamage = 3 `d` 1 , iaspects = [ SetFlag Unique , AddSkill SkHurtMelee $ (-7 + 1 `dL` 5) * 3 , AddSkill SkArmorMelee $ (2 + 1 `d` 2 + 1 `dL` 2) * 5 , AddSkill SkArmorRanged $ (1 + 1 `dL` 2) * 3 -- very random on purpose and can even be good on occasion -- or when ItemRerolled enough times , SetFlag Durable, SetFlag Equipable , EqpSlot EqpSlotArmorMelee , toVelocity 50 ] -- flaps and flutters , idesc = "Rigid, bulky handgear embedding a welding equipment, complete with an affixed small shield and a darkened visor. Awe-inspiring." } hatUshanka = ItemKind { isymbol = symbolMiscArmor , iname = "ushanka hat" , ifreq = [("common item", 100), ("misc armor", 1)] , iflavour = zipPlain [Brown] , icount = 1 , irarity = [(1, 6), (10, 2)] , iverbHit = "tickle" , iweight = 500 , idamage = 0 , iaspects = [ Timeout $ (2 + 1 `d` 2) * 3 , AddSkill SkArmorMelee 5, AddSkill SkHearing (-10) , SetFlag Periodic, SetFlag Durable, SetFlag Equipable , EqpSlot EqpSlotArmorMelee , toVelocity 50 ] -- flaps and flutters , ieffects = [RefillCalm 1] , idesc = "Soft and warm fur. It keeps your ears warm." , ikit = [] } capReinforced = ItemKind { isymbol = symbolMiscArmor , iname = "construction cap" , ifreq = [("common item", 100), ("misc armor", 1)] , iflavour = zipPlain [BrYellow] , icount = 1 , irarity = [(6, 9), (10, 3)] , iverbHit = "cut" , iweight = 1000 , idamage = 0 , iaspects = [ AddSkill SkArmorMelee $ (1 `d` 2) * 5 , AddSkill SkProject 1 -- the brim shields against blinding by light sources, etc. , SetFlag Durable, SetFlag Equipable , EqpSlot EqpSlotProject ] , ieffects = [] , idesc = "A hard plastic shell that might soften a blow." , ikit = [] } helmArmored = ItemKind { isymbol = symbolMiscArmor , iname = "spacesuit helmet" , ifreq = [("common item", 100), ("misc armor", 1)] , iflavour = zipPlain [BrCyan] , icount = 1 , irarity = [(6, 9), (10, 3)] , iverbHit = "bounce" , iweight = 2000 , idamage = 0 , iaspects = [ AddSkill SkArmorMelee $ (1 + 1 `dL` 4) * 5 , AddSkill SkArmorRanged $ (2 + 1 `dL` 2) * 3 -- headshot , AddSkill SkHearing (-7), AddSkill SkSight (-1) , AddSkill SkSmell (-5) , SetFlag Durable, SetFlag Equipable , EqpSlot EqpSlotArmorRanged ] , ieffects = [] , idesc = "Blocks out everything, including your senses." , ikit = [] } -- ** Shields -- Shield doesn't protect against ranged attacks to prevent -- micromanagement: walking with shield, melee without. -- Note that AI will pick them up but never wear and will use them at most -- as a way to push itself (but they won't recharge, not being in eqp). -- Being @Meleeable@ they will not be use as weapons either. -- This is OK, using shields smartly is totally beyond AI. buckler = ItemKind { isymbol = symbolShield , iname = "buckler" , ifreq = [("common item", 100)] , iflavour = zipPlain [Blue] , icount = 1 , irarity = [(4, 5)] , iverbHit = "bash" , iweight = 2000 , idamage = 0 -- safe to be used on self , iaspects = [ Timeout $ (3 + 1 `d` 3 - 1 `dL` 3) * 2 , AddSkill SkArmorMelee 40 -- not enough to compensate; won't be in eqp , AddSkill SkHurtMelee (-30) -- too harmful; won't be wielded as weapon , SetFlag MinorEffects, SetFlag Durable, SetFlag Meleeable , EqpSlot EqpSlotArmorMelee , toVelocity 50 ] -- unwieldy to throw , ieffects = [PushActor (ThrowMod 200 50 1)] -- 1 step, fast , 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 = [(8, 4)] -- the stronger variants add to total probability , iflavour = zipPlain [Green] , iweight = 4000 , idamage = 4 `d` 1 , iaspects = [ Timeout $ (3 + 1 `d` 3 - 1 `dL` 3) * 4 , AddSkill SkArmorMelee 80 -- not enough to compensate; won't be in eqp , AddSkill SkHurtMelee (-70) -- too harmful; won't be wielded as weapon , SetFlag MinorEffects, SetFlag Durable, SetFlag Meleeable , EqpSlot EqpSlotArmorMelee , toVelocity 50 ] -- unwieldy to throw , ieffects = [PushActor (ThrowMod 400 50 1)] -- 2 steps, fast , 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." } shield2 = shield { ifreq = [("common item", 3 * 2), ("museum", 100)] -- very low base rarity , iweight = 5000 , idamage = 8 `d` 1 , idesc = "A relic of long-past wars, heavy and with a central spike." } shield3 = shield2 { ifreq = [("common item", 1 * 2), ("museum", 10)] -- very low base rarity , iweight = 6000 , idamage = 12 `d` 1 } -- ** Weapons dagger = ItemKind { isymbol = symbolEdged , iname = "cleaver" , ifreq = [("common item", 100), ("starting weapon", 200)] , iflavour = zipPlain [BrCyan] , icount = 1 , irarity = [(3 * 10/15, 35), (4 * 10/15, 1)] -- no weapons brought by aliens, initially, so cleaver common , iverbHit = "cut" , iweight = 1000 , idamage = 6 `d` 1 , iaspects = [ Timeout 2 , AddSkill SkHurtMelee $ (-1 + 1 `d` 2 + 1 `dL` 2) * 3 , AddSkill SkArmorMelee $ (1 `d` 2) * 5 -- very common, so don't make too random , SetFlag Durable, SetFlag Meleeable , EqpSlot EqpSlotWeaponFast , toVelocity 40 ] -- ensuring it hits with the tip costs speed , ieffects = [] , 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 quick to move and hard to block. Especially useful in conjunction with a larger weapon." , ikit = [] } daggerDropBestWeapon = dagger { iname = "Double Dagger" , ifreq = [("treasure", 20), ("museum", 100)] , irarity = [(1, 3), (10, 3)] , iaspects = [SetFlag Unique] ++ iaspects dagger , ieffects = [DropBestWeapon, Yell] -- powerful and low timeout, but makes -- noise and useless against stupid foes , idesc = "An antique double dagger that a focused fencer can use to catch and twist away an opponent's blade." } hammerTemplate = ItemKind { isymbol = symbolHafted , iname = "demolition hammer" , ifreq = [("hammer unknown", 1)] , iflavour = zipFancy [BrMagenta] -- avoid "pink" , icount = 1 , irarity = [(3 * 10/15, 1), (5 * 10/15, 20), (8 * 10/15, 1)] -- don't make it too common on lvl 3 , iverbHit = "club" , iweight = 1600 , idamage = 8 `d` 1 -- we are lying about the dice here, but the dungeon -- is too small and the extra-dice hammers too rare -- to subdivide this identification class by dice , iaspects = [ HideAs "hammer unknown" , SetFlag Durable, SetFlag Meleeable , toVelocity 40 ] -- ensuring it hits with the tip costs speed , ieffects = [] , idesc = "One of many kinds of hammers employed in construction work. The ones with completely blunt heads don't cause grave wounds, but any fitted with a long enough handle can shake and bruise even most armored foes. However, such large hammers require more time to recover after a swing. This one looks average at a quick glance." -- if it's really the average kind, the weak kind, the description stays; if not, it's replaced with one of the descriptions below at identification time , ikit = [] } hammer1 = hammerTemplate { ifreq = [("common item", 100), ("starting weapon", 70)] , iaspects = [Timeout 5, EqpSlot EqpSlotWeaponBig] ++ iaspects hammerTemplate } hammer2 = hammerTemplate { ifreq = [("common item", 20), ("starting weapon", 7)] , iverbHit = "gouge" , iaspects = [Timeout 3, EqpSlot EqpSlotWeaponFast] ++ iaspects hammerTemplate , idesc = "Upon closer inspection, this hammer turns out particularly handy and well balanced, with a narrowing, sharpened head compensating the modest size." } hammer3 = hammerTemplate { ifreq = [("common item", 3), ("starting weapon", 1)] , iverbHit = "puncture" , iweight = 2400 -- weight gives it away , idamage = 12 `d` 1 , iaspects = [ Timeout 12 -- balance, or @DupItem@ would break the game , EqpSlot EqpSlotWeaponBig] ++ delete (HideAs "hammer unknown") (iaspects hammerTemplate) , idesc = "This hammer sports a long metal handle that increases the momentum of the sharpened head's swing, at the cost of long recovery." } hammerParalyze = hammerTemplate { iname = "Concussion Hammer" , ifreq = [("treasure", 20)] , irarity = [(5, 1), (8, 6)] , iaspects = [ SetFlag Unique , Timeout 5 , EqpSlot EqpSlotWeaponBig ] ++ iaspects hammerTemplate , ieffects = [Paralyze 10] , idesc = "This exquisite demolition hammer with a titanium head and exceptionally long synthetic handle leaves no wall and no body standing." } hammerSpark = hammerTemplate { iname = "Grand Smithhammer" , ifreq = [("treasure", 20), ("museum", 100)] , irarity = [(5, 1), (8, 6)] , iweight = 2400 -- weight gives it away , idamage = 12 `d` 1 , iaspects = [ SetFlag Unique , Timeout 10 , EqpSlot EqpSlotWeaponBig , AddSkill SkShine 3] ++ delete (HideAs "hammer unknown") (iaspects hammerTemplate) , ieffects = [Explode "spark"] -- we can't use a focused explosion, because it would harm the hammer -- wielder as well, unlike this one , idesc = "High carbon steel of this heavy old hammer doesn't yield even to the newest alloys and produces fountains of sparks in defiance." } sword = ItemKind { isymbol = symbolPolearm , iname = "sharpened pipe" , ifreq = [("common item", 100), ("starting weapon", 30)] , iflavour = zipPlain [BrBlue] , icount = 1 , irarity = [(4, 1), (6, 15)] , iverbHit = "stab" , iweight = 2000 , idamage = 10 `d` 1 , iaspects = [ Timeout 7 , SetFlag Durable, SetFlag Meleeable , EqpSlot EqpSlotWeaponBig , toVelocity 40 ] -- ensuring it hits with the tip costs speed , ieffects = [] , idesc = "A makeshift weapon of simple design, but great potential. Hard to master, though." , ikit = [] } swordImpress = sword { isymbol = symbolEdged , iname = "Master's Sword" , ifreq = [("treasure", 20), ("museum", 100)] , irarity = [(5, 1), (8, 6)] , iverbHit = "slash" , iaspects = [SetFlag Unique] ++ iaspects sword , ieffects = [Impress] , idesc = "A particularly well-balance museum piece. It has a long history and in the right hands lends itself to impressive shows of fencing skill." } swordNullify = sword { isymbol = symbolEdged , iname = "Roasting Rapier" , ifreq = [("treasure", 20)] , iverbHit = "pierce" , irarity = [(5, 1), (8, 6)] , iaspects = [SetFlag Unique, Timeout 3, EqpSlot EqpSlotWeaponFast] ++ (iaspects sword \\ [Timeout 7, EqpSlot EqpSlotWeaponBig]) , ieffects = [ DropItem 1 maxBound COrgan "condition" , RefillCalm (-10) , Yell ] , idesc = "A thin, acutely sharp steel blade that pierces deeply and sends its victim into abrupt, sobering shock. Originally, an exuberant hand-forged roasting implement, intentionally and wisely kept blunt." } halberd = ItemKind { isymbol = symbolPolearm , iname = "pole cleaver" , ifreq = [("common item", 100), ("starting weapon", 20)] , iflavour = zipPlain [BrYellow] , icount = 1 , irarity = [(5, 0), (8, 15)] , iverbHit = "impale" , iweight = 3000 , idamage = 12 `d` 1 , iaspects = [ Timeout 10 , AddSkill SkHurtMelee $ (-5 + 1 `dL` 3) * 5 -- useless against armor at game start , AddSkill SkArmorMelee 20 , SetFlag Durable, SetFlag Meleeable , EqpSlot EqpSlotWeaponBig , toVelocity 20 ] -- not balanced , ieffects = [] , idesc = "An improvised but deadly weapon made of a long, sharp kitchen knife glued and bound to a long pole. Not often one succeeds in making enough space to swing it freely, but even when stuck between terrain obstacles it blocks approaches effectively and makes using other weapons difficult, both by friends and foes." , ikit = [] } halberd2 = halberd { iname = "pollaxe" , ifreq = [("common item", 3 * 3), ("starting weapon", 1)] , iverbHit = "carve" , iweight = 4000 , iaspects = [AddSkill SkHurtMelee $ (-6 + 1 `dL` 4) * 10] -- balance, or @DupItem@ would break the game; -- together with @RerollItem@, it's allowed to, though ++ (iaspects halberd \\ [AddSkill SkHurtMelee $ (-6 + 1 `dL` 4) * 5]) , idamage = 18 `d` 1 , idesc = "A long-hafted axe: once used for maintenance, now turned to a bloodier purpose." } halberdPushActor = halberd { iname = "Swiss Halberd" , ifreq = [("curious item", 20)] -- not museum; reenactors , irarity = [(7, 0), (9, 15)] , iaspects = [SetFlag Unique] ++ iaspects halberd , ieffects = [PushActor (ThrowMod 200 100 1)] -- 2 steps, slow , idesc = "A perfect replica made for a reenactor troupe, hardened, missing only some final sharpening. Versatile, with great reach and leverage. Foes are held at a distance." } -- ** Wands wandTemplate = ItemKind { isymbol = symbolWand , iname = "injector" , ifreq = [("wand unknown", 1)] , iflavour = zipFancy brightCol , icount = 1 , irarity = [] , iverbHit = "club" , iweight = 300 , idamage = 0 , iaspects = [ HideAs "wand unknown" , AddSkill SkShine 1, AddSkill SkSpeed (-1) -- pulsing with power, distracts , SetFlag Durable , toVelocity 125 ] -- sufficiently advanced tech , ieffects = [] , idesc = "Buzzing with dazzling light that shines even through appendages that handle it." , ikit = [] } wand1 = wandTemplate { ifreq = [] , ieffects = [] -- will be: emit a cone of sound shrapnel that makes enemy cover his ears and so drop '|' and '{' } -- ** Treasure gemTemplate = ItemKind { isymbol = symbolGold , iname = "gem" , ifreq = [("gem unknown", 1), ("valuable", 100)] , iflavour = zipPlain $ delete BrYellow brightCol -- natural, so not fancy , icount = 1 , irarity = [(3, 0), (10, 24)] , iverbHit = "tap" , iweight = 50 , idamage = 0 , iaspects = [HideAs "gem unknown", SetFlag Precious] , ieffects = [] , idesc = "Precious, though useless. Worth around 100 gold grains." , ikit = [] } gem1 = gemTemplate { ifreq = [ ("treasure", 100), ("gem", 100), ("any jewelry", 100) , ("valuable", 100) ] , irarity = [(3, 0), (6, 12), (10, 8)] , iaspects = [AddSkill SkShine 1, AddSkill SkSpeed (-1)] -- reflects strongly, distracts; so it glows in the dark, -- is visible on dark floor, but not too tempting to wear ++ iaspects gemTemplate } gem2 = gem1 { ifreq = [ ("treasure", 100), ("gem", 100), ("any jewelry", 100) , ("valuable", 100) ] , irarity = [(5, 0), (7, 25), (10, 8)] } gem3 = gem1 { ifreq = [ ("treasure", 100), ("gem", 100), ("any jewelry", 100) , ("valuable", 100) ] , irarity = [(7, 0), (8, 20), (10, 8)] } gem4 = gem1 { ifreq = [ ("treasure", 100), ("gem", 100), ("any jewelry", 100) , ("valuable", 100) ] , irarity = [(9, 0), (10, 70)] } gem5 = gem1 { isymbol = symbolSpecial , iname = "stimpack" , ifreq = [ ("treasure", 100), ("gem", 25), ("any jewelry", 10) , ("valuable", 100) ] , iflavour = zipPlain [BrYellow] , irarity = [(1, 40), (10, 10)] , iaspects = [ ELabel "of youth", SetFlag Precious -- not hidden , AddSkill SkOdor (-1) ] , ieffects = [RefillCalm 10, RefillHP 40] , idesc = "Calms, heals, invigorates, rejuvenates and smells nice. No side-effects. As valuable as precious gems, at 100 gold grains each." } currencyTemplate = ItemKind { isymbol = symbolGold , iname = "gold grain" , ifreq = [("currency unknown", 1), ("valuable", 1)] , iflavour = zipPlain [BrYellow] , icount = 10 + 1 `d` 20 + 1 `dL` 20 , irarity = [(1, 25), (10, 10)] , iverbHit = "tap" , iweight = 1 , idamage = 0 , iaspects = [HideAs "currency unknown", SetFlag Precious] , ieffects = [] , idesc = "Reliably valuable in every civilized place." , ikit = [] } currency = currencyTemplate { ifreq = [("treasure", 100), ("currency", 100), ("valuable", 1)] , iaspects = [AddSkill SkShine 1, AddSkill SkSpeed (-1)] ++ iaspects currencyTemplate } -- * Allure-specific items needle = ItemKind { isymbol = symbolProjectile , iname = "needle" , ifreq = [ ("needle", 1), ("common item", 1) -- marked as common to ensure can be polymorphed , ("unreported inventory", 1) ] -- too weak to spam , iflavour = zipPlain [Blue] , icount = 1 + 8 `d` 3 , irarity = [(1, 1)] , iverbHit = "prick" , iweight = 3 , idamage = 1 `d` 1 , iaspects = [ AddSkill SkHurtMelee $ -10 * 5 , SetFlag Fragile -- breaks easily despite being piercing , ToThrow $ ThrowMod 70 100 3 ] -- piercing; good shape , ieffects = [] , idesc = "A long sturdy hypodermic needle ending in a dried out micro-syringe that is easy to break off. It's too thin to cause great harm, but it passes through flesh easily." , ikit = [] } needleSleep = ItemKind { isymbol = symbolProjectile , iname = "tranquillizer dart" , ifreq = [ ("tranquillizer dart", 1), ("common item", 1) ] -- marked as common to ensure can be polymorphed , iflavour = zipPlain [BrBlue] , icount = 1 `dL` 3 , irarity = [(1, 1)] , iverbHit = "prick" , iweight = 10 , idamage = 1 `d` 1 , iaspects = [ AddSkill SkHurtMelee $ -10 * 5 , SetFlag Fragile , toVelocity 70 ] -- syringe blocks piercing; slender fins , ieffects = [PutToSleep] , idesc = "A long hypodermic needle ending in a micro-syringe with residues of the sleeping agent." , ikit = [] } constructionHooter = necklaceTemplate { iname = "construction hooter" , ifreq = [ ("construction hooter", 1), ("common item", 1) -- extremely rare, but dropped by decontamination chambers , ("unreported inventory", 1) ] , iflavour = zipPlain [BrRed] , irarity = [(1, 1)] , iweight = 1000 , iaspects = [ AddSkill SkArmorMelee 2 , SetFlag Durable, toVelocity 50 , SetFlag Equipable, EqpSlot EqpSlotArmorMelee] , ieffects = [Yell, Summon "construction robot" 1] , idesc = "An emergency hooter for alarming human personnel in case their life is in danger. Worn by construction robots around their \"neck\", where it's least exposed, but even there it needs to be heavily armored and running on its own power supply." } wasteContainer = ItemKind { isymbol = symbolTool , iname = "waste container" , ifreq = [("waste container", 1), ("unreported inventory", 1)] , iflavour = zipLiquid [Green] , icount = 1 , irarity = [(1, 1)] , iverbHit = "spill over" , iweight = 30000 , idamage = 0 , iaspects = [ Timeout $ (1 `d` 2) * 30 -- robots should not summon too often , AddSkill SkArmorMelee 20 -- tempting , SetFlag Periodic, SetFlag Equipable ] , ieffects = [ Detect DetectLoot 20 , Summon "mobile animal" $ 1 `dL` 2 , Explode "waste" ] -- very important effect that disables item movement -- and so makes wielding seeingItem a tiny bit risky, -- and so not a no-brainer , idesc = "Waste recognition and utilization subsystem. Detects any stray item not registered as passenger cargo. Leaks a little." , ikit = [] } spotlight = ItemKind { isymbol = symbolLight , iname = "spotlight" , ifreq = [("spotlight", 1), ("unreported inventory", 1)] , iflavour = zipPlain [White] , icount = 1 , irarity = [(1, 1)] , iverbHit = "illuminate" , iweight = 3000 , idamage = 0 , iaspects = [ AddSkill SkShine 4 , AddSkill SkHurtMelee (-3) -- heavy and unwieldy , SetFlag Equipable, EqpSlot EqpSlotShine ] , ieffects = [Detect DetectHidden 20] , idesc = "Powerful wide-beam spotlight in an unwieldy rack-mounted package. On overdrive, it can shine through thin construction surfaces, underlying fault lines." , ikit = [] } scrollAd1 = scrollTemplate { ifreq = [("common item", 100), ("any scroll", 100)] , icount = 1 , irarity = [(1, 1)] -- not every playthrough needs one , iaspects = [ELabel "of tourist guide"] ++ iaspects scrollTemplate , ieffects = [ Impress , toOrganGood "resolute" (500 + 1 `d` 200) -- a drawback (at least initially) due to @calmEnough@ , Explode "cruise ad hologram" , Detect DetectLoot 5 ] -- short so useless most of the time , idesc = "Biodegradable self-powered mini-projector displaying holographic ads and shopping hints." } blowtorch = ItemKind { isymbol = symbolLight , iname = "blowtorch" -- not unique, but almost never generated on floor , ifreq = [("blowtorch", 1), ("valuable", 20), ("curious item", 1)] , iflavour = zipPlain [BrYellow] , icount = 1 , irarity = [(1, 1)] , iverbHit = "scorch" , iweight = 2000 , idamage = 0 , iaspects = [ Timeout 4 , AddSkill SkAlter 2 , SetFlag Durable, SetFlag Meleeable , EqpSlot EqpSlotAlter ] , ieffects = [Burn 2, Impress] -- is used for melee in precedence to fists, but not to cleavers; -- so if player wants to hit with it, it's enough to pack other gear , idesc = "A sturdy old-fashioned portable blowtorch for fine cutting or welding of metals. Rather weak, but does not require access codes to high current power outlets." , ikit = [] } Allure-0.9.5.0/GameDefinition/Content/ItemKindActor.hs0000644000000000000000000011623207346545000020632 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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 Prelude () import Game.LambdaHack.Core.Prelude import Game.LambdaHack.Content.ItemKind import Game.LambdaHack.Definition.Ability import Game.LambdaHack.Definition.Color import Game.LambdaHack.Definition.Defs import Game.LambdaHack.Definition.Flavour actors :: [ItemKind] actors = [warrior, warrior2, warrior3, warrior4, warrior5, scout, ranger, escapist, ambusher, soldier, civilian, civilian2, civilian3, civilian4, civilian5, eye, fastEye, nose, elbow, torsor, goldenJackal, griffonVulture, skunk, armadillo, gilaMonster, rattlesnake, hyena, komodoDragon, alligator, rhinoceros, beeSwarm, hornetSwarm, thornbush] -- Allure-specific ++ [giantOctopus, razorwireFence, electricFence, activeFence, steamFaucet, biogasFaucet, medbotFaucet, surveillanceDrone, shepherdDrone, huntingDrone, homeRobot, wasteRobot, lightRobot, heavyRobot, weldedRobot, cleanerRobot] warrior, warrior2, warrior3, warrior4, warrior5, scout, ranger, escapist, ambusher, soldier, civilian, civilian2, civilian3, civilian4, civilian5, eye, fastEye, nose, elbow, torsor, goldenJackal, griffonVulture, skunk, armadillo, gilaMonster, rattlesnake, hyena, komodoDragon, alligator, rhinoceros, beeSwarm, hornetSwarm, thornbush :: ItemKind -- Allure-specific giantOctopus, razorwireFence, electricFence, activeFence, steamFaucet, biogasFaucet, medbotFaucet, surveillanceDrone, shepherdDrone, huntingDrone, homeRobot, wasteRobot, lightRobot, heavyRobot, weldedRobot, cleanerRobot :: ItemKind -- Note that the actors that appear in the crawl scenario should -- be generated with at most ordinary ammo. Otherwise, farming them -- may be rational though boring endeavour. Any exceptions to that -- should be well thought of. E.g., unique guaranteed items on bosses -- are safe, just as restricted kinds of weak items. -- * Hunams humanOrgans :: [(GroupName ItemKind, CStore)] humanOrgans = [ ("fist", COrgan), ("foot", COrgan) , ("eye 6", COrgan), ("ear 3", COrgan) , ("sapient brain", COrgan) ] warrior = ItemKind { isymbol = '@' , iname = "mercenary" -- modified if initial actors in hero faction , ifreq = [("hero", 100), ("crawl hero", 100), ("mobile", 1)] , iflavour = zipPlain [BrWhite] , icount = 1 , irarity = [(1, 5)] , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 90 -- partially from clothes and first aid , AddSkill SkMaxCalm 70 , AddSkill SkSpeed 20 , AddSkill SkNocto 2 , AddSkill SkWait 1 -- can lurk , AddSkill SkProject 2 -- can lob , AddSkill SkApply 2 -- can even apply periodic items , AddSkill SkOdor 1 , SetFlag Durable ] , ieffects = [] , idesc = "" , ikit = humanOrgans ++ [("genetic flaw 10", COrgan)] } warrior2 = warrior { iname = "pilot" -- , idesc = "" } warrior3 = warrior { iname = "engineer" , ifreq = [("crawl hero", 100), ("mobile", 1)] , ikit = ikit warrior ++ [("currency", CSha)] -- , idesc = "" } warrior4 = warrior { iname = "doctor" , ifreq = [("crawl hero", 100), ("mobile", 1)] , ikit = ikit warrior ++ [("currency", CSha)] -- , idesc = "" } warrior5 = warrior { iname = "hacker" , ifreq = [("crawl hero", 100), ("mobile", 1)] , ikit = ikit warrior ++ [("currency", CSha)] -- , idesc = "" } scout = warrior { iname = "scout" , ifreq = [("scout hero", 100), ("mobile", 1)] , ikit = humanOrgans -- no flaw ++ [ ("add sight", CEqp) , ("armor ranged", CEqp) , ("add nocto 1", CInv) ] -- , idesc = "" } ranger = warrior { iname = "ranger" , ifreq = [("ranger hero", 100), ("mobile", 1)] , ikit = humanOrgans -- no flaw ++ [ ("armor ranged", CEqp) , ("weak arrow", CInv) ] -- , idesc = "" } escapist = warrior { iname = "escapist" , ifreq = [("escapist hero", 100), ("mobile", 1)] , ikit = humanOrgans -- no flaw ++ [ ("add sight", CEqp) , ("armor ranged", CEqp) , ("weak arrow", CInv) -- mostly for probing , ("light source", CInv) , ("wooden torch", CInv) , ("blanket", CInv) ] -- , idesc = "" } ambusher = warrior { iname = "ambusher" , ifreq = [("ambusher hero", 100), ("mobile", 1)] , ikit = humanOrgans -- dark and numerous, so more kit without exploring ++ [ ("ring of opportunity sniper", CEqp) , ("any arrow", CSha) , ("weak arrow", CInv) , ("explosive", CSha) , ("light source", CEqp) , ("wooden torch", CInv) ] -- , idesc = "" } soldier = warrior { iname = "soldier" , ifreq = [("soldier hero", 100), ("mobile", 1)] , ikit = humanOrgans -- no flaw ++ [ ("starting weapon", CEqp) , ("explosive", CSha) ] -- , idesc = "" } civilian = warrior { iname = "clerk" , ifreq = [("civilian", 100), ("mobile", 1)] , iflavour = zipPlain [BrBlack] -- , idesc = "" } civilian2 = civilian { iname = "hairdresser" -- , idesc = "" } civilian3 = civilian { iname = "lawyer" -- , idesc = "" } civilian4 = civilian { iname = "peddler" -- , idesc = "" } civilian5 = civilian { iname = "tax collector" -- , idesc = "" } -- * Aliens -- They have bright colours, because they are not natural. eye = ItemKind { isymbol = 'w' , iname = "beckoning walker" , ifreq = [ ("monster", 100), ("mobile", 1) , ("mobile monster", 100), ("scout monster", 10) ] , iflavour = zipFancy [BrRed] , icount = 1 , irarity = [(3 * 10/15, 0), (4 * 10/15, 10), (10, 8)] , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 16, AddSkill SkMaxCalm 70 , AddSkill SkSpeed 20, AddSkill SkNocto 2 , AddSkill SkAggression 1 , AddSkill SkProject 2 -- can lob , AddSkill SkApply 1 -- can even use cultural artifacts , SetFlag Durable ] , ieffects = [] , idesc = "Walks with a stately dignity. You read death in the slow beckoning gestures of its revolting upper appendages." , ikit = [ ("foot", COrgan), ("tentacle", COrgan) , ("bark", COrgan), ("eye 6", COrgan) , ("sapient brain", COrgan) ] -- no voice, no hearing } fastEye = ItemKind { isymbol = 'b' , iname = "rolling biter" , ifreq = [ ("monster", 100), ("mobile", 1) , ("mobile monster", 100), ("scout monster", 60) ] , iflavour = zipFancy [BrBlue] , icount = 1 , irarity = [(3 * 10/15, 0), (4 * 10/15, 3), (10, 12)] , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 5, AddSkill SkMaxCalm 70 , AddSkill SkSpeed 30, AddSkill SkNocto 2 , AddSkill SkAggression 1 , SetFlag Durable ] , ieffects = [] , idesc = "It bites as blindingly fast as it runs. Or rolls? Or crawls? Also, cuts and pierces." , ikit = [ ("jaw", COrgan), ("razor", COrgan), ("horn", COrgan) , ("speed gland 10", COrgan) , ("eye 3", COrgan), ("ear 3", COrgan) , ("sapient brain", COrgan) ] } nose = ItemKind -- depends solely on smell { isymbol = 'h' , iname = "clawing horror" , ifreq = [ ("monster", 100), ("mobile", 1), ("mobile monster", 100) , ("aquatic", 30), ("aquatic monster", 30) ] -- likes liquids , iflavour = zipFancy [BrGreen] , icount = 1 , irarity = [(3 * 10/15, 0), (4 * 10/15, 5), (10, 9)] , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 30, AddSkill SkMaxCalm 30 , AddSkill SkSpeed 16, AddSkill SkNocto 2 , AddSkill SkAggression 1 , AddSkill SkProject (-1) -- can't project , AddSkill SkSwimming 30 , SetFlag Durable ] , ieffects = [] , idesc = "A blind, slimy mass of loose tissue. You'd think it's powerless, but as soon as it touches your trembling body, clawing, stinging and burning erupts and can't be fended off." , ikit = [ ("small claw", COrgan), ("sting", COrgan) , ("venom tooth", COrgan) , ("nostril", COrgan) , ("sapient brain", COrgan) ] -- no sight nor hearing } elbow = ItemKind { isymbol = 's' , iname = "creepy shooter" , ifreq = [ ("monster", 100), ("mobile", 1) , ("mobile monster", 100), ("scout monster", 30) ] , iflavour = zipFancy [BrMagenta] , icount = 1 , irarity = [(3 * 10/15, 0), (4 * 10/15, 1), (10, 12)] , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 12, AddSkill SkMaxCalm 80 , AddSkill SkSpeed 20, AddSkill SkNocto 2 , AddSkill SkProject 2 -- can lob , AddSkill SkApply 1 -- can even use cultural artifacts , AddSkill SkMelee (-1) , SetFlag Durable ] , ieffects = [] , idesc = "It moves in sudden jerks and never makes a noise. Speaks in hard objects hurled at deadly speeds." , ikit = [ ("speed gland 5", COrgan) , ("eye 6", COrgan), ("ear 8", COrgan) -- too powerful to get stronger sight , ("sapient brain", COrgan) , ("any arrow", CSha), ("any arrow", CInv) , ("weak arrow", CInv), ("weak arrow", CInv) ] } torsor = ItemKind { isymbol = 'M' , iname = "Maker" , ifreq = [("monster", 100), ("mobile", 1)] , iflavour = zipFancy [BrCyan] , icount = 1 , irarity = [(14 * 10/15, 0), (15 * 10/15, 1000)] -- unique , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ SetFlag Unique, ELabel "of Contact" , AddSkill SkMaxHP 300, AddSkill SkMaxCalm 100 , AddSkill SkSpeed 10, AddSkill SkNocto 2 , AddSkill SkAggression 3 , AddSkill SkProject 2 -- can lob , AddSkill SkApply 1 -- can even use cultural artifacts , AddSkill SkAlter (-1) -- can't exit the gated level; a boss, -- but can dig rubble, ice , SetFlag Durable ] , ieffects = [] , idesc = "The mind, the big heart behind it all. Warmth and sympathy pour out through the graceful undulation of tentacles, sharp claws, snapping jaw and dripping fangs." , ikit = [ ("tentacle", COrgan), ("hooked claw", COrgan) -- at least one non-timed , ("large jaw", COrgan), ("venom fang", COrgan) , ("speed gland 5", COrgan) , ("eye 6", COrgan), ("ear 8", COrgan) , ("sapient brain", COrgan) , ("gem", CInv), ("gem", CInv), ("gem", CInv), ("gem", CInv) ] } -- * Animals -- They need rather strong melee, because they don't use items. -- They have dull colors, except for yellow, because there is no dull variant. goldenJackal = ItemKind -- basically a much smaller and slower hyena { isymbol = 'j' , iname = "golden jackal" , ifreq = [ ("animal", 100), ("mobile", 1), ("mobile animal", 100) , ("scavenger", 50) ] , iflavour = zipPlain [BrYellow] , icount = 1 , irarity = [(1, 4), (10, 2)] , iverbHit = "thud" , iweight = 13000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 15, AddSkill SkMaxCalm 70 , AddSkill SkSpeed 24, AddSkill SkNocto 2 , SetFlag Durable ] , ieffects = [] , idesc = "An opportunistic predator, feeding on carrion and the weak." , ikit = [ ("small jaw", COrgan) , ("eye 6", COrgan), ("nostril", COrgan), ("ear 8", COrgan) , ("animal brain", COrgan) , ("genetic flaw 3", COrgan) ] } griffonVulture = ItemKind { isymbol = 'v' , iname = "griffon vulture" , ifreq = [ ("animal", 100), ("mobile", 1), ("mobile animal", 100) , ("scavenger", 30) ] , iflavour = zipPlain [BrYellow] , icount = 1 , irarity = [(1, 3), (10, 3)] , iverbHit = "thud" , iweight = 13000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 15, AddSkill SkMaxCalm 80 -- enough Calm to summon twice only if not attacked at all; -- loses a lot of sight after summoning , AddSkill SkSpeed 22, AddSkill SkNocto 2 , AddSkill SkAlter (-2) -- can't use normal stairs nor doors , AddSkill SkFlying 10 -- flies slowly, but far , SetFlag Durable ] -- Animals don't have leader, usually, so even if only one on level, -- it pays the communication overhead, so the speed is higher to get -- them on par with human leaders moving solo. Common random double moves, -- on either side, are just too bothersome. , ieffects = [] , idesc = "It soars high above, searching for vulnerable prey." , ikit = [ ("screeching beak", COrgan) -- in reality it grunts and hisses , ("small claw", COrgan) , ("eye 8", COrgan), ("ear 8", COrgan) -- can't shoot, so strong sight is OK , ("animal brain", COrgan) , ("genetic flaw 3", COrgan) ] } skunk = ItemKind { isymbol = 's' , iname = "hog-nosed skunk" , ifreq = [("animal", 100), ("mobile", 1), ("mobile animal", 100)] , iflavour = zipPlain [White] , icount = 1 , irarity = [(1, 8), (5, 1)] , iverbHit = "thud" , iweight = 4000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 13, AddSkill SkMaxCalm 30 , AddSkill SkSpeed 22, AddSkill SkNocto 2 , AddSkill SkAlter (-2) -- can't use normal stairs nor doors , AddSkill SkOdor 5 -- and no smell skill, to let it leave smell , SetFlag Durable ] , ieffects = [] , idesc = "Its only defence is the terrible stench." , ikit = [ ("scent gland", COrgan) , ("small claw", COrgan), ("snout", COrgan) , ("eye 3", COrgan), ("ear 6", COrgan) , ("animal brain", COrgan) , ("genetic flaw 3", COrgan) ] } armadillo = ItemKind { isymbol = 'a' , iname = "giant armadillo" , ifreq = [("animal", 100), ("mobile", 1), ("mobile animal", 100)] , iflavour = zipPlain [Brown] , icount = 1 , irarity = [(1, 7)] , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 13, AddSkill SkMaxCalm 30 , AddSkill SkSpeed 20, AddSkill SkNocto 2 , AddSkill SkAlter (-2) -- can't use normal stairs nor doors , SetFlag Durable ] , ieffects = [] , idesc = "When threatened, it rolls into a ball." , ikit = [ ("hooked claw", COrgan), ("snout", COrgan) , ("armored skin", COrgan), ("armored skin", COrgan) , ("eye 3", COrgan), ("nostril", COrgan), ("ear 6", COrgan) , ("animal brain", COrgan) , ("genetic flaw 3", COrgan) ] } gilaMonster = ItemKind { isymbol = 'g' , iname = "Gila monster" , ifreq = [("animal", 100), ("mobile", 1), ("mobile animal", 100)] , iflavour = zipPlain [Magenta] , icount = 1 , irarity = [(2, 5), (10, 2)] , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 15, AddSkill SkMaxCalm 50 , AddSkill SkSpeed 18, AddSkill SkNocto 2 , AddSkill SkAlter (-2) -- can't use normal stairs nor doors , SetFlag Durable ] , ieffects = [] , idesc = "Numbing venom ensures that even the fastest prey has no escape." , ikit = [ ("venom tooth", COrgan), ("small claw", COrgan) , ("eye 3", COrgan), ("nostril", COrgan), ("ear 6", COrgan) , ("animal brain", COrgan) , ("genetic flaw 3", COrgan) ] } rattlesnake = ItemKind { isymbol = 's' , iname = "rattlesnake" , ifreq = [("animal", 100), ("mobile", 1), ("mobile animal", 100)] , iflavour = zipPlain [Brown] , icount = 1 , irarity = [(5, 1), (10, 7)] , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 28, AddSkill SkMaxCalm 60 , AddSkill SkSpeed 16, AddSkill SkNocto 2 , AddSkill SkAlter (-2) -- can't use normal stairs nor doors , SetFlag Durable ] , ieffects = [] , idesc = "Beware its rattle - it serves as a warning of an agonising death." , ikit = [ ("venom fang", COrgan) -- when on cooldown, it's weaponless , ("rattle", COrgan) , ("eye 3", COrgan), ("nostril", COrgan), ("ear 6", COrgan) , ("animal brain", COrgan) , ("genetic flaw 3", COrgan) ] } hyena = ItemKind { isymbol = 'h' , iname = "spotted hyena" , ifreq = [ ("animal", 100), ("mobile", 1), ("mobile animal", 100) , ("scavenger", 20) ] , iflavour = zipPlain [BrYellow] , icount = 1 , irarity = [(4, 1), (10, 5)] -- gets summoned often, so low base rarity , iverbHit = "thud" , iweight = 60000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 23, AddSkill SkMaxCalm 70 , AddSkill SkSpeed 32, AddSkill SkNocto 2 , SetFlag Durable ] , ieffects = [] , idesc = "Skulking in the shadows, waiting for easy prey." , ikit = [ ("jaw", COrgan) , ("eye 6", COrgan), ("nostril", COrgan), ("ear 8", COrgan) , ("animal brain", COrgan) , ("genetic flaw 3", COrgan) ] } komodoDragon = ItemKind { isymbol = 'k' , iname = "Komodo dragon" , ifreq = [("animal", 100), ("mobile", 1), ("mobile animal", 100)] , iflavour = zipPlain [BrRed] -- speedy, so bright red , icount = 1 , irarity = [(9, 0), (10, 11)] , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 40, AddSkill SkMaxCalm 60 , AddSkill SkSpeed 17, AddSkill SkNocto 2 , AddSkill SkAggression 1 -- match the description , SetFlag Durable ] , ieffects = [] , idesc = "Larger and more aggressive than any other lizard, but as easily recovering from wounds as its lesser cousins." , ikit = [ ("large tail", COrgan), ("jaw", COrgan) , ("hooked claw", COrgan) , ("speed gland 5", COrgan), ("armored skin", COrgan) , ("eye 3", COrgan), ("nostril", COrgan), ("ear 3", COrgan) , ("animal brain", COrgan) , ("genetic flaw 3", COrgan) ] -- not to wake it up too soon } alligator = ItemKind { isymbol = 'a' , iname = "alligator" , ifreq = [ ("animal", 100), ("mobile", 1), ("mobile animal", 100) , ("aquatic", 70), ("aquatic animal", 70) ] -- amphibious , iflavour = zipPlain [Blue] , icount = 1 , irarity = [(9, 0), (10, 10)] -- extra spawns in water, so lower rarity , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 55, AddSkill SkMaxCalm 70 , AddSkill SkSpeed 18, AddSkill SkNocto 2 , AddSkill SkSwimming 100 -- swims better than walks , AddSkill SkWait 1 -- can sleep despite the genetic flaw , AddSkill SkApply 1 -- can eat food despite the genetic flaw , SetFlag Durable ] , ieffects = [] , idesc = "An armored predator from the dawn of time. You better not get within its reach." , ikit = [ ("huge tail", COrgan), ("large jaw", COrgan) , ("small claw", COrgan) , ("armored skin", COrgan) , ("eye 6", COrgan), ("ear 8", COrgan) , ("animal brain", COrgan) , ("genetic flaw 10", COrgan) ] } rhinoceros = ItemKind { isymbol = 'R' , iname = "Maddened Rhinoceros" , ifreq = [("animal", 100), ("mobile", 1)] , iflavour = zipPlain [Brown] , icount = 1 , irarity = [(7 * 10/15, 0), (8 * 10/15, 1000), (9 * 10/15, 0)] -- unique , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ SetFlag Unique , AddSkill SkMaxHP 120, AddSkill SkMaxCalm 60 , AddSkill SkSpeed 27, AddSkill SkNocto 2 , AddSkill SkAggression 2 , AddSkill SkAlter (-1) -- can't use normal stairs nor dig; -- a weak miniboss , SetFlag Durable ] , ieffects = [] , idesc = "The last of its kind. Blind with rage, or perhaps due to the postoperative scars. A huge mass of muscle that charges at deadly speed." , ikit = [ ("rhino horn", COrgan), ("snout", COrgan) , ("armored skin", COrgan) , ("eye 3", COrgan), ("ear 8", COrgan) , ("animal brain", COrgan) ] } -- * Non-animal animals beeSwarm = ItemKind { isymbol = 'b' , iname = "bee swarm" , ifreq = [("animal", 100), ("mobile", 1)] , iflavour = zipPlain [Brown] , icount = 1 , irarity = [(1, 3), (10, 4)] , iverbHit = "buzz" , iweight = 1000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 8, AddSkill SkMaxCalm 60 , AddSkill SkSpeed 30, AddSkill SkNocto 2 -- armor in sting , AddSkill SkAlter (-2) -- can't use normal stairs nor doors , AddSkill SkWait (-2) -- can't brace, sleep and lurk , AddSkill SkFlying 10 -- flies slowly, but far , SetFlag Durable ] , ieffects = [] , idesc = "Every bee would die for the queen." , ikit = [ ("bee sting", COrgan) -- weaponless when it's used up , ("vision 6", COrgan), ("ear 6", COrgan) , ("insect mortality", COrgan), ("animal brain", COrgan) ] } hornetSwarm = ItemKind { isymbol = 'h' , iname = "hornet swarm" , ifreq = [("animal", 100), ("mobile", 1), ("mobile animal", 100)] , iflavour = zipPlain [Magenta] , icount = 1 , irarity = [(5, 1), (10, 4)] -- should be many, because die after a time , iverbHit = "buzz" , iweight = 1000 , idamage = 0 , iaspects = [ AddSkill SkArmorMelee 80, AddSkill SkArmorRanged 40 , AddSkill SkMaxHP 8, AddSkill SkMaxCalm 70 , AddSkill SkSpeed 30, AddSkill SkNocto 2 , AddSkill SkAlter (-2) -- can't use normal stairs nor doors , AddSkill SkWait (-2) -- can't brace, sleep and lurk , AddSkill SkFlying 10 -- flies slowly, but far , SetFlag Durable ] , ieffects = [] , idesc = "A vicious cloud of stings and hate." , ikit = [ ("sting", COrgan) -- when on cooldown, it's weaponless , ("vision 6", COrgan), ("ear 6", COrgan) , ("insect mortality", COrgan), ("animal brain", COrgan) ] } thornbush = ItemKind { isymbol = 't' , iname = "thornbush" , ifreq = [("animal", 30), ("immobile animal", 50)] , iflavour = zipPlain [Brown] , icount = 1 , irarity = [(1, 13)] , iverbHit = "scrape" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 20, AddSkill SkMaxCalm 999 , AddSkill SkSpeed 22, AddSkill SkNocto 2 , AddSkill SkWait 1, AddSkill SkMelee 1 -- no brain , SetFlag Durable ] , ieffects = [] , idesc = "Each branch bears long, curved thorns." , ikit = [ ("thorn", COrgan) -- after all run out, it's weaponless , ("bark", COrgan) ] } -- * Allure-specific animals giantOctopus = ItemKind { isymbol = 'o' , iname = "giant octopus" , ifreq = [ ("animal", 100), ("mobile", 1), ("mobile animal", 100) , ("aquatic", 90), ("aquatic animal", 90) ] -- weak on land , iflavour = zipPlain [BrMagenta] , icount = 1 , irarity = [(1, 3)] , iverbHit = "thud" , iweight = 72000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 17, AddSkill SkMaxCalm 80 , AddSkill SkSwimming 100 -- swims better than walks , AddSkill SkSpeed 27, AddSkill SkNocto 3 -- good night vision , AddSkill SkAlter (-2) -- can't use normal stairs nor doors , SetFlag Durable ] , ieffects = [] , idesc = "It has eight arms of rage." , ikit = [ ("tentacle", COrgan), ("tentacle", COrgan) , ("small beak", COrgan) -- TODO: use when tentacles torn out , ("eye 8", COrgan) -- shots not too damaging, so can have strong sight , ("animal brain", COrgan) , ("genetic flaw 3", COrgan) ] } -- * Robots, Allure-specific -- Robots have any colors but only f, d and r letters. Avoid these letters -- for other factions. razorwireFence = ItemKind { isymbol = 'f' , iname = "razorwire fence" , ifreq = [("robot", 15), ("immobile robot", 10)] , iflavour = zipPlain [Cyan] , icount = 1 , irarity = [(3 * 10/15, 0), (4 * 10/15, 20), (10, 4)] , iverbHit = "scrape" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkArmorMelee 30, AddSkill SkArmorRanged 15 , AddSkill SkMaxHP 30, AddSkill SkMaxCalm 999 , AddSkill SkSpeed 20, AddSkill SkNocto 2 , AddSkill SkWait 1, AddSkill SkMelee 1 -- no brain , SetFlag Durable ] , ieffects = [] , idesc = "Must have been bought by previous ship owners to contain the wild animal infestation." , ikit = [("razor", COrgan), ("razor", COrgan)] } electricFence = ItemKind { isymbol = 'f' , iname = "electric fence" , ifreq = [("robot", 15), ("immobile robot", 10)] , iflavour = zipPlain [Blue] , icount = 1 , irarity = [(3 * 10/15, 0), (4 * 10/15, 15), (10, 5)] , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkArmorMelee 30, AddSkill SkArmorRanged 15 , AddSkill SkMaxHP 10, AddSkill SkMaxCalm 999 , AddSkill SkSpeed 40, AddSkill SkNocto 2 , AddSkill SkWait 1, AddSkill SkMelee 1 -- no brain , SetFlag Durable ] , ieffects = [] , idesc = "Marginally intelligent electric shepherd. Originally used in orbital dairy farms and planetary zoos." , ikit = [("live wire", COrgan)] } activeFence = ItemKind { isymbol = 'f' , iname = "active fence" , ifreq = [("robot", 27), ("immobile robot", 20)] , iflavour = zipPlain [BrMagenta] , icount = 1 , irarity = [(5 * 10/15, 0), (10, 7)] , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkArmorMelee 30, AddSkill SkArmorRanged 15 , AddSkill SkMaxHP 20, AddSkill SkMaxCalm 999 , AddSkill SkSpeed 20, AddSkill SkNocto 2 , AddSkill SkWait 1 , AddSkill SkProject 3 -- no brain, but can lob , SetFlag Durable ] , ieffects = [] , idesc = "Makeshift, mostly non-lethal, autonomous perimeter defense outpost." , ikit = [ ("vision 6", COrgan) , ("needle", CInv), ("can of sticky foam", CInv) ] -- can of sticky foam is exploitable, but it spawns -- reasonably often only on one level and not for -- a long period } steamFaucet = ItemKind { isymbol = 'f' , iname = "steam faucet" , ifreq = [("robot", 8), ("immobile robot", 15)] , iflavour = zipPlain [BrBlue] , icount = 1 , irarity = [(1, 10), (10, 6)] , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 10, AddSkill SkMaxCalm 999 , AddSkill SkSpeed 11, AddSkill SkNocto 2 , AddSkill SkWait 1, AddSkill SkMelee 1 -- no brain , SetFlag Durable ] , ieffects = [] , idesc = "A cracked valve on one of the superheated water pipes spreading radially outward from the tokamak level." , ikit = [("boiling vent", COrgan), ("boiling fissure", COrgan)] } biogasFaucet = ItemKind { isymbol = 'f' , iname = "biogas faucet" , ifreq = [("robot", 8), ("immobile robot", 30)] , iflavour = zipPlain [BrGreen] , icount = 1 , irarity = [(1, 10), (10, 6)] , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 20, AddSkill SkMaxCalm 999 , AddSkill SkSpeed 22, AddSkill SkNocto 2, AddSkill SkShine 3 , AddSkill SkWait 1, AddSkill SkMelee 1 -- no brain , SetFlag Durable ] , ieffects = [] , idesc = "An emergency pressure-release vent on a smelly biogas pipe." , ikit = [("biogas vent", COrgan), ("biogas fissure", COrgan)] } medbotFaucet = ItemKind { isymbol = 'f' , iname = "nano medbot faucet" , ifreq = [("robot", 8), ("immobile robot", 100)] , iflavour = zipPlain [BrYellow] , icount = 1 , irarity = [(1, 10), (10, 6)] , iverbHit = "thud" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 20, AddSkill SkMaxCalm 999 , AddSkill SkSpeed 22, AddSkill SkNocto 2, AddSkill SkShine 3 , AddSkill SkWait 1, AddSkill SkMelee 1 -- no brain , SetFlag Durable ] , ieffects = [] , idesc = "A faucet of a malfunctioning nano medical robot dispenser. Let's hope the medbots are still effective." , ikit = [("medbot vent", COrgan), ("medbot fissure", COrgan)] } surveillanceDrone = ItemKind { isymbol = 'd' , iname = "surveillance drone" , ifreq = [("robot", 100), ("mobile", 100), ("mobile robot", 100)] , iflavour = zipPlain [Blue] , icount = 1 , irarity = [(1, 3)] , iverbHit = "clank" , iweight = 1000 , idamage = 0 , iaspects = [ AddSkill SkArmorMelee 30, AddSkill SkArmorRanged 15 , AddSkill SkMaxHP 6, AddSkill SkMaxCalm 90 , AddSkill SkSpeed 30, AddSkill SkNocto 2 , AddSkill SkDisplace (-1) -- as dumb as an animal , AddSkill SkMoveItem (-1) , AddSkill SkProject (-1) , AddSkill SkMelee (-1) , SetFlag Durable ] , ieffects = [] , idesc = "A video camera in each room would violate privacy of passengers, hence surveillance drones. Programmed to be easy to fend off, they keep a respectful distance." , ikit = [ ("vision 16", COrgan), ("robot brain", COrgan) ] } shepherdDrone = ItemKind { isymbol = 'd' , iname = "oversight drone" , ifreq = [ ("robot", 100), ("mobile", 100), ("mobile robot", 100) , ("construction robot", 100) ] , iflavour = zipPlain [BrRed] , icount = 1 , irarity = [(1, 3), (10, 4)] -- gets summoned often, so low base rarity , iverbHit = "clank" , iweight = 1000 , idamage = 0 , iaspects = [ AddSkill SkArmorMelee 80, AddSkill SkArmorRanged 40 , AddSkill SkMaxHP 3, AddSkill SkMaxCalm 60 , AddSkill SkSpeed 30, AddSkill SkNocto 2 , AddSkill SkAlter (-1) -- can't open doors; roams open spaces , AddSkill SkDisplace (-1) -- as dumb as an animal , AddSkill SkMoveItem (-1) , AddSkill SkProject (-1) , SetFlag Durable ] , ieffects = [] , idesc = "An tiny airborne robot designed to take construction measurements, synchronize robot workers and report irregularities, if any." , ikit = [ ("live wire", COrgan), ("vision 16", COrgan), ("ear 8", COrgan) , ("robot brain", COrgan) ] } huntingDrone = ItemKind { isymbol = 'd' , iname = "hunting drone" , ifreq = [("robot", 100), ("mobile", 100), ("mobile robot", 100)] , iflavour = zipPlain [Green] , icount = 1 , irarity = [(4, 0), (5, 5), (10, 8)] , iverbHit = "clank" , iweight = 500 , idamage = 0 , iaspects = [ AddSkill SkArmorMelee 30, AddSkill SkArmorRanged 15 , AddSkill SkMaxHP 6, AddSkill SkMaxCalm 60 , AddSkill SkSpeed 40, AddSkill SkNocto 2 , AddSkill SkDisplace (-1) -- almost as dumb as an animal , AddSkill SkMoveItem (-1) -- but can project , AddSkill SkMelee (-1) , SetFlag Durable ] , ieffects = [] , idesc = "Originally designed for hunting down and putting to sleep stray animals. The sleeping agent must have long since dried up." , ikit = [ ("eye 8", COrgan), ("nostril", COrgan), ("ear 8", COrgan) -- week projectiles, so strong sight OK , ("robot brain", COrgan) , ("needle", CInv), ("tranquillizer dart", CInv) ] } homeRobot = ItemKind { isymbol = 'r' , iname = "feral home robot" -- TODO: name another 'deranged', tertiary imperative: survival , ifreq = [("robot", 100), ("mobile", 100), ("mobile robot", 100)] , iflavour = zipPlain [Magenta] , icount = 1 , irarity = [(1, 15), (10, 5)] , iverbHit = "clank" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 12, AddSkill SkMaxCalm 30 , AddSkill SkSpeed 20, AddSkill SkNocto 2 , AddSkill SkProject (-1) -- can't project , SetFlag Durable ] , ieffects = [] , idesc = "Once a timid household robot, now sufficiently adapted to survive in the deadly environment." , ikit = [ ("fist", COrgan) , ("eye 3", COrgan), ("nostril", COrgan), ("ear 3", COrgan) , ("robot brain", COrgan) ] } wasteRobot = ItemKind { isymbol = 'r' , iname = "waste disposal robot" , ifreq = [ ("robot", 100), ("mobile", 100), ("mobile robot", 100) , ("construction robot", 100) ] , iflavour = zipPlain [Green] , icount = 1 , irarity = [(5, 9)] -- gets summoned often, so low base rarity , iverbHit = "clank" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 17, AddSkill SkMaxCalm 30 , AddSkill SkSpeed 15, AddSkill SkNocto 2 , SetFlag Durable ] , ieffects = [] , idesc = "You are not in its database, hence you are waste." , ikit = [ ("tentacle", COrgan) , ("nostril", COrgan) -- only smell, for variety , ("robot brain", COrgan) , ("waste container", CEqp) ] } lightRobot = ItemKind { isymbol = 'r' , iname = "decoration robot" , ifreq = [ ("robot", 100), ("mobile", 100), ("mobile robot", 100) , ("construction robot", 100) ] , iflavour = zipPlain [BrYellow] , icount = 1 , irarity = [(3 * 10/15, 0), (4 * 10/15, 6), (10, 6)] -- gets summoned often, so low rarity , iverbHit = "clank" , iweight = 80000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 17, AddSkill SkMaxCalm 40 -- can't summon again for a long time; -- loses a lot of sight after summoning , AddSkill SkSpeed 30, AddSkill SkNocto 2 , AddSkill SkProject 2 -- can lob , AddSkill SkAlter 3 -- uses all stairs , AddSkill SkApply 1 -- can apply the hooter , SetFlag Durable ] , ieffects = [] , idesc = "Interior and exterior decoration robot. Strongly fancies deep reds recently." , ikit = [ ("hooked claw", COrgan), ("tentacle", COrgan) , ("hull plating", COrgan) , ("eye 6", COrgan), ("ear 8", COrgan) , ("robot brain", COrgan) , ("construction hooter", CEqp) ] } heavyRobot = ItemKind { isymbol = 'r' , iname = "demolition robot" , ifreq = [ ("robot", 100), ("mobile", 100), ("mobile robot", 100) , ("construction robot", 70) ] , iflavour = zipPlain [Cyan] , icount = 1 , irarity = [(7 * 10/15, 0), (8 * 10/15, 4), (10, 13)] , iverbHit = "clank" , iweight = 800000 , idamage = 0 , iaspects = [ AddSkill SkMaxHP 41, AddSkill SkMaxCalm 40 -- can't summon again for a long time; -- loses a lot of sight after summoning , AddSkill SkSpeed 20, AddSkill SkNocto 2 , AddSkill SkProject 2 -- can lob , AddSkill SkAlter 3 -- uses all stairs , AddSkill SkApply 1 -- can apply the hooter , SetFlag Durable ] , ieffects = [] , idesc = "Heavy multi-purpose construction robot. Excels at discharging, dismantling and demolition." , ikit = [ ("large jaw", COrgan), ("small claw", COrgan) , ("hull plating", COrgan) , ("eye 3", COrgan), ("ear 6", COrgan) , ("robot brain", COrgan) , ("spotlight", CEqp), ("construction hooter", CEqp) ] } weldedRobot = ItemKind { isymbol = 'W' , iname = "Smiling Welded Robot" , ifreq = [("robot", 100), ("immobile robot", 100)] , iflavour = zipPlain [BrCyan] , icount = 1 , irarity = [(1 * 10/15, 1000), (2 * 10/15, 0)] -- unique , iverbHit = "clank" , iweight = 80000 , idamage = 0 , iaspects = [ SetFlag Unique , AddSkill SkMaxHP 200, AddSkill SkMaxCalm 100 , AddSkill SkSpeed 20, AddSkill SkNocto 2 , SetFlag Durable ] , ieffects = [] , idesc = "A well-built humanoid luggage unloading robot with a smooth satin silvery skin. Its graceful moves are stunted by a thick irregular weld fastening both its shapely legs to the floor. A whiff of smoke escapes whenever it opens its mouth in a charming toothy smile while brandishing a blowtorch in its trembling hand." , ikit = [ ("fist", COrgan) , ("eye 6", COrgan), ("ear 3", COrgan) , ("mouth vent", COrgan) , ("robot brain", COrgan) , ("crude weld", COrgan), ("blowtorch", CEqp) ] } cleanerRobot = ItemKind { isymbol = 'C' , iname = "Void Cleaner Robot" , ifreq = [("robot", 100), ("mobile", 1)] , iflavour = zipPlain [BrGreen] , icount = 1 , irarity = [(11 * 10/15, 0), (12 * 10/15, 1000), (13 * 10/15, 0)] -- unique, appears at 11 of 12 , iverbHit = "clank" , iweight = 800000 , idamage = 0 , iaspects = [ SetFlag Unique , AddSkill SkMaxHP 120, AddSkill SkMaxCalm 40 -- can't summon again for a long time; -- loses a lot of sight after summoning , AddSkill SkSpeed 18, AddSkill SkNocto 2 , AddSkill SkAggression 1 -- can't use normal stairs nor dig; a weak miniboss , AddSkill SkApply 1 -- can apply the hooter , SetFlag Durable ] , ieffects = [] , idesc = "An oversize waste disposal robot repaired with parts from a demolition robot, including a scaled up goal matrix. The cosmic void is now the only acceptable model of cleanliness. The robot's bulky trunk doesn't fit into even the larger lift carriages." , ikit = [ ("live wire", COrgan), ("large jaw", COrgan) , ("tentacle", COrgan) , ("boiling vent", COrgan), ("hull plating", COrgan) , ("eye 3", COrgan), ("nostril", COrgan), ("ear 6", COrgan) , ("robot brain", COrgan) , ("currency", CInv), ("currency", CInv), ("currency", CInv) , ("waste container", CEqp), ("spotlight", CEqp) , ("construction hooter", CEqp) ] } Allure-0.9.5.0/GameDefinition/Content/ItemKindBlast.hs0000644000000000000000000010005207346545000020620 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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. -- -- | Blast definitions. module Content.ItemKindBlast ( blasts ) where import Prelude () import Game.LambdaHack.Core.Prelude import Game.LambdaHack.Content.ItemKind import Game.LambdaHack.Core.Dice import Game.LambdaHack.Definition.Ability import Game.LambdaHack.Definition.Color import Game.LambdaHack.Definition.Defs import Game.LambdaHack.Definition.Flavour blasts :: [ItemKind] blasts = [burningOil2, burningOil3, burningOil4, firecracker1, firecracker2, firecracker3, firecracker4, firecracker5, spreadFragmentation, spreadFragmentation8, focusedFragmentation, spreadConcussion, spreadConcussion8, focusedConcussion, spreadFlash, spreadFlash8, focusedFlash, singleSpark, glassPiece, focusedGlass, fragrance, pheromone, mistCalming, odorDistressing, mistHealing, mistHealing2, mistWounding, distortion, smoke, boilingWater, glue, waste, mistAntiSlow, mistAntidote, mistSleep, denseShower, sparseShower, protectingBalmMelee, protectingBalmRanged, vulnerabilityBalm, resolutionDust, hasteSpray, slownessMist, eyeDrop, ironFiling, smellyDroplet, eyeShine, whiskeySpray, youthSprinkle, poisonCloud, blastNoSkMove, blastNoSkMelee, blastNoSkDisplace, blastNoSkAlter, blastNoSkWait, blastNoSkMoveItem, blastNoSkProject, blastNoSkApply, blastBonusSkMove, blastBonusSkMelee, blastBonusSkDisplace, blastBonusSkAlter, blastBonusSkWait, blastBonusSkMoveItem, blastBonusSkProject, blastBonusSkApply] -- Allure-specific ++ [cruiseAdHologram, outerAdHologram, victoriaClassHologram, allureIntroHologram] burningOil2, burningOil3, burningOil4, firecracker1, firecracker2, firecracker3, firecracker4, firecracker5, spreadFragmentation, spreadFragmentation8, focusedFragmentation, spreadConcussion, spreadConcussion8, focusedConcussion, spreadFlash, spreadFlash8, focusedFlash, singleSpark, glassPiece, focusedGlass, fragrance, pheromone, mistCalming, odorDistressing, mistHealing, mistHealing2, mistWounding, distortion, smoke, boilingWater, glue, waste, mistAntiSlow, mistAntidote, mistSleep, denseShower, sparseShower, protectingBalmMelee, protectingBalmRanged, vulnerabilityBalm, resolutionDust, hasteSpray, slownessMist, eyeDrop, ironFiling, smellyDroplet, eyeShine, whiskeySpray, youthSprinkle, poisonCloud, blastNoSkMove, blastNoSkMelee, blastNoSkDisplace, blastNoSkAlter, blastNoSkWait, blastNoSkMoveItem, blastNoSkProject, blastNoSkApply, blastBonusSkMove, blastBonusSkMelee, blastBonusSkDisplace, blastBonusSkAlter, blastBonusSkWait, blastBonusSkMoveItem, blastBonusSkProject, blastBonusSkApply :: ItemKind -- Allure-specific cruiseAdHologram, outerAdHologram, victoriaClassHologram, allureIntroHologram :: ItemKind -- We take care (e.g., in burningOil below) that blasts are not faster -- than 100% fastest natural speed, or some frames would be skipped, -- which is a waste of perfectly good frames. -- * Parameterized blasts burningOil :: Int -> ItemKind burningOil n = ItemKind { isymbol = '*' , iname = "burning oil" , ifreq = [(toGroupName $ "burning oil" <+> tshow n, 1)] , iflavour = zipPlain [BrYellow] , icount = intToDice (4 + n * 4) , irarity = [(1, 1)] , iverbHit = "sear" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity (min 100 $ n `div` 2 * 10) , SetFlag Fragile, SetFlag Blast , AddSkill SkShine 2 ] , ieffects = [ Burn 1 , toOrganBad "pacified" (1 `d` 2) ] -- slips and frantically puts out fire , idesc = "Sticky oil, burning brightly." , ikit = [] } burningOil2 = burningOil 2 -- 2 steps, 2 turns burningOil3 = burningOil 3 -- 3 steps, 2 turns burningOil4 = burningOil 4 -- 4 steps, 2 turns firecracker :: Int -> ItemKind firecracker n = ItemKind { isymbol = '*' , iname = "firecracker" , ifreq = [(toGroupName $ if n == 5 then "firecracker" else "firecracker" <+> tshow n, 1)] , iflavour = zipPlain [brightCol !! ((n + 2) `mod` length brightCol)] , icount = if n <= 3 then 1 `d` min 2 n else 2 + 1 `d` 2 , irarity = [(1, 1)] , iverbHit = if n >= 4 then "singe" else "crack" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 , SetFlag Fragile, SetFlag Blast , AddSkill SkShine $ intToDice $ 1 + n `div` 2 ] , ieffects = [if n >= 4 then Burn 1 else RefillCalm (-2)] ++ [DropBestWeapon | n >= 4] ++ [ OnSmash $ Explode $ toGroupName $ "firecracker" <+> tshow (n - 1) | n >= 2 ] , idesc = "Scraps of burnt paper, covering little pockets of black powder, buffeted by colorful explosions." , ikit = [] } firecracker5 = firecracker 5 firecracker4 = firecracker 4 firecracker3 = firecracker 3 firecracker2 = firecracker 2 firecracker1 = firecracker 1 -- * Focused blasts spreadFragmentation = ItemKind { isymbol = '*' , iname = "fragmentation burst" , ifreq = [("violent fragmentation", 1)] , iflavour = zipPlain [Red] , icount = 16 -- strong but few, so not always hits target , irarity = [(1, 1)] , iverbHit = "tear apart" , iweight = 1 , idamage = 3 `d` 1 -- deadly and adjacent actor hit by 2 on average; -- however, moderate armour blocks completely , iaspects = [ ToThrow $ ThrowMod 100 20 4 -- 4 steps, 1 turn , SetFlag Lobable, SetFlag Fragile, SetFlag Blast , AddSkill SkShine 3, AddSkill SkHurtMelee $ -12 * 5 ] , ieffects = [DropItem 1 1 COrgan "condition"] , idesc = "Flying shards, flame and smoke." , ikit = [] } spreadFragmentation8 = spreadFragmentation { iname = "fragmentation burst" , ifreq = [("fragmentation", 1)] , icount = 8 , iaspects = [ ToThrow $ ThrowMod 100 10 2 -- 2 steps, 1 turn , SetFlag Lobable, SetFlag Fragile, SetFlag Blast , AddSkill SkShine 3, AddSkill SkHurtMelee $ -12 * 5 ] -- smaller radius, so worse for area effect, but twice the direct damage } focusedFragmentation = ItemKind { isymbol = '`' , iname = "deflagration ignition" -- improvised fertilizer, etc. , ifreq = [("focused fragmentation", 1)] , iflavour = zipPlain [BrYellow] , icount = 4 -- 32 in total vs 16; on average 4 hits , irarity = [(1, 1)] , iverbHit = "ignite" , iweight = 1 , idamage = 0 , iaspects = [ toLinger 0 -- 0 steps, 1 turn , SetFlag Fragile, SetFlag Blast ] -- when the target position is occupied, the explosion starts one step -- away, hence we set range to 0 steps, to limit dispersal , ieffects = [OnSmash $ Explode "fragmentation"] , idesc = idesc spreadFragmentation , ikit = [] } spreadConcussion = ItemKind { isymbol = '*' , iname = "concussion blast" , ifreq = [("violent concussion", 1)] , iflavour = zipPlain [Magenta] , icount = 16 , irarity = [(1, 1)] , iverbHit = "shock" , iweight = 1 , idamage = 1 `d` 1 -- only air pressure, so not as deadly as fragmentation, -- but armour can't block completely that easily , iaspects = [ ToThrow $ ThrowMod 100 20 4 -- 4 steps, 1 turn , SetFlag Lobable, SetFlag Fragile, SetFlag Blast , AddSkill SkShine 3, AddSkill SkHurtMelee $ -8 * 5 ] -- outdoors it has short range, but we only model indoors in the game; -- it's much faster than black powder shock wave, but we are beyond -- human-noticeable speed differences on short distances anyway , ieffects = [ DropItem maxBound 1 CEqp "misc armor" , PushActor (ThrowMod 400 25 1) -- 1 step, fast; after DropItem -- this produces spam for braced actors; too bad , toOrganBad "immobile" 3 -- no balance , toOrganBad "deafened" 23 ] , idesc = "Shock wave, hot gases, some fire and smoke." , ikit = [] } spreadConcussion8 = spreadConcussion { iname = "concussion blast" , ifreq = [("concussion", 1)] , icount = 8 , iaspects = [ ToThrow $ ThrowMod 100 10 2 -- 2 steps, 1 turn , SetFlag Lobable, SetFlag Fragile, SetFlag Blast , AddSkill SkShine 3, AddSkill SkHurtMelee $ -8 * 5 ] } focusedConcussion = ItemKind { isymbol = '`' , iname = "detonation ignition" -- stabilized high explosive liquid , ifreq = [("focused concussion", 1)] , iflavour = zipPlain [BrYellow] , icount = 4 , irarity = [(1, 1)] , iverbHit = "ignite" , iweight = 1 , idamage = 0 , iaspects = [ toLinger 0 -- 0 steps, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [OnSmash $ Explode "concussion"] , idesc = idesc spreadConcussion , ikit = [] } spreadFlash = ItemKind { isymbol = '`' , iname = "magnesium flash" -- or aluminum, but let's stick to one , ifreq = [("violent flash", 1)] , iflavour = zipPlain [BrWhite] , icount = 16 , irarity = [(1, 1)] , iverbHit = "dazzle" , iweight = 1 , idamage = 0 , iaspects = [ ToThrow $ ThrowMod 100 20 4 -- 4 steps, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkShine 5 ] , ieffects = [toOrganBad "blind" 5, toOrganBad "weakened" 20] -- Wikipedia says: blind for five seconds and afterimage -- for much longer, harming aim , idesc = "A very bright flash of fire." , ikit = [] } spreadFlash8 = spreadFlash { iname = "spark" , ifreq = [("spark", 1)] , icount = 8 , iverbHit = "blind" , iaspects = [ ToThrow $ ThrowMod 100 10 2 -- 2 steps, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkShine 5 ] } focusedFlash = ItemKind { isymbol = '`' , iname = "magnesium ignition" , ifreq = [("focused flash", 1)] , iflavour = zipPlain [BrYellow] , icount = 4 , irarity = [(1, 1)] , iverbHit = "ignite" , iweight = 1 , idamage = 0 , iaspects = [ toLinger 0 -- 0 steps, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [OnSmash $ Explode "spark"] , idesc = idesc spreadFlash , ikit = [] } singleSpark = spreadFlash { iname = "single spark" , ifreq = [("single spark", 1)] , icount = 1 , iverbHit = "spark" , iaspects = [ toLinger 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkShine 3 ] , ieffects = [] , idesc = "A glowing ember." , ikit = [] } glassPiece = ItemKind { isymbol = '*' , iname = "glass piece" , ifreq = [("glass hail", 1)] , iflavour = zipPlain [Blue] , icount = 8 , irarity = [(1, 1)] , iverbHit = "cut" , iweight = 1 , idamage = 2 `d` 1 , iaspects = [ ToThrow $ ThrowMod 100 20 4 -- 4 steps, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkHurtMelee $ -15 * 5 ] -- brittle, not too dense; armor blocks , ieffects = [] , idesc = "Swift, sharp edges." , ikit = [] } focusedGlass = glassPiece -- when blowing up windows { ifreq = [("focused glass hail", 1)] , icount = 4 , iaspects = [ toLinger 0 -- 0 steps, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkHurtMelee $ -15 * 5 ] , ieffects = [OnSmash $ Explode "glass hail"] } -- * Assorted blasts don't induce conditions or not mainly so fragrance = ItemKind { isymbol = '`' , iname = "fragrance" -- instant, fast fragrance , ifreq = [("fragrance", 1)] , iflavour = zipPlain [Magenta] , icount = 12 , irarity = [(1, 1)] , iverbHit = "engulf" , iweight = 1 , idamage = 0 , iaspects = [ toLinger 10 -- 2 steps, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [Impress, toOrganGood "rose-smelling" 45] -- Linger 10, because sometimes it takes 2 turns due to starting just -- before actor turn's end (e.g., via a necklace). , idesc = "A pleasant scent." , ikit = [] } pheromone = ItemKind { isymbol = '`' , iname = "musky whiff" -- a kind of mist rather than fragrance , ifreq = [("pheromone", 1)] , iflavour = zipPlain [BrMagenta] , icount = 16 , irarity = [(1, 1)] , iverbHit = "tempt" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 10 -- 2 steps, 2 turns , SetFlag Fragile, SetFlag Blast ] , ieffects = [Dominate] , idesc = "A sharp, strong scent." , ikit = [] } mistCalming = ItemKind -- unused { isymbol = '`' , iname = "mist" , ifreq = [("calming mist", 1)] , iflavour = zipPlain [BrGreen] , icount = 8 , irarity = [(1, 1)] , iverbHit = "sooth" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [RefillCalm 2] , idesc = "A soothing, gentle cloud." , ikit = [] } odorDistressing = ItemKind { isymbol = '`' , iname = "distressing whiff" , ifreq = [("distressing odor", 1)] , iflavour = zipFancy [BrRed] -- salmon , icount = 8 , irarity = [(1, 1)] , iverbHit = "distress" , iweight = 1 , idamage = 0 , iaspects = [ toLinger 10 -- 2 steps, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [ RefillCalm (-10) , toOrganBad "foul-smelling" (20 + 1 `d` 5) , toOrganBad "impatient" (2 + 1 `d` 2) ] , idesc = "It turns the stomach." -- and so can't stand still , ikit = [] } mistHealing = ItemKind { isymbol = '`' , iname = "mist" -- powerful, so slow and narrow , ifreq = [("healing mist", 1)] , iflavour = zipFancy [BrGreen] , icount = 8 , irarity = [(1, 1)] , iverbHit = "revitalize" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkShine 1 ] , ieffects = [RefillHP 2] , idesc = "It fills the air with light and life. And lots of organic chemicals." , ikit = [] } mistHealing2 = ItemKind { isymbol = '`' , iname = "mist" , ifreq = [("healing mist 2", 1)] , iflavour = zipPlain [Green] , icount = 8 , irarity = [(1, 1)] , iverbHit = "revitalize" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkShine 2 ] , ieffects = [RefillHP 4] , idesc = "At its touch, wounds close and bruises fade. Not the most frugal way to apply nanobots, though." , ikit = [] } mistWounding = ItemKind { isymbol = '`' , iname = "mist" , ifreq = [("wounding mist", 1)] , iflavour = zipPlain [BrRed] , icount = 8 , irarity = [(1, 1)] , iverbHit = "devitalize" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [RefillHP (-2)] , idesc = "The air itself stings and itches." , ikit = [] } distortion = ItemKind { isymbol = 'v' , iname = "vortex" , ifreq = [("distortion", 1)] , iflavour = zipPlain [White] , icount = 8 -- braced are immune to Teleport; avoid failure messages , irarity = [(1, 1)] , iverbHit = "engulf" , iweight = 1 , idamage = 0 , iaspects = [ toLinger 10 -- 2 steps, 1 turn , SetFlag Lobable, SetFlag Fragile, SetFlag Blast ] , ieffects = [Teleport $ 15 + 1 `d` 10] , idesc = "The air shifts oddly, as though light is being warped." , ikit = [] } smoke = ItemKind -- when stuff burns out -- unused { isymbol = '`' , iname = "smoke fume" -- pluralizes better than 'smokes' , ifreq = [("smoke", 1)] , iflavour = zipPlain [BrBlack] , icount = 16 , irarity = [(1, 1)] , iverbHit = "choke" -- or "obscure" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 20 -- 4 steps, 2 turns , SetFlag Fragile, SetFlag Blast ] , ieffects = [toOrganBad "withholding" (5 + 1 `d` 3)] -- choking and tears, can roughly see, but not aim , idesc = "Twirling clouds of grey smoke." , ikit = [] } boilingWater = ItemKind { isymbol = '*' , iname = "boiling water" , ifreq = [("boiling water", 1)] , iflavour = zipPlain [White] , icount = 18 , irarity = [(1, 1)] , iverbHit = "boil" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 30 -- 6 steps, 2 turns , SetFlag Fragile, SetFlag Blast ] , ieffects = [Burn 1] , idesc = "It bubbles and hisses." , ikit = [] } glue = ItemKind { isymbol = '*' , iname = "glue droplet" , ifreq = [("glue", 1)] , iflavour = zipPlain [Cyan] , icount = 8 -- Paralyze doesn't stack; avoid failure messages , irarity = [(1, 1)] , iverbHit = "glue" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 20 -- 4 steps, 2 turns , SetFlag Fragile, SetFlag Blast ] , ieffects = [Paralyze 10] , idesc = "Thick and clinging." , ikit = [] } waste = ItemKind { isymbol = '*' , iname = "waste piece" , ifreq = [("waste", 1)] , iflavour = zipPlain [Brown] , icount = 16 , irarity = [(1, 1)] , iverbHit = "splosh" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [ toOrganBad "foul-smelling" (30 + 1 `d` 10) , toOrganBad "dispossessed" (10 + 1 `d` 5) ] , idesc = "Sodden and foul-smelling." , ikit = [] } mistAntiSlow = ItemKind { isymbol = '`' , iname = "mist" , ifreq = [("anti-slow mist", 1)] , iflavour = zipFancy [BrYellow] , icount = 8 , irarity = [(1, 1)] , iverbHit = "propel" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [DropItem 1 1 COrgan "slowed"] , idesc = "A cleansing rain." , ikit = [] } mistAntidote = ItemKind { isymbol = '`' , iname = "mist" , ifreq = [("antidote mist", 1)] , iflavour = zipFancy [BrBlue] , icount = 8 , irarity = [(1, 1)] , iverbHit = "cure" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [DropItem 1 maxBound COrgan "poisoned"] , idesc = "Washes away death's dew." , ikit = [] } mistSleep = ItemKind { isymbol = '`' , iname = "mist" , ifreq = [("sleep mist", 1)] , iflavour = zipFancy [BrMagenta] , icount = 8 , irarity = [(1, 1)] , iverbHit = "put to sleep" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [PutToSleep] , idesc = "Lulls weary warriors." , ikit = [] } -- * Condition-inducing blasts -- Almost all have @toLinger 10@, that travels 2 steps in 1 turn. -- These are very fast projectiles, not getting into the way of big -- actors and not burdening the engine for long. -- A few are slower 'mists'. denseShower = ItemKind { isymbol = '`' , iname = "dense shower" , ifreq = [("dense shower", 1)] , iflavour = zipFancy [Green] , icount = 12 , irarity = [(1, 1)] , iverbHit = "strengthen" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood "strengthened" 5] , idesc = "A thick rain of droplets." , ikit = [] } sparseShower = ItemKind { isymbol = '`' , iname = "sparse shower" , ifreq = [("sparse shower", 1)] , iflavour = zipFancy [Red] , icount = 8 , irarity = [(1, 1)] , iverbHit = "weaken" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganBad "weakened" 7] , idesc = "Light droplets that cling to clothing." , ikit = [] } protectingBalmMelee = ItemKind { isymbol = '`' , iname = "balm droplet" , ifreq = [("melee protective balm", 1)] , iflavour = zipFancy [Brown] , icount = 16 , irarity = [(1, 1)] , iverbHit = "balm" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood "protected from melee" (3 + 1 `d` 3)] , idesc = "A thick ointment that hardens the skin." , ikit = [] } protectingBalmRanged = ItemKind { isymbol = '`' , iname = "balm droplet" , ifreq = [("ranged protective balm", 1)] , iflavour = zipPlain [BrYellow] , icount = 16 , irarity = [(1, 1)] , iverbHit = "balm" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood "protected from ranged" (3 + 1 `d` 3)] , idesc = "Grease that protects from flying death." , ikit = [] } vulnerabilityBalm = ItemKind { isymbol = '`' , iname = "fluorescent paint" , ifreq = [("fluorescent paint", 1)] , iflavour = zipPlain [BrRed] , icount = 16 , irarity = [(1, 1)] , iverbHit = "paint" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganBad "painted" (3 + 1 `d` 3)] , idesc = "Softly glowing red pain that marks a target." , ikit = [] } resolutionDust = ItemKind { isymbol = '`' , iname = "resolution dust" , ifreq = [("resolution dust", 1)] , iflavour = zipPlain [Brown] , icount = 16 , irarity = [(1, 1)] , iverbHit = "calm" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood "resolute" (3 + 1 `d` 3)] -- short enough duration that @calmEnough@ not a big problem , idesc = "A handful of honest earth, to strengthen the soul." , ikit = [] } hasteSpray = ItemKind { isymbol = '`' , iname = "haste spray" , ifreq = [("haste spray", 1)] , iflavour = zipFancy [BrYellow] , icount = 16 , irarity = [(1, 1)] , iverbHit = "haste" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood "hasted" (3 + 1 `d` 3)] , idesc = "A quick spurt." , ikit = [] } slownessMist = ItemKind { isymbol = '`' , iname = "slowness mist" , ifreq = [("slowness mist", 1)] , iflavour = zipPlain [BrBlue] , icount = 8 , irarity = [(1, 1)] , iverbHit = "slow" , iweight = 0 , idamage = 0 , iaspects = [toVelocity 5, SetFlag Fragile, SetFlag Blast] -- 1 step, 1 turn, mist, slow , ieffects = [toOrganBad "slowed" (3 + 1 `d` 3)] , idesc = "Clammy fog, making each movement an effort." , ikit = [] } eyeDrop = ItemKind { isymbol = '`' , iname = "eye drop" , ifreq = [("eye drop", 1)] , iflavour = zipFancy [BrCyan] , icount = 16 , irarity = [(1, 1)] , iverbHit = "cleanse" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood "far-sighted" (3 + 1 `d` 3)] , idesc = "Not to be taken orally." , ikit = [] } ironFiling = ItemKind { isymbol = '`' , iname = "iron filing" , ifreq = [("iron filing", 1)] , iflavour = zipPlain [Red] , icount = 16 , irarity = [(1, 1)] , iverbHit = "blind" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganBad "blind" (10 + 1 `d` 10)] , idesc = "A shaving of bright metal." , ikit = [] } smellyDroplet = ItemKind { isymbol = '`' , iname = "smelly droplet" , ifreq = [("smelly droplet", 1)] , iflavour = zipFancy [Blue] , icount = 16 , irarity = [(1, 1)] , iverbHit = "sensitize" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood "keen-smelling" (5 + 1 `d` 3)] , idesc = "A viscous lump that stains the skin." , ikit = [] } eyeShine = ItemKind { isymbol = '`' , iname = "eye shine" , ifreq = [("eye shine", 1)] , iflavour = zipFancy [Cyan] , icount = 16 , irarity = [(1, 1)] , iverbHit = "smear" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood "shiny-eyed" (3 + 1 `d` 3)] , idesc = "They almost glow in the dark." , ikit = [] } whiskeySpray = ItemKind { isymbol = '`' , iname = "whiskey spray" , ifreq = [("whiskey spray", 1)] , iflavour = zipFancy [Brown] , icount = 16 , irarity = [(1, 1)] , iverbHit = "inebriate" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood "drunk" (3 + 1 `d` 3)] , idesc = "It burns in the best way." , ikit = [] } youthSprinkle = ItemKind { isymbol = '`' , iname = "youth sprinkle" , ifreq = [("youth sprinkle", 1)] , iflavour = zipFancy [BrGreen] , icount = 16 , irarity = [(1, 1)] , iverbHit = "sprinkle" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [ toOrganGood "rose-smelling" (40 + 1 `d` 20) , toOrganNoTimer "regenerating" ] , idesc = "Bright and smelling of the Spring." , ikit = [] } poisonCloud = ItemKind { isymbol = '`' , iname = "poison cloud" , ifreq = [("poison cloud", 1)] , iflavour = zipFancy [BrMagenta] , icount = 16 , irarity = [(1, 1)] , iverbHit = "poison" , iweight = 0 , idamage = 0 , iaspects = [ ToThrow $ ThrowMod 10 100 2 -- 2 steps, 2 turns , SetFlag Fragile, SetFlag Blast ] , ieffects = [toOrganNoTimer "poisoned"] , idesc = "Choking gas that stings the eyes." , ikit = [] } blastNoStat :: Text -> ItemKind blastNoStat grp = ItemKind { isymbol = '`' , iname = "mist" , ifreq = [(toGroupName $ grp <+> "mist", 1)] , iflavour = zipFancy [White] , icount = 12 , irarity = [(1, 1)] , iverbHit = "drain" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 10 -- 2 steps, 2 turns , SetFlag Fragile, SetFlag Blast ] , ieffects = [toOrganBad (toGroupName grp) (3 + 1 `d` 3)] , idesc = "Completely disables one personal faculty." , ikit = [] } blastNoSkMove = blastNoStat "immobile" blastNoSkMelee = blastNoStat "pacified" blastNoSkDisplace = blastNoStat "irreplaceable" blastNoSkAlter = blastNoStat "retaining" blastNoSkWait = blastNoStat "impatient" blastNoSkMoveItem = blastNoStat "dispossessed" blastNoSkProject = blastNoStat "withholding" blastNoSkApply = blastNoStat "parsimonious" blastBonusStat :: Text -> ItemKind blastBonusStat grp = ItemKind { isymbol = '`' , iname = "dew" , ifreq = [(toGroupName $ grp <+> "dew", 1)] , iflavour = zipFancy [White] , icount = 12 , irarity = [(1, 1)] , iverbHit = "elevate" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 10 -- 2 steps, 2 turns , SetFlag Fragile, SetFlag Blast ] , ieffects = [toOrganGood (toGroupName grp) (20 + 1 `d` 5)] , idesc = "Temporarily enhances the given personal faculty." , ikit = [] } blastBonusSkMove = blastBonusStat "more mobile" blastBonusSkMelee = blastBonusStat "more combative" blastBonusSkDisplace = blastBonusStat "more displacing" blastBonusSkAlter = blastBonusStat "more altering" blastBonusSkWait = blastBonusStat "more patient" blastBonusSkMoveItem = blastBonusStat "more tidy" blastBonusSkProject = blastBonusStat "more projecting" blastBonusSkApply = blastBonusStat "more practical" -- * Allure-specific -- ** Lore blasts -- They exist for a short time only, but the lore can be read -- from the lore menu. Only optional story bits should go there, -- because some players may not even notice them (at first, at least). -- This is designed not to spam gameplay with story. Gameplay first. -- Generally, 3 to 5 blasts of each kind should suffice for variety. -- More would induce excessive repetition of some to see all -- (they are shown at random). With mild exceptions, they should have -- no effects. cruiseAdHologram = ItemKind { isymbol = '`' , iname = "cruise ad hologram" , ifreq = [("cruise ad hologram", 1), ("advertisement", 10)] , iflavour = zipFancy [BrMagenta] , icount = 8 , irarity = [(1, 1)] , iverbHit = "excite" , iweight = 0 -- delay of 1 turn at the start, to easily read the text , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [toOrganGood "resolute" (5 + 1 `d` 2), DropBestWeapon] , idesc = "The fitful holographic clip shows a couple that laughs, watches in silence Saturn's rings through a huge window, throws treats to a little rhino frolicking in reduced gravity, runs through corridors wearing alien masks in a mock chase. An exited female voice proclaims: \"...safety, security and comfort...for each of your senses...personalized life support zones...robot servants...guessing your every wish...\"" , ikit = [] } outerAdHologram = cruiseAdHologram { iname = "cruise ad hologram" , ifreq = [("advertisement", 20)] , icount = 4 , ieffects = [] -- weak, 4 particles, no effect , idesc = "A composed young man in a hat looks straight into your eyes with unwavering stare and extols the opportunities, freedom and excitement of the outer Solar System frontier life with unshakable conviction. Names of Neptune-area realtors scroll at the bottom in small font with oversize serifs." } victoriaClassHologram = outerAdHologram { iname = "space fleet hologram" , ifreq = [("story-telling", 20)] , iflavour = zipFancy [BrBlue] , icount = 1 , iverbHit = "bore" , idesc = "A series of huge spaceships zoom in and out of view in a solemn procession. Male voice drones over crackling static: Victoria-class cruise liners are the largest passenger ships ever serially manufactured and the third largest in general, including transport vessel series. Bigger ships are sometimes cobbled ad-hoc, by wiring together cheap modules and primitive cargo hulls welded in space, but they are rarely certified for public commercial operation. Victoria-class passenger cruisers are produced for over three decades now, in slowly evolving configurations, one every two years on average. The design is as conservative, as possible. A disc large enough for comfortable artificial gravity through constant spinning. Fusion reactor in the middle of the axle powering engines protruding far back from the rear plane. Meteor shield at the front. Numerous redundant rechargeable power sources and autonomous life support areas within several independently pressurized slices of the disc, eliminating the \"all locked in a single can, breathing the same air\" space travel grievance. Actually, everything is redundant twice over, due to strict regulations. To sum it up, these are the most boring spaceships in the galaxy." } allureIntroHologram = victoriaClassHologram { iname = "spaceship hologram" , ifreq = [("story-telling", 10)] , idesc = "A wavy 3D wireframe of a spaceship rotates ponderously. Male voice drones: Allure of the Stars belongs to a long line of luxurious orbit-to-orbit cruise liners, the Victoria-class. The ship is named after the largest passenger sea vessel of the early 21st century, with which it shares the grandeur and extravagance. This particular Victoria-class specimen has been designed for long cruises to gas giants, their moons and the moon cities (with their notorious saloons and night life). It has a meteor shield in the form of a flat, multi-layer. unpressurized cargo bay covering the front plane. Such extra cargo capacity enables long space journeys with no limits on resource usage. On shorter legs of the journeys it also enables opportunistic mass cargo transport (in accordance to strictest regulations and completely isolated from the airflow on passenger decks), which is always in demand at the profusely productive, but scarcely populated Solar System frontier. It also makes the unit much thicker than usual: the length from the tip of the cargo bay to the engines' exhausts is almost two thirds of the diameter of the disk. All in all, it is a particularly sturdy and self-sufficient member of a class famed for exceptional resilience and safety." } Allure-0.9.5.0/GameDefinition/Content/ItemKindEmbed.hs0000644000000000000000000005231507346545000020577 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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. -- -- | Definitions of items embedded in map tiles. module Content.ItemKindEmbed ( embeds ) where import Prelude () import Game.LambdaHack.Core.Prelude import Game.LambdaHack.Content.ItemKind import Game.LambdaHack.Core.Dice import Game.LambdaHack.Definition.Ability import Game.LambdaHack.Definition.Color import Game.LambdaHack.Definition.Defs import Game.LambdaHack.Definition.Flavour embeds :: [ItemKind] embeds = [scratchOnWall, obscenePictogram, subtleFresco, treasureCache, treasureCacheTrap, signboardExit, signboardEmbed, signboardMerchandise, fireSmall, fireBig, frost, rubble, doorwayTrapTemplate, doorwayTrap1, doorwayTrap2, doorwayTrap3, stairsUp, stairsDown, escape, staircaseTrapUp, staircaseTrapDown, pulpit, shallowWater, straightPath, frozenGround] -- Allure-specific ++ [blackStarrySky, disengagedDocking, ruinedFirstAidKit, wall3dBillboard, depositBox, jewelryCase, liftUp, liftDown, liftTrap, liftTrap2, shuttleHardware, machineOil, crudeWeld, decontaminator] scratchOnWall, obscenePictogram, subtleFresco, treasureCache, treasureCacheTrap, signboardExit, signboardEmbed, signboardMerchandise, fireSmall, fireBig, frost, rubble, doorwayTrapTemplate, doorwayTrap1, doorwayTrap2, doorwayTrap3, stairsUp, stairsDown, escape, staircaseTrapUp, staircaseTrapDown, pulpit, shallowWater, straightPath, frozenGround :: ItemKind -- Allure-specific blackStarrySky, disengagedDocking, ruinedFirstAidKit, wall3dBillboard, depositBox, jewelryCase, liftUp, liftDown, liftTrap, liftTrap2, shuttleHardware, machineOil, crudeWeld, decontaminator :: ItemKind -- Make sure very few walls are substantially useful, e.g., caches, -- and none that are secret. Otherwise the player will spend a lot of time -- bumping walls, which is boring compared to fights or dialogues -- and ever worse, the player will bump all secret walls, wasting time -- and foregoing the fun of guessing how to find entrance to a disjoint part -- of the level by bumping the least number of secret walls. scratchOnWall = ItemKind { isymbol = '?' , iname = "claw mark" , ifreq = [("scratch on wall", 1)] , iflavour = zipPlain [BrBlack] , icount = 1 , irarity = [(1, 1)] , iverbHit = "scratch" , iweight = 1000 , idamage = 0 , iaspects = [SetFlag Durable] , ieffects = [ VerbMsg "start making sense of the scratches" , Detect DetectHidden 3 ] , idesc = "A seemingly random series of scratches, carved deep into the wall." , ikit = [] } obscenePictogram = ItemKind { isymbol = '*' , iname = "repulsing graffiti" , ifreq = [("obscene pictogram", 1)] , iflavour = zipPlain [BrMagenta] , icount = 1 , irarity = [(1, 1)] , iverbHit = "infuriate" , iweight = 1000 , idamage = 0 , iaspects = [Timeout 7, SetFlag Durable] , ieffects = [ VerbMsg "enter inexplicable rage at a glimpse of the inscrutable graffiti" , RefillCalm (-20) , OneOf [ toOrganGood "strengthened" (3 + 1 `d` 2) , CreateItem CInv "sandstone rock" timerNone ] ] , idesc = "" -- alien writing? or runaway robot AI? , ikit = [] } subtleFresco = ItemKind { isymbol = '*' , iname = "subtle mural" , ifreq = [("subtle fresco", 1)] , iflavour = zipPlain [BrGreen] , icount = 1 , irarity = [(1, 1)] , iverbHit = "sooth" , iweight = 1000 , idamage = 0 , iaspects = [Timeout 7, SetFlag Durable] , ieffects = [ VerbMsg "feel refreshed by the subtle fresco" , toOrganGood "far-sighted" (3 + 1 `d` 2) , toOrganGood "keen-smelling" (3 + 1 `d` 2) ] -- hearing gets a boost through bracing, so no need here , idesc = "Expensive yet tasteful." , ikit = [] } treasureCache = ItemKind { isymbol = '0' , iname = "set" , ifreq = [("abandoned cache", 1)] , iflavour = zipPlain [BrBlue] , icount = 1 , irarity = [(1, 1)] , iverbHit = "crash" , iweight = 10000 , idamage = 0 , iaspects = [ELabel "of odds and ends", SetFlag Durable] , ieffects = [CreateItem CGround "common item" timerNone] , idesc = "If this stash is hidden, it's in plain sight. Or, more probably, it's just tucked aside so that it doesn't get in the way. Whomever worked there, apparently failed to return and retrieve his belongings." , ikit = [] } treasureCacheTrap = ItemKind { isymbol = '^' , iname = "anti-theft protection" , ifreq = [("jewelry display trap", 1)] , iflavour = zipPlain [Red] , icount = 1 , irarity = [(1, 1)] , iverbHit = "taint" , iweight = 1000 , idamage = 0 , iaspects = [] -- not Durable, springs at most once , ieffects = [OneOf [ toOrganBad "blind" (10 + 1 `d` 10) , RefillCalm (-99) , Explode "focused concussion" , RefillCalm (-1), RefillCalm (-1), RefillCalm (-1) ]] , idesc = "A display of such kingly trinkets warrants an autonomous guarding device. The precaution is particularly understandable if some of the merchandise is capable of instantly frying video monitoring equipment across the hall." , ikit = [] } signboardExit = ItemKind { isymbol = '?' , iname = "sticker" , ifreq = [("signboard", 50)] , iflavour = zipPlain [BrMagenta] , icount = 1 , irarity = [(1, 1)] , iverbHit = "whack" , iweight = 10000 , idamage = 0 , iaspects = [SetFlag Durable] , ieffects = [Detect DetectExit 100] -- low tech, hence fully operational , idesc = "Mandatory emergency exit information in low-tech form." -- This is a rare tile so use it to convey some more backstory. , ikit = [] } signboardEmbed = signboardExit { iname = "notice" , ifreq = [("signboard", 50)] , ieffects = [Detect DetectEmbed 12] -- low tech, hence fully operational , idesc = "Detailed schematics for the maintenance crew." -- This is a rare tile so use it to convey some more backstory. } signboardMerchandise = signboardExit { iname = "shop list" , ifreq = [("signboard", 50)] , ieffects = [Detect DetectLoot 20] -- high tech, so slightly confused , idesc = "A list of nearby commercial outlets, constantly updated by tracking merchandise not registered as passenger property. Customers are kindly asked to refrain from littering in this heavily monitored public area." } fireSmall = ItemKind { isymbol = '%' , iname = "small fire" , ifreq = [("small fire", 1)] , iflavour = zipPlain [BrRed] , icount = 1 , irarity = [(1, 1)] , iverbHit = "burn" , iweight = 10000 , idamage = 0 , iaspects = [SetFlag Durable] , ieffects = [Burn 1, Explode "single spark"] , idesc = "A few small logs, burning brightly." , ikit = [] } fireBig = fireSmall { isymbol = '0' , iname = "big fire" , ifreq = [("big fire", 1)] , ieffects = [ Burn 2 , CreateItem CInv "wooden torch" timerNone , Explode "spark" ] , idesc = "Glowing with light and warmth." , ikit = [] } frost = ItemKind { isymbol = '^' , iname = "frost" , ifreq = [("frost", 1)] , iflavour = zipPlain [BrBlue] , icount = 1 , irarity = [(1, 1)] , iverbHit = "burn" , iweight = 10000 , idamage = 0 , iaspects = [SetFlag Durable] , ieffects = [ Burn 1 -- sensory ambiguity between hot and cold , RefillCalm 20 -- cold reason , PushActor (ThrowMod 400 10 1) ] -- slippery ice , idesc = "Intricate patterns of shining ice." , ikit = [] } rubble = ItemKind { isymbol = '&' , iname = "rubble" , ifreq = [("rubble", 1)] , iflavour = zipPlain [BrYellow] , icount = 1 , irarity = [(1, 1)] , iverbHit = "bury" , iweight = 100000 , idamage = 0 , iaspects = [SetFlag Durable] , ieffects = [OneOf [ Explode "focused glass hail" , Summon "mobile animal" $ 1 `dL` 2 , toOrganNoTimer "poisoned" , CreateItem CGround "common item" timerNone , RefillCalm (-1), RefillCalm (-1), RefillCalm (-1) , RefillCalm (-1), RefillCalm (-1), RefillCalm (-1) ]] , idesc = "Broken chunks of foam concrete, glass and torn and burned equipment." , ikit = [] } doorwayTrapTemplate = ItemKind { isymbol = '+' , iname = "doorway trap" , ifreq = [("doorway trap unknown", 1)] , iflavour = zipPlain brightCol , icount = 1 , irarity = [(1, 1)] , iverbHit = "cripple" , iweight = 10000 , idamage = 0 , iaspects = [HideAs "doorway trap unknown"] -- not Durable, springs at most once , ieffects = [] , idesc = "Just turn the handle..." , ikit = [] } doorwayTrap1 = doorwayTrapTemplate { ifreq = [("doorway trap", 50)] , ieffects = [toOrganBad "blind" $ (1 `dL` 4) * 5] -- , idesc = "" } doorwayTrap2 = doorwayTrapTemplate { ifreq = [("doorway trap", 25)] , ieffects = [toOrganBad "slowed" $ (1 `dL` 4) * 10] -- , idesc = "" } doorwayTrap3 = doorwayTrapTemplate { ifreq = [("doorway trap", 25)] , ieffects = [toOrganBad "weakened" $ (1 `dL` 4) * 10 ] -- , idesc = "" } stairsUp = ItemKind { isymbol = '<' , iname = "flight" , ifreq = [("staircase up", 1)] , iflavour = zipPlain [BrWhite] , icount = 1 , irarity = [(1, 1)] , iverbHit = "crash" -- the verb is only used when the item hits, -- not when it's applied otherwise, e.g., from tile , iweight = 100000 , idamage = 0 , iaspects = [ELabel "of steps", SetFlag Durable] , ieffects = [Ascend True] , idesc = "Stairs that rise towards the spaceship core." , ikit = [] } stairsDown = stairsUp { isymbol = '>' , ifreq = [("staircase down", 1)] , ieffects = [Ascend False] , idesc = "Stairs that descend towards the outer ring." } escape = stairsUp { isymbol = 'E' , iname = "way" , ifreq = [("escape", 1)] , iflavour = zipPlain [BrYellow] , iaspects = [SetFlag Durable] , ieffects = [Escape] , idesc = "May this nightmare have an end?" -- generic escape, so the text should be too; -- for moon outdoors, spaceship, everywhere } staircaseTrapUp = ItemKind { isymbol = '^' , iname = "staircase trap" , ifreq = [("staircase trap up", 1)] , iflavour = zipPlain [Red] , icount = 1 , irarity = [(1, 1)] , iverbHit = "buffet" , iweight = 10000 , idamage = 0 , iaspects = [] -- not Durable, springs at most once , ieffects = [ VerbMsg "be caught in decompression blast" , Teleport $ 3 + 1 `dL` 10 ] , idesc = "" , ikit = [] } -- Needs to be separate from staircaseTrapUp, to make sure the item is -- registered after up staircase (not only after down staircase) -- so that effects are invoked in the proper order and, e.g., teleport works. staircaseTrapDown = staircaseTrapUp { ifreq = [("staircase trap down", 1)] , iverbHit = "open up under" , ieffects = [ VerbMsg "tumble down the stairwell" , toOrganGood "drunk" (20 + 1 `d` 5) ] , idesc = "A treacherous slab, to teach those who are too proud." } pulpit = ItemKind { isymbol = '?' , iname = "VR harness" , ifreq = [("pulpit", 1)] , iflavour = zipFancy [BrYellow] , icount = 1 , irarity = [(1, 1)] , iverbHit = "immerse" , iweight = 10000 , idamage = 0 , iaspects = [] -- not Durable, springs at most once , ieffects = [ OneOf [ CreateItem CGround "any scroll" timerNone , Detect DetectAll 20 , Paralyze $ (1 `dL` 6) * 10 , toOrganGood "drunk" (20 + 1 `d` 5) ] , Explode "story-telling" ] , idesc = "" , ikit = [] } shallowWater = ItemKind { isymbol = '~' , iname = "shallow water" , ifreq = [("shallow water", 1)] , iflavour = zipFancy [BrCyan] , icount = 1 , irarity = [(1, 1)] , iverbHit = "impede" , iweight = 10000 , idamage = 0 , iaspects = [SetFlag Durable] , ieffects = [ParalyzeInWater 2] , idesc = "" , ikit = [] } straightPath = ItemKind { isymbol = '.' , iname = "straight path" , ifreq = [("straight path", 1)] , iflavour = zipFancy [BrRed] , icount = 1 , irarity = [(1, 1)] , iverbHit = "propel" , iweight = 10000 , idamage = 0 , iaspects = [SetFlag Durable] , ieffects = [InsertMove 2] , idesc = "" , ikit = [] } frozenGround = ItemKind { isymbol = '.' , iname = "shade" , ifreq = [("frozen ground", 1)] , iflavour = zipFancy [BrBlue] , icount = 50 -- very thick ice and refreezes , irarity = [(1, 1)] , iverbHit = "betray" , iweight = 10000 , idamage = 0 , iaspects = [ELabel "of ice"] -- no Durable or some items would be impossible to pick up , ieffects = [PushActor (ThrowMod 400 10 1)] , idesc = "" , ikit = [] } -- * Allure-specific blackStarrySky = ItemKind { isymbol = ' ' , iname = "black starry sky" , ifreq = [("black starry sky", 1)] , iflavour = zipPlain [Black] , icount = 1 , irarity = [(1, 1)] , iverbHit = "awe" , iweight = 1000 , idamage = 0 , iaspects = [SetFlag Durable] , ieffects = [ VerbMsg "look into the void and it looks back" , OneOf [RefillCalm 5, RefillCalm (-5)] ] , idesc = "Occasionally a planet or the Sun zips by, but is unable to disperse the darkness. The black starscape constantly rotates. The frantic dance is silent, muted, indifferent. There is not even a hint of vibration, just the sense of heaviness and dizziness." -- appears only on 100% flavour tiles, useless and trivial to notice, so the writeup can be longer; who am I kidding, I can't make myself write condensed prose , ikit = [] } disengagedDocking = ItemKind { isymbol = '<' , iname = "disengaged docking gear" , ifreq = [("disengaged docking", 1)] , iflavour = zipPlain [BrBlack] , icount = 1 , irarity = [(1, 1)] , iverbHit = "disappoint" , iweight = 10000 , idamage = 0 , iaspects = [SetFlag Durable] , ieffects = [RefillCalm (-10)] , idesc = "Unfortunately this airlock has no space boat attached. Many fine small craft were originally docked with such sockets and clamps, but after the spaceship spontaneously deorbited Neptune, a lot of them were seen jettisoned and drifting astern. What a waste." , ikit = [] } ruinedFirstAidKit = ItemKind { isymbol = '?' , iname = "ruined first aid kit" , ifreq = [("ruined first aid kit", 1)] , iflavour = zipPlain [BrGreen] , icount = 1 , irarity = [(1, 1)] , iverbHit = "prick" , iweight = 1000 , idamage = 0 , iaspects = [] -- not Durable, springs at most once , ieffects = [ VerbMsg "inspect a tattered CPR instruction soaked in a residue of oily drugs" , OneOf [ toOrganNoTimer "poison resistant" , toOrganNoTimer "slow resistant" , toOrganGood "drunk" (20 + 1 `d` 5) ] , CreateItem CInv "needle" timerNone ] , idesc = "" -- regulations require; say HP not regenerated in the game; mention how to regain HP , ikit = [] } wall3dBillboard = ItemKind { isymbol = '*' , iname = "3D display" , ifreq = [("3D display", 1)] , iflavour = zipPlain [BrGreen] , icount = 1 , irarity = [(1, 1)] , iverbHit = "push" , iweight = 1000 , idamage = 0 , iaspects = [Timeout 3, SetFlag Durable] , ieffects = [ VerbMsg "make it cough up a wobbly standalone hologram once more" , OneOf [ Explode "advertisement" , Explode "story-telling" ] ] , idesc = "One can still make out excited moves of bleached shapes." , ikit = [] } depositBox = treasureCache { iname = "intact deposit box" , ifreq = [("deposit box", 1)] , iaspects = [SetFlag Durable] , ieffects = [CreateItem CGround "treasure" timerNone] -- can't be "valuable" or template items generated , idesc = "The reports of intact deposit boxes in the ship's safes have been greatly exaggerated, but there are still a few with glittering gems and gold, just waiting to be taken. Whomever looted these halls wasn't thorough or, judging from the damage to some of the boxes, was in an extreme hurry." } jewelryCase = treasureCache { iname = "jewelry case" , ifreq = [("jewelry case", 1)] , iaspects = [SetFlag Durable] , ieffects = [CreateItem CGround "any jewelry" timerNone] , idesc = "The customers of these shops must have been extremely well off, judging from abundance and quality of the jewelry, often extremely valuable in each of the artistic, material and nanotechnology aspects. Outer Solar System trips are expensive, but they offer unique trade and investment opportunities. Many deals are of the kind that can only be negotiated in a sealed room out of reach of satellites and screened by both parties. Among the jewelry are portable versions of such screening hardware --- in a truly breathtaking package." } liftUp = stairsUp { iname = "carriage" , ifreq = [("lift up", 1)] , iaspects = [SetFlag Durable] , idesc = "" -- describe inner levels of the ship } liftDown = stairsDown { iname = "carriage" , ifreq = [("lift down", 1)] , iaspects = [SetFlag Durable] , idesc = "" -- describe outer levels of the ship } liftTrap = staircaseTrapUp { iname = "elevator trap" -- hat tip to US heroes , ifreq = [("lift trap", 100)] , iverbHit = "squeeze" , ieffects = [ VerbMsg "be crushed by the sliding doors" , DropBestWeapon, Paralyze 10 ] , idesc = "" } liftTrap2 = liftTrap { ifreq = [("lift trap", 50)] , iverbHit = "choke" , ieffects = [ VerbMsg "inhale the gas lingering inside the cab" , toOrganBad "slowed" $ (1 `dL` 4) * 10 ] , idesc = "" } shuttleHardware = ItemKind { isymbol = '#' , iname = "shuttle hardware" , ifreq = [("shuttle hardware", 1)] , iflavour = zipPlain [BrWhite] , icount = 1 , irarity = [(1, 1)] , iverbHit = "resist" , iweight = 10000 , idamage = 0 , iaspects = [SetFlag Durable] , ieffects = [] , idesc = "While the hull of the spacecraft is intact, the flight hardware that normally lines the walls seems broken, worn out and often missing. This shuttle was probably scavenged for spare parts to repair other craft and it's unlikely that anything of use remains. This was the common \"taxi\" kind, fit only for lunar and orbital courier duties and single family trips. It's relatively cheap to operate, because no permanent airlock needs to be leased. Instead, the craft is brought through a large airlock to a dry-dock and serviced and even stored inside." , ikit = [] } machineOil = ItemKind { isymbol = '!' , iname = "oil layer" , ifreq = [("machine oil", 1)] , iflavour = zipPlain [BrYellow] , icount = 3 -- not durable, wears off , irarity = [(1, 1)] , iverbHit = "oil" , iweight = 1000 , idamage = 0 , iaspects = [] , ieffects = [PushActor (ThrowMod 600 10 1)] -- the high speed represents gliding rather than flying -- and so no need to lift actor's weight off the ground; -- low linger comes from abrupt halt over normal surface , idesc = "Slippery run out, probably from a life support equipment or vehicle engine." , ikit = [] } crudeWeld = ItemKind -- this is also an organ { isymbol = '_' , iname = "crude weld" , ifreq = [("crude weld", 1)] , iflavour = zipPlain [BrMagenta] , icount = 1 -- not durable, destroyed on activation , irarity = [(1, 1)] , iverbHit = "weld" , iweight = 3000 , idamage = 0 , iaspects = [AddSkill SkMove (-5), AddSkill SkDisplace (-1)] , ieffects = [Explode "spark"] , idesc = "This is a messy and irregularly layered weld, but no amount of kicking nor hammering makes any impression on it. A heavy duty cutting tool would be required." , ikit = [] } decontaminator = ItemKind { isymbol = 'o' , iname = "decontamination chamber" , ifreq = [("decontamination chamber", 1)] , iflavour = zipPlain [BrBlue] , icount = 1 , irarity = [(1, 1)] , iverbHit = "cleanse" , iweight = 500000 , idamage = 0 , iaspects = [SetFlag Durable] , ieffects = [ DropItem 1 1 COrgan "genetic flaw" , DropItem maxBound maxBound CEqp "common item" , DropItem maxBound maxBound CInv "common item" , DropItem maxBound maxBound CSha "common item" , DropItem maxBound maxBound CEqp "curious item" , DropItem maxBound maxBound CInv "curious item" , DropItem maxBound maxBound CSha "curious item" , DropItem maxBound maxBound CEqp "treasure" , DropItem maxBound maxBound CInv "treasure" , DropItem maxBound maxBound CSha "treasure" , toOrganGood "rose-smelling" (20 + 1 `d` 5) ] , idesc = "The area is under quarantine. No departure is permitted without decontamination. Personal belongings are to be decontaminated separately." , ikit = [] } Allure-0.9.5.0/GameDefinition/Content/ItemKindOrgan.hs0000644000000000000000000005171207346545000020631 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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 organ definitions. module Content.ItemKindOrgan ( organs ) where import Prelude () import Game.LambdaHack.Core.Prelude import Game.LambdaHack.Content.ItemKind import Game.LambdaHack.Core.Dice import Game.LambdaHack.Definition.Ability import Game.LambdaHack.Definition.Color import Game.LambdaHack.Definition.Defs import Game.LambdaHack.Definition.Flavour organs :: [ItemKind] organs = [fist, foot, hookedClaw, smallClaw, snout, smallJaw, jaw, largeJaw, antler, horn, rhinoHorn, tentacle, thorn, boilingFissure, arsenicFissure, sulfurFissure, beeSting, sting, venomTooth, venomFang, screechingBeak, largeTail, hugeTail, armoredSkin, bark, eye3, eye6, eye8, vision6, vision12, vision16, nostril, ear3, ear6, ear8, rattleOrgan, insectMortality, sapientBrain, animalBrain, speedGland5, speedGland10, scentGland, boilingVent, arsenicVent, sulfurVent, bonusHP, braced, asleep, impressed] -- Allure-specific ++ [smallBeak, razor, liveWire, robotBrain, hullPlating, mouthVent, geneticFlaw3, geneticFlaw10] fist, foot, hookedClaw, smallClaw, snout, smallJaw, jaw, largeJaw, antler, horn, rhinoHorn, tentacle, thorn, boilingFissure, arsenicFissure, sulfurFissure, beeSting, sting, venomTooth, venomFang, screechingBeak, largeTail, hugeTail, armoredSkin, bark, eye3, eye6, eye8, vision6, vision12, vision16, nostril, ear3, ear6, ear8, rattleOrgan, insectMortality, sapientBrain, animalBrain, speedGland5, speedGland10, scentGland, boilingVent, arsenicVent, sulfurVent, bonusHP, braced, asleep, impressed :: ItemKind -- Allure-specific smallBeak, razor, liveWire, robotBrain, hullPlating, mouthVent, geneticFlaw3, geneticFlaw10 :: ItemKind -- Weapons -- * Human weapon organs fist = ItemKind { isymbol = ',' , iname = "fist" , ifreq = [("fist", 100)] , iflavour = zipPlain [Red] , icount = 2 , irarity = [(1, 1)] , iverbHit = "punch" , iweight = 2000 , idamage = 4 `d` 1 , iaspects = [SetFlag Durable, SetFlag Meleeable] , ieffects = [] , idesc = "Simple but effective." , ikit = [] } foot = fist { iname = "foot" , ifreq = [("foot", 50)] , iverbHit = "kick" , idamage = 4 `d` 1 , idesc = "A weapon you can still use if disarmed." -- great example of tutorial hints inside a flavourful text } -- * Other weapon organs hookedClaw = fist { iname = "hooked claw" , ifreq = [("hooked claw", 50)] , icount = 2 -- even if more, only the fore claws used for fighting , iverbHit = "hook" , idamage = 2 `d` 1 , iaspects = Timeout (12 - 1 `dL` 3) : iaspects fist , ieffects = [toOrganBad "slowed" 2] , idesc = "A curved talon." } smallClaw = fist { iname = "small claw" , ifreq = [("small claw", 50)] , iverbHit = "slash" , idamage = 2 `d` 1 , idesc = "A pearly spike." } snout = fist { iname = "snout" , ifreq = [("snout", 10)] , icount = 1 , iverbHit = "bite" , idamage = 2 `d` 1 , idesc = "Sensitive and wide-nostrilled." } smallJaw = fist { iname = "small jaw" , ifreq = [("small jaw", 20)] , icount = 1 , iverbHit = "rip" , idamage = 3 `d` 1 , idesc = "Filled with small, even teeth." } jaw = fist { iname = "jaw" , ifreq = [("jaw", 20)] , icount = 1 , iverbHit = "rip" , idamage = 5 `d` 1 , idesc = "Delivers a powerful bite." } largeJaw = fist { iname = "large jaw" , ifreq = [("large jaw", 100)] , icount = 1 , iverbHit = "crush" , idamage = 10 `d` 1 , iaspects = [Timeout $ 2 + 1 `d` 2] -- no effect, but limit raw damage ++ iaspects fist , idesc = "Enough to swallow anything in a single gulp." } antler = fist { iname = "antler" , ifreq = [("antler", 100)] , icount = 2 , iverbHit = "ram" , idamage = 4 `d` 1 , iaspects = [ Timeout $ 3 + (1 `d` 3) * 3 , AddSkill SkArmorMelee 10 ] -- bonus doubled ++ iaspects fist , ieffects = [PushActor (ThrowMod 100 50 1)] -- 1 step, slow , idesc = "" } horn = fist { iname = "horn" , ifreq = [("horn", 100)] , icount = 2 , iverbHit = "impale" , idamage = 5 `d` 1 , iaspects = [ AddSkill SkHurtMelee 10 , AddSkill SkArmorMelee 10 ] -- bonus doubled ++ iaspects fist , idesc = "Sharp and long, for defence or attack." } rhinoHorn = fist { iname = "ugly horn" -- made of keratin, unlike real horns , ifreq = [("rhino horn", 100)] , icount = 1 -- single, unlike real horns , iverbHit = "gore" , idamage = 5 `d` 1 , iaspects = [Timeout 5, AddSkill SkHurtMelee 20] ++ iaspects fist , ieffects = [Impress, Yell] -- the owner is a mid-boss, after all , idesc = "Very solid, considering it has the same composition as fingernails." } tentacle = fist { iname = "tentacle" , ifreq = [("tentacle", 50)] , icount = 4 , iverbHit = "slap" , idamage = 4 `d` 1 , idesc = "Damp and dextrous." } thorn = fist { iname = "thorn" , ifreq = [("thorn", 100)] , icount = 2 + 1 `d` 3 , iverbHit = "puncture" , idamage = 2 `d` 1 , iaspects = [SetFlag Meleeable] -- not Durable , ieffects = [VerbNoLonger "be not so thorny any more"] , idesc = "Sharp yet brittle." } boilingFissure = fist { iname = "fissure" , ifreq = [("boiling fissure", 100)] , icount = 5 + 1 `d` 5 , iverbHit = "hiss at" , idamage = 1 `d` 1 , iaspects = [ AddSkill SkHurtMelee 20 -- decreasing as count decreases , SetFlag Meleeable ] -- not Durable , ieffects = [ DropItem 1 1 COrgan "condition" -- useful; limited , VerbNoLonger "widen the crack, releasing pressure" ] , idesc = "" } arsenicFissure = boilingFissure { iname = "fissure" , ifreq = [("biogas fissure", 100)] , icount = 3 + 1 `d` 3 , idamage = 2 `d` 1 , ieffects = [ toOrganBad "parsimonious" (5 + 1 `d` 3) -- weaken/poison, impacting intellectual abilities first , VerbNoLonger "become clogged with organic residue" ] , idesc = "" } sulfurFissure = boilingFissure { iname = "fissure" , ifreq = [("medbot fissure", 100)] , icount = 2 + 1 `d` 2 , idamage = 0 -- heal not via (negative) idamage, for armour would block it , ieffects = [ RefillHP 5 , VerbNoLonger "run out of nano medbot liquid" ] , idesc = "" } beeSting = fist { iname = "bee sting" , ifreq = [("bee sting", 100)] , icount = 1 , iverbHit = "sting" , idamage = 0 , iaspects = [ AddSkill SkArmorMelee 200, AddSkill SkArmorRanged 45 , SetFlag Meleeable ] -- not Durable , ieffects = [Paralyze 6, RefillHP 4] -- no special message when runs out, because it's 1 copy , idesc = "Painful, but beneficial." } sting = fist { iname = "sting" , ifreq = [("sting", 100)] , icount = 1 , iverbHit = "inject" , idamage = 1 `d` 1 , iaspects = [Timeout $ 10 - 1 `dL` 4, AddSkill SkHurtMelee 40] ++ iaspects fist , ieffects = [toOrganBad "retaining" (3 + 1 `d` 3)] , idesc = "Painful, debilitating and harmful." } venomTooth = fist { iname = "venom tooth" , ifreq = [("venom tooth", 100)] , icount = 2 , iverbHit = "bite" , idamage = 1 `d` 1 , iaspects = Timeout (7 - 1 `dL` 3) : iaspects fist , ieffects = [toOrganBad "slowed" (3 + 1 `d` 3)] , idesc = "A chilling numbness spreads from its bite." } venomFang = fist { iname = "venom fang" , ifreq = [("venom fang", 100)] , icount = 2 , iverbHit = "bite" , idamage = 0 , iaspects = Timeout (10 - 1 `dL` 5) : iaspects fist , ieffects = [toOrganNoTimer "poisoned"] , idesc = "Dripping with deadly venom." } screechingBeak = fist { iname = "screeching beak" , ifreq = [("screeching beak", 100)] , icount = 1 , iverbHit = "peck" , idamage = 3 `d` 1 , iaspects = Timeout (7 - 1 `dL` 3) : iaspects fist , ieffects = [Summon "scavenger" $ 1 `dL` 3] , idesc = "Both a weapon and a beacon, calling more scavengers to the meal." } largeTail = fist { iname = "large tail" , ifreq = [("large tail", 50)] , icount = 1 , iverbHit = "knock" , idamage = 7 `d` 1 , iaspects = [Timeout $ 2 + 1 `d` 2, AddSkill SkHurtMelee 20] ++ iaspects fist -- timeout higher, lest they regain push before closing again , ieffects = [PushActor (ThrowMod 200 50 1)] -- 1 step, fast , idesc = "Almost as long as the trunk." } hugeTail = largeTail { iname = "huge tail" , ifreq = [("huge tail", 50)] , iverbHit = "upend" , iaspects = [Timeout $ 3 + 1 `d` 2, AddSkill SkHurtMelee 20] ++ iaspects fist -- timeout higher, lest they regain push before closing again , ieffects = [PushActor (ThrowMod 400 50 1)] -- 2 steps, fast , idesc = "Slow but immensely heavy." } -- Non-weapons -- * Armor organs armoredSkin = ItemKind { isymbol = ',' , iname = "armored skin" , ifreq = [("armored skin", 100)] , iflavour = zipPlain [Red] , icount = 1 , irarity = [(1, 1)] , iverbHit = "bash" , iweight = 2000 , idamage = 0 , iaspects = [ AddSkill SkArmorMelee 30, AddSkill SkArmorRanged 15 , SetFlag Durable ] , ieffects = [] , idesc = "Homemade armour is just as good." -- hmm, it may get confused with leather armor jackets, etc. , ikit = [] } bark = armoredSkin { iname = "bark" , ifreq = [("bark", 100)] , idesc = "" } -- * Sense organs eye :: Int -> ItemKind eye n = armoredSkin { iname = "eye" , ifreq = [(toGroupName $ "eye" <+> tshow n, 100)] , icount = 2 , iverbHit = "glare at" , iaspects = [ AddSkill SkSight (intToDice n) , SetFlag Durable ] , idesc = "A piercing stare." } eye3 = eye 3 eye6 = eye 6 eye8 = eye 8 vision :: Int -> ItemKind vision n = armoredSkin { iname = "vision" , ifreq = [(toGroupName $ "vision" <+> tshow n, 100)] , iverbHit = "visualize" , iaspects = [ AddSkill SkSight (intToDice n) , SetFlag Durable ] , idesc = "" } vision6 = vision 6 vision12 = vision 12 vision16 = vision 16 nostril = armoredSkin { iname = "nostril" , ifreq = [("nostril", 100)] , icount = 2 , iverbHit = "snuff" , iaspects = [ AddSkill SkSmell 1 -- times 2, from icount , SetFlag Durable ] , idesc = "" } ear :: Int -> ItemKind ear n = armoredSkin { iname = "ear" , ifreq = [(toGroupName $ "ear" <+> tshow n, 100)] , icount = 2 , iverbHit = "overhear" , iaspects = [ AddSkill SkHearing (intToDice n) , SetFlag Durable ] , idesc = "" } ear3 = ear 3 ear6 = ear 6 ear8 = ear 8 -- * Assorted rattleOrgan = armoredSkin { iname = "rattle" , ifreq = [("rattle", 100)] , iverbHit = "announce" , iaspects = [ Timeout $ 10 + (1 `d` 3) * 10 -- long, to limit spam , SetFlag Periodic, SetFlag Durable ] , ieffects = [Yell, RefillCalm 5] , idesc = "" } insectMortality = armoredSkin { iname = "insect mortality" , ifreq = [("insect mortality", 100)] , iverbHit = "age" , iaspects = [ AddSkill SkAggression 2 -- try to attack before you die , Timeout $ 30 + (1 `d` 3) * 10 -- die very slowly , SetFlag Periodic, SetFlag Durable ] , ieffects = [RefillHP (-1), Yell] , idesc = "" } sapientBrain = armoredSkin { iname = "sapient brain" , ifreq = [("sapient brain", 100)] , iverbHit = "outbrain" , iaspects = [AddSkill sk 1 | sk <- [SkMove .. SkApply]] ++ [AddSkill SkMove 4] -- can move at once when waking up ++ [AddSkill SkAlter 4] -- can use all stairs; dig rubble, ice ++ [AddSkill SkWait 2] -- can brace and sleep ++ [AddSkill SkApply 1] -- can use most items, not just foods ++ [SetFlag Durable] , idesc = "" } animalBrain = armoredSkin { iname = "animal brain" , ifreq = [("animal brain", 100)] , iverbHit = "blank" , iaspects = [AddSkill sk 1 | sk <- [SkMove .. SkApply]] ++ [AddSkill SkMove 4] -- can move at once when waking up ++ [AddSkill SkAlter 2] -- can use normal stairs; can't dig ++ [AddSkill SkWait 2] -- can brace and sleep -- No @SkAppy@ bonus, so can only apply foods. ++ [AddSkill SkDisplace (-1)] -- no melee tactics ++ [AddSkill SkMoveItem (-1)] -- no item gathering ++ [AddSkill SkProject (-1)] -- nor item flinging ++ [SetFlag Durable] , idesc = "" } speedGland :: Int -> ItemKind speedGland n = armoredSkin { iname = "speed gland" , ifreq = [(toGroupName $ "speed gland" <+> tshow n, 100)] , iverbHit = "spit at" , iaspects = [ AddSkill SkSpeed $ intToDice n , Timeout $ intToDice (100 `div` n) , SetFlag Periodic, SetFlag Durable ] , ieffects = [RefillHP 1] , idesc = "" } speedGland5 = speedGland 5 speedGland10 = speedGland 10 scentGland = armoredSkin { iname = "scent gland" , ifreq = [("scent gland", 100)] , icount = 10 + 1 `d` 3 -- runs out , iverbHit = "spray at" , iaspects = [ Timeout $ (1 `d` 3) * 10 , SetFlag Periodic, SetFlag Fragile ] -- not Durable , ieffects = [ VerbNoLonger "look spent" , ApplyPerfume , Explode "distressing odor" ] -- keep explosion at the end to avoid the ambiguity of -- "of ([foo explosion] of [bar])" , idesc = "" } boilingVent = armoredSkin { iname = "vent" , ifreq = [("boiling vent", 100)] , iflavour = zipPlain [BrBlue] , iverbHit = "menace" , iaspects = [ Timeout $ (2 + 1 `d` 3) * 5 , SetFlag Periodic, SetFlag Durable ] , ieffects = [RefillHP 2, Explode "boiling water"] , idesc = "" } arsenicVent = armoredSkin { iname = "vent" , ifreq = [("biogas vent", 100)] , iflavour = zipPlain [BrGreen] , iverbHit = "menace" , iaspects = [ Timeout $ (2 + 1 `d` 3) * 5 , SetFlag Periodic, SetFlag Durable ] , ieffects = [RefillHP 2, Explode "sparse shower"] , idesc = "" } sulfurVent = armoredSkin { iname = "vent" , ifreq = [("medbot vent", 100)] , iflavour = zipPlain [BrYellow] , iverbHit = "menace" , iaspects = [ Timeout $ (2 + 1 `d` 3) * 5 , SetFlag Periodic, SetFlag Durable ] , ieffects = [RefillHP 2, Explode "dense shower"] , idesc = "" } -- * Special bonusHP = armoredSkin { isymbol = 'H' -- '+' reserved for conditions , iname = "bonus HP" , ifreq = [("bonus HP", 1)] , iflavour = zipPlain [BrBlue] , iverbHit = "intimidate" , iweight = 0 , iaspects = [AddSkill SkMaxHP 1] , idesc = "Special training and connections in the right places give this adventurer reinforced musculature and augmented internal organs, much more resilient to damage." } braced = armoredSkin { isymbol = 'B' , iname = "braced" , ifreq = [("braced", 1)] , iflavour = zipPlain [BrGreen] , iverbHit = "brace" , iweight = 0 , iaspects = [ AddSkill SkArmorMelee 50, AddSkill SkArmorRanged 25 , AddSkill SkHearing 10 , SetFlag Condition ] -- hack: display as condition , idesc = "Apart of increased resilience to attacks, being braced protects from displacement by foes and other forms of forced translocation, e.g., pushing or pulling." } asleep = armoredSkin { isymbol = 'S' , iname = "asleep" , ifreq = [("asleep", 1)] , iflavour = zipPlain [BrGreen] -- regenerates HP (very slowly) , icount = 5 , iverbHit = "slay" , iweight = 0 , iaspects = [AddSkill sk (-1) | sk <- [SkMove .. SkApply]] ++ [ AddSkill SkMelee 1, AddSkill SkAlter 1, AddSkill SkWait 1 , AddSkill SkSight (-3), AddSkill SkArmorMelee (-10) , SetFlag Condition ] -- hack: display as condition , idesc = "Sleep helps to regain health, albeit extremely slowly. Being asleep makes you vulnerable, with gradually diminishing effects as the slumber wears off over several turns. Any non-idle action, not only combat but even yawning or stretching removes a sizable portion of the sleepiness." } impressed = armoredSkin { isymbol = 'I' , iname = "impressed" , ifreq = [("impressed", 1), ("condition", 1)] , iflavour = zipPlain [BrRed] , iverbHit = "confuse" , iweight = 0 , iaspects = [ AddSkill SkMaxCalm (-1) -- to help player notice on HUD -- and to count as bad condition , SetFlag Fragile -- to announce "no longer" only when -- all impressions gone , SetFlag Condition ] -- this is really a condition, -- just not a timed condition , ieffects = [ OnSmash $ verbMsgLess "impressed" , OnSmash $ verbMsgNoLonger "impressed" ] -- not periodic, so no wear each turn, so only @OnSmash@ , idesc = "Being impressed by one's adversary sounds like fun, but on battlefield it equals treason. Almost. Throw in depleted battle calm and it leads to mindless desertion outright." } -- * Allure-specific smallBeak = fist { iname = "small beak" , ifreq = [("small beak", 50)] , icount = 1 , iverbHit = "nom" , idamage = 2 `d` 1 , idesc = "Cute, but painful." } razor = fist { iname = "razor edge" , ifreq = [("razor", 100)] , icount = 1 + 1 `d` 2 , iverbHit = "slice" , idamage = 2 `d` 1 , iaspects = [SetFlag Meleeable] -- not Durable , ieffects = [ toOrganBad "weakened" (2 + 1 `dL` 3) , VerbNoLonger "lose all sharpness" ] -- we interpret charges as sharpness of the actor or his razor' -- no pronoun in the message to avoid "you lose its sharpness" , idesc = "" } liveWire = fist { iname = "live wire" , ifreq = [("live wire", 100)] , icount = 1 , iverbHit = "shock" , idamage = 0 , iaspects = [ Timeout $ 3 + 1 `d` 2 , AddSkill SkHurtMelee 20 ] ++ iaspects fist , ieffects = [ toOrganBad "immobile" (3 + 1 `d` 3) , RefillHP (-1) ] , idesc = "" } robotBrain = armoredSkin { iname = "robot brain" , ifreq = [("robot brain", 100)] , iverbHit = "outcompute" , iaspects = [AddSkill sk 1 | sk <- [SkMove .. SkApply]] ++ [AddSkill SkMove 4] -- can move at once when waking up ++ [AddSkill SkAlter 1] -- can open doors; only easiest stairs ++ [AddSkill SkWait 2] -- can brace and sleep -- No @SkAlter@ bonus, so can only use the easiest stairs. ++ [AddSkill SkApply (-1)] -- can't even eat food, but can fling ++ [SetFlag Durable] , idesc = "" } hullPlating = armoredSkin { iname = "hull plating" , ifreq = [("hull plating", 100)] , idesc = "" } mouthVent = armoredSkin { iname = "mouth vent" , ifreq = [("mouth vent", 100)] , iflavour = zipPlain [BrMagenta] , iverbHit = "surprise" , iaspects = [ Timeout 7 , SetFlag Periodic, SetFlag Durable ] , ieffects = [OneOf $ map Explode ["pheromone", "cruise ad hologram", "immobile mist", "smoke", "spark"]] , idesc = "" } geneticFlaw :: Int -> ItemKind -- HP change varies due to body size geneticFlaw n = armoredSkin { isymbol = 'F' , iname = "genetic flaw" , ifreq = [ ("genetic flaw", 1) , (toGroupName $ "genetic flaw" <+> tshow n, 1) ] , iflavour = zipPlain [BrRed] , iverbHit = "flaw" , iweight = 0 , iaspects = [ AddSkill SkMaxHP (intToDice $ - n) , Odds (1 `d` 400) [AddSkill SkArmorMelee (-20)] [AddSkill SkArmorRanged (-10)] , SetFlag Condition ] -- destroy on drop to run the @OnSmash@ effects ++ [AddSkill SkWait (-1) | n >= 10] ++ [AddSkill SkApply (-1) | n >= 10] , ieffects = [ OnSmash $ DropItem maxBound maxBound COrgan "condition" -- key for AI is it eliminates all impression conditions , OnSmash $ RefillHP n , OnSmash $ VerbNoLonger "undergo instant infracellular decontamination" ] -- unlike the civilian version, this one is instant and the attunement is automatic and relatively quick (the usual double cooldown when equipping items again) , idesc = "Nobody is perfect. At least without infracellular engineering, which is heavily regulated, insanely expensive and automatically reverted without refund before critical medical interventions. One more reason to be a good citizen, work hard and not die often. But where is the fun in that?" } geneticFlaw3 = geneticFlaw 3 geneticFlaw10 = geneticFlaw 10 Allure-0.9.5.0/GameDefinition/Content/ItemKindTemporary.hs0000644000000000000000000001457507346545000021553 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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. -- -- | Temporary aspect pseudo-item definitions. module Content.ItemKindTemporary ( temporaries ) where import Prelude () import Game.LambdaHack.Core.Prelude import Game.LambdaHack.Content.ItemKind import Game.LambdaHack.Core.Dice import Game.LambdaHack.Definition.Ability import Game.LambdaHack.Definition.Color import Game.LambdaHack.Definition.Defs import Game.LambdaHack.Definition.Flavour temporaries :: [ItemKind] temporaries = [tmpStrengthened, tmpWeakened, tmpProtectedMelee, tmpProtectedRanged, tmpVulnerable, tmpResolute, tmpFast20, tmpSlow10, tmpFarSighted, tmpBlind, tmpKeenSmelling, tmpFoulSmelling, tmpRoseSmelling, tmpNoctovision, tmpDeafened, tmpDeaf, tmpDrunk, tmpBonusSkAggresion, tmpNoSkMove, tmpNoSkMelee, tmpNoSkDisplace, tmpNoSkAlter, tmpNoSkWait, tmpNoSkMoveItem, tmpNoSkProject, tmpNoSkApply, tmpBonusSkMove, tmpBonusSkMelee, tmpBonusSkDisplace, tmpBonusSkAlter, tmpBonusSkWait, tmpBonusSkMoveItem, tmpBonusSkProject, tmpBonusSkApply, tmpRegenerating, tmpPoisoned, tmpSlow10Resistant, tmpPoisonResistant] tmpStrengthened, tmpWeakened, tmpProtectedMelee, tmpProtectedRanged, tmpVulnerable, tmpResolute, tmpFast20, tmpSlow10, tmpFarSighted, tmpBlind, tmpKeenSmelling, tmpFoulSmelling, tmpRoseSmelling, tmpNoctovision, tmpDeafened, tmpDeaf, tmpDrunk, tmpBonusSkAggresion, tmpNoSkMove, tmpNoSkMelee, tmpNoSkDisplace, tmpNoSkAlter, tmpNoSkWait, tmpNoSkMoveItem, tmpNoSkProject, tmpNoSkApply, tmpBonusSkMove, tmpBonusSkMelee, tmpBonusSkDisplace, tmpBonusSkAlter, tmpBonusSkWait, tmpBonusSkMoveItem, tmpBonusSkProject, tmpBonusSkApply, tmpRegenerating, tmpPoisoned, tmpSlow10Resistant, tmpPoisonResistant :: ItemKind -- The @name@ is be used in item description, so it should be an adjective -- describing the temporary set of aspects. -- The messages are needed also under @OnSmash@ to display when item removed -- via @DropItem@ and not via natural periodic activation. tmpAspects :: Text -> [Aspect] -> ItemKind tmpAspects name aspects = ItemKind { isymbol = '+' , iname = name , ifreq = [(toGroupName name, 1), ("condition", 1)] , iflavour = zipPlain [BrWhite] , icount = 1 , irarity = [(1, 1)] , iverbHit = "affect" , iweight = 0 , idamage = 0 , iaspects = -- timeout is 0; activates and vanishes soon, -- depending on initial timer setting aspects ++ [SetFlag Periodic, SetFlag Fragile, SetFlag Condition] , ieffects = [ OnSmash $ verbMsgLess name -- announce partial neutralization -- not spamming for normal periodic wear each turn , OnSmash $ verbMsgNoLonger name -- for forced neutralization , verbMsgNoLonger name ] -- for periodic wear of last copy , idesc = "" -- no description needed; powers are enough , ikit = [] } tmpEffects :: Text -> Dice -> [Effect] -> ItemKind tmpEffects name icount effects = let tmp = tmpAspects name [] in tmp { icount , ieffects = effects ++ ieffects tmp } tmpStrengthened = tmpAspects "strengthened" [AddSkill SkHurtMelee 20] tmpWeakened = tmpAspects "weakened" [AddSkill SkHurtMelee (-30)] -- don't cancel out ^ tmpProtectedMelee = tmpAspects "protected from melee" [AddSkill SkArmorMelee 50] tmpProtectedRanged = tmpAspects "protected from ranged" [AddSkill SkArmorRanged 25] tmpVulnerable = tmpAspects "painted" [ AddSkill SkArmorMelee (-50) , AddSkill SkArmorRanged (-25) , AddSkill SkShine 1 ] tmpResolute = tmpAspects "resolute" [AddSkill SkMaxCalm 60] tmpFast20 = tmpAspects "hasted" [AddSkill SkSpeed 20] tmpSlow10 = tmpAspects "slowed" [AddSkill SkSpeed (-10)] tmpFarSighted = tmpAspects "far-sighted" [AddSkill SkSight 5] tmpBlind = tmpAspects "blind" [AddSkill SkSight (-99)] tmpKeenSmelling = tmpAspects "keen-smelling" [AddSkill SkSmell 2] tmpFoulSmelling = tmpAspects "foul-smelling" [AddSkill SkOdor 2] tmpRoseSmelling = tmpAspects "rose-smelling" [AddSkill SkOdor (-4)] tmpNoctovision = tmpAspects "shiny-eyed" [AddSkill SkNocto 2] tmpDeafened = tmpAspects "deafened" [AddSkill SkHearing (-10)] tmpDeaf = tmpAspects "deaf" [AddSkill SkHearing (-99)] tmpDrunk = tmpAspects "drunk" [ AddSkill SkHurtMelee 30 -- fury , AddSkill SkArmorMelee (-20) , AddSkill SkArmorRanged (-20) , AddSkill SkSight (-8) ] tmpBonusSkAggresion = tmpAspects "frenzied" [AddSkill SkAggression 5] tmpNoSkMove = tmpAspects "immobile" [AddSkill SkMove (-99)] tmpNoSkMelee = tmpAspects "pacified" [AddSkill SkMelee (-99)] tmpNoSkDisplace = tmpAspects "irreplaceable" [AddSkill SkDisplace (-99)] tmpNoSkAlter = tmpAspects "retaining" [AddSkill SkAlter (-99)] tmpNoSkWait = tmpAspects "impatient" [AddSkill SkWait (-99)] tmpNoSkMoveItem = tmpAspects "dispossessed" [AddSkill SkMoveItem (-99)] tmpNoSkProject = tmpAspects "withholding" [AddSkill SkProject (-99)] tmpNoSkApply = tmpAspects "parsimonious" [AddSkill SkApply (-99)] tmpBonusSkMove = tmpAspects "more mobile" [AddSkill SkMove 5] tmpBonusSkMelee = tmpAspects "more combative" [AddSkill SkMelee 5] tmpBonusSkDisplace = tmpAspects "more displacing" [AddSkill SkDisplace 5] tmpBonusSkAlter = tmpAspects "more altering" [AddSkill SkAlter 5] tmpBonusSkWait = tmpAspects "more patient" [AddSkill SkWait 5] tmpBonusSkMoveItem = tmpAspects "more tidy" [AddSkill SkMoveItem 5] tmpBonusSkProject = tmpAspects "more projecting" [AddSkill SkProject 8] -- TODO: 11, but let player control potion throwing by henchmen; -- beware also of capReinforced and other sources of the skill tmpBonusSkApply = tmpAspects "more practical" [AddSkill SkApply 5] tmpRegenerating = tmpEffects "regenerating" (4 + 1 `d` 2) [RefillHP 1] tmpPoisoned = tmpEffects "poisoned" (4 + 1 `d` 2) [RefillHP (-1)] tmpSlow10Resistant = tmpEffects "slow resistant" (8 + 1 `d` 4) [DropItem 1 1 COrgan "slowed"] tmpPoisonResistant = tmpEffects "poison resistant" (8 + 1 `d` 4) [DropItem 1 maxBound COrgan "poisoned"] Allure-0.9.5.0/GameDefinition/Content/ModeKind.hs0000644000000000000000000011143007346545000017622 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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 ( content ) where import Prelude () import Game.LambdaHack.Core.Prelude import Content.ModeKindPlayer import Game.LambdaHack.Content.CaveKind (CaveKind) import Game.LambdaHack.Content.ModeKind import Game.LambdaHack.Core.Dice import Game.LambdaHack.Definition.Defs content :: [ModeKind] content = [raid, brawl, shootout, hunt, escape, zoo, ambush, crawl, crawlEmpty, crawlSurvival, dig, see, safari, safariSurvival, battle, battleDefense, battleSurvival, defense, defenseEmpty, screensaverRaid, screensaverBrawl, screensaverShootout, screensaverHunt, screensaverEscape, screensaverZoo, screensaverAmbush, screensaverCrawl, screensaverSafari] raid, brawl, shootout, hunt, escape, zoo, ambush, crawl, crawlEmpty, crawlSurvival, dig, see, safari, safariSurvival, battle, battleDefense, battleSurvival, defense, defenseEmpty, screensaverRaid, screensaverBrawl, screensaverShootout, screensaverHunt, screensaverEscape, screensaverZoo, screensaverAmbush, screensaverCrawl, screensaverSafari :: ModeKind -- What other symmetric (two only-one-moves factions) and asymmetric vs crowd -- scenarios make sense (e.g., are good for a tutorial or for standalone -- extreme fun or are impossible as part of a crawl)? -- sparse melee at night: no, shade ambush in brawl is enough -- dense melee: no, keeping big party together is a chore and big enemy -- party is less fun than huge enemy party -- crowd melee in daylight: no, possible in crawl and at night is more fun -- sparse ranged at night: no, less fun than dense and if no reaction fire, -- just a camp fest or firing blindly -- dense ranged in daylight: no, less fun than at night with flares -- crowd ranged: no, fish in a barrel, less predictable and more fun inside -- crawl, even without reaction fire raid = ModeKind -- mini-crawl { msymbol = 'r' , mname = "solo raid (1)" , mfreq = [("solo", 1), ("raid", 1), ("campaign scenario", 1)] , mroster = rosterRaid , mcaves = cavesRaid , mendMsg = [ (Killed, "That was unfortunate. The bill for the rescue team and for the subsequent nano medbot treatment will reach the stars. Perhaps more stealth was needed? Perhaps the items lying around the area could aid survival instead of ending up ignored or passively hoarded? Or perhaps a wise course of action would be to choose a Neptune Area Administration challenge with a lower difficulty?") , (Defeated, "Sadly, you got worked up in the tunnels while another team snatched the prize. Remember, you are at the Outer Frontier to gain wealth and independence through industriousness and commerce and that means clashing with competing agents, not just fighting feral nature.") , (Escape, "You are the first to clear a route through the sewer system. Triton City authorities will now be able to establish a perimeter and mop up the side tunnels. You collect your reward of 100 gold grains and start looking for a way to invest it profitably at this Solar System's commercial frontier, abounding in more or less (usually less) regulated opportunities.\nAfter some thought you decide to start by splurging on genetic enhancement for your team. The effects won't be visible at once and you have no time to lose, having just made fresh enemies.") ] , mdesc = "Neptune Area Administration confirms isolated spottings of oversize vermin in non-residential zones of the Neptune's Triton moon's largest city. To put it plainly: Triton City sewers need purging. The first person to break through to the other exit will be paid 100 gold grains. The Administration \"strongly urges participants not to resort to violence against each other.\" However, no punitive consequences are specified, not even disqualification from the contest." } brawl = ModeKind -- sparse melee in daylight, with shade for melee ambush { msymbol = 'k' , mname = "melee brawl (2)" , mfreq = [("melee", 1), ("brawl", 1), ("campaign scenario", 1)] , mroster = rosterBrawl , mcaves = cavesBrawl , mendMsg = [ (Killed, "That treacherous villain didn't honour his word and brought his friends to the fight. It would still not turn so bad if we remembered to use terrain to protect us from missiles or even completely hide our presence and if we honourably kept together to the end, at the same time preventing the overwhelming enemy forces from brutishly ganging up on our modest-sized, though valiant, squad. Having to repurchase genetic therapy was the most painful outcome, one that would send you broke and in shame to Earth, if repeated, to start collecting your Basic Income.") , (Conquer, "Bringing help was a sober and prudent move that resulted in well-earned victory and a splendid trophy of a title to a real inter-planetary space vessel. Unfortunately, the treacherous foe called reinforcements at the last moment, which start to arrive just now. It may be wise to move the celebration of the victory to a more fitting area, assuming that the dignified translocation can be accomplished timely and inconspicuously.") ] , mdesc = "\"You scoundrel! You cheated in the sewers. Come alone to the woody biosphere behind the saloon at noon, if you dare. Given that I win, I take back all your gold. Otherwise, you get the scrapping rights for the giant spaceliner's hull in orbit. Yes, it's mine, you tramp; here's the docking transmitter and the paperwork. The fight is to the last man standing, no evasion, no breaks for nano-healing in town.\"" } -- The trajectory tip is important because of tactics of scout looking from -- behind a bush and others hiding in mist. If no suitable bushes, -- fire once and flee into mist or behind cover. Then whomever is out of LOS -- range or inside mist can shoot at the last seen enemy locations, -- adjusting aim according to sounds and incoming missile trajectories. -- If the scout can't find bushes or glass building to set a lookout, -- the other team members are more spotters and guardians than snipers -- and that's their only role, so a small party makes sense. shootout = ModeKind -- sparse ranged in daylight { msymbol = 's' , mname = "foggy shootout (3)" , mfreq = [("foggy", 1), ("shootout", 1), ("campaign scenario", 1)] , mroster = rosterShootout , mcaves = cavesShootout , mendMsg = [ (Killed, "This is a disgrace. How is a thuggish robbery in broad daylight even possible in a moon city that styles itself as the capital of Outer System technological innovation and commercial opportunity? Where are the municipal surveillance drones, normally so eager to eavesdrop and needlessly complicate an honest tax-free business, when one's health and wealth for once depend on their nosy presence? Speaking of drones, we could use one in this skirmish, or even just a human lookout placed in a covered but unobstructed spot. Then the rest of the squad could snipe from concealment or from a safe distance.\nBarring that, we would end up in a better shape even if we all hid and fired blindly. We'd listen to impact sounds and wait with ten-fold vigilance for incoming enemy missiles, in order to register their trajectories and derive hints of enemy location. Apparently, ranged combat requires a change of pace and better planning than our previous illustrious successes accustomed us to.") , (Conquer, "That was a good fight, with skillful application of missiles, cover and concealment. The outcome is especially commendable given the high bar of tactical proficiency. Not even professional enforcement units can routinely deduce enemy position from the trajectory of their projectiles nor by firing without line of sight and interpreting auditory cues. However, while this steep hurdle is overcome, the chase is not over yet.") ] , mdesc = "The fight crashes over to a nearby mechanized farm. Law enforcement, crippled by the ban on firearms, won't show up until only wounded and dying remain to be revived and locked up. Farm supplies, scattered around, beg to be flung at foes as improvised missiles. Intense light makes it easy to aim and to discern trajectory of soaring items (point at enemy projectiles with the crosshair in aiming mode). The effects of the last infracellular therapy finally start showing." } hunt = ModeKind -- melee vs ranged with reaction fire in daylight { msymbol = 'h' , mname = "perilous hunt (4)" , mfreq = [("perilous", 1), ("hunt", 1), ("campaign scenario", 1)] , mroster = rosterHunt , mcaves = cavesHunt , mendMsg = [ (Killed, "Next time let's try to remember we are not on a sightseeing expedition. Also, leaving concealment is risky, leaving cover is foolhardy and wandering off is deadly. Also, what was that taking pictures by the mangrove tree all about? Were you trying to immortalize your handsome faces in case our shared pool of money was not enough to revive your sorry carcasses after the defeat? Good call, because after paying the techno-medical bills we are broke and the military grade communication and reaction fire implants of the gang foot soldiers that chase us don't raise our prospects either. And we were so close to complete victory and unfathomable wealth, if only we strove to lower the difficulty of this mission instead of raising it.") -- the guy is wrong about implants (though the items are genetically attuned), but being wrong is plausible when the team is killed off/chased off and can't scour the battleground -- this is in the middle of the scenario list and the mission is not tricky, so a subtle reminder about lowering difficulty, in case the player struggles , (Conquer, "We chased them off, like we knew that we would. It feels nice to stick together and prevail. Now we can do no wrong just minding our business and going our way to the spaceport. We taught them a lesson, despite their superior equipment, and nobody else needs to be harmed while we take possession of our rightful property, the glorious spaceship in Triton's orbit.") ] , mdesc = "Who is the hunter and who is the prey? The only criterion is remaining conscious versus becoming incapacitated when the chase ends." } escape = ModeKind -- asymmetric ranged and stealth race at night { msymbol = 'e' , mname = "night escape (5)" , mfreq = [("night", 1), ("escape", 1), ("campaign scenario", 1)] , mroster = rosterEscape , mcaves = cavesEscape , mendMsg = [ (Killed, "Somebody must have tipped the gang guards off. However, us walking along a lit trail, yelling, could have been a contributing factor. Also, it's worth noting that the torches prepared for this assault are best used as thrown makeshift flares. On the other hand, equipping a lit torch makes one visible in the dark, regrettably but not quite unexpectedly. Lastly, the goal of this foray was to find the exit back to the city, marked by a yellow '>' sign, and to gather some treasure along the way, but not to bedevil every local evildoer, as much as they do deserve it.") , (Conquer, "It was enough to reach the escape area, namely the exit tunnel from the park marked by yellow '>' symbol. Spilling that much blood was risky and unnecessary. Having said that --- impressive indeed.") , (Escape, "Congratulations, you took your revenge and it's heavy in your pockets.") ] , mdesc = "Bloodied spaceship deed in hand notwithstanding, you can reach the derelict spaceliner only via a shuttle from the Central Triton Spaceport across the city. After hours of being chased in the opposite direction towards the border wall, you sneak back and make a desperate dash through the very den of the pursuing gang. Any valuables you come upon in this public park turned miscreant lair will be fair compensation for your losses, but you need to find the exit before the foes find you. Rein in your wrath and don't attack your tormentors. Foiling their plans by eluding them will be revenge enough." } zoo = ModeKind -- asymmetric crowd melee at night { msymbol = 'b' , mname = "burning zoo (6)" , mfreq = [("burning", 1), ("zoo", 1), ("campaign scenario", 1)] , mroster = rosterZoo , mcaves = cavesZoo , mendMsg = [ (Killed, "Against such an onslaught, only clever positioning, use of terrain and patient vigilance gives any chance of survival.") , (Conquer, "That was a grim harvest. The city is safe again. So are your precious selves, with nothing and no one blocking your way to the spaceport any more.") ] , mdesc = "As justified and satisfying as setting the enemy headquarters on fire has been, it backfires when the blaze immediately spreads to the public zoo on the path to the spaceport. Crazed animals mill around while the flames ignite greenery and consume nets, cages and security equipment. Whether that's a good sign or bad, apparently nobody is willing to pursue you any more. You are on your own, having to completely clean up the area, up to the last lurking predator, in order to safely move through." } -- The tactic is to sneak in the dark, highlight enemy with thrown torches -- (and douse thrown enemy torches with blankets) and only if this fails, -- actually scout using extended noctovision. -- With reaction fire, larger team is more fun. -- -- For now, while we have no shooters with timeout, massive ranged battles -- without reaction fire don't make sense, because then usually only one hero -- shoots (and often also scouts) and others just gather ammo. ambush = ModeKind -- dense ranged with reaction fire vs melee at night { msymbol = 'm' , mname = "ranged ambush (7)" , mfreq = [("ranged", 1), ("ambush", 1), ("campaign scenario", 1)] , mroster = rosterAmbush , mcaves = cavesAmbush , mendMsg = [ (Killed, "You turned out to be the prey, this time, not the hunter. In fact, you are not even in the hunters' league. And it's hard to operate a space dock while being chased round a spaceport. When fighting against such odds, passively waiting for enemy to spring a trap is to no avail, because a professional team can sneak in darkness and ambush the ambushers. Granted, good positioning is crucial, so that each squad member can overwatch the battlefield and fire opportunistically, using the recently recovered mil-grade communication equipment. However, there is no hope without active scouting, throwing lit objects and probing suspect areas with missiles while paying attention to sounds. And that may still not be enough.") , (Conquer, "The new communication equipment, enabling simultaneous ranged attacks with indirect aiming, apparently proved effective beyond expectations. With the mercenaries gone and nobody else having the slightest wish to interfere, the shuttle to the space cruiser at orbit is easy to launch at last. Now is your moment of glory. Now your turbulent adventure ends and the boring life of space cruiser scrap parts supplier or, as it may be, of a refurbished giant space liner operator, commences.\nA pity that the last round of shoddy genetic enhancements, bought at the grey market, scandalously auto-reverts at this very moment, leaving the personalized equipment that attuned to the previous genetic configuration inoperable. Fortunately, danger, debt and the gangster debt collectors are now behind you and the grey market won't see you again.") ] , mdesc = "Not even the unexplained carnage at the Central Triton Spaceport will prevent you from claiming the prize awaiting you at the orbit. After all, you didn't take to the stars to let others decide your fate. There is still no news coverage from the ruin of what was the largest and tightest security facility in the whole Neptune Area. Without waiting for explanations nor for the personnel to return, you creep along the burning booths, scouting for any airlock with a shuttle still attached." -- this is the only scenario with no objective specified, to give a bit of suspense, misdirection and mystery until the first win (death gives a hint only); being the last of the small scenarios, it won't scare off new players } crawl = ModeKind { msymbol = 'c' , mname = "upward crawl (long)" , mfreq = [("upward", 1), ("crawl", 1), ("campaign scenario", 1)] , mroster = rosterCrawl , mcaves = cavesCrawl , mendMsg = [ (Killed, "It was not supposed to end this way. Perhaps more stealth was in order? Perhaps the gathered items should be used for survival instead of hoarded? Or perhaps the challenge, chosen freely but without awareness of the grisly difficulty, was insurmountable and lost from the very start? Nobody is going to find out, even if humans ever set their feet here again and prevail, another time, another way.") , (Escape, "The shuttle doors close behind, docking clamps grind in farewell and the giant rotating disc slowly tumbles away in rear view. You feel at once a relief and a sense of loss. This is not finished. You are changed forever, but you know nothing. You've heard the call, but you made no answer. You came for petty change, found a treasure beyond comprehension, then barely escaped with your life as the prize.\nAnd nobody will believe you at home. But you don't need their understanding any more. You have enough money to heal, regroup, track the ship down and try again. It's your personal space cruiser, after all, with a world of its own, inside.") ] , mdesc = "You are busy looting, with utmost satisfaction, the blasted bridge of an old and extravagantly luxurious cruise liner. Suddenly, the inert spaceship, supposedly long deserted and barely able to sustain life support, tremors and dials her fusion engines up to red overdrive. The space map flickering among the irreversibly damaged consoles shows the ship manoeuvre deftly off Triton orbit and purposefully climb the Neptune's gravity well. There's no way to control the ship and static floods all communication channels. You decide to scour the nearby dilapidated decks for missing squad members and get back to the spaceport the way you came, in your shuttle. However, you are determined not to leave the ship without taking at least a portion of the wealth that is rightfully yours." -- later, when the player can visit other level sections: you turn on the deck status list display and notice that most levels are fully pressurized, including the complete autonomous slice of the disc that includes the bridge deck } safari = ModeKind -- Easter egg available only via screensaver { msymbol = 'f' , mname = "safari" , mfreq = [("safari", 1)] , mroster = rosterSafari , mcaves = cavesSafari , mendMsg = [] , 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 topmost level.\" This is a VR recording recovered from an alien nest debris." } -- * Testing modes dig = ModeKind { msymbol = 'd' , mname = "dig" , mfreq = [("dig", 1)] , mroster = rosterCrawlEmpty , mcaves = cavesDig , mendMsg = [] , mdesc = "Delve deeper!" } see = ModeKind { msymbol = 'a' , mname = "see" , mfreq = [("see", 1)] , mroster = rosterCrawlEmpty , mcaves = cavesSee , mendMsg = [] , mdesc = "See all!" } crawlEmpty = ModeKind { msymbol = 'c' , mname = "crawl empty" , mfreq = [("crawl empty", 1)] , mroster = rosterCrawlEmpty , mcaves = cavesCrawlEmpty , mendMsg = [] , mdesc = "Enjoy the free space." } crawlSurvival = ModeKind { msymbol = 'd' , mname = "crawl survival" , mfreq = [("crawl survival", 1)] , mroster = rosterCrawlSurvival , mcaves = cavesCrawl , mendMsg = [] , mdesc = "Lure the human intruders deeper and deeper." } safariSurvival = ModeKind { msymbol = 'u' , mname = "safari survival" , mfreq = [("safari survival", 1)] , mroster = rosterSafariSurvival , mcaves = cavesSafari , mendMsg = [] , mdesc = "In this simulation you'll discover the joys of being hunted among the most exquisite of Earth's flora and fauna, both animal and semi-intelligent." } battle = ModeKind { msymbol = 'b' , mname = "battle" , mfreq = [("battle", 1)] , mroster = rosterBattle , mcaves = cavesBattle , mendMsg = [] , mdesc = "Odds are stacked against those that unleash the horrors of abstraction." } battleDefense = ModeKind { msymbol = 'f' , mname = "battle defense" , mfreq = [("battle defense", 1)] , mroster = rosterBattleDefense , mcaves = cavesBattle , mendMsg = [] , mdesc = "Odds are stacked for those that breathe mathematics." } battleSurvival = ModeKind { msymbol = 'i' , mname = "battle survival" , mfreq = [("battle survival", 1)] , mroster = rosterBattleSurvival , mcaves = cavesBattle , mendMsg = [] , mdesc = "Odds are stacked for those that ally with the strongest." } defense = ModeKind -- perhaps a real scenario in the future { msymbol = 'e' , mname = "defense" , mfreq = [("defense", 1)] , mroster = rosterDefense , mcaves = cavesCrawl , mendMsg = [] , mdesc = "Don't let the half-witted humans derail your operation and flee, like the puny, naked, tentacle-less beasts that they are!" } defenseEmpty = ModeKind { msymbol = 'e' , mname = "defense empty" , mfreq = [("defense empty", 1)] , mroster = rosterDefenseEmpty , mcaves = cavesCrawlEmpty , mendMsg = [] , mdesc = "Lord over." } -- * Screensaver modes screensave :: AutoLeader -> Roster -> Roster screensave auto r = let f [] = [] f ((player, initial) : rest) = (player {fleaderMode = LeaderAI auto}, initial) : rest in r {rosterList = f $ rosterList r} screensaverRaid = raid { mname = "auto-raid (1)" , mfreq = [("insert coin", 1), ("no confirms", 1)] , mroster = screensave (AutoLeader False False) rosterRaid } screensaverBrawl = brawl { mname = "auto-brawl (2)" , mfreq = [("no confirms", 1)] , mroster = screensave (AutoLeader False False) rosterBrawl } screensaverShootout = shootout { mname = "auto-shootout (3)" , mfreq = [("insert coin", 1), ("no confirms", 1)] , mroster = screensave (AutoLeader False False) rosterShootout } screensaverHunt = hunt { mname = "auto-hunt (4)" , mfreq = [("insert coin", 1), ("no confirms", 1)] , mroster = screensave (AutoLeader False False) rosterHunt } screensaverEscape = escape { mname = "auto-escape (5)" , mfreq = [("insert coin", 1), ("no confirms", 1)] , mroster = screensave (AutoLeader False False) rosterEscape } screensaverZoo = zoo { mname = "auto-zoo (6)" , mfreq = [("no confirms", 1)] , mroster = screensave (AutoLeader False False) rosterZoo } screensaverAmbush = ambush { mname = "auto-ambush (7)" , mfreq = [("no confirms", 1)] , mroster = screensave (AutoLeader False False) rosterAmbush } screensaverCrawl = crawl { mname = "auto-crawl (long)" , mfreq = [("no confirms", 1)] , mroster = screensave (AutoLeader False False) rosterCrawl } screensaverSafari = safari { mname = "auto-safari" , mfreq = [("insert coin", 1), ("no confirms", 1)] , mroster = -- changing leader by client needed, because of TFollow screensave (AutoLeader False True) rosterSafari } rosterRaid, rosterBrawl, rosterShootout, rosterHunt, rosterEscape, rosterZoo, rosterAmbush, rosterCrawl, rosterCrawlEmpty, rosterCrawlSurvival, rosterSafari, rosterSafariSurvival, rosterBattle, rosterBattleDefense, rosterBattleSurvival, rosterDefense, rosterDefenseEmpty :: Roster rosterRaid = Roster { rosterList = [ ( playerHero {fhiCondPoly = hiHeroShort} , [(3, 1, "hero")] ) , ( playerAntiHero { fname = "Red Collar Bro" , fhiCondPoly = hiHeroShort } , [(3, 1, "hero")] ) , ( playerAnimal -- starting over escape , [(3, 2, "animal")] ) , ( playerRobot , [(3, 1, "robot")] ) , (playerHorror, []) ] -- for summoned monsters , rosterEnemy = [ ("Spacefarer", "Animal Kingdom") , ("Spacefarer", "Robot Anarchy") , ("Spacefarer", "Horror Den") , ("Spacefarer", "Red Collar Bro") , ("Red Collar Bro", "Animal Kingdom") , ("Red Collar Bro", "Robot Anarchy") , ("Red Collar Bro", "Horror Den") ] , rosterAlly = [("Robot Anarchy", "Animal Kingdom")] } rosterBrawl = Roster { rosterList = [ ( playerHero { fcanEscape = False , fhiCondPoly = hiHeroMedium } , [(4, 3, "hero")] ) , ( playerAntiHero { fname = "Red Collar Bro" , fcanEscape = False , fhiCondPoly = hiHeroMedium } , [(4, 3, "hero")] ) , (playerHorror, []) ] , rosterEnemy = [ ("Spacefarer", "Red Collar Bro") , ("Spacefarer", "Horror Den") , ("Red Collar Bro", "Horror Den") ] , rosterAlly = [] } -- Exactly one scout gets a sight boost, to help the aggressor, because he uses -- the scout for initial attack, while camper (on big enough maps) -- can't guess where the attack would come and so can't position his single -- scout to counter the stealthy advance. rosterShootout = Roster { rosterList = [ ( playerHero { fcanEscape = False , fhiCondPoly = hiHeroMedium } , [(5, 1, "scout hero"), (5, 2, "ranger hero")] ) , ( playerAntiHero { fname = "Red Collar Bro" , fcanEscape = False , fhiCondPoly = hiHeroMedium } , [(5, 1, "scout hero"), (5, 2, "ranger hero")] ) , (playerHorror, []) ] , rosterEnemy = [ ("Spacefarer", "Red Collar Bro") , ("Spacefarer", "Horror Den") , ("Red Collar Bro", "Horror Den") ] , rosterAlly = [] } rosterHunt = Roster { rosterList = [ ( playerHero { fcanEscape = False , fhiCondPoly = hiHeroMedium } , [(7, 7, "soldier hero")] ) , ( playerAntiHero { fname = "Red Collar Bro" , fcanEscape = False , fhiCondPoly = hiHeroMedium } , [(7, 1, "scout hero"), (7, 6, "ambusher hero")] ) , (playerHorror, []) ] , rosterEnemy = [ ("Spacefarer", "Red Collar Bro") , ("Spacefarer", "Horror Den") , ("Red Collar Bro", "Horror Den") ] , rosterAlly = [] } rosterEscape = Roster { rosterList = [ ( playerHero {fhiCondPoly = hiHeroMedium} , [(9, 1, "scout hero"), (9, 2, "escapist hero")] ) , ( playerAntiHero { fname = "Red Collar Bro" , fcanEscape = False -- start on escape , fneverEmpty = False -- loot after killing , fhiCondPoly = hiHeroMedium } , [(9, 1, "scout hero"), (9, 6, "ambusher hero")] ) , (playerHorror, []) ] , rosterEnemy = [ ("Spacefarer", "Red Collar Bro") , ("Spacefarer", "Horror Den") , ("Red Collar Bro", "Horror Den") ] , rosterAlly = [] } rosterZoo = Roster { rosterList = [ ( playerHero { fcanEscape = False , fhiCondPoly = hiHeroLong } , [(11, 5, "soldier hero")] ) , ( playerAnimal {fneverEmpty = True} , [(11, 100, "mobile animal")] ) , (playerHorror, []) ] -- for summoned monsters , rosterEnemy = [ ("Spacefarer", "Animal Kingdom") , ("Spacefarer", "Horror Den") ] , rosterAlly = [] } rosterAmbush = Roster { rosterList = [ ( playerHero { fcanEscape = False , fhiCondPoly = hiHeroMedium } , [(13, 1, "scout hero"), (13, 5, "ambusher hero")] ) , ( playerAntiHero { fname = "Gray Off-World Mercenary" , fcanEscape = False , fhiCondPoly = hiHeroMedium } , [(13, 12, "soldier hero")] ) , (playerHorror, []) ] , rosterEnemy = [ ("Spacefarer", "Gray Off-World Mercenary") , ("Spacefarer", "Horror Den") , ("Gray Off-World Mercenary", "Horror Den") ] , rosterAlly = [] } rosterCrawl = Roster { rosterList = [ ( playerHero , [(3, 3, "crawl hero")] ) , ( playerMonster , [] ) , ( playerAnimal , -- Optional huge battle at the end: [(15, 100, "mobile animal")] ) , ( playerRobot , [] ) ] -- gentle introduction , rosterEnemy = [ ("Spacefarer", "Alien Hierarchy") , ("Spacefarer", "Animal Kingdom") , ("Spacefarer", "Robot Anarchy") ] , rosterAlly = [ ("Alien Hierarchy", "Animal Kingdom") , ("Alien Hierarchy", "Robot Anarchy") , ("Robot Anarchy", "Animal Kingdom") ] } rosterCrawlEmpty = Roster { rosterList = [ ( playerHero , [(1, 1, "crawl hero")] ) , (playerHorror, []) ] -- for spawned and summoned monsters , rosterEnemy = [] , rosterAlly = [] } rosterCrawlSurvival = rosterCrawl { rosterList = [ ( playerAntiHero , [(3, 3, "crawl hero")] ) , ( playerMonster , [] ) , ( playerAnimal {fhasUI = True} , -- Fun from the start to avoid empty initial level: [ (3, 5 + 1 `d` 2, "animal") -- many, because no spawning -- Optional huge battle at the end: , (15, 100, "mobile animal") ] ) , ( playerRobot , [] ) ] } -- gentle introduction -- No horrors faction needed, because spawned heroes land in civilian faction. rosterSafari = Roster { rosterList = [ ( playerMonsterTourist , [(5, 15, "monster")] ) , ( playerHunamConvict , [(5, 2, "civilian")] ) , ( playerAnimalMagnificent , [(10, 15, "mobile animal")] ) , ( playerAnimalExquisite -- start on escape , [(15, 20, "mobile animal")] ) , (playerHorror, []) ] -- construction hooter; neutral , rosterEnemy = [ ("Alien Tourist Office", "Hunam Convict") , ( "Alien Tourist Office" , "Animal Magnificent Specimen Variety" ) , ( "Alien Tourist Office" , "Animal Exquisite Herds and Packs Galore" ) , ( "Animal Magnificent Specimen Variety" , "Hunam Convict" ) , ( "Hunam Convict" , "Animal Exquisite Herds and Packs Galore" ) ] , rosterAlly = [ ( "Animal Magnificent Specimen Variety" , "Animal Exquisite Herds and Packs Galore" ) ] } rosterSafariSurvival = rosterSafari { rosterList = [ ( playerMonsterTourist { fleaderMode = LeaderAI $ AutoLeader True True , fhasUI = False } , [(5, 15, "monster")] ) , ( playerHunamConvict , [(5, 3, "civilian")] ) , ( playerAnimalMagnificent { fleaderMode = LeaderUI $ AutoLeader True False , fhasUI = True } , [(10, 20, "mobile animal")] ) , ( playerAnimalExquisite , [(15, 30, "mobile animal")] ) , (playerHorror, []) ] } rosterBattle = Roster { rosterList = [ ( playerHero { fcanEscape = False , fhiCondPoly = hiHeroLong } , [(10, 5, "soldier hero")] ) , ( playerMonster {fneverEmpty = True} , [(10, 35, "mobile monster")] ) , ( playerAnimal {fneverEmpty = True} , [(10, 20, "mobile animal")] ) , ( playerRobot {fneverEmpty = True} , [(10, 15, "mobile robot")] ) ] , rosterEnemy = [ ("Spacefarer", "Alien Hierarchy") , ("Spacefarer", "Animal Kingdom") , ("Spacefarer", "Robot Anarchy") ] , rosterAlly = [ ("Alien Hierarchy", "Animal Kingdom") , ("Alien Hierarchy", "Robot Anarchy") , ("Robot Anarchy", "Animal Kingdom") ] } rosterBattleDefense = rosterBattle { rosterList = [ ( playerHero { fcanEscape = False , fhiCondPoly = hiHeroLong , fleaderMode = LeaderAI $ AutoLeader False False , fhasUI = False } , [(10, 5, "soldier hero")] ) , ( playerMonster { fneverEmpty = True , fhasUI = True } , [(10, 35, "mobile monster")] ) , ( playerAnimal {fneverEmpty = True} , [(10, 20, "mobile animal")] ) , ( playerRobot {fneverEmpty = True} , [(10, 15, "mobile robot")] ) ] } rosterBattleSurvival = rosterBattle { rosterList = [ ( playerHero { fcanEscape = False , fhiCondPoly = hiHeroLong , fleaderMode = LeaderAI $ AutoLeader False False , fhasUI = False } , [(10, 5, "soldier hero")] ) , ( playerMonster {fneverEmpty = True} , [(10, 35, "mobile monster")] ) , ( playerAnimal { fneverEmpty = True , fhasUI = True } , [(10, 20, "mobile animal")] ) , ( playerRobot {fneverEmpty = True} , [(10, 15, "mobile robot")] ) ] } rosterDefense = rosterCrawl { rosterList = [ ( playerAntiHero , [(3, 3, "crawl hero")] ) , ( playerAntiMonster , [] ) , ( playerAnimal , -- Fun from the start to avoid empty initial level: [ (3, 5 + 1 `d` 2, "animal") -- many, because no spawning -- Optional huge battle at the end: , (15, 100, "mobile animal") ] ) , ( playerRobot , [] ) ] } rosterDefenseEmpty = rosterCrawl { rosterList = [ ( playerAntiMonster {fneverEmpty = True} , [(4, 1, "scout monster")] ) , (playerHorror, []) ] -- for spawned and summoned animals , rosterEnemy = [] , rosterAlly = [] } cavesRaid, cavesBrawl, cavesShootout, cavesHunt, cavesEscape, cavesZoo, cavesAmbush, cavesCrawl, cavesCrawlEmpty, cavesDig, cavesSee, cavesSafari, cavesBattle :: Caves cavesRaid = [([3], ["caveRaid"])] cavesBrawl = [([4], ["caveBrawl"])] cavesShootout = [([5], ["caveShootout"])] cavesHunt = [([7], ["caveHunt"])] cavesEscape = [([9], ["caveEscape"])] cavesZoo = [([11], ["caveZoo"])] cavesAmbush = [([13], ["caveAmbush"])] listCrawl :: [([Int], [GroupName CaveKind])] listCrawl = [ ([1], ["caveOutermost"]) , ([2], ["caveShallowRogue"]) , ([3], ["caveBridge"]) , ([4], ["caveNoise"]) , ([5], ["caveRogue"]) , ([6], ["caveArena"]) , ([7], ["caveResidential"]) -- reversed order, to match @reverse@ later on , ([8], ["caveLaboratory"]) , ([11, 10, 9], ["default random", "default random", "caveMuseum"]) , ([12], ["caveExit"]) , ([14, 13], ["default random", "caveCasino"]) , ([15], ["cavePower"]) ] -- Reversed to have the last cave small and exactly in the middle -- of the screen. cavesCrawl = reverse listCrawl cavesCrawlEmpty = reverse $ map (\(ns, grps) -> (ns, if grps == ["caveBridge"] then ["caveShallowRogue"] else grps)) listCrawl renumberCaves :: Int -> ([Int], [GroupName CaveKind]) -> ([Int], [GroupName CaveKind]) renumberCaves offset (ns, l) = (map (+ offset) ns, l) cavesDig = reverse $ concat $ zipWith (map . renumberCaves) [0, 15 ..] (replicate 100 listCrawl) cavesSee = let numberCaves n c = ([n], [c]) in reverse $ zipWith numberCaves [1..] $ concatMap (replicate 8) allCaves allCaves :: [GroupName CaveKind] allCaves = [ "caveRaid", "caveBrawl", "caveShootout", "caveHunt", "caveEscape", "caveZoo" , "caveAmbush" , "caveRogue", "caveResidential", "caveLaboratory", "caveArena", "caveCasino" , "caveMuseum", "caveNoise", "cavePower", "caveOutermost", "caveExit" ] cavesSafari = reverse [ ([5], ["caveSafari1"]) , ([10], ["caveSafari2"]) , ([15], ["caveSafari3"]) ] cavesBattle = [([10], ["caveBattle"])] Allure-0.9.5.0/GameDefinition/Content/ModeKindPlayer.hs0000644000000000000000000001452607346545000021007 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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, playerAntiHero, playerCivilian , playerMonster, playerAntiMonster, playerAnimal , playerHorror, playerMonsterTourist, playerHunamConvict , playerAnimalMagnificent, playerAnimalExquisite , hiHeroShort, hiHeroMedium, hiHeroLong, hiDweller , playerRobot ) where import Prelude () import Game.LambdaHack.Core.Prelude import Game.LambdaHack.Content.ModeKind import Game.LambdaHack.Definition.Ability playerHero, playerAntiHero, playerCivilian, playerMonster, playerAntiMonster, playerAnimal, playerHorror, playerMonsterTourist, playerHunamConvict, playerAnimalMagnificent, playerAnimalExquisite :: Player playerRobot :: Player playerHero = Player { fname = "Spacefarer" , fgroups = ["hero"] , fskillsOther = meleeAdjacent , fcanEscape = True , fneverEmpty = True , fhiCondPoly = hiHeroLong , fhasGender = True , ftactic = TExplore , fleaderMode = LeaderUI $ AutoLeader False False , fhasUI = True } playerAntiHero = playerHero { fleaderMode = LeaderAI $ AutoLeader True False , fhasUI = False } playerCivilian = Player { fname = "Civilian" , fgroups = ["hero", "civilian"] , fskillsOther = zeroSkills -- not coordinated by any leadership , fcanEscape = False , fneverEmpty = True , fhiCondPoly = hiHeroMedium , fhasGender = True , ftactic = TPatrol , fleaderMode = LeaderNull -- unorganized , fhasUI = False } playerMonster = Player { fname = "Alien Hierarchy" , fgroups = ["monster", "mobile monster", "aquatic monster"] , fskillsOther = zeroSkills , fcanEscape = False , fneverEmpty = False , fhiCondPoly = hiDweller , fhasGender = False , ftactic = TExplore , fleaderMode = -- No point changing leader on level, since all move and they -- don't follow the leader. LeaderAI $ AutoLeader True True , fhasUI = False } playerAntiMonster = playerMonster { fleaderMode = LeaderUI $ AutoLeader True True , fhasUI = True } playerAnimal = Player { fname = "Animal Kingdom" , fgroups = [ "animal", "mobile animal", "immobile animal", "aquatic animal" , "scavenger" ] , fskillsOther = zeroSkills , fcanEscape = False , fneverEmpty = False , fhiCondPoly = hiDweller , fhasGender = False , ftactic = TRoam -- can't pick up, so no point exploring , fleaderMode = LeaderNull , fhasUI = False } -- | 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 brawl game between two hero factions 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. playerHorror = Player { fname = "Horror Den" , fgroups = [horrorGroup] , fskillsOther = zeroSkills , fcanEscape = False , fneverEmpty = False , fhiCondPoly = [] , fhasGender = False , ftactic = TPatrol -- disoriented , fleaderMode = LeaderNull , fhasUI = False } playerMonsterTourist = playerAntiMonster { fname = "Alien Tourist Office" , fcanEscape = True , fneverEmpty = True -- no spawning , fhiCondPoly = hiHeroMedium , ftactic = TFollow -- follow-the-guide, as tourists do , fleaderMode = LeaderUI $ AutoLeader False False } playerHunamConvict = playerCivilian { fname = "Hunam Convict" , fleaderMode = LeaderAI $ AutoLeader True False } playerAnimalMagnificent = playerAnimal { fname = "Animal Magnificent Specimen Variety" , fneverEmpty = True } playerAnimalExquisite = playerAnimal { fname = "Animal Exquisite Herds and Packs Galore" , fneverEmpty = True } victoryOutcomes :: [Outcome] victoryOutcomes = [Conquer, Escape] hiHeroLong, hiHeroMedium, hiHeroShort, hiDweller :: HiCondPoly hiHeroShort = [ ( [(HiLoot, 100)] , [minBound..maxBound] ) , ( [(HiConst, 100)] , victoryOutcomes ) , ( [(HiSprint, -500)] -- speed matters, but only if fast enough , victoryOutcomes ) , ( [(HiSurvival, 10)] -- few points for surviving long , [minBound..maxBound] \\ victoryOutcomes ) ] hiHeroMedium = [ ( [(HiLoot, 200)] -- usually no loot, but if so, no harm , [minBound..maxBound] ) , ( [(HiConst, 200), (HiLoss, -10)] , victoryOutcomes ) , ( [(HiSprint, -500)] -- speed matters, but only if fast enough , victoryOutcomes ) , ( [(HiBlitz, -100)] -- speed matters always , victoryOutcomes ) , ( [(HiSurvival, 10)] -- few points for surviving long , [minBound..maxBound] \\ victoryOutcomes ) ] -- Heroes in long crawls rejoice in loot. hiHeroLong = [ ( [(HiLoot, 10000)] -- multiplied by fraction of collected , [minBound..maxBound] ) , ( [(HiSprint, -20000)] -- speedrun bonus, if below this number of turns , victoryOutcomes ) , ( [(HiBlitz, -100)] -- speed matters always , victoryOutcomes ) , ( [(HiSurvival, 10)] -- few points for surviving long , [minBound..maxBound] \\ victoryOutcomes ) ] -- Spawners get no points from loot, but try to kill -- all opponents fast or at least hold up for long. hiDweller = [ ( [(HiConst, 1000)] -- no loot, so big win reward , victoryOutcomes ) , ( [(HiConst, 1000), (HiLoss, -10)] , victoryOutcomes ) , ( [(HiSprint, -1000)] -- speedrun bonus, if below , victoryOutcomes ) , ( [(HiBlitz, -100)] -- speed matters , victoryOutcomes ) , ( [(HiSurvival, 100)] , [minBound..maxBound] \\ victoryOutcomes ) ] -- Allure-specific playerRobot = Player { fname = "Robot Anarchy" , fgroups = [ "robot", "mobile robot", "immobile robot" --, "aquatic robot" , "construction robot" ] , fskillsOther = zeroSkills , fcanEscape = False , fneverEmpty = False , fhiCondPoly = hiDweller , fhasGender = False , ftactic = TRoam -- TODO:TFollow -- coordinated via net, follow alien leader , fleaderMode = LeaderNull , fhasUI = False } Allure-0.9.5.0/GameDefinition/Content/PlaceKind.hs0000644000000000000000000014262107346545000017770 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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 ( content ) where import Prelude () import Game.LambdaHack.Core.Prelude import qualified Data.Text as T import Game.LambdaHack.Content.PlaceKind import Game.LambdaHack.Content.TileKind (TileKind) import Game.LambdaHack.Definition.Defs content :: [PlaceKind] content = [deadEnd, rect, rect2, rectWindows, glasshouse, glasshouse2, glasshouse3, glasshouse4, pulpit, ruin, ruin2, collapsed, collapsed2, collapsed3, collapsed4, collapsed5, collapsed6, collapsed7, pillar, pillar2, pillar3, pillar4, pillar5, pillar6, colonnade, colonnade2, colonnade3, colonnade4, colonnade5, colonnade6, colonnade7, colonnade8, colonnade9, colonnade10, lampPost, lampPost2, lampPost3, lampPost4, treeShade, fogClump, fogClump2, smokeClump, smokeClump2, smokeClump3FGround, bushClump, escapeDown, escapeDown2, escapeDown3, escapeDown4, escapeDown5, escapeDown6, escapeDown7, escapeDown8, escapeDown9, staircase1, staircase2, staircase3, staircase4, staircase5, staircase6, staircase7, staircase8, staircase9, staircase10, staircase11, staircase12, staircase13, staircase14, staircase15, staircase16, staircase17, staircase18, staircase19, staircase20, staircase21, staircase22, staircase23, staircase24, staircase25, staircase26, staircase27, staircase28, staircase29, staircase30, staircase31, staircase32, staircase33, staircase34, staircase35, staircase36, staircase37] -- Allure-specific ++ [staircaseLift11, staircaseLift12, staircaseLift13, staircaseLift14, staircaseLift15, staircaseLift16, staircaseLift17, staircaseLift18, staircaseLift19, staircaseLift20, staircaseLift21, staircaseLift22, staircaseLift23, staircaseLift24, staircaseLift25] -- automatically generated ++ generatedStairs ++ generatedEscapes -- Allure-specific, continued ++ [ pumps, oval, ovalFloor, ovalSquare, ovalBasin, ovalBasin2, squareBasin, squareBasin2, floodedRoom, maze, maze2, maze3, mazeBig, mazeBig2, cells, cells2, cells3, cells4, cells5, cells6, cells7, tank, tank2, tank3, tank4, tank5, shuttleHusk, shuttleHusk2, shuttleHusk3, shuttleHusk4, shuttleHusk5, shuttleHusk6] deadEnd, rect, rect2, rectWindows, glasshouse, glasshouse2, glasshouse3, glasshouse4, pulpit, ruin, ruin2, collapsed, collapsed2, collapsed3, collapsed4, collapsed5, collapsed6, collapsed7, pillar, pillar2, pillar3, pillar4, pillar5, pillar6, colonnade, colonnade2, colonnade3, colonnade4, colonnade5, colonnade6, colonnade7, colonnade8, colonnade9, colonnade10, lampPost, lampPost2, lampPost3, lampPost4, treeShade, fogClump, fogClump2, smokeClump, smokeClump2, smokeClump3FGround, bushClump, escapeDown, escapeDown2, escapeDown3, escapeDown4, escapeDown5, escapeDown6, escapeDown7, escapeDown8, escapeDown9, staircase1, staircase2, staircase3, staircase4, staircase5, staircase6, staircase7, staircase8, staircase9, staircase10, staircase11, staircase12, staircase13, staircase14, staircase15, staircase16, staircase17, staircase18, staircase19, staircase20, staircase21, staircase22, staircase23, staircase24, staircase25, staircase26, staircase27, staircase28, staircase29, staircase30, staircase31, staircase32, staircase33, staircase34, staircase35, staircase36, staircase37 :: PlaceKind -- Allure-specific staircaseLift11, staircaseLift12, staircaseLift13, staircaseLift14, staircaseLift15, staircaseLift16, staircaseLift17, staircaseLift18, staircaseLift19, staircaseLift20, staircaseLift21, staircaseLift22, staircaseLift23, staircaseLift24, staircaseLift25, pumps, oval, ovalFloor, ovalSquare, ovalBasin, ovalBasin2, squareBasin, squareBasin2, floodedRoom, maze, maze2, maze3, mazeBig, mazeBig2, cells, cells2, cells3, cells4, cells5, cells6, cells7, tank, tank2, tank3, tank4, tank5, shuttleHusk, shuttleHusk2, shuttleHusk3, shuttleHusk4, shuttleHusk5, shuttleHusk6 :: PlaceKind staircase, staircaseLift :: PlaceKind -- templates staircaseBasic :: [PlaceKind] staircaseBasic = [staircase1, staircase2, staircase3, staircase4, staircase5, staircase6, staircase7, staircase8, staircase9, staircase10, staircase11, staircase12, staircase13, staircase14, staircase15, staircase16, staircase17, staircase18, staircase19, staircase20, staircase21, staircase22, staircase23, staircase24, staircase25, staircase26, staircase27, staircase28, staircase29, staircase30, staircase31, staircase32, staircase33, staircase34, staircase35, staircase36, staircase37] -- Allure-specific ++ [staircaseLift11, staircaseLift12, staircaseLift13, staircaseLift14, staircaseLift15, staircaseLift16, staircaseLift17, staircaseLift18, staircaseLift19, staircaseLift20, staircaseLift21, staircaseLift22, staircaseLift23, staircaseLift24, staircaseLift25] generatedStairs :: [PlaceKind] generatedStairs = let (stairs, lifts) = partition ((/= "a lift") . pname) staircaseBasic gatedStairs = map switchStaircaseToGated stairs gatedLifts = map switchLiftToGated lifts decontaminatingStairs = map switchStaircaseToDecontaminating stairs decontaminatingLifts = map switchLiftToDecontaminating lifts weldedStairs = map switchStaircaseToWelded stairs weldedLifts = map switchLiftToWelded lifts outdoorStairs = map switchStaircaseToOutdoor stairs stairsAll = stairs ++ gatedStairs ++ decontaminatingStairs ++ weldedStairs ++ outdoorStairs liftsAll = lifts ++ gatedLifts ++ decontaminatingLifts ++ weldedLifts in gatedStairs ++ gatedLifts ++ decontaminatingStairs ++ decontaminatingLifts ++ weldedStairs ++ weldedLifts ++ outdoorStairs ++ map (switchExitToUp "stair terminal") stairsAll ++ map (switchExitToUp "lift terminal") liftsAll ++ map (switchExitToDown "stair terminal") stairsAll ++ map (switchExitToDown "lift terminal") liftsAll escapeDownBasic :: [PlaceKind] escapeDownBasic = [ escapeDown, escapeDown2, escapeDown3, escapeDown4, escapeDown5, escapeDown6 , escapeDown7, escapeDown8, escapeDown9 ] generatedEscapes :: [PlaceKind] generatedEscapes = let upEscapes = map switchEscapeToUp escapeDownBasic outdoorEscapes = map switchEscapeToOutdoorDown escapeDownBasic spaceshipEscapes = map switchEscapeToSpaceshipDown escapeDownBasic in upEscapes ++ outdoorEscapes ++ spaceshipEscapes -- The dots below are @Char.chr 183@, as defined in @TileKind.floorSymbol@. deadEnd = PlaceKind -- needs to have index 0 { psymbol = 'd' , pname = "a dead end" , pfreq = [] , prarity = [] , pcover = CStretch , pfence = FNone , ptopLeft = ["·"] , poverrideDark = [] , poverrideLit = [] } rect = PlaceKind -- Valid for any nonempty area, hence low frequency. { psymbol = 'r' , pname = "a room" , pfreq = [("rogue", 100), ("laboratory", 10)] , prarity = [(1, 10), (10, 6)] , pcover = CStretch , pfence = FWall , ptopLeft = ["·"] , poverrideDark = [] , poverrideLit = [] } rect2 = rect { pname = "a pen" , pfreq = [("shootout", 1), ("zoo", 10)] } rectWindows = PlaceKind { psymbol = 'w' , pname = "a shed" , pfreq = [("brawl", 12), ("escape", 20)] , prarity = [(1, 10), (10, 10)] , pcover = CStretch , pfence = FNone , ptopLeft = [ "#%" , "%·" ] , poverrideDark = [('%', "rectWindowsOver_%")] , poverrideLit = [('%', "rectWindowsOver_%")] } glasshouse = PlaceKind { psymbol = 'g' , pname = "a glasshouse" , pfreq = [("shootout", 8)] , prarity = [(1, 10), (10, 7)] , pcover = CStretch , pfence = FNone , ptopLeft = [ "%%" , "%·" ] , poverrideDark = [] , poverrideLit = [] } glasshouse2 = glasshouse { pname = "a glass cage" , pfreq = [("laboratory", 2), ("zoo", 30)] } glasshouse3 = glasshouse { pname = "an entertainment center" , pfreq = [("arena", 1), ("ambush", 10)] } glasshouse4 = glasshouse { pname = "an exhibition area" , pfreq = [("arena", 1), ("museum", 1)] } pulpit = PlaceKind { psymbol = 'p' , pname = "a stand podium" , pfreq = [("arena", 15), ("museum", 15), ("zoo", 80)] , prarity = [(1, 1)] , pcover = CMirror , pfence = FGround , ptopLeft = [ "%%·" , "%··" , "··0" ] , poverrideDark = [('0', "pulpit")] , poverrideLit = [('0', "pulpit")] -- except for floor, this will all be lit, regardless of night/dark; OK } ruin = PlaceKind { psymbol = 'R' , pname = "ruins" , pfreq = [("battle", 660), ("ambush", 70)] , prarity = [(1, 1)] , pcover = CStretch , pfence = FWall , ptopLeft = ["X"] , poverrideDark = [] , poverrideLit = [] } ruin2 = ruin { pname = "a scaffolding" , pfreq = [("noise", 2000), ("exit", 5), ("museum", 1)] } collapsed = PlaceKind { psymbol = 'c' , pname = "a hardware stack" , pfreq = [("noise", 1)] -- no point taking up space if very little space taken, -- but if no other place can be generated, a failsafe is useful , prarity = [(1, 1)] , pcover = CStretch , pfence = FNone , ptopLeft = [ "#" ] , poverrideDark = [('#', "doorlessMachineryOver_#")] , poverrideLit = [('#', "doorlessMachineryOver_#")] } collapsed2 = collapsed { pfreq = [("noise", 1000), ("battle", 200)] , ptopLeft = [ "X#" , "##" ] } collapsed3 = collapsed { pfreq = [("noise", 2000), ("battle", 200)] , ptopLeft = [ "XX#" , "###" ] } collapsed4 = collapsed { pfreq = [("noise", 2200), ("battle", 200)] , ptopLeft = [ "XXX#" , "####" ] } collapsed5 = collapsed { pfreq = [("noise", 3000), ("battle", 500)] , ptopLeft = [ "XX#" , "X##" , "###" ] } collapsed6 = collapsed { pfreq = [("noise", 4000), ("battle", 1000)] , ptopLeft = [ "XXX#" , "X###" , "####" ] } collapsed7 = collapsed { pfreq = [("noise", 4000), ("battle", 1000)] , ptopLeft = [ "XXX#" , "XX##" , "####" ] } pillar = PlaceKind { psymbol = 'p' , pname = "a market" , pfreq = [("rogue", 300), ("arena", 10000), ("empty", 400)] , prarity = [(1, 1)] , pcover = CStretch , pfence = FWall -- Larger rooms require support pillars. , ptopLeft = [ "····" , "·0··" , "····" , "····" ] , poverrideDark = [] , poverrideLit = [] } pillar2 = pillar { pname = "a mall" , pfreq = [("rogue", 10000), ("arena", 100000), ("empty", 5000)] , ptopLeft = [ "0····" , "·····" , "·····" , "···0·" , "····~" ] , poverrideDark = [('~', "poolOver_~_Dark")] , poverrideLit = [('~', "poolOver_~_Lit")] } pillar3 = pillar { pname = "a court" , pfreq = [ ("rogue", 250), ("arena", 15), ("museum", 10) , ("laboratory", 200) ] , ptopLeft = [ "#··" , "···" , "···" ] } pillar4 = pillar { pname = "a plaza" , pfreq = [ ("rogue", 1500), ("arena", 5000) , ("museum", 4000), ("laboratory", 1500) ] , ptopLeft = [ "#·#·" , "····" , "#···" , "····" ] } pillar5 = pillar { pname = "a bank outlet" , pfreq = [ ("rogue", 1200), ("arena", 6000) , ("empty", 600), ("exit", 600) ] , ptopLeft = [ "&i%·" , "ii#·" , "%#+·" , "····" ] , poverrideDark = [ ('&', "cache deposit"), ('+', "trapped door") , ('i', "floorActorItem") ] -- lit or not, randomly , poverrideLit = [ ('&', "cache deposit"), ('+', "trapped door") , ('i', "floorActorItem") ] -- lit or not, randomly } pillar6 = pillar { pname = "a jewelry store" , pfreq = [ ("rogue", 1200), ("arena", 6000) , ("museum", 7000), ("empty", 500) ] , ptopLeft = [ "0f··" , "ff%·" , "·%&·" , "····" ] , poverrideDark = [ ('&', "cache jewelry"), ('0', "lampPostOver_0") , ('f', "floorActorLit") ] , poverrideLit = [ ('&', "cache jewelry"), ('0', "lampPostOver_0") , ('f', "floorActorLit") ] } colonnade = PlaceKind { psymbol = 'c' , pname = "a colonnade" , pfreq = [ ("rogue", 12), ("noise", 1000), ("escape", 200) , ("exit", 180) ] , prarity = [(1, 12), (10, 12)] , pcover = CAlternate , pfence = FFloor , ptopLeft = [ "#·" , "··" ] , poverrideDark = [] , poverrideLit = [] } colonnade2 = colonnade { pfreq = [("rogue", 300)] , prarity = [(1, 1)] , pfence = FWall , ptopLeft = [ "#·" , "·#" ] } colonnade3 = colonnade { prarity = [(1, 120), (10, 120)] , ptopLeft = [ "··#" , "·#·" , "#··" ] } colonnade4 = colonnade { prarity = [(1, 1)] , pfreq = [("rogue", 1000)] , pfence = FWall , ptopLeft = [ "#··" , "·#·" , "··#" ] } colonnade5 = colonnade { prarity = [(1, 25), (10, 25)] , ptopLeft = [ "#··" , "··#" ] } colonnade6 = colonnade { prarity = [(1, 14), (10, 14)] , ptopLeft = [ "#·" , "··" , "·#" ] } colonnade7 = colonnade { pfreq = [("arena", 50), ("museum", 30), ("empty", 800)] , prarity = [(1, 7), (10, 7)] , ptopLeft = [ "0·" , "··" ] } colonnade8 = colonnade7 { prarity = [(1, 50), (10, 50)] , ptopLeft = [ "··0" , "·0·" , "0··" ] } colonnade9 = colonnade7 { prarity = [(1, 20), (10, 20)] , ptopLeft = [ "0··" , "··0" ] } colonnade10 = colonnade7 { prarity = [(1, 10), (10, 10)] , ptopLeft = [ "0·" , "··" , "·0" ] } lampPost = PlaceKind { psymbol = 'l' , pname = "a lamp-lit area" , pfreq = [ ("escape", 200), ("zoo", 100), ("ambush", 1000) , ("battle", 100) ] , prarity = [(1, 1)] , pcover = CVerbatim , pfence = FNone , ptopLeft = [ "X·X" , "·0·" , "X·X" ] , poverrideDark = [('0', "lampPostOver_0"), ('·', "floorActorLit")] , poverrideLit = [('0', "lampPostOver_0"), ('·', "floorActorLit")] } lampPost2 = lampPost { ptopLeft = [ "···" , "·0·" , "···" ] } lampPost3 = lampPost { pfreq = [("escape", 3000), ("zoo", 500), ("battle", 1100)] , ptopLeft = [ "XX·XX" , "X···X" , "··0··" , "X···X" , "XX·XX" ] } lampPost4 = lampPost { pfreq = [("escape", 3000), ("zoo", 500), ("battle", 600)] , ptopLeft = [ "X···X" , "·····" , "··0··" , "·····" , "X···X" ] } treeShade = PlaceKind { psymbol = 't' , pname = "a tree shade" , pfreq = [("brawl", 500)] , prarity = [(1, 1)] , pcover = CMirror , pfence = FNone , ptopLeft = [ "··s" , "s0·" , "Xs·" ] , poverrideDark = [ ('0', "treeShadeOver_0_Dark") , ('s', "treeShadeOver_s_Dark") , ('·', "shaded ground") ] , poverrideLit = [ ('0', "treeShadeOver_0_Lit") , ('s', "treeShadeOver_s_Lit") , ('·', "shaded ground") ] } fogClump = PlaceKind { psymbol = 'f' , pname = "a foggy patch" , pfreq = [("empty", 400), ("shootout", 70), ("escape", 60)] , prarity = [(1, 1)] , pcover = CMirror , pfence = FNone , ptopLeft = [ "f;" , ";f" , ";X" ] , poverrideDark = [('f', "fogClumpOver_f_Dark"), (';', "fog Lit")] , poverrideLit = [('f', "fogClumpOver_f_Lit"), (';', "fog Lit")] } fogClump2 = fogClump { pfreq = [("empty", 3000), ("shootout", 400), ("escape", 100)] , ptopLeft = [ "X;f" , "f;f" , ";;f" , "Xff" ] } smokeClump = PlaceKind { psymbol = 's' , pname = "a smoky patch" , pfreq = [("exit", 50), ("zoo", 40), ("ambush", 50)] , prarity = [(1, 1)] , pcover = CMirror , pfence = FNone , ptopLeft = [ "f;" , ";f" , ";X" ] , poverrideDark = [ ('f', "smokeClumpOver_f_Dark"), (';', "smoke Lit") , ('·', "floorActorDark") ] , poverrideLit = [ ('f', "smokeClumpOver_f_Lit"), (';', "smoke Lit") , ('·', "floorActorLit") ] } smokeClump2 = smokeClump { pfreq = [("exit", 300), ("zoo", 200), ("ambush", 150)] , ptopLeft = [ "X;f" , "f;f" , ";;f" , "Xff" ] } smokeClump3FGround = smokeClump { pname = "a burned out area" , pfreq = [("laboratory", 25)] , prarity = [(1, 1)] , pcover = CVerbatim , pfence = FGround , ptopLeft = [ ";f;" , "f·f" , "f·f" , ";f;" ] -- should not be used in caves with trails, because bushes should -- not grow over such artificial trails } bushClump = PlaceKind { psymbol = 'b' , pname = "a bushy patch" , pfreq = [("shootout", 100)] , prarity = [(1, 1)] , pcover = CMirror , pfence = FNone , ptopLeft = [ "f;" , ";X" -- one sure exit needed not to block a corner , ";f" ] , poverrideDark = [('f', "bushClumpOver_f_Dark"), (';', "bush Lit")] , poverrideLit = [('f', "bushClumpOver_f_Lit"), (';', "bush Lit")] -- should not be used in caves with trails, because bushes can't -- grow over such artificial trails } escapeDown = PlaceKind { psymbol = '>' , pname = "an escape down" , pfreq = [("escape down", 1)] , prarity = [(1, 1)] , pcover = CVerbatim , pfence = FGround , ptopLeft = [ ">" ] , poverrideDark = [ ('*', "oil spill"), ('g', "frozen path") , ('0', "lampPostOver_0") , ('f', "floorActorLit"), ('r', "rubbleOrWaste_Dark") ] , poverrideLit = [ ('*', "oil spill"), ('g', "frozen path") , ('0', "lampPostOver_0") , ('f', "floorActorLit"), ('r', "rubbleOrWaste_Lit") ] } escapeDown2 = escapeDown { pfreq = [("escape down", 200)] , pfence = FFloor , ptopLeft = [ "#·#" , "·>·" , "#·#" ] } escapeDown3 = escapeDown { pfreq = [("escape down", 200)] , pfence = FFloor , ptopLeft = [ "·#·" , "#>#" , "·#·" ] } escapeDown4 = escapeDown { pfreq = [("escape down", 200)] , pfence = FWall , ptopLeft = [ "^·^" , "·>·" , "^·^" ] } escapeDown5 = escapeDown { pfreq = [("escape down", 200)] , pcover = CMirror , pfence = FFloor , ptopLeft = [ "r#·" , "r>#" , "rrr" ] } escapeDown6 = escapeDown { pfreq = [("escape down", 1000)] , pfence = FWall , ptopLeft = [ "··#··" , "·#*#·" , "#*>*#" , "·#*#·" , "··#··" ] } escapeDown7 = escapeDown { pfreq = [("escape down", 1000)] , pfence = FFloor , ptopLeft = [ "·*#*·" , "*#*#*" , "#*>*#" , "*#*#*" , "·*#*·" ] } escapeDown8 = escapeDown { pfreq = [("escape down", 1000)] , pcover = CMirror , pfence = FWall , ptopLeft = [ "··#g·" , "·#gg·" , "·#>g#" , "·gg#·" , "g·#··" ] } escapeDown9 = escapeDown { pfreq = [("escape down", 1000)] , pcover = CMirror , pfence = FFloor , ptopLeft = [ "·f·#" , "%f>·" , "%0f·" , "ff%%" ] } staircase = PlaceKind { psymbol = '/' , pname = "a staircase" , pfreq = [("tiny staircase", 1)] -- no cover when arriving; low freq , prarity = [(1, 100), (10, 100)] , pcover = CVerbatim , pfence = FGround , ptopLeft = [ "" ] , poverrideDark = [ ('<', "staircase up"), ('>', "staircase down") , ('I', "signboard"), ('S', "fillerWall") ] , poverrideLit = [ ('<', "staircase up"), ('>', "staircase down") , ('I', "signboard"), ('S', "fillerWall") ] } staircase1 = staircase { prarity = [(1, 1)] -- no cover when arriving; so low rarity } staircase2 = staircase { pfreq = [("tiny staircase", 3)] , prarity = [(1, 1)] , pfence = FGround , ptopLeft = [ "··" ] } -- Allure-specific: staircaseLift = PlaceKind { psymbol = '|' , pname = "a lift" , pfreq = [("tiny lift", 1)] , prarity = [(1, 100), (10, 100)] , pcover = CVerbatim , pfence = FFloor , ptopLeft = [ "" ] , poverrideDark = overrideLift , poverrideLit = overrideLift } staircase3 = staircaseLift { prarity = [(1, 1)] } staircase4 = staircaseLift { pfreq = [("tiny lift", 3)] , prarity = [(1, 1)] , ptopLeft = [ "··" ] } staircase5 = staircase { pfreq = [("open staircase", 200)] -- no cover, open , pfence = FGround , ptopLeft = [ "#·#" , "···" , "" , "···" , "#·#" ] } staircase6 = staircaseLift { pfreq = [("open lift", 300)] , pfence = FGround , ptopLeft = [ "#·#·#" , "·····" , "··" , "·····" , "#·#·#" ] } staircase7 = staircase { pfreq = [("open staircase", 500)] , pfence = FGround , ptopLeft = [ "#·#·#·#" , "·······" , "#··#" , "·······" , "#·#·#·#" ] } staircase8 = staircaseLift { pfreq = [("open lift", 2000)] , pfence = FGround , ptopLeft = [ "·#·#·#·" , "#·····#" , "····" , "#·····#" , "·#·#·#·" ] } staircase9 = staircase { pfreq = [("open staircase", 500)] , pfence = FGround , ptopLeft = [ "#·······#" , "······" , "#·······#" ] } staircase10 = staircaseLift { pfreq = [("open lift", 500)] , pfence = FGround , ptopLeft = [ "0·····0" , "····" , "0·····0" ] } staircase11 = staircase { pfreq = [("closed staircase", 2000)] -- weak cover, low freq , pfence = FFloor , ptopLeft = [ "·#·" , "#·#" , "···" , "" , "···" , "#·#" , "·#·" ] } staircase12 = staircase { pfreq = [("closed staircase", 4000)] , pfence = FFloor , ptopLeft = [ "·#·#·" , "#·#·#" , "·····" , "··" , "·····" , "#·#·#" , "·#·#·" ] } staircase13 = staircase { pfreq = [("closed staircase", 6000)] , pfence = FFloor , ptopLeft = [ "·#·#·#·" , "#·#·#·#" , "·······" , "0··0" , "·······" , "#·#·#·#" , "·#·#·#·" ] } staircase14 = staircase { pfreq = [("closed staircase", 10000)] , pfence = FFloor , ptopLeft = [ "#·#·#·#" , "·#·#·#·" , "#·····#" , "····" , "#·····#" , "·#·#·#·" , "#·#·#·#" ] } staircase15 = staircase { pfreq = [("closed staircase", 20000)] , pfence = FFloor , ptopLeft = [ "·#·#·#·#·" , "#·#·#·#·#" , "·#~~~~~#·" , "#~~~~#" , "·#~~~~~#·" , "#·#·#·#·#" , "·#·#·#·#·" ] } staircase16 = staircase { pfreq = [("closed staircase", 20000)] , pfence = FFloor , ptopLeft = [ "#·#·#·#·#" , "·#·#·#·#·" , "#·······#" , "·#··#·" , "#·······#" , "·#·#·#·#·" , "#·#·#·#·#" ] } staircase17 = staircase { pfreq = [("closed staircase", 20000)] , pfence = FFloor , ptopLeft = [ "#·#·#·#·#·#" , "·#·#·#·#·#·" , "#·#·····#·#" , "·#····#·" , "#·#·····#·#" , "·#·#·#·#·#·" , "#·#·#·#·#·#" ] } staircase18 = staircase { pfreq = [("closed staircase", 80000)] , pfence = FFloor , ptopLeft = [ "XX#·#·#·#XX" , "X#·#·#·#·#X" , "#·#·····#·#" , "·#····#·" , "#·#·····#·#" , "X#·#·#·#·#X" , "XX#·#·#·#XX" ] } staircase19 = staircase { pfreq = [("closed staircase", 20000)] , pfence = FFloor , ptopLeft = [ "·#·#·#·#·#·" , "#·#·#·#·#·#" , "·#·······#·" , "#·#··#·#" , "·#·······#·" , "#·#·#·#·#·#" , "·#·#·#·#·#·" ] } staircase20 = staircase { pfreq = [("closed staircase", 5000)] , pfence = FFloor , ptopLeft = [ "·#·#·0·#·#·" , "#·#·····#·#" , "·#····#·" , "#·#·····#·#" , "·#·#·I·#·#·" ] } staircase21 = staircase { pfreq = [("closed staircase", 5000)] , pfence = FFloor , ptopLeft = [ "#·#·I·#·#" , "·#·····#·" , "#····#" , "·#·····#·" , "#·#·0·#·#" ] } staircase22 = staircase { pfreq = [("closed staircase", 2000)] , pfence = FFloor , ptopLeft = [ "#·#·····#·#" , "·#····#·" , "#·#·····#·#" ] } staircase23 = staircase { pfreq = [("closed staircase", 1000)] , pfence = FFloor , ptopLeft = [ "·#·······#·" , "#·#··#·#" , "·#·······#·" ] } staircase24 = staircase { pfreq = [("closed staircase", 1000)] , pfence = FFloor , ptopLeft = [ "·#·····#·" , "#····#" , "·#·····#·" ] } staircase25 = staircase { pfreq = [("walled staircase", 100)] , pfence = FWall , ptopLeft = [ "·····" , "··" , "·····" ] } staircase26 = staircase { pfreq = [("walled staircase", 200)] , pfence = FWall , ptopLeft = [ "·······" , "····" , "·······" ] } staircase27 = staircaseLift { pfreq = [("walled lift", 500)] , pfence = FWall , ptopLeft = [ "#·····#" , "····" , "#·····#" ] } staircase28 = staircaseLift { pfreq = [("walled lift", 1000)] , pfence = FWall , ptopLeft = [ "·····" , "·····" , "··" , "·····" , "·····" ] } staircase29 = staircase { pfreq = [("walled staircase", 1000)] , pfence = FWall , ptopLeft = [ "#···#" , "·····" , "··" , "·····" , "#···#" ] } staircase30 = staircaseLift { pfreq = [("walled lift", 1000)] , pfence = FWall , ptopLeft = [ "#···#" , "·····" , "··" , "·····" , "#···#" ] } staircase31 = staircase { pfreq = [("walled staircase", 2000)] , pfence = FWall , ptopLeft = [ "·······" , "·~~~~~·" , "·~~·" , "·~~~~~·" , "·······" ] } staircase32 = staircaseLift { pfreq = [("walled lift", 5000)] , pfence = FWall , ptopLeft = [ "#·····#" , "·······" , "····" , "·······" , "#·····#" ] } staircase33 = staircase { pfreq = [("walled staircase", 5000)] , pfence = FWall , ptopLeft = [ "#·#·#·#" , "·······" , "#··#" , "·······" , "#·#·#·#" ] } staircase34 = staircaseLift { pfreq = [("walled lift", 5000)] , pfence = FWall , ptopLeft = [ "·#·#·#·" , "#·····#" , "····" , "#·····#" , "·#·#·#·" ] } staircase35 = staircase { pfreq = [("walled staircase", 1000)] , pfence = FWall , ptopLeft = [ "·········" , "······" , "·········" ] } staircase36 = staircaseLift { pfreq = [("walled lift", 1000)] , pfence = FWall , ptopLeft = [ "·#·····#·" , "#····#" , "·#·····#·" ] } staircase37 = staircase { pfreq = [("walled staircase", 1000)] , pfence = FWall , ptopLeft = [ "·········" , "·0··0·" , "·········" ] } -- * Allure-specific overrideLift :: [(Char, GroupName TileKind)] overrideLift = [ ('<', "staircase lift up"), ('>', "staircase lift down") , ('I', "signboard"), ('S', "lift shaft") ] staircaseLift11 = staircase11 { pname = "a lift" , pfreq = [("closed lift", 2000)] -- weak cover, low freq , poverrideDark = overrideLift , poverrideLit = overrideLift } staircaseLift12 = staircase12 { pname = "a lift" , pfreq = [("closed lift", 4000)] , poverrideDark = overrideLift , poverrideLit = overrideLift } staircaseLift13 = staircase13 { pname = "a lift" , pfreq = [("closed lift", 6000)] , poverrideDark = overrideLift , poverrideLit = overrideLift } staircaseLift14 = staircase14 { pname = "a lift" , pfreq = [("closed lift", 10000)] , poverrideDark = overrideLift , poverrideLit = overrideLift } staircaseLift15 = staircase15 { pname = "a lift" , pfreq = [("closed lift", 20000)] , poverrideDark = overrideLift , poverrideLit = overrideLift } staircaseLift16 = staircase16 { pname = "a lift" , pfreq = [("closed lift", 20000)] , poverrideDark = overrideLift , poverrideLit = overrideLift } staircaseLift17 = staircase17 { pname = "a lift" , pfreq = [("closed lift", 20000)] , poverrideDark = overrideLift , poverrideLit = overrideLift } staircaseLift18 = staircase18 { pname = "a lift" , pfreq = [("closed lift", 80000)] , poverrideDark = overrideLift , poverrideLit = overrideLift } staircaseLift19 = staircase19 { pname = "a lift" , pfreq = [("closed lift", 20000)] , poverrideDark = overrideLift , poverrideLit = overrideLift } staircaseLift20 = staircase20 { pname = "a lift" , pfreq = [("closed lift", 5000)] , poverrideDark = overrideLift , poverrideLit = overrideLift } staircaseLift21 = staircase21 { pname = "a lift" , pfreq = [("closed lift", 5000)] , poverrideDark = overrideLift , poverrideLit = overrideLift } staircaseLift22 = staircase22 { pname = "a lift" , pfreq = [("closed lift", 2000)] , poverrideDark = overrideLift , poverrideLit = overrideLift } staircaseLift23 = staircase23 { pname = "a lift" , pfreq = [("closed lift", 1000)] , poverrideDark = overrideLift , poverrideLit = overrideLift } staircaseLift24 = staircase24 { pname = "a lift" , pfreq = [("closed lift", 1000)] , poverrideDark = overrideLift , poverrideLit = overrideLift } staircaseLift25 = staircase25 { pname = "a lift" , pfreq = [("walled lift", 100)] , poverrideDark = overrideLift , poverrideLit = overrideLift } pumps = PlaceKind { psymbol = 'w' , pname = "water pumps" , pfreq = [ ("rogue", 200), ("laboratory", 100), ("empty", 2000) , ("brawl", 80), ("shootout", 50) ] , prarity = [(1, 1)] , pcover = CAlternate , pfence = FWall , ptopLeft = [ "·f" , "%·" ] , poverrideDark = [ ('%', "doorlessMachineryOver_#") , ('f', "pumpsOver_f_Dark") ] , poverrideLit = [ ('%', "doorlessMachineryOver_#") , ('f', "pumpsOver_f_Lit") ] } oval = PlaceKind { psymbol = 'o' , pname = "a dome" , pfreq = [ ("rogue", 20000), ("arena", 30000), ("museum", 30000) , ("laboratory", 50000), ("empty", 5000), ("exit", 5000) , ("ambush", 20000) ] , prarity = [(1, 1)] , pcover = CStretch , pfence = FWall , ptopLeft = [ "####·" , "##···" , "#··tt" , "#·t··" , "··t··" ] , poverrideDark = [ ('t', "trailLit"), ('a', "safeTrailLit") , ('~', "poolOver_~_Dark") ] , poverrideLit = [ ('t', "trailLit"), ('a', "safeTrailLit") , ('~', "poolOver_~_Lit") ] } ovalFloor = oval { pfreq = [ ("rogue", 150000), ("arena", 60000), ("museum", 60000) , ("laboratory", 100000), ("empty", 10000), ("exit", 5000) , ("ambush", 100000) ] , pfence = FGround , ptopLeft = [ "aXXX##" , "X+###·" , "X#a···" , "X#·a·a" , "##··a·" , "#··a··" ] } ovalSquare = oval { pfence = FGround , ptopLeft = [ "X###+" , "##···" , "#····" , "#····" , "+····" ] } ovalBasin = oval { pname = "a water basin" , pfreq = [ ("rogue", 100000), ("arena", 200000), ("laboratory", 200000) , ("empty", 20000) ] , pfence = FGround , ptopLeft = [ "XXX+##" , "X###··" , "X#····" , "+#··~~" , "#··~~~" , "#··~~~" ] } ovalBasin2 = oval { pname = "a water basin" , pfreq = [ ("rogue", 600), ("arena", 10000), ("laboratory", 3000) , ("empty", 1800) ] , pfence = FWall , ptopLeft = [ "#···" , "··~~" , "·~~~" , "·~~~" ] } squareBasin = oval { pname = "a water basin" , pfreq = [("arena", 15000), ("laboratory", 3000), ("empty", 4000)] , pfence = FNone , ptopLeft = [ "0tt0t" , "t~~~~" , "t~0~~" , "0~~~~" , "t~~~~" ] } squareBasin2 = oval { pname = "a water basin" , pfreq = [("arena", 100000), ("laboratory", 50000), ("empty", 15000)] , pfence = FNone , ptopLeft = [ "0t0ttt" , "t~~~~~" , "0~~~~~" , "t~~0~~" , "t~~~~~" , "t~~~~~" ] } floodedRoom = PlaceKind -- Valid for any nonempty area, hence low frequency. { psymbol = 'f' , pname = "a flooded room" , pfreq = [("rogue", 10), ("laboratory", 12), ("brawl", 40), ("zoo", 50)] , prarity = [(1, 1)] , pcover = CStretch , pfence = FWall , ptopLeft = ["~"] , poverrideDark = [] , poverrideLit = [] } maze = PlaceKind { psymbol = 'm' , pname = "an intricate maze" , pfreq = [ ("rogue", 60), ("laboratory", 1500), ("arena", 3) , ("museum", 3), ("exit", 300) ] , prarity = [(1, 1)] , pcover = CStretch , pfence = FWall , ptopLeft = [ "##··" , "#··#" , "··#·" ] , poverrideDark = [ ('&', "cache maze"), ('+', "trapped door") , ('i', "floorActorItem") -- lit or not, randomly , ('$', "trappableWall") ] , poverrideLit = [ ('&', "cache maze"), ('+', "trapped door") , ('i', "floorActorItem") -- lit or not, randomly , ('$', "trappableWall") ] } maze2 = maze { pfreq = [ ("rogue", 180), ("laboratory", 12000), ("arena", 6) , ("museum", 6), ("exit", 360) ] , ptopLeft = [ "#·##·" , "·#··#" , "···#·" ] } maze3 = maze { pfreq = [ ("rogue", 300), ("laboratory", 15000), ("arena", 9) , ("exit", 400) ] , ptopLeft = [ "##·##·" , "#·#··#" , "~·%···" ] } mazeBig = maze { pfreq = [ ("rogue", 600), ("laboratory", 3000), ("arena", 5000) , ("exit", 500) ] , pfence = FNone , ptopLeft = [ "X$$$$" , "$·##·" , "$#···" , "$#·+%" , "$··%i" ] } mazeBig2 = maze { pfreq = [ ("rogue", 1500), ("laboratory", 8000), ("arena", 10000) , ("exit", 700) ] , pfence = FNone , ptopLeft = [ "XX$$$~" , "X#···%" , "$·###·" , "$·+&%%" , "$·#iii" ] } cells = PlaceKind { psymbol = '#' , pname = "air filters" , pfreq = [ ("rogue", 40), ("laboratory", 48), ("museum", 10) , ("exit", 240), ("noise", 480) , ("zoo", 700), ("ambush", 80) ] , prarity = [(1, 1)] , pcover = CReflect , pfence = FWall , ptopLeft = [ "#··" , "·%·" , "··#" ] , poverrideDark = [ ('%', "doorlessMachineryOver_#") , ('f', "bushClumpOver_f_Dark"), ('o', "oilOver_o_Dark") ] , poverrideLit = [ ('%', "doorlessMachineryOver_#") , ('f', "bushClumpOver_f_Lit"), ('o', "oilOver_o_Lit") ] } cells2 = cells { pname = "humidity equalizers" , prarity = [(1, 2), (10, 2)] , ptopLeft = [ "f·#·" -- extra column to avoid blocked exits , "·#··" , "·#··" ] } cells3 = cells { pname = "thermostat units" , ptopLeft = [ "·^#" , "·#~" , "··#" ] } cells4 = cells { pname = "a power node" , ptopLeft = [ "·o#" , "o#o" , "#o·" ] } cells5 = cells -- this one is distinct enough from others, so needs a boost { pname = "broken robot holds" , pfreq = [ ("rogue", 20), ("laboratory", 15) , ("empty", 80), ("exit", 90), ("noise", 150) ] , ptopLeft = [ "··#" , "··#" , "##o" ] } cells6 = cells { pname = "animal holding pens" , pfreq = [ ("arena", 2), ("laboratory", 8), ("zoo", 80)] , ptopLeft = [ "··#" , "##'" ] } cells7 = cells { pname = "a defunct control room" , pfreq = [ ("rogue", 5), ("laboratory", 20) , ("empty", 100), ("exit", 30), ("noise", 100), ("ambush", 50) ] , pfence = FFloor , ptopLeft = [ "%·o" , "·#o" ] } tank = PlaceKind { psymbol = 'c' , pname = "a tank" , pfreq = [("empty", 1)] -- no point taking up space if very little space taken, -- but if no other place can be generated, a failsafe is useful , prarity = [(1, 1)] , pcover = CStretch , pfence = FNone , ptopLeft = [ "#" ] , poverrideDark = [('#', "doorlessWallOver_#"), ('r', "reinforced wall")] , poverrideLit = [('#', "doorlessWallOver_#"), ('r', "reinforced wall")] } tank2 = tank { pfreq = [ ("empty", 500), ("exit", 15), ("noise", 100) , ("battle", 50) ] , ptopLeft = [ "0#" , "##" ] } tank3 = tank { pfreq = [ ("empty", 600), ("exit", 30), ("noise", 200) , ("battle", 100) ] , ptopLeft = [ "rr#" , "r##" , "###" ] } tank4 = tank { pfreq = [ ("empty", 800), ("exit", 120), ("noise", 300) , ("battle", 300) ] , ptopLeft = [ "XX0#" , "Xrr#" , "0r##" , "####" ] } tank5 = tank { pname = "a cistern" , pfreq = [ ("empty", 1000), ("exit", 150), ("noise", 300) , ("battle", 300) ] , ptopLeft = [ "XXr#" , "Xr##" , "r###" , "####" ] } shuttleHusk = PlaceKind { psymbol = 's' , pname = "a shuttle husk" , pfreq = [("empty", 1000), ("exit", 15000), ("ambush", 15000)] , prarity = [(1, 1)] , pcover = CMirror , pfence = FGround , ptopLeft = [ "X·###·X" -- 7 x 9 , "X%#w#%X" , "#%···%#" , "#··h··#" , "#w··rw#" , "···rr&c" , "###&###" , "XhhchhX" , "hh#w#hh" ] , poverrideDark = [ ('·', "oily floor Dark") , ('r', "rubbleOrWaste_Dark") , ('#', "shuttle hull") , ('c', "cache shuttle") , ('h', "hardware rack") , ('w', "reinforced wall") ] , poverrideLit = [ ('·', "oily floor Lit") , ('r', "rubbleOrWaste_Lit") , ('#', "shuttle hull") , ('c', "cache shuttle") , ('h', "hardware rack") , ('w', "reinforced wall") ] } shuttleHusk2 = shuttleHusk { pfreq = [("empty", 1000), ("exit", 15000), ("ambush", 15000)] , ptopLeft = map (T.cons 'X' . flip T.snoc 'X') $ ptopLeft shuttleHusk -- 9 x 9 } shuttleHusk3 = shuttleHusk { pfreq = [("empty", 300), ("exit", 5000), ("ambush", 5000)] , ptopLeft = [ "X··##··X" -- 8 x 8 , "X#%ww%#X" , "#w····w#" , "····h·r#" , "#·rrrrr#" , "###&&###" , "XhhcchhX" , "hh#ww#hh" ] } shuttleHusk4 = shuttleHusk3 { pfreq = [("empty", 300), ("exit", 5000), ("ambush", 5000)] , ptopLeft = map (T.cons 'X' . flip T.snoc 'X') $ ptopLeft shuttleHusk3 -- 10 x 8 } shuttleHusk5 = shuttleHusk { pfreq = [("empty", 1600), ("exit", 80000), ("ambush", 80000)] , pfence = FGround , ptopLeft = [ "···##···" -- 8 x 10 , "w#%ww%#w" , "X#····#X" , "X···h·#X" , "#w····w#" , "%rr····%" , "##rrrr##" , "X##&&##X" , "XhhcchhX" , "hh#ww#hh" ] } shuttleHusk6 = shuttleHusk { pfreq = [("empty", 2000), ("exit", 120000), ("ambush", 120000)] , ptopLeft = [ "X··###··X" -- 9 x 10 , "X#%#w#%#X" , "##·h·h·##" , "········%" , "#w·····w#" , "%·····rr%" , "##·rrrr##" , "X###&###X" , "XXhhchhXX" , "Xhh#w#hhX" ] } -- * Helper functions switchExitToUp :: Text -> PlaceKind -> PlaceKind switchExitToUp terminal s = s { psymbol = '<' , pname = pname s <+> "up" , pfreq = map (\(t, k) -> (toGroupName $ fromGroupName t <+> "up", k)) $ pfreq s , poverrideDark = ('>', toGroupName $ terminal <+> "Dark") : filter ((/= '>') . fst) (poverrideDark s) , poverrideLit = ('>', toGroupName $ terminal <+> "Lit") : filter ((/= '>') . fst) (poverrideLit s) } switchExitToDown :: Text -> PlaceKind -> PlaceKind switchExitToDown terminal s = s { psymbol = '>' , pname = pname s <+> "down" , pfreq = map (\(t, k) -> (toGroupName $ fromGroupName t <+> "down", k)) $ pfreq s , poverrideDark = ('<', toGroupName $ terminal <+> "Dark") : filter ((/= '<') . fst) (poverrideDark s) , poverrideLit = ('<', toGroupName $ terminal <+> "Lit") : filter ((/= '<') . fst) (poverrideLit s) } overrideGatedStaircase :: [(Char, GroupName TileKind)] overrideGatedStaircase = [ ('<', "gated staircase up"), ('>', "gated staircase down") , ('I', "signboard"), ('S', "fillerWall") ] switchStaircaseToGated :: PlaceKind -> PlaceKind switchStaircaseToGated s = s { psymbol = 'g' , pname = T.unwords $ "a gated" : tail (T.words (pname s)) , pfreq = map (first (\t -> toGroupName $ "gated" <+> fromGroupName t)) $ pfreq s , poverrideDark = overrideGatedStaircase , poverrideLit = overrideGatedStaircase } overrideGatedLift :: [(Char, GroupName TileKind)] overrideGatedLift = [ ('<', "gated lift up"), ('>', "gated lift down") , ('I', "signboard"), ('S', "lift shaft") ] switchLiftToGated :: PlaceKind -> PlaceKind switchLiftToGated s = s { psymbol = 'g' , pname = T.unwords $ "a gated" : tail (T.words (pname s)) , pfreq = map (first (\t -> toGroupName $ "gated" <+> fromGroupName t)) $ pfreq s , poverrideDark = overrideGatedLift , poverrideLit = overrideGatedLift } overrideDecontaminatingStaircase :: [(Char, GroupName TileKind)] overrideDecontaminatingStaircase = [ ('<', "decontaminating staircase up") , ('>', "decontaminating staircase down") , ('I', "signboard"), ('S', "fillerWall") ] switchStaircaseToDecontaminating :: PlaceKind -> PlaceKind switchStaircaseToDecontaminating s = s { psymbol = 'd' , pfreq = map (first (\t -> toGroupName $ "decontaminating" <+> fromGroupName t)) $ pfreq s , poverrideDark = overrideDecontaminatingStaircase , poverrideLit = overrideDecontaminatingStaircase } overrideDecontaminatingLift :: [(Char, GroupName TileKind)] overrideDecontaminatingLift = [ ('<', "decontaminating lift up") , ('>', "decontaminating lift down") , ('I', "signboard"), ('S', "lift shaft") ] switchLiftToDecontaminating :: PlaceKind -> PlaceKind switchLiftToDecontaminating s = s { psymbol = 'd' , pfreq = map (first (\t -> toGroupName $ "decontaminating" <+> fromGroupName t)) $ pfreq s , poverrideDark = overrideDecontaminatingLift , poverrideLit = overrideDecontaminatingLift } overrideWeldedStaircase :: [(Char, GroupName TileKind)] overrideWeldedStaircase = [ ('<', "welded staircase up"), ('>', "ordinary staircase down") , ('I', "signboard"), ('S', "fillerWall") ] switchStaircaseToWelded :: PlaceKind -> PlaceKind switchStaircaseToWelded s = s { psymbol = 'w' , pfreq = map (first (\t -> toGroupName $ "welded" <+> fromGroupName t)) $ pfreq s , poverrideDark = overrideWeldedStaircase , poverrideLit = overrideWeldedStaircase } overrideWeldedLift :: [(Char, GroupName TileKind)] overrideWeldedLift = [ ('<', "welded lift up"), ('>', "ordinary lift down") , ('I', "signboard"), ('S', "lift shaft") ] switchLiftToWelded :: PlaceKind -> PlaceKind switchLiftToWelded s = s { psymbol = 'w' , pfreq = map (first (\t -> toGroupName $ "welded" <+> fromGroupName t)) $ pfreq s , poverrideDark = overrideWeldedLift , poverrideLit = overrideWeldedLift } overrideOutdoor :: [(Char, GroupName TileKind)] overrideOutdoor = [ ('<', "staircase outdoor up"), ('>', "staircase outdoor down") , ('I', "signboard"), ('S', "fillerWall") ] switchStaircaseToOutdoor :: PlaceKind -> PlaceKind switchStaircaseToOutdoor s = s { psymbol = 'o' , pname = "an outdoor area exit" , pfreq = map (first (\t -> toGroupName $ "outdoor" <+> fromGroupName t)) $ pfreq s , poverrideDark = overrideOutdoor , poverrideLit = overrideOutdoor } switchEscapeToUp :: PlaceKind -> PlaceKind switchEscapeToUp s = s { psymbol = '<' , pname = "an escape up" , pfreq = map (\(_, n) -> ("escape up", n)) $ pfreq s , poverrideDark = ('>', "escape up") : poverrideDark s , poverrideLit = ('>', "escape up") : poverrideLit s } switchEscapeToOutdoorDown :: PlaceKind -> PlaceKind switchEscapeToOutdoorDown s = s { pname = "outdoor escape route" , pfreq = map (\(_, n) -> ("escape outdoor down", n)) $ pfreq s , poverrideDark = ('>', "escape outdoor down") : poverrideDark s , poverrideLit = ('>', "escape outdoor down") : poverrideLit s } switchEscapeToSpaceshipDown :: PlaceKind -> PlaceKind switchEscapeToSpaceshipDown s = s { pname = "escape from spaceship" , pfreq = map (\(_, n) -> ("escape spaceship down", n)) $ pfreq s , poverrideDark = ('>', "escape spaceship down") : poverrideDark s , poverrideLit = ('>', "escape spaceship down") : poverrideLit s } Allure-0.9.5.0/GameDefinition/Content/RuleKind.hs0000644000000000000000000000260107346545000017644 0ustar0000000000000000{-# LANGUAGE TemplateHaskell #-} -- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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 ( standardRules ) where import Prelude () import Language.Haskell.TH.Syntax import System.FilePath import System.IO (readFile) -- Cabal import qualified Paths_Allure as Self (getDataFileName, version) import Game.LambdaHack.Content.RuleKind standardRules :: RuleContent standardRules = RuleContent { rtitle = "Allure of the Stars" , rXmax = 80 , rYmax = 42 , rfontDir = $(do x <- qRunIO (Self.getDataFileName "GameDefinition/fonts") lift x) , rexeVersion = Self.version -- The strings containing the default configuration file -- included from config.ui.default. , rcfgUIName = "config.ui" <.> "ini" , rcfgUIDefault = $(do let path = "GameDefinition" "config.ui" <.> "default" qAddDependentFile path x <- qRunIO (readFile path) lift x) , rwriteSaveClips = 1000 , rleadLevelClips = 50 , rscoresFile = "Allure.scores" , rnearby = 20 , rstairWordCarried = ["staircase", "lift"] , rsymbolProjectile = '{' } Allure-0.9.5.0/GameDefinition/Content/TileKind.hs0000644000000000000000000010023507346545000017634 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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 ( content ) where import Prelude () import Game.LambdaHack.Core.Prelude import qualified Data.Text as T import Game.LambdaHack.Content.TileKind import Game.LambdaHack.Definition.Color import Game.LambdaHack.Definition.Defs content :: [TileKind] content = [unknown, unknownOuterFence, basicOuterFence, bedrock, wall, wallSuspect, wallObscured, wallObscuredDefaced, wallObscuredFrescoed, pillar, pillarCache, lampPost, signboardUnread, signboardRead, tree, treeBurnt, treeBurning, rubble, rubbleSpice, doorTrapped, doorClosed, stairsUp, stairsTrappedUp, stairsOutdoorUp, stairsGatedUp, stairsDown, stairsTrappedDown, stairsOutdoorDown, stairsGatedDown, escapeUp, escapeDown, escapeOutdoorDown, wallGlass, wallGlassSpice, pillarIce, pulpit, bush, bushBurnt, bushBurning, fog, fogDark, smoke, smokeDark, doorOpen, floorCorridor, floorArena, floorDamp, floorDirt, floorDirtSpice, floorActor, floorActorItem, floorAshes, shallowWater, shallowWaterSpice, shallowWater2, floorRed, floorBlue, floorGreen, floorBrown, floorArenaShade ] ++ map makeDarkColor ldarkColorable -- Allure-specific ++ [oriel, outerHullWall, rubbleBurning, rubbleBurningSpice, wallOpenable, wallObscuredSafety, wallObscured3dBillboard, liftShaft, rock, pillarCache2, pillarCache3, stairsDecontaminatingUp, stairsWelded, stairsLiftUp, stairsLiftTrappedUp, stairsLiftGatedUp, stairsLiftDecontaminatingUp, stairsLiftWelded, stairsDecontaminatingDown, stairsLiftDown, stairsLiftTrappedDown, stairsLiftGatedDown, stairsLiftDecontaminatingDown, escapeSpaceshipDown, emptyAirlock, reinforcedWall, reinforcedWallSpice, wallShuttle, wallShuttleSpice, machineWall, machineWallSpice, floorOily, oilSpill, oilSpillSpice, floorWindow] unknown, unknownOuterFence, basicOuterFence, bedrock, wall, wallSuspect, wallObscured, wallObscuredDefaced, wallObscuredFrescoed, pillar, pillarCache, lampPost, signboardUnread, signboardRead, tree, treeBurnt, treeBurning, rubble, rubbleSpice, doorTrapped, doorClosed, stairsUp, stairsTrappedUp, stairsOutdoorUp, stairsGatedUp, stairsDown, stairsTrappedDown, stairsOutdoorDown, stairsGatedDown, escapeUp, escapeDown, escapeOutdoorDown, wallGlass, wallGlassSpice, pillarIce, pulpit, bush, bushBurnt, bushBurning, fog, fogDark, smoke, smokeDark, doorOpen, floorCorridor, floorArena, floorDamp, floorDirt, floorDirtSpice, floorActor, floorActorItem, floorAshes, shallowWater, shallowWaterSpice, shallowWater2, floorRed, floorBlue, floorGreen, floorBrown, floorArenaShade :: TileKind -- Allure-specific oriel, outerHullWall, rubbleBurning, rubbleBurningSpice, wallOpenable, wallObscuredSafety, wallObscured3dBillboard, liftShaft, rock, pillarCache2, pillarCache3, stairsDecontaminatingUp, stairsWelded, stairsLiftUp, stairsLiftTrappedUp, stairsLiftGatedUp, stairsLiftDecontaminatingUp, stairsLiftWelded, stairsDecontaminatingDown, stairsLiftDown, stairsLiftTrappedDown, stairsLiftGatedDown, stairsLiftDecontaminatingDown, escapeSpaceshipDown, emptyAirlock, reinforcedWall, reinforcedWallSpice, wallShuttle, wallShuttleSpice, machineWall, machineWallSpice, floorOily, oilSpill, oilSpillSpice, floorWindow :: TileKind ldarkColorable :: [TileKind] ldarkColorable = [tree, bush, floorCorridor, floorArena, floorDamp, floorDirt, floorDirtSpice, floorActor, floorActorItem, shallowWater, shallowWaterSpice, shallowWater2, floorOily] -- Symbols to be used: -- LOS noLOS -- Walk .'~ :; -- noWalk %^ #O&<>+ -- -- can be opened ^&+ -- can be closed ' -- some noWalk can be changed without opening, regardless of symbol -- not used yet: -- : (curtain, etc., not flowing, but solid and static) -- ` (not distinct enough from ' and already used for some blasts) -- Note that for AI hints and UI comfort, most multiple-use @Embed@ tiles -- should have a variant, which after first use transforms into a different -- colour tile without @ChangeTo@ and similar (which then AI no longer touches). -- If a tile is supposed to be repeatedly activated by AI (e.g., cache), -- it should keep @ChangeTo@ for the whole time. -- * Main tiles, modified for Allure; some removed -- ** Not walkable -- *** Not clear unknown = TileKind -- needs to have index 0 and alter 1; no other with 1 { tsymbol = ' ' , tname = "unknown space" , tfreq = [("unknown space", 1)] , tcolor = defFG , tcolor2 = defFG , talter = 1 , tfeature = [Dark] } unknownOuterFence = TileKind { tsymbol = ' ' , tname = "unknown space" , tfreq = [("unknown outer fence", 1)] , tcolor = defFG , tcolor2 = defFG , talter = maxBound -- impenetrable , tfeature = [Dark] } basicOuterFence = TileKind { tsymbol = '#' , tname = "habitat containment wall" , tfreq = [("habitat containment wall", 1)] , tcolor = BrBlack , tcolor2 = BrBlack , talter = maxBound -- impenetrable , tfeature = [] } bedrock = TileKind { tsymbol = '#' , tname = "wall" , tfreq = [ ("fillerWall", 1), ("legendLit", 100), ("legendDark", 100) , ("rogueSet", 60), ("museumSetDark", 4), ("noiseSetLit", 450) , ("powerSetDark", 450), ("battleSetDark", 250) , ("escapeSetDark", 4) , ("stair terminal Lit", 100), ("stair terminal Dark", 100) , ("doorlessWallOver_#", 80), ("doorlessMachineryOver_#", 1) ] , tcolor = BrWhite , tcolor2 = defFG , talter = 100 , tfeature = [] } wall = bedrock { tfreq = [("trappableWall", 1), ("rectWindowsOver_%", 80)] , tfeature = [BuildAs "suspect wall"] } wallSuspect = TileKind -- only on client { tsymbol = '#' , tname = "suspect wall" , tfreq = [("suspect wall", 1)] , tcolor = BrWhite , tcolor2 = defFG , talter = 2 , tfeature = [ RevealAs "trapped door" , ObscureAs "obscured wall" ] } wallObscured = TileKind { tsymbol = '#' , tname = "scratched wall" , tfreq = [("obscured wall", 70)] , tcolor = BrWhite , tcolor2 = defFG , talter = 5 , tfeature = [ Embed "scratch on wall" , HideAs "suspect wall" ] } wallObscuredDefaced = TileKind { tsymbol = '#' , tname = "defaced wall" , tfreq = [ ("obscured wall", 45), ("escapeSetDark", 2) , ("museumSetDark", 2) ] , tcolor = BrWhite , tcolor2 = defFG , talter = 5 , tfeature = [ Embed "obscene pictogram" , HideAs "suspect wall" ] } wallObscuredFrescoed = TileKind { tsymbol = '#' , tname = "subtle mural" , tfreq = [("obscured wall", 5), ("museumSetDark", 2)] , tcolor = BrWhite , tcolor2 = defFG , talter = 5 , tfeature = [ Embed "subtle fresco" , HideAs "suspect wall" ] -- a bit beneficial, but AI would loop if allowed to trigger -- so no @ConsideredByAI@ } pillar = TileKind { tsymbol = '0' , tname = "construction beam" , tfreq = [ ("legendLit", 100), ("legendDark", 100) , ("museumSetDark", 20), ("emptySetLit", 20) ] , tcolor = BrCyan -- not BrWhite, to tell from heroes , tcolor2 = Cyan , talter = 100 , tfeature = [] } pillarCache = TileKind { tsymbol = '#' , tname = "abandoned stash" , tfreq = [ ("cachable abandoned", 20) , ("cache maze", 33), ("cache shuttle", 25) ] , tcolor = BrBlue , tcolor2 = Blue , talter = 5 , tfeature = [ Embed "abandoned cache" , ChangeTo "cachable abandoned", ConsideredByAI ] -- Not explorable, but prominently placed, so hard to miss. -- Very beneficial, so AI eager to trigger, unless wary of traps. } lampPost = TileKind { tsymbol = '0' , tname = "lamp post" , tfreq = [("lampPostOver_0", 1)] , tcolor = BrYellow , tcolor2 = Brown , talter = 100 , tfeature = [] -- embed something and explain how there's often -- artificial ambient light in the habitats, but not in all -- of them and in both cases lamps are used to provide fancy -- (extra) lighting; say how low energy drain, such as -- permanent ambient light, is not a problem due to tech -- and also because it's a tiny fraction of what is needed -- for the ecosystem/life support } signboardUnread = TileKind -- client only, indicates never used by this faction { tsymbol = '0' , tname = "signboard" , tfreq = [("signboard unread", 1)] , tcolor = BrCyan , tcolor2 = Cyan , talter = 5 , tfeature = [ ConsideredByAI -- changes after use, so safe for AI , RevealAs "signboard" -- to display as hidden ] } signboardRead = TileKind { tsymbol = '0' , tname = "signboard" , tfreq = [ ("signboard", 1), ("emptySetLit", 1) , ("arenaSetLit", 1), ("arenaSetDark", 1), ("museumSetDark", 1) , ("escapeSetDark", 1) ] , tcolor = BrCyan , tcolor2 = Cyan , talter = 5 , tfeature = [Embed "signboard", HideAs "signboard unread"] } tree = TileKind { tsymbol = '0' , tname = "tree" , tfreq = [ ("brawlSetLit", 140), ("shootoutSetLit", 10) , ("huntSetLit", 10), ("escapeSetLit", 35), ("zooSetDark", 20) , ("treeShadeOver_0_Lit", 1) ] , tcolor = BrGreen , tcolor2 = Green , talter = 50 , tfeature = [] } treeBurnt = tree { tname = "burnt tree" , tfreq = [("zooSetDark", 10), ("tree with fire", 30)] , tcolor = BrBlack , tcolor2 = BrBlack , tfeature = Dark : tfeature tree } treeBurning = tree { tname = "burning tree" , tfreq = [("zooSetDark", 60), ("tree with fire", 70)] , tcolor = BrRed , tcolor2 = Red , talter = 5 , tfeature = Embed "big fire" : ChangeTo "tree with fire" : tfeature tree -- TODO: dousing off the tree will have more sense when it periodically -- explodes, hitting and lighting up the team and so betraying it } rubble = TileKind { tsymbol = '&' , tname = "rubble pile" , tfreq = [ ("rubble", 1), ("legendLit", 1), ("legendDark", 1) , ("stair terminal Lit", 6), ("stair terminal Dark", 6) , ("lift terminal Lit", 6), ("lift terminal Dark", 6) , ("emptySetLit", 4), ("exitSetLit", 8) , ("noiseSetLit", 50), ("powerSetDark", 150) , ("zooSetDark", 100), ("ambushSetDark", 3) ] , tcolor = BrYellow , tcolor2 = Brown , talter = 4 -- boss can dig through , tfeature = [OpenTo "floorAshesLit", Embed "rubble"] -- It's not explorable, due to not being walkable nor clear and due -- to being a door (@OpenTo@), which is kind of OK, because getting -- the item is risky and, e.g., AI doesn't attempt it. -- Also, AI doesn't go out of its way to clear the way for heroes. } rubbleSpice = rubble { tfreq = [ ("smokeClumpOver_f_Lit", 1), ("smokeClumpOver_f_Dark", 1) , ("rubbleOrWaste_Lit", 1), ("rubbleOrWaste_Dark", 1) , ("cache deposit", 33), ("cachable deposit", 80) ] , tfeature = Spice : tfeature rubble } doorTrapped = TileKind { tsymbol = '+' , tname = "trapped door" , tfreq = [("trapped door", 1)] , tcolor = BrRed , tcolor2 = Red , talter = 2 , tfeature = [ Embed "doorway trap" , OpenTo "open door" , HideAs "suspect wall" ] } doorClosed = TileKind { tsymbol = '+' , tname = "closed door" , tfreq = [("legendLit", 100), ("legendDark", 100), ("closed door", 1)] , tcolor = Brown , tcolor2 = BrBlack , talter = 2 , tfeature = [OpenTo "open door"] -- never hidden } stairsUp = TileKind { tsymbol = '<' , tname = "staircase up" , tfreq = [("staircase up", 9), ("ordinary staircase up", 1)] , tcolor = BrWhite , tcolor2 = defFG , talter = 0 -- very easy stairs, unlike all others , tfeature = [Embed "staircase up", ConsideredByAI] } stairsTrappedUp = TileKind { tsymbol = '<' , tname = "windy staircase up" , tfreq = [("staircase up", 1)] , tcolor = BrRed , tcolor2 = Red , talter = talterForStairs , tfeature = [ Embed "staircase up", Embed "staircase trap up" , ConsideredByAI, ChangeTo "ordinary staircase up" ] -- AI uses despite the trap; exploration more important } stairsOutdoorUp = stairsUp { tname = "signpost pointing backward" , tfreq = [("staircase outdoor up", 1)] , talter = talterForStairs } stairsGatedUp = stairsUp { tname = "gated staircase up" , tfreq = [("gated staircase up", 1)] , talter = talterForStairs + 2 -- animals and bosses can't use } stairsDown = TileKind { tsymbol = '>' , tname = "staircase down" , tfreq = [("staircase down", 9), ("ordinary staircase down", 1)] , tcolor = BrWhite , tcolor2 = defFG , talter = 0 -- very easy stairs, unlike all others , tfeature = [Embed "staircase down", ConsideredByAI] } stairsTrappedDown = TileKind { tsymbol = '>' , tname = "crooked staircase down" , tfreq = [("staircase down", 1)] , tcolor = BrRed , tcolor2 = Red , talter = talterForStairs , tfeature = [ Embed "staircase down", Embed "staircase trap down" , ConsideredByAI, ChangeTo "ordinary staircase down" ] } stairsOutdoorDown = stairsDown { tname = "signpost pointing forward" , tfreq = [("staircase outdoor down", 1)] , talter = talterForStairs } stairsGatedDown = stairsDown { tname = "gated staircase down" , tfreq = [("gated staircase down", 1)] , talter = talterForStairs + 2 -- animals and bosses can't use } escapeUp = TileKind { tsymbol = '<' , tname = "exit hatch up" , tfreq = [("legendLit", 1), ("legendDark", 1), ("escape up", 1)] , tcolor = BrYellow , tcolor2 = BrYellow , talter = 0 -- anybody can escape (or guard escape) , tfeature = [Embed "escape", ConsideredByAI] } escapeDown = TileKind { tsymbol = '>' , tname = "exit trapdoor down" , tfreq = [("legendLit", 1), ("legendDark", 1), ("escape down", 1)] , tcolor = BrYellow , tcolor2 = BrYellow , talter = 0 -- anybody can escape (or guard escape) , tfeature = [Embed "escape", ConsideredByAI] } escapeOutdoorDown = escapeDown { tname = "exit back to town" , tfreq = [("escape outdoor down", 1)] } -- *** Clear wallGlass = TileKind { tsymbol = '%' , tname = "transparent polymer wall" , tfreq = [("legendLit", 1), ("legendDark", 1), ("museumSetDark", 8)] , tcolor = BrBlue , tcolor2 = Blue , talter = 10 , tfeature = [BuildAs "closed door", Clear] } wallGlassSpice = wallGlass { tfreq = [ ("rectWindowsOver_%", 20) , ("cache jewelry", 66), ("cachable jewelry", 80) ] , tfeature = Spice : tfeature wallGlass } pillarIce = TileKind { tsymbol = '^' , tname = "ice buildup" , tfreq = [ ("legendLit", 1), ("legendDark", 1), ("noiseSetLit", 300) , ("brawlSetLit", 20), ("lift terminal Dark", 4) ] -- ice only in dark staircases , tcolor = BrBlue , tcolor2 = Blue , talter = 4 -- boss can dig through , tfeature = [Clear, Embed "frost", OpenTo "shallow water Lit"] -- Is door, due to @OpenTo@, so is not explorable, but it's OK, because -- it doesn't generate items nor clues. This saves on the need to -- get each ice pillar into sight range when exploring level. } pulpit = TileKind { tsymbol = '%' , tname = "VR booth" , tfreq = [("pulpit", 1)] , tcolor = BrYellow , tcolor2 = Brown , talter = 5 , tfeature = [Clear, Embed "pulpit"] -- mixed blessing, so AI ignores, saved for player fun } bush = TileKind { tsymbol = '%' , tname = "bush" , tfreq = [ ("bush Lit", 1), ("arenaSetLit", 10), ("shootoutSetLit", 30) , ("huntSetLit", 30), ("escapeSetLit", 40), ("zooSetDark", 100) , ("bushClumpOver_f_Lit", 1), ("pumpsOver_f_Lit", 1) , ("lift terminal Lit", 4) ] , tcolor = BrGreen , tcolor2 = Green , talter = 10 , tfeature = [Clear] } bushBurnt = bush { tname = "burnt bush" , tfreq = [ ("battleSetDark", 30), ("ambushSetDark", 3), ("zooSetDark", 50) , ("bush with fire", 70) ] , tcolor = BrBlack , tcolor2 = BrBlack , tfeature = Dark : tfeature bush } bushBurning = bush { tname = "burning bush" , tfreq = [ ("ambushSetDark", 10), ("zooSetDark", 300) , ("bush with fire", 30) ] , tcolor = BrRed , tcolor2 = Red , talter = 5 , tfeature = Embed "small fire" : ChangeTo "bush with fire" : tfeature bush } -- ** Walkable -- *** Not clear fog = TileKind { tsymbol = ';' , tname = "faint fog" , tfreq = [ ("fog Lit", 1), ("emptySetLit", 50), ("noiseSetLit", 120) , ("shootoutSetLit", 30), ("huntSetLit", 30) , ("fogClumpOver_f_Lit", 60), ("fogClumpOver_f_Dark", 60) , ("lift terminal Lit", 40) ] -- lit fog is OK for shootout, because LOS is mutual, as opposed -- to dark fog, and so camper has little advantage, especially -- on big maps, where he doesn't know on which side of fog patch to hide , tcolor = BrCyan , tcolor2 = Cyan , talter = 0 , tfeature = [Walkable, NoItem, OftenActor] } fogDark = fog { tname = "thick fog" , tfreq = [("escapeSetDark", 50), ("lift terminal Dark", 40)] , tfeature = Dark : tfeature fog } smoke = TileKind { tsymbol = ';' , tname = "billowing smoke" , tfreq = [ ("smoke Lit", 1), ("labTrailLit", 1) , ("stair terminal Lit", 2), ("lift terminal Lit", 6) , ("smokeClumpOver_f_Lit", 3), ("smokeClumpOver_f_Dark", 3) , ("exitSetLit", 20), ("ambushSetDark", 20) ] , tcolor = Brown , tcolor2 = BrBlack , talter = 0 , tfeature = [Walkable, NoItem] -- not dark, embers } smokeDark = smoke { tname = "lingering smoke" , tfreq = [ ("powerSetDark", 100) , ("zooSetDark", 20), ("ambushSetDark", 40), ("battleSetDark", 5) , ("stair terminal Dark", 2), ("lift terminal Dark", 6) ] , tfeature = Dark : tfeature smoke } -- *** Clear doorOpen = TileKind { tsymbol = '\'' , tname = "open door" , tfreq = [("legendLit", 100), ("legendDark", 100), ("open door", 1)] , tcolor = Brown , tcolor2 = BrBlack , talter = 4 , tfeature = [ Walkable, Clear, NoItem, NoActor , CloseTo "closed door" ] } floorCorridor = TileKind { tsymbol = floorSymbol , tname = "floor" , tfreq = [("floorCorridorLit", 1)] , tcolor = BrWhite , tcolor2 = defFG , talter = 0 , tfeature = [Walkable, Clear] } floorArena = floorCorridor { tfreq = [ ("floorArenaLit", 1), ("arenaSetLit", 200) , ("museumSetLit", 400), ("zooSetLit", 600) ] } floorDamp = floorArena { tname = "damp floor" , tfreq = [ ("noiseSetLit", 600), ("emptySetLit", 900) , ("damp floor Lit", 1) , ("stair terminal Lit", 20), ("lift terminal Lit", 6) ] } floorDirt = floorArena { tname = "dirt" , tfreq = [ ("brawlSetLit", 1000), ("shootoutSetLit", 1000) , ("huntSetLit", 1000), ("escapeSetLit", 1000) , ("ambushSetLit", 1000), ("battleSetLit", 1000) , ("dirt Lit", 1) ] } floorDirtSpice = floorDirt { tfreq = [ ("treeShadeOver_s_Lit", 1), ("bushClumpOver_f_Lit", 1) , ("pumpsOver_f_Lit", 3) ] , tfeature = Spice : tfeature floorDirt } floorActor = floorArena { tfreq = [("floorActorLit", 1)] , tfeature = OftenActor : tfeature floorArena } floorActorItem = floorActor { tfreq = [("floorActorItem", 1), ("legendLit", 100)] , tfeature = VeryOftenItem : tfeature floorActor } floorAshes = floorActor { tfreq = [ ("smokeClumpOver_f_Lit", 2), ("smokeClumpOver_f_Dark", 2) , ("floorAshesLit", 1), ("floorAshesDark", 1) ] , tname = "dirt and ash pile" , tcolor = Brown , tcolor2 = Brown } shallowWater = TileKind { tsymbol = '~' , tname = "water puddle" , tfreq = [ ("aquatic", 1), ("shallow water Lit", 1), ("legendLit", 100) , ("emptySetLit", 5), ("noiseSetLit", 30), ("shootoutSetLit", 5) , ("huntSetLit", 250), ("lift terminal Lit", 4) ] , tcolor = BrCyan , tcolor2 = Cyan , talter = 0 , tfeature = Embed "shallow water" : tfeature floorActor } shallowWaterSpice = shallowWater { tfreq = [ ("fogClumpOver_f_Lit", 40), ("pumpsOver_f_Lit", 3) , ("rubbleOrWaste_Lit", 1) ] , tfeature = Spice : tfeature shallowWater } shallowWater2 = shallowWater { tname = "water pool" , tfreq = [("poolOver_~_Lit", 1)] } floorRed = floorCorridor { tname = "emergency walkway" , tfreq = [ ("trailLit", 70), ("safeTrailLit", 70) , ("lift terminal Lit", 6), ("lift terminal Dark", 6) ] , tcolor = BrRed , tcolor2 = Red , tfeature = [Embed "straight path", Trail, Walkable, Clear] } floorBlue = floorRed { tname = "frozen path" , tfreq = [("trailLit", 100), ("frozen path", 1)] , tcolor = BrBlue , tcolor2 = Blue , tfeature = [Embed "frozen ground", Trail, Walkable, Clear] } floorGreen = floorRed { tname = "greenery trail" , tfreq = [("trailLit", 70), ("safeTrailLit", 70)] , tcolor = BrGreen , tcolor2 = Green } floorBrown = floorRed { tname = "transport route" , tfreq = [ ("trailLit", 50), ("safeTrailLit", 50) , ("transport route", 1) ] , tcolor = BrMagenta , tcolor2 = Magenta } floorArenaShade = floorActor { tname = "shaded ground" , tfreq = [("shaded ground", 1), ("treeShadeOver_s_Lit", 2)] , tcolor = BrYellow -- match others, even though no lit counterpart , tcolor2 = BrBlack , tfeature = Dark : NoItem : tfeature floorActor } -- * Allure-specific -- ** Not walkable -- *** Not clear oriel = TileKind { tsymbol = '%' -- story-wise it's transparent, hence the symbol , tname = "oriel" , tfreq = [ ("oriels fence", 15) , ("airlock fence", 5), ("empty airlock fence", 5) ] , tcolor = White , tcolor2 = Black , talter = 5 , tfeature = [Embed "black starry sky", Dark] } outerHullWall = basicOuterFence { tname = "outer hull wall" , tfreq = [ ("basic outer fence", 1), ("oriels fence", 85) , ("airlock fence", 40), ("empty airlock fence", 40) ] } rubbleBurning = TileKind -- present in "emptySetLit" for early light source { tsymbol = '&' , tname = "burning installation" , tfreq = [ ("emptySetLit", 2), ("powerSetDark", 20) , ("ambushSetDark", 15), ("zooSetDark", 30) , ("stair terminal Lit", 4), ("stair terminal Dark", 4) , ("lift terminal Lit", 4), ("lift terminal Dark", 4) ] , tcolor = BrRed , tcolor2 = Red , talter = 4 -- boss can dig through , tfeature = [ChangeTo "rubble", Embed "big fire"] } rubbleBurningSpice = rubbleBurning { tfreq = [ ("smokeClumpOver_f_Lit", 1), ("smokeClumpOver_f_Dark", 1) , ("cache deposit", 33) ] , tfeature = Spice : tfeature rubbleBurning } wallOpenable = bedrock { tfreq = [("openableWall", 1)] , tfeature = [BuildAs "closed door"] } wallObscuredSafety = TileKind { tsymbol = '#' , tname = "safety procedures board" , tfreq = [("obscured wall", 5), ("exitSetLit", 1)] , tcolor = BrWhite , tcolor2 = defFG , talter = 5 , tfeature = [ Embed "ruined first aid kit" , HideAs "suspect wall" ] } wallObscured3dBillboard = TileKind { tsymbol = '#' , tname = "3D billboard" , tfreq = [("obscured wall", 25)] , tcolor = BrWhite , tcolor2 = defFG , talter = 5 , tfeature = [ Embed "3D display" , HideAs "suspect wall" ] } liftShaft = pillar { tname = "lift shaft" , tfreq = [("lift shaft", 1)] } rock = pillar { tname = "rock" , tfreq = [("arenaSetLit", 4), ("arenaSetDark", 4), ("brawlSetLit", 30)] } pillarCache2 = pillarCache { tname = "rack of deposit boxes" , tfreq = [ ("cachable deposit", 20), ("cache deposit", 33) , ("stair terminal Lit", 1), ("stair terminal Dark", 1) ] , tfeature = [ Embed "deposit box" , ChangeTo "cachable deposit", ConsideredByAI ] } pillarCache3 = pillarCache { tname = "jewelry display" , tfreq = [ ("cachable jewelry", 20), ("cache jewelry", 33) , ("museumSetDark", 2) ] , tfeature = [ Embed "jewelry case", Embed "jewelry display trap" , ChangeTo "cachable jewelry", ConsideredByAI ] } stairsDecontaminatingUp = stairsUp { tname = "decontaminating staircase up" , tfreq = [("decontaminating staircase up", 1)] , tcolor = BrBlue , tcolor2 = Blue , talter = talterForStairs , tfeature = Embed "decontamination chamber" : tfeature stairsUp } stairsWelded = stairsUp { tname = "staircase up welded shut" , tfreq = [("welded staircase up", 1)] , tcolor = BrMagenta , tcolor2 = Magenta , talter = talterForStairs + 3 -- gear needed , tfeature = [ ConsideredByAI, ChangeTo "ordinary staircase up" , Embed "crude weld" ] } stairsLiftUp = stairsUp { tname = "lift up" , tfreq = [("staircase lift up", 9), ("ordinary lift up", 1)] , talter = talterForStairs , tcolor = BrCyan , tcolor2 = Cyan , tfeature = [Embed "lift up", ConsideredByAI] } stairsLiftTrappedUp = stairsTrappedUp { tname = "corroded lift up" , tfreq = [("staircase lift up", 1)] , tcolor = BrBlue , tcolor2 = Blue , tfeature = [ Embed "lift up", Embed "lift trap" , ConsideredByAI, ChangeTo "ordinary lift up" ] -- AI uses despite the trap; exploration more important } stairsLiftGatedUp = stairsLiftUp { tname = "manually opened lift up" , tfreq = [("gated lift up", 1)] , talter = talterForStairs + 2 -- animals and bosses can't use } stairsLiftDecontaminatingUp = stairsLiftUp { tname = "decontaminating lift up" , tfreq = [("decontaminating lift up", 1)] , tcolor = BrBlue , tcolor2 = Blue , tfeature = Embed "decontamination chamber" : tfeature stairsLiftUp } stairsLiftWelded = stairsLiftUp { tname = "lift up welded shut" , tfreq = [("welded lift up", 1)] , tcolor = BrMagenta , tcolor2 = Magenta , talter = talterForStairs + 3 -- gear needed , tfeature = [ ConsideredByAI, ChangeTo "ordinary lift up" , Embed "crude weld" ] } stairsDecontaminatingDown = stairsDown { tname = "decontaminating staircase down" , tfreq = [("decontaminating staircase down", 1)] , tcolor = BrBlue , tcolor2 = Blue , talter = talterForStairs , tfeature = Embed "decontamination chamber" : tfeature stairsDown } stairsLiftDown = stairsDown { tname = "lift down" , tfreq = [("staircase lift down", 9), ("ordinary lift down", 1)] , tcolor = BrCyan , tcolor2 = Cyan , talter = talterForStairs , tfeature = [Embed "lift down", ConsideredByAI] } stairsLiftTrappedDown = stairsTrappedDown { tname = "corroded lift down" , tfreq = [("staircase lift down", 1)] , tcolor = BrBlue , tcolor2 = Blue , tfeature = [ Embed "lift down", Embed "lift trap" , ConsideredByAI, ChangeTo "ordinary lift down" ] } stairsLiftGatedDown = stairsLiftDown { tname = "manually opened lift down" , tfreq = [("gated lift down", 1)] , talter = talterForStairs + 2 -- animals and bosses can't use } stairsLiftDecontaminatingDown = stairsLiftDown { tname = "decontaminating lift down" , tfreq = [("decontaminating lift down", 1)] , tcolor = BrBlue , tcolor2 = Blue , tfeature = Embed "decontamination chamber" : tfeature stairsLiftDown } escapeSpaceshipDown = escapeDown { tname = "airlock to a shuttle" , tfreq = [("escape spaceship down", 1), ("airlock fence", 3)] } emptyAirlock = escapeUp { tname = "empty airlock" , tfreq = [ ("airlock fence", 2), ("empty airlock fence", 7) , ("emptySetLit", 2), ("ambushSetDark", 7) ] -- not in exitSetLit; space can't be seen , tcolor = BrBlack , tcolor2 = BrBlack , tfeature = [Embed "disengaged docking"] } reinforcedWall = TileKind { tsymbol = '#' , tname = "reinforced wall" , tfreq = [("reinforced wall", 1), ("rogueSet", 15), ("exitSetLit", 20)] , tcolor = White , tcolor2 = BrBlack , talter = 100 , tfeature = [] } reinforcedWallSpice = reinforcedWall { tfreq = [ ("doorlessWallOver_#", 20) , ("cache maze", 66), ("cachable abandoned", 80) ] , tfeature = Spice : tfeature reinforcedWall } wallShuttle = bedrock { tname = "shuttle hull" , tfreq = [("shuttle hull", 1)] , tfeature = [Embed "shuttle hardware"] } wallShuttleSpice = wallShuttle { tfreq = [("cache shuttle", 75)] , tfeature = Spice : tfeature wallShuttle } -- *** Clear machineWall = TileKind { tsymbol = '%' , tname = "hardware rack" , tfreq = [ ("hardware rack", 1) , ("rogueSet", 25), ("noiseSetLit", 250), ("powerSetDark", 250) , ("exitSetLit", 30) , ("lift terminal Lit", 40), ("lift terminal Dark", 40) ] , tcolor = White , tcolor2 = BrBlack , talter = 100 , tfeature = [Clear] } machineWallSpice = machineWall { tfreq = [("doorlessMachineryOver_#", 1)] , tfeature = Spice : tfeature machineWall } -- ** Walkable -- *** Clear floorOily = floorArena { tname = "oily floor" , tfreq = [ ("powerSetLit", 600), ("exitSetLit", 900) , ("oily floor Lit", 1), ("rubbleOrWaste_Lit", 1) , ("oilOver_o_Lit", 4) ] } oilSpill = TileKind { tsymbol = '~' , tname = "oil spill" , tfreq = [ ("powerSetDark", 35), ("exitSetLit", 1) , ("ambushSetDark", 20), ("oil spill", 1) ] , tcolor = BrYellow , tcolor2 = BrGreen , talter = 0 , tfeature = Embed "machine oil" : tfeature floorActor } oilSpillSpice = oilSpill { tfreq = [ ("rubbleOrWaste_Lit", 1), ("rubbleOrWaste_Dark", 1) , ("oilOver_o_Lit", 1), ("oilOver_o_Dark", 1) ] , tfeature = Spice : tfeature oilSpill } floorWindow = floorArena { tsymbol = ' ' -- story-wise it's transparent, hence the symbol , tname = "floor window" , tfreq = [("emptySetLit", 6)] , tcolor = defFG , tcolor2 = defFG , tfeature = Embed "black starry sky" : tfeature floorCorridor } -- * Helper functions makeDark :: TileKind -> TileKind makeDark k = let darkText :: GroupName TileKind -> GroupName TileKind darkText t = maybe t (toGroupName . (<> "Dark")) $ T.stripSuffix "Lit" $ fromGroupName 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 (BuildAs t) = Just $ BuildAs $ darkText t darkFeat (RevealAs t) = Just $ RevealAs $ darkText t darkFeat (ObscureAs t) = Just $ ObscureAs $ darkText t darkFeat VeryOftenItem = Just OftenItem darkFeat OftenItem = Nothing -- items not common in the dark darkFeat feat = Just feat in k { tfreq = darkFrequency , tfeature = Dark : mapMaybe darkFeat (tfeature k) } -- The yellow colour represents a dark tile lit by artificial light source, -- or seen (felt, if very close) via noctovision. It is used to distinguish -- ambiently lit tiles and dark tiles lit by dynamic light. makeDarkColor :: TileKind -> TileKind makeDarkColor k = (makeDark k) { tcolor = if tsymbol k == floorSymbol && tcolor k == BrWhite then BrYellow else tcolor k , tcolor2 = BrBlack } Allure-0.9.5.0/GameDefinition/0000755000000000000000000000000007346545000014162 5ustar0000000000000000Allure-0.9.5.0/GameDefinition/InGameHelp.txt0000644000000000000000000001714107346545000016700 0ustar0000000000000000This is a snapshot of in-game help, rendered with default config file. For more general gameplay information see https://github.com/AllureOfTheStars/Allure/blob/master/GameDefinition/PLAYING.md Minimal cheat sheet for casual play. 7 8 9 Walk throughout a level with the mouse or the numeric keypad \|/ (top diagram) or the Vi editor keys (bottom) or with a compact 4-5-6 laptop setup (middle) that needs to be enabled in config.ui.ini. /|\ 1 2 3 Run until disturbed with Shift or Control. Go-to a position with LMB (left mouse button). Run collectively with S-LMB (press the button while holding Shift). 7 8 9 \|/ In aiming mode, the same keys (and mouse) move the x-hair u-i-o (aiming crosshair). Press `KP_5` (`5` on keypad) to wait, /|\ bracing for impact, which reduces any damage taken j k l and prevents displacement by foes. Press `C-KP_5` or `C-KP_5` (the same key with Shift or Control) to lurk 0.1 of a turn, without bracing. y k u \|/ You displace enemies by running into them with Shift/Control h-.-l or S-LMB. Search, open, descend and attack by bumping into /|\ walls, doors, stairs and enemies. The best item to attack with b j n is automatically chosen from among melee weapons in your personal equipment and your body parts. The following commands, joined with the basic set above, let you accomplish anything in the game, though not necessarily with the fewest keystrokes. You can also play the game exclusively with a mouse, or both mouse and keyboard. (See the ending help screens for mouse commands.) Lastly, you can select a command with arrows or mouse directly from the help screen or the dashboard and execute it on the spot. keys command E manage equipment of the leader g or , grab item(s) ESC open main menu/finish aiming RET or INS open dashboard/accept target SPACE clear messages and show history S-TAB cycle among all party members KP_* or ! cycle x-hair among enemies KP_/ or / cycle x-hair among items c close door % yell/yawn Here is the complete list of commands from the snapshot of in-game help. For more general gameplay information see https://github.com/AllureOfTheStars/Allure/blob/master/GameDefinition/PLAYING.md Item menu commands. keys command g or , grab item(s) d or . drop item(s) f fling projectile C-f auto-fling and keep choice a apply consumable C-a apply and keep choice p or i pack item e equip item s stash and share item Remaining item-related commands. keys command E manage equipment of the leader P or I manage inventory pack of the leader S manage the shared party stash G manage items on the ground A manage all owned items @ describe organs of the leader # show skill summary of the leader ~ display known lore Note how lower case item commands (pack an item, equip, stash) let you move items into a particular item store, while upper case item commands (manage Pack, Equipment, Stash, etc.) let you view and organize items within an item store. Once a store management menu is opened, you can switch stores at will, so the multiple commands only determine the starting item store. Each store is accessible from the dashboard as well. All terrain exploration and alteration commands. keys command TAB cycle among party members on the level S-TAB cycle among all party members c close door C open or close or alter = select (or deselect) party member _ deselect (or select) all on the level ; go to x-hair for 25 steps : run to x-hair collectively for 25 steps x explore nearest unknown spot X autoexplore 25 times R rest (wait 25 times) C-R heed (lurk 0.1 turns 100 times) 0, 1 ... 6 pick a particular actor as the new leader Aiming commands. keys command ESC open main menu/finish aiming RET or INS open dashboard/accept target KP_* or ! cycle x-hair among enemies KP_/ or / cycle x-hair among items + swerve the aiming line - unswerve the aiming line \ cycle aiming modes C-? set x-hair to nearest unknown spot C-/ set x-hair to nearest item C-{ set x-hair to nearest upstairs C-} set x-hair to nearest dnstairs < move aiming one level up > move aiming one level down BACKSPACE clear chosen item and x-hair Mouse commands. Screen area and UI mode (exploration/aiming) determine mouse click effects. First, we give an overview of effects of each button over the game map area. The list includes not only left and right buttons, but also the optional middle mouse button (MMB) and the mouse wheel, which is also used over menus, to page-scroll them. (For mice without RMB, one can use Control key with LMB and for mice without MMB, one can use C-RMB or C-S-LMB.) Next we show mouse button effects per screen area, in exploration mode and (if different) in aiming mode. keys command LMB go to pointer for 25 steps/fling at enemy S-LMB run to pointer collectively for 25 steps/fling at enemy RMB or C-LMB start aiming at enemy under pointer S-RMB open or close or alter at pointer MMB or C-RMB snap x-hair to floor under pointer WHEEL-UP swerve the aiming line WHEEL-DN unswerve the aiming line exploration LMB (left mouse button) RMB (right mouse button) message line clear messages and show history display help leader on map grab item(s) drop item(s) party on map pick new leader on screen select party member on screen the map area go to pointer for 25 steps set x-hair to enemy level number move aiming one level up move aiming one level down level caption open dashboard open main menu percent seen explore nearest unknown spot autoexplore 25 times x-hair info cycle x-hair among enemies cycle x-hair among items party roster pick new leader on screen select party member on screen Calm value yell/yawn yell/yawn HP gauge rest (wait 25 times) heed (lurk 0.1 turns 100 times) HP Value wait a turn, bracing for impact lurk 0.1 of a turn leader info auto-fling and keep choice clear chosen item and x-hair aiming mode LMB (left mouse button) RMB (right mouse button) the map area fling at enemy under pointer snap x-hair to enemy level caption accept target cancel aiming percent seen set x-hair to nearest upstairs set x-hair to nearest dnstairs Assorted commands. keys command SPACE clear messages and show history % yell/yawn C-s start new game C-x save and exit to desktop C-t toggle autoplay (insert coin) C-q quit game and start autoplay C-c exit to desktop without saving ? display help F1 display help immediately F12 open dashboard v voice again the recorded commands V voice recorded commands 100 times C-v voice recorded commands 1000 times C-V voice recorded commands 25 times ' start recording commands C-S save game backup C-P print screen Allure-0.9.5.0/GameDefinition/Main.hs0000644000000000000000000000564707346545000015416 0ustar0000000000000000{-# LANGUAGE PackageImports #-} -- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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 "TieKnot" is separated to make it usable in tests. module Main ( main ) where import Prelude () import Game.LambdaHack.Core.Prelude import Control.Concurrent.Async import qualified Control.Exception as Ex import qualified Options.Applicative as OA import System.Exit import qualified System.IO as SIO #ifndef USE_JSFILE import qualified GHC.IO.Handle import System.FilePath import Game.LambdaHack.Common.File (tryCreateDir) import Game.LambdaHack.Common.Misc #endif import Game.LambdaHack.Server (serverOptionsPI) -- For the case of flattened .cabal file, to avoid ambiguity. import "Allure" TieKnot -- | Parse commandline options, tie the engine, content and clients knot, -- run the game and handle exit. main :: IO () main = do -- This test is faulty with JS, because it reports the browser console -- is not a terminal, but then we can't open files to contain the logs. -- Also it bloats the outcome JS file, so disabled. #ifndef USE_JSFILE -- Special case hack, when the game is started not on a console. -- Without this, any attempt to output on stdout crashes a Windows exe -- (at least on Windows Vista) launched from the desktop or start menu. -- This is very crude and results in the inability to, e.g., process -- the output of @--help@ through a unix pipe. However, this should be -- effective on all Windows version, without the need to test all. isTerminal <- SIO.hIsTerminalDevice SIO.stdout unless isTerminal $ do dataDir <- appDataDir tryCreateDir dataDir fstdout <- SIO.openFile (dataDir "stdout.txt") SIO.WriteMode fstderr <- SIO.openFile (dataDir "stderr.txt") SIO.WriteMode GHC.IO.Handle.hDuplicateTo fstdout SIO.stdout GHC.IO.Handle.hDuplicateTo fstderr SIO.stderr #else -- Work around display of one character per line. SIO.hSetBuffering SIO.stderr SIO.LineBuffering #endif -- Fail here, not inside server code, so that savefiles are not removed, -- because they are not the source of the failure. !serverOptions <- OA.execParser serverOptionsPI resOrEx :: Either Ex.SomeException () <- Ex.try $ tieKnot serverOptions let unwrapEx e = #if MIN_VERSION_async(2,2,1) case Ex.fromException e of Just (ExceptionInLinkedThread _ ex) -> unwrapEx ex _ -> #endif e case resOrEx of Right () -> return () Left e -> case Ex.fromException $ unwrapEx e of Just ExitSuccess -> exitSuccess -- we are in the main thread, so here it really exits _ -> Ex.throwIO $ unwrapEx e Allure-0.9.5.0/GameDefinition/MainMenu.ascii0000755000000000000000000001002007346545000016701 0ustar0000000000000000 · ·· Allure of the Stars ······· · ········.··········· ···········..············· ·············..··················· {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ········....--:---.....··········· {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ·····..--::://+////:::--..··.-···· {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ··..--:////////::://////:-.-/+-····· {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ·.-:////:---.-:....---:///::::.······ {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ .-://:--......-........--://:-..······ {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ://:-.........:..........-:///:..······ {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ //:-....-.----:------......-://:-.····· {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ .-......---:::/:::::----....-://:..······· {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ -....----:////++////::---....-://-....··· {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ .....--::/+++oooooo+//::--....-:+/:..···· {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ....--://+oosyhhyysoo+/::--..--://:.······ {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ...---:/+osyhdmdddhyso+/:::--..-:+:-.····· {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ..--://+oshdmmNNNNmdhso+/:---...-//-.····· {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ..--:/+osydmNNNNNNNmdyo+/::-....-//:.····· {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ ..--:/+osydNNNNNNNNmdyo+/::-....-//:.····· ·······-/+/-----:://+sydmmNNNNNNmdyo+//:--...-//:.····· ·······.://-...--::/osyhdmmNNNNmdhso+/:--....-//-.····· ······.-//-...-::/+ooyhhhdmmddhyso+//::-....:+/-.····· ·······.-:+:----://+osyyyyyhhyysso++/:----..-//:.······ ·······.-/+::::::/+oossssssoooo++//::-....-:+/-.······ ·····-.-:++/:::///+++oooo+++////::---....-//:-.····· ·····.-/++//////++++++//:::::----...---//:-.······ ···.-:+o++/+++//////::------......-://:-.······ ···.-//+o++++//::::---.........--://:-.······ ····+-//+oo++//:::--.........--://:-..······ ···-.--+//+oo+///:--.....---:////:-.······· · ·/··/+-/-//++o++//:::::://///:--..······· ··/···+·..+.--:::////////////::--..········· ·+·····.··/··....···...---:---...·········· ·.··/·+·.·············.··············· ·· ···· ··························· ···.· /·· ····················· ··.··· ·.· ··········· Version X.X.X (frontend: xxx, engine: LambdaHack X.X.X) Allure-0.9.5.0/GameDefinition/MoveKeys.txt0000755000000000000000000000222307346545000016467 0ustar00000000000000007 8 9 Walk throughout a level with the mouse or the numeric keypad \|/ (top diagram) or the Vi editor keys (bottom) or with a compact 4-5-6 laptop setup (middle) that needs to be enabled in config.ui.ini. /|\ 1 2 3 Run until disturbed with Shift or Control. Go-to a position with LMB (left mouse button). Run collectively with S-LMB (press the button while holding Shift). 7 8 9 \|/ In aiming mode, the same keys (and mouse) move the x-hair u-i-o (aiming crosshair). Press `KP_5` (`5` on keypad) to wait, /|\ bracing for impact, which reduces any damage taken j k l and prevents displacement by foes. Press `C-KP_5` or `C-KP_5` (the same key with Shift or Control) to lurk 0.1 of a turn, without bracing. y k u \|/ You displace enemies by running into them with Shift/Control h-.-l or S-LMB. Search, open, descend and attack by bumping into /|\ walls, doors, stairs and enemies. The best item to attack with b j n is automatically chosen from among melee weapons in your personal equipment and your body parts. Allure-0.9.5.0/GameDefinition/PLAYING.md0000644000000000000000000004706407346545000015622 0ustar0000000000000000Playing Allure of the Stars =========================== The following blurb is a copy of the game intro screen. Your party of trusty explorers is about to test its fortune by plundering a vast derelict passenger cruiser. The spaceship was abandoned and lost after an accident at the Solar System's outer frontier, but recently unexpectedly reappeared. Reportedly, deposit safes and jewelry inventories were never salvaged. Neither were emptied the gilded robot holds, the expensive arboretum nor the extravagant whole-deck habitat of natural and enhanced wild animals. Up to this day, countless autonomous life support and damage mitigation subsystems with redundant power sources busy themselves throughout dozens of decks. They seem successful, because there are abundant traces of ongoing metabolism all over the ship. That should make exploration so much easier. Yours can't be the only shady Neptune Area crew interested in the giant wreck, so you shouldn't count on reaching it unopposed. The feral outer frontier denizens are not famed for scruples nor for restraint when using hazardous nano, cyber and bio technologies, so never assume you are safe. Be ready to hide in shadows, create distractions, set up ambushes, bump into unspeakable horrors, puzzling machinery and astounding treasures and make creative use of all you find, because you are on your own. If ever you turn your back in fear, expect to be chased tirelessly by sight, sound and smell. Allure of the Stars is a turn-based game. You issue a command. Then you watch its results unfold on the screen without you being able to intervene. Then all settles down and you have as much time as you want to inspect the battlefield and think about your next move. 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, because the game's plot and characters are yet very lightly sketched. However there are already hours and days of replayable fun to be had and gameplay mastery to build, confirm via high scores and pit against challenges. Contributions of all kinds are welcome. Please offer feedback to mikolaj.konarski@funktory.com or, preferably, at any of the public forums. If the game window is too large for your screen or you experience other technical issues, please consult [README.md](https://github.com/AllureOfTheStars/Allure/blob/master/README.md) or describe your problem on gitter or the issue tracker. Game map -------- The map of any particular scenario consists of one or many levels and each level has a large number of tiles with a particular terrain kind on each. The game world is persistent, i.e., every time the player visits a level during a single game, its layout is the same. Terrain is depicted with non-letter and non-digit (except zero `0`) characters, the same as items lying on the ground, though blocky solid symbol are more likely to be non-passable terrain than items. In case of doubt, one of the aiming commands (keypad `/`, with default keybinding) cycles through all visible and remembered items on the level and another (keypad `*`, with default keybinding) through all foes. Also, pointing at a map position with `MMB` (middle mouse button) displays a short description of its contents. The basic terrain kinds are as follows. terrain type on-screen symbol wall # tree or rock or man-made column 0 rubble & bush, transparent obstacle % trap, ice obstacle ^ closed door + open door ' smoke or fog ; ground, corridor . water ~ stairs or exit up < stairs or exit down > Actors are marked with lower and upper case letters and with characters `@` and `1` through `9` (but never `0`). Player-controlled heroes are always bright white and by default they are selected (e.g., to run together) so they have a blue highlight around their symbol. If player manages to control animals or other actors, they retain their letter and color, but gain a highlight as well. So, for example, the following map shows a room with a closed door, full of actors, connected by a corridor with a room with an open door, a pillar, a staircase down and rubble that obscures one of the corners. The lower row of the larger room is full of items. ###### ###### #@19.#########....&& #r...+.......'...0.>&&# #Ra..#########[?!,)$"=# ###### ########## Heroes ------ The heroes are displayed on the map with bright white color (red if they are about to fall down) and symbols `@` and `1` through `9` (never `0`). The currently chosen party leader is yellow-highlighted on the map and his attributes are displayed at the bottom-most status line which, in its most complex form, looks as follows. *@12 2m/s Calm: 20/60 HP: 33/50 Leader: Haskell Alvin 6d1+5% 4d1 The line starts with the list of party members, with the current leader highlighted in yellow. Most commands involve only the leader, including movement with keyboard's keypad or `LMB` (left mouse button). If more heroes are selected (highlighted in blue), they run together whenever `:` or `S-LMB` (while holding Shift) over map area is pressed. Any sleeping hero is highlighted in green and can be woken up by yelling with `%`, which also taunts or stresses nearby enemies. Next on the bottom-most status line is the leader's current and maximum Calm (morale, composure, focus, attentiveness), then his current and maximum HP (hit points, health). The colon after "Calm" turning into a dot signifies that the leader is in a position without ambient illumination, making a stealthy conduct easier. A brace sign instead of a colon after "HP" means the leader is braced for combat (see section [Basic Commands](#basic-commands)). In the second half of the bottom-most status line, the leader's name is shown. Then come damage dice of the leader's melee weapons and leader's appendages, ordered by their power. The dice of the first recharged weapon, the one that would be used in this moment, is adorned with percentage damage bonus collected from the whole equipment of the leader. If the dice are displayed with upper-case `D` instead of lower-case `d`, the weapon has additional effects apart of the usual kinetic damage. The nature of the effects can be appraised via the `E`quipment screen. Weapon damage and other item properties are displayed using the dice notation `xdy`, which denotes `x` rolls of `y`-sided dice. A variant written `xdLy` is additionally scaled by the level depth in proportion to the maximal level depth (at the first level it's always one, then it grows up to full rolled value at the last level). Section [Monsters](#monsters) below describes combat resolution in detail, including the role of the percentage damage bonus. The second, the upper status line describes the current level in relation to the party. 5 Lofty hall [33% seen] X-hair: dire basilisk [**__] First comes the depth of the current level and its name. Then the percentage of its explorable tiles already seen by the heroes. The `X-hair` (aiming crosshair) is the common focus of the whole party, marked on the map with a red box and manipulated with mouse or movement keys in aiming mode. In this example, the crosshair points at a dire basilisk monster, with its hit points drawn as a bar. Instead of a monster, the `X-hair` area may describe a position on the map, a recently spotted item on the floor or an item in inventory selected for further action or, if none are available, a summary of the team status. For example, this form 5 Lofty hall [33% seen] X-hair: exact spot (71,12) p15 l10 indicates that the party is aiming at an exact spot on the map. At the end of the status line comes the length of the shortest path from the leader's position to the spot and the straight-line distance between the two points, one that a flung projectile would travel. Basic Commands -------------- This section is a copy of the few basic screens of in-game help. The help pages are automatically generated based on a game's keybinding content and on overrides in the player's config file. The remaining in-game help screens, not shown here, list all game commands grouped by categories in detail. A text snapshot of the complete in-game help is in [InGameHelp.txt](InGameHelp.txt). Walk throughout a level with mouse or numeric keypad (left diagram below) or the Vi editor keys (right) or with a compact laptop setup (middle) that requires enabling in config.ui.ini. Run until disturbed with Shift or Control. Go-to with LMB (left mouse button). Run collectively via S-LMB (holding Shift). 7 8 9 7 8 9 y k u \|/ \|/ \|/ 4-5-6 u-i-o h-.-l /|\ /|\ /|\ 1 2 3 j k l b j n In aiming mode, the same keys (and mouse) move the x-hair (aiming crosshair). Press `KP_5` (`5` on keypad) to wait, bracing for impact, which reduces any damage taken and prevents displacement by foes. Press `S-KP_5` or `C-KP_5` (the same key with Shift or Control) to lurk 0.1 of a turn, without bracing. Displace enemies by running into them with Shift/Control or S-LMB. Search, open, descend and attack by bumping into walls, doors, stairs and enemies. The best melee weapon is automatically chosen from your equipment and from among your body parts. The following commands, joined with the basic set above, let you accomplish anything in the game, though not necessarily with the fewest keystrokes. You can also play the game exclusively with a mouse, or both mouse and keyboard. (See the ending help screens for mouse commands.) Lastly, you can select a command with arrows or mouse directly from the help screen or the dashboard and execute it on the spot. keys command E manage equipment of the leader g or , grab item(s) ESC open main menu/finish aiming RET or INS open dashboard/accept target SPACE clear messages and show history S-TAB cycle among all party members KP_* or ! cycle x-hair among enemies KP_/ or / cycle x-hair among items c close door % yell/yawn Screen area and UI mode (exploration/aiming) determine mouse click effects. First, we give an overview of effects of each button over the game map area. The list includes not only left and right buttons, but also the optional middle mouse button (MMB) and the mouse wheel, which is also used over menus, to page-scroll them. (For mice without RMB, one can use Control key with LMB and for mice without MMB, one can use C-RMB or C-S-LMB.) keys command LMB go to pointer for 25 steps/fling at enemy S-LMB run to pointer collectively for 25 steps/fling at enemy RMB or C-LMB start aiming at enemy under pointer S-RMB open or close or alter at pointer MMB or C-RMB snap x-hair to floor under pointer WHEEL-UP swerve the aiming line WHEEL-DN unswerve the aiming line Advanced Commands ----------------- For ranged attacks, setting the aiming crosshair beforehand is not mandatory, because x-hair is set automatically as soon as a monster comes into view and can still be adjusted for as long as the missile to fling is not chosen. However, sometimes you want to examine the level map tile by tile or assign persistent personal targets to party members. The latter is essential in the rare cases when your henchmen (non-leader characters) can move autonomously or fire opportunistically (via innate skills or rare equipment). Also, if your henchman is adjacent to more than one enemy, setting his target makes him melee a particular foe. You can enter the aiming mode with the `*` keypad key that selects enemies or the `/` key that cycles among items on the floor and marks a tile underneath an item. You can move x-hair with direction keys and assign a personal target to the leader with a `RET` key (Return, Enter). The details of the shared x-hair mark are displayed in a status line close to the bottom of the screen, as explained in section [Heroes](#heroes) above. Commands for saving and exiting the current game, starting a new game, configuring convenience settings for the current game and challenges for the next game are listed in the main menu, brought up by the `ESC` key. Game difficulty, from the challenges menu, determines hitpoints at birth: difficulty below 5 multiplies hitpoints of player characters, difficulty over 5 multiplies hitpoints of their enemies. Of the convenience settings, the `suspect terrain` choice is particularly interesting, because it determines not only screen display of the level map, but also whether suspect tiles are considered for auto-explore and for the `C-?` command that marks the nearest unexplored position. The "lone wolf" challenge mode reduces player's starting actors to exactly one (consequently, this does not affect the initial 'raid' scenario). The "cold fish" challenge mode makes it impossible for player characters to be healed by actors from other factions (this is a significant restriction in the final 'crawl' scenario). For a person new to roguelikes, the 'raid' scenario offers a gentle introduction. The subsequent game scenarios lead the player along an optional story arc. They gradually introduce squad combat, stealth, opportunity fire, asymmetric battles and more. Starting from the second scenario, the player controls a whole team of characters and will develop his repertoire of squad formations, preferred rendezvous locations and the use of light sources. The last scenario, a multi-level crawl, is the gist and the main challenge of the game. It spans 15 varied spaceship decks, requiring lots of time, focus and flexibility to beat and providing considerable replayability. The player has a choice of exploring a single level at a time or portions of many floors along a single staircase. On some levels he may explore and loot with a single scout eluding most opponents. On others he may be forced to change the pace and perform a complete exterminatory sweep involving his whole party. On yet others, his best course of action may be to defend a key location until the first wave of attackers is broken. The size of the crawl scenario calls for strategic thinking, including resource management, area denial and unavoidable temporary retreats to other levels. Compared to that, the smaller scenarios, where the arena is a single floor only, provide a mostly tactical training and additional entertainment by trying to beat a high-score. They offer variety and a breather between the deaths^H^H^H^H^H^H the brave attempts at the long crawl scenario. Some gameplay elements, however, like totally symmetric skirmishes, a race to the exit or heavy reliance on opportunity fire, feature only in the small scenarios. Monsters -------- The life of the heroes is full of dangers. Monstrosities, natural and out of this world, roam the dark corridors and crawl from damp holes 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. Monsters are depicted on the map with letters. Upper case letters are unique monsters, often guardians of special floors, and lower case letters are the rabble. If there are humans not from our team, they are marked with `@` and `1` through `9` in other colours than white. When a hero walks and bumps into a monster or a monster attacks the hero, melee combat occurs. Hero *running* into and displacing a monster (with the `Shift` or `Control` key), or the other way around, does not inflict damage, but exchanges places. This gives the opponent a free blow, but can improve the tactical situation or aid escape. In some circumstances actors are immune to the displacing, e.g., when both parties form a continuous front-line. In melee combat, the best recharged equipped weapon (or the best fighting organ that is not on cooldown) of each opponent is taken into account for determining the damage and any extra effects of the blow. To determine the damage dealt, the outcome of the weapon's damage dice roll is multiplied by a percentage bonus. The bonus is calculated by taking the damage bonus (summed from the equipped items of the attacker, capped at 200%) minus the melee armor modifier of the defender (capped at 200%, as well), with the outcome bounded between -99% and 99%, which means that at least 1% of damage always gets through and the damage is always lower than twice the dice roll. The current leader's melee bonus, armor modifier and other detailed skills can be viewed via the `#` command. In ranged combat, the projectile is assumed to be attacking the defender in melee, using itself as the weapon, with the usual dice and damage bonus. This time, the ranged armor skill of the defender is taken into account and, additionally, the speed of the missile (based on shape and weight) figures in the calculation. You may propel any item from your inventory (by default you are offered only the appropriate items; press `+` to cycle item menu modes). Only items of a few kinds inflict any damage, but some have other effects, beneficial, detrimental or mixed. In-game detailed item descriptions contain melee and ranged damage estimates. They do not take into account damage from effects and, if bonuses are not known, guesses are based on averages for the item kind in question. The displayed figures are rounded, but the game internally keeps track of minute fractions of HP. The stress of combat drains Calm, gradually limiting viewing radius and, if Calm reaches zero and the actor is sufficiently impressed by his foes, making him defect and surrender to their domination. Whenever the monster's or hero's hit points reach zero, the combatant is incapacitated and promptly dies. When the last hero dies or is dominated, the scenario ends in defeat. On Winning and Dying -------------------- You win a scenario if you escape the location alive (which may prove difficult, because your foes tend to gradually build up the ambush squad blocking your escape route) or, in scenarios with no exit locations, if you eliminate all opposition. In the former case, your score is based predominantly on the gold and precious gems you've plundered. In the latter case, your score is most influenced by the number of turns you spent overcoming your foes (the quicker the victory, the better; the slower the demise, the better). Bonus points, affected by the number of heroes lost, are awarded only if you win. The score is heavily modified by the chosen game difficulty, but not by any other challenges. When all your heroes fall, you are going to invariably see a new foolhardy party of adventurers clamoring to be led into the unknown perils. They start their conquest from a new entrance, with no experience and no equipment, and new undaunted enemies bar their way. Lead the new hopeful explorers to fame, wealth and glory! Allure-0.9.5.0/GameDefinition/PLAYING.md0000755000000000000000000004706407346545000015625 0ustar0000000000000000Playing Allure of the Stars =========================== The following blurb is a copy of the game intro screen. Your party of trusty explorers is about to test its fortune by plundering a vast derelict passenger cruiser. The spaceship was abandoned and lost after an accident at the Solar System's outer frontier, but recently unexpectedly reappeared. Reportedly, deposit safes and jewelry inventories were never salvaged. Neither were emptied the gilded robot holds, the expensive arboretum nor the extravagant whole-deck habitat of natural and enhanced wild animals. Up to this day, countless autonomous life support and damage mitigation subsystems with redundant power sources busy themselves throughout dozens of decks. They seem successful, because there are abundant traces of ongoing metabolism all over the ship. That should make exploration so much easier. Yours can't be the only shady Neptune Area crew interested in the giant wreck, so you shouldn't count on reaching it unopposed. The feral outer frontier denizens are not famed for scruples nor for restraint when using hazardous nano, cyber and bio technologies, so never assume you are safe. Be ready to hide in shadows, create distractions, set up ambushes, bump into unspeakable horrors, puzzling machinery and astounding treasures and make creative use of all you find, because you are on your own. If ever you turn your back in fear, expect to be chased tirelessly by sight, sound and smell. Allure of the Stars is a turn-based game. You issue a command. Then you watch its results unfold on the screen without you being able to intervene. Then all settles down and you have as much time as you want to inspect the battlefield and think about your next move. 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, because the game's plot and characters are yet very lightly sketched. However there are already hours and days of replayable fun to be had and gameplay mastery to build, confirm via high scores and pit against challenges. Contributions of all kinds are welcome. Please offer feedback to mikolaj.konarski@funktory.com or, preferably, at any of the public forums. If the game window is too large for your screen or you experience other technical issues, please consult [README.md](https://github.com/AllureOfTheStars/Allure/blob/master/README.md) or describe your problem on gitter or the issue tracker. Game map -------- The map of any particular scenario consists of one or many levels and each level has a large number of tiles with a particular terrain kind on each. The game world is persistent, i.e., every time the player visits a level during a single game, its layout is the same. Terrain is depicted with non-letter and non-digit (except zero `0`) characters, the same as items lying on the ground, though blocky solid symbol are more likely to be non-passable terrain than items. In case of doubt, one of the aiming commands (keypad `/`, with default keybinding) cycles through all visible and remembered items on the level and another (keypad `*`, with default keybinding) through all foes. Also, pointing at a map position with `MMB` (middle mouse button) displays a short description of its contents. The basic terrain kinds are as follows. terrain type on-screen symbol wall # tree or rock or man-made column 0 rubble & bush, transparent obstacle % trap, ice obstacle ^ closed door + open door ' smoke or fog ; ground, corridor . water ~ stairs or exit up < stairs or exit down > Actors are marked with lower and upper case letters and with characters `@` and `1` through `9` (but never `0`). Player-controlled heroes are always bright white and by default they are selected (e.g., to run together) so they have a blue highlight around their symbol. If player manages to control animals or other actors, they retain their letter and color, but gain a highlight as well. So, for example, the following map shows a room with a closed door, full of actors, connected by a corridor with a room with an open door, a pillar, a staircase down and rubble that obscures one of the corners. The lower row of the larger room is full of items. ###### ###### #@19.#########....&& #r...+.......'...0.>&&# #Ra..#########[?!,)$"=# ###### ########## Heroes ------ The heroes are displayed on the map with bright white color (red if they are about to fall down) and symbols `@` and `1` through `9` (never `0`). The currently chosen party leader is yellow-highlighted on the map and his attributes are displayed at the bottom-most status line which, in its most complex form, looks as follows. *@12 2m/s Calm: 20/60 HP: 33/50 Leader: Haskell Alvin 6d1+5% 4d1 The line starts with the list of party members, with the current leader highlighted in yellow. Most commands involve only the leader, including movement with keyboard's keypad or `LMB` (left mouse button). If more heroes are selected (highlighted in blue), they run together whenever `:` or `S-LMB` (while holding Shift) over map area is pressed. Any sleeping hero is highlighted in green and can be woken up by yelling with `%`, which also taunts or stresses nearby enemies. Next on the bottom-most status line is the leader's current and maximum Calm (morale, composure, focus, attentiveness), then his current and maximum HP (hit points, health). The colon after "Calm" turning into a dot signifies that the leader is in a position without ambient illumination, making a stealthy conduct easier. A brace sign instead of a colon after "HP" means the leader is braced for combat (see section [Basic Commands](#basic-commands)). In the second half of the bottom-most status line, the leader's name is shown. Then come damage dice of the leader's melee weapons and leader's appendages, ordered by their power. The dice of the first recharged weapon, the one that would be used in this moment, is adorned with percentage damage bonus collected from the whole equipment of the leader. If the dice are displayed with upper-case `D` instead of lower-case `d`, the weapon has additional effects apart of the usual kinetic damage. The nature of the effects can be appraised via the `E`quipment screen. Weapon damage and other item properties are displayed using the dice notation `xdy`, which denotes `x` rolls of `y`-sided dice. A variant written `xdLy` is additionally scaled by the level depth in proportion to the maximal level depth (at the first level it's always one, then it grows up to full rolled value at the last level). Section [Monsters](#monsters) below describes combat resolution in detail, including the role of the percentage damage bonus. The second, the upper status line describes the current level in relation to the party. 5 Lofty hall [33% seen] X-hair: dire basilisk [**__] First comes the depth of the current level and its name. Then the percentage of its explorable tiles already seen by the heroes. The `X-hair` (aiming crosshair) is the common focus of the whole party, marked on the map with a red box and manipulated with mouse or movement keys in aiming mode. In this example, the crosshair points at a dire basilisk monster, with its hit points drawn as a bar. Instead of a monster, the `X-hair` area may describe a position on the map, a recently spotted item on the floor or an item in inventory selected for further action or, if none are available, a summary of the team status. For example, this form 5 Lofty hall [33% seen] X-hair: exact spot (71,12) p15 l10 indicates that the party is aiming at an exact spot on the map. At the end of the status line comes the length of the shortest path from the leader's position to the spot and the straight-line distance between the two points, one that a flung projectile would travel. Basic Commands -------------- This section is a copy of the few basic screens of in-game help. The help pages are automatically generated based on a game's keybinding content and on overrides in the player's config file. The remaining in-game help screens, not shown here, list all game commands grouped by categories in detail. A text snapshot of the complete in-game help is in [InGameHelp.txt](InGameHelp.txt). Walk throughout a level with mouse or numeric keypad (left diagram below) or the Vi editor keys (right) or with a compact laptop setup (middle) that requires enabling in config.ui.ini. Run until disturbed with Shift or Control. Go-to with LMB (left mouse button). Run collectively via S-LMB (holding Shift). 7 8 9 7 8 9 y k u \|/ \|/ \|/ 4-5-6 u-i-o h-.-l /|\ /|\ /|\ 1 2 3 j k l b j n In aiming mode, the same keys (and mouse) move the x-hair (aiming crosshair). Press `KP_5` (`5` on keypad) to wait, bracing for impact, which reduces any damage taken and prevents displacement by foes. Press `S-KP_5` or `C-KP_5` (the same key with Shift or Control) to lurk 0.1 of a turn, without bracing. Displace enemies by running into them with Shift/Control or S-LMB. Search, open, descend and attack by bumping into walls, doors, stairs and enemies. The best melee weapon is automatically chosen from your equipment and from among your body parts. The following commands, joined with the basic set above, let you accomplish anything in the game, though not necessarily with the fewest keystrokes. You can also play the game exclusively with a mouse, or both mouse and keyboard. (See the ending help screens for mouse commands.) Lastly, you can select a command with arrows or mouse directly from the help screen or the dashboard and execute it on the spot. keys command E manage equipment of the leader g or , grab item(s) ESC open main menu/finish aiming RET or INS open dashboard/accept target SPACE clear messages and show history S-TAB cycle among all party members KP_* or ! cycle x-hair among enemies KP_/ or / cycle x-hair among items c close door % yell/yawn Screen area and UI mode (exploration/aiming) determine mouse click effects. First, we give an overview of effects of each button over the game map area. The list includes not only left and right buttons, but also the optional middle mouse button (MMB) and the mouse wheel, which is also used over menus, to page-scroll them. (For mice without RMB, one can use Control key with LMB and for mice without MMB, one can use C-RMB or C-S-LMB.) keys command LMB go to pointer for 25 steps/fling at enemy S-LMB run to pointer collectively for 25 steps/fling at enemy RMB or C-LMB start aiming at enemy under pointer S-RMB open or close or alter at pointer MMB or C-RMB snap x-hair to floor under pointer WHEEL-UP swerve the aiming line WHEEL-DN unswerve the aiming line Advanced Commands ----------------- For ranged attacks, setting the aiming crosshair beforehand is not mandatory, because x-hair is set automatically as soon as a monster comes into view and can still be adjusted for as long as the missile to fling is not chosen. However, sometimes you want to examine the level map tile by tile or assign persistent personal targets to party members. The latter is essential in the rare cases when your henchmen (non-leader characters) can move autonomously or fire opportunistically (via innate skills or rare equipment). Also, if your henchman is adjacent to more than one enemy, setting his target makes him melee a particular foe. You can enter the aiming mode with the `*` keypad key that selects enemies or the `/` key that cycles among items on the floor and marks a tile underneath an item. You can move x-hair with direction keys and assign a personal target to the leader with a `RET` key (Return, Enter). The details of the shared x-hair mark are displayed in a status line close to the bottom of the screen, as explained in section [Heroes](#heroes) above. Commands for saving and exiting the current game, starting a new game, configuring convenience settings for the current game and challenges for the next game are listed in the main menu, brought up by the `ESC` key. Game difficulty, from the challenges menu, determines hitpoints at birth: difficulty below 5 multiplies hitpoints of player characters, difficulty over 5 multiplies hitpoints of their enemies. Of the convenience settings, the `suspect terrain` choice is particularly interesting, because it determines not only screen display of the level map, but also whether suspect tiles are considered for auto-explore and for the `C-?` command that marks the nearest unexplored position. The "lone wolf" challenge mode reduces player's starting actors to exactly one (consequently, this does not affect the initial 'raid' scenario). The "cold fish" challenge mode makes it impossible for player characters to be healed by actors from other factions (this is a significant restriction in the final 'crawl' scenario). For a person new to roguelikes, the 'raid' scenario offers a gentle introduction. The subsequent game scenarios lead the player along an optional story arc. They gradually introduce squad combat, stealth, opportunity fire, asymmetric battles and more. Starting from the second scenario, the player controls a whole team of characters and will develop his repertoire of squad formations, preferred rendezvous locations and the use of light sources. The last scenario, a multi-level crawl, is the gist and the main challenge of the game. It spans 15 varied spaceship decks, requiring lots of time, focus and flexibility to beat and providing considerable replayability. The player has a choice of exploring a single level at a time or portions of many floors along a single staircase. On some levels he may explore and loot with a single scout eluding most opponents. On others he may be forced to change the pace and perform a complete exterminatory sweep involving his whole party. On yet others, his best course of action may be to defend a key location until the first wave of attackers is broken. The size of the crawl scenario calls for strategic thinking, including resource management, area denial and unavoidable temporary retreats to other levels. Compared to that, the smaller scenarios, where the arena is a single floor only, provide a mostly tactical training and additional entertainment by trying to beat a high-score. They offer variety and a breather between the deaths^H^H^H^H^H^H the brave attempts at the long crawl scenario. Some gameplay elements, however, like totally symmetric skirmishes, a race to the exit or heavy reliance on opportunity fire, feature only in the small scenarios. Monsters -------- The life of the heroes is full of dangers. Monstrosities, natural and out of this world, roam the dark corridors and crawl from damp holes 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. Monsters are depicted on the map with letters. Upper case letters are unique monsters, often guardians of special floors, and lower case letters are the rabble. If there are humans not from our team, they are marked with `@` and `1` through `9` in other colours than white. When a hero walks and bumps into a monster or a monster attacks the hero, melee combat occurs. Hero *running* into and displacing a monster (with the `Shift` or `Control` key), or the other way around, does not inflict damage, but exchanges places. This gives the opponent a free blow, but can improve the tactical situation or aid escape. In some circumstances actors are immune to the displacing, e.g., when both parties form a continuous front-line. In melee combat, the best recharged equipped weapon (or the best fighting organ that is not on cooldown) of each opponent is taken into account for determining the damage and any extra effects of the blow. To determine the damage dealt, the outcome of the weapon's damage dice roll is multiplied by a percentage bonus. The bonus is calculated by taking the damage bonus (summed from the equipped items of the attacker, capped at 200%) minus the melee armor modifier of the defender (capped at 200%, as well), with the outcome bounded between -99% and 99%, which means that at least 1% of damage always gets through and the damage is always lower than twice the dice roll. The current leader's melee bonus, armor modifier and other detailed skills can be viewed via the `#` command. In ranged combat, the projectile is assumed to be attacking the defender in melee, using itself as the weapon, with the usual dice and damage bonus. This time, the ranged armor skill of the defender is taken into account and, additionally, the speed of the missile (based on shape and weight) figures in the calculation. You may propel any item from your inventory (by default you are offered only the appropriate items; press `+` to cycle item menu modes). Only items of a few kinds inflict any damage, but some have other effects, beneficial, detrimental or mixed. In-game detailed item descriptions contain melee and ranged damage estimates. They do not take into account damage from effects and, if bonuses are not known, guesses are based on averages for the item kind in question. The displayed figures are rounded, but the game internally keeps track of minute fractions of HP. The stress of combat drains Calm, gradually limiting viewing radius and, if Calm reaches zero and the actor is sufficiently impressed by his foes, making him defect and surrender to their domination. Whenever the monster's or hero's hit points reach zero, the combatant is incapacitated and promptly dies. When the last hero dies or is dominated, the scenario ends in defeat. On Winning and Dying -------------------- You win a scenario if you escape the location alive (which may prove difficult, because your foes tend to gradually build up the ambush squad blocking your escape route) or, in scenarios with no exit locations, if you eliminate all opposition. In the former case, your score is based predominantly on the gold and precious gems you've plundered. In the latter case, your score is most influenced by the number of turns you spent overcoming your foes (the quicker the victory, the better; the slower the demise, the better). Bonus points, affected by the number of heroes lost, are awarded only if you win. The score is heavily modified by the chosen game difficulty, but not by any other challenges. When all your heroes fall, you are going to invariably see a new foolhardy party of adventurers clamoring to be led into the unknown perils. They start their conquest from a new entrance, with no experience and no equipment, and new undaunted enemies bar their way. Lead the new hopeful explorers to fame, wealth and glory! Allure-0.9.5.0/GameDefinition/config.ui.default0000644000000000000000000000417107346545000017414 0ustar0000000000000000; Copyright (c) 2008--2011 Andres Loeh ; Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) ; 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 copy of the default UI settings config file ; that is embedded in the game binary. A user config file can override ; these options. Option names are case-sensitive and only ';' for comments ; is permitted. ; ; The game looks for the config file at the same path where saved games ; directory is located. E.g. on Linux the file is at ; ~/.Allure/config.ui.ini ; and on Windows it can be at ; C:\Documents And Settings\user\Application Data\Allure\config.ui.ini ; or at ; C:\Users\\AppData\Roaming\Allure\config.ui.ini ; or elsewhere. [additional_commands] ; Angband compatibility (accept target) Cmd_2 = ("KP_Insert", ([CmdAim], "", ByAimMode AimModeCmd {exploration = ExecuteIfClear Dashboard, aiming = Accept})) [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] ; These two are mutually exclusive: movementViKeys_hjklyubn = True movementLaptopKeys_uk8o79jl = False ; The font to use for scaling SDL2 display (best by multiples or 0.5): ;sdlFontFile = "16x16xw.woff" scalableFontSize = 16 sdlScalableSizeAdd = 0 sdlFontFile = "16x16xw.bdf" sdlBitmapSizeAdd = 0 ;sdlFontFile = "8x8xb.fnt" ;sdlFontFile = "8x8x.fnt" ;sdlBitmapSizeAdd = 2 ; New historyMax takes effect after removal of savefiles. historyMax = 5000 maxFps = 24 noAnim = False hpWarningPercent = 20 ; Uncomment to make all messages white. ; messageColors = [] overrideCmdline = "" ; Legacy: monospace fonts that have fixed size regardless of boldness (on some OSes at least) gtkFontFamily = "DejaVu Sans Mono,Consolas,Courier New,Liberation Mono,Courier,FreeMono,Monospace" ; sdlFonSizeAdd is now ignored ; runStopMsgs is now ignored Allure-0.9.5.0/GameDefinition/config.ui.default0000755000000000000000000000417107346545000017417 0ustar0000000000000000; Copyright (c) 2008--2011 Andres Loeh ; Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) ; 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 copy of the default UI settings config file ; that is embedded in the game binary. A user config file can override ; these options. Option names are case-sensitive and only ';' for comments ; is permitted. ; ; The game looks for the config file at the same path where saved games ; directory is located. E.g. on Linux the file is at ; ~/.Allure/config.ui.ini ; and on Windows it can be at ; C:\Documents And Settings\user\Application Data\Allure\config.ui.ini ; or at ; C:\Users\\AppData\Roaming\Allure\config.ui.ini ; or elsewhere. [additional_commands] ; Angband compatibility (accept target) Cmd_2 = ("KP_Insert", ([CmdAim], "", ByAimMode AimModeCmd {exploration = ExecuteIfClear Dashboard, aiming = Accept})) [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] ; These two are mutually exclusive: movementViKeys_hjklyubn = True movementLaptopKeys_uk8o79jl = False ; The font to use for scaling SDL2 display (best by multiples or 0.5): ;sdlFontFile = "16x16xw.woff" scalableFontSize = 16 sdlScalableSizeAdd = 0 sdlFontFile = "16x16xw.bdf" sdlBitmapSizeAdd = 0 ;sdlFontFile = "8x8xb.fnt" ;sdlFontFile = "8x8x.fnt" ;sdlBitmapSizeAdd = 2 ; New historyMax takes effect after removal of savefiles. historyMax = 5000 maxFps = 24 noAnim = False hpWarningPercent = 20 ; Uncomment to make all messages white. ; messageColors = [] overrideCmdline = "" ; Legacy: monospace fonts that have fixed size regardless of boldness (on some OSes at least) gtkFontFamily = "DejaVu Sans Mono,Consolas,Courier New,Liberation Mono,Courier,FreeMono,Monospace" ; sdlFonSizeAdd is now ignored ; runStopMsgs is now ignored Allure-0.9.5.0/GameDefinition/fonts/0000755000000000000000000000000007346545000015313 5ustar0000000000000000Allure-0.9.5.0/GameDefinition/fonts/16x16x.fnt0000644000000000000000000002225507346545000017007 0ustar0000000000000000­$Mikolaj Konarski and others 2019; released under GNU GPL-2 `` X0ÿÿ ž$~~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ > ^ ~ ž ¾ Þ þ  > ^ ~ ž ¾ Þ þ  > ^ ~ ž ¾ Þ þ  > ^ ~ ž ¾ Þ þ  > ^ ~ ž ¾ Þ þ >^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ>^~ž¾Þþ > ^ ~ ž ¾ Þ þ !>!^!~!ž!¾!Þ!þ!">"^"~"ž"¾"Þ"þ"#>#^#~#ž#¾#Þ#þ#$>$^$  €€ÀÀÀÀ€€€€À€0000 ?? ?? 00üü0000üü00111€ð˜€€€ð˜ŒŒ˜ð€6"6 0`À€8lDl888À`0`ÀÆl88|΀ÀÀ€ðÀ€€Àð€ÀàààààÀ€0pàøøàp0€€€€øø€€€€€ÀÀ€øø€ÀÀ€ 80 0`À€0001000ð Œ ð?ÀÀÀÀÀÀÀÀÀÀþ800?ð 8àü8ð ø  ø00000 ü ?000?8üð ð 00?000ðð ð?þ8pàÀ€  00à00ð ð008ð ü ð€ÀÀ€€ÀÀ€€ÀÀ€€ÀÀ€888à€€à8øøøøÀppÀ ð 8à€€À€8133318ð üøð ~ÀÀ` 0ø ?ð ø  ø0000000ø  øà0 0àüðü~üð0000000ð ÿ ð|| ü ??ü€€€€€€€€€üp? ð||>0`ÀÀ`0 ~þx|0`À€À`0>| >0`À€€€€€à?`?þ8pàÀ€þðð08 €À`0 à`````````à 0€À`0 þþ€Ààp00ø ü çxsø ü0````0ø ü0000< ü ç0```0ø øü?üøÀ00pç ü øx~ø ÀÀÀÀÀÀÀÀÿp ü øx~0`Àà0?þü~111111qpŒŒŒŒŒŒs~ð 0````0ø  øsxø ü0000ì ü y ü€88püø üøüx< ç|  0`ÀÀx ÌÌx0|| 0ÀÀ0 xp? ü ø?`8?þ8à€þð€€€€€€ð€€€€€€€€€€€€€€€ÀpÀ€€€90 œøð?? ??øüÀÀÀÀüø€€€øø€€€€€€€€€€€øø€€€øø€€€000`Àø ø  øpÀÀp0000000üÆÀÀÀøÀÀÀÆü?`?`Àü8pàÀ€ü€ÀÀ€88p`À€üø üÀpÀ3aaaa3|Ɔü€€Æ|?`8?`À€þ8à€þ| ``>0`À€€€€à€À€€€€ÀÀÀÀ€1111€€øŒ€€€€Œø€€?7?ðø ÀÀ€øø  € P ØØ P €08 8pàøø€øø€€ðøàðèø8ðà``3666663ðÌl lÌðð00üü8Ž8à8Ž?ü 7447544ðÌl,ÌŒÌlðàà à00à€€€øø€€€øøð8à€øðððÀ€  8 ç>>>ü0000000000€€À€€€€€€€øððø88à8Ž8àxppÀff~xppÀ|<`~||ppÀff~ €À€€à8 ð ~€ÀÀ` 0ø ? ~À€À` 0ø ? ~À`À` 0ø ? ~`ÀÀ` 0ø ? ~00À` 0ø ? ~À€À` 0ø ? 00yüÆÀÀÀøÀÀÀÆü0000000ø  øÀ€€ÀüðüÀ€üðüÀ`üðü``üðü??€ü€€€€€€€€ü??À€ü€€€€€€€€ü??À`ü€€€€€€€€ü??``ü€€€€€€€€üà0 Œ 0àx~`À? ŒÌl<  0000 €à0 0à 0000 À€à0 0à 0000 À`à0 0à 0000 `Àà0 0à 0000 ``à0 0à  0pàÀÀàp0 001367ì0hÌŒ 0à| €À ð| À€ ð| À` ð| 00 ð| À€>0`À€€€€ààð88ðàøü8pàp8|øp00€€ø ü çp00À€ø ü çp00€À`ø ü çp00`Àø ü çp00``ø ü çp00€@€ø ü ç>c1aa>|Ɔü€€Æ|0````0ø üÀ€0```0€€ø øü0```0À€ø øü0```0€À`ø øü0```0``ø øü€€ÀÀÀÀÀÀÿ`À€ÀÀÀÀÀÀÿ€À`ÀÀÀÀÀÀÿ00ÀÀÀÀÀÀÿ000`€À`0ø ðs~°àð 0````0€€ø  ø0````0À€ø  ø0````0€À`ø  ø0````0`Àø  ø0````0``ø  ø€€øø€€0038/ú<æ† øx€€< çxÀ€< çx€À`< çx``< çxpÀ€? ü øàøøàxp``? ü øAngband 16x16xAllure-0.9.5.0/GameDefinition/fonts/16x16xw.bdf0000644000000000000000000017643407346545000017153 0ustar0000000000000000STARTFONT 2.1 FONT -Angband-16x16x-Medium-R-Normal--16-120-100-100-C-80-ISO10646-1 SIZE 12 100 100 FONTBOUNDINGBOX 16 16 0 -3 STARTPROPERTIES 20 FAMILY_NAME "16x16x" FOUNDRY "Angband" WEIGHT_NAME "Medium" SLANT "R" SETWIDTH_NAME "Normal" FONT_VERSION "1.0" COPYRIGHT "Mikolaj Konarski, Leon Marrick and others 2019; released under GNU GPL-2" CAP_HEIGHT 13 PIXEL_SIZE 16 POINT_SIZE 120 X_HEIGHT 8 RESOLUTION_X 100 RESOLUTION_Y 100 SPACING "C" AVERAGE_WIDTH 80 WEIGHT 10 QUAD_WIDTH 16 DEFAULT_CHAR 32 FONT_DESCENT 3 FONT_ASCENT 13 ENDPROPERTIES CHARS 385 STARTCHAR U+0007 ENCODING 7 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 0000 0000 0180 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+0020 ENCODING 32 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+0021 ENCODING 33 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0180 03C0 03C0 03C0 03C0 0180 0180 0180 0000 0180 03C0 0180 0000 0000 ENDCHAR STARTCHAR U+0022 ENCODING 34 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0630 0630 0630 0630 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+0023 ENCODING 35 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0C30 0C30 3FFC 3FFC 0C30 0C30 0C30 0C30 3FFC 3FFC 0C30 0C30 0000 0000 ENDCHAR STARTCHAR U+0024 ENCODING 36 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0180 0FF0 1998 3180 3180 1980 0FF0 0198 018C 018C 3198 1FF0 0180 0000 0000 ENDCHAR STARTCHAR U+0025 ENCODING 37 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 1C18 3618 2230 3660 1CC0 0180 0338 066C 0C44 186C 1838 0000 0000 0000 ENDCHAR STARTCHAR U+0026 ENCODING 38 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 07C0 0E60 1C30 0E60 07C0 0FC6 1C6C 3838 3838 1C7C 0FCE 0000 0000 0000 ENDCHAR STARTCHAR U+0027 ENCODING 39 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0180 03C0 03C0 0180 0300 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+0028 ENCODING 40 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 00F0 01C0 0380 0700 0700 0700 0700 0700 0380 01C0 00F0 0000 0000 0000 ENDCHAR STARTCHAR U+0029 ENCODING 41 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0F00 0380 01C0 00E0 00E0 00E0 00E0 00E0 01C0 0380 0F00 0000 0000 0000 ENDCHAR STARTCHAR U+002A ENCODING 42 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0630 0770 03E0 0FF8 0FF8 03E0 0770 0630 0000 0000 0000 0000 ENDCHAR STARTCHAR U+002B ENCODING 43 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0180 0180 0180 0180 1FF8 1FF8 0180 0180 0180 0180 0000 0000 0000 ENDCHAR STARTCHAR U+002C ENCODING 44 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0180 03C0 03C0 0180 0700 0000 ENDCHAR STARTCHAR U+002D ENCODING 45 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 0000 1FF8 1FF8 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+002E ENCODING 46 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0180 03C0 03C0 0180 0000 0000 ENDCHAR STARTCHAR U+002F ENCODING 47 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 000C 001C 0030 0060 00C0 0180 0300 0600 0C00 3800 3000 0000 0000 0000 ENDCHAR STARTCHAR U+0030 ENCODING 48 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF0 1818 300C 300C 300C 318C 300C 300C 300C 1818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+0031 ENCODING 49 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 00C0 01C0 0FC0 00C0 00C0 00C0 00C0 00C0 00C0 00C0 3FFE 0000 0000 0000 ENDCHAR STARTCHAR U+0032 ENCODING 50 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF0 3818 000C 000C 0038 01E0 0700 1C00 3000 3006 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0033 ENCODING 51 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 07F0 1C18 000C 000C 0018 03F8 000C 0006 0006 380C 0FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0034 ENCODING 52 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 300C 300C 300C 300C 300C 1FFC 000C 000C 000C 000C 000C 0000 0000 0000 ENDCHAR STARTCHAR U+0035 ENCODING 53 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 3FFC 3000 3000 3000 3FF0 0018 000C 000C 000C 3818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+0036 ENCODING 54 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 07F0 0C18 1800 3000 3000 3FF0 3018 300C 300C 1818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+0037 ENCODING 55 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 3FFE 000E 001C 0038 0070 00E0 01C0 0380 0700 0E00 1C00 0000 0000 0000 ENDCHAR STARTCHAR U+0038 ENCODING 56 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 07E0 0C30 1818 1818 0C30 0FF0 1818 300C 300C 1818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+0039 ENCODING 57 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF0 1818 300C 300C 180C 0FFC 000C 000C 000C 3818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+003A ENCODING 58 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0180 03C0 03C0 0180 0000 0000 0180 03C0 03C0 0180 0000 0000 ENDCHAR STARTCHAR U+003B ENCODING 59 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0180 03C0 03C0 0180 0000 0000 0180 03C0 03C0 0180 0700 0000 ENDCHAR STARTCHAR U+003C ENCODING 60 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0038 00E0 0380 0E00 3800 3800 0E00 0380 00E0 0038 0000 0000 0000 ENDCHAR STARTCHAR U+003D ENCODING 61 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 1FF8 1FF8 0000 0000 1FF8 1FF8 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+003E ENCODING 62 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 1C00 0700 01C0 0070 001C 001C 0070 01C0 0700 1C00 0000 0000 0000 ENDCHAR STARTCHAR U+003F ENCODING 63 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 07F0 0C18 180C 000C 000C 0038 00E0 0180 0000 0180 03C0 0180 0000 0000 ENDCHAR STARTCHAR U+0040 ENCODING 64 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF0 1C18 380C 31FC 331C 331C 331C 31F8 3800 1C18 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+0041 ENCODING 65 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FC0 01C0 0360 0220 0630 0410 0FF8 0C18 180C 180C 7E3F 0000 0000 0000 ENDCHAR STARTCHAR U+0042 ENCODING 66 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7FF0 1818 180C 180C 1818 1FF8 180C 1806 1806 180C 7FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0043 ENCODING 67 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF8 180C 3006 3000 3000 3000 3000 3000 3006 180C 0FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0044 ENCODING 68 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7FE0 1830 1818 180C 180C 180C 180C 180C 1818 1830 7FE0 0000 0000 0000 ENDCHAR STARTCHAR U+0045 ENCODING 69 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7FFC 1806 1800 1800 1800 1FF0 1800 1800 1800 1806 7FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0046 ENCODING 70 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7FFC 1806 1800 1800 1800 1FF0 1800 1800 1800 1800 7E00 0000 0000 0000 ENDCHAR STARTCHAR U+0047 ENCODING 71 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF0 1818 300C 3000 3000 3000 30FF 300C 300C 1818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+0048 ENCODING 72 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7C1F 180C 180C 180C 180C 1FFC 180C 180C 180C 180C 7C1F 0000 0000 0000 ENDCHAR STARTCHAR U+0049 ENCODING 73 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 3FFC 0180 0180 0180 0180 0180 0180 0180 0180 0180 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+004A ENCODING 74 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 003F 000C 000C 000C 000C 000C 000C 000C 000C 7018 1FF0 0000 0000 0000 ENDCHAR STARTCHAR U+004B ENCODING 75 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7C3E 1818 1830 1860 18C0 1FC0 1860 1830 1818 180C 7C1F 0000 0000 0000 ENDCHAR STARTCHAR U+004C ENCODING 76 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7E00 1800 1800 1800 1800 1800 1800 1800 1800 1803 7FFE 0000 0000 0000 ENDCHAR STARTCHAR U+004D ENCODING 77 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 780F 1C1C 1E3C 1B6C 19CC 188C 180C 180C 180C 180C 7C1F 0000 0000 0000 ENDCHAR STARTCHAR U+004E ENCODING 78 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 783F 180C 1C0C 1E0C 1B0C 198C 18CC 186C 183C 181C 7E0C 0000 0000 0000 ENDCHAR STARTCHAR U+004F ENCODING 79 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 07E0 0C30 1818 300C 300C 300C 300C 300C 1818 0C30 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+0050 ENCODING 80 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7FF8 180C 1806 1806 180C 1FF8 1800 1800 1800 1800 7E00 0000 0000 0000 ENDCHAR STARTCHAR U+0051 ENCODING 81 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 07E0 0C30 1818 300C 300C 300C 300C 300C 19D8 0CF0 07E0 0038 0000 0000 ENDCHAR STARTCHAR U+0052 ENCODING 82 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7FF0 1818 180C 180C 1818 1FF0 18C0 1860 1830 1818 7C3F 0000 0000 0000 ENDCHAR STARTCHAR U+0053 ENCODING 83 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF8 180C 3000 3000 1800 0FF8 000C 0006 0006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0054 ENCODING 84 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 3FFC 6186 0180 0180 0180 0180 0180 0180 0180 0180 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+0055 ENCODING 85 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7C1F 180C 180C 180C 180C 180C 180C 180C 180C 0C18 07F0 0000 0000 0000 ENDCHAR STARTCHAR U+0056 ENCODING 86 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7C1F 180C 180C 0C18 0C18 0630 0630 0360 0360 01C0 01C0 0000 0000 0000 ENDCHAR STARTCHAR U+0057 ENCODING 87 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7C1F 180C 180C 180C 180C 188C 19CC 1B6C 1E3C 1C1C 180C 0000 0000 0000 ENDCHAR STARTCHAR U+0058 ENCODING 88 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7C3E 1818 0C30 0660 03C0 0180 03C0 0660 0C30 1818 7C3E 0000 0000 0000 ENDCHAR STARTCHAR U+0059 ENCODING 89 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7C3E 1818 0C30 0660 03C0 0180 0180 0180 0180 0180 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+005A ENCODING 90 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 3FFE 601C 0038 0070 00E0 01C0 0380 0700 0E00 1C03 3FFE 0000 0000 0000 ENDCHAR STARTCHAR U+005B ENCODING 91 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 07F0 0600 0600 0600 0600 0600 0600 0600 0600 0600 07F0 0000 0000 0000 ENDCHAR STARTCHAR U+005C ENCODING 92 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 3000 3800 0C00 0600 0300 0180 00C0 0060 0030 001C 000C 0000 0000 0000 ENDCHAR STARTCHAR U+005D ENCODING 93 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FE0 0060 0060 0060 0060 0060 0060 0060 0060 0060 0FE0 0000 0000 0000 ENDCHAR STARTCHAR U+005E ENCODING 94 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0180 03C0 0660 0C30 1818 300C 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+005F ENCODING 95 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 7FFE 7FFE 0000 0000 ENDCHAR STARTCHAR U+0060 ENCODING 96 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0700 0380 01C0 00E0 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+0061 ENCODING 97 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 1FF8 700C 000C 0FFC 180C 300C 301C 1FE7 0000 0000 0000 ENDCHAR STARTCHAR U+0062 ENCODING 98 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7800 1800 1800 1800 1FF8 180C 1806 1806 1806 1C06 73FC 0000 0000 0000 ENDCHAR STARTCHAR U+0063 ENCODING 99 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 1FF8 300C 6000 6000 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0064 ENCODING 100 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 003C 000C 000C 000C 0FFC 180C 300C 300C 300C 301C 1FE7 0000 0000 0000 ENDCHAR STARTCHAR U+0065 ENCODING 101 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 1FF8 300C 600C 7FF8 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0066 ENCODING 102 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 01FC 0606 0600 7FF8 0600 0600 0600 0600 0600 3FC0 0000 0000 0000 ENDCHAR STARTCHAR U+0067 ENCODING 103 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0FE7 181C 300C 300C 180C 0FFC 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+0068 ENCODING 104 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7800 1800 1800 1800 1FF8 180C 180C 180C 180C 180C 7E0F 0000 0000 0000 ENDCHAR STARTCHAR U+0069 ENCODING 105 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 00C0 00C0 0000 0000 1FC0 00C0 00C0 00C0 00C0 00C0 7FFF 0000 0000 0000 ENDCHAR STARTCHAR U+006A ENCODING 106 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 000C 000C 0000 0000 03FC 000C 000C 000C 000C 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+006B ENCODING 107 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7800 1800 1800 181E 1830 1860 18C0 1FE0 1830 1818 7E3F 0000 0000 0000 ENDCHAR STARTCHAR U+006C ENCODING 108 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 FE00 0600 0600 0600 0600 0600 0600 0600 0607 01FC 0000 0000 0000 ENDCHAR STARTCHAR U+006D ENCODING 109 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 7E70 318C 318C 318C 318C 318C 318C 718F 0000 0000 0000 ENDCHAR STARTCHAR U+006E ENCODING 110 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 73F0 1C18 180C 180C 180C 180C 180C 7E0F 0000 0000 0000 ENDCHAR STARTCHAR U+006F ENCODING 111 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 1FF8 300C 6006 6006 6006 6006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0070 ENCODING 112 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 73F8 1C0C 1806 1806 1806 1806 1FFC 1800 1800 1800 7800 ENDCHAR STARTCHAR U+0071 ENCODING 113 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0FEC 181C 300C 300C 300C 300C 1FFC 000C 000C 000C 000F ENDCHAR STARTCHAR U+0072 ENCODING 114 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 79FC 0E07 0C00 0C00 0C00 0C00 0C00 7F80 0000 0000 0000 ENDCHAR STARTCHAR U+0073 ENCODING 115 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0FFC 3807 3800 0FF8 000C 0006 7006 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0074 ENCODING 116 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0600 0600 0600 7FF8 0600 0600 0600 0600 0607 01FC 0000 0000 0000 ENDCHAR STARTCHAR U+0075 ENCODING 117 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 783C 180C 180C 180C 180C 180C 181C 0FE7 0000 0000 0000 ENDCHAR STARTCHAR U+0076 ENCODING 118 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 7C1F 180C 180C 0C18 0630 0360 01C0 01C0 0000 0000 0000 ENDCHAR STARTCHAR U+0077 ENCODING 119 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 780F 180C 180C 180C 19CC 19CC 0F78 0630 0000 0000 0000 ENDCHAR STARTCHAR U+0078 ENCODING 120 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 7C1F 180C 0630 01C0 01C0 0630 180C 7C1F 0000 0000 0000 ENDCHAR STARTCHAR U+0079 ENCODING 121 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 783F 180C 180C 180C 180C 0FFC 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+007A ENCODING 122 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 3FFE 600E 0038 00E0 0380 0E00 3803 3FFE 0000 0000 0000 ENDCHAR STARTCHAR U+007B ENCODING 123 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 00F0 0180 0180 0180 0300 0E00 0300 0180 0180 0180 00F0 0000 0000 0000 ENDCHAR STARTCHAR U+007C ENCODING 124 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0180 0180 0180 0180 0180 0180 0180 0180 0180 0180 0180 0180 0000 0000 ENDCHAR STARTCHAR U+007D ENCODING 125 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0F00 0180 0180 0180 00C0 0070 00C0 0180 0180 0180 0F00 0000 0000 0000 ENDCHAR STARTCHAR U+007E ENCODING 126 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 0F0C 1F9C 39F8 30F0 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00A0 ENCODING 160 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00A1 ENCODING 161 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0180 03C0 0180 0000 0180 0180 0180 03C0 03C0 03C0 03C0 0180 0000 0000 ENDCHAR STARTCHAR U+00A2 ENCODING 162 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0180 0180 0FF8 198C 3180 3180 3180 3180 198C 0FF8 0180 0180 0000 0000 ENDCHAR STARTCHAR U+00A3 ENCODING 163 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 01F0 03F8 071C 060C 1FC0 1FC0 0600 1E00 3F00 3780 3FF8 1CF8 0000 0000 0000 ENDCHAR STARTCHAR U+00A4 ENCODING 164 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0180 05A0 0A50 05A0 1BD8 1BD8 05A0 0A50 05A0 0180 0000 0000 0000 ENDCHAR STARTCHAR U+00A5 ENCODING 165 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 300C 381C 1C38 0E70 07E0 1FF8 1FF8 0180 1FF8 1FF8 0180 0180 0000 0000 0000 ENDCHAR STARTCHAR U+00A6 ENCODING 166 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0300 0300 0300 0300 0300 0000 0000 0300 0300 0300 0300 0300 0000 0000 ENDCHAR STARTCHAR U+00A7 ENCODING 167 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 07F0 0FF8 1C08 1800 1FE0 17F0 1018 1808 0FE8 07F8 0018 1038 1FF0 0FE0 0000 ENDCHAR STARTCHAR U+00A8 ENCODING 168 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0660 0660 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00A9 ENCODING 169 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF0 1818 33CC 366C 360C 360C 360C 366C 33CC 1818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+00AA ENCODING 170 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF0 1830 1830 0FFC 0000 1FFC 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00AB ENCODING 171 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 038E 0E38 38E0 0E38 038E 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00AC ENCODING 172 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 0000 3FFC 000C 000C 000C 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00AE ENCODING 174 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF0 1818 37CC 346C 342C 37CC 358C 34CC 346C 1818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+00AF ENCODING 175 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 03E0 03E0 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00B0 ENCODING 176 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 07E0 0C30 0C30 07E0 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00B1 ENCODING 177 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0180 0180 0180 1FF8 1FF8 0180 0180 0180 0000 1FF8 1FF8 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00B2 ENCODING 178 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 07F0 1C18 0038 00E0 0380 0E00 1FF8 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00B3 ENCODING 179 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 07F0 1C18 0018 01F0 0018 1C18 07F0 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00B4 ENCODING 180 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 00C0 0180 0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00B5 ENCODING 181 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0C0C 0C0C 0C0C 0C0C 0C0C 0C0C 0C1C 0FE7 0C00 0C00 3800 ENDCHAR STARTCHAR U+00B6 ENCODING 182 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 1FFC 3E30 3E30 3E30 1E30 0630 0630 0630 0630 0630 0630 0000 0000 0000 ENDCHAR STARTCHAR U+00B7 ENCODING 183 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 0000 0180 0180 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00B8 ENCODING 184 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 00C0 0060 01C0 ENDCHAR STARTCHAR U+00B9 ENCODING 185 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0180 0780 0180 0180 0180 0180 1FF8 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00BA ENCODING 186 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF0 1818 1818 0FF0 0000 1FF8 0000 0000 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00BB ENCODING 187 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 38E0 0E38 038E 0E38 38E0 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00BC ENCODING 188 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 1800 7800 1800 181C 1870 01C0 0700 1C66 7066 007E 0006 0006 0000 0000 ENDCHAR STARTCHAR U+00BD ENCODING 189 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 1800 7800 1800 181C 1870 01C0 0700 1C7C 7006 003C 0060 007E 0000 0000 ENDCHAR STARTCHAR U+00BE ENCODING 190 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7C00 0600 1E00 061C 7C70 01C0 0700 1C66 7066 007E 0006 0006 0000 0000 ENDCHAR STARTCHAR U+00BF ENCODING 191 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0180 03C0 0180 0000 0180 00E0 0038 000C 000C 180C 0C18 07F0 0000 0000 ENDCHAR STARTCHAR U+00C0 ENCODING 192 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0180 00C0 0000 0FC0 0360 0220 0630 0410 0FF8 0C18 180C 180C 7E3F 0000 0000 0000 ENDCHAR STARTCHAR U+00C1 ENCODING 193 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 00C0 0180 0000 0FC0 0360 0220 0630 0410 0FF8 0C18 180C 180C 7E3F 0000 0000 0000 ENDCHAR STARTCHAR U+00C2 ENCODING 194 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0360 0000 0FC0 0360 0220 0630 0410 0FF8 0C18 180C 180C 7E3F 0000 0000 0000 ENDCHAR STARTCHAR U+00C3 ENCODING 195 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 05C0 0000 0FC0 0360 0220 0630 0410 0FF8 0C18 180C 180C 7E3F 0000 0000 0000 ENDCHAR STARTCHAR U+00C4 ENCODING 196 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0630 0630 0000 0FC0 0360 0220 0630 0410 0FF8 0C18 180C 180C 7E3F 0000 0000 0000 ENDCHAR STARTCHAR U+00C5 ENCODING 197 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 03C0 0180 0000 0FC0 0360 0220 0630 0410 0FF8 0C18 180C 180C 7E3F 0000 0000 0000 ENDCHAR STARTCHAR U+00C6 ENCODING 198 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FFC 03C6 06C0 04C0 0CC0 0FF8 18C0 18C0 30C0 30C6 79FC 0000 0000 0000 ENDCHAR STARTCHAR U+00C7 ENCODING 199 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF8 180C 3006 3000 3000 3000 3000 3000 3006 180C 0FF8 00C0 0060 01C0 ENDCHAR STARTCHAR U+00C8 ENCODING 200 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0180 00C0 0000 7FFC 1806 1800 1800 1FF0 1800 1800 1800 1806 7FFC 0000 0000 0000 ENDCHAR STARTCHAR U+00C9 ENCODING 201 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 00C0 0180 0000 7FFC 1806 1800 1800 1FF0 1800 1800 1800 1806 7FFC 0000 0000 0000 ENDCHAR STARTCHAR U+00CA ENCODING 202 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0360 0000 7FFC 1806 1800 1800 1FF0 1800 1800 1800 1806 7FFC 0000 0000 0000 ENDCHAR STARTCHAR U+00CB ENCODING 203 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0660 0660 0000 7FFC 1806 1800 1800 1FF0 1800 1800 1800 1806 7FFC 0000 0000 0000 ENDCHAR STARTCHAR U+00CC ENCODING 204 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0300 0180 0000 3FFC 0180 0180 0180 0180 0180 0180 0180 0180 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+00CD ENCODING 205 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 00C0 0180 0000 3FFC 0180 0180 0180 0180 0180 0180 0180 0180 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+00CE ENCODING 206 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0360 0000 3FFC 0180 0180 0180 0180 0180 0180 0180 0180 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+00CF ENCODING 207 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0660 0660 0000 3FFC 0180 0180 0180 0180 0180 0180 0180 0180 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+00D0 ENCODING 208 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7FE0 1830 1818 180C 180C 7F8C 180C 180C 1818 1830 7FE0 0000 0000 0000 ENDCHAR STARTCHAR U+00D1 ENCODING 209 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 05C0 0000 783F 1C0C 1E0C 1B0C 198C 18CC 186C 183C 181C 7E0C 0000 0000 0000 ENDCHAR STARTCHAR U+00D2 ENCODING 210 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0300 0180 0000 07E0 0C30 1818 300C 300C 300C 300C 1818 0C30 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+00D3 ENCODING 211 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 00C0 0180 0000 07E0 0C30 1818 300C 300C 300C 300C 1818 0C30 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+00D4 ENCODING 212 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0360 0000 07E0 0C30 1818 300C 300C 300C 300C 1818 0C30 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+00D5 ENCODING 213 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 05C0 0000 07E0 0C30 1818 300C 300C 300C 300C 1818 0C30 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+00D6 ENCODING 214 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0660 0660 0000 07E0 0C30 1818 300C 300C 300C 300C 1818 0C30 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+00D7 ENCODING 215 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0C30 0E70 07E0 03C0 03C0 07E0 0E70 0C30 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00D8 ENCODING 216 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 07EC 0C18 1830 3068 30CC 318C 330C 360C 1C18 1830 37E0 0000 0000 0000 ENDCHAR STARTCHAR U+00D9 ENCODING 217 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0180 00C0 0000 7C1F 180C 180C 180C 180C 180C 180C 180C 0C18 07F0 0000 0000 0000 ENDCHAR STARTCHAR U+00DA ENCODING 218 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 00C0 0180 0000 7C1F 180C 180C 180C 180C 180C 180C 180C 0C18 07F0 0000 0000 0000 ENDCHAR STARTCHAR U+00DB ENCODING 219 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0360 0000 7C1F 180C 180C 180C 180C 180C 180C 180C 0C18 07F0 0000 0000 0000 ENDCHAR STARTCHAR U+00DC ENCODING 220 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0630 0630 0000 7C1F 180C 180C 180C 180C 180C 180C 180C 0C18 07F0 0000 0000 0000 ENDCHAR STARTCHAR U+00DD ENCODING 221 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 00C0 0180 0000 7C3E 1818 0C30 0660 03C0 0180 0180 0180 0180 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+00DE ENCODING 222 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 1800 1800 1FE0 1FF0 1838 1818 1818 1838 1FF0 1FE0 1800 1800 0000 0000 0000 ENDCHAR STARTCHAR U+00DF ENCODING 223 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0FF8 1FFC 181C 181C 1838 1870 18E0 1870 1838 181C 187C 19F8 0000 0000 0000 ENDCHAR STARTCHAR U+00E0 ENCODING 224 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0300 0180 0080 0000 1FF8 700C 000C 0FFC 180C 300C 301C 1FE7 0000 0000 0000 ENDCHAR STARTCHAR U+00E1 ENCODING 225 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 00C0 0180 0100 0000 1FF8 700C 000C 0FFC 180C 300C 301C 1FE7 0000 0000 0000 ENDCHAR STARTCHAR U+00E2 ENCODING 226 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0080 01C0 0360 0000 1FF8 700C 000C 0FFC 180C 300C 301C 1FE7 0000 0000 0000 ENDCHAR STARTCHAR U+00E3 ENCODING 227 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0360 05C0 0000 1FF8 700C 000C 0FFC 180C 300C 301C 1FE7 0000 0000 0000 ENDCHAR STARTCHAR U+00E4 ENCODING 228 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0660 0660 0000 1FF8 700C 000C 0FFC 180C 300C 301C 1FE7 0000 0000 0000 ENDCHAR STARTCHAR U+00E5 ENCODING 229 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0080 0140 0080 0000 1FF8 700C 000C 0FFC 180C 300C 301C 1FE7 0000 0000 0000 ENDCHAR STARTCHAR U+00E6 ENCODING 230 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 3E7C 63C6 0186 1FFC 3180 6180 61C6 3E7C 0000 0000 0000 ENDCHAR STARTCHAR U+00E7 ENCODING 231 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 1FF8 300C 6000 6000 6000 6000 3007 1FFC 00C0 0060 01C0 ENDCHAR STARTCHAR U+00E8 ENCODING 232 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0300 0180 0080 0000 1FF8 300C 600C 7FF8 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+00E9 ENCODING 233 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 00C0 0180 0100 0000 1FF8 300C 600C 7FF8 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+00EA ENCODING 234 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0080 01C0 0360 0000 1FF8 300C 600C 7FF8 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+00EB ENCODING 235 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0660 0660 0000 1FF8 300C 600C 7FF8 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+00EC ENCODING 236 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0300 0180 0080 0000 0000 1FC0 00C0 00C0 00C0 00C0 00C0 7FFF 0000 0000 0000 ENDCHAR STARTCHAR U+00ED ENCODING 237 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0060 00C0 0080 0000 0000 1FC0 00C0 00C0 00C0 00C0 00C0 7FFF 0000 0000 0000 ENDCHAR STARTCHAR U+00EE ENCODING 238 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0080 01C0 0360 0000 0000 1FC0 00C0 00C0 00C0 00C0 00C0 7FFF 0000 0000 0000 ENDCHAR STARTCHAR U+00EF ENCODING 239 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0330 0330 0000 0000 1FC0 00C0 00C0 00C0 00C0 00C0 7FFF 0000 0000 0000 ENDCHAR STARTCHAR U+00F0 ENCODING 240 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0360 0180 06C0 0060 0030 0FF8 181C 300C 300C 300C 1818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+00F1 ENCODING 241 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 01B0 02E0 0000 73F0 1C18 180C 180C 180C 180C 180C 7E0F 0000 0000 0000 ENDCHAR STARTCHAR U+00F2 ENCODING 242 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0300 0180 0080 0000 1FF8 300C 6006 6006 6006 6006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+00F3 ENCODING 243 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 00C0 0180 0100 0000 1FF8 300C 6006 6006 6006 6006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+00F4 ENCODING 244 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0080 01C0 0360 0000 1FF8 300C 6006 6006 6006 6006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+00F5 ENCODING 245 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0360 05C0 0000 1FF8 300C 6006 6006 6006 6006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+00F6 ENCODING 246 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0660 0660 0000 1FF8 300C 6006 6006 6006 6006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+00F7 ENCODING 247 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0180 0180 0000 1FF8 1FF8 0000 0180 0180 0000 0000 0000 0000 ENDCHAR STARTCHAR U+00F8 ENCODING 248 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0FFA 180E 303C 30E6 3386 1E06 380C 2FF8 0000 0000 0000 ENDCHAR STARTCHAR U+00F9 ENCODING 249 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0300 0180 0080 0000 783C 180C 180C 180C 180C 180C 181C 0FE7 0000 0000 0000 ENDCHAR STARTCHAR U+00FA ENCODING 250 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 00C0 0180 0100 0000 783C 180C 180C 180C 180C 180C 181C 0FE7 0000 0000 0000 ENDCHAR STARTCHAR U+00FB ENCODING 251 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0080 01C0 0360 0000 783C 180C 180C 180C 180C 180C 181C 0FE7 0000 0000 0000 ENDCHAR STARTCHAR U+00FC ENCODING 252 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0660 0660 0000 783C 180C 180C 180C 180C 180C 181C 0FE7 0000 0000 0000 ENDCHAR STARTCHAR U+00FD ENCODING 253 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 00C0 0180 0100 0000 783F 180C 180C 180C 180C 0FFC 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+00FE ENCODING 254 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 1800 1800 1800 1FE0 1FF8 1818 1818 1FF8 1FE0 1800 1800 1800 0000 ENDCHAR STARTCHAR U+00FF ENCODING 255 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0660 0660 0000 783F 180C 180C 180C 180C 0FFC 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+0100 ENCODING 256 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 03E0 03E0 0000 0FC0 0360 0220 0630 0410 0FF8 0C18 180C 180C 7E3F 0000 0000 0000 ENDCHAR STARTCHAR U+0101 ENCODING 257 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 03E0 03E0 0000 1FF8 700C 000C 0FFC 180C 300C 301C 1FE7 0000 0000 0000 ENDCHAR STARTCHAR U+0102 ENCODING 258 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0220 01C0 0000 0FC0 0360 0220 0630 0410 0FF8 0C18 180C 180C 7E3F 0000 0000 0000 ENDCHAR STARTCHAR U+0103 ENCODING 259 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0220 01C0 0000 0000 1FF8 700C 000C 0FFC 180C 300C 301C 1FE7 0000 0000 0000 ENDCHAR STARTCHAR U+0104 ENCODING 260 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FC0 01C0 0360 0220 0630 0410 0FF8 0C18 180C 180C 7E3F 000C 0018 000E ENDCHAR STARTCHAR U+0105 ENCODING 261 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 1FF8 700C 000C 0FFC 180C 300C 301C 1FE7 000C 0018 000E ENDCHAR STARTCHAR U+0106 ENCODING 262 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 00C0 0180 0000 0FF8 180C 3006 3000 3000 3000 3000 3006 180C 0FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0107 ENCODING 263 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 00C0 0180 0100 0000 1FF8 300C 6000 6000 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0108 ENCODING 264 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0360 0000 0FF8 180C 3006 3000 3000 3000 3000 3006 180C 0FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0109 ENCODING 265 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0080 01C0 0360 0000 1FF8 300C 6000 6000 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+010A ENCODING 266 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0180 0180 0000 0FF8 180C 3006 3000 3000 3000 3000 3006 180C 0FF8 0000 0000 0000 ENDCHAR STARTCHAR U+010B ENCODING 267 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0180 0180 0000 1FF8 300C 6000 6000 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+010C ENCODING 268 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 01C0 0000 0FF8 180C 3006 3000 3000 3000 3000 3006 180C 0FF8 0000 0000 0000 ENDCHAR STARTCHAR U+010D ENCODING 269 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0360 01C0 0080 0000 1FF8 300C 6000 6000 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+010E ENCODING 270 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 06C0 0380 0000 7FE0 1830 1818 180C 180C 180C 180C 1818 1830 7FE0 0000 0000 0000 ENDCHAR STARTCHAR U+010F ENCODING 271 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0001 007B 001A 0018 0018 1FF8 3018 6018 6018 6018 6038 3FCE 0000 0000 0000 ENDCHAR STARTCHAR U+0110 ENCODING 272 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7FE0 1830 1818 180C 180C 7F8C 180C 180C 1818 1830 7FE0 0000 0000 0000 ENDCHAR STARTCHAR U+0111 ENCODING 273 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 003C 000C 00FF 000C 0FFC 180C 300C 300C 300C 301C 1FE7 0000 0000 0000 ENDCHAR STARTCHAR U+0112 ENCODING 274 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 03E0 03E0 0000 7FFC 1806 1800 1800 1FF0 1800 1800 1800 1806 7FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0113 ENCODING 275 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 03E0 03E0 0000 1FF8 300C 600C 7FF8 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0114 ENCODING 276 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0220 01C0 0000 7FFC 1806 1800 1800 1FF0 1800 1800 1800 1806 7FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0115 ENCODING 277 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0220 01C0 0000 0000 1FF8 300C 600C 7FF8 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0116 ENCODING 278 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0180 0180 0000 7FFC 1806 1800 1800 1FF0 1800 1800 1800 1806 7FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0117 ENCODING 279 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0180 0180 0000 1FF8 300C 600C 7FF8 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0118 ENCODING 280 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7FFC 1806 1800 1800 1800 1FF0 1800 1800 1800 1806 7FFC 00C0 0180 00E0 ENDCHAR STARTCHAR U+0119 ENCODING 281 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 1FF8 300C 600C 7FF8 6000 6000 3007 1FFC 00C0 0180 00E0 ENDCHAR STARTCHAR U+011A ENCODING 282 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 01C0 0000 7FFC 1806 1800 1800 1FF0 1800 1800 1800 1806 7FFC 0000 0000 0000 ENDCHAR STARTCHAR U+011B ENCODING 283 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0360 01C0 0080 0000 1FF8 300C 600C 7FF8 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+011C ENCODING 284 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0360 0000 0FF0 1818 300C 3000 3000 30FF 300C 300C 1818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+011D ENCODING 285 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0080 01C0 0360 0000 0FE7 181C 300C 300C 180C 0FFC 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+011E ENCODING 286 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0220 01C0 0000 0FF0 1818 300C 3000 3000 30FF 300C 300C 1818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+011F ENCODING 287 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0220 01C0 0000 0000 0FE7 181C 300C 300C 180C 0FFC 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+0120 ENCODING 288 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0180 0180 0000 0FF0 1818 300C 3000 3000 30FF 300C 300C 1818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+0121 ENCODING 289 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0180 0180 0000 0000 0FE7 181C 300C 300C 180C 0FFC 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+0122 ENCODING 290 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF0 1818 300C 3000 3000 3000 30FF 300C 300C 1818 0FF0 0180 00C0 0380 ENDCHAR STARTCHAR U+0123 ENCODING 291 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 00C0 0180 0180 0000 0FE7 181C 300C 300C 180C 0FFC 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+0124 ENCODING 292 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0360 0000 7C1F 180C 180C 180C 1FFC 180C 180C 180C 180C 7C1F 0000 0000 0000 ENDCHAR STARTCHAR U+0125 ENCODING 293 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0700 0D80 0000 7800 1800 1800 1FF8 180C 180C 180C 180C 180C 7E0F 0000 0000 0000 ENDCHAR STARTCHAR U+0126 ENCODING 294 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7C1F 180C 3FFE 180C 180C 1FFC 180C 180C 180C 180C 7C1F 0000 0000 0000 ENDCHAR STARTCHAR U+0127 ENCODING 295 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7800 1800 7F80 1800 1FF8 180C 180C 180C 180C 180C 7E0F 0000 0000 0000 ENDCHAR STARTCHAR U+0128 ENCODING 296 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 05C0 0000 3FFC 0180 0180 0180 0180 0180 0180 0180 0180 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0129 ENCODING 297 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0360 05C0 0000 0000 1FC0 00C0 00C0 00C0 00C0 00C0 7FFF 0000 0000 0000 ENDCHAR STARTCHAR U+012A ENCODING 298 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 07C0 07C0 0000 3FFC 0180 0180 0180 0180 0180 0180 0180 0180 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+012B ENCODING 299 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 03E0 03E0 0000 0000 1FC0 00C0 00C0 00C0 00C0 00C0 7FFF 0000 0000 0000 ENDCHAR STARTCHAR U+012C ENCODING 300 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0440 0380 0000 3FFC 0180 0180 0180 0180 0180 0180 0180 0180 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+012D ENCODING 301 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0220 01C0 0000 0000 0000 1FC0 00C0 00C0 00C0 00C0 00C0 7FFF 0000 0000 0000 ENDCHAR STARTCHAR U+012E ENCODING 302 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 3FFC 0180 0180 0180 0180 0180 0180 0180 0180 0180 3FFC 0180 0300 01C0 ENDCHAR STARTCHAR U+012F ENCODING 303 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 00C0 00C0 0000 0000 1FC0 00C0 00C0 00C0 00C0 00C0 7FFF 00C0 0180 00E0 ENDCHAR STARTCHAR U+0130 ENCODING 304 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0180 0180 0000 3FFC 0180 0180 0180 0180 0180 0180 0180 0180 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0131 ENCODING 305 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 1FC0 00C0 00C0 00C0 00C0 00C0 7FFF 0000 0000 0000 ENDCHAR STARTCHAR U+0134 ENCODING 308 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 001C 0036 0000 003F 000C 000C 000C 000C 000C 000C 000C 7018 1FF0 0000 0000 0000 ENDCHAR STARTCHAR U+0135 ENCODING 309 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0008 001C 0036 0000 0000 03FC 000C 000C 000C 000C 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+0136 ENCODING 310 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7C3E 1818 1830 1860 18C0 1FC0 1860 1830 1818 180C 7C1F 0180 0180 0700 ENDCHAR STARTCHAR U+0137 ENCODING 311 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7800 1800 1800 181E 1830 1860 18C0 1FE0 1830 1818 7E3F 0180 0180 0700 ENDCHAR STARTCHAR U+0138 ENCODING 312 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 781E 1830 1860 18C0 1FE0 1830 1818 7E3F 0000 0000 0000 ENDCHAR STARTCHAR U+0139 ENCODING 313 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0600 0C00 0000 7E00 1800 1800 1800 1800 1800 1800 1800 1803 7FFE 0000 0000 0000 ENDCHAR STARTCHAR U+013A ENCODING 314 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0180 0300 0000 FE00 0600 0600 0600 0600 0600 0600 0600 0607 01FC 0000 0000 0000 ENDCHAR STARTCHAR U+013B ENCODING 315 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7E00 1800 1800 1800 1800 1800 1800 1800 1800 1803 7FFE 00C0 0060 01C0 ENDCHAR STARTCHAR U+013C ENCODING 316 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 FE00 0600 0600 0600 0600 0600 0600 0600 0607 01FC 00C0 0060 01C0 ENDCHAR STARTCHAR U+013D ENCODING 317 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0020 0060 7E40 1800 1800 1800 1800 1800 1800 1800 1800 1803 7FFE 0000 0000 0000 ENDCHAR STARTCHAR U+013E ENCODING 318 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0020 0060 FE40 0600 0600 0600 0600 0600 0600 0600 0607 01FC 0000 0000 0000 ENDCHAR STARTCHAR U+013F ENCODING 319 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7E00 1800 1800 1800 18C0 18C0 1800 1800 1800 1803 7FFE 0000 0000 0000 ENDCHAR STARTCHAR U+0140 ENCODING 320 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 FE00 0600 0600 0630 0630 0600 0600 0600 0607 01FC 0000 0000 0000 ENDCHAR STARTCHAR U+0141 ENCODING 321 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7E00 1800 1800 18C0 1B80 1E00 3800 7800 1800 1803 7FFE 0000 0000 0000 ENDCHAR STARTCHAR U+0142 ENCODING 322 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 FE00 0600 0600 06C0 0780 0E00 1E00 0600 0607 01FC 0000 0000 0000 ENDCHAR STARTCHAR U+0143 ENCODING 323 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 00C0 0180 0000 783F 1C0C 1E0C 1B0C 198C 18CC 186C 183C 181C 7E0C 0000 0000 0000 ENDCHAR STARTCHAR U+0144 ENCODING 324 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0060 00C0 0080 0000 73F0 1C18 180C 180C 180C 180C 180C 7E0F 0000 0000 0000 ENDCHAR STARTCHAR U+0145 ENCODING 325 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 783F 180C 1C0C 1E0C 1B0C 198C 18CC 186C 183C 181C 7E0C 0018 000C 0038 ENDCHAR STARTCHAR U+0146 ENCODING 326 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 73F0 1C18 180C 180C 180C 180C 180C 7E0F 0018 000C 0038 ENDCHAR STARTCHAR U+0147 ENCODING 327 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 01C0 0000 783F 1C0C 1E0C 1B0C 198C 18CC 186C 183C 181C 7E0C 0000 0000 0000 ENDCHAR STARTCHAR U+0148 ENCODING 328 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0360 01C0 0080 0000 73F0 1C18 180C 180C 180C 180C 180C 7E0F 0000 0000 0000 ENDCHAR STARTCHAR U+0149 ENCODING 329 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 3000 7800 3000 6000 0000 73F0 1C18 180C 180C 180C 180C 180C 7E0F 0000 0000 0000 ENDCHAR STARTCHAR U+014A ENCODING 330 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 783F 180C 1C0C 1E0C 1B0C 198C 18CC 186C 183C 181C 7E0C 0018 0070 0000 ENDCHAR STARTCHAR U+014B ENCODING 331 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 73F0 1C18 180C 180C 180C 180C 180C 7E0F 0018 0070 0000 ENDCHAR STARTCHAR U+014C ENCODING 332 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 03E0 03E0 0000 07E0 0C30 1818 300C 300C 300C 300C 1818 0C30 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+014D ENCODING 333 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 03E0 03E0 0000 1FF8 300C 6006 6006 6006 6006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+014E ENCODING 334 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0220 01C0 0000 07E0 0C30 1818 300C 300C 300C 300C 1818 0C30 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+014F ENCODING 335 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0220 01C0 0000 0000 1FF8 300C 6006 6006 6006 6006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0150 ENCODING 336 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 06C0 0000 07E0 0C30 1818 300C 300C 300C 300C 1818 0C30 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+0151 ENCODING 337 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0330 0660 0440 0000 1FF8 300C 6006 6006 6006 6006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0152 ENCODING 338 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FFC 18C6 30C0 30C0 30C0 30F8 30C0 30C0 30C0 18C6 0FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0153 ENCODING 339 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 1E7C 33C6 6186 61FC 6180 6180 33C6 1E7C 0000 0000 0000 ENDCHAR STARTCHAR U+0154 ENCODING 340 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 00C0 0180 0000 7FF0 1818 180C 180C 1FF8 18C0 1860 1830 1818 7C3F 0000 0000 0000 ENDCHAR STARTCHAR U+0155 ENCODING 341 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0030 0060 0040 0000 79FC 0E07 0C00 0C00 0C00 0C00 0C00 7F80 0000 0000 0000 ENDCHAR STARTCHAR U+0156 ENCODING 342 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7FF0 1818 180C 180C 1818 1FF0 18C0 1860 1830 1818 7C3F 0180 0180 0700 ENDCHAR STARTCHAR U+0157 ENCODING 343 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 79FC 0E07 0C00 0C00 0C00 0C00 0C00 7F80 0C00 0600 1C00 ENDCHAR STARTCHAR U+0158 ENCODING 344 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 01C0 0000 7FF0 1818 180C 180C 1FF8 18C0 1860 1830 1818 7C3F 0000 0000 0000 ENDCHAR STARTCHAR U+0159 ENCODING 345 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 01B0 00E0 0040 0000 79FC 0E07 0C00 0C00 0C00 0C00 0C00 7F80 0000 0000 0000 ENDCHAR STARTCHAR U+015A ENCODING 346 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 00C0 0180 0000 0FF8 180C 3000 3000 1FF8 000C 0006 0006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+015B ENCODING 347 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0060 00C0 0080 0000 0FFC 3807 3800 0FF8 000C 0006 7006 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+015C ENCODING 348 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0360 0000 0FF8 180C 3000 3000 1FF8 000C 0006 0006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+015D ENCODING 349 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0040 00E0 01B0 0000 0FFC 3807 3800 0FF8 000C 0006 7006 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+015E ENCODING 350 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF8 180C 3000 3000 1800 0FF8 000C 0006 0006 300C 1FF8 0180 00C0 0380 ENDCHAR STARTCHAR U+015F ENCODING 351 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0FFC 3807 3800 0FF8 000C 0006 7006 1FFC 00C0 0060 01C0 ENDCHAR STARTCHAR U+0160 ENCODING 352 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 01C0 0000 0FF8 180C 3000 3000 1FF8 000C 0006 0006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0161 ENCODING 353 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0360 01C0 0080 0000 0FFC 3807 3800 0FF8 000C 0006 7006 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0162 ENCODING 354 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 3FFC 6186 0180 0180 0180 0180 0180 0180 0180 0180 07E0 0180 00C0 0380 ENDCHAR STARTCHAR U+0163 ENCODING 355 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0600 0600 0600 7FF8 0600 0600 0600 0600 0607 01FC 0060 0030 00E0 ENDCHAR STARTCHAR U+0164 ENCODING 356 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 01C0 0000 3FFC 6186 0180 0180 0180 0180 0180 0180 0180 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+0165 ENCODING 357 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0020 0060 0640 0600 0600 7FF8 0600 0600 0600 0600 0607 01FC 0000 0000 0000 ENDCHAR STARTCHAR U+0166 ENCODING 358 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 3FFC 6186 0180 0180 0FF0 0180 0180 0180 0180 0180 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+0167 ENCODING 359 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0600 0600 0600 7FF8 0600 0600 1FE0 0600 0607 01FC 0000 0000 0000 ENDCHAR STARTCHAR U+0168 ENCODING 360 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01B0 02E0 0000 7C1F 180C 180C 180C 180C 180C 180C 180C 0C18 07F0 0000 0000 0000 ENDCHAR STARTCHAR U+0169 ENCODING 361 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0360 05C0 0000 783C 180C 180C 180C 180C 180C 181C 0FE7 0000 0000 0000 ENDCHAR STARTCHAR U+016A ENCODING 362 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 03E0 03E0 0000 7C1F 180C 180C 180C 180C 180C 180C 180C 0C18 07F0 0000 0000 0000 ENDCHAR STARTCHAR U+016B ENCODING 363 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 03E0 03E0 0000 783C 180C 180C 180C 180C 180C 181C 0FE7 0000 0000 0000 ENDCHAR STARTCHAR U+016C ENCODING 364 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0220 01C0 0000 7C1F 180C 180C 180C 180C 180C 180C 180C 0C18 07F0 0000 0000 0000 ENDCHAR STARTCHAR U+016D ENCODING 365 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0220 01C0 0000 0000 783C 180C 180C 180C 180C 180C 181C 0FE7 0000 0000 0000 ENDCHAR STARTCHAR U+016E ENCODING 366 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 03C0 0180 0000 7C1F 180C 180C 180C 180C 180C 180C 180C 0C18 07F0 0000 0000 0000 ENDCHAR STARTCHAR U+016F ENCODING 367 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0100 0280 0100 0000 783C 180C 180C 180C 180C 180C 181C 0FE7 0000 0000 0000 ENDCHAR STARTCHAR U+0170 ENCODING 368 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01B0 0360 0000 7C1F 180C 180C 180C 180C 180C 180C 180C 0C18 07F0 0000 0000 0000 ENDCHAR STARTCHAR U+0171 ENCODING 369 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0330 0660 0440 0000 783C 180C 180C 180C 180C 180C 181C 0FE7 0000 0000 0000 ENDCHAR STARTCHAR U+0172 ENCODING 370 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7C1F 180C 180C 180C 180C 180C 180C 180C 180C 0C18 07F0 00C0 0180 00E0 ENDCHAR STARTCHAR U+0173 ENCODING 371 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 783C 180C 180C 180C 180C 180C 181C 0FE7 000C 0018 000E ENDCHAR STARTCHAR U+0174 ENCODING 372 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0360 0000 7C1F 180C 180C 180C 188C 19CC 1B6C 1E3C 1C1C 180C 0000 0000 0000 ENDCHAR STARTCHAR U+0175 ENCODING 373 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0080 01C0 0360 0000 780F 180C 180C 180C 19CC 19CC 0F78 0630 0000 0000 0000 ENDCHAR STARTCHAR U+0176 ENCODING 374 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0360 0000 7C3E 1818 0C30 0660 03C0 0180 0180 0180 0180 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+0177 ENCODING 375 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0080 01C0 0360 0000 783F 180C 180C 180C 180C 0FFC 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+0178 ENCODING 376 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0660 0660 0000 7C3E 1818 0C30 0660 03C0 0180 0180 0180 0180 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+0179 ENCODING 377 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 00C0 0180 0000 3FFC 6038 0070 00E0 01C0 0380 0700 0E00 1C06 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+017A ENCODING 378 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 00C0 0180 0100 0000 3FFE 600E 0038 00E0 0380 0E00 3803 3FFE 0000 0000 0000 ENDCHAR STARTCHAR U+017B ENCODING 379 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0180 0180 0000 3FFC 6038 0070 00E0 01C0 0380 0700 0E00 1C06 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+017C ENCODING 380 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0180 0180 0000 3FFE 600E 0038 00E0 0380 0E00 3803 3FFE 0000 0000 0000 ENDCHAR STARTCHAR U+017D ENCODING 381 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 01C0 0000 3FFC 6038 0070 00E0 01C0 0380 0700 0E00 1C06 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+017E ENCODING 382 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0360 01C0 0080 0000 3FFE 600E 0038 00E0 0380 0E00 3803 3FFE 0000 0000 0000 ENDCHAR STARTCHAR U+0180 ENCODING 384 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7800 1800 7F80 1800 1FF8 180C 1806 1806 1806 1C06 73FC 0000 0000 0000 ENDCHAR STARTCHAR U+0181 ENCODING 385 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 3FF0 4C18 4C0C 6C0C 0C18 0FF8 0C0C 0C06 0C06 0C0C 3FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0187 ENCODING 391 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 000E 0013 0010 0FF8 180C 3006 3000 3000 3000 3000 3006 180C 0FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0188 ENCODING 392 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 000E 0013 0010 1FF8 300C 6000 6000 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0189 ENCODING 393 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 7FE0 1830 1818 180C 180C 7F8C 180C 180C 1818 1830 7FE0 0000 0000 0000 ENDCHAR STARTCHAR U+018A ENCODING 394 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 3FF0 4C18 4C0C 6C06 0C06 0C06 0C06 0C06 0C0C 0C18 3FF0 0000 0000 0000 ENDCHAR STARTCHAR U+018E ENCODING 398 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 3FFE 6018 0018 0018 0018 0FF8 0018 0018 0018 6018 3FFE 0000 0000 0000 ENDCHAR STARTCHAR U+0193 ENCODING 403 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 001C 0026 0020 0FF0 1818 300C 3000 3000 30FF 300C 300C 1818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+01C3 ENCODING 451 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0180 03C0 03C0 03C0 03C0 0180 0180 0180 0000 0180 03C0 0180 0000 0000 ENDCHAR STARTCHAR U+01CD ENCODING 461 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 01C0 0000 0FC0 0360 0220 0630 0410 0FF8 0C18 180C 180C 7E3F 0000 0000 0000 ENDCHAR STARTCHAR U+01CE ENCODING 462 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0360 01C0 0080 0000 1FF8 700C 000C 0FFC 180C 300C 301C 1FE7 0000 0000 0000 ENDCHAR STARTCHAR U+01CF ENCODING 463 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 01C0 0000 3FFC 0180 0180 0180 0180 0180 0180 0180 0180 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+01D0 ENCODING 464 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0360 01C0 0080 0000 0000 1FC0 00C0 00C0 00C0 00C0 00C0 7FFF 0000 0000 0000 ENDCHAR STARTCHAR U+01D1 ENCODING 465 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 01C0 0000 07E0 0C30 1818 300C 300C 300C 300C 1818 0C30 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+01D2 ENCODING 466 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0360 01C0 0080 0000 1FF8 300C 6006 6006 6006 6006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+01D3 ENCODING 467 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 01C0 0000 7C1F 180C 180C 180C 180C 180C 180C 180C 0C18 07F0 0000 0000 0000 ENDCHAR STARTCHAR U+01D4 ENCODING 468 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0360 01C0 0080 0000 783C 180C 180C 180C 180C 180C 181C 0FE7 0000 0000 0000 ENDCHAR STARTCHAR U+01DD ENCODING 477 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0FFC 1806 1803 0FFF 0003 0003 7006 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+01E2 ENCODING 482 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01F0 01F0 0000 1FFC 06C6 04C0 0CC0 0FF8 18C0 18C0 30C0 30C6 79FC 0000 0000 0000 ENDCHAR STARTCHAR U+01E3 ENCODING 483 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 03E0 03E0 0000 3E7C 63C6 0186 1FFC 3180 6180 61C6 3E7C 0000 0000 0000 ENDCHAR STARTCHAR U+01E6 ENCODING 486 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 01C0 0000 0FF0 1818 300C 3000 3000 30FF 300C 300C 1818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+01E7 ENCODING 487 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0360 01C0 0080 0000 0FE7 181C 300C 300C 180C 0FFC 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+01EA ENCODING 490 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 07E0 0C30 1818 300C 300C 300C 300C 300C 1818 0C30 07E0 0180 0300 01C0 ENDCHAR STARTCHAR U+01EB ENCODING 491 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 1FF8 300C 6006 6006 6006 6006 300C 1FF8 0180 0300 01C0 ENDCHAR STARTCHAR U+01EC ENCODING 492 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 03E0 03E0 0000 07E0 0C30 1818 300C 300C 300C 300C 1818 0C30 07E0 0180 0300 01C0 ENDCHAR STARTCHAR U+01ED ENCODING 493 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 03E0 03E0 0000 1FF8 300C 6006 6006 6006 6006 300C 1FF8 0180 0300 01C0 ENDCHAR STARTCHAR U+01F0 ENCODING 496 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0036 001C 0008 0000 0000 03FC 000C 000C 000C 000C 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+01F4 ENCODING 500 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 00C0 0180 0000 0FF0 1818 300C 3000 3000 30FF 300C 300C 1818 0FF0 0000 0000 0000 ENDCHAR STARTCHAR U+01F5 ENCODING 501 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0060 00C0 0080 0000 0FE7 181C 300C 300C 180C 0FFC 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+01F8 ENCODING 504 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0220 01C0 0000 783F 1C0C 1E0C 1B0C 198C 18CC 186C 183C 181C 7E0C 0000 0000 0000 ENDCHAR STARTCHAR U+01F9 ENCODING 505 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0220 01C0 0000 0000 73F0 1C18 180C 180C 180C 180C 180C 7E0F 0000 0000 0000 ENDCHAR STARTCHAR U+01FC ENCODING 508 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0060 00C0 0000 1FFC 06C6 04C0 0CC0 0FF8 18C0 18C0 30C0 30C6 79FC 0000 0000 0000 ENDCHAR STARTCHAR U+01FD ENCODING 509 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 00C0 0180 0100 0000 3E7C 63C6 0186 1FFC 3180 6180 61C6 3E7C 0000 0000 0000 ENDCHAR STARTCHAR U+01FE ENCODING 510 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 00C0 0180 0000 07D8 0C30 1868 30CC 318C 330C 360C 1C18 1830 37E0 0000 0000 0000 ENDCHAR STARTCHAR U+01FF ENCODING 511 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0060 00C0 0080 0000 0FFA 180E 303C 30E6 3386 1E06 380C 2FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0202 ENCODING 514 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0380 0440 0000 0FC0 0360 0220 0630 0410 0FF8 0C18 180C 180C 7E3F 0000 0000 0000 ENDCHAR STARTCHAR U+0203 ENCODING 515 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 01C0 0220 0000 0000 1FF8 700C 000C 0FFC 180C 300C 301C 1FE7 0000 0000 0000 ENDCHAR STARTCHAR U+0206 ENCODING 518 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0220 0000 7FFC 1806 1800 1800 1FF0 1800 1800 1800 1806 7FFC 0000 0000 0000 ENDCHAR STARTCHAR U+0207 ENCODING 519 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 01C0 0220 0000 0000 1FF8 300C 600C 7FF8 6000 6000 3007 1FFC 0000 0000 0000 ENDCHAR STARTCHAR U+020A ENCODING 522 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0380 0440 0000 3FFC 0180 0180 0180 0180 0180 0180 0180 0180 3FFC 0000 0000 0000 ENDCHAR STARTCHAR U+020B ENCODING 523 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 01C0 0220 0000 0000 0000 1FC0 00C0 00C0 00C0 00C0 00C0 7FFF 0000 0000 0000 ENDCHAR STARTCHAR U+020E ENCODING 526 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0220 0000 07E0 0C30 1818 300C 300C 300C 300C 1818 0C30 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+020F ENCODING 527 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 01C0 0220 0000 0000 1FF8 300C 6006 6006 6006 6006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0212 ENCODING 530 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0220 0000 7FF0 1818 180C 180C 1FF8 18C0 1860 1830 1818 7C3F 0000 0000 0000 ENDCHAR STARTCHAR U+0213 ENCODING 531 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 00E0 0110 0000 0000 79FC 0E07 0C00 0C00 0C00 0C00 0C00 7F80 0000 0000 0000 ENDCHAR STARTCHAR U+0216 ENCODING 534 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 01C0 0220 0000 7C1F 180C 180C 180C 180C 180C 180C 180C 0C18 07F0 0000 0000 0000 ENDCHAR STARTCHAR U+0217 ENCODING 535 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 01C0 0220 0000 0000 783C 180C 180C 180C 180C 180C 181C 0FE7 0000 0000 0000 ENDCHAR STARTCHAR U+0218 ENCODING 536 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0FF8 180C 3000 3000 1800 0FF8 000C 0006 0006 300C 1FF8 0000 0180 0300 ENDCHAR STARTCHAR U+0219 ENCODING 537 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0FFC 3807 3800 0FF8 000C 0006 7006 1FFC 0000 00C0 0180 ENDCHAR STARTCHAR U+021A ENCODING 538 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 3FFC 6186 0180 0180 0180 0180 0180 0180 0180 0180 07E0 0000 0180 0300 ENDCHAR STARTCHAR U+021B ENCODING 539 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0600 0600 0600 7FF8 0600 0600 0600 0600 0607 01FC 0000 0060 00C0 ENDCHAR STARTCHAR U+021E ENCODING 542 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0360 01C0 0000 7C1F 180C 180C 180C 1FFC 180C 180C 180C 180C 7C1F 0000 0000 0000 ENDCHAR STARTCHAR U+021F ENCODING 543 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0D80 0700 0200 7800 1800 1800 1FF8 180C 180C 180C 180C 180C 7E0F 0000 0000 0000 ENDCHAR STARTCHAR U+0226 ENCODING 550 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0180 0180 0000 0FC0 0360 0220 0630 0410 0FF8 0C18 180C 180C 7E3F 0000 0000 0000 ENDCHAR STARTCHAR U+0227 ENCODING 551 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0180 0180 0000 1FF8 700C 000C 0FFC 180C 300C 301C 1FE7 0000 0000 0000 ENDCHAR STARTCHAR U+0228 ENCODING 552 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 7FFC 1806 1800 1800 1FF0 1800 1800 1800 1806 7FFC 00C0 0060 01C0 ENDCHAR STARTCHAR U+0229 ENCODING 553 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 1FF8 300C 600C 7FF8 6000 6000 3007 1FFC 00C0 0060 01C0 ENDCHAR STARTCHAR U+022E ENCODING 558 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0180 0180 0000 07E0 0C30 1818 300C 300C 300C 300C 1818 0C30 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+022F ENCODING 559 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0180 0180 0000 1FF8 300C 6006 6006 6006 6006 300C 1FF8 0000 0000 0000 ENDCHAR STARTCHAR U+0232 ENCODING 562 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 03C0 03C0 0000 7C3E 1818 0C30 0660 03C0 0180 0180 0180 0180 07E0 0000 0000 0000 ENDCHAR STARTCHAR U+0233 ENCODING 563 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 03E0 03E0 0000 783F 180C 180C 180C 180C 0FFC 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+0237 ENCODING 567 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 03FC 000C 000C 000C 000C 000C 700C 1FF8 0000 0000 ENDCHAR STARTCHAR U+2020 ENCODING 8224 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0180 0180 0180 1FF8 1FF8 0180 0180 0180 0180 0180 0180 0180 0180 0000 ENDCHAR STARTCHAR U+2021 ENCODING 8225 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0180 0180 0180 1FF8 1FF8 0180 0180 0180 1FF8 1FF8 0180 0180 0180 0000 ENDCHAR STARTCHAR U+2022 ENCODING 8226 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 0180 03C0 03C0 0180 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+2039 ENCODING 8249 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0070 01C0 0700 01C0 0070 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+203A ENCODING 8250 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0700 01C0 0070 01C0 0700 0000 0000 0000 0000 0000 0000 ENDCHAR STARTCHAR U+20AC ENCODING 8364 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 03F8 07FC 0E04 3FC0 3FC0 0C00 0C00 3FC0 3FC0 0E04 07FC 03F8 0000 0000 0000 ENDCHAR STARTCHAR U+22C5 ENCODING 8901 SWIDTH 1000 0 DWIDTH 16 0 BBX 16 16 0 -3 BITMAP 0000 0000 0000 0000 0000 0000 0000 0000 0180 0000 0000 0000 0000 0000 0000 0000 ENDCHAR ENDFONT Allure-0.9.5.0/GameDefinition/fonts/16x16xw.woff0000644000000000000000000012734007346545000017351 0ustar0000000000000000wOFF®à×`DSIG®˜FFTM®Ä†ÈGDEF® $&'ªOS/2øJ`‰‹Ecmapü2Nž™—åcvt DÜLfpgm0±e´/§gasp®ÿÿglyf `¢ŘÚó¨ðhead€56™%,hhea¸ $ YhmtxDµ”ˆ¸locaT  Íy_žmaxpØ ©íname¬ð‡à|˜post®x ÿ;eprepä__ýÿP¦xœc`d``âÓ~Žïâùm¾2ȳ9En¤vnÓûBþ]asbr9˜@¢KÀ Cxœc`d``ùw•Íáÿ?6'  `pG~„\ xœc`as`üÂÀÊÀÀ"À’ÀÀÀðB330ø3Îc@ ü@Ê Æ÷vÊ ²+eùw•U„Q&ǬÀâ¤Ô Uxœ•RÛ„ |XŒCW†PñíP‡5XÀ-äÀ@ð¼›$,yl0Ë‹hiËF"»™“#Û&»³[åö¢ŒøË{µåYr@‰™…å» Ôå`‚%žX£Y‹*ǺŠÎçÀÑåŽûˆ˜K±‡ÕgMÂbHû£·)p*^£S~U¾­®_kÒû­¯ægo:®_s?ÝýÑ%þ¢Ì?¯8öš”×·Wk\™ˆ<çgž‰7hXº›xœ­’kLPÇÏ)E!Š\¢^!r)]èâNîw’¤’¤!„6÷"·a¹Ímîׄ…¹4}3ߘ06›Í†­íq¼ï;£ÏÎöüŸsyžÿÎùÿà+:!‘$»çÚSzÚ<ša4Á oЍ()’b)•2)—:y!¯ä|”ÏòE¾ËOQãa¼¯ñ3&È„˜pibLœ#Ô‘è¨}¦jù¼qpŠJ‰•MRâæynyÞÊùdy¾Éi0ÆxÓÒø›@lÂL„‰¶<G‚‹Gô½ÖéS}¬´F«µJ·êz-Ð|]ªyºHs5G³5K35]Ó4US4Y'ëx«£ê3êǼyùºÖõÞÿ0ìMÊшñ·ŽÆ=7› W§§[é¦4Ã_šÓ‚–øÑŠÖø@ÚH;ÚÓŽY:LˆU´ ¡t¥Ý £= §½éC_"ˆ¤QDC,ý@ñ$È@1˜! µg#Ib”õ{ cÇx&0‘ILf S™ÆtfÌLR˜E*³IcédÉ\²˜G¶½ÿvJØÉ.Ê9ÂIÎr†s\à<¹ÌU®PÁ5®SÉ nRÅmnq‡»Tó€û<¤V YÉrY,YÃi–³Ä²®"ÏâŽZ,pê´Õi·” /QC19äÿÙ_F¡Åùlf‡Å_þQüž'o¥ßlb±Ó„"ÖºO·²›-ì¡”½ìc?eäÝ?ÀqNpŒ¯Îªîêu®ô Tuž)xœ]Q»N[AÝ ÄØ 9Ú³™ï…6H ®.ÂÈvc9BÚ\äb\ÀP Qƒökh(S¤Mƒ $>Oˆ”™5‰¢4;;³sΙ3KÊ‘ªwi½ç©sHánƒf›~'¤ÚE€ÒõFFÚÁ#-63zåº}¿Áf4åN@yÏ[ÊCFÓN í¹2?ƒá>ÿË<ƒ–fšžZg!=„À|3nið5£YwýA_±:\ †ÓTÜõÇTÊÿ–æ\m¶63šwp!"?˜hj­@ÓŸ:¤z>Žb rùl¬ &¦¬?ÉDpa2]ÕT-3¾vpŸì,:ؤJsà°Už‚‡ã£ …ô-‰2KC„ƒØ*1BÄ$‡BN9w²?)P>’„1o’Òθa­qä50¨ÍÓ¾ÌfSÛ[‡0~GðÝ/Æ’>²¡6F„ØŽX `‘QU¾¡Æs/‹¹Ôþ3%`yúí_'­;6/emcŒ‚žß6ßùeÅݪ\çE¡»wU5T锿C/gßãO…á ±àÍç}£@í ‹ šÁÞÞÿÑZuÄUÞ Ùo5³±¸ÿ…°K°PX±ŽY±F+X!°YK°RX!°€Y°+\X° E°+D° E²+°+D° E°+D° Eºÿ+±Fv+DY°+ LdÈÈÈ>jÚ®Üè.ž ’Ò 8r¢8vªè d  j 2 Ð , š , N Þà¸NÖ`Æ À0jÂŽÚŒH†Vº4Úæ–Hx¤Ôê"¦  Š þ!~!ê"~"Þ#$#r$"$\$Æ%B%Ä&8&¢&ö'z'Ì(,(Ú)T**†++l+ˆ+ò,N,N,ž-0-Ú.þ/®/Ö0¤0Ì1š1î2ˆ2°3’3ª3ò4<4 55B5¦5ì66<6|6Ò7j88Ä9r:&;;ø<Ú=Ò>°?œ@^A"A¶BJBäCnCÖD>D²EE¼F¸GfHHÈI’J6J²KœLDLìMšN:OOnPPÒQŒRTS&SÖT²UpVVÐW~Xyyèz²{d| |Þ}œ~>~ÒdÚ€^€æ0xò‚d‚ʃDƒƒÈ„H„Â…¶†ˆ‡:‡¦ˆˆ–‰‰|‰äŠBŠŠ‹‹tŒZêŽ~:æ‘À’Z’ò“ˆ”D”ü•Ì– —4—è˜Ä™Fš6šº›¤œ8¾žŒŸR 6 ö¡Ì¢”£ £ª¤<¤Â¥<¥¦¦d§ §ž¨ ¨Ä©Xªª°«l¬ ¬Ò­b®:®ö¯Ð°‚±L²²à³´.µµè¶€·8·æ¸~¹$¹Æº.ºô»L¼6½½z½þ¾¸¿~À4ÀØÁXÂ$ÂöÃÎĤÅ^ÆÆìÇÀÈ>ÉÉÐʾËjÌLÍ>ÎJÏJÐ2ÐðÑŒÒ@Ò²Ó"ÓØÔŽÕvÖÖ²×BØØÐÙXÙÚÚ„Û*ÛþÜœÝ<ÝöÞŠßßÜàbà ààá6ápáÂââ²âÌxœì½{Œ+ivVÅG7Ù|UñÙ$›M²É~²»Ù]¼}ïôÎÌîÌììkvô´”Y10ðe úËZ'#¬Á®…À±¥YÛyXVþ±í 6U$W ‘bÄÂ^Þ‰àÚÑ… «•`C;‹$6¢Ù$ÐÞÛ›ó;çûŠUl²o÷Þ]åŸÜg±Èî®ïœóï<Ç0#o›oE?g¾oDºá}ÏŒ¾gº±¾g˜=/Ï‹›=ãäÔ<”"oOÍ·†C#yã;¿ýFìu#eT £}6 7¥N©sµùÚîÐïÈÃépö¿"oà\~úò]óÐ0"æûÑV̹ô³Wcd˜FÏ &fÌHÄznÜ1ÝDß5á9ܨåÅè‘Vé‘’òHöÀnÓ_óý©y8¶Ì·.?¿FĘ~çWâ?KÏW7šÆ/£Õ}ßÔ«+TÏŒ½çÙŽC?p­7~ɨ%{nÉÁ¢s›ôvœÞNfúé­¾[{äEVÇ«ÒÏMàkjU|MÍ ¯‰9nÕòÊôTk úH‰>’¶è#¥2>R*ÐG²Ž×æ§½wFTaJµ…Z¶P¬Mïµíö¿Ì·ø¿éå§q}ùéaèŽ| ja}Ÿ!ºõŒñ¼™6F­p{àE£ï¹wœQ . ¼SzY¥—§xžœMϳGŒ=°Zÿ¬ïv`µ{×™l5ìLÏÛŠ½7Y9Æ¥[x+ôÞï<öž»by‡ô^j?–¢ËR…?æ ¼},C”z|r×fÕ¡ã&Zl/}@Ô<¦§Ø·göF1«ï©vãïòµ;téîZÞQpýœnwˆ‚åMºy_Þ¦W/B v~´’ÍŸŸ{{v~\Üènw+熷ҴónãÜ=¶G«‰MzŸé\"ržuΘÚg vô>ëØøŸ©^ÕÛgÕRÇÄéÓ‡fïò]ªyøŽy8|ø€þ¡_—ï¾sùé‹áƒCó[†ÃøÀ[¾P“<ëkyzãñ×é¥aqcJÿ|†÷IßxÞø˜ñ—Ì¿gŒ> ^¥ÞkÑ÷Fiºö2$oVý­Úýð`òbÌHÅzžý2Ý{ÑòŽcï¢àhcà=OŸmÞ%à Šm¯z‡(½F¼ÚvÜ5Ësˆ+ÇuˆætoÍr Ðsµ3ཕâ½åÕéÛ¶éçO ­7?4›½üQbÄÐ7Øwܱ¼RŒÔÁñ.tˆ“çÎä$n¤é;Ð7·ˆ9ƒ{ôñ½³âŒû=+ÑóÒô"Ý÷"kôH}º¶,7‹DìŒ%hI=kr&ßã¬ïæÞ>}¨ˆOT¸e\lÓÅÇñAï³ç®;Þkôµ[?â8“ËÖð©~”~ ‰ûšå}’>÷CŽ÷azµ÷šô/½J?ìÃÖääk~ ïý8mEï0c罜a)ºj³ ´Ïl—Ðo•àï( Œˆ MàkïîO‡æÉÄWY .†Ã‡úb:¼?¤?þ€©^¿ !ƒØ=yõá}‘¨©-Rküÿã¯ë]\\Ї H¶þdëÔxÑø„ùÓÆèrµ?ðîïv~é9ÄÐmˆ 4‚÷1¾øIÅ«Îh ú¶4ðRôgœZKd{ne0ɈŒØÎÄ0s¢ Úö/=ϯÚï%ú¾-úª¸ã¶,¯K¯ž{ óµ¾{B s8u'ÎBüü‰ ¿‰Ã7Ü‹•Ã(–><¾$w?æ¸w,ïœ4ÄÙˆ¨óe¥ °)¶åû‘’uë–·I¢Öï9Ìo÷`åáî8Ï™i ÷Ží®ž{÷Îíü—íõêá‘ÅšãÎ1}¢×?Á'Û=<÷ž7íü$«66énËvkçÞÚKô©¾òa|*e»ýr¦x-úÅ×)"þ5‰D£sö¼ •ƪ¾ùe¾¯™-ºfúä‹t©ù-§§/þç|íƒ h#úE:ÇŒ¼y›Îf×È?iŒâPÉ#†§œQ<†ƒ ¾šìL¨ ƒ"CrbºVß<¢=ìeˆŠ g”‰à“™Qt0{9bŠ­í!€ZÂÛ¦å7ÛÄÞÈV笶ì"]^»E”¨Ÿ»†ínœ“uH,O®1kE:[Rý•W‚ä‚Ó¡Ú\r¡oáž¾Àž‚±J´øã?`¸k}ü!"¬ âÎÈ4°3𤔦·¹ÇKÒâbÎ(¹†÷’ØskI\® ¼ŒÚE0`Ûd°tl’°·Øè›êÿaÎüóßÿÎsÑoÐSä ÒóQèù5ÙÓ´ScQ|ÓØ /×ÇŽæÍl>£xÕ¥ÙÌM¯aÛ§õ“b#{iÐ,“13 ±r3DÂxx·ÉÊ– ¥¤6¸ÐÆ|+^Œ¼A'RAü‡˜øÚoh—ÌCzx²c ÑOðh-)ãuÙ3 éH$¾)ƒ^ˆò<ôSš|VÂØ5Œ+‡üƒ¾SšiÜiPÓ^¹2 uÃÎ+¿Ñ1þ¹1² Ê´óù¢H«[wX{ ºÉMºYs&­¶'«º¾uÙÌ*Òbó¢ù¼2]7·hy-âN¸ŽåUé2E—|ˆŽfQÙ¼UŠyÚ±¸…­’©ú‡ á•-zA†TdÑ¥Œ,>‚5Ž$×LR,^¼A‰®&ÄŒ¶ýÃuÔâ=ö]l>Èà¢[l|ìœtr™½w¦8`ΰ^¹¸ˆüæýûС̦Õ׈VÍvCèpJUFQK«¡,ŸH´.Zê(ÅÇQ*Cœ¤p!ÎÓ¿1âŽùOKV?Km¨iä Ú=‡ÃwH­E~“Œ¯ÇëÃÀÏÞ7¾ª~v‡ØQ;²Ñ÷¼=ž‘·}o²3 ð‰è²µÂ—ġɿ*_nÒåÚ_Òé5©Ôø²¯²À¾ÙT/ÊtØ1²ͼ5âRU —4 U¨ÀŒv·«L`¯VàL4_€1’¶¿K$³9¶LHÝo4ˆ‹Û-c·vhGLðl 4em´Cæ‰smvè<óhJüºüê”y8¥‹iôs‡âñLbŽí~‡i÷?£=>âˆvÐ.O´3öxåÛâUÆr÷*™Þ$5vbìãL꛸¿Ã+UøÓÕW¤Oç„N±G^"K¦YÿÞF˹ÖÀÛ¤µ²bÓ›Z‘¹Û–ÛÁVp¼ôÙsì©£Ò[¯BäÍ()´øí. ¸¼×l‰‹ØÖÙBZù;#"EÞþä'Ÿ|ÁüNF¢Qä·A’×^>þŒÐæç_Ó´úÒÏO• ðûHÆMØ`ñB  ë¶Y`#a"˜À± ^œðk´„è]ç®i»)qW8âAžìÙôa´õðá㟋¼a¾™6ßÿö„D=ø³ëÆ?5F5ͧ”–q£Æ”¯ø|Ê­ÕRħóÉÍÑÃ(;…T¯áÀäÃÍSLo²Á”ÕÂ’›Wž³vîÆHiѽ‚3LÐ\(» Û+”ÙZ!±us¶]äóJ…ÏÁ ÆõI©<þ¹Øèq%ÚVš:åðµHöâò”… ½ñ×Ý6zÆŸ£M¬¼K+ç‹­|ƒqmk3Ñsö*G…@’Q:LÒqã{C9gk\èm‚8!NÁòöAœCæÝ¯ßm)UÝ…««¨³É¦²»e±RNï+f þÌ.¤Ѥ#z«»EâºJæ¨Wߥ Ÿ(n4ØÆën ë×sw‹­›B>Y" z)ÒñlÊj--’ÛQ†l`Çû:"ÎÆùoÂÀó‰©Ôö«S¶ßñëâÚö¤¸¼Ò™Ÿ4Ät¯h¾JT„t³Á1ç ­hx•2±¾pîV‰Ùd°¹±ü8gíîÑI”µÙúÝ^p8Oãeõdpš/ô¹ýÓ‹€O¤nß¿oðyü'ôÌoÒ37Iîу6Xè)ù¢E¼î:²'Îôæ¸G7Ém=Üß Ž#âž8“Õ¼ríÎ$ÖSÏõÝM$ðö•{뵈ᛖÇubC¾ÎA‡8½{ª‚ˆV‘¾¢)¡ÏäéF¶F7:–»­ŽxÁÞ™¶^ŠŒYo»-½´µARA*¤¢e*F WûùI¤T6wp8Úãh¡xŒã’+σ¬ (bŠÅ$Úìñ±ð*³É„»LF“(5µñØnB”è´{™ü0ÄÚÿƒk,æQÑ’Tò£ÝyðlégrlKËF.AÎÉzÈ(’-#ÆBfõ(ytƉ5#‹¨äd5αwRìÕ+vuôª= XÚ‘7f~AD|zîDï¯ed«(”CÐrd[xÇ.øþ̸-àÙ7àÕŒâù<›Ñjq݌ң[ƒÉšC³UérüÌžÑ73Êhk§v]_ÔX5 àP_ÅÄ&;Ý="½ÛÀÅr÷Iö7`„™î Uø{šºä¨`[±#d‘eâ á•”ËH“²ç<½:¥·ì ïá”lÚîþ¹wˆPR6_€ó[$Ûk¼º²³+W[Lí¬í5zôùÃü8•³ØãêÛ£4{Î^­0ó—Ýu{­â{ÇónâŠÏL›‚3e—Ù²‘êÀÝFÊZeÈ^3ÂoX„"‚›ï›‡´¿Ä“Æ;â—ùÑÇá›ü ¶¬¼Ä¾Æ©Ù7FGг-²>`ún‚ä[“‰éo8£bDÅaùªgwå¨HlH×È"Ù¥ÝbÅñ‘I+¦Ýt¾ÛäÞí@C÷HCX^&Å Ë®ƒ\á)~â…EïFâF7Ö›DåC=ǰL'òd]î­[“ÈMõé…·š"ÏA$“=dA¥z8ÜG›üèÍýhm1m³pšèÜf§Â[K)SÙðNæïn³ì²XqH;''§fÇ·€$ †ÍöcÀR׃è¯üÃ×Á¬×Ÿ¼ÏÛDìæé“/òâÿ£ŸãíÈûk:;F`›•]"khÛøJ RV!"]uÝ!öl6Œ¸è1X®“dš_&¡Dw$á(Ñ&y,eAfºl!óìUê‡P¼lž¶GSY?iì¢)˵•CâVIÒý]D(ÚÊ/Qáf²â¶—¿™w³ç^,IwWIôm}­eÂôöœ—MÔˆý öŸÿˆ=ëWU؈ˆÆöãŸàí?&£óKÁxMÇ£èT"¹å‹[ ãBK<º­ÆÖ!É•ÐÎÒÊ(ÏÑéQ ʈV×DHTâLnÔÑq·<6å̕ę+ø‘ê:,K‡³“0.³[a‹• \5¯Á‰ˆÍ&lÇ>(‰¢‡hûGˆtÀ/ I«vûÃ!" ÓÈo!7ÛûÉG..Ľ‘½îÇßHN‘4-Gc:ôÖcïÍdiS‡éf]­{”â´O‹å§H;+R OQ¢Œ™ø{c;SMˆï_ê#móÒݪåÇsL–6»°~5¼2Y`nŠÒËfˆ:« ?@”}Zm·ý|$%úMQtO¾ © Ú^,$J^ ÍÿsxA22T2R1þv€"v`/¥¯,‘½"”[†· ‡·ç»lk­3%lq;Â6háF;HÛòò&çJ" R AוrE¸>[šÓ`~Ó’È“}øøë‘ßzòáh‹­–ói. àØ^KÁøKײlÅ ($—.qH²ÿ½þGøfeñÃÂ> =µ²…W^áØúÿjŒºzvg{ôV›qR«wWiuØÎ qíÔÖÜY¶5›,~£&'‘š$Ž£¶%YnãÍr-Ùc¯°Ã{¶‹=Ûæ=ËÙ%Ã+uéE{{çEÁÍ­ùhøÜNnûæ²ÞÍ[¼›¿È.ÜåÏD·¦h‘-M;ZY„çL?ö’Ø»+°ç;²KUœÞœÂÍ ÀýÑj*G·&ëI–€õ¨êˆíUYf•Ù^­ Vè<¨y.•J]’‘‘]ö½¬,‘‡¥£\L2A* ® G[9°²b[‰„ù-¨+ó[ä¤XyA.±¢åþMäNY¹0ÍgŠæƒ Ü ,ï–kíI}œžc|ïl^UßU~‚Ý–ðV¬Á)’"œ5ìÌ>,42ÖÙ˜‡¡>Úfûq»å´½K伇háq‡ˆØ†¡>Ú⺠/Eç…›<‰¢ï;]õRµµÆÔR³‡Ã“äTÛÍ$®¢¿”ÄjŸ*ÓjÙÕ|ÉÑÕ2Ùõ²r¶¤Uæ5,ÆÈU†dØMŠîÍH)…—!Ýë!IgÌ­SŽ de´lÃÏÕ7þ­’—ºÈKµqä댋 0t-DÅ`ÇݳX™rølOø‚šž$'ôG‡øpSž‡ý2ZÒ‘dñxUGý$ £ÈQpaG–w s3–—•ñv;K.ñŽXò;}”ñàªÍ%<ˆÀ‘êU9¯S­$áõ6Yomæ“pWØ‘koÛ(j0æ ‡R d¡´“v|ù·‚Ï+®šŸgeEzø§Px¥N2ùÚŠ³Å¸ÌDˆÆäÀ}+L_Zz”Ä ¶7£'¨7Ù,8ʰlÙ| ó=ÓåK‹U ‚ÑŠ#)ìÌc&¸”ÔzLð|-:ã"½ Á{âãp,(3Iˆ.›ñò aší1¯ùC*²5;ªoà{Õ«$ u\n”éÛ¶¯Oßsg¦Z‚6aÁ¦+X´W‰¯­7Qsg¡ßÒÓþ»9~¨¯•‡„_ ùãu}0~qˆ/ÔIº£,vÝ‚j¸è±6ׂȦÈÆ•0ªGT®‡/vÄØSr\±§/ç$–èâ#®:ä4{yÀÄÞqÜ}öW«¸wY¤‰b[ìA¹¸KÞfŠ‹¥ìŒm©M`1íí÷äб{d“éëmÿ96Óƒc ½#„ä% ¿oW× Eö>pwìQKçn5ïÆàœ†¬ã¶¦+ ¼© å@h!öºOF¡íC­ßÌ·øM<`ƒš$Þ7¬ulgfÖÿa‰ZS׈¥YEmŠº–ï#äœnøi1h‘^µE+ª ¡’Vý‚Dq3•@CÑ’s¶l?Õí°é 8ž#Þæ4å˜ mqñ8™BË6uãMãNâu¬¿NrÕÐÉĆN&(_š„‡6µ·wHJ` dЧøâŒ3H£{Ã㲪0ÌcC…Lv÷êkD©]äd‹Žd–¢8dâ;Çœa<ã Ë&‰%5ØÞ‡ÔÄÍ­ÓÙ犬¬å‘XæéU_ÛÀ§ór¤šülÒ(¹Ö€tumwóÜ=Í{ûôªgÓ•õ‹g žl$Êâyφφ²:d`ÚäˆÈÛ3 ;oÀ¶_sÅ|Ѝ*4ÓYÆéå»*⨠¬¹‚z¾ÂnÖ¡ë_£oÆ”V–<ѨR߯ÉÇ ïRÐû=VòzlK$….»{|Ùåd/³”¨z0'Áröms¹Æh›%Ë(²”àmÖ«Þ>‘ˆÜjì®x+YGòÄ!] în‰®Þ°˜oRêÂ:>EzL6¼½®ýÁM„^[Cí9[(:mÍÃ'_€NF"=†~Ͷ‡²åÿc¿ÿJzØ®æú™äX: výÌÝNçñ]ÒÈ“µæª—á­°f!1Éeùn%!R:c84_wTš¨’ØPõ2z ”©ZBëÒQà•·ˆÎ+ÊÌäüz4M"½ÆñD€Sç\ òåb©ÕÞÛg¡_›™©ôÖ¬…@E®‚9=?¬™úv<kì q ]ŽµéŒžú2äçFp9©Šªr²1‰†LÒ†r’о3\08Ë‹å—FY\eeI,Sœ—àŠ8+UBQa6Ž•ñÑž¾ríJÃ!éɇ—}úäW§—]H°è2ä«þSU °ªk¤~BŠ]2üÈ£({«|ÔyqzÖZÜï©Y\ÌËGi„ë.`³kº¦ƒ/¨ŠJ(ׂVÍBœÜu·Lv ìæb ÇÂj™˜\³3níbµ6«1°W|1è°!*z YØ3xò ­ð´Ò?¾¸ˆ6}~¶‚¶vÏøCc´…¥¦TÙ,l^g¡Õƒ[“ ˜WE|dÙ¼ìƒæb©e³‘ "ζœNtt•2 3™ÝS¹ç^Š¿‡X”ØÏyß~Î[b\rr’‚bovî 5òåÕœÕØDkäGñ›…¾ „;hV½,ß¡ßL,í¸”wû°á’3’PC×bÀjÞò­f¡ö¾Šî³‡¹:Ògt°ï“_*™T-^K$nœ±[䣬‰g²ÖŸdäŠ,“š)©pи¦i¬[ÀŠâ @ÏØ™™•¬ÄNU–.´‘5MY µ?B”|¨ˆú„”úÉ9™HП4ÿš:Ÿ—SðüÅO@ UîÞsFŸ„±±<ÃFsWUñÉÇérÜ[îGqçe¡ó©3*E¤›¬ˆsµ³‹ïˆ[:ÔstO{$öu[>À±½}‡ƒÌ`*ú´^ï»y®ã­r_Ï(Ïô˃!EÇ—ØKì¨üÑ×¥ÆÀûˆèþªå}P,ñs9Ï?ˆïqþ<³Øý å¾„¦’V÷…­ì^œ-´WT-Ö÷¤y?@ŒªWÉ O¦3 ˆÿGl)±yéâÞÉ)íŽ3{tÜwØØ\ÓÍ¿JogéñPuÃçí•ümg¶sìšÑ uøp¨Û}x?M‡Á8… TðË ýÁë~ãÇ=ãÏT¾¤ÍqTÙo¶Úo¹‚¯®ö„£?(sJŠù¥ ë@ò¸«&wP¢ÓGÍ{´c‡wNÏ­ŠoJzjœll%È€‹Õ×SCdJÙY³¤å—|VT%‹Ì¦l2æHw›8RGàgÞ™GÞZrN…]e„UX€ä8ñ´ Ù?ißé°ñ–ª0lJ„…Ïm‡oc“ãAˆ`·õ)îáwøGØmÀlVÒèÐ =‰D7[mÉ-å­\Öó“•Õ˜ª ¬5¥šÒ°Ç…âê¼\3ïöÏõi¾°¤nIaNû@mRþMõG :ýåµ/€ò"ÐÛ³JÔ…÷«£ïéÎ]ˆEÜÐ]G\Ë/eªÚÓ|?ò6‚·äŸ"t®Õ/œ…" ºJâlþ÷¢ZýèçVëÏzvfÏmFgî?w„E{Y ÆžÕsKìÙ6ßBà™T3QéÛ~nóýÀsz <¹î1<¶ýn°ðæ&Ù#ßô¡ôYDûhÈ ôYÜ#rã?ûçÿÙp ÞD[´Fô€½HkŒ(/Þ¤M‡VR¸ °‚ñ¶¦Š_M®†µ°šDéaZúhÚ¾ò’¶(ö×P¢£ :/¹ò ™KU£m|A,ZtÕX襦©7;E¸€›Ñ1Ø ›¥&nNJRb[²Ðe41 þ¤ŽÍoõ]ë‘Wã`óÈâƒØ#6!*¾`è¢Ì²f¡‹/)–°7³¦…¸«ùQl-%ž&§³}óמ5êéô¿-Åà!rÓ˯>àªãhûñ×Q­÷ªx±eá¼>©ˆ/½v%~òËêdV)†@rß³9b 3 ÉÕ:Îɪ€gu<)JP%gc´dƒ“³A†E\Œ¿à⸛n&?J¨IµHo¦S0üëóÙW;PªRº§ 9jÇõÁ¿ö€ÄJ>{ƒIh“zMëBâyÝøE)±±Liy›” ë´*¬¾ÌMè“Õ$ß E“ØqÚ{ý8D©ýTöõæ*=©‹ùr5NØÁÄçl¥ŸcFxe;I›TO}.Y7K[µ•ý >~¹L(óhúíѬ N§$©òGuã¿ ’â–nTAɳ$‰dð'ñj>I|Œ É ¯û ÌGaz,á¶UØW« ›ÄL4x{ÑlL©Ä€W/«/Næ‹-ÒÖΫxñáÐXmEt/„…\­kö.”%iþ×Bû¶iüåÑå4úY¤¢]VÜ+ò‰7©¥q[|²ºÆ—ºš¢Å+Έ‹Î ëÜÂâÄ QEq¶(™/¼Ìœ%¬¬¥,›;;ǼõV±eÍ0gÙ ŸñµÀ—ÂÝáãŠÏÜ‹èçˆ×8­Zú†÷é­ Ãðí%²¨+ÆnŒŠ*wh§V´ qz5™àôRQÉ´©`Öûn™-[w/kßUÅ:Uf•»•8¿H½£vÀkcq%Ö’„/œµ,ç$Îô'¢‚ÿÉ#?ñä æÑ㯙‡‘O¡ þbøàâ2C\ý3Çýί¨½¹mü–ÔÞ‚S¢¤õc”3%•؉›¬lÖrÄDÀ>¬bf¼¾ƒÄ¡ÝÆ¥Û`óÂÉ”K<òÒ5GŠ®;ŽXklŽÖ6twª¯Q4Ù”Ðj‹6p±M•D%¡ç ëUfü&R«hDã\¯Š,úqåÉk«‡æQ´%¥Õ‘ß~€Î¦Çå ][}_'Ûõ6Àf„òhão)maâx)Û™éëɪÐÐÁJ‹•ëãÚY¢Éê cRY:i­E*Ùf @!U<½ü™'¯N•¦Ã&òâån8š42Æâõ«*®+rýgŽGýžº5>.¡ÉVùáW“xxߨYÔVKÄqc-òÛ‘7íwHÚ.ˆ¾±×j™ã<ư¿¢d.­e.©dŽ[nè¡VWÒ­U Åöáñ5åmönÙUª¢Æ¼;ˆ“‹"=òΪ=PáâUv„v,8Ì“Lo€ÖÜÅF¢±+¢±ËÔÝÝuwƒ¢±ky]T¨·¤/ÈÍ;ãJ½KJ&ÄGŸŸ®%;ª$vëPµg£Æ¾_ÃM¢7ÜìÔ¥3|•Á 2tôsÛ˜/[¾áß^*†¾a‰ãŒ¹ùyU,AâË4ËŸ I\øÞ€Š |Ž|ƒxÿ’1ZSqaXÒä2’àù°BY4j œ;JsýÚAã8-:ÞNNmUÜ!´‘ߊ¼AÛùÉ+SúéœÿF›½K:®bü%ù¹Â@kf>¸øæVÉqtWv}%ÈŒŠåý,*GU¹ÄÒݬ¦ DËQ"¹Â}µ–êÎCÃùh5‘’¸£›ÆãÏf4PL?–KÚË—ðÎå¨TíŸÈÛO^Å_#dS}AÉ©-ú™œàš ±ëÐJPá Õkê× ®V!hˆz–\ÞGÊ[R8­MÊ*LÊ•Uî–4p&¯½n†j]B VKÖf7™>@ó­šËcuJì þ/w¤u£®ñ×–uOÏÛ$d^hccqËô’>éöíû¤d|9[U•ß*ùò´ieŽAR¦Zå ”¹©ò²æ/^\ .ßU4¨¿dŒb`vBhÿ$„`s £[ï#ñûdÍQ1œü+:#“¹j"œElOœ¬¢Ç‘sbRçÑ$ Ø› âµ—.q½áaTgÏݺ¸O'§•0“‘\m›úì.£/öñÏ]þ X-ˆõƒègµU}ùió[æ/ùý—ﲌÛdu~Öð…IŸLŸ›/ÉE ¤Ô‡á¨…3‹Œ¨Ñ:˜.‡l¢à8ó'-ìÌ|D[WÙu±®¼¼%CÉV]Ó>ÏÔ†—tlÁš¸ÿ„÷ñÏ]Ȫ÷W/`G¨EÍömÉø«S¸Þ²9Ú²yCYÑzË–yË’òxËJز…`à¾^AoÈ@ù›p£-õBt^¾k~žAf?úðül«Þg³çl_Rñ«¨n£'j˜›™ wsºuÇ5Ø”¸ðÏW·Ëó'%kÅþN¿š†u{RI ¿¼ª6aä™:)Þ%2v=I¤3›M쨘-ꦞŸdseì*%†‹.©“„ÜlÝ:ÇåuÑÏqv?úMZÿ㯳ûmäü§¯ý¼nž™†ì>:¯ à+T¢f9û˜’“Ë“ •# _1¸GQG²5"EÞ¯òÊ'uP[jjóºd©àƒ|ÌÎ52Cˆק·û]¾ËF´6µ6Ù³ÝPÈ1siO[“ö4nz†û“A¾¤y®APƒ8¹ºaM0r¿’©~š¾y:BÝ»b—N çÅøŠ8ëVqßø—3¤âCéE`dÉ]–¶©J @,µÝÜAn³üMú1F î# Ðç úŒ_>ª¥…\õ†seà‘ŠO£«€Ï–ÍnÈ tÑÀ!Ã}±2+¢bA\Ͻ ÜÅt†+Ý¢ýåln«£ÚÅû‡R6hÚî–ïDv|õh+i?¥­,è{ôÁ)7Þ³òšb—BºX³¥§Z¹éd¶ü3ÕÛ‚ä.c|ç2^Ž~“i:0îÏ2>l|Ìø¤ñCÆ_¢ò“æO$L£z³ƒr˜}t†<÷qlƒ—ö÷`Vü0ÝÝ"“p‡ËCH3Ž*xm ÐØ£Ò ¯ã£'&Œ¨ ß{åGé΀ïü{ 1ë½ú†ôÇQáƒ?ˆ/Dò?™±ñ…‹ÇègÜýËt—L~öàœóï÷ÝG£í¨6Q°±ô£¶wè+Œ8G Oˆú‡w蛟X“=©Ä¢} Î– ÷ÑÚù‹ØÛmD?ÎOúR{+Ñ›ÉgúÞé™Ëâå«Îøe¼í~d0ùa¾åýž\PFÙOü§!c ¢È7`þþÈO X•Ü!-ã¯ÌcŸê¿%a²ÄÊMþÒg*òQþ[üoϽ֟1ˆÍ?ýæï¾ùÓÂtu{“ ùŸß¡_Sÿå›oš¿8ÿq¹ü7úw~úÍK‹îÑ?æ?ô/qÛ˜ÕZÑo1Lýš ®C·û—TìäXï4äãéÔæmó>UU{hȨÊN4}t3À–ì0Ã`ô¶9tÝFкX#C|‹[3·h_z{ÇÂXDyµ£ˆ7B—Ƀ#ìĶdÈ>•¹‘ßÍ‹uq¸¯j% (qÇ™,¾.Šã—Ϥ9çlV;Íé¶’´¬ëz­©.Íà¿‚1¯ÿC½P•ƒ7¶dÕùÕbdÕØSh¼‘†Ä¹Ï(†¿E9a JL`‘Da•¼ï$e&ø—ñ>ž‹‰_»äU”%¾Ã™Q¤ÀÞ\˜ÍxæŠ[V%·¶î?E¹ŸÅ`T\8ˆÖ´ˆ•~ØC\ç㉦ á°çBU`±K'-0)tV (ÚÎ ÇkÙ#TØ_N¤,{÷/Vò/­Å’ëîvïÐÁ#{’/l6·ƒð}†·†0Ðá×®r]ŠwŠî¤^(ðptgv%šÌ‰|gº3W÷*Ìj·ƒ±Z›Ï;‰)‘¶¥ÓJJ:¸=ä‹:>ÿª®ŒŸ!¼ûÙÄ/ª×SÆbyUEñ"óúHªnPÒ(ü¸~Ò"æûÄðØë …)ú³ª×`Ú·À›£ÍX£0ºCúÚL’žszV'ÕjžA†Ýää˜_Ÿ(ûãÎSHÑ'Õã~PÈ@_º¦úK#ígáH;úvìs·—muPcɇ訋ÂKØÆãÕln…×pmÜ?…¶²<ú.PÛâú)l÷’’©Ö÷‹ó¿>ô{Ä Å^£ „.Õ²h“âøa`ÐÌ›(g;J,?®ɪð " èõñS_’å4¤e'kqÖ‹ûD¹«8É·§:³1F³N³½fgU”^AérÑÇ@Š=ÚæaìõoOMõx}(0l£ xl/²ûÿs »Æÿ¬bíU >×4«vÄNm;®ÍØ~6á¹(©´[Ö ÝJÊ&ªÅÏ £{Å!SÜ¢ã7¯°“úìÉhøgĆ»Œá¯Á•jθÝéJOhŠ{Bݲð³!F¬•WÙ^/—Qeþ^w'Xb=ªÒÕií÷|¥ËwSjöbq•œ‰Sò•Þ0âÆ‰ž‡¢ç„Ä^a R̆"¾«~Ä«cOc.¾?ðg1â+d«}&öƒÄƒŠÑ1ÎŒçÍ–Ç:íÁ"÷ˆëE"àÈHmÁ †cð¤Pû»ÑañÆ~¾n%ÞÇèUÂdŽsË݇–ÆpÖg#nÜÒuôLŽÐn^—¶Æ"g…&[¢²ï2Fa˜tîÀøŒOßõA‰}…Ãf5Yd÷ä‹îõéÐØ÷UUQ®öý‹ó¶Ó@†m}¶¹½cT§ÍÖ‹Ÿ=|Øîü¸©-Ã<üH¶<¿Ûþ mñ.oñ?$èÍaäÇhÓ¿©Ë*ß>ùï‡æß^þ˯Dþïô—ðo,òÿõ›ì0Óíߥ #¿1¼üÞ*Ìj_·—t=å”k±Byûì-5×&eäà·*X¶£VÕ,†¨®½Ô}ãÄ*îò°vUµ‡§ îÉ[µV3 i")8#æ¬J”Á[>3Y&\þ*CŒÅ6d»!ÊÏ£ ØïˆIŠ^zwfÓø²¡yœXˈše9†—U *;ãÀ3œ›Æ2G+ûSÆ´âá?&ëP—žñ.]U×vÜ s†¾À ÿ»ÐŠ‹J¯c‚5}ã2B §ˆ¯Xû~Ÿ _•Œ•û\(Ö\p‘Å©Ì×¢€ÐH‚T׳pŽ«Q)ó4ª_Q·ÙàÐ⺔ç7”5áCþïÑ«®ãCû76ÉŽÅ%ÇÓ²Gy˜·çn‡|d©|v÷lIŸì*àçÙÔ¡™‰«BYÊé°µÙ…$©qC¡•ã¡Bì×·pˆ±Rô©ôtŽf§ÆŸ£>CeÃ3䞌0 'Ç>ò{ÇœÂ%FO 2)ÇøÆ®Ôþo;“•b_%'‰<_wÍâ- ¯óú¢„$±ã° :ês©¿OÛ? 4î¾TWö8]ËÐ!Š·}Š÷ó_Å·:¸ÝµuÕÃSi-m"~z»´ˆæœžÂVFrf1ñ×€¹AúïýÿÀµ#Bÿ™Ün;£ U‡Ûißë]‘a Ìɰ$|ªJ—:ÜÛÔÔQ³Îµ nÎBˆuOdW¹ú'ôêé̔ܮÙù__Y-–¶8IåΓÞLxO”ðö5jy °h>¾Ž´ª°çL&ª-gèr!«º$¬ßÈñ.ÓW[ìßNîÿm0 zÜ KUMp1Ôc„^F,äŠ3êÌZºÉi=Hpæ[b×™$ q„N’$º)›/IµNrY¾ÌE¥%y“«RÄbŠJí êÕ€ËÊ•Ý=ÇÙl[Û–Èr9A¶%° `ò­èFÈ¢4BFIžÝ Ž„4Î9Dtë›x Cº;2QP¨°ÏUE€êô[“u E ÷Åïó`$Iê¼*&¡[«]ÉT(Äà¡Â6]y…ìÅmòŸ3?8ÐÑÑu“XL*!åûÑ÷Æ'û‡ †C™´N]h Œ!yžNáµ{&¹¾´5yN¾z@Ò|ÎõsTõvü¢¹ˆÀðãèn‹ NÕÐŒb#¨íríסgœÍ òǽgywpŒËá¾!<U¸¥¡R%S#_Ù 'Å4Dì%ñç|c®|€> ,áQ9:gT ÷P× 76Û0 ž;å‚bK&ËyY›'”2h™¥Õk|oV=¤øU™+ëˆ2ÓV;»œæÄÃpjÞ'^ j¿9}òÁ¦5ßšôŽðb>xÚ¦ÎrÆ\ðÖ¼ÿä#S™Õ4ÏÏWnÂÏFò'~íž•„Ÿsü<ø>òsB<l•=ô÷5“Ÿ³Þñ=m·7åéî }¼wžž§ôçi<¾C.ç)º4éO~mO1;öø&<=†Wë ø´ÙuƧ½ãïÙI뎱?ÇYzí>çsöyùw%uCÎ"Yô8OeþÞþ~ÀP Û»ûÐqÏÄNK‹Ë©6^éíí»,„œ2Ç• òñù;KøxþµyW‚u…ëYx14icúXH˸84Iÿšäf<<7^6?qžƒ‡‚ïM&ÚøÞî9f'œvœIë 9ùAŸ“/Ëwz8ùÊ"N*Öí9ÞK¾Àu;æd×™<'Ñ–ã>gñ™GèÉ}Éo`b€©ÇŽûüÍ™úaFò ¦Ï>ðý‡x÷¢0Ù¨‡0[_þÀÒíynKým¶§Þ¢íÝ0ùá~Ó>$ æþð)Û•7,}Ìß³±¿ ǸgîÞ„ãšã1Ì„ž´z OÕ¾ÏaG¾òH ÈVaö”2îôViÏGàåöçY¿ÞÄô2©Õ²$‹¼Ú€ìpôL‡ò¶|7ò8üçø{®ù{@›õPÚNò¶{oޝNïٷ댈¬.ãâCåsš‡ÍÅü›>d¶™¿ôpjÎëÛSãÜ|ù¦ú–Ù¶kñïâžcœÎq^»w}îËWß!î}àVšö9}Œ:þ1ÚWñþÑa_@©=Þ¸g70ŒÜâêñù¼VÁ§0¹FUC¤£kâÁ0ò¹'R>EÏf`›kjþuSFÒ—xd½ÌÀö'_™п8¹»ÛgWe{7ÁÐ:Ì,ÉvrŸh¸]iålë ÚaŸ·yò‡¶8Dñw÷)cÀŸÂ çÓ`­x‡ˆTï‡Ç xí}wxƒ±Ø-ºílÉ‚Ëwï›ÃËß7§è9^0Ž€ÞÙïS{t\ÅØB´-ˆº ÍñV{ P&¦r“r‘¡pž±ª-ž¬J157~un ̯Ðth±!5ªa°~„…ê˜ÜD刻y‚î÷êp«×Ï—Cø›3_ë šÿ“WĽF›*‘ÕNU@g,¦ÓcªšUÀ%m܈Nß j‚Ë$µ@¨5m,¢S s[<½=G§*jH×ÓIû/ è$.Ë<”£2O§Ð„¢SKa“5XwŽ;VB0ZŸN­z€Z»·‘*ÙÄu„ÆlÎÓkŸYWT²»ÎM‡ æÓƒ2zùÜËìÐÿ/œ NÔóØ#õ^ÿeºqo~ÌTÉÏxœ-X°(®³tˆA(¢ã'A¤¨T€J†\l éuêzŒ³¤®w'"e»ãƒÎŽø¼uàU£!nqѯÉP~<Ô ÷”Ò]ä¢÷46¼ÿ%%»‡s¥{="åî¹»m»;7‚ʈ7üB>¯µn€”Q…³é¸z:õ‡äL$ ïß2j9°3"ŸRI?9oJÛƒˆ£ŽwÛè±í>mrº­½ä¶oL[ ò»H¢Â™»%mÛôÅÛ7 mðX^D[³'ôBâêÃ:LÛcã½%´ÝƒÞ:`¨³Ûvƽm´užJáþS¤WõtA}ïJ c Oæh|ˆ9ÚîåíÂ?îÞ–Î7’Ý]°P~}a)••±¦ó³gÒy èÜæ²€ñi{@çà¹í:O¡ö²2ÿq«L¶ðÄQ­3á&™ÞAŒˆ.÷oSí?8÷¶"ûñ¹·¿ÃÁ¾[‹ù€C7cüò^È‹ûÃwîÏBñKÙáklÄ߃<éûÆW—p¥«œÓvŒ{?¯çÂÁ 46)j´…sîr)á{W ÿý‘sm-.$«˜‹ *&$z«‡±QôsFÇøoP“HkPmÆnEšŒ«e z•›´&+³þÎ.÷!%ü™Ìi)±Zã¦1X–ÆSsëV`Üuv Íõ&>ðêį̀ì&7†µÎ½ÄŠoúmû5h~›˜_k®A,Ä®{8œ2x_p‘„_@+Å­³s‰{ÊŒ™ÏA F (aãùÍjršŒOF;ö‡¸tÈfX¾È14àSKÎqÑUæ6 bzÜn)÷Ýß©xXðgLa6zqà”-ÎÀÔ/qÝqL¸¡€;WœMïžìºß¥WËDÖ€ÛÞk(ÏâܬZ߾ܑI5iGàœZ@¥˜DI½—‘C ªÚ½štõâéêîstµ· °‡S ö qf¿¥‹Yâ‹jIîϪ‹ y`ò›9H'¶Í^¹_Œ95¬Q½ ÍΪ]PŸÉâÌlÙïucÇø“%Ó08¨×$Kc§‰ ^C ™fc 3ÑÝ›ÈØP(¶¤ÛŠzúØ „§ôØŒf—£Än}ËO¢á5·8Vsý0`\ôÊ\ ó-1Þ¢Ÿ“èqä75e¥jYŒ·›ÑsGu»; XÅ Y£õ]ÓsÓìI[jKÍNkß–ž›\­ƒ©JÛ7¡gc‡ûƯ§çv ~º€žb¯-¢ç4[™Ñsݽ éÉçÕÞ@M { ”M¡jó*Un.¥êÄÚžcO§koFWÔæïc2{t^g›‰gú²ªËX@ÚC]‹±Œ¸(ÂätëFËØ†5°ºªnÐZën9KvþÎÓi:Þˆ×Ⱥ+ËÜ£…“rÆ] ±,·û,ÉEgž¼»š¼DÈn‚½‡ïŽŒ÷fÙ+$œÒAÿþCs!ýt ißïwÍVxRÅ]>·h‹Žî&¸3UÚédÛaÇbýh•‘ä¹Ç•ˆÄh0­Àœ‹Ùˆ Mk7™Zj$HÎÂÙ[–Ô0 ¾¡æÜ~”Åsf`”"ªwI-?΂ã,¼£»œ+¿ÝX‹yͱhÂEP1šÎ[CýE*ÃMŒež%PÁ4]bŒ£¨FÍdo´*®ø“íÞŸÑVÛÝ‹ª$g Š/Q€L:Õr`÷Á4µÉ¬Wi“ð¬,ÃPºÛ];g|–`ß¶ ówÐ8ñlÍ¡¹]¦cîTM’cXî1a»Ë% ø¯d"ÿ[ÑÛɪƾÕg!ÜëK/™ØçÊç©q±„nr]qƹ<íÉ™é­o º'vÍmr›ÒfY63ÏŠìÔÂG± iXßíëÁ\î&¡ºwÓhü%ó,ÕsÎÀeô E¶)*®ÑìFó#}ÁB!U7=Cþ öQø°$6)8$z•yó«ûÅ¢T—_½¯˜¯ð}<®j]G4Äl‡¾¹2Ýa› xI ú*deäûMÆ>èdý‚™'Kf>X–Œ¸dQ ç\¾òSÇÛÙÿu×â1žG}¸¯1hZ­åu[ñö‘Ê¥ïÂCJóìÎUÛÑ´U·ƒK¸»7gqªxñ‰/L.‚X0ObÊÅ©‰·çxp ë9ìóÜS’k¬óèï ú·àAWÅf:xã þžÆcÙ ÿ$Dü§ý˜³Ð7!z ε|t‡ v Íð:ñ”߬–]Ñ|`®.”{x2ƒ×-,ö¼:Ž{ ì>;ñïÜ‚ø;fo²Ïô;û0ÕpI‡6EŸoIJd?ij7Ž0¾¶¾Á%&« \áÇ …_uø†Ö² ÀƒÏ`n-á†è)3Ð[@>4øÁsÒ—ñ#Šâàqg±Ýwå:ŸgdÆÝ2c¼ÕBíŽÈ~`[ìrf„s*iΓØp/Èèû³so÷ŽTš÷ö˜)ýåLñ:gªºü†Ì¹’âXÌžûÁ ÇuÒ‘²XˆG;dÝý›+\ê(¶Üî3såðögXˆƒ#Žæ±sî쪃øÙö„_ð„Ø>[¦–ØrŽ…tÒ)í‚ÎbúîTÙèè çÁ6YÓNç4ÁÝzQ$ïsããäP wÆÎa?áãNlõU¤y<àÛ¢¿æ_¶5:RIV„ÔbÏ8Rê88Rj]Q:'Ù’ŒŸ-ïu0ÇU ¡ç¹‡µ$0tŠ”’—YŸ êôØ®Êð)>æò­‹‡P™aãÉH*eeý/Nq_`û7CÌÎõi½ #{͇þóg£õÑõ´ÖÇh[å»'=ŸÜ"ÏùiÄ=¼R(°”¸#mIù‹H{䛸s´=5¾5'Ç|ŽÆ¸ÕìÔâF©¶$0€yølDv®'2Ê‹Ÿì"&˵” 9>â=1)$Ì‘¼·Ëm§Ï–{^u>ÂèÌÞ;C9p¢ ¸W辬ž6ì‡]ã‡<•î×x7$øwMâ£Ö*Ïö I,È}sá´?í‚û¶ãñkÄĹ?ÂÄ\Cì{KHgŽôÚãø¾ T¼br,£¿vDPp»Ú ñ@cmgžÂ‰­ŽÛ©¢ÚsÀKp¤¶N[:œ¶Tê-ý®ªn¿›zÛ…ûá™ oråA¨ðv9[|Å ñ>â¿X™§ù‹Ì‰ïW½í÷OÞ¯¸ŠsU%·‹uŒ8ŠQÆþ-G?Ǹô)ãØ`Ôb…œãqÃɘ zÆP[Ëå1d$øHšl"Ã<Œ~óɯ¾óÎ; Âö® Îê[¿ÆskwÐÖU­ÅžÆ?ê@O)pû®ÀXf¸W@špdçœÉis=I¶ï)ÇX'í>¿js#ë¤sį:³©@qnÌæt¬(î¢jg='0LÕŸ.–šß¥?IËW¥û¼•6Ж\çÚsl!¯q„"Ô^ el¾¥ê9†¿xåö\ÇÎW©4—N]W¥ZXRŸÊ>~ô¸Å~øø3÷‡¦§ª—5l×p6†&6R‡A_²dtK™›YåÊɘ²0lµb¡ø)£$»KFI‡"su¼Y¨"|ÝRh°[ ›ÄÎRÃ&%€Ý8÷V@ïæN ÐGN#ºõóe(猜¹q”æ¡_W1?˜’‡‰q¤×f7ÍÑ«2rº‚ Z×nB¯Îzil»I²ÚöI¶€PÝ¡h‹«$—h;%§Ï[ºbž<ÓYh4DŸ]ãwÊ<Û]®m„‘Ðä@œ»ÖŸJ¨½%„ª‘M"ÃxÆ;™ *¾D›yÜámÙ¹…”ÛP®tm<¶Å8¼+öS¦šn_ g\¬Y½ÂÒƒ³ØFɨÑÉõß]¡„ÊÝp™ýiã\[ H5.G‹³ ˆVn Y6’¥­Èâå¡®6ë•÷éd Öz†É1Uë«RèÆÜHޝïÑtáäHv6£‚/Ëu›’˜»v¤äîµ#%u|»$h»)®yƒi“¨ÒxÚ´IFáÖ®:NU,AéoÄ+³(u˜ph¨™?åè7x–À…á®õ½40åÓ>¶}®/õ˜9]©Ç ¤P}™vÀ‹g çxé5ó½hÎ4g ó]5ÛªÒr:Å´â'_œÆ\ÁY 3î}…¬âø›tòüö.ƒ¹( Ýä)¿×ó¶»”·ãšEq.qˆþ\çt®n+®Ž‰«›ÈWßvˆhÀ[ÀKµqRÙa°ùå›à€õTcÒ:\ˆÝv⣠äkŽÅ$ºú‰«œ¨ËŽ%ÚS¸ŽîŠÅ•cÇŽŽ’j±.¼µnŒ±ØÈ(β[Ô´ 0A3û Õ×v˜Í²L¶©» ^õ¤,Zˆu#Sá¶ôú:#%yön€ø;(Ëɸº óÒ˜Ù\æZ±~~>ÀhûsÔBòmð4‡$Í_ ¸?[â²¶È÷·¿|š›pM$½ƒ~ {)Jî%™ Ol+œ$ø\ ž²ìYy€ñC9^Íë2LÒ$õ˜D§UC$åœ(ZZER/N½T2Ú“ XUÜ1î´BU|ÊD€žA€ºè7YU ø–] eýêrÏ•“U[÷V‰°‡’6¶¯Ç­²7¥ò6¿v!^Uìuh ˆµÙ»x¼.Gü[DEàZþÿX¯ßc¬×©:ÿ7Œ.]êȲ¨Ü¢*×ÏD¥…6@Ë™T›õ5™ˆèÎ$¾Å¯”(v!ŠÛ,Š -Šõ«Q™?é­¤È͇˜æœQ±Å‰Ã|8j£;ý-vú["1ÜÕ†/{-2;GÕÚ¦T°xÀ†1¼nSËÞÖœì¡zZ}¸"„8¼Ú—Ÿ6IüèÏ4$ƒL.Ò°÷/¦O>¢E0ŒÿÞ0þË0’9›LÕØm§lÞï= WŽS¡¿õ-½dß®\bêW`Ü%q©|GW½0ÛÆx®æÙÛv®ï t»ìÎu»Ô‘lm1Pͳu1Y–v1uw¼ÌaAý~X&ºzÆÄn½›à4cUújo'#{·˜ ¨y!³fÒô™°ü@ñÙÙ…Ú¡ótnâ\çõfø¤¼ Ž%_‘¬`DÁô ß ÷»õ=ß·y ö¬­W'Om½Ò`'X:רv:ß°Ùâ2S@®õ¾'ímaú.Ñ™—ôlÎH=§ÃþÑ_¬ Ø~WÕÙͧ.,œÞñ΂9ÓЬ+_ýú_´ 8ר´ï…Ĭ^Ó|JZ®È¸kZ7.ˆ*ÈeµØ{þ4täÉš}ÖlízS%oÊÅZܾDÃÿjœgH%áëîÜTN0,ªépßI•=‰ªÊÖpù=$¨:/A f¾Ê±ÓÀqèuê §g™©5¾ƒy'v—ˆxÊh!žvšxä¥kä/or$Bà:‘±‰8£µ ¿Òr“gú©=3¾{tàcƒ¢´h<à§Âð#)JlòñÀ5F ¿MÄ;=C¶\Wbv~œ/¬Wy'm.(FÔ9sî¹Tåˆ~Ûå¼5U ˆðûo?@»Ùãò—{1€¹†ZEµƒ”/Ž2v-y´Ùºgn-ÙCw"râŽïõîG ×{è¹ë÷n ”Ѳ“¾¼ú®wÒùÜNâþμn²‹¼Þ@•÷o¹ŸB>Çu*àu,ÛRÁ@xO¯séžò}ùUxϸ“îÞb'ʳöƒûêêæ¹7·y¸µÍ9wlT×IÏø÷`…ýÀë6QÐã^¼Þð$¸Ž09eá>:Ò8ªßí¾9~ÊÙÎkÝr›ôç¶É÷øx™ NY´ dXgç‰8Ÿa¹ï!B´PîŸE¾Ý^À ;x1ל‘>šéØ> ¯e··PÎ[±ŸAŽ•wzôš=øð‹Åö-P“çê²×Ü4FC„Èù•- "ñ-Ý{ÉΪ­èÝB†æªº™ÀÝÃ>JDÇǨbÙ!®oœB†É™p7}û©¨ªu¦Í=š@¬;LL†XÅÉ{àŒN¹æíô0ÙS]²Ä).M9££)´àÕV-iãÌ ¸g !8ÜÅ3éŸÉeéœÝâvÎNWr\ÇRƒQÐÍ­;gª­ÓhuæE¼²\ÆÜÝ"Ãu^ØõÔÝp+ÔÔ]F¦–º0,Ä–ùãý%2Ïšå@†<³½tzKñÊ ƒ:ígnìípÝ=¶ádÄzßÃ]¡ë·†V¹Ä6BQ׃ vš¯ð{*’S‚Û˜¢wÍt…õ¤¬âºL³Ä …U úƒZ¸ÊžqµžDzñ*@Èâi qŽ­ø{#‹Ú- \È;£ŠÅŠb’O”Æì$8f!ìØ3pÎè(À…)Љ|æ·¦ÓË7ƒé:-v‘é<b’$‘‘#—IycÊqU?Çú_+ •E’Š5E&¨'ÎáÕ‰UeŠX3-¢H(²–£¯ª1EjX\-Aª…óÒ5Kæ«¢9“·Y±LoFEÄölŒ3?*&Â4@:¬N-›Ÿ§ß—ŸödùÍ‹ûS(|-á¹¹Mã ái²M577áºq#Ó”Ñ!9î&ŸžÛê»éG˜bÀ­,–‘3ö³tõxàqž'Í’©É]¦<Û¹vî•0q¶Šæ:D„J G‡1#B3hCA¡™º\ Ù¾X3ÈNY‚Ÿ&ª#%Õi›\ÂBÂköÝÔ#ÕuŒì9qÔÊεc‚(6ˆ’VQQŵûÜ„`›Õ`Rx ›5‡á¥7|l†ÜІBöíQhÚhRÍ'HP.lãGÃras‘AìÊ”ëüMæ cxÇ•áÁàÓü ·š Ã<È#Ëø¡ø}Ö^Ÿ}|7çÁÛ8ÁnSý>nÛt~ætÝøå0ÖõLðzn¤¥¨wÑ<Í6x×äD`r"0ˆ—–®ª=¶°S&þ2.gÉ¥å,IF_ÏËZ"­tExPs(^¤ú\öן>—‹T8ƒ5ãï.ÀŠÄH”ZD ˜tô ä^7HVÖ›mâõ$‡ ¢PÙLɦx^B¦‰_Eß 9àV†zÖf(‘5²ÏÂõJUão)ýŸhÆú µUò†ûÌâR® ¶„éÖúîú#/B‡¦BxeØ+ΤØä¢‹¼¸Ç¥–Œx•¸×º$öÂå†WA¡D¦<Ϻpz&À8Í`Æ #ƒuªkÖçµNzMåŽÝµfY;æQLØ÷²´”bì‘k!¦ÕZ­òhÉÃÅdpoµN'ZšO©ô˜”H\E)­,ް¬/ðR» ê+[H¿´@ú•³ÑÒyX}…—i‹ê3!Y+¯–Œˆþé æî›‚Áxh’ý¬<Ú´öh“ÊÁŠHâwS&‚‘á’ô~äIÊêJºá\$ï„Ø#²KUeñ(Æ‚[!Þ4’1¢" 2³}.¤‹Y“’è9’ …ÀÛÜàÕªê†r}!Cˆò:3< $—%Þ2yC-$$ÒÉ#Ó3O€1ƒhïª HÉtOÇnòDfZy@¡áºLdÎ9a}ÿ¿ÖÞkWí*×9}Ñeêøœ3c¯õÿÿú/ßÿ}o3uÀzÆfå€"Ká`´ÎÃHõ¤÷û UÌËÍ›á<;$,¿“ƒÇìì Ôû™x)†—Wï¡òŠcúɵó¶5|ëw©;Ók7¾S·†­“S"zA²µv¨`Ïýj¥›6µKÍO.±sMí®lÍ..JJ¨Ñ&µ(H pg>¥Û(âÁ4|à·i䟻ÎôµÄ=Ÿ›[ÆðÐà¹/Ë_€îjxnp½»¥à:­Ï· Æ'{o5oÜŒúºãÕ½Ó 6vú*­ß¡°eˆý^J A,±¢.t_¿Ðý4Ñù¡US ÀÇܾI¶lâׂ¬.]6Zršß:Ýï°N’º…û«7Åý,P¥§}q1±39¡tŽ­á!QÂÔzbÕ‚o*çq+Ë:Ú#ËjÒ žº´¦·ß×ZkTZÓu™ßãR p0(„—s°wøíûÈG*ǼLa@¹è楆ü¹Râçú[Æ0®Þn¯°È¡°€óº±8½Ú úIƦÏðR7ýPIæ{JßS?TRVÜyPYG’1ʳòLj¬ÓáoUE8YqŸ–Ìv<*'Õ]údé[æÑý‹÷…ѳä¯Ü!E­ý0P;¿~¼ª¿)}aCåÔÀªéa ©u¡V¹R!Fw8^OnÁâ×ñcÕB ͉k[#þ/jÿoJ]F¹6iquµE}¼­-ª{7 Tã÷´›$E:†É öãýk}™Tú'^JîµÛ¹Æ0ö…¨¿/9×˜Ó ”xQªú³â6²ÈÇ‘&ö”VèeíXæÛ-Óí–%ñÙ¦)ó´“PîœïÑžþ†=ÌÓBI¾(þ¬eSí)ÓOg¸‰,åcÛü€l•î+¼ ¼+÷ ‘ú”oþÝ oª»vWÓ6“˜Ñ¼'šv­¨î¦ºcλlQÄ7LQÜ„lZZN€{ã"Ú úëã~*ÌÛ¿PŒî´újùâ¬(ƒ Y§Œ‚ñkš¯nàÇZA¦Z?:Õ}øNK"§Óž*î2mª²w”ϤÅÏ¥JçžT fѪÿ82êõPmzþ껫ù=üDfÀ]ïMÎ!eŸeCT†ß›ðQ=˜Ziz,¼G› ]XÚd"ͬ-¹Ç¯E¿‘÷?õ¯Ãü©âÍ »~•⾕º ¸Ÿ5Òó¨ïE™'¿ÎKB$6«Îwò\ñi'úGÚi¾üeñ-ù½ä¦ñëÚIVìa‚üiJ3Üăª»QãD¤E‘Uú‰RH@dß(ÓWDðgŠô1ƒ E¥kŒ÷KEéZYRœ)C.Uü6sܶ%›±œ‡¤µ^@‰‡ƒ@ÄÑaH Òsÿ*úÞ‚©º–q™ˆ[¹½ÿtð@wƒ´•”t¿£×rVu7XU£ b/AÅöX®(;QŠÆ{òÖh”¨E¼ÍÏDúO±lIœ[Bë2äyE.*ééÙ’¿q5*…Æä ÊÁ¿Iù#.}r+~uŸ÷T[Ñ7Ï?~ªïjqíȸ2Ÿf(À½\´T½«#c̺Gé‹E¯Š®–%4k ¤l}l ³ÛfŒkTío:á0¨ÆŠ.¯Ù)šÇ"zb:h:×äq]λtýÝ#Ù¹èê~×e ö‰M¯ -ÈÇ\µŸÛIÉ£J 4rõÔœª5\‹²6•‘ÏAPwag_•x§~>­»ÕˆJVCn=!šµÞÏ÷nÌkÖ($¦ÝU®ø5ÑM™å< d«s©––Û=ŒGÍívŒ Ìãnv>ÒîpdÑG°¥Nw•çô”眦‰ žc:OèB®ØM®èN®n¤›\é×rÅí~ž8yó”“ǾlÝ2f4ÅoíÜŠ¢ŽùÃìa£CpᎿ¶PÓîVñ›»˜ïµÄßyKüåþ¹ôínÓ†ô#Þ¡3EBt•Iÿ@nöòw¸ó@_ÃÛ)àåx^Ä•ÞÝJ½nÕCô5÷Œÿ4á;â¾jà¡Ò=¡%ŒºØÈ¨P.I6ªX‡\£á»Æ>ݵjèФ.íèw°CØq€;òü¬å)Ìäá•41ø šFÝ’,ÀO³øí*fàïÙÑÜ‚ŽÕÍV¤Sd±ÛªŽè@†8Fà˜=/ÑýâÇÞÑêJ¶â³<Ñ¥oÒ¯ïÆSóƒ©wãæTœÜÓÓQ”]°æKß~ïGoòõxû^=Ì dô'òõx¯ǶW^zû,²áBg\äíxgòí¸‘»+”oÇéøÇçS”‹¼“+áOÈ6 óŒè“± 'Ɔ¼#‹qcÌ}Pì…tÌ~Œã‘—¥¯¿,”ó…îì·åQ-Ÿ° i5ŸÀjÆôã ên'4Ý;EÑSçÞJrC¦ÙPÀ”ÇÎ{¼U¶A¢ñzlÀ©ìPTKLç´úhÀ¹+Û6†F´V×[|›wÚ€pn–¤ÝÏz½«[’¬mÞI›*[ÏqŽ>}Æèª÷%ìýþ•»[žPùO®dÙ6HGŒÄ/„5'žñþ¬gü$ .0ÇVk'ÛDlÚA_Ó¢{ˆX‡M±TÄ:L;ÇÞ«Íæ>‡§>}ÿ\†§¾nû}‚~#Žè7(óùá>V÷‰öpokqÉ#›nS\ÚF\Ú³=ÒÉzÁ©}|¢® ¯µ MÍ:)<öpós²À›­^ìð{À†Þk-ïL¼ÕmãÇÆ°dpe^AÝ™òŒ¦Œ7Uaÿì¿âÇ›m:y‘Šjp.Ë%µ°²²í²gÛå4/‹m1†¨B‹ô: ’>»é½ÎEõ:ãQŽƒBUœc!G] ¯}åY†?Ì|~¯2ŽM=ÉRo„¹v°güof¨Âtt"UKì<ëLä@L§³3Gf† ¶`u˜B^|n4vJ"°ˆwð1E˜e°ËF€a]H†À6ŒªØ1K³°<Àâ(N@geê{ÙžŽNÇøÑ9RRo蜈MâOS#J#š˜”…â³ ×ËQg¥ÛVšÀ¡gZFÀ§G½öaLßæœok'ó5ˆfÒ!Ì8ßÓ‰ó R#,pÆšºíC\ÎîböºÀ4a™Õ¥ûüXËÅ‚:h=ã¿ÎÑàZˆ§‚LöÏÛq¿¶ìYEŤqëÇ=CÙOçÑí¼ofœw_î^ò1N›ý‘{oÓæ#Ö¾€ö™ÓP\Òµ3ç_¦Ùž"Ð]L C°¾/ƒv¸¸ šî ¯©~Ø zí„´ònlX´x÷3ðµÏغƕiÍQ_tl¾‘ž”BÖe¡Àí4ú`Îù,¹^ôŠ Æxàq«#ù=_¹ä¯œ¥Iñú-3/êÆ|3Jû]k1¥F¯+Ö&å¿– u gƒOiö±,gfK7R*.%¯%q{¶‘‰¯bMB¤ )Ô§óE•x˧SE‰<—äN„[NËV$s~*Åu¡@ ^ç‘&ÔiÂ4uR¶-?1@†°YcÞÄ4ÖR’Ük‚=QçïgûÄ$ÜÙ÷ï^þÄ<Á¦ûÀÇhv_þ„”‘ä©iT‰~"òܦqlœ¿kP ç±MÈt/³ÁÝ9•æ*Šlwï̶ÇÅ|MÖÐjí @+Š3«ÔÅ—{é¡›"_Žë5‰hr#«¶GƒÐ’ö‹#Ü^&—h¥)/Áöˆ^b“»ë:S*Z :7P åá¯ÇÖVÊ[UèÆ6­Ì8¾¾!7‘òÛL|8ž$>È#T&JÉ/ÅŠeL3ˆM iD.Žôeµß°Ê[óÙ`éÛæwÅqKâŸú€§·æwÍÁ¨5<-Ko×ôÊlNjrt€a)Ëø1ªmBRK”o3 ê*JÊ•4Q%DìñÞ¶qÄ|{¸´PöñL1cé7Œ³³‹ú££×î4‰#ßàÕxËDⲯVp“(ÑZ•çèÅbg,I#*àÅÃ³É¸Ž†ldQiá.®H…ãpˆMæ®êÑá{Ï–~ëþåï`·îÈT"o•—ú^0xó‡}ãÌxË|×öp ¶0ÔnÏŽ±¾zpùiæ¼eðùŒy,ˆY:,å‰ Ã7Ñ/Çç;g’¿ötÏ‚¶Y àÔöì>p+OÈG÷|‡«íKj7E¥‰ËÄ2hÚÈjÜì1+1^ʼÁ4o÷hÊÜF„x^— š¸Ä=R $8—hAÏ0–Èá𥺿Qs¡ÈOzöð‚ЧâJŽÙŠ6D u7Úåÿ–|‹Ý¨ µñhÆI|Á­W©|uwá>›½}rŸnŸ»q/*‘”dLWšt¦¾îNt5ìN/>(eÍ'ECt5 j©yT€­&˜ÿ™k¼ÿ!yú³âtz¤÷ÒÞíHÊÃ<s¥ƒ)W:XàAHcá`. Äçƒm©µE¶FÂA‡¨\_ï¹95qáîäãúiVp&ÿ ô÷æÒ¬hïÍL¿7öÞì«÷æj‘÷FR•¾Æ{sxo$›ŸÛ;dw™—…éD~‹¿;ÂbÞË£8„¼=ûìúûsnšÚûó8{ì›y.&œfÞØ}å2äåQ¼²_áå C+Íz|ƒ ¥©÷GQ*z˜%Ÿ·»iü†A'”gU:³aDÁŒ×làá!ë“-äbt¦¢¤'Dúʪ§à%á¢@sjÔ uãYÔýçLÎf@tx˜!b‚Ljx'b5E€¦~DTtel¹«1q~QÔÒñjX¥òµ&Ì™ãê¸=±'Åa‰ÃÁö Tl¿¿ùËÔá!(¿.D}}Ó¿0ZÆ?7†uœKšLø1uŠŒ,Í—åæ›³Ñª4k¤³ƒõS”À´l²~½×Ù‰/Cƒt'üJ;)͸×â‰3S1æUy@Xï®^«Z”žx“z NÕrÊâ82eI¾’ÅX ÌÜš‚ ÔÒ·Í?äå)ùÚÝ@Fˆ"x`¾L ´WÎüiûZPŸ°R²t¯ÙºO"ìªZâeL#¦ÖËÔ4eÿ•iœ^Θ<›w²¼´ÉÛ†›ow-ÙǽÇÇ )HÛ¨Wd_|…bõJLØv€"›à…Û¥ ’T)[0\޶‰ÇbÅÛc.ìËÍ’,¯æÄÞÔZ÷äq~O˜¨Ô|§y¯Ó‡±ø–8lyß ä„7ÁËjÇÔ¬’ y¾:m±­Ç-Fú¨eRrã[ãp«Ú„ÑÅðr9q$îNVYÕ)Û£N£%T&Hpò=4E‘›ïЗ¥q6BÃâf¤ ŒXš3Š&¦ Úâg5=ó1•4œçŠJpÚZww<è¼ ±VöélìõØø?3ìõ8˜V9'lx9acÚv{‹Ù®J©–:z|W|ö„ ŸmøøÚÝ{,!<~å„°ýH>(’í¹Ùà@ÇX]7Œ#l‰OØõ–œã ºÚ–fÞêV…aŽ?x,Âϰn• ’BnuùKõ UxʹOÙáøÐÓ¿V=ÚI¬Ää¾_l|;âØ{^¶Ø€ú`úyw¼±Ö [™Ÿ#†aCòD ’6Ã45ÌÖúŠl "[eE¶mÍÎÍ%¾q–°fÛ¶§äÙ(ÛÞc»Þ#»ÞÑîÉ}Xß®_{<.#_Þá<ÆzlzdVjl«¸È²ÄÙ÷îޜݞeC3I7é{OŽíÇÜn|þïî"uB"ëœ<Àܤiük‰›Õ2àíƒFêlö$…–äˆo-×L^‹tꜜ7Øjdµ ÍjW6m¿iPÔšñê©iPŒir!Q§4=Ò ªP·t vµËrË*b@~¼1e ŒISMv6Vß(…«L5€ilñöŽ×è–¾Œ±]ãÚ¬4Îp®ú€J9Göèòô,FØV˜V©OÖÓ«´l4×ê} ÿ ñAëÑ¢P‡Á†·E\±cô†‘lA…àϘÅ-j÷ˆÅ-"ÎfÇ êÀ`YŠ­`ƒ2Ýô›:âÎ!³ žŠy¦ I2Éõ±ÁéYFª4ÒºÈÖ‡eZ!.ƒÇ˦ñ`l…—®ÛÖ(ž  ªÜd.Â9“šâƒ9Ÿ±{­H).kDÿÂ~oI=ê&üÀÓ )¼™:…åò—‹×L2!'ëÁÙÆ©ñ¿ ‚ºaÄ ÚœUÖ¬nd+â¤I5œÛùè—nªjÛÞþ”ð§ÓxÝävͽFæ^Cý^ŽÔ¤Žx„'-{¼Ê÷³'Å'ÔPF ‹1ÛÑ0E´®h*¬T íe¢áÅmÚœÑ]µŠ o8þÇÝî\K!Çk§+.Þk;á€-/l¨ã÷ŸE}˜ŽTä™yüLxo?ðÚˆô‚‡üÓgÏ–¾)ȹË(§L¬ç¥úÒ]ãÈð†!÷ª,ãå\Oû CÓD¸Ù‰ø+ì""˜ÇU¦ÞI„`¼Ç÷W°‰ÉCÄuÀ)§@Œ?Xöüd•ƒú±s´Vmyòj¬ñÀ‹A(4¯Ä‰ãÀY0Zªá5IâwÓ„6äÉblÍDkœËŠLñ-jp2ÚðjüÅ-%­Ì¨\99£™à6ƒãk^ùÇ>2E êÇ|þ7à+«œ¿0¾›™CÑ¥{Þν0CçbG: ï—(—’¸µÿ&ùp‹ ÍðYÂ…ƒXK?;ÄùÐæ™ß~ƒ _‡ “],ŽEbq3ã•T1¡¨¢IϽb˜xŒš¥1j’+„H % |tЄϔ1¹íaj>Ú¥/t8«„­Û|äQuäŠD7ÍÜ“n j/‘•%"òh’G¸¹¨$±2ÜTˆ² sRzÏkÌÄu¯†H±†ý<¯¹ô\ÄѾLâ|‰~÷#ß-Ôn ùʼnql‚îÆ:퓘¬ÚÀ~þp±˜?L9ƒÛ8ì³;ÛÒN¥ ôpL_—Ñqâ*Oç(_¿UP?züìùìAÀm~W’€ÖEZu«ÿÑ[í–nAÜ‚m'fLS·íâröd§Šø$öˆ-e1¹…5ÞÌä#ÌgÂz¿Gè8¹E1â«Åéc ôz1úØ šTú›Ë}f–;¥{”ä(;&eB"î)Ñ~N‘9E*!rÚÎ!5nò|ƒ´RÜ÷è I•ª#îd¼Q,WÖqa=ËM%UñÞ'mWÖb&= –„[êßé Ü dš—ó÷Âì‰ïŸ>>ÿòF8‚ëÃÓ_ËP‰ßô“'Æ}ÐOžŸD_Ñ;ÞÒ½ãBœê¡í^³õ__àì®Ù;†׺/\û¾ðt†/\gFÅÒÉ)tËÆä*Ë´õ«_Ðà?]ÄÚµ>8i/í¿­ÙyGq̽y»>ÐíZák„énïz'K´¤ EìvÀ`w­Q2E‹N:3Z©‘¡:Yk´ÝÌÁf¶U:Ñp#§8Ã@¥ÖŠo›_7AÛ|Çw-ìñë×ï {|»€Žm­W²Õ¿ Ûê¡°ÕС¡'ö›c÷AŸ¬77i¯é´óaáFü¦¨ãNúîS^ª}zƒ?öT>i߬n¬‘ÌfÜJ¦m‹¥ãÞû8åÌ•E€Ú}"®ßzjefÅùë÷ÅßÅÓë¯dóS`ŒùÖ?Иëd#󯱻áùÂ5R$ñHv¯ÎÛý(íô_D öúæäfÂIÀ0*üdt,´³ÕŸz:§¤]pÊïÁðì¿:ó½H!c”9+Ÿz"}j¸QÄ.ºð¨a*IB‘ÝSÿ®`SìUÜ)¥î^AÍóPGS*³LMùé mÏäfY‘[õÙ:håª!åä³Lo+U4Ø?-Œu”8ZU‰£Uik¬J²hĩ׀,Z•á‚yÕHÆ®WÁ&~‡*v*[âðZÖ¨TfôßfC‚lZUñ»¹ÍkâÔÈ vi ÞAá4ZúGƒóRriM¨~áÙ@ö|5†*ß#á rã`¿‹naQr´¤?ÌÒ6ôËQº¹ Âý`è GÔP‚yW«RI3sVkS2gQe|&'nÔ.Ñ Žü·íaž¸õòK 5§Ìy›»¼]Ç[sÈ`0!ˆc‡4CGÌÎ 9òŒW%x+·IgéÔèS¼Ê(ÛI\;;7¹-,¸¸*ìziÙ„]G,gÑÇò¤z5€+θŸ3V­†Jú„°”÷¢´:äEPbNÊÁæ=ƒcÐúyñCˆ—Ò¨éi!÷Œÿ,500C:Tdem{´W¥ŽÑ‡@,Ös¢ŒE^’Üëö(HÅH`–É&ÏC iâ#ØÃš„+ˆʈÌhƱä Éˆ‚iŒ-”"7žW+»±rŸ(ãpKÛ’¨#fêÇDpHÕhg°æ‚À <è”R ÊŪ'qX©’ƒC{ê‡hö<ÿp \0Ð?C–ŒÆ[½kXúäùç”»ü1~\Ï6Ð÷—š|2Ö÷ͤ1ãï$Ír¶y.Õ½‘2߃šÒg/~p¯sþ²'E´{ó)JÜ?3ïåƵüâëâIÑ0%£i\b«v]jè”) /QG°.ý®$ðĘOœ÷'TG"eI[ë( ÓÔs§Ó_ÌÕé‹r·©IàTú #Çiû,ý 0ÄŸ¦§#mðòøÏÜ¥uXÈ2ìÈmô‘Ý©ç- +–º$ésUi1PóX=+g$tÀí´èâÜýž,xÜUzdâ u¤>ÙMmÇÂÇkpµ(¾fqŒhë:³xf€ÜÞäçùç\ì<›*åX–®…˜UyÁV«ƒº¸çµuqE²SZH?:)‹VťЛ$q—(†¸Ù5ëQIÜÀæ&‰û{:pšoàÛ»˜£L 1»³)’ö˜"i>óp6Òãh'œ)ˆv×1ÅG“À÷ްâ¶õJ ÷°…äI0qð­ž ~Ÿ°ÙHCäPu¼]EµN[ßuõ‹9†YLùKú9{\Žá H¶Æ‰8}LÊÍæ,N2ç>X·¯0'TârtZnIŽ0²q$¶”LÁ r+(eÿÔ¡³¬Ãë" x ÑÚê¶òvÊ2›rI» ÜúgÃüúsÎXH¢å—°[û1ªd«î´¾™uAUÖuâNëËpɹ) ËÈT(IÜkQÒ’cB´¬=Ž'6z)*¯]ëÀæ’ÉÑt:´£À…1‰gP<êQN:œðÞYì!çgv´}æÍØÃ X@¾Ø ŠºF ü6Ì»h¢—:pTNî1YA± ÎðDNÅ&IûÆp[eqöË+‘ö6üöP¬^«T_Ïô'\ h&¾ž¥ógNyªÁ†¦Ñ¹ »ÚàÙ­Èù±"D!Ч?V!õcQ†í.- û¢^ïb_dçÆp@A ­—Ò@M:Qt+ȱÐи™ÄºFôK·)®D ãå#üŽ’Ð¼ ÈÙƒþD’þÆêMŸRQ¢×€*£j~îÇw?–p-ë{â‚‹å i):r8ñ ê_ÖÄ.Y´Z¤ò˜^`J]ưçXœwlíäôWÅúõt&»½³‹_Ô2®}&n§i7‹¥V› G¢@s#QÉ"!Í^uOf‘Âö©ÁÂÔõ&ÕýÜOyù“ÄÛ ^ØÄØ`½yD¿òa=¯¡{:$Ô¶ùò—ï%ÿ‡ä¼4k²C,Š%þ€.KÁžÍ²&›2èÖ$hƦLF¡d(âñ¸\Ù^•³¤ª-?(”¨Î1‡¬²‡“}À%’¤†ƒÒ¡N}ÒzUïs.Òõ<1ä¡ …ò+«5—'¹?šE¤)­6¹Qmš&ã¹³ÖШ·è¯h ~n2·/3UˆpŠÒ ±þöS/QTy6Ç;¡rE‰ý«áQýWVè¿=À<üfÇp_ºò¹«(‘)+‡kó;°R+˶!XS¶ §¯@mÊjâ#òK¦4oè&±c]£.¶¯ù¾dãÔ½ˆ#DÖ¼âxt±¿#ÞÛ¾­Q¼zâÚ¸YgÞNxÛVÌK Ýýê~¸G}qMHE¢àlÉJÂåZ@Ðçhñ ‚YO`gFí,ƒxeëx½Ÿçï˜ýq¢~vPú^et9§G¯KÄQõ!ñƒaχPú}Eš—a(\ZÑdNZ0º-KŠ=t‘ ,\ÊB?¹aæ¢ë.‘XC3ª`s¾Hw`a¤½•vJŠ^Öb¦k$ôj~(z¬”è$׋–áÝÔ®–ÊW²¼±]CJ_o\ÓQ¥ôÝ£…Rú©M=Á÷ê)ñ°øû^e%ÙÄ)ò96D–ùww<ë' íE,tæ¦:sóÿã3÷Ê'ñ’«3ÿŽ_Hé•“~樠¸g;oH“ò¯Ò£§îåbG&—´ò¥èêÝ‚k8{Ýk@(¤9mHdO™Æ¥œO\ÊV‰ \Ž»i_¿Òõ,wçiú̽• …Ÿp˜Öú xÅ„æÇW„{*?zO= ÚYÔMþ¼Ÿ7á>úBáN¢44éKRqˆðýÔJ5ãÉ>©^ø5~áÑ…T¼(Y{hIblU)k¯®$­5/ˆ'JMÉ5Jh‡Ñ55âYkјԙ祕hZ-‚‹L+J75˜´+#ÁãÔ (YZ+RÎuÞ­vŽW7‰ ®ñâÂŒŸç—>y¸} ýàVX'âxô/#Э9棶Ÿ‘†ð¿n&ÚŸ“‰0‚l’ûwñT”Øõü3Èÿ»@öéÓ/ž{ªÄfNÚ)i€g¥œ ¨;˜oöêÍ7¼ox„(îDQu¢Õu¯—fž½Bš©ê†4 {¬AÌj<…üëÍó‰D…ÝÜÓ=éÓzÊ¢‰æ4;ð¬Óü®Çž\z4ÁAýÙ÷þ|êÏN)Î@ŸoØöøœo"cŸËºäP‰¦]G<Û=%?«ËÒîÉW"åÝ¥?´é¿#T‘–IäÑ׌Ý\ûê³çoD}6À\1S}Vc°XT~6 ?ÛUø£€j]íRtƒB´ªÎzÒ§³¤fÕ>zÙžæXY@øtJfv¡Œ)V^Wlvò 'dfõž-2«iÉy8½ÐaˆàÍ¢ÝB;Ð-¼~#ÝBwÿØ–Jçö¬ŽaA*£ãq:鑾êT 8'˜\A²Å¹¼v+xzíq^©¨­Ím&>»“ü óº‰ò5òõÏÐO|j|`žNõ Ij,>GùÍDñÝÅû‹oOõßë/~mþ¢»rbÓ¸—o‹0ø„}‹TuÏÅ·Þ³½Æã;^ãñëSG7¶&Üê ˜ž¸åXÉŒ²ÞínŠ7¬ïèÞ<¥å¾×é?êXvá>$/+ÝBÞç±N¤|Ö¨)îXÍŸÿžß0ÿª¡'Ρ„aBkûX²AbŸз7"Yqî`êxBëóâÃ5> ¦¹¤GF˜Ã7`ï`ÕäoO|_XÌÁ -ñwÏ¥j ’ ¯þWmg·Ë1#ù‹tïQv´-¾wg¥Ïò„tmqïÚ`Ëwãï‹nâO¼Ý'`Ð×mÆk_-3[)0ùX=9“bˤ{Ð#%DaÅ=^BþÌkåIoþòó€Ð.IÓpoꟼõ øïü÷ç®3‘ í\Ûó¶jßù†ø­¤k·5…²¶?yÍY¾ß3è„¡Ú¿Ù@¾)ž·¿|K;ÂÉooé)°Q„dþÅ@)`yŠ C‘R‡Hy¨hHC¥]ü½‹»FßxÏü&Ϲ€ ß“É(­×Ø£>­eéi¤©¹û^”[¢îÆ i÷í¨¬R´ Â™Ñ. ¾Æ§õâZŠ(Hå4{ô«&ƒ[ÚGô«¶„½OU•a#!WØ¡Wd±Ã(°-Ú—£u£#,Ä9oI‡wΉbâ-ñ7ßá¿Ù£…¹®ÍØÔFló*’q’ÿd²ç~€Ô(ßµ"! úäVOŧ·ÞŸZMÜvWCï4“+‰ØaZn¾ŒfS[丫±D¡ãí÷¨3>iý€9dg˜B0Jp ñk·„@þ¡ò÷÷±ŽfW¥º·)†¸ï[ÁËäÙHSé€yØ¿¾ñļ^û×4ÁG§»ý•ãÆ™±?ý¿=ˆÄþ=áÿŽ îtOcÿ$ØoÏ&ų €÷ýƶä¥"!ˆeñµeЖ:7i`&Ä-¨ );õ7Ê r%íd(H òö2w=Ž.‰‡3|r6ø à?Å]Àw=ú÷@ü¸ÃûÙÈ?ÎÆPhNãþzØæžÀýQ!ÙÑÄ5zr¿æ«¡ýN^ í§¸SÉ1ÇûÒÿ&a~§˜ßqK.’.©(JPÔ5¨Ÿv3!~Þ-„Âû¸oäü(oúm ëf1¾Ô%ʧFíR‡›{"WÅç7©4Ì‹©4W‰p¡åµ ¯êÑjÈy’$]RЕᒥ—%ªãm>Õí4ÍcP¼ÝÀm1°¹uðDl%LõR.˜ š'x¿œÇ>ÈÒ'/>ˆ4¨%"ώ޼<Ô3ÛX‰T‘¾˜ÜpoKy$¬¢B¦g/‘5Þ´òRÇ ¢{\NæåšÝx5N¹y¥¦èz–™ïÊc·R\¡I¶°C’ZÓÔªA‚¾FøCÊREêAÂï‚M'wwŸ9®ÖÄ;2^‰'Ò¥T+Â`!…Ð/õÒDµ`à áÄérôyÁ[¶¹‹|D PïY³T%‚"a¸¿“[¥¬³ããNKÆ÷ƒ¸S"íõЦ£BªÄ”úÀnh¸Ó2$Y$¬k4Kò@Òö<ê(äé8+·òÄß)&%ª‡á§›º.š„^j?»9ý0`S„8ýígôñ¦Eãoñ¦Dw¾.Œ&¹ÄÔùE.3W¢FR¡LKâMQû/(øðópºacôóÅâp·Iìé&°§ã ÿ|<rÈÍĦ3…,Õ¯VC”ú?D“jJI“8Ò#ã¿ÏÀ40£nó(Æ~4Gzüˆˆû,·˜eìM`§]äÕð¤‹éPkfŠ!õ_Õ™Úà:WÄÎ>ë…c¡Fÿ<ñkCF§ÃÓ$TTKaB`¢^p êt>Y\§“^+vtÝ{£ã5t:ßzÎñ _Ì ï.HqåWÓTvË—}¥Í©º·iê¼J¹1¤£7hMœ þ8Çóq1K±óuÄ•/÷|•Ήw|¦Äò4ï\Îhÿ"¨ÑÙ”¼¶ß-ê¾ÚÊœÛ I,³Hç¸Å'Ú¢5E%3Aª^Cµ••ZÚ¢i9¶àµptÅeíĦ…9ý3 ˆ.{á[Ç@ïÿcz?Ð~íV÷¥,W¸ZÁÁâ<ß’?8–_‰ç»DBï_;{¼Kì¶;ÌÙù –;gÂH«Ý‹PBÚ‰÷v7Íí=Ëôæ#ž·çp{Ìl&·wGƒ8ÃêÜbIÆÝár´T!˜G˜¬ÒW²W§ÌbJHì° ]ãÂ<4† ÓìéúõhÈuD¬„‘/]〴Ov•(Èx§} týâuúˆ}@Ôï`¶¨ß%‹ú<"ê7º¨'e¥^gid´àû¯ ãwe†èø‰@zÌŒl}UýNhüUýÎMOã»=[ÒJeÄ~÷ KÊ E¿0¦²kÉK[7‰xežŽß^eý¨ÙًѤø«I’u'$Éä&^KÍ÷Ö ÚtRƒl¿Eɉ³kìï)‘)–ÂWU$ó{¶&õàSU¼{ÿéò’‡ãÉ5cÔ’¢Íù ³Žl1r®„VR-Tv¬®‹Håý¡‘(Œ*$™S—K¾BˆZHJåÓœ`Q¢â«aZå«HUó´±½’¦!UÊyrI! RÚÙLˆGÉ¡~0OÅÇŸ'mî Òú‡¾n”Së! må‰Ö5B:c™GtÆÖŠªÉuÉÀ@¸þB<šH”[©Á“Á#³Å¢.i?š,cR,êÐÄ‚ô§SjQÏ?7'ò97ù]™•f9+µ0ŸŸ³µT\3ª¬Åˆ* L«üx/û L<:FuZ¢”¦TYëÒœ?d–²ÅTàVNúd4»LãùÆDšZžà,NÚ4GÆôX[_2ôí¤¾÷&ûsb2kz_óâ?Â#^çû— zj&DÜ¡G5@e.Î\$‡ÁQ¼v¦Y‘íÿ{y¦)žÅ',›5%°¡”gÞÏ&™6BYbb˯¦iË|•©;±çµÇp„žØ’¦ÙÖ*@O¨á&¬€¤ÐºJá‰È3!•²zk“CV’nb]­ŠŠÊ]‹£P’f‡[Øö$Ýä¹Z²Iç©¡ØYù@D¤ºùK/¾&ÂÐë|dt ,éµôMa ò,Rõ@ïßw>˜†ïßSÁº `Êaè®þ‰×¯ïóß9öuÙÕ§ÁÚª¢Ü¦v½Zä¯F/Ñ¥mýyýy@ÃŽ¦ûó´±ÓäMTBp\»é#B>ûôýïާdÍïÏ›ŸšóóâN¹)¯õ8úò»Æ¿êË·å¥|ÕFüÞ«¯Ý£¦Õšîû¦{µƒŽA²‚£\µ^¯Ñ.© g4ØÍ®$7œî­cŸFéŠw¨ãE`9µfÎßí¨ßFï š^£j³ÎoÓ8¿¹í÷Õ·e_ÝIöœˆli.ÜSoI1…A—¨ªõo†Û±·ë„¾ ë±[¬–¢wÖݬ¹r=»ÃTÊœê°ûjÄ v…5ôÜq—±ûJ9©Í5?B€ÈÕ½i•zUêlZ-­ÁÞ±Ç{I|-”ñj¼Þ`ß³=üçC–¹Á.—©›%ÁjôÐWìa‹Þ±V•êX2F½á®>[ÜYÛ´Ù uJ üvûÑüvû„ê³j¾O´Û²ÏÜxtÛ=Ì1uÝ'ú´ãG3z‡Üjv_vg±ýþ=Â݉á›nº²{‡6[É·Ãû¬„Éö9ùœ>™qNM¹¤<£©úg~>¯¿d¿:£S †×ЩÏ+yÓOÁd ³¦ŸÊ½¦7Ç—n÷œíÏœCà‹%ìÆR`Ok.…±©Ë$*Ȇ„éqY$B‘¹oJ­€ÓkgÍâþuE”ŒÃ­êÉW!J×ÃÌïƒÁò£Aà$Ïž°Ú¿@óÉÎШ,±=ΧÿoÌ¥ÿ”Õá«¿µÜ2ø=s¯ÈéϧÆãÏKÈÓþr׍Š—~d¤ŒŸß pVz¼±ñÓÈ­—ýÙ¢:”ML-:è{ Þ6ƒøß6ÿäjySÜCÂøEƒ*rîÛ¡î&ÙÐ0ñ?dÄQp&iÏ~‰W3DÁ¹WãÉa|MÜÝ”Ùÿû¦’¥µDÅxh~|ºEä$÷¤°ûüsÖòþ÷³Æ1\Åÿ¾×²æ$ÍèaëÇ$l›úf2øf6Eü™»´¢ñŒ­Œßoµ‡Ê62œm¸9ú¶:܈–ßšÿí½üŽüéÛ:„¿Qú?âô2Ñô‹|!î)!îIiúFIÓ×?$'Ò{Õs"‚1"C÷™ïÇœñâ|~jFqVY㯠ѹO÷xªÜ£%ƒèôœxm~:˜4~J¯gÅ¥6Ò÷§3í¾Gõ]z =ú™Ëoù¯G‘¯ý;Éä ¤†„­UE—ìÅÊìÄCÑJðþ€Ao€¨Žé 9Î,²\ ì°)"ºÓKi¯U…¡HÜ¡4lGf¿¬´ µWÍ’³€|,ž@‡]©öµ³•¥’’«¿‚a$VoDçó:ÒYôýS_º¯fç ]¦æé…uÃÖLYÅ×8{ðZx÷ªŸGvÿ#óc‘°ýTdC^«éD{®aR[Ù]V†œQñíÿÍi´xœ}ÏJÃ@Æ¿Mk­‹ ^ÄÃDPº¥I©`{ê©bÿP„ÒsÚ,mlI`Û‚OàY|ŸÂg|ôæl²­T¥!Éþvæ›ovÀ^ >×x²,PÀ—eûâÔrçâÁr‡âÕò2âÃrGÎJŸÇ®sÃU"»Ç»ÇÄÁ°À Þ,;8yËÜ ÏrgâÙòrâÝrâÓr§†BLcw ´˜#f9ÇC9Ö†J¢Äj“Ñq–x!à5ÆV™*‚‡2\\¡Î¬9:ãÏçŒJ´Ë¤Æh MtÑOÖw‘\‰N8gþµâÈ×óiX¤¶Š#êøZ‡£)ùQ@ñb¢ôœ¼²{U'­fÊŸ«€–Q 45»}jöÚ’ÜhŒáú..qoÿhDã¡ñr/ïùÅFRbÀš3JŽ •ÈA(éþµ­ñ·­­ÝR­‡*ûV’iÓ{Z¦F›Ç"Ó“£^UV¤wûP?ð™±Äá–Ê¿}ä¶ù­—Üz+¾¬„”xœc`fƒÿ )@Š‘ %² ÿÿxœc`d``àb19&FFÆf ÉabFÓÕ¤'Øe‰¶Ø¾TQAllure-0.9.5.0/GameDefinition/fonts/8x8x.fnt0000644000000000000000000000621307346545000016645 0ustar0000000000000000‹ Leon Marrick, 2005. Freeware. Share and enjoy!``,0ÿÿ † ~~†Ž–ž¦®¶¾ÆÎÖÞæîöþ&.6>FNV^fnv~†Ž–ž¦®¶¾ÆÎÖÞæîöþ&.6>FNV^fnv~†Ž–ž¦®¶¾ÆÎÖÞæîöþ&.6>FNV^fnv~†Ž–ž¦®¶¾ÆÎÖÞæîöþ&.6>FNV^fnv~†Ž–ž¦®¶¾ÆÎÖÞæîöþ    & . 6 > F N V ^ f n v ~ † Ž – ž ¦ ® ¶ ¾ Æ Î Ö Þ æ î ö þ     & . 6 > F N V ^ f n v ~ † Ž – ž ¦ ® ¶ ¾ Æ Î Ö Þ æ î ö þ     & . 6 > F N V ^ f n v ~ † Ž – ž ¦ ® ¶ ¾ Æ Î Ö Þ æ î ö þ     & . 6 > F N V ^ f n v ÿÿÿÿÿÿÿÿÛÿ·ý¿öß–ýU¯U»Uë€$H@ €@@<<8|||8 vªþ|ªT(~Õ«Õÿ«Õÿ~ÿZÛl(8(P 8lTl*"\zf(@@$$$((þ(þ((|Ð||D¤H$JD0Hh0JL6  l8Ö8l|< @@|‚‚’‚‚|0|B< <<  8D8Dšªœ@<$BB~BB|BB|BB|F:@@\bBB|<@@@<:FBB><@@\bBBB0< $@@DX`XD08ì’’’’\bBBBBB>\" >@<|< BBBF:DD((‚’’ªDD((DBBF:<| |`   2LUªUªUªUª"x x" 88V (T8T(D(|| $8X400ÿ  80@@08 (Tº|ºT( ¢ljŒ’l|º|l’ @D8F:<>F:<>F:(<>F:$<>F:<>F:~ ˜n<@@@<FNV^fnv~†Ž–ž¦®¶¾ÆÎÖÞæîöþ&.6>FNV^fnv~†Ž–ž¦®¶¾ÆÎÖÞæîöþ&.6>FNV^fnv~†Ž–ž¦®¶¾ÆÎÖÞæîöþ&.6>FNV^fnv~†Ž–ž¦®¶¾ÆÎÖÞæîöþ    & . 6 > F N V ^ f n v ~ † Ž – ž ¦ ® ¶ ¾ Æ Î Ö Þ æ î ö þ     & . 6 > F N V ^ f n v ~ † Ž – ž ¦ ® ¶ ¾ Æ Î Ö Þ æ î ö þ     & . 6 > F N V ^ f n v ~ † Ž – ž ¦ ® ¶ ¾ Æ Î Ö Þ æ î ö þ     & . 6 > F N V ^ f n v ÿÿÿÿÿÿÿÿÛÿ·ý¿öß–ýU¯U»Uë€$H@ €@@<<8|||8 vªþ|ªT(~Õ«Õÿ«Õÿ~ÿZÛl(8(P 8lTl*"\zf(@@<<$$$llþlþll|Ð||f¬Ø6jÌ8l8vÌÌv000  l8Ö8l~< 0`À€|ÆÆÖÆÆ|8<f< 0`0 <<0  0F>``|fff|>```>>fff>ff><``lvfff8<  L8``flxlf8<ÆîþÖÆlvfffff>\2000>p<|<fffn6ÆÆl8ÆÖþîÆÌx0xÌfff><~ 0~ p `0000`2ZLUªUªUªUª8dø`ød820ü0x¶@$Z<XØþØØÞ|ÀÀÀ|~`x`~~`x`~~`x`~$~`x`~<<<<<<$<<øÌFöFÌø(æöÞÎÆ<``|f|``$ff><8X8xbAllure-0.9.5.0/GameDefinition/fonts/Fix15Mono-Bold.woff0000644000000000000000000030657407346545000020620 0ustar0000000000000000wOFF|ßèÎDSIGlhFFTM`€Ñ GDEFlp¸ôq–w;GPOSutì;¢È'¨GSUBm(LL@F„OS/2$X`˜búUcmap\ Ž.\ÅHcvt ¼rr?æfpgmt±e´/§gaspl`glyf)´?yI<ºqhead¨66"_hheaà!$éhmtx|Ý<-9ëÆloca0„@˜@maxp L“namei0¥ô^ÖÏpostlL þð2prep(”Ó×âI4¼"£›Ì_<õèÒaêØgH­ÿþ Txœc`d``^þï;ký‰¿‹YC€"È€õ< ? Ïà[TZxœc`fºÎ´‡•©‹)‚ÁB3Æ11ÚE¹98A’ , LíL Œ PàââÄ ÀÀûÿ?óòߘ—3r&00ÌÉ1 3mR ,„í>xœ˜ytÕÅÇïÌ<–° (% Y_äe#Hòò@e_„z¤Ô¶p\Ђ¶ZÛ£(²–¥ Rl ˆ† «"mmE(dQp=*tú™ÉÓZmÏéßsg~¿ßܹûÜùé­R!«D ETЍ¯%Ÿñ ú~I1$Ãô‘¾*SòÔIé’ô$W/”"5Uú#a5VŠŒH‚)”"}—$ëW$C4ýœdëW¡ãùcÐפ>&9êF鯦H~J õ‹R¦×I–-I&I‚f”¤ëãRfºHHÄ»`)óÖÌ3-ýàÔ–ñZž÷gþ4›÷ï@»A롱ð9Åwg¥¿™,)ú’dšxI5¿E§V’«ÖI…Q’¨j$Ý$ÛÜ*åjdê¿°þ%x¯‚Ãã<«ya¿bIÔo3¾OÒL#)ÕO€ƒ|û¢„õhz=‹ ~˺*)6m%UŸcüß;¹žÂ–‡!I* ièïmŸ…î|½ûÃ&_J/ÕUJô ž“f6ûä¡g!ö¨K˜g¹j+ãÈ9NJÔÓv™zÏV©EðZ-ú¾K‘bu·d«ŸÙÑz¾äè“ÒÇl”8³\ºš¬"Ùü_‘…Oœ/þ$Æ£T‘ãñ3ðK‰1W ï'Ȳzô³sLmŠí}¶¿’}ÏÊ€ïÂÜ'7éÓØñ})5%輇o^{¿ ›ræ« eØ|oo€Dôpä¸Þ^Ò?­I_]-ñ&Œ}|c›Ã2åJdó¨FÿŽø„øsÔŒ”)nO§³ßwëˆÓÛ¯F&ºú½¹þ=–JúÔ—£vr2~Ÿº8ÞÇûʆ9ñ<=’~@Ûzš‚>1Á4õr¤éIÞÞZ’fúztÃÜÑQÄ£‹Iç‹ èWÈõ2qòÄëö4±C,%c‡R]ck‰Ù½]ÚGIäO»$ég$@þ$éOÙç7àS¿wOý…ëZb×ÍWI}wäš‹wçcgÛoi¶AÞ¦›6Øn({^•Òœ<Í5Mä?_)Í©']'í=Ý uù° ûGçÄC&²e£…ø©94C?€oÏzâ<­ŠÒJ‰EÏþ~þ1óg˜ŸGæ•à¢LâÝxcÞ¿Ž¶D†jiâéêS}-þȔۉ±»ˆÓ!Ø>ÿFÈÃð(¢6w9¯"ä^3;Zµ‚æaëäûÜkD],j5q$q›Ëš)$ûù<ä;k©-v­6Ô×<ž³ï«yv–N°×}á—¯Vz›êÄšt)SwÛ©ø¼Ô|ßà§@žqà.ìÛ˜½?$¯gØÇU 5î=dØE®41è—­Ç#ÃMÒG}`óÉ¥tÕ=§ã‡ñöU5×nÔ§m–éh3ô64‡mžyÔfšT›ÅÚD|—ŽÍËt ¾z/“ˆ‰ß!öv99ŒšßLÊÍ@|L}ù„o].·ôß $"úò”côVÆg¥œµÉ¦ƒ·I…¡.b«b-Ó×üíè°R£CΕTïƒ8jP ñ<޼^¦7a?òÝR‘k >#fšÜ€Ê8ë&Ró#ÄD9ë#ÔÃ|ö˜émºÂÿ ïÎÈ@ÖEL^©Ô›Cþ|Í¡D8ç‚ø*?æ˜éÈšMä›zÞ}†î_°®hÉÞÃyvŽñ•ÈÓÔËÔå›ðªÅ6?ç|ºšý©{ô}/“ cÏxö SW2ðMqfîr1ŒoÒ©™í¨NÇTäÊÓŸcãã¼Û(ùØ?l‚Œ`çzè °•ñeâð5dSÇÞb¾ûM¶‡á™ƒ?Ò¨8;ëk©á®Þ„©«¥ì{¶IàYº“Ã4G÷z¹–3)x šIèXƒ}úÂócd ¡g2ßugÜ\Í|¼þÌûç=ßÄp˜¸‚Ì™Ø(™ÚšjvÈÓæyy޵¹ø4›FˆÙ°þûlö9ìòËå]DßÂó<[A\b¾~M8³›‡]ˆå·‘+ßû L]è¼o¾çÙ«£‰,ï/ä þFȇ0=O„| “¯!ìògúà(û×¢Ç2Îôdí¯¥—§·±G 2œ„ï)ôh‹]ÎáË×é|r¾Ëáë}Ÿõ uqŠ='âïÛè_\ SW3Èý ŸìFÎuÉÉ’«×_%Rèãà^Î?¿Á>޾ -“›Íj¹Ë‹½¼EæÓ¬‰%¯ÞC®è^Øt$¾ÌCï ï{¹G¯DO7 SküAüá—ÛÎ?Çб=¾Þj/ë7¸py„¿¥Äè`êHºë5éuÂøs*{ÜLÿ‘ ÿ$3 ׂdöýœƒÿNìÛÙSøËÅN†³3ü‚ø4ˆ/#|SFn rè3S‘/ =²‰‰â-ûd S˜ Ò—DÌ/ø>@gñ¾;¾ØîëÒXôŠÖ…ÉÑ ÆAjZÄd0wqpÜÇOÄå·™ˆ-‚à*xôDÆ <:€dÖ5gOÎMb~‚??ÏÊxÖOÂ_üùy+ö£nƒ~QúC µûÁn³Ùn0ÏÛ:ó0tô÷v™c7 gWû^Òc¶‹>ocÍ›öYPgöA÷Ù:r ›?#ž+ÀðXÛðÌÄØ8Óu—ùþ2ëê¡õ¶.ÐØî û=L|Ϥï›}g5Ðyà1°l±qzƒí̸Ñ,BֵеÐÈ[ËúýøìMßÿ7à`5-mÄ´µ½Æn`¯:s’5§—3…xkí íJmj Q˜{lq —5À8duçOSìÛ@ˆ+ìÓÉ&Zð}Kö9Á>'¡‡‘ï-Æ×csаé>iClt%WºQ_RîäOƒ¼‰ÈµIº›©Q¾nMÀûñ?a¢ü†áÇaÞuøq=~¬3³Áö˾%²“sz¹¹‹š»ËÜ*ÀPÿl§ij»˜+m's‰o_.B¿ã—ÿKïŽ6þê­£r@ çr ‹d2Lño—ƒÍœåST^ãú#C®ÅƒÁľӡBv;êci˜¼¨?±!ß%Øï‘Ê5š5ê2k:K.žfQfbW‡E>®29_šÓ‹·ÒÛYO_¥›sßúš\îÀ÷.&¶ÈÕÐ"môÖÛèA6òœ9}ÒO=fÛß‹u³±ÔÑ\ÅÒÛ£5uîÛÜ!ÏZ#ßÛ‡¾;„ ©#Ô½R-%ôÍ}ÞÁä‘ûåà1!·wÄLôÉô}h?}'zÝ Íöã¾èR¤§&½Iss>}ìΞáÔÝZÖ±+è+ת:»T¶«ÕL;[}fŸQG¹sþÊNSKìïÕJî ½í  —Ú(¥~Í;Q­±T§ì*æUÜS—¨ã¶ZUÂçœ]§ÞµOúõ‹í<õˆ}DeÙq*Óörÿ tgrp»\CÑ—úZÄ}2~½Ü  f•r¿ÞG¼ï•.æήÝô°/ÉõæÏÜû×sŽm1æ-éaÞ‘|7Ѽ.ó8¯S©gîÎ4÷ó#$#ðóÁ<¯ Oÿ 0XŠÝé=¾ø@WlRÏyrÌõj;ðërü»Ò º›J±×¯a}?úŠGéqÞ Fo"~ÆÒ‹Uù{I¾ÈûrÆËèñID½ ï½ Ì“H£û¤Œq0 ‘«ZJ¸›—É»R¡¤?M:ë¡` HÁAζ¡øi{´ç|Šãùèbh;žÇñ|~] M€G˜ŒÙãéô©CÀpÆ.'Rá9z ¾¦1†£SÁ4úÆiØë^èUäÚðI<½g*t óeÐ?2¯‚>ÊwA—ѳ¹ù$Λ)ð˜½ú‡è+BœõEÀõ$Eœw!ÿ¾‡7ÌÝØÙc2ö8)åênÆë¸ï<ÜÁ¨=&€tô‹ÞãÑ1#j‹jhϪyžÊša`Œ·i!ãlÆô=.¾ ɳb³8ù½o¾ä| pwp}ä þ?V_ÝIJä¼å΢»ãÏû¢ôb“½Ô¬¯f>Ÿ?ÎÙ[Í=h%}ÿ\ä8ÝϱÞáCdq¨£AK|¾LÈ+ï4Ìé=ËÍxbë}Æð‘ã<ßD>;¼Àù~„µ°Í5¼/Ž>;@¬µ¬½܈ž‚ ×—g¸_›¯çÙG¼!°ýC÷,î‰Q¼ˆ.Ò{ŒÂFŸ1^ê냇6ªa¬²ž=ÌBú•ùð~ˆšò䩞æšÑøs Häî“ÀwI®×/÷E)p¼gEÇŒéG ¿ ú¢z8ù ‰ËlÝ _íÄGµäßzpžyžôVõÔéÉ­/ñºpOH0G%1@ŸØO½~êú´Ïùî‚dú¢3%ß×ÑXzËOY—mgø»W ò£ÂÖ»Aø­‡ÿÏT'íéM#K‘¾•šµƒ=žçŽºº“sÂý­B.÷t?ñø66hŠMŽPn£Ö®…¾=B¯ÅfOGôÝÈ–¯Ú?©ŸJšZÇóã¼?Ìù°zŒšúdR—×ðM¥û‡« ¨g¿áÝ!»,T먱5ÔæSö¸Ueï/ûdÙ1 Õ,•¹þ|ÐÈÛÈîâܘàïïH¬šcç«ùö×ß=Wôà¶¾_:êÎv7ãþäOñ|µ:ŽÙ›¼)5ke‘ZE®.AéȽ„ÚîjüT;•úØÍôç¾ô°ý˜;t ½Î^¢F¨¡ ©ŸWè§è£ª¤-½Z ž·Õ×Ù½ÔÓNðN 'ºÐ íYÎÉVÎÖÔßûõr{™8HÖ3Dé¢9ÓZq¦õðÿTº¡s%=q'r¨‚ü¸ù3žL®àý Æý‘uyE]×îÙPÖpU=‰D :ª›k¥ô_¹+E+xœå–‹sTWÇ¿wϹ!0@„{ÎÞõÜ@ÓE&¼SBcðBÊ£¼:Ô`;E˜B©[‘¢•bÑ)â±(E”ŽíÐ0LgP(­²ÉÞ…Ž-#³°wýîž ãŒ3þfæ“ï7;Ù»÷ûûýÎï.€ ÷I{º6ñU'÷º@Aîu)þ¿/c3ò°=°ÉÙäìt2‘‘Ñ‘æÈ±ÈÉÈ©È!E¾è. EQ&F‰*Q-Ö‰çÄV±Mìír½;,º%Ú¡ŠÕ U­¦©yj¾jP ÕFuXPgÔꊺ¦B¯»éb]ª£ÚÓ¾®+õd]«õv}@ÔÍúx¬(Ö7æÅ†ÆÇvÇ>ò"^¡×Û+öJ½¨7Ä+÷j¼Ç½ÞÛñH¼g</Ÿ6¬1ûÌAsÈ4›cæ„9iÞ1gÌysÑ|lnúÚëOô«ü%þ2¥¿ºloy—6q'f2¦îטön¤„i2m Ó¾' òDÓ _ŒÌ¥mDÓnûÄ'rktsôª‚*QZÕ¨i«ÍêˆjQïª êªº¡»0moÝOÔ:—¶¢3íÓ¹´Gÿ#m}lGìR.m/¦í/íoygZ÷siaº›µfÿ½´-æ”9mΙ÷͇æ ÓVÞK»Â_Å´nî8Ù´™ë™ óVæ`fJfh¦(ܾ¾¾®ç…sÃ9a}8#œŽËB“¾“¾¾ž¾–îH_M§ÒgSM©’T÷TA*?•—’)‘Фœ‚0HwƒOƒÛÁÍàFð¯àrp)¸¤‚ h Î Z‚7ƒ=ÁîàÙ`C°6øJP”=‚H²5ùzrirjrBr|rl²"9*y²ûïY]£ÿ'õ sÏè.„}שÝ,â&µ7ÉæºEíGJé9/z ‰æ-Ð̨™U²ÑÚ·HöY·Èìµ+H%=?CO¶HÖM×Zdö3-’5ÔOöFrŽõ‹d õA‹BåLjΤ¼zÜ"ù¼‹YäÔ¾9”êY${j‘¼¿X=a]åƒÔd7ýxê%ò=ûæE,’ýó -’}ôzÖHN§[$gÞëOX+9‹µHöÚb‘s¨å9—Zc‘œ o yœþQêrÂÙ— ¨o[$ç$±HÎG¼§ErNâìE¹HÏž™ÉÇôq*ç×p]æñµÅe¿|Δ?–~u¢Ååžð«,.÷…¿Äâr—ùË,îCTæ÷™ÛålúÌìsg¸c€²½wPÎlåÌárÚX«6ÖÊåμÃgÌÖßåÙ3÷8=sÀ­A^¤ »ü×óÈÉmftnèÿõcß)xÌ\~;ë‚|tå·¶nÜù=ð¢'z¡7ŠÐÅè‹~(A”bb¢\J1xˆã³l´2 Æ܇r~û{C1 Ãñ FàsøOˆ”™5‰¢4;;³sΙ3KÊ‘ªwi½ç©sHánƒf›~'¤ÚE€ÒõFFÚÁ#-63zåº}¿Áf4åN@yÏ[ÊCFÓN í¹2?ƒá>ÿË<ƒ–fšžZg!=„À|3nið5£YwýA_±:\ †ÓTÜõÇTÊÿ–æ\m¶63šwp!"?˜hj­@ÓŸ:¤z>Žb rùl¬ &¦¬?ÉDpa2]ÕT-3¾vpŸì,:ؤJsà°Už‚‡ã£ …ô-‰2KC„ƒØ*1BÄ$‡BN9w²?)P>’„1o’Òθa­qä50¨ÍÓ¾ÌfSÛ[‡0~GðÝ/Æ’>²¡6F„ØŽX `‘QU¾¡Æs/‹¹Ôþ3%`yúí_'­;6/emcŒ‚žß6ßùeÅݪ\çE¡»wU5T锿C/gßãO…á ±àÍç}£@í ‹ šÁÞÞÿÑZuÄUÞ Ùo5³±xœÛÁø¿uc/ƒ÷Ž€ˆŒŒ}‘ÝØ´#7Dzo 2"e7°iÇD0l`UpÝÀ¬í²]Áuk/“6˜Ãä°‹A9 ™b‡q'T=P”Ó“I{#³[Ë äò(ù\@.7œË«àº‹³þ?\„¨€7 Îårùlà\ —ŸÆÜ ¢ *<éÿ"µöuPqzžP‹–ž¤¨ð°²«nj¸¶†˜Ô´wމ|’Þ定sVƒœ¢”bS\`'%-075=+xœ]ÖytÖå•ðç÷J+VT¤´bÅ"ÈVED…!! jö= ¡,&‘I@¡$ VP¤(èhEEEBe•jØZFaЦ#‹‚-**:óátþ2çÜó¾ù=÷Þïrïï=Ogþ¢¸Åæb½C8«}müÿ“º~ºPx~v;‘% ¡mg1I,ûC8GîÏ: yç–„Ðnðü¼!œ¿Hì áÿ·—a¡ï…+Å¡:èÛÁgGŸõüE_¡Ï/û 9árѧ!t‚Ýi[Ç‹%bO¿šÂ%p/YBg¼;ŸáRx¿ž*ZCè2JÈír2„ËÒÄŽº¦ŠâtÝò.ÝÔwÓûòµ!tÇ¡»üëC詯Ž!ôÖã7— ¼úLr¯ ¹/-}ùÓv?®Ä÷ªq!ôWÓÆÕ´\]-pàû:®q>°H¨»¶VœøW\§ïõ|½þXƒø5æ`Ÿ7t¾ÇñýÆ5! (ð‚ëÐCˆç[¼ï t%è›@{‚Þ‰ô&қĿ$¾'©Mv–|*„a<fFÃèOÑ/…O)x¥ð"VŠÜ‡7…*'U]ê™ï8¤¶Þ¦Ò2ÂÐk}#ðÉ‘4ŒÔs¤ž#õ û&¾Üdn’w“¼QòFÉçf87Û›y~ -·Ð{ oo1ï[Õ¤ÁLƒ™3 f:Ìt˜éö#ætû–AwŸ3è΀•¡.V¬Ì9!dឥO–>Yúdé“­O¶yfó8›ÿ9m…çð%×<óÔä©ÉS“§&OM¾š|Øù°óaçÃÎ7Ã|¹p h-0‹‚íÂl x]ÈÿBEþ/ò±ÿ‹õ/¶Çż-æm±úbXŰƘÁ3Û»X «V)¬RX¥ö»Ô¾–â^æs,¼±ðÆÙ¯q4—Ó\Áß þV˜C…9Tè]¡wtŒ§c<ãõ¯÷x½'ð~ï&ðn‚>ô™¨ÏD}&êó;ù¿ãS¥^•zUêU©Ša’³IzýÞì&Ó3™žÉò&Ë›,o²¼)ò¦È›"o Ì)0§š×4z§Ñ;ÞÛøQEGU²0Ó*xÕÞÃj{\íýªöÎÖx·jäÔÈ©‘Scî5úÔà~;ìéM÷~L÷þMW;]ítµÓÕÖª­U[«¶Vm­Ú8ÍÀiN3pšÁã<žÁÛ<žav3íãL}gê;S¿™xÍÒk–΂3Ëlëè¨óYooëÍ£fÍ Ÿ/óéh”ߨg£çö´QN#ÌF<qn´—Mö²‰MΛàÝå=¸ËLî²wãp·œêðg_˜ëµ ñ]èûBßïÁï:î±?Äï^ó¼WÍ"^-òl ‹i\l§ã¼Øn.ö±×ûÌå~8÷ã¶Äþ< ~)ÎKyõ'–9_ãAÏTó ñg¹¼åž¯ õa\¶kÐñˆyÿ¯Õû1Xͼn6çf>5ãÙLG3ã°ÒŒVÑ¿ŠÞUø¯âñâI}WÓý”çO«{Ú.<£fÜ5x®ñ¬ù?gÏÓô¼½XË‹ut¯£{Œu´¬“»ÎÖy^€÷‚Ý{ÑÙz<ÖÓ÷o^¦åeó{çWä¾B_‹¾-ø·ÐÖb¿[ä¼êÙk~§^ƒó­ìØÚ6Øå vf#7šÝFßÿŒëëü~ÝÞmÒg3Þ›oö¾máã>nQ·UÎVœ·â¼¯­8¿áÙfo¶á»o:{“þ·œ½ ÿm\·óþµï˜ë»8¾Ë‹÷ôÛ¡vì¿ø|ßìßÇý3i•ÛʧVÜZÕìô|—ß]ôîâånßw;ßëöÂÜ‹Ï^3ø«gUó7Ü÷ѰgÿŽó‡Þ£Íê#{ûŸ?²×ûñØÏ«¸àõž€y@íÐ|_õ8h_êq·ƒô|ŸOhû„¯ÿ©ÇÉ=dî‡ìßÛ¿ÓòwïÌÿ˜Û§žÆÿz~”†£æ{ÔùQ>Õãücjùÿ˜9®÷q}NøüBÍxÿƒOÿäÓIû}Ò÷“ò¾¤å+º¾¢ñk}OÁù—oyÿYžVšÖïÕýp&ìÝÿ®Q¸L<¢(Yì Q¬Høµþïób½.>¢_áwI¼ð¼sšø4D—êùë¼ué+âD–ßežßŸ..]à^æ{WgîoQWZºêÕ7w¹¨.ÝÖ†èòTQ"pºÿËW‹Í‚Ý—„¨Ozàß·+…ž=ôï¡Ï6‚ÆžÅ(1NàØ×^¸õ­üÞÎ~Ó>D}äöqv¯ø8D}å÷Õ»Ÿÿ¯Äá*ùýÍ¢?ì«=û}šÓ@¼òêZÜ®3‹ë=ÔVðp0N¿Uƒü8þÆÑz㜠Ñ(=C[Äv¡ïPøñ0Ì#‘‡I0“a S;ÌYŠïÃy3ÜÜSõL…9’†Q°nÆß]+º•ÿîZÑ­|¸•i|Hs–Ƈ4ZÓà¦ñ!if’¦Wžiz¥›u:Žéú¤Ó–?Ý¥ó6]Ït=ÓõÌÐ3CÏ =3ôÌÐ3CÏ =3ôÌÐ3ƒ‡f™ÙIÈË”—)/S^¦¼Ly™ò2agÂ΂;Ë^eÑ›eæYò²ìA–ÝÈâq–~ÙôgÓ˜mÙò²ù•mþÙ8fãèeë—c¦9òrìPܸ9úåÀÍ›7G^.Ü\¸¹psõË…›+/W^®¼\y¹òòäåÉËãMoòxã^åÁÍ3÷<¸y'B”oùæŸï]Ë÷nä›Y¾yç{Oóiɧ%ß, xX ¯@¿ïM½)ЯÀ;_`' Z…¼B»PÈÃÂþ‚–Bs/ıÐûPh íN¡¼"¸E½…œ"˜Ez9/r^ä¼ÿb=ŠqrOŠÕãSl¦ÅÞéÑæ9š£y5ZíhúGã0š¦1¼c†cðt§Æà8†7cô-[·n ܵ%pKà–8/u^ê¼ÔüKá–ò¶”¾R¾–ÑVF[^ex•©/S_¦™þegrx?÷±¼Ë«±òÆâ8–ïãÔ–ëQî¬÷rÏËñ+W_£ÿr*äTÈ­p^Aóx³ï½ï·gåN”[Ic%ž•ò*õ©ÄµÒO²G“Î|òé÷¼˜l÷¦˜ÁN¡uŠùO3ïi¸M£ašyO3ïi°nóì6VÑà>¹GUúWé_¿ÊïA•¨²ßUö»Ú~Wó£zêBn5O«ùQcwÜ™£ø5<º¿·Ó1ÿéÞZŸµæê>¹ûF³ìë,|Ýo£Y0êxUçY®îºQ>uü¬ãC.î¾Qœz³«·õøÔÓRo&õö¼Þo€ûpÔ€kìsi ³®8 ÞG÷㨶œpœ×ßAËðæÊ§öòçãÕèÿF3iÄ£N#?šèl2Û&Z›œ79orÞä¼éÌ9-wÑq7¼»Íy!òþòîU{¯ç‹Ìk¼ÅøÝçü>üïÇk‰x—hYêl)–Ê[ª¿{jô'\—y¾ÌùC΂·Ün,·ËéYAû ù+xõ0nÛGøý=Á|̳fõÍj›Í¦YÍãð÷ó8/]¢•¸¯„·Ò^­òþ¬âÃ*xO˜Ïpž éI{õ$î¯Ñjs]m¯žRûœ§ìÕÓz<ë3¸=£ï¼Ö8sŸžõÛø,½ÏÁ|Îçóæô¼¹¬Ås-îkét¿Ö™ù <~Á®¼ˆû‹ðÖ›ýzþ¬·G/éý’9¾lÜm£Wð{EM }-t½j^Åõ5¾o0¯ 泑þøýÙ<^×ëux›ôÞ¤f›èÙì÷o³ß³Í<ØÂ›-xoÁi+¾[á½ç œ¶Ñ´Mý6>½©ï›jß’óì·Õ¼ g;®ïèñŽßwÍÞý5zÏî¾çsw˜ß_xú¾ú÷ñûÏÎ|ªmÅ£•ÆV³j5«V}w굓_;õßÉ×ôí’· î.þì²Ï»Ìj·g»Í`7ÜÝžíÖoÞ{øºGÞ{±Ç³½òöÒ¾—Gšã!|óå0n‡ùwÏÃæx÷#fq„Þ#þwŽÚ£æ~¯cfwLíg¼üLÎgæà.}ŽÃ縎çq¾—sœÏÇõp¥ŒNÀ9ãüþïøþOÜNês’ÿ_:ÿRîW¸|-ÿk¾–sŠÞSò¿áÍ7°¾åé·~?¿¥õ;:¾ƒù^§ùuZÓêOóõ{œ¾Wó½½ûîôp¯¹×ÆÂÊ‹z‹!k ±³æ„X›Ô;»cˆµ]bç¬ ±s…X»¸;oœø4ÄÎßbÈqwµ/ ± ;‹©bsˆuP×Á³NóB¬ó¾»t[ˆõ€ÕSß^%ÿŠ>ÿ?F =ûèÓVŸ5B~ýûœ ±+Ú‰îv_ßûêÑOÿ~‡Ø•µ!výa÷×ój}Èp:Ä®;°H<b×ö´]§öú¬sŒ ‚;Øç`xƒqþm{ã zÄù?NÍýE²Èž Y/¶ ý‡ ±¡Aà3îP ¥yh«8$N…X<ŒøN‚¿ñ4ÄÃÇ+~’À'~ÉÂ,âaÄó ~Ð'ž mœ8 |KÀ)V‚Ù$Ò—/hKœ ø’Ø$–‰ÕÂLqNÄ9ÑìñJÂ+ ¯$¼’ðNâc$³HZ(ø‘ÄŸ¤b‡ ?‰æ$þ&›E2ß“Õ$ã‘Ìçd\‡é;l‘ !Ån¥ð3…Άû8.©wöì™™d&!Ë„™L&I!„!„°/¢ ˆ ‹²‰Š¨¸ï¢‚[w­Õ{'C[-"u­]­mikûÚömk›öõg­mÕ*“ÿ9ç¹3™¨}ß·¿ßçóI&O.÷>ÏyÎsÎ÷¬WÐ ssˆ{´¥‚F0ÕBp\…XV«lÚ¹.–­áŸÊcY }Ê”[Ì #By•©A6IJŒ™\“…ÓY­YÃÅZ§âc Y‰~ ûBö†lÄ,,†_IN¥~e§_eJíx¯R#ÜËîTôð ‘ßAW}ZÊjè³2‰5(’Oreýášh]?-G$Ù™”òÉ¥ØÜétËd·ÔÔÝAwk["îóèÌ£E’©.–l ‡à£«µ ÇCsÅ&g®”ÉÎ\÷вÐPksŸÎáqèÚ¦ W4•¸g{*=žÊܺ=ÿ¼¶Uç<óU·§ûü)†&‹ÍfY¤ ÖÏ´Ûr#UO•WQè{Wø‹x(g²£`…•5PÅSkqEç•Mñ³Ž‹eT¶Ä³eT±ÁâÌÉ5¢ÑDX› 5’K6ÚÚÔ)kšpGÛœÖÖ9-y.«™›LÎMНäæ4‡©ìûìEñmÚ¿.¶DY­Q0…8“1Ys:+Z' ˆNÅDÖÓOŠ žm†L›N @DxþúPù®×qíßÎý‘r¤çœÍ5B™P%2%°VÙ“ËbŠË—H(‚nTq–Çã²&¦Ø+a@kUŒÖx<£ÕÀwkõ°Çf˜OuL.=­0]<®øp þ¿S©2yãY§CðÁÌ,nu:R-&W&” ÌÕ_ ”ѧå I6ðù¦ÂÑD*a ¿þ0ý §ào2\ ¿;¹Q³Ü½•Ô}WóŒf‰û†?}Cü.{f1s|W÷=VùÛ½Â{»ûQøo÷oa‰BÃØjqP³L(Bp2¥¸RBÑèFåpʧR ‹óZG‰Ó+ °H–V¼µ°1;lŒ¢Áu iÙ!}•é]ÞÊj:ðkCE:-[%ÙÜ2ùüÉfÖÚ–J&¼>¿!õVÂ!0xÃ0êòÀ/õî¶dk$Ú00sÁ«7Ÿµà¶…ó’koX¿õà‚¾‹.ó×Vl=+Ú6Y§þõšsŽœo>|§yæ‚FÝÓá5Oî¶¾]×*Š­Aé].`ï­šäžÐ ±±?ˆ_#þwg„…—…LÐK©Òf4@Ù”PÜúÑlØ_f²5(aøè0ÐG‡~”É51™ÎÚ8sÚœŠÌ©ã?霊~ªà?U8‘²%œq‘^6&¹2¢Á˜H’lIË:—¢Ñ§ÓJ…Hã+ƒñ $›Òr‰+ã7—¦‘’Ue@IcZK#ž@‰Ȩ¸pø­Ž!M5¼¼°p3?=¾x[k$”kSŽ-¹máÂ; ìÒ+r«{=q—”üÁÂç.|¾ª|nYÙ<ö››–,¾iqîRñùð™éâ¦ùu‘Eá3oÞ´dÑÍ‹^¬‹,¬Á3•û?âÇâ«B…P+U)ÔfLÈXÃhÖSƒ´’}‰¬Ç DQÎFPÎ*Up.HDºè¼ÈUN%4 ØG32bÀkjP¢0T¥ƒ‹iÙ%Éei9äÊ8J«‘dI±Y‘$A$I -×HÈb ¡˜FV“miÙä’­@ŽTk*I¶¥ÚRqd,§_"è KvVÝÌ ©d8”|òjV9ýw5X9µgéLÖ7·þŠÜ_¯šöÔÒGÖýò½µÚªÝ±È0«i˜ÓÔ0XŸû(29µö²óºÊ€²Œ SØ)áCñïp BFТÕ¢øRD”:֠ʨ)'7‹Ï}‡þMçØZvB³B°2ÙŽ ¥L£Šƒ.os¶¥üvæõT2˜yçÁVž··uí야ÀÚßß²pÛóû]uÅÐÂ-üùup¯G‹ï¥=­X ÷òw‰x~R•Ì©7ÔÍ^Ûº÷¼•<øÀÜ¡+®Z´ïùm ·¼ŸûÖû[à>iaƒ¸Jt vA2×áˆ)N¾€”?š0¤ü¿!jˆ¦Òчƒß®z¸îÁ½—mÞpé.Ö½Ú]wwï/ß2ÿÐ5ó/„{M¦‹Ãâd8aè™eCBaFØýxF`¸ÓŠ&àG¦1‘Αͧe1®˜¬£²6ž1™ñw&\f6áG³`ÂビY‘LøSÞ0H‰i'ïd§Nþdï‰lß7¾ÁiÛÆRÂ÷+p(“m´Fç¨bÆB5¥0+)*’ÄãáEÅÛ9¥mÖÆ>OÅ‚oÿ¨²£©««¹<•z€Ów–ð‰x‚í‚ýuãZp!¸ÃêÖ¦’Aï,ñâOöíÃk§½Ë*àÙˆJ šÕ„GÀHJUÑÁDL|“Õ£9­{UOϪÉ+{zVöÐó"c·Šoj&ÃóºPL2‹CÁñ rÚJåH)S4Bók‚"hš_c ñ³Èš_ƒßŠLîKQ§ì;󭔿üô'÷¨+¦ýY¿st~á*>OÅbä²OqG³~·AÒÎ+ s’N#Q§xA/x„ ~€YE 5ÅìqfCqfE ë$p‚âGÀ ˜tV`7ü 5ÚP€ÃWûœúj—Ä”s\lM;Ân½ûHn[Ùð3 †¿^iDÚŸbË^~1÷ØËì½\îâ‹™xqî¿R‘H*B´›j6`³°_Èèq]`;M<Ã`i#f=Cõf!b"ŽM£‘ØKÔ¡‰é@é+Öq2›9™ÍDÚgËýÊ Þ³Nœ2;¥•ÍNÙtJ”MÍLfÍ*Ýݵ )á &’a³Ýx(gýñ ±éÚ3/îÙÃXóŒÁ<ïê ÎÓœ§¿‰îÉ®ÓY=ÉÉŒKÓrÙ`Z˜´Þ%¡„³ >ØAüI½Ó‡òQƒßÅâ~àk;3 Ád—Ø âÏ«¿úO3/i½ç!v0âU_]Ø?cwZJw•µìOoºrÍÞm»¯>kQKÒ±iì]ñ‹0¿°CÈq~˜ŸççÔfͦ øÃlq½Æ¹$ÁäpLÖŸV*죲„¼R"¨§k‡Y–! r@`’†ÀŒÃ(âAf;i!^IvsPˆƒÖo`©j-˜{´-áÃhUáPÓò¾ƒCçÈ«Ëzú/š±}á‚5?x¡«ü–‡§_³ëÍ¥ {ÚZÎß[ØÔ±h5[V7yÿ$ß]S×´ãºÚ€îWúìÂ…œîÖ”´64–‘!¾ŒVÈÃ?‚²ý4ˆ.Å¢ÉÏXþw[P‚ÙѪ趃h’-` ÀÁГÄT,zX«­¡œpû5ù¼ ”[Ѷßÿͳ®C3gÞÍn?Ÿ}/žÛù裻n¿=OûÛ€‡K„…Li¨”Ã6Ô®.cÀ ´wF3F>ÞhÁY–ÆdËiD¢^à'ÍË ƒxT‡Ö>ª”Áw'¡vf pÐKp%?~ôº» O©6ÀwÉ(e˜Ç‹LårÝ‚»RÉpW`7°•·-PÍÎB‘¦Us®?÷¦î®¢Ç•;5çðòÖÞëß¾véÂêÐŒ¶Ý~vÑö»ü©ó®ß6-E˜d¤x;ñ~•°MÈxp…¥°-®Ð+´Uz´°B›a”€7œU?0•…w9šUÀYˆ¬Ëý¦L6SŠ‘¤L%ÀÎŒSpÐF ð€!-k%áp4Z€V é `tÑ Â¡H*¿¶i÷Ì¿~swGÝ}ÛŒ+/ï_ÖÚµk«ràa±û¦é-aéÖÆYÓ9åΚֶñ¦3ž¹æ‚uýÝûiÏþ"n=ÓÉÉh‘¯Pà 710n#H|… Ä0P,ÊšÄîÜ'Øj±k÷g‰‰U ›[6G6~!² d˜©SÔ1ãý&!IH LÀlxÎÂðÐxÄíNÙ…Ãð¹Ì U#‚,΀!e_Z®sxËJ«QÛ+$Ù¥“RÁl®êZ.“”7ƒ! ô‚£˜œŽŠ d3‹êŸw1@•­½í•]'žë¨ˆ·ê¸ü—¬›wÇœúë*úçÇ£_±}yixVº½qcK&mè«îÝ›ZÝžº¯)™œÓPåšÄªæµx-}ÍÈícÿ)>4pþ^)p¶({ÅS,ðÍS|H†J"ƒô’Û©øÑ(¯‚ïnTFf ì¿_R´d‹øœhw 6*—2‚ž¥Ó„—»˜ÝN’Ñ.–Ò‡%!*ì`ÍÀí=·n~âÊï}'xÏÂkwIÝ3ëš~oÇÔëÙ7lŸvW_TuaÕ†i¶iOG{~ö¢&˜{÷ØïYHŒnm2@QY‡Q0kÉí ¡O —7°£²5Žjµˆê÷î«§O_=ƒ¾Ö.ïî^ÞÍ]>}úòi‚jÇÏd-bpŽôIƉÏò¨Oð"ê‘mq>²GÇÆ¿Æ>ùçu¤“37ôzÊwÌZßÛ»î¯U¦¦Lm(iŸ|¯Ø³°«kQéØ.Á!îׯ îd­ßÆ ]ìï}¹ÅìËýŒmËÉg·Óüú…ÛÄ=ì-²ñKóȉ€j8ÀC¦€ª…¿ýbË™×Å–Û.¹ä‡û÷ãsâðœ-ü9©&–ÒyuqöDnIû{ÎzÉóÏìøëŽ¿ÒsêàÌÔ¿”ÂÙÛ"dBˆº*¹?…»ÀÇr*?­v-˜¹ÕåF8- ®«ŠÏÒ *ZRWv°¬¾*z•Áž}5œ ðP ‹ÞŽ&™,J\Ï‚!­¤7ØY ÃaQumÀÔ­:¶¬sGÜjë¸5áí®KÕÌé,íœ3½{®¸r³¿á¼Ù®@YS·ta‹§¡*^Ù™óÏ…3jJh{ìÔWÁ>m¾(8È B%ð’3–òOf´§ÊøçÆXÖKŸ˜Ü“ݧ•ZXa­S©Çóo!)Q9îG‰Áh- 09œ–ë%ÅéEûÊ5bÖØ‚´nX.Ø¡‚-C°Ü(¸ÜzU]ø+ÉVU„pšCŽD\•Ñ0ÉTtjù%8Q #ðD\(9À( é[z¼ðÕ£e3¿0Õ u­˜»zð‚›6 •w”>²ñœêÅ5ú²¾FqaGûO¿uè±eó:ë[÷ÿáæÆÜÛšÛ¶ÿö¦9«rÿuíÔºª_˜ªN 44òg™…F°ÀÐó¡IpÅ®7  Ø=ÊaK Q€d£êªJ¸ƒîp4hë¬ùlÒÛr[îõ¶Uÿ¹]<~fî]w1+K^î‡ÍxîoU)œ+dìŒÃdÎ^•€‡ü>;>Ær©Š4–4–?.;œ Ž€”*C©¬U2Š›ô ™Ä^ ªÐ¯tÉ:œ˜D´Ô*ÁÔ‡£„‚XRýÞÿáã·÷§zÎÿ³ç®X²fù¢u‹ûÎ/\=uÀn™7páª=‘ó·F×â9JÁùx›ôíL!ãÆ¹ÛŒymk1¸µŠý4m˜(bLA±!gHiÙòÒìžW´&òcqJ&5YÔ°£~}8¤¾²âû›‡†Þ¼òŠm}«#sV½|Ë’ÇÙÙnˆDÖ$öüõâêʳWOZ(¨²AeÚ3‡Ð®Z FJQî–“æc2¸odk œÊKÅdr‘>N¤Kö¿¾•[jݾ{϶Vñø/åؽ±³ø¼5ð< XsÄ!Š žF:Z û§3 öO‡ûgåÖ›¡„M€°À6åö¨j„&ñ?ýb‰”»õæN°‹Åã?ºCÙ¥>s<Óv=süyF=ψ 5ÎóD“jü*–‰“úÅrg{ôµ]¹w¸Š{ü*ìq‰p¥ñãúìyþ„=κÜ~‘cƽ_4r¸Oµ_Z„X½&2Ï^BŽnx4ÁE+B,ÑBÏ‹JP쀺d/wkZvXÔ#ÐkJÝ·3ˆ ‚‡ “:Z¢AI8‹Ý²qcã’à̶íÎÙÔ7õÊkÛñäéûØ*vASýòŠÒݹ3[½÷ïÈ=ÖG¶<ÒðFÚ·iêÉ6$ˆŒ².žv¤¢ÆXØ5 PQŒ#Äô$Lß/þ' úú䡇>çþÁÌg沚Ü/ÉoÏòOàÔW¦xF§áÀ?=H¤íÊ[‹ÈúxÞŒDSž«> Àp}N oç½÷²7ï½w/{iÏž\Ç^¸ËØ{âeð<'hT.Sç“͈K’Èž‚%eôçõFØž­=ÑÉ´P‘¹L%R¹¥«fø– ¹WØ[·ŸI®¸Ä>Ä‚"Âp‰ÿDK¸ÃÐT)MXãó4‘ïìÜúZôV«hÖ]üì~»h.éf§`©õ¾eg·æXvçªdîMu½Ã|mÂYBÆ„óÔùê䇃ùÚ@íÚœè´Q rÉáÔ_±þîg4uLÝ|JÑ8>ÒÉâ) ØÈfœº¨1™Õ©sZ¹#Id]æóJýÿç“À ¿Ï}ºýäèµÌtf®ØôÕ¹i_Sc?P}; >dzCruÜc—«ã>Eg“\ªÏÆa÷3ÖM“šàžùŒcF峇I:á3—‚bÞ‹`4“r&)(¤ 9^<3âw§™ Â.m^î{ô Ì ÐMÐÿ÷×ï¹#»c|b±x|ûÛ»ÿÀÎÚµE¥ÇBñ ½€ W¨Ú¯D§Ò£Z†ð`ÐÃGñz*AŸÀ}ÐèÇre4 9äKP9‚MY ] ôÓ „HþÚh$ì ‡Âd)%8ø ÙYêz¶íºÛU~(P’xTd챃Oô.êè.+빸§Œ­øò §žcï_МÍd'¾rpGb£¼1žØX8¯ß:"Ö_9~^‰” ¥ÅF¤´ órѤ´ÅQºKê¢Ð¬„}Ð)g0áRl¾TŒ< p*Â%,7þþÚÍ—ö73W/Y¶@<~þ7Æs¿d¦Ül_üüf˜M3蟷È_´«È_dWýY#RÐŽJ'Œ>Š<­Ñ+Q‘§5Ì0šä¸Æhw—"•+Ð’/#’çG’4Â̾ ü­‡€“]R½>šm´™‘Y‡Ú'¤':‚(¤Í ×=0xöÐæSçÍ<°åWgÏ«Ý{Ýpdɲ»öô^åG Wõ5 6øj×Ý´ªeÅòŠŠpÐWYêª^¿búºÊj ÿÓ„W¦p¿¢jß“s‘• ªÜetä«ÓÏèu$µ™©AµtÀî7 úi/wþçCbê²Ëμ&¦Hvvý¾D²/%d$ÕoÉű¥ ü@|ʧbÆ8’ä bÖLC3 ¬ø E÷jt?ìíÜÑå}xʞ˾rÕÙ÷rÛf Õ×Í`·æýÛ»qìÐ 7M¾‹ º6 („w]z: ȑɠ¯Ýôá©Üßô1yf.Ýg2Ðè%âш±ª*äå¡-†x¸•ÅŒ9¿ü¯ [Xxò=)/&C·,xb`ÑSpߟ²Ÿç¢b=Þ¿äœtÿF¸ÿ?H?G&žÒXÖ)]îŸpkþ*- küÁ©gïûÒÈK?Q¾–eÛØÌ·Þʽ»Žsh0îm†¸ÔT÷W“€[›b²‘vIòûÛ“þcÉo¡Y+OéæúÈm ß09QUgŠ´è­£²Þ™5ðybÀÐùy*“‚Í÷ßÏZsßÕ‰¯ìúdß»Mtˆß×  Ï°AÔÐöëŸýúÉî¬3÷⫯Â5sÆ:4µc_ãñ M …@Q<È(}Žø‹3µ³/Á3ÁÖ³ÛÄ›áZÁÒ&2WŠýñ‘g¶‘nzW¼U¬pî®âž^Ù@WWÆ*òUe5ÕèìÍjôB;šõ!RÞ% JÈ–G¨é°Ž*aXo †–MæBõJ)c°hw V”òüRp‘?´"!Å€þ “ãÕÔ©”y‚îöê æ¡€€ùÙÀ2ëÙ&p0 φz˜œ7–•ÔÉù(£¨”Ñš Iy&§ìF×·Ã)`zŽXÖMŸ(äÖÂÔСú¸-Õ–¤Éa8<ï—.î»ûvtÑnûMÿ‚drx½»¼ãzæßœ»fûáå%škæ% Õîz Î8úIšŠPg~W ž÷”(¢N÷⮹k`Iõ31ýÃ#ßÌ‚‚9cbá¿ü9÷³|œw@|hЫžV˜&A+Γ­tߌ•r÷¬Hw,NÃM8`3—B^jÀQ¸a ©ÔÄÖÖFk»²JÜ·ùÌ7§:7…/XÞÇç¢2yäpJaâ ›7‘È0Q]f¿•ÂL\q ²Áê*àÜWðìX/Ïló:)ä…Ü*¸JQ¼>Œ³é0ÿî†X): in\ú1&0‘™óßû.2O_Úíno»Öé›T¿MòMª݉™Ó¦Í]ÛÍvWøÂ¹½ê·ü:VÀ:$a`ü¼Vñéóö©Ã¦*ÁñCÇìjtVeÑ û®·œ{ýÌyü¼¹;ç/š §mY<Ò™»)¯—Â<Ð62ÆÝ\{t‹ÜŽ™NôhœAXc¸÷ߪXŸ¦P5î¬Ç ²ÔhÒiÕÝŽ‚/‘|_ê’ÐQ_wmî+×>8óŽ™3ï`æL_øHÿÇÓ󇞚ÏåÀ,Ð anN¡qW.¨ˆV„»ü8Kîv"­(Õ«N”üÀ*fðæq—MÅ]n Õ­÷ZfÐ,Â]Q¯äS³8fÝh¨ß9uçê–U‹.š=ùPoGÇ@ê-ñ½©ÑÈ× _1;õ>;;6ÿøì.AõÝ„Ä0w;Ç;4wæâÜQPp ûÇñ]´Ï²'N[˜ÁSµ!&P´VNdôcÛT¼ã¢$?y ù$r!¤R4©Wý8wÿb<Щ¿þØà_Î~°«c µ¥çZÂ; gÒ?»îºú¬ÙˆvxœTÏà á.-’ÀîxÆŒ‘Z;å…¤1‰9Án8ðnÀn/¨hÑ]äUÆ@7œº¬Í,xò’…°Þ?pȽNŒ)‘—K ÝÑ¡cÄ¡*—4ê¹2Ò¹² ã `Ê«N´ÅÐŒ–Y¤çXýÀÜÀ±ë ÕWÝ>ïNvyîpmUU»øÌ;]‘ú¥¿É¯a>Eþñðï4¾tÁ³¹ÓÏŠîÜyìè™w þ¸ÏDÿŽø¿õïÜjÏÆknxª¯ÿ ¸ïÛ’»ƒÉgÞaës÷Òý›àþ§àþý;âç߉¢Ç€fzÓ7ž8qàùØ3#_¸‡ù?yâ‰ä~ Ö:÷Å·iÞ˜ëˆHÃhà[‘4ÚD¢0yt±¼øúŸ:U׎]¶¢kÇM®g§~ùoò¼?M³ÂD#Œé­~©;%dDƒ_˜¨ÑÒç|èA€§ñ†‚F¥ŠF¯Ãœ“póÉ{ûÚ÷7æ^v m­² ³§Î¼óCû6sK’r‹I†¸?íÂ3(ê&ø†&}ñõ|C–ÿoh ʽaÃŽm¬q÷…¹ïáç)=v{RÓ/Ô ž~dª@ùÑBl}L®9-ëã”od‹gj*P`Õ ÀªpÊ´¢`*DÉý°"ªÈ¢”ìD§òhÄýB5ìn &MÔòbŽ ¢w/%ãÉ(æ¬$¼èÖ­b…ø¸ƒÁÏ>†ßNc­é;šK.72[0´hPt°¦Éöi¬òÀâûæá™[KÊuº;MΞkwÁs§NWVºµoØìûÂbÕ'v·ð–f`>@ŽPW>—Ô›4÷Žš;>Q󯛀N_:E…Kž"é3àŠIäTÅ”J¤S%ä¸ãJ Ù³™u5X¤qÊF “lO(A PyÜo`vqxÁâAÑÎÎ:°O8|8 ÝY岸L@–¤J•p¸Ö©Â{ tÚd **GÜF»QÂúb¨•Å ÊH€Ã°šŒ¥¦ˆTŠyû»YD0µfáªöá…“C³ê–…­jZ/¨gÎ9‹ª&{£ó†+ãžAÊLï‹Õlôj.Y‹•,ùb%“kpÆ‹•LEÅJã¥wÂ=-9·µunÌ{™˜ÓÖ6'yæì¹Ü ¾·SÇÎ{Å, §5¹d³^¤ä‹a^—QËCéì4zä1ÒË—5qŠqèâ|~‰«>Aq %®ü°¢€i̇ăeRQˆæ´Zbƒ^Ñ Hžá„S,ÑH®ãL«7ø(͵B1z¼&üèp7[lN—›ê×ʼxÀ\·Y%hD‡?š\ǵ:ƒÙj£è4iMESþ6€‡~ƒÏƒ`NòÜ&æñ¡ÊÊ¡þ¡i?èꬮìêþ~÷к[ç̹õæñ&ÍZPQ14k~òêäü¾Áòò!Ö{Á”)LáüV þ¾xÖºKÈ8 ±m"+¹ì™9¡Hzô e½>Ð'/ 㔩ï ƒy &Øoe'[Ñg”¶ì¸P)QSݨp䮯ð“”)Q9‰; ëOÖÞñÌ÷.Ïf³ÇFFF.ç~Ë*r_îÞ³¾À>͹ù3’›˜ïG~x»¨5芢 IgÞqÇÙæÜb¿ªucOŠsw„6áaê1ìP%Œ»"ÜÔ‡[‹ªÅ ǬѩÄ)„ˆQE¹‡#0‰)¥ŽQ¥~E9ØÕ˜¿–ƒ“Ðîte õIü‘2¶Ê0~ŠƒÉånÁO¥RÆc!?ºCêp%¿M:.ZJƒ-Iä #O"󌪌 EF~E ”æOŠ“QŒL¦0Ésg§OaÛ¦(ëRk[ÛmëÍß~QǺ›${W´O³–Ü<<÷úà¢ÕõÁ¥gEYb ÑÜ{^·²tU¤$jñTfuÎ7öWçi_ÓP±øË}‹|e%¾Úxi©·’h9]¼T,ÓTP.@+ÕXÚ(6ÝZ^ÓH™Y¯ÅâA¬'Bò|ÔBñ˜ú}zË̾¾™ïÎêm‰ÍŸœÑÜ<#£¯åÉu«4¥â ¡½  o2Z-f¤òúÛJrïë1‹7ëàŹ !Cz®Q~šóò3[Ís5·• æQRÕ˜í­1G)%]úšIëð””ÕFèô†¢ð;ÉVËc_à¸3y nS‰+ã²–~ó9ë.O­-óVÀî>éè»ïÓ}}'ÿyŸýà£Çî»ï@ûê gÎn\Ú¶>›1ô:›sâȲeGNܽt)Û4zÇ£wæŽ>³©¥Ã—œ²¥¬#_ˆÛf-B¹P#á•§”ånE¢)M3ë¯*±Â–Y¿^h€%»âYMÇ R¦–(Sa%ïKõx¸'‚.0ó²F³¥„¬«j0öüîÉX)ÊHÁ¯ê`9D¶„ýR`W¨!W¾fC> ùTû*˜ãæQ`[ ¢C•Èé§ì¸g~êî™Á•̵²²²1ퟷQ/;“»ñ–É-ƒ=ìÒ+­¡ÿŠªyEMËt¥e¹×7of§±iåÀ‡]‚ò»ì XY#ç–î´š C¡@½Ã:=¯±y½ì'7"–µËz§,œ攵§@HiÈÒW5<˜JREšú­ëÅëžzêºsþºrçΕï¬ûEúÇ?Iÿ’ã²µW8_f—:¡%Ÿœ¯FÓšxŽسËh¾ø=n†|äLè^Ñ~‰{sïÍ×…±çÿûº0¶‡ê´ “¬)§³QÖM“ð¨z:üü(À¡pòO5±l?15u„à ¯KãrS,[®­7Ÿ,K˜…5xžâ™iéH%ü›ˆSñ¨§3}#è†3kÒ˜é‘5iý¡ItpjÀà1ØT‚r$Ór“+«gk%©»‰GD[!™ÄxUº? {“<'ÝWîÔ¬Y§rwiË»Þôx{ûã›îZ¶î“©ñÛ¾pQCÃÚuõìž#—õ÷_vd?/j^ÇÚκèìÔyï²òeåuæ]6|©¶÷J¼íÇÆik(¦-Pô²¸xû–-Wb²Óâ‡`o— ÿèZ¢R@{,륓¥z·²n.ZxÅ@ÖbFaH(Íø%cÀjÌï01[ŠüoSÐwâã½à„k+m»œ‰ì@¢´4yŶҭ‰³‰sÄÁÖÈÐPdCtÁ‚èÒY ³&¡n¤ÜÂfX‘d!»P“- òû‚¾ÖÜÒÚniÍ*Ð"9m' £0ÆxÆFŠÜ¦¡ÒôŒÝV(AÒæ xx±HRÕá3Ù¹æG¯zôÑ«öìa¥{î»oÏ Ý˦ ?:5ºsÇÎÏ8ö K2/­ÛŠcX×(neK53xÛo˜öf×;âóWí^Íí¥°¸lÔrá|^¯ ƒ×¸¤‚ŸQ¶‚™]Aœ‹¾òr+y>,¼hCÙJ9£’^Å‚ai¯/©=Šä¦ò Tàåèž#ôÌ1pc¢%'—ˆ§ŽD+Y›{Lkìç´³ÞlÔ–/YÝèq¹þCüKîÉ¥I–få_~®=ØX[ï)¯›Ö´‚Ö—„5ÜF¹+}`ë <÷R ŒÈy6¬Nå6…3ËxF‹ažf1é,£Ü÷a4c–¡Žëš¶DPBï¶AŠ$îcç\µÿªM슓»>ÙkÑD?ù…½mâr©GøXø{ôtåË&_1êÈWŒæõqOK_<ÞÇZæ$“s’jÞB[ø* X^¢AHÃÜ_ò5™N+fóèˆÎl26dí£·IgBè$—–Ȩ(«½¤èqò«1óp*A•ùáP[M¨²­±Å¾,Þ:Ü3ã³¥*·ý@·¾uU7ðÎ2à—¹â~àµcaâÐN~zŒ[cµýÕ7'aÅU^¼µùZ|S Ê èy€M<Ô‚@1ƒÞÃô< ø+N)!¿6»±IÕƒ™'¸Í}ê©PцڷO9G£91¥¬,ýÜÑÝQ›;ص¿ëCÑwc{ÛÚzeë–Ks 7o=½½W –jöи³qf˜ ÃlÔa×a±×~²…ë0Ø÷§@VËVÐaF+ê0üªê°i ¬ ¯AýÖ ºë½÷¾z쥗æüäÇé_¬ûeš£ó gLÐŽ‰YgH·ù]ÁÖšÙ¯¨½ž Ðï+Æÿ—âߟËVÒïçÑßo Lü÷½„›ÆBbØÙXKs¡ñ£·ÌÒ)SKjÔ„Iµå† Ê-€Í£#f*ª1À1p»»&7Ð¥³Ar}Õîò«U5‚âR³ÈCRF0zhÇüXjÖÅ:Y³]$§;/-È3~S‹'”J`!MESM_ûºUw vn?цV{ÛìW ¢%â .jv7UÆ+;æmö7ˆådÑsÚÈÓœ«yÆj:§¨{ñÒÏ?1aüiu\£;%,?\¸þÕ ×-ŒsÂø[…ñW.å¶æ~2Ç!¸„˹GU‰Úµ<¯%(P ¨Ðî´b~§Ý€µ ô‘jÜ1TòÈn¿x÷NÕo)»šeÁ @ñ#ÌžaðÍá±;\î†'~Õ˜Ýát|”•ÂÂ~Ðð7 cILË×ÙŸ\_ Ýwm͹Ô¾1iæ±yâñ å­Ï\xä3±.^wû'Õ–Ôb7¬f0——È%1¥B_¨2‰ªL¢(0+J€ J±*‘·¾°ý5'/ú³¸}E ì«O•  ?vûŽoÏi‹7Ïïé—¸áSÅ(‹ÕÖUÍÝ•$ÁÖ{žÅ½ý&–/Ô}ƒxäo|?=~bÂøÓ…ñS-ŒS½D>û-ݧñ»tÿ7>üÄ„ñ§ ã§~6>þwº?ÿ朧âj.!âÌM MXˆÍˆjW|þø ¿Æ€f8¾˜ÆOÝ€ã7Àø\¸?Ž/¢ñWáøm0¾h‰ã+hü›7òxÇFÑÏÎ-’Îj÷‹É_¼ô¾û–Ò×S;wâúÊuÝØâi ÆüÊ…°pZ×Q`¨"ÎñD™ý¿ÔDF-löó6(û(¶ˆÁÃ<å¾·çÐa.i¶ËSJØû‘N®@_~ Œ¾ü@IEX=»ŠwõˆÒ½]Ò ’·¸·ˆQAwZ.“„³hy¾z‚Xj¦ öôÀž(~7Änî°h¿õùšú†+BSºn}¾¶~~x ül¥ke³«ì¬¡[ùø‹º5Á­_ÚÌ?4}é3SØcÚœO{q.…û9ö®øñt;£]kP÷ùSã'&Œ?]?+?Zÿ¦zýZ ø!ºOG åó áÖB®üctÜØ]¡Py•5[©^´4n^:„1O¾tH­q*ʳ¹ÙÜj¦ yEãVe¶vÈ JòþþÑ›ŸÙ¹vɲ•+WˆÇ·íÝuÑŸS{Ú0OæÿàŸ:á êl¨ ÁoäH©5ŒªÈ”:Ó¨\çĔЬ•'¶X9ú‘ì£#F©Ð[˜*üA gô‰â'UuÀÌ KÇÝZ_¹—|V—ⱪKÐøsñžCvlÅL#Ú•k¥Œ3eh]­jE¼ˆ~*®<©^lÅÂÖÞ+õíºkõ¾–Òæ@M¯}Ûé%-CÍÉd]s¨:˜´2.º·ì®Ÿ5¯1V©žìkÿò¹U›ÕÓ›J}•±îX{8VÖÖ~æm¾iêp3ì_¯û*̨åãíØÿ@3Çq¿…]5Åã±ü8¬)º&¿[\[<^Q¸ÿ¦ ÷_S¸v5âg÷]U¬¥zÛ„ð†ªÏ*JÄ@!»H¦MÖÀçäx¶Ù¶5ØnvÊt=6 ß¦•윀B5NE gº®å–§?—¢EžõpžÄè#{“ÜZiÄ`¡[KnÆòê{“”2,·õ¸2._9Ù¨‘0fô–Ó¯ýR¦¬¦?5“§Y’=<¿ÀŒ²8ÓÅù½z,xÇDœøxJ¤žÒçB)ôEÐëS›À Šöu×u G+k&õÌØ;©ášÜëöE“;zVlj«\twëÌÎzmuÿ4VqB¬Y›÷¥åþõûR·4kÖu×–n¨žŸ^ÔèŠ7NÚ6§óiÛ3l:G1«£VÅ ¦ndk¨~½\‹è¡JõòšrZ¹=â ÛÁFPÀÍ.ìnà(ÿÈctr’²X'¦ß†à6M¤E´OÌÇí¿t^ëÚu‰å¾ºÖÆ¡ž~çž­L¿°(;·ÓXÆdã8Â}òXxì*âíþ÷ˆ·ë8ïÑ8ñ6ß5a<–gƒÆ+ ×oRÇ|ýšîÿþëtÿp;M÷ÿºÿË\‡~ ã? û¿ÿ<Ýÿ$¿ >ûÝÿý—éþ/q‘„çÞK}ó"ýÅnrX蜱k¹C>«­-EÖ§Ì•(±{9È®rjx¦øÀ¤¯SMú¬Æl±Q %(}MkrJú’Rò6ù0KEPj±¬^`>u£ô”)b4‘ùŸq¢bS3§aç"¨§p¯òª‹÷£PG8”œºöðêIñ­‹¶M©KT-_¹usÏæ]þxÙÙ·ÎëÛ‡Ž~áðöi%¥k“鿇iƒµd ¯­ó•ëš×ñÍëç-˜ìo@š€˜Ó$OüŠä‰–Óª™ú² ͇? šG‹Æ‰æ||ׄñX~œ NÆO¯(ÜgS”Ë¥6Á.Î/„O¨Ñæ²%–51–ï©à¦`$Yg áYãXá—•œ¡ä).ª³»y§‡‹wN“Xû©žm¢'waë@+ü?¸cpp÷î}žš7²ÿ,ø4Bjl·øñnÁîæ±**] £[ 3Ï×+;`Áæm[MT¬€ 'ýøï¦È ÈñŸR‚>9årüA9þ@y0r|,rªA<:%­ªÝLF…årJÁnÀþ”½n*$Üãb—Šrä¤:/Û㬜z ššrí—›Û¯¬K­/»ÕèHyf•Œ«4tŸùùzŠx%` »àG;r¥|^ßxαWÇxaö!P^t¾±ó–XÈ‚BõZì–b(Ò"ð(‰2³½T¨“(™g¶ú1ùs²ûúÍýÛÄÔ>ÍKRî³>“ÛWXWEa]›æóñÍÀ\ë4ûÑVîB¬÷òeÅXa¬ Ë·×ÛÖG 6úsªÎu|° ãÔpº5i4«z…€p×Ä^²-–5‘³8ëña5%¶Ïôè0cò §½2 ‘{_Ò>YH·q9±GiÀ ·Æÿ‘pޏhqûñ+ð´+<}\Ô¸ÜþÀ¸á­˜ljr€,HŠ™´t‚YXO ŠW­m)µGÙ$&ο'Ö_i­l^{`õŠæñ† 3%†³ŒÓ·÷—È÷®Á>ÿÕE…áGB&Š|Ò§Ô|’¯2’+bÙ@x5[Æ ¡‰E‹Ë&Óq®³Hm*Ä£äÒøˆÏÑdäUÕ1Åg¥˜l/IŠòª£«!‚Q¹É%7`ù‰\ƒ+¥"„‡8€1ªÒJ¾jÄ2Òˆà ¹þ’%,HŒï¿­`šŸ¨´VTöì9F@úWÕL¾¶Š6¤íE³Keã…MÀgSÏþD6HDK¶ŒÊ¯:OkÚ`¼ïû\Ï¿_týÓêõèSº²èúPþzÐÿÅ×?R¸ÿ î_^¸~xÂõ™ÂýOþ‹ûÏW¯G›ûqº>J6÷É2~ÿ8\¿MüÆg}Œ÷ù»0Á˜°„×`Šn¯Éç>¿ rÈ/TãyÂÊÕŒ—q37c.Ô$USÒIµ•=‘5òàŒÎUd“ZÐFÕצxœr-ñŒ“rÉœ©pâÇ L¯ˆé•þgž964t£1xáœmk˜Þ1·=y/dZ½jŽ”^uæé¢Z¦‚gÁ¿óòߊðÉ)Ž×¶×ûƒŽ®î£b|,ྮ¤pý Å÷×Ô®Vs_ûÇ4ÔߤóF¨÷¯%1¡Å T8ù¡ÖK ÍNÊŠšŒL‚‘â1{€‚Jù¶'v¤{9ÅjÈ_'(No^å‚dãÆãx;”°~ü&[SÅÝQæß³´ºÒZÕ¸nÏvµQJÃŒÉx´¦,Œq~Òˆw’ Výš‰y¢&Ê ÊBͽ©@l7ÜYjÈl¯â}î°8{íAã5àP`”»6´0yãkf Ë…ÏAú”sG¤EÊ”T…ðŠ@¡jmÿ§ŠÇÀj(ÏT‹ÄËÈRËÈšÛŽ6TZCMç8ÿðž|1™i¨¨š,"±I½\nOék²ÞýèiÅûŸ)ìÿÉ ü2n'ÌWùeÆIre’—|'›øxà„ûèú9gŠ1(¿þHáúç&\,\¿`Âõ®a}ñõõ…ë‡ó×çNj_U¯×°õâI÷©‰÷kSZ¿ðáÿ}•šÜËö¨ x³ÿwõj#}ÕS¿»£rwLéƒoSã5ls>UÃÖ‡5lÖñ¶žþÿç*6¥§Ÿ¸ìÿ¹š-Ò:% ×ÿýº¶dxöžºæžóþú¶ûš×ì,ëk÷Ó^M¼Ö@:ãT˜G`|Šæ×0>÷-'sÌ_~H½ üÂn^))ÛxtU6$²§ {ÍzŒT6‰-¾D[ôƒ’ }@V­ž¦õÄãu.w¡_ZâµHz/hÌ‘ƒüBŒ+ðLþ„WˆKü?‘ 7§zç¡~yèwØßV­‡ÿV嬬>÷Sö·B^úåâ?„”­T¥íHçŽÚûQû &`ÇJ\ Ÿ¶¬ã^õMÚì¥5¤ý$VýØÔ8à§hœ¿Ÿ;&^jãpª©¾Ä͵ Áö~ºrª©ëؼîÖ6̘}L\°*휽jgq= ¸`<Žp¸/xõqûÿ'd‹’ýÏ¿ÄÇÍ0þ;Òoß#ýö£q¿ÃH¿½ÿ"é·ŠãG ÷îgã×ÿ˜äÉû/‘¿J• ,ùº‹–œ ùº¨|ƒªÂÌù ÕùðîÙbx̓½û ÏpqFËj¹:qÆÕþ¢T­tYG3.z Ëƒtb•çP«Ñ±ŒÏ%ªIîEñèuQl>/!M=[Üýxî¯îß7ØGCç±?­?ó÷;ž®º0´¨q{2ç;ó'A7^ñRgý&ÖŒY¡¡¨t7޹45‰l ÷UÇ)´úß։ίè·7 ¯xy”“¯AÅ‘‡ª8UŨ?V–·X%åØlG1`zHu-ñ‹Eâö K¥ªb’–šg”š|SѾn±½÷Î;[çìë>5øÏ¶áÎÎafïnkžé¸ ·aý• ª.öµÌïf¹—ò5‰*À%Þ©{OÜIú¦éï¤WVqŸæï^"b6ç$aÕOרãl°QBBó_ÐvyVÜGã“`|®øŒþ'Ç$ç‘~ê£þŽîÏôBËWM¬ð-ôB3¸Ã}TÙ{üŬè>óócËý†ÏM†{¶];I±©±\GŽš¥õÁø|´«„]c~ãN˜Û šsì[|Ϋ9¾‚ñCâÛùëaÎ_¢qXªØ,~¯?4ùÆ4­ŠÇàþd·Íçv› “ÝÆ¯?®^¯aÃÂ-9¥pýøý‡YUîiUç=C½Í.R½KFµŸàˆÎB é`¥)Z;Ij-Ï…*ʇÁlN2;Ña¸ô¥_‘Ä’91±ÓpJfÎWIéŒ œ˜ÕÆ“wRÀI)¿Î‹íË Mkzv8÷7vÈyæífVÝÉ–ýu`ñ…¯ü}¹P\GíÅz;Š·šŠê¨}è¹ÁrPÝgœ$9œ(9¨i0¯ø@“WË‚”ÕhÃ)ýó>S~C>18Ò ŒžJ6±³ÛïVË«»Ûv‰û6ç>¨[>ç¼ÊzVÙ²Î\!žýL!ž}BÍCAù|z Þ"߀†÷À^o¡=šüOÎ×Òx#ŒÏkñú·9¬-Š—g ÷?™æ÷ Áxaþ¿$qßîéWÄO@·— ×ð]•=€Ã´ª+ˆ:Sw4zŒ©Dƒû\A=»ÊM£#ºr Àgdd1ÀeäíGײGMà³P9c:ï.,­bÔëñæ«+KˆÖ<ÕLgN¿³ÄÁÂ)÷gê®›{­ÖIƒ¾ëÍgßÒ;x,Ô0³O¼iFcC¼:0´êÌMãÅØ“£XŒvp9õ›  õè™Ø“À:…baµ#®Úš âr€Zˆå=|…&}žf»ìФÏË›ôy¼yÿ´+€n<*ŒÆëh xø n Íû<¼ ÞÖÉÆûøm¼lÇŠéÙ‘Öâ~~-kÎoZ%UÕÔúúa 9Dµî%ª|÷œB7ißxw‰‰¼).µÚ½¬È_â’hK0¹]½€Â|Ÿ©}×ô†(µN(ÔÀ¯»®o€­n\»hJhVU3/… ùÕ£=Õ•9]µ‹Y$N( ¹û‹r3^¾b<†2Vˆqlçx)ºþ¹«Çc"ÁB¬DµGÇ®†ëgjNÓõƒtýKOŽ_¿¼pýµß,úƒH}«„›ÔkvôƒRCÀ|óyƒ!ßÓÌM“ÕyV¦¢.ôJÖ@‚Z-U­e”(cÁª(«C­ŠÂ4DPŸä¤ÌìoLƒnv)ÒžœSþ²앚ˆûƒ†°³¯ô†„7ˆˆË¥6YéÛÏôô2ó«!ýž=úÈwso÷vݵá†Ö­žÖ“ÙJ¶ÙuaÏÖ­ιPz†I¸hçŸ6·ÄÇãÙà™R¡l°çÔóP’À·ðî;UpÖ¼8ÛDQmúQ©“¦Þæ1Âòë1úã> ùZÞ÷A®cþù$Ö5óHv 6”.‡e–h¨÷~Æ §¨Þ$WFò4ã'³”1Z]Dì’¤¸|X¸^…@‰Ü2õ’bF۹Υ0J\hRs.ڜȖŸ°‡\žJ2Søž¨ŽG­Wîž3ÓÝôΠ&÷ ë‚ú†Ž‹Ï‹»gÎÚ]'E‚¢X骭[ËLZÕ|³ÝÝP¿èÚëx°z(ZÏvÝÛ_娼dÅÜ=s§©ñ Ìa=A²<ù’åå|`™˜$Y¾ø{$Ë j¼döF’åÉ÷¸,¿ŠÆ·Âøt1Œ×·pY¾ªèþ™ÂýO‹ïËߟÍWï?øù#šO[Íg-÷Àø94Ÿ%¿§ùÔ_ÿtáúSНå¯gƒµ—7çþIý' ÷ ™䛪Ą–ŽrmL™¤‘Z¨r0þyjgÇŒ‰Q@/u[©¹cUum]c¬…·xÌ:¥²P˜¼p“ðíaaôÔµHJ¨.ÿB“ÿ»¦žBt<¸ù—= /»m^ǦukÛ(Èïøæ¿ê™Ýeb¸Ÿg ®±bžÐêR8g͘ÿžo ‡FëG±'{¾ë¬Ð/¡Eí—u8ýÕAZz4ŒNÊê².×âÂóÉÿ^uÑÅkžüù-vlío]õ­¶Df5ùÝæ¬0…ŠÖk)ðR¦ÀK'ÿ/ÍWy é#“oz…PÜ6=t.=wB—¨Ý3K Ý3K¨¢„©žg`‡¬Þ`szxú°÷ù*DÍÔÞšÞ|B[aùai2¶Û M¼¸gÊ`[¨²µ±ÅáÍ7[ô­õ uiÛDìó‡¹Î€°©¨‡Du¡Š¡ÐHKËÔ—Á…ŠûI x4…$×H ¬ªš—–bÕ¯«~RÆ]R•æåWÿºÍħø¶°“Å m'ú6÷µ®X77QªÚm9XÜ‚¢Q[•ß«àù¡{ßãû‚}Hž£ýJÙi¿ZUÙûU§é†ñ¥o’ ±w/í:.ž¢¼äs¸¶xÓ²6«™qW—mÜÕå¤R{¼ÐÆÜ<±yþ^ ÌVS¾Âv-ï’*Äp«Ž{èèQÜ /­Ê½Â¦¬úÕg¼+þ” «ãœŸéí‘- xpj0‹yŠ–)N~"ßiE,Eç`Þgóå݃¹H|Sy„lˆ„<ã<<”À\¢â-B7Üx7œt’¶æ»ßU{‚œ{®º%ç.Pû‚,8·³Çx¸ÇøjCqì?PÈ Xœ+Î{Ü_¸þåâë Cñ\í®?R¸þ95²Æ›C-û)a¨ù8õœ¥¼ôvBP¯L*žÏšÂ|N¸ÿéÂý_ZZ|ÿå…û/QcR=cñAà£j”‹j+[tÇå=xÁ|SÛ‘r ž\Ö ím1ÎçÂx¯¾’ CÖàôøK¸”}Ø% Í ?vŠÈè))î³MpÅ >¬fÖ£6Ä]òXϲš:{CÓ¹;w®ÿTgÜe—5%Ê“äÅšÓà8XX öt©FeU¾‹¥ L‰ñ›ìä¯àɺ'.tB³Ù±[ŒFõÍ1| -™ÀTÑ«u•©Âœ(»¤”a𛅷ɍra6O€t*ýbbk˜‰¾»¶Tq§˜‚çnwoò³Mc þ»æîÀl û»ë;Li%ì æjœã¿"y¿¢‘°C¯P”—ût!/÷”p¸(ç#–Ïù`ƒó‹¯?Z¸þ›˜Ç«b¢Æé#Œ3ȯ70×Ys™„¢ë)\ÿ„ëëó׳á ×g ן\X|}¬pý|µN+ 6XHüdЀ)£ ­Úê »Qa#u®ãBG{{Røi§I´øµª_ßià 6V.ýó ê°çc¼¨ç#¾U&õµ oüþÆÆÍMº¯išy„–Öέ±¡õ¡ žªhýÖÜÑûfKøÜ·c/g¢ÙµÓyNôý4¾l¢ÙcÝD3µ6epìñ¿èú£>¢ñ>Û-¦ëŸý®¯Wq$à×£×Cݸö8û`|)ù(–üãÚ4> ÆwN9øõ7qÝãˆGT݃×ÊÓ˜}ç̆oOúLWÀüÛ-'öÌ¿èrB£¿ñ[ûaOvŒèÝ’ ¾ž PYŠ­y¦ ݼ .ñçF¹­¹Œ>€5„ÙܱJ””l7X"üTü‡`Êò¢ÈÆu䡪½‚»»8ÐÃ1¥iFSyÍ|—xe_SCGbÆ|Õ.žËrš½O)•ÀƒÎ#·ÞÓþØcâC7Ü0}5ÕXN…k>É_ƒ má©éÇk¿çVñÝîÕ«»©^¡W¼ŸíÒØþ‡šÙû·n¥g®c¯i‚0÷ÉBQ#wu2ó¨Ì(qYÑ™iðk=ŒÖ`õq_9âJ sBvb´Z4Œ²áÅ_½£Öãê{Üd+ûÔ7ó Id˜[žhlôÙç7/¶ô´ølâ»ìǹØ^å `¾¸ýE³œúwÌ¡~ºu‡§§D\»-ºvµìÜ=ÁÍ«vîVt¬„Õp_®ß0ù ]ëîzlÃ-›ˆ‡_šüµÈ ‰¯rÞßÊ×wv½Ù(~w÷U þ§šã©â8¶¢33õè­w·?ú˜xÃÁƒÓ/Æsûs áaÀU€¨ŽâÏ_·ÿ!¾éÔÛÇ6Œý‚Î^‡8}‹êò£ ´¼î—|Afþ. ÞtŒaCQÁÀ—ƒ/[áüß±Ô<ùüÉæ¥†%?\"þÁYUQQåœ ǹ/>™ðïœimt®šg ó/e/j*0;ò1œÿõb«pLÓÒráØ\œ?Œ}OœË.×´"êºå$“æß8‹äÄ”)=Ú~÷­â€*ÓRØçwÆ÷YíÐn,th7ýï;´Ã£+×P¼ÏS7ݲ·ý®uÚHâ…è×'¿TóŸý𥰤àÙ|ïS›švAØgK•›†"¹™OrèôO*«nêÏѲvgÙ,µ¿bî¤ðû±ç'þûq¹ë+ÈÝþ¦ÞF¼E¶¯©3€n;rÿö Nà…}cøV;ò±²R±ŠíºøP~b(ŸÎõÚÇ~ÎJÏ:K½^óõÿñzÍŽüõÿÿŸi¶z+ë; ü=UM±¬–l¶¼òÔ7/[NgE.¶°W–hQ[·Rõ¥ÒU äìmu¥¥u-z'UÕ9fÖöM!ÚÍÆ Òû1ÚŠ+®4úñ74q3К2zÏ•AWx7½È”f?È’¹ïˆÇs¿*÷&ßÄibÖЧv=GÈ5hMxoƒúö'ÓiLøÂWýiqF=UŒRG^~ˆùkûR>Þ‘*,µ¶ßbC9ù˜hóô´ï}ƒ]67—~‰jÈæ cÁ6ówXÓÚ#µÐÄÕ—Oe-<ဿ|Šj %šÕh‹L!a+2x½â5{÷=´‡ÝÊjs¿xüÌ«búq²uCÔgÑ‚ïd0PB7â“Mkz˜²‰¿ØJ1x ÙñW⺠R8dH6ŠÚßÛ×™k×™»$ñ ðþ1À3ûÏhϬSy¿eìfnGYëÇÚß]ç]M°Àzñ.ÌùdŸ|L}Oè½n@ÛÕµÕ­ö¦NÞå[s&7Z /mJžóK™‚*úflœ¨¸ éd7Ut. ªèô.w>¨btHü=ÇThÊ_X{ç104uÐÙ‡Æ ›u¸Œ±‡\æ¾~Ÿ9÷OÑýå½ç±ës_ …­;ófÖ<Ñœ»Ö¡1µjÎŒ†uoO©ëÆžô›ÄZ êÛÐÉÉ£<@G}e1Î/ð@ê›aF‡êÈ1q‡¡^XE­ŸB‘¶¾é_>kî³}½-[Wgêýé–亦YOÔ ÞsÍÓ3ÊM¤©† –º#\Ìó£èím”üˆoo+ó»°5B™Û¾’qÁø«Î,<Wbç­¼î³(‘F´6»‰œOvÞÚ @L3÷³à+˜ ¼NB?^'QT“WµRº÷úsvÎïÒqû²-ÓûþäÜÖH?¾ `†ZÕ×—™ÑØû$ÀZ"DÏrÌ–ú E³å7f”—«k© ïL)¬¥”‡âÔL,õaéh°R­Ž¿z.Oþr˜¾–^W‰>@XÊÆÿv+Â…V­}Ó·¬Ø[²fÚ}‡®ž±~‡6ÖßÔÔÿ©ùÖgeêØL!&‚Þ*s”ÍD1¦÷Äý”Ý”#ù$Îþ¡™ŸÇ)í‘{–‰«Þ¯þÆ`Òâr±Só,õ-t£ÝHv‚=ÂïÐxÃ4>þcOƒ³i¼±Ÿÿ“ƧŒýYÃhßï,Íaúú]à—’-Ÿ Æð?§JŸË5@éœç©y™z<¿~„çÖ5sÑ§Ô ÛÕç#ŠÞœÌAáÛ…ƒpÔ·¼~xfõNP“OhGé 8š,/Ñ•ö‹¥°04þ£ ­Þ…&zÿQ  Û¬>•m–Õä…5#YµÈ±'Hï 3ç“Ãüž^ôÓÁœøCLÈ…1N'ªð6\òÿ\ÓqâI45x¶þB|9ðÜÈÿ{¢"Þä4€êˆ„–‘²¡Û&r[Qaé¸êVR*Ï üY»Ã ©Ý<”Yt&+¼îè/Zb3žTDOSóÖî%•{.•Ÿõ´ojkß(]ÓO¦?ú°|÷£äSùøúu„¬—ÿ2wîÿ¹F%»IêÜ•Š˜¤ƒP´Â”]Æb(ÃdÎuÊÖ²Òÿ&Åïô?ñ,BqÔ±ÇqÿP#Kc÷ܮì¯[ð÷ Ì]C¬Ê!ôQ,ˆd_ÕŽ™Œ‚ÎVÌ(ޏŸ¦0_… ôË;N\yìJq¥ëØ»äŸ\ ÆÎ9GþØØ”;÷%¾.þó:‰tz·ìÙ+ïJŸ|oûäƒêäþí¸°~=ÖsëB迨ùÚ7‘7ÿaÝĉ?¢›ÈÖ٭ȇUÊÇÞ¬ºt'Ù¾Í×p‘(LÀHû°Î« {GQ–ÅSåÓH@~Ÿ\»é7mzbÜo¶°{´ŽaÌèœÇÍg­™úÖ`yR 6 œQš,Ìyy©v+SÀþÙÝ6ÀvûbCv,ƒë·D‡4|-#†D[ú¨b”IVš°! ðíþAŸÕf,r³h•»lȧƭ þÒÄy­|nÌ<%Ò@qW¯cª‡Xœiv kß 1 H\«aË—‡ˆ“Ñ»¨QìÖ»He~Aíú;ï¼mÓæwÖÞlœ®qïšyf¼A¬gé¦LÑm—¿:_ÛÙ©%Kî›EÈ"ÿ’Ì>4ƒÀœL¦ãàÇ9FŸ•ÎÑè¸ø èQçÄ`‹Å†¼zL·™b ¯©…0 i-=õ|LÌ%29&·¡bô€*¬UPuvX˜l8FhÕÓï<{ƒÊ³»rê¶ÉÕ¯¼òúã¹ØåÏF™ÉUòJKÝhâ’¿\²ÕùÀý!ˆåж¾J÷4rŒ8¦ál6_4e«×{›“‹9\L!ûPÉÅ阪Òj¬Œ4ØEŒLùÓ•|‰‚ÃÃàÔnÎF²×˜7\ãôD~ús,¿¾ñB¢½°qÇzù£¦šŽ»;êåÖï g.¼fæÌkiÚ°.m˻˗ÿiKúº çJÛ/1NŸçä3¶Oz霜Ãò#1–ÙÍòºô {]3…ÚB7Cm 93È>ï ¯oÇ×o{_w±×ƒÔ¯lÁ×ïø ¾žÎ^/A›jŠjSÉk}ôõÙhkÝÿG´µþÈÎÎ:úú˨‡‚[Êý€»œŽ4ÀUaŽNUCpÙ®Œ¯„y!IÁ¤w©#õ™¿4TKIAÊIg,/%‘ºÊm´æ_;=SŸˆ–7:™[^^¹où²_S”ºÎ™Ô>áìoÖ‡3t›ŒeUm­W’R9qûœV+o¿§>Ižp!÷¯ütYè {¡çi0Ó7I¬FPåAþk…zŽ · I{"ì@ |#c°J„=pµ»ü¨C–F KÙI@²âb5rÔ[ñè.ˆ®WDB¿„e‰*‹=í­RJ]LâˆjÉÑ{[ëV>?vscg÷Êê%O-hØ=saG…=T^S½¤î=qüÂXzÅ–±’qÖÒñ§Ö½CƧÕo½ºj~ùH#«<ž«ñˆŒU'Í0J™œB‹T#øu@kE 5âô»ýÀ«O}BÀþl:5ðàÀq¡Ðq¸(´†|RÛüÒNružÝZXoµ¶ž³µQZ8_ A¡ØÇ3+þ0qÞ…É#D‡T¯08‡k„Ÿ³{„ô ¬è”F  »mîô<a¿4h²xÌèÙÚ²©‡(è-~|ÇÄêãœýÕÓ83ÖîÁøæÇ= 5c'Õ“jŠ6ø”¶šîh¥ÅuÆ¢‘sÆœõYöý$+Ø:~|å—“×fÇ”O˜1ffn ×êeå6ïž²¹1{ìW_k(ñ„§±\ÀçtmFÊra ½ ¦Y2$Oж%Vc0Bí»únw0éŸNb9Š@Õ£x¨³‡[rY)]D!pس©¿>ŠÀo瘸üÚ¦‰gî¼ìù¹&Éß}“ÿÊ‹ìéjYôûÛ.½jÔ8sÆüñ“kfdÕdd/ÝX8{ÜL¶Nê‡ÄÕâB¶ð+`èe—|X¶"ÑlFtÈÍ"×9ìþdÅ£GàÖögP7&x$!¥í·¡»eÐa—ÜÅô{öÅÙGôtÕ CA»CÊ@g… ÂϪ>7¤lèN`ôÛ p»©óëÔà±kÐùaªåݧ&L<ŒÉ”6õô«¥¨þšoJÞ8U"_HCoåtÝ;!kÎŽY£k Î\XqlùC ìëæ¯{hFAYNi~Yî˜ù…ó}¹é#\7‡Íeޏc³¹žŸY)º&>;Wrrý@O …•!#¯!µ)ŠR.3ÆQQÎZ1,FîãøZCRýªör»yéEÍí}Ù#'B 2-Ö9­ýØ=’XxZ²} ÚÄpîÞF÷ج~a¥bµÒõA¸„‡ŒÌ—1òHt#5JœÑ~#ãú¥(ȹâ¹fLZ²Õ’5‚³^^€ikImŠA둵ä…Aå:G_wY°k—¼OÒOn…òc¤ÞØ޵O¾œùÔãò®§ÉŒ³—ψ[æÝRä]ªœIŸ‹ó1Ç;*©{†‡ˆÏ¦(Ÿý´ÜY̪'˜õè˜fšÑ¦´1aÆé¶"Õ›ƒ^Â%äÑß/Î/ÈûÂ’fÌ–­?Êná¸÷Ç8ÔÂsÓ;‘g5T97sLÙ¸)?7 Œ`ös°ãþEô'ˆ¹UUÄxš"’3®¯rKgá™{šNÓj¾"óå;Ë‹¦ÎضçÒó¨â92†îgÐN 7››Ýg\Sè[]JÎÓ.œ`[Y: æ\¨™4$q9O£ ÀIcažšŽch\8Å8” {€'ä2 VOÐÙæ²2> ?à×|^§Îk¨ÊÍ£k”.QºnÇT]?©º¹ó/3å/¶ÈÇÉÖ‰£uæx‘W\»az—õ‹Õk~±û¸ñ¸õ¥ÀDˬó[I¼Eàw Gcs©µCOKr[#ÔV£‚Q0™—`6±2ê½oew· i·ÍÎ~ Ðn[vÛ¢F„ünzC2?Gã6XHÙg½³iiÖíÿôƒþæ)²qÑ-µÕuçÏ"Þ°|—|y1©–Ÿák!G|ˆ®…€°ŒóÝsäŸ):àU¡ ƒÂVi©0/ôQNüHGüKÌ÷X˜P¥Í£2o9”…"© ##"¬÷ªJɸójÇœY]í _œ¹ô¦3oXø,i•WÆ ä¹Õiì»ç|ù_g¹H/YÏ`6>Ä<ÝB>°0äñš£Qf/=†\~ÉEBye…ðå´0f?eyX¥„&y*9ˆYMÏbžnlÁ<ö²Hݼ`êRaÅ:£IÜ‹µ;|8‡ÎàúªKkCE™Vÿ:sffQzÝÞÊ}íçÄÎ}_n¼ëº³»šmþ¹ZíJÏÖšºôñ36ï»g½|¬¼&^Áë¿æ¯¹ë[ä33Û&›¾Þ¯ßÿ'|c@Á½bBò—œ9‡½ÂØÇ5öq&¯Ý\@_ÿ¾þ`.¾¾Ýímǃâ[¯öª®Wò¬V:p©xy†Á„åúìê·ÎÂ(¦úOÚ#Ôá=Úo8B¯ƒ Mú·/©$¨T=ø ü¥Ÿ°|'$@¶èŽySk Ûäß½tKó©®›Ýë((‚ø;YKÆËO®]t –*9’íÔs ™tm,àÕq>§§Íå—÷Q†4ÀÃ"a°Ï V¶(ÂÔÒJ&_:VŒ8Þ5R¹Áž䡞x5ËËÂ_pé‚[ÁˆM qtå¨V›×þþé3~WQØ6³aÓjùÝ>qÌö ›‹šÒÂËffgŒšKfŸÝûÈôú êL+nY3–ôl?­±á<÷cúä¸?°T±·Ó~eÑ^má·‡zKòï2³æSÇ)'ˆ]c,‘c`Ý´v ù#`ÜÇ‚Y 4~ bwLB8v{ÐŒä³8ZhB"?GA›ÐþfcuŸ]Œ@Í@ sì0G9HC5Š”’Hmz-ÉÞê*Ê!g\¸lÅ5yí•k5š§_rÊiÖqåb}´¸÷ÜÍ+.} gñ¢{îËÏͬþ#é¹öâ¶1ì¬,¡™+>)HÂ,f¿±¥G— ¢ž®…,¡u ü°øžZøîl5„.A=S ¡K' ¡»ãÜZÎÑ –^òâ-krO™Ÿ0§{-Ç…[ ¨þøØ¸yµÆ“.ÿ™…ÖyŽwærÃøås,Ç 9M=Ä5ÉcŒwžÎêGÓóõaô}Ò„ °Š9áPÕƒV„äwêmpP)¬ öè6€¯cn‚× L·šš.^ ’A99S fv0Ýá4ù9oÙP:û‰Ú´PgdaŠÖB¬À™†³…`ˆO›ëk ñª¸7$ÒìãÈÎã—ôîjgÁèº%Ón𾤮nñtr™¾¤³±¦þ-[îß¿¶Aÿ{ç‡úúÕû׎6¼,½§¯'Þý]zÒ©“YH•%`ó¼BÏiŸPUÌfv¿C¤XˆJ¬„ÎFù HðZfÚ¡,Ô´éÏB‰Þx#AtÀ…ÙˆE:¡®. ­à|j(5B"bfÆq4htùB¬¿l ÓÎR³ÉǸrጮªŒë >ž5Ê1^Y «Èlhõ£Ë¦Nmlt8ÇÕßZš}mæ„ÀJSzZn ¿D¾·šÉŠØY¯Ž·˜˜ÛokÕ>[ZBó 7÷—“)n¡6N®°OÈNñ=!—¦cÚX9Ôk§ûSËJrt œÎ~3ìÖ%ãÌL+ ÖzEÿïïĵn¤­áH" €GÙ<2dÁAk0fe+À#m€W}¨%6àö§1M ÈÏø[jN\vGf­w‘ø”ÄNaN(ϯŒ“we~õȦ¶t)íu¥‹â²Þñgd·6Õ4‹•¥ò+óˆ› ®µwŒ)\ÑFÖGäC#"6²½waÀ=ÏÓ03ûÂäÝÒ‰ŒO¦T|îsð!OãÈm¨Æ4• 9¦:‘t"1DåÄl‹‹gURd±ªA‡ÓíÁôµ‹‡!&2@¤Ž“ ¡‡ÄóL<­9ÒšËÖ|òûÛ1¯ ŒðßuÉáŒgŸ­ žÛäöê~ôå¼kµ wᘓÁ•»jn¦Í5'9JÁß0[àbqJ/:õ€s  < b—à:¡6Q¾"Ã8fô¶Íw\ôÛL@§÷ÆGÏn¹nó%K¯ûÈ´¿·îxX|ƒÞÛ!ÀÁ{žócØ/f/›Ì 6+œÓOÊÁŽñ˜Aj’þWW4‡´¼êºõæò—?Ò]8ýâ9£k:N;­l)™³tÊíç®YR߯*5bTwA¯?ìugg…ò;i{h{¶‰“„ˆ0AH ¯Î„$;†AÝÒÏüH(4Dû0ð ÒèìiéÙ$w ØgÎèꉧN*˜rlñ)!»M eXF7åxÁò)yžàØ ³ {}‘€;˜æÏˆ«˜Ž-tíj¶š(yz›6˜l‡àÐFìˆ)±‹¦b8¡¹¤¼Á^&•Qvi¢Xá”Ï}´nl ·dêxhçívÇ §üW6-tÜzé™éŸ råPëvÈêAœ€•/6ú|/ÒK2¥ZÈø[¸•UcZ&6è° GyvKyoé”G«Ÿ©« äM|èOb4>+º‘æÍ°9NqÊ ÖŽ‡û1o_–’ÃÒ˜ *ª…I6sà¦e\M$LÂ~!áÑ­ü[²?]ÞñÈ¿ ¿$ù£ ¸ ÏnÎKÅoèýÐÊïz0cÀ¸T¬JÛ–‡ÏP ó‘„/x´ß{D4™½>ÀT~R.÷8«Np<¿ƒ CtÑÞü2ÛËbÇì²¹€tç—Ú_ÖtÌ* -ZöpËœŠpõÖy±©§‘[ç”ÃÏ#;…/íOˆQ¹E[­!ãŒo¢ªå -}|úgpÝ~m)€›4¡£p¢ëBG•7-@]DD»xPßMøÝ ßéµ K&`õ˜já.$zêBWïg)öÛ0˜TAŒ#´»@3’¸Ò/!#w¯Z¶dGîâ™õÇÚþúWBvÍ’s_&"Þ%~Ë"%cj€;]T¶×‡ ÌŒ0°H—)ì7± ý.$3 NÙ¿'“c„^ZA‰<"î|hZhÉþrâ#Ù鮳Ê\—/{ -ü­èn?o¾ü_Ç[Žw]qEç„/ÈÆH–ÜÊÖ ¬uȲIÍÎ&C·éeý~zoZðÞ„ \’ü’|ù÷¯¤^’¸$½xIzØ%™¤<Ñú1ê0Kœ@‡xÁ`’†_‰šœ.܃ÑÒ¦Iô,é%î´R¸åW{EOÊý—/?‰Xù¯ÊÍÚ²añ\ä²ÈÿÊ£Þ!aºÃÍA`ß]4 xD0#‚Y<"˜Ï#‚ M˜?Ò€Ùƒ ¯z×€Ã3B ”¼Äè`˜áâU©ÑAOHbs¨æÊÙõÞ [Èø±Þ®u““ïhµ_ev¦ïXÞÝWº«ukK]Þgç_rÑÖ‰[[Ç4e…Ý.…3Ú­¶…Ǫ'O¼¼k.›3ðUNÇœz¯ov(`3w Ó?°²g ÆÈHÜR3$¯Ã,/’ÝÖ×4È_5{Ç.€ðª*ÙùÍ`«;žC~§A=äɯƒÞ‰qá'©§û ?ò¸ÑßLjyNQ¬y‰}ø£à÷ŠgŽ»ñ#ûDäÜ¢wÿRñkúû‘?+ýüˆÚ/>¸ß0Ž–*¥¨DùU•(ì­Í-ýt¡@0¬ö!¨žÇ/yÇ òO½E¼Þs cŽ9šÆ_dg8Ô jLhu±XLÉÁÀ¶óз#T,§Ë PNwã'YG?üÂQ©Â5GŽlÈ‘-ý ù…tôàKˆ#}Ëž°†öÛŽ>2úÛ-ì=C)@@ ΄>‡úf:g˜sT¸_c´Ú@ÑK9ÓÈXÇ‚Nxgø¡çG ”;R ¢šˆÆï1h*&|Ú1ïíÒ«Í¢V\ýÄLbñŽøwù2íØ§{ ÎkË7Et6ÊûÀþþÖÛè:‹xÜ8 ã|âxåé†ô î£zöòŠè(&¿Ý¯÷“hÂ¥ >àðDr:—“:ân—BY£–Îm?HŽ»`òµ†ÓÀR«N²”x}ʰ>”èª"n5_Ü‘üŠy376?ÿ|_Ãۥ͹ ^IZ”pþÜÞQR;Éå!}wþoºNý°N!š¦ #?ujö!ëIK1\L8 ­ÁÓ͵Næ†ñ%[”Î<$Kg©2ºT+&ö6­ÙyƱö¦Ê —_ÞÕwǬ=OLžÌÚðõºè‚‚Ø(N–ß{®>ÚÞ¸u4‹Go÷.m·S€v±•ŶQÀUEí;¬„ fhxî%> &#FA%ÔÆbp’bpàÉzyGÒÑž`›ÙË+¼ð?ê©zÂ1΋a¾32qçö§ŸY!ÿiÓvḱ}̼ xH>F4ôkÙò÷H£üÛ5¤jõHÂ㡸wܰw\<Ÿ=lû8\êöñ0PÛ>ÞDlÎ1MÇ´…oh¸Eâxuï8~¸w€ÆpØ®¹>uÃ|OÌÊNáøï7qŸÈßá>±³5˜Ö«ñõïñõG¿b¯÷ÿ\³¸^DC¹^êyMìñ.q7ú^å‚2;J!…ÆŽY(-¿\!ó¤ÕðHOj1…7RÐzàû÷={V¬:Övð Ÿ §¾T~çüoâ'xœÇjƳ§Ó(.¼+Xà䕸Þ^ðµŸ×øAÖM—0çÒ½m9á. †¸´âÒ qiéÞÖZD ÛÛZ™ÿ¬äˆÍFžŽ³­Á-m(Ï+Êr†ÄÐö@ÓÆ®Ù™Wì}ûX›Xsƃ½¦ÙAÏw;óƒJMÖnü½XP8T_ü?«™ªùéš©”:BÄZSkÑúá|¬ Óî Ù@˜Õ ŠMP2H‡!~ìif³±“ö9öòx2;•þž/*œQ÷³š%#¬¯"z·bÜ{;W[6s³h@Ðh1Nà(Ã$ð'C¾KØ!ßš‡ùÖÃukÞÿ„¹ûšÒ¸´pø¢ÎsÍ«=í©}‚˜9˜{:}à³Ä#E½ùØCÏUn8ø ß²µ¹SèR]@öÉñžS¢ÆÕ†‚"–g­9þÚ·7él„\h?8’°{-1àhƒR§´(¤“r“eNy8ÃN@;©b( ‹™Í›idYÍ=bA'Hçc¤]­eòþŒZ&7àö%»èV'êo”’‚š ·l;°qÓÍÛnÎ!ÖÀiÕ£ƒŸ°b·©~–ä_cœ4ÉxüÖ¯ “'HEGé\y@;²G~ÍØ]Ú¡'•”ŽÔòuîc5NÙxFP›é7xw-åçœÕ‚n&Ál*þi; "¾&ˆø²8o¿¹ŒW=á0+¤_(% -¸t¡jµü,7´èÍzç¥xý0…5Ÿo„"44ªì|¿%ÛCíS¸ÏÌì€aºßâì·ÁôØÙ;ö2.Žƒd7ò€<òØX¬Ã§‡O¶”M’ÒX>Q"ú/qxVŠÞºÂ˜9¤q#K‰†¡¶ºfe<ô'VGT·ÛŠ7d†ôŒ{RÑ›–ÜüV/ù¦ã©k®¾ÿÛë£+ViGoF×m´\S5î ØÛtÞ4¼£½Bš0‡Y§ý¾’^ãRòÓûÏkSÛÆ¨ÃíÌ_ãèc(r¢¶(T@Ò8ÍÂ…ß½°“f…#†eL†»œÀï²ýzQmð¼~§gÚ´ksÈÀ.ñЇ5áʼ²ÍÖÄ›ÖÉ7ÁÁ«ø Ì™IÔ^ç§(÷#†4’I½£],!ËêÁÍLõÍ•¨Œ¬&¡‘¤dº±YàO<°ì©«¯¾Ó²îî¹ éýýÉïoÚ_WÅs&¯Ó»- ðOå 8vfÈ HÌ[´$°×ÒQgÕ¥Çõ<è/ã &ÀŒ5½„µ±X×)Yp?rÓ,® —’Èp’Šh{Ë®?Xå³ÉNêåçMl^²êå_˜±÷Ñ–9U¿]·`zõÌ¢‘¿¾÷›)#¸_ŽÚ{O .!z3(àW® ´?h «P²”™fA›i—ŠŽñX°2ïXˆz§ßŽ%9°- Y+¿¹ŒN Ædƒ®„;]Ý9ÐÌþdç§1cãD&ó‰Û›õÝÛ–MÏ-3[ÛôŒ3·5×nÏmÉ£×ÓGW^ÝÙ·ýðÀ/o–_"½´²¤dåK+‹™ÝQε(ó07iÅ)>ÕÅ)èmŪv‹†…‰lh{B¹‹‘ƒèmnäC±˜E¡ê§ä–ù½˪žÇà†ºª*j%_·ñÒˆñÀŽ¡Œó»ç&iÕ¯Zu¬í»ïÈkµ¿Ç:f:W@DhÒ(vÔÀ„0(\ûQ‘N ”o 9³ý0NhlN*]?žx˜:.£ë·CvHgqjýŒøšñï%²3$×€Û €±Û‘K^kQ¤êX&WkàRóðpfM^Ï=k«ë ;ni+Ôϸ´«§ºqûù…¾+&t6÷5‘’uWÌKse—d„"‘ÚòI£×ß¼±žøowÓø1ôLi¡ÛÄqAб),ú3.Ðù¼6ÐðòO_HQží÷á¡Á+”Hƒ‹±”¬,Š”ÆâÑ:«õyY¹O†„Ir&=“8 Åçgûºª”“*dIÎ1´l#®sꪶK»®]¿j—©vìÚ¥vÖf‹vÿ¤¦’:›´®«cù„ìÜi£A,…`JEwj,@uÝ;â0Ÿßðï}~7óù5-We|}÷UéßpR¯cŸÞqÖby“ ÖË7jìÎ1õ§Ô¶ÞFÛ:Üç‡ûü†¤Ïo:¹ÏŸœð–¾Óï¹öòý·ž"ºŸy†Îð»ï²ú„¿ásp~¨þ>¦ìuIß„æxª_N=šǼ,Ó™m³‹Rß]ZstYK§'½óÁcŸ’_ÛzQG¶ÂÁp×õ îu z¾®Ñ+á & bå`ÀäÇȃ’Éãlž<Î>*ôqÌ`Îâ^0Û ¶ìÕLq<¢¡ÿù<qLÎsk—¼œ»Û¬ÕëWÞ½AoÒ³è–MZŽ}z¨nA•ü")·—äß«ÎÃ\ä±KåùQæÁœŒ½XU×áF®§ EÅf×}¤oÃyéãyɰøÜ_ç1~BàfRDJ̃ՇÂZ|ôÅOF«1+Ä<Ü,æ1ê®ÞüaÌãÆ<¬)1ë°˜‡Ñ€~?‘0_Ë"z>J~{Ãí÷?ªü¸«sUv]›]äà±O_²¯6—W±êñÔ«ÎF‚Æží[¸ïúó£ÇŠX&Áj‰úF˜[iªh€Sµ¡htÈÅîf}^méòú8Qƹ. DÆ-%4 s3ÂÅ®B›„äšÈ÷âÂÜäÙWÂ&Ô² æÓ)¹öê¨_ò{Ñœƒ™¯¡ŠänKÔ°6èÝ\,ÈP7¦¯zMíôê:ÏÞŽØšêŽKwg8ÊÒ¼ÎÌ GÆ7áæ1}\1]ri9m_U4nY Pú™íÛ‘$ýì,É.‘É&eÉ_dµßÖÁÚ‚ûX_‚:<«Š 7ņzHA‚Ñ¥8ŠüÁV¬tƒã§Íªá.?¯dþ5ÓÇH$'T_e´kT_ß¼ fÎ"µo>‘›ùðاODg«{ú¿p ‡n³ÿ1‘–]ÛÖo½@é2é;ö© Œù—xϬN>/a°D‡GEÄÿçQ‘ÆBX c›ÜÉF*s#â¹sŽ‹âÃ,bP*û ÿ£XˆÞž aQ°7–íU£ ˜Ñ&úѤdë5ÿêk;f\ó²;zç‘ýò³yÓóî³Ü‹ú¢½?²Võ»b`vÜaÄý<Ì|µHœÀ®T³eX¤‹Ä!ÑæÇÌNüAˆ…´\`¿eýÚ=9£êë3H7ãýs~=Qñ¼ò§p¶ãøA[—ò¶NJ&‹)qC2bÖ:ûσ´ôuܱkÿìyãÆ6ÏÝ}=Í8=ofƒl£w©ÆÊÇ×4cÄç¤Ãdà¥%âvÐÛÄ­A”¡ñ)AzæÓóÏ Æ¨×jSˆ:!’Ïâ Ì_ÍÉ6Wê1Ëo“°ûÚ%uM¥Ëß¼ºaܾw–VNϯ·dMÞ¬œ¬Ö·Ý’ƒÜ>Ÿ‹¿¥íu ™Â™Ü‹S1x%¡v@:¬>‡UO@'ÐMê5àb™¸" ÇÒ€Á*Õ&ã@¸ºü,ðapTB ¨Q0|H}N>µ•°83­çM4ÎYýF÷s ­Ï›ÃkddvŽè~ñ´Mò_¾iídòm¹¹íºrÕxǹ¸\JD,'°,I†ŽüÙ˜v`žGÏÌQNÔÖ“ƒYO~Þ%òÇ0 Q»r1ÀT¢“$.ûϯ¬ExàƒÅ=ÎéÞqÿ?û6_¹fúœËß*¹{Á±O&§L¾ZÕ=_ÜCmï4СÆszĦC¥Ðú=ÖYÆ,Sޏ]üJÈ&ÐOa7mRE;U´3~¨¢.ëÏB}¥¢ÞÊ‚…Y¡¬ü˜GȉkPÑDøàbu°ÉËâüj– éäªÚLÅ–T©Ä,% ®½|[s{ÙœeÓ§wä%¶×·Nk—Ÿ·f|h}ZCi g2¥m¬w{“vøaÐÎýW vÆÛl j°–öV;Ãe'­T„±ì^@ïYԽűM^Æ"e—‚ èe€rƒ‘÷J'’÷BÂ\ÑÆË¯iºdë SzøH…ü‚ëÎÞÚñÓ®?ûbdî]¸fÉÖ¹c›éœ~ê™h?Δa´±E p;æVÓézqNÿñGœÓY?Ï!/0¬ð¬níoâ;è§ᦂbˆhȇ˔¹Fàù‚^X½~؆Pa€•oáYæc !_2 q"'pðë\UðAÑB­¥„!Èy\¹W¥ÊÑ·RO[¦ÁHfÛ._vÚ¶¾9}f] Yo‹Ž¶uH¾²ÛŸ¼eÎý½äÎëÏj®/\X¨žÇD[# xcl ÷4äJ¹9À‘qB½?@bø†¨M—ØùÂôéÁ£q±Ž¹X<ݬÄÓÀdö©' Æûñ¦£þŽÒ‡–{v8¿Y½÷Â=Ä®W_÷‹î|ð®™³¾újIΔ\¶ÿ@ËøZñ+:'§aÝ3ý}®ÅÐp-rÝBÀ¬Çý›‰õÐã¹®`)µí?ŸZèAM¨ßµ ª ÒƒgR¹ðÓÞOâŠZ~ùÖ/o2ëáØ§2L8ÃÅå ¯ ¹¼.Ýbd²×¹°Á-+ÌêO‹)m&+„p ÑlV¥(¢ ÙÙÀÿÝü鹌¡ jôGbþQ]¿öÈáÑ«?saq‰Ñ9h0††~O᪹‹LE­Þ :Ë€Mèr‘’9‘S‹,"iEÆÚw!aÉeUïZºaƒŠ˜öG5Öÿ"0¹ŒÄøWz G`¿'iw§m)›˜—kÛ—›_Ú¹§ÜZö)ï[WÝsÉ’§33>ÿ<þôi×ôä-ºõ£ËZËÊçã¼M¡{ø/`§“Ýœ5Ü`íÒ{ÑAõ!æê‡LiÑšðÈ…ù‘[ÌÜt”L¦G®ËÎ\¢™\pä:]j¨’¯c›ƒ¯c³¨¦4%×X…k™±©ù+XÍ#×øõ¯‹îÝ»gÿMèšÑ ó§L™ßvú6ŠyM|YT½ Ï÷c?–(ý0¨ÊoC‚Rò "Š\k²üÎP›jgz¸>—ÄJ^OÚd.ô†6SXmrù˜¾'=ƒm·¯¿Lþ¢o:ØN“É“óV9·Ï›9÷þùäIùÖ¼i¹˜Ãü\S*>)„ ^ƒIºj‘¨Yj9\éÔ"éόׂ¾9ËÍ„˜UÂÈsH2!gŒÀÂ4¤äð×&¬V-G$• –d32ÐA3\Ù[¹ºñýÍÕÑœ¼)šW^!“¦—æ”ÔÍ”o͘ > ¿Ùuáùι Ö-_ ÍÏ%Õò[ˆ%ü\Ü@ï«Lá¼Ôág–•…öÃæ XU¶Ðfbe²#0“ ëŒØ´ 6--m&íI:òÜéH²)°R[j'zé…mà :jLÚZü£Ýät´»ZwM´žqWÍØ¬Ü‰æ½{µíþlw}]b¥¹™š[§l­kl[rÃÞ4vÛéo“{\#bþÖld<ãÌQdX¯hTJ»XŽÖÈ«DÚÆ!jìZí¬xËScÃîXAôËϾ¸qAùæÊ¿8¿òœÿü׿þI–~­úI¿Å³Ô.Ô§>FõGž™°¢¸4p+ê~ì¡Ïýó¹Kg•¬*íܾ²¼Šûè’‘`¹Bû Uå{Y´rP0X¹~–Hë'±!Ik„Bz¯R\Ÿ0Ù¢*©«›M¤›‘‚X>§”>¼êËÝãñ–öëK¥l°Vsz“ú}ôÕ’õ† «›U>Z$Z„¢KX©`»ˆ;BwfâöÞÎo®:»-°4}Ò¶šö-ŽŠâýr?é<ÖFŒò×Ä$CÿþŠœBôê}ýÖíø„SùŠ¥]„ÊC=ãð2{!U8&Ú”°Ij‡ÜìÖK/O¼$›œðø`&ô^\£*:LˆH<⥓ѲuùÌço_ÛR0?Ò¸>ÚñÕÂ(½ôd"ûtÿéAe-ü Ïišµ0Ad©‡]œ“Ü‹|ÜCgç…l«""í&ê$Ð;°U¸4 ¨ÃlHªÛ®îÝ#V^2ýy«‹¶\³è̵ä²gçÌyV>¸màKœóÔSêý3Ú>áW¬]ƒ&³M‚õ+4­ImƼ|l1Ôoÿkšð#Gt )LׂóÈáG×þµ…üÌ¥sÓ%L!úŽñˆ0HŒ'+ÖˆÑd¶8¥Ôº¥á½ ?ÞWe3о.ï=G Ÿê)çOl=§µ}õ¢ydä“&Ý(¿ò ýC_r Ï¡ËâÇtüýB:!,6$X¬ðuc$úûÓ£Cj’A!³+ƒ@×щÂÊPõÁéêñ3A2›®Lö[ùõr®&ßï*…L»[w®%¯îèáÇo|ÿ9|SË2$i:j£Ž®ûäƒãøzzi"fìO;bOá=Ó‘ÃGîøê÷øž­´ßR énsÁQˆž[ Žj„1Õ…iu0¢V›ËíñÒÒX–púÙeÈ7â ë7£?>q{ßrhÖ„º-…y«óFl.šòdÏLØoÿnÖ¬ß%WýzJ\ð»ß±Ø‹ÆÁ÷#bPÐ1Éý˜ðè?ri¬0¬&/Vß•þ¨bD'w%·1¬x &ô¡ÓU›9¹pÜà/hÙö·=äÞÆ’—룫6·¯%Y3Z­9¢èþóµ“&]+¿ð2ýC~{É%Û¼K3€|1ÍÃgQ34³lH˲‚²þôׇŒŒ8`ŒéPG#"ñ Àn²PmBÌ⎵[… Ñv‘±àUVÇDÈÑUå¦ÐËÿJ¬X=R=rüôW›Ï˜>#zãíD”Ÿ©»ÿɺ_ïë¶n|H3oþ¦Ro¾/HëxJõ˜LW  «³ûaWu½*ŽÅs4eØþ µ•Dff@«¡­BÂc‡Uî•P'‚VM`h‰G‹-äºa“×÷eI…eÿý•ü°˜÷fͲîòîÁ¶@FpÜí…µ=V3´wRe£?ÝgÍ•z.[{ÆíG„\N¿ÛÒ[£¹E ©]:ƒ6ìsÔɸÞvjËññ´Së™þäçâ'€¯ò1PäH¤¿ÿæ(â+‘׿iÁ<˜¬%Š‘Ú0K¯Ymg逤CL"EO®ò­m+ö{f¯A~û9z?EŽ´3­3=ǹsˆ8Ž>#ª<ƒÝ MÐÛOò„I¤~§^àe )ZœHÉãó¯ ¬˜T8"Ý”éÔËÇÓc©ok]£uzäÚGêôh?Ô|猈³…óP¿\$~+ìG;þA|o}oŽp©úÃkÖRßìŸÔ®4ÒS9$<Ânñ!+sGƒNÂfâ³8K6»¼ÎBuBU€\°C:ÖtRÏê=ŒŸ¬†-_†ø¥º„¯žÖþ#BÂã§ÈãõùÕÚLXÃlq:D¯¹¥´ô¢Œihá%|tR—äs(_2s9ÁˆsæçøY.‡Xk§-¨ãõÌÜ¢ܼ©YR8{ÁÆÌË}啿è½dÆ£ò•w!ßÊïoÝJÒ·v²<σ¹=c•±zçÃÀ!ò‚z®å ß¼pbˆEš³Áìì c\w7Ú‚´¿wiìØßËSûëÓ0pKºðS=Ž?òîUÃzìûé¸Ü@ Á:¯‰•†,Ö@ZÞ?è¶;Ùm IévË•éïܺlÑ9… ¾77Î46,k0ÎÔÏþólEÙìLù‰ƒwlZ ï';Í|þ}ÿSŸ?þöùSè‘5g¼|Ï~ù_fM˜6³­C4õtvöL§ß$ŸN?óù·¡íZõùef °~Rú‘ ú±i'óû½ÜïG†Eˆà°ú@mx`xà ÂpQSÇÿ#ó;S÷oÛµÿý¾ÉgožN®ë,*꬙s_¹N~µµ‰cXïDÜr H“z-×¶;Q¯ Ä™ôÐ9£ÀxÎhVT>à`gˆŽêa½@]'2á[X½²NÑqœ?RÀÕ\â1?+‰û׫×ÖW6tVOèX»&Ý¿aãœÈCt·¬Y3~ihi›õC2OsöÂÌÚÓ1w’#^„<¢aagý¹Œ4,{LË /(t–h±“¿‚ZL*$„8ÈNAçÜ I ?ÁYš¢›Ý[#M¢Îý;›ö Í _RÓÓÏ¡°¬_HÅ"£ô Ћ­— ×Õoî­,oì¨Ì ­o˨+sŸ¾©=³á²ºwÄ¿*È¿â‚çå¬ìÔÅÿAæ§ù6OË{°µA©ùÓtÒ{sLjÍŸ ƈ»#ÐÁ4a¿ŒvÄ;‹¼xø³t¢bǤ0]"P H.ºKo¸a'Ú KxWê3Ć)ù Ó>£…´ÝˆÃk¯!Á}q/bºgñÜ·†»Ð­`Õ ËI¡‘Gvpë£̲ZL&ø®¥³kµ .QP%´é`U–^°ýË'‹Q§|Îë¯ SíÎsÉ Âq-Õ´-§ Lm‹ÈÛ"+?^ÖÓ°¶˜~f[ât;ò¶PŸ®zâ-ì{mñ[[.~í5^ßEmÞû±F~ã õœœssÈT™P榥³ÒÃt ¯¥Cj:Ö²`éÇ{ÒAŒÀ†úŽfêeð¼àÜ›E1rKZ–Z $…}³ŠþNCùúÅ߭ߦ°1ó¤‘ÖŽuOZCòù¦äóí6åùZiXÝD€¾ïà–ŽM™£9$vÍ»ïr[ãiäø8õ„~Ó»Yã†~ƒV/js#|Ë-ÑûOƒèΤ2xz¬Mô K=‡œf!‚< )ZÄe|`£óeØäÒÄ+«ãÎÍ}7þëîû‚ñj¨°Ù·°Z¹jÿ~ùYn³\œöóZÁJÏ'3¬\b¢ç“Ñn3Û-•0êQYÛŽ”vh¯ÑŽ"Û?»½è?Î|ï2N/‡1`jYÂôÄ6;¦ðÑÃÏÞ:†oÛKû­¥ ‹Ù>¸eý„Õ™° gz¿¥”ÜÇâ™)u°BJÞ<¤ïm¹²²ÒÕ{í–Gn½ÖUY)º_[·îµ¯ä÷>Ù°á…#ä8WË8‹¾sZ¸:LjZtÈ$¹ ó °Çî¼%·ê-q.+0ep¢LRh¨¸FIn’ÚÛ·÷<±ïƃõ}óÇŽ¿6YW.ú¿¦m]‘l«Šž¶Y¸W$ €hXn4ÎMÁd{MÿÃö2„LrX¥¢Ž¾èºûº+nºm ½O¬ê™!-ëùCÅ‹Uʸ~ pÚ†×ܳšHK²îÐ7 +®Z…6AaUáø`˜¦ŽÙWÓ¹±¯ÿž#³®Go–?%n® ùq4ç@¤mxëqRÛ ò6NÚÓ¿kC8u¢Ä°à—×_|íí7w÷‘ýkx]ٯإ¬¦Ø`xXRÎ?»¢q;`ÇÀn†mäT]C1Ê%V¸ÜíaXÒ~òÚbE·ü,ÏxE W™6.;#÷#®taJÅámÔ´&¥6ª?h6Ø’ÀÞ“´ üØ.ŽâoÙäéF ?BHËÏÎÏçÑÇ™ÊÛdJæaŒ°v¬ÁÒ… Ü£vF ÅÆÌÆŠ µXò7`D¨W= 6. Ö#3@Ê<› Бù†©Gräw|ï}èÛt¤´g,€ŠµÝ_v•o’5ÀÌ@⓹M†5Àc¸z‚{Hn`Uß=0åÅt˜?óíP8›?;s@ÝR¬KC:’M…•Ø-H–Ϊt¡)i ¤näà©4êÒ$ & ²Z :FÆ¥Ç SÁ pÔ&t~(…%Õ­átÖ ¡=rNÝÎÆ^zXeV‡Ê§„F…v­§ùu¸k¼|ôÅ~ßTïx²$!É ±õتó1×Ú·t^ d}sÐ7ކ° B X¾é¬oÜ]3ò2Õô ¥oè›+¥o®í›Bo†}¤õpÀÁÁ’ r]ýy,lh̬vådO¬d_|¾è~=8}âw/¥}³˜F-·ÿ‰Ü"ÏÅ:º•â!ñi!G(†Š‚lÂ,?ÆËg¡kÖ[” È>/ºÃƒÆläå+Á°#§é¦S5a{;âèç§OŒ¤ý‹Ð‹þ3Oé ÑïwÑ/ «B™-!©Hì.&ˆèu%Ü‚¤ (3•s¬šé/-+5 ¾Q$Ÿ1Û ûƒ—<“òsôñ܉¯4]P>»²9§aþ¼zsi×Àܺª¼ò®YåáüßO$§UŽ Å³?øpÚ#Ftg¤y\ØÒ»ozçUg¨k5+jº}Ǹ)%§dC§+¨­œ-Œ"DWàös„`Œ”´r‘ÂwÊáCaæ…À{Í%TÅ\…aHk²g"_}us]zX×€?-Ó!ÉuŸUpxüö|È% Xˆ“‹N¤×|XôþpX >±i÷ŠÖÙù¹cL“Ù>ã¦êhNuSg}nè•f²4Ø ¤#¹êJ÷”­Úú5/­\ޝio0œ¿|diæØ’pàÉ2½'#èTA%qì” e2ò CV&ÙÁŸ÷òºÀÎC“-†‹Â+ µn?®†Ì[ iP0{Q‹ã§¨ à')ÎÐÚžÀ:i÷Êõ·”(ï^qðŠøÛ¥í5iSì£J¥yŸN£s;E¡¯íO+ bŸ6s>±Y ì‰Tæ  ( ,éYkOËC·|ÈNÀnY 9oL3‹sÞºÀyË4Uõ<ƒ½N€Û°¤²pÑ#õ¹E½E+ÎÛHôÓR¨p«l¾úØ« ߨ2ÇÈiMïÊ»'Ô!¨ä` +0Œp9Z±¦ ÄÌJeCʱ¾ÊL½•¢e¨ÖY±ëz¤x¶óÏ­W{ÅøöíòxzU‹qÄäwa={v²”ëdÏ6ýoŸu^Ë®uuc©×ïé…LúŽæ ‚æläJ©/WpÜ_ж‘Hea¦ÑíT5ºë¦¼ßÇÀ—ºR]Úbµæ5@u 1""1³áY!—×PUòľÛïûì#Ñ-o"ûòeéÏxŒ m™Œv妊‘Ô²ØÍ„Y½–¤ˆÇÄdW¯b°vÍ& +³ï •Oÿ寨ˆÑ©þ^â: däv8b)ˆh/ÞTÂB“‘ªØTÿí«ß¸cW_3ïé§ç%±ï_ -z€å!!eaÇ”£V:Çíü7V‰ÓS`=\·ïƒéø¶K@ž[|Ëìt΄X|;u2F!e8‡nU 'ãéE|´k›¹jöo¤çg+™³cñçÔiý׃ºØ:éâœ?çŒÈtQí¸{íV…‡È€þ B,ˆ½ÒYéž·«•œüó@Z©Cv¨h 8VvZËÜææõ^V¦H'0¥ZÆ$ªœ ÌdK%d£oýó{ËWxäùbÛŠrç+ÛX­{¯…>Ci»ÑR›/þïšoýxÐjÒSßÂ’,QSšüÆVµ¹Kseý¼”ܳl™ü¯Q#÷ Ö¼K| q+…R©ßU‰‹–úlpœzR™•œ*³ÈÉYa¯ßVÆ ¯0æŽËÌ…¸UÐÿÖ»8Ü&…r‰ù?úœüZ¤]×l8ó )’/䔸ã3³Uþ†¶•Žì€K—lë0ñA¥­Ô!³™AèÈšD :5Ø>)½8•ÒGVùÈ[†Õ˺FõMØè™£Ô?6E>Ä!„ H–ûÙIÇ0w€C妲&åîØ°éz¢žÚ¼œ?7þP `°DQ‹ ù_‰C±Op¨ü´YÕœ¡ ØÀ@&ë@E¼±|ÄéželÄjâ†O>4¯Êgš5ñÌ$wVêóËÖ"CŸ›-5 ³ÕIJ ›Ú6ª:Ú£Y(£­wÃô»ØÏFVÙaŽ¢Þ#x_: ÂBV[åP†˜u¨Jí s]_k}i¤¯/=«Þå™zŒsñü&”šz¬3š5³“†‡.°TÃ!9KI.°dôI8˜ †W‹`à÷ƒP%H"U,cu —+Œ½½¢ªÑ->ü@IOñvÌ¿$µÔ/ÔFgÇ·.Y{+™”ÒE$¼QUÈ‹<ó"Å%V„áÕWûfïhíìË-l+~à”=nÖTùÒ“Q%f¸íÏÅ·¨íòÝ£ÓÍ`ä˜DèPÈ€KF,â´ÄX;2¤c™%z•°]àcâ°Ijµ`ùˆ*r˜¨&‡+aLçÚ.ÔŽ°ºìóG3À 뀬÷‡Q²‡B˜€øõt° ACùÅY‘VAN~^¬}­hf¯¯É¸îÒ¯uòåbû¤¢úÐ¨Ž³¹ÎØÓNª?¬Ø4Šª.Ï §WŠ7ûòçtû¼S&]ÝT¯Éxêì>&Ï ^?²mÈ;«ºaê[~3Ãé±" G$rˆ…:'„øX䦌…AJhÒQâ1aJc Y’ßÁFcÐlç M@á„7ÈAZ1¡XVGLJ¬d+<0ʘ”’¼FECÝžVë*b\!Êô{¢Õ†ŽÍ7n4övê×ÅÒq²¤¬"''½øÔ—žœí–:ÆŸµŠ´Æ5ŽÁñÐà)bƒ[Q¾4úsÐ%K‘\#X™? Gå Ã1"¹@J¢ƒyŽÆâD†ŪFòá©Jž¸TòèR)¤>wà ¢´Ó#©W“æ æT€Ûbu¢ë&•Íü ̆±ÈÊ+¨E*eù”ýÔòáEq ˯ªŒçk~r1•×tŽ››c-¹xù”}öŸZV#]¾hf•ažq\]{Y‘p´)o`¹™+²ˆÀycOZð&nWZ °¢s" °H€?‡Ø‘$¶;RI€+ú;BÂî†\&¬r:`ræ!¤&|å¨ÎÀøMS9-0 *f`ìÖÁºÍÞ?T‡×´œ&X;hH RjS‰üeñâ¶ëŒ•ËšbS¸ZéZÙ9»…'¬uSpó+SZãyIûð¼$޾O«1…p“ ‰™,kJ.E]Þ `Ìøo®Ÿ9Öµ’T©`+š´+y• ò¥´‘¯gsTú©mLRyL'¶Ñ”ÒF+S1Ç 0‡™½ 0%¯’‚=bÉ•¥gœ;ª½¶µ€1%½Â9ÂñW“ù©Ѧœþcù)5Çr¢eiK#—›2É'IC±)¦'‹º—ì*¬‘e[p…©ùÚ–ËÑwœúSy¨ŸJ>ýTCXÞ q¶˜té[´dGaf]puaÞüÂ[pÏ:Ñ/<Át¨Îà€4»i¸ûçPš‹I¥ŸÌ Œ€Ãšt§y~¹àú݃¤ðLêg@âì<06Ã}À?‡êø¥¶ Öƒ¹}ÀÁgýç·Xú–uŒé›ïùåÚî‹©ó7ë¡;š"Ïûô ‰¬ªàþH=ïÜX3µ‹Ï—™!ºúµ1E¨J¡ü N­OQ30üó=µÎIs$áôí—ŽDQ“AV…S“„f˜CúíÒ€èò2µ6¬ùaå—zƒ»6…« çX·¶&¢ñy š†üçfLy<Ô³x}a¥‘˜§FºÇ’#lŽð•Ô_$7“Ã[»«ä7‘köM‹ç¦ôMä}S™Ö•eå}ã¤koøreªÊ—<ÚïL雨Iég\ùt­ëÄ~ RËΡxª+È/€nydLÎ -Õod,Y²² Ö¨×5ßÕA´œ† ô¡™ -tÖ¤{U®ŽêE‰Â”ïT°/@Çì‹-̾®ó˱ö¿IDû"½Î>½úù‡7¤~>¨|^XÁ? ý|Ú3Æá÷¥Ç?×Ô"¿Äí#“:H»U¤ç¿’œ"hß §ˆîw…¬Fx*ßDmk¿°•)^‚tì€EÃhÔ†D—ТáãAƒÓ’T rÑáBZ~ 6)/"dªy~‰Î!,1Æ åò²|¡(¡ìÄ-z¥Ô§2’-FÙ lp ³בï´ËÞhk‹îZñäåWÈ[.¾ôÞ1GK¦†Ã‹zâ3‹Kî—ûþëðÖ¥ÝÝK¾:ÐPs iÂZ¥?ŠŸ¦ÞMÑif¼›ÈÁÈ$@‰œ ¯Cg¬L´1áæA2õµÙœè‰!~\¤VNBœ é{ÍÉn0´œ¢˜–Gã7\£!¯šïØÔ¨ïû>/Š>ü|« ®‘+ñó9lŒP4 >_E ½‹Wž¨2€n»Ñ¬´vޤô`¦`ûö(älŒþHÇLì„ñdÊFàÐtôED¼µ¤6E€Â›:¶º¾f/Ù¾g¼Ã§íº³S/ßI¦§ÜQIJoR8¤-J€ÃX«rICè½µ¥–ýÊ#Ú)7«:`—"'ÜXA¥§>Ù³Lÿƒg1îêS¯w}õÛŒ¾öw-]Äå8Ž8§«÷¹øŽCY6ŽC#k[õs~ƒµg V.C×4» VYöPþ3´2!èþ˜#:àÁ²Zëqáw›©xÀ€TúêL²R µó4º4 ²¢ÛÎâ/š~~Vœˆ*µt…~;TTŸS™>©£öõ×WíY0ù>(¹(TªY^»rÑ)ÐBÚ€~ˆ)ýмFÖë‡ñ¤ý0b?Œj?Œÿ¶xÀlrÕð~ާW6µµ‘\ò3.»`ÞäûæHã‹Y!Ì‚KamÐñ ¦s2÷s»Õ7,Ë«aàÈ£ Ög…·³OšŽí~ÓõÃt¬‡§cOyëbö¦¯ÊÆÀðt¬ÿÄt,+NMÇ+¥@ûðÔ¬7¥ê$b!å{ûÕ¾}o|r¸kù…ëgϵ–ÜHÍÓ^É i ‰QþFÉI5.ÌÿlçuÞ@LÍ×âHèp$ú=¯ÿܽ |”EÒ8ÜýÌ}fŽLfrg29€f’L!$„"r ˆ·"**¢¢²®÷¬«¾ÞëÎ$ÂˆŠ·àñ×UƒâµËÊ®"«è»*™|]Õý<óLw÷;~ ™t÷ôQU]UÝ]GÌœv@Hè“÷‡¥D®ð•gŠÏ„z}Igˆ?`Ôð bËéÒ‚õ¸ê ¸ß’J ð|éÚwŸ¿iöâ+Λ1+<©4²åvþüÐoÄQ½ìå—…Ï×OèÓ9:ù¾®©`ØŠt6xx“C™CðþÂã@Jü2Œ¿Há]—›Ñ‡1#.7@ö‘Õ«îØ±ù÷Ý¿»lí£±mqÚt*u3¨~}jâY'ÿyôÅ•_ÏÏ¡q-Åh*Vî¿¢œŠÁõZypvúsh°Á½ƒß¹hýŽK.ÿúå+îî¾mËáé»·mÛ=ýð[o¡ŽÌþùÈ ÒÎ=Ý1×­s‚8Œ:UNªHÙ“78 ¹ ² ¼jGRà….‘Ý¡îÎç—ÜŸøb{ƬYKæÎ?÷ÓUï@óÏ«þø^ãAîêqDοû>Þ³ƒ·‡‡[gB¤hOñ×¹ˆ\ u§•çeÖåŠìAQ›³Ë‚üø)©­°¨˜ÓXËêÖÙÄ]ˆ;";gˆ¥¡ñ._[Mu $½zmyyaÞÌRÓú3.›°´$gFÛ´©ô3fŸX;Ö7ª¶ãVDô¨ Õç´µŠ{í.¼Çj—mú˜ÀO òä>€Ót\Jº“¶éÒ!8¼Õ^¯x‘‘÷« ¾B>·’@ðÙÝ7äÍÛtòey?»ý÷4Sj>oéém§d>öø¦s–†*…ߛӹDÌi' ˆ1þˆH’ÎÁ«š“¯ÿœœŽ£Í©T†×c÷®-*?êªÜ17?rÉ%18ÍšVÕ–} Ó)gê8ƒQ¹SäÑÍ ƒ› ÝðŠXºž9:2¨œA/ü¾8Ò¦¼n@úRo.©>‘¾T‡‰KUï$¦õÁÐêT[Àbi³Ý˜ÉŹº×ÉŽBê…Ñ׈¼‡9Ž» o¸TÿÆÔéÕfc^]]‡¯°µ÷PoÏpdy‰OžL·>|Çï§ËkÞÉp kF_›\¾fät>auŸÑ·äÌ*Ö,bF4½ùs®ê’“©CÙš³vE³Ý™Y>¶fö¯zÍšL~÷éËLFHƒ ›[µf7_³OY3Oÿ‚F¼ÉÝ‹†”ÏUYF‘å) ˜¯Ó/:súœFKuæ°ß’Óþ‘8;=cÒíl/\sõÜiTsé“còsù›À7Òkè{ ûRg(!¨å—œ å6>éy …„ó _N¸ã…ó ”x;ÄMƒ‡ Üé9„‚+G5Î.&‹Q=¸¤, ò€†?~ýÚõ9é%EÆ«ôs.¢Òò²ŒµÒÖÄg4Dׄ›7\6¡¤æúÄÇ"vá;¨Ó‹ÜcZÆì´xÜóÀ ™æZn[d7ñk]H#Ǿ¢Á÷<tg±ó·Lr)ËñjmÅÃÝú•—Ÿv:•F¬Y“˜w=#¨Ë¯\¶ä±7ex'¾Ãœ.ÏW%q¾ècÇânÅœÑ|Ú-Ìq¾Vþ²‡‰­¨Yx­šuÌb8g ;Іè®ç›BÆ;õ g½¹œþþÜsßV7olqû™u g/|Ï¿‘H/“"Ù˜{(‡é/& OKO÷úM6LŽÒmó›àƼ˜ç"³C.²¨ |’õ©!ˆƒ% Áðô\lëB"¢|`¿`c‘Žv\6'Ff)½“L‡ÔHum¤’Êþ&ܯb$5 •¾S]ZR{ʉ“&ŽgÕïj;ç\{Ò)§LýcÎ /6ó®…S—Zß~ÝË'›ìã.,ŸW^ybmygÙùK«j›¦š]-ÇÔ~P*aë\Nº )÷%â7éà)åñš¹ç Þ+ÆzX¡+/-[/–&›â0.Kò1²oLÒðH¿ú4n:bW–YIÃUè0RàëÒ+ë*©›2~tS~Ë3ÒsóZ;?7Úl»»½cÊä›§Ž]ðÆc7ß>r´ÞZ7¼ÂßÑ<­´.'qAC 8«mê%¹“ÐG6ñ}Î…­oUx¢ÝLÌ"n°+g×fî"ž'üØféI3wzj.aùAÜ'ÐÉMÔïáI;)O6÷HÉ0,ÞÆ¥ù"ϰX߃(_ÛHW.¬Ïˆá¸£Sìâ”Î%­çŠáÿìm´a_¿ŒJâ˜ÍMQ©ù•èâ³ÎŸó£©™–²àÀͦXN·3¡ìGþt¿ˆ@dñ†E6g£)–uDåeóߟNQt\F÷® kÿ‘ÎïK þ´¢^f²ó®MŸÉÄÔ¿  uk f7Š©ÕŒ&3c¡ºFë2bSi@p¶‡ƒ}À]*”Ÿ´|»ƒšgÍYæªË—/_·¢¹ÊlΫ«eúOÛχ¾ü2ñ\âêJ¤gïêXû^ÔAW [nsF˜‡Ióm¡‰ÊÁ_¨;Î<\yÔíèv¹lYìßuÇÅÕ§+¹§RA›ôVTõ¹n#Œç ¸˜¤Rc›9íª%«®^±xêưÙòq¥Mé_~™zo¸bçhÐg0&“¦m<`¹¢X¬òˆgðä¦Df‚%ñÇÝ4 Q̳{8ìœüA>êêåÀKÈx B.ů¹ÇºøŠõ×m¾·sCMñ¹g—J[žòlbgâ7´¢íotæWü³½¯PSÍä7Pþ25ÿ2ËR"-q/î‚ì¤{'ßMÅ%nÊ *•[,ËA06*†ÖƒGþlg—Ùv6LQ+1þËgGäR“ç ÚÏ2´ÎÛ‘qîÆsW_·Ö±æäÖQÅÓ†Øs²*ƒKÿÞòÙ›‰ÞÄ¡WŸ_ñíÈ™|OG^_ äzÁbý_#NãXóðÖà­j Å-v—§æŒ¦cœ ±&mOÌkE xòÈâö•æPWº¢§Yáøœ‡X«$;÷!é ¦¤ãëyÌ"2Fæ8cZ/¿pcÒ¦‘†ýÄ /Pý5ƒ|Ù^ª}ÑR:ßyßu×Å;ƒ—Ûù4³`ֆő³?këy?ÿ,ÙΪýDyÏùžá+›I—aäy¡GzeScà- œøPžÓQ V¶q‡ˆÝ[†¹9„E-¸«#…E‹èªË89ûTƒc£d®†Û8cÙ`i›éŠúñ.Äk,¼–¸ºÌ.Ô¥Ùù9 ïEÈlºizfºBººlùÐ.àdÖó<5x_$ˆd:Û ”j#B/Z;ÖÍŸSµhé5egÌÓ$þ*µ ­lj{hQZà ÍÈêl]^pÔÛ[hÑÄ’žòEÁÉA×o×ù}—Nh=cÞzý¤!óƬkk wh#ûN”~B¶Z ¿×öJç -À´>ø‚õ}¶#†ÂïSÙïï`¾©Y~Ùæü´÷’ãˆ8úÇÓH±£âqD”ø10f„cvùx)à•¬¡Ôàæ±DfÍØ8ò–ö{¦Î/YZ·§ëó¹`ú¾¬lZåÉ¿-ŸœÁ£0Ù/üÔ[Ts‘RçbègÓ5p.1«]9¤Ì†G©=£öÂÈíES ~ÿ †iòŸPܼªpbq Ï<(ËÐ?`΄W¸'m´XH§¼/*OÜ”U¬“£â—À-U<—ß?êñÌÆØœì Rú 'ö8±ûrb÷ó{_9½ææ1½Ûá›/Ä[]1>g{œMåAŸh–ËÆ ’âàuëäiD0-žŽ…Kól<Î×¾hXÇ¥#óª ¦•Öçæ_\k2æ×Eø±>ñ¿þ[wE¦Vx3NðäÑ¥aG"*u¨Î÷¹Ò› Åä™$ìð°³Q2³Šá4eT‡[X'C ³’”þ‚, X¸+Zèèö0±S$ ŸKÀ~ ‹9]°.Y Ý2$Â…lÛpP` sÉ 3re.(âÊ.ËM“‹67\Ù>Á¨æÜˆ«0|C¡c“Ñ\í+Gé9еý>q- ì‹_b´æ'· ºÏUlẠÀeÊ&"û¸ši€×«‚úùÁÚ.p°Îå‰P,Áð¢"\ncš‡{ IŸ'Ó º‰eƒwN}̤¼mˆ›ƒ£,¸rÍú—Œ™;oôèœH^prÞÈœõkøýAâ_ý¢0zAãDnËùF+…äV±ö<Å6Öž1øÚý@6Üw»¯½]K`íy|íy<ö£ì_‘—/¯ÝkÏP­=#uí~Œ« Ž„o~‰Àæñêk¯îÏàêkáÎaÚ{zT±K,d®*o§†ûrw™ñíÙ¬NÇàn? ²v ɨ|¤ô‚ÑE˜aLx3ƒUŸF[/"L(qJ¤V¦„;Fzw+ïß<ßàÕ\Ä•Ç`s1%çb:Э×eÇ3þ8É3îÂô™@fô}†\›»eAu<§¸Î™ô½â¢n»œ"ÁÎ}¯¢FGÔ ä€÷‚˜ðlRÀܱ,ÜË©¼Ò9“nY€Oî“'\³æ¾¬êwKÓõàœuhøšóÏ`€Ú?:’ôÏbs½[úç‰Å¹Ú„–Þ…j.¦6ŒÜˆÖÃçj2‹¥=éb »ÒîAg­¨ÕÉ3¥(ÑHõèã"¹×-+ƒRvßvîúζ•鳊†ŽkD®ü“§¼  m,Ì®N<ÁæWÒ—‹vóŠ¡‘û2 p›iFR^}z ÜS+Á¨OåAè¼ê<ü‚4?õy#^dÂ1”ý‡›£!ÝjΨºÿÈý÷Y6âŸæ˜´Úé#´âž@‹ÏEÁ¹å°óØN>„îCÈp ã&‡Ý GƒÊ@ã-py3*Ùž„O ’Mæf—ç´T•ÓVLÍ›QE1»íây·Á‘TjÂ,·ßÀ¬4h |ߤ”ºHW&ž œéáp8žƒ/À1R ueæ`W/D¶ ¡VÐe²ÙY«X¾þ@Üêò«qI8fÕsŸ§!ÁhvO,Ë|®>s™JPd&~®#a¼ ¶®x:/3‡º3Ò‹¥x1ö5à ÄÄö`Lì¸{³cñPD|á?»P4Z+Ñ}ÛÊ7äG„<± ùqÇóå_ñ\®Ê¨£2–f7"j+X ‡#æ¬çû´Jú'«ÍžæàçEÉb¾æ:»µ™:Œ‚"çD²@‰åÁœ<¤¡7\¨ËÉÈ0ÛßiœíkXоvÉò̶Ö§í“V¬(Ô²l] †Ü÷øªØŽWBPÇÇœ¦ÑÞ>qXÑ'<Æ8Ï˙ͤC µŽÀ@|Hƒâ£8‰Òþø(ø8@Z@ÊÅtóŽŒ"Ž ·‚ ·@ç¿> þ™9>úª¦?2*2*Üñâµýnd2‚Ç@†ѥ˄ø×I\ô ʦ…*êó\.£õ‹Ö¾Æy—.Z–Ѿ̾Ý6õÂ%C4Ú¬Z[._ó¨’W£`Á´Ug–^Åí!Ææwhó™ÇNiw kÚ,ã˜ÅÍ ïÈÂ+o;ƒ¼3„ןé íü\;Ü€æÃþ-VçKЂ:IjÌnAµкì6ôu;ôÙä?NÝ[M§7+^–8?—¿Ú:EþRôlæž/à©&÷4RI©¿¦TaÀ0èk¯*®Ó»èo«.IO<”÷ÛŠÜÞs&Q%k‹šL2ê%ßÝw…GXsjžG9ù82djû‚ÄKÑS÷FgGd˜¼¶¦ù &È01 ‘'€ÇÕx‚%^ ¯È™”$€ã¥fådñÓ±@T QA®lØp étìaT»*¯P£ñÐßÏHOÄó.¯tZguPéðí¶²É—] §·^¼®xˆÑžóhbFâo B™Þê¡öÅ;»dx×åÂ_ ΜL¦?v4-sŠ¿Ö/‡`“¹fÿðÝÛ‘kP.®±àa¨dX~Z=Tµ6½u¥Ã×z|éŠ*TŠÿÖè¿Õq4ÿ-sŠÿV·Ù`M†sÃT¼ƒ;q©¦Ã¸¾±ꊕkT‡ üØ9ú_š'…dD5Ø>/ìKç±ò¿@NB2«sŽååýÛïíçÂÝä6$³Ê1·a«ºýJûgÕý£¿ï¹èŸizš ØCìEŸ'7e¿tç3Gƒó™ÌÛ7ö}#õhÆ9 é}ZV®Ù9•—êW~X¯n?V)ß]3xyOöàå{ ^¾·I]¾M)u‚º|»Rþ^ËÁL³Hz‰•¯odëÕììÛÜw)+¡_ùá¾ë±¼›•ï–v8t=¹r’hv÷­é»ûêbuoˆº‡°®§o­¨ƒïÝÅêX@Íø–øÎf^¾Ê÷Â7XùK¬ü^é(_ å¯öÝÑgýl‘^„òUPþ^ß('¶¾KÞîE<Œáëî_~ø{^ž6=¿{…ƒ—÷/ß3iðò½Üº¡O:áw5E¸&>Gøe²òsxyÂ5ñ–ÇÙºNFØ]M¾p]«‚kj]®ð½“DÝw„CVý½Ôº½rÉë+”Ú.ÿá%è0—•ãå_ ¼¾T—UÊwg ^ÞÓ;xùžæÁË÷úÕåÛ”òWËÕåÛ•ò÷<¾9 ŽÛŽË8|¿Pàû"/¯ëßGiÞ ðM­K…ïâ.gø¦Ö)ðEúÝÊèꆅ‚•½ðGFÃPWH*ÆõBþÝÿGD¼”q8xXùɼü_ˆ—yy9–UÊwÛxùÐ~å=ß Þ~Oýàå{½êòmJù«uùv¥ü=K/ãþ×…ÔxÉB,¯àxáûa+ƒÅ„áuÔ)ðr±Šg‰:›À‹\ßkuÅ/êï¥ÖíUê/mˆ—ëhp¼ŒA¼\G‡õà ¼ùß‚ðq¼LPû®`9ÇKB]>V)ß]>xykðò=3/ß[Ëá ö9_J/³ò½œo;ž€÷¯yy‡ó·œo÷}£ù˜•è–*¾Íê>uŽþ|›Õ=ÍëÈ×DáÜÊ÷žu𙎷}„ðÊ×ãVèxÛ‡¯å}.Ó/ßm¼¼çÛÁË÷Ô ^¾7C]¾M)µP]¾])ÏÌáËØ•f#Òëmõ\þYdù§‡´uù¡MBÝ ^G³ûÑã#ÚeH[·QŸ ­«m͇·%„É“E«ó„ŽÒ¯ü°ð¯âíÇ*å»§^ÞÓ0X9à ¹|Ðö{ç«ÛoSÊ_]¡.ß®”¿7ʉBé ÒÜ]Yœ3Vàö=/÷sZüFÑ! ÝÜE=ƒèuƒèœÞî"ÿèO‹¬n—¨ûj^¼MÔ}>Èžïu÷Ûó¨3ÎÇu&ÒR¥Ö¥Z”ò•U*]Û£®AZòÕ:H‹R¾2_%Û°=Ê6Ò"x—Í-²l&+Ý*ž‹í‘ç’¡›p™Ñ"Ë ²Ò¤âØ>ÆÛQó”¥|åy\Ö¶Ç=«äÏgå3±ý¶±½QEØé´LQÓI‹R¾rŠ ·jm@щ AWvhèri?‘uæÔz¦3¨/ä:¯êwWóú¿þB}OÖÑë÷Ì?zýÞÆÔz>ÿmÊü˜n2?^¿]©g:¶º¾ïV?CÑ©\׆šl¬¡_=êܪú.V¿Sè×÷h±»ouߨâR1FŒµyV´yÛôÀÁ6ëEèg׹χ{”^¦(õ7(:y€ï$¬?‘ï'V«¢›ønÂú™BfTkoTtôßQXÂé¹¾BÍ Ïú0¹縓¼O8¬¶X>ÏÚ|(ÚlÄ6‡É&Ñæw)mƪÚì&;Ù¦‡Ÿ[ŽÚfùò˜mö’—m³MÕæUòç~møÚ·«ÖþÙ‘ºö¾l¿a\‡†Ð] [|õ>Váõ„LâSQÿ“ ]®ÐKsÈ4ð—$ èòT:o€óYló©hýd‹6Ù.J?«úÉQéÀjjùD´aô¢¢Ò…ÕóÕX…*XM5òþ›ÏÖ]¢ÈÃB“¸êD–—©õL^¦ÔóïUê™ÜŒFÝAåOÐ=JêY9f肌¨`j—!b‚E’¡.8=0ÜW^žaŸ\9Ó_Õ\•a“î]i·¤§{K.°ç§ûàM2¨1*1,R¶ÿ ê`¯7yüøXçd…15“ßfÙƒH{â:Lí ¶Ú9´,^À=cüCÈîi´@ºÖhú\¸ºÒ¶¨9áÕ>Û‹ãZ«‚c¥õ-••-ÁÏkƈV¤û6a‘J¦´¨dÊ—d[?yúkó£ihs­¨»'E&©¿ÿÝ€ïó{Ÿró”ÐUŸí+Ô™¶&W Ú¶‹ïÞ-öp„6 M)æ´jÀrÈ˲š—gBùk‰#Jû}X^6IÝž­Vz•—7ñö?âZ½þ„´½ñ'>òSýF¥Vú†f,£Yˆé9(zq‰ Ñ6I^C]ykS ®3ç÷ =Yú³ Ýå¯@÷þ5}aÂl¥³Q×%;;å«À‡ØW…4–þ]³õS@:I47÷‰#1Cþ7ØN FØ~ôôÊt ×`,3²Œ¬N\Sì²Wà>Id¥@f^˜œ']Ó+©Hožò•±ÓY9;?˜_\•a/h\Òh÷•œ™Þ ]Ý’&v‘Í•î›î¯¨ð»ŠsÊGyUg ¿|Ö SÄY£ÎÈký y-œ£‰Ïs4ÃÅC2‰b‘šåhÖN-ºÅ=|;„”€öÝ™'8"â o¸5VcY,- }òÜiº³¡ žŸ¦$]¶¦±MéäŽEnôœÍæ9†Á:ÆWÍwuëL9~„š{V4†úÌÕæÊξ…è<†¦5N‘£ÐͰ*ïÖá6Ú±¨¨¤¤ùµE×Tͬ¬œIW\ÞPR7«ªj½ç¼ÄM#Ëó§Pò·æÊŠ–Jj:ñ‘šÉøqxÜý+¾ï¦_¢¾qÝ[¨oìMòð…È{Ë'¨y2Ä8…—·sžüò¸ZÆ/ß<&¿„ä¾@Mµ•ÍÍ¡!óBOó}·µ¼b\Öy ÖræûkúÞ«ô¼Wîë5ï= ÙNœ$xov( x¯%u†czF4i²NI8ó™ªÒó:xv!¯ "lé-iˆî4‹ÐSô"£è)©jŠà¼0·JZœQR¡RYò–Žªw]˜e׌¹0Ç%ë.'–Wø‡yËs‹’w©~ù^†N÷2~V>yî¶¿¨yn+¿HvÒ9L !â/½`òÕåƒýÇsøþ)åû'jw一ŠUâf²ÒÐlè 4‘Í-‡ïB¾‰ ƒñ® ƒ×ý Æ}Ù¹°A²œ1]ûYèêÖ;ÝøÎotv›óCàc‰+VTŠFë˜{•òþ±‚ÞŒÌÂbîùÞŸ˜²%ŒÑ¬ÀýÓ5?nÚR½ºsÈ#9›ZO×j~È«j=ºUšõ¬úqmUUmqzJ⑪aSNZ»é7ë·7äJ·`Ëÿ/Ã,æË˱<b]ùE¥õÿÌÔ|{0˜-}aáMcÛ…Yö ôWÄtÂ…xÞîþXý†XЯüðÕý"ò{þ&ð”AM¯#ìƒ$BÞéûûZöô`8`û´€žÏ>³ [—‚‹xz*:j †3üèð`¼†³þzŽnFÂA€y–³[—_^‡»ºÜN?&snÕ›CC(®qu—„kác?´T EËÜX~€ý,9fJ‘qÈ9Çàˆ*ªjcŠ*æÖŽâ-Ëš”ÞÜPXÕòÙ_è訪ꀷ[¸X™íBŸrnXo(ðƒ9oS•¯UÊ_$7"¯ËÊ/G^ßæ2ÀƒåÃYù&^.ôòŸ±ÞbßÄ{ª›‡)o±x.›)ùÙ^30)ä&3Ź̮œË\¡n‹AcTâ¹1N¯ÄHãV³pãf²÷¨“GCƒðÝTkãYWdè:U¼¢¾ªµ¹¹uÞ ³F´¶VV¶JW `ÿµù& Ïei~ê}Y_ÙÊþ¬xaÎ+£›Ûp‚ýw%Ã¥3éxM ›)68¼q_¹ôÚ…ë§$ïZ”;¤/§¤Þ1Êê‡Jn¨·c_‘Á¾÷Ý”þwSp§ïSÞ~žwúOŠ» V~iêÍF+×úþ¡©EÚ5©õ†jVžÆË}œf²ž¡qC9½+¥}#£¥oyy¶ï3âø'Á¼ùWfrÆ”DŒ&'aÙ×øµôÌú çñº6òö±î2@dGÊ[Ë r:CÒ»måmÙç-àwã¨$}Gײ¾Ý$JØ×Á&Y„Ä <gœô•V¯F?¡# ]ù m#ØvçÖT´=ñèm5VhËÖ½˜iüt ÃÄyC˜^3¶o¨woFµ9"Ò•LHƒ‰FAH‘ßüüo¬´²w#üíŒtÂý }šü¤ñ3“~”!Ò7p1!- h)¯CkNwu €XKê Úg•—ÔvÖJ¾a·Ä²O®®f}5°¾ê¾4©}iÀ…ÏÌûŠ”p )6`GíôéXÎI55%Coa}êë }ìÔx}y“}}ý §T2dô-x†§OK l^’Aj š‘C´HØæconó8‘eÑ VùQ·+–æÄ1màâ!ÄPD›³}íèS§U5{fYidÆúí¨`á-±œª’êYšÜi5Õ0‡QôeiŒ&—ÍÁ‹sð¡G Á±%00’ƒ‡0à+³`bw)‘îŠÙ¼©0cçytâ“=¬„ ìÉžýrsÃÔ“kòÛéË ’lùžÊ’›b9Áö±¬ñ&~ŸÁàJF¸zHA³u²0;-‹»8œ½j8ƒÝ:D¡tŬ5ÔÅdä£Ê‡D&×Ú]ãî«鬱¹*V«GUP¦WWt€æ™Ê 5Iò|vfU|t ý``âR’×üèLÖQmh¤h„çµ#ªüÊ΀³æÉ›Ÿ|òfzûºßüf]b)½b;£Êƒl§-ã«h5…!¦bÔêÒap ë;N(8®Fm|Ni!äûìT éC!Œdd´²s¨ÝUi&°‹ïraö 1¡›Gìà0†ôiŸ1a\Ó“OÂäØ?7\vÕ¥7ÜpéU—Ýp›ßò K?g»ÙOØ&†øëF0Â5"·Šëð«ØÒ²Ó¹¶³s Í\Íþídœ ±ï+é6&Ó $Q[“ˆŸjχ¡;+û¾ÙâÁ5’R RÙÒ@MÂ8êž4$G‚Óp”þ?ÃmápÛ}øïý¡¶êê¶ü¶P~Kþ 4g 5}ÿ+='½ÌffE_ábRAj¨FäÁ+Ç2ê u9Àø¶X [cqË¢¹L[‹V‡cV;$÷§[¶²˜ŸÕS¨§ÑZTù´”¡(Öï[$/ÅÙw OA™3é¦Jø‚¼ 舅Ùoeü7FW4ß–dј†Tî&1¢©ÜMcT‚Ï­ÜÍj%Ê#’ƒ#2‚ÈvÆÒ-‘•íãúúX°„Éþ!õ±²0û9T$«ŒMÚ¸PˆQ?÷à*vvÛœù…üž¥Ø«órx òè‹Õ%…’øéæ;½ Vü^#]˜Ñ»‘¶oi7éŽñwÿ‹¼ nwczüûfû–¶Ä;‹<ìó(:íOc·^Û4ù„+&Jcš:']11ñó˜Bk>½¹…ý(HXXݘMl.ô·`\wâ¤s¤rˆÏ©aÔkhܹpݺ…_/ú`ôëoŒF9XÍÚLåmšhiÄë1T_rÉü§ŸžòÆë£?XÄóyDÈ5ùŒÓhÈhÕ0B ‚H|I¨&/¼aûP/HÏ ímþ™’‰}â]¡Ïù0õŒž”« bϨÄÔˆ„Ý´”ÖI£O§–ü/œóâ­—?z}Æ_§µxþeYY Ýi—Ø6­uTå%Å—¬‚³¨/@¿”¶2þ`'N’Mºå¨‚ú]v"RºÄ3 Lú£?O#ø1MÏóÙ{ÀÕă§2Y<Ï ãçà,…žN÷ýã*%’«“'GM þ¾yý˜œÎ5MNȳÙ1ÿ`45“«Û ™xág±s褣F–ÉO UÃ!-ƒN>É{ îp©ão–ê=¡õ¯O¬žøJgë • 'mŸßšU9mÈ”ÛùW%.z{êŒÙ÷-.ºÃ,Íÿ¦wKîÂÚŠðH†ó¦›\~L'ˆ˜?Ý næá%0Ó]¸÷YlL;Áâ¸^¿Á»ª^ƒgAþ ˜!‚ÿEü5~ˆ_ï÷2¼L±S}вò¾¼ÄnZ[pÏJiìïÇe´ŽÐ5N¿7þ&%ófLñ¯òŠ[ÒÛ‹iæMã'77ŽŸtvóäQõ¦sÝtËm"Ê圞ћÂQ1¬¥y´PرÎP\«Ã¶…µHc¢¤ íÒm?À6¦]º1„´ÛÉTÝtŒ(–ÎUKð0fúYÜÂï°0.R®Ž‡ª1ò©Bí„p5騆+ž¤Ð2ÚÔØØ¸£ç‘ûwÖ¾ñÆý÷—<>ç”Ì3O¬_BO:ç½sëO<óÌoWÖÕÀ½9ãC…Òÿ²“S.D=s)1xÁ¥8ýqâžž( ¡çµ7Î×07C2T F¯eÊO¦3¦³ÕCV®4‡ßÍm< ø†hš'Ã+^ jäÔëùíd5D0÷º§bùü•[—^¹dXiñèæŽÿÛêºfÒ×ôÑÒóoº¡é¾‘ŽåÓ‡~sœ†qŒ×t0¼ü =…Ú0øÍ~""çs8 ÏE<!Üå†íÀEŽù>7Ûe^±Ä¢~òQ¯ÈG m&"ã¹\›ÌÅ ¿qçEÅœ=7þ;Ò¬™ñ"Ë®˜¦êG]T‚ Ø Ï c¶Èl(g{ŠõèPËu:]Ý.¯/”HS"»ÝYÙÈ—¼™¼I Ÿ)šV‡/¢ë¸;\‚Á¯4Œ\¦°qe`'Y§ì¸ñZmî¹oÖæÑüºGëªúᎴ°Ó–¶ö~qÇõ?ôN²7_ÿ-]þá…+÷]øÃŠRàÆºú#è;Ç4š#ÒvÆÞ rΟX£jêÊ06_&;éÓC§Q7ÞØÆõ~9~ußt¨óê¤ ù1jßµcÔ—ß<Ïãji+c’ÆÈªì1kåQÛ.×€*Cþ'I£U~Á6Ü":µ‘‰D¥^¤öFÂî@iMu$`”ð 7%™úÚ›Õ'ÀfTwƧ¼þQ¿ë‡&¿Dýý%t=Ö—&¿ÿµúûKè:¬Ÿ‚߇ú3sR¿ÖÆú§XýY†Ôúµ„¿5+ã÷©ëO£c±~¦RvQjý8¬/L~ÿ{uý2ºë§'ççO­?EÜ»*ýW¦ÖÏÃúMX¿•ÕŸ;w°úròG¤Ì_Ãê?'<×öš1ÒìD]À£ˆÁ Æ¡°á‡°_œ<2ž›z zÐÞ2ò©a8ݸyù©S%SïO —o¦ãiç̉íuEã&Î$<Ö»¦DêbZÙ¤Ëý²Ã›§¤gôˆ …­xqç8GR˜Ûù9ÎÎ…té²×o‚igZW”îanáÂ\ÃÏxÞ¯ÿ·Ó8¢ú]1BQ ¾±ãý;_{#ãéÝZ½Æ]Ö­ƒw”¬}í#,·;º­v +·Á¿]ì_•K­µ¾‹5Oõ±ýÕÚtz‹UpÚïwqÚt›¨¡´’–²=o§i´Š®¥«gÍ^í»1½¶j½†Mì]0Ö?,7QFßÉ*/hãçÑQ 'Èø0b$4q‘+ãÕ1?’–iÄĎε‘Q’iê© +7/_ØIMëíg&¢‰è̉ãŠxßÁ¾ýšbév†“/;Hc’mŽ]¶TtPŽ*À|› ö]Qêˆj9:¬6hg³ ´m”ÑauDM v#¨cŒÕ¾¿^€:º%ªe`×À¿;J–4™Ý“•!‚ժனïbŪÀG[%‹]£5 ¤ü&c âÍ£^gØ Á¼48gNUmú¾šªÙ³hÚ‚¶‚ò,úN¢,·<ì‚Ä^£áĤ}Bºu¯¨Sl…Œ ½y¸cÄRŸÜ Iˆ]qææwJ«&,›´™ž™Ø´yê’‰½×užz"솙uã ýu3/$vÍl_X4®a&ƯÍÑjÖLzâÅ Éq³`¶.MI» '‘/„WSGLæ3Ø[Ìý·Œ`Pl »Ãåå¯ß¯à2SK;Ç¥½ÿÖb›Ï¹‹éáF®Zc[¯Úú¼bìß½þ4oëuDÓÞ3L@³Þw¼?óµÞAñ.oC³£Ûh6°rü›Ü¶NGwšÓ-o|í –¤;º3Ò½ŒBXK…ë’LÄ‚¬ïbÍU”3Ú*™¬i™­ÁèL¯Tý¡¿\%hŠÐìèRyƒsò*Gò‚½=‡oõªŸ µ¶ã©I÷Á._À÷}~ynïlFxm =HwcÈPM¾t qxÏe Ç$HT…jƒ9q«BppìQ"î÷ :yüœˆ»Øk€×Ô@ó¨'ŽÉ–š?pzG6Ñ·%Ìf£¤_CßÈXg4'[D§ ÉËÜÀ龂oaã§‘±$ª Bd =¨çz¼ÅÖšxêNj]&LSc²šø¥\æÄ v˜Š^'˜S„ê ¥ÛP Ii}»iªó³´4c“^r%Ì×Óif㺌DÈ´ÁíÌnM<.Ïé1KãøGëiy4Û{sFN”–?sÖ=gáü‹ûKoiFãüÏçRL¬€gD"R8·ñ%9ùkˆ…‰Ì$ÀÏD0}-þ&O˜åÿ<“’MǸ°Lºy6¾†¤ì…MeìäJ1‚Oi1N§?œí;ìÍi8ýÈé¤ :,Ñ“pdäädÐC½I§ØÜÇ0ØÿCÀþR‘9ÄDÝÁ¸6 {‚×Fn›o¡õ¡¸“cÂ’gýÞèN6mº>Œ‰H·ÞÀxÒ˜Á!gç°É& <<èáìèê¯1ÑaIÄo¨`H“E¿¥W$NN ÷f—K ´¡ô>÷ÍÍÞìhâÄ;ÑÇYÏ<ÃñPÚw¯ô¶t×r+;;`¤1¾[0šŽSü…I´PHØ"À9*ÀÏQ€s Þý^…«Œ&Ôeôè¢i•Œü¬L³Tÿ#LVX–¬vÑÄ’<<Éwòa'äÑH{aZêÅü¾¥çxû²NPoEb?Ízª·ä‚ ­:¦pùƒÖH_;ÎQä3 Ø1"Š!çù4(šÎÓ}êC Aüô—Nå l>g—éÅ[”l°Á£šéº<’dbœ“‰ºˆ“|–Ôbhòš’@a}hÆøK¦¼|YÍyeÄÊÏÎßÚ°Nj˜X}ÛuËZæ_»¢ì¯/L^?iä¡Õcî*ªã<¾¯ãõ[àýÀL0‚²’3%¦15âS-¼Óª^fáõM¯>VE0iTïµ~OÀ ñ Î iqÃ/Þ*5^xá‘ïšü‡Ë—Z¼¥ll+ +ˆýçgHÔ²Í"©®Á•0gÆÒ«‰”²aü^;Õ~õ•JÜúÃtù¹_8÷Âg[ž¿PØwŸ¥ÙǰÙHÿyÍðŸÉcç2=ýOdþ äç¾/èrZÃBŸ`d˜­YNŒ¤Pœ ôAž˜P 3Æ  ³Oº#nÊ A•¿?Ÿé¿ù4±4N_/OÜ$}¼ª×ŽVcÈ9šeL˜¤c6¦S ãoð@íe$äÙ…ÑÀÈCˆ1ÎÁo©2hnù—Œ^¶jŒ6wV¿Jró[¸\g7%3\,hø-i-ÜÃyñ)€‡–„kf•ª¤„±«êÇLZ±ijñ’–NštÆ Ë‡”,¸´êÄŠ°7+\Jí¾ê¡'M+þéŸÎZXY}öÖ³‡WU†iåKõõCËÎRþR=‡U¡Ò¿¤å ú£”HÝ`æž ¯wóŸñ:Y˜(f†I:-¿q2Ê1EŠUu%-´³Omí÷}poÇÚ†%«–4P:küÅãÙÿ‰è¬!­CØÿ‰ØxÅ—X3?ƒq]9?+¾¹Ø Õ0+鶸LÆ2 z…SÒ1ÅNä¹Ç'#Æ6ç‘þ, ”ú4xAˆ™lÂKÃ+¢ÙÖBÆ€B½âè—•Ï-óÚø²Ê“Jß›½ó´ôübé¹¹‹ü§¥÷6>ÃùÆHr‰t=Èæ6„: ;#{#QGó–!‚œ—}*ÓÈö!;fª`r üïÀÏÿù_1ã]±Lçºhö®>|þ0–;*A0Ä´y¬\¿kÇß=Ϻ{·N«w—EL§w0>šéèÎÊÌfŠÝEŦӳ_“ªz+ƒì[ð#Íúû6ˆl•™(R©íZÞžæÈÌÊPÛcN­Ä]ÏÝ\çÅJ Ù§ô!ì“7‡}ÊˉpBy`3.W)êy~æÔ¢‘9/ßV\_`Ÿ¡þ4±ºmb ¥0V7ÖcÉÌ®¬ke?³²ÖuåY²räß ¾Õ¥ó˜¾áf»µÊ0ª›4‡ *áèÓLD5þˆrß±¿~Ci¤åžIéܳ:k;îx0qÿÙµ¿]3}íU³ÖN_sMålØïd˜äÆ£}—…qAÁ—-±`޻ÊïÞ1¢ 1}ÒA lWà;‚Ma]Åâo})1‚ÿ¶f͟׬ykíZ¸¯Dþz“Ë`Ä-FŒÐ³%&RȨ‹½6j`:¥§™%N£w„)‹N»ö¡3/]y~tÕ*¤S"-8z?4¢óè ¬Ÿ‘ôÎÄ’0ý.aÊú \xÉY]{?ôÃÎU´„jèÅlÕn°ƒ›6•1›bù2¢³®®“Ž.ÊÌ,ÊÂ}ñ;ŒR6Ó4Ld<ç"BWÀ î˜*•1E“™œ¤EÁd`|Dƒ¿aÞ*@$8œé@ jŒ")Q±ÎYì¯)Ö5Ó…tQï:iDâ³Ä´úoK¼6æGEþÕN–JÓé¢#UD“YZ >ôüÎÆ¢di)hàr‚q^»dOœ¿”º/ºûŸ°ÒŒYÈTÂE‘±!#(Ùq¦KIoÑ2Ždd^U¥ …‹7C"RhN‘&NÅ„Æ î“°j+ÏÏË8Of<‘nÖ|Éæä2y¢Æœ<ÞZ‘ ù@Œû™Åµ£`ua…ÅmÌMkûùÇgxn†íï$°Ec(Æ´™Òl¢ 2{Ù¥‘RC©Á;>Û+-¤Ï%{·x³Oµ{÷â={ïÞ=ë™I’ß›x&±3çZ6lhÙp娫®{%‘ûËúMcú¥èW„„عævPR,õf¿¹Xî|ñì<ÛÛû ÓÜúuÏ誔è¦I1M¤™af!9—\Nndšúò3‰Vã%œÞJªH%eLº)¿•ë³ùÁø8üÔµdÃmEÞPWþ8h–ŸÍšMÆÎÜÄtßï }úÊP(m vÙæ]‘BÑ¢ów([ð}$6“ ø}1E±Åë`´|*–tŸxj‡±,6Â| :";‘ý8Õ[Ϊ¯àÕç]±œUÏb峂±óØ+±ÕàÇ| {£kµ± ôéÖó=€Ó’*†ÓòúØäq<'cÝìšGÞÂÕM#º @ Ù¿PÏN¡xÕJŠäÖ¢¶&bà¸pCºH‡ ’Œ½ý~ü‡õºHuiDµgù´y³GY‰áF«Õa¥ ÁÄ?Œ½/Y].«´Éêzµ&'ãÈr_VƒÕØeFë«q|œg´Þk5.‚‹X©Ëz&|dÿì´—ÀÇ%Xz6|dÿH¹ãêÚZ£uýéÌ1lHcüs¹Éeš|žR'öY }*ó<în#ØmëVL•á›Áò5,ßjóxÖ¡ÄôJ¶p ‡‘Rñ i@“ÒÂÞIü첟¾¥‚¥À÷qvÁ.[X—ûI®# ñþɀВìsð9‚ù:,ziB†Qûh¹2M>Oi¼ Ë£Ìó»`·-¬[1UÎW¿f}H#Á«=X°ásû^—FŸÄ“éÉ`†$ ]Ôx2©¨Ôϸ6šx81#Î;“cŒ1døo sPæ§cؾ ³qLdAª «—cLŽ#™øÁLjãtŒò Q££Ûh$vH§ŽŽiöC}û€‡s ?ÒÃ%Íl\+Ž;™G#0ý1àéÃãj 2³ÅqMèmÓ­5š˜ÒIÙJiË ~8bÇyà0.—ñåæÎN: ˜=£\%ϯÂã— "íÛ§ÂêlŒ®mŠ€i?ôý`(`ËÁÊwxo 2M>vŽ=}?´8ð´ch{$W’–’°ý4{¼àÅQ(©cûbŸŒ¿T¹Å晲¯ðVžÀ‚ô:yòÈ‚Î::µ“3¶ŸŠ@”Éò[^ÇYö놉ˆaš`à ?1Lá:¤aˆ§08-©–bì7F’@Œˆ:#܈tŒ@$$¨”]{,*†¯*uû¨¯SæÞ¸¹›•÷ ‡eT:Æ¡è FF(p›`þnQÖ¡Ã:;ñ¡· ²÷WáÐ1(Å ûR£ãPŽk›-àÛÿG7!ˆ¹ˆà›‘ÏÁ$ïE…ŽþK Ž( nBÃн…ò”û×Òð``Ž0710+$ÌÇЄ™)ðÕ„û¡RtŒ H>Ú º‘¥5I‡QPtv "EÝWSÇôJ!Ÿú '0ì2éIÊg'ÈUnªBj~>*SA.2äÁ¸~£Ø¸ÃåqSiÆ%l\¢æ¬ ˜ÊÅŽë†÷twÊ7l½Œ¹)º>®WàÁt ꎬ1P+‚•"‘0¹îÿÙqáÍql¼ñ7J÷ï;¤B›8üí×ãÍq\x㞙츰oß!k”4°1ÿr8ÓÀ™ãX8 ‹•6ìó^cêµÎŽÒˆ¨@*£ŒëïšYÉý,óê~›ôX|ÏêÒ¡ñ¸ ªY‡Zôù=tê*Fƒœ7wY_Öœ"ë.`Ê`¨3Êó¥Ädì‡7eШ14ȸ´Ë‚mׂ#'G¦µ¥SŒÝÀÆž!=@ÿçø3²±uê±!¥ÔQ×lIY³¿¦]Ë×}ðPgʺ ¤µ¯þ·@,/•/”óæC⌣™y\xäç‘£ã3ÏyØ™gé>ÿ6qÀcãð´À¨û’¤d$÷äcàÏ0(þ޶VKÊZý5#aÜÞ§Õèûµø;6håeâ"ôq½MSŽo(Ó!uªÚdî'Z“~çæãð;D*ôRK2b“¼å.ÎaŽ‚_#®À£ Õ¿f6ÕlšäÙ|+r2 9ýyn*$nßÿd*²3 —“nª\ÿ z~ >ÝÇI0úàCƒm¬Á,ÙËÕ&#(A¦ÝÞ7P¸žýÎe èŸ&sªþ9øfIEN@èûx2L™Œz.¿zß8Ž'^ƒ8.âY`_ÿáU´a#+úïëà{’1ËÛÆŽq- +4´À4¬øhG$+C’5‰$H«—Ö]ŠCÂè}ûVÉ›¨Sèc 6š2yn¿¸‡´ª=µ„•md?NŠZÃ2 ¥  ¡@MDPѪ䮒öu*g‰Ïq~g€U$Sè2£ŽdØpXƒ†e2'ù C¯;Xštë,ÖAéÊ”JWiªý&âÀc*|°áU]E[8¿TøY’ðÓÉð3³ùøü4òü€ÐØ» 8?­#P•ç·&¦ä­Ir~&$Iùû:eÊï,¡íYÈ)¿Ž/ýj¶Q¡´I TÍ ’¸´ù¿v.¿–-DTl¡I°…nIRæóȲcsˆˆŠC4!‡HdjþôȱŸS jQÃãß‘aÿ6 J$Õû¥dâ ´2§VÙÎÀÁŽDcåD'×á%|Ó,Ä7M©ßWs~ë§áQµ`,“v ©s1õ.ìißA—ngGŸC‡X +¹ß0!7NAÃÓ_êCò„ÂÎ@& ;;:áž‹qýÕÀþa= +­üûÕ÷#âûcÙ¨û*öL`=ãØzNëÉR4v-ª ²uÔ8MΑ/49û;;ïˆHxª?(ë7'×o> ¾òÄ7ÜUâ_f“ï¨&ðIàwå*¾$^j•›\è:ÔeDÄÙÉ}ª•UOòU•ëP= ‡”·Ðl†{œM LUF?sùnÖ„>ãêaŒhþÞÿõV+€cl¬·ž`+Â'WÍ0~G.‰±à½ÐÂh Yõl(žŒM:Œƒ¤,Ì*?Gµ4°2³Í(}ÍÜÒÉ6jüÉX~”}+qiç+Ôô¬n;å÷ÙfÏ/dx¼'‘›r¥£ºÔ†’çYø-²` /¬ ˜©o¬žƒÝñ¢üù…‹G$xÜOž_9@韜üéUè7¾ã¸“ðð¢ Ù®õ(ºž‹Á Tƒ± tT<à,­á¯8æÎlèýÈ2ïaËÔ¬oª_á™Ã-‰ëõe¿y*S ,Å;°0§âÃF§|7 ¿³šøùŽÇ§ ©ž>™ËÃ$w— Ú-Êë”Èîìiï\´J¼¾òó³„﯋ðÍÐB&(£±U™’$J‘îd91¢^±'N¥dœ¸Æb–­rOâñUø@;©óx†nfðüBÏ$·QE“Îz<¶tI&Yò¤Í° Í©H›ßZex¸‡ÀÕ©owTb}é¥XÔrý7jߪEòQ_aÁ¯f¿4;ž”ÃIƒ^ÑMžÆ‘=¾ËhQ6„#B`ܧò ;‹qè1tOgïþ}«öwJ]G÷€¶EýŽ þýtWìv © £G6 X¿vY"A¬6õƒª'ù¨š|X•Ù)çýRò~ ¼° Éj¡<9éú“p J¹.‹Vž…j ²$ñIJÈ"5ªñM$ ôšTÙ30†`Z6VhÉØ`"–ìä&&bâyèç[SD‹àÄt8ß)ö°)çí³Bæ‹2ù`§Âé_d¼ з#y®…¢E2½JÖªl”Ñ›äd/èž¿YH¤ì^ðžÈ’|õRÝÓÂý—j’ì6‘c(E¹ 8µ;:;_I¾+éAY®Á;j»Ø iuMàÔÖP¿½´gã8ÑÂ}¢ÅȽ!e›Ž3…{ä`J ÀÁw0Z‘Y8ì‘#„ùƒM ;§Dð[ìÓ/¨ñ2à椂Qm:S©ß"K‡÷óóï=üîdå+LVZÄݽÆ÷' ]H}.Ä7Èü‹¾ABtJ·sÙ)tž´Ex e§IÆ ;,#“2‡Ô˜±'e¨ã—e(Dâ´³ {TØM¸£úáÄïÑqÀ‰´1ñ/jÜ®à…³°C߯™'øÇ¤~ÒœRûí}O?á#£Ä¤ DÛÏšùX3è¬üžÔV<]õ]µ…L“GéL¡RÂzT)ÑoR–þg!dbLj¬Zµ/)6¶@ Êäú/ UˆšyŒ2›2ßJÂ!eå@%àðcãu‚ßiÔ\ŒC%9+„ ÎL†ÌÎÂ^5!67ˆ ô’ÆéŦЋ ¹¸q ‚-u Pó¯ˆ*³7E‘WØœ,„»rˆŸmçí¹òûKß[™ªùÚ ' ¼ÏɯGUÓrb Wt*„³€ÚGZÌW`y ÖÚ.v¡‚ìänÿNà‘/ é$^²!l綦ìHìHL¥‡ 7jŽéæÑIÎ1Þ!®ƒU§‡º¸:‡Ug„DèR5õª$œÌMaãvnW³ÔÎþ²®‚,—~+Mýoű¬Êê{ß½þ±>1å×õŸ Ñ/†ŠÒ¿;B õl)“õ.|êjXÿw°þ-äL8©±!ÄžçqñUóWú¤1“>EÀµ÷žyý| à qtk5F7„-2ªâ2Dµ•lÎÂeKcrÊÁÕJ1%’×Pj¨ùðÃú¬Çï{òÉzùnsMß>ºÍ5Ý$l®ñ>Û ›h Å -¹1“ßì°zDÄFø5}³3 ¹ýèöÙíÜ n’ðõÙO{ŽiÿM7Éöß`[wt{îöCÿAÿpÏ0bl)°9t( ¦×k梾¡²÷J½&Ñ_3†Ne§Z|6ïLžÁC¨‡¥ó[Kï8¼ÏA]ª¹¬‡6pã!¢²™7ô[SÊM úAÑ=ü…¹qÃÎÇt¸z<vÉ»`Ocu ;Åñä'ÍIs¿<žAÀÐ2a+ƒÓéwŽ×X’öº`®'013ñ ‡?··¤Àî+NÐXN¼²“ŸU4'÷]¡noHiïõ;ý ýʼnkøš4'Æ_naíÇ@ûÆÞ7„màÝä'ÖÞ«à,›T+`_+Íè}è'X|'t/Ýz”ï¸Ùw:à;të‘““ß‘ÎI~g¤À8”}'aÕ.þù.Åvð>Mù1¾3¾£+øé/ªï|y\ßQùDH3Žã;¶~ß±û;ô¹~¾ÏÇw.ì÷ ã;åý¾S~ OSÛ“O´·¦´¿µ_û[ás2á?ZCÒËך»…jã´Õ!ŸH))#A&2’4‘2ŽK&“ÉÉd69…œJN#§“³ÈyäB²†\J® W‘kÉoÈMä6rù¹¨p°ŠºùWG߃ K0šuù#† #«¨š±î¡7¡‚mßaSWß»*«Ò¹êžW BŒ—O[{ÿkPÁ4ÉxÅIÿÏëPa Æ«ç¬ì¨`øxÍÜ+ÿð.T¤ã ‹®‹V1jñõ[?‚Š¢`|âù›_ø *ŠYÅ Üýâ׬‚F£Ù=£MDk´:Òs ŠXa< ݪF›¨Þdwfä–@YŽX e…CÊ«ªëZÛ'BËfÑrhåðÚúƶŽIвÙ;ZvN›1gþ¢gŸ-—‹–S¦Ïœ·`ə箄–˱› åªµëÖ_}ÝÍ·o†–7Š–]rÙ†k6Ýzçhy£#ö$´¼çþ‡‹ÆwîzZî-ÿÀÃÇþôôs/AËŽØçÐò•×Þ|罿øò+hù™h¹û·zÞÿxÿß²ÂØ?Åý¿'0І=àXí¬ {4ý~–Š¿îÿŸ´ë ü3áÿ²Ì ·N˜ð)c•&ô~7A:8a‘—'h³&@ñ­øËÿ§ëA&Î&mLîúû¸ùŽü/ù™ôQ 5P M£n¦ÚgÓ| ¥´Œ©ða¡#im¡ãè:™žHO¦³é)ôTz=žEÏ£Ò5ôRz½Š^KCo¢·Ñ»èïè}ôAú(ý#í¦Ûè“ôú<}™¾JÿÓb÷Òè'ºY¤ë6Æív2µþcZBϤ~p»þÀNÆhÿB‡Ð³évà{Nl´ÚNo ï V¶“ü‰$hÓy{X£îôÛo3²V;¨D;ètŸà9;ÉNª¥éÍôCèê& ºª'ûh!]N» ÑÍÐ(B>¤Et#ÆOš9wÁb¨½jO$ïÒ\º˜þZqýrcYüäÙ§œz48ü|OGÑ+)²Ãë‚;ÉòÍ¡‹ècÐäJh2™¼N=t.ýèãì+¯ƒÉ>FÓºž"K=ZýùšÖЋé‹ÐÑzÖÑ ä5šNçÐû¡ÉÅÐdy‘ÚèIônèèü‹×CG÷“¯h5]K_€V@«»É_i½€>­e'/P+¤ €&« É8²‹i'½:"«ÖBG›É´œžOwB+ ­î!_Ò*ºŠî‚ŽÖ°ŽÆ’稙©ÑwB“uФ…¼Bt½:Ò®[ÝKþNCt5}NH‹ä!rˆÖÑueɬ£1duÑYô^hr54i"oRO‚ŽŒW_=B¾eGË)Ê#´Š’ÑÑôjŠÒêZÖÑ(ògšEÒG É Ðd$yÐ¥4 Yo¸:ê"?Ñfº‘þYˆ©$NŽÐVz}:º‹u4œ|F‡Ñséh’ÍäR~ ´,}ø²ï‚>ž¦z:‰ÞJ?†Ç=×_<´×vú—`t9“\’Þlwep[f>0Ú´™ ‰í;¡£ë—õ¬à¡œVeI穎_/äBJ nÔD—9b›,¬0%Ðoo¹$È»¢eÞ®˜dyïCöï:bK å”@[ŸäÇ›Œ1‘/È—ä+rˆ&ÿb«&T “éY¼ÄÈš<ûDïô)›ÂNšK c€hËØ× …XrÓ^ ØÃ,vÄR¨ÝOƒäŸäò#饔ê`¼0#¢*F‘uŒ¼G3·SÏOÒ<²€,$Føn5Q;uÒ šIý´˜ÅÁ«/aÄ9ÑÕFKÙæ<_àˆÍƒÁi%ÎN¡õ´‘Ž¡céxz >?ŸÑëZFjë•\ÇXÆÍ8ø2—ÌメSèt:“Σ è2z=ÿƒzðaôvº™ÞCï§Ñ(#'ŠÎuÄfáà+éEôzÝ@¯¡×ÓßÒ[`ð™8øNº‹¾@_¡¯Ñ7é;ô=ä;Ñ™Ž'èãÄ—Ó;èú{ú}˜ÆèVú óDÎÊPíˆÆf¡¸œèˆM‡¯Ð§é³ô%º›¾AߢïÒ÷)èPñ“ÄW@ýÍôŸNVøý”È ˜¤g¿žð`E*Ÿcü­ öWÕ?ÄË¥ášRöÓÉzÖ¨~²j4s{~±^ùëþå~ ÿ¥~ä6†côc8Î~þ[ó9®~Ú†«þ„:BáñÕãÃéR þ ŸX5qøöÿÐŽùVGÇ„ ©& ð'4>åÏ„ ìo•ø É?ûµ‚?ƒôu\óʜؑüO=Á‰ÿ›üÃKhÇ­Ÿu$;:${G¯«£C3‚5£;޼ =$Þéè «:zbõ÷‹^Ž\¬|‰ÆáK4õì+Çý-õP0Ø/| ûl,ÞŸü%vP?ΑŽ2;B*•;‹QLeêÁ Li9‰ÌdLrYL–‘3È9är¹˜\F®$×ëÉoÉ-ä¦Yüž©)3'F¶’'ÈSäYò"ÙM^'o‘wÉûä#ò)ù+ _“JY¤kœgM—ÜûÒßAfÎd2Ó²öž¾el:œgm«·<·ªN‚´(«6ïúX_C0Î$o8“YEñy·=ù |§a2\Œ7SY|hÅðšzh<)œ{ëÊãXcÿé¿éÞ mÁxþòMÿWs_Wq$ÜýÞ›7÷Ì{oNF£Ñh4ëiN]ÖáC–e[–oø¾0¶¹ 1æB’€aI „Ó‡°ÉÌh¸ ÂØN6›d€“plÈ&bé¯ê~#É6$Ùÿßÿÿ~ŽÑt¿~=UÕÕÕUÝU]Å£ø WëMŸýæËø 'QªÜxå=/áƒð bëÁoýÌN”|Û¯Î3Svxvºÿgø`A¢äÚ{ýƒÌ”] Ô}7=ö[%㥇Ÿc¦ì:x`¸ì®Þa U¢$^qäÅ÷tMŠæÿÀ"å§ëb›IùÅËO[‡m§+…N4ûfÎYº% ø½åÆ­;AØñe¸d;Ññ°žmc”•@(‚t(…,v²yÛ®=çžá%—c'½“+~ñØ®wÜ…-3J!‰-¯úü5×}å«·Þy7¶lÓ[Þó­âýƒñú¶lS -ØòÞo—xô»ß{öûزYoùÒŽþì—¯që5߬àµl}æW~øÓÿÕ¯ßüÝ»ØršÞ’ë8Üœ/¼_Þ|ùÇÖœ]uÔDÖþÖfž°òãåó'þ³ù° w¹æýÍ;~Žýhˆ˜yÇ@Åú“¿øó„ïÛ‰M,vgÊYÁI{Õ™Ï<Ñ&6=úhy_ðŸþξàД}AôÃ<ëïï=Ó¦±Mì=ÿï¼3ìóþæþ#Û¥§Mú.ýÔ}dóДù;ܯºüêäuló’o_×ø>?ÛWgg Ѳ‡§þs ³N8i›'Àg³~~„€¸Ž«Â;°Ÿ €¿ÜË °űý'Ãògö~”¿/M¼À”ÿFSn H „ãÃ(@ñ¿CCtÀï^«û¹êTꃅ×RK@ã T€¦ÐMÒ)C(¼+¼}ÜÅèPîozzœ…aFÒìçø† óM$ÂV!ÈÎnØ-~,ÉßÇc”b'A!xüuîŸJˆeïI«~[,úN±4FîûË2Gr¯TƒÎýæ‰ÎêØ±ÈÏŽï:?ƒÝŽP¼#q&ô[ýb×!žµ·UŠöëÅ~yFMàcuÀï×ê7/R={é'Ú­¢Ž±?mñÝÛÙ»è{>9º½ÑdÄPç«Çþë‘G°Ã‘Ý:<Â_XŸþSᙄPd@0ÞwÄðÿ5™š2ç”!á÷ºí¿ÃÏ´j*?Ó¯ÿñ3žþrꔹaj‚Î ý °nL…Id’ßÅ]‰Utƒ„ÏÉ¿þÍö*ŠB}ˆðåö¶''¶wÕÐf_wëý'¡ýë'´?©U“8XÔqB{\÷Šâ 4ÕW2³DøÇîÆwÆþÀ়gÄl-SÞÔO¢ ÓŒìNf³ úrõz?o½õæ›å¾¨ãk_»ç]|\ ýÙH$Þ&ž×¶ –%ž.ECVLîÕç]“/‡Rpër"†w{;ðZf³UªŒ0I¡ZU-oî(„¢ªV‚©ë0NˆŒ¤äõ8¼Ó›‰ŒL¬>V‘y>y¯Çé<|½tîî¹÷ÿâ~Ó‚Ënºâºûýõé-}«û—?uݹsÌ:08øÁ¶©ÔŠt²i}ê¡Õýý«k…J>Rðñ¬póåYBŠÊ2}±¿Ù³Ü{äᶃ?¹],ñä\¦êòæÇ®&ÌëBGE‰}ÑD¨“NXÊùi­èKåêkS?øð¹±7î®?Ozúf™žÌúõ±»èê×^{•Â4öÿß‘½I&{'ÉdoÏ Pmîé _~Óeœd×MPlÛŠtŠùà€H 9 ¯¡ö5„P7N…:ÐFákTawt‡ákx’?šðiPÕŠV± ¯y«E%âÃoamT I5xi·[-Z43»^ç|DÅÌ{1Àº2ìÂ6 jÞØ‘i£î ­>…Ÿrd¨u~’#1=opU^?÷¶ Ò¼ýÛ‡fì_;¿ïSýê甊Xeel o=“Ö)uzãFä­¾ýªZ¡ën@7á46¦5zpIÐY 5ãÔ踩Õ3x@ŠÉ!ÑyDxú³òGy <2K„—ÿ:ø…00õ0!‹ H‹©Î,ù;KÌâq M“<’â¿] äÑi@ ùÀܹœ9tà™W̾lÁ$4&†óT˜ £y¦®‚« “aâÙèÑ‹Ma|[2ñ[jü,1=KðG nƒˆšN†ÈXË7¥2¦ÝtŸ}þëœáag¯Ý?WdLK¤N˜K.¼Y)_²±•‘ƒ¥ÊÇô´ºóäRÈ‚xϹÝ6u:Ù,8 Ë~QÙ-öS‡*WÃ/`Ÿ2Ÿ„NœLSˆõ ŸÔʇkbŽëž—k \®áRÊpI*¬Ü§À¥ Í“çù¨ç¦Oä+òUÉ1…^Ê$½t‘îœFÍ üT°âåô‡³… \Š úoÇ©üU“áô¡„ÿ`$iÕ ÌõÌc@-}þÐùæŠgÒYŸ?—+žýˆÊæÎЛ7Ç_Ôõ’•å>È +!9¹”Ê¡b AÎ z'Þ¸|¶®k™ø%ÆØ]ÉÁswÜLû è¾NAfmx>Ï¢éãÆ‹áÅÜ^žÑ·àÃ4˜&¾Â|@É`±JzÂË•L‘ÞÞ)# ë£kÏ9pÎZü¨ŒÏ^4{Ú4ø@ƒÎ?°³§g'~ü«^ë±Ô!é¼8—g×1Ê»€4b*URLxs93žÅÇÊc—ĉ,> R`Äm.ž`oœÒS¤ô$ƒ¢_{ë÷®½ {ÛþíÓ¹vуpõĦø„^ 0•áa–9<nÀ£NÂBN˜È*dæ aÊð˜„ÇÎàI©)}"€êVƒôj¡šøñ[è“Ó·ïßÖMÔxœølû p.ú˜I=á³`JÌ™ ›f„èAÌ{avQðÑHje ûë„þËýñ|îzŸª0å¶rØR©Ù‰ý¤WÐGà ›³sñÒ@/ÖŸL9|e ¨eâr“©ä¡õzG X½¨ <ÀlZø˜SîiàSnH1èøŽä |SFW jà é½ê±ÓÀ_€¯ åô³A6F?Ñ=¸y dŠ“›gF R09a EžíÂ¥óQ™¯z™HaB–‘˜E§3ÐE¬<ØïÚiyÜìåqc‰C”2•ò”ÿ®¹ü»t’w\¬Ãù¦w„IЦœt_N¿F`â_üMÛªh;0›ç¿aküãíkXû“íž·KÔ¦‰¾™ý%<­Û ©O¶¿J×+þÆ–Â…c×Ѫ±_OaÿpßSl»ò’§ô}üǧö-*¬o™¤Oê›b°GÁÄòèã`ƒŠ.±Dè Ï?(Ä&MÇï›Ã,#ÌÆ2ÌE‰ÍI,÷-¦Ñè}Ó½ïã?›è]œK¾Ñ?Å Ç/0yKò¤ý Wæ0´Ù|êþ˜À˜yƒE_}•¶½újyÿâŠ2NÿÿÚŒ&â|F3è!çr«•Í]A§zÞ–,™-¢–‹òrLЃ'H9Æ»‡j¯“p½?üh€p†\/äø¸‹ñÄ¢h¹åÆÉ(ÖÕ ß3îÍÁ²…Ûñ±—Ç^ž æoFn˜Ü‹*¡ÌŸ2†} ÑïÑhB…€óù$¼¦dy8-=‡WäðNÙïÁ{ ؤÖôø; ˆF~Ãt* æO€…yâû‰0œFªŸCM¦†"- ´íø;|õ›Æ®¸á”q;eOÎÌÇÍhù8:H,; ˜7–#æ'€Áe±Ö@LÆ%m{™“â77ÜÀ÷'„¯3¾ö‚~¶Cçlç„fí³ 9jÕÌSqý^üE?Æ”z¹¡„¼Žš˜†©ÆÌNžwÌæ,ëÙ>ffJÚ(•=§0~ޝéX½§>•A÷Àh=ÝyÀæØ~Ñó?½þµC¹…“ìKÿ2X>fnw¼:rÈ6Âyje>;06õ<œG .ÀÃéB<œˆ‡KÏ¢­ãáu!RÇì˜Q#q2YUóÞŽ|@û8ƒ&D}™ú”qá“xÛÂÜ¡×6\:|ÙSðÈX¼æØ1ÐYv2Þ“ñ‹°T©0<*u<&­ NôJ>œè3š¹fìçhÝ<œŽ‡ñPÔ¼­#ïþX<Ü^_&Å4CÍ9{ÿa„ùðý¦K6¾ CÊC[v¡íÚ)vǬíŽ×ú–§V¾mÉ}"“›‹ó•ë<\e<\'àáâx8.e _Ùt¾rWžÊW(P³¹Z`) S?—]ì³ñÚ”=Ѳ[Ö8V~„˜HŽøÄ.¡t¢jÒJÚaÅ™KN#;é ¤EDÚMÄëú`2Jä7¥J.®w¯KC ƒP0×ödޓȯIÚ=iGc~VªÔl"UÐle¢`s€z¾„¿%&1R~V¯3ùàÑ’%Z)}ØUP53ãù4 kýLž-c¦Rè¶6–,ÄMº±iCš6(…ÕÐt×d—Ç‹±[^ÝòŸûÔ¿óľLì+Á\Îûxà5«±áê5¼á›+ŸúOÞpµ’ßùx~’_û8uûÖîdi7Šnö…e¼ÄÄ[`ŠYªÇ²ê6k¸¦¹­£‹3µb´³7¥ÔbcÓÌæ ¦º¾££°Ò£j÷54&:ºYë´z±÷ -? K´Që´Öyøµ]í³È–p<™™9€nZ…(fÉ«©g;²él/aVºjê©—#¸E…‘f˜œ.«èy½n£Çè«MÐLVß»‚F˜úP6NTd0q4ôþì®Ôs>¶ÝUkd¹îêsšÓn²9*Ô†Áª„ˈlŽm·VÙ»ãâ†3Ò+»ƒ õÉù•îH2I.©­u;My–¿Æï¯ùlƒÉ´Åª…á9±u>ÅípÈŠ½ÒJe›*Tš}ÎN%çq]ês(õ }ŠËî?¶e >¯vssZ›7OKç"~Äw³ÑXÕ\¥lø+j|¤”@Øé3W ªÍëútC½âð©~›[éCÙb`: ^¶’‰‘’%ÿ®ïð(ÜgS“gÛ,Õ…p†–êø“PcfLDT,5´à³|&UjIx° 86ÇLK;Ë!„*îR6Yå›”B5pk„'JGªM¥VƬ˜)Í¿EØV&®u˜²¨^cZ¼ÊŽ|“zŸÅ)VÕqì[YŠ¡jõ>³"E“¦Pµ„˜T³GøöeQ¶ÑŽ“%šÀ%A–o„})o²>åõàÞeVßÄ,ÿíYxø™û—Žþùa÷Òýù hr÷•·­énªySèW|k“\9}Ú´éÏ‚Á†§Pf0ÁAÉy›»º’©ÎÎä™g\µÊn6{Á—êúÊJöÉ÷‚…‡ý} Mê1¿)_mºT¬61bÄ’%_%£p$Uò•sê¡E¢ Ê8“™@Þ … ÈŸ5J¡×0ë±Â4ø[ŠÇ*µdqxD”úÐØµ¬Ïn ©eTó*æw,¯Ó…êJõ6”£øµ¾¼ÙëØôýê7Î{ã_M?uÕùÆveáò…JK¼/ï+²ÏI"ÝÙ¾`Aû´ÖÖiŸ-S>¹~9<ßœ@•ù#)VãyBm"Nä«R¥FN’È{Ê nó®d>‘(™yÁ–,š, ïp&(°V>z/oN–B<ßÍB6@ã˃[h›”‹µQwÑZŒou*ø]qrÑW·ôE‘Å·Ö*£‘ZÅÕX„Ï©ñ­`ÜÂÿüø¢¶èȇÕ|EG¾‘±/QGýuÓšö QI7#éÍ*Ë®wj ¨³4…™T6W2¯Ëò¢ÌòúRžZƒde£§X×XŸ‹Õ—åSv9-º+™̶‰Ê{öÈuk£û²}­ÝÍgDWE k.Ú»öš÷ñðHt±O:ã É·8:R=-¯ŽŽxäÝ»eÏHt8R;¸¾·w}‡n0˜<Šz˜•²öQªæbAs)ȘÖTIÓ³'KžJ¬+yô-'afóVp¿ì Fï¼;YN ¶Saš—ÝÜXT˜Æ¢`œº“ñ2JLüTƒ‰3+`ÝÕ0£ UÀ¦E©2Ä– äT–JΕΈ÷úÜ@$Ý¿ LZ¦S÷úô®ìzzڪϾõàÁ•kÒ«/X»özÑÆz'¶©{™iI|ÇŽøbÓò]:’Ëé›ÄOÂäQRô¡„ räÂåŒÑys¢dá$±rif—Ú`uv©G ‡<Ø Ã«B€˜›#á¦Õ㿲TÒy{KÞÚ‚"Ó†©¤­JÁ‘ú€ä-t“+—Ç ¡žÿ,^Ÿ™Ÿæ€NM a\p ÕÜX'©yðÌaubûr`œjj¬‡Ö.=×/#N¦qÇ•½wú?#ÿÂÖ$KÂõц]Wì0­¾fݺkö¬l¨ø²@ Ö£Â&¿Ÿ~¹yËœxüÎ ^¡,ŸãyŒW2å3tNO²heû~–z²ää§5h ;q­&"ßaÌ¥rla%Ó‹iÕqYõ¥|]ñ'ýÝ››3™õW]Õº%Ó²©Ûÿd¼ÿ³3:V/_±tIÓšE­3>Û" arí‰0„’EùÖ`!*0¬·|±&ËzZÃáª`pº*L¦2 vf©Ÿ’›^çèórŸÖDI8©OÁZ–×ÔSÃ2?bJ¾½œ¾Ì2îµÑÚ”¯ô]ï æ±?Ìÿm±ú óÜØØUÞÊòµaìè$OÙf3fbçÉ×3jŒÎ¢³ŸzïðõlëŠ7ôRÌ•U?~‡x¿ðôYIXw BYôî,\Y"'¤¯¯¡õO²®è³Çÿ<%g=èÒ‰ñ/I &K¨D=´™f„&Å=8?L0Ã{|M°£»ö[ìûÃ4K i|”6Hf'Ìà{˜Ú‘€ð˜]ÖÔ˜O'Jg°%Ééd¼këF½ê×äßà};VýšgU|fù±£¥ø™ÎGÊCTð(ô‹ñ7^ø™)¬-÷¿Ýf!5 ï¾yÛ= ïîå/ܦžGOðÒJá;P ðR@ÉW`²è@¹|!Q¨°{ˆæÐ!ô£1U»íÆÕïÿñƒí ò¤šÚo»øt²’l%ÛÈŸÈŸÉz `‚GvíòuR/eŠÏ=j¿lI“3Ènrù<¹šŒ’ùy•ü–¼MÞ¥Fj¦~¥¨5å¿©åÿ££pÛ½ªÖï„‘›F@ΓûȘüÏÈÏÉ/È[´…&°õ3j¿Èãd1æ‡È—‰Jî=æEò ùWòr”ü„üˆøò&m¥m4ï¼ =ÕaœfO¨ù§:òßÑ ¡GPÇ8# <‘ìÈïQG­gƒm7jÅ–íû±íéjŸµszÿÚ­ûÎ?pñ§/c¨6iý yx¶ô’dYBV“Ïo’oÌ“GÈ äC2´˜FØ+!µß¦‡`’ÎûЗ ˆÔ¤D@8?Óõß´~ ľ èüˆ¼ÌÂN_%ïƒÂ §j¥6ª;2o_«Þ\K~4eKØ[Záíw˜¡œÍëÁ"J%½©,êù n†X„}n‡ayÜëc‡h”á_¯OŽÔ·ÐúX}.A³9ßäÿç"˜Mjrn&Kew*™óá;¨Á†h ÔVXÛ1|=X©l&}ƒÈ5º‹eà-X’pç, Ê-þ[+»Aƒõ©EHçRÕ4›I'hªð_PZj#·¯6–I£9—  ûŒ ÁìÈøã:—ŠEœˆ5úX®o7v[+;i½ÌÚ8)¾ÑB3¼E¦LþTõÌ€l쥠:Ázhºô:ºåê½[Ÿ•CmÑl¹a¦Q¶øª=Õ²»K©KuÖWù¦ÕšL²Í&KÁ3ú·‡Ó®tD°L‹4IÖªy’;wž¸^:OôÌõ÷.x)(deØì—ìC~Y^.öµ5ãöJ1Ÿdu7$g§Í¨RË4›\¬7( ÿüu¿Ù¿QUªmSìö‘š'õU¹ƒa‡ÁàÒ´Œ˜œ·|EÓÒN»ÍlÕ—uCÅÒ>©I˜9¿Ijcn[й@¸&Qa7¨ÓzeÑMgìXÙnª´ªÆ(©vA Sº³bu…Ó²‹²ê±Äé‘t55µØ+©Ò꤆ÚJ1¼,ú_Z&n°i5tWǺ:ÓÖÓç7;¢‰ˆlÓB™*·6m¶±+c•ˆâ´Ù=u^¸Ç£x%§£;ØRŒ¶ ÕkšV6v§ºMµ›¢3ìÞP]K³4'd%ɶH—!–H Þ&©Ò.{YU´U¹}º,´"ªÑ•Œ‰Á6™VIö¨Õ’d™–5›Ç, F‹–hÎ…+>­[ôô´·[<¢;^åÝQÕbq›•sU–f ÑŒU<­>¥Énè0Uy¼l_º×-šEƒgö,¯d;*¨"~y…Á5:l É#­¨2‹ªDMBD’BŠDe©M4ËiêM~ßUvü~é«Â Ûž‰ú&}œ+pAxšk¨µÉÑXÅÓ ‰kxùšDéjžþùΫ¯êüúD©ûU¢””I|K*¥´žT÷-¶›í¹7™,màù/œ˜m…¶”B+ˆó,çYžz!?ï?Æõª÷7?ÑÏ7÷.Pòû/ìmû Îã£gí=ÇÕ8z6~ƒÑó/ØTNjXù³;ŠPºÖý{÷uö9ç_ÐÂÿ¡'•™õ²¬·>¿Í®CÕñiË–_ü…›nþÚíwÉîûÞ³¯°ÍµÐ°$kV+5·¬Zó+¬Rû5±¶T휭ÛÎ8÷S¯½ñ&Ö.Ôò# Ÿ¯> «ÐUŸûâu×ß~V¿¡ö©Îé‹V­ÛzæÈ%Ÿ9òìsÏÿÅר–¡V\¶ü—(µ¥;þåø-­õ©ªæ‰7·º³]÷=ôèw_úñϱqRÍ?Ñ‘Z+†ªŸD³³&Keï.öR_.›K¡(Ê–Ó¼¾GÀÝFx(RjAìÀœ ’bHDo ìzo5õ¢hٕٕÂÅMPÜ_« AAîÁ[Øo= ·“Ç24B R ¤b5õ8¨å¥Ïè¡WoDIFÏLâ `ª¥si•õ±6v{Ùoö ;Až‚EXŸi‡ÂÖo¢¤óÈ9o*Ù ëLV,² ‚dqHr8$B‚¥}å´½‚[’?·¢!`r/ûR§°Àój¡öŒ(Î8{‹0C^qìâpY&Á$›ÌÛoÛ;( ™54™Ü­ ¡ÆZjÐê@|ì_pVPKº×EíV¬ïµ4(r,•mq‹ É¶NE’›ÜJ·äײ7µ÷IËe94Ç*ù[‡-+ûKBÀáÖdÉ‘”Ýî5q9º8*"²7n“„ £ÅJÿeF2 »Ò/ʪР‡h Z$ï¬ÙLiwoÚ').ÚXeŠø v%jòµzÉš‰24[e®Qd›ÃbT£nÑUÕâ0öôxÄnÙã Éá\ó@B³<¯Wë«4—Éâ¢bÔ.UQË\1–t‰ —¢j…€Ï]eÕ¬3—Z5!ˆDa—$}^Ñ h5ýDT°9•°?`4EÙ,¶I2•*4øˆ&*©¢Ù]k0‰nÌ/Ÿ ?£ÿ,Ì%FXÛ½$H¢ %HŽL}‡m|õ$òmGq[g|Z)L‡ßÅg|/w`Húdà˜/;âÂîfKkáŸjš†ÕWC\.sÐÒó¦¡84—J"Ÿº-Ai²Ù,KV–Á&¨›d3ÉÆAÐ"b…I‘âÙ¢IͪI„¹"HjÉæ78d‹Sø“Ãn4IqÅf°Ø%IÑ6H·Aq¸­*ðKðY}q0û¦c@cj¡YÚC躄Śo¦»è9âRÜû7µîj]ën>QëîgÕ¥W¸d Æ¡ëáuzø.]éÞDÖ“½Ð(Ý›ø–Ïë?yÅ¥×Ë*ø¹‰üGG¢2S¼½So/¨ã.Vë˜RëP G`Xnáêø7n9Òþ>b·À ]ì…ÙS^˜­¾GáïÎdé1Þî1veÎÉŠú³ ¨?«+êç.à}ÿ{rÿ}%ÿÜãwûyï㣷Dû÷•Ñç¿ÿHú𳕓¾u(çŸÿÂ÷ÝïsÏOøË(àûTíÕëWnÛð§?£Yð¨¯.•©ÿ õÑ”®GTP‘¹ú¿‹ì!ÈA0 ¤8Eý7Q h½´Ž ßÐ ¿Ù]¸å0Ô à[ 1ÿ€]¾òS0þ”ú·@zµÒS«»ÔüWáÏl4êÉmä&r;hÌw€ð:,Äm4C~L§Ó^Ú‡¿ð=µ?œ&1r-¹Ü:øË aƒêL“4Eûé :‡Òaº.¥Ëéit-»®e ¾û¬ö0©¦gÒݸ¦<Æ–ŽG *D§{ÙFå.݈ØËŒˆ³ñM`Dìø¾°ŒˆŽîuýÛÎÛwáE—~šÞ¬õ×ÀÀ7ž b-¹‚|ƒÜ 8?@b¨Ù@Ù2Ãt]FWTëª t ݆ààï¼¢~´$î(ù h³_è×ÀX{©tVhŒ {T­>T™ ým45^2ÿ‹‰\65d04ìÔ³2Bs`¹ÏŸ{ýƒÃD­§™ØàðÈ‘²½ÁÌ‹O28dhð§Z¾ÈÞ`¿À—]ÏÉæ[Š{h:6ÅÚóTs£ Üfýƒ~äoY™ ‹Ãs²ÅQïõáïÆ|Þ$è\+{@A€Ïj u2¢Rïs£íäuCpdÄjÁ\¹~óvo _)·µz%´VfɲÅv‡ew§oíŒýñ¨ÑhtX-ÁåWl¯f¶Šr€±â Iîì¹Òzé\É;¨+6‡Ðâ—ÌX‘úÚoÊj~©[q7É’Òi“5Á·ÉÑ`L榊¶ßäߨyý6-v[D4·à¢¡"Éš¦¥…äü{›–t‰V€²hr:ég†Ê,4T"`¨T‚R>_èÜŒ]wôÉ’[è=M•P@…á7m°T²E:ì_ãvËIìØíÝ‘tÈÔâ ޤCŽPþ¤¥ãX*.A–€–.[:$(²Üà7¨°lyM6)KU .)¦Š:IÒ,rXðÊ·m6o`¶MT²ºÐ¶q4ŸbÛô¹*@ÐM³Çòq¶Í´$Ø6°êûŒ'X7Z«þ]ÛFÐ,&K<'j>U8Õ´Ùcõˆb š›6V‹f±xÕmgµU´|‘7oêÄIûÆßöØ7§»l(:b£ 8-²ã8 ¢ÑöY 6Ùïíqšà‘ §Û¡̪Mp:)ǼAb{…m„º^A‘¢†'}¾TÁe<–w&‹2¬ã‹»@åí©1âÀ4@ï#¼±Øgc—û™O„ŸpŸ7óu9Vtº™í£š‹nv®äÖÌ…Jt*ñ³mp<6±à†jQ6™€f;¦Ž¼¬²=OLþ”Άq&ÊU”§&äwˆ¶ ï¡îá¦ä-=tkߨ‹k^ú2ýúîÆÅÛ"ÛÜ ºÆVíÚE;ÆVÓ¯sÇßžðÄñÓLgª¨âi¯Í„7õÌCVðuDÑ ?8ªfˆ†ÑŠ$W"vÛ1v"ªf˜€GÁX rÚ‚Àƒ·Aµ££àCl<ìh×TƆ©|g¦–m’"j)#CjNòôowíªsx«Û²C «7§Tlú "–YÚª*Çïj5å^4LÿSŽÆc»uô`UèÿOið;Xˆ5ÇjRGa\s°hÍ"Cd„¬€EkÙI΢Ëu¦.ÐÊò+RúùY)ÛÀN¸g§JY®ƒÍJ–l.¬+6Í;3•J•l\›‹ÍÝžã¶“ûŒ¤J¼ý" ÕÙìÍÆ• Wˆ4~ÔãuMÉ|L)dhc±¡¹»éeõÅÙóA)ß«æBûùÉÒÞþLvAÔv¨ÛÍ<ïPm>ýÚ0€ÄáàqO>¦Ž*Þó7Èh÷YÄh0ÙŽ¼s{Uí>³4cÉÊuøl‡:ºfýæ3ðëvmtãÖÓö²³¢¬´$G0”é]¹f+÷YUâs6ãW›~ßâÒÏáó꨷u˜uҥ݉ú×­ßË´)‘Á"î°Á:”Â=4ÙëF½Ìêø'Þ¥ÀêAÉÇšLÄ(»rØ6ƒk3)xŠ‹3zG¸X¼G•=–ëÑ~¬—»®ü­yÿÊ+ßû?¬——ÏèñJO> fU÷ò ÎøÜªT:Ý–K­ºJBë¶¼ñÆé›C-™3ÕeëN_j3ì¼Óµ+³vÅÚÕ›o Õ{V¬_š=Ãh;ýŠÝ­-«W·t7¯Þ¿J~šú|ôiyU5¾ôímÛ¾TÚ´¤R1˜åò/;²ÔÓ³X¡ßöj‹ú|cÍìÖÄÑ¢«gì¯Ë‚"N*âƒtþñ;èÈR ”wO´¯×C#¢²b=~ºg©W–ÏZàò,KjÅ›þ8{öæE~2>N:aÎ_T"$&E4ˆ½ã0Ö¦FèOlF¹eùH¼¦cxÊ(Ñ|%?B±1?XR~ë±¼Ÿ;#Ê ¯‚åƒsGÁïVµ¢MÙq–Z°›Pöìü¤Ë«-N±CÖ¶¬’M…½`nUçÒ5‘r´aïU7ÑÀU}W}ѱúÖ5½cÿup(Ú¶_GÝ·ÞzðàaÚ²ù´Õ›úI¦.š­c²cz{„n°§õx£%ÓÒo•géa¬,ý•`žH»ƒ£Í, žA0‡`ž8sªKé+ƒ1IéÕ—ŒU?W¤_6Ö¹o6ÂÎÈp ÐЃ~½,²Ï ¿éÂx¬¡z´ ;Ž•ÏþlfvÐYUø(cFynÇ3çQqzØ”w•=rŒ5ÆšL€{áÆTÃÁÿØÑ^¿éºL9þÂóÓgL?ÐE_îên[ºeþÊþó÷®\Ó=0mÅYŒ_!|`ª{–ûˆG`¡eÖ®9Q°Àø*‰‚ዲКãXÞfeŒ%z¡Y˜¯Dè0š†pùQÑËEÑŠšeó5ïP}¸Šh#Í¥’lÓTcÈ&ÑŸ0—Ï»`hÕ7×F†gì^°ðôgvíÊÎ\ßsÉï¿àîK·nÝÞ4ÒØ¹hMËð™#šiÉ‚Îu¹lù\úá:ÀÅÁóG`âÉÀ‚‹“!èZ¢{¶³4ÝÎDÞ~4oHl–aÊÆÂZl˜sÏÎrÚ1ƃlv} $¢sc.ãò‰©¿Ø­¶>õ›GÿxðÊÁÁ;„à6ú½ÌØ¥wÞyÞÕWó¸y ñ5Âtâ'—¢„4ö™t›Ö{“Z΂˜w$ VœG,ù Ó_Xö §;ÃÈ,êûX!Àò¿Àü1QÓ+«£¢Qõ2/äR0Ið”ºÜl ©y'ôÚÖyàO¶ìÍÕ´Æ¿ñÊ-ç]ßEÇÕ±{æÞ¾i¿¹Ê=ª™±»ÝG÷œu­/·ùÊݽ9" , Ï/¬ñ{IÑÐ_MD–6+ÙCnôäµ#Ìí§à[“¨•áüWÍǘ'OЇÕv‚IÆù.-EE%XiWóVô]ÁøcIe1&èÛ“K2U̘‰ˆeÒµ‘Þ¯,<¸«¯;~ó^ÓêKW¦{öí.\úu¡ï ýç.§lLÒæõÁmk{³;¾pÎ̇>{ÆæÁ¾˜÷`üBa7È™Tò»ÿ ,,Ep!lôùÅ8´žf„ޱÇ¥³è3ûvÿF+IèrÐÅGjÀTÏ‹”©ÊX2 Ɖøm¿ùX^ÆYTkfÂý"f ÍkX]ß«ÍÌ£¸ý2ûý|-ó3k£žJ¦uU*zBC%¨D¶ká:ÝåMY´PÑ‹ÆÖsÙÆìO0Œt[6=«»½)Ôóèwº«’íWv_ò§ 7/¸nhÚ¢ù›«&ë»ÏûôY«µs:Ú›N£työð¬OåÖµçnnÎd†«µZ½ ÕíohA?©éã ÿsÐ ¼±F³Ñ?ü©N$+€ ^@Ó« +ç•dÁäà\á-åjAÒ'üÃ3_­ 51WN-ÍŒg†7ÿÁ:Îò…ŒÝÈôš9OèÞwÚ{Õú±oë¾Ïä>3¸i Ú~=õ_‘=72ó®K¿½§zOdãðô­ß:+ Ö¢qÕr¾Î _14²ìËIÑÈ"óa EC»a"Ûdc¡C¸Ä@úùÎZêýŸÝÊwÖ,JÞúxÁÙŒ;kdÔbuzÙ6ÙÄ7vÂä0: 7†è±`ÇÐU*J%ö*2,z>0½‹ ÑúÞKèš‹/;ì1…o™;=Ü=2hø]ýØcc_ÿ.=sy†nˆœ3vH;ûs¹}ýž‡q±¬ß—éë·—Lyᆉj·±X%¿ŽUc•¼ø§÷r¬œJ^y¼àN|VNÅàX•¿1¬ì8_„޼_- A•7pÙÉA­Ý+ѪàOq« nˆÚUtßÕÅ f]~ÈÿûšÖÑÑæQ?­:xëmco®|bim12?¶hð\×ø‡ôv:tWsåÑBL%Á`ܲ\@èJ‡ÑÖ<ƒ -p²k‘]`Ç{<ó½DÏ(æ~VvŒëZ~zaÙšûÎ Í®¬œ}Û𪻮øñÚiõc@Ó»–ê5å8¨ GÔ X„[-ËÁâPEÑYU¬¨ 3;ZªáºœYÕ5æÿª¨(y¯–w³Ì/!ŠãÎõ”á2S `j3½@ót†·5>hÐÖuÆZüí}ŸZ24«)~Ú]ËÛrª#ì·[*íJGª-žUŒ‘HK¦pÝp‚™¼ŽK"–?;UŽ ”'i%g‘¿«  Œ[$Ç„.ó'tLnÿ•7ø–75ímŸñJøî… çµ·—izEÿ°ƒÜ?Œåš@ƒ?ÎF"µZ²ê×±ùÑ· ]áÜ`œ*Ì“T±sW8Lµåá4GJ8¸è³P®D*]ZÑ¡yÙ(ˆ>ô¯ô@¥•ßmPÐÐãRqw0ê{uªk35ÆZç˜H¦·®Õ_Q_éžOM¶ë#•©þßL䂚3l}bA£-·m:ó Ÿ(`ñoà¾Á”ê‹n«³,¼È)DÞ{´äàPãî‹ÄÁ¨l38y„¾Â6+ò*2 ½\Là¼ÈݳÌ]ш\ÌÿgX¤sËþ¦æÊšÖÔ¥3—/j¨Žtúg ß°Éßk™YÙÚi ¢Î¥r_·ñ?Ñ­l®†ù\HösÊ‚fÄú\?­»iÇÕï-š9ö—Æ—ÙZ2gðv“ ©#¤è¢üâ̼`ÖÏácLðèU({ˆÊ·f¢>¶^[•Êjîù·p™ÃVmîÊx¿6’s#‚õrÎÍ×k¹+ …F‡â+·?xöõMí­ÚŒ€'”­Zª³:ÃѶ֞Å 7µï úíŠÙqžb7ÙàoÂäåûô€Ýœ¸D——XèH”T>f^}ÌXüjÉ9ÉiNôWLf¿mï© 6œÊÌÉXÔ 5D`çË2 Jâ6u¤kÍ‹¿ðŠYgćv红Q”Ë;¶ô M_µÁµÐT]ØvÜþ½•î¡áQ°”7Œo¦çñû¡è94,”`ÜZ»U(/'þ†˜…!-{¹æ˜¸mFq+l™·Ðß^áa.o‘ßd‚fñTÞvž"o… ty;R"º¼¥gÒ»&o½"‹CŸäÄîÿˆ¼uåþ{ò6Ú˜"oéáO¸ü.? éíÂw€·Îç4=Qæ:˜!æ`†Ø©â—‰ºO¿¸“'[X2YÄ2÷aÎÛTn˜•…±ëDaܱÿ¢O¯w®hjÚN¿Ùÿ¯Ò¸L󳀟Ü(ÍbùNfêÛ0e³›Mƒ’Ái2Ûõ !<,g­ e;ËXoG³ÍÎïñÐøÀ`8žÝÄÝ êÖð5­huº¸LFuh¨©6Æ|Ø™¾+çM~œ0ÞPïóOÅôŽ\°ßúÄpJb˜/‡MxæË¶ñô¾ßLwÒåˆRÅç ¿#ãc­rmLÈ ›£”{ ú¼úŒ°>wŒïÁ>¡î6œNV·s| ûBÞc:³•,âò„iË®m“&.hÂÜ|'Ú£5̱²Ùf±²Àû‚ÅŒó²Q`²Åhb³ }.êEWÊÕ™—NÏKx.ö s†²Ù¡Ìñwèƒcƒî­kÆgœ£[^*XÙA„#¬ÃÁâ/ N»#`m,…œ\5jÙÊ?[ù¦:Šº¼Ô’QÕî·«ÞÊ îØ¯zqèÜx–Z¤FW9²LÄd,n£Cp{õmõú2ìmÁ†¡ô—RžÞx®v0·yÝõ7w\Ý‹l_ÑQ—n¹«·º«“¡îá3–†߃?â<±J‰<~>á²ñG0ÂsÄE ë¾ú'(‚²Ê"Y?¾eüO¬Í½ã’_‰ÍP×3¾A¯»êžbu}ãõº×ÆWÒ âôeý:öµg|%yÊ"±ÏÁ6¨—ŽßFÆé£Ä‹7‡5ÁÄÝ©_”eÇ­ÜI³kÆ@wX‰F•p÷ÀÚ;>5+Û칩/Øš:ôõÑÔ¾¤²f®÷åC±‰§¼l_(Õ*5ÓgϘ1»¡58ýÖnègÖ§î¸`6ÀºŠzH•ؼxñxרk¢îñ÷ÄV¨»dì¿è¹Œ†_ QñFz‹"ˆÄ¡¼Ê5¬üAË4*܆e¢¼åñïÑ(킲HöŒ qÖÇ:*ˆzÞù‹ËͤGøš° Þ9óÝf(W@ùs¬|ÑPÿé!ÿ eQ2/› ¡îB¨»‘Õ™Ççð:øÿtÁ,”à½ÍOc9KæEa3”·JXö¯:Å•P6þûxj¼–îîSiÚ!|Þ|ÿ¨ð,”ã&,·³;ñy£ˆå(?ÇÊM*–ƒPÞÀÊ ÿ†eÜ“¼ß'[>Ä2Þù;|N¶Uaù:r£øˆÐí—.ŽÃ<›C¦ÓµTe÷4NÊS{Rf>L<‡zÇ~K½Ó/þô’%<Îàbº‚üË'äXÄ×ú©÷â… ÙúLZh­©²ŒíçSåÔ哉‚§$1Õç¼×‚­$R²hf›gf#´œL"<‘·œ˜¡6Ó9²eáÂ-–ŒŒ,:ß@óä^á à£Çê²ï‹ô?Éa¡ên_ ×Mo'û„CP÷Õñv^GBäba?}h¶â×X^F~ VÓoM7ð÷ˆC„=P~èa|n#× Ýô—P?…Ï?"N!+lrÍóø\‚1i> ý­fåCä,ñaAÆ1Y„eu<"¬×Ay9òPÖ) ³÷«Œe ÞogïŸö ÿ½íB€^Ïw?ÇŸ$Äè>x>ò}üý—Éz=Ïo¼Ÿû‰IÄþ¤•¬¿ðÜváu(/xÛŸ5þ¦0Mxæ‹i|—QdÙøŸ…×_ÃØæw¤ŸŽ mЧã^|î€þò9‡á”¾ÂørXÆòå„H{ÅP^² ßÿ+àО/|Ÿ7@ù1,¬Æ2¿WPï`Ïz'½Cø ”Ï~Qÿ=Á/Ü ï‹ÿV>/ibeé×,×äØcäñï3»ãÚ¬‚Á\¾œ‰48imn°yV“¯m¤²4ÐÜ4вá”ô%ò;X{D¢ý¶ËÉ+EAéªûü0ýå1õ-h;Gx—®‚¶Íùi÷;bïþ}KÙý³ðìâìÎ.í”ñ{3 Wے̃$XaiÛÞfYa\ñÊrñsJuUUµ2kù2¼ZxWÅ"žã¸X>ÕÚÙGŽ´åñ¬þeËú/ã9‚?¤}Ìg˜ !¯[¡fß+1Å+DF ³©±l¯¹5p‡JaÚ Þ¶@Ì@CíÅŒ;Îú?zš€ö…â»6’FBÙ¦VÇÊdzñŒ™oÍU«]ŽKûäôš>†ïï£ømk Vn¼æ+íGŽˆÍ—]Тn1WøP¨ob¾)ÂÉ©r`•…_>‹:*~w™ÝÉŽhyšgí¤Pî¹­³f ¼;g ¥e@ŒÏji™Õ’˜‘€OäáTïbwÛ–„?b“¦ÜÇû5ŸÐï`v$›],ƤRóSúž69¾Ý?‰3÷íG1 cÿ6ýH<Êdça†K‚Ý×$eÛúæÉèc£„Ç’£ 2~— S³÷ Fz<…Ùà«Ç0׸íñE,5^y<»Í;Ï`¾ùÚã˸Þüâñ\W<žE/üàñnL-Ñ{ÎpõÆ)±8À5|õ¸éàšÇMìw<q+xçñnŸ=¾€›Àã‹8hDOc§ñÉãl6y|­æ¯ N{<‹*ÜòxKá7<€Æ>GÅq …!„#á:! G0n×­‚÷], æ³íÑ2Z´îp‡â¼ÅS§<‘ò¶,}®Ÿ#󼚫ŒÖÄYì)Å} {ήéÓžyŠkx ÷u¥OÕP†I•È /^½PÉ{é.ÄÝ6Ë-Ù9P²•Ÿê4M¤Ÿ?ϸWç™$ÙPvTªöòLy­‘±O''Nt-5ã@_ŸÄˤȈïÓRîçéN~Fáv6Lƒr ˆ¸ çÂû•OÎHê=1V™¬Å³„­’6Ϫ~nö•t£éɹ±~i‰WÛ‹6¾Õßk>÷‰³À.U”gÉ^¤^ëy…¯”)mn£îÂÊÌcÞö¯¥mS¡I›ü$BÓ8[åÞ ézÄÙà¶œßõÏ•±îRZ¸çymØo¤MRÇ£KI¤2ÉPs(ùÞOßz=7EnÜÇæ©uçÖ¤5Io%làžpžçxèÄfÜ[ð„¢`›µ‘+M›µ5îÆzbLNcWJ6ž=‘yy8TYYhu¨Ì(É2YÛø;ÿàø÷Nm[V$ê¡ÃûØÝ‘k£s)‘kå7WUÑëtŽ£AÍ òÑ"Ùtí[VÿJê¶·ÁÙò¨‹`›n” sÜY2qÒþLŽ&*8¦ûØ”åJ}: êsÂÿ»^©XÛ…ÊÄö—ø—-9òUG±äFR¦ÓLF]R‚ýÓ´ÙhKW©‘oû…÷)t}90º¨Ê¨ÔiÄ6îl÷7ñº?Bxœc`fƒoŒ°1²!ÿÿxœÏÉm‚Q …Ñkßx—hB¡0@ 0tÀÏÌŠIY  `˰ç =Y:²ô¤Ï0Ÿš5vp¤`(k*zDÕ¾a–³hE+ÉeÓÞª^ƒù¯×áÞð?¹é-¹í¹ë=¹Ï!Œ#Ž@Ž9–'œÈS.å7ò–{ùÀ£|âY¾ð"_y“ï|ÈÏHÃ"_ðÈÆ@N"c3ysyÿjþÐþžPójó*w5ë"«¨Üßýkä.xœÝW{P”×?wÏ=,å)oD­Ñ©‘𨙦Iˆ‚1 "â—‡Åð² ´Ô‹MJM65&ñ™Ú‡‰tlš¶ÆhÒv2iÓÉt2ijfœLÇÚD;Ö阞{öCa%nþJf2wöܳßw¾ó;÷žóßý@@¨º„Q`[š›W žV/dæëðÉ'Γ _!ˆ‚hˆi q÷Chvî 'lÈ.ÏqÂÎ%Ù%N8°ÄÍòÌŠìr'\Èwå9UhaÞ §šïvå;UA Û¨Í%n¾Òп¹1é~P@ {@‹à€!-BZ„´p´hÐ"ÒÏ"Áãih…¾*#÷VyZj`¤º¡nì¯ö65ÂÁÍž*x±¡©ªNŠ|Eäi‘oˆ|Kä_D¾'ò}‘D^ô¶56Ãå&žàZSsµWAK[e‹ niÛÜ¢"ZùºŠÝVÓܤ’9N›ÄjædH=Ad¢ÈH–hÅoþ‡‰ "2TdH-Ò.’¬=0Eúv%^°Ì^˜‘¾ Œ™ip/äB”ÂzØ^h‡í° ž„AxÂq8 ¯ÂYx þ çáŸpþ§´r¨X•¦æ«E²×}˜:Ó÷Ÿ¬ëôuk¾Çš ¬yƒ5W[s¿¬ÈFOÓ)ëÊ»¾ÕÑ{Öÿk¾9èNköZóQkþК/ú<ýÇžèÓì‹ìe>_öfŸ½Çš{}s°Ûw?ØÂ ¾ì{2øzH¥h:äxèHX¯£Óg^é³ ï›„s´…ž¤©G‡Ò ô,4@'m£ú4‹õoÑVz†Úè{¼º'h€^¢ßÐctˆ¾C¯ÑËôSú5õR;åÑrÓé!*¤TDùT¬rÕ2õ ZNTB¯Ò+ô+ú-¡×é4ý’ÞP=ªWíV}ª_ ¨a5¢FùÊäÑ;aìö}~£Â°Æ°ßð÷ïïóÓíoF0Ž7ޱ—ÞLy‚~O»èÛ´“NÒý„§ÝÔOß§§è´—ŽÑÏèôszž~DGé  ´†½ø8îÆïbîÁ§qq÷á0Žà(>/àA<„‡ñÅcx_—ñ$Žái| Ïàëx߯?áŸñü;¾ÿÀóø^À‹ø/¼„ÿÆðc¼ŠÿÅkµÖv¬CôWô\}‡ž§çë|] ]ºX—êUºL—ë5F+éaj FòRm¦G¨™Z¨•þÀY¹Äٸ߬…Zh…nèãNs€ûÌ)Þå·á]ø|¤gëxê¦íÔÉú@;èQêb}¦žF?¤a:A:I;ÉÃx|':µ’JYOVƯ¢U¬§BGRMe¬O×áS ­f=MGpt©œõ:’ãÜDkXwê(ޏ–Ö²ž®£9ö:ZÇz†ŽáUÔÓzÐ:ŽFhˆösÇ:ËËF}´‡-2u,Ò>:ÌWž£A^o wpwâ\Ä}>I:*8¡¯èB]bú9!KÅ•9Q·ñ“z¼ ˜~?^{·¹3ùùTãó¸³Lè+¦Ÿ·´s}Ÿ˜TÛ\Ó“< °G,G¬8^ÓõRåŽKäVKÿ4«¬ø­2ŸågLìa¬MÒø^g™\ s8ëI:Y§èTÎ`gËÉ™É`¶±qGV‹àax.÷´9ÎÆï|¤Ž× zšv@×Z›×:RGéh£ãt¬0îm2Ä~Ä W⮺©ªz„F?³—í\ÃÃSv¬!Ú÷¼ðâUÙÁÙÍ2ö«dÍæÔ d×c¬óÅts#n•ÿJ‡ÞÖÂhª·ü$O²RýR?¬[m²¸«Þ´Q’Û`“UýU~ÂÍgùB¹0:^aûzȲøó8¿Ç¥´ŠÊh5•ÓZKëh=3ê~z–ùó&{Ö<Â\¹‡ÙÂÇþ,q˜y⹉LÁxY#L½¿3¸rÓ™nòWx`Æð ^µzŸß+äÎW2±÷ñŠ‚ ê¤.êñ„ÿÛ„ó 㟲øþ>§7™ý ÷ÖËzˆ²xË0V•°”á¨vCÝÊ@ܹ?–nmút‰tÝdÉ„×ï \ž]”Ã2Oò±\ÞCUÈ™Œß Z)ùMô˯R}|×ÁüÖÁ»T_aŽó[ hfµ9à`¾*†fª Hd^Ú©Ì6ci˜æ2»œ‡y†W¸L1`¢ñÃè¶0P0Â#Z¼'ˆ÷â=Süζξæýè¼QåÑ7<îäª3¾ìâ+’ùw1Ä1ë.ƒéâw–Ä>9¶ ÆbæÓQ¸Yô,<ã…æÌw`5¯éXÇØA%#ÅLDâsÏ(#¼tÁ›+x o±àÝ'x9‚·\ðŠoµày¯Nð¼‚×"x[¯Sö°Óïþò®Õ×SlüuÒó¹¯VÉWÕç¿æñÕÆ~þbÖ<ùd`:ÒVÑl–fãÞáby¶˜/-óû²| MøšâŒÀkNdÎä*È⡘‘ '»y dHK†Èø„0ã‘û±ÉS¸ä)Nò”"yš)yš'yZ(yºKòôMÉSŽä)_ò´RòT.yªx>x*x*ø>ð§¾ÜžÎñyäm çç!ÿøcà|p~’Íx–NÈÙçm€Nø ð”$’™ÚIÛŸ þ$ø“`ú¼yàIàIIíDÁQp3x6øãà'=;åFp¸j¬Í‘÷ ¡ï¢òÇÁ'ñ§ÁŸß¾ügÁ}¿á÷ÓŸü8—xç,p?àõ$tÈÈŸF?? ΀νàYÁ³øüpÐŽí5°9Ë"øNp9¸óŸïeÚg¯€#`js/Ú“áËi6õüÄ×y 6?å? Wô¡/wÑ·¿£Þ…³ ù4ð´$޽¿ý·Ñ'oƒ¯ƒßNtÊÀÁÁgƒsÁñý~k°­ ý _%o¡Í›à›ÐúŸË°ùç8ÿrÅogät0N}Ù¿E߈Œúÿè¶ÿu°Žû’À·Gû|ä}Š`\øòJ&&`Ì’m¼g¸:Èë / ÞK$a±ýóø¥8ÿ÷åõàzȧƒ§C><ò—Á/ûò‘S°aЗœCŸ›…èçÂDùÈ»àȧýãëO?ùðgC7¼ó·Á3C3HüxgcBÓf*8òûaÃýèg&v±ã‹ìƒü9ÈÿžéÃb\[ ù°ÏÁ3>7¦ôm9ÃïÃdcûÞYû©\L’ÇÆ»Ï3À3h‚ißÞ ¾òæeíøcóqñ¹íÐç}ž‰ÿ¬<ælLöåŸ? y6øÈ'Œå‹à¾á¤gTÁ*ÆE+¸r–ÙÜÇÚÌÆ½û`'mSÓxó‡Ý v¦C':ðòlhbž=?°32&GÎÉûògèxŒß3êç¬<4•‘÷=Ú=Wÿ¨þÈc~u4¡ °Áö-ôc±Åo'wÇb;#OŒþÈ0£ä²P9{ûI\>‹cÜog4/$ê³ù"xG°3–ü~¦ñÇL³±œ ýXŽðõ¿ ¦ó"ïÚMŠo•Wþ^ß.—ÆÅ™}:îZ ÅùÝ̽sq/ö"† 2c¶…ΣÀL<¤ó„jp5ͧLœåîÄÎÆj6¿ÇÚ÷埥qr6w4ÀΆ¤8³3Bâç¨4?>À¾ ÈÙÜÍÆ@¬‘9Ú36oäºÁÝqs†Ä¸Çú¼ ¶!ù¿×ÿ^¼#þ:]¸¶ üyðçiß‚i߯biÄóÂTî"wÕ»|7‰ÎÛüGÈýü|&)à³øI ÿ?™”óOðÏ’gùF¾‘tðM|y‰oç?Gñ|'YÂwñ_"_ä—ó«Èk|ßCÖñ«ùµäk¼÷Czù×ù^òÿ&ÿuò&¿•ÿ&ÙÂïáÏ“üþ—äüÿ.ù7þ=þ&ù-+Ä‘ßy6…¸güXȽȵÇ[—÷—ø¹ªÚ;ê¼£Þ;š¼£Õ;Ú½£Ã;xÇ"ïXâ˽c•w¬ñŽõ^ßlôŽ-o÷~ïòŽ>ïéß@¯lÅù*2áaœ_ƒä$ÎÍ€É+8ÿäÿáŸyG鈩ó)B#Ù5ÆËžöÏѳÑE„^#7åOõ‰?Õ'þTŸø¿©OØ=öZ{ƒ½ÉÞjï°÷Øûìƒö»ß>iŸ±ÏÛöûš=lßrGs'ÅIw²œ\'ß)rJœR§Ü©rjN£Óâ´9óœNg¡³ØYæ¬tV;ëœ^g³³ÍÙéìuö;‡œ£Îqç”sÖ¹à\r®:CÎ0 Ka#ì†SÃáìð¸pA¸8¼1¼%¼=¼+Ü>>>>>>¾¾ _ßtyWq-7ꦹ™nŽ›çºã݉n™[éÖ¸ÓÝ·ÙåÎuç»]n·»Ô]áö¸kÝ î&w«»ÃÝãîsºGÜ~÷¤{Æ=ï¸WÜkî°{+"D´ˆI‰¤G²"¹‘üHQ¤$R)TEj#3"‘–H[d^¤3²0²8²,²2²:².ÒÙÙÙÙÙ99999¹¹¹ŠÜˆ’¨5¢n45šÍŽŽ‹D‹£¢“¢Ñêh]´>Úmúñü-ÄÑ·0oÀjœC4}ÑôIä°X¾LÌ‘ØA´ŽÍS}qÁ\a÷hŽoNªGÄÖ±‰u¥bpq’;W k€4ÜëEp[â:-®~Du^LªQýG“ê;“Á“¡9+y—©¡<.—0í3sô&¶×>»n¼ƒÐõŒÏ€ÏÏŒ›K±óŸŸ?›4W êS˜³ׂÓ\J×>6¦br¼ßXÍÅo'¶e&ÍGÑ>];ÕXºvBNß×¼`\ûíÿöüíÜù]ÐÇ<˜“ÐçtÍ@çÓSÑÎTÈÓ_Ò!×c­ïp´?™qÇèwÀ´&ÂÔˆ9 mZqµ¿Ä±Yz¦®_ûÛp-[Ÿ¥ãeb艓[ ÿhŒ¹ŒÐäQ.døAF'7ôŒ¾ÏˆK䝸C£Ü ?wþ1¸‹ßëq/x ø ðLè|ü9\û&¸œ‚{Á0cì“ÃcÌE`3åû΂ÆÚÈ[h¾:2è3xEò}þŠoÿ$/0Üíë‡óÛ¤1‡Üd¸Œ¹t߆€bøFç^¿Gõýþ|¶ ÀÎÆÎJÆÎJÆÎ ÆÎŠ1;yº¶Xk±6&_B›÷ŽÙOã$µ?àcjÀ ?ÀèäÀælÆ~Z'p/Zƒ°aâ©‚mÔ÷vÃæ§ÿã^è /­¸1lfìŸÂØ 1öÿ,ζ1›K~:§DB›è·‘!܋ږ P›# Ûî×¼•mßh ¤}‚XG.3ü1æ4Ø 0còŒN}Ó÷yæ˜ßòÈM¤6 öA¦ÁβÀ¶Qßæ:Ðæ“ÁXc‘áZØ@¹•áçØÓ÷9š¸×4Æ?1¾Èݰu1² v"’OƒçÉKÐAm‚ü%®Õ‚øpˆÄçw–ip™ÍûÁؼ+ipo’<;‰Ù\Æ~ËaóËKGŠH,®‚ƒ¸úEðñ1æ>о¥ü0Ãyc×q•2«{Ы”Wù4p}ø1ð_ –^—ƒ¯‚i\Ó¸:¦qµ÷úwØð,x#Ãó>›)ÿ„á1:?„Í´Íïßô9ˆ·;ÀoÃþ5°áAØÿU0c«ÁÔ·¿<¯¯ó˜Æ±¯i[{Q?§\ȰÈ0õsÊ­ ?ÏèP?éûüîEýüoûWBNýüË`êç-`êç3ÁÔÏÀÔÏŸÿ~?_ÊøÌ—(3ò“—¡Ïó¿Î_!ñë–Ùõ Ëð«@§¶ÑÑDßãÜ«¾SZïar_Ÿü°ó³k¥.pWÒšè%\Kçoì8Íaú„ËïÇ›=Û0'$7’ÖJ¯@畤õ;öÙï¬<.>`ö øFçíàÿIsBŸÜnMÄö òÝÈÆÏŸÂ»xLççT>…‰Û4.½ùN¼ ¶ÍØwÍÄ{±ßJ{p­_—ç‰ÍÍö¿‹rŸã:ˆÀ½Ì½L$n·€ÈܫܫDá>Ïý Q¹/sß#iÜ÷¹Ãdw„û%y*d„¾E愾ú6wW軡#Þ¬àXè'^.þYè-oñëÐ5o…òGZ±uÎ:‹ïø[YȲ…qBP,L& BµP'Ô MB«Ð.t „EÂa¹°JX#¬6 [„íÂ.¡O8 Ž '„ÓÂ9á¢pY® 7E^TDKŒŠib¦˜#扅âxq¢X&VŠ5ât±Alg‰sÅùb—Ø-.Wˆ=âZqƒ¸IÜ*î÷ˆûăâ±_<)žÏ‹âñš8,Þ’I“)EJ—²¤\)_*’J¤R©\ª’j¥R£Ô"µIó¤Ni¡´XZ&­”VKë¤^i³´MÚ)í•öK‡¤£Òqé”tVº ]’®JCÒ ™È’lÈ®œ*gÈÙò8¹@.–'È“ä ¹Z®“ëå&¹Un—;äò"y‰¼\^%¯‘×Ëå-òvy—Ü'ËÇäòiùœ|Q¾,Ê×å› ¯(Š¥D•4%SÉQò”Be¼2Q)S*•eºÒ 4+³”¹Ê|¥KéV–*+”e­²AÙ¤lUv({”}ÊAåˆÒ¯œTÎ(ç•åŠrMVn©‚ª©Žš¢¦«Yj®š¯©%j©Z®V©µê µQmQÛÔyj§ºP]¬.SWª«Õuj¯ºYݦîT÷ªûÕCêQõ¸zJ=«^P/©WÕ!õ†F4I34WKÕ2´lmœV k´IZ…V­ÕiõZ“ÖªµkÚm‘¶D[®­ÒÖhëµÚm»¶KëÓh‡µcÚ í´vN»¨]ÖµëÚM×ÝÒ£zšž©çèyz¡>^Ÿ¨—é•z>]oЛõYú\}¾Þ¥wëKõz¾Vß oÒ·ê;ô=ú>ý ~Dï×Oêgôóú€~E¿¦ë· ÁÐ ÇH1Ò,#×È7ŠŒ£Ô(7ªŒZc†Ñh´mÆ<£ÓXh,6–+ÕÆ:£×Øll3v{ýÆ!ã¨qÜ8eœ5.—Œ«ÆqÃ$¦d¦k¦šf¶9Î,0‹Í æ$³Â¬6ëÌz³Él5ÛÍs¹È\b.7W™kÌõæFs‹¹ÝÜeö™ÌÃæ1ó„yÚnŸ²ÏÚìKöU{ȾáGr ÇuR 'Ûç8ÅÎg’SáT;uN½Óä´:^<ãŽüÊ?£¢ÂfêLp&ó5‘~¡¤ÙðNd´ØÎŸO€O0_ý?Ëèç$Uÿhukzb•/С­šÒvèWÌ>ØÜ›ÙŠ»cì¾±6骊«Mªf<~ŒÕ.÷LRu´–¹öð Ì—ÔñL%37®Ò5@âwu°Õ9fç9 ~Ø—`†ÀKl‡\BÆ~—‘ýA?$Þ‹Ýˤ‰+v•q9òVlÇX4ðT{‚÷»Â³ágtG+l`º{ 6Ëòy|Ð?~›Â˜ÍtFÄqС٠•äÃÌ® *§ÕéÞD_%ï}ò;°s‚ Cþ> ž f;c3FT³É«Ðy5‰¿þ¸Ü ^ ^Š6ÙX¬¾ãZÖ?ÓƒY«ÏìΘƒñ˜È¬³c†Õ!´Jüçй'ðy)ÞŸß—ýxǃþ÷+–‡Áÿ Æ.rüð l`g±š–ûGwÆÀžZ Ÿ\º-û;TBÁûe«¯Œ<1~²ýÉú*Ûç¬>CØx{w /ýåÔWS㾤 $øóÃcq‰/q±ëÃÊ™|Á>›GâbãJÛYåß7ý~ˆU³âÇþ¨OFâsÙÈ÷ÁtfÏ꿤HN~•¤Ïȃ÷…Ý9q1Ÿý"ìP‡ÍÌŠ/èOúÞÙ¼€‹ä•Dy\Îýrºj#¿H’310î‹›»Ùɬ>»b]^–x-KÙ1~[9Vú¤+Q·ó)¶º÷Ûÿ0­ì±óúeöå¸j@¢>ÝF¿Ú`·tðuïvrvNB«ˆY¿WŸÝUO+Æ?ÆNbZ¡_]™'§•ÒS3¹ƒuHþSp(.ïP}ækoÜü¡ LwþÍÓÝcL.‹‹½ùŽ™ƒQ_åt>¬œîÀ{òRðܱ9O°Û’Éqïˆ#±sKv¾ÄŽ_öyÙùÒíú!ãycúýïÛ?íIsv,°öÓÝØm<òè\bâÍìØdÇãŸAóó)Ol!þ8Ï&y²2ò¹‹,&kÉ#dé%Ud#ùyš|“ì%/>ò+ò"ù5ù-ù*¹îeúœåõé·¸®”à&ysÙß„„N†ÄJ±ÎË ¤RBò½s%1¼Ù²F’BÒÑzìÌý‹¿“žœÁLU m\#×,~ÏëÞëôÇ‹Ä"þ× ÿ?ü*›¿¨ñ¿Šçç@ÿ¿küûûóe¿êèûD·wøóÏÞÑó¿ôäxZïyR¼s®÷„¾ýÞPçõæ?þßÜL®•kóÞ¥¿VðýÊÿB“Šï9¶Ï–{OÂy>ex?i$“ä Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. Allure-0.9.5.0/GameDefinition/fonts/LICENSE.Fix15Mono-Bold0000644000000000000000000001064307346545000020726 0ustar0000000000000000Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. with Reserved Font Name < Fira >, This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL ----------------------------------------------------------- SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ----------------------------------------------------------- PREAMBLE The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. DEFINITIONS "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. "Reserved Font Name" refers to any names specified as such after the copyright statement(s). "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. PERMISSION & CONDITIONS Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. TERMINATION This license becomes null and void if any of the above conditions are not met. DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Allure-0.9.5.0/GameDefinition/game-src/Client/UI/Content/0000755000000000000000000000000007346545000021025 5ustar0000000000000000Allure-0.9.5.0/GameDefinition/game-src/Client/UI/Content/Input.hs0000644000000000000000000003005307346545000022461 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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 overridden -- via macros in the config file. module Client.UI.Content.Input ( standardKeysAndMouse #ifdef EXPOSE_INTERNAL -- * Internal operations , closeDoorTriggers, applyTs #endif ) where import Prelude () import Game.LambdaHack.Core.Prelude import Game.LambdaHack.Client.UI.Content.Input import Game.LambdaHack.Client.UI.HumanCmd import qualified Game.LambdaHack.Content.TileKind as TK import Game.LambdaHack.Definition.Defs -- | Description of default key-command bindings. -- -- In addition to these commands, mouse and keys have a standard meaning -- when navigating various menus. standardKeysAndMouse :: InputContentRaw standardKeysAndMouse = InputContentRaw $ map evalKeyDef $ -- 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 aiming -- mode) first. -- Main menu [ ("e", ([CmdMainMenu], "enter challenges menu>", ChallengesMenu)) , ("s", ([CmdMainMenu], "start new game", GameRestart)) , ("x", ([CmdMainMenu], "save and exit to desktop", GameExit)) , ("v", ([CmdMainMenu], "visit settings menu>", SettingsMenu)) , ("t", ([CmdMainMenu], "toggle autoplay (insert coin)", AutomateToggle)) , ("?", ([CmdMainMenu], "see command help", Help)) , ("F12", ([CmdMainMenu], "switch to dashboard", Dashboard)) , ("Escape", ([CmdMainMenu], "back to playing", AutomateBack)) -- Minimal command set, in the desired presentation order. -- A lot of these are not necessary, but may be familiar to new players. , ("E", ( [CmdMinimal, CmdItem, CmdDashboard] , "manage equipment of the leader" , ChooseItemMenu (MStore CEqp) )) , ("g", addCmdCategory CmdMinimal $ grabItems "grab item(s)") , ("Escape", ( [CmdMinimal, CmdAim] , "open main menu/finish aiming" , ByAimMode AimModeCmd { exploration = ExecuteIfClear MainMenuAutoOff , aiming = Cancel } )) , ("C-Escape", ([CmdNoHelp], "", MainMenuAutoOn)) -- required by frontends; not shown , ("Return", ( [CmdMinimal, CmdAim] , "open dashboard/accept target" , ByAimMode AimModeCmd { exploration = ExecuteIfClear Dashboard , aiming = Accept } )) , ("space", ( [CmdMinimal, CmdMeta] , "clear messages and show history" , ExecuteIfClear LastHistory )) , ("Tab", ( [CmdMove] , "cycle among party members on the level" , MemberCycle )) -- listed here to keep proper order , ("BackTab", ( [CmdMinimal, CmdMove] , "cycle among all party members" , MemberBack )) , ("KP_Multiply", ( [CmdMinimal, CmdAim] , "cycle x-hair among enemies" , AimEnemy )) , ("KP_Divide", ([CmdMinimal, CmdAim], "cycle x-hair among items", AimItem)) , ("c", ( [CmdMinimal, CmdMove] , descTs closeDoorTriggers , AlterDir closeDoorTriggers )) , ("%", ([CmdMinimal, CmdMeta], "yell/yawn", Yell)) -- Item menu, first part of item use commands , ("comma", grabItems "") , ("d", dropItems "drop item(s)") , ("period", dropItems "") , ("f", addCmdCategory CmdItemMenu $ projectA flingTs) , ("C-f", addCmdCategory CmdItemMenu $ replaceDesc "auto-fling and keep choice" $ projectI flingTs) , ("a", addCmdCategory CmdItemMenu $ applyI applyTs) , ("C-a", addCmdCategory CmdItemMenu $ replaceDesc "apply and keep choice" $ applyIK applyTs) , ("p", moveItemTriple [CGround, CEqp, CSha] CInv "item" False) , ("i", replaceDesc "" $ moveItemTriple [CGround, CEqp, CSha] CInv "item" False) , ("e", moveItemTriple [CGround, CInv, CSha] CEqp "item" False) , ("s", moveItemTriple [CGround, CInv, CEqp] CSha "and share item" False) -- Terrain exploration and alteration , ("C", ([CmdMove], "open or close or alter", AlterDir [])) , ("=", ( [CmdMove], "select (or deselect) party member", SelectActor) ) , ("_", ([CmdMove], "deselect (or select) all on the level", SelectNone)) , ("semicolon", ( [CmdMove] , "go to x-hair for 25 steps" , Macro ["C-semicolon", "C-quotedbl", "C-V"] )) , ("colon", ( [CmdMove] , "run to x-hair collectively for 25 steps" , Macro ["C-colon", "C-quotedbl", "C-V"] )) , ("x", ( [CmdMove] , "explore nearest unknown spot" , autoexploreCmd )) , ("X", ( [CmdMove] , "autoexplore 25 times" , autoexplore25Cmd )) , ("R", ([CmdMove], "rest (wait 25 times)", Macro ["KP_Begin", "C-V"])) , ("C-R", ( [CmdMove], "heed (lurk 0.1 turns 100 times)" , Macro ["C-KP_Begin", "V"] )) -- Item use, continued , ("P", ( [CmdItem, CmdDashboard] , "manage inventory pack of the leader" , ChooseItemMenu (MStore CInv) )) , ("I", ( [CmdItem, CmdDashboard] , "" , ChooseItemMenu (MStore CInv) )) , ("S", ( [CmdItem, CmdDashboard] , "manage the shared party stash" , ChooseItemMenu (MStore CSha) )) , ("G", ( [CmdItem, CmdDashboard] , "manage items on the ground" , ChooseItemMenu (MStore CGround) )) , ("A", ( [CmdItem, CmdDashboard] , "manage all owned items" , ChooseItemMenu MOwned )) , ("@", ( [CmdItem, CmdDashboard] , "describe organs of the leader" , ChooseItemMenu MOrgans )) , ("#", ( [CmdItem, CmdDashboard] , "show skill summary of the leader" , ChooseItemMenu MSkills )) , ("~", ( [CmdItem] , "display known lore" , ChooseItemMenu (MLore SItem) )) -- Dashboard, in addition to commands marked above , ("safeD0", ([CmdInternal, CmdDashboard], "", Cancel)) -- blank line ] ++ map (\(k, slore) -> ("safeD" ++ show (k :: Int) , ( [CmdInternal, CmdDashboard] , "display" <+> ppSLore slore <+> "lore" , ChooseItemMenu (MLore slore) ))) (zip [1..] [minBound..maxBound]) ++ [ ("safeD98", ( [CmdInternal, CmdDashboard] , "display place lore" , ChooseItemMenu MPlaces) ) , ("safeD99", ([CmdInternal, CmdDashboard], "", Cancel)) -- blank line -- Aiming , ("!", ([CmdAim], "", AimEnemy)) , ("/", ([CmdAim], "", AimItem)) , ("+", ([CmdAim], "swerve the aiming line", EpsIncr True)) , ("-", ([CmdAim], "unswerve the aiming line", EpsIncr False)) , ("\\", ([CmdAim], "cycle aiming modes", AimFloor)) , ("C-?", ( [CmdAim] , "set x-hair to nearest unknown spot" , XhairUnknown )) , ("C-/", ( [CmdAim] , "set x-hair to nearest item" , XhairItem )) , ("C-{", ( [CmdAim] , "set x-hair to nearest upstairs" , XhairStair True )) , ("C-}", ( [CmdAim] , "set x-hair to nearest dnstairs" , XhairStair False )) , ("<", ([CmdAim], "move aiming one level up" , AimAscend 1)) , ("C-<", ( [CmdNoHelp], "move aiming 10 levels up" , AimAscend 10) ) , (">", ([CmdAim], "move aiming one level down", AimAscend (-1))) -- 'lower' would be misleading in some games, just as 'deeper' , ("C->", ( [CmdNoHelp], "move aiming 10 levels down" , AimAscend (-10)) ) , ("BackSpace" , ( [CmdAim] , "clear chosen item and x-hair" , ComposeUnlessError ClearTargetIfItemClear ItemClear)) -- Assorted (first few cloned from main menu) , ("C-s", ([CmdMeta], "start new game", GameRestart)) , ("C-x", ([CmdMeta], "save and exit to desktop", GameExit)) , ("C-t", ([CmdMeta], "toggle autoplay (insert coin)", Automate)) , ("C-q", ([CmdMeta], "quit game and start autoplay", GameQuit)) , ("C-c", ([CmdMeta], "exit to desktop without saving", GameDrop)) , ("?", ([CmdMeta], "display help", Hint)) , ("F1", ([CmdMeta, CmdDashboard], "display help immediately", Help)) , ("F12", ([CmdMeta], "open dashboard", Dashboard)) , ("v", ([CmdMeta], "voice again the recorded commands", Repeat 1)) , ("V", repeatTriple 100) , ("C-v", repeatTriple 1000) , ("C-V", repeatTriple 25) , ("'", ([CmdMeta], "start recording commands", Record)) , ("C-S", ([CmdMeta], "save game backup", GameSave)) , ("C-P", ([CmdMeta], "print screen", PrintScreen)) -- Dashboard, in addition to commands marked above , ("safeD101", ([CmdInternal, CmdDashboard], "display history", AllHistory)) -- Mouse , ( "LeftButtonRelease" , mouseLMB goToCmd "go to pointer for 25 steps/fling at enemy" ) , ( "S-LeftButtonRelease" , mouseLMB runToAllCmd "run to pointer collectively for 25 steps/fling at enemy" ) , ("RightButtonRelease", mouseRMB) , ("C-LeftButtonRelease", replaceDesc "" mouseRMB) -- Mac convention , ( "S-RightButtonRelease" , ([CmdMouse], "open or close or alter at pointer", AlterWithPointer []) ) , ("MiddleButtonRelease", mouseMMB) , ("C-RightButtonRelease", replaceDesc "" mouseMMB) , ( "C-S-LeftButtonRelease", addCmdCategory CmdNoHelp $ replaceDesc "" mouseMMB ) , ("WheelNorth", ([CmdMouse], "swerve the aiming line", Macro ["+"])) , ("WheelSouth", ([CmdMouse], "unswerve the aiming line", Macro ["-"])) -- Debug and others not to display in help screens , ("C-semicolon", ( [CmdNoHelp] , "move one step towards the x-hair" , MoveOnceToXhair )) , ("C-colon", ( [CmdNoHelp] , "run collectively one step towards the x-hair" , RunOnceToXhair )) , ("C-quotedbl", ( [CmdNoHelp] , "continue towards the x-hair" , ContinueToXhair )) , ("C-comma", ([CmdNoHelp], "run once ahead", RunOnceAhead)) , ("safe1", ( [CmdInternal] , "go to pointer for 25 steps" , goToCmd )) , ("safe2", ( [CmdInternal] , "run to pointer collectively" , runToAllCmd )) , ("safe3", ( [CmdInternal] , "pick new leader on screen" , PickLeaderWithPointer )) , ("safe4", ( [CmdInternal] , "select party member on screen" , SelectWithPointer )) , ("safe5", ( [CmdInternal] , "set x-hair to enemy" , AimPointerEnemy )) , ("safe6", ( [CmdInternal] , "fling at enemy under pointer" , aimFlingCmd )) , ("safe7", ( [CmdInternal, CmdDashboard] , "open main menu" , MainMenuAutoOff )) , ("safe8", ( [CmdInternal] , "cancel aiming" , Cancel )) , ("safe9", ( [CmdInternal] , "accept target" , Accept )) , ("safe10", ( [CmdInternal] , "wait a turn, bracing for impact" , Wait )) , ("safe11", ( [CmdInternal] , "lurk 0.1 of a turn" , Wait10 )) , ("safe12", ( [CmdInternal] , "snap x-hair to enemy" , XhairPointerEnemy )) ] ++ map defaultHeroSelect [0..6] closeDoorTriggers :: [TriggerTile] closeDoorTriggers = [ TriggerTile { ttverb = "close" , ttobject = "door" , ttfeature = TK.CloseTo "closed door" } , TriggerTile { ttverb = "close" , ttobject = "door" , ttfeature = TK.CloseTo "closed door" } ] applyTs :: [TriggerItem] applyTs = [TriggerItem { tiverb = "apply" , tiobject = "consumable" , tisymbols = "!,?-" }] Allure-0.9.5.0/GameDefinition/game-src/Client/UI/Content/Screen.hs0000644000000000000000000000563407346545000022610 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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. -- {-# LANGUAGE TemplateHaskell #-} -- | The default screen layout and features definition. module Client.UI.Content.Screen ( standardLayoutAndFeatures ) where import Prelude () import Game.LambdaHack.Core.Prelude import qualified Data.EnumMap.Strict as EM import Language.Haskell.TH.Syntax import System.IO import Game.LambdaHack.Client.UI.Content.Screen -- | Description of default screen layout and features. standardLayoutAndFeatures :: ScreenContent standardLayoutAndFeatures = ScreenContent { rwidth = 80 , rheight = 45 -- ASCII art for the main menu. Only pure 7-bit ASCII characters are allowed, -- except for character 183 ('·'), which is rendered as very tiny middle dot. -- The encoding should be utf-8-unix. -- When displayed in the main menu screen, the picture is overwritten -- with game and engine version strings and keybindings. -- The keybindings overwrite places marked with left curly brace signs. -- This sign is forbidden anywhere else in the picture. -- The picture and the whole main menu is displayed dull white on black. -- The glyphs, or at least the character cells, are perfect squares. -- The picture for Allure should be exactly 45 rows by 80 columns. , rmainMenuArt = $(do let path = "GameDefinition/MainMenu.ascii" qAddDependentFile path x <- qRunIO $ do handle <- openFile path ReadMode hSetEncoding handle utf8 hGetContents handle lift x) , rintroScreen = $(do let path = "GameDefinition/PLAYING.md" qAddDependentFile path x <- qRunIO $ do handle <- openFile path ReadMode hSetEncoding handle utf8 hGetContents handle let paragraphs :: [String] -> [String] -> [[String]] paragraphs [] rows = [reverse rows] paragraphs (l : ls) rows = if null l then reverse rows : paragraphs ls [] else paragraphs ls (l : rows) intro = case paragraphs (lines x) [] of _title : _blurb : par1 : par2 : par3 : _rest -> ["", "", ""] ++ par1 ++ [""] ++ par2 ++ [""] ++ par3 ++ ["", "", "", "", ""] _ -> error "not enough paragraphs in intro screen text" lift intro) , rmoveKeysScreen = $(do let path = "GameDefinition/MoveKeys.txt" qAddDependentFile path x <- qRunIO $ do handle <- openFile path ReadMode hSetEncoding handle utf8 hGetContents handle lift $ lines x) , rapplyVerbMap = EM.fromList [('!', "imbibe"), (',', "eat"), ('?', "activate")] } Allure-0.9.5.0/GameDefinition/game-src/Implementation/0000755000000000000000000000000007346545000020645 5ustar0000000000000000Allure-0.9.5.0/GameDefinition/game-src/Implementation/MonadClientImplementation.hs0000644000000000000000000001457507346545000026320 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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. -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | The implementation of our custom game client monads. Just as any other -- component of the library, this implementation can be substituted. module Implementation.MonadClientImplementation ( executorCli #ifdef EXPOSE_INTERNAL -- * Internal operations , CliState(..), CliImplementation(..) #endif ) where import Prelude () import Game.LambdaHack.Core.Prelude import Control.Concurrent import qualified Control.Monad.IO.Class as IO import Control.Monad.Trans.State.Strict hiding (State) import Game.LambdaHack.Atomic (MonadStateWrite (..)) import Game.LambdaHack.Client import qualified Game.LambdaHack.Client.BfsM as BfsM import Game.LambdaHack.Client.HandleAtomicM import Game.LambdaHack.Client.HandleResponseM import Game.LambdaHack.Client.LoopM import Game.LambdaHack.Client.MonadClient import Game.LambdaHack.Client.State import Game.LambdaHack.Client.UI import Game.LambdaHack.Client.UI.SessionUI import Game.LambdaHack.Common.Kind import Game.LambdaHack.Common.MonadStateRead import qualified Game.LambdaHack.Common.Save as Save import Game.LambdaHack.Common.State import Game.LambdaHack.Common.Types import Game.LambdaHack.Server (ChanServer (..)) data CliState = CliState { cliState :: State -- ^ current global state , cliClient :: StateClient -- ^ current client state , cliSession :: Maybe SessionUI -- ^ UI state, empty for AI clients , cliDict :: ChanServer -- ^ this client connection information , cliToSave :: Save.ChanSave (StateClient, Maybe SessionUI) -- ^ connection to the save thread } -- | Client state transformation monad. newtype CliImplementation a = CliImplementation { runCliImplementation :: StateT CliState IO a } deriving (Monad, Functor, Applicative) instance MonadStateRead CliImplementation where {-# INLINE getsState #-} getsState f = CliImplementation $ gets $ f . cliState instance MonadStateWrite CliImplementation where {-# INLINE modifyState #-} modifyState f = CliImplementation $ state $ \cliS -> let !newCliS = cliS {cliState = f $ cliState cliS} in ((), newCliS) {-# INLINE putState #-} putState newCliState = CliImplementation $ state $ \cliS -> let !newCliS = cliS {cliState = newCliState} in ((), newCliS) instance MonadClientRead CliImplementation where {-# INLINE getsClient #-} getsClient f = CliImplementation $ gets $ f . cliClient liftIO = CliImplementation . IO.liftIO instance MonadClient CliImplementation where {-# INLINE modifyClient #-} modifyClient f = CliImplementation $ state $ \cliS -> let !newCliS = cliS {cliClient = f $ cliClient cliS} in ((), newCliS) instance MonadClientSetup CliImplementation where saveClient = CliImplementation $ do toSave <- gets cliToSave cli <- gets cliClient msess <- gets cliSession IO.liftIO $ Save.saveToChan toSave (cli, msess) restartClient = CliImplementation $ state $ \cliS -> case cliSession cliS of Just sess -> let !newSess = (emptySessionUI (sUIOptions sess)) { schanF = schanF sess , sccui = sccui sess , shistory = shistory sess , sstart = sstart sess , sgstart = sgstart sess , sallTime = sallTime sess , snframes = snframes sess , sallNframes = sallNframes sess } !newCliS = cliS {cliSession = Just newSess} in ((), newCliS) Nothing -> ((), cliS) instance MonadClientUI CliImplementation where {-# INLINE getsSession #-} getsSession f = CliImplementation $ gets $ f . fromJust . cliSession {-# INLINE modifySession #-} modifySession f = CliImplementation $ state $ \cliS -> let !newCliSession = f $ fromJust $ cliSession cliS !newCliS = cliS {cliSession = Just newCliSession} in ((), newCliS) updateClientLeader aid = do s <- getState modifyClient $ updateLeader aid s getCacheBfs = BfsM.getCacheBfs getCachePath = BfsM.getCachePath instance MonadClientReadResponse CliImplementation where receiveResponse = CliImplementation $ do ChanServer{responseS} <- gets cliDict IO.liftIO $ takeMVar responseS instance MonadClientWriteRequest CliImplementation where sendRequestAI scmd = CliImplementation $ do ChanServer{requestAIS} <- gets cliDict IO.liftIO $ putMVar requestAIS scmd sendRequestUI scmd = CliImplementation $ do ChanServer{requestUIS} <- gets cliDict IO.liftIO $ putMVar (fromJust requestUIS) scmd clientHasUI = CliImplementation $ do mSession <- gets cliSession return $! isJust mSession instance MonadClientAtomic CliImplementation where {-# INLINE execUpdAtomic #-} execUpdAtomic _ = return () -- handleUpdAtomic, until needed, save resources -- Don't catch anything; assume exceptions impossible. {-# INLINE execPutState #-} execPutState = putState -- | Run the main client loop, with the given arguments and empty -- initial states, in the @IO@ monad. executorCli :: CCUI -> UIOptions -> ClientOptions -> COps -> Bool -> FactionId -> ChanServer -> IO () executorCli ccui sUIOptions clientOptions cops isUI fid cliDict = let cliSession | isUI = Just $ emptySessionUI sUIOptions | otherwise = Nothing stateToFileName (cli, _) = ssavePrefixCli (soptions cli) <> Save.saveNameCli cops (sside cli) totalState cliToSave = CliState { cliState = updateCOpsAndCachedData (const cops) emptyState -- state is empty, so the cached data is left empty and untouched , cliClient = emptyStateClient fid , cliDict , cliToSave , cliSession } m = loopCli ccui sUIOptions clientOptions exe = evalStateT (runCliImplementation m) . totalState in Save.wrapInSaves cops stateToFileName exe Allure-0.9.5.0/GameDefinition/game-src/Implementation/MonadServerImplementation.hs0000644000000000000000000002151307346545000026336 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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. -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | The implementation of our custom game server monads. Just as any other -- component of the library, this implementation can be substituted. module Implementation.MonadServerImplementation ( executorSer #ifdef EXPOSE_INTERNAL -- * Internal operations , SerState(..), SerImplementation(..) #endif ) where import Prelude () import Game.LambdaHack.Core.Prelude import Control.Concurrent import qualified Control.Exception as Ex import qualified Control.Monad.IO.Class as IO import Control.Monad.Trans.State.Strict hiding (State) import qualified Data.EnumMap.Strict as EM import qualified Data.Text.IO as T import Options.Applicative (defaultPrefs, execParserPure, handleParseResult) import System.Exit (ExitCode (ExitSuccess)) import System.FilePath import System.IO (hFlush, stdout) import Game.LambdaHack.Atomic import Game.LambdaHack.Client import Game.LambdaHack.Common.File import Game.LambdaHack.Common.Kind import Game.LambdaHack.Common.Misc import Game.LambdaHack.Common.MonadStateRead import qualified Game.LambdaHack.Common.Save as Save import Game.LambdaHack.Common.State import Game.LambdaHack.Common.Thread import Game.LambdaHack.Server import Game.LambdaHack.Server.BroadcastAtomic import Game.LambdaHack.Server.HandleAtomicM import Game.LambdaHack.Server.MonadServer import Game.LambdaHack.Server.ProtocolM import Game.LambdaHack.Server.ServerOptions import Game.LambdaHack.Server.State import Implementation.MonadClientImplementation (executorCli) data SerState = SerState { serState :: State -- ^ current global state , serServer :: StateServer -- ^ current server state , serDict :: ConnServerDict -- ^ client-server connection information , serToSave :: Save.ChanSave (State, StateServer) -- ^ connection to the save thread } -- | Server state transformation monad. newtype SerImplementation a = SerImplementation {runSerImplementation :: StateT SerState IO a} deriving (Monad, Functor, Applicative) instance MonadStateRead SerImplementation where {-# INLINE getsState #-} getsState f = SerImplementation $ gets $ f . serState instance MonadStateWrite SerImplementation where {-# INLINE modifyState #-} modifyState f = SerImplementation $ state $ \serS -> let !newSerS = serS {serState = f $ serState serS} in ((), newSerS) {-# INLINE putState #-} putState newSerState = SerImplementation $ state $ \serS -> let !newSerS = serS {serState = newSerState} in ((), newSerS) instance MonadServer SerImplementation where {-# INLINE getsServer #-} getsServer f = SerImplementation $ gets $ f . serServer {-# INLINE modifyServer #-} modifyServer f = SerImplementation $ state $ \serS -> let !newSerS = serS {serServer = f $ serServer serS} in ((), newSerS) chanSaveServer = SerImplementation $ gets serToSave liftIO = SerImplementation . IO.liftIO instance MonadServerComm SerImplementation where {-# INLINE getsDict #-} getsDict f = SerImplementation $ gets $ f . serDict {-# INLINE modifyDict #-} modifyDict f = SerImplementation $ state $ \serS -> let !newSerS = serS {serDict = f $ serDict serS} in ((), newSerS) liftIO = SerImplementation . IO.liftIO instance MonadServerAtomic SerImplementation where execUpdAtomic cmd = do oldState <- getState (ps, atomicBroken, executedOnServer) <- handleCmdAtomicServer cmd when executedOnServer $ cmdAtomicSemSer oldState cmd handleAndBroadcast ps atomicBroken (UpdAtomic cmd) execUpdAtomicSer cmd = SerImplementation $ StateT $ \cliS -> do cliSNewOrE <- Ex.try $ execStateT (runSerImplementation $ handleUpdAtomic cmd) cliS case cliSNewOrE of Left AtomicFail{} -> return (False, cliS) Right !cliSNew -> -- We know @cliSNew@ differs only in @serState@. return (True, cliSNew) execUpdAtomicFid fid cmd = SerImplementation $ StateT $ \cliS -> do -- Don't catch anything; assume exceptions impossible. let sFid = sclientStates (serServer cliS) EM.! fid cliSNew <- execStateT (runSerImplementation $ handleUpdAtomic cmd) cliS {serState = sFid} -- We know @cliSNew@ differs only in @serState@. let serServerNew = (serServer cliS) {sclientStates = EM.insert fid (serState cliSNew) $ sclientStates $ serServer cliS} !newCliS = cliS {serServer = serServerNew} return ((), newCliS) execUpdAtomicFidCatch fid cmd = SerImplementation $ StateT $ \cliS -> do let sFid = sclientStates (serServer cliS) EM.! fid cliSNewOrE <- Ex.try $ execStateT (runSerImplementation $ handleUpdAtomic cmd) cliS {serState = sFid} case cliSNewOrE of Left AtomicFail{} -> return (False, cliS) Right cliSNew -> do -- We know @cliSNew@ differs only in @serState@. let serServerNew = (serServer cliS) {sclientStates = EM.insert fid (serState cliSNew) $ sclientStates $ serServer cliS} !newCliS = cliS {serServer = serServerNew} return (True, newCliS) execSfxAtomic sfx = do ps <- posSfxAtomic sfx handleAndBroadcast ps [] (SfxAtomic sfx) execSendPer = sendPer -- Don't inline this, to keep GHC hard work inside the library -- for easy access of code analysis tools. -- | Run the main server loop, with the given arguments and empty -- initial states, in the @IO@ monad. executorSer :: COps -> CCUI -> ServerOptions -> UIOptions -> IO () executorSer cops ccui soptionsNxtCmdline sUIOptions = do soptionsNxtRaw <- case uCmdline sUIOptions of [] -> return soptionsNxtCmdline args -> handleParseResult $ execParserPure defaultPrefs serverOptionsPI args -- Options for the clients modified with the configuration file. let clientOptions = applyUIOptions cops sUIOptions $ sclientOptions soptionsNxtRaw soptionsNxt = soptionsNxtRaw {sclientOptions = clientOptions} -- Partially applied main loop of the clients. executorClient = executorCli ccui sUIOptions clientOptions cops -- Wire together game content, the main loop of game clients -- and the game server loop. let stateToFileName (_, ser) = ssavePrefixSer (soptions ser) <> Save.saveNameSer cops totalState serToSave = SerState { serState = updateCOpsAndCachedData (const cops) emptyState -- state is empty, so the cached data is left empty and untouched , serServer = emptyStateServer , serDict = EM.empty , serToSave } m = loopSer soptionsNxt executorClient exe = evalStateT (runSerImplementation m) . totalState exeWithSaves = Save.wrapInSaves cops stateToFileName exe defPrefix = ssavePrefixSer defServerOptions bkpOneSave name = do dataDir <- appDataDir let path bkp = dataDir "saves" bkp <> name b <- doesFileExist (path "") when b $ renameFile (path "") (path "bkp.") bkpAllSaves = unless (sbenchmark $ sclientOptions soptionsNxt) $ do T.hPutStrLn stdout "The game crashed, so savefiles are moved aside." bkpOneSave $ defPrefix <> Save.saveNameSer cops forM_ [-99..99] $ \n -> bkpOneSave $ defPrefix <> Save.saveNameCli cops (toEnum n) -- Wait for clients to exit even in case of server crash -- (or server and client crash), which gives them time to save -- and report their own inconsistencies, if any. Ex.handle (\ex -> case Ex.fromException ex of Just ExitSuccess -> -- User-forced shutdown, not crash, so the intention is -- to keep old saves and also clients may be not ready to save. Ex.throwIO ex _ -> do Ex.uninterruptibleMask_ $ threadDelay 1000000 -- let clients report their errors and save when (ssavePrefixSer soptionsNxt == defPrefix) bkpAllSaves hFlush stdout Ex.throwIO ex -- crash eventually, which kills clients ) exeWithSaves -- T.hPutStrLn stdout "Server exiting, waiting for clients." -- hFlush stdout waitForChildren childrenServer -- no crash, wait for clients indefinitely -- T.hPutStrLn stdout "Server exiting now." -- hFlush stdout Allure-0.9.5.0/GameDefinition/game-src/0000755000000000000000000000000007346545000015660 5ustar0000000000000000Allure-0.9.5.0/GameDefinition/game-src/TieKnot.hs0000644000000000000000000001457607346545000017606 0ustar0000000000000000-- Copyright (c) 2008--2011 Andres Loeh -- Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) -- 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, frontend and the game-specific -- content definitions is tied, resulting in an executable game. module TieKnot ( tieKnotForAsync, tieKnot ) where import Prelude () import Game.LambdaHack.Core.Prelude import Control.Concurrent import Control.Concurrent.Async import qualified Control.Exception as Ex import qualified Data.Primitive.PrimArray as PA import GHC.Compact import qualified System.Random as R import Game.LambdaHack.Client import qualified Game.LambdaHack.Client.UI.Content.Input as IC import qualified Game.LambdaHack.Client.UI.Content.Screen as SC import Game.LambdaHack.Client.UI.ContentClientUI import Game.LambdaHack.Common.Kind import Game.LambdaHack.Common.Misc import Game.LambdaHack.Common.Point (speedupHackXSize) import qualified Game.LambdaHack.Common.Tile as Tile import qualified Game.LambdaHack.Content.CaveKind as CK import qualified Game.LambdaHack.Content.ItemKind as IK import qualified Game.LambdaHack.Content.ModeKind as MK import qualified Game.LambdaHack.Content.PlaceKind as PK import qualified Game.LambdaHack.Content.RuleKind as RK import qualified Game.LambdaHack.Content.TileKind as TK import Game.LambdaHack.Server import qualified Client.UI.Content.Input as Content.Input import qualified Client.UI.Content.Screen as Content.Screen 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 Implementation.MonadServerImplementation (executorSer) -- | Tie the LambdaHack engine client, server and frontend code -- with the game-specific content definitions, and run the game. -- -- The custom monad types to be used are determined by the @executorSer@ -- call, which in turn calls @executorCli@. If other functions are used -- in their place- the types are different and so the whole pattern -- of computation differs. Which of the frontends is run inside the UI client -- depends on the flags supplied when compiling the engine library. -- Similarly for the choice of native vs JS builds. tieKnotForAsync :: ServerOptions -> IO () tieKnotForAsync options@ServerOptions{ sallClear , sboostRandomItem , sdungeonRng } = do -- Set the X size of the dungeon from content ASAP, before it's used. speedupHackXSizeThawed <- PA.unsafeThawPrimArray speedupHackXSize PA.writePrimArray speedupHackXSizeThawed 0 $ RK.rXmax Content.RuleKind.standardRules void $ PA.unsafeFreezePrimArray speedupHackXSizeThawed -- This setup ensures the boosting option doesn't affect generating initial -- RNG for dungeon, etc., and also, that setting dungeon RNG on commandline -- equal to what was generated last time, ensures the same item boost. initialGen <- maybe R.getStdGen return sdungeonRng let soptionsNxt = options {sdungeonRng = Just initialGen} boostedItems = IK.boostItemKindList initialGen Content.ItemKind.items coitem = IK.makeData $ if sboostRandomItem then boostedItems ++ Content.ItemKind.otherItemContent else Content.ItemKind.content coItemSpeedup = speedupItem coitem cotile = TK.makeData coitem Content.TileKind.content coTileSpeedup = Tile.speedupTile sallClear cotile coplace = PK.makeData cotile Content.PlaceKind.content cocave = CK.makeData coitem coplace cotile Content.CaveKind.content -- Common content operations, created from content definitions. -- Evaluated fully to discover errors ASAP and to free memory. -- Fail here, not inside server code, so that savefiles are not removed, -- because they are not the source of the failure. copsRaw = COps { cocave , coitem , comode = MK.makeData cocave coitem Content.ModeKind.content , coplace , corule = RK.makeData Content.RuleKind.standardRules , cotile , coItemSpeedup , coTileSpeedup } benchmark = sbenchmark $ sclientOptions soptionsNxt -- Evaluating for compact regions catches all kinds of errors in content ASAP, -- even in unused items. -- -- Not using @compactWithSharing@, because it helps with residency, -- but nothing else and costs a bit at startup. #ifdef USE_JSFILE let cops = copsRaw -- until GHCJS implements GHC.Compact #else cops <- getCompact <$> compact copsRaw #endif -- Parse UI client configuration file. -- It is reparsed at each start of the game executable. -- Fail here, not inside client code, so that savefiles are not removed, -- because they are not the source of the failure. sUIOptions <- mkUIOptions cops benchmark -- Client content operations containing default keypresses -- and command descriptions. let !ccui = CCUI { coinput = IC.makeData sUIOptions Content.Input.standardKeysAndMouse , coscreen = SC.makeData Content.Screen.standardLayoutAndFeatures } -- Wire together game content, the main loops of game clients -- and the game server loop. executorSer cops ccui soptionsNxt sUIOptions -- | Runs tieKnotForAsync in an async and applies the main thread workaround. tieKnot :: ServerOptions -> IO () tieKnot serverOptions = do #ifdef USE_JSFILE -- Hard to tweak the config file when in the browser, so hardwire. let serverOptionsJS = serverOptions {sdumpInitRngs = True} a <- async $ tieKnotForAsync serverOptionsJS wait a #else let fillWorkaround = -- Set up void workaround if nothing specific required. void $ tryPutMVar workaroundOnMainThreadMVar $ return () -- Avoid the bound thread that would slow down the communication. a <- async $ tieKnotForAsync serverOptions `Ex.finally` fillWorkaround link a -- Run a (possibly void) workaround. It's needed for OSes/frontends -- that need to perform some actions on the main thread -- (not just any bound thread), e.g., newer OS X drawing with SDL2. workaround <- takeMVar workaroundOnMainThreadMVar workaround wait a #endif Allure-0.9.5.0/LICENSE0000644000000000000000000010333007346545000012305 0ustar0000000000000000 GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU Affero General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Remote Network Interaction; Use with the GNU General Public License. Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . Allure-0.9.5.0/Makefile0000755000000000000000000006175207346545000012756 0ustar0000000000000000# Copyright (c) 2008--2011 Andres Loeh # Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) # 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. # play: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix play --dumpInitRngs shot: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix play --dumpInitRngs --printEachScreen expose-lore: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix know --newGame 5 --dumpInitRngs --gameMode crawl --knowItems --exposePlaces --exposeItems --exposeActors --showItemSamples --benchmark --noAnim --maxFps 1000 dig-lore: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix know --newGame 5 --dumpInitRngs --gameMode dig --knowItems --exposePlaces --exposeItems --exposeActors --showItemSamples --benchmark --noAnim --maxFps 1000 see-caves: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix know --newGame 5 --dumpInitRngs --gameMode see --knowItems --exposePlaces --exposeItems --exposeActors --showItemSamples --benchmark --noAnim --maxFps 1000 configure-debug: cabal configure --enable-profiling --profiling-detail=all-functions -fwith_expensive_assertions --disable-optimization configure-prof: cabal configure --enable-profiling --profiling-detail=exported-functions ghcjs-new-build: cabal new-build -j1 --ghcjs --disable-library-profiling --disable-profiling . chrome-log: google-chrome --enable-logging --v=1 file:///home/mikolaj/r/allureofthestars.github.io/play/index.html & chrome-prof: google-chrome --no-sandbox --js-flags="--logfile=%t.log --prof" ../allureofthestars.github.io/play/index.html minific: npx google-closure-compiler dist-newstyle/build/x86_64-linux/ghcjs-8.6.0.1/Allure-0.9.5.0/x/Allure/build/Allure/Allure.jsexe/all.js --compilation_level=ADVANCED_OPTIMIZATIONS --isolation_mode=IIFE --assume_function_wrapper --externs=dist-newstyle/build/x86_64-linux/ghcjs-8.6.0.1/Allure-0.9.5.0/x/Allure/build/Allure/Allure.jsexe/all.js.externs --jscomp_off="*" > ../allureofthestars.github.io/play/allure.all.js minificForNode: npx google-closure-compiler dist-newstyle/build/x86_64-linux/ghcjs-8.6.0.1/Allure-0.9.5.0/x/Allure/build/Allure/Allure.jsexe/all.js --compilation_level=ADVANCED_OPTIMIZATIONS --isolation_mode=IIFE --assume_function_wrapper --externs=dist-newstyle/build/x86_64-linux/ghcjs-8.6.0.1/LambdaHack-0.9.5.0/x/LambdaHack/build/LambdaHack/LambdaHack.jsexe/all.js.externs --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/assert.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/child_process.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/crypto.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/dns.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/events.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/globals.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/https.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/os.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/punycode.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/readline.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/stream.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/tls.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/url.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/vm.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/buffer.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/cluster.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/dgram.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/domain.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/fs.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/http.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/net.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/path.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/querystring.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/repl.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/string_decoder.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/tty.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/util.js --externs=/home/mikolaj/r/closure-compiler/contrib/nodejs/zlib.js --jscomp_off="*" > ../allureofthestars.github.io/play/allure.all.js # Low delay to display animations swiftly and not bore the public too much. # Delay can't be lower than 2, because browsers sometimes treat delay 1 # specially and add their extra delay. create-gif : find ~/.Allure/screenshots/ -name 'prtscn*.bmp' -print0 | xargs -0 -r mogrify -format gif gifsicle -O3 --careful -d2 -l ~/.Allure/screenshots/prtscn*.gif -o ~/.Allure/screenshots/screenshot.gif frontendRaid: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 5 --dumpInitRngs --automateAll --gameMode raid --exposeActors frontendBrawl: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 5 --dumpInitRngs --automateAll --gameMode brawl frontendShootout: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 5 --dumpInitRngs --automateAll --gameMode shootout frontendHunt: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 5 --dumpInitRngs --automateAll --gameMode hunt frontendEscape: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 3 --dumpInitRngs --automateAll --gameMode escape frontendZoo: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 2 --dumpInitRngs --automateAll --gameMode zoo --exposeActors frontendAmbush: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 5 --dumpInitRngs --automateAll --gameMode ambush frontendCrawl: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 1 --dumpInitRngs --automateAll --gameMode crawl --exposeItems --exposeActors frontendCrawlEmpty: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 1 --dumpInitRngs --automateAll --gameMode "crawl empty" frontendSafari: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 2 --dumpInitRngs --automateAll --gameMode safari --exposeActors frontendSafariSurvival: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 5 --dumpInitRngs --automateAll --gameMode "safari survival" --exposeActors frontendBattle: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 4 --dumpInitRngs --automateAll --gameMode battle --exposeActors frontendBattleDefense: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 6 --dumpInitRngs --automateAll --gameMode "battle defense" --exposeActors frontendBattleSurvival: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 6 --dumpInitRngs --automateAll --gameMode "battle survival" --exposeActors frontendDefense: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 9 --dumpInitRngs --automateAll --gameMode defense --exposeItems --exposeActors frontendDefenseEmpty: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 9 --dumpInitRngs --automateAll --gameMode "defense empty" fastCrawl: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --savePrefix test --newGame 1 --dumpInitRngs --automateAll --gameMode crawl --exposeItems --exposeActors --showItemSamples --noAnim --maxFps 100000 benchMemoryAnim: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --newGame 1 --maxFps 100000 --benchmark --stopAfterFrames 33000 --automateAll --keepAutomated --gameMode crawl --setDungeonRng 120 --setMainRng 47 --frontendNull --noAnim +RTS -s -A1M -RTS benchBattle: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --newGame 3 --noAnim --maxFps 100000 --frontendNull --benchmark --stopAfterFrames 1500 --automateAll --keepAutomated --gameMode battle --setDungeonRng 7 --setMainRng 7 benchAnimBattle: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --newGame 3 --maxFps 100000 --frontendNull --benchmark --stopAfterFrames 7000 --automateAll --keepAutomated --gameMode battle --setDungeonRng 7 --setMainRng 7 benchFrontendBattle: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --newGame 3 --noAnim --maxFps 100000 --benchmark --stopAfterFrames 2000 --automateAll --keepAutomated --gameMode battle --setDungeonRng 7 --setMainRng 7 benchCrawl: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --newGame 1 --noAnim --maxFps 100000 --frontendNull --benchmark --stopAfterFrames 7000 --automateAll --keepAutomated --gameMode crawl --setDungeonRng 0 --setMainRng 0 benchFrontendCrawl: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --newGame 1 --noAnim --maxFps 100000 --benchmark --stopAfterFrames 7000 --automateAll --keepAutomated --gameMode crawl --setDungeonRng 0 --setMainRng 0 benchDig: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --newGame 1 --noAnim --maxFps 100000 --frontendNull --benchmark --stopAfterFrames 1 --automateAll --keepAutomated --gameMode dig --setDungeonRng 0 --setMainRng 0 benchNull: benchBattle benchAnimBattle benchCrawl bench: benchBattle benchAnimBattle benchFrontendBattle benchCrawl benchFrontendCrawl nativeBenchCrawl: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --newGame 1 --noAnim --maxFps 100000 --frontendNull --benchmark --stopAfterFrames 2000 --automateAll --keepAutomated --gameMode crawl --setDungeonRng 0 --setMainRng 0 nativeBenchBattle: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --newGame 3 --noAnim --maxFps 100000 --frontendNull --benchmark --stopAfterFrames 1000 --automateAll --keepAutomated --gameMode battle --setDungeonRng 0 --setMainRng 0 nativeBench: nativeBenchBattle nativeBenchCrawl nodeBenchCrawl: node dist/build/Allure/Allure.jsexe/all.js --dbgMsgSer --logPriority 4 --newGame 1 --noAnim --maxFps 100000 --frontendNull --benchmark --stopAfterFrames 2000 --automateAll --keepAutomated --gameMode crawl --setDungeonRng 0 --setMainRng 0 nodeBenchBattle: node dist/build/Allure/Allure.jsexe/all.js --dbgMsgSer --logPriority 4 --newGame 3 --noAnim --maxFps 100000 --frontendNull --benchmark --stopAfterFrames 1000 --automateAll --keepAutomated --gameMode battle --setDungeonRng 0 --setMainRng 0 nodeBench: nodeBenchBattle nodeBenchCrawl test-travis: test-sniff test-short test-medium benchNull test: test-sniff test-short test-medium benchNull test-short: test-short-new test-short-load test-medium: testRaid-medium testBrawl-medium testShootout-medium testHunt-medium testEscape-medium testZoo-medium testAmbush-medium testCrawl-medium testCrawlEmpty-medium testCrawl-medium-know testSafari-medium testSafariSurvival-medium testBattle-medium testBattleDefense-medium testBattleSurvival-medium testDig-medium testDefenseEmpty-medium test-sniff: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --newGame 5 --noAnim --maxFps 100000 --frontendTeletype --benchmark --stopAfterFrames 1 --dumpInitRngs --automateAll --keepAutomated --gameMode raid --sniff 2> /tmp/teletypetest.log testRaid-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 20 --dumpInitRngs --automateAll --keepAutomated --gameMode raid 2> /tmp/teletypetest.log testBrawl-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 20 --dumpInitRngs --automateAll --keepAutomated --gameMode brawl 2> /tmp/teletypetest.log testShootout-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 20 --dumpInitRngs --automateAll --keepAutomated --gameMode shootout 2> /tmp/teletypetest.log testHunt-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 20 --dumpInitRngs --automateAll --keepAutomated --gameMode hunt 2> /tmp/teletypetest.log testEscape-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 3 --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 40 --dumpInitRngs --automateAll --keepAutomated --gameMode escape 2> /tmp/teletypetest.log testZoo-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 2 --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 40 --dumpInitRngs --automateAll --keepAutomated --gameMode zoo 2> /tmp/teletypetest.log testAmbush-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --noAnim --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 20 --dumpInitRngs --automateAll --keepAutomated --gameMode ambush 2> /tmp/teletypetest.log testCrawl-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --newGame 1 --noAnim --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 200 --dumpInitRngs --automateAll --keepAutomated --gameMode crawl 2> /tmp/teletypetest.log testCrawlEmpty-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --newGame 1 --noAnim --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 40 --dumpInitRngs --automateAll --keepAutomated --gameMode "crawl empty" 2> /tmp/teletypetest.log testCrawl-medium-know: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --savePrefix know --newGame 1 --noAnim --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 100 --dumpInitRngs --automateAll --keepAutomated --gameMode crawl --knowItems --exposePlaces --exposeItems --exposeActors --showItemSamples 2> /tmp/teletypetest.log testSafari-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 2 --noAnim --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 100 --dumpInitRngs --automateAll --keepAutomated --gameMode safari 2> /tmp/teletypetest.log testSafariSurvival-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 8 --noAnim --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 40 --dumpInitRngs --automateAll --keepAutomated --gameMode "safari survival" 2> /tmp/teletypetest.log testBattle-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 3 --noAnim --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 20 --dumpInitRngs --automateAll --keepAutomated --gameMode battle 2> /tmp/teletypetest.log testBattleDefense-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 7 --noAnim --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 40 --dumpInitRngs --automateAll --keepAutomated --gameMode "battle defense" 2> /tmp/teletypetest.log testBattleSurvival-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 7 --noAnim --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 40 --dumpInitRngs --automateAll --keepAutomated --gameMode "battle survival" 2> /tmp/teletypetest.log testDefense-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --newGame 9 --noAnim --maxFps 100000 --frontendLazy --benchmark --stopAfterSeconds 200 --dumpInitRngs --automateAll --keepAutomated --gameMode defense 2> /tmp/teletypetest.log testDig-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --newGame 1 --noAnim --maxFps 100000 --frontendTeletype --benchmark --stopAfterFrames 100 --dumpInitRngs --automateAll --keepAutomated --gameMode dig 2> /tmp/teletypetest.log testDefenseEmpty-medium: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 9 --noAnim --maxFps 100000 --frontendTeletype --benchmark --stopAfterSeconds 40 --dumpInitRngs --automateAll --keepAutomated --gameMode "defense empty" 2> /tmp/teletypetest.log test-short-new: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --savePrefix raid --dumpInitRngs --automateAll --keepAutomated --gameMode raid --frontendTeletype --stopAfterSeconds 2 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --savePrefix brawl --dumpInitRngs --automateAll --keepAutomated --gameMode brawl --showItemSamples --frontendTeletype --stopAfterSeconds 2 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --savePrefix shootout --dumpInitRngs --automateAll --keepAutomated --gameMode shootout --showItemSamples --frontendTeletype --stopAfterSeconds 2 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --savePrefix hunt --dumpInitRngs --automateAll --keepAutomated --gameMode hunt --showItemSamples --frontendTeletype --stopAfterSeconds 2 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --savePrefix escape --dumpInitRngs --automateAll --keepAutomated --gameMode escape --showItemSamples --frontendTeletype --stopAfterSeconds 2 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --savePrefix zoo --dumpInitRngs --automateAll --keepAutomated --gameMode zoo --frontendTeletype --stopAfterSeconds 2 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --savePrefix ambush --dumpInitRngs --automateAll --keepAutomated --gameMode ambush --frontendTeletype --stopAfterSeconds 2 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --savePrefix crawl --dumpInitRngs --automateAll --keepAutomated --gameMode crawl --frontendTeletype --stopAfterSeconds 2 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --savePrefix safari --dumpInitRngs --automateAll --keepAutomated --gameMode safari --frontendTeletype --stopAfterSeconds 2 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --savePrefix safariSurvival --dumpInitRngs --automateAll --keepAutomated --gameMode "safari survival" --showItemSamples --frontendTeletype --stopAfterSeconds 2 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --savePrefix battle --showItemSamples --dumpInitRngs --automateAll --keepAutomated --gameMode battle --frontendTeletype --stopAfterSeconds 2 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --savePrefix battleDefense --dumpInitRngs --automateAll --keepAutomated --gameMode "battle defense" --frontendTeletype --stopAfterSeconds 2 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --newGame 5 --savePrefix battleSurvival --dumpInitRngs --automateAll --keepAutomated --gameMode "battle survival" --frontendTeletype --stopAfterSeconds 2 2> /tmp/teletypetest.log # "--setDungeonRng 0 --setMainRng 0" is needed for determinism relative to seed # generated before game save test-short-load: dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --savePrefix raid --dumpInitRngs --automateAll --keepAutomated --gameMode raid --frontendTeletype --stopAfterSeconds 2 --setDungeonRng 0 --setMainRng 0 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --savePrefix brawl --dumpInitRngs --automateAll --keepAutomated --gameMode brawl --frontendTeletype --stopAfterSeconds 2 --setDungeonRng 0 --setMainRng 0 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --savePrefix shootout --dumpInitRngs --automateAll --keepAutomated --gameMode shootout --frontendTeletype --stopAfterSeconds 2 --setDungeonRng 0 --setMainRng 0 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --savePrefix hunt --dumpInitRngs --automateAll --keepAutomated --gameMode hunt --frontendTeletype --stopAfterSeconds 2 --setDungeonRng 0 --setMainRng 0 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --savePrefix escape --dumpInitRngs --automateAll --keepAutomated --gameMode escape --frontendTeletype --stopAfterSeconds 2 --setDungeonRng 0 --setMainRng 0 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --savePrefix zoo --dumpInitRngs --automateAll --keepAutomated --gameMode zoo --frontendTeletype --stopAfterSeconds 2 --setDungeonRng 0 --setMainRng 0 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --savePrefix ambush --dumpInitRngs --automateAll --keepAutomated --gameMode ambush --frontendTeletype --stopAfterSeconds 2 --setDungeonRng 0 --setMainRng 0 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --savePrefix crawl --dumpInitRngs --automateAll --keepAutomated --gameMode crawl --frontendTeletype --stopAfterSeconds 2 --setDungeonRng 0 --setMainRng 0 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --savePrefix safari --dumpInitRngs --automateAll --keepAutomated --gameMode safari --frontendTeletype --stopAfterSeconds 2 --setDungeonRng 0 --setMainRng 0 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --savePrefix safariSurvival --dumpInitRngs --automateAll --keepAutomated --gameMode "safari survival" --frontendTeletype --stopAfterSeconds 2 --setDungeonRng 0 --setMainRng 0 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --savePrefix battle --dumpInitRngs --automateAll --keepAutomated --gameMode battle --frontendTeletype --stopAfterSeconds 2 --setDungeonRng 0 --setMainRng 0 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --savePrefix battleDefense --dumpInitRngs --automateAll --keepAutomated --gameMode "battle defense" --frontendTeletype --stopAfterSeconds 2 --setDungeonRng 0 --setMainRng 0 2> /tmp/teletypetest.log dist/build/Allure/Allure --dbgMsgSer --logPriority 4 --boostRandomItem --savePrefix battleSurvival --dumpInitRngs --automateAll --keepAutomated --gameMode "battle survival" --frontendTeletype --stopAfterSeconds 2 --setDungeonRng 0 --setMainRng 0 2> /tmp/teletypetest.log version: dist/build/Allure/Allure --version build-binary-common: cabal v1-install --disable-library-profiling --disable-profiling --disable-documentation --enable-optimization --only-dependencies cabal v1-configure --disable-library-profiling --disable-profiling --enable-optimization --prefix=/ --datadir=. --datasubdir=. cabal v1-build exe:Allure mkdir -p AllureOfTheStars/GameDefinition/fonts cabal v1-copy --destdir=AllureOfTheStarsInstall cp GameDefinition/config.ui.default AllureOfTheStars/GameDefinition cp GameDefinition/fonts/16x16xw.woff AllureOfTheStars/GameDefinition/fonts cp GameDefinition/fonts/16x16xw.bdf AllureOfTheStars/GameDefinition/fonts cp GameDefinition/fonts/16x16x.fnt AllureOfTheStars/GameDefinition/fonts cp GameDefinition/fonts/8x8xb.fnt AllureOfTheStars/GameDefinition/fonts cp GameDefinition/fonts/8x8x.fnt AllureOfTheStars/GameDefinition/fonts cp GameDefinition/fonts/LICENSE.16x16x AllureOfTheStars/GameDefinition/fonts cp GameDefinition/fonts/Fix15Mono-Bold.woff AllureOfTheStars/GameDefinition/fonts cp GameDefinition/fonts/LICENSE.Fix15Mono-Bold AllureOfTheStars/GameDefinition/fonts cp GameDefinition/InGameHelp.txt AllureOfTheStars/GameDefinition cp GameDefinition/PLAYING.md AllureOfTheStars/GameDefinition cp README.md AllureOfTheStars cp CHANGELOG.md AllureOfTheStars cp LICENSE AllureOfTheStars cp COPYLEFT AllureOfTheStars cp CREDITS AllureOfTheStars #in LambdaHack/ # cabal v1-install --disable-library-profiling --disable-profiling --disable-documentation --enable-optimization build-binary-ubuntu: build-binary-common cp AllureOfTheStarsInstall/bin/Allure AllureOfTheStars dist/build/Allure/Allure --version > /dev/null; \ LH_VERSION=$$(cat ~/.Allure/stdout.txt); \ tar -czf Allure_$${LH_VERSION}_ubuntu-16.04-amd64.tar.gz AllureOfTheStars build-binary-macosx: build-binary-common cp AllureOfTheStarsInstall/bin/Allure AllureOfTheStars dist/build/Allure/Allure --version > /dev/null; \ LH_VERSION=$$(cat ~/.Allure/stdout.txt); \ OS_VERSION=$$(sw_vers -productVersion); \ tar -czf Allure_$${LH_VERSION}_macosx-$${OS_VERSION}-amd64.tar.gz AllureOfTheStars #in LambdaHack/ # cabal v1-install --disable-library-profiling --disable-profiling --disable-documentation --enable-optimization -fvty build-binary-screen-reader-ubuntu: build-binary-common cp AllureOfTheStarsInstall/bin/Allure AllureOfTheStars dist/build/Allure/Allure --version > /dev/null; \ LH_VERSION=$$(cat ~/.Allure/stdout.txt); \ tar -czf Allure_$${LH_VERSION}_screen-reader-ubuntu-16.04-amd64.tar.gz AllureOfTheStars new-build-dev: cabal new-build --datadir=. --disable-optimization -j1 all Allure-0.9.5.0/README.md0000644000000000000000000002415007346545000012561 0ustar0000000000000000Allure of the Stars =================== [![Build Status](https://travis-ci.org/AllureOfTheStars/Allure.svg?branch=master)](https://travis-ci.org/AllureOfTheStars/Allure) [![Hackage](https://img.shields.io/hackage/v/Allure.svg)](https://hackage.haskell.org/package/Allure) [![Join the chat at https://gitter.im/AllureOfTheStars/Allure](https://badges.gitter.im/AllureOfTheStars/Allure.svg)](https://gitter.im/AllureOfTheStars/Allure?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Allure of the Stars is a near-future Sci-Fi roguelike[2] and tactical squad combat game. Binaries and the game manual are available at the homepage[6]. You can try the game out in the browser at http://allureofthestars.com/play. (It runs fastest on Chrome. Keyboard commands and savefiles are supported only on recent enough versions of browsers. Mouse should work everywhere.) ![gameplay screenshot](https://raw.githubusercontent.com/AllureOfTheStars/media/master/screenshot/allureofthestars.com.updown.png) Not a single picture in this game. You have to imagine everything yourself, like with a book (a grown-up book, without pictures). Once you learn to imagine things, though, you can keep exploring and mastering the world and making up stories for a long time. The game is written in Haskell[1] using the LambdaHack[10] roguelike game engine. 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. Contributions are welcome. Please offer feedback to mikolaj.konarski@funktory.com or, preferably, at any of the public forums. Game installation from binary archives -------------------------------------- The game runs rather slowly in the browser (fastest on Chrome) and you are limited to only one font, though it's scalable. Also, savefiles are prone to corruption on the browser, e.g., when it's closed while the game is still saving progress (which takes a long time). Hence, after trying out the game, you may prefer to use a native binary for your architecture, if it exists. Pre-compiled game binaries are available through the release page[11] (and, for Windows, dev versions continuously from AppVeyor[18]). To use a pre-compiled binary archive, unpack it and run the executable in the unpacked directory or use program shortcuts from the installer, if available. On Linux, make sure you have the SDL2 libraries installed on your system (e.g., libsdl2-2.0-0 and libsdl2-ttf-2.0-0 on Ubuntu). For Windows (XP no longer supported), the SDL2 and all other needed libraries are already contained in the game's binary archive. Max OS X binaries for the few most popular OS versions are accessible from Homebrew via `brew install allureofthestars`, which also takes care of all dependencies. Screen and keyboard configuration --------------------------------- The game UI can be configured via a config file. The default settings, the same that are built into the binary, are in [GameDefinition/config.ui.default](https://github.com/AllureOfTheStars/Allure/blob/master/GameDefinition/config.ui.default). When the game is run for the first time, the file is copied to the default user data folder, which is `~/.Allure/` on Linux, `C:\Users\\AppData\Roaming\Allure\` (or `C:\Documents And Settings\user\Application Data\Allure\` or something else altogether) on Windows, and in RMB menu, under `Inspect/Application/Local Storage` when run inside the Chrome browser. Screen font and consequently window size can be changed by editing the config file in the user data folder. The default bitmap font `16x16xw.bdf` covers most national characters in the Latin alphabet (e.g. to give custom names to player characters) and results in a game window of exactly 720p (standard HD) dimensions. The `8x8xb.fnt` bitmap font results in a tiny window and covers latin-1 characters only. The scalable `16x16xw.woff` font results in window sizes dependent on the `scalableFontSize` parameter in the config file. With `scalableFontSize = 16` it should look almost the same as the pixel-perfect `16x16xw.bdf`. If you don't have a numeric keypad, you can use the Vi editor keys (aka roguelike keys) or mouse for movement or you can enable the compact laptop keys (uk8o79jl) in the config file. If numeric keypad doesn't work, toggling the Num Lock key sometimes helps. If running with the Shift key and keypad keys doesn't work, try Control key instead. The game is fully playable with mouse only, as well as with keyboard only, but the most efficient combination for some players is mouse for go-to, inspecting, and aiming at distant positions and keyboard for everything else. If you are using a terminal frontend, e.g. the best supported vty frontend, numeric keypad (e.g., keypad '*' and '/') may not work correctly depending on versions of the libraries, terminfo and terminal emulators. Toggling the Num Lock key may help or make issues worse. As a workaround for the vty frontend, numbers are used for movement, which sadly prevents the number keys from selecting heroes. The commands that require pressing Control and Shift together won't work either, but fortunately they are not crucial to gameplay. Some effort has been put to help using the vty frontend with screen readers, but without feedback it's hard to say how accesible that setup is. As a side effect of screen reader support, there is no aiming line nor path in vty frontend. Screen readers may also work better with animations turned off using `--noAnim` or the corresponding config file option. Note that unicode and cursor support are now necessary for correct output. Compilation from source ----------------------- If you want to compile native binaries from the source code, use Cabal (already a part of your OS distribution, or available within The Haskell Platform[7]), which also takes care of all the dependencies. The recommended frontend is based on SDL2, so you need the SDL2 libraries for your OS. On Linux, remember to install the -dev versions as well, e.g., libsdl2-dev and libsdl2-ttf-dev on Ubuntu Linux 16.04. (Compilation to JavaScript for the browser is more complicated and requires the ghcjs[15] compiler and optionally the Google Closure Compiler[16] as well.) The latest official version of the game can be downloaded, compiled for SDL2 and installed automatically by Cabal from Hackage[3] as follows cabal update cabal install Allure For a newer version, install a matching LambdaHack library snapshot, clone the game source from github[5] and run `cabal install` from the main directory. Testing and debugging --------------------- The [Makefile](https://github.com/AllureOfTheStars/Allure/blob/master/Makefile) contains many sample test commands. Numerous tests that use the screensaver game modes (AI vs. AI) and the teletype frontend are gathered in `make test`. Of these, travis runs `test-travis` on each push to github. 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, the `--sniff` option is very useful (though verbose and initially cryptic), for displaying 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). Coding style ------------ Stylish Haskell is used for slight auto-formatting at buffer save; see [.stylish-haskell.yaml](https://github.com/AllureOfTheStars/Allure/blob/master/.stylish-haskell.yaml). As defined in the file, indentation is 2 spaces wide and screen is 80-columns wide. Spaces are used, not tabs. Spurious whitespace avoided. Spaces around arithmetic operators encouraged. Generally, relax and try to stick to the style apparent in a file you are editing. Put big formatting changes in separate commits. Haddocks are provided for all module headers and for all functions and types from major modules, in particular the modules that are interfaces for a whole directory of modules. Apart of that, only very important functions and types are distinguished by having a haddock. If minor ones have comments, they should not be haddocks and they are permitted to describe implementation details and be out of date. Prefer assertions to comments, unless too verbose. Further information ------------------- For more information, visit the wiki[4] and see [PLAYING.md](https://github.com/AllureOfTheStars/Allure/blob/master/GameDefinition/PLAYING.md), [CREDITS](https://github.com/AllureOfTheStars/Allure/blob/master/CREDITS) and [COPYLEFT](https://github.com/AllureOfTheStars/Allure/blob/master/COPYLEFT). Have fun! Copyright --------- Copyright (c) 2008--2011 Andres Loeh Copyright (c) 2010--2019 Mikolaj Konarski and others (see git history) 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 the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program in file LICENSE. If not, see . Exceptions and detailed copyright information is contained in file COPYLEFT. [1]: https://www.haskell.org/ [2]: http://roguebasin.roguelikedevelopment.org/index.php?title=Berlin_Interpretation [3]: https://hackage.haskell.org/package/Allure [4]: https://github.com/AllureOfTheStars/Allure/wiki [5]: https://github.com/AllureOfTheStars/Allure [6]: http://allureofthestars.com [7]: https://www.haskell.org/platform [10]: https://github.com/LambdaHack/LambdaHack [11]: https://github.com/AllureOfTheStars/Allure/releases [15]: https://github.com/ghcjs/ghcjs [16]: https://www.npmjs.com/package/google-closure-compiler [18]: https://ci.appveyor.com/project/Mikolaj/allure/build/artifacts Allure-0.9.5.0/Setup.hs0000644000000000000000000000005707346545000012736 0ustar0000000000000000import Distribution.Simple main = defaultMain Allure-0.9.5.0/test/0000755000000000000000000000000007346545000012257 5ustar0000000000000000Allure-0.9.5.0/test/test.hs0000644000000000000000000000212507346545000013572 0ustar0000000000000000{-# LANGUAGE PackageImports #-} import Prelude () import Options.Applicative import Game.LambdaHack.Client.UI.Frontend.Chosen import Game.LambdaHack.Core.Prelude import Game.LambdaHack.Server -- For the case of flattened .cabal file, to avoid ambiguity. import "Allure" TieKnot main :: IO () main = do let args = words "--dbgMsgSer --logPriority 4 --newGame 1 --noAnim --maxFps 100000 --frontendNull --benchmark --stopAfterFrames 50 --automateAll --keepAutomated --gameMode crawl --setDungeonRng 0 --setMainRng 0" serverOptions <- handleParseResult $ execParserPure defaultPrefs serverOptionsPI args tieKnot serverOptions when (frontendName == "sdl") $ do -- The hacky log priority 0 tells SDL frontend to init and quit at once, -- for testing on CIs without graphics access. let args2 = words "--dbgMsgSer --logPriority 0 --newGame 3 --maxFps 100000 --benchmark --stopAfterFrames 50 --automateAll --keepAutomated --gameMode battle --setDungeonRng 7 --setMainRng 7" serverOptions2 <- handleParseResult $ execParserPure defaultPrefs serverOptionsPI args2 tieKnot serverOptions2