Use lua for special level files
Game is playable, and should compile on linux and Windows. Assumes you have a lua 5.3 library available. Removes level compiler and associated files. Replaces special level des-files with lua scripts. Exposes some NetHack internals to lua: - des-table with commands to create special levels - nh-table with NetHack core commands - nhc-table with some constants - u-table with some player-specific data (u-struct) - selection userdata Adds some rudimentary tests. Adds new extended command #wizloadlua to run a specific script, and #wizloaddes to run a specific level-creation script. nhlib.lua is loaded for every lua script. Download and untar lua: mkdir lib cd lib curl -R -O http://www.lua.org/ftp/lua-5.3.5.tar.gz tar zxf lua-5.3.5.tar.gz Then make nethack normally.
This commit is contained in:
100
src/cmd.c
100
src/cmd.c
@@ -148,6 +148,7 @@ STATIC_PTR int NDECL(wiz_where);
|
||||
STATIC_PTR int NDECL(wiz_detect);
|
||||
STATIC_PTR int NDECL(wiz_panic);
|
||||
STATIC_PTR int NDECL(wiz_polyself);
|
||||
STATIC_PTR int NDECL(wiz_load_lua);
|
||||
STATIC_PTR int NDECL(wiz_level_tele);
|
||||
STATIC_PTR int NDECL(wiz_level_change);
|
||||
STATIC_PTR int NDECL(wiz_show_seenv);
|
||||
@@ -785,16 +786,14 @@ wiz_identify(VOID_ARGS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* #wizmakemap - discard current dungeon level and replace with a new one */
|
||||
STATIC_PTR int
|
||||
wiz_makemap(VOID_ARGS)
|
||||
void
|
||||
makemap_prepost(pre, wiztower)
|
||||
boolean pre, wiztower;
|
||||
{
|
||||
NHFILE tmpnhfp;
|
||||
struct monst *mtmp;
|
||||
|
||||
if (wizard) {
|
||||
struct monst *mtmp;
|
||||
boolean was_in_W_tower = In_W_tower(u.ux, u.uy, &u.uz);
|
||||
|
||||
if (pre) {
|
||||
rm_mapseen(ledger_no(&u.uz));
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (mtmp->isgd) { /* vault is going away; get rid of guard */
|
||||
@@ -844,14 +843,14 @@ wiz_makemap(VOID_ARGS)
|
||||
angel on Astral or setting off alarm on Ft.Ludios are handled
|
||||
by goto_level(do.c) so won't occur for replacement levels */
|
||||
mklev();
|
||||
|
||||
} else {
|
||||
vision_reset();
|
||||
g.vision_full_recalc = 1;
|
||||
cls();
|
||||
/* was using safe_teleds() but that doesn't honor arrival region
|
||||
on levels which have such; we don't force stairs, just area */
|
||||
u_on_rndspot((u.uhave.amulet ? 1 : 0) /* 'going up' flag */
|
||||
| (was_in_W_tower ? 2 : 0));
|
||||
| (wiztower ? 2 : 0));
|
||||
losedogs();
|
||||
/* u_on_rndspot() might pick a spot that has a monster, or losedogs()
|
||||
might pick the hero's spot (only if there isn't already a monster
|
||||
@@ -870,6 +869,21 @@ wiz_makemap(VOID_ARGS)
|
||||
#ifdef INSURANCE
|
||||
save_currentstate();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* #wizmakemap - discard current dungeon level and replace with a new one */
|
||||
STATIC_PTR int
|
||||
wiz_makemap(VOID_ARGS)
|
||||
{
|
||||
if (wizard) {
|
||||
boolean was_in_W_tower = In_W_tower(u.ux, u.uy, &u.uz);
|
||||
makemap_prepost(TRUE, was_in_W_tower);
|
||||
/* create a new level; various things like bestowing a guardian
|
||||
angel on Astral or setting off alarm on Ft.Ludios are handled
|
||||
by goto_level(do.c) so won't occur for replacement levels */
|
||||
mklev();
|
||||
makemap_prepost(FALSE, was_in_W_tower);
|
||||
} else {
|
||||
pline(unavailcmd, "#wizmakemap");
|
||||
}
|
||||
@@ -930,6 +944,70 @@ wiz_detect(VOID_ARGS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC_PTR int
|
||||
wiz_load_lua(VOID_ARGS)
|
||||
{
|
||||
if (wizard) {
|
||||
char buf[BUFSZ];
|
||||
getlin("Load which lua file?", buf);
|
||||
if (buf[0] == '\033' || buf[0] == '\0')
|
||||
return 0;
|
||||
if (!strchr(buf, '.'))
|
||||
strcat(buf, ".lua");
|
||||
(void) load_lua(buf);
|
||||
} else
|
||||
pline("Unavailable command 'wiz_load_lua'.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC_PTR int
|
||||
wiz_load_splua(VOID_ARGS)
|
||||
{
|
||||
if (wizard) {
|
||||
boolean was_in_W_tower = In_W_tower(u.ux, u.uy, &u.uz);
|
||||
char buf[BUFSZ];
|
||||
int ridx;
|
||||
|
||||
getlin("Load which des lua file?", buf);
|
||||
if (buf[0] == '\033' || buf[0] == '\0')
|
||||
return 0;
|
||||
if (!strchr(buf, '.'))
|
||||
strcat(buf, ".lua");
|
||||
makemap_prepost(TRUE, was_in_W_tower);
|
||||
|
||||
/* TODO: need to split some of this out of mklev(), makelevel(), makemaz() */
|
||||
g.in_mklev = TRUE;
|
||||
oinit(); /* assign level dependent obj probabilities */
|
||||
clear_level_structures();
|
||||
|
||||
(void) load_special(buf);
|
||||
|
||||
bound_digging();
|
||||
mineralize(-1, -1, -1, -1, FALSE);
|
||||
g.in_mklev = FALSE;
|
||||
if (g.level.flags.has_morgue)
|
||||
g.level.flags.graveyard = 1;
|
||||
if (!g.level.flags.is_maze_lev) {
|
||||
struct mkroom *croom;
|
||||
for (croom = &g.rooms[0]; croom != &g.rooms[g.nroom]; croom++)
|
||||
#ifdef SPECIALIZATION
|
||||
topologize(croom, FALSE);
|
||||
#else
|
||||
topologize(croom);
|
||||
#endif
|
||||
}
|
||||
set_wall_state();
|
||||
/* for many room types, g.rooms[].rtype is zeroed once the room has been
|
||||
entered; g.rooms[].orig_rtype always retains original rtype value */
|
||||
for (ridx = 0; ridx < SIZE(g.rooms); ridx++)
|
||||
g.rooms[ridx].orig_rtype = g.rooms[ridx].rtype;
|
||||
|
||||
makemap_prepost(FALSE, was_in_W_tower);
|
||||
} else
|
||||
pline("Unavailable command 'wiz_load_splua'.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ^V command - level teleport */
|
||||
STATIC_PTR int
|
||||
wiz_level_tele(VOID_ARGS)
|
||||
@@ -3452,6 +3530,10 @@ struct ext_func_tab extcmdlist[] = {
|
||||
wiz_intrinsic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
|
||||
{ C('v'), "wizlevelport", "teleport to another level",
|
||||
wiz_level_tele, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
|
||||
{ '\0', "wizloaddes", "load and execute a des-file lua script",
|
||||
wiz_load_splua, IFBURIED | WIZMODECMD },
|
||||
{ '\0', "wizloadlua", "load and execute a lua script",
|
||||
wiz_load_lua, IFBURIED | WIZMODECMD },
|
||||
{ '\0', "wizmakemap", "recreate the current level",
|
||||
wiz_makemap, IFBURIED | WIZMODECMD },
|
||||
{ C('f'), "wizmap", "map the level",
|
||||
|
||||
Reference in New Issue
Block a user