Commit Graph

402 Commits

Author SHA1 Message Date
nhmall
1dbba0f63b rename IS_ROCK() macro to IS_OBSTRUCTED()
It has included trees since they were added, so give it a
more fitting name.
2024-11-09 11:12:42 -05:00
Pasi Kallinen
f12635ccd9 Prevent monster generation in the sokoban trap hallway
Makes Sokoban far less tedious when you don't have to worry about
monsters randomly popping up in the trap hallway while you're pushing
the boulder.

Adds a new exclusion zone for monster generation, and the goodpos
routine avoids the zones when GP_AVOID_MONPOS is used.
2024-10-18 13:30:51 +03:00
Pasi Kallinen
9e4b2c121b Improve the exclusion zone code
I forgot to add the code to flip the exclusion zones when implementing them.
Also improve the zone coordinates so they're correct outside of map contents.
2024-10-17 12:34:06 +03:00
PatR
993c3b303f some reformatting (4 of 4) 2024-09-05 16:49:42 -07:00
nhmall
6c0ae092c6 distinguish global variables that get written to savefile
The g? structs had a mix of variables that were written to
the savefile, and those that were not.

For better clarity and to distinguish those that end up in
the savefile, relocate some g? variables that get written
directly to the savefile into different structs.

This updates EDITLEVEL, although technically it probably
didn't need to, since savefile contents are not changing.

Details:

    gb.bases            -> svb.bases
    gb.bbubbles         -> svb.bbubbles
    gb.branches         -> svb.branches
    gc.context          -> svc.context
    gd.disco            -> svd.disco
    gd.dndest           -> svd.dndest
    gd.doors            -> svd.doors
    gd.doors_alloc      -> svd.doors_alloc
    gd.dungeon_topology -> svd.dungeon_topology
    gd.dungeons         -> svd.dungeons
    ge.exclusion_zones  -> sve.exclusion_zones
    gh.hackpid          -> svh.hackpid
    gi.inv_pos          -> svi.inv_pos
    gk.killer           -> svk.killer
    gl.lastseentyp      -> svl.lastseentyp
    gl.level            -> svl.level
    gl.level_info       -> svl.level_info
    gm.mapseenchn       -> svm.mapseenchn
    gm.moves            -> svm.moves
    gm.mvitals          -> svm.mvitals
    gn.n_dgns           -> svn.n_dgns
    gn.n_regions        -> svn.n_regions
    gn.nroom            -> svn.nroom
    go.oracle_cnt       -> svo.oracle_cnt
    gp.pl_character     -> svp.pl_character
    gp.pl_fruit         -> svp.pl_fruit
    gp.plname           -> svp.plname
    gp.program_state    -> svp.program_state
    gq.quest_status     -> svq.quest_status
    gr.rooms            -> svr.rooms
    gs.sp_levchn        -> svs.sp_levchn
    gs.spl_book         -> svs.spl_book
    gt.timer_id         -> svt.timer_id
    gt.tune             -> svt.tune
    gu.updest           -> svu.updest
    gx.xmax             -> svx.xmax
    gx.xmin             -> svx.xmin
    gy.ymax             -> svy.ymax
    gy.ymin             -> svy.ymin

Related note:
There are some pointer variables that are heads of chains that were not
moved from 'g?' to 'sv?', because they are not actually written to the
savefile directly, but the objects/monst/trap/lightsource/timer in the
chains they point to are. That can be changed, if desired.
Examples: gi.invent, gm.migrating_objs, gb.billobjs, gm.migrating_mons,
          gf.ftrap, gl.light_base, gt.timer_base
2024-07-13 14:57:50 -04:00
Pasi Kallinen
951401e52a Allow fixed-destination teleport traps
Add a theme room with multiple visible teleportation traps
which will always teleport to specific locations in the same level.

Teleport trap change from xNetHack by copperwater <aosdict@gmail.com>.
2024-06-14 19:50:20 +03:00
nhmall
295d6e257c used, unused variables
some variables marked as unused, are now actually used
some unused variables are eliminated or commented out
2024-03-16 12:53:58 -04:00
nhkeni
9c0ed8ae63 NOSTATICFN for src/* 2024-03-14 17:41:51 -04:00
PatR
1922dd96eb theme room vampire fix
From a reddit thread:  a 'mausoleum' theme room picked a vampire for
its occupant and applied the wait-for-you strategy to it.  Hero's ESP
or monster detection showed a meditating vampire bat.  Change monster
creation by the special level loader (which also handles theme rooms)
to force such a creature into its normal vampire form.

That revealed an older bug which wouldn't have been exercized prior
to theme rooms:  a meditating vampire could and would shape change
without ceasing meditation.  Make it not shape change rather come out
of its trance.
2024-03-11 17:40:01 -07:00
PatR
76826744d7 fix analyzer complaint about get_mkroom_name()
Force the result to be non-Null.
2024-03-08 10:08:11 -08:00
nhmall
50811037f3 split some code into separate files
new .h files: hacklib.h selvar.h stairs.h

new .c files: calendar.c, getpos.c, report.c, selvar.c, stairs.c,
              strutil.c, wizcmds.c

cleanup of hacklib.c and mdlib.c

hacklib contains functions that do not have to link with the core

relocate wiz commands from cmd.c to wizcmds.c

relocate CRASHREPORT stuff to report.c

relocate getpos stuff from do_name.c to getpos.c

remove temporary struct definition from extern.h

cross-compile PRE-section split into cross-pre1.370 and cross-pre2.370

Windows sys/windows/Makefile.nmake and sys/windows/Makefile.mingw32 and
visual studio project file updates

Unix sys/unix/Makefile.src, sys/unix/Makefile.utl

populate selvar.c and selvar.h

build on MS-DOS (not cross-compile) Makefile updates
for sys/msdos/Makefile.GCC (untested)

vms updates for above (untested)
2024-03-07 11:01:04 -05:00
nhkeni
acf60063d5 Add missing prototypes for static functions to avoid warnings. 2024-02-29 10:49:53 -05:00
RainRat
a3658f85ac fix typos 2024-02-28 20:15:56 -08:00
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
70d8d9e0d1 Unify getting coords or region from lua table 2024-01-23 13:37:16 +02:00
Pasi Kallinen
2212cf27ec Lua: Allow creating gas clouds
Use the gas clouds in the Clouds themeroom.
Use the existing visible_region_at() in the vision code.
2024-01-19 17:59:43 +02:00
nhmall
25a8c258e6 replace x >= LOW_PM with ismnum(x) shorthand macro 2024-01-11 14:01:10 -05: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
86f4afa780 sp_lev.c lava tweaks
Some bits I noticed while looking for something else.
2024-01-09 00:04:43 -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
Mika Kuoppala
e6c4838161 sp_lvl: fix memory leak on lspo_region
If tutorial is entered, we get following leak on exit:

=================================================================
==81358==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 96 byte(s) in 3 object(s) allocated from:
    #0 0x7f6996edefdf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
        #1 0x5601c255bcbb in alloc /home/miku/src/NetHack/src/alloc.c:71

Indirect leak of 5064 byte(s) in 3 object(s) allocated from:
    #0 0x7f6996edefdf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
        #1 0x5601c255be1e in alloc /home/miku/src/NetHack/src/alloc.c:71
	    #2 0x5601c255be1e in dupstr /home/miku/src/NetHack/src/alloc.c:236

SUMMARY: AddressSanitizer: 5160 byte(s) leaked in 6 allocation(s).

Fix this by freeing the cloned selection before returning.
2023-12-17 11:47:26 +02:00
nhmall
3cfd579d37 init NhRect, before passing to selection_getbounds
selection_getbounds() has a check and early return.
Initialization will ensure a known state if that early return
were ever taken.

This is an alternative approach to pr #1163.
2023-12-13 00:21:32 -05:00
nhmall
ee3ebcc10d fix bug in mon.c reported by paxed
Also adds a shorthand macro
    monsym(&mons[n])
for getting the default symbol, used in the bugfix.
2023-12-06 22:18:11 -05:00
Pasi Kallinen
5dc94f3d83 Macro for picking random entry from array 2023-12-05 10:06:27 +02:00
nhmall
d064ac2cda more cast style consistency 2023-11-13 20:31:02 -05:00
nhmall
a7242760f7 consistent cast syntax 2023-11-13 19:28:19 -05:00
Pasi Kallinen
2e8adda028 Clouds cannot have engravings in them
... so delete the existing engraving if a cloud is put on the map.
2023-11-09 18:08:00 +02:00
Pasi Kallinen
16ed7e49c3 Separate level flags for premapped and sokoban 2023-10-29 12:35:32 +02:00
PatR
dd05f5183e addinv_nomerge()
Replace several instances of
 obj->nomerge = 1;
 addinv(obj);
 obj->nomerge = 0;
with new
 addinv_nomerge(obj);
and add various related comments.
2023-09-19 14:40:33 -07: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
nhmall
1c8a5d62bc suppress four new warnings
src/sp_lev.c(5348) : warning C4702: unreachable code
src/sp_lev.c(5608) : warning C4702: unreachable code
src/sp_lev.c(6281) : warning C4702: unreachable code
src/sp_lev.c(6334) : warning C4702: unreachable code
2023-07-04 23:44:36 -04:00
copperwater
0e01828ed8 Fix: when a themeroom failed, xstart/ystart weren't reset
Revealed this bug when testing the previous commit:

Themed room generation with a randomly placed map involves picking a
single random point on the map at which to plop it down, and then
declaring the themed room failed and exiting if it would go beyond the
map bounds or overlaps with an existing room. In the process,
xstart/ystart/xsize/ysize have been modified, but weren't getting reset.
(They would get reset if the map successfully got placed and it had a
contents function, as of commit 4af086b, but there wasn't handling for
the failure to place it.)
2023-07-04 16:19:28 -07:00
copperwater
2ae5ce8ab3 Fix and guard against out-of-bounds writes in splev code
I traced a memory corruption bug in xNetHack to a themed room that
looked something like this:

    function()
       des.room({ type="themed", contents = function()
          des.feature({ type='sink' })
          ...
       end })
    end

Placing a feature at a random spot within a room or region is a
reasonable thing for the parser to handle, but the code was not equipped
to handle it, and so the unspecified x and y set as -1 got passed
directly to SP_COORD_PACK, ending up as coordinates way off the map.
Since sel_set_feature does not do an isok() check, this ended up writing
data to unrelated memory.

This commit does the following things:

- Enables des.feature() with no coordinates specified, both via a table
  with 'type' set, and as the single string argument. When no
  coordinates are specified, it will pick a random normal-floor spot
  within the enclosing room or region if there is one, or anywhere
  on the level if there isn't.
- Prevents sel_set_feature from corrupting memory outside
  g.level.locations. Additionally, if EXTRA_SANITY_CHECKS is defined and
  this gets attempted, it causes an impossible.
- Guards the existing "door coord not ok" Lua error with an immediate
  return from lspo_door.
- Adds similar "coord not ok" errors to all the other locations in
  sp_lev.c which did not already check for a unspecified/invalid
  coordinate and for which a random coordinate is nonsensical:
  des.terrain(), des.drawbridge(), and des.mazewalk().
2023-07-04 16:19:27 -07:00
copperwater
cba85d2314 Allow des.object "trapped" field to be a boolean
I thought there were more object fields that currently only accept ints
but ought to accept booleans, but when I checked I found that most of
them do already, and the ones that take ints are the ones that the
number carries meaning (spe, recharged, etc).

Except for trapped. In struct obj, otrapped is a 1-bit flag, so there's no
good reason for the level parser to treat it as a type error if someone
intuitively makes a des.object call with trapped=true or trapped=false.
Change it to an optional boolean argument, like the other boolean flags
(locked, greased, etc).

Note that get_table_boolean_opt still accepts ints, so existing uses of
trapped=0 or trapped=1 won't be affected.
2023-07-04 15:38:26 -07:00
copperwater
c6fa9c3099 Fix chained selection xor and subtraction operations
Something that's reasonable to expect to see in Lua files is something
like:

    local sel4 = sel1 - sel2 - sel3

or more generally, producing a selection from subtraction that will then
be used in subsequent selection math.

I discovered this wasn't actually working correctly, and that it also
applied to the xor operation. The reason behind this is that
l_selection_sub and l_selection_xor create a new selection from nothing,
which by default has "lower" bounds of COLNO, ROWNO and "upper" bounds
of 0,0. Iterating across the intersecting rectangle of both selections
does not reliably set the bounds of the resulting selection properly,
since the first selection_setpoint with a value of 0 will cause the
selection's bounds_dirty flag to be set, at which point they will cease
to change as more points are added.

Then this selection with its incorrect boundaries is pushed back onto
the Lua stack, and becomes the first operand of the next subtraction
(i.e. selr in the first l_selection_sub becomes sela in the second
l_selection_sub). Depending on how broken the bounding box is, results
may vary, but if the bounding box is still (COLNO,ROWNO,0,0), the
resulting selection will have no points selected at all.

This fixes this problem by forcibly recalculating the bounds of the
result selection, so any subsequent operations on it will be valid.
2023-07-04 14:53:16 -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
PatR
b48cb5bcd9 sp_lev.c reformatting typo 2023-05-28 15:24:44 -07:00
PatR
3ccbfc4d6c sp_lev.c formatting 2023-05-28 00:49:53 -07:00
Pasi Kallinen
ba60bfac25 Themeroom: buried zombies
- add a themeroom with random buried zombifying corpses
- disturbing buried zombies makes them revive much faster
- lua des.object() now returns the object it created
2023-04-01 14:05:18 +03:00
Pasi Kallinen
fa0ae08f94 Lua object generation didn't obey locked state
Defining des.object({ id="large box", locked=false })
was the same as random locked state. Make it actually mean unlocked,
and not defining locked at all means random.
2023-03-19 20:13:47 +02:00
Pasi Kallinen
f360dee4dd Engraving sanity checking 2023-03-18 07:30:25 +02:00
Pasi Kallinen
aa83dadc1e Add stormy level flag
Which makes clouds create lightning bolts at random.
This flag is used on the plane of air.

Breaks saves and bones.
2023-03-17 20:13:32 +02:00
Pasi Kallinen
4799fc937a Add level flag for plane of fire fumaroles
Also reduce the size of the gas clouds.

Breaks saves and bones.
2023-03-17 19:36:00 +02:00
Pasi Kallinen
da0a681688 Make lua map and terrain commands use same routine 2023-03-17 13:25:43 +02:00
Pasi Kallinen
a5934470dd Fix boulder-on-lava sanity error
Special level creation could make levels with boulders on top
of lava or water; this was caused by mazewalk populating the maze
before the rest of the level was created.

Add a post-level-creation map cleanup routine, where boulders
and traps on liquid terrain are removed.
2023-03-17 13:13:24 +02:00
Pasi Kallinen
8e6cf385b1 Fix subroom doors
Doors weren't getting added to the correct subrooms in certain cases.

Also fix one of the themerooms, because doors have to be added
after subrooms; there was a possibility of no door to the subroom(s)
in that themeroom, because the subrooms overwrote the doors in
the parent room.

Test case for the subroom doors:

Large room, with a medium subroom, with a tiny subroom inside that.
The doors go from outermost room <-> tiny innermost room <-> middle room.

des.room({ type = "ordinary", x = 1, y = 1, w = 10, h = 10,
   contents = function()
      des.room({ type = "ordinary", w = 6, h = 6, x = 2, y = 2,
         contents = function()
            des.room({ type = "ordinary", w = 2, h = 2, x = 0, y = 0,
               contents = function()
                  des.door({ state="random", wall="south", pos = 1 });
               end
            });
            des.door({ state="random", wall="north", pos = 1 });
         end
      });
   end
});

Before this fix:

ROOM: ndoors:1, subrooms:1
  SUBROOM: ndoors:1, subrooms:1
    SUBROOM: ndoors:1, subrooms:0

after this fix:

ROOM: ndoors:1, subrooms:1
  SUBROOM: ndoors:1, subrooms:1
    SUBROOM: ndoors:2, subrooms:0
2023-03-07 09:43:44 +02:00
copperwater
69d37be878 Fix: using a selection in a lit des.region modified it
The intuitive behavior when passing a selection to des.region, e.g.

    local foo = selection.area(07,02,10,24)
    des.region(foo, "lit")

is that foo will remain unmodified for further use. However, this wasn't
the case whenever making a lit region from it, because in order to light
walls adjacent to the lit area, the selection was having a grow
transformation applied as well. (This also seems like a problem - it
grows the selection even if what is being lit is not surrounded by
walls. I added a note in lua.adoc about this behavior.)

This fixes the selection mutation by cloning the passed-in selection and
growing the clone which leaves the original one unaffected.

This should not affect any special levels currently because the only
instance of des.region being used with a selection appears to be in
bigrm-2, which specifies *unlit* areas, which did not get grown.
2023-03-01 17:32:15 +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