Commit Graph

66 Commits

Author SHA1 Message Date
PatR
dc5c098cb5 analyzer lint for n*.c 2025-01-21 19:39:35 -08:00
PatR
cc1066b1ff some reformatting (3 of 4) 2024-09-05 15:55:24 -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
nhkeni
9c0ed8ae63 NOSTATICFN for src/* 2024-03-14 17:41:51 -04:00
RainRat
a3658f85ac fix typos 2024-02-28 20:15:56 -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
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
d064ac2cda more cast style consistency 2023-11-13 20:31:02 -05:00
SHIRAKATA Kentaro
7e735d9386 remove unused assignments 2023-11-07 16:26:12 -08: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
copperwater
9d0df0c9f0 Invert the behavior of selection.gradient
selection.gradient has some pretty unintuitive behavior, in that it
selects points that are NOT close to the defined center. I've used
gradient selections several times and so far all of them have had to be
negated, because I wanted to select points close to the center with a
decreasing probability further out.

This implements that behavior, and also fixes a bug in which the x,y
coordinates of the gradient center(s) were not converted properly when
used within a des.room or des.map. Also updated the lua documentation
for gradient.

I removed the "limited" argument, as it was previously used to control
whether the rest of the map outside the max given distance would be
included in the selection; now that the area beyond maxdist is naturally
never in the selection, it doesn't have much use. (And I can't think of
a reasonable use case for the inverse: wanting to select points close to
the center, with decreasing chance towards maxdist, but then select the
entire map beyond maxdist.)

Currently this does not affect any special levels or themed rooms
because none of them use selection.gradient.
2023-02-14 09:13:59 +02:00
Pasi Kallinen
744d64487b Helltweaks: improve lava river
The lava river will now draw another river, until a certain
amount of map locations have been turned into lava, so you don't
get a teensy "river" made out of 2 lava pools.

Add a lua selection method to count the number of locations
in the selection.
2023-01-30 17:10:39 +02:00
Pasi Kallinen
4af086be73 More interesting Gehennom levels
Instead of just plain old boring mazes, spice up Gehennom by
occasionally adding lava, iron bars, or even mines-style levels
(with lava, of course).

Of the fixed Gehennom levels, only Asmodeus' lair has been changed
to add some random lava pools.

Also some lua fixes and changes:
- Fixed a selection negation bounding box being wrong.
- Fixed a selection negated and ORed returning wrong results.
- des.map now returns a selection of the map grids it touched.
- When using des.map contents-function the commands following the
  map are not relative to it.
2023-01-10 12:20:21 +02:00
Pasi Kallinen
c68b21d735 Fix lua selection logical-or bounds 2023-01-07 10:55:09 +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
nhmall
4b04b1e6ac expand support for noreturn declarations
Although gcc specifies support for declaring a function as
noreturn after the function name and parameters, other compilers
do so via an attribute at the start of the declaration. Add some
macro support for the attribute-at-the-beginning method:
  o MS Visual Studio compiler
  o Upcoming C23 standard (untested at this point)
2022-11-24 00:51:42 -05:00
Pasi Kallinen
3605f18a8e Split themeroom shape from themeroom contents
Previously, the tetris-shaped rooms were always either
normal rooms, or turned into shops or other special rooms
in NetHack core. Now, the themed room lua code first picks
the themed room (which can be a themed or shaped), and some
of those will then pick a random filling (eg. ice floor,
traps, corpses, 3 altars).

Adds a new lua binding to create a selection picking locations
in current room.

The content-function in special level regions now get passed
the room data as a parameter.
2022-09-15 18:09:40 +03:00
copperwater
f71bff3285 Standardize all core and obj functions with relative coords
This is a large iteration on a previous implementation of making
nh.getmap() parse its coordinates as relative to the last defined map or
room rather than absolute to the entire level. Now, everything in the
nh.* and obj.* functions interprets coords as relative rather than
absolute. (By default; if no map or room has been defined, or if the lua
code is executing after level creation is done, they will interpret the
coordinates as absolute).

The general motivation is basically the same - routines that use
absolute coordinates are difficult to use in level creation routines,
because then the designer has to remember to convert the relative
coordinate to an absolute one (and that was impossible before
nh.abscoord was added, particularly in themed rooms). And once
nh.getmap() takes relative coordinates, it would be very strange to have
all the other functions (setting timers, burying objects, etc) remain
with absolute ones.

In a couple places, code is changed to account for coordinates that are
relative to a *room* (which uses g.coder->croom->[lx,ly] as an offset,
instead of relative to a *map*, which uses [xstart,ystart].
Specifically, selection.iterate did not account for this, and without
this the ice themed room timer was not being started in the proper
place.

All tests are updated to respect the new behavior. Most of the modified
functions are not actually used anywhere in level files; the one
exception is starting a timer in a themed room, and that has been
adjusted.

Documentation updated as well to clarify when various things are tossing
around relative and absolute coordinates, both in comments and in
lua.adoc.
2022-08-31 18:26:05 +03:00
Pasi Kallinen
723ee6d1f6 Expose selection bounds to lua 2022-08-26 13:07:52 +03:00
Pasi Kallinen
5e9ed7a290 Some selection optimizations
- Add bounds, so that we don't process any locations outside
  as those locations are known to be unset
- The bounds are only recalculated if needed
- Replace instances of selection_not where we actually want
  a new selection with all locations set
2022-08-26 12:43:40 +03:00
Pasi Kallinen
3a255e86c4 Some lua selection userdata code cleanup 2022-08-23 17:34:29 +03:00
Pasi Kallinen
d39b2f3a23 Remove extra definitions 2022-08-23 16:52:05 +03:00
Pasi Kallinen
4cfefb056a Clear or copy whole selectionvar 2022-08-23 14:39:39 +03:00
nhmall
3004cf2d34 be more consistent with coordinates 2022-07-02 09:10:03 -04:00
nhmall
30b557f7d5 change xchar to other typedefs
One of the drivers of this change was that screen coordinates require a
type that can hold values greater than 127. Parameters to the window
port routines require a large type in order to be able to have values
a fair bit larger than COLNO and ROWNO passed to them, particularly for
their use to the right of the map window.

This splits the uses of xchar into 3 different situations, and adjusts
their type and size:

                        xchar
                          |
               -----------------------
               |          |          |
            coordxy     xint16     xint8

coordxy: Actual x or y coordinates for various things (moved to 16-bits).

xint16:  Same data size as coordxy, but for non-coordinate use (16-bits).

xint8:   There are only a few use cases initially, where it was very
         plain to see that the variable could remain as 8-bits, rather
         than be bumped to 16-bits.  There are probably more such cases
         that could be changed after additional review.

Note: This first changed all xchar variables to coordxy. Some were
reviewed and got changed to xint16 or xint8 when it became apparent that
their usage was not for coordinates.

This increments EDITLEVEL in patchlevel.h
2022-06-30 23:48:18 -04:00
Rebecca Kelly
78658e9609 patch from ToxicFrog 2022-05-31 19:09:52 -04:00
nhmall
a8f0e91ddf replace leading tabs in several files 2022-05-30 12:09:35 -04:00
nhkeni
6bd2172ba7 Lua sandbox
This is enough to prevent abuse by denying access to functions and
    denial of service (RAM and instruction step limits), but not enough
    to allow restricted use of things that require finer control (e.g.
    filesystem access).

    If something goes wrong, the whole thing can be turned off, for
    now, in config.h (see NHL_SANDBOX).

    None of the current functionality requires changes to build systems;
    some of the possible future functionality may require some #defines
    - TBD.  There is lots of dead code (#ifdef notyet) for bits of that
    additional functionality; we can rip it out if we don't want those
    additions or we can complete (parts of) it depending on our needs.

    All current uses of Lua are connected to sandboxes and guarded with
    nhl_pcall (sandbox and lua_pcall wrapper); options and limits can
    be set at the callsites in the passed nhl_sandbox_info.  Some of
    the error handling may be wrong - panic() vs.  impossible() vs
    silence.

    Memory and instruction step limits should be tuned prior to release;
    there's no point tuning them now.
2022-04-29 19:46:33 -04: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
copperwater
cc04bf9d8f Fix selection "random" grow direction, and other code cleanup
Noticed that when I set a selection to grow in a random direction, it
instead grew in all directions, which is not what I wanted. Turns out
the -1 random dir ended up being passed straight to the code which
checks bitmasks, without any form of randomizing among directions.

So this adds code to do that, and defines W_RANDOM as -1 rather than
using a magic number. In the process I also noticed that specifying
"random" as the wall for a door in a room made it rerandomize the
direction every iteration of its loop, essentially rolling two rn2(4)s
and only proceeding if they matched. That was pointless so I cleaned it
up a bit.

Also added safety checks in the form of an impossible for des.corridor()
being called with "random" as either walldir, because this is not
implemented currently.

And lastly, I noticed that create_secret_door was entirely unused
(secret door creation is handled in create_door), so I deleted it.

The only behavior change caused by this is that the Valkyrie quest lava
pools will be a little smaller, which is the only place grow is
currently used. If it's desired to keep them the same, that should be
changed to "all".
2022-03-15 07:44:56 +02:00
copperwater
b4a460f81b Implement selection addition and difference
Selection difference is something I have found myself wanting a lot when
working on levels, and have had to defer to a clunkier xor-then-and
approach. This commit implements the TODO-ed addition and subtraction
operators on two sets.

I don't see how the addition operator would be any different from
logical or, so it just calls l_selection_or rather than implement a new
function.
2022-03-14 18:42:28 +02:00
Pasi Kallinen
f43bfc3f71 Lua: diagonals for selection floodfill 2021-08-15 13:50:28 +03:00
nhmall
5bd95649de fix some warnings seen by Microsoft Visual Studio compiler
../src/nhlsel.c(467) : warning C4701: potentially uninitialized local variable 'x1' used
../src/nhlsel.c(591) : warning C4701: potentially uninitialized local variable 'x' used
../src/nhlsel.c(467) : warning C4701: potentially uninitialized local variable 'y1' used
../src/nhlsel.c(591) : warning C4701: potentially uninitialized local variable 'y' used
../src/nhlsel.c(469) : warning C4701: potentially uninitialized local variable 'x2' used
../src/nhlsel.c(469) : warning C4701: potentially uninitialized local variable 'y2' used
2021-01-28 09:45:16 -05:00
nhmall
f963c5aca7 switch source tree from k&r to c99 2021-01-26 21:06:16 -05:00
Pasi Kallinen
deb730d9b5 More hypothetical type mismatches 2020-11-15 13:51:47 +02:00
Pasi Kallinen
289c8d654d Futureproofing hypothetical type mismatches
If we ever want huge maps with COLNO or ROWNO larger than signed char,
this will at least allow the game to compile and start when typedef'ing
xchar to int. Trying to use huge maps exposes more bugs.
2020-11-14 13:53:09 +02:00
Pasi Kallinen
47fb7e5ee5 Fix double free 2020-04-12 16:55:00 +03:00
copperwater
0befdbfd02 Re-implement gradient selections
Uncomments and makes available selection.gradient in Lua. (The backend C
code for this still existed, it just wasn't used.)

The only valid way to specify a gradient is with a table. I considered
adding non-table versions, but decided that there are too many
independent variables that can be optional. A non-table version, without
named parameters, would be confusing to read, especially since most of
the arguments are ints.

Also adds an impossible in the (possibly unreachable) case that
selection_do_gradient gets called with a bad gradient type.
2020-04-06 18:54:39 +03:00
Pasi Kallinen
e215f09ddb Fix even more warnings 2020-04-06 13:34:07 +03:00
Pasi Kallinen
ac2b34654f Fix lua selection error
There was a rare selection bug where selection was freed by the gc
but it was still in use. Don't remove the selections from the stack
while we're handling them.
2020-03-31 19:11:49 +03:00
nhmall
7902bacf70 build fix for vs2019
src\nhlsel.c(604) : error C4703: potentially uninitialized local pointer variable 'mf' used
2020-03-03 18:34:27 -05:00
Pasi Kallinen
c9b21e36a7 Add lua selection match method
Also improve the replace_terrain command parameters.
2020-03-02 16:17:53 +02:00
Pasi Kallinen
7a54edf91f Implement lua selection iteration
... and showcase it by dehardcoding the Fort Ludios treasury.
2020-02-26 17:25:28 +02:00
PatR
19df82971d fix nhlsel.c warning
A recent change has resulted in complaints about 'sel' not being
used in
  struct selectionvar *sel = l_selection_check(L, 1);
  struct selectionvar *ret;
  int p = (int) luaL_checkinteger(L, 2);

  lua_pop(L, 1);
  (void) l_selection_clone(L);
  ret = l_selection_check(L, 1);
  selection_filter_percent(ret, p);

This preserves the semantics of that code while getting rid of the
warning, but I have no idea whether it makes any sense.
2020-02-25 16:04:41 -08:00
Pasi Kallinen
dc70132da8 Change lua selection floodfill and add some tests 2020-02-22 18:35:41 +02:00
Pasi Kallinen
fe3dae85d5 Make lua selection filter_mapchar create a new selection 2020-02-22 17:51:29 +02:00
Pasi Kallinen
50eaf95c27 Make lua selection grow create a new selection 2020-02-22 16:58:45 +02:00
Pasi Kallinen
6648ecfe04 Make lua selection randline create a new selection 2020-02-22 16:34:50 +02:00
Pasi Kallinen
b3f337bdf6 Make lua selection rect and fillrect create a new selection 2020-02-22 15:23:30 +02:00