1 /* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */
2 /* move.c */
3 /* general functions for player moving */
4 
5 #include "glob.h"
6 
7 
8 
9 /* various miscellaneous location functions */
l_water()10 void l_water()
11 {
12   if (! gamestatusp(MOUNTED))  {
13     if ((Player.possessions[O_ARMOR] != NULL)) {
14       print1("Your heavy armor drags you under the water!");
15       morewait();
16       p_drown();
17       print2("You reach the surface again.");
18     }
19     else if (Player.itemweight > ((int) (Player.maxweight / 2))) {
20       print1("The weight of your burden drags you under water!");
21       morewait();
22       p_drown();
23       print2("You reach the surface again.");
24     }
25     else switch(random_range(32)) {
26     case 0:print1("Splish. Splash!"); break;
27     case 1:print1("I want my ducky!"); break;
28     case 2:print1("So finally you take a bath!"); break;
29     case 3:print1("You must be very thirsty!"); break;
30     }
31   }
32   else switch(random_range(32)) {
33     case 0:print1("Your horse frolics playfully in the water."); break;
34     case 1:print1("Your horse quenches its thirst."); break;
35     case 2:print1("Your steed begins to swim...."); break;
36     case 3:print1("Your mount thrashes about in the water."); break;
37     }
38 }
39 
40 
41 
l_chaos()42 void l_chaos()
43 {
44   if (gamestatusp(MOUNTED)) {
45     print1("Your steed tries to swim in the raw Chaos, but seems to");
46     print2("be having some difficulties...");
47     morewait();
48     print1("probably because it's just turned into a chaffinch.");
49     morewait();
50     resetgamestatus(MOUNTED);
51   }
52   if (! onewithchaos)
53     print1("You are immersed in raw Chaos....");
54   if (Player.rank[ADEPT]) {
55     if (! onewithchaos)
56     {
57       onewithchaos = 1;
58       print2("You achieve oneness of Chaos....");
59     }
60     Player.mana = max(Player.mana,calcmana());
61     Player.hp = max(Player.hp, Player.maxhp);
62   }
63   else if (Player.rank[PRIESTHOOD] && (! saved)) {
64     print2("A mysterious force protects you from the Chaos!");
65     print3("Wow.... You feel a bit smug.");
66     gain_experience(500);
67     saved = TRUE;
68   }
69   else {
70     print2("Uh oh....");
71     if (saved) nprint2("Nothing mysterious happens this time....");
72     morewait();
73     print1("Congratulations! You've achieved maximal entropy!");
74     Player.alignment -= 50;
75     gain_experience(1000);
76     p_death("immersion in raw Chaos");
77   }
78 }
79 
80 
81 
82 
l_hedge()83 void l_hedge()
84 {
85   if (Player.patron == DRUID) print1("You move through the hedges freely.");
86   else {
87     print1("You struggle in the brambly hedge... ");
88     switch(random_range(6)) {
89     case 0:
90       print2("You are stabbed by thorns!");
91       p_damage(random_range(6),NORMAL_DAMAGE,"a hedge");
92       print3("The thorns were poisonous!");
93       p_poison(random_range(12));
94       break;
95     case 1:
96       print2("You are stabbed by thorns!");
97       p_damage(random_range(12),NORMAL_DAMAGE,"a hedge");
98       break;
99     case 2:
100       print2("You seem to have gotten stuck in the hedge.");
101       Player.status[IMMOBILE]+=random_range(5)+1;
102       break;
103     case 3:
104       if (Player.possessions[O_CLOAK] != NULL) {
105 	print2("Your cloak was torn on the brambles!");
106 	dispose_lost_objects(1,Player.possessions[O_CLOAK]);
107       }
108       else print2("Ouch! These thorns are scratchy!");
109       break;
110     default: print2("You make your way through unscathed."); break;
111     }
112   }
113 }
114 
115 
116 
l_lava()117 void l_lava()
118 {
119   print1("Very clever -- walking into a pool of lava...");
120   if (gamestatusp(MOUNTED)) {
121     print2("Your horse is incinerated... You fall in too!");
122     resetgamestatus(MOUNTED);
123   }
124   morewait();
125   if (strcmp(Player.name,"Saltheart Foamfollower")==0) {
126     print1("Strangely enough, you don't seem terribly affected.");
127     p_damage(1,UNSTOPPABLE,"slow death in a pool of lava");
128   }
129   else {
130     p_damage(random_range(75),FLAME,"incineration in a pool of lava");
131     if (Player.hp> 0) p_drown();
132     Player.status[IMMOBILE]+=2;
133   }
134 }
135 
136 
137 
l_fire()138 void l_fire()
139 {
140   print1("You boldly stride through the curtain of fire...");
141   if (gamestatusp(MOUNTED)) {
142     print2("Your horse is fried and so are you...");
143     resetgamestatus(MOUNTED);
144   }
145   p_damage(random_range(100),FLAME,"self-immolation");
146 }
147 
l_abyss()148 void l_abyss()
149 {
150   int i;
151   if (Current_Environment != Current_Dungeon) {
152     print1("You fall through a dimensional portal!");
153     morewait();
154     strategic_teleport(-1);
155   }
156   else {
157     print1("You enter the infinite abyss!");
158     morewait();
159     if (random_range(100)==13) {
160       print1("As you fall you see before you what seems like");
161       print2("an infinite congerie of iridescent bubbles.");
162       print3("You have met Yog Sothoth!!!");
163       morewait();
164       clearmsg();
165       if (Player.alignment > -10)
166 	p_death("the Eater of Souls");
167       else {
168 	print1("The All-In-One must have taken pity on you.");
169 	print2("A transdimensional portal appears...");
170 	morewait();
171 	change_level(Level->depth,Level->depth+1,FALSE);
172 	gain_experience(2000);
173 	Player.alignment -= 50;
174       }
175     }
176     else {
177       i = 0;
178       print1("You fall...");
179       while(random_range(3)!=2) {
180 	if (i%6 == 0)
181 	    print2("and fall... ");
182 	else
183 	    nprint2("and fall... ");
184 	i++;
185 	morewait();
186       }
187       i++;
188       print1("Finally,you emerge through an interdimensional interstice...");
189       morewait();
190       if (Level->depth+i>MaxDungeonLevels) {
191 	print2("You emerge high above the ground!!!!");
192 	print3("Yaaaaaaaah........");
193 	morewait();
194 	change_environment(E_COUNTRYSIDE);
195 	do {
196 	  Player.x = random_range(WIDTH);
197 	  Player.y = random_range(LENGTH);
198 	} while(Country[Player.x][Player.y].base_terrain_type == CHAOS_SEA);
199 	p_damage(i*50,NORMAL_DAMAGE,"a fall from a great height");
200       }
201       else {
202 	print2("You built up some velocity during your fall, though....");
203 	morewait();
204 	p_damage(i*5,NORMAL_DAMAGE,"a fall through the abyss");
205 	change_level(Level->depth,Level->depth+i,FALSE);
206 	gain_experience(i*i*50);
207       }
208     }
209   }
210 }
211 
212 
l_lift()213 void l_lift()
214 {
215   char response;
216   int levelnum;
217   int distance;
218   int too_far = 0;
219 
220   Level->site[Player.x][Player.y].locchar = FLOOR;
221   Level->site[Player.x][Player.y].p_locf = L_NO_OP;
222   lset(Player.x, Player.y, CHANGED);
223   print1("You walk onto a shimmering disk....");
224   print2("The disk vanishes, and a glow surrounds you.");
225   print3("You feel weightless.... You feel ghostly....");
226   morewait();
227   clearmsg();
228   print1("Go up, down, or neither [u,d,ESCAPE] ");
229   do response = (char) mcigetc();
230   while ((response != 'u') &&
231 	 (response != 'd') &&
232 	 (response != ESCAPE));
233   if (response != ESCAPE) {
234     print1("How many levels?");
235     levelnum = (int) parsenum();
236     if (levelnum > 6) {
237       too_far = 1;
238       levelnum = 6;
239     }
240     if (response == 'u' && Level->depth - levelnum < 1) {
241       distance = levelnum - Level->depth;
242       change_environment(E_COUNTRYSIDE); /* "you return to the countryside." */
243       if (distance > 0) {
244 	nprint1("..");
245 	print2("...and keep going up!  You hang in mid air...");
246 	morewait();
247 	print3("\"What goes up...\"");
248 	morewait();
249 	print3("Yaaaaaaaah........");
250 	p_damage(distance*10,NORMAL_DAMAGE,"a fall from a great height");
251       }
252       return;
253     }
254     else if (response == 'd' && Level->depth + levelnum > MaxDungeonLevels) {
255       too_far = 1;
256       levelnum = MaxDungeonLevels - Level->depth;
257     }
258     if (levelnum == 0) {
259       print1("Nothing happens.");
260       return;
261     }
262     if (too_far) {
263       print1("The lift gives out partway...");
264       print2("You rematerialize.....");
265     }
266     else
267       print1("You rematerialize.....");
268     change_level(Level->depth,
269 		(response=='d' ?
270 		 Level->depth+levelnum :
271 		 Level->depth-levelnum),
272 		FALSE);
273     roomcheck();
274   }
275 }
276 
277 
l_magic_pool()278 void l_magic_pool()
279 {
280   int possibilities=random_range(100);
281   print1("This pool seems to be enchanted....");
282   if (gamestatusp(MOUNTED)) {
283     if (random_range(2)) {
284       print2("Your horse is polymorphed into a fig newton.");
285       resetgamestatus(MOUNTED);
286     }
287     else print2("Whatever it was, your horse enjoyed it....");
288   }
289   else  if (possibilities == 0) {
290     print1("Oh no! You encounter the DREADED AQUAE MORTIS...");
291     if (random_range(1000) < Player.level*Player.level*Player.level) {
292       print2("The DREADED AQUAE MORTIS throttles you within inches....");
293       print3("but for some reason chooses to let you escape.");
294       gain_experience(500);
295       Player.hp = 1;
296     }
297     else p_death("the DREADED AQUAE MORTIS!");
298   }
299   else if (possibilities < 25)
300     augment(0);
301   else if (possibilities < 30)
302     augment(1);
303   else if (possibilities < 60)
304     augment(-1);
305   else if (possibilities < 65)
306     cleanse(1);
307   else if (possibilities < 80) {
308     if (Player.possessions[O_WEAPON_HAND] != NULL) {
309       print1("You drop your weapon in the pool! It's gone forever!");
310       dispose_lost_objects(1,Player.possessions[O_WEAPON_HAND]);
311     }
312     else print1("You feel fortunate.");
313   }
314   else if (possibilities < 90) {
315     if (Player.possessions[O_WEAPON_HAND] != NULL) {
316       print1("Your weapon leaves the pool with a new edge....");
317       Player.possessions[O_WEAPON_HAND]->plus += random_range(10)+1;
318       calc_melee();
319     }
320     else print1("You feel unfortunate.");
321   }
322   else if (possibilities < 95) {
323     Player.hp += 10;
324     print1("You feel healthier after the dip...");
325   }
326   else if (possibilities < 99) {
327     print1("Oooh, a tainted pool...");
328     p_poison(10);
329   }
330   else if (possibilities == 99) {
331     print1("Wow! A pool of azoth!");
332     heal(10);
333     cleanse(1);
334     Player.mana = calcmana()*3;
335     Player.str = (Player.maxstr++)*3;
336   }
337   print2("The pool seems to have dried up.");
338   Level->site[Player.x][Player.y].locchar = TRAP;
339   Level->site[Player.x][Player.y].p_locf = L_TRAP_PIT;
340   lset(Player.x, Player.y, CHANGED);
341 }
342 
343 
344 
345 
346 
347 
348 
349 
350 
351 
352 
353 
354 
l_no_op()355 void l_no_op()
356 {
357 }
358 
359 
l_tactical_exit()360 void l_tactical_exit()
361 {
362   if (optionp(CONFIRM)) {
363     clearmsg();
364     print1("Do you really want to leave this place? ");
365     if (ynq1() != 'y')
366       return;
367   }
368   /* Free up monsters and items, and the level, if not SAVE_LEVELS */
369   free_level(Level);
370   Level = NULL;
371   if ((Current_Environment == E_TEMPLE) ||
372       (Current_Environment == E_TACTICAL_MAP) )
373     change_environment(E_COUNTRYSIDE);
374   else change_environment(Last_Environment);
375 }
376 
377 
l_rubble()378 void l_rubble()
379 {
380   int screwup = random_range(100) - (Player.agi + Player.level);
381   print1("You climb over the unstable pile of rubble....");
382   if (screwup < 0) print2("No problem!");
383   else {
384     print2("You tumble and fall in a small avalanche of debris!");
385     print3("You're trapped in the pile!");
386     Player.status[IMMOBILE]+=2;
387     p_damage(screwup/5,UNSTOPPABLE,"rubble and debris");
388     morewait();
389   }
390 }
391 
392 
393 
394 
395 
396 /* Drops all portcullises in 5 moves */
l_portcullis_trap()397 void l_portcullis_trap()
398 {
399   int i,j,slam=FALSE;
400 
401   print3("Click.");
402   morewait();
403   for (i=max(Player.x-5,0);i<min(Player.x+6,WIDTH);i++)
404     for(j=max(Player.y-5,0);j<min(Player.y+6,LENGTH);j++) {
405       if ((Level->site[i][j].p_locf == L_PORTCULLIS) &&
406 	  (Level->site[i][j].locchar != PORTCULLIS)) {
407 	Level->site[i][j].locchar = PORTCULLIS;
408 	lset(i, j, CHANGED);
409 	putspot(i,j,PORTCULLIS);
410 	if ((i==Player.x)&&(j==Player.y)) {
411 	  print3("Smash! You've been hit by a falling portcullis!");
412 	  morewait();
413 	  p_damage(random_range(1000),NORMAL_DAMAGE,"a portcullis");
414 	}
415 	slam = TRUE;
416       }
417     }
418   if (slam) print3("You hear heavy walls slamming down!");
419 }
420 
421 /* drops every portcullis on level, then kills itself and all similar traps. */
l_drop_every_portcullis()422 void l_drop_every_portcullis()
423 {
424   int i,j,slam=FALSE;
425 
426   print3("Click.");
427   morewait();
428   for (i=0;i<WIDTH;i++)
429     for(j=0;j<LENGTH;j++) {
430       if (Level->site[i][j].p_locf == L_DROP_EVERY_PORTCULLIS) {
431 	Level->site[i][j].p_locf = L_NO_OP;
432 	lset(i, j, CHANGED);
433       }
434       else if ((Level->site[i][j].p_locf == L_PORTCULLIS) &&
435 	  (Level->site[i][j].locchar != PORTCULLIS)) {
436 	Level->site[i][j].locchar = PORTCULLIS;
437 	lset(i, j, CHANGED);
438 	putspot(i,j,PORTCULLIS);
439 	if ((i==Player.x)&&(j==Player.y)) {
440 	  print3("Smash! You've been hit by a falling portcullis!");
441 	  morewait();
442 	  p_damage(random_range(1000),NORMAL_DAMAGE,"a portcullis");
443 	}
444 	slam = TRUE;
445       }
446     }
447   if (slam) print3("You hear heavy walls slamming down!");
448 }
449 
450 
451 
l_raise_portcullis()452 void l_raise_portcullis()
453 {
454   int i,j,open=FALSE;
455   for (i=0;i<WIDTH;i++)
456     for(j=0;j<LENGTH;j++) {
457       if (Level->site[i][j].locchar == PORTCULLIS) {
458 	Level->site[i][j].locchar = FLOOR;
459 	lset(i, j, CHANGED);
460 	putspot(i,j,FLOOR);
461 	open = TRUE;
462       }
463     }
464   if (open) print1("You hear the sound of steel on stone!");
465 }
466 
467 
l_arena_exit()468 void l_arena_exit()
469 {
470   resetgamestatus(ARENA_MODE);
471 #ifndef MSDOS_SUPPORTED_ANTIQUE
472   free_level(Level);
473 #endif
474   Level = NULL;
475   change_environment(E_CITY);
476 }
477 
478 
l_house_exit()479 void l_house_exit()
480 {
481   if (optionp(CONFIRM)) {
482     clearmsg();
483     print1("Do you really want to leave this abode? ");
484     if (ynq1() != 'y')
485       return;
486   }
487 #ifndef MSDOS_SUPPORTED_ANTIQUE
488   free_level(Level);
489 #endif
490   Level = NULL;
491   change_environment(Last_Environment);
492 }
493 
494 
l_void()495 void l_void()
496 {
497   clearmsg();
498   print1("Geronimo!");
499   morewait();
500   clearmsg();
501   print1("You leap into the void.");
502   if (Level->mlist) {
503     print2("Death peers over the edge and gazes quizzically at you....");
504     morewait();
505     print3("'Bye-bye,' he says... 'We'll meet again.'");
506   }
507   morewait();
508   while(Player.hp>0) {
509     Time+=60;
510     hourly_check();
511     usleep(250000);
512   }
513 }
514 
515 
l_fire_station()516 void l_fire_station()
517 {
518   print1("The flames leap up, and the heat is incredible.");
519   if (Player.immunity[FLAME]) {
520     print2("You feel the terrible heat despite your immunity to fire!");
521     morewait();
522   }
523   print2("Enter the flames? [yn] ");
524   if (ynq2()=='y') {
525     if (Player.hp == 1) p_death("total incineration");
526     else Player.hp = 1;
527     dataprint();
528     print1("You feel like you are being incinerated! Jump back? [yn] ");
529     if (ynq1()=='y')
530       print2("Phew! That was close!");
531     else {
532       Player.pow -= (15+random_range(15));
533       if (Player.pow > 0) {
534 	print2("That's odd, the flame seems to have cooled down now....");
535 	print3("A flicker of fire seems to dance above the void nearby.");
536 	Level->site[Player.x][Player.y].locchar = FLOOR;
537 	Level->site[Player.x][Player.y].p_locf = L_NO_OP;
538 	stationcheck();
539       }
540       else {
541 	print2("The flames seem to have leached away all your mana!");
542 	p_death("the Essence of Fire");
543       }
544     }
545   }
546   else print2("You flinch away from the all-consuming fire.");
547 }
548 
549 
550 
551 
l_water_station()552 void l_water_station()
553 {
554   print1("The fluid seems murky and unknowably deep.");
555   print2("It bubbles and hisses threateningly.");
556   morewait();
557   if (Player.status[BREATHING]) {
558     print1("You don't feel sanguine about trying to breathe that stuff!");
559     morewait();
560   }
561   if (Player.immunity[ACID]) {
562     print2("The vapor burns despite your immunity to acid!");
563     morewait();
564   }
565   print1("Enter the fluid? [yn] ");
566   if (ynq1()=='y') {
567     if (Player.hp == 1) p_death("drowning in acid (ick, what a way to go)");
568     else Player.hp = 1;
569     dataprint();
570     print2("You choke....");
571     morewait();
572     nprint2("Your lungs burn....");
573     morewait();
574     print2("Your body begins to disintegrate.... Leave the pool? [yn] ");
575     if (ynq2()=='y')
576       print2("Phew! That was close!");
577     else {
578       clearmsg();
579       Player.con -= (15+random_range(15));
580       if (Player.con > 0) {
581 	print1("That's odd, the fluid seems to have been neutralized....");
582 	print2("A moist miasma wafts above the void nearby.");
583 	Level->site[Player.x][Player.y].locchar = FLOOR;
584 	Level->site[Player.x][Player.y].p_locf = L_NO_OP;
585 	stationcheck();
586       }
587       else {
588 	print2("The bubbling fluid has destroyed your constitution!");
589 	p_death("the Essence of Water");
590       }
591     }
592 
593   }
594   else print2("You step back from the pool of acid.");
595 }
596 
597 
598 
599 
l_air_station()600 void l_air_station()
601 {
602   print1("The whirlwind spins wildly and crackles with lightning.");
603   if (Player.immunity[ELECTRICITY])
604     print2("You feel static cling despite your immunity to electricity!");
605   morewait();
606   print1("Enter the storm? [yn] ");
607   if (ynq1()=='y') {
608     if (Player.hp == 1) p_death("being torn apart and then electrocuted");
609     else Player.hp = 1;
610     dataprint();
611     print1("You are buffeted and burnt by the storm....");
612     print2("You begin to lose consciousness.... Leave the storm? [yn] ");
613     if (ynq1()=='y')
614       print2("Phew! That was close!");
615     else {
616       Player.iq -= (random_range(15)+15);
617       if (Player.iq > 0) {
618 	print1("That's odd, the storm subsides....");
619 	print2("A gust of wind brushes past the void nearby.");
620 	Level->site[Player.x][Player.y].locchar = FLOOR;
621 	Level->site[Player.x][Player.y].p_locf = L_NO_OP;
622 	stationcheck();
623       }
624       else {
625 	print2("The swirling storm has destroyed your intelligence!");
626 	p_death("the Essence of Air");
627       }
628     }
629   }
630   else print2("You step back from the ominous whirlwind.");
631 }
632 
633 
634 
635 
l_earth_station()636 void l_earth_station()
637 {
638   pob o;
639   print1("The tendrilled mass reaches out for you from the muddy ooze.");
640   if (find_item(&o,THINGID+6,-1))
641     print2("A splash of salt water does nothing to dissuade the vines.");
642   morewait();
643   print1("Enter the overgrown mire? [yn] ");
644   if (ynq1()=='y') {
645     if (Player.hp == 1) p_death("being eaten alive");
646     else Player.hp = 1;
647     dataprint();
648     print1("You are being dragged into the muck. Suckers bite you....");
649     print2("You're about to be entangled.... Leave the mud? [yn] ");
650     if (ynq2()=='y')
651       print2("Phew! That was close!");
652     else {
653       Player.str -= (15+random_range(15));
654       if (Player.str > 0) {
655 	print1("That's odd, the vine withdraws....");
656 	print2("A spatter of dirt sprays into the void nearby.");
657 	Level->site[Player.x][Player.y].locchar = FLOOR;
658 	Level->site[Player.x][Player.y].p_locf = L_NO_OP;
659 	stationcheck();
660       }
661       else {
662 	print2("The tendril has destroyed your strength!");
663 	p_death("the Essence of Earth");
664       }
665     }
666   }
667   else print2("You step back from the ominous vegetation.");
668 }
669 
stationcheck()670 void stationcheck()
671 {
672   int stationsleft=FALSE;
673   int i,j;
674   morewait();
675   clearmsg();
676   print1("You feel regenerated.");
677   Player.hp = Player.maxhp;
678   dataprint();
679   for(i=0;i<WIDTH;i++)
680     for(j=0;j<LENGTH;j++)
681       if ((Level->site[i][j].locchar == WATER) ||
682 	  (Level->site[i][j].locchar == HEDGE) ||
683 	  (Level->site[i][j].locchar == WHIRLWIND) ||
684 	  (Level->site[i][j].locchar == FIRE))
685 	stationsleft=TRUE;
686   if (! stationsleft) {
687     print1("There is a noise like a wild horse's neigh.");
688     print2("You spin around, and don't see anyone around at all");
689     print3("except for a spurred black cloaked figure carrying a scythe.");
690     morewait();clearmsg();
691     print1("Death coughs apologetically. He seems a little embarrassed.");
692     print2("A voice peals out:");
693     print3("'An Adept must be able to conquer Death himself....");
694     make_site_monster(32,4,DEATH);
695   }
696 }
697 
698 
699 /* To survive the void, the other four stations must be visited first,
700    to activate the void, then something (Death's scythe, possibly)
701    must be thrown in to satiate the void, then all other items must
702    be dropped, then the void must be entered. */
703 
l_void_station()704 void l_void_station()
705 {
706   int i,something=FALSE;
707   print1("You are at the brink of an endless void. Enter it? [yn] ");
708   if (ynq()=='y') {
709     if (Level->mlist == NULL) {
710       print2("You fall forever. Eventually you die of starvation.");
711       morewait();
712       while(Player.hp>0) {
713 	Time+=60;
714 	hourly_check();
715 	usleep(250000);
716       }
717     }
718     else {
719       print1("You enter the void.");
720       print2("You feel a sudden surge of power from five directions.");
721       morewait();
722       something = (Player.packptr > 0);
723       if (! something)
724 	for(i=0;((i<MAXITEMS)&&(!something));i++)
725 	  if (Player.possessions[i] != NULL)
726 	    something = TRUE;
727       if (something) {
728 	print1("The flow of power is disrupted by something!");
729 	print2("The power is unbalanced! You lose control!");
730 	morewait();
731 	print1("Each of your cells explodes with a little scream of pain.");
732 	print2("Your disrupted essence merges with the megaflow.");
733 	p_death("the Power of the Void");
734       }
735       else if (! gamestatusp(PREPARED_VOID)){
736 	print1("The hungry void swallows you whole!");
737 	print2("Your being dissipates with a pathetic little sigh....");
738 	p_death("the Emptyness of the Void");
739       }
740       else {
741 	print1("The flow of power rages through your body,");
742 	print2("but you manage to master the surge!");
743 	print3("You feel adept....");
744 	morewait();clearmsg();
745 	print1("With a thought, you soar up through the void to the");
746 	print2("place from whence you came.");
747 	print3("As the platform of the Challenge dwindles beneath you");
748 	morewait();
749 	clearmsg();
750 	print1("You see Death raise his scythe to you in a salute.");
751 	Player.rank[ADEPT] = 1;
752 	setgamestatus(COMPLETED_CHALLENGE);
753 	FixedPoints = calc_points();
754 	/* set so change_environment puts player in correct temple! */
755 	Player.x = 49;
756 	Player.y = 59;
757 	print2("You find yourself back in the Temple of Destiny.");
758 	morewait();
759 	change_environment(E_TEMPLE);
760       }
761     }
762   }
763   else print2("You back away from the edge....");
764 }
765 
766 
l_voice1()767 void l_voice1()
768 {
769   print1("A mysterious voice says: The Hunger of the Void must be satiated.");
770   Level->site[Player.x][Player.y].p_locf = L_NO_OP;
771 }
772 
l_voice2()773 void l_voice2()
774 {
775   print1("A strange voice recites: Enter the Void as you entered the World.");
776   Level->site[Player.x][Player.y].p_locf = L_NO_OP;
777 }
778 
l_voice3()779 void l_voice3()
780 {
781   print1("An eerie voice resounds: The Void is the fifth Elemental Station.");
782   Level->site[Player.x][Player.y].p_locf = L_NO_OP;
783 }
784 
785 
l_whirlwind()786 void l_whirlwind()
787 {
788   print1("Buffeting winds swirl you up!");
789   p_damage(random_range(difficulty()*10),NORMAL_DAMAGE,"a magic whirlwind");
790   if (random_range(2)) {
791     print2("You are jolted by lightning!");
792     p_damage(random_range(difficulty()*10),ELECTRICITY,"a magic whirlwind");
793   }
794   morewait();
795   if (random_range(2)) {
796     print1("The whirlwind carries you off....");
797     if (random_range(20)==17)
798       print2("'I don't think we're in Kansas anymore, toto.'");
799     p_teleport(0);
800   }
801 }
802 
803 
l_enter_circle()804 void l_enter_circle()
805 {
806   print1("You see a translucent stairway before you, leading down.");
807   print2("Take it? [yn] ");
808   if (ynq()=='y')
809     change_environment(E_CIRCLE);
810 }
811 
l_circle_library()812 void l_circle_library()
813 {
814   print1("You see before you the arcane library of the Circle of Sorcerors.");
815 }
816 
l_tome1()817 void l_tome1()
818 {
819   menuclear();
820   menuprint("\nYou discover in a dusty tome some interesting information....");
821   menuprint("\nThe Star Gem holds a vast amount of mana, usable");
822   menuprint("\nfor either Law or Chaos. It is magically linked to Star Peak");
823   menuprint("\nand can either be activated or destroyed there. If destroyed,");
824   menuprint("\nits power will be used for Chaos, if activated, for Law.");
825   menuprint("\n\nIt is said the LawBringer has waited for an eternity");
826   menuprint("\nat Star Peak for someone to bring him the gem.");
827   menuprint("\nIt is also rumored that while anyone might destroy the gem,");
828   menuprint("\nreleasing chaotic energy, only the LawBringer can release");
829   menuprint("\nthe lawful potential of the gem.");
830   showmenu();
831   morewait();
832   xredraw();
833 }
834 
835 
l_tome2()836 void l_tome2()
837 {
838   menuclear();
839   menuprint("\nYou discover in some ancient notes that the Star Gem can be");
840   menuprint("\nused for transportation, but also read a caution that it must");
841   menuprint("\nbe allowed to recharge a long time between uses.");
842   menuprint("\nA marginal note says 'if only it could be reset to go somewhere");
843   menuprint("\nbesides Star Peak, the gem might be useful....'");
844   showmenu();
845   morewait();
846   xredraw();
847 }
848 
849 
l_temple_warning()850 void l_temple_warning()
851 {
852   print1("A stern voice thunders in the air around you:");
853   print2("'No unbelievers may enter these sacred precincts;");
854   print3("those who defile this shrine will be destroyed!");
855 }
856 
l_throne()857 void l_throne()
858 {
859   pob o;
860   int i;
861   print1("You have come upon a huge ornately appointed throne!");
862   print2("Sit in it? [yn] ");
863   if (ynq1()=='y') {
864     if (! find_item(&o,ARTIFACTID+22,-1)) {
865       print1("The throne emits an eerie violet-black radiance.");
866       print2("You find, to your horror, that you cannot get up!");
867       print3("You feel an abstract sucking sensation...");
868       for(i=0;i<NUMSPELLS;i++) Spells[i].known = FALSE;
869       Player.pow = 3;
870       Player.mana = 0;
871       Player.hp = 1;
872       dispel(-1);
873       morewait();clearmsg();
874       print1("The radiance finally ceases. You can get up now.");
875     }
876     else {
877       if (HiMagicUse == Date)
878 	print3("You hear the sound of a magic kazoo played by an asthmatic.");
879       else {
880 	HiMagicUse = Date;
881 	print1("Following some strange impulse, you raise the Sceptre....");
882 	print2("You hear a magical fanfare, repeated three times.");
883 	switch(HiMagic++) {
884 	case 0:
885 	  print3("Strength.");
886 	  Player.str+=5;
887 	  Player.maxstr+=5;
888 	  break;
889 	case 1:
890 	  print3("Constitution.");
891 	  Player.con+=5;
892 	  Player.maxcon+=5;
893 	  break;
894 	case 2:
895 	  print3("Dexterity.");
896 	  Player.dex+=5;
897 	  Player.maxdex+=5;
898 	  break;
899 	case 3:
900 	  print3("Agility.");
901 	  Player.agi+=5;
902 	  Player.maxagi+=5;
903 	  break;
904 	case 4:
905 	  print3("Intelligence.");
906 	  Player.iq+=5;
907 	  Player.maxiq+=5;
908 	  break;
909 	case 5:
910 	  print3("Power.");
911 	  Player.pow+=5;
912 	  Player.maxpow+=5;
913 	  break;
914 	default:
915 	  if (Spells[S_WISH].known) {
916 	    print1("A mysterious voice mutters peevishly....");
917 	    print2("So what do you want now? A medal?");
918 	  }
919 	  else {
920 	    print1("Mystic runes appear in the air before you:");
921 	    print2("They appear to describe some high-powered spell.");
922 	    morewait();
923 	    print1("You hear a distant voice....");
924 	    print2("'You may now tread the path of High Magic.'");
925 	    Spells[S_WISH].known = TRUE;
926 	  }
927 	  break;
928 	case 17:
929 	  print1("Weird flickering lights play over the throne.");
930 	  print2("You hear a strange droning sound, as of a magical");
931 	  morewait();
932 	  print1("artifact stressed by excessive use....");
933 	  print2("With an odd tinkling sound the throne shatters!");
934 	  Level->site[Player.x][Player.y].locchar = RUBBLE;
935 	  Level->site[Player.x][Player.y].p_locf = L_RUBBLE;
936 	  lset(Player.x, Player.y, CHANGED);
937 	  if (find_and_remove_item(ARTIFACTID+22,-1)) {
938 	    morewait();
939 	    print1("Your sceptre reverberates with the noise, and");
940 	    print2("it too explodes in a spray of shards.");
941 	  }
942 	  break;
943 	}
944 	calc_melee();
945 	dataprint();
946       }
947     }
948   }
949 }
950 
951 
l_escalator()952 void l_escalator()
953 {
954   print1("You have found an extremely long stairway going straight up.");
955   print2("The stairs are grilled steel and the bannister is rubber.");
956   morewait();
957   print1("Take the stairway? [yn] ");
958   if (ynq1()=='y') {
959     print1("The stairs suddenly start moving with a grind of gears!");
960     print2("You are wafted to the surface....");
961     change_environment(E_COUNTRYSIDE);
962   }
963 }
964 
l_enter_court()965 void l_enter_court()
966 {
967   print1("You have found a magical portal! Enter it? [yn] ");
968   if (ynq1()=='y') {
969     if (! gamestatusp(COMPLETED_CASTLE)) {
970       if (! gamestatusp(ATTACKED_ORACLE)) {
971 	print2("A dulcet voice says: 'Jolly good show!'");
972 	morewait();
973       }
974       setgamestatus(COMPLETED_CASTLE);
975     }
976     change_environment(E_COURT);
977   }
978 }
979 
l_chaostone()980 void l_chaostone()
981 {
982   print1("This is a menhir carved of black marble with veins of gold.");
983   print2("It emanates an aura of raw chaos, which is not terribly");
984   morewait();
985   print1("surprising, considering its location.");
986   if (Player.alignment < 0)
987     print2("You feel an almost unbearable attraction to the stone.");
988   else print2("You find it extremely difficult to approach the stone.");
989   morewait();
990   clearmsg();
991   print1("Touch it? [yn] ");
992   if (ynq1()=='y') {
993     print1("A sudden flux of energy surrounds you!");
994     morewait();
995     if (stonecheck(-1)) {
996       print2("You feel stronger!");
997       Player.maxstr = min(Player.maxstr+10,max(30,Player.maxstr));
998       dataprint();
999     }
1000   }
1001   else print1("You step back from the ominous dolmech.");
1002 }
1003 
1004 
l_balancestone()1005 void l_balancestone()
1006 {
1007   print1("This is a massive granite slab teetering dangerously on a corner.");
1008   print2("You feel a sense of balance as you regard it.");
1009   morewait();
1010   clearmsg();
1011   print1("Touch it? [yn] ");
1012   if (ynq1()=='y') {
1013     print1("A vortex of mana spins about you!");
1014     if (abs(Player.alignment) > random_range(50)) {
1015       print2("The cyclone whirls you off to a strange place!");
1016       morewait();
1017       change_environment(E_COUNTRYSIDE);
1018       do {
1019 	Player.x = random_range(WIDTH);
1020 	Player.y = random_range(LENGTH);
1021       } while (Country[Player.x][Player.y].current_terrain_type == CHAOS_SEA);
1022       screencheck(Player.y);
1023       drawvision(Player.x,Player.y);
1024     }
1025     else {
1026       print2("You are being drained of experience! Step back? [yn] ");
1027       if (ynq2()=='y') {
1028 	clearmsg();
1029 	print1("The vortex calms down, dimishes, and then disappears.");
1030       }
1031       else {
1032 	Player.xp -= Player.xp/4;
1033 	dataprint();
1034 	print2("The vortex vanishes. Suddenly, there is a clap of thunder!");
1035 	morewait();
1036 	Player.alignment = 0;
1037 	strategic_teleport(1);
1038       }
1039     }
1040   }
1041   else print1("You step back from the unlikely boulder.");
1042 }
1043 
1044 
l_lawstone()1045 void l_lawstone()
1046 {
1047   print1("This is a stele carved of blueish-green feldspar.");
1048   print2("You feel an aura of serenity rising from it, and your gaze");
1049   morewait();
1050   print1("is attracted to the bulk of Star Peak to the North-East.");
1051   if (Player.alignment > 0)
1052     print2("You feel a subtle attraction to the stone.");
1053   else print2("You find the stone extremely distasteful to contemplate.");
1054   morewait();
1055   clearmsg();
1056   print1("Touch it? [yn] ");
1057   if (ynq()=='y') {
1058     print1("A matrix of power flows about you!");
1059     morewait();
1060     if (stonecheck(1)) {
1061       print2("You feel more vigorous!");
1062       Player.maxcon = min(Player.maxcon+10,max(Player.maxcon,30));
1063       dataprint();
1064     }
1065   }
1066   else print1("You step back from the strange obelisk.");
1067 }
1068 
1069 
l_voidstone()1070 void l_voidstone()
1071 {
1072   int i;
1073   print1("This is a grey and uninteresting stone.");
1074   print2("A feeling of nihility emanates from it.");
1075   morewait();
1076   clearmsg();
1077   print1("Touch it? [yn] ");
1078   if (ynq()=='y') {
1079     print1("You feel negated.");
1080     morewait();
1081     Player.mana = 0;
1082     toggle_item_use(TRUE);
1083     for(i=0;i<NUMSTATI;i++)
1084       Player.status[i] = 0;
1085     for(i=0;i<MAXITEMS;i++)
1086       if (Player.possessions[i] != NULL) {
1087 	Player.possessions[i]->blessing = 0;
1088 	Player.possessions[i]->plus = 0;
1089 	Player.possessions[i]->usef = I_NOTHING;
1090       }
1091     toggle_item_use(FALSE);
1092     calc_melee();
1093   }
1094   else print1("You back away from the strange rock.");
1095 }
1096 
l_sacrificestone()1097 void l_sacrificestone()
1098 {
1099   int sacrifice=1;
1100   int oldmaxhp = Player.maxhp;
1101   print1("You have come on a weathered basaltic block.");
1102   print2("On the top surface is an indentation in human shape.");
1103   morewait();
1104   print1("You see old rust colored stains in the grain of the stone.");
1105   print2("You sense something awakening. Touch the block? [yn] ");
1106   if (ynq2() == 'y') {
1107     print1("You sense great pain emanating from the ancient altar.");
1108     print2("Climb on to the block? [yn] ");
1109     if (ynq2() == 'y') {
1110       print1("You are stuck fast to the block!");
1111       print2("You feel your life-force being sucked away!");
1112       morewait();
1113       print1("Hit ESCAPE to try and get up at any moment, SPACE to remain.");
1114       do {
1115 	switch(random_range(4)) {
1116 	  case 0: print2("You feel weaker."); break;
1117 	  case 1: print2("You feel your life fading."); break;
1118 	  case 2: print2("Your energy is vanishing."); break;
1119 	  case 3: print2("You are being drained."); break;
1120 	  }
1121 	Player.hp -= sacrifice;
1122 	Player.maxhp -= sacrifice/2;
1123 	sacrifice *= 2;
1124 	dataprint();
1125 	if ((Player.hp < 1) || (Player.maxhp < 1))
1126 	  p_death("self-sacrifice");
1127       } while (stillonblock());
1128       print1("You manage to wrench yourself off the ancient altar!");
1129       print2("You leave some skin behind, though....");
1130       morewait();
1131       if ((oldmaxhp > 10) && (Player.maxhp < 3 * oldmaxhp/4)) {
1132 	print1("A strange red glow arises from the altar.");
1133 	print2("The glow surrounds you.... You sense gratitude.");
1134 	Player.pow += sacrifice;
1135 	Player.maxpow += sacrifice/10;
1136 	dataprint();
1137       }
1138       else {
1139 	print1("You a have a sense of rejection.");
1140 	print2("A roil of fetid vapor smokes up from the altar.");
1141 	gain_experience(sacrifice);
1142       }
1143     }
1144     else {
1145       print1("You sense an emotion of pique all around you.");
1146       print2("You retreat from the strange stone.");
1147     }
1148   }
1149   else {
1150     print1("You decide discretion to be the better part of valour.");
1151     print2("The stone seems to subside sleepily.");
1152   }
1153 }
1154 
l_mindstone()1155 void l_mindstone()
1156 {
1157   print1("You approach a giant crystal of some opaline material.");
1158   print2("Flashes of irridescent light glint from the object.");
1159   morewait();
1160   print1("You feel your attention being drawn by the intricate crystal.");
1161   print2("Look away from the interesting phenomenon? [yn] ");
1162   if (ynq2()=='n') {
1163     print1("Your gaze focuses deeply on the gem....");
1164     print2("The crystal seems to open up and surround you!");
1165     morewait();
1166     if (stonecheck(0)) {
1167       print1("Your mind has been enhanced by the experience!");
1168       Player.maxiq = min(Player.maxiq+10,max(Player.maxiq,30));
1169       dataprint();
1170     }
1171   }
1172   else {
1173     print1("You manage to wrench your gaze from the odd jewel.");
1174     print2("The light flashes from the crystal diminish in frequency.");
1175   }
1176 }
1177