1 /* File: script.c */
2 
3 #include "angband.h"
4 
5 #include "script.h"
6 
7 
8 #include "lua/lua.h"
9 #include "lua/lualib.h"
10 #include "lua/lauxlib.h"
11 #include "lua/tolua.h"
12 #include "lua/luadebug.h"
13 
14 
15 /*
16  * Lua state
17  */
18 static lua_State* L = NULL;
19 
20 
xxx_msgf(lua_State * L)21 static int xxx_msgf(lua_State *L)
22 {
23 	cptr text = lua_tostring(L, 1);
24 	if (text) msgf(text);
25 	lua_pop(L, 1);
26 
27 	return 0;
28 }
29 
30 
xxx_msg_flush(lua_State * L)31 static int xxx_msg_flush(lua_State *L)
32 {
33 	/* Hack - ignore parameter */
34 	(void) L;
35 
36 	message_flush();
37 
38 	return 0;
39 }
40 
41 
xxx_build_script_path(lua_State * L)42 static int xxx_build_script_path(lua_State *L)
43 {
44 	char buf[1024];
45 	cptr filename;
46 
47 	if (!tolua_istype(L, 1, LUA_TSTRING,0))
48 		tolua_error(L, "#vinvalid type in variable assignment.");
49 
50 	filename = tolua_getstring(L, 1, 0);
51 
52 	path_make(buf, ANGBAND_DIR_SCRIPT, filename);
53 
54 	tolua_pushstring(L, buf);
55 
56 	return 1;
57 }
58 
59 
xxx_get_rumor(lua_State * L)60 static int xxx_get_rumor(lua_State *L)
61 {
62 	errr err;
63 	char buf[1024];
64 
65 	switch (randint1(20))
66 	{
67 		case 1:
68 			err = get_rnd_line("chainswd.txt", 0, buf);
69 			break;
70 		case 2:
71 			err = get_rnd_line("error.txt", 0, buf);
72 			break;
73 		case 3:
74 		case 4:
75 		case 5:
76 			err = get_rnd_line("death.txt", 0, buf);
77 			break;
78 		default:
79 			err = get_rnd_line("rumors.txt", 0, buf);
80 			break;
81 	}
82 
83 	/* An error occured */
84 	if (err) strcpy(buf, "Some rumors are wrong.");
85 
86 	/* Push the rumor */
87 	tolua_pushstring(L, buf);
88 
89 	/* One result */
90 	return (1);
91 }
92 
xxx_get_rnd_line(lua_State * L)93 static int xxx_get_rnd_line(lua_State *L)
94 {
95 	cptr filename;
96 	char buf[1024];
97 	int err;
98 
99 	filename = lua_tostring(L, 1);
100 
101 	/* Pop off the filename */
102 	lua_pop(L, 1);
103 
104 	err = get_rnd_line(filename, 0, buf);
105 
106 	/* Check for error */
107 	if (err)
108 		return 0;
109 
110 	tolua_pushstring(L, buf);
111 	return (1);
112 }
113 
xxx_get_aim_dir(lua_State * L)114 static int xxx_get_aim_dir(lua_State *L)
115 {
116 	int dir;
117 	bool success;
118 
119 	success = get_aim_dir(&dir);
120 	tolua_pushbool(L, success);
121 	lua_pushnumber(L, dir);
122 
123 	return 2;
124 }
125 
126 
xxx_fire_beam(lua_State * L)127 static int xxx_fire_beam(lua_State *L)
128 {
129 	int typ, dir, dam;
130 	bool result;
131 
132 	typ = (int)luaL_check_number(L, 1);
133 	dir = (int)luaL_check_number(L, 2);
134 	dam = (int)luaL_check_number(L, 3);
135 	result = fire_beam(typ, dir, dam);
136 	tolua_pushbool(L, result);
137 
138 	return 1;
139 }
140 
141 
142 #ifdef RISCOS
143 extern char *riscosify_name(const char *);
144 
xxx_dofile(lua_State * L)145 static int xxx_dofile(lua_State *L)
146 {
147 	cptr filename = lua_tostring(L, 1);
148 
149 	/* Pop off the filename */
150 	lua_pop(L, 1);
151 
152 	if (filename)
153 	{
154 	 	return lua_dofile(L, riscosify_name(filename));
155 	}
156 
157 	return 0;
158 }
159 #endif /* RISCOS */
160 
xxx_building_options(lua_State * L)161 static int xxx_building_options(lua_State *L)
162 {
163 	int i;
164 
165 	/* number of arguments */
166 	int n = lua_gettop(L);
167 
168 	cptr *strings;
169 
170 	/* Make array of strings */
171 	C_MAKE(strings, n, cptr);
172 
173 	for (i = 1; i <= n; i++)
174 	{
175 		if (!tolua_istype(L,i,LUA_TSTRING,0))
176 		{
177 			tolua_error(L, "#vinvalid type in lua_building_options().");
178 		}
179 
180 		strings[i - 1] =  lua_tostring(L, i);
181 	}
182 
183 	/* Print them out */
184 	print_building_options(strings, n);
185 
186 	/* Free saved pointers */
187 	FREE((vptr) strings);
188 
189 	return 0;
190 }
191 
192 
193 static const struct luaL_reg anglib[] =
194 {
195 	{"msg_print", xxx_msgf},
196 	{"msg_flush", xxx_msg_flush},
197 	{"get_aim_dir", xxx_get_aim_dir},
198 	{"fire_beam", xxx_fire_beam},
199 	{"build_script_path", xxx_build_script_path},
200 	{"get_rumor", xxx_get_rumor},
201 	{"get_rnd_line", xxx_get_rnd_line},
202 	{"building_options", xxx_building_options},
203 #ifdef RISCOS
204 	{"dofile", xxx_dofile},
205 #endif /* RISCOS */
206 };
207 
208 
209 #define MULTIADIC(name, op) \
210 	static int name(lua_State* L) \
211 	{ \
212 		int i, n = lua_gettop(L);\
213 		\
214 		int result = luaL_check_int(L, 1); \
215 		\
216 		for (i = 2; i <= n; i++)\
217 		{	\
218 			result = result op luaL_check_int(L, i); \
219 		}	\
220 		lua_pushnumber(L, result); \
221 		return 1; \
222 	}
223 
224 #define DYADIC(name, op) \
225     static int name(lua_State* L) \
226 	{ \
227         lua_pushnumber(L, luaL_check_int(L, 1) op luaL_check_int(L, 2)); \
228 		return 1; \
229     }
230 
231 #define MONADIC(name, op) \
232     static int name(lua_State* L) \
233 	{ \
234         lua_pushnumber(L, op luaL_check_int(L, 1)); \
235 		return 1; \
236     }
237 
238 
239 DYADIC(intMod,      % )
240 MULTIADIC(intAnd,      & )
241 MULTIADIC(intOr,       | )
242 DYADIC(intXor,      ^ )
243 DYADIC(intShiftl,   <<)
244 DYADIC(intShiftr,   >>)
245 MONADIC(intBitNot,  ~ )
246 
247 
math_min(lua_State * L)248 static int math_min(lua_State *L)
249 {
250 	int i;
251 
252 	/* number of arguments */
253 	int n = lua_gettop(L);
254 
255 	long dmin = luaL_check_number(L, 1);
256 
257 	for (i = 2; i <= n; i++)
258 	{
259 		long d = luaL_check_number(L, i);
260 		if (d < dmin) dmin = d;
261 	}
262 
263 	lua_pushnumber(L, dmin);
264 
265 	return 1;
266 }
267 
268 
math_max(lua_State * L)269 static int math_max(lua_State *L)
270 {
271 	int i;
272 
273 	/* number of arguments */
274 	int n = lua_gettop(L);
275 
276 	long dmax = luaL_check_number(L, 1);
277 
278 	for (i = 2; i <= n; i++)
279 	{
280 		long d = luaL_check_number(L, i);
281 		if (d > dmax) dmax = d;
282 	}
283 
284 	lua_pushnumber(L, dmax);
285 
286 	return 1;
287 }
288 
289 static const struct luaL_reg intMathLib[] =
290 {
291     {"mod",    intMod   },
292     {"bAnd",   intAnd   },
293     {"bOr",    intOr    },
294     {"bXor",   intXor   },
295     {"bNot",   intBitNot},
296     {"shiftl", intShiftl},
297     {"shiftr", intShiftr},
298 	{"min",    math_min },
299 	{"max",    math_max },
300 };
301 
302 /*
303  * Execute a piece of lua code, passing global variables and returning values.
304  *
305  * The "format" string should consist of zero or more format codes for
306  * values to pass to the script, optionally followed by a ':' and zero or more
307  * format codes for values to pass and return. Format codes are:
308  *
309  * i - an integer
310  * b - a boolean
311  * s - a string [cptr]
312  * p - a pointer to a user-defined type
313  *
314  * For 'i', 'b', and 's', the vararg list should include a cptr giving the name
315  * of the variable to pass it in, followed by a value of the correct type (if
316  * before the ':') or a pointer to a variable of the correct type (if after).
317  * The macros LUA_VAR(x) and LUA_RETURN(x) pass a variable in the appropriate
318  * form for before or after the ':' respectively.
319  *
320  * For 'p', it should include a cptr with the variable name, a cptr with the
321  * name of the type, and the pointer itself, in order.
322  *
323  * If the script returns values, they are returned in the return variables,
324  * in the order they are declared in the format. If fewer values are returned
325  * than there are returned variables, the remaining variables recieve the
326  * values they have at the end of the lua code - generally the same as was
327  * passed in, unless the lua code changed it. Any excess return values are
328  * ignored.
329  *
330  * The value returned for string arguments is always made with string_make()
331  * and should be freed with string_free() when no longer needed.
332  */
call_lua_hook(cptr script,cptr format,va_list vp)333 static bool call_lua_hook(cptr script, cptr format, va_list vp)
334 {
335 	int i, status;
336 	cptr vars[20];
337 	void *out[20];
338 	int first_return = 0;
339 
340 	int oldtop = lua_gettop(L);
341 
342 	bool success;
343 
344 	for (i = 0; format[i] && i < 20; i++)
345 	{
346 		cptr type, var;
347 
348 		switch (format[i])
349 		{
350 		case 'i':
351 			/* Get the next argument */
352 			var = va_arg(vp, cptr);
353 			vars[i] = var;
354 
355 			lua_pushnumber(L, va_arg(vp, int));
356 			lua_setglobal(L, var);
357 			break;
358 
359 		case 'b':
360 			/* Get the next argument */
361 			var = va_arg(vp, cptr);
362 			vars[i] = var;
363 
364 			tolua_pushbool(L, va_arg(vp, int));
365 			lua_setglobal(L, var);
366 			break;
367 
368 		case 's':
369 			/* Get the next argument */
370 			var = va_arg(vp, cptr);
371 			vars[i] = var;
372 
373 			tolua_pushstring(L, va_arg(vp, char *));
374 			lua_setglobal(L, var);
375 			break;
376 
377 		case 'p':
378 			/* Get the next argument */
379 			var = va_arg(vp, cptr);
380 			vars[i] = var;
381 
382 			/* Get the type */
383 			type = va_arg(vp, cptr);
384 
385 			tolua_pushusertype(L, va_arg(vp, void *), tolua_tag(L, type));
386 			lua_setglobal(L, var);
387 			break;
388 
389 		case ':':
390 			/* Start of return arguments */
391 			break;
392 		}
393 
394 		if (format[i] == ':')
395 		{
396 			i++;
397 			break;
398 		}
399 	}
400 
401 	/* Save the first return argument (or the '\0' if none) */
402 	first_return = i;
403 
404 	for (i = first_return; format[i] && i < 20; i++)
405 	{
406 		cptr var;
407 		int *ival;
408 		bool *bval;
409 		cptr *sval;
410 
411 		switch (format[i])
412 		{
413 		case 'i':
414 			/* Get the next argument */
415 			var = va_arg(vp, cptr);
416 			vars[i] = var;
417 
418 			ival = va_arg(vp, int *);
419 			out[i] = (void *)ival;
420 
421 			lua_pushnumber(L, *ival);
422 			lua_setglobal(L, var);
423 			break;
424 
425 		case 'b':
426 			/* Get the next argument */
427 			var = va_arg(vp, cptr);
428 			vars[i] = var;
429 
430 			bval = va_arg(vp, bool *);
431 			out[i] = (void *)bval;
432 
433 			tolua_pushbool(L, *bval);
434 			lua_setglobal(L, var);
435 			break;
436 
437 		case 's':
438 			/* Get the next argument */
439 			var = va_arg(vp, cptr);
440 			vars[i] = var;
441 
442 			sval = va_arg(vp, cptr *);
443 			out[i] = (void *)sval;
444 
445 			lua_pushstring(L, *sval);
446 			lua_setglobal(L, var);
447 			break;
448 
449 		default:
450 			vars[i] = NULL;
451 			out[i] = NULL;
452 			break;
453 		}
454 	}
455 
456 	status = lua_dostring(L, script);
457 
458 	if (status == 0)
459 	{
460 		int *ival;
461 		bool *bval;
462 		cptr *sval;
463 
464 		int n = 1;
465 		int top = lua_gettop(L);
466 
467 		for (i = first_return; format[i] && i < 20; i++)
468 		{
469 			int where;
470 
471 			if (top < oldtop + n)
472 			{
473 				lua_getglobal(L, vars[i]);
474 				where = -1;
475 			}
476 			else
477 				where = oldtop + n;
478 
479 			switch (format[i])
480 			{
481 			case 'i':
482 				ival = (int *)out[i];
483 				*ival = tolua_getnumber(L, where, 0);
484 				n++;
485 				break;
486 
487 			case 'b':
488 				bval = (bool *)out[i];
489 				*bval = tolua_getbool(L, where, FALSE);
490 				n++;
491 				break;
492 
493 			case 's':
494 				sval = (cptr *)out[i];
495 				*sval = string_make(tolua_getstring(L, where, ""));
496 				n++;
497 				break;
498 			}
499 		}
500 
501 		lua_settop(L, oldtop);
502 
503 		/* Worked */
504 		success = TRUE;
505 	}
506 	else
507 	{
508 		/* We failed */
509 		success = FALSE;
510 	}
511 
512 	/* Clear variables */
513 	for (i = 0; format[i] && i < 20; i++)
514 	{
515 		switch (format[i])
516 		{
517 		case 'i':
518 		case 'b':
519 		case 's':
520 		case 'p':
521 			lua_pushnil(L);
522 			lua_setglobal(L, vars[i]);
523 			break;
524 		}
525 	}
526 
527 	/* Done */
528 	return (success);
529 }
530 
531 /*
532  * Apply an object trigger, a small lua script which can be attached to an
533  * object type or a specific item (usually an ego-item or artifact).
534  *
535  * Currently defined triggers, and their normal arguments, include:
536  *
537  * TRIGGER_USE - for activating a wearable item or using any other item.
538  * Wearable items neither take nor return values. Other items may or may not
539  * have a 'dir' value, depending on type, and may return 'result' and 'ident'
540  * which indicate if the action used a charge and if it should identify the
541  * object, respectively.
542  *
543  * TRIGGER_MAKE - called once near the end of object generation. Takes one
544  * argument, 'lev', which is the level the object is being generated at for
545  * non-artifacts and the level of the artifact for artifacts.
546  *
547  * TRIGGER_BONUS - called on worn items during calc_bonuses(). No arguments.
548  *
549  * TRIGGER_SMASH - called for potions when they break.
550  *
551  * TRIGGER_DESC - called to get an activation/use description for an item.
552  * Returns a string describing the activation or use.
553  */
apply_object_trigger(int trigger_id,object_type * o_ptr,cptr format,...)554 void apply_object_trigger(int trigger_id, object_type *o_ptr, cptr format, ...)
555 {
556 	va_list vp;
557 
558 	object_kind *k_ptr = &k_info[o_ptr->k_idx];
559 
560 	cptr script = NULL;
561 
562 	void *q_ptr = NULL;
563 
564 	bool success;
565 
566 	if (o_ptr->trigger[trigger_id])
567 		script = quark_str(o_ptr->trigger[trigger_id]);
568 	else if (k_ptr->trigger[trigger_id])
569 		script = k_text + k_ptr->trigger[trigger_id];
570 	else
571 		return;
572 
573 	/* Save parameter so recursion works. */
574 	lua_getglobal (L, "object");
575 	if (tolua_istype(L, -1, tolua_tag(L, "object_type"), 0))
576 	{
577 		q_ptr = tolua_getuserdata(L, -1, NULL);
578 	}
579 	lua_pop(L,1);
580 
581 	/* Set parameters (really global) */
582 	tolua_pushusertype(L, (void*)o_ptr, tolua_tag(L, "object_type"));
583 	lua_setglobal(L, "object");
584 
585 	/* Begin the Varargs Stuff */
586 	va_start(vp, format);
587 
588 	success = call_lua_hook(script, format, vp);
589 
590 	/* End the Varargs Stuff */
591 	va_end(vp);
592 
593 	/* Restore global so recursion works*/
594 	tolua_pushusertype(L, q_ptr, tolua_tag(L,"object_type"));
595 	lua_setglobal(L, "object");
596 
597 	/* Paranoia */
598 	if (!success)
599 	{
600 		msgf("Script for object: %v failed.", OBJECT_STORE_FMT(o_ptr, FALSE, 3));
601 	}
602 }
603 
604 /*
605  * Callback for using an object
606  *
607  * If the object is a scroll of identify this function may have a side effect.
608  * The side effect is that the o_ptr no longer points at the scroll of identity
609  * because of the sorting done by the identify_spell.
610  * This side effect is countered in do_cmd_read_scroll_aux, the only place where
611  * it matters.
612  */
use_object(object_type * o_ptr,bool * id_return,int dir)613 bool use_object(object_type *o_ptr, bool *id_return, int dir)
614 {
615 	bool result = TRUE, ident = *id_return;
616 
617 	apply_object_trigger(TRIGGER_USE, o_ptr, "i:bb",
618 			LUA_VAR(dir), LUA_RETURN(result), LUA_RETURN(ident));
619 
620 	*id_return = ident;
621 	return result;
622 }
623 
624 static bool field_delete = FALSE;
625 
626 /*
627  * Delete current field when finish processing.
628  *
629  * This is a horrible name...
630  */
deleteme(void)631 void deleteme(void)
632 {
633 	field_delete = TRUE;
634 }
635 
636 /*
637  * Apply an field trigger, a small lua script which does
638  * what the old field action functions did.
639  */
apply_field_trigger(cptr script,field_type * f_ptr,cptr format,va_list vp)640 bool apply_field_trigger(cptr script, field_type *f_ptr, cptr format, va_list vp)
641 {
642 	field_thaum *t_ptr = &t_info[f_ptr->t_idx];
643 
644 	void *q_ptr = NULL;
645 
646 	bool success;
647 	bool delete_save, delete;
648 
649 	/* Save parameter so recursion works. */
650 	lua_getglobal (L, "field");
651 	if (tolua_istype(L, -1, tolua_tag(L, "field_type"), 0))
652 	{
653 		q_ptr = tolua_getuserdata(L, -1, NULL);
654 	}
655 	lua_pop(L,1);
656 	delete_save = field_delete;
657 
658 	/* Default to no deletion */
659 	field_delete = FALSE;
660 
661 	/* Set parameters (really global) */
662 	tolua_pushusertype(L, (void*)f_ptr, tolua_tag(L, "field_type"));
663 	lua_setglobal(L, "field");
664 
665 	success = call_lua_hook(script, format, vp);
666 
667 	/* Restore global so recursion works*/
668 	tolua_pushusertype(L, q_ptr, tolua_tag(L,"field_type"));
669 	lua_setglobal(L, "field");
670 	delete = field_delete;
671 	field_delete = delete_save;
672 
673 	/* Paranoia */
674 	if (!success)
675 	{
676 		msgf("Script for field: %s failed.", t_ptr->name);
677 	}
678 
679 	/* Does the field want to be deleted? */
680 	return (delete);
681 }
682 
683 
684 /*
685  * Apply an field trigger, a small lua script which does
686  * what the old field action functions did.
687  *
688  * This version doesn't modify the field, but uses a copy instead.
689  * This allows const versions of field hooks.
690  *
691  * The field cannot be deleted.
692  */
const_field_trigger(cptr script,const field_type * f_ptr,cptr format,va_list vp)693 void const_field_trigger(cptr script, const field_type *f_ptr, cptr format, va_list vp)
694 {
695 	/* Structure copy to get local working version */
696 	field_type temp_field = *f_ptr;
697 
698 	(void) apply_field_trigger(script, &temp_field, format, vp);
699 }
700 
line_hook(lua_State * L,lua_Debug * ar)701 static void line_hook(lua_State *L, lua_Debug *ar)
702 {
703 	int j;
704 
705 	/* Scan windows */
706 	for (j = 0; j < ANGBAND_TERM_MAX; j++)
707 	{
708 		term *old = Term;
709 
710 		/* No window */
711 		if (!angband_term[j]) continue;
712 
713 		/* No relevant flags */
714 		if (window_flag[j] & PW_SCRIPT_SOURCE)
715 		{
716 			/* Activate */
717 			Term_activate(angband_term[j]);
718 
719 			lua_getstack(L, 0, ar);
720 			lua_getinfo(L, "S", ar);
721 			show_file(ar->source + 1, ar->short_src, ar->currentline - 1, 1);
722 
723 			/* Fresh */
724 			Term_fresh();
725 
726 			/* Restore */
727 			Term_activate(old);
728 		}
729 		else if (window_flag[j] & PW_SCRIPT_VARS)
730 		{
731 			char buf[1024];
732 
733 			/* Activate */
734 			Term_activate(angband_term[j]);
735 
736 			path_make(buf, ANGBAND_DIR_SCRIPT, "trace.lua");
737 
738 			/* Execute the file */
739 			script_do_file(buf);
740 
741 			/* Fresh */
742 			Term_fresh();
743 
744 			/* Restore */
745 			Term_activate(old);
746 		}
747 	}
748 }
749 
750 
script_trace_start(void)751 static void script_trace_start(void)
752 {
753 	if (!L) return;
754 
755 	lua_setlinehook(L, line_hook);
756 }
757 
758 
script_trace_stop(void)759 static void script_trace_stop(void)
760 {
761 	if (!L) return;
762 
763 	lua_setlinehook(L, NULL);
764 }
765 
766 
do_cmd_script(void)767 void do_cmd_script(void)
768 {
769 	int ch;
770 	char tmp[80];
771 
772 
773 	/* Save screen */
774 	screen_save();
775 
776 	/* Clear screen */
777 	Term_clear();
778 
779 	/* Ask for a choice */
780 	prtf(0, 2, "Debug scripts");
781 
782 	/* Give some choices */
783 	prtf(5, 4, "(1) Execute a script file");
784 	prtf(5, 5, "(2) Execute a script command");
785 	prtf(5, 6, "(3) Start tracing scripts");
786 	prtf(5, 7, "(4) Stop tracing scripts");
787 	prtf(5, 8, "(5) Re-initialize scripts");
788 
789 	/* Prompt */
790 	prtf(0, 15, "Command: ");
791 
792 	/* Prompt */
793 	ch = inkey();
794 
795 	/* Load screen */
796 	screen_load();
797 
798 	switch (ch)
799 	{
800 		case '1':
801 		{
802 			char buf[1024];
803 
804 			/* Prompt */
805 			prtf(0, 0, "Lua script: ");
806 
807 			/* Default filename */
808 			sprintf(tmp, "test.lua");
809 
810 			/* Ask for a file */
811 			if (!askfor_aux(tmp, 80)) break;
812 
813 			/* Clear the prompt */
814 			clear_msg();
815 
816 			path_make(buf, ANGBAND_DIR_SCRIPT, tmp);
817 
818 			/* Execute the file */
819 			script_do_file(buf);
820 
821 			break;
822 		}
823 		case '2':
824 		{
825 			/* Prompt */
826 			prtf(0, 0, "Lua command: ");
827 
828 			/* Empty default */
829 			tmp[0] = 0;
830 
831 			/* Ask for a command */
832 			if (!askfor_aux(tmp, 80)) break;
833 
834 			/* Clear the prompt */
835 			clear_msg();
836 
837 			/* Execute the command */
838 			script_do_string(tmp);
839 
840 			break;
841 		}
842 		case '3':
843 		{
844 			script_trace_start();
845 
846 			break;
847 		}
848 		case '4':
849 		{
850 			script_trace_stop();
851 
852 			break;
853 		}
854 		case '5':
855 		{
856 			char buf[1024];
857 
858 			/* Initialization code */
859 			path_make(buf, ANGBAND_DIR_SCRIPT, "init.lua");
860 			script_do_file(buf);
861 
862 			break;
863 		}
864 	}
865 }
866 
867 
868 extern int tolua_player_open(lua_State* tolua_S);
869 extern void tolua_player_close(lua_State* tolua_S);
870 extern int tolua_object_open(lua_State* tolua_S);
871 extern void tolua_object_close(lua_State* tolua_S);
872 extern int tolua_monst_open(lua_State* tolua_S);
873 extern void tolua_monst_close(lua_State* tolua_S);
874 extern int tolua_random_open(lua_State* tolua_S);
875 extern void tolua_random_close(lua_State* tolua_S);
876 extern int tolua_ui_open(lua_State* tolua_S);
877 extern void tolua_ui_close(lua_State* tolua_S);
878 extern int tolua_misc_open(lua_State* tolua_S);
879 extern void tolua_misc_close(lua_State* tolua_S);
880 extern int tolua_spell_open(lua_State* tolua_S);
881 extern void tolua_spell_close(lua_State* tolua_S);
882 extern int tolua_field_open(lua_State* tolua_S);
883 extern void tolua_field_close(lua_State* tolua_S);
884 
885 
886 /*
887  * Initialize scripting support
888  */
script_init(void)889 errr script_init(void)
890 {
891 	char buf[1024];
892 
893 	/* Start the interpreter with default stack size */
894 	L = lua_open(0);
895 
896 	/* Register the Lua base libraries */
897 	lua_baselibopen(L);
898 	lua_strlibopen(L);
899 	lua_dblibopen(L);
900 
901 	/* Register library with binary functions */
902 	luaL_openl(L, intMathLib);
903 
904 	/* Register the Angband base library */
905 	luaL_openl(L, anglib);
906 
907 	/* Register various Angband libraries */
908 	tolua_player_open(L);
909 	tolua_object_open(L);
910 	tolua_monst_open(L);
911 	tolua_random_open(L);
912 	tolua_ui_open(L);
913 	tolua_misc_open(L);
914 	tolua_spell_open(L);
915 	tolua_field_open(L);
916 
917 	/* Initialization code */
918 	path_make(buf, ANGBAND_DIR_SCRIPT, "init.lua");
919 	script_do_file(buf);
920 
921 	return 0;
922 }
923 
924 
script_free(void)925 errr script_free(void)
926 {
927 	if (L)
928 	{
929 		lua_close(L);
930 		return 0;
931 	}
932 	else
933 	{
934 		/* Error */
935 		return -1;
936 	}
937 }
938 
939 
script_do_string(cptr script)940 bool script_do_string(cptr script)
941 {
942 	if (!L) return FALSE;
943 
944 	if (!lua_dostring(L, script)) return TRUE;
945 
946 	return FALSE;
947 }
948 
949 
script_do_file(cptr filename)950 bool script_do_file(cptr filename)
951 {
952 	if (!L) return FALSE;
953 #ifdef RISCOS
954 	{
955 		char *realname = riscosify_name(filename);
956 		if (!lua_dofile(L, realname)) return TRUE;
957 	}
958 #else /* RISCOS */
959 	if (!lua_dofile(L, filename)) return TRUE;
960 #endif /* RISCOS */
961 
962 	return FALSE;
963 }
964 
965 /*
966  * Does the player have a certain resistance?
967  */
player_res(u32b flag)968 bool player_res(u32b flag)
969 {
970 	return ((p_ptr->flags[1] & flag) ? TRUE : FALSE);
971 }
972 
973 
974 /*
975  * Debug lua stack overflow
976  */
977 #include "lua/lstate.h"
debug_lua_stack(void)978 void debug_lua_stack(void)
979 {
980 	/* Need interpreter */
981 	if (!L) return;
982 
983 	msgf("Current stack depth: %d", L->stack_last - L->top);
984 }
985