1 /* source/misc3.c: misc code for maintaining the dungeon, printing player info
2 
3    Copyright (c) 1989-94 James E. Wilson, Robert A. Koeneke
4 
5    This software may be copied and distributed for educational, research, and
6    not for profit purposes provided that this copyright and statement are
7    included in all such copies. */
8 
9 #ifdef __TURBOC__
10 #include	<stdio.h>
11 #endif
12 
13 #include "config.h"
14 #include "constant.h"
15 #include "types.h"
16 #include "externs.h"
17 
18 #include <ctype.h>
19 
20 #ifndef USG
21 #include <sys/types.h>
22 #include <sys/param.h>
23 #endif
24 
25 #ifdef USG
26 #ifndef ATARIST_MWC
27 #include <string.h>
28 #else
29 char *index();
30 #endif
31 #else
32 #include <strings.h>
33 #endif
34 
35 #if defined(LINT_ARGS)
36 static void prt_lnum(char *, int32, int, int);
37 static void prt_7lnum(char *, int32, int, int);
38 static void prt_num(char *, int, int, int);
39 static void prt_long(int32, int, int);
40 static void prt_int(int, int, int);
41 static void gain_level(void);
42 #endif
43 
44 static char *stat_names[] = { "STR : ", "INT : ", "WIS : ",
45 				 "DEX : ", "CON : ", "CHR : " };
46 #define BLANK_LENGTH	24
47 static char blank_string[] = "                        ";
48 
49 
50 /* Places a particular trap at location y, x		-RAK-	*/
place_trap(y,x,subval)51 void place_trap(y, x, subval)
52 int y, x, subval;
53 {
54   register int cur_pos;
55 
56   cur_pos = popt();
57   cave[y][x].tptr  = cur_pos;
58   invcopy(&t_list[cur_pos], OBJ_TRAP_LIST + subval);
59 }
60 
61 
62 /* Places rubble at location y, x			-RAK-	*/
place_rubble(y,x)63 void place_rubble(y, x)
64 int y, x;
65 {
66   register int cur_pos;
67   register cave_type *cave_ptr;
68 
69   cur_pos = popt();
70   cave_ptr = &cave[y][x];
71   cave_ptr->tptr = cur_pos;
72   cave_ptr->fval = BLOCKED_FLOOR;
73   invcopy(&t_list[cur_pos], OBJ_RUBBLE);
74 }
75 
76 
77 /* Places a treasure (Gold or Gems) at given row, column -RAK-	*/
place_gold(y,x)78 void place_gold(y, x)
79 int y, x;
80 {
81   register int i, cur_pos;
82 #ifdef M_XENIX
83   /* Avoid 'register' bug.  */
84   inven_type *t_ptr;
85 #else
86   register inven_type *t_ptr;
87 #endif
88 
89   cur_pos = popt();
90   i = ((randint(dun_level+2)+2) / 2) - 1;
91   if (randint(OBJ_GREAT) == 1)
92     i += randint(dun_level+1);
93   if (i >= MAX_GOLD)
94     i = MAX_GOLD - 1;
95   cave[y][x].tptr = cur_pos;
96   invcopy(&t_list[cur_pos], OBJ_GOLD_LIST+i);
97   t_ptr = &t_list[cur_pos];
98   t_ptr->cost += (8L * (long)randint((int)t_ptr->cost)) + randint(8);
99   if (cave[y][x].cptr == 1)
100     msg_print ("You feel something roll beneath your feet.");
101 }
102 
103 
104 /* Returns the array number of a random object		-RAK-	*/
get_obj_num(level,must_be_small)105 int get_obj_num(level,must_be_small)
106 int level,must_be_small;
107 {
108   register int i, j;
109 
110   if (level == 0)
111     i = randint(t_level[0]) - 1;
112   else
113     {
114       if (level >= MAX_OBJ_LEVEL)
115 	level = MAX_OBJ_LEVEL;
116       else if (randint(OBJ_GREAT) == 1)
117 	{
118 	  level = level * MAX_OBJ_LEVEL / randint (MAX_OBJ_LEVEL) + 1;
119 	  if (level > MAX_OBJ_LEVEL)
120 	    level = MAX_OBJ_LEVEL;
121 	}
122 
123       /* This code has been added to make it slightly more likely to get the
124 	 higher level objects.	Originally a uniform distribution over all
125 	 objects less than or equal to the dungeon level.  This distribution
126 	 makes a level n objects occur approx 2/n% of the time on level n,
127 	 and 1/2n are 0th level. */
128       do
129 	{
130 	  if (randint(2) == 1)
131 	    i = randint(t_level[level]) - 1;
132 	  else
133 	    /* Choose three objects, pick the highest level. */
134 	    {
135 	      i = randint(t_level[level]) - 1;
136 	      j = randint(t_level[level]) - 1;
137 	      if (i < j)
138 		i = j;
139 	      j = randint(t_level[level]) - 1;
140 	      if (i < j)
141 		i = j;
142 	      j = object_list[sorted_objects[i]].level;
143 	      if (j == 0)
144 		i = randint(t_level[0]) - 1;
145 	      else
146 		i = randint(t_level[j]-t_level[j-1]) - 1 + t_level[j-1];
147 	    }
148 	}
149       while ((must_be_small)
150 	     && (set_large(&object_list[sorted_objects[i]])));
151     }
152   return(i);
153 }
154 
155 
156 /* Places an object at given row, column co-ordinate	-RAK-	*/
place_object(y,x,must_be_small)157 void place_object(y, x, must_be_small)
158 int y, x, must_be_small;
159 {
160   register int cur_pos, tmp;
161 
162   cur_pos = popt();
163   cave[y][x].tptr = cur_pos;
164   /* split this line up to avoid a reported compiler bug */
165   tmp = get_obj_num(dun_level, must_be_small);
166   invcopy(&t_list[cur_pos], sorted_objects[tmp]);
167   magic_treasure(cur_pos, dun_level);
168   if (cave[y][x].cptr == 1)
169     msg_print ("You feel something roll beneath your feet.");	/* -CJS- */
170 }
171 
172 
173 /* Allocates an object for tunnels and rooms		-RAK-	*/
174 void alloc_object(alloc_set, typ, num)
175 int (*alloc_set)();
176 int typ, num;
177 {
178   register int i, j, k;
179 
180   for (k = 0; k < num; k++)
181     {
182       do
183 	{
184 	  i = randint(cur_height) - 1;
185 	  j = randint(cur_width) - 1;
186 	}
187       /* don't put an object beneath the player, this could cause problems
188 	 if player is standing under rubble, or on a trap */
189       while ((!(*alloc_set)(cave[i][j].fval)) ||
190 	     (cave[i][j].tptr != 0) || (i == char_row && j == char_col));
191       if (typ < 4) {	/* typ == 2 not used, used to be visible traps */
192 	if (typ == 1) place_trap(i, j, randint(MAX_TRAP)-1); /* typ == 1 */
193 	else	      place_rubble(i, j); /* typ == 3 */
194       } else {
195 	if (typ == 4) place_gold(i, j); /* typ == 4 */
196 	else	      place_object(i, j, FALSE); /* typ == 5 */
197       }
198     }
199 }
200 
201 
202 /* Creates objects nearby the coordinates given		-RAK-	*/
random_object(y,x,num)203 void random_object(y, x, num)
204 int y, x, num;
205 {
206   register int i, j, k;
207   register cave_type *cave_ptr;
208 
209   do
210     {
211       i = 0;
212       do
213 	{
214 	  j = y - 3 + randint(5);
215 	  k = x - 4 + randint(7);
216 	  cave_ptr = &cave[j][k];
217 	  if (in_bounds(j, k) && (cave_ptr->fval <= MAX_CAVE_FLOOR)
218 	      && (cave_ptr->tptr == 0))
219 	    {
220 	      if (randint(100) < 75)
221 		place_object(j, k, FALSE);
222 	      else
223 		place_gold(j, k);
224 	      i = 9;
225 	    }
226 	  i++;
227 	}
228       while(i <= 10);
229       num--;
230     }
231   while (num != 0);
232 }
233 
234 
235 /* Converts stat num into string			-RAK-	*/
cnv_stat(stat,out_val)236 void cnv_stat(stat, out_val)
237 int8u stat;
238 char *out_val;
239 {
240   register int part1, part2;
241 
242   if (stat > 18)
243     {
244       part1 = 18;
245       part2 = stat - 18;
246       if (part2 == 100)
247 	(void) strcpy(out_val, "18/100");
248       else
249 	(void) sprintf(out_val, " %2d/%02d", part1, part2);
250     }
251   else
252     (void) sprintf(out_val, "%6d", stat);
253 }
254 
255 
256 /* Print character stat in given row, column		-RAK-	*/
prt_stat(stat)257 void prt_stat(stat)
258 int stat;
259 {
260   stat_type out_val1;
261 
262   cnv_stat(py.stats.use_stat[stat], out_val1);
263   put_buffer(stat_names[stat], 6+stat, STAT_COLUMN);
264   put_buffer (out_val1, 6+stat, STAT_COLUMN+6);
265 }
266 
267 
268 /* Print character info in given row, column		-RAK-	*/
269 /* the longest title is 13 characters, so only pad to 13 */
prt_field(info,row,column)270 void prt_field(info, row, column)
271 char *info;
272 int row, column;
273 {
274   put_buffer (&blank_string[BLANK_LENGTH-13], row, column);
275   put_buffer (info, row, column);
276 }
277 
278 /* Print long number with header at given row, column */
prt_lnum(header,num,row,column)279 static void prt_lnum(header, num, row, column)
280 char *header;
281 int32 num;
282 int row, column;
283 {
284   vtype out_val;
285 
286   (void) sprintf(out_val, "%s:%7ld", header, num);
287   put_buffer(out_val, row, column);
288 }
289 
290 /* Print long number (7 digits of space) with header at given row, column */
prt_7lnum(header,num,row,column)291 static void prt_7lnum(header, num, row, column)
292 char *header;
293 int32 num;
294 int row, column;
295 {
296   vtype out_val;
297 
298   (void) sprintf(out_val, "%s: %7ld", header, num);
299   put_buffer(out_val, row, column);
300 }
301 
302 /* Print number with header at given row, column	-RAK-	*/
prt_num(header,num,row,column)303 static void prt_num(header, num, row, column)
304 char *header;
305 int num, row, column;
306 {
307   vtype out_val;
308 
309   (void) sprintf(out_val, "%s: %6d", header, num);
310   put_buffer(out_val, row, column);
311 }
312 
313 /* Print long number at given row, column */
prt_long(num,row,column)314 static void prt_long(num, row, column)
315 int32 num;
316 int row, column;
317 {
318   vtype out_val;
319 
320   (void) sprintf(out_val, "%7ld", num);
321   put_buffer(out_val, row, column);
322 }
323 
324 /* Print number at given row, column	-RAK-	*/
prt_int(num,row,column)325 static void prt_int(num, row, column)
326 int num, row, column;
327 {
328   vtype out_val;
329 
330   (void) sprintf(out_val, "%6d", num);
331   put_buffer(out_val, row, column);
332 }
333 
334 
335 /* Adjustment for wisdom/intelligence				-JWT-	*/
stat_adj(stat)336 int stat_adj(stat)
337 int stat;
338 {
339   register int value;
340 
341   value = py.stats.use_stat[stat];
342   if (value > 117)
343     return(7);
344   else if (value > 107)
345     return(6);
346   else if (value > 87)
347     return(5);
348   else if (value > 67)
349     return(4);
350   else if (value > 17)
351     return(3);
352   else if (value > 14)
353     return(2);
354   else if (value > 7)
355     return(1);
356   else
357     return(0);
358 }
359 
360 
361 /* Adjustment for charisma				-RAK-	*/
362 /* Percent decrease or increase in price of goods		 */
chr_adj()363 int chr_adj()
364 {
365   register int charisma;
366 
367   charisma = py.stats.use_stat[A_CHR];
368   if (charisma > 117)
369     return(90);
370   else if (charisma > 107)
371     return(92);
372   else if (charisma > 87)
373     return(94);
374   else if (charisma > 67)
375     return(96);
376   else if (charisma > 18)
377     return(98);
378   else
379     switch(charisma)
380       {
381       case 18:	return(100);
382       case 17:	return(101);
383       case 16:	return(102);
384       case 15:	return(103);
385       case 14:	return(104);
386       case 13:	return(106);
387       case 12:	return(108);
388       case 11:	return(110);
389       case 10:	return(112);
390       case 9:  return(114);
391       case 8:  return(116);
392       case 7:  return(118);
393       case 6:  return(120);
394       case 5:  return(122);
395       case 4:  return(125);
396       case 3:  return(130);
397       default: return(100);
398       }
399 }
400 
401 
402 /* Returns a character's adjustment to hit points	 -JWT-	 */
con_adj()403 int con_adj()
404 {
405   register int con;
406 
407   con = py.stats.use_stat[A_CON];
408   if (con < 7)
409     return(con - 7);
410   else if (con < 17)
411     return(0);
412   else if (con ==  17)
413     return(1);
414   else if (con <  94)
415     return(2);
416   else if (con < 117)
417     return(3);
418   else
419     return(4);
420 }
421 
422 
title_string()423 char *title_string()
424 {
425   register char *p;
426 
427   if (py.misc.lev < 1)
428     p = "Babe in arms";
429   else if (py.misc.lev <= MAX_PLAYER_LEVEL)
430     p = player_title[py.misc.pclass][py.misc.lev-1];
431   else if (py.misc.male)
432     p = "**KING**";
433   else
434     p = "**QUEEN**";
435   return p;
436 }
437 
438 
439 /* Prints title of character				-RAK-	*/
prt_title()440 void prt_title()
441 {
442   prt_field(title_string(), 4, STAT_COLUMN);
443 }
444 
445 
446 /* Prints level						-RAK-	*/
prt_level()447 void prt_level()
448 {
449   prt_int((int)py.misc.lev, 13, STAT_COLUMN+6);
450 }
451 
452 
453 /* Prints players current mana points.		 -RAK-	*/
prt_cmana()454 void prt_cmana()
455 {
456   prt_int(py.misc.cmana, 15, STAT_COLUMN+6);
457 }
458 
459 
460 /* Prints Max hit points				-RAK-	*/
prt_mhp()461 void prt_mhp()
462 {
463   prt_int(py.misc.mhp, 16, STAT_COLUMN+6);
464 }
465 
466 
467 /* Prints players current hit points			-RAK-	*/
prt_chp()468 void prt_chp()
469 {
470   prt_int(py.misc.chp, 17, STAT_COLUMN+6);
471 }
472 
473 
474 /* prints current AC					-RAK-	*/
prt_pac()475 void prt_pac()
476 {
477   prt_int(py.misc.dis_ac, 19, STAT_COLUMN+6);
478 }
479 
480 
481 /* Prints current gold					-RAK-	*/
prt_gold()482 void prt_gold()
483 {
484   prt_long(py.misc.au, 20, STAT_COLUMN+5);
485 }
486 
487 
488 /* Prints depth in stat area				-RAK-	*/
prt_depth()489 void prt_depth()
490 {
491   vtype depths;
492   register int depth;
493 
494   depth = dun_level*50;
495   if (depth == 0)
496     (void) strcpy(depths, "Town level");
497   else
498     (void) sprintf(depths, "%d feet", depth);
499   prt(depths, 23, 65);
500 }
501 
502 
503 /* Prints status of hunger				-RAK-	*/
prt_hunger()504 void prt_hunger()
505 {
506   if (PY_WEAK & py.flags.status)
507     put_buffer("Weak  ", 23, 0);
508   else if (PY_HUNGRY & py.flags.status)
509     put_buffer("Hungry", 23, 0);
510   else
511     put_buffer(&blank_string[BLANK_LENGTH-6], 23, 0);
512 }
513 
514 
515 /* Prints Blind status					-RAK-	*/
prt_blind()516 void prt_blind()
517 {
518   if (PY_BLIND & py.flags.status)
519     put_buffer("Blind", 23, 7);
520   else
521     put_buffer(&blank_string[BLANK_LENGTH-5], 23, 7);
522 }
523 
524 
525 /* Prints Confusion status				-RAK-	*/
prt_confused()526 void prt_confused()
527 {
528   if (PY_CONFUSED & py.flags.status)
529     put_buffer("Confused", 23, 13);
530   else
531     put_buffer(&blank_string[BLANK_LENGTH-8], 23, 13);
532 }
533 
534 
535 /* Prints Fear status					-RAK-	*/
prt_afraid()536 void prt_afraid()
537 {
538   if (PY_FEAR & py.flags.status)
539     put_buffer("Afraid", 23, 22);
540   else
541     put_buffer(&blank_string[BLANK_LENGTH-6], 23, 22);
542 }
543 
544 
545 /* Prints Poisoned status				-RAK-	*/
prt_poisoned()546 void prt_poisoned()
547 {
548   if (PY_POISONED & py.flags.status)
549     put_buffer("Poisoned", 23, 29);
550   else
551     put_buffer(&blank_string[BLANK_LENGTH-8], 23, 29);
552 }
553 
554 
555 /* Prints Searching, Resting, Paralysis, or 'count' status	-RAK-	*/
prt_state()556 void prt_state()
557 {
558   char tmp[16];
559 #ifdef ATARIST_MWC
560   int32u holder;
561 #endif
562 
563 #ifdef ATARIST_MWC
564   py.flags.status &= ~(holder = PY_REPEAT);
565 #else
566   py.flags.status &= ~PY_REPEAT;
567 #endif
568   if (py.flags.paralysis > 1)
569     put_buffer ("Paralysed", 23, 38);
570   else if (PY_REST & py.flags.status)
571     {
572       if (py.flags.rest < 0)
573 	(void) strcpy (tmp, "Rest *");
574       else if (display_counts)
575 	(void) sprintf (tmp, "Rest %-5d", py.flags.rest);
576       else
577 	(void) strcpy (tmp, "Rest");
578       put_buffer (tmp, 23, 38);
579     }
580   else if (command_count > 0)
581     {
582       if (display_counts)
583 	(void) sprintf (tmp, "Repeat %-3d", command_count);
584       else
585 	(void) strcpy (tmp, "Repeat");
586 #ifdef ATARIST_MWC
587       py.flags.status |= holder;
588 #else
589       py.flags.status |= PY_REPEAT;
590 #endif
591       put_buffer (tmp, 23, 38);
592       if (PY_SEARCH & py.flags.status)
593 	put_buffer ("Search", 23, 38);
594     }
595   else if (PY_SEARCH & py.flags.status)
596     put_buffer("Searching", 23, 38);
597   else		/* "repeat 999" is 10 characters */
598     put_buffer(&blank_string[BLANK_LENGTH-10], 23, 38);
599 }
600 
601 
602 /* Prints the speed of a character.			-CJS- */
prt_speed()603 void prt_speed ()
604 {
605   register int i;
606 
607   i = py.flags.speed;
608   if (PY_SEARCH & py.flags.status)   /* Search mode. */
609     i--;
610   if (i > 1)
611     put_buffer ("Very Slow", 23, 49);
612   else if (i == 1)
613     put_buffer ("Slow     ", 23, 49);
614   else if (i == 0)
615     put_buffer (&blank_string[BLANK_LENGTH-9], 23, 49);
616   else if (i == -1)
617     put_buffer ("Fast     ", 23, 49);
618   else
619     put_buffer ("Very Fast", 23, 49);
620 }
621 
622 
prt_study()623 void prt_study()
624 {
625 #ifdef ATARIST_MWC
626   int32u holder;
627 #endif
628 
629 #ifdef ATARIST_MWC
630   py.flags.status &= ~(holder = PY_STUDY);
631 #else
632   py.flags.status &= ~PY_STUDY;
633 #endif
634   if (py.flags.new_spells == 0)
635     put_buffer (&blank_string[BLANK_LENGTH-5], 23, 59);
636   else
637     put_buffer ("Study", 23, 59);
638 }
639 
640 
641 /* Prints winner status on display			-RAK-	*/
prt_winner()642 void prt_winner()
643 {
644   if (noscore & 0x2)
645     {
646       if (wizard)
647 	put_buffer("Is wizard  ", 22, 0);
648       else
649 	put_buffer("Was wizard ", 22, 0);
650     }
651   else if (noscore & 0x1)
652     put_buffer("Resurrected", 22, 0);
653   else if (noscore & 0x4)
654     put_buffer ("Duplicate", 22, 0);
655   else if (total_winner)
656     put_buffer("*Winner*   ", 22, 0);
657 }
658 
659 
modify_stat(stat,amount)660 int8u modify_stat (stat, amount)
661 int stat;
662 int16 amount;
663 {
664   register int loop, i;
665   register int8u tmp_stat;
666 
667   tmp_stat = py.stats.cur_stat[stat];
668   loop = (amount < 0 ? -amount : amount);
669   for (i = 0; i < loop; i++)
670     {
671       if (amount > 0)
672 	{
673 	  if (tmp_stat < 18)
674 	    tmp_stat++;
675 	  else if (tmp_stat < 108)
676 	    tmp_stat += 10;
677 	  else
678 	    tmp_stat = 118;
679 	}
680       else
681 	{
682 	  if (tmp_stat > 27)
683 	    tmp_stat -= 10;
684 	  else if (tmp_stat > 18)
685 	    tmp_stat = 18;
686 	  else if (tmp_stat > 3)
687 	    tmp_stat--;
688 	}
689     }
690   return tmp_stat;
691 }
692 
693 
694 /* Set the value of the stat which is actually used.	 -CJS- */
set_use_stat(stat)695 void set_use_stat(stat)
696 int stat;
697 {
698 #ifdef ATARIST_MWC
699   int32u holder;
700 #endif
701 
702   py.stats.use_stat[stat] = modify_stat (stat, py.stats.mod_stat[stat]);
703 
704   if (stat == A_STR)
705     {
706 #ifdef ATARIST_MWC
707       py.flags.status |= (holder = PY_STR_WGT);
708 #else
709       py.flags.status |= PY_STR_WGT;
710 #endif
711       calc_bonuses();
712     }
713   else if (stat == A_DEX)
714     calc_bonuses();
715   else if (stat == A_INT && class[py.misc.pclass].spell == MAGE)
716     {
717       calc_spells(A_INT);
718       calc_mana(A_INT);
719     }
720   else if (stat == A_WIS && class[py.misc.pclass].spell == PRIEST)
721     {
722       calc_spells(A_WIS);
723       calc_mana(A_WIS);
724     }
725   else if (stat == A_CON)
726     calc_hitpoints();
727 }
728 
729 
730 /* Increases a stat by one randomized level		-RAK-	*/
inc_stat(stat)731 int inc_stat(stat)
732 register int stat;
733 {
734   register int tmp_stat, gain;
735 
736   tmp_stat = py.stats.cur_stat[stat];
737   if (tmp_stat < 118)
738     {
739       if (tmp_stat < 18)
740 	tmp_stat++;
741       else if (tmp_stat < 116)
742 	{
743 	  /* stat increases by 1/6 to 1/3 of difference from max */
744 	  gain = ((118 - tmp_stat)/3 + 1) >> 1;
745 	  tmp_stat += randint(gain) + gain;
746 	}
747       else
748 	tmp_stat++;
749 
750       py.stats.cur_stat[stat] = tmp_stat;
751       if (tmp_stat > py.stats.max_stat[stat])
752 	py.stats.max_stat[stat] = tmp_stat;
753       set_use_stat (stat);
754       prt_stat (stat);
755       return TRUE;
756     }
757   else
758     return FALSE;
759 }
760 
761 
762 /* Decreases a stat by one randomized level		-RAK-	*/
dec_stat(stat)763 int dec_stat(stat)
764 register int stat;
765 {
766   register int tmp_stat, loss;
767 
768   tmp_stat = py.stats.cur_stat[stat];
769   if (tmp_stat > 3)
770     {
771       if (tmp_stat < 19)
772 	tmp_stat--;
773       else if (tmp_stat < 117)
774 	{
775 	  loss = (((118 - tmp_stat) >> 1) + 1) >> 1;
776 	  tmp_stat += -randint(loss) - loss;
777 	  if (tmp_stat < 18)
778 	    tmp_stat = 18;
779 	}
780       else
781 	tmp_stat--;
782 
783       py.stats.cur_stat[stat] = tmp_stat;
784       set_use_stat (stat);
785       prt_stat (stat);
786       return TRUE;
787     }
788   else
789     return FALSE;
790 }
791 
792 
793 /* Restore a stat.  Return TRUE only if this actually makes a difference. */
res_stat(stat)794 int res_stat (stat)
795 int stat;
796 {
797   register int i;
798 
799   i = py.stats.max_stat[stat] - py.stats.cur_stat[stat];
800   if (i)
801     {
802       py.stats.cur_stat[stat] += i;
803       set_use_stat (stat);
804       prt_stat (stat);
805       return TRUE;
806     }
807   return FALSE;
808 }
809 
810 /* Boost a stat artificially (by wearing something). If the display argument
811    is TRUE, then increase is shown on the screen. */
bst_stat(stat,amount)812 void bst_stat (stat, amount)
813 int stat, amount;
814 {
815 #ifdef ATARIST_MWC
816   int32u holder;
817 #endif
818 
819   py.stats.mod_stat[stat] += amount;
820 
821   set_use_stat (stat);
822   /* can not call prt_stat() here, may be in store, may be in inven_command */
823 #ifdef ATARIST_MWC
824   py.flags.status |= ((holder = PY_STR) << stat);
825 #else
826   py.flags.status |= (PY_STR << stat);
827 #endif
828 }
829 
830 
831 /* Returns a character's adjustment to hit.		 -JWT-	 */
tohit_adj()832 int tohit_adj()
833 {
834   register int total, stat;
835 
836   stat = py.stats.use_stat[A_DEX];
837   if	  (stat <   4)	total = -3;
838   else if (stat <   6)	total = -2;
839   else if (stat <   8)	total = -1;
840   else if (stat <  16)	total =	 0;
841   else if (stat <  17)	total =	 1;
842   else if (stat <  18)	total =	 2;
843   else if (stat <  69)	total =	 3;
844   else if (stat < 118)	total =	 4;
845   else			total =	 5;
846   stat = py.stats.use_stat[A_STR];
847   if	  (stat <   4)	total -= 3;
848   else if (stat <   5)	total -= 2;
849   else if (stat <   7)	total -= 1;
850   else if (stat <  18)	total -= 0;
851   else if (stat <  94)	total += 1;
852   else if (stat < 109)	total += 2;
853   else if (stat < 117)	total += 3;
854   else			total += 4;
855   return(total);
856 }
857 
858 
859 /* Returns a character's adjustment to armor class	 -JWT-	 */
toac_adj()860 int toac_adj()
861 {
862   register int stat;
863 
864   stat = py.stats.use_stat[A_DEX];
865   if	  (stat <   4)	return(-4);
866   else if (stat ==  4)	return(-3);
867   else if (stat ==  5)	return(-2);
868   else if (stat ==  6)	return(-1);
869   else if (stat <  15)	return( 0);
870   else if (stat <  18)	return( 1);
871   else if (stat <  59)	return( 2);
872   else if (stat <  94)	return( 3);
873   else if (stat < 117)	return( 4);
874   else			return( 5);
875 }
876 
877 
878 /* Returns a character's adjustment to disarm		 -RAK-	 */
todis_adj()879 int todis_adj()
880 {
881   register int stat;
882 
883   stat = py.stats.use_stat[A_DEX];
884   if	  (stat <   4)	return(-8);
885   else if (stat ==  4)	return(-6);
886   else if (stat ==  5)	return(-4);
887   else if (stat ==  6)	return(-2);
888   else if (stat ==  7)	return(-1);
889   else if (stat <  13)	return( 0);
890   else if (stat <  16)	return( 1);
891   else if (stat <  18)	return( 2);
892   else if (stat <  59)	return( 4);
893   else if (stat <  94)	return( 5);
894   else if (stat < 117)	return( 6);
895   else			return( 8);
896 }
897 
898 
899 /* Returns a character's adjustment to damage		 -JWT-	 */
todam_adj()900 int todam_adj()
901 {
902   register int stat;
903 
904   stat = py.stats.use_stat[A_STR];
905   if	  (stat <   4)	return(-2);
906   else if (stat <   5)	return(-1);
907   else if (stat <  16)	return( 0);
908   else if (stat <  17)	return( 1);
909   else if (stat <  18)	return( 2);
910   else if (stat <  94)	return( 3);
911   else if (stat < 109)	return( 4);
912   else if (stat < 117)	return( 5);
913   else			return( 6);
914 }
915 
916 
917 /* Prints character-screen info				-RAK-	*/
prt_stat_block()918 void prt_stat_block()
919 {
920   register int32u status;
921   register struct misc *m_ptr;
922   register int i;
923 
924   m_ptr = &py.misc;
925   prt_field(race[py.misc.prace].trace,	  2, STAT_COLUMN);
926   prt_field(class[py.misc.pclass].title,  3, STAT_COLUMN);
927   prt_field(title_string(),		  4, STAT_COLUMN);
928   for (i = 0; i < 6; i++)
929     prt_stat (i);
930   prt_num ("LEV ", (int)m_ptr->lev,    13, STAT_COLUMN);
931   prt_lnum("EXP ", m_ptr->exp,	       14, STAT_COLUMN);
932   prt_num ("MANA", m_ptr->cmana,	 15, STAT_COLUMN);
933   prt_num ("MHP ", m_ptr->mhp,	       16, STAT_COLUMN);
934   prt_num ("CHP ", m_ptr->chp,	 17, STAT_COLUMN);
935   prt_num ("AC  ", m_ptr->dis_ac,      19, STAT_COLUMN);
936   prt_lnum("GOLD", m_ptr->au,	       20, STAT_COLUMN);
937   prt_winner();
938   status = py.flags.status;
939   if ((PY_HUNGRY|PY_WEAK) & status)
940     prt_hunger();
941   if (PY_BLIND & status)
942     prt_blind();
943   if (PY_CONFUSED & status)
944     prt_confused();
945   if (PY_FEAR & status)
946     prt_afraid();
947   if (PY_POISONED & status)
948     prt_poisoned();
949   if ((PY_SEARCH|PY_REST) & status)
950     prt_state ();
951   /* if speed non zero, print it, modify speed if Searching */
952   if (py.flags.speed - ((PY_SEARCH & status) >> 8) != 0)
953     prt_speed ();
954   /* display the study field */
955   prt_study();
956 }
957 
958 
959 /* Draws entire screen					-RAK-	*/
draw_cave()960 void draw_cave()
961 {
962   clear_screen ();
963   prt_stat_block();
964   prt_map();
965   prt_depth();
966 }
967 
968 
969 /* Prints the following information on the screen.	-JWT-	*/
put_character()970 void put_character()
971 {
972   register struct misc *m_ptr;
973 
974   m_ptr = &py.misc;
975   clear_screen ();
976   put_buffer ("Name        :", 2, 1);
977   put_buffer ("Race        :", 3, 1);
978   put_buffer ("Sex         :", 4, 1);
979   put_buffer ("Class       :", 5, 1);
980   if (character_generated)
981     {
982       put_buffer (m_ptr->name, 2, 15);
983       put_buffer (race[m_ptr->prace].trace, 3, 15);
984       put_buffer ((m_ptr->male ? "Male" : "Female"), 4, 15);
985       put_buffer (class[m_ptr->pclass].title, 5, 15);
986     }
987 }
988 
989 
990 /* Prints the following information on the screen.	-JWT-	*/
put_stats()991 void put_stats()
992 {
993   register struct misc *m_ptr;
994   register int i;
995   vtype buf;
996 
997   m_ptr = &py.misc;
998   for (i = 0; i < 6; i++)
999     {
1000       cnv_stat (py.stats.use_stat[i], buf);
1001       put_buffer (stat_names[i], 2+i, 61);
1002       put_buffer (buf, 2+i, 66);
1003       if (py.stats.max_stat[i] > py.stats.cur_stat[i])
1004 	{
1005 	  cnv_stat (py.stats.max_stat[i], buf);
1006 	  put_buffer (buf, 2+i, 73);
1007 	}
1008     }
1009   prt_num("+ To Hit    ", m_ptr->dis_th,  9, 1);
1010   prt_num("+ To Damage ", m_ptr->dis_td, 10, 1);
1011   prt_num("+ To AC     ", m_ptr->dis_tac, 11, 1);
1012   prt_num("  Total AC  ", m_ptr->dis_ac, 12, 1);
1013 }
1014 
1015 
1016 /* Returns a rating of x depending on y			-JWT-	*/
likert(x,y)1017 char *likert(x, y)
1018 int x, y;
1019 {
1020   switch((x/y))
1021     {
1022       case -3: case -2: case -1: return("Very Bad");
1023       case 0: case 1:		 return("Bad");
1024       case 2:			 return("Poor");
1025       case 3: case 4:		 return("Fair");
1026       case  5:			 return("Good");
1027       case 6:			 return("Very Good");
1028       case 7: case 8:		 return("Excellent");
1029       default:			 return("Superb");
1030       }
1031 }
1032 
1033 
1034 /* Prints age, height, weight, and SC			-JWT-	*/
put_misc1()1035 void put_misc1()
1036 {
1037   register struct misc *m_ptr;
1038 
1039   m_ptr = &py.misc;
1040   prt_num("Age          ", (int)m_ptr->age, 2, 38);
1041   prt_num("Height       ", (int)m_ptr->ht, 3, 38);
1042   prt_num("Weight       ", (int)m_ptr->wt, 4, 38);
1043   prt_num("Social Class ", (int)m_ptr->sc, 5, 38);
1044 }
1045 
1046 
1047 /* Prints the following information on the screen.	-JWT-	*/
put_misc2()1048 void put_misc2()
1049 {
1050   register struct misc *m_ptr;
1051 
1052   m_ptr = &py.misc;
1053   prt_7lnum("Level      ", (int32)m_ptr->lev, 9, 28);
1054   prt_7lnum("Experience ", m_ptr->exp, 10, 28);
1055   prt_7lnum("Max Exp    ", m_ptr->max_exp, 11, 28);
1056   if (m_ptr->lev >= MAX_PLAYER_LEVEL)
1057     prt ("Exp to Adv.: *******", 12, 28);
1058   else
1059     prt_7lnum("Exp to Adv.", (int32)(player_exp[m_ptr->lev-1]
1060 				    * m_ptr->expfact / 100), 12, 28);
1061   prt_7lnum("Gold       ", m_ptr->au, 13, 28);
1062   prt_num("Max Hit Points ", m_ptr->mhp, 9, 52);
1063   prt_num("Cur Hit Points ", m_ptr->chp, 10, 52);
1064   prt_num("Max Mana       ", m_ptr->mana, 11, 52);
1065   prt_num("Cur Mana       ", m_ptr->cmana, 12, 52);
1066 }
1067 
1068 
1069 /* Prints ratings on certain abilities			-RAK-	*/
put_misc3()1070 void put_misc3()
1071 {
1072   int xbth, xbthb, xfos, xsrh, xstl, xdis, xsave, xdev;
1073   vtype xinfra;
1074   register struct misc *p_ptr;
1075 
1076   clear_from(14);
1077   p_ptr = &py.misc;
1078   xbth	= p_ptr->bth + p_ptr->ptohit*BTH_PLUS_ADJ
1079     + (class_level_adj[p_ptr->pclass][CLA_BTH] * p_ptr->lev);
1080   xbthb = p_ptr->bthb + p_ptr->ptohit*BTH_PLUS_ADJ
1081     + (class_level_adj[p_ptr->pclass][CLA_BTHB] * p_ptr->lev);
1082   /* this results in a range from 0 to 29 */
1083   xfos	= 40 - p_ptr->fos;
1084   if (xfos < 0)	 xfos = 0;
1085   xsrh	= p_ptr->srh;
1086   /* this results in a range from 0 to 9 */
1087   xstl	= p_ptr->stl + 1;
1088   xdis	= p_ptr->disarm + 2*todis_adj() + stat_adj(A_INT)
1089     + (class_level_adj[p_ptr->pclass][CLA_DISARM] * p_ptr->lev / 3);
1090   xsave = p_ptr->save + stat_adj(A_WIS)
1091     + (class_level_adj[p_ptr->pclass][CLA_SAVE] * p_ptr->lev / 3);
1092   xdev	= p_ptr->save + stat_adj(A_INT)
1093     + (class_level_adj[p_ptr->pclass][CLA_DEVICE] * p_ptr->lev / 3);
1094 
1095   (void) sprintf(xinfra, "%d feet", py.flags.see_infra*10);
1096 
1097   put_buffer ("(Miscellaneous Abilities)", 15, 25);
1098   put_buffer ("Fighting    :", 16, 1);
1099   put_buffer (likert (xbth, 12), 16, 15);
1100   put_buffer ("Bows/Throw  :", 17, 1);
1101   put_buffer (likert (xbthb, 12), 17, 15);
1102   put_buffer ("Saving Throw:", 18, 1);
1103   put_buffer (likert (xsave, 6), 18, 15);
1104 
1105   put_buffer ("Stealth     :", 16, 28);
1106   put_buffer (likert (xstl, 1), 16, 42);
1107   put_buffer ("Disarming   :", 17, 28);
1108   put_buffer (likert (xdis, 8), 17, 42);
1109   put_buffer ("Magic Device:", 18, 28);
1110   put_buffer (likert (xdev, 6), 18, 42);
1111 
1112   put_buffer ("Perception  :", 16, 55);
1113   put_buffer (likert (xfos, 3), 16, 69);
1114   put_buffer ("Searching   :", 17, 55);
1115   put_buffer (likert (xsrh, 6), 17, 69);
1116   put_buffer ("Infra-Vision:", 18, 55);
1117   put_buffer (xinfra, 18, 69);
1118 }
1119 
1120 
1121 /* Used to display the character on the screen.		-RAK-	*/
display_char()1122 void display_char()
1123 {
1124   put_character();
1125   put_misc1();
1126   put_stats();
1127   put_misc2();
1128   put_misc3();
1129 }
1130 
1131 
1132 /* Gets a name for the character			-JWT-	*/
get_name()1133 void get_name()
1134 {
1135   prt("Enter your player's name  [press <RETURN> when finished]", 21, 2);
1136   put_buffer (&blank_string[BLANK_LENGTH-23], 2, 15);
1137 #if defined(MAC) || defined(AMIGA)
1138   /* Force player to give a name, would be nice to get name from chooser
1139      (STR -16096), but that name might be too long */
1140   while (!get_string(py.misc.name, 2, 15, 23) || py.misc.name[0] == 0);
1141 #else
1142   if (!get_string(py.misc.name, 2, 15, 23) || py.misc.name[0] == 0)
1143     {
1144       user_name (py.misc.name);
1145       put_buffer (py.misc.name, 2, 15);
1146     }
1147 #endif
1148   clear_from (20);
1149 #ifdef MAC
1150   /* Use the new name to set save file default name. */
1151   initsavedefaults();
1152 #endif
1153 }
1154 
1155 
1156 /* Changes the name of the character			-JWT-	*/
change_name()1157 void change_name()
1158 {
1159   register char c;
1160   register int flag;
1161 #ifndef MAC
1162   vtype temp;
1163 #endif
1164 
1165   flag = FALSE;
1166   display_char();
1167   do
1168     {
1169       prt( "<f>ile character description. <c>hange character name.", 21, 2);
1170       c = inkey();
1171       switch(c)
1172 	{
1173 	case 'c':
1174 	  get_name();
1175 	  flag = TRUE;
1176 	  break;
1177 	case 'f':
1178 #ifdef MAC
1179 	  /* On mac, file_character() gets filename with std file dialog. */
1180 	  if (file_character ())
1181 	    flag = TRUE;
1182 #else
1183 	  prt ("File name:", 0, 0);
1184 	  if (get_string (temp, 0, 10, 60) && temp[0])
1185 	    if (file_character (temp))
1186 	      flag = TRUE;
1187 #endif
1188 	  break;
1189 	case ESCAPE: case ' ':
1190 	case '\n': case '\r':
1191 	  flag = TRUE;
1192 	  break;
1193 	default:
1194 	  bell ();
1195 	  break;
1196 	}
1197     }
1198   while (!flag);
1199 }
1200 
1201 
1202 /* Destroy an item in the inventory			-RAK-	*/
inven_destroy(item_val)1203 void inven_destroy(item_val)
1204 int item_val;
1205 {
1206   register int j;
1207   register inven_type *i_ptr;
1208 #ifdef ATARIST_MWC
1209   int32u holder;
1210 #endif
1211 
1212   i_ptr = &inventory[item_val];
1213   if ((i_ptr->number > 1) && (i_ptr->subval <= ITEM_SINGLE_STACK_MAX))
1214     {
1215       i_ptr->number--;
1216       inven_weight -= i_ptr->weight;
1217     }
1218   else
1219     {
1220       inven_weight -= i_ptr->weight*i_ptr->number;
1221       for (j = item_val; j < inven_ctr-1; j++)
1222 	inventory[j] = inventory[j+1];
1223       invcopy(&inventory[inven_ctr-1], OBJ_NOTHING);
1224       inven_ctr--;
1225     }
1226 #ifdef ATARIST_MWC
1227   py.flags.status |= (holder = PY_STR_WGT);
1228 #else
1229   py.flags.status |= PY_STR_WGT;
1230 #endif
1231 }
1232 
1233 
1234 /* Copies the object in the second argument over the first argument.
1235    However, the second always gets a number of one except for ammo etc. */
take_one_item(s_ptr,i_ptr)1236 void take_one_item (s_ptr, i_ptr)
1237 register inven_type *s_ptr, *i_ptr;
1238 {
1239   *s_ptr = *i_ptr;
1240   if ((s_ptr->number > 1) && (s_ptr->subval >= ITEM_SINGLE_STACK_MIN)
1241       && (s_ptr->subval <= ITEM_SINGLE_STACK_MAX))
1242     s_ptr->number = 1;
1243 }
1244 
1245 
1246 /* Drops an item from inventory to given location	-RAK-	*/
inven_drop(item_val,drop_all)1247 void inven_drop(item_val, drop_all)
1248 register int item_val, drop_all;
1249 {
1250   int i;
1251   register inven_type *i_ptr;
1252   vtype prt2;
1253   bigvtype prt1;
1254 #ifdef ATARIST_MWC
1255   int32u holder;
1256 #endif
1257 
1258   if (cave[char_row][char_col].tptr != 0)
1259     (void) delete_object(char_row, char_col);
1260   i = popt ();
1261   i_ptr = &inventory[item_val];
1262   t_list[i] = *i_ptr;
1263   cave[char_row][char_col].tptr = i;
1264 
1265   if (item_val >= INVEN_WIELD)
1266     takeoff (item_val, -1);
1267   else
1268     {
1269       if (drop_all || i_ptr->number == 1)
1270 	{
1271 	  inven_weight -= i_ptr->weight*i_ptr->number;
1272 	  inven_ctr--;
1273 	  while (item_val < inven_ctr)
1274 	    {
1275 	      inventory[item_val] = inventory[item_val+1];
1276 	      item_val++;
1277 	    }
1278 	  invcopy(&inventory[inven_ctr], OBJ_NOTHING);
1279 	}
1280       else
1281 	{
1282 	  t_list[i].number = 1;
1283 	  inven_weight -= i_ptr->weight;
1284 	  i_ptr->number--;
1285 	}
1286       objdes (prt1, &t_list[i], TRUE);
1287       (void) sprintf (prt2, "Dropped %s", prt1);
1288       msg_print (prt2);
1289     }
1290 #ifdef ATARIST_MWC
1291   py.flags.status |= (holder = PY_STR_WGT);
1292 #else
1293   py.flags.status |= PY_STR_WGT;
1294 #endif
1295 }
1296 
1297 
1298 /* Destroys a type of item on a given percent chance	-RAK-	*/
1299 int inven_damage(typ, perc)
1300 int (*typ)();
1301 register int perc;
1302 {
1303   register int i, j;
1304 
1305   j = 0;
1306   for (i = 0; i < inven_ctr; i++)
1307     if ((*typ)(&inventory[i]) && (randint(100) < perc))
1308       {
1309 	inven_destroy(i);
1310 	j++;
1311       }
1312   return(j);
1313 }
1314 
1315 
1316 /* Computes current weight limit			-RAK-	*/
weight_limit()1317 int weight_limit()
1318 {
1319   register int weight_cap;
1320 
1321   weight_cap = py.stats.use_stat[A_STR] * PLAYER_WEIGHT_CAP + py.misc.wt;
1322   if (weight_cap > 3000)  weight_cap = 3000;
1323   return(weight_cap);
1324 }
1325 
1326 
1327 /* this code must be identical to the inven_carry() code below */
inven_check_num(t_ptr)1328 int inven_check_num (t_ptr)
1329 register inven_type *t_ptr;
1330 {
1331   register int i;
1332 
1333   if (inven_ctr < INVEN_WIELD)
1334     return TRUE;
1335   else if (t_ptr->subval >= ITEM_SINGLE_STACK_MIN)
1336     for (i = 0; i < inven_ctr; i++)
1337       if (inventory[i].tval == t_ptr->tval &&
1338 	  inventory[i].subval == t_ptr->subval &&
1339 	  /* make sure the number field doesn't overflow */
1340 	  ((int)inventory[i].number + (int)t_ptr->number < 256) &&
1341 	  /* they always stack (subval < 192), or else they have same p1 */
1342 	  ((t_ptr->subval < ITEM_GROUP_MIN) || (inventory[i].p1 == t_ptr->p1))
1343 	  /* only stack if both or neither are identified */
1344 	  && (known1_p(&inventory[i]) == known1_p(t_ptr)))
1345 	return TRUE;
1346   return FALSE;
1347 }
1348 
1349 /* return FALSE if picking up an object would change the players speed */
inven_check_weight(i_ptr)1350 int inven_check_weight(i_ptr)
1351 register inven_type *i_ptr;
1352 {
1353   register int i, new_inven_weight;
1354 
1355   i = weight_limit();
1356   new_inven_weight = i_ptr->number*i_ptr->weight + inven_weight;
1357   if (i < new_inven_weight)
1358     i = new_inven_weight / (i + 1);
1359   else
1360     i = 0;
1361 
1362   if (pack_heavy != i)
1363     return FALSE;
1364   else
1365     return TRUE;
1366 }
1367 
1368 
1369 /* Are we strong enough for the current pack and weapon?  -CJS-	 */
check_strength()1370 void check_strength()
1371 {
1372   register int i;
1373   register inven_type *i_ptr;
1374 #ifdef ATARIST_MWC
1375   int32u holder;
1376 #endif
1377 
1378   i_ptr = &inventory[INVEN_WIELD];
1379   if (i_ptr->tval != TV_NOTHING
1380       && (py.stats.use_stat[A_STR]*15 < i_ptr->weight))
1381     {
1382       if (weapon_heavy == FALSE)
1383 	{
1384 	  msg_print("You have trouble wielding such a heavy weapon.");
1385 	  weapon_heavy = TRUE;
1386 	  calc_bonuses();
1387 	}
1388     }
1389   else if (weapon_heavy == TRUE)
1390     {
1391       weapon_heavy = FALSE;
1392       if (i_ptr->tval != TV_NOTHING)
1393 	msg_print("You are strong enough to wield your weapon.");
1394       calc_bonuses();
1395     }
1396   i = weight_limit();
1397   if (i < inven_weight)
1398     i = inven_weight / (i+1);
1399   else
1400     i = 0;
1401   if (pack_heavy != i)
1402     {
1403       if (pack_heavy < i)
1404 	msg_print("Your pack is so heavy that it slows you down.");
1405       else
1406 	msg_print("You move more easily under the weight of your pack.");
1407       change_speed(i - pack_heavy);
1408       pack_heavy = i;
1409     }
1410 #ifdef ATARIST_MWC
1411   py.flags.status &= ~(holder = PY_STR_WGT);
1412 #else
1413   py.flags.status &= ~PY_STR_WGT;
1414 #endif
1415 }
1416 
1417 
1418 /* Add an item to players inventory.  Return the	*/
1419 /* item position for a description if needed.	       -RAK-   */
1420 /* this code must be identical to the inven_check_num() code above */
inven_carry(i_ptr)1421 int inven_carry(i_ptr)
1422 register inven_type *i_ptr;
1423 {
1424   register int locn, i;
1425   register int typ, subt;
1426   register inven_type *t_ptr;
1427   int known1p, always_known1p;
1428 #ifdef ATARIST_MWC
1429   int32u holder;
1430 #endif
1431 
1432   typ = i_ptr->tval;
1433   subt = i_ptr->subval;
1434   known1p = known1_p (i_ptr);
1435   always_known1p = (object_offset (i_ptr) == -1);
1436   /* Now, check to see if player can carry object  */
1437   for (locn = 0; ; locn++)
1438     {
1439       t_ptr = &inventory[locn];
1440       if ((typ == t_ptr->tval) && (subt == t_ptr->subval)
1441 	  && (subt >= ITEM_SINGLE_STACK_MIN) &&
1442 	  ((int)t_ptr->number + (int)i_ptr->number < 256) &&
1443 	  ((subt < ITEM_GROUP_MIN) || (t_ptr->p1 == i_ptr->p1)) &&
1444 	  /* only stack if both or neither are identified */
1445 	  (known1p == known1_p(t_ptr)))
1446 	{
1447 	  t_ptr->number += i_ptr->number;
1448 	  break;
1449 	}
1450       /* For items which are always known1p, i.e. never have a 'color',
1451 	 insert them into the inventory in sorted order.  */
1452       else if ((typ == t_ptr->tval && subt < t_ptr->subval
1453 		&& always_known1p)
1454 	       || (typ > t_ptr->tval))
1455 	{
1456 	  for (i = inven_ctr - 1; i >= locn; i--)
1457 	    inventory[i+1] = inventory[i];
1458 	  inventory[locn] = *i_ptr;
1459 	  inven_ctr++;
1460 	  break;
1461 	}
1462     }
1463 
1464   inven_weight += i_ptr->number*i_ptr->weight;
1465 #ifdef ATARIST_MWC
1466   py.flags.status |= (holder = PY_STR_WGT);
1467 #else
1468   py.flags.status |= PY_STR_WGT;
1469 #endif
1470   return locn;
1471 }
1472 
1473 
1474 /* Returns spell chance of failure for spell		-RAK-	*/
spell_chance(spell)1475 int spell_chance(spell)
1476 int spell;
1477 {
1478   register spell_type *s_ptr;
1479   register int chance;
1480   register int stat;
1481 
1482   s_ptr = &magic_spell[py.misc.pclass-1][spell];
1483   chance = s_ptr->sfail - 3*(py.misc.lev-s_ptr->slevel);
1484   if (class[py.misc.pclass].spell == MAGE)
1485     stat = A_INT;
1486   else
1487     stat = A_WIS;
1488   chance -= 3 * (stat_adj(stat)-1);
1489   if (s_ptr->smana > py.misc.cmana)
1490     chance += 5 * (s_ptr->smana-py.misc.cmana);
1491   if (chance > 95)
1492     chance = 95;
1493   else if (chance < 5)
1494     chance = 5;
1495   return chance;
1496 }
1497 
1498 
1499 /* Print list of spells					-RAK-	*/
1500 /* if nonconsec is -1: spells numbered consecutively from 'a' to 'a'+num
1501                   >=0: spells numbered by offset from nonconsec */
print_spells(spell,num,comment,nonconsec)1502 void print_spells(spell, num, comment, nonconsec)
1503 int *spell;
1504 register int num;
1505 int comment, nonconsec;
1506 {
1507   register int i, j;
1508   vtype out_val;
1509   register spell_type *s_ptr;
1510   int col, offset;
1511   char *p;
1512   char spell_char;
1513 
1514   if (comment)
1515     col = 22;
1516   else
1517     col = 31;
1518   offset = (class[py.misc.pclass].spell==MAGE ? SPELL_OFFSET : PRAYER_OFFSET);
1519   erase_line(1, col);
1520   put_buffer("Name", 1, col+5);
1521   put_buffer("Lv Mana Fail", 1, col+35);
1522   /* only show the first 22 choices */
1523   if (num > 22)
1524     num = 22;
1525   for (i = 0; i < num; i++)
1526     {
1527       j = spell[i];
1528       s_ptr = &magic_spell[py.misc.pclass-1][j];
1529       if (comment == FALSE)
1530 	p = "";
1531       else if ((spell_forgotten & (1L << j)) != 0)
1532 	p = " forgotten";
1533       else if ((spell_learned & (1L << j)) == 0)
1534 	p = " unknown";
1535       else if ((spell_worked & (1L << j)) == 0)
1536 	p = " untried";
1537       else
1538 	p = "";
1539       /* determine whether or not to leave holes in character choices,
1540 	 nonconsec -1 when learning spells, consec offset>=0 when asking which
1541 	 spell to cast */
1542       if (nonconsec == -1)
1543 	spell_char = 'a' + i;
1544       else
1545 	spell_char = 'a' + j - nonconsec;
1546       (void) sprintf(out_val, "  %c) %-30s%2d %4d %3d%%%s", spell_char,
1547 		     spell_names[j+offset], s_ptr->slevel, s_ptr->smana,
1548 		     spell_chance (j), p);
1549       prt(out_val, 2+i, col);
1550     }
1551 }
1552 
1553 
1554 /* Returns spell pointer				-RAK-	*/
get_spell(spell,num,sn,sc,prompt,first_spell)1555 int get_spell(spell, num, sn, sc, prompt, first_spell)
1556 int *spell;
1557 register int num;
1558 register int *sn, *sc;
1559 char *prompt;
1560 int first_spell;
1561 {
1562   register spell_type *s_ptr;
1563   int flag, redraw, offset, i;
1564   char choice;
1565   vtype out_str, tmp_str;
1566 
1567   *sn = -1;
1568   flag = FALSE;
1569   (void) sprintf(out_str, "(Spells %c-%c, *=List, <ESCAPE>=exit) %s",
1570 		 spell[0]+'a'-first_spell, spell[num-1]+'a'-first_spell,
1571 		 prompt);
1572   redraw = FALSE;
1573   offset = (class[py.misc.pclass].spell==MAGE ? SPELL_OFFSET : PRAYER_OFFSET);
1574   while (flag == FALSE && get_com (out_str, &choice))
1575     {
1576       if (isupper((int)choice))
1577 	{
1578 	  *sn = choice-'A'+first_spell;
1579 	  /* verify that this is in spell[], at most 22 entries in spell[] */
1580 	  for (i = 0; i < num; i++)
1581 	    if (*sn == spell[i])
1582 	      break;
1583 	  if (i == num)
1584 	    *sn = -2;
1585 	  else
1586 	    {
1587 	      s_ptr = &magic_spell[py.misc.pclass-1][*sn];
1588 	      (void) sprintf (tmp_str, "Cast %s (%d mana, %d%% fail)?",
1589 			      spell_names[*sn+offset], s_ptr->smana,
1590 			      spell_chance (*sn));
1591 	      if (get_check (tmp_str))
1592 		flag = TRUE;
1593 	      else
1594 		*sn = -1;
1595 	    }
1596 	}
1597       else if (islower((int)choice))
1598 	{
1599 	  *sn = choice-'a'+first_spell;
1600 	  /* verify that this is in spell[], at most 22 entries in spell[] */
1601 	  for (i = 0; i < num; i++)
1602 	    if (*sn == spell[i])
1603 	      break;
1604 	  if (i == num)
1605 	    *sn = -2;
1606 	  else
1607 	    flag = TRUE;
1608 	}
1609       else if (choice == '*')
1610 	{
1611 	  /* only do this drawing once */
1612 	  if (!redraw)
1613 	    {
1614 	      save_screen ();
1615 	      redraw = TRUE;
1616 	      print_spells (spell, num, FALSE, first_spell);
1617 	    }
1618 	}
1619       else if (isalpha((int)choice))
1620 	*sn = -2;
1621       else
1622 	{
1623 	  *sn = -1;
1624 	  bell();
1625 	}
1626       if (*sn == -2)
1627 	{
1628 	  (void) sprintf (tmp_str, "You don't know that %s.",
1629 			  (offset == SPELL_OFFSET ? "spell" : "prayer"));
1630 	  msg_print(tmp_str);
1631 	}
1632     }
1633   if (redraw)
1634     restore_screen ();
1635 
1636   erase_line(MSG_LINE, 0);
1637   if (flag)
1638     *sc = spell_chance (*sn);
1639 
1640   return(flag);
1641 }
1642 
1643 
1644 /* calculate number of spells player should have, and learn forget spells
1645    until that number is met -JEW- */
calc_spells(stat)1646 void calc_spells(stat)
1647 int stat;
1648 {
1649   register int i;
1650   register int32u mask;
1651   int32u spell_flag;
1652   int j, offset;
1653   int num_allowed, new_spells, num_known, levels;
1654   vtype tmp_str;
1655   char *p;
1656   register struct misc *p_ptr;
1657   register spell_type *msp_ptr;
1658 
1659   p_ptr = &py.misc;
1660   msp_ptr = &magic_spell[p_ptr->pclass-1][0];
1661   if (stat == A_INT)
1662     {
1663       p = "spell";
1664       offset = SPELL_OFFSET;
1665     }
1666   else
1667     {
1668       p = "prayer";
1669       offset = PRAYER_OFFSET;
1670     }
1671 
1672   /* check to see if know any spells greater than level, eliminate them */
1673   for (i = 31, mask = 0x80000000L; mask; mask >>= 1, i--)
1674     if (mask & spell_learned)
1675       {
1676 	if (msp_ptr[i].slevel > p_ptr->lev)
1677 	  {
1678 	    spell_learned &= ~mask;
1679 	    spell_forgotten |= mask;
1680 	    (void) sprintf(tmp_str, "You have forgotten the %s of %s.", p,
1681 			   spell_names[i+offset]);
1682 	    msg_print(tmp_str);
1683 	  }
1684 	else
1685 	  break;
1686       }
1687 
1688   /* calc number of spells allowed */
1689   levels = p_ptr->lev - class[p_ptr->pclass].first_spell_lev + 1;
1690   switch(stat_adj(stat))
1691     {
1692     case 0:		    num_allowed = 0; break;
1693     case 1: case 2: case 3: num_allowed = 1 * levels; break;
1694     case 4: case 5:	    num_allowed = 3 * levels / 2; break;
1695     case 6:		    num_allowed = 2 * levels; break;
1696     case 7:		    num_allowed = 5 * levels / 2; break;
1697     }
1698 
1699   num_known = 0;
1700   for (mask = 0x1; mask; mask <<= 1)
1701     if (mask & spell_learned)
1702       num_known++;
1703   new_spells = num_allowed - num_known;
1704 
1705   if (new_spells > 0)
1706     {
1707       /* remember forgotten spells while forgotten spells exist of new_spells
1708 	 positive, remember the spells in the order that they were learned */
1709       for (i = 0; (spell_forgotten && new_spells
1710 		   && (i < num_allowed) && (i < 32)); i++)
1711 	{
1712 	  /* j is (i+1)th spell learned */
1713 	  j = spell_order[i];
1714 	  /* shifting by amounts greater than number of bits in long gives
1715 	     an undefined result, so don't shift for unknown spells */
1716 	  if (j == 99)
1717 	    mask = 0x0;
1718 	  else
1719 	    mask = 1L << j;
1720 	  if (mask & spell_forgotten)
1721 	    {
1722 	      if (msp_ptr[j].slevel <= p_ptr->lev)
1723 		{
1724 		  new_spells--;
1725 		  spell_forgotten &= ~mask;
1726 		  spell_learned |= mask;
1727 		  (void) sprintf(tmp_str, "You have remembered the %s of %s.",
1728 				 p, spell_names[j+offset]);
1729 		  msg_print(tmp_str);
1730 		}
1731 	      else
1732 		num_allowed++;
1733 	    }
1734 	}
1735 
1736       if (new_spells > 0)
1737 	{
1738 	  /* determine which spells player can learn */
1739 	  /* must check all spells here, in gain_spell() we actually check
1740 	     if the books are present */
1741 	  spell_flag = 0x7FFFFFFFL & ~spell_learned;
1742 
1743 	  mask = 0x1;
1744 	  i = 0;
1745 	  for (j = 0, mask = 0x1; spell_flag; mask <<= 1, j++)
1746 	    if (spell_flag & mask)
1747 	      {
1748 		spell_flag &= ~mask;
1749 		if (msp_ptr[j].slevel <= p_ptr->lev)
1750 		  i++;
1751 	      }
1752 
1753 	  if (new_spells > i)
1754 	    new_spells = i;
1755 	}
1756     }
1757   else if (new_spells < 0)
1758     {
1759       /* forget spells until new_spells zero or no more spells know, spells
1760 	 are forgotten in the opposite order that they were learned */
1761       for (i = 31; new_spells && spell_learned; i--)
1762 	{
1763 	  /* j is the (i+1)th spell learned */
1764 	  j = spell_order[i];
1765 	  /* shifting by amounts greater than number of bits in long gives
1766 	     an undefined result, so don't shift for unknown spells */
1767 	  if (j == 99)
1768 	    mask = 0x0;
1769 	  else
1770 	    mask = 1L << j;
1771 	  if (mask & spell_learned)
1772 	    {
1773 	      spell_learned &= ~mask;
1774 	      spell_forgotten |= mask;
1775 	      new_spells++;
1776 	      (void) sprintf(tmp_str, "You have forgotten the %s of %s.", p,
1777 			     spell_names[j+offset]);
1778 	      msg_print(tmp_str);
1779 	    }
1780 	}
1781 
1782       new_spells = 0;
1783     }
1784 
1785   if (new_spells != py.flags.new_spells)
1786     {
1787       if (new_spells > 0 && py.flags.new_spells == 0)
1788 	{
1789 	  (void) sprintf(tmp_str, "You can learn some new %ss now.", p);
1790 	  msg_print(tmp_str);
1791 	}
1792 
1793       py.flags.new_spells = new_spells;
1794       py.flags.status |= PY_STUDY;
1795     }
1796 }
1797 
1798 
1799 /* gain spells when player wants to		- jw */
gain_spells()1800 void gain_spells()
1801 {
1802   char query;
1803   int stat, diff_spells, new_spells;
1804   int spells[31], offset, last_known;
1805   register int i, j;
1806   register int32u spell_flag, mask;
1807   vtype tmp_str;
1808   struct misc *p_ptr;
1809   register spell_type *msp_ptr;
1810 
1811   /* Priests don't need light because they get spells from their god,
1812      so only fail when can't see if player has MAGE spells.  This check
1813      is done below.  */
1814   if (py.flags.confused > 0)
1815     {
1816       msg_print("You are too confused.");
1817       return;
1818     }
1819 
1820   new_spells = py.flags.new_spells;
1821   diff_spells = 0;
1822   p_ptr = &py.misc;
1823   msp_ptr = &magic_spell[p_ptr->pclass-1][0];
1824   if (class[p_ptr->pclass].spell == MAGE)
1825     {
1826       stat = A_INT;
1827       offset = SPELL_OFFSET;
1828 
1829       /* People with MAGE spells can't learn spells if they can't read their
1830 	 books.  */
1831       if (py.flags.blind > 0)
1832 	{
1833 	  msg_print("You can't see to read your spell book!");
1834 	  return;
1835 	}
1836       else if (no_light())
1837 	{
1838 	  msg_print("You have no light to read by.");
1839 	  return;
1840 	}
1841     }
1842   else
1843     {
1844       stat = A_WIS;
1845       offset = PRAYER_OFFSET;
1846     }
1847 
1848   for (last_known = 0; last_known < 32; last_known++)
1849     if (spell_order[last_known] == 99)
1850       break;
1851 
1852   if (!new_spells)
1853     {
1854       (void) sprintf(tmp_str, "You can't learn any new %ss!",
1855 		     (stat == A_INT ? "spell" : "prayer"));
1856       msg_print(tmp_str);
1857       free_turn_flag = TRUE;
1858     }
1859   else
1860     {
1861       /* determine which spells player can learn */
1862       /* mages need the book to learn a spell, priests do not need the book */
1863       if (stat == A_INT)
1864 	{
1865 	  spell_flag = 0;
1866 	  for (i = 0; i < inven_ctr; i++)
1867 	    if (inventory[i].tval == TV_MAGIC_BOOK)
1868 	      spell_flag |= inventory[i].flags;
1869 	}
1870       else
1871 	spell_flag = 0x7FFFFFFF;
1872 
1873       /* clear bits for spells already learned */
1874       spell_flag &= ~spell_learned;
1875 
1876       mask = 0x1;
1877       i = 0;
1878       for (j = 0, mask = 0x1; spell_flag; mask <<= 1, j++)
1879 	if (spell_flag & mask)
1880 	  {
1881 	    spell_flag &= ~mask;
1882 	    if (msp_ptr[j].slevel <= p_ptr->lev)
1883 	      {
1884 		spells[i] = j;
1885 		i++;
1886 	      }
1887 	  }
1888 
1889       if (new_spells > i)
1890 	{
1891 	  msg_print("You seem to be missing a book.");
1892 	  diff_spells = new_spells - i;
1893 	  new_spells = i;
1894 	}
1895       if (new_spells == 0)
1896 	;
1897       else if (stat == A_INT)
1898 	{
1899 	  /* get to choose which mage spells will be learned */
1900 	  save_screen();
1901 	  print_spells (spells, i, FALSE, -1);
1902 	  while (new_spells && get_com ("Learn which spell?", &query))
1903 	    {
1904 	      j = query - 'a';
1905 	      /* test j < 23 in case i is greater than 22, only 22 spells
1906 		 are actually shown on the screen, so limit choice to those */
1907 	      if (j >= 0 && j < i && j < 22)
1908 		{
1909 		  new_spells--;
1910 		  spell_learned |= 1L << spells[j];
1911 		  spell_order[last_known++] = spells[j];
1912 		  for (; j <= i-1; j++)
1913 		    spells[j] = spells[j+1];
1914 		  i--;
1915 		  erase_line (j+1, 31);
1916 		  print_spells (spells, i, FALSE, -1);
1917 		}
1918 	      else
1919 		bell();
1920 	    }
1921 	  restore_screen();
1922 	}
1923       else
1924 	{
1925 	  /* pick a prayer at random */
1926 	  while (new_spells)
1927 	    {
1928 	      j = randint(i) - 1;
1929 	      spell_learned |= 1L << spells[j];
1930 	      spell_order[last_known++] = spells[j];
1931 	      (void) sprintf (tmp_str,
1932 			      "You have learned the prayer of %s.",
1933 			      spell_names[spells[j]+offset]);
1934 	      msg_print(tmp_str);
1935 	      for (; j <= i-1; j++)
1936 		spells[j] = spells[j+1];
1937 	      i--;
1938 	      new_spells--;
1939 	    }
1940 	}
1941       py.flags.new_spells = new_spells + diff_spells;
1942       if (py.flags.new_spells == 0)
1943 	py.flags.status |= PY_STUDY;
1944       /* set the mana for first level characters when they learn their
1945 	 first spell */
1946       if (py.misc.mana == 0)
1947 	calc_mana(stat);
1948     }
1949 }
1950 
1951 
1952 /* Gain some mana if you know at least one spell	-RAK-	*/
calc_mana(stat)1953 void calc_mana(stat)
1954 int stat;
1955 {
1956   register int new_mana, levels;
1957   register struct misc *p_ptr;
1958   register int32 value;
1959 #ifdef ATARIST_MWC
1960   int32u holder;
1961 #endif
1962 
1963   p_ptr = &py.misc;
1964   if (spell_learned != 0)
1965     {
1966       levels = p_ptr->lev - class[p_ptr->pclass].first_spell_lev + 1;
1967       switch(stat_adj(stat))
1968 	{
1969 	case 0: new_mana = 0; break;
1970 	case 1: case 2: new_mana = 1 * levels; break;
1971 	case 3: new_mana = 3 * levels / 2; break;
1972 	case 4: new_mana = 2 * levels; break;
1973 	case 5: new_mana = 5 * levels / 2; break;
1974 	case 6: new_mana = 3 * levels; break;
1975 	case 7: new_mana = 4 * levels; break;
1976 	}
1977       /* increment mana by one, so that first level chars have 2 mana */
1978       if (new_mana > 0)
1979 	new_mana++;
1980 
1981       /* mana can be zero when creating character */
1982       if (p_ptr->mana != new_mana)
1983 	{
1984 	  if (p_ptr->mana != 0)
1985 	    {
1986 	      /* change current mana proportionately to change of max mana,
1987 		 divide first to avoid overflow, little loss of accuracy */
1988 	      value = (((long)p_ptr->cmana << 16) + p_ptr->cmana_frac)
1989 		/ p_ptr->mana * new_mana;
1990 	      p_ptr->cmana = value >> 16;
1991 	      p_ptr->cmana_frac = value & 0xFFFF;
1992 	    }
1993 	  else
1994 	    {
1995 	      p_ptr->cmana = new_mana;
1996 	      p_ptr->cmana_frac = 0;
1997 	    }
1998 	  p_ptr->mana = new_mana;
1999 	  /* can't print mana here, may be in store or inventory mode */
2000 #ifdef ATARIST_MWC
2001 	  py.flags.status |= (holder = PY_MANA);
2002 #else
2003 	  py.flags.status |= PY_MANA;
2004 #endif
2005 	}
2006     }
2007   else if (p_ptr->mana != 0)
2008     {
2009       p_ptr->mana = 0;
2010       p_ptr->cmana = 0;
2011       /* can't print mana here, may be in store or inventory mode */
2012 #ifdef ATARIST_MWC
2013       py.flags.status |= (holder = PY_MANA);
2014 #else
2015       py.flags.status |= PY_MANA;
2016 #endif
2017     }
2018 }
2019 
2020 
2021 /* Increases hit points and level			-RAK-	*/
gain_level()2022 static void gain_level()
2023 {
2024   register int32 dif_exp, need_exp;
2025   vtype out_val;
2026   register struct misc *p_ptr;
2027   register class_type *c_ptr;
2028 
2029   p_ptr = &py.misc;
2030   p_ptr->lev++;
2031   (void) sprintf(out_val, "Welcome to level %d.", (int)p_ptr->lev);
2032   msg_print(out_val);
2033   calc_hitpoints();
2034 
2035   need_exp = player_exp[p_ptr->lev-1] * p_ptr->expfact / 100;
2036   if (p_ptr->exp > need_exp)
2037     {
2038       /* lose some of the 'extra' exp when gaining several levels at once */
2039       dif_exp = p_ptr->exp - need_exp;
2040       p_ptr->exp = need_exp + (dif_exp / 2);
2041     }
2042   prt_level();
2043   prt_title();
2044   c_ptr = &class[p_ptr->pclass];
2045   if (c_ptr->spell == MAGE)
2046     {
2047       calc_spells(A_INT);
2048       calc_mana(A_INT);
2049     }
2050   else if (c_ptr->spell == PRIEST)
2051     {
2052       calc_spells(A_WIS);
2053       calc_mana(A_WIS);
2054     }
2055 }
2056 
2057 /* Prints experience					-RAK-	*/
prt_experience()2058 void prt_experience()
2059 {
2060   register struct misc *p_ptr;
2061 
2062   p_ptr = &py.misc;
2063   if (p_ptr->exp > MAX_EXP)
2064     p_ptr->exp = MAX_EXP;
2065 
2066   while ((p_ptr->lev < MAX_PLAYER_LEVEL) &&
2067 	 (player_exp[p_ptr->lev-1] * p_ptr->expfact / 100) <= p_ptr->exp)
2068     gain_level();
2069 
2070   if (p_ptr->exp > p_ptr->max_exp)
2071     p_ptr->max_exp = p_ptr->exp;
2072 
2073   prt_long(p_ptr->exp, 14, STAT_COLUMN+5);
2074 }
2075 
2076 
2077 /* Calculate the players hit points */
calc_hitpoints()2078 void calc_hitpoints()
2079 {
2080   register int hitpoints;
2081   register struct misc *p_ptr;
2082   register int32 value;
2083 #ifdef ATARIST_MWC
2084   int32u holder;
2085 #endif
2086 
2087   p_ptr = &py.misc;
2088   hitpoints = player_hp[p_ptr->lev-1] + (con_adj() * p_ptr->lev);
2089   /* always give at least one point per level + 1 */
2090   if (hitpoints < (p_ptr->lev + 1))
2091     hitpoints = p_ptr->lev + 1;
2092 
2093   if (py.flags.status & PY_HERO)
2094     hitpoints += 10;
2095   if (py.flags.status & PY_SHERO)
2096     hitpoints += 20;
2097 
2098   /* mhp can equal zero while character is being created */
2099   if ((hitpoints != p_ptr->mhp) && (p_ptr->mhp != 0))
2100     {
2101       /* change current hit points proportionately to change of mhp,
2102 	 divide first to avoid overflow, little loss of accuracy */
2103       value = (((long)p_ptr->chp << 16) + p_ptr->chp_frac) / p_ptr->mhp
2104 	* hitpoints;
2105       p_ptr->chp = value >> 16;
2106       p_ptr->chp_frac = value & 0xFFFF;
2107       p_ptr->mhp = hitpoints;
2108 
2109       /* can't print hit points here, may be in store or inventory mode */
2110 #ifdef ATARIST_MWC
2111       py.flags.status |= (holder = PY_HP);
2112 #else
2113       py.flags.status |= PY_HP;
2114 #endif
2115     }
2116 }
2117 
2118 
2119 /* Inserts a string into a string				*/
insert_str(object_str,mtc_str,insert)2120 void insert_str(object_str, mtc_str, insert)
2121 char *object_str, *mtc_str, *insert;
2122 {
2123   int obj_len;
2124   char *bound, *pc;
2125   register int i, mtc_len;
2126   register char *temp_obj, *temp_mtc;
2127   char out_val[80];
2128 
2129   mtc_len = strlen(mtc_str);
2130   obj_len = strlen(object_str);
2131   bound = object_str + obj_len - mtc_len;
2132   for (pc = object_str; pc <= bound; pc++)
2133     {
2134       temp_obj = pc;
2135       temp_mtc = mtc_str;
2136       for (i = 0; i < mtc_len; i++)
2137 	if (*temp_obj++ != *temp_mtc++)
2138 	  break;
2139       if (i == mtc_len)
2140 	break;
2141     }
2142 
2143   if (pc <= bound)
2144     {
2145 #ifdef __TURBOC__
2146       /* Avoid complaint about possible loss of significance.  */
2147       (void) strncpy(out_val, object_str, (size_t)(pc-object_str));
2148 #else
2149       (void) strncpy(out_val, object_str, (pc-object_str));
2150 #endif
2151       /* Turbo C needs int for array index.  */
2152       out_val[(int)(pc-object_str)] = '\0';
2153       if (insert)
2154 	(void) strcat(out_val, insert);
2155       (void) strcat(out_val, (char *)(pc+mtc_len));
2156       (void) strcpy(object_str, out_val);
2157     }
2158 }
2159 
2160 
2161 #if 0
2162 /* this is no longer used anywhere */
2163 /* Inserts a number into a string				*/
2164 void insert_num(object_str, mtc_str, number, show_sign)
2165 char *object_str;
2166 register char *mtc_str;
2167 int number;
2168 int show_sign;
2169 {
2170   int mlen;
2171   vtype str1, str2;
2172   register char *string, *tmp_str;
2173   int flag;
2174 
2175   flag = 1;
2176   mlen = strlen(mtc_str);
2177   tmp_str = object_str;
2178   do
2179     {
2180       string = index(tmp_str, mtc_str[0]);
2181       if (string == CNIL)
2182 	flag = 0;
2183       else
2184 	{
2185 	  flag = strncmp(string, mtc_str, mlen);
2186 	  if (flag)
2187 	    tmp_str = string+1;
2188 	}
2189     }
2190   while (flag);
2191   if (string)
2192     {
2193 #ifdef __TURBOC__
2194       /* Avoid complaint about possible loss of significance.  */
2195       (void) strncpy(str1, object_str, (size_t)(string - object_str));
2196 #else
2197       (void) strncpy(str1, object_str, string - object_str);
2198 #endif
2199       /* Turbo C needs int for array index.  */
2200       str1[(int)(string - object_str)] = '\0';
2201       (void) strcpy(str2, string + mlen);
2202       if ((number >= 0) && (show_sign))
2203 	(void) sprintf(object_str, "%s+%d%s", str1, number, str2);
2204       else
2205 	(void) sprintf(object_str, "%s%d%s", str1, number, str2);
2206     }
2207 }
2208 #endif
2209 
insert_lnum(object_str,mtc_str,number,show_sign)2210 void insert_lnum(object_str, mtc_str, number, show_sign)
2211 char *object_str;
2212 register char *mtc_str;
2213 int32 number;
2214 int show_sign;
2215 {
2216   int mlen;
2217   vtype str1, str2;
2218   register char *string, *tmp_str;
2219   int flag;
2220 
2221   flag = 1;
2222   mlen = strlen(mtc_str);
2223   tmp_str = object_str;
2224   do
2225     {
2226       string = index(tmp_str, mtc_str[0]);
2227       if (string == 0)
2228 	flag = 0;
2229       else
2230 	{
2231 	  flag = strncmp(string, mtc_str, mlen);
2232 	  if (flag)
2233 	    tmp_str = string+1;
2234 	}
2235     }
2236   while (flag);
2237   if (string)
2238     {
2239       (void) strncpy(str1, object_str, string - object_str);
2240       str1[string - object_str] = '\0';
2241       (void) strcpy(str2, string + mlen);
2242       if ((number >= 0) && (show_sign))
2243 	(void) sprintf(object_str, "%s+%ld%s", str1, number, str2);
2244       else
2245 	(void) sprintf(object_str, "%s%ld%s", str1, number, str2);
2246     }
2247 }
2248 
2249 
2250 /* lets anyone enter wizard mode after a disclaimer...		- JEW - */
enter_wiz_mode()2251 int enter_wiz_mode()
2252 {
2253   register int answer;
2254 
2255   if (!noscore)
2256     {
2257       msg_print("Wizard mode is for debugging and experimenting.");
2258       answer = get_check(
2259 	"The game will not be scored if you enter wizard mode. Are you sure?");
2260     }
2261   if (noscore || answer)
2262     {
2263       noscore |= 0x2;
2264       wizard = TRUE;
2265       return(TRUE);
2266     }
2267   return(FALSE);
2268 }
2269 
2270 
2271 /* Weapon weight VS strength and dexterity		-RAK-	*/
attack_blows(weight,wtohit)2272 int attack_blows(weight, wtohit)
2273 int weight;
2274 int *wtohit;
2275 {
2276   register int adj_weight;
2277   register int str_index, dex_index, s, d;
2278 
2279   s = py.stats.use_stat[A_STR];
2280   d = py.stats.use_stat[A_DEX];
2281   if (s * 15 < weight)
2282     {
2283       *wtohit = s * 15 - weight;
2284       return 1;
2285     }
2286   else
2287     {
2288       *wtohit = 0;
2289       if      (d <  10)	 dex_index = 0;
2290       else if (d <  19)	 dex_index = 1;
2291       else if (d <  68)	 dex_index = 2;
2292       else if (d < 108)	 dex_index = 3;
2293       else if (d < 118)	 dex_index = 4;
2294       else		 dex_index = 5;
2295       adj_weight = (s * 10 / weight);
2296       if      (adj_weight < 2)	str_index = 0;
2297       else if (adj_weight < 3)	str_index = 1;
2298       else if (adj_weight < 4)	str_index = 2;
2299       else if (adj_weight < 5)	str_index = 3;
2300       else if (adj_weight < 7)	str_index = 4;
2301       else if (adj_weight < 9)	str_index = 5;
2302       else			str_index = 6;
2303       return (int)blows_table[str_index][dex_index];
2304     }
2305 }
2306 
2307 
2308 /* Special damage due to magical abilities of object	-RAK-	*/
tot_dam(i_ptr,tdam,monster)2309 int tot_dam(i_ptr, tdam, monster)
2310 register inven_type *i_ptr;
2311 register int tdam;
2312 int monster;
2313 {
2314   register creature_type *m_ptr;
2315   register recall_type *r_ptr;
2316 #ifdef ATARIST_MWC
2317   int32u holder;
2318 #endif
2319 
2320 #ifdef ATARIST_MWC
2321   if ((i_ptr->flags & (holder = TR_EGO_WEAPON)) &&
2322 #else
2323   if ((i_ptr->flags & TR_EGO_WEAPON) &&
2324 #endif
2325       (((i_ptr->tval >= TV_SLING_AMMO) && (i_ptr->tval <= TV_ARROW)) ||
2326        ((i_ptr->tval >= TV_HAFTED) && (i_ptr->tval <= TV_SWORD)) ||
2327        (i_ptr->tval == TV_FLASK)))
2328     {
2329       m_ptr = &c_list[monster];
2330       r_ptr = &c_recall[monster];
2331       /* Slay Dragon  */
2332       if ((m_ptr->cdefense & CD_DRAGON) && (i_ptr->flags & TR_SLAY_DRAGON))
2333 	{
2334 	  tdam = tdam * 4;
2335 	  r_ptr->r_cdefense |= CD_DRAGON;
2336 	}
2337       /* Slay Undead  */
2338 #ifdef ATARIST_MWC
2339       else if ((m_ptr->cdefense & CD_UNDEAD)
2340 	       && (i_ptr->flags & (holder = TR_SLAY_UNDEAD)))
2341 #else
2342       else if ((m_ptr->cdefense & CD_UNDEAD)
2343 	       && (i_ptr->flags & TR_SLAY_UNDEAD))
2344 #endif
2345 	{
2346 	  tdam = tdam * 3;
2347 	  r_ptr->r_cdefense |= CD_UNDEAD;
2348 	}
2349       /* Slay Animal  */
2350       else if ((m_ptr->cdefense & CD_ANIMAL)
2351 	       && (i_ptr->flags & TR_SLAY_ANIMAL))
2352 	{
2353 	  tdam = tdam * 2;
2354 	  r_ptr->r_cdefense |= CD_ANIMAL;
2355 	}
2356       /* Slay Evil     */
2357       else if ((m_ptr->cdefense & CD_EVIL) && (i_ptr->flags & TR_SLAY_EVIL))
2358 	{
2359 	  tdam = tdam * 2;
2360 	  r_ptr->r_cdefense |= CD_EVIL;
2361 	}
2362       /* Frost	       */
2363 #ifdef ATARIST_MWC
2364       else if ((m_ptr->cdefense & CD_FROST)
2365 	       && (i_ptr->flags & (holder = TR_FROST_BRAND)))
2366 #else
2367       else if ((m_ptr->cdefense & CD_FROST)
2368 	       && (i_ptr->flags & TR_FROST_BRAND))
2369 #endif
2370 	{
2371 	  tdam = tdam * 3 / 2;
2372 	  r_ptr->r_cdefense |= CD_FROST;
2373 	}
2374       /* Fire	      */
2375 #ifdef ATARIST_MWC
2376       else if ((m_ptr->cdefense & CD_FIRE)
2377 	       && (i_ptr->flags & (holder = TR_FLAME_TONGUE)))
2378 #else
2379       else if ((m_ptr->cdefense & CD_FIRE)
2380 	       && (i_ptr->flags & TR_FLAME_TONGUE))
2381 #endif
2382 	{
2383 	  tdam = tdam * 3 / 2;
2384 	  r_ptr->r_cdefense |= CD_FIRE;
2385 	}
2386     }
2387   return(tdam);
2388 }
2389 
2390 
2391 /* Critical hits, Nasty way to die.			-RAK-	*/
critical_blow(weight,plus,dam,attack_type)2392 int critical_blow(weight, plus, dam, attack_type)
2393 register int weight, plus, dam;
2394 int attack_type;
2395 {
2396   register int critical;
2397 
2398   critical = dam;
2399   /* Weight of weapon, plusses to hit, and character level all	    */
2400   /* contribute to the chance of a critical			   */
2401   if (randint(5000) <= (int)(weight + 5 * plus
2402 			     + (class_level_adj[py.misc.pclass][attack_type]
2403 				* py.misc.lev)))
2404     {
2405       weight += randint(650);
2406       if (weight < 400)
2407 	{
2408 	  critical = 2*dam + 5;
2409 	  msg_print("It was a good hit! (x2 damage)");
2410 	}
2411       else if (weight < 700)
2412 	{
2413 	  critical = 3*dam + 10;
2414 	  msg_print("It was an excellent hit! (x3 damage)");
2415 	}
2416       else if (weight < 900)
2417 	{
2418 	  critical = 4*dam + 15;
2419 	  msg_print("It was a superb hit! (x4 damage)");
2420 	}
2421       else
2422 	{
2423 	  critical = 5*dam + 20;
2424 	  msg_print("It was a *GREAT* hit! (x5 damage)");
2425 	}
2426     }
2427   return(critical);
2428 }
2429 
2430 
2431 /* Given direction "dir", returns new row, column location -RAK- */
mmove(dir,y,x)2432 int mmove(dir, y, x)
2433 int dir;
2434 register int *y, *x;
2435 {
2436   register int new_row, new_col;
2437   int bool;
2438 
2439   switch(dir)
2440     {
2441     case 1:
2442       new_row = *y + 1;
2443       new_col = *x - 1;
2444       break;
2445     case 2:
2446       new_row = *y + 1;
2447       new_col = *x;
2448       break;
2449     case 3:
2450       new_row = *y + 1;
2451       new_col = *x + 1;
2452       break;
2453     case 4:
2454       new_row = *y;
2455       new_col = *x - 1;
2456       break;
2457     case 5:
2458       new_row = *y;
2459       new_col = *x;
2460       break;
2461     case 6:
2462       new_row = *y;
2463       new_col = *x + 1;
2464       break;
2465     case 7:
2466       new_row = *y - 1;
2467       new_col = *x - 1;
2468       break;
2469     case 8:
2470       new_row = *y - 1;
2471       new_col = *x;
2472       break;
2473     case 9:
2474       new_row = *y - 1;
2475       new_col = *x + 1;
2476       break;
2477     }
2478   bool = FALSE;
2479   if ((new_row >= 0) && (new_row < cur_height)
2480       && (new_col >= 0) && (new_col < cur_width))
2481     {
2482       *y = new_row;
2483       *x = new_col;
2484       bool = TRUE;
2485     }
2486   return(bool);
2487 }
2488 
2489 /* Saving throws for player character.		-RAK-	*/
player_saves()2490 int player_saves()
2491 {
2492   /* MPW C couldn't handle the expression, so split it into two parts */
2493   int16 temp = class_level_adj[py.misc.pclass][CLA_SAVE];
2494 
2495   if (randint(100) <= (py.misc.save + stat_adj(A_WIS)
2496 		       + (temp * py.misc.lev / 3)))
2497     return(TRUE);
2498   else
2499     return(FALSE);
2500 }
2501 
2502 
2503 /* Finds range of item in inventory list		-RAK-	*/
find_range(item1,item2,j,k)2504 int find_range(item1, item2, j, k)
2505 int item1, item2;
2506 register int *j, *k;
2507 {
2508   register int i;
2509   register inven_type *i_ptr;
2510   int flag;
2511 
2512   i = 0;
2513   *j = -1;
2514   *k = -1;
2515   flag = FALSE;
2516   i_ptr = &inventory[0];
2517   while (i < inven_ctr)
2518     {
2519       if (!flag)
2520 	{
2521 	  if ((i_ptr->tval == item1) || (i_ptr->tval == item2))
2522 	    {
2523 	      flag = TRUE;
2524 	      *j = i;
2525 	    }
2526 	}
2527       else
2528 	{
2529 	  if ((i_ptr->tval != item1) && (i_ptr->tval != item2))
2530 	    {
2531 	      *k = i - 1;
2532 	      break;
2533 	    }
2534 	}
2535       i++;
2536       i_ptr++;
2537     }
2538   if (flag && (*k == -1))
2539     *k = inven_ctr - 1;
2540   return(flag);
2541 }
2542 
2543 
2544 /* Teleport the player to a new location		-RAK-	*/
teleport(dis)2545 void teleport(dis)
2546 int dis;
2547 {
2548   register int y, x, i, j;
2549 
2550   do
2551     {
2552       y = randint(cur_height) - 1;
2553       x = randint(cur_width) - 1;
2554       while (distance(y, x, char_row, char_col) > dis)
2555 	{
2556 	  y += ((char_row-y)/2);
2557 	  x += ((char_col-x)/2);
2558 	}
2559     }
2560   while ((cave[y][x].fval >= MIN_CLOSED_SPACE) || (cave[y][x].cptr >= 2));
2561   move_rec(char_row, char_col, y, x);
2562   for (i = char_row-1; i <= char_row+1; i++)
2563     for (j = char_col-1; j <= char_col+1; j++)
2564       {
2565 	cave[i][j].tl = FALSE;
2566 	lite_spot(i, j);
2567       }
2568   lite_spot(char_row, char_col);
2569   char_row = y;
2570   char_col = x;
2571   check_view();
2572   creatures(FALSE);
2573   teleport_flag = FALSE;
2574 }
2575