Commit Graph
100 Commits
Author SHA1 Message Date
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
Pasi Kallinen 3834bb2ca0 Get out of moverock correctly, so we clear next_boulder 2022-03-05 15:46:16 +02:00
Pasi Kallinen d2efae280a Fix monster trapped in nonexistent trap, pt 2
Monster hiding under an item on a location with a land mine,
a rolling boulder trap launches a boulder which blows up the mine,
and all the items scatter away. If the hider survived that, it
was still hiding.
2022-03-05 13:42:28 +02:00
Pasi Kallinen 4c1d1a0666 Fix monster trapped in nonexistent trap
A monster trapped in a bear trap on ice, exploding fiery monster
turned the ice into water turning the trap into object, the trapped
monster claimed to be still trapped in the nonexistent trap.
2022-03-05 11:29:06 +02:00
Pasi Kallinen fab1048f2f Fix segfault with uball
Drowning in a pool while punished and carrying the ball,
and the only available space to crawl back on dry land
has a magic trap, which unpunishes you.
2022-03-05 10:09:54 +02:00
Pasi Kallinen 7a1db1d0bd Fix couple cases of unhiding monsters
Hidden monster might be forced to move to a location where it
can't hide, perhaps because it's mostly surrounded by other monsters.

Hidden monster in a pit under items, getting hit by a rolling boulder,
the boulder will fill the pit burying the items, making the monster
unable to hide there.
2022-03-04 19:58:24 +02:00
Pasi Kallinen 7c2ffaa8c5 More trap sanity 2022-03-04 17:18:05 +02:00
Pasi Kallinen 62906e732e Trap sanity checking 2022-03-04 16:54:43 +02:00
Pasi Kallinen 2cdd8f8dcb Fix checking monster moving into a trap return value
When I added a new trap return value, this was one place that
should've checked it.

This was really annoying to debug - it manifested as a temp level
file loading error, because a monster moved on to a level teleport
trap, which zeroes out (mx, my), then later in the monster movement,
a web spinner created a web at (0,0), and then hero leaving the level,
the traps were saved into the level file ... and when loaded, the code
thought a trap with x == 0 meant there were no more traps.
2022-03-04 16:42:15 +02:00
Pasi Kallinen ab8a18d1f0 Unhide monster when boulder rolls away 2022-03-04 10:48:38 +02:00
Pasi Kallinen 70795fa124 Prevent monster hurtling outside map 2022-03-03 22:24:17 +02:00
Pasi Kallinen 13d85abde5 Fix uninitialized variables
... as found by valgrind
2022-03-02 13:31:18 +02:00
Pasi Kallinen e83917bbf3 Unhide monster hiding under chain when unpunished 2022-03-01 16:14:07 +02:00
Pasi Kallinen 473ae4a6a0 Prevent segfault trying to make non-existent trap seen 2022-03-01 15:31:22 +02:00
Pasi Kallinen b172957831 Use macro for spell pw cost per spell level 2022-02-28 22:21:37 +02:00
Pasi Kallinen 6a65b41270 Using magic portals and level teleporters stuns for a few turns
It's taxing to teleport long distances.

Yes, this makes the entrance to the planes and the quest more
dangerous, and nerfs portal dancing Fort Ludios.
2022-02-27 11:25:58 +02:00
Pasi Kallinen 1d4d0f4b0e Use more u_locomotion
... and make it autocapitalize the first letter, just like locomotion
2022-02-27 11:07:31 +02:00
Pasi Kallinen 9e666b75f6 Make rope golem have some death drops 2022-02-26 23:46:55 +02:00
Pasi Kallinen d0f349cbd1 Use find_mid finding the leashed mon 2022-02-26 22:42:37 +02:00
Pasi Kallinen f8cb7ae0b8 Unify shopkeeper/guard/priest bit in m_move 2022-02-26 18:05:43 +02:00
Pasi Kallinen 7523623d95 Make m_move return defines instead of magic numbers 2022-02-26 17:40:17 +02:00
Pasi Kallinen 4b6b976e3b Split escaping from sticking monster check out of domove 2022-02-25 22:26:12 +02:00
Pasi Kallinen f88dce6970 Unify domove and lookaround trap/liquid avoidance code
Nearly same code was in two places - the only difference was
how g.context.run == 1 was handled.  Previously, if you were
blind, and knew about the water or lava, you still ran into it.
Now, we always avoid the dunking if running/rushing.
2022-02-25 21:52:52 +02:00
Pasi Kallinen e57c631ef9 Minor code clarification 2022-02-25 19:48:17 +02:00
Pasi Kallinen 86bc0a2633 Split movement out of bounds check out of domove 2022-02-25 18:33:50 +02:00
Pasi Kallinen 4e11a85fb7 Split carrying too much check out of domove 2022-02-25 18:12:55 +02:00
Pasi Kallinen 2012254c39 Split impaired movement code out of domove 2022-02-25 17:06:25 +02:00
Pasi Kallinen 7733cbe399 Split water turbulence code out of domove 2022-02-25 16:59:52 +02:00
Pasi Kallinen 7a29110514 Split ice fumbling code out of domove 2022-02-25 16:43:09 +02:00
Pasi Kallinen 1cc79b7156 Wizard-mode wishing for (melting) ice 2022-02-25 16:42:08 +02:00
Pasi Kallinen cb5ca657ed Split air turbulence code out of domove 2022-02-25 16:13:27 +02:00
Pasi Kallinen d617875a82 Split force-fighting empty square out of domove 2022-02-25 15:19:51 +02:00
Pasi Kallinen 48cd81dbfd Split swapping places with pet code out of domove 2022-02-25 15:09:56 +02:00
Pasi Kallinen f44a4b0485 Change unknown mintrap result into impossible 2022-02-25 14:57:03 +02:00
Pasi Kallinen 3b521aa955 Split force-fight iron bars code out of domove 2022-02-25 14:54:33 +02:00
Pasi Kallinen 57f55f5ca6 Split some code out of domove
Should have no change in behaviour.
2022-02-25 14:46:45 +02:00
Pasi Kallinen 6fa4fd46f7 Move output delay from walk_path to mhurtle_step
... in case walk_path is ever used for something that
doesn't need the delay.  The hero hurtling already had
delay, so it was done twice.
2022-02-24 19:50:37 +02:00
Pasi Kallinen 0c20bf116c Moving a monster with telekinesis hurles it through the air
... and at the end of the flight, it can't avoid a trap, if it
lands on one.
2022-02-24 19:27:59 +02:00
Pasi Kallinen 9ae2ec1f98 Most traps now require touching the floor to trigger
It was silly how some clearly mechanical traps didn't consider
flight or levitation when to trigger.  Do those checks in dotrap/mintrap
making hero and monster trap triggering match more closely.
2022-02-24 18:55:14 +02:00
Pasi Kallinen 2777f45bd5 Get rid of force_mintrap, allow passing flags to mintrap
It uses the same flags as dotrap, so simulate force_mintrap
by passing FORCETRAP flag.
2022-02-24 17:13:23 +02:00
Pasi Kallinen 9716f22851 Make trap return values more consistent
Instead of returning monster's mtrapped-state, return specific
trap return values.
Add one extra trap return value, for when a monster was
moved by the trap.
2022-02-24 16:24:02 +02:00
Pasi Kallinen 547f6e9244 Remove forced trap activation from mhurtle 2022-02-24 15:18:00 +02:00
Pasi Kallinen 16a8caac97 Allow using #wiztelekinesis on yourself 2022-02-24 15:10:39 +02:00
Pasi Kallinen 8e91320d2f Use u_at macro 2022-02-23 20:28:55 +02:00
Pasi Kallinen 645720d1bc Fix the force_mintrap 2022-02-23 19:11:32 +02:00
Pasi Kallinen 9ad1e7e620 Hurtling monster always triggers a trap 2022-02-23 18:59:57 +02:00