Standardize all core and obj functions with relative coords · NetHack/NetHack@f71bff3 · GitHub
Skip to content

Commit f71bff3

Browse files
copperwaterpaxed
authored andcommitted
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.
1 parent a30a45b commit f71bff3

9 files changed

Lines changed: 138 additions & 67 deletions

File tree

‎dat/themerms.lua‎

Lines changed: 1 addition & 2 deletions

‎doc/lua.adoc‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66

77
Functions exposed from the NetHack core. They are all in the `nh` table.
88

9+
All core functions involving xy coordinates interpret these as relative to the
10+
last defined map or room.
11+
912
=== abscoord
1013

11-
Convert a room-relative coordinate to map-absolute.
14+
Convert a room- or map-relative coordinate to absolute.
1215
Can accept one table with x and y keys (and in that case, returns similar),
1316
or two integer values (and returns two integer values)
14-
des-routines tend to use relative coordinates, nh and obj use absolute.
15-
(This mess is still very much in need of improvement.)
17+
des, nh, and obj routines all treat inputs as relative coordinates, but this is
18+
here in case an absolute one is needed for some reason (debugging?).
1619

1720
Example:
1821

@@ -385,6 +388,9 @@ Example:
385388

386389
Functions for creating special levels. They are in the `des` table.
387390

391+
All special level functions involving xy coordinates interpret these as relative
392+
to the last defined map or room.
393+
388394
=== altar
389395

390396
Create an altar of certain type and alignment.

‎include/extern.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2610,6 +2610,8 @@ extern void selection_do_gradient(struct selectionvar *, long, long, long,
26102610
extern int lspo_reset_level(lua_State *);
26112611
extern int lspo_finalize_level(lua_State *);
26122612
extern boolean get_coord(lua_State *, int, lua_Integer *, lua_Integer *);
2613+
extern void cvt_to_abscoord(coordxy *, coordxy *);
2614+
extern void cvt_to_relcoord(coordxy *, coordxy *);
26132615
extern int nhl_abs_coord(lua_State *);
26142616
extern void update_croom(void);
26152617
extern const char *get_trapname_bytype(int);

‎src/nhlobj.c‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,8 @@ l_obj_at(lua_State *L)
363363

364364
x = (coordxy) luaL_checkinteger(L, 1);
365365
y = (coordxy) luaL_checkinteger(L, 2);
366+
cvt_to_abscoord(&x, &y);
367+
366368
lua_pop(L, 2);
367369
(void) l_obj_push(L, g.level.objects[x][y]);
368370
return 1;
@@ -386,6 +388,8 @@ l_obj_placeobj(lua_State *L)
386388

387389
x = (coordxy) luaL_checkinteger(L, 2);
388390
y = (coordxy) luaL_checkinteger(L, 3);
391+
cvt_to_abscoord(&x, &y);
392+
389393
lua_pop(L, 3);
390394

391395
if (lobj_is_ok(lo)) {
@@ -569,6 +573,7 @@ l_obj_bury(lua_State *L)
569573
} else if (argc == 3) {
570574
x = (coordxy) lua_tointeger(L, 2);
571575
y = (coordxy) lua_tointeger(L, 3);
576+
cvt_to_abscoord(&x, &y);
572577
} else
573578
nhl_error(L, "l_obj_bury: Wrong args");
574579

@@ -617,7 +622,7 @@ l_obj_register(lua_State *L)
617622
luaL_setfuncs(L, l_obj_meta, 0);
618623
/* metatable.__index points at the object method table. */
619624
lua_pushvalue(L, -2);
620-
lua_setfield(L, -2, "__index");
625+
lua_setfield(L, -2, "__index");
621626

622627
/* Don't let lua code mess with the real metatable.
623628
Instead offer a fake one that only contains __gc. */

‎src/nhlsel.c‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,10 @@ l_selection_gradient(lua_State *L)
839839
return 1;
840840
}
841841

842-
/* sel:iterate(function(x,y) ... end); */
842+
/* sel:iterate(function(x,y) ... end);
843+
* The x, y coordinates passed to the function are map- or room-relative
844+
* rather than absolute, unless there has been no previous map or room defined.
845+
*/
843846
static int
844847
l_selection_iterate(lua_State *L)
845848
{
@@ -854,9 +857,11 @@ l_selection_iterate(lua_State *L)
854857
for (y = rect.ly; y <= rect.hy; y++)
855858
for (x = max(1,rect.lx); x <= rect.hx; x++)
856859
if (selection_getpoint(x, y, sel)) {
860+
coordxy tmpx = x, tmpy = y;
861+
cvt_to_relcoord(&tmpx, &tmpy);
857862
lua_pushvalue(L, 2);
858-
lua_pushinteger(L, x - g.xstart);
859-
lua_pushinteger(L, y - g.ystart);
863+
lua_pushinteger(L, tmpx);
864+
lua_pushinteger(L, tmpy);
860865
if (nhl_pcall(L, 2, 0)) {
861866
impossible("Lua error: %s", lua_tostring(L, -1));
862867
/* abort the loops to prevent possible error cascade */

‎src/nhlua.c‎

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ void
172172
nhl_error(lua_State *L, const char *msg)
173173
{
174174
lua_Debug ar;
175-
char buf[BUFSZ];
175+
char buf[BUFSZ*2];
176176

177177
lua_getstack(L, 1, &ar);
178178
lua_getinfo(L, "lS", &ar);
@@ -389,6 +389,7 @@ nhl_gettrap(lua_State *L)
389389
}
390390
x = (coordxy) lx;
391391
y = (coordxy) ly;
392+
cvt_to_abscoord(&x, &y);
392393

393394
if (isok(x, y)) {
394395
struct trap *ttmp = t_at(x,y);
@@ -439,7 +440,8 @@ nhl_deltrap(lua_State *L)
439440
}
440441
x = (coordxy) lx;
441442
y = (coordxy) ly;
442-
443+
cvt_to_abscoord(&x, &y);
444+
443445
if (isok(x, y)) {
444446
struct trap *ttmp = t_at(x,y);
445447

@@ -452,6 +454,11 @@ nhl_deltrap(lua_State *L)
452454
/* get parameters (XX,YY) or ({ x = XX, y = YY }) or ({ XX, YY }),
453455
and set the x and y values.
454456
return TRUE if there are such params in the stack.
457+
Note that this does not adjust the values of x and y at all from what is
458+
specified in the level file; so, it returns absolute coordinates rather than
459+
map-relative coordinates. Callers of this function must decide if they want
460+
to interpret the values as absolute or as map-relative, and adjust
461+
accordingly.
455462
*/
456463
boolean
457464
nhl_get_xy_params(lua_State *L, lua_Integer *x, lua_Integer *y)
@@ -487,23 +494,9 @@ nhl_getmap(lua_State *L)
487494
nhl_error(L, "Incorrect arguments");
488495
return 0;
489496
}
490-
if (g.in_mklev) {
491-
/* xstart and ystart are set by the des.map() command to give
492-
* coordinates relative to the 0,0 of that map. It can be quite useful
493-
* to check what terrain is on a given space. But without compensating
494-
* for the change in xstart and ystart here, this will lead to results
495-
* like des.terrain(4,6,'L') and then nh.getmap(4,6) not being lava.
496-
*
497-
* Only valid during mklev, because xstart and ystart are not saved
498-
* with the level and can change during the level creating process when
499-
* additional des.map() are executed. They will not necessarily be the
500-
* same later. */
501-
x += g.xstart;
502-
y += g.ystart;
503-
}
504-
505497
x = (coordxy) lx;
506498
y = (coordxy) ly;
499+
cvt_to_abscoord(&x, &y);
507500

508501
if (isok(x, y)) {
509502
char buf[BUFSZ];
@@ -1177,6 +1170,7 @@ nhl_timer_has_at(lua_State *L)
11771170

11781171
x = (coordxy) lx;
11791172
y = (coordxy) ly;
1173+
cvt_to_abscoord(&x, &y);
11801174

11811175
if (isok(x, y)) {
11821176
when = spot_time_expires(x, y, timertype);
@@ -1205,6 +1199,7 @@ nhl_timer_peek_at(lua_State *L)
12051199

12061200
x = (coordxy) lx;
12071201
y = (coordxy) ly;
1202+
cvt_to_abscoord(&x, &y);
12081203

12091204
if (timer_is_pos(timertype) && isok(x, y))
12101205
when = spot_time_expires(x, y, timertype);
@@ -1230,6 +1225,7 @@ nhl_timer_stop_at(lua_State *L)
12301225

12311226
x = (coordxy) lx;
12321227
y = (coordxy) ly;
1228+
cvt_to_abscoord(&x, &y);
12331229

12341230
if (timer_is_pos(timertype) && isok(x, y))
12351231
spot_stop_timers(x, y, timertype);
@@ -1254,6 +1250,7 @@ nhl_timer_start_at(lua_State *L)
12541250

12551251
x = (coordxy) lx;
12561252
y = (coordxy) ly;
1253+
cvt_to_abscoord(&x, &y);
12571254

12581255
if (timer_is_pos(timertype) && isok(x, y)) {
12591256
long where = ((long) x << 16) | (long) y;

‎src/sp_lev.c‎

Lines changed: 66 additions & 9 deletions

0 commit comments

Comments
 (0)