comparison arogue7/init.c @ 125:adfa37e67084

Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Fri, 08 May 2015 15:24:40 -0400
parents
children b786053d2f37
comparison
equal deleted inserted replaced
124:d10fc4a065ac 125:adfa37e67084
1 /*
2 * init.c - global variable initializaton
3 *
4 * Advanced Rogue
5 * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
6 * All rights reserved.
7 *
8 * Based on "Rogue: Exploring the Dungeons of Doom"
9 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
10 * All rights reserved.
11 *
12 * See the file LICENSE.TXT for full copyright and licensing information.
13 */
14
15 /*
16 * global variable initializaton
17 *
18 */
19
20 #include "curses.h"
21 #include <ctype.h>
22 #include "rogue.h"
23 #include "mach_dep.h"
24
25
26 /*
27 * If there is any news, put it in a character string and assign it to
28 * rogue_news. Otherwise, assign NULL to rogue_news.
29 */
30 static char *rogue_news = "You no longer fall into trading posts. They are \
31 now entered like going down the stairs.";
32
33 char *rainbow[] = {
34
35 "amber", "aquamarine", "beige",
36 "black", "blue", "brown",
37 "clear", "crimson", "ecru",
38 "gold", "green", "grey",
39 "indigo", "khaki", "lavender",
40 "magenta", "orange", "pink",
41 "plaid", "purple", "red",
42 "silver", "saffron", "scarlet",
43 "tan", "tangerine", "topaz",
44 "turquoise", "vermilion", "violet",
45 "white", "yellow",
46 };
47 #define NCOLORS (sizeof rainbow / sizeof(char *))
48 int cNCOLORS = NCOLORS;
49
50 static char *sylls[] = {
51 "a", "ab", "ag", "aks", "ala", "an", "ankh", "app", "arg", "arze",
52 "ash", "ban", "bar", "bat", "bek", "bie", "bin", "bit", "bjor",
53 "blu", "bot", "bu", "byt", "comp", "con", "cos", "cre", "dalf",
54 "dan", "den", "do", "e", "eep", "el", "eng", "er", "ere", "erk",
55 "esh", "evs", "fa", "fid", "for", "fri", "fu", "gan", "gar",
56 "glen", "gop", "gre", "ha", "he", "hyd", "i", "ing", "ion", "ip",
57 "ish", "it", "ite", "iv", "jo", "kho", "kli", "klis", "la", "lech",
58 "man", "mar", "me", "mi", "mic", "mik", "mon", "mung", "mur",
59 "nej", "nelg", "nep", "ner", "nes", "net", "nih", "nin", "o", "od",
60 "ood", "org", "orn", "ox", "oxy", "pay", "pet", "ple", "plu", "po",
61 "pot", "prok", "re", "rea", "rhov", "ri", "ro", "rog", "rok", "rol",
62 "sa", "san", "sat", "see", "sef", "seh", "shu", "ski", "sna",
63 "sne", "snik", "sno", "so", "sol", "sri", "sta", "sun", "ta",
64 "tab", "tem", "ther", "ti", "tox", "trol", "tue", "turs", "u",
65 "ulk", "um", "un", "uni", "ur", "val", "viv", "vly", "vom", "wah",
66 "wed", "werg", "wex", "whon", "wun", "xo", "y", "yot", "yu",
67 "zant", "zap", "zeb", "zim", "zok", "zon", "zum",
68 };
69
70 char *stones[] = {
71 "agate", "alexandrite", "amethyst",
72 "azurite", "bloodstone", "cairngorm",
73 "carnelian", "chalcedony", "chrysoberyl",
74 "chrysolite", "chrysoprase", "citrine",
75 "coral", "diamond", "emerald",
76 "garnet", "heliotrope", "hematite",
77 "hyacinth", "jacinth", "jade",
78 "jargoon", "jasper", "kryptonite",
79 "lapus lazuli", "malachite", "mocca stone",
80 "moonstone", "obsidian", "olivine",
81 "onyx", "opal", "pearl",
82 "peridot", "quartz", "rhodochrosite",
83 "rhodolite", "ruby", "sapphire",
84 "sardonyx", "serpintine", "spinel",
85 "tiger eye", "topaz", "tourmaline",
86 "turquoise", "zircon",
87 };
88 #define NSTONES (sizeof stones / sizeof(char *))
89 int cNSTONES = NSTONES;
90
91 char *wood[] = {
92 "avocado wood", "balsa", "banyan", "birch",
93 "cedar", "cherry", "cinnibar", "dogwood",
94 "driftwood", "ebony", "eucalyptus", "hemlock",
95 "ironwood", "mahogany", "manzanita", "maple",
96 "oak", "pine", "redwood", "rosewood",
97 "teak", "walnut", "zebra wood", "persimmon wood",
98 };
99 #define NWOOD (sizeof wood / sizeof(char *))
100 int cNWOOD = NWOOD;
101
102 char *metal[] = {
103 "aluminium", "bone", "brass", "bronze",
104 "copper", "chromium", "iron", "lead",
105 "magnesium", "pewter", "platinum", "silver",
106 "steel", "tin", "titanium", "zinc",
107 };
108 #define NMETAL (sizeof metal / sizeof(char *))
109 int cNMETAL = NMETAL;
110 #define MAX3(a,b,c) (a > b ? (a > c ? a : c) : (b > c ? b : c))
111
112 static bool used[MAX3(NCOLORS, NSTONES, NWOOD)];
113
114
115 /*
116 * make sure all the percentages specified in the tables add up to the
117 * right amounts
118 */
119 badcheck(name, magic, bound)
120 char *name;
121 register struct magic_item *magic;
122 register int bound;
123 {
124 register struct magic_item *end;
125
126 if (magic[bound - 1].mi_prob == 1000)
127 return;
128 printf("\nBad percentages for %s:\n", name);
129 for (end = &magic[bound] ; magic < end ; magic++)
130 printf("%4d%% %s\n", magic->mi_prob, magic->mi_name);
131 printf(retstr);
132 fflush(stdout);
133 while (getchar() != '\n')
134 continue;
135 }
136
137 /*
138 * init_colors:
139 * Initialize the potion color scheme for this time
140 */
141
142 init_colors()
143 {
144 register int i, j;
145
146 for (i = 0; i < NCOLORS; i++)
147 used[i] = FALSE;
148
149 for (i = 0 ; i < MAXPOTIONS ; i++)
150 {
151 do
152 j = rnd(NCOLORS);
153 until (!used[j]);
154 used[j] = TRUE;
155 p_colors[i] = rainbow[j];
156 p_know[i] = FALSE;
157 p_guess[i] = NULL;
158 if (i > 0)
159 p_magic[i].mi_prob += p_magic[i-1].mi_prob;
160 }
161 badcheck("potions", p_magic, MAXPOTIONS);
162 }
163
164 /*
165 * do any initialization for food
166 */
167
168 init_foods()
169 {
170 register int i;
171
172 for (i=0; i < MAXFOODS; i++) {
173 if (i > 0)
174 foods[i].mi_prob += foods[i-1].mi_prob;
175 }
176 badcheck("foods", foods, MAXFOODS);
177 }
178
179 /*
180 * init_materials:
181 * Initialize the construction materials for wands and staffs
182 */
183
184 init_materials()
185 {
186 register int i, j;
187 register char *str;
188 static bool metused[NMETAL];
189
190 for (i = 0; i < NWOOD; i++)
191 used[i] = FALSE;
192 for (i = 0; i < NMETAL; i++)
193 metused[i] = FALSE;
194
195 for (i = 0 ; i < MAXSTICKS ; i++)
196 {
197 for (;;)
198 if (rnd(100) > 50)
199 {
200 j = rnd(NMETAL);
201 if (!metused[j])
202 {
203 ws_type[i] = "wand";
204 str = metal[j];
205 metused[j] = TRUE;
206 break;
207 }
208 }
209 else
210 {
211 j = rnd(NWOOD);
212 if (!used[j])
213 {
214 ws_type[i] = "staff";
215 str = wood[j];
216 used[j] = TRUE;
217 break;
218 }
219 }
220
221 ws_made[i] = str;
222 ws_know[i] = FALSE;
223 ws_guess[i] = NULL;
224 if (i > 0)
225 ws_magic[i].mi_prob += ws_magic[i-1].mi_prob;
226 }
227 badcheck("sticks", ws_magic, MAXSTICKS);
228 }
229
230 /*
231 * do any initialization for miscellaneous magic
232 */
233
234 init_misc()
235 {
236 register int i;
237
238 for (i=0; i < MAXMM; i++) {
239 m_know[i] = FALSE;
240 m_guess[i] = NULL;
241 if (i > 0)
242 m_magic[i].mi_prob += m_magic[i-1].mi_prob;
243 }
244 badcheck("miscellaneous magic", m_magic, MAXMM);
245 }
246
247 /*
248 * init_names:
249 * Generate the names of the various scrolls
250 */
251
252 init_names()
253 {
254 register int nsyl;
255 register char *cp, *sp;
256 register int i, nwords;
257
258 for (i = 0 ; i < MAXSCROLLS ; i++)
259 {
260 cp = prbuf;
261 nwords = rnd(cols/20) + 1 + (cols > 40 ? 1 : 0);
262 while(nwords--)
263 {
264 nsyl = rnd(3)+1;
265 while(nsyl--)
266 {
267 sp = sylls[rnd((sizeof sylls) / (sizeof (char *)))];
268 while(*sp)
269 *cp++ = *sp++;
270 }
271 *cp++ = ' ';
272 }
273 *--cp = '\0';
274 s_names[i] = (char *) new(strlen(prbuf)+1);
275 s_know[i] = FALSE;
276 s_guess[i] = NULL;
277 strcpy(s_names[i], prbuf);
278 if (i > 0)
279 s_magic[i].mi_prob += s_magic[i-1].mi_prob;
280 }
281 badcheck("scrolls", s_magic, MAXSCROLLS);
282 }
283
284 /*
285 * init_player:
286 * roll up the rogue
287 */
288
289 init_player()
290 {
291 int stat_total, round, minimum, maximum, ch, i, j;
292 short do_escape, *our_stats[NUMABILITIES-1];
293 struct linked_list *weap_item, *armor_item;
294 struct object *obj;
295
296 weap_item = armor_item = NULL;
297
298 if (char_type == -1) {
299 /* See what type character will be */
300 wclear(hw);
301 touchwin(hw);
302 wmove(hw,2,0);
303 for(i=1; i<=NUM_CHARTYPES-1; i++) {
304 wprintw(hw,"[%d] %s\n",i,char_class[i-1].name);
305 }
306 mvwaddstr(hw, 0, 0, "What character class do you desire? ");
307 draw(hw);
308 char_type = (wgetch(hw) - '0');
309 while (char_type < 1 || char_type > NUM_CHARTYPES-1) {
310 wmove(hw,0,0);
311 wprintw(hw,"Please enter a character type between 1 and %d: ",
312 NUM_CHARTYPES-1);
313 draw(hw);
314 char_type = (wgetch(hw) - '0');
315 }
316 char_type--;
317 }
318 player.t_ctype = char_type;
319 player.t_quiet = 0;
320 pack = NULL;
321
322 /* Select the gold */
323 purse = 2700;
324 switch (player.t_ctype) {
325 case C_FIGHTER:
326 purse += 1800;
327 when C_THIEF:
328 case C_ASSASIN:
329 purse += 600;
330 }
331 #ifdef WIZARD
332 /*
333 * allow me to describe a super character
334 */
335 if (wizard && strcmp(getenv("SUPER"),"YES") == 0) {
336 pstats.s_str = 25;
337 pstats.s_intel = 25;
338 pstats.s_wisdom = 25;
339 pstats.s_dext = 25;
340 pstats.s_const = 25;
341 pstats.s_charisma = 25;
342 pstats.s_exp = 10000000L;
343 pstats.s_lvladj = 0;
344 pstats.s_lvl = 1;
345 pstats.s_hpt = 500;
346 pstats.s_carry = totalenc(&player);
347 strncpy(pstats.s_dmg, "3d4", sizeof(pstats.s_dmg));
348 check_level();
349 mpos = 0;
350 if (player.t_ctype == C_FIGHTER ||
351 player.t_ctype == C_RANGER ||
352 player.t_ctype == C_PALADIN)
353 weap_item = spec_item(WEAPON, TWOSWORD, 5, 5);
354 else
355 weap_item = spec_item(WEAPON, SWORD, 5, 5);
356 obj = OBJPTR(weap_item);
357 obj->o_flags |= ISKNOW;
358 add_pack(weap_item, TRUE, NULL);
359 cur_weapon = obj;
360 if (player.t_ctype != C_MONK) {
361 j = PLATE_ARMOR;
362 if (player.t_ctype == C_THIEF || player.t_ctype == C_ASSASIN)
363 j = STUDDED_LEATHER;
364 armor_item = spec_item(ARMOR, j, 10, 0);
365 obj = OBJPTR(armor_item);
366 obj->o_flags |= (ISKNOW | ISPROT);
367 obj->o_weight = armors[j].a_wght;
368 add_pack(armor_item, TRUE, NULL);
369 cur_armor = obj;
370 }
371 purse += 10000;
372 }
373 else
374 #endif
375
376 {
377 switch(player.t_ctype) {
378 case C_MAGICIAN:round = A_INTELLIGENCE;
379 when C_FIGHTER: round = A_STRENGTH;
380 when C_RANGER: round = A_STRENGTH;
381 when C_PALADIN: round = A_STRENGTH;
382 when C_CLERIC: round = A_WISDOM;
383 when C_DRUID: round = A_WISDOM;
384 when C_THIEF: round = A_DEXTERITY;
385 when C_ASSASIN: round = A_DEXTERITY;
386 when C_MONK: round = A_DEXTERITY;
387 }
388
389 do {
390 wclear(hw);
391
392 /* If there is any news, display it */
393 if (rogue_news) {
394 register int i;
395
396 /* Print a separator line */
397 wmove(hw, 12, 0);
398 for (i=0; i<cols; i++) waddch(hw, '-');
399
400 /* Print the news */
401 mvwaddstr(hw, 14, 0, rogue_news);
402 }
403
404 stat_total = MAXSTATS;
405 do_escape = FALSE; /* No escape seen yet */
406
407 /* Initialize abilities */
408 pstats.s_intel = 0;
409 pstats.s_str = 0;
410 pstats.s_wisdom = 0;
411 pstats.s_dext = 0;
412 pstats.s_const = 0;
413 pstats.s_charisma = 0;
414
415 /* Initialize pointer into abilities */
416 our_stats[A_INTELLIGENCE] = &pstats.s_intel;
417 our_stats[A_STRENGTH] = &pstats.s_str;
418 our_stats[A_WISDOM] = &pstats.s_wisdom;
419 our_stats[A_DEXTERITY] = &pstats.s_dext;
420 our_stats[A_CONSTITUTION] = &pstats.s_const;
421
422 /* Let player distribute attributes */
423 for (i=0; i<NUMABILITIES-1; i++) {
424 wmove(hw, 2, 0);
425 wprintw(hw, "You are creating a %s with %2d attribute points.",
426 char_class[player.t_ctype].name, stat_total);
427
428 /*
429 * Player must have a minimum of 7 in any attribute and 11 in
430 * the player's primary attribute.
431 */
432 minimum = (round == i ? 11 : 7);
433
434 /* Subtract out remaining minimums */
435 maximum = stat_total - (7 * (NUMABILITIES-1 - i));
436
437 /* Subtract out remainder of profession minimum (11 - 7) */
438 if (round > i) maximum -= 4;
439
440 /* Maximum can't be greater than 18 */
441 if (maximum > 18) maximum = 18;
442
443 wmove(hw, 4, 0);
444 wprintw(hw,
445 "Minimum: %2d; Maximum: %2d (%s corrects previous entry)",
446 minimum, maximum, unctrl('\b'));
447
448 wmove(hw, 6, 0);
449 wprintw(hw, " Int: %-2d", pstats.s_intel);
450 wprintw(hw, " Str: %-2d", pstats.s_str);
451 wprintw(hw, " Wis: %-2d", pstats.s_wisdom);
452 wprintw(hw, " Dex: %-2d", pstats.s_dext);
453 wprintw(hw, " Con: %-2d", pstats.s_const);
454 wprintw(hw, " Cha: %-2d", pstats.s_charisma);
455 wclrtoeol(hw);
456 wmove(hw, 6, 11*i + 9);
457 if (do_escape == FALSE) draw(hw);
458
459 /* Get player's input */
460 if (do_escape || maximum == minimum) {
461 *our_stats[i] = maximum;
462 stat_total -= maximum;
463 }
464 else for (;;) {
465 ch = wgetch(hw);
466 if (ch == '\b') { /* Backspace */
467 if (i == 0) continue; /* Can't move back */
468 else {
469 stat_total += *our_stats[i-1];
470 *our_stats[i] = 0;
471 *our_stats[i-1] = 0;
472 i -= 2; /* Back out */
473 break;
474 }
475 }
476 if (ch == '\033') { /* Escape */
477 /*
478 * Escape will result in using all maximums for
479 * remaining abilities.
480 */
481 do_escape = TRUE;
482 *our_stats[i] = maximum;
483 stat_total -= maximum;
484 break;
485 }
486
487 /* Do we have a legal digit? */
488 if (ch >= '0' && ch <= '9') {
489 ch -= '0'; /* Convert it to a number */
490 *our_stats[i] = 10 * *our_stats[i] + ch;
491
492 /* Is the number in range? */
493 if (*our_stats[i] >= minimum &&
494 *our_stats[i] <= maximum) {
495 stat_total -= *our_stats[i];
496 break;
497 }
498
499 /*
500 * If it's too small, get more - 1x is the only
501 * allowable case.
502 */
503 if (*our_stats[i] < minimum && *our_stats[i] == 1) {
504 /* Print the player's one */
505 waddch(hw, '1');
506 draw(hw);
507 continue;
508 }
509 }
510
511 /* Error condition */
512 putchar('\007');
513 *our_stats[i] = 0;
514 i--; /* Rewind */
515 break;
516 }
517 }
518
519 /* Discard extra points over 18 */
520 if (stat_total > 18) stat_total = 18;
521
522 /* Charisma gets what's left */
523 pstats.s_charisma = stat_total;
524
525 /* Intialize constants */
526 pstats.s_lvl = 1;
527 pstats.s_lvladj = 0;
528 pstats.s_exp = 0L;
529 strncpy(pstats.s_dmg, "1d4", sizeof(pstats.s_dmg));
530 pstats.s_carry = totalenc(&player);
531
532 /* Get the hit points. */
533 pstats.s_hpt = 12 + const_bonus(); /* Base plus bonus */
534
535 /* Add in the component that varies according to class */
536 pstats.s_hpt += char_class[player.t_ctype].hit_pts;
537
538 /* Display the character */
539 wmove(hw, 2, 0);
540 wprintw(hw,"You are creating a %s.",
541 char_class[player.t_ctype].name);
542 wclrtoeol(hw);
543
544 /* Get rid of max/min line */
545 wmove(hw, 4, 0);
546 wclrtoeol(hw);
547
548 wmove(hw, 6, 0);
549 wprintw(hw, " Int: %2d", pstats.s_intel);
550 wprintw(hw, " Str: %2d", pstats.s_str);
551 wprintw(hw, " Wis: %2d", pstats.s_wisdom);
552 wprintw(hw, " Dex: %2d", pstats.s_dext);
553 wprintw(hw, " Con: %2d", pstats.s_const);
554 wprintw(hw, " Cha: %2d", pstats.s_charisma);
555 wclrtoeol(hw);
556
557 wmove(hw, 8, 0);
558 wprintw(hw, " Hp: %2d", pstats.s_hpt);
559 wclrtoeol(hw);
560
561 wmove(hw, 10, 0);
562 wprintw(hw, " Gold: %d", purse);
563
564 mvwaddstr(hw, 0, 0, "Is this character okay? ");
565 draw(hw);
566 } while(wgetch(hw) != 'y');
567 }
568
569 pstats.s_arm = 10;
570 max_stats = pstats;
571
572 /* Set up the initial movement rate */
573 player.t_action = A_NIL;
574 player.t_movement = 6;
575 player.t_no_move = 0;
576 player.t_using = NULL;
577 }
578
579
580
581
582
583
584 /*
585 * init_stones:
586 * Initialize the ring stone setting scheme for this time
587 */
588
589 init_stones()
590 {
591 register int i, j;
592
593 for (i = 0; i < NSTONES; i++)
594 used[i] = FALSE;
595
596 for (i = 0 ; i < MAXRINGS ; i++)
597 {
598 do
599 j = rnd(NSTONES);
600 until (!used[j]);
601 used[j] = TRUE;
602 r_stones[i] = stones[j];
603 r_know[i] = FALSE;
604 r_guess[i] = NULL;
605 if (i > 0)
606 r_magic[i].mi_prob += r_magic[i-1].mi_prob;
607 }
608 badcheck("rings", r_magic, MAXRINGS);
609 }
610
611 /*
612 * init_things
613 * Initialize the probabilities for types of things
614 */
615 init_things()
616 {
617 register struct magic_item *mp;
618
619 for (mp = &things[1] ; mp < &things[NUMTHINGS] ; mp++)
620 mp->mi_prob += (mp-1)->mi_prob;
621 badcheck("things", things, NUMTHINGS);
622 }
623
624