Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

The big, ugly, pending pull request #11

Closed
wants to merge 240 commits into from

2 participants

@Mikolaj
Owner

Ping! :D

I hope this fits the mood of LambdaHack. At least, the monsters have been preserved, though their behaviour is a bit more varied now. Feel free to pick and choose, of course, I'll just reapply the rejected commits as initial commits of Allure --- the distant SF fork.

Mikolaj and others added some commits
@Mikolaj Mikolaj multiple heroes: a hero now carries his personal number with him cbb5b67
@Mikolaj Mikolaj multiple heroes: a number of heroes possible on each level 05a0949
@Mikolaj Mikolaj multiple heroes: help text for hero selection keys
And a remark that the keys listed are the default keys,
in case we allow the user to change them (via config file or UI) later.
8152f6f
@Mikolaj Mikolaj multiple heroes: prepare keys for hero selection commands b048766
@Mikolaj Mikolaj the current target and look mode fields (see issue 28) c4fcdc8
@Mikolaj Mikolaj multiple heroes: a few tweaks around the type of heroes on a level
We should probably use the same type for monsters, to have a number
with which to indicate a targeted monster. Monsters probably don't need
to carry their numbers in them, unlike heroes, because they don't get
moved to and from any "current monster" state field.
f473230
@Mikolaj Mikolaj allow player to change levels freely in look mode 76af3b0
@Mikolaj Mikolaj enable the look mode
TODO: some actions should behave differently in look mode, e.g., movement
de7f68b
@Mikolaj Mikolaj fix a typo that breaks savegames and TODO about another bug b28dc42
@Mikolaj Mikolaj mutiple heroes: Tab cycles among heroes on a level
TODO: currently all but on hero must remain on level 1. Either hero switching
in look mode or via number keys will solve that.
8959e49
@Mikolaj Mikolaj tweaks and comments, mostly about TODOs for actions 7bd9ccf
@Mikolaj Mikolaj multiple heroes: spawn the number of heroes specified in config
Plus a few tweaks around.
be4f887
@Mikolaj Mikolaj vty support status update: vty maintainer OK with numpad number keys
I'll prepare a patch to differentiate numpad and top row number keys.
0417f4f
@Mikolaj Mikolaj multiple heroes: Tab cycles heroes also in look mode
So it's now possible to move more than one hero to levels > 1.
4e1f146
@Mikolaj Mikolaj multiple heroes: monsters chase closest heroes on the level 6d9a881
@Mikolaj Mikolaj fix of a bug caused by config file options being case insensitive
TODO: perhaps make the options case sensitive; it costs too much debugging.
4b4d2cb
@Mikolaj Mikolaj multiple heroes: monster attacks any hero correctly; infrastructure c…
…omplete

Plus a bit of clean-up.
adc3f4f
@Mikolaj Mikolaj switch config file behaviour to case sensitive and rename options 7f861f6
@Mikolaj Mikolaj change datatype of look mode from a tuple to a record
That's after I myself didn't remember what the components are used for.
Now it's documented in record field names.
de20d76
@Mikolaj Mikolaj code naming convention: "player" is the currently selected hero
This is short form of "player-controlled hero".
Other heroes and all heroes in general are just "heroes".
081101a
@Mikolaj Mikolaj all heroes on level now displayed; player in reverse video 96a3f1e
@Mikolaj Mikolaj fix issue #9 on kosmikus' fork (High score table, number of steps) de46aad
@Mikolaj Mikolaj fix issue #8 on kosmikus' fork (High score table, boolean flags)
Exactly as proposed; minimal changes to get it working again.
4f4fa31
@Mikolaj Mikolaj fix monsters unable to attack selected hero
I misuderstood how the action monad "abort" propagates through nested actions.
790861c
@Mikolaj Mikolaj all heroes (not only the player) regenrate at once
That's because we really want hero selection to be a purely UI distinction;
otherwise players will waste time micromanaging cycling among heroes before
the end of the turn.
e9b28ba
@Mikolaj Mikolaj changing hero selection takes no time now
Via a tmp hack, until the TODOs below playerCommand implemented.
f4f946c
@Mikolaj Mikolaj the loot of all heroes on the current level now counts for the winnin…
…g score

Only heroes from the current level are taken into account, or leaving
one hero camping near the exit would be a too powerful tactics.
088a0a5
@Mikolaj Mikolaj say which hero selected, instead of the boring fixed message e1914e0
@Mikolaj Mikolaj add '*' and '?' to the list of confimation keys
This is to to let the keys that request (more) information (help screen,
item list for dropping, etc.) toggle display of the obtained information off.
No two keys required ('?' and ' '), just tap '?' once, look, tap again.
ad8ac60
@Mikolaj Mikolaj fix a bug with case sensitivity of config; harden code
The bug was wiping out savegame on every other save attempt. I've forgotten
to set case sensitivity in some of the places config is created. Affects only
my branch. With the new code it's much harder to make such a bug again.
1e2783c
@Mikolaj Mikolaj fix a bug where gold can't be dropped under GTK (other frontends are OK) 0340098
@Mikolaj Mikolaj bumping into a hero switches selection to him
TODO: it takes a turn and it shouldn't
dfe2cf3
@Mikolaj Mikolaj on levels with no heroes monsters now chase each other
Actually, they don't actively follow each other (no monster FOV, so they
can't see each other), but they always attack when adjacent, and not
only when bumping into each other by chance, as on levels with heroes.
To see this behaviour toggle look mode, change level and press '.'.
f459fa1
@Mikolaj Mikolaj fix a bug (regression) where monsters can't open secret doors a82badc
@Mikolaj Mikolaj heroes can now be selected with number keys (top row of keyboard)
TODO: refactor the hero code
780d118
@Mikolaj Mikolaj refactor hero selection code; surprisingly small now 11f89ad
@Mikolaj Mikolaj simplify and corret lvlswitch
Now it does not reveal the location of the other end of stairs is look mode.
8dfc54d
@Mikolaj Mikolaj highlight the look mode cursor d2b94b6
@Mikolaj Mikolaj illustrate issue #31 with TODO comments 12c64d4
@Mikolaj Mikolaj movement in look mode advances the cursor and describes terrain 4083fc2
@Mikolaj Mikolaj in look mode, describe only terrain explored by the player 7211356
@Mikolaj Mikolaj close #29 (Naming convention for player/hero/party) bf87826
@Mikolaj Mikolaj in look mode, don't focus on hero unless level changed
Plus some refactoring and hardening.
5a717ec
@Mikolaj Mikolaj some extra banter when exiting the program
In the future we can plug in there some extra statistics,
character dump commands, etc.
e6ade65
@Mikolaj Mikolaj debug for keys; update about the vty keypad patch; misc fixes a25dcbb
@Mikolaj Mikolaj killed actors (monsters and heroes) now drop loot uniformly
Plus some cleanup and TODOs.
8d82c19
@Mikolaj Mikolaj misc tweaks 4426842
@Mikolaj Mikolaj implement and set as default: game does not end util at least one her…
…o alive
34135ef
@Mikolaj Mikolaj monster and hero death now handled right after damage dealt 540f1f2
@Mikolaj Mikolaj ultra-hack: default config file gets included in the binary
In this way, we avoid the usual headaches with paths, OSes and permissions.
At startup it's always parsed, but a user config is used instead, if it exists.
TODO: throughout the code, lookup default values in the default config instead
of specifying them every time an option is queried. In this way, the various
game balance parameters are in sync and all in one place (the default config).
The user configs can be short and modify only some options, the rest is taken
from the default config. Diffs between user and default configs are easy.
The cost of all this is a bit of dynamic typing, and so runtime failures.
Can be limited by defining some types for sets of config parameters.
61eef35
@Mikolaj Mikolaj level layout config options more readable and now mandatory 304b824
@Mikolaj Mikolaj big fixes to do with look mode and level switching eff038a
@Mikolaj Mikolaj default config now underlies config from savefile and from user confi…
…g file
89b1bdb
@Mikolaj Mikolaj defaults no longer needed when querying config
The default config file is now the only source of defaults and we get
an immediate runtime error if the sought option is not found in it
(nor in the main config file carried by the savegame, which may also contain
options from the user config file from the time the game was started).
447b0fc
@Mikolaj Mikolaj add a command to dump current configuration; close #30
Also rewritten the default config file to make diffing with dumps easier.
208fc62
@Mikolaj Mikolaj config file now always has to specify savegame and highscore paths
Previously, the current directory was chosen if no paths were given,
now it's only when the ~/.LambadaHack directory does not exist.
a9cc93d
@Mikolaj Mikolaj make some parameters configurable, as requested in TODOs 59e1577
@Mikolaj Mikolaj running into a monster or hero switches positions 0cd6f38
@Mikolaj Mikolaj simplify moveOrAttack by assuming one moster per tile 910adb1
@Mikolaj Mikolaj factor out the moveOrAttack code dealing with 2 actors a754ad3
@Mikolaj Mikolaj faster, deterministic and better looking extra heroes placement 6c92870
@Mikolaj Mikolaj balance multi-hero mode a bit better d1449bd
@Mikolaj Mikolaj looking at terrain tiles now also mentions monsters
It's out of sync currently, because it erronously takes time,
so monsters can move away before the player reads the description.
b524686
@Mikolaj Mikolaj disallow use of some commands when in look mode on a remote level 4288992
@Mikolaj Mikolaj a mock-up of all the commands of the targeting mode e1082a4
@Mikolaj Mikolaj implement the basic targeting mode commands; close #28
TODO: targeting monsters gets broken as soon as monsters change numbers.
fe3a4f2
@Mikolaj Mikolaj refactor attack code to show a problem with actor representation
See sn issue on tracker with a similar title.
6572e30
@Mikolaj Mikolaj simplify the Target type b73debe
@Mikolaj Mikolaj drastically simplify targeting mode; no more accept/cancel
KISS above all.
8164ccb
@Mikolaj Mikolaj cursor is now permanent, though visible only in targeting mode 9f11d75
@Mikolaj Mikolaj cursor no longer taken as argument for Actions
Since cursor is a component of state, it should not be duplicated
as an explicit argument of Action functions that have access to state.
984fc45
@Mikolaj Mikolaj rename the fields of Cursor e0443f0
@Mikolaj Mikolaj tweaks to variable names and UI messages for targeting 7620e9b
@Mikolaj Mikolaj a few changes and a bit of refactoring of targeting d0c1b04
@Mikolaj Mikolaj rename the Monster/Hero type to Movable 41125e8
@Mikolaj Mikolaj simplified the monsterGenChance formula; more monsters at deep levels…
…, too
f1c674f
@Mikolaj Mikolaj add the (AHero n) form of actor; unused yet 8fb5d5a
@Mikolaj Mikolaj bugfix: forbid closing a door with a hero inside 60cf479
@Mikolaj Mikolaj use AHero to avoid duplicating state in combat; close #34
TODO: many minor points described in #34.
d8f271a
@Mikolaj Mikolaj style: change all foldl to foldl'
(I've just read how unfashionable foldl is and at a glance all the functions
are or should be strict, so changing it to foldr would not make sense.)
5c58cf0
@Mikolaj Mikolaj gut out Actor module, to avoid cyclic dependencies later aba4fc2
@Mikolaj Mikolaj the splayer field of state is now an actor; close #34 (again)
TODO: simplification and clean-up
49e12bd
@Mikolaj Mikolaj heroes now have names intead of numbers
No more duplication of the number inside the hero and in the index of the
intmap at which the hero is stored.
85d26dd
@Mikolaj Mikolaj more cleanup: Actors instead of Ints, etc. 3d3ac7a
@Mikolaj Mikolaj bugfix: heroes no longer obscured by the targeting cursor 5c8defa
@Mikolaj Mikolaj nontrivial default names for the first few heroes; configurable 734ef8a
@Mikolaj Mikolaj death message includes the name of the actor
Plus lots of renames, layout fixes, various tiny tweaks.
05ab163
@Mikolaj Mikolaj asdfasdf b880066
@Mikolaj Mikolaj clean-up complete; operations on current level and all levels separated 50f88bf
@Mikolaj Mikolaj target is now an actor, not a number; close #34 (yet again) 8937a50
@Mikolaj Mikolaj monsters stored on intmap, not time-sorted list; close #34 (for the l…
…ast time)

Asymptotic complexity is the same: finding first monster to move is linear,
but previously inserting the monster back into the time-sorted list was linear.
6097568
@Mikolaj Mikolaj add darts as dungeon items, a bit more rare than swords 0940258
@Mikolaj Mikolaj implement the simplest variant of shooting darts 477519c
@Mikolaj Mikolaj bugfix: cycle heroes was off by one b1e07d2
@Mikolaj Mikolaj bugfix: game laoding was broken for darts c330edb
@Mikolaj Mikolaj aiming a wand at a monster puts it under player control
TODO: when the fatigue stat is introduced, monster will be released quickly
TODO: I bet it crashes in cases like inventory management, etc.; review
4abe663
@Mikolaj Mikolaj moved a comment to the issue on the vty github page c244d18
@Mikolaj Mikolaj fix cycling among monsters and heroes
(Was inaccurate, because there are discontinuities in numeration,
especially for monsters.)
0ff2010
@Mikolaj Mikolaj bugfix: correctly calculate the actor at a target location ad8af59
@Mikolaj Mikolaj if target monster not visible, don't fire at all 70bdc0c
@Mikolaj Mikolaj bugfix: off by 1, when cycling heroes fde611f
@Mikolaj Mikolaj rewrite the cursor and location targetting modes
Now the only way to move from cursor to location is via accepting
with the Return key and the '/' key, in targetting mode, returns
the cursor to the target location.
ccfe246
@Mikolaj Mikolaj add the cursor level field 5f4a91c
@Mikolaj Mikolaj add checks of target validity
In particular, the initial cursor position is invalid, so targetting starts
at player position. Cursor positions set at other levels are invalid, too,
but explicit location targets from other levels are accepted.
Dead or invisible monsters are invalid targets.
02f6a6e
@Mikolaj Mikolaj highlight player, even if he's a monster f46dafe
@Mikolaj Mikolaj backup savegames in case of computer hardware malfunction
The backups are removed at game over, so permadeath still enforced.
1f87418
@Mikolaj Mikolaj generalize Hero to Movable in many places to handle player-controlled…
… monsters
f436888
@Mikolaj Mikolaj remove the Hero and Monster types
They are almost never used and not enforced (not newtypes).
54d27e3
@Mikolaj Mikolaj move time management to particular actions
Possibly, it's correct now in all cases. In particular, targeting is free.
254a878
@Mikolaj Mikolaj move most of Monster.hs to Movable.hs and Hero.hs b13c7e7
@Mikolaj Mikolaj move hero creation code to HeroState.hs 753e2b7
@kosmikus kosmikus Moved Actor type, rearranged some modules.
Heavily edited by Mikolaj for inclusion in master branch.
6a58b4d
@Mikolaj Mikolaj move dungeon setup code to DungeonState.hs
The module does not use State yet, but it's close.
dc34ab7
@Mikolaj Mikolaj fix highlighting in terminal frontends ff6b65d
@Mikolaj Mikolaj add per-hero perception; unused 41800b4
@Mikolaj Mikolaj helper functions for actors 23ad4e2
@Mikolaj Mikolaj use multiple perception to determine if a monster sees a particular hero b39b854
@Mikolaj Mikolaj don't target and fire at actors others can see/reach, but you can't d178c1d
@Mikolaj Mikolaj player-controlled monster perceives, too; close #31 2edcc2c
@Mikolaj Mikolaj prevent a player-controlled monster from tageting itself
and let it run, despite seeing a monster (itself)
5eca39e
@Mikolaj Mikolaj enable 16 colors and emulate them in gtk with the Linux console set a6f9199
@Mikolaj Mikolaj replace setBold with explicit bright color selection 82dbed4
@Mikolaj Mikolaj hack vty to display bright colors by abusing the bold attribute db72379
@Mikolaj Mikolaj rewrite color handling in curses 15c0482
@Mikolaj Mikolaj rewrite color usage everywhere
TODO: tweak colors a bit and clean up Display2.hs, then differentiate
visited/currently seen/visited dark/illuminated dark dungeon floor.
f4fa77e
@Mikolaj Mikolaj remove savefile if corrupted (but backup first) d0e9837
@Mikolaj Mikolaj all monster type data is now in one place cf8765a
@Mikolaj Mikolaj move the State argument to the rear, to work well with gets 2eb1d33
@Mikolaj Mikolaj a quick fix to increase display spead 592c183
@Mikolaj Mikolaj simplify color management even more fb4db25
@Mikolaj Mikolaj clean-up of Display2.hs 1822170
@Mikolaj Mikolaj indicate LOS and light with colors; close #24 11dea08
@Mikolaj Mikolaj move Dungeon type to Dungeon.hs 83c6b31
@Mikolaj Mikolaj move functions from Level.hs to Geometry.hs and others f65ed2f
@Mikolaj Mikolaj move functions from Level.hs to a newly created GeometryRnd.hs 6ead362
@Mikolaj Mikolaj split Level.hs into halves, the other one called Terrain.hs
-- TODO: let terrain types be defined in a config file. Group them
-- and assign frequency so that they can be used for dungeon building.
-- Goal: Have 2 tileset configs, one small, Rouge/Nethack style,
-- the other big, Angband/UFO style. The problem is that the Rogue walls
-- are very complex, while Angband style is much simpler, and I love KISS. Hmmm.
18003aa
@Mikolaj Mikolaj half of the display frontend no longer accessible outside 61fa355
@Mikolaj Mikolaj move a few functions from Display.hs to Keys.hs; assorted tweaks b551293
@Mikolaj Mikolaj rename a file and a few types to avoid confusion db79784
@Mikolaj Mikolaj refactor dungeon and movable creation 729c0ac
@Mikolaj Mikolaj new heroes can now easily be generated mid-game
Plus assorted refactorings.
5dd6b46
@Mikolaj Mikolaj fix and extend HP regeneration 3efa011
@Mikolaj Mikolaj split Item in two, the half containing item definitions is ItemKind 4e344cc
@Mikolaj Mikolaj gather all properties of an item in its definition; close #11 (almost) f618512
@Mikolaj Mikolaj tweak colors for readability d700b77
@Mikolaj Mikolaj rename Attr.hs to Color.hs 0e2905a
@Mikolaj Mikolaj 26 flavours ought to be enough for anybody c5c829a
@Mikolaj Mikolaj create a separate file for in-game effects 7be79d7
@Mikolaj Mikolaj potions now work via effects 20a0752
@Mikolaj Mikolaj in look mode, differentiate between "look" and "remember" 0ec2133
@Mikolaj Mikolaj give newly spawned monsters and heroes fresh indexes
So that, e.g., target at a dead monster does not carry over
to a new monster by chance.
fa9bc38
@Mikolaj Mikolaj all physical damage now done through effects
Lots of TODOs generated.
52119d6
@Mikolaj Mikolaj wand of domination now works through effects c26a3d8
@Mikolaj Mikolaj add 2 scrolls 2ace9a4
@Mikolaj Mikolaj move the implementation of Effects to a separate file d700898
@Mikolaj Mikolaj add potion of wounding 337d9c4
@Mikolaj Mikolaj improve item UI a bit cd77a31
@Mikolaj Mikolaj split ItemAction.hs off of Actions.hs 45cf165
@Mikolaj Mikolaj refactor ItemAction.hs 98af482
@Mikolaj Mikolaj various UI tweaks a345406
@Mikolaj Mikolaj monsters now discover traitors if adjacent
Plus a lot of reindentation and renaming.
50ed98f
@Mikolaj Mikolaj a bugfix and a few tweaks to items and effects 273aa66
@Mikolaj Mikolaj potion of water was boring; tweaked 4d00940
@Mikolaj Mikolaj prevent free monster moves after domination; second part 8dabd75
@Mikolaj Mikolaj changes and additions to dice rolls for items f9d3c84
@Mikolaj Mikolaj blind monsters don't see, but can smell; even under player domination f799aa1
@Mikolaj Mikolaj only gold and gems count for score
Plus a lot of other tweaks.
cf184ec
@Mikolaj Mikolaj merge the V and R commands bd7a498
@Mikolaj Mikolaj change the probability scaled by level to a more intuitive formula e194de9
@Mikolaj Mikolaj add some magical jewelery 899ffb3
@Mikolaj Mikolaj fix a minor bug in item pickup 6a8b25f
@Mikolaj Mikolaj reindent and comment ItemAction.hs before extending it c529e07
@Mikolaj Mikolaj add item choice '_' that picks the first item on the floor
Not perfect, but it can wait until item management is rewritten
with strong invariants.
e55bb95
@Mikolaj Mikolaj fix messages and removing items from a dead hero's inventory a8a3c43
@Mikolaj Mikolaj speed up the gtk frontend
Plus a few fixes and tweaks (too low barehand damage, bright white
status line for curses, and others).
c28d014
@Mikolaj Mikolaj implement macros (only single mappings, for now) 14ff83f
@Mikolaj Mikolaj mark important choices by turning the screen black and white e2bc759
@Mikolaj Mikolaj fully evaluate macros to catch errors in their definitions early
And simplify keyTranslate in all frontends.
389ffd5
@Mikolaj Mikolaj for in-game help override default keybindings with player aliases 810d6ee
@Mikolaj Mikolaj simplify the frontend interface even more e0ef25f
@Mikolaj Mikolaj a TODO to have multi-char macros 5d5900b
@Mikolaj Mikolaj avoid useless recomputation of the display function in gtk frontend
At the cost of two list lookups, which is totally not worth it,
but I have a plan...
c89bea5
@Mikolaj Mikolaj dramatic speedup of the gtk frontend 1413f3e
@Mikolaj Mikolaj a bytestring optimization of the gtk frontend c32a171
@Mikolaj Mikolaj unify eyes and noses 61f4c69
@Mikolaj Mikolaj bugfix: monster in shadow couldn't see heroes 302d666
@Mikolaj Mikolaj refactor strategy calculations e95f561
@Mikolaj Mikolaj intelligent monsters move even more steady c2286dc
@Mikolaj Mikolaj strategy now contains actions, not dirs a9a016b
@Mikolaj Mikolaj refactor strategies: pickup not an empty move any more 3d69f3e
@Mikolaj Mikolaj let monsters target heroes and prefer their targets b3b5fb2
@Mikolaj Mikolaj bugfix: nose was too common; wrongly copied from old format ea4a7e1
@Mikolaj Mikolaj add "last seen at" field to enemy target 6a595a9
@Mikolaj Mikolaj unify strategy targetting for heroes and for traitor monsters 4c364f8
@Mikolaj Mikolaj let monsters push through actors if chasing a target 0c8d8a9
@Mikolaj Mikolaj simplify debug commands now that time is advanced manually e4e6055
@Mikolaj Mikolaj improve target reset and guard commands that can use items from the f…
…loor
4dfcb34
@Mikolaj Mikolaj focus on summoned heroes and let a dying monster emit a dramatic yell 52ecc02
@Mikolaj Mikolaj generalize item usage functions to arbitrary actors da2aa2e
@Mikolaj Mikolaj let monsters apply and throw items sometimes 66e9f55
@Mikolaj Mikolaj bugfix: I was not saving some messages to history
Plus rename of the function that wipes out messages so that it's not used
lightly again.
d6f80aa
@Mikolaj Mikolaj let applied items be always cosumed, to prevent AI loops e9a9cd4
@Mikolaj Mikolaj bugfix: fast monsters desynchronized the party by attacking not selec…
…ted heroes
a8b32f4
@Mikolaj Mikolaj help monsters find room exits and forbid turning around in corridors c3de966
@Mikolaj Mikolaj overhaul combat messages
Item selection generates messages about the source actor,
applying effect of the item generates messages about the target actor.
4a6d667
@Mikolaj Mikolaj make the default config file closer to its dumped form c042c22
@Mikolaj Mikolaj bumping into walls searches surroundings; close #32 bfc4d8f
@Mikolaj Mikolaj update the manual wrt the game and the game wrt the manual f0b24cf
@Mikolaj Mikolaj change the floor item character from _ to -
I've borrowed it wrongly from Angband.
fbc50e6
@Mikolaj Mikolaj limit search by bumping only to walls and when not running 2b0954a
@Mikolaj Mikolaj little edits to manuals 4422943
@Mikolaj Mikolaj use the 'P' key in place of 'M'
Neither Angband nor Nethack use 'M'; let's not be original.
71c7038
@Mikolaj Mikolaj do not let on a secret door position by disallowing search via bumping fc550fc
@Mikolaj Mikolaj drop individual items instead of whole stacks
TODO: dropping all or a given number of identical items would be nice, too.
e1d2492
@Mikolaj Mikolaj the double mystery about potion of water wasn't as much fun as I expe…
…cted
4543a7f
@Mikolaj Mikolaj abort some actions with an empty message
In this way, it's obvious when a move accomplished nothing, e.g.,
a diagonal move from a door after a few bumps into walls that left
searching messages on the screen.
3cd423e
@Mikolaj Mikolaj port to GHC 7.0 7ea7803
@Mikolaj Mikolaj secret doors now searchable; close #32 bd2ab29
@Mikolaj Mikolaj grammar fix: replacing "a" by "the" takes into account "an" 9c28d06
@Mikolaj Mikolaj rebalance the frequency of some items d7d8f0d
@Mikolaj Mikolaj make the fast eye the monster focused on a single (not the closest) foe 5fd0b2c
@Mikolaj Mikolaj don't let blind monsters panic and use items when player in LOS 5d1700f
@Mikolaj Mikolaj let waiting take time for AI monsters; close #42 f04d77d
@Mikolaj Mikolaj update the distributed high scores file 6183089
@Mikolaj Mikolaj add LambdaHack.scores to the release files; see #7 on kosmikus/Lambda…
…Hack

The releases are not very common, so I'd advocate making the high scores
available, so that the players can relate their scores to anything.
ca2847d
@Mikolaj Mikolaj make the beneficial and interesting scroll more common fc61c15
@Mikolaj Mikolaj fix a typo in README 6222c10
@Mikolaj
Owner

I see there is a lot of whitespace changes. Sorry about that --- I've spent enough time on the code that reformatting was very worthwhile for me. I think I was consistent in the changes and most of them adhere to one of the styles you used.

Major changes:

  • +effectToAction :: Effect.Effect -> Actor -> Actor -> Int -> Action (Bool, String)
    items could now be defined in a config file, because, when used, they now have Effects instead of causing hard-coded actions; Effects not only can be evaluated to actions, but also have descriptions, AI valuations, different action for different player commands, etc.

  • rework of the modularization (datatypes, location of functions, decision what is content and what is engine code): Level vs Dungeon, Geometry vs GeometryRnd, Foo vs FooState vs FooAction, items vs. item kinds vs. effects, tiles, vs. tile kinds (this one only started), Movable vs. MovableKind vs. MovableAdd,

  • +lheroes :: Party, -- ^ all heroes on the level
    +lmonsters :: Party, -- ^ all monsters on the level
    multiple heroes, next actor to move searched for in the Party data structure, which is no longer a list sorted by times; heroes and monsters now very interchangeable, but still a long way to get PvsP or a bot doing AIvsAI and run LambdaHack as a screensaver, which I will surely try doing at some point and which would prove the code is extremely well structured

  • lvlChange :: VDir -> Action ()
    rewritten level changing; now it's possible to browse levels other than the current level of the player; e.g., level where other heroes reside or any levels in the targeting mode

  • -lookAround :: Action a
    +targetFloor :: Action ()
    +targetMonster :: Action ()
    +checkCursor :: Action () -> Action ()
    targeting mode replaces look around command; it changes behaviour of some actions; in particular checkCursor is a wrapper for actions that do not make sense if the browsed level is not the one with the current player character on it; the scursor component of the state records the position of the targeting cursor and related data; each hero and monster has his own target, set by AI for monsters and via targeting mode for heroes

  • +advanceTime :: Actor -> Action ()
    +playerAdvanceTime :: Action ()
    time is now advanced manually inside action definitions

  • +deleteActor :: Actor -> State -> State
    +checkPartyDeath :: Action ()
    checking monster and hero death now unified and refactored out; surviving heroes carry on

  • +-- | Resolves the result of an actor running into another.
    +-- This involves switching positions of the two movables.
    +actorRunActor :: Actor -> Actor -> Action ()
    also, a hero bumping into another selects him, bumping into a wall performs a search

  • also: colours and keypresses configurable, colormaps change during the game, frontends refactored accordingly, GTK frontend optimized (not quite enough), colours of items generalized to flavours (color + color name + (in the future) extra description), default config compiled into the binary, extended AI (e.g., monsters use and/or throw all items), juggling multiple perception (from multiple heroes and/or player-controlled monsters)

@Mikolaj
Owner

About EDSLs for game content, with reflection:

The refactorings of items vs. item kinds vs. effects and the same started for movables and now also started for tiles in the Allure fork, are a first step to have DSLs for building game content. The crucial point is that the game should be able to modify the content and dump the new definitions so that the content can be automatically pre-balanced each time new content is added and also continuously changed in response to player actions. Ideally the game would also be able to load the new definitions without recompiling. Also, ideally the DSLs would be EDSLs. These two minor goals are in conflict, though, because AFAIK Haskell does not have (comfortable) reflection and, anyway, reflection is a dangerously powerful tool.

Edit: make that one DSL with 3 main types, since some effects will be shared, say, flaming sword, lava and fire elemental will share the flame effect primitive (or combinator taking duration, power, etc.).

Mikolaj added some commits
@Mikolaj Mikolaj improve the playing manual 9cfe372
@Mikolaj Mikolaj make ghc 7.3 happy a03cc33
@Mikolaj Mikolaj revert a part of "abort some actions with an empty message"
This reverts q part of commit 3cd423e
concerning running, because the message for the last move of running
was being lost.
2fe2852
@Mikolaj Mikolaj readd the deprecated syntax for quasiquotes, for 6.12.3 compatibility
Since gtk does not work with most 7.*, compatibility with 6.12.3 makes sense,
even at the cost of incompatibility with 8.*.
b0e8c02
@kosmikus kosmikus commented on the diff
src/Action.hs
((23 lines not shown))
--- | Print message, await confirmation. Return value indicates if the
--- player tried to abort/escape.
-messageMoreConfirm :: Message -> Action Bool
-messageMoreConfirm msg =
- do
- message (msg ++ more)
- display
- session getConfirm
+-- | Print message, await confirmation. Return value indicates
+-- if the player tried to abort/escape.
+messageMoreConfirm :: Bool -> Message -> Action Bool
+messageMoreConfirm blackAndWhite msg = do
+ messageAdd (msg ++ more)
+ if blackAndWhite then displayBW else display
@kosmikus Owner

This indicates that it'd be better to have one function

 display :: Bool -> ...

that takes the BW mode, and just pass the argument through.

@Mikolaj Owner
Mikolaj added a note

implemented in 7f49100

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kosmikus kosmikus commented on the diff
src/Action.hs
((20 lines not shown))
-- | Set the current message.
-message :: Message -> Action ()
-message nm = Action (\ s e p k a st ms -> k st nm ())
+messageWipeAndSet :: Message -> Action ()
+messageWipeAndSet nm = Action (\ s e p k a st ms -> k st nm ())
@kosmikus Owner

I think the name is too long.

@Mikolaj Owner
Mikolaj added a note

implemented in a6e2b80

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kosmikus kosmikus commented on the diff
src/Action.hs
((6 lines not shown))
currentPerception = Action (\ s e p k a st ms -> k st ms p)
+-- | If in targeting mode, check if the current level is the same
+-- as player level and refuse performing the action otherwise.
+checkCursor :: Action () -> Action ()
+checkCursor h = do
+ cursor <- gets scursor
+ level <- gets slevel
+ if creturnLn cursor == lname level
+ then h
+ else abortWith "this command does not work on remote levels"
+
+updateAnyActor :: Actor -> (Movable -> Movable) -> Action ()
@kosmikus Owner

Why not rename Movable to Actor, and Actor to ActorId?

@Mikolaj Owner
Mikolaj added a note

implemented in a72f566 and 22d6553

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kosmikus kosmikus commented on the diff
src/Actions.hs
((72 lines not shown))
run :: Dir -> Action ()
-run dir =
- do
- modify (updatePlayer (\ p -> p { mdir = Just dir }))
- moveOrAttack False False APlayer dir -- attacks and opening doors disallowed while running
+run dir = do
+ pl <- gets splayer
+ targeting <- gets (ctargeting . scursor)
+ if targeting
@kosmikus Owner

Think about doing the mode dispatch elsewhere.

@Mikolaj Owner
Mikolaj added a note

Noted as a TODO comment in the code; extended a bit.

@Mikolaj Owner
Mikolaj added a note

Implemented in 1e7daa2. Done in the simplest way. There are better ways, for sure (as the message aggregation proopsed in TODO inside the changed code), but I'd need some more complex messages to evaluate (e.g., missed blows, criticals).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kosmikus kosmikus commented on the diff
src/Actions.hs
((123 lines not shown))
+ per <- currentPerception
+ let groupName = "sword"
+ verb = attackToVerb groupName
+ sloc = mloc sm
+ swordKindIndex = fromJust $ L.elemIndex ItemKind.sword ItemKind.loot
+ -- The hand-to-hand "weapon", equivalent to +0 sword.
+ h2h = Item swordKindIndex 0 Nothing 1
+ str = strongestItem (mitems sm) groupName
+ stack = fromMaybe h2h str
+ single = stack { icount = 1 }
+ -- The message describes the source part of the action.
+ -- TODO: right now it also describes the victim and weapon;
+ -- perhaps, when a weapon is equipped, just say "you hit" or "you miss"
+ -- and then "nose dies" or "nose yells in pain".
+ msg = subjectVerbMObject sm verb tm $
+ if isJust str then " with " ++ objectItem state single else ""
@kosmikus Owner

Make combat messages less verbose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kosmikus kosmikus commented on the diff
src/FOV.hs
@@ -14,7 +14,7 @@ import FOV.Shadow
import Geometry
import Level
-data FovMode = Shadow | Permissive Int | Digital Int
+data FovMode = Shadow | Permissive Int | Digital Int | Blind
@kosmikus Owner

Should this really be an FOV, or a modifier?

@Mikolaj Owner
Mikolaj added a note

Noted as a TODO comment in the code; extended a bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kosmikus kosmikus commented on the diff
src/ItemAction.hs
((42 lines not shown))
+-- | Display inventory
+inventory :: Action a
+inventory = do
+ items <- gets (mitems . getPlayerBody)
+ if L.null items
+ then abortWith "Not carrying anything."
+ else do
+ displayItems "Carrying:" True items
+ session getConfirm
+ abortWith ""
+
+-- | Let the player choose any item with a given group name.
+-- Note that this does not guarantee an item from the group to be chosen,
+-- as the player can override the choice.
+getGroupItem :: [Item] -> -- all objects in question
+ String -> -- name of the group
@kosmikus Owner

There should be a datatype for item groups.

@Mikolaj Owner
Mikolaj added a note

Fully agreed. Noted as a TODO comment in the code. Extended a bit as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kosmikus kosmikus commented on the diff
src/ItemKind.hs
((2 lines not shown))
+
+import qualified Data.List as L
+import qualified Data.IntMap as IM
+
+import Color
+import Effect
+import Random
+
+data ItemKind = ItemKind
+ { jsymbol :: !Char -- ^ map symbol
+ , jflavour :: [Flavour] -- ^ possible flavours
+ , jname :: String -- ^ item group name
+ , jeffect :: Effect -- ^ the effect when activated
+ , jcount :: RollQuad -- ^ created in that quantify
+ , jfreq :: !Int -- ^ created that often
+ , jpower :: RollQuad -- ^ created with that power
@kosmikus Owner

I think jpower should be part of the Effect. It doesn't make sense for all items, and will mean different things.

@Mikolaj Owner
Mikolaj added a note

Noted as a TODO comment in the code; edited and discussed a bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kosmikus kosmikus commented on the diff
src/Movable.hs
@@ -0,0 +1,83 @@
+module Movable where
+
+import Data.Binary
+import Control.Monad
+
+import Geometry
+import Item
+import MovableKind
+
+-- | Monster properties that are changing a lot. If they are dublets
+-- of properties form MovableKind, the intention is they may be modified
+-- temporarily, but will return to the original value over time. E.g., HP.
+data Movable = Movable
+ { mkind :: !MovableKind, -- ^ kind of the movable; TODO: make this Int
@kosmikus Owner

Probably not an Int, but ...

@Mikolaj Owner
Mikolaj added a note

Fixed the TODO and added similar for ItemKind (where it's already an Int, but should probably be a newtype of Int).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kosmikus kosmikus commented on the diff
src/Item.hs
((18 lines not shown))
data Item = Item
- { icount :: Int,
- itype :: ItemType,
- iletter :: Maybe Char } -- inventory identifier
+ { ikind :: !Int,
@kosmikus Owner

I don't think this should be an Int.

@Mikolaj Owner
Mikolaj added a note

Added the TODO. I think I will fix this together with ActorKind and TileKind at some point. I'm a bit worried about not being able to use IntMap if I make it a newtype instead of Int, but there is a generalization of IntMap, so I may try to use it instead.

@Mikolaj Owner
Mikolaj added a note

Actually, I've manage to do this without the generalization of IntMap, see #13..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kosmikus kosmikus commented on the diff
src/Turn.hs
((13 lines not shown))
- modify (updateLevel (updateMonsters (const ms)))
- -- place the monster's possessions on the map
- modify (updateLevel (scatterItems (mitems m) (mloc m)))
- handleMonsters
- | otherwise -> -- monster m should move; we temporarily remove m from the level
- -- TODO: removal isn't nice. Actor numbers currently change during
- -- a move. This could be cleaned up.
- do
- modify (updateLevel (updateMonsters (const ms)))
- handleMonster m
+ ms <- gets (lmonsters . slevel)
+ pl <- gets splayer
+ if IM.null ms
+ then nextMove
+ else let order = Ord.comparing (mtime . snd)
+ (i, m) = L.minimumBy order (IM.assocs ms)
@kosmikus Owner

We should replace this structure using a priority search queue/tree.

@Mikolaj Owner
Mikolaj added a note

Fully agreed. Noted as a TODO comment in the code. With some luck such a structure will be updated to 7.4 before I get to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kosmikus kosmikus closed this in f618512
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.