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