1 /* $Id$ */
2 /* File: lua_bind.c */
3 
4 /* Purpose: various lua bindings */
5 
6 /*
7  * Copyright (c) 2001 DarkGod
8  *
9  * This software may be copied and distributed for educational, research, and
10  * not for profit purposes provided that this copyright and statement are
11  * included in all such copies.
12  */
13 
14 /* added this for consistency in some (unrelated) header-inclusion,
15    it IS a server file, isn't it? */
16 #define SERVER
17 
18 #include "angband.h"
19 
20 #if 0
21 /*
22  * Get a new magic type
23  */
24 magic_power *new_magic_power(int num)
25 {
26 	magic_power *m_ptr;
27 	C_MAKE(m_ptr, num, magic_power);
28 	return (m_ptr);
29 }
30 magic_power *grab_magic_power(magic_power *m_ptr, int num)
31 {
32 	return (&m_ptr[num]);
33 }
34 static char *magic_power_info_lua_fct;
35 static void magic_power_info_lua(char *p, int power)
36 {
37 	int oldtop = lua_gettop(L);
38 
39 	lua_getglobal(L, magic_power_info_lua_fct);
40 	tolua_pushnumber(L, power);
41 	lua_call(L, 1, 1);
42 	strcpy(p, lua_tostring(L, -1));
43 	lua_settop(L, oldtop);
44 }
45 int get_magic_power_lua(int *sn, magic_power *powers, int max_powers, char *info_fct, int plev, int cast_stat)
46 {
47 	magic_power_info_lua_fct = info_fct;
48 	return (get_magic_power(sn, powers, max_powers, magic_power_info_lua, plev, cast_stat));
49 }
50 
51 bool lua_spell_success(magic_power *spell, int stat, char *oups_fct)
52 {
53 	int             chance;
54 	int             minfail = 0;
55 
56 	/* Spell failure chance */
57 	chance = spell->fail;
58 
59 	/* Reduce failure rate by "effective" level adjustment */
60 	chance -= 3 * (p_ptr->lev - spell->min_lev);
61 
62 	/* Reduce failure rate by INT/WIS adjustment */
63 	chance -= 3 * (adj_mag_stat[p_ptr->stat_ind[stat]] - 1);
64 
65 	/* Not enough mana to cast */
66 	if (spell->mana_cost > p_ptr->csp) {
67 		chance += 5 * (spell->mana_cost - p_ptr->csp);
68 	}
69 
70 	/* Extract the minimum failure rate */
71         minfail = adj_mag_fail[p_ptr->stat_ind[stat]];
72 
73 	/* Minimum failure rate */
74 	if (chance < minfail) chance = minfail;
75 
76 	/* Stunning makes spells harder */
77 	if (p_ptr->stun > 50) chance += 25;
78 	else if (p_ptr->stun) chance += 15;
79 
80 	/* Always a 5 percent chance of working */
81 	if (chance > 95) chance = 95;
82 
83 	/* Failed spell */
84 	if (rand_int(100) < chance) {
85 		if (flush_failure) flush();
86 		msg_print("You failed to concentrate hard enough!");
87 #ifdef USE_SOUND_2010
88 #else
89 		sound(SOUND_FAIL);
90 #endif
91 
92 		if (oups_fct != NULL)
93 			exec_lua(format("%s(%d)", oups_fct, chance));
94 		return (FALSE);
95 	}
96 	return (TRUE);
97 }
98 
99 /*
100  * Create objects
101  */
102 object_type *new_object()
103 {
104 	object_type *o_ptr;
105 	MAKE(o_ptr, object_type);
106 	return (o_ptr);
107 }
108 
109 void end_object(object_type *o_ptr)
110 {
111 	FREE(o_ptr, object_type);
112 }
113 
114 /*
115  * Powers
116  */
117 s16b    add_new_power(cptr name, cptr desc, cptr gain, cptr lose, byte level, byte cost, byte stat, byte diff)
118 {
119 	/* Increase the size */
120 	reinit_powers_type(power_max + 1);
121 
122 	/* Copy the strings */
123 	C_MAKE(powers_type[power_max - 1].name, strlen(name) + 1, char);
124 	strcpy(powers_type[power_max - 1].name, name);
125 	C_MAKE(powers_type[power_max - 1].desc_text, strlen(desc) + 1, char);
126 	strcpy(powers_type[power_max - 1].desc_text, desc);
127 	C_MAKE(powers_type[power_max - 1].gain_text, strlen(gain) + 1, char);
128 	strcpy(powers_type[power_max - 1].gain_text, gain);
129 	C_MAKE(powers_type[power_max - 1].lose_text, strlen(lose) + 1, char);
130 	strcpy(powers_type[power_max - 1].lose_text, lose);
131 
132 	/* Copy the other stuff */
133 	powers_type[power_max - 1].level = level;
134 	powers_type[power_max - 1].cost = cost;
135 	powers_type[power_max - 1].stat = stat;
136 	powers_type[power_max - 1].diff = diff;
137 
138 	return (power_max - 1);
139 }
140 
141 static char *lua_item_tester_fct;
142 static bool lua_item_tester(object_type* o_ptr)
143 {
144 	int oldtop = lua_gettop(L);
145 	bool ret;
146 
147 	lua_getglobal(L, lua_item_tester_fct);
148 	tolua_pushusertype(L, o_ptr, tolua_tag(L, "object_type"));
149 	lua_call(L, 1, 1);
150 	ret = lua_tonumber(L, -1);
151 	lua_settop(L, oldtop);
152 	return (ret);
153 }
154 
155 void    lua_set_item_tester(int tval, char *fct)
156 {
157 	if (tval) {
158 		item_tester_tval = tval;
159 	} else {
160 		lua_item_tester_fct = fct;
161 		item_tester_hook = lua_item_tester;
162 	}
163 }
164 
165 char *lua_object_desc(object_type *o_ptr, int pref, int mode)
166 {
167 	static char buf[150];
168 
169 	object_desc(buf, o_ptr, pref, mode);
170 	return (buf);
171 }
172 
173 /*
174  * Monsters
175  */
176 
177 void find_position(int y, int x, int *yy, int *xx)
178 {
179 	int attempts = 500;
180 
181 	do {
182 		scatter(yy, xx, y, x, 6, 0);
183 	} while (!(in_bounds(*yy, *xx) && cave_floor_bold(*yy, *xx)) && --attempts);
184 }
185 
186 static char *summon_lua_okay_fct;
187 bool summon_lua_okay(int r_idx)
188 {
189 	int oldtop = lua_gettop(L);
190 	bool ret;
191 
192 	lua_getglobal(L, lua_item_tester_fct);
193 	tolua_pushnumber(L, r_idx);
194 	lua_call(L, 1, 1);
195 	ret = lua_tonumber(L, -1);
196 	lua_settop(L, oldtop);
197 	return (ret);
198 }
199 
200 bool lua_summon_monster(int y, int x, int lev, bool friend, char *fct)
201 {
202 	summon_lua_okay_fct = fct;
203 
204 	if (!friend)
205 		return summon_specific(y, x, lev, SUMMON_LUA, 1, 0);
206 	else
207 		return summon_specific_friendly(y, x, lev, SUMMON_LUA, TRUE);
208 }
209 
210 /*
211  * Quests
212  */
213 s16b add_new_quest(char *name)
214 {
215 	int i;
216 
217 	/* Increase the size */
218 	reinit_quests(max_xo_idx + 1);
219 	quest[max_xo_idx - 1].type = HOOK_TYPE_LUA;
220 	strncpy(quest[max_xo_idx - 1].name, name, 39);
221 
222 	for (i = 0; i < 10; i++)
223 		strncpy(quest[max_xo_idx - 1].desc[i], "", 39);
224 
225 	return (max_xo_idx - 1);
226 }
227 
228 void desc_quest(int q_idx, int d, char *desc)
229 {
230 	if (d >= 0 && d < 10)
231 		strncpy(quest[q_idx].desc[d], desc, 79);
232 }
233 
234 /*
235  * Misc
236  */
237 bool get_com_lua(cptr prompt, int *com)
238 {
239 	char c;
240 
241 	if (!get_com(prompt, &c)) return (FALSE);
242 	*com = c;
243 	return (TRUE);
244 }
245 #endif	// 0
246 
247 /* Spell schools */
new_school(int i,cptr name,s16b skill)248 s16b new_school(int i, cptr name, s16b skill)
249 {
250 	schools[i].name = string_make(name);
251 	schools[i].skill = skill;
252 	return (i);
253 }
254 
new_spell(int i,cptr name)255 s16b new_spell(int i, cptr name)
256 {
257 	school_spells[i].name = string_make(name);
258 	school_spells[i].level = 0;
259 	school_spells[i].level = 0;
260 	return (i);
261 }
262 
grab_spell_type(s16b num)263 spell_type *grab_spell_type(s16b num)
264 {
265 	return (&school_spells[num]);
266 }
267 
grab_school_type(s16b num)268 school_type *grab_school_type(s16b num)
269 {
270 	return (&schools[num]);
271 }
272 
273 /* Change this fct if I want to switch to learnable spells */
lua_get_level(int Ind,s32b s,s32b lvl,s32b max,s32b min,s32b bonus)274 s32b lua_get_level(int Ind, s32b s, s32b lvl, s32b max, s32b min, s32b bonus)
275 {
276 	player_type *p_ptr = Players[Ind];
277 	s32b tmp;
278 
279 	tmp = lvl - ((school_spells[s].skill_level - 1) * (SKILL_STEP / 10));
280 	lvl = (tmp * (max * (SKILL_STEP / 10)) / (SKILL_MAX / 10)) / (SKILL_STEP / 10);
281 	if (lvl < min) lvl = min;
282 	else if (lvl > 0) {
283 //		tmp += p_ptr->to_s * (SKILL_STEP / 10);
284 		tmp += bonus;
285 //		  tmp += (get_skill_scale(p_ptr, SKILL_SPELL, 20) * (SKILL_STEP / 10));
286 //		  tmp /= 100; tmp *= (100 + (get_skill_scale(p_ptr, SKILL_SPELL, 40) * (SKILL_STEP / 10)));
287 		lvl = (tmp * (max * (SKILL_STEP / 10)) / (SKILL_MAX / 10)) / (SKILL_STEP / 10);
288 		if (school_spells[s].spell_power) {
289 			lvl *= (100 + get_skill_scale(p_ptr, SKILL_SPELL, 40));
290 			lvl /= 100;
291 		}
292 	}
293 	return lvl;
294 }
295 
296 /* adj_mag_stat? stat_ind??  pfft */
297 //s32b lua_spell_chance(s32b chance, int level, int skill_level, int mana, int cur_mana, int stat)
298 /* NOTE: KEEP CONSISTENT WITH CLIENT-SIDE lua_bind.c:lua_spell_chance()! */
lua_spell_chance(int i,s32b chance,int level,int skill_level,int mana,int cur_mana,int stat)299 s32b lua_spell_chance(int i, s32b chance, int level, int skill_level, int mana, int cur_mana, int stat)
300 {
301 	player_type *p_ptr = Players[i];
302 	int             minfail;
303 
304 //DEBUG:s_printf("chance %d - level %d - skill_level %d", chance, level, skill_level);
305 	/* correct LUA overflow bug ('fail' is type char, ie unsigned byte) */
306 	if (chance >= 156) chance -= 256;
307 
308 #if 0 /* requires client-side modification too, so I'm moving it into s_aux.lua instead - C. Blue */
309 	/* hack - -99 means 'never fails'. This is used for 'stop' spells that
310 	   turn off durational spells that have been cast, like Wraithform,
311 	   and also don't cost any mana to "cast". - C. Blue */
312 	if (chance == -99) return(0);
313 #endif
314 
315 	/* Reduce failure rate by "effective" level adjustment */
316 	chance -= 3 * (level - skill_level);
317 
318 	/* Reduce failure rate by INT/WIS adjustment */
319 	chance -= 3 * (adj_mag_stat[p_ptr->stat_ind[stat]] - 1);
320 
321 	 /* Not enough mana to cast */
322 	if (chance < 0) chance = 0;
323 #if 0 /* you cannot cast the spell anyway, so this just confuses */
324 	if (mana > cur_mana) {
325 		chance += 15 * (mana - cur_mana);
326 	}
327 #endif
328 
329 	/* Extract the minimum failure rate */
330 	minfail = adj_mag_fail[p_ptr->stat_ind[stat]];
331 
332 #if 0	// disabled for the time being
333 	/*
334 	 * Non mage characters never get too good
335 	 */
336 	if (!(PRACE_FLAG(PR1_ZERO_FAIL))) {
337 		if (minfail < 5) minfail = 5;
338 	}
339 
340 	/* Hack -- Priest prayer penalty for "edged" weapons  -DGK */
341 	if ((forbid_non_blessed()) && (p_ptr->icky_wield)) chance += 25;
342 #endif	// 0
343 
344 	/* Minimum failure rate */
345 	if (chance < minfail) chance = minfail;
346 
347 	/* Stunning makes spells harder */
348 	if (p_ptr->stun > 50) chance += 25;
349 	else if (p_ptr->stun) chance += 15;
350 
351 	/* Always a 5 percent chance of working */
352 	if (chance > 95) chance = 95;
353 
354 	/* Return the chance */
355 	return (chance);
356 }
357 
358 #if 0
359 /* Cave */
360 cave_type *lua_get_cave(int y, int x)
361 {
362 	return (&(cave[y][x]));
363 }
364 
365 void set_target(int y, int x)
366 {
367 	target_who = -1;
368 	target_col = x;
369 	target_row = y;
370 }
371 
372 /* Level gen */
373 void get_map_size(char *name, int *ysize, int *xsize)
374 {
375 	*xsize = 0;
376 	*ysize = 0;
377 	init_flags = INIT_GET_SIZE;
378 	process_dungeon_file_full = TRUE;
379 	process_dungeon_file(name, ysize, xsize, cur_hgt, cur_wid, TRUE);
380 	process_dungeon_file_full = FALSE;
381 
382 }
383 
384 void load_map(char *name, int *y, int *x)
385 {
386 	/* Set the correct monster hook */
387 	set_mon_num_hook();
388 
389 	/* Prepare allocation table */
390 	get_mon_num_prep(0, NULL);
391 
392 	init_flags = INIT_CREATE_DUNGEON;
393 	process_dungeon_file_full = TRUE;
394 	process_dungeon_file(name, y, x, cur_hgt, cur_wid, TRUE);
395 	process_dungeon_file_full = FALSE;
396 }
397 
398 bool alloc_room(int by0, int bx0, int ysize, int xsize, int *y1, int *x1, int *y2, int *x2)
399 {
400 	int xval, yval, x, y;
401 
402 	/* Try to allocate space for room.  If fails, exit */
403 	if (!room_alloc(xsize + 2, ysize + 2, FALSE, by0, bx0, &xval, &yval)) return FALSE;
404 
405 	/* Get corner values */
406 	*y1 = yval - ysize / 2;
407 	*x1 = xval - xsize / 2;
408 	*y2 = yval + (ysize) / 2;
409 	*x2 = xval + (xsize) / 2;
410 
411 	/* Place a full floor under the room */
412 	for (y = *y1 - 1; y <= *y2 + 1; y++) {
413 		for (x = *x1 - 1; x <= *x2 + 1; x++) {
414 			cave_type *c_ptr = &cave[y][x];
415 			cave_set_feat(y, x, floor_type[rand_int(1000)]);
416 			c_ptr->info |= (CAVE_ROOM);
417 			c_ptr->info |= (CAVE_GLOW);
418 		}
419 	}
420 	return TRUE;
421 }
422 
423 
424 /* Files */
425 void lua_print_hook(cptr str)
426 {
427 	fprintf(hook_file, str);
428 }
429 
430 
431 /*
432  * Finds a good random bounty monster
433  * Im too lazy to write it in lua since the lua API for monsters is not very well yet
434  */
435 
436 /*
437  * Hook for bounty monster selection.
438  */
439 static bool lua_mon_hook_bounty(int r_idx)
440 {
441 	monster_race* r_ptr = &r_info[r_idx];
442 
443 	/* Reject 'non-spawning' monsters */
444 	if (r_ptr->rarity == 255) return (FALSE);
445 
446 	/* Reject uniques */
447 	if ((r_ptr->flags1 & RF1_UNIQUE)) return (FALSE);
448 
449 	/* Reject quest NPCs */
450 	if ((r_ptr->flags1 & RF1_QUESTOR)) return (FALSE);
451 
452 	/* Reject those who cannot leave anything */
453 	if (!(r_ptr->flags9 & RF9_DROP_CORPSE)) return (FALSE);
454 
455 	/* Accept only monsters that can be generated */
456 	if ((r_ptr->flags9 & RF9_SPECIAL_GENE)) return (FALSE);
457 	if ((r_ptr->flags9 & RF9_NEVER_GENE)) return (FALSE);
458 
459 	/* Reject pets */
460 	if ((r_ptr->flags7 & RF7_PET)) return (FALSE);
461 
462 	/* Reject friendly creatures */
463 	if ((r_ptr->flags7 & RF7_FRIENDLY)) return (FALSE);
464 
465 	/* Reject neutral creatures */
466 	if ((r_ptr->flags7 & RF7_NEUTRAL)) return (FALSE);
467 
468 	/* Accept only monsters that are not breeders */
469 	if ((r_ptr->flags4 & RF4_MULTIPLY)) return (FALSE);
470 
471 	/* Forbid joke monsters */
472 	if ((r_ptr->flags8 & RF8_JOKEANGBAND)) return (FALSE);
473 
474 	/* Forbid C. Blue's monsters */
475 	if ((r_ptr->flags8 & RF8_BLUEBAND)) return (FALSE);
476 
477 	/* Accept only monsters that are not good */
478 	if ((r_ptr->flags3 & RF3_GOOD)) return (FALSE);
479 
480 	/* The rest are acceptable */
481 	return (TRUE);
482 }
483 
484 int lua_get_new_bounty_monster(int lev)
485 {
486 	int r_idx;
487 
488 	/*
489 	 * Set up the hooks -- no bounties on uniques or monsters
490 	 * with no corpses
491 	 */
492 	get_mon_num_hook = lua_mon_hook_bounty;
493 	get_mon_num_prep(0, NULL);
494 
495 	/* Set up the quest monster. */
496 	r_idx = get_mon_num(lev, lev);
497 
498 	/* Undo the filters */
499 	get_mon_num_hook = dungeon_aux;
500 
501 	return r_idx;
502 }
503 
504 #endif
505 
506 /* To do some connection magik ! */
remote_update_lua(int Ind,cptr file)507 void remote_update_lua(int Ind, cptr file)
508 {
509 	player_type *p_ptr = Players[Ind];
510 
511 	/* Count # of LUA files to check for updates (for 4.4.8.1.0.0 crash bug) */
512 	p_ptr->warning_lua_count++;
513 
514 	remote_update(p_ptr->conn, file);
515 	return;
516 }
517 
518 /* Write a string to the log file */
lua_s_print(cptr logstr)519 void lua_s_print(cptr logstr) {
520 	s_printf(logstr);
521 	return;
522 }
523 
lua_add_anote(char * anote)524 void lua_add_anote(char *anote) {
525 	int i;
526 	bracer_ff(anote); /* allow colouring */
527 	for (i = 0; i < MAX_ADMINNOTES; i++)
528 		if (!strcmp(admin_note[i], "")) break;
529 	if (i < MAX_ADMINNOTES) {
530 		strcpy(admin_note[i], anote);
531 		msg_broadcast_format(0, "\377s->MotD: %s", anote);
532 	} else {
533 		s_printf("lua_add_anote() failed: out of notes.\n");
534 	}
535 	return;
536 }
537 
lua_count_houses(int Ind)538 void lua_count_houses(int Ind) {
539 	int i;
540 	player_type *p_ptr = Players[Ind];
541 
542 	p_ptr->houses_owned = 0;
543 	p_ptr->castles_owned = 0;
544 	for (i = 0; i < num_houses; i++)
545 		if ((houses[i].dna->owner_type == OT_PLAYER) &&
546 		    (houses[i].dna->owner == p_ptr->id)) {
547 			p_ptr->houses_owned++;
548 
549 			if (cfg.houses_per_player &&
550 			    p_ptr->houses_owned > (p_ptr->max_plv >= 50 ? 50 : p_ptr->max_plv) / cfg.houses_per_player)
551 				s_printf("HOUSES_EXCEEDED: %s owns %d houses.\n", p_ptr->name, p_ptr->houses_owned);
552 
553 			if (houses[i].flags & HF_MOAT) {
554 				p_ptr->castles_owned++;
555 
556 				if (cfg.castles_per_player &&
557 				    p_ptr->castles_owned > cfg.castles_per_player)
558 					s_printf("HOUSES_EXCEEDED: %s owns %d castles.\n", p_ptr->name, p_ptr->castles_owned);
559 
560 				if (cfg.castles_for_kings && !p_ptr->once_winner)
561 					s_printf("HOUSES_EXCEEDED: non-(ex)winner %s owns castle(s).\n", p_ptr->name);
562 			}
563 		}
564 	return;
565 }
566 
567 /* keep whole function in sync with birth.c! */
lua_recalc_char(int Ind)568 void lua_recalc_char(int Ind) {
569 	player_type *p_ptr = Players[Ind];
570 	int i, j, min_value, max_value, min_value_king = 0, max_value_king = 9999;
571 	int tries = 500;
572 
573 	/* Hitdice */
574 	p_ptr->hitdie = p_ptr->rp_ptr->r_mhp + p_ptr->cp_ptr->c_mhp;
575 
576 	/* keep in sync with birth.c! */
577 #if 0
578 	/* Minimum hitpoints at highest level */
579         min_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 3) / 8;
580 	min_value += PY_MAX_LEVEL;
581 
582 	/* Maximum hitpoints at highest level */
583 	max_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 5) / 8;
584 	max_value += PY_MAX_LEVEL;
585 #endif
586 #if 0 /* 300 tries */
587 	/* Minimum hitpoints at kinging level */
588         min_value_king = (50 * (p_ptr->hitdie - 1) * 15) / 32;
589 	min_value_king += 50;
590 	/* Maximum hitpoints at kinging level */
591 	max_value_king = (50 * (p_ptr->hitdie - 1) * 17) / 32;
592 	max_value_king += 50;
593 
594 	/* Minimum hitpoints at highest level */
595         min_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 15) / 32;
596 	min_value += PY_MAX_LEVEL;
597 	/* Maximum hitpoints at highest level */
598 	max_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 17) / 32;
599 	max_value += PY_MAX_LEVEL;
600 #endif
601 #if 1
602 	/* Minimum hitpoints at kinging level */
603 	min_value_king = (50 * (p_ptr->hitdie - 1) * 31) / 64;
604 	min_value_king += 50;
605 	/* Maximum hitpoints at kinging level */
606 	max_value_king = (50 * (p_ptr->hitdie - 1) * 33) / 64;
607 	max_value_king += 50;
608 
609 	/* Minimum hitpoints at highest level */
610 	min_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 31) / 64;
611 	min_value += PY_MAX_LEVEL;
612 	/* Maximum hitpoints at highest level */
613 	max_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 33) / 64;
614 	max_value += PY_MAX_LEVEL;
615 #endif
616 
617 	/* Pre-calculate level 1 hitdice */
618 	p_ptr->player_hp[0] = p_ptr->hitdie;
619 
620 	/* Roll out the hitpoints */
621 	while (--tries) {
622 		/* Roll the hitpoint values */
623 		for (i = 1; i < PY_MAX_LEVEL; i++) {
624 //			j = randint(p_ptr->hitdie);
625 			j = 2 + randint(p_ptr->hitdie - 4);
626 			p_ptr->player_hp[i] = p_ptr->player_hp[i-1] + j;
627 		}
628 		/* XXX Could also require acceptable "mid-level" hitpoints */
629 
630 		/* Require "valid" hitpoints at kinging level */
631 		if (p_ptr->player_hp[50 - 1] < min_value_king) continue;
632 		if (p_ptr->player_hp[50 - 1] > max_value_king) continue;
633 
634 		/* Require "valid" hitpoints at highest level */
635 		if (p_ptr->player_hp[PY_MAX_LEVEL - 1] < min_value) continue;
636 		if (p_ptr->player_hp[PY_MAX_LEVEL - 1] > max_value) continue;
637 
638 		/* Acceptable */
639 		break;
640 	}
641 
642 	if (!tries) s_printf("CHAR_REROLLING: %s exceeded 500 tries for HP rolling.\n", p_ptr->name);
643 
644 	p_ptr->update |= PU_HP;
645 	update_stuff(Ind);
646 }
647 
lua_examine_item(int Ind,int Ind_target,int item)648 void lua_examine_item(int Ind, int Ind_target, int item) {
649 	identify_fully_aux(Ind, &Players[Ind_target]->inventory[item], FALSE);
650 	return;
651 }
652 
lua_determine_level_req(int Ind,int item)653 void lua_determine_level_req(int Ind, int item) {
654 	/* -9999 is a fixed hack value, see object2.c, determine_level_req.
655 	   It means: assume that finding-depth is same as object-base-level,
656 	   for smooth and easy calculation. */
657 	determine_level_req(-9999, &Players[Ind]->inventory[item]);
658 	return;
659 }
660 
661 /* the essential function for art reset */
lua_strip_true_arts_from_present_player(int Ind,int mode)662 void lua_strip_true_arts_from_present_player(int Ind, int mode) {
663 	player_type *p_ptr = Players[Ind];
664 	object_type *o_ptr;
665 	int i, total_number = 0;
666 	bool reimbursed = FALSE, gold_overflow = FALSE;
667 	s32b cost;
668 
669 	for (i = 0; i < INVEN_TOTAL; i++) {
670 		o_ptr = &p_ptr->inventory[i];
671 		if (resettable_artifact_p(o_ptr))
672 			total_number++;
673 	}
674 
675 	/* Tell the player what's going on.. */
676 	if (total_number == 1) msg_print(Ind, "\377yYour true artifact vanishes into the air!");
677 	else if (total_number == 2) msg_print(Ind, "\377yBoth of your true artifacts vanish into the air!");
678 	else if (total_number) msg_print(Ind, "\377yYour true artifacts all vanish into the air!");
679 
680 	for (i = 0; i < INVEN_TOTAL; i++) {
681 		o_ptr = &p_ptr->inventory[i];
682 		if (resettable_artifact_p(o_ptr)) {
683 			//char  o_name[ONAME_LEN];
684 			//object_desc(Ind, o_name, o_ptr, TRUE, 0);
685 			//msg_format(Ind, "%s fades into the air!", o_name);
686 
687 			/* reimburse player monetarily */
688 			cost = a_info[o_ptr->name1].cost;
689 			if (cost > 0) {
690 //				if (cost > 500000) cost = 500000; //not required, it's still fair
691 				if (gain_au(Ind, cost, gold_overflow, FALSE)) reimbursed = TRUE;
692 				else gold_overflow = TRUE;
693 			}
694 
695 			if (mode == 0) handle_art_d(o_ptr->name1);
696 
697 			/* Decrease the item, optimize. */
698 			inven_item_increase(Ind, i, -o_ptr->number);
699 			inven_item_describe(Ind, i);
700 			inven_item_optimize(Ind, i);
701 			i--;
702 		}
703 	}
704 	if (total_number) s_printf("True-art strip: %s loses %d artifact(s).\n", p_ptr->name, total_number);
705 	if (reimbursed) msg_print(Ind, "\377yYour purse magically seems heavier.");
706 }
707 
lua_check_player_for_true_arts(int Ind)708 void lua_check_player_for_true_arts(int Ind) {
709 	player_type *p_ptr = Players[Ind];
710 	object_type *o_ptr;
711 	int i, total_number = 0;
712 
713 	for (i = 0; i < INVEN_TOTAL; i++) {
714 		o_ptr = &p_ptr->inventory[i];
715 		if (true_artifact_p(o_ptr)) total_number++;
716 	}
717 	if (total_number) s_printf("True-art scan: %s carries %d.\n", p_ptr->name, total_number);
718 }
719 
lua_strip_true_arts_from_absent_players(void)720 void lua_strip_true_arts_from_absent_players(void) {
721 	strip_true_arts_from_hashed_players();
722 }
723 
724 /* Remove all true artifacts lying on the (mang-house) floor
725    anywhere in the world. Not processing traditional houses atm. */
lua_strip_true_arts_from_floors(void)726 void lua_strip_true_arts_from_floors(void) {
727 	int i, cnt = 0, dcnt = 0;
728 	object_type *o_ptr;
729 #if 0
730 	cave_type **zcave;
731 #endif
732 
733 	for (i = 0; i < o_max; i++) {
734 		o_ptr = &o_list[i];
735 		if (o_ptr->k_idx) {
736 			cnt++;
737 			/* check items on the world's floors */
738 #if 0
739 			if ((zcave = getcave(&o_ptr->wpos)) &&
740 			    resettable_artifact_p(o_ptr))
741 			{
742 				delete_object_idx(zcave[o_ptr->iy][o_ptr->ix].o_idx, TRUE);
743                                 dcnt++;
744 			}
745 #else
746 			if (resettable_artifact_p(o_ptr))
747 			{
748 				delete_object_idx(i, TRUE);
749                                 dcnt++;
750 			}
751 #endif
752 		}
753 	}
754 	s_printf("Scanned %d objects. Removed %d artefacts.\n", cnt, dcnt);
755 }
756 
757 /* Return a monster level */
lua_get_mon_lev(int r_idx)758 int lua_get_mon_lev(int r_idx) {
759 	return(r_info[r_idx].level);
760 }
761 /* Return a monster name */
lua_get_mon_name(int r_idx)762 char *lua_get_mon_name(int r_idx) {
763 	return(r_name + r_info[r_idx].name);
764 }
765 
766 /* Return the last chat line */
lua_get_last_chat_line()767 inline char *lua_get_last_chat_line() {
768 	return last_chat_line;
769 }
770 
771 /* Return the last person who said the last chat line */
lua_get_last_chat_owner()772 char *lua_get_last_chat_owner() {
773 	return last_chat_owner;
774 }
775 
776 /* Reset all towns */
lua_towns_treset(void)777 void lua_towns_treset(void) {
778 	int x, y;
779 	struct worldpos wpos;
780 
781 	wpos.wz = 0;
782 
783 	for (x = 0; x < MAX_WILD_X; x++)
784 	for (y = 0; y < MAX_WILD_Y; y++) {
785 		wpos.wx = x;
786 		wpos.wy = y;
787 		if (istown(&wpos)) {
788 			unstatic_level(&wpos);
789 			if(getcave(&wpos)) dealloc_dungeon_level(&wpos);
790 		}
791 	}
792 }
793 
794 /* To do some connection magik ! */
lua_player_exp(int level,int expfact)795 long lua_player_exp(int level, int expfact) {
796 	//s32b adv_exp;
797 	s64b adv;
798 	if ((level > 1) && (level < 100))
799 #ifndef ALT_EXPRATIO
800 	        adv = ((s64b)player_exp[level - 2] * (s64b)expfact / 100L);
801 #else
802 	        adv = (s64b)player_exp[level - 2];
803 #endif
804 	else
805 		adv = 0;
806 
807 	//adv_exp = (s32b)(adv);
808 	return adv;
809 }
810 
811 /* Fix all spellbooks not in players inventories (houses...)
812  * Adds mod to spellbook pval if it's greater than or equal to spell
813  * spell in most cases is the number of the new spell and mod is 1
814  * - mikaelh */
lua_fix_spellbooks(int spell,int mod)815 void lua_fix_spellbooks(int spell, int mod)
816 {
817 	int i, j;
818 	object_type *o_ptr;
819 	house_type *h_ptr;
820 
821 #ifndef USE_MANG_HOUSE_ONLY
822 	/* scan world (includes MAngband-style houses) */
823 	for (i = 0; i < o_max; i++) {
824 		o_ptr = &o_list[i];
825 		if (o_ptr->tval == TV_BOOK) {
826 			if (o_ptr->sval == SV_SPELLBOOK && o_ptr->pval >= spell) o_ptr->pval += mod;
827 			/* spells inside custom books */
828 			if (is_custom_tome(o_ptr->sval)) {
829 				if (o_ptr->xtra1 - 1 >= spell) o_ptr->xtra1 += mod;
830 				if (o_ptr->xtra2 - 1 >= spell) o_ptr->xtra2 += mod;
831 				if (o_ptr->xtra3 - 1 >= spell) o_ptr->xtra3 += mod;
832 				if (o_ptr->xtra4 - 1 >= spell) o_ptr->xtra4 += mod;
833 				if (o_ptr->xtra5 - 1 >= spell) o_ptr->xtra5 += mod;
834 				if (o_ptr->xtra6 - 1 >= spell) o_ptr->xtra6 += mod;
835 				if (o_ptr->xtra7 - 1 >= spell) o_ptr->xtra7 += mod;
836 				if (o_ptr->xtra8 - 1 >= spell) o_ptr->xtra8 += mod;
837 			}
838 		}
839 	}
840 #endif
841 
842 	/* scan traditional (vanilla) houses */
843 	for (j = 0; j < num_houses; j++) {
844 		h_ptr = &houses[j];
845 		for (i = 0; i < h_ptr->stock_num; i++) {
846 			o_ptr = &h_ptr->stock[i];
847 			if (!o_ptr->k_idx) continue;
848 			if (o_ptr->tval == TV_BOOK) {
849 				if (o_ptr->sval == SV_SPELLBOOK && o_ptr->pval >= spell) o_ptr->pval += mod;
850 				/* spells inside custom books */
851 				if (is_custom_tome(o_ptr->sval)) {
852 					if (o_ptr->xtra1 - 1 >= spell) o_ptr->xtra1 += mod;
853 					if (o_ptr->xtra2 - 1 >= spell) o_ptr->xtra2 += mod;
854 					if (o_ptr->xtra3 - 1 >= spell) o_ptr->xtra3 += mod;
855 					if (o_ptr->xtra4 - 1 >= spell) o_ptr->xtra4 += mod;
856 					if (o_ptr->xtra5 - 1 >= spell) o_ptr->xtra5 += mod;
857 					if (o_ptr->xtra6 - 1 >= spell) o_ptr->xtra6 += mod;
858 					if (o_ptr->xtra7 - 1 >= spell) o_ptr->xtra7 += mod;
859 					if (o_ptr->xtra8 - 1 >= spell) o_ptr->xtra8 += mod;
860 				}
861 			}
862 		}
863 	}
864 }
865 
866 /* hacked crap if above function wasn't executed properly -.- regarding custom tomes */
lua_fix_spellbooks_hackfix(int spell,int mod)867 void lua_fix_spellbooks_hackfix(int spell, int mod)
868 {
869 	int i, j;
870 	object_type *o_ptr;
871 	house_type *h_ptr;
872 
873 #ifndef USE_MANG_HOUSE_ONLY
874 	/* scan world (includes MAngband-style houses) */
875 	for (i = 0; i < o_max; i++) {
876 		o_ptr = &o_list[i];
877 		if (o_ptr->tval == TV_BOOK) {
878 			/* spells inside custom books */
879 			if (is_custom_tome(o_ptr->sval)) {
880 				if (o_ptr->xtra1 - 1 >= spell) o_ptr->xtra1 += mod;
881 				if (o_ptr->xtra2 - 1 >= spell) o_ptr->xtra2 += mod;
882 				if (o_ptr->xtra3 - 1 >= spell) o_ptr->xtra3 += mod;
883 				if (o_ptr->xtra4 - 1 >= spell) o_ptr->xtra4 += mod;
884 				if (o_ptr->xtra5 - 1 >= spell) o_ptr->xtra5 += mod;
885 				if (o_ptr->xtra6 - 1 >= spell) o_ptr->xtra6 += mod;
886 				if (o_ptr->xtra7 - 1 >= spell) o_ptr->xtra7 += mod;
887 				if (o_ptr->xtra8 - 1 >= spell) o_ptr->xtra8 += mod;
888 			}
889 		}
890 	}
891 #endif
892 
893 	/* scan traditional (vanilla) houses */
894 	for (j = 0; j < num_houses; j++) {
895 		h_ptr = &houses[j];
896 		for (i = 0; i < h_ptr->stock_num; i++) {
897 			o_ptr = &h_ptr->stock[i];
898 			if (!o_ptr->k_idx) continue;
899 			if (o_ptr->tval == TV_BOOK) {
900 				/* spells inside custom books */
901 				if (is_custom_tome(o_ptr->sval)) {
902 					if (o_ptr->xtra1 - 1 >= spell) o_ptr->xtra1 += mod;
903 					if (o_ptr->xtra2 - 1 >= spell) o_ptr->xtra2 += mod;
904 					if (o_ptr->xtra3 - 1 >= spell) o_ptr->xtra3 += mod;
905 					if (o_ptr->xtra4 - 1 >= spell) o_ptr->xtra4 += mod;
906 					if (o_ptr->xtra5 - 1 >= spell) o_ptr->xtra5 += mod;
907 					if (o_ptr->xtra6 - 1 >= spell) o_ptr->xtra6 += mod;
908 					if (o_ptr->xtra7 - 1 >= spell) o_ptr->xtra7 += mod;
909 					if (o_ptr->xtra8 - 1 >= spell) o_ptr->xtra8 += mod;
910 				}
911 			}
912 		}
913 	}
914 }
915 
916 /* This function is called after load_player, so his artifacts would already be set to 1;
917    for that reason we disable the mega-hack in load2.c instead for players whose updated_savegame
918    flag shows that they might still carry unfixed arts, and do a general incrementing here  - C. Blue */
lua_arts_fix(int Ind)919 void lua_arts_fix(int Ind) {
920 	player_type *p_ptr = Players[Ind];
921 	object_type *o_ptr;
922 	int i; //, total_number = 0;
923 
924 	for (i = 0; i < INVEN_TOTAL; i++) {
925 		o_ptr = &p_ptr->inventory[i];
926 		if (resettable_artifact_p(o_ptr))
927 			handle_art_i(o_ptr->name1);
928 	}
929 }
930 
931 /* Display a player's global_event status */
lua_get_pgestat(int Ind,int n)932 void lua_get_pgestat(int Ind, int n) {
933 	player_type *p_ptr = Players[Ind];
934 	msg_format(Ind, "%s: #%d, type %d, signup %ld, started %ld,",
935 		    p_ptr->name, n, p_ptr->global_event_type[n], (long)p_ptr->global_event_signup[n], (long)p_ptr->global_event_started[n]);
936 	msg_format(Ind, "  progress: %d,%d,%d,%d", p_ptr->global_event_progress[n][0], p_ptr->global_event_progress[n][1],
937 		    p_ptr->global_event_progress[n][2], p_ptr->global_event_progress[n][3]);
938 }
939 
lua_start_global_event(int Ind,int evtype,char * parm)940 void lua_start_global_event(int Ind, int evtype, char *parm) {
941 	start_global_event(Ind, evtype, parm);
942 }
943 
944 /* Fix items that were changed on updating the server. If Ind == 0 -> scan world/houses - C. Blue */
lua_apply_item_changes(int Ind,int changes)945 void lua_apply_item_changes(int Ind, int changes) {
946 	int i, j;
947 	object_type *o_ptr;
948 	house_type *h_ptr;
949 
950 	if (!Ind) {
951 	/* scan world/houses */
952 #ifndef USE_MANG_HOUSE_ONLY
953 		/* scan traditional (vanilla) houses */
954 		for(j = 0; j < num_houses; j++){
955 			h_ptr = &houses[j];
956 			for (i = 0; i < h_ptr->stock_num; i++){
957 				o_ptr = &h_ptr->stock[i];
958 		                if(!o_ptr->k_idx) continue;
959 				lua_apply_item_changes_aux(o_ptr, changes);
960 			}
961 		}
962 #endif
963 		/* scan world (includes MAngband-style houses) */
964 		for(i = 0; i < o_max; i++) {
965 			o_ptr = &o_list[i];
966 			if(!o_ptr->k_idx) continue;
967 			lua_apply_item_changes_aux(o_ptr, changes);
968 		}
969 	} else {
970 		/* scan a player's inventory/equipment */
971 		for (i = 0; i < INVEN_TOTAL; i++){
972 			o_ptr = &Players[Ind]->inventory[i];
973 			if (!o_ptr->k_idx) continue;
974 			lua_apply_item_changes_aux(o_ptr, changes);
975 		}
976 	}
977 }
lua_apply_item_changes_aux(object_type * o_ptr,int changes)978 void lua_apply_item_changes_aux(object_type *o_ptr, int changes) {
979 }
980 
981 /* sets LFx_ flags on the dungeon master's floor to specific values */
lua_set_floor_flags(int Ind,u32b flags)982 void lua_set_floor_flags(int Ind, u32b flags) {
983 	getfloor(&Players[Ind]->wpos)->flags1 = flags;
984 }
985 
lua_get_skill_mod(int Ind,int i)986 s32b lua_get_skill_mod(int Ind, int i) {
987 	s32b value = 0, mod = 0;
988 	player_type *p_ptr = Players[Ind];
989 	compute_skills(p_ptr, &value, &mod, i);
990 	return mod;
991 }
992 
lua_get_skill_value(int Ind,int i)993 s32b lua_get_skill_value(int Ind, int i) {
994 	s32b value = 0, mod = 0;
995 	player_type *p_ptr = Players[Ind];
996 	compute_skills(p_ptr, &value, &mod, i);
997 	return value;
998 }
999 
1000 /* fix dual-wield slot position change */
lua_fix_equip_slots(int Ind)1001 void lua_fix_equip_slots(int Ind) {
1002 	int i;
1003 	player_type *p_ptr = Players[Ind];
1004 	object_type *o_ptr;
1005 
1006 	for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
1007 		if (p_ptr->inventory[i].k_idx &&
1008 		    wield_slot(Ind, &p_ptr->inventory[i]) != i &&
1009 		    !(i == INVEN_ARM && wield_slot(Ind, &p_ptr->inventory[i]) == INVEN_WIELD)) {
1010 
1011 			/* Hack - wield_slot always returns INVEN_LEFT for rings because they're already being worn
1012 			 * This prevents the ring in the right hand from being taken off
1013 			 * - mikaelh
1014 			 */
1015 			if ((i == INVEN_RIGHT || i == INVEN_LEFT) &&
1016 			    p_ptr->inventory[i].tval == TV_RING)
1017 				continue;
1018 
1019 			bypass_inscrption = TRUE;
1020 			inven_takeoff(Ind, i, 255, FALSE);
1021 	}
1022 	bypass_inscrption = FALSE;
1023 
1024 	/* excise bugged zero-items */
1025 	/* (same as in do_cmd_refresh) */
1026 	/* Hack -- fix the inventory count */
1027 	p_ptr->inven_cnt = 0;
1028 	for (i = 0; i < INVEN_PACK; i++) {
1029 		o_ptr = &p_ptr->inventory[i];
1030 		/* Skip empty items */
1031 		if (!o_ptr->k_idx || !o_ptr->tval) {
1032 			/* hack - make sure the item is really erased - had some bugs there
1033 			   since some code parts use k_idx, and some tval, to kill/test items - C. Blue */
1034 			invwipe(o_ptr);
1035 			continue;
1036 		}
1037 		p_ptr->inven_cnt++;
1038 	}
1039 }
1040 
lua_season_change(int s,int force)1041 void lua_season_change(int s, int force) {
1042 	season_change(s, (force != 0) ? TRUE : FALSE);
1043 }
1044 
1045 #if 0 /* no pointer support / dangerous ? */
1046 /* added for changing seasons via lua cron_24h() - C. Blue */
1047 void lua_get_date(int *weekday, int *day, int *month, int *year)
1048 {
1049 	time_t		now;
1050 	struct tm	*tmp;
1051 	time(&now);
1052 	tmp = localtime(&now);
1053 	*weekday = tmp->tm_wday;
1054 	*day = tmp->tm_mday;
1055 	*month = tmp->tm_mon + 1;
1056 	*year = tmp->tm_mday;
1057 }
1058 #endif
1059 
1060 /* for Player-Customizable Tomes feature - C. Blue */
get_inven_sval(int Ind,int inven_slot)1061 int get_inven_sval(int Ind, int inven_slot) {
1062 	return (Players[Ind]->inventory[inven_slot].sval);
1063 }
get_inven_xtra(int Ind,int inven_slot,int n)1064 int get_inven_xtra(int Ind, int inven_slot, int n) {
1065 	switch (n) {
1066 	case 1: return (Players[Ind]->inventory[inven_slot].xtra1);
1067 	case 2: return (Players[Ind]->inventory[inven_slot].xtra2);
1068 	case 3: return (Players[Ind]->inventory[inven_slot].xtra3);
1069 	case 4: return (Players[Ind]->inventory[inven_slot].xtra4);
1070 	case 5: return (Players[Ind]->inventory[inven_slot].xtra5);
1071 	case 6: return (Players[Ind]->inventory[inven_slot].xtra6);
1072 	case 7: return (Players[Ind]->inventory[inven_slot].xtra7);
1073 	case 8: return (Players[Ind]->inventory[inven_slot].xtra8);
1074 	case 9: return (Players[Ind]->inventory[inven_slot].xtra9);
1075 	default: return (0); //failure
1076 	}
1077 }
1078 
1079 /* re-initialize the skill chart, keeping all values though */
1080 //#define MODIFY_DEV_STATE /* mess with expand/collapse status? might be annoying if happens on every login */
lua_fix_skill_chart(int Ind)1081 void lua_fix_skill_chart(int Ind) {
1082 	player_type *p_ptr = Players[Ind];
1083 	int i, j;
1084 
1085 #ifdef MODIFY_DEV_STATE
1086 	for (i = 0; i < MAX_SKILLS; i++)
1087 		p_ptr->s_info[i].dev = FALSE;
1088 #endif
1089 	for (i = 0; i < MAX_SKILLS; i++) {
1090 //		s32b value = 0, mod = 0;
1091 		/* Make sure all are touched */
1092 		p_ptr->s_info[i].touched = TRUE;
1093 //		compute_skills(p_ptr, &value, &mod, i);
1094 //		init_skill(p_ptr, value, mod, i);
1095 		/* pseudo-init-skill */
1096 #if 0 //SMOOTH_SKILLS
1097 		if (s_info[i].flags1 & SKF1_HIDDEN) {
1098 			p_ptr->s_info[i].hidden = TRUE;
1099 		} else {
1100 			p_ptr->s_info[i].hidden = FALSE;
1101 		}
1102 		if (s_info[i].flags1 & SKF1_DUMMY) {
1103 			p_ptr->s_info[i].dummy = TRUE;
1104 		} else {
1105 			p_ptr->s_info[i].dummy = FALSE;
1106 		}
1107 #else
1108 		p_ptr->s_info[i].flags1 = (char)(s_info[i].flags1 & 0xFF);
1109 
1110 		/* hack: Rangers can train limited Archery skill */
1111 		if (p_ptr->pclass == CLASS_RANGER && i == SKILL_ARCHERY)
1112 			p_ptr->s_info[i].flags1 |= SKF1_MAX_10;
1113 		/* hack: Druids/Vampires can't train Mimicry skill */
1114 		if ((p_ptr->pclass == CLASS_DRUID || p_ptr->prace == RACE_VAMPIRE)
1115 		    && i == SKILL_MIMIC)
1116 			p_ptr->s_info[i].flags1 |= SKF1_MAX_1;
1117 #endif
1118 		/* Develop only revelant branches */
1119 		if (p_ptr->s_info[i].value || p_ptr->s_info[i].mod) {
1120 			j = s_info[i].father;
1121 			while (j != -1) {
1122 #ifdef MODIFY_DEV_STATE
1123 				p_ptr->s_info[j].dev = TRUE;
1124 #endif
1125 				j = s_info[j].father;
1126 				if (j == 0) break;
1127 			}
1128 		}
1129 	}
1130 
1131 	/* hack - fix SKILL_STANCE skill */
1132 	if (get_skill(p_ptr, SKILL_STANCE)) {
1133 		if (p_ptr->max_plv < 50) p_ptr->s_info[SKILL_STANCE].value = p_ptr->max_plv * 1000;
1134 		else p_ptr->s_info[SKILL_STANCE].value = 50000;
1135 		/* Update the client */
1136 		Send_skill_info(Ind, SKILL_STANCE, TRUE);
1137 		/* Also update the client's 'm' menu for fighting techniques */
1138 		calc_techniques(Ind);
1139 		Send_skill_info(Ind, SKILL_TECHNIQUE, TRUE);
1140 	}
1141 
1142 	p_ptr->update |= PU_SKILL_INFO | PU_SKILL_MOD;
1143 	update_stuff(Ind);
1144 }
1145 
lua_takeoff_costumes(int Ind)1146 void lua_takeoff_costumes(int Ind) {
1147 	player_type *p_ptr = Players[Ind];
1148 
1149 	if ((p_ptr->inventory[INVEN_BODY].tval == TV_SOFT_ARMOR) && (p_ptr->inventory[INVEN_BODY].sval == SV_COSTUME)) {
1150 		bypass_inscrption = TRUE;
1151 		inven_takeoff(Ind, INVEN_BODY, 255, FALSE);
1152 		bypass_inscrption = FALSE;
1153 		msg_print(Ind, "It's not that time of the year anymore.");
1154 	}
1155 }
1156 
lua_is_unique(int r_idx)1157 bool lua_is_unique(int r_idx) {
1158 	if (r_info[r_idx].flags1 & RF1_UNIQUE) return TRUE; else return FALSE;
1159 }
1160 
1161 /* Return if a certain race/class combo could in theory learn a monster form if mimicry was high enough */
lua_mimic_eligible(int Ind,int r_idx)1162 bool lua_mimic_eligible(int Ind, int r_idx) {
1163 	/* also filter out unattainable (in theory) forms */
1164 	if (r_info[r_idx].rarity == 255) return FALSE;
1165 	if ((r_info[r_idx].flags1 & RF1_UNIQUE)) return FALSE;
1166 	if (!mon_allowed_chance(&r_info[r_idx])) return FALSE;
1167 
1168 	if (Players[Ind]->prace == RACE_VAMPIRE) {
1169 		return (mimic_vampire(r_idx, Players[Ind]->lev));
1170 	}
1171 
1172 	if (Players[Ind]->pclass == CLASS_SHAMAN) {
1173 		return (mimic_shaman(r_idx));
1174 	} else if (Players[Ind]->pclass == CLASS_DRUID) {
1175 		return (mimic_druid(r_idx, Players[Ind]->lev));
1176 	}
1177 
1178 	return TRUE;
1179 }
1180 
1181 /* Return if a monster form is considered basically humanoid, ie has all extremities required for full equipment */
lua_mimic_humanoid(int r_idx)1182 bool lua_mimic_humanoid(int r_idx) {
1183 	if (!r_info[r_idx].body_parts[BODY_WEAPON]) return FALSE;
1184 	if (r_info[r_idx].body_parts[BODY_FINGER] < 2) return FALSE;
1185 	if (!r_info[r_idx].body_parts[BODY_HEAD]) return FALSE;
1186 	if (!r_info[r_idx].body_parts[BODY_ARMS]) return FALSE;
1187 	if (!r_info[r_idx].body_parts[BODY_TORSO]) return FALSE;
1188 	if (!r_info[r_idx].body_parts[BODY_LEGS]) return FALSE;
1189 	return TRUE;
1190 }
1191 
swear_add(char * word,int level)1192 void swear_add(char *word, int level) {
1193 	int i;
1194 
1195 	for (i = 0; i < MAX_SWEAR; i++) {
1196 		if (swear[i].word[0]) continue;
1197 		strcpy(swear[i].word, word);
1198 		swear[i].level = level;
1199 		return;
1200 	}
1201 	s_printf("FAILED to add swear word '%s' (%d).\n", word, level);
1202 }
swear_get_word(int i)1203 char *swear_get_word(int i) { return swear[i].word; }
swear_get_level(int i)1204 int swear_get_level(int i) { return swear[i].level; }
1205 
nonswear_add(char * word,int affix)1206 void nonswear_add(char *word, int affix) {
1207 	int i;
1208 
1209 	for (i = 0; i < MAX_NONSWEAR; i++) {
1210 		if (nonswear[i][0]) continue;
1211 		strcpy(nonswear[i], word);
1212 		nonswear_affix[i] = affix;
1213 		return;
1214 	}
1215 	s_printf("FAILED to add non-swear word '%s'.\n", word);
1216 }
nonswear_get(int i)1217 char *nonswear_get(int i) { return nonswear[i]; }
nonswear_affix_get(int i)1218 int nonswear_affix_get(int i) { return nonswear_affix[i]; }
1219 
lua_fix_max_depth(int Ind)1220 void lua_fix_max_depth(int Ind) {
1221 	player_type *p_ptr = Players[Ind];
1222         fix_max_depth(p_ptr);
1223 }
1224 
lua_fix_max_depth_bug(int Ind)1225 void lua_fix_max_depth_bug(int Ind) {
1226 	player_type *p_ptr = Players[Ind];
1227         fix_max_depth_bug(p_ptr);
1228 }
1229 
1230 /* for use with flavour reset by '-f' */
lua_forget_flavours(int Ind)1231 void lua_forget_flavours(int Ind) {
1232 	int i;
1233         for (i = 0; i < MAX_K_IDX; i++) {
1234                 Players[Ind]->obj_aware[i] = FALSE;
1235                 Players[Ind]->obj_tried[i] = FALSE;
1236                 Players[Ind]->obj_felt[i] = FALSE;
1237                 Players[Ind]->obj_felt_heavy[i] = FALSE;
1238         }
1239 }
1240 
1241 /* for use with '-w' wilderness creation */
lua_forget_map(int Ind)1242 void lua_forget_map(int Ind) {
1243 	int i;
1244         for (i = 0; i < MAX_WILD_8; i++)
1245 		Players[Ind]->wild_map[i] = 0;
1246 }
1247 
1248 /* for resetting all party information */
lua_forget_parties(void)1249 void lua_forget_parties(void) {
1250 	int i, j;
1251 	for (i = 1; i <= NumPlayers; i++) {
1252 		Players[i]->party = 0;
1253 		clockin(i, 2);
1254 	}
1255 	for (i = 0; i < MAX_PARTIES; i++) {
1256 		parties[i].name[0] = '\0';
1257 	        parties[i].owner[0] = '\0';
1258 	        parties[i].members = 0;
1259 	        parties[i].created = 0;
1260 	        parties[i].mode = 0;
1261 	        parties[i].cmode = 0;
1262 	        parties[i].flags = 0x0;
1263 	        for (j = 0; j < BBS_LINES; j++)
1264     			pbbs_line[i][j][0] = '\0';
1265 	}
1266 }
1267 
1268 /* for resetting all guild information
1269    --note: guild halls/save files? */
lua_forget_guilds(void)1270 void lua_forget_guilds(void) {
1271 	int i, j;
1272 	for (i = 1; i <= NumPlayers; i++) {
1273 		Players[i]->guild = 0;
1274 		clockin(i, 3);
1275 	}
1276 	for (i = 0; i < MAX_GUILDS; i++) {
1277 		guilds[i].name[0] = '\0';
1278 		guilds[i].master = 0;
1279 		guilds[i].members = 0;
1280 	        guilds[i].cmode = 0;
1281 		guilds[i].flags = 0x0;
1282 		guilds[i].minlev = 0;
1283                 for (j = 0; j < 5; j++)
1284                         guilds[i].adder[j][0] = '\0';
1285 	        for (j = 0; j < BBS_LINES; j++)
1286     			gbbs_line[i][j][0] = '\0';
1287 	}
1288 }
1289