Rogue 3.6 reconstruction from http://rogue.rogueforge.net/rogue36/.
[rogue-pphs.git] / init.c
1 /*
2 * global variable initializaton
3 *
4 * @(#)init.c 3.33 (Berkeley) 6/15/81
5 *
6 * Rogue: Exploring the Dungeons of Doom
7 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
8 * All rights reserved.
9 *
10 * See the file LICENSE.TXT for full copyright and licensing information.
11 */
12
13 #include "curses.h"
14 #include <ctype.h>
15 #include <string.h>
16 #include "rogue.h"
17
18 bool playing = TRUE, running = FALSE, wizard = FALSE;
19 bool notify = TRUE, fight_flush = FALSE, terse = FALSE, door_stop = FALSE;
20 bool jump = FALSE, slow_invent = FALSE, firstmove = FALSE, askme = FALSE;
21 bool amulet = FALSE, in_shell = FALSE;
22 struct linked_list *lvl_obj = NULL, *mlist = NULL;
23 struct object *cur_weapon = NULL;
24 int mpos = 0, no_move = 0, no_command = 0, level = 1, purse = 0, inpack = 0;
25 int total = 0, no_food = 0, count = 0, fung_hit = 0, quiet = 0;
26 int food_left = HUNGERTIME, group = 1, hungry_state = 0;
27 int lastscore = -1;
28
29 struct thing player;
30 struct room rooms[MAXROOMS];
31 struct room *oldrp;
32 struct stats max_stats;
33 struct object *cur_armor;
34 struct object *cur_ring[2];
35 bool after;
36 bool waswizard;
37 coord oldpos; /* Position before last look() call */
38 coord delta; /* Change indicated to get_dir() */
39
40 bool s_know[MAXSCROLLS]; /* Does he know what a scroll does */
41 bool p_know[MAXPOTIONS]; /* Does he know what a potion does */
42 bool r_know[MAXRINGS]; /* Does he know what a ring does
43 */
44 bool ws_know[MAXSTICKS]; /* Does he know what a stick does */
45
46 char take; /* Thing the rogue is taking */
47 char runch; /* Direction player is running */
48 char whoami[80]; /* Name of player */
49 char fruit[80]; /* Favorite fruit */
50 char huh[80]; /* The last message printed */
51 int dnum; /* Dungeon number */
52 char *s_names[MAXSCROLLS]; /* Names of the scrolls */
53 char *p_colors[MAXPOTIONS]; /* Colors of the potions */
54 char *r_stones[MAXRINGS]; /* Stone settings of the rings */
55 char *a_names[MAXARMORS]; /* Names of armor types */
56 char *ws_made[MAXSTICKS]; /* What sticks are made of */
57 char *s_guess[MAXSCROLLS]; /* Players guess at what scroll is */
58 char *p_guess[MAXPOTIONS]; /* Players guess at what potion is */
59 char *r_guess[MAXRINGS]; /* Players guess at what ring is */
60 char *ws_guess[MAXSTICKS]; /* Players guess at what wand is */
61 char *ws_type[MAXSTICKS]; /* Is it a wand or a staff */
62 char file_name[80]; /* Save file name */
63 char home[80]; /* User's home directory */
64 char prbuf[80]; /* Buffer for sprintfs */
65 int max_hp; /* Player's max hit points */
66 int ntraps; /* Number of traps on this level */
67 int max_level; /* Deepest player has gone */
68 int seed; /* Random number seed */
69
70 struct trap traps[MAXTRAPS];
71
72
73 #define ___ 1
74 #define _x {1,1}
75 struct monster monsters[26] = {
76 /* Name CARRY FLAG str, exp, lvl, amr, hpt, dmg */
77 { "giant ant", 0, ISMEAN, { _x, 10, 2, 3, ___, "1d6" } },
78 { "bat", 0, 0, { _x, 1, 1, 3, ___, "1d2" } },
79 { "centaur", 15, 0, { _x, 15, 4, 4, ___, "1d6/1d6" } },
80 { "dragon", 100, ISGREED,{ _x,9000, 10, -1, ___, "1d8/1d8/3d10" } },
81 { "floating eye",0, 0, { _x, 5, 1, 9, ___, "0d0" } },
82 { "violet fungi",0, ISMEAN, { _x, 85, 8, 3, ___, "000d0" } },
83 { "gnome", 10, 0, { _x, 8, 1, 5, ___, "1d6" } },
84 { "hobgoblin", 0, ISMEAN, { _x, 3, 1, 5, ___, "1d8" } },
85 { "invisible stalker",0,ISINVIS,{ _x,120, 8, 3, ___, "4d4" } },
86 { "jackal", 0, ISMEAN, { _x, 2, 1, 7, ___, "1d2" } },
87 { "kobold", 0, ISMEAN, { _x, 1, 1, 7, ___, "1d4" } },
88 { "leprechaun", 0, 0, { _x, 10, 3, 8, ___, "1d1" } },
89 { "mimic", 30, 0, { _x,140, 7, 7, ___, "3d4" } },
90 { "nymph", 100, 0, { _x, 40, 3, 9, ___, "0d0" } },
91 { "orc", 15, ISBLOCK,{ _x, 5, 1, 6, ___, "1d8" } },
92 { "purple worm", 70, 0, { _x,7000, 15, 6, ___, "2d12/2d4" } },
93 { "quasit", 30, ISMEAN, { _x, 35, 3, 2, ___, "1d2/1d2/1d4" } },
94 { "rust monster",0, ISMEAN, { _x, 25, 5, 2, ___, "0d0/0d0" } },
95 { "snake", 0, ISMEAN, { _x, 3, 1, 5, ___, "1d3" } },
96 { "troll", 50, ISREGEN|ISMEAN,{ _x, 55, 6, 4, ___, "1d8/1d8/2d6" } },
97 { "umber hulk", 40, ISMEAN, { _x,130, 8, 2, ___, "3d4/3d4/2d5" } },
98 { "vampire", 20, ISREGEN|ISMEAN,{ _x,380, 8, 1, ___, "1d10" } },
99 { "wraith", 0, 0, { _x, 55, 5, 4, ___, "1d6" } },
100 { "xorn", 0, ISMEAN, { _x,120, 7, -2, ___, "1d3/1d3/1d3/4d6" } },
101 { "yeti", 30, 0, { _x, 50, 4, 6, ___, "1d6/1d6" } },
102 { "zombie", 0, ISMEAN, { _x, 7, 2, 8, ___, "1d8" } }
103 };
104 #undef ___
105
106 /*
107 * init_player:
108 * roll up the rogue
109 */
110
111 init_player()
112 {
113 pstats.s_lvl = 1;
114 pstats.s_exp = 0L;
115 max_hp = pstats.s_hpt = 12;
116 if (rnd(100) == 7)
117 {
118 pstats.s_str.st_str = 18;
119 pstats.s_str.st_add = rnd(100) + 1;
120 }
121 else
122 {
123 pstats.s_str.st_str = 16;
124 pstats.s_str.st_add = 0;
125 }
126 strcpy(pstats.s_dmg,"1d4");
127 pstats.s_arm = 10;
128 max_stats = pstats;
129 pack = NULL;
130 }
131
132 /*
133 * Contains defintions and functions for dealing with things like
134 * potions and scrolls
135 */
136
137 char *rainbow[] = {
138 "red",
139 "blue",
140 "green",
141 "yellow",
142 "black",
143 "brown",
144 "orange",
145 "pink",
146 "purple",
147 "grey",
148 "white",
149 "silver",
150 "gold",
151 "violet",
152 "clear",
153 "vermilion",
154 "ecru",
155 "turquoise",
156 "magenta",
157 "amber",
158 "topaz",
159 "plaid",
160 "tan",
161 "tangerine"
162 };
163
164 #define NCOLORS (sizeof rainbow / sizeof (char *))
165 const int cNCOLORS = NCOLORS;
166
167 char *sylls[] = {
168 "a", "ab", "ag", "aks", "ala", "an", "ankh", "app", "arg", "arze",
169 "ash", "ban", "bar", "bat", "bek", "bie", "bin", "bit", "bjor",
170 "blu", "bot", "bu", "byt", "comp", "con", "cos", "cre", "dalf",
171 "dan", "den", "do", "e", "eep", "el", "eng", "er", "ere", "erk",
172 "esh", "evs", "fa", "fid", "for", "fri", "fu", "gan", "gar",
173 "glen", "gop", "gre", "ha", "he", "hyd", "i", "ing", "ion", "ip",
174 "ish", "it", "ite", "iv", "jo", "kho", "kli", "klis", "la", "lech",
175 "man", "mar", "me", "mi", "mic", "mik", "mon", "mung", "mur",
176 "nej", "nelg", "nep", "ner", "nes", "nes", "nih", "nin", "o", "od",
177 "ood", "org", "orn", "ox", "oxy", "pay", "pet", "ple", "plu", "po",
178 "pot", "prok", "re", "rea", "rhov", "ri", "ro", "rog", "rok", "rol",
179 "sa", "san", "sat", "see", "sef", "seh", "shu", "ski", "sna",
180 "sne", "snik", "sno", "so", "sol", "sri", "sta", "sun", "ta",
181 "tab", "tem", "ther", "ti", "tox", "trol", "tue", "turs", "u",
182 "ulk", "um", "un", "uni", "ur", "val", "viv", "vly", "vom", "wah",
183 "wed", "werg", "wex", "whon", "wun", "xo", "y", "yot", "yu",
184 "zant", "zap", "zeb", "zim", "zok", "zon", "zum",
185 };
186
187 char *stones[] = {
188 "agate",
189 "alexandrite",
190 "amethyst",
191 "carnelian",
192 "diamond",
193 "emerald",
194 "granite",
195 "jade",
196 "kryptonite",
197 "lapus lazuli",
198 "moonstone",
199 "obsidian",
200 "onyx",
201 "opal",
202 "pearl",
203 "ruby",
204 "saphire",
205 "tiger eye",
206 "topaz",
207 "turquoise",
208 };
209
210 #define NSTONES (sizeof stones / sizeof (char *))
211 const int cNSTONES = NSTONES;
212
213 char *wood[] = {
214 "avocado wood",
215 "balsa",
216 "banyan",
217 "birch",
218 "cedar",
219 "cherry",
220 "cinnibar",
221 "driftwood",
222 "ebony",
223 "eucalyptus",
224 "hemlock",
225 "ironwood",
226 "mahogany",
227 "manzanita",
228 "maple",
229 "oak",
230 "persimmon wood",
231 "redwood",
232 "rosewood",
233 "teak",
234 "walnut",
235 "zebra wood",
236 };
237
238 #define NWOOD (sizeof wood / sizeof (char *))
239 const int cNWOOD = NWOOD;
240
241 char *metal[] = {
242 "aluminium",
243 "bone",
244 "brass",
245 "bronze",
246 "copper",
247 "iron",
248 "lead",
249 "pewter",
250 "steel",
251 "tin",
252 "zinc",
253 };
254
255 #define NMETAL (sizeof metal / sizeof (char *))
256 const int cNMETAL = NMETAL;
257
258 struct magic_item things[NUMTHINGS] = {
259 { "", 27 }, /* potion */
260 { "", 27 }, /* scroll */
261 { "", 18 }, /* food */
262 { "", 9 }, /* weapon */
263 { "", 9 }, /* armor */
264 { "", 5 }, /* ring */
265 { "", 5 }, /* stick */
266 };
267
268 struct magic_item s_magic[MAXSCROLLS] = {
269 { "monster confusion", 8, 170 },
270 { "magic mapping", 5, 180 },
271 { "light", 10, 100 },
272 { "hold monster", 2, 200 },
273 { "sleep", 5, 50 },
274 { "enchant armor", 8, 130 },
275 { "identify", 21, 100 },
276 { "scare monster", 4, 180 },
277 { "gold detection", 4, 110 },
278 { "teleportation", 7, 175 },
279 { "enchant weapon", 10, 150 },
280 { "create monster", 5, 75 },
281 { "remove curse", 8, 105 },
282 { "aggravate monsters", 1, 60 },
283 { "blank paper", 1, 50 },
284 { "genocide", 1, 200 },
285 };
286
287 struct magic_item p_magic[MAXPOTIONS] = {
288 { "confusion", 8, 50 },
289 { "paralysis", 10, 50 },
290 { "poison", 8, 50 },
291 { "gain strength", 15, 150 },
292 { "see invisible", 2, 170 },
293 { "healing", 15, 130 },
294 { "monster detection", 6, 120 },
295 { "magic detection", 6, 105 },
296 { "raise level", 2, 220 },
297 { "extra healing", 5, 180 },
298 { "haste self", 4, 200 },
299 { "restore strength", 14, 120 },
300 { "blindness", 4, 50 },
301 { "thirst quenching", 1, 50 },
302 };
303
304 struct magic_item r_magic[MAXRINGS] = {
305 { "protection", 9, 200 },
306 { "add strength", 9, 200 },
307 { "sustain strength", 5, 180 },
308 { "searching", 10, 200 },
309 { "see invisible", 10, 175 },
310 { "adornment", 1, 100 },
311 { "aggravate monster", 11, 100 },
312 { "dexterity", 8, 220 },
313 { "increase damage", 8, 220 },
314 { "regeneration", 4, 260 },
315 { "slow digestion", 9, 240 },
316 { "teleportation", 9, 100 },
317 { "stealth", 7, 100 },
318 };
319
320 struct magic_item ws_magic[MAXSTICKS] = {
321 { "light", 12, 120 },
322 { "striking", 9, 115 },
323 { "lightning", 3, 200 },
324 { "fire", 3, 200 },
325 { "cold", 3, 200 },
326 { "polymorph", 15, 210 },
327 { "magic missile", 10, 170 },
328 { "haste monster", 9, 50 },
329 { "slow monster", 11, 220 },
330 { "drain life", 9, 210 },
331 { "nothing", 1, 70 },
332 { "teleport away", 5, 140 },
333 { "teleport to", 5, 60 },
334 { "cancellation", 5, 130 },
335 };
336
337 int a_class[MAXARMORS] = {
338 8,
339 7,
340 7,
341 6,
342 5,
343 4,
344 4,
345 3,
346 };
347
348 char *a_names[MAXARMORS] = {
349 "leather armor",
350 "ring mail",
351 "studded leather armor",
352 "scale mail",
353 "chain mail",
354 "splint mail",
355 "banded mail",
356 "plate mail",
357 };
358
359 int a_chances[MAXARMORS] = {
360 20,
361 35,
362 50,
363 63,
364 75,
365 85,
366 95,
367 100
368 };
369
370 #define MAX3(a,b,c) (a > b ? (a > c ? a : c) : (b > c ? b : c))
371 static bool used[MAX3(NCOLORS, NSTONES, NWOOD)];
372
373 /*
374 * init_things
375 * Initialize the probabilities for types of things
376 */
377 init_things()
378 {
379 register struct magic_item *mp;
380
381 for (mp = &things[1]; mp <= &things[NUMTHINGS-1]; mp++)
382 mp->mi_prob += (mp-1)->mi_prob;
383 badcheck("things", things, NUMTHINGS);
384 }
385
386 /*
387 * init_colors:
388 * Initialize the potion color scheme for this time
389 */
390
391 init_colors()
392 {
393 register int i, j;
394
395 for (i = 0; i < NCOLORS; i++)
396 used[i] = 0;
397 for (i = 0; i < MAXPOTIONS; i++)
398 {
399 do
400 j = rnd(NCOLORS);
401 until (!used[j]);
402 used[j] = TRUE;
403 p_colors[i] = rainbow[j];
404 p_know[i] = FALSE;
405 p_guess[i] = NULL;
406 if (i > 0)
407 p_magic[i].mi_prob += p_magic[i-1].mi_prob;
408 }
409 badcheck("potions", p_magic, MAXPOTIONS);
410 }
411
412 /*
413 * init_names:
414 * Generate the names of the various scrolls
415 */
416
417 init_names()
418 {
419 register int nsyl;
420 register char *cp, *sp;
421 register int i, nwords;
422
423 for (i = 0; i < MAXSCROLLS; i++)
424 {
425 cp = prbuf;
426 nwords = rnd(4)+2;
427 while(nwords--)
428 {
429 nsyl = rnd(3)+1;
430 while(nsyl--)
431 {
432 sp = sylls[rnd((sizeof sylls) / (sizeof (char *)))];
433 while(*sp)
434 *cp++ = *sp++;
435 }
436 *cp++ = ' ';
437 }
438 *--cp = '\0';
439 s_names[i] = (char *) new(strlen(prbuf)+1);
440 s_know[i] = FALSE;
441 s_guess[i] = NULL;
442 strcpy(s_names[i], prbuf);
443 if (i > 0)
444 s_magic[i].mi_prob += s_magic[i-1].mi_prob;
445 }
446 badcheck("scrolls", s_magic, MAXSCROLLS);
447 }
448
449 /*
450 * init_stones:
451 * Initialize the ring stone setting scheme for this time
452 */
453
454 init_stones()
455 {
456 register int i, j;
457
458 for (i = 0; i < NSTONES; i++)
459 used[i] = FALSE;
460 for (i = 0; i < MAXRINGS; i++)
461 {
462 do
463 j = rnd(NSTONES);
464 until (!used[j]);
465 used[j] = TRUE;
466 r_stones[i] = stones[j];
467 r_know[i] = FALSE;
468 r_guess[i] = NULL;
469 if (i > 0)
470 r_magic[i].mi_prob += r_magic[i-1].mi_prob;
471 }
472 badcheck("rings", r_magic, MAXRINGS);
473 }
474
475 /*
476 * init_materials:
477 * Initialize the construction materials for wands and staffs
478 */
479
480 init_materials()
481 {
482 register int i, j;
483 static bool metused[NMETAL];
484
485 for (i = 0; i < NWOOD; i++)
486 used[i] = FALSE;
487 for (i = 0; i < NMETAL; i++)
488 metused[i] = FALSE;
489
490 for (i = 0; i < MAXSTICKS; i++)
491 {
492 for (;;)
493 if (rnd(100) > 50)
494 {
495 j = rnd(NMETAL);
496 if (!metused[j])
497 {
498 metused[j] = TRUE;
499 ws_made[i] = metal[j];
500 ws_type[i] = "wand";
501 break;
502 }
503 }
504 else
505 {
506 j = rnd(NWOOD);
507 if (!used[j])
508 {
509 used[j] = TRUE;
510 ws_made[i] = wood[j];
511 ws_type[i] = "staff";
512 break;
513 }
514 }
515
516 ws_know[i] = FALSE;
517 ws_guess[i] = NULL;
518 if (i > 0)
519 ws_magic[i].mi_prob += ws_magic[i-1].mi_prob;
520 }
521 badcheck("sticks", ws_magic, MAXSTICKS);
522 }
523
524 badcheck(name, magic, bound)
525 char *name;
526 register struct magic_item *magic;
527 register int bound;
528 {
529 register struct magic_item *end;
530
531 if (magic[bound - 1].mi_prob == 100)
532 return;
533 printf("\nBad percentages for %s:\n", name);
534 for (end = &magic[bound]; magic < end; magic++)
535 printf("%3d%% %s\n", magic->mi_prob, magic->mi_name);
536 printf("[hit RETURN to continue]");
537 fflush(stdout);
538 while (getchar() != '\n')
539 continue;
540 }
541
542 struct h_list helpstr[] = {
543 '?', " prints help",
544 '/', " identify object",
545 'h', " left",
546 'j', " down",
547 'k', " up",
548 'l', " right",
549 'y', " up & left",
550 'u', " up & right",
551 'b', " down & left",
552 'n', " down & right",
553 'H', " run left",
554 'J', " run down",
555 'K', " run up",
556 'L', " run right",
557 'Y', " run up & left",
558 'U', " run up & right",
559 'B', " run down & left",
560 'N', " run down & right",
561 't', "<dir> throw something",
562 'f', "<dir> forward until find something",
563 'p', "<dir> zap a wand in a direction",
564 'z', " zap a wand or staff",
565 '>', " go down a staircase",
566 's', " search for trap/secret door",
567 ' ', " (space) rest for a while",
568 'i', " inventory",
569 'I', " inventory single item",
570 'q', " quaff potion",
571 'r', " read paper",
572 'e', " eat food",
573 'w', " wield a weapon",
574 'W', " wear armor",
575 'T', " take armor off",
576 'P', " put on ring",
577 'R', " remove ring",
578 'd', " drop object",
579 'c', " call object",
580 'o', " examine/set options",
581 CTRL('L'), " redraw screen",
582 CTRL('R'), " repeat last message",
583 ESCAPE, " cancel command",
584 'v', " print program version number",
585 '!', " shell escape",
586 'S', " save game",
587 'Q', " quit",
588 0, 0
589 };