1 /* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */
2 /* aux3.c */
3 /* some functions called by com.c, also see aux1.c, aux2.c */
4 /* This is a real grab bag file. It contains functions used by
5 aux1.c and omega.c, as well as elsewhere. It is mainly here so aux1.c
6 and aux2.c are not huge */
7
8 #include "glob.h"
9
10 /* check every ten minutes */
tenminute_check()11 void tenminute_check()
12 {
13 if (Time % 60 == 0) hourly_check();
14 else {
15 if (Current_Environment == Current_Dungeon) wandercheck();
16 minute_status_check();
17 tenminute_status_check();
18 if ((Player.status[DISEASED] < 1) && (Player.hp < Player.maxhp))
19 Player.hp = min(Player.maxhp,Player.hp+Player.level+1);
20 if (Current_Environment != E_COUNTRYSIDE && Current_Environment != E_ABYSS)
21 indoors_random_event();
22 }
23 }
24
25
26
27 /* hourly check is same as ten_minutely check except food is also
28 checked, and since time moves in hours out of doors, also
29 outdoors_random_event is possible */
30
hourly_check()31 void hourly_check()
32 {
33 Player.food--;
34 foodcheck();
35 if (hour()==0) { /* midnight, a new day */
36 moon_check();
37 Date++;
38 }
39 torch_check();
40 if (Current_Environment == Current_Dungeon) wandercheck();
41 minute_status_check();
42 tenminute_status_check();
43 if ((Player.status[DISEASED] == 0) && (Player.hp < Player.maxhp))
44 Player.hp = min(Player.maxhp,Player.hp+Player.level+1);
45 if (Current_Environment != E_COUNTRYSIDE && Current_Environment != E_ABYSS)
46 indoors_random_event();
47 }
48
49
50
51
indoors_random_event()52 void indoors_random_event()
53 {
54 pml ml;
55 pol ol;
56 switch(random_range(1000)) {
57 case 0:
58 print3("You feel an unexplainable elation.");
59 morewait();
60 break;
61 case 1:
62 print3("You hear a distant rumbling.");
63 morewait();
64 break;
65 case 2:
66 print3("You realize your fly is open.");
67 morewait();
68 break;
69 case 3:
70 print3("You have a sudden craving for a pecan twirl.");
71 morewait();
72 break;
73 case 4:
74 print3("A mysterious healing flux settles over the level.");
75 morewait();
76 for (ml=Level->mlist;ml!=NULL;ml=ml->next)
77 if (ml->m->hp > 0) ml->m->hp = Monsters[ml->m->id].hp;
78 Player.hp = max(Player.hp,Player.maxhp);
79 break;
80 case 5:
81 print3("You discover an itch just where you can't scratch it.");
82 morewait();
83 break;
84 case 6:
85 print3("A cosmic ray strikes!");
86 p_damage(10,UNSTOPPABLE,"a cosmic ray");
87 morewait();
88 break;
89 case 7:
90 print3("You catch your second wind....");
91 Player.maxhp++;
92 Player.hp = max(Player.hp, Player.maxhp);
93 Player.mana = max(Player.mana, calcmana());
94 morewait();
95 break;
96 case 8:
97 print3("You find some spare change in a hidden pocket.");
98 morewait();
99 Player.cash += Player.level*Player.level+1;
100 break;
101 case 9:
102 print3("You feel strangely lucky.");
103 morewait();
104 break;
105 case 10:
106 print3("You trip over something hidden in a shadow...");
107 morewait();
108 ol = ((pol) checkmalloc(sizeof(oltype)));
109 ol->thing = create_object(difficulty()); /* FIXED! 12/30/98 */
110 assert(ol->thing); /* WDT I want to make sure... */
111 ol->next = Level->site[Player.x][Player.y].things;
112 Level->site[Player.x][Player.y].things = ol;
113 pickup();
114 break;
115 case 11:
116 print3("A mysterious voice echoes all around you....");
117 morewait();
118 hint();
119 morewait();
120 break;
121 case 12:
122 if (Balance > 0) {
123 print3("You get word of the failure of your bank!");
124 Balance = 0;
125 }
126 else print3("You feel lucky.");
127 break;
128 case 13:
129 if (Balance > 0) {
130 print3("You get word of a bank error in your favor!");
131 Balance += 5000;
132 }
133 else print3("You feel unlucky.");
134 break;
135 }
136 dataprint();
137 showflags();
138 }
139
140
141
outdoors_random_event()142 void outdoors_random_event()
143 {
144 int num,i,j;
145 pob ob;
146
147 switch(random_range(300)) {
148 case 0:
149 switch(Country[Player.x][Player.y].current_terrain_type) {
150 case TUNDRA:
151 mprint("It begins to snow. Heavily.");
152 break;
153 case DESERT:
154 mprint("A sandstorm swirls around you.");
155 break;
156 default:
157 if ((Date > 75) && (Date < 330))
158 mprint("You are drenched by a sudden downpour!");
159 else mprint("It begins to snow. Heavily.");
160 }
161 morewait();
162 mprint("Due to the inclement weather conditions, you have become lost.");
163 morewait();
164 Precipitation+=random_range(12)+1;
165 setgamestatus(LOST);
166 break;
167 case 1:
168 mprint("You enter a field of brightly colored flowers...");
169 mprint("Wow, man! These are some pretty poppies...");
170 morewait();
171 mprint("poppies...");
172 morewait();
173 mprint("poppies...");
174 morewait();
175 print3("You become somewhat disoriented...");
176 setgamestatus(LOST);
177 break;
178 case 2:
179 mprint("You discover a sprig of athelas growing lonely in the wild.");
180 morewait();
181 mprint("Using your herbalist lore you cook a cake of lembas....");
182 morewait();
183 ob = ((pob) checkmalloc(sizeof(objtype)));
184 *ob = Objects[FOODID+1];
185 gain_item(ob);
186 break;
187 case 3:
188 if (Precipitation > 0) {
189 mprint("You are struck by a bolt of lightning!");
190 p_damage(random_range(25),ELECTRICITY,"a lightning strike");
191 morewait();
192 }
193 else mprint("You feel static cling");
194 break;
195 case 4:
196 mprint("You find a fast-food establishment.");
197 morewait();
198 l_commandant();
199 break;
200 case 5:
201 mprint("A weird howling tornado hits from out of the West!");
202 morewait();
203 mprint("You've been caught in a chaos storm!");
204 morewait();
205 num = random_range(300);
206 if (num <10) {
207 mprint("Your cell-structure was disrupted!");
208 p_damage(random_range(100),UNSTOPPABLE,"a chaos storm");
209 morewait();
210 }
211 else if (num < 20) {
212 mprint("The chaos storm warps your frame!");
213 morewait();
214 mprint("Your statistical entropy has been maximized.");
215 morewait();
216 mprint("You feel average...");
217 morewait();
218 toggle_item_use(TRUE); /* FIXED! 12/30/98 */
219 Player.str = Player.maxstr = Player.con = Player.maxcon =
220 Player.dex = Player.maxdex = Player.agi = Player.maxagi =
221 Player.iq = Player.maxiq = Player.pow = Player.maxpow =
222 ((Player.maxstr+Player.maxcon+Player.maxdex+Player.maxagi+
223 Player.maxiq+Player.maxpow+12)/6);
224 toggle_item_use(FALSE); /* FIXED! 12/30/98 */
225 }
226 else if (num < 30) {
227 mprint("Your entire body glows with an eerie flickering light.");
228 morewait();
229 toggle_item_use(TRUE); /* FIXED! 12/30/98 */
230 for(i=1;i<MAXITEMS;i++)
231 if (Player.possessions[i] != NULL) {
232 Player.possessions[i]->plus++;
233 if (Player.possessions[i]->objchar == STICK)
234 Player.possessions[i]->charge+=10;
235 Player.possessions[i]->blessing+=10;
236 }
237 toggle_item_use(FALSE); /* FIXED! 12/30/98 */
238 cleanse(1);
239 mprint("You feel filled with energy!");
240 morewait();
241 Player.maxpow += 5;
242 Player.pow += 5;
243 Player.mana = Player.maxmana = calcmana() * 5;
244 mprint("You also feel weaker. Paradoxical, no?");
245 morewait();
246 Player.con -= 5;
247 Player.maxcon -= 5;
248 if (Player.con < 3)
249 p_death("congestive heart failure");
250 }
251 else if (num < 40) {
252 mprint("Your entire body glows black.");
253 morewait();
254 dispel(-1);
255 dispel(-1);
256 Player.pow-=10;
257 Player.mana=0;
258 }
259 else if (num < 60) {
260 mprint("The storm deposits you in a strange place....");
261 morewait();
262 Player.x = random_range(WIDTH);
263 Player.y = random_range(LENGTH);
264 screencheck(Player.y);
265 }
266 else if (num < 70) {
267 mprint("A tendril of the storm condenses and falls into your hands.");
268 morewait();
269 ob = ((pob) checkmalloc(sizeof(objtype)));
270 make_artifact(ob,-1);
271 gain_item(ob);
272 }
273 else if (num < 80) {
274 if (gamestatusp(MOUNTED)) {
275 mprint("Your horse screams as he is transformed into an");
276 morewait();
277 mprint("imaginary unseen dead tortoise.");
278 morewait();
279 mprint("You are now on foot.");
280 morewait();
281 resetgamestatus(MOUNTED);
282 }
283 else {
284 mprint("You notice you are riding a horse. Odd. Very odd....");
285 morewait();
286 mprint("Now that's a horse of a different color!");
287 morewait();
288 setgamestatus(MOUNTED);
289 }
290 }
291 else if (num < 90) {
292 mprint("You feel imbued with godlike power....");
293 morewait();
294 wish(1);
295 }
296 else if (num < 100) {
297 mprint("The chaos storm has wiped your memory!");
298 morewait();
299 mprint("You feel extraordinarily naive....");
300 morewait();
301 mprint("You can't remember a thing! Not even your name.");
302 morewait();
303 Player.xp = 0;
304 Player.level = 0;
305 for (i=0;i<NUMRANKS;i++) Player.rank[i] = 0;
306 for (i=0;i<NUMSPELLS;i++) Spells[i].known = FALSE;
307 rename_player();
308 }
309 else {
310 mprint("You survive the chaos storm relatively unscathed.");
311 morewait();
312 mprint("It was a learning experience.");
313 morewait();
314 gain_experience(1000);
315 }
316 break;
317 case 6: case 7: case 8: case 9: case 10:
318 mprint("An encounter!");
319 morewait();
320 change_environment(E_TACTICAL_MAP);
321 break;
322 case 11:
323 mprint("You find a Traveller's Aid station with maps of the local area.");
324 morewait();
325 if (gamestatusp(LOST)) {
326 resetgamestatus(LOST);
327 mprint("You know where you are now.");
328 }
329 for(i=Player.x-5;i<Player.x+6;i++)
330 for(j=Player.y-5;j<Player.y+6;j++)
331 if (inbounds(i,j)) {
332 c_set(i, j, SEEN);
333 if (Country[i][j].current_terrain_type !=
334 Country[i][j].base_terrain_type) {
335 c_set(i, j, CHANGED);
336 Country[i][j].current_terrain_type =
337 Country[i][j].base_terrain_type;
338 }
339 }
340 show_screen();
341 break;
342 case 12:
343 if (! gamestatusp(MOUNTED)) {
344 mprint("You develop blisters....");
345 p_damage(1,UNSTOPPABLE,"blisters");
346 }
347 break;
348 case 13:
349 mprint("You discover an itch just where you can't scratch it.");
350 break;
351 case 14:
352 mprint("A cosmic ray strikes!");
353 morewait();
354 p_damage(10,UNSTOPPABLE,"a cosmic ray");
355 break;
356 case 15:
357 mprint("You feel strangely lucky.");
358 break;
359 case 16:
360 mprint("The west wind carries with it a weird echoing voice....");
361 morewait();
362 hint();
363 morewait();
364 break;
365 }
366 dataprint();
367 showflags();
368 }
369
370
getlocation()371 char getlocation()
372 {
373 char c = '\0';
374
375 menuprint(" (enter location [HCL]) ");
376 showmenu();
377 while (c == '\0')
378 switch (c = ((char) mcigetc())) {
379 case 'h':menuprint(" High."); break;
380 case 'c':menuprint(" Center."); break;
381 case 'l':menuprint(" Low."); break;
382 default: c = '\0'; break;
383 }
384 showmenu();
385 return (c - 'a' + 'A');
386 }
387
388
389
390
391
392
393 /* chance for player to resist magic somehow */
394 /* hostile_magic ranges in power from 0 (weak) to 10 (strong) */
magic_resist(hostile_magic)395 int magic_resist(hostile_magic)
396 int hostile_magic;
397 {
398 if ((Player.rank[COLLEGE]+Player.rank[CIRCLE] > 0) &&
399 (Player.level/2 + random_range(20) >
400 hostile_magic + random_range(20))) {
401 if (Player.mana > hostile_magic * hostile_magic) {
402 mprint("Thinking fast, you defend youself with a counterspell!");
403 Player.mana -= hostile_magic * hostile_magic;
404 dataprint();
405 return(TRUE);
406 }
407 }
408 if (Player.level/4 + Player.status[PROTECTION] + random_range(20) >
409 hostile_magic + random_range(30)) {
410 mprint("You resist the spell!");
411 return(TRUE);
412 }
413 else return(FALSE);
414 }
415
416
terrain_check(takestime)417 void terrain_check(takestime)
418 int takestime;
419 {
420 int faster = 0;
421
422 if (Player.patron == DRUID) {
423 faster = 1;
424 switch(random_range(32)) {
425 case 0:print2("Along the many paths of nature..."); break;
426 case 1:print2("You move swiftly through the wilderness."); break;
427 }
428 }
429 else if (gamestatusp(MOUNTED)) {
430 faster = 1;
431 switch(random_range(32)) {
432 case 0:
433 case 1:print2("Clippity Clop.");break;
434 case 2:print2("....my spurs go jingle jangle jingle....");break;
435 case 3:print2("....as I go riding merrily along....");break;
436 }
437 }
438 else if (Player.possessions[O_BOOTS] &&
439 Player.possessions[O_BOOTS]->usef == I_BOOTS_7LEAGUE) {
440 takestime = 0;
441 switch(random_range(32)) {
442 case 0:print2("Boingg!"); break;
443 case 1:print2("Whooosh!"); break;
444 case 2:print2("Over hill, over dale...."); break;
445 case 3:print2("...able to leap over 7 leagues in a single bound....");
446 break;
447 }
448 }
449 else if (Player.status[SHADOWFORM]) {
450 faster = 1;
451 switch(random_range(32)) {
452 case 0:print2("As swift as a shadow."); break;
453 case 1:print2("\"I walk through the trees...\""); break;
454 }
455 }
456 else switch(random_range(32)) {
457 case 0:print2("Trudge. Trudge."); break;
458 case 1:print2("The road goes ever onward...."); break;
459 }
460 switch(Country[Player.x][Player.y].current_terrain_type) {
461 case RIVER:
462 if ((Player.y < 6) && (Player.x > 20)) locprint("Star Lake.");
463 else if (Player.y < 41) {
464 if (Player.x < 10) locprint("Aerie River.");
465 else locprint("The Great Flood.");
466 }
467 else if (Player.x < 42) locprint("The Swamp Runs.");
468 else locprint("River Greenshriek.");
469 if (takestime) {
470 Time += 60;
471 hourly_check();
472 Time += 60;
473 hourly_check();
474 Time += 60;
475 hourly_check();
476 }
477 break;
478 case ROAD:
479 locprint("A well-maintained road.");
480 if (takestime) {
481 Time += 60;
482 hourly_check();
483 }
484 break;
485 case PLAINS:
486 locprint("A rippling sea of grass.");
487 if (takestime) {
488 Time += 60;
489 hourly_check();
490 if (! faster) {
491 Time += 60;
492 hourly_check();
493 }
494 }
495 break;
496 case TUNDRA:
497 locprint("The Great Northern Wastes.");
498 if (takestime) {
499 Time += 60;
500 hourly_check();
501 if (! faster) {
502 Time += 60;
503 hourly_check();
504 }
505 }
506 break;
507 case FOREST:
508 if (Player.y < 10) locprint("The Deepwood.");
509 else if (Player.y < 18) locprint("The Forest of Erelon.");
510 else if (Player.y < 46) locprint("The Great Forest.");
511 if (takestime) {
512 Time += 60;
513 hourly_check();
514 if (Player.rank[PRIESTHOOD] == 0 || Player.patron != DRUID) {
515 Time += 60;
516 hourly_check();
517 if (! faster) {
518 Time += 60;
519 hourly_check();
520 }
521 }
522 }
523 break;
524 case JUNGLE:
525 locprint("Greenshriek Jungle.");
526 if (takestime) {
527 Time += 60;
528 hourly_check();
529 Time += 60;
530 hourly_check();
531 if (! faster) {
532 Time += 60;
533 hourly_check();
534 Time += 60;
535 hourly_check();
536 }
537 }
538 break;
539 case DESERT:
540 locprint("The Waste of Time.");
541 if (takestime) {
542 Time += 60;
543 hourly_check();
544 Time += 60;
545 hourly_check();
546 if (! faster) {
547 Time += 60;
548 hourly_check();
549 Time += 60;
550 hourly_check();
551 }
552 }
553 break;
554 case MOUNTAINS:
555 if ((Player.y < 9) && (Player.x < 12))
556 locprint("The Magic Mountains");
557 else if ((Player.y < 9) && (Player.y > 2) && (Player.x < 40))
558 locprint("The Peaks of the Fist.");
559 else if (Player.x < 52)
560 locprint("The Rift Mountains.");
561 else locprint("Borderland Mountains.");
562 if (takestime) {
563 Time += 60;
564 hourly_check();
565 Time += 60;
566 hourly_check();
567 Time += 60;
568 hourly_check();
569 Time += 60;
570 hourly_check();
571 Time += 60;
572 hourly_check();
573 if (! faster) {
574 Time += 60;
575 hourly_check();
576 Time += 60;
577 hourly_check();
578 Time += 60;
579 hourly_check();
580 }
581 }
582 break;
583 case PASS:
584 locprint("A hidden pass.");
585 if (takestime) {
586 Time += 60;
587 hourly_check();
588 }
589 break;
590 case CHAOS_SEA:
591 locprint("The Sea of Chaos.");
592 if (takestime) {
593 Time += 60;
594 hourly_check();
595 }
596 mprint("You have entered the sea of chaos...");
597 morewait();
598 l_chaos();
599 break;
600 case SWAMP:
601 locprint("The Loathly Swamp.");
602 if (takestime) {
603 Time += 60;
604 hourly_check();
605 Time += 60;
606 hourly_check();
607 Time += 60;
608 hourly_check();
609 Time += 60;
610 hourly_check();
611 Time += 60;
612 hourly_check();
613 Time += 60;
614 hourly_check();
615 if (! faster) {
616 Time += 60;
617 hourly_check();
618 Time += 60;
619 hourly_check();
620 }
621 }
622 break;
623 case CITY:
624 if (gamestatusp(LOST)) {
625 resetgamestatus(LOST);
626 mprint("Well, I guess you know where you are now....");
627 }
628 locprint("Outside Rampart, the city.");
629 break;
630 case VILLAGE:
631 if (gamestatusp(LOST)) {
632 resetgamestatus(LOST);
633 mprint("The village guards let you know where you are....");
634 }
635 locprint("Outside a small village.");
636 break;
637 case CAVES:
638 locprint("A deserted hillside.");
639 if (takestime) {
640 Time += 60;
641 hourly_check();
642 }
643 mprint("You notice a concealed entrance into the hill.");
644 break;
645 case CASTLE:
646 locprint("Near a fortified castle.");
647 if (takestime) {
648 Time += 60;
649 hourly_check();
650 }
651 mprint("The castle is hewn from solid granite. The drawbridge is down.");
652 break;
653 case TEMPLE:
654 switch(Country[Player.x][Player.y].aux) {
655 case ODIN: locprint("A rough-hewn granite temple."); break;
656 case SET: locprint("A black pyramidal temple made of sandstone."); break;
657 case ATHENA: locprint("A classical marble-columned temple."); break;
658 case HECATE: locprint("A temple of ebony adorned with ivory."); break;
659 case DRUID: locprint("A temple formed of living trees."); break;
660 case DESTINY: locprint("A temple of some mysterious blue crystal."); break;
661 }
662 if (takestime) {
663 Time += 60;
664 hourly_check();
665 }
666 mprint("You notice an entrance conveniently at hand.");
667 break;
668 case MAGIC_ISLE:
669 locprint("A strange island in the midst of the Sea of Chaos.");
670 if (takestime) {
671 Time += 60;
672 hourly_check();
673 }
674 mprint("There is a narrow causeway to the island from here.");
675 break;
676 case STARPEAK:
677 locprint("Star Peak.");
678 if (takestime) {
679 Time += 60;
680 hourly_check();
681 }
682 mprint("The top of the mountain seems to glow with a allochroous aura.");
683 break;
684 case DRAGONLAIR:
685 locprint("A rocky chasm.");
686 if (takestime) {
687 Time += 60;
688 hourly_check();
689 }
690 mprint("You are at a cave entrance from which you see the glint of gold.");
691 break;
692 case VOLCANO:
693 locprint("HellWell Volcano.");
694 if (takestime) {
695 Time += 60;
696 hourly_check();
697 }
698 mprint("A shimmer of heat lightning plays about the crater rim.");
699 break;
700 default:
701 locprint("I haven't any idea where you are!!!");
702 break;
703 }
704 outdoors_random_event();
705 }
706
707
708
countrysearch()709 void countrysearch()
710 {
711 int x,y;
712 Time+=60;
713 hourly_check();
714 for (x=Player.x-1;x<Player.x+2;x++)
715 for (y=Player.y-1;y<Player.y+2;y++)
716 if (inbounds(x,y)) {
717 if (Country[x][y].current_terrain_type !=
718 Country[x][y].base_terrain_type) {
719 clearmsg();
720 mprint("Your search was fruitful!");
721 Country[x][y].current_terrain_type=Country[x][y].base_terrain_type;
722 c_set(x, y, CHANGED);
723 mprint("You discovered:");
724 mprint(countryid(Country[x][y].base_terrain_type));
725 }
726 }
727 }
728
countryid(terrain)729 char *countryid(terrain)
730 Symbol terrain;
731 {
732 switch(terrain&0xff) {
733 case MOUNTAINS&0xff:
734 strcpy(Str1,"Almost impassable mountains");
735 break;
736 case PLAINS&0xff:
737 strcpy(Str1,"Seemingly endless plains");
738 break;
739 case TUNDRA&0xff:
740 strcpy(Str1,"A frosty stretch of tundra");
741 break;
742 case ROAD&0xff:
743 strcpy(Str1,"A paved highway");
744 break;
745 case PASS&0xff:
746 strcpy(Str1,"A secret mountain pass");
747 break;
748 case RIVER&0xff:
749 strcpy(Str1,"A rolling river");
750 break;
751 case CITY&0xff:
752 strcpy(Str1,"The city of Rampart");
753 break;
754 case VILLAGE&0xff:
755 strcpy(Str1,"A rural village");
756 break;
757 case FOREST&0xff:
758 strcpy(Str1,"A verdant forest");
759 break;
760 case JUNGLE&0xff:
761 strcpy(Str1,"A densely overgrown jungle");
762 break;
763 case SWAMP&0xff:
764 strcpy(Str1,"A swampy fen");
765 break;
766 case VOLCANO&0xff:
767 strcpy(Str1,"A huge active volcano");
768 break;
769 case CASTLE&0xff:
770 strcpy(Str1,"An imposing castle");
771 break;
772 case STARPEAK&0xff:
773 strcpy(Str1,"A mysterious mountain.");
774 break;
775 case DRAGONLAIR&0xff:
776 strcpy(Str1,"A cavern filled with treasure.");
777 break;
778 case MAGIC_ISLE&0xff:
779 strcpy(Str1,"An island emanating magic.");
780 break;
781 case CAVES&0xff:
782 strcpy(Str1,"A hidden cave entrance");
783 break;
784 case TEMPLE&0xff:
785 strcpy(Str1,"A neoclassical temple");
786 break;
787 case DESERT&0xff:
788 strcpy(Str1,"A sere desert");
789 break;
790 case CHAOS_SEA&0xff:
791 strcpy(Str1,"The Sea of Chaos");
792 break;
793 default:
794 strcpy(Str1,"I have no idea.");
795 break;
796 }
797 return(Str1);
798 }
799
800 static char *sitenames[] = { /* alphabetical listing */
801 "alchemist", "arena", "armorer", "bank", "brothel", "casino", "castle",
802 "city gates", "collegium magii", "condo", "department of public works",
803 "diner", "explorers' club", "fast food", "gymnasium", "healer", "hospice",
804 "les crapuleux", "library", "mercenary guild", "oracle", "order of paladins",
805 "pawn shop", "sorcerors' guild ", "tavern", "temple", "thieves' guild" };
806
807 static int sitenums[] = { /* the order matches sitenames[] */
808 L_ALCHEMIST, L_ARENA, L_ARMORER, L_BANK, L_BROTHEL, L_CASINO, L_CASTLE,
809 L_COUNTRYSIDE, L_COLLEGE, L_CONDO, L_DPW, L_DINER, L_CLUB, L_COMMANDANT,
810 L_GYM, L_HEALER, L_CHARITY, L_CRAP, L_LIBRARY, L_MERC_GUILD, L_ORACLE,
811 L_ORDER, L_PAWN_SHOP, L_SORCERORS, L_TAVERN, L_TEMPLE, L_THIEVES_GUILD };
812
showknownsites(first,last)813 void showknownsites(first, last)
814 int first, last;
815 {
816 int i,printed=FALSE;
817
818 menuclear();
819 menuprint("\nPossible Sites:\n");
820 for (i = first; i <= last; i++)
821 if (CitySiteList[sitenums[i] - CITYSITEBASE][0]) {
822 printed = TRUE;
823 menuprint(sitenames[i]);
824 menuprint("\n");
825 }
826 if (! printed)
827 menuprint("\nNo known sites match that prefix!");
828 showmenu();
829 }
830
parsecitysite()831 int parsecitysite()
832 {
833 int first, last, pos;
834 char byte, prefix[80];
835 int found = 0;
836 int f, l;
837
838 first = 0;
839 last = NUMCITYSITES - 1;
840 pos = 0;
841 print2("");
842 do {
843 byte = mgetc();
844 if (byte == BACKSPACE || byte == DELETE) {
845 if (pos > 0) {
846 prefix[--pos] = '\0';
847 byte = prefix[pos - 1];
848 f = first;
849 while (f >= 0 && !strncmp(prefix, sitenames[f], pos)) {
850 if (CitySiteList[sitenums[f] - CITYSITEBASE][0])
851 first = f;
852 f--;
853 }
854 l = last;
855 while (l < NUMCITYSITES && !strncmp(prefix, sitenames[l], pos)) {
856 if (CitySiteList[sitenums[l] - CITYSITEBASE][0])
857 last = l;
858 l++;
859 }
860 if (found)
861 found = 0;
862 print2(prefix);
863 }
864 if (pos == 0) {
865 first = 0;
866 last = NUMCITYSITES - 1;
867 found = 0;
868 print2("");
869 }
870 }
871 else if (byte == ESCAPE) {
872 xredraw();
873 return ABORT;
874 }
875 else if (byte == '?')
876 showknownsites(first, last);
877 else if (byte != '\n') {
878 if (byte >= 'A' && byte <= 'Z')
879 byte += 'a' - 'A';
880 if (found)
881 continue;
882 f = first;
883 l = last;
884 while (f < NUMCITYSITES &&
885 (!CitySiteList[sitenums[f] - CITYSITEBASE][0] ||
886 strlen(sitenames[f]) < pos || sitenames[f][pos] < byte))
887 f++;
888 while (l >= 0 && (!CitySiteList[sitenums[l] - CITYSITEBASE][0] ||
889 strlen(sitenames[l]) < pos || sitenames[l][pos] > byte))
890 l--;
891 if (l < f)
892 continue;
893 prefix[pos++] = byte;
894 prefix[pos] = '\0';
895 nprint2(prefix + pos - 1);
896 first = f;
897 last = l;
898 if (first == last && !found) { /* unique name */
899 found = 1;
900 nprint2(sitenames[first] + pos);
901 }
902 }
903 } while (byte != '\n');
904 xredraw();
905 if (found)
906 return sitenums[first] - CITYSITEBASE;
907 else {
908 print3("That is an ambiguous abbreviation!");
909 return ABORT;
910 }
911 }
912
913
914 /* are there hostile monsters within 2 moves? */
hostilemonstersnear()915 int hostilemonstersnear()
916 {
917 int i,j,hostile = FALSE;
918
919 for (i=Player.x-2;((i<Player.x+3)&&(! hostile));i++)
920 for (j=Player.y-2;((j<Player.y+3)&&(! hostile));j++)
921 if (inbounds(i,j))
922 if (Level->site[i][j].creature != NULL)
923 hostile = m_statusp(Level->site[i][j].creature,HOSTILE);
924
925 return(hostile);
926 }
927
928 /* random effects from some of stones in villages */
929 /* if alignment of stone is alignment of player, gets done sooner */
stonecheck(alignment)930 int stonecheck(alignment)
931 int alignment;
932 {
933 int *stone,match=FALSE,cycle=FALSE,i;
934
935 if (alignment == 1) {
936 stone = &Lawstone;
937 match = Player.alignment > 0;
938 }
939 else if (alignment == -1) {
940 stone = &Chaostone;
941 match = Player.alignment < 0;
942 }
943 else {
944 stone = &Mindstone;
945 match = FALSE;
946 }
947 *stone += random_range(4) + (match ? random_range(4) : 0);
948 switch((*stone)++) {
949 case 0:case 2:case 4:case 6:case 8:case 10:case 12:case 14:case 16:case 18:
950 case 20:case 22:case 24:case 26:case 28:case 30:case 32:case 34:case 36:
951 case 38:case 40: print1("The stone glows grey.");
952 print2("Not much seems to happen this time.");
953 (*stone)--;
954 break;
955 case 1: print1("The stone glows black");
956 print2("A burden has been removed from your shoulders.....");
957 print3("Your pack has disintegrated!");
958 for(i=0;i<MAXPACK;i++)
959 if (Player.pack[i] != NULL) {
960 free((char *) Player.pack[i]);
961 Player.pack[i] = NULL;
962 }
963 Player.packptr = 0;
964 break;
965 case 3: print1("The stone glows microwave");
966 print2("A vortex of antimana spins about you!");
967 morewait();
968 dispel(-1);
969 break;
970 case 5: print1("The stone glows infrared");
971 print2("A portal opens nearby and an obviously confused monster appears!");
972 summon(-1,-1);
973 morewait();
974 break;
975 case 7: print1("The stone glows brick red");
976 print2("A gold piece falls from the heavens into your money pouch!");
977 Player.cash++;
978 break;
979 case 9: print1("The stone glows cherry red");
980 print2("A flush of warmth spreads through your body.");
981 augment(1);
982 break;
983 case 11: print1("The stone glows orange");
984 print2("A flux of energy blasts you!");
985 manastorm(Player.x,Player.y,random_range(Player.maxhp)+1);
986 break;
987 case 13: print1("The stone glows lemon yellow");
988 print2("You're surrounded by enemies! You begin to foam at the mouth.");
989 Player.status[BERSERK] += 10;
990 break;
991 case 15: print1("The stone glows yellow");
992 print2("Oh no! The DREADED AQUAE MORTIS!");
993 morewait();
994 print2("No, wait, it's just your imagination.");
995 break;
996 case 17: print1("The stone glows chartreuse");
997 print2("Your joints stiffen up.");
998 Player.agi -= 3;
999 break;
1000 case 19: print1("The stone glows green");
1001 print2("You come down with an acute case of Advanced Leprosy.");
1002 Player.status[DISEASED] = 1100;
1003 Player.hp = 1;
1004 Player.dex -= 5;
1005 break;
1006 case 21: print1("The stone glows forest green");
1007 print2("You feel wonderful!");
1008 Player.status[HERO]+=10;
1009 break;
1010 case 23: print1("The stone glows cyan");
1011 print2("You feel a strange twisting sensation....");
1012 morewait();
1013 strategic_teleport(-1);
1014 break;
1015 case 25: print1("The stone glows blue");
1016 morewait();
1017 print1("You feel a tingle of an unearthly intuition:");
1018 morewait();
1019 hint();
1020 break;
1021 case 27: print1("The stone glows navy blue");
1022 print2("A sudden shock of knowledge overcomes you.");
1023 morewait();
1024 clearmsg();
1025 identify(1);
1026 knowledge(1);
1027 break;
1028 case 29: print1("The stone glows blue-violet");
1029 print2("You feel forgetful.");
1030 for(i=0;i<NUMSPELLS;i++)
1031 if (Spells[i].known) {
1032 Spells[i].known = FALSE;
1033 break;
1034 }
1035 break;
1036 case 31: print1("The stone glows violet");
1037 morewait();
1038 acquire(0);
1039 break;
1040 case 33: print1("The stone glows deep purple");
1041 print2("You vanish.");
1042 Player.status[INVISIBLE]+=10;
1043 break;
1044 case 35: print1("The stone glows ultraviolet");
1045 print2("All your hair rises up on end.... A bolt of lightning hits you!");
1046 p_damage(random_range(Player.maxhp),ELECTRICITY,"mystic lightning");
1047 break;
1048 case 37: print1("The stone glows roentgen");
1049 print2("You feel more experienced.");
1050 gain_experience((Player.level+1)*250);
1051 break;
1052 case 39: print1("The stone glows gamma");
1053 print2("Your left hand shines silvery, and your right emits a golden aura.");
1054 morewait();
1055 enchant(1);
1056 bless(1);
1057 print3("Your hands stop glowing.");
1058 break;
1059 case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 48:case 49:
1060 print1("The stone glows cosmic!");
1061 print2("The stone's energy field quiets for a moment...");
1062 *stone = 50;
1063 cycle = TRUE;
1064 break;
1065 default: print1("The stone glows polka-dot (?!?!?!?)");
1066 print2("You feel a strange twisting sensation....");
1067 morewait();
1068 *stone = 0;
1069 strategic_teleport(-1);
1070 break;
1071 }
1072 calc_melee();
1073 return(cycle);
1074 }
1075
alert_guards()1076 void alert_guards()
1077 {
1078 int foundguard=FALSE;
1079 pml ml;
1080 int suppress = 0;
1081 for(ml=Level->mlist;ml!=NULL;ml=ml->next)
1082 if (((ml->m->id == GUARD) ||
1083 ((ml->m->id == HISCORE_NPC) && (ml->m->aux2 == 15))) && /*justiciar*/
1084 (ml->m->hp > 0)) {
1085 foundguard=TRUE;
1086 m_status_set(ml->m,AWAKE);
1087 m_status_set(ml->m,HOSTILE);
1088 }
1089 if (foundguard) {
1090 mprint("You hear a whistle and the sound of running feet!");
1091 if (Current_Environment == E_CITY)
1092 Level->site[40][60].p_locf = L_NO_OP; /* pacify_guards restores this */
1093 }
1094 if ((! foundguard) && (Current_Environment == E_CITY) &&
1095 !gamestatusp(DESTROYED_ORDER)) {
1096 suppress = gamestatusp(SUPPRESS_PRINTING);
1097 resetgamestatus(SUPPRESS_PRINTING);
1098 print2("The last member of the Order of Paladins dies....");
1099 morewait();
1100 gain_experience(1000);
1101 Player.alignment -= 250;
1102 if (! gamestatusp(KILLED_LAWBRINGER)) {
1103 print1("A chime sounds from far away.... The sound grows stronger....");
1104 print2("Suddenly the great shadowy form of the LawBringer appears over");
1105 print3("the city. He points his finger at you....");
1106 morewait();
1107 print1("\"Cursed art thou, minion of chaos! May thy strength fail thee");
1108 print2("in thy hour of need!\" You feel an unearthly shiver as the");
1109 print3("LawBringer waves his palm across the city skies....");
1110 morewait();
1111 Player.str /= 2;
1112 dataprint();
1113 print1("You hear a bell tolling, and eerie moans all around you....");
1114 print2("Suddenly, the image of the LawBringer is gone.");
1115 print3("You hear a guardsman's whistle in the distance!");
1116 morewait();
1117 resurrect_guards();
1118 }
1119 else {
1120 print1("The Order's magical defenses have dropped, and the");
1121 print2("Legions of Chaos strike....");
1122 morewait();
1123 print1("The city shakes! An earthquake has struck!");
1124 print2("Cracks open in the street, and a chasm engulfs the Order HQ!");
1125 print3("Flames lick across the sky and you hear wild laughter....");
1126 morewait();
1127 gain_experience(5000);
1128 destroy_order();
1129 }
1130 }
1131 if (suppress)
1132 resetgamestatus(SUPPRESS_PRINTING);
1133 }
1134
1135
1136 /* can only occur when player is in city, so OK to use Level */
destroy_order()1137 void destroy_order()
1138 {
1139 int i,j;
1140 setgamestatus(DESTROYED_ORDER);
1141 if (Level != City) print1("Zounds! A Serious Mistake!");
1142 else
1143 for(i=35;i<46;i++)
1144 for(j=60;j<63;j++) {
1145 if (i == 40 && (j == 60 || j == 61)) {
1146 lreset(i,j,SECRET);
1147 Level->site[i][j].locchar = FLOOR;
1148 Level->site[i][j].p_locf = L_NO_OP;
1149 lset(i, j, CHANGED);
1150 }
1151 else {
1152 Level->site[i][j].locchar = RUBBLE;
1153 Level->site[i][j].p_locf = L_RUBBLE;
1154 lset(i, j, CHANGED);
1155 }
1156 if (Level->site[i][j].creature != NULL) {
1157 Level->site[i][j].creature->hp = -1;
1158 Level->site[i][j].creature = NULL;
1159 }
1160 make_site_monster(i,j,GHOST);
1161 Level->site[i][j].creature->monstring = "ghost of a Paladin";
1162 m_status_set(Level->site[i][j].creature,HOSTILE);
1163 }
1164 }
1165
1166
1167
maneuvers()1168 int maneuvers()
1169 {
1170 int m;
1171
1172 m = 2 + Player.level/7;
1173 if (Player.rank[ARENA]) m++;
1174 if (Player.status[HASTED])
1175 m *= 2;
1176 if (Player.status[SLOWED])
1177 m /= 2;
1178 m = min(8,max(1,m));
1179
1180 return(m);
1181 }
1182
1183 /* for when haste runs out, etc. */
default_maneuvers()1184 void default_maneuvers()
1185 {
1186 int i;
1187 morewait();
1188 clearmsg();
1189 print1("Warning, resetting your combat options to the default.");
1190 print2("Use the 'F' command to select which options you prefer.");
1191 morewait();
1192 for(i=0;i<maneuvers();i+=2) {
1193 Player.meleestr[i*2]='A';
1194 Player.meleestr[(i*2)+1]='C';
1195 Player.meleestr[(i+1)*2]='B';
1196 Player.meleestr[((i+1)*2)+1]='C';
1197 }
1198 Player.meleestr[maneuvers()*2]=0;
1199 }
1200