Tutorial level
Add a tutorial level to teach commands to new players. Very much a WIP. Breaks save and bones compat.
This commit is contained in:
@@ -315,4 +315,15 @@ dungeon = {
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "The Tutorial",
|
||||
base = 1,
|
||||
flags = { "mazelike", "unconnected" },
|
||||
levels = {
|
||||
{
|
||||
name = "tut-1",
|
||||
base = 1,
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -14,6 +14,45 @@ function get_variables_string()
|
||||
return "nh_lua_variables=" .. table_stringify(nh_lua_variables) .. ";";
|
||||
end
|
||||
|
||||
function nh_callback_set(cb, fn)
|
||||
local cbname = "_CB_" .. cb;
|
||||
|
||||
-- pline("callback_set(%s,%s)", cb, fn);
|
||||
|
||||
if (type(nh_lua_variables[cbname]) ~= "table") then
|
||||
nh_lua_variables[cbname] = {};
|
||||
end
|
||||
nh_lua_variables[cbname][fn] = true;
|
||||
end
|
||||
|
||||
function nh_callback_rm(cb, fn)
|
||||
local cbname = "_CB_" .. cb;
|
||||
|
||||
-- pline("callback_RM(%s,%s)", cb, fn);
|
||||
|
||||
if (type(nh_lua_variables[cbname]) ~= "table") then
|
||||
nh_lua_variables[cbname] = {};
|
||||
end
|
||||
nh_lua_variables[cbname][fn] = nil;
|
||||
end
|
||||
|
||||
function nh_callback_run(cb, ...)
|
||||
local cbname = "_CB_" .. cb;
|
||||
|
||||
-- pline("callback_run(%s)", cb);
|
||||
-- pline("TYPE:%s", type(nh_lua_variables[cbname]));
|
||||
|
||||
if (type(nh_lua_variables[cbname]) ~= "table") then
|
||||
nh_lua_variables[cbname] = {};
|
||||
end
|
||||
for k, v in pairs(nh_lua_variables[cbname]) do
|
||||
if (not _G[k](table.unpack{...})) then
|
||||
return false;
|
||||
end
|
||||
end
|
||||
return true;
|
||||
end
|
||||
|
||||
-- This is an example of generating an external file during gameplay,
|
||||
-- which is updated periodically.
|
||||
-- Intended for public servers using dgamelaunch as their login manager.
|
||||
|
||||
@@ -174,3 +174,55 @@ function table_stringify(tbl)
|
||||
-- pline("table_stringify:(%s)", str);
|
||||
return "{" .. str .. "}";
|
||||
end
|
||||
|
||||
--
|
||||
-- TUTORIAL
|
||||
--
|
||||
|
||||
-- extended commands available in tutorial
|
||||
local tutorial_whitelist_commands = {
|
||||
["movesouth"] = true,
|
||||
["movenorth"] = true,
|
||||
["moveeast"] = true,
|
||||
["movewest"] = true,
|
||||
["movesoutheast"] = true,
|
||||
["movenorthwest"] = true,
|
||||
["movenortheast"] = true,
|
||||
["movesouthwest"] = true,
|
||||
["kick"] = true,
|
||||
["search"] = true,
|
||||
["pickup"] = true,
|
||||
["wear"] = true,
|
||||
["wield"] = true,
|
||||
-- ["save"] = true,
|
||||
};
|
||||
|
||||
function tutorial_cmd_before(cmd)
|
||||
-- nh.pline("TUT:cmd_before:" .. cmd);
|
||||
|
||||
if (tutorial_whitelist_commands[cmd]) then
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
end
|
||||
end
|
||||
|
||||
function tutorial_enter()
|
||||
-- nh.pline("TUT:enter");
|
||||
nh.gamestate();
|
||||
end
|
||||
|
||||
function tutorial_leave()
|
||||
-- nh.pline("TUT:leave");
|
||||
|
||||
-- remove the tutorial level callbacks
|
||||
nh.callback("cmd_before", "tutorial_cmd_before", true);
|
||||
nh.callback("level_enter", "tutorial_enter", true);
|
||||
nh.callback("level_leave", "tutorial_leave", true);
|
||||
nh.callback("end_turn", "tutorial_turn", true);
|
||||
nh.gamestate(true);
|
||||
end
|
||||
|
||||
function tutorial_turn()
|
||||
-- nh.pline("TUT:turn");
|
||||
end
|
||||
|
||||
143
dat/tut-1.lua
Normal file
143
dat/tut-1.lua
Normal file
@@ -0,0 +1,143 @@
|
||||
|
||||
des.level_init({ style = "solidfill", fg = " " });
|
||||
des.level_flags("mazelevel", "noflip",
|
||||
"nomongen", "nodeathdrops", "noautosearch");
|
||||
|
||||
des.map([[
|
||||
---------------------------------------------------------------------------
|
||||
|-.--|.......|....|.......................................................|
|
||||
|.-..........|....+.......................................................|
|
||||
||.--|.......|....|.......................................................|
|
||||
||.|.|.......|....|.......................................................|
|
||||
||.|.|.......|....|.......................................................|
|
||||
|-+-S-------------|.......................................................|
|
||||
|......| |.......................................................|
|
||||
|......| ###### |.......................................................|
|
||||
|----.-| -+- # |.......................................................|
|
||||
|----+----.----+---.......................................................|
|
||||
|........|.|......|.......................................................|
|
||||
|.P......-S|......|------.................................................|
|
||||
|..........|......+.|...|.................................................|
|
||||
|.W......---......|.|.|.|.................................................|
|
||||
|....Z.L.|.F......|.|.|.|+---.............................................|
|
||||
|........|--......|...|.....|.............................................|
|
||||
---------------------------------------------------------------------------
|
||||
]]);
|
||||
|
||||
|
||||
des.region(selection.area(01,01, 73, 16), "lit");
|
||||
|
||||
des.non_diggable();
|
||||
|
||||
des.teleport_region({ region = { 9,3, 9,3 } });
|
||||
|
||||
-- TODO:
|
||||
-- - save hero state when entering, restore hero state when leaving
|
||||
-- - quit-command should maybe exit the tutorial?
|
||||
|
||||
-- turn on some newbie-friendly options
|
||||
nh.parse_config("OPTIONS=mention_walls");
|
||||
nh.parse_config("OPTIONS=autoopen");
|
||||
nh.parse_config("OPTIONS=lit_corridor");
|
||||
|
||||
local movekeys = nh.eckey("movewest") .. " " ..
|
||||
nh.eckey("movesouth") .. " " ..
|
||||
nh.eckey("movenorth") .. " " ..
|
||||
nh.eckey("moveeast");
|
||||
|
||||
local diagmovekeys = nh.eckey("movesouthwest") .. " " ..
|
||||
nh.eckey("movenortheast") .. " " ..
|
||||
nh.eckey("movesoutheast") .. " " ..
|
||||
nh.eckey("movenorthwest");
|
||||
|
||||
des.engraving({ coord = { 9,3 }, type = "engrave", text = "Move around with " .. movekeys, degrade = false });
|
||||
des.engraving({ coord = { 5,2 }, type = "engrave", text = "Move diagonally with " .. diagmovekeys, degrade = false });
|
||||
|
||||
--
|
||||
|
||||
des.engraving({ coord = { 2,5 }, type = "engrave", text = "Open the door by moving into it", degrade = false });
|
||||
des.door({ coord = { 2,6 }, state = "closed" });
|
||||
|
||||
--
|
||||
|
||||
des.engraving({ coord = { 4,5 }, type = "engrave", text = "You can leave the tutorial via the magic portal.", degrade = false });
|
||||
des.trap({ type = "magic portal", coord = { 4,4 }, seen = true });
|
||||
|
||||
--
|
||||
|
||||
des.engraving({ coord = { 5,9 }, type = "engrave", text = "This door is locked. Kick it with " .. nh.eckey("kick"), degrade = false });
|
||||
des.door({ coord = { 5,10 }, state = "locked" });
|
||||
|
||||
--
|
||||
|
||||
des.engraving({ coord = { 10,13 }, type = "engrave", text = "Use " .. nh.eckey("search") .. " to search for secret doors", degrade = false });
|
||||
|
||||
--
|
||||
|
||||
des.engraving({ coord = { 10,10 }, type = "engrave", text = "Behind this door is a dark corridor", degrade = false });
|
||||
des.door({ coord = { 10,9 }, state = percent(50) and "locked" or "closed" });
|
||||
des.region(selection.match("#"), "unlit");
|
||||
des.region(selection.match(" "), "unlit");
|
||||
des.door({ coord = { 15,10 }, state = percent(50) and "locked" or "closed" });
|
||||
|
||||
--
|
||||
|
||||
des.engraving({ coord = { 15,11 }, type = "engrave", text = "There are four traps next to you! Search for them.", degrade = false });
|
||||
local locs = { {14,11}, {14,12}, {15,12}, {16,12}, {16,11} };
|
||||
shuffle(locs);
|
||||
for i = 1, 4 do
|
||||
des.trap({ type = percent(50) and "sleep gas" or "board",
|
||||
coord = locs[i], victim = false });
|
||||
end
|
||||
|
||||
--
|
||||
|
||||
des.door({ coord = { 18,13 }, state = "closed" });
|
||||
|
||||
des.engraving({ coord = { 19,13 }, type = "engrave", text = "Pick up items with '" .. nh.eckey("pickup") .. "'", degrade = false });
|
||||
|
||||
local armor = (u.role == "Monk") and "leather gloves" or "leather armor";
|
||||
|
||||
des.object({ id = armor, spe = 0, buc = "not-cursed", coord = { 19,14} });
|
||||
|
||||
des.engraving({ coord = { 19,15 }, type = "engrave", text = "Wear armor with '" .. nh.eckey("wear") .. "'", degrade = false });
|
||||
|
||||
des.object({ id = "dagger", spe = 0, buc = "not-cursed", coord = { 21,15} });
|
||||
|
||||
des.engraving({ coord = { 21,14 }, type = "engrave", text = "Wield weapons with '" .. nh.eckey("wield") .. "'", degrade = false });
|
||||
|
||||
|
||||
des.engraving({ coord = { 22,13 }, type = "engrave", text = "Hit monsters by walking into them.", degrade = false });
|
||||
|
||||
des.monster({ id = "lichen", coord = { 23,15 }, waiting = true, countbirth = false });
|
||||
|
||||
--
|
||||
|
||||
des.door({ coord = { 25,15 }, state = percent(50) and "locked" or "closed" });
|
||||
|
||||
des.engraving({ coord = { 24,16 }, type = "engrave", text = "Now you know the very basics. You can leave the tutorial via the magic portal.", degrade = false });
|
||||
|
||||
des.trap({ type = "magic portal", coord = { 27,16 }, seen = true });
|
||||
|
||||
--
|
||||
|
||||
des.engraving({ coord = { 25,14 }, type = "burn", text = "UNDER CONSTRUCTION", degrade = false });
|
||||
|
||||
--
|
||||
|
||||
des.door({ coord = { 18,2 }, state = percent(50) and "locked" or "closed" });
|
||||
|
||||
----------------
|
||||
|
||||
nh.callback("cmd_before", "tutorial_cmd_before");
|
||||
nh.callback("level_enter", "tutorial_enter");
|
||||
nh.callback("level_leave", "tutorial_leave");
|
||||
nh.callback("end_turn", "tutorial_turn");
|
||||
|
||||
----------------
|
||||
|
||||
-- temporary stuff here
|
||||
-- des.trap({ type = "magic portal", coord = { 9,5 }, seen = true });
|
||||
-- des.trap({ type = "magic portal", coord = { 9,1 }, seen = true });
|
||||
-- des.object({ id = "leather armor", spe = 0, coord = { 9,2} });
|
||||
|
||||
@@ -4546,6 +4546,9 @@ Persistent.
|
||||
." .lp travel_debug
|
||||
." Display intended path during each step of travel (default off).
|
||||
." Debug mode only.
|
||||
.lp tutorial
|
||||
Play a tutorial level at the start of the game.
|
||||
Setting this option on or off in the config file will skip the query.
|
||||
.lp "verbose "
|
||||
Provide more commentary during the game (default on). Persistent.
|
||||
.lp whatis_coord
|
||||
|
||||
@@ -4979,6 +4979,10 @@ command. Persistent.
|
||||
% Display intended path during each step of travel (default off).
|
||||
% Debug mode only.
|
||||
%.lp
|
||||
\item[\ib{tutorial}]
|
||||
Play a tutorial level at the start of the game.
|
||||
Setting this option on or off in the config file will skip the query.
|
||||
%.lp
|
||||
\item[\ib{verbose}]
|
||||
Provide more commentary during the game (default on). Persistent.
|
||||
%.lp
|
||||
|
||||
@@ -1987,6 +1987,7 @@ add items given a Japanese name when playing as a Samurai to discoveries list
|
||||
make music improvisations more varied and interesting, as well as useful
|
||||
give a helpful tip when first entering "farlook" mode
|
||||
add a boolean option tips to disable all of the helpful tips
|
||||
add a tutorial level
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific New Features
|
||||
|
||||
34
doc/lua.adoc
34
doc/lua.adoc
@@ -33,6 +33,26 @@ Example:
|
||||
local str = nh.an("unicorn");
|
||||
|
||||
|
||||
=== callback
|
||||
|
||||
Add or remove a lua function to callback list.
|
||||
First argument is the callback list, second is the name of the lua function to be called.
|
||||
Two arguments adds the callback, if optional 3rd argument is true, removes the callback.
|
||||
Cannot add the same function to the same callback list does nothing.
|
||||
|
||||
|===
|
||||
| cmd_before | called before an extended command is executed. The command name is given as a parameter. If this function returns false, the command will not execute.
|
||||
| level_enter | called when hero enters the level for the first time.
|
||||
| level_leave | called when hero leaves the level.
|
||||
| end_turn | called after player input is handled. May not be exact turn, if eg. hero is running or otherwise occupied.
|
||||
|===
|
||||
|
||||
Example:
|
||||
|
||||
nh.callback("level_enter", "tutorial_enter");
|
||||
nh.callback("level_enter", "tutorial_enter", true);
|
||||
|
||||
|
||||
=== debug_flags
|
||||
|
||||
Set debugging flags.
|
||||
@@ -90,6 +110,16 @@ Example:
|
||||
local filename = nh.dump_fmtstr("/tmp/nethack.%n.%d.log");
|
||||
|
||||
|
||||
=== eckey
|
||||
|
||||
Return the key bound to an extended command, or the full extended
|
||||
command name, if it is not bound to any key.
|
||||
|
||||
Example:
|
||||
|
||||
local k = nh.eckey("help");
|
||||
|
||||
|
||||
=== getlin
|
||||
|
||||
Asks the player for a text to enter, and returns the entered string.
|
||||
@@ -482,6 +512,8 @@ Example:
|
||||
Create an engraving.
|
||||
|
||||
* type is one of "dust", "engrave", "burn", "mark", or "blood".
|
||||
* optional boolean `degrade` defaults to true; engraving can degrade or be wiped out.
|
||||
* optional boolean `guardobjects` defaults to false (unless making a level and the text is "Elbereth"); are items on the engraving protected from monsters.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -579,6 +611,8 @@ Set flags for this level.
|
||||
| hot | Level is hot. Dungeon flag "hellish" automatically sets this.
|
||||
| cold | Level is cold.
|
||||
| temperate | Level is neither hot nor cold.
|
||||
| nomongen | Prevents random monster generation.
|
||||
| nodeathdrops | Prevents killed monsters from dropping corpses or random death drops.
|
||||
|===
|
||||
|
||||
Example:
|
||||
|
||||
@@ -245,6 +245,10 @@ extern const struct class_sym def_monsyms[MAXMCLASSES];
|
||||
/* current mon class symbols */
|
||||
extern uchar monsyms[MAXMCLASSES];
|
||||
|
||||
/* lua callback queue names */
|
||||
extern const char * const nhcb_name[];
|
||||
extern int nhcb_counts[];
|
||||
|
||||
#include "obj.h"
|
||||
extern NEARDATA struct obj *uarm, *uarmc, *uarmh, *uarms, *uarmg, *uarmf,
|
||||
*uarmu, /* under-wear, so to speak */
|
||||
|
||||
@@ -53,10 +53,11 @@ struct tmpbranch {
|
||||
/*
|
||||
* Flags that map into the dungeon flags bitfields.
|
||||
*/
|
||||
#define TOWN 1 /* levels only */
|
||||
#define HELLISH 2
|
||||
#define MAZELIKE 4
|
||||
#define ROGUELIKE 8
|
||||
#define TOWN 0x01 /* levels only */
|
||||
#define HELLISH 0x02
|
||||
#define MAZELIKE 0x04
|
||||
#define ROGUELIKE 0x08
|
||||
#define UNCONNECTED 0x10
|
||||
|
||||
#define D_ALIGN_NONE 0
|
||||
#define D_ALIGN_CHAOTIC (AM_CHAOTIC << 4)
|
||||
|
||||
@@ -19,7 +19,7 @@ typedef struct d_flags { /* dungeon/level type flags */
|
||||
Bitfield(maze_like, 1); /* is this a maze? */
|
||||
Bitfield(rogue_like, 1); /* is this an old-fashioned presentation? */
|
||||
Bitfield(align, 3); /* dungeon alignment. */
|
||||
Bitfield(unused, 1); /* etc... */
|
||||
Bitfield(unconnected, 1); /* dungeon not connected to any branch */
|
||||
} d_flags;
|
||||
|
||||
typedef struct s_level { /* special dungeon level element */
|
||||
|
||||
@@ -24,7 +24,8 @@ struct engr {
|
||||
* against monsters when an object is present
|
||||
* even when hero isn't (so behaves similarly
|
||||
* to how Elbereth did in 3.4.3) */
|
||||
/* 7 free bits */
|
||||
Bitfield(nowipeout, 1); /* this engraving will not degrade */
|
||||
/* 6 free bits */
|
||||
};
|
||||
|
||||
#define newengr(lth) \
|
||||
|
||||
@@ -245,6 +245,7 @@ extern int domonability(void);
|
||||
extern const struct ext_func_tab *ext_func_tab_from_func(int(*)(void));
|
||||
extern char cmd_from_func(int(*)(void));
|
||||
extern char cmd_from_dir(int, int);
|
||||
extern char *cmd_from_ecname(const char *);
|
||||
extern const char *cmdname_from_func(int(*)(void), char *, boolean);
|
||||
extern boolean redraw_cmd(char);
|
||||
extern const char *levltyp_to_name(int);
|
||||
@@ -2008,6 +2009,7 @@ extern int shiny_obj(char);
|
||||
|
||||
/* ### options.c ### */
|
||||
|
||||
extern boolean ask_do_tutorial(void);
|
||||
extern boolean match_optname(const char *, const char *, int, boolean);
|
||||
extern uchar txt2key(char *);
|
||||
extern void initoptions(void);
|
||||
|
||||
@@ -35,6 +35,7 @@ struct flag {
|
||||
boolean goldX; /* for BUCX filtering, whether gold is X or U */
|
||||
boolean help; /* look in data file for info about stuff */
|
||||
boolean tips; /* show helpful hints? */
|
||||
boolean tutorial; /* ask if player wants tutorial level? */
|
||||
boolean ignintr; /* ignore interrupts */
|
||||
boolean implicit_uncursed; /* maybe omit "uncursed" status in inventory */
|
||||
boolean ins_chkpt; /* checkpoint as appropriate; INSURANCE */
|
||||
|
||||
@@ -524,6 +524,16 @@ enum nhcore_calls {
|
||||
NUM_NHCORE_CALLS
|
||||
};
|
||||
|
||||
/* Lua callbacks. TODO: Merge with NHCORE */
|
||||
enum nhcb_calls {
|
||||
NHCB_CMD_BEFORE = 0,
|
||||
NHCB_LVL_ENTER,
|
||||
NHCB_LVL_LEAVE,
|
||||
NHCB_END_TURN,
|
||||
|
||||
NUM_NHCB
|
||||
};
|
||||
|
||||
/* Macros for messages referring to hands, eyes, feet, etc... */
|
||||
enum bodypart_types {
|
||||
ARM = 0,
|
||||
|
||||
@@ -628,6 +628,8 @@ static int optfn_##a(int, int, boolean, char *, char *);
|
||||
NHOPTB(travel_debug, Advanced, 0, opt_out, set_wizonly,
|
||||
Off, No, No, No, NoAlias, (boolean *) 0, Term_False)
|
||||
#endif
|
||||
NHOPTB(tutorial, Advanced, 0, opt_out, set_in_config,
|
||||
On, Yes, No, No, NoAlias, &flags.tutorial, Term_False)
|
||||
NHOPTB(use_darkgray, Advanced, 0, opt_out, set_in_config,
|
||||
On, Yes, No, No, NoAlias, &iflags.wc2_darkgray, Term_False)
|
||||
NHOPTB(use_inverse, Advanced, 0, opt_out, set_in_game,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Incrementing EDITLEVEL can be used to force invalidation of old bones
|
||||
* and save files.
|
||||
*/
|
||||
#define EDITLEVEL 74
|
||||
#define EDITLEVEL 75
|
||||
|
||||
/*
|
||||
* Development status possibilities.
|
||||
|
||||
@@ -389,6 +389,10 @@ struct levelflags {
|
||||
normal mode descendant of such) */
|
||||
Bitfield(corrmaze, 1); /* Whether corridors are used for the maze
|
||||
rather than ROOM */
|
||||
Bitfield(rndmongen, 1); /* random monster generation allowed? */
|
||||
Bitfield(deathdrops, 1); /* monsters may drop corpses/death drops */
|
||||
Bitfield(noautosearch, 1); /* automatic searching disabled */
|
||||
|
||||
schar temperature; /* +1 == hot, -1 == cold */
|
||||
};
|
||||
|
||||
|
||||
@@ -355,6 +355,8 @@ struct you {
|
||||
d_level uz, uz0; /* your level on this and the previous turn */
|
||||
d_level utolev; /* level monster teleported you to, or uz */
|
||||
uchar utotype; /* bitmask of goto_level() flags for utolev */
|
||||
d_level ucamefrom; /* level where you came from; used for tutorial */
|
||||
boolean nofollowers; /* level change ignores monster followers/pets */
|
||||
boolean umoved; /* changed map location (post-move) */
|
||||
int last_str_turn; /* 0: none, 1: half turn, 2: full turn
|
||||
* +: turn right, -: turn left */
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
static void moveloop_preamble(boolean);
|
||||
static void u_calc_moveamt(int);
|
||||
static void maybe_do_tutorial(void);
|
||||
#ifdef POSITIONBAR
|
||||
static void do_positionbar(void);
|
||||
#endif
|
||||
@@ -303,7 +304,7 @@ moveloop_core(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (Searching && gm.multi >= 0)
|
||||
if (!gl.level.flags.noautosearch && Searching && gm.multi >= 0)
|
||||
(void) dosearch0(1);
|
||||
if (Warning)
|
||||
warnreveal();
|
||||
@@ -498,12 +499,41 @@ moveloop_core(void)
|
||||
/* [should this be flush_screen() instead?] */
|
||||
display_nhwindow(WIN_MAP, FALSE);
|
||||
}
|
||||
|
||||
if (gl.luacore && nhcb_counts[NHCB_END_TURN]) {
|
||||
lua_getglobal(gl.luacore, "nh_callback_run");
|
||||
lua_pushstring(gl.luacore, nhcb_name[NHCB_END_TURN]);
|
||||
nhl_pcall(gl.luacore, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_do_tutorial(void)
|
||||
{
|
||||
s_level *sp = find_level("tut-1");
|
||||
|
||||
if (!sp)
|
||||
return;
|
||||
|
||||
if (ask_do_tutorial()) {
|
||||
assign_level(&u.ucamefrom, &u.uz);
|
||||
u.nofollowers = TRUE;
|
||||
schedule_goto(&sp->dlevel, UTOTYPE_NONE, (char *) 0, (char *) 0);
|
||||
deferred_goto();
|
||||
vision_recalc(0);
|
||||
docrt();
|
||||
u.nofollowers = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
moveloop(boolean resuming)
|
||||
{
|
||||
moveloop_preamble(resuming);
|
||||
|
||||
if (!resuming)
|
||||
maybe_do_tutorial();
|
||||
|
||||
for (;;) {
|
||||
moveloop_core();
|
||||
}
|
||||
|
||||
32
src/cmd.c
32
src/cmd.c
@@ -482,6 +482,15 @@ can_do_extcmd(const struct ext_func_tab *extcmd)
|
||||
{
|
||||
int ecflags = extcmd->flags;
|
||||
|
||||
if (gl.luacore && nhcb_counts[NHCB_CMD_BEFORE]) {
|
||||
lua_getglobal(gl.luacore, "nh_callback_run");
|
||||
lua_pushstring(gl.luacore, nhcb_name[NHCB_CMD_BEFORE]);
|
||||
lua_pushstring(gl.luacore, extcmd->ef_txt);
|
||||
nhl_pcall(gl.luacore, 2, 1);
|
||||
if (!lua_toboolean(gl.luacore, -1))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!wizard && (ecflags & WIZMODECMD)) {
|
||||
pline(unavailcmd, extcmd->ef_txt);
|
||||
return FALSE;
|
||||
@@ -3607,6 +3616,29 @@ cmd_from_func(int (*fn)(void))
|
||||
return '\0';
|
||||
}
|
||||
|
||||
/* return visual interpretation of the key bound to extended command,
|
||||
or the ext cmd name if not bound to any key. */
|
||||
char *
|
||||
cmd_from_ecname(const char *ecname)
|
||||
{
|
||||
static char cmdnamebuf[QBUFSZ];
|
||||
const struct ext_func_tab *extcmd;
|
||||
|
||||
for (extcmd = extcmdlist; extcmd->ef_txt; ++extcmd)
|
||||
if (!strcmp(extcmd->ef_txt, ecname)) {
|
||||
char key = cmd_from_func(extcmd->ef_funct);
|
||||
|
||||
if (key)
|
||||
Sprintf(cmdnamebuf, "%s", visctrl(key));
|
||||
else
|
||||
Sprintf(cmdnamebuf, "#%s", ecname);
|
||||
return cmdnamebuf;
|
||||
}
|
||||
|
||||
cmdnamebuf[0] = '\0';
|
||||
return cmdnamebuf;
|
||||
}
|
||||
|
||||
static const char *
|
||||
ecname_from_fn(int (*fn)(void))
|
||||
{
|
||||
|
||||
@@ -45,6 +45,14 @@ const int shield_static[SHIELD_COUNT] = {
|
||||
S_ss1, S_ss2, S_ss3, S_ss2, S_ss1, S_ss2, S_ss4,
|
||||
};
|
||||
|
||||
const char * const nhcb_name[NUM_NHCB] = {
|
||||
"cmd_before",
|
||||
"level_enter",
|
||||
"level_leave",
|
||||
"end_turn",
|
||||
};
|
||||
|
||||
int nhcb_counts[NUM_NHCB] = DUMMY;
|
||||
|
||||
NEARDATA const struct c_color_names c_color_names = {
|
||||
"black", "amber", "golden", "light blue", "red", "green",
|
||||
|
||||
13
src/do.c
13
src/do.c
@@ -1481,6 +1481,12 @@ goto_level(
|
||||
if (on_level(newlevel, &u.uz))
|
||||
return; /* this can happen */
|
||||
|
||||
if (gl.luacore && nhcb_counts[NHCB_LVL_LEAVE]) {
|
||||
lua_getglobal(gl.luacore, "nh_callback_run");
|
||||
lua_pushstring(gl.luacore, nhcb_name[NHCB_LVL_LEAVE]);
|
||||
nhl_pcall(gl.luacore, 1, 0);
|
||||
}
|
||||
|
||||
/* tethered movement makes level change while trapped feasible */
|
||||
if (u.utrap && u.utraptype == TT_BURIEDBALL)
|
||||
buried_ball_to_punishment(); /* (before we save/leave old level) */
|
||||
@@ -1511,7 +1517,8 @@ goto_level(
|
||||
set_ustuck((struct monst *) 0); /* clear u.ustuck and u.uswallow */
|
||||
set_uinwater(0); /* u.uinwater = 0 */
|
||||
u.uundetected = 0; /* not hidden, even if means are available */
|
||||
keepdogs(FALSE);
|
||||
if (!u.nofollowers)
|
||||
keepdogs(FALSE);
|
||||
recalc_mapseen(); /* recalculate map overview before we leave the level */
|
||||
/*
|
||||
* We no longer see anything on the level. Make sure that this
|
||||
@@ -1611,6 +1618,7 @@ goto_level(
|
||||
if (portal && !In_endgame(&u.uz)) {
|
||||
/* find the portal on the new level */
|
||||
register struct trap *ttrap;
|
||||
struct stairway *stway;
|
||||
|
||||
for (ttrap = gf.ftrap; ttrap; ttrap = ttrap->ntrap)
|
||||
if (ttrap->ttyp == MAGIC_PORTAL)
|
||||
@@ -1623,6 +1631,9 @@ goto_level(
|
||||
after already getting expelled once. The portal back
|
||||
doesn't exist anymore - see expulsion(). */
|
||||
u_on_rndspot(0);
|
||||
} else if ((stway = stairway_find_dir(TRUE)) != 0) {
|
||||
/* returning from tutorial via portal */
|
||||
u_on_newpos(stway->sx, stway->sy);
|
||||
} else {
|
||||
panic("goto_level: no corresponding portal!");
|
||||
}
|
||||
|
||||
@@ -714,9 +714,10 @@ get_dgn_flags(lua_State *L)
|
||||
{
|
||||
int dgn_flags = 0;
|
||||
static const char *const flagstrs[] = {
|
||||
"town", "hellish", "mazelike", "roguelike", NULL
|
||||
"town", "hellish", "mazelike", "roguelike", "unconnected", NULL
|
||||
};
|
||||
static const int flagstrs2i[] = { TOWN, HELLISH, MAZELIKE, ROGUELIKE, 0 };
|
||||
static const int flagstrs2i[] = { TOWN, HELLISH, MAZELIKE, ROGUELIKE,
|
||||
UNCONNECTED, 0 };
|
||||
|
||||
lua_getfield(L, -1, "flags");
|
||||
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
@@ -1040,6 +1041,7 @@ init_dungeons(void)
|
||||
gd.dungeons[i].flags.maze_like = !!(dgn_flags & MAZELIKE);
|
||||
gd.dungeons[i].flags.rogue_like = !!(dgn_flags & ROGUELIKE);
|
||||
gd.dungeons[i].flags.align = dgn_align;
|
||||
gd.dungeons[i].flags.unconnected = !!(dgn_flags & UNCONNECTED);
|
||||
|
||||
/*
|
||||
* Set the entry level for this dungeon. The entry value means:
|
||||
@@ -1063,7 +1065,9 @@ init_dungeons(void)
|
||||
gd.dungeons[i].entry_lev = 1; /* defaults to top level */
|
||||
}
|
||||
|
||||
if (i) { /* set depth */
|
||||
if (gd.dungeons[i].flags.unconnected) {
|
||||
gd.dungeons[i].depth_start = 1;
|
||||
} else if (i) { /* set depth */
|
||||
branch *br;
|
||||
schar from_depth;
|
||||
boolean from_up;
|
||||
|
||||
@@ -296,8 +296,8 @@ wipe_engr_at(coordxy x, coordxy y, xint16 cnt, boolean magical)
|
||||
{
|
||||
register struct engr *ep = engr_at(x, y);
|
||||
|
||||
/* Headstones are indelible */
|
||||
if (ep && ep->engr_type != HEADSTONE) {
|
||||
/* Headstones and some specially marked engravings are indelible */
|
||||
if (ep && ep->engr_type != HEADSTONE && !ep->nowipeout) {
|
||||
debugpline1("asked to erode %d characters", cnt);
|
||||
if (ep->engr_type != BURN || is_ice(x, y) || (magical && !rn2(2))) {
|
||||
if (ep->engr_type != DUST && ep->engr_type != ENGR_BLOOD) {
|
||||
|
||||
@@ -1141,7 +1141,7 @@ makemon(
|
||||
fakemon = cg.zeromonst;
|
||||
cc.x = cc.y = 0;
|
||||
|
||||
if (iflags.debug_mongen)
|
||||
if (iflags.debug_mongen || (!gl.level.flags.rndmongen && !ptr))
|
||||
return (struct monst *) 0;
|
||||
|
||||
/* if caller wants random location, do it here */
|
||||
|
||||
@@ -1016,6 +1016,12 @@ makelevel(void)
|
||||
for (i = 0; i < gn.nroom; ++i) {
|
||||
fill_special_room(&gr.rooms[i]);
|
||||
}
|
||||
|
||||
if (gl.luacore && nhcb_counts[NHCB_LVL_ENTER]) {
|
||||
lua_getglobal(gl.luacore, "nh_callback_run");
|
||||
lua_pushstring(gl.luacore, nhcb_name[NHCB_LVL_ENTER]);
|
||||
nhl_pcall(gl.luacore, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1518,6 +1524,9 @@ mktrap(
|
||||
(void) makemon(&mons[PM_GIANT_SPIDER], m.x, m.y, NO_MM_FLAGS);
|
||||
if (t && (mktrapflags & MKTRAP_SEEN))
|
||||
t->tseen = TRUE;
|
||||
if (kind == MAGIC_PORTAL && (u.ucamefrom.dnum || u.ucamefrom.dlevel)) {
|
||||
assign_level(&t->dst, &u.ucamefrom);
|
||||
}
|
||||
|
||||
/* The hero isn't the only person who's entered the dungeon in
|
||||
search of treasure. On the very shallowest levels, there's a
|
||||
|
||||
@@ -34,6 +34,7 @@ static void pacify_guard(struct monst *);
|
||||
|
||||
#define LEVEL_SPECIFIC_NOCORPSE(mdat) \
|
||||
(Is_rogue_level(&u.uz) \
|
||||
|| !gl.level.flags.deathdrops \
|
||||
|| (gl.level.flags.graveyard && is_undead(mdat) && rn2(3)))
|
||||
|
||||
/* A specific combination of x_monnam flags for livelogging. The livelog
|
||||
|
||||
140
src/nhlua.c
140
src/nhlua.c
@@ -36,6 +36,9 @@ static int nhl_timer_has_at(lua_State *);
|
||||
static int nhl_timer_peek_at(lua_State *);
|
||||
static int nhl_timer_stop_at(lua_State *);
|
||||
static int nhl_timer_start_at(lua_State *);
|
||||
static int nhl_get_cmd_key(lua_State *);
|
||||
static int nhl_callback(lua_State *);
|
||||
static int nhl_gamestate(lua_State *);
|
||||
static int nhl_test(lua_State *);
|
||||
static int nhl_getmap(lua_State *);
|
||||
static char splev_typ2chr(schar);
|
||||
@@ -1474,6 +1477,140 @@ nhl_timer_start_at(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns the visual interpretation of the key bound to an extended command,
|
||||
or the ext cmd name if not bound to any key */
|
||||
/* local helpkey = eckey("help"); */
|
||||
static int
|
||||
nhl_get_cmd_key(lua_State *L)
|
||||
{
|
||||
int argc = lua_gettop(L);
|
||||
|
||||
if (argc == 1) {
|
||||
const char *cmd = luaL_checkstring(L, 1);
|
||||
char *key = cmd_from_ecname(cmd);
|
||||
|
||||
lua_pushstring(L, key);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* add or remove a lua function callback */
|
||||
/* callback("level_enter", "function_name"); */
|
||||
/* callback("level_enter", "function_name", true); */
|
||||
/* level_enter, level_leave, cmd_before */
|
||||
static int
|
||||
nhl_callback(lua_State *L)
|
||||
{
|
||||
int argc = lua_gettop(L);
|
||||
int i;
|
||||
|
||||
if (argc == 2) {
|
||||
const char *fn = luaL_checkstring(L, -1);
|
||||
const char *cb = luaL_checkstring(L, -2);
|
||||
|
||||
if (!gl.luacore) {
|
||||
nhl_error(L, "nh luacore not inited");
|
||||
/*NOTREACHED*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_NHCB; i++)
|
||||
if (!strcmp(cb, nhcb_name[i]))
|
||||
break;
|
||||
|
||||
if (i >= NUM_NHCB)
|
||||
return 0;
|
||||
|
||||
nhcb_counts[i]++;
|
||||
|
||||
lua_getglobal(gl.luacore, "nh_callback_set");
|
||||
lua_pushstring(gl.luacore, cb);
|
||||
lua_pushstring(gl.luacore, fn);
|
||||
nhl_pcall(gl.luacore, 2, 0);
|
||||
} else if (argc == 3) {
|
||||
boolean rm = lua_toboolean(L, -1);
|
||||
const char *fn = luaL_checkstring(L, -2);
|
||||
const char *cb = luaL_checkstring(L, -3);
|
||||
|
||||
if (!gl.luacore) {
|
||||
nhl_error(L, "nh luacore not inited");
|
||||
/*NOTREACHED*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_NHCB; i++)
|
||||
if (!strcmp(cb, nhcb_name[i]))
|
||||
break;
|
||||
|
||||
if (i >= NUM_NHCB)
|
||||
return 0;
|
||||
|
||||
if (rm) {
|
||||
nhcb_counts[i]--;
|
||||
if (nhcb_counts[i] < 0)
|
||||
impossible("nh.callback counts are wrong");
|
||||
} else {
|
||||
nhcb_counts[i]++;
|
||||
}
|
||||
|
||||
lua_getglobal(gl.luacore, rm ? "nh_callback_rm" : "nh_callback_set");
|
||||
lua_pushstring(gl.luacore, cb);
|
||||
lua_pushstring(gl.luacore, fn);
|
||||
nhl_pcall(gl.luacore, 2, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* store or restore game state */
|
||||
/* NOTE: doesn't work when saving/restoring the game */
|
||||
/* currently handles inventory and turns. */
|
||||
/* gamestate(); -- save state */
|
||||
/* gamestate(true); -- restore state */
|
||||
static int
|
||||
nhl_gamestate(lua_State *L)
|
||||
{
|
||||
int argc = lua_gettop(L);
|
||||
boolean reststate = argc > 0 ? lua_toboolean(L, -1) : FALSE;
|
||||
static struct obj *invent = NULL;
|
||||
static long moves = 0;
|
||||
static boolean stored = FALSE;
|
||||
|
||||
if (reststate && stored) {
|
||||
/* restore game state */
|
||||
gm.moves = moves;
|
||||
while (gi.invent)
|
||||
useupall(gi.invent);
|
||||
while (invent) {
|
||||
struct obj *otmp = invent;
|
||||
long wornmask = otmp->owornmask;
|
||||
otmp->owornmask = 0L;
|
||||
extract_nobj(otmp, &invent);
|
||||
addinv(otmp);
|
||||
if (wornmask)
|
||||
setworn(otmp, wornmask);
|
||||
}
|
||||
stored = FALSE;
|
||||
} else {
|
||||
/* store game state */
|
||||
while (gi.invent) {
|
||||
struct obj *otmp = gi.invent;
|
||||
long wornmask = otmp->owornmask;
|
||||
setnotworn(otmp);
|
||||
freeinv(otmp);
|
||||
otmp->nobj = invent;
|
||||
otmp->owornmask = wornmask;
|
||||
invent = otmp;
|
||||
}
|
||||
moves = gm.moves;
|
||||
stored = TRUE;
|
||||
}
|
||||
update_inventory();
|
||||
return 0;
|
||||
}
|
||||
|
||||
RESTORE_WARNING_UNREACHABLE_CODE
|
||||
|
||||
static const struct luaL_Reg nhl_functions[] = {
|
||||
@@ -1499,6 +1636,9 @@ static const struct luaL_Reg nhl_functions[] = {
|
||||
{"menu", nhl_menu},
|
||||
{"text", nhl_text},
|
||||
{"getlin", nhl_getlin},
|
||||
{"eckey", nhl_get_cmd_key},
|
||||
{"callback", nhl_callback},
|
||||
{"gamestate", nhl_gamestate},
|
||||
|
||||
{"makeplural", nhl_makeplural},
|
||||
{"makesingular", nhl_makesingular},
|
||||
|
||||
@@ -368,6 +368,52 @@ extern int curses_read_attrs(const char *attrs);
|
||||
extern char *curses_fmt_attrs(char *);
|
||||
#endif
|
||||
|
||||
/* ask user if they want a tutorial, except if tutorial boolean option has been
|
||||
set in config - either on or off - in which case just obey that setting
|
||||
without asking. */
|
||||
boolean
|
||||
ask_do_tutorial(void)
|
||||
{
|
||||
boolean dotut = flags.tutorial;
|
||||
|
||||
if (!opt_set_in_config[opt_tutorial]) {
|
||||
winid win;
|
||||
menu_item *sel;
|
||||
anything any;
|
||||
int n;
|
||||
|
||||
do {
|
||||
win = create_nhwindow(NHW_MENU);
|
||||
start_menu(win, MENU_BEHAVE_STANDARD);
|
||||
any = cg.zeroany;
|
||||
any.a_char = 'y';
|
||||
add_menu(win, &nul_glyphinfo, &any, any.a_char, 0,
|
||||
ATR_NONE, 0, "Yes, do a tutorial", MENU_ITEMFLAGS_NONE);
|
||||
any.a_char = 'n';
|
||||
add_menu(win, &nul_glyphinfo, &any, any.a_char, 0,
|
||||
ATR_NONE, 0, "No", MENU_ITEMFLAGS_NONE);
|
||||
|
||||
any = cg.zeroany;
|
||||
add_menu(win, &nul_glyphinfo, &any, 0, 0,
|
||||
ATR_NONE, 0, "", MENU_ITEMFLAGS_NONE);
|
||||
add_menu(win, &nul_glyphinfo, &any, 0, 0,
|
||||
ATR_NONE, 0, "", MENU_ITEMFLAGS_NONE);
|
||||
add_menu(win, &nul_glyphinfo, &any, 0, 0,
|
||||
ATR_NONE, 0, "Put \"OPTIONS=notutorial\" in the config file to skip this query.", MENU_ITEMFLAGS_NONE);
|
||||
|
||||
end_menu(win, "Do you want a tutorial?");
|
||||
|
||||
n = select_menu(win, PICK_ONE, &sel);
|
||||
destroy_nhwindow(win);
|
||||
} while (n <= 0 && !gp.program_state.done_hup);
|
||||
if (n > 0) {
|
||||
dotut = (sel[0].item.a_char == 'y');
|
||||
free((genericptr_t) sel);
|
||||
}
|
||||
}
|
||||
return dotut;
|
||||
}
|
||||
|
||||
/*
|
||||
**********************************
|
||||
*
|
||||
|
||||
18
src/sp_lev.c
18
src/sp_lev.c
@@ -3712,6 +3712,12 @@ lspo_level_flags(lua_State *L)
|
||||
gl.level.flags.temperature = 1;
|
||||
else if (!strcmpi(s, "cold"))
|
||||
gl.level.flags.temperature = -1;
|
||||
else if (!strcmpi(s, "nomongen"))
|
||||
gl.level.flags.rndmongen = 0;
|
||||
else if (!strcmpi(s, "nodeathdrops"))
|
||||
gl.level.flags.deathdrops = 0;
|
||||
else if (!strcmpi(s, "noautosearch"))
|
||||
gl.level.flags.noautosearch = 1;
|
||||
else {
|
||||
char buf[BUFSZ];
|
||||
Sprintf(buf, "Unknown level flag %s", s);
|
||||
@@ -3783,6 +3789,9 @@ lspo_engraving(lua_State *L)
|
||||
long ecoord;
|
||||
coordxy x = -1, y = -1;
|
||||
int argc = lua_gettop(L);
|
||||
boolean guardobjs = FALSE;
|
||||
boolean wipeout = TRUE;
|
||||
struct engr *ep;
|
||||
|
||||
create_des_coder();
|
||||
|
||||
@@ -3795,6 +3804,8 @@ lspo_engraving(lua_State *L)
|
||||
y = ey;
|
||||
etyp = engrtypes2i[get_table_option(L, "type", "engrave", engrtypes)];
|
||||
txt = get_table_str(L, "text");
|
||||
wipeout = get_table_boolean_opt(L, "degrade", TRUE);
|
||||
guardobjs = get_table_boolean_opt(L, "guardobjects", FALSE);
|
||||
} else if (argc == 3) {
|
||||
lua_Integer ex, ey;
|
||||
(void) get_coord(L, 1, &ex, &ey);
|
||||
@@ -3814,6 +3825,11 @@ lspo_engraving(lua_State *L)
|
||||
get_location_coord(&x, &y, DRY, gc.coder->croom, ecoord);
|
||||
make_engr_at(x, y, txt, 0L, etyp);
|
||||
Free(txt);
|
||||
ep = engr_at(x, y);
|
||||
if (ep) {
|
||||
ep->guardobjects = guardobjs;
|
||||
ep->nowipeout = !wipeout;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6826,6 +6842,8 @@ sp_level_coder_init(void)
|
||||
|
||||
gl.level.flags.is_maze_lev = 0;
|
||||
gl.level.flags.temperature = In_hell(&u.uz) ? 1 : 0;
|
||||
gl.level.flags.rndmongen = 1;
|
||||
gl.level.flags.deathdrops = 1;
|
||||
|
||||
reset_xystart_size();
|
||||
|
||||
|
||||
@@ -1128,7 +1128,8 @@ void
|
||||
domagicportal(struct trap *ttmp)
|
||||
{
|
||||
struct d_level target_level;
|
||||
boolean already_stunned;
|
||||
s_level *tutlvl = find_level("tut-1");
|
||||
const char *stunmsg = (char *) 0;
|
||||
|
||||
if (u.utrap && u.utraptype == TT_BURIEDBALL)
|
||||
buried_ball_to_punishment();
|
||||
@@ -1154,13 +1155,16 @@ domagicportal(struct trap *ttmp)
|
||||
return;
|
||||
}
|
||||
|
||||
already_stunned = !!Stunned;
|
||||
make_stunned((HStun & TIMEOUT) + 3L, FALSE);
|
||||
target_level = ttmp->dst;
|
||||
schedule_goto(&target_level, UTOTYPE_PORTAL,
|
||||
!already_stunned ? "You feel slightly dizzy."
|
||||
: "You feel dizzier.",
|
||||
(char *) 0);
|
||||
|
||||
/* coming back from tutorial doesn't trigger stunning */
|
||||
if (!(tutlvl && tutlvl->dlevel.dnum == u.uz.dnum)) {
|
||||
stunmsg = !Stunned ? "You feel slightly dizzy."
|
||||
: "You feel dizzier.";
|
||||
make_stunned((HStun & TIMEOUT) + 3L, FALSE);
|
||||
}
|
||||
|
||||
schedule_goto(&target_level, UTOTYPE_PORTAL, stunmsg, (char *) 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -97,7 +97,7 @@ SPEC_LEVS = asmodeus.lua baalz.lua bigrm-*.lua castle.lua fakewiz?.lua \
|
||||
juiblex.lua knox.lua medusa-?.lua minend-?.lua minefill.lua \
|
||||
minetn-?.lua oracle.lua orcus.lua sanctum.lua soko?-?.lua \
|
||||
tower?.lua valley.lua wizard?.lua nhcore.lua nhlib.lua themerms.lua \
|
||||
astral.lua air.lua earth.lua fire.lua water.lua hellfill.lua
|
||||
astral.lua air.lua earth.lua fire.lua water.lua hellfill.lua tut-?.lua
|
||||
QUEST_LEVS = ???-goal.lua ???-fil?.lua ???-loca.lua ???-strt.lua
|
||||
|
||||
DATNODLB = $(VARDATND) license symbols
|
||||
|
||||
@@ -1387,6 +1387,7 @@
|
||||
"$(NH_DAT_DIR)/tower1.lua",
|
||||
"$(NH_DAT_DIR)/tower2.lua",
|
||||
"$(NH_DAT_DIR)/tower3.lua",
|
||||
"$(NH_DAT_DIR)/tut-1.lua",
|
||||
"$(NH_DAT_DIR)/Val-fila.lua",
|
||||
"$(NH_DAT_DIR)/Val-filb.lua",
|
||||
"$(NH_DAT_DIR)/Val-goal.lua",
|
||||
@@ -1411,7 +1412,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "cd \"${NH_DAT_DIR}\"\n\"${NH_UTIL_DIR}\"/dlb cf nhdat help hh cmdhelp keyhelp history opthelp optmenu wizhelp dungeon.lua tribute asmodeus.lua baalz.lua bigrm-*.lua castle.lua fakewiz?.lua juiblex.lua knox.lua medusa-?.lua minend-?.lua minefill.lua minetn-?.lua oracle.lua orcus.lua sanctum.lua soko?-?.lua tower?.lua valley.lua wizard?.lua nhcore.lua nhlib.lua themerms.lua hellfill.lua astral.lua air.lua earth.lua fire.lua water.lua ???-goal.lua ???-fil?.lua ???-loca.lua ???-strt.lua bogusmon data engrave epitaph oracles options quest.lua rumors\n";
|
||||
shellScript = "cd \"${NH_DAT_DIR}\"\n\"${NH_UTIL_DIR}\"/dlb cf nhdat help hh cmdhelp keyhelp history opthelp optmenu wizhelp dungeon.lua tribute asmodeus.lua baalz.lua bigrm-*.lua castle.lua fakewiz?.lua juiblex.lua knox.lua medusa-?.lua minend-?.lua minefill.lua minetn-?.lua oracle.lua orcus.lua sanctum.lua soko?-?.lua tower?.lua tut-?.lua valley.lua wizard?.lua nhcore.lua nhlib.lua themerms.lua hellfill.lua astral.lua air.lua earth.lua fire.lua water.lua ???-goal.lua ???-fil?.lua ???-loca.lua ???-strt.lua bogusmon data engrave epitaph oracles options quest.lua rumors\n";
|
||||
};
|
||||
3192867021A39F6A00325BEB /* Install */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
|
||||
@@ -40,7 +40,7 @@ $ spec_files = "air.lua,asmodeus.lua,astral.lua,baalz.lua," -
|
||||
+ "fire.lua,juiblex.lua,knox.lua,medusa-%.lua," -
|
||||
+ "minefill.lua,minetn-%.lua,minend-%.lua,nhlib.lua," -
|
||||
+ "oracle.lua,orcus.lua,sanctum.lua,soko%-%.lua," -
|
||||
+ "tower%.lua,valley.lua,water.lua,wizard%.lua,hellfill.lua"
|
||||
+ "tower%.lua,valley.lua,water.lua,wizard%.lua,hellfill.lua,tut-%.lua"
|
||||
$ qstl_files = "%%%-goal.lua,%%%-fil%.lua,%%%-loca.lua,%%%-strt.lua"
|
||||
$ dngn_files = "dungeon.lua"
|
||||
$!
|
||||
|
||||
@@ -443,7 +443,7 @@ LUALIST = air Arc-fila Arc-filb Arc-goal Arc-loca Arc-strt \
|
||||
Tou-strt tower1 tower2 tower3 Val-fila Val-filb \
|
||||
Val-goal Val-loca Val-strt valley water Wiz-fila \
|
||||
Wiz-filb Wiz-goal Wiz-loca Wiz-strt wizard1 wizard2 \
|
||||
wizard3
|
||||
wizard3 tut-1
|
||||
|
||||
LUAFILES = $(addprefix $(DAT)/, $(addsuffix .lua, $(LUALIST)))
|
||||
|
||||
|
||||
@@ -523,7 +523,7 @@ LUA_FILES = $(DAT)\air.lua $(DAT)\Arc-fila.lua $(DAT)\Arc-filb.lua \
|
||||
$(DAT)\valley.lua $(DAT)\water.lua $(DAT)\Wiz-fila.lua \
|
||||
$(DAT)\Wiz-filb.lua $(DAT)\Wiz-goal.lua $(DAT)\Wiz-loca.lua \
|
||||
$(DAT)\Wiz-strt.lua $(DAT)\wizard1.lua $(DAT)\wizard2.lua \
|
||||
$(DAT)\wizard3.lua
|
||||
$(DAT)\wizard3.lua $(DAT)\tut-1.lua
|
||||
#
|
||||
# Utility Objects.
|
||||
#
|
||||
|
||||
@@ -127,6 +127,7 @@
|
||||
<Luafiles Include = "tower1.lua"/>
|
||||
<Luafiles Include = "tower2.lua"/>
|
||||
<Luafiles Include = "tower3.lua"/>
|
||||
<Luafiles Include = "tut-1.lua"/>
|
||||
<Luafiles Include = "Val-fila.lua"/>
|
||||
<Luafiles Include = "Val-filb.lua"/>
|
||||
<Luafiles Include = "Val-goal.lua"/>
|
||||
|
||||
Reference in New Issue
Block a user