Commit Graph
100 Commits
Author SHA1 Message Date
Pasi Kallinen 82f0b1e8ea Scared hostile monster which cannot move away will attack 2022-07-21 20:21:10 +03:00
Pasi Kallinen 8747d2ddce Sitting on amorphous corpse 2022-07-21 18:27:50 +03:00
Pasi Kallinen 8a52716936 Wielding Giantslayer prevents knockback from monsters 2022-07-20 14:44:15 +03:00
Pasi Kallinen ced920df54 Adjust Demonbane invoke ability
Demon lords and princes have a chance to resist the effect.
Demons in quest when nemesis is alive have a very high chance
of resisting.
When invoked in Gehennom, teleports the demons within the same
level.
2022-07-20 09:42:28 +03:00
Pasi Kallinen b1a5a9c390 Demonbane changes
Demonbane is now a mace, the first sac gift for priests,
and gets an invoke ability to banish demons.
2022-07-19 21:23:26 +03:00
Pasi Kallinen d713c1826b Buzz macros and related stuff
Add macros to convert AD_foo, WAN_foo, and SPE_foo to relative values
for passing to BZ_U_foo and BZ_M_foo macros.

Change some return values in monster spellcasting function from
magic numbers to MM_MISS or MM_HIT.

Make buzzmu consider hero resistances - previously the
monster with innate zapping ray (Angels and Asmodeus) would
just keep doing that attack, but they will now just curse if
it saw the hero resist the attack.
2022-07-19 15:14:55 +03:00
Pasi Kallinen 0bca93be87 Large monster can knock back smaller ones
When a monster at least two sizes larger hits another one,
there's a chance the smaller defender will be knocked back.

This applies also to hero, attacking when polymorphed to
a large monster, or defending from a large monster.

Most of the monsters that can knock back are giants and dragons.

Idea and some of the code from EvilHack.
2022-07-18 23:01:11 +03:00
Pasi Kallinen 7bf02ade48 Bigroom 2 can have ice floor in unlit areas 2022-07-18 17:58:45 +03:00
Pasi Kallinen e4cb3f0832 Rangers always succeed in disarming bear traps 2022-07-18 17:22:19 +03:00
Pasi Kallinen 88ec641770 Allow entering a known pit without taking damage 2022-07-18 17:00:20 +03:00
Pasi Kallinen aa09f3eef5 Use macro unhideable_trap 2022-07-18 13:27:39 +03:00
Pasi Kallinen 06efa695be Abort wiztelekinesis if changing levels 2022-07-18 13:14:11 +03:00
Pasi Kallinen a4ef5ee533 timed_delay doc bits 2022-07-18 08:33:10 +03:00
Pasi Kallinen 7c96825525 Demote elf-queen to a lady 2022-07-17 21:47:32 +03:00
Pasi Kallinen 823a6f247b Unify picking crawl goodpos 2022-07-17 21:37:31 +03:00
Pasi Kallinen 6fe0f7c132 Unify impaired movement direction checks 2022-07-17 12:23:49 +03:00
Pasi Kallinen 1ae2bc7063 Wielding a bec de corbin makes ravens generate peaceful 2022-07-17 09:04:15 +03:00
Pasi Kallinen 94c1e94d20 Move mtrack push and clear to separate functions 2022-07-16 18:43:22 +03:00
Pasi Kallinen 486ed29077 Blessed potion of polymorph asks user for monster to poly into
... unless there's some other form that would override the choice,
such as a worn dragon armor, lycanthropy, or vampirism.

The polymorph will be in effect for 10-24 turns.
2022-07-14 14:04:27 +03:00
Pasi Kallinen a1ca981907 Grid bugs don't have hands
Fixes #799
2022-07-13 11:21:21 +03:00
Pasi Kallinen c09ae332c8 Valkyries start with a spear instead of a long sword
Long swords are overused, and Knights already start with a long sword.
No other roles start with a spear. Lawful Valks shouldn't have an easy
way to get Excalibur.

There's also historical precedence for valkyries with spears, see eg.
Wagner's Ring Cycle.

This makes Valks early game damage slightly lower, although dwarven spear
does the same damage to small monsters as long sword, and there should be
plenty of chances to get one from the mines. Spears can also be thrown.

This change has been done in several variants, eg. xNetHack and Fourk.
2022-07-12 23:05:46 +03:00
Pasi Kallinen 81d54f15ce Applying a cursed lamp can make your hands slippery 2022-07-12 22:12:52 +03:00
Pasi Kallinen e339f8a1fa More message variation on eating palatable corpses 2022-07-12 21:51:41 +03:00
Pasi Kallinen 40b1e55801 Always give a message when dipping an item into a fountain 2022-07-12 21:10:19 +03:00
Pasi Kallinen 5c7c9d10ae Rejigger anti-magic traps
My changes were too drastic, so reduce the drain and damage so it
matches all the other traps. Now the anti-magic trap will always
ding your max energy a bit, in addition to the physical damage done
if wearing magic resistance.
2022-07-12 20:24:30 +03:00
Pasi Kallinen 314715038d Praying on an altar with pet corpse on it can revive the pet 2022-07-10 12:56:20 +03:00
Pasi Kallinen 1dcd14bffd Make sure getdir return values are in range
u.dx and u.dy should be [-1, +1]
2022-07-10 11:00:27 +03:00
Pasi Kallinen f3e2f08b54 Unhide monster when object is dropped through hole
Monster hiding under an object on a hole, the object got
knocked down the hole, the monster kept hiding.
2022-07-09 18:44:35 +03:00
Pasi Kallinen c4bd9db98c Fix monster hiding under candle burning away
Reveal the monster when the candle it was hiding under burned away.
2022-07-08 13:39:28 +03:00
Pasi Kallinen 96f6c52082 Trapped monster cannot move to swallow another
The swallower kept their trapped-state, but could be moved to
another location. Just deal with it by not letting a trapped monster
swallow.
2022-07-08 10:47:14 +03:00
Pasi Kallinen 4c343d079a Untrap monster when lregion removes the trap
This check really should go in deltrap itself, but that would require
more effort than I have spoons for right now.
2022-07-07 12:29:03 +03:00
Pasi Kallinen 640b6d6ce5 Untrap monster in trap on melting ice
Monster trapped in a trap on melting ice, the monster stayed
trapped even as the trap was removed when the ice melted.
2022-07-06 20:16:24 +03:00
Pasi Kallinen 134363cead Fire trap on ice can indirectly kill a monster via drowning
Make the trap routine claim the trap killed the monster even
though it was drowning that did it, otherwise callers cannot
rely on the trap routine return value.
2022-07-05 12:17:50 +03:00
Pasi Kallinen 361e6a924a Fix segfault with fire trap on ice and monster triggering it
When a monster with innate teleporting stepped on a fire trap on ice,
the ice melted and the monster teleported away before falling
into the pool. If the monster's new location had a trap, the code
tried to access the deleted fire trap.
2022-07-05 10:51:28 +03:00
Pasi Kallinen c6a3ae5c6c Curses: Obey timed_delay option 2022-05-19 18:40:15 +03:00
Pasi Kallinen 8532b8d990 Add missing void 2022-05-18 18:59:01 +03:00
Pasi Kallinen 2a801538fa Fix warnings, add newline before function braces 2022-05-02 12:46:02 +03:00
Pasi Kallinen 71c55e4285 Remove extra full stop from SOUND error 2022-04-30 16:53:47 +03:00
Pasi Kallinen c3c60b0b2c When setting user sounds, allow also setting a MSGTYPE
The SOUND lines now have an optional msgtype parameter:

   SOUND=MESG hide "^You miss the " "swing.wav" 75

Fixes #571
2022-04-27 13:32:34 +03:00
Pasi Kallinen 5d20140b74 Qt: To play user sounds with volume, replace QSound with QSoundEffect 2022-04-27 12:40:59 +03:00
Pasi Kallinen 4cffa9700e Split trap statue creation into separate function 2022-04-26 18:09:36 +03:00
Pasi Kallinen 99efeafec7 Split trap note choosing into separate function 2022-04-26 14:00:09 +03:00
Pasi Kallinen f10cdc2d9c Use get_mleash to find the leash attached to monster 2022-04-26 08:46:55 +03:00
Pasi Kallinen 9c2ca1577f Unify probing an object chain 2022-04-25 18:11:32 +03:00
Pasi Kallinen 9b1872ba05 Couple more monster iterator uses 2022-04-25 12:53:04 +03:00
Pasi Kallinen 4a01c8fbd7 Monster list iterator
Add some basic functions to iterate through the monster list,
ignoring dead monsters. Mainly just to allow splitting up code
into discrete functions.

Not quite happy with the get_iter_mons_xy - should probably have
a pointer to iterator data struct, which gets passed through instead,
but this works for now.
2022-04-24 13:03:47 +03:00
Pasi Kallinen af7db2f8f1 Fix panic on thrown potion of acid when swallowed
When you're swallowed and throw a missile that kills the swallower,
the thrown missile is picked up by the swallower before death.
This caused a panic when you threw a potion, which was first picked up
by the swallower, which upon death dropped the potion on the floor,
but then throw code was trying to destroy the potion ...
2022-04-19 15:00:00 +03:00
Pasi Kallinen 262e178243 Unify mhitm magic attack negation checks 2022-04-18 19:14:40 +03:00
Pasi Kallinen d7eb95cbf0 Minor code dedup in sp_lev 2022-04-18 13:38:01 +03:00
Pasi Kallinen cb02ce88c5 Revisit the Valkyrie goal level hack
Instead of hardcoding the lava terrain change in core, if the stairs
are created in a fixed location, force the terrain to room floor first.
Move the surrounding lava changing to room floor to the Val-goal lua
file.
2022-04-15 18:52:49 +03:00
Pasi Kallinen 43856fe023 Fix uninitialized var in dip 2022-04-14 18:59:03 +03:00
Pasi Kallinen 28e416da3a Add moving on the trap to the mouse menu 2022-04-11 15:08:50 +03:00
Pasi Kallinen 503b85b1cf Add spell casting to mouse menu 2022-04-11 14:54:12 +03:00
Pasi Kallinen 32fa807050 When autopicking objects, you can count to two
Show "two" instead of "a few" when autopicking up objects, and
there's some left you didn't pick up.
2022-04-11 11:31:32 +03:00
Pasi Kallinen 24d3c96c1d X11: set menu entries to same length
While testing the new mouse action menus, it was quite annoying
to try and hit some shorter entries. Make all the selectable entries
the same maximum length, and with text left justified.
2022-04-10 16:09:43 +03:00
Pasi Kallinen a1f2000afd Fix castle engraving and scroll
Fixes #723
2022-04-10 14:30:58 +03:00
Pasi Kallinen ec4fafcf53 Fix erroneous test_move params 2022-04-10 12:52:39 +03:00
Pasi Kallinen e53a4c0abd Context sensitive item usage from inventory
Allow selecting an item from inventory and show a menu of actions
applicable for that particular item. Some of the entries might
be slightly spoilerish (eg. it'll reveal that you can read T-shirts),
but the improved usability for new players is more than worth it.

Generally known as "item actions", this was first implemented
in AceHack by Alex Smith.
2022-04-09 15:28:23 +03:00
Pasi Kallinen 093f7452af Some more therecmdmenu
If on, therecmdmenu handles clicking anywhere on the map,
not just on or next to hero.  Add throwing items to the menu.
2022-04-08 19:48:01 +03:00
Pasi Kallinen 77cf464836 Add chat and offer to herecmdmenu 2022-04-07 18:06:31 +03:00
Pasi Kallinen 10fd0deab2 When levitating, hide drink and dip from herecmd_menu 2022-04-07 16:44:16 +03:00
Pasi Kallinen eb9c7d77d4 Improve therecmdmenu
Turning on herecmd_menu and clicking with mouse is now actually
somewhat playable.
2022-04-06 21:23:27 +03:00
Pasi Kallinen e260c9ded5 Fix mouse travel and look
Looks like I broke mouse travel and clicklook a while back, and
no-one noticed...
2022-04-05 15:03:20 +03:00
Pasi Kallinen 16d813b44a Give a message when stinking cloud is created on top of hero 2022-04-03 20:43:04 +03:00
Pasi Kallinen 92c21b588b Ask to kick a locked door open, if hero has no unlocking tool 2022-04-03 13:58:50 +03:00
Pasi Kallinen 565a3cf0a9 Reverse the unique requirement 2022-04-03 08:55:09 +03:00
Pasi Kallinen 38a6cee1ab Don't pacify unique monsters when untrapping them from web 2022-04-02 19:38:50 +03:00
Pasi Kallinen 6977aef436 Fix stuck travel for good
My fixes to the travel stuck oscillation did not fix all of them,
and I've even seen a 3-step loop - which my fixes cannot detect.
I guess there could be arbitrary-sized loops too.

To definitely fix this, keep track of all the map locations travel
has moved the hero through, and if it tries to go on a location already
used, stop travel and give the unsure -message.
2022-04-02 18:27:53 +03:00
Pasi Kallinen f45e79e1a0 Fix medusa levels
My recent commit broke medusa-3 and medusa-4, so fix those.

Make des.stair and des.ladder also accept hash-coordinate:
  des.stair("up", {8, 10});
2022-04-01 08:53:15 +03:00
Pasi Kallinen 476e47b2cd Use correct findtravelpath param value 2022-03-31 17:50:00 +03:00
Pasi Kallinen 2bbcfb5540 Prevent random stairs overwriting other terrain
When creating stairs in a random location in a special level lua file,
there was a chance it overwrote eg. other stairs. Make randomly placed
stairs pick locations with room, corridor, or ice terrain.

Fixes github issue #702
2022-03-29 18:02:30 +03:00
Pasi Kallinen c763e26aa7 Second fix to stuck travel
There were at least two cases of travel oscillation that occurred,
even after my previous fix. To fix those, the guessing routine
would also have to consider distance to original target location.
I opted not to make that part more complex - as there was
no guarantee those changes would catch all of the oscillation cases.

Instead, when we're guessing where to move, and we would actually move
back to where we came from, stop travel, and give a message.

This should fix (and fuzzing seems to confirm) all of the travel
oscillation bugs for good, and it shouldn't affect actual good travel.
(Other than the player getting a YAFM in the occasional case of trying
to travel to a location with no travel path)
2022-03-27 10:58:12 +03:00
Pasi Kallinen 1d78d3c3f2 Fix travel getting stuck oscillating between two locations
There's been occasional reports (perhaps once or twice a year)
of travel getting stuck moving repeatedly between two locations
next to each other, but it has never been reproduced before.

This special level lua code fragment is a minimal test case
which triggers it:

--- special level lua fragment, indented
  des.map([[
  --##---
  ###----
  #-+----
  ####--L
  ]]);
  des.door("open", 2,2)
--- end of special level lua fragment

The open door is required.

Magic map the level. Start from somewhere NW of the door, and try
to travel to the lava pool. Hero will get stuck oscillating between NW
of the door and two steps west of the door.

Here are the maps of the travel[][] array values from findtravelpath()
in those two steps in the above map:

-------------  -------------
|  . . 2 3  |  |  . . 1 2  |
|  1 1 2 .  |  |  1 @ 1 .  |
|  @ . . .  |  |  1 . 2 .  |
|  1 1 2 .  |  |  2 . 3 4  |
-------------  -------------

There are two possible closest locations to the lava pool,
the one marked with "3" on the left map, and "4" on the right map.
Based on that alone, both would be valid places to path to.

But, in the left case, hero could not see the bottom location, so
the code won't even consider pathing to it, so it will start moving
towards the "3".

When hero moves to the second position, in the right map, now the "4"
could be seen. Now there are two possible closest locations we could
choose from. The code that scans the possible locations goes from top-left
to bottom-right, first going down (y-axis). So, the code sees the
"2" on the right. distmin() to there is 2. Good, we pick that location
to path to. Next, going down, the code considers the "4" ... which is
also equally close to the lava pool. and distmin does not consider terrain,
so ignores the door, so it has the same distmin value of "2", so the
code picks this location.

But: this was just a guess, because there's no known valid path to the
lava pool. The code loops back up to rebuild the travel[][] array
with a new starting location as the "4" from the right map, pathing
back to hero.

This is that travel array map:
-------------
|  . . . .  |
|  4 @ 3 .  |
|  3 . 2 .  |
|  3 2 1 x  |
-------------

The way travelstepx and travelstepy arrays are built means that the first
location that considers the hero's location is the "3" SW of hero, so
hero will move there next. Repeat from beginning. If there was no door,
the travelsteps would reach hero's location first from SE.

(I left the travel[][] array rebuild and travelstepx/travelstrepy build
off from the other movement position, as it's not relevant)

The fix: When considering which of the two possible closest places to the
lava pool to path to, use the one with the lowest value in the travel array.
That value is the real number of moves it takes for the hero to walk there,
so the code will consistently path to the upper location, as it is "2",
instead of considering the "4" below it.

Also some minor code reorg, so it considers couldsee first instead of
later in two separate places.
2022-03-26 23:58:30 +02:00
Pasi Kallinen 60bf399f91 Don't stop travel when going past a closed door 2022-03-24 19:33:37 +02:00
Pasi Kallinen 27ea4b7e52 nit: Indented function end brace 2022-03-23 12:08:46 +02:00
Pasi Kallinen ade53925a6 Lua: error when supplied coordinate is not table 2022-03-22 11:06:28 +02:00
Pasi Kallinen 6eadff01b8 Lua: selection get and rndcoord changes 2022-03-22 10:45:20 +02:00
Pasi Kallinen 27898340b9 Lua: coordinate tweaking
Make selection rndcoord return a table with x and y keys.
Allow (most) coordinate parameters accept such a table.
Fix selection and des lua tests broken by the above changes and
an earlier change, because selections tried to set terrain
at column 0, and it now causes a complaint.
2022-03-22 09:16:19 +02:00
Pasi Kallinen 81ef433def Fix dmonsfree pending when hero was hit with drain-life artifact
When a monster hit hero with an artifact with drain-life attack
(Stormbringer or The Staff of Aesculapius), and hero lost a level
and hero had more max hp in the lower xp level, the math made the
attacker lose hp. This could put the monster hp in the negative,
causing "dmonsfree: 1 removed doesn't match 0 pending"
2022-03-18 18:33:36 +02:00
Pasi Kallinen 39acd095b2 Add helpless monster macro 2022-03-18 10:19:04 +02:00
Pasi Kallinen 074476758c Change map terrain changing from macro to function
The function handles setting lava lit, and removing ice melt timers.
2022-03-16 20:59:58 +02:00
Pasi Kallinen 811299edaf Lua: allow calling impossible 2022-03-16 16:58:42 +02:00
Pasi Kallinen d1ca594d1c Remove melting ice timeouts when terrain changes
If special level lua code creates a melting ice timeout, but
later in the code places stairs, or a trap which might change
the ice to room floor, the timer sanity checking doesn't
like that.
2022-03-16 16:51:53 +02:00
Pasi Kallinen 49b26dbe99 Simplify abscoord code
No need to call get_location_coord, as we're never dealing with
random coordinates or rooms.
2022-03-16 16:46:10 +02:00
Pasi Kallinen d76cf9377d Unhide monster when rolling boulder explodes 2022-03-16 16:43:42 +02:00
Pasi Kallinen 38924002e0 Lua: ice theme room and melting ice
Allow the ice theme room to occasionally have melting ice.
Add nh.abscoord() to convert room-relative to map-absolute coords.
2022-03-15 22:05:36 +02:00
Pasi Kallinen bdc81ab389 Lua: allow obj chain iteration 2022-03-15 18:24:49 +02:00
Pasi Kallinen e33dd11e99 Document the lua object class 2022-03-15 14:17:46 +02:00
Pasi Kallinen 957c0fbee0 Lua: location-specific timers
Expose map-location specific timers to lua scripts. For example:

  nh.start_timer_at(x,y, "melt-ice", 10);

Currently only available timer type is "melt-ice".
2022-03-15 13:46:56 +02:00
Pasi Kallinen 006ae67029 Fix autowielding tools taking no time
When applying some tools (whips, polearms, grapples), or rubbing
a lamp, or when fireassist is on and you fire something without
wielded launcher, the automatic wielding should take as much time
as wielding the item normally does.

Fixes #696
2022-03-15 11:34:48 +02:00
Pasi Kallinen b271826147 Add test for selection subtraction 2022-03-14 19:06:51 +02:00
Pasi Kallinen 9dd69f4b88 Fix potentially uninitialized variables 2022-03-14 10:06:23 +02:00
Pasi Kallinen 39f3988f76 Lua: object bury method 2022-03-13 18:38:23 +02:00
Pasi Kallinen 20f214592a Lua: object timers
Expose object timers to lua scripts. For example:

   local o = obj.new("cockatrice egg");
   o:placeobj(5, 5);
   o:start_timer("hatch-egg", 3);

Available methods are:

- obj.has_timer("rot-corpse")
    returns true if object has attached timer, false otherwise.

- obj.peek_timer("hatch-egg")
    returns an integer value, which is the turn when the timer
    attached to the object would trigger. returns 0 if no such timer.

- obj.stop_timer("shrink-glob")
    stops attached timer, or if no timer type is given, stops all
    timers attached to the object.

- obj.start_timer("zombify-mon", 15)
    starts a timer with a trigger time in that many turns in the future.
    replaces any previous timer of the same type.

Valid timers are "rot-organic", "rot-corpse", "revive-mon",
"zombify-mon", "burn-obj", "hatch-egg", "fig-transform",
and "shrink-glob". Also "melt-ice" is recognized, but does nothing
to objects.
2022-03-13 14:50:07 +02:00
Pasi Kallinen 4be6fb0df9 Rolling boulder launch coordinates
Allow defining rolling boulder launching location in special level
lua scripts:

 des.trap({ type="rolling boulder", coord={7, 5}, launchfrom={-2, -2} });

launchfrom is relative to the trap coord.
2022-03-12 18:34:44 +02:00
Pasi Kallinen 625571062e Separate function for finding random launch coordinate 2022-03-12 18:04:29 +02:00
Pasi Kallinen ea52bacfce Unhide monster hiding under shrinking glob 2022-03-11 17:34:26 +02:00
Pasi Kallinen 785463ba31 Can't swallow trapped monsters
Gulping can move the trapped monster to another location, while
still being marked as trapped.  I don't want to deal with this,
so just say purple worms can't swallow trapped monsters...
2022-03-05 18:30:36 +02:00
Pasi Kallinen 0dec6cad34 Illiterate and blank spellbooks from gods
Make gods avoid giving blank spellbooks as gifts, if you're
illiterate.  But if you do get a blank spellbook as a gift,
don't force-learn that non-existent spell.
2022-03-05 16:42:46 +02:00
Pasi Kallinen 71fe55eba8 Reset next_boulder when boulder was pushed 2022-03-05 16:36:26 +02:00