Commit Graph

188 Commits

Author SHA1 Message Date
nhmall
688ac6ffbe remove register from variable declarations 2024-02-19 16:30:07 -05:00
Pasi Kallinen
2952bdab63 No secret doors or corridors on the early levels
New players often get stuck on the first level when they can't
find the secret door or corridor.  Make the first two levels
have no such features.
2024-02-18 11:47:02 +02:00
Pasi Kallinen
0d7fc06eb9 Do garbage collection on luacore
Another lua state that is not freed until end of game,
so clean up the stack and do GC regularly.
2024-02-03 12:55:10 +02:00
Pasi Kallinen
95e42bf692 Split out random trap type picking 2024-01-29 20:10:07 +02:00
PatR
524ae27c99 fake trap deaths
Eliminate the 'goto' for human corpse added a day or two ago.

If a dead gnome is generated with a candle, light it if/when the spot
is dark.  (Testing never managed to verify that this works as intended.)

mkcorpstat() never returns Null.
2024-01-26 12:52:52 -08:00
PatR
ec4691a859 fewer human corpses
When a low-level trap is created with a dead pseudo-adventurer,
usually make a player monster when the human case gets picked.

They have default level and no inventory.  They should probably be
given montraits that force low level but this doesn't do that.
2024-01-25 14:12:05 -08:00
PatR
1d165f20ee supply_chest fix fix
Reordering some tests to put the cheapest one first accidentally
removed a negation, unintentionally changing the semantics.
2024-01-23 16:52:39 -08:00
PatR
267daeaa0f supply chest fixes for "odd encumbrance behavior"
Changing the quantity to 2 (50:50 chance) when creating a potion of
healing (also 50:50 chance for each attempt) to place inside a supply
chest wasn't updating the potion stack's weight, resulting in the odd
encumbrance behavior that was reported last December.

Taking the stack out of the container doesn't fix the weight but
drinking one of the potions splits the stack of 2 into two stacks
of 1 and does update the weight for both.  That gives the hero higher
encumbrance when the formerly weightless one has its proper weight.
Finishing drinking the potion uses it up, removing second potion's
weight again.  When below an encumbrance threshold by the weight of
one potion or less, player will see encumbrance increase and then
decrease, with healing message given before both due to sequencing.

Supply chests weren't having their own weight updated when they were
populated, so would behave as if empty if hero carried them around.
Removing something, breaking something by kicking the chest, or adding
something would update its weight to match its contents.

I also noticed a refutation (or should that be rebuttable?) to my own
remarks in this:

| commit cd91d0630b
| Author: PatR <rankin@nethack.org>
| Date:   Sat Dec 30 17:10:39 2023 -0800
|
| github issue #1180 - humans and murder
|
| Issue reported by Umbire:  reviving a human corpse into a human
| monster and then killing it entails murder penalty even when it is
| hostile.
|
| This is probably a non-issue.  Human monsters tend to not leave
| human corpses, they leave shopkeeper corpses or sergeant corpses
[...]

Dead fake hero corpses placed at trap locations on early levels are
leaving plain human|dwarf|elf|gnome|orc corpses rather than fake
player monster ones (which are always human but resurrect as player
monsters rather than as plain humans), so there are more plain human
corpses now than there were in 3.6.x or early to-be-3.7.  I've added
a comment about the situation.
2024-01-23 15:42:19 -08:00
Pasi Kallinen
5d28e24477 Some lua state allocator fixes
Run GC on the themeroom lua states, as they're not freed
until end of game.

Allocate the exact amount of data we use instead of padding it.

Free our state data after closing the lua state; doing it
the other way is the way to madness, which was kept at bay
by the padded allocation amount.
2024-01-17 17:41:44 +02:00
PatR
3f3d5b7bda mktrap() flags
This started out as a fix for a comment typo, then morphed a bit....
2024-01-09 17:17:19 -08:00
PatR
d672ea3051 remove redundant mktrap() tests
The 'tm' and 'croom' ?: tests introduced to this sprintf() a couple
of days ago will both always yield their else clause because execution
will only get into the block when they're Null (due to
  if (!tm && !croom && ...) {}
that isn't visible in the diff's context).
2024-01-09 16:36:50 -08:00
PatR
3a8971cc17 more invocation handling
While testing the wall crumbling message TODO yesterday, I saw a
case where the top line of the moat around the invocation area was
truncated even through there were 3 lines of map (on a cavernous
level rather than maze one) above where it cut off.  This improves
things although it may not be 100% correct.

Picking the invocation position is unchanged, so there should be no
risk of it now being positioned too close to the map edge.  It's
possible that it has been farther away from the edge than necessary
though; if so, it will still be.
2024-01-09 12:07:24 -08:00
PatR
0333495b8b DO mkinvokearea() TODO
When performing the invocation, you would get
|The floor shakes violently under you!
|The walls around you begin to bend and crumble!
even if all the nearby walls had been dug away or the level's maze was
made of lava pools instead of walls.  Suppress the second message when
it isn't applicable.
2024-01-09 00:41:35 -08:00
PatR
9cb270d4ca mktrap() sanity-adjacent
Log an error if the argument combination passed to mktrap() will never
place a trap.  Based on the code being used in the latter part of the
routine.
2024-01-09 00:24:51 -08:00
nhkeni
c7ab9a0565 Some lua catchup and cleanup
- add nhl_pcall_handle() to wrap all nhl_pcall calls that didn't check
  return value and either panic() or impossible()
- add --loglua (unix only) to dump Lua memory and steps info to livelog
- remove old logging
- set memory and step limits on all Lua VMs
2024-01-04 10:37:38 -05:00
nhmall
d123cd77d1 static analyzer bit in mklev.c
src/mklev.c(137): warning: Using uninitialized memory 'ri'.

There was a for-loop assigning values to some elements of
ri[], but not all of them.

Initialize the array.
2023-12-22 22:02:18 -05:00
nhmall
a03a614883 include assert.h in cstd.h
Three src files already were including it, and another was
about to be added, so include it in include/cstd.h.
2023-12-22 19:24:09 -05:00
PatR
1bb8544303 even more mklev.c
This should eliminate the last analyzer complaint about maybe using
a Null pointer.  I didn't notice this one yesterday.
2023-12-17 11:02:30 -08:00
PatR
3d27d8e998 more mklev.c
This got accidentally omitted from the previous patch.  The
clear_level_structures() prototype is in extern.h.
2023-12-16 18:43:39 -08:00
PatR
f2671fd1a7 mklev.c: somexyspace() revisited
Replace one recenly added 'croom' test with assert(croom != NULL);
keep the other one.  Mark fill_ordinary_room() as requiring that its
first argument be non-Null.  Check for malformed subroom data before
calling it.

Plus miscellaneous reformatting.
2023-12-16 18:38:29 -08:00
nhmall
3e83d23b19 skip calling somexyspace() if mkroom ptr is NULL 2023-12-16 18:30:35 -05:00
PatR
ae80e7db47 fix analyzer complaints about Knox level
Fix some of the extreme verbosity for null vs non-null triggered
by mklev.c.  dungeon_branch() never returns Null.

'#include <assert.h>' should probably be moved out of multiple .c
files and into cstd.h or some such but this doesn't do that.
2023-12-16 13:26:17 -08:00
Pasi Kallinen
20b91270ba Fix wrong level flags in mazes below Medusa
The mazes between Medusa and the Castle had couple wrong default
level flags, because those levels don't go through the special
level routines.
2023-12-08 14:10:12 +02:00
PatR
c41cb1a7fa source reformatting
Fixup some of the inconsistently formatted code that has been
introduced recently or been building up for a while.  Done manually.
I wasn't systematic except for looking for lines ending in '&' or '|'
(which wouldn't find such things if they're followed by a comment)
so there might be lots more.  I changed a bunch of C++-style //...
comments to old style C /*...*/ so that they'll match the rest of
the core's code rather than because they shouldn't be used.
2023-12-08 00:30:10 -08:00
PatR
5186af22c7 another MONITOR_HEAP bit
Another instance of freeing a null pointer.
2023-12-07 18:31:56 -08:00
Pasi Kallinen
5dc94f3d83 Macro for picking random entry from array 2023-12-05 10:06:27 +02:00
Alex Smith
fe2d8faed9 Fix for use-after-free in supply chest generation 2023-12-03 00:50:28 +00:00
Alex Smith
ae3e5d281f Add bonus items to some early-game Dungeons levels
These are primarily in chests (apart from one guaranteed good food
item on the Mines branch level), and are quite likely to be potions
of healing, although other items that are useful for early-game
survivability are also possibilities.

This is part of a series of commits that aim to make the early game
less about waiting to heal up and more about pressing forwards. In
particular, this means that characters need likely access to
healing sources other than waiting/backtracking/hiding in closets.
In a future commit, I plan to make permafood generate primarily
through exploration (rather than drops from monsters) in order to
deter waiting around or grinding; the early guaranteed food drop is
present to give the more nutrition-intensive characters (e.g. orc
wizard or vegetarian Monk) a fair chance to reach the more abundant
food sources in Minetown or Sokoban.
2023-12-02 08:18:01 +00:00
Alex Smith
99141b3242 Add magic traps to the list of traps marked with victims early
These can generate on dlvl1 and be immediately fatal, so should be
marked to prevent near-unavoidable early game instadeaths.
2023-11-23 16:34:47 +00:00
Pasi Kallinen
c44906b28e Put random room engravings on room locations only
Another case of engraving going on a cloud.
2023-11-10 20:08:45 +02:00
Pasi Kallinen
e407af4477 Allow defining random-teleport exclusion zones in lua
Adds a new lua command

  des.exclusion({ type = "teleport", region = { x1,y1, x2,y2 } });

which allows defining "exclusion zones" in the level, areas where
random teleports (or falling into the level) will never place the hero.
Does not prevent targeted teleportation into the area.

Breaks saves and bones.
2023-08-24 18:38:39 +03:00
PatR
7ea091048c count_level_features() bit
The relatively recent code to recalculate the number of fountains and
sinks on a level was including column 0.  levl[*][0] is not used for
the map.
2023-08-12 15:01:02 -07:00
PatR
8d60b92407 cleanup when exiting tutorial
When returning to play from within the tutorial, remove the level files
similar to how they're discarded for the rest of the dungeon when going
into the endgame.  It turned out to be a bit messier than anticipated.

The dungeon.c bit is sufficient for #overview, which now hides regular
level 1 while in the tutorial and hides all tutorial levels once exited.
Those will still appear in end-of-game disclosure.
2023-07-17 14:27:28 -07:00
PatR
60a3263a85 fix github issue #1070 - Minetown achievement
Issue reported by vultur-cadens:  arriving on the Mine Town level
via falling or level teleport won't register the "entered Minetown"
achievement if hero doesn't arrive inside a room.

Reorder some code in check_special_room() so that town entry will be
tested before the early return if no room entry has occurred.  This
adds 'level.flags.has_town' to make the town test be cheaper when
the hero hasn't attained the achievement yet and is wandering around
the mines.

Fixes #1070
2023-07-06 13:18:19 -07:00
PatR
bf47cc878e fountain and sink bookkeeping
This replaces most of commit 0ca2af4d8b
from a couple of days ago with something more robust.  That change
actually introduced redundant code that caused fountain and/or sink
count to be off instead of preventing it.

Revise set_levltyp() to update level.flags.nfountains and
level.flags.nsinks if setting the type to or from fountain or sink.
A bunch of places that were setting levl[x][y].typ directly needed
to be revised to use set_levltyp() instead.  set_levltyp() itself
hadn't been updated to handle LAVAWALL (to force such to be lit).
2023-06-12 15:07:34 -07:00
nhmall
826ce951e7 get rid of NetHack macro conflict with curses routine delay_output() 2023-04-21 08:25:53 -04:00
Pasi Kallinen
6fcce6e135 Redo the portal breakage for the fuzzer 2023-04-17 11:09:58 +03:00
Pasi Kallinen
51ebfb2f0b Fix tutorial breaking other portals 2023-04-15 13:25:43 +03:00
Pasi Kallinen
ad4c71fab3 Avoid placing random niches into subroom walls
Wizmode testing shop generation, I encountered impossible
"Where is shopdoor" - the room that was being turned into
a shop had a subroom sharing the outer south wall with
the parent room, with a random niche placed such that it was
actually in the subroom wall. The niche door was still added
to the parent room, and the shop generation was trying to use
that door as the shop entrance.

As random niches are only used in room-and-corridor style
levels, subrooms aren't that common, so I just opted to
skip the niche generation if it was going to be placed
without being directly attached to the room it wanted.

The niche generation could be changed at a later date to actually
add the niche door to the correct room instead, if we ever feel
it's necessary to have random niches in subrooms.

As an interesting side note, I had no idea random niches were
only placed in the south or north walls of rooms, never to
east or west.
2023-04-13 18:50:31 +03:00
Pasi Kallinen
f3d457dbd4 Split trap victim generation into separate function 2023-03-19 10:06:50 +02:00
Pasi Kallinen
e37428d5cd Fix fuzzer teleporting out of Fort Ludios 2023-03-18 08:51:37 +02:00
Pasi Kallinen
c6a2803f49 Better algo for picking a room to put stairs in 2023-03-04 18:04:38 +02:00
Pasi Kallinen
fc7a32b86e Tutorial level
Add a tutorial level to teach commands to new players.
Very much a WIP.

Breaks save and bones compat.
2023-03-01 14:00:29 +02:00
Pasi Kallinen
00c756ba75 Lua: Traps without victims
Traps may get corpses generated on them on early dungeon levels,
to warn off fragile starting heroes. Allow creating traps in lua
without the corpse.
2023-02-25 18:05:09 +02:00
Pasi Kallinen
8eb3b3d8d1 Silence valgrind uninitialized bytes complaints
Just zero out the allocated memory.

Explicitly setting struct field values isn't enough, because field alignment
means there can be several unused bytes which are written to savefile.
2023-01-07 13:25:07 +02:00
nhmall
02a48aa8cf split g into multiple structures
The consolidation of global variables from scattered source
files into decl.c and declared in decl.h was begun in 3.7.0.
Their placement in common files was done for centralized
initialization and potential re-initialization during a
"play again" scenario.

It wasn't really necessary for all of them to be housed in a
single huge structure to meet the "play again" requirement,
and the single huge structure has been a little unwieldy when
it comes to maintenance.

Following this commit, instead of one single extremely large structure
named 'g' to house all of the relocated global variables, they
are distributed into several ga through gz.

To make things easy for the developer, each variable is placed
into the struct corresponding to the starting letter of the variable.
That way, no lookup is required in order to know which struct houses
a particular variable, it is a simple match to the starting letter
for all the centralized global variables.

A global variable named 'amulets', would be found in ga.
    ga.amulets
     ^ ^
A global varable named 'move', would be found in gm.
    gm.moves
     ^ ^
A global variable named 'val_for_n_or_more' would be found in gv.
    gv.val_for_n_or_more
     ^ ^
A global variable named 'youmonst' would be found in gy.
    gy.youmonst
     ^ ^
2022-11-29 21:53:21 -05:00
SHIRAKATA Kentaro
0d441b0c2f remove the code to silence lint
Warning facilities on recent compilers are incredibly improved,
so the code to silence "good-old" lint is much less sense.
2022-11-19 00:49:11 -08:00
Michael Meyer
d1f4e7df85 Fix: IS_SUBROOM_INDEX range
The macro (currently unused, I think) for checking whether a particular
index designates a subroom was off by one on the maximum allowable
value.

Because of the dedicated extra space for the g.rooms array terminator
flag (hx == -1), subroom indices in g.rooms are set out in the range
[MAXNROFROOMS+1, MAXNROFROOMS*2], inclusive.

Also some minor formatting tweaks.
2022-09-28 14:11:05 -07:00
Pasi Kallinen
bb3dc379bc Themerooms: Engraving hints the location of buried treasure
Add two new themeroom functions that are called when generating
the level: pre_themerooms_generate and post_themerooms_generate,
calles before and after themerooms_generate.

Allow the buried treasure -themeroom to put down an engraving
anywhere on the level, hinting at the location of the treasure.

des.object contents function now gets the generated object passed
to it as a parameter.
2022-09-18 12:45:16 +03:00
Pasi Kallinen
a733004912 Remove the per dungeon level door limit
Number of doors in a room-and-corridor style level was fixed
at 120; now the doors-array is dynamically allocated when needed.

Breaks saves and bones.
2022-09-09 19:40:45 +03:00