Home | History | Annotate | Line # | Download | only in larn
      1 /*	$NetBSD: action.c,v 1.2 2021/05/02 12:50:45 rillig Exp $	*/
      2 
      3 /*
      4  * action.c 		Larn is copyrighted 1986 by Noah Morgan.
      5  *
      6  * Routines in this file:
      7  *
      8  * ...
      9  */
     10 #include <sys/cdefs.h>
     11 #ifndef lint
     12 __RCSID("$NetBSD: action.c,v 1.2 2021/05/02 12:50:45 rillig Exp $");
     13 #endif				/* not lint */
     14 #include <stdlib.h>
     15 #include <unistd.h>
     16 #include "header.h"
     17 #include "extern.h"
     18 
     19 static void ohear(void);
     20 
     21 /*
     22  * act_remove_gems
     23  *
     24  * Remove gems from a throne.
     25  *
     26  * arg is zero if there is a gnome king associated with the throne.
     27  *
     28  * Assumes that cursors() has been called previously, and that a check
     29  * has been made that the throne actually has gems.
     30  */
     31 void
     32 act_remove_gems(int arg)
     33 {
     34 	int i, k;
     35 
     36 	k = rnd(101);
     37 	if (k < 25) {
     38 		for (i = 0; i < rnd(4); i++)
     39 			creategem();	/* gems pop off the
     40 					 * throne */
     41 		item[playerx][playery] = ODEADTHRONE;
     42 		know[playerx][playery] = 0;
     43 	} else if (k < 40 && arg == 0) {
     44 		createmonster(GNOMEKING);
     45 		item[playerx][playery] = OTHRONE2;
     46 		know[playerx][playery] = 0;
     47 	} else
     48 		lprcat("\nnothing happens");
     49 }
     50 
     51 /*
     52  * act_sit_throne
     53  *
     54  * Sit on a throne.
     55  *
     56  * arg is zero if there is a gnome king associated with the throne
     57  *
     58  * Assumes that cursors() has been called previously.
     59  */
     60 void
     61 act_sit_throne(int arg)
     62 {
     63 	int k;
     64 
     65 	k = rnd(101);
     66 	if (k < 30 && arg == 0) {
     67 		createmonster(GNOMEKING);
     68 		item[playerx][playery] = OTHRONE2;
     69 		know[playerx][playery] = 0;
     70 	} else if (k < 35) {
     71 		lprcat("\nZaaaappp!  You've been teleported!\n");
     72 		beep();
     73 		oteleport(0);
     74 	} else
     75 		lprcat("\nnothing happens");
     76 }
     77 
     78 /*
     79  * Code to perform the action of drinking at a fountain.  Assumes that
     80  * cursors() has already been called, and that a check has been made
     81  * that the player is actually standing at a live fountain.
     82  */
     83 void
     84 act_drink_fountain(void)
     85 {
     86 	int x;
     87 
     88 	if (rnd(1501) < 2) {
     89 		lprcat("\nOops!  You seem to have caught the dreadful sleep!");
     90 		beep();
     91 		lflush();
     92 		sleep(3);
     93 		died(280);
     94 		return;
     95 	}
     96 	x = rnd(100);
     97 	if (x < 7) {
     98 		c[HALFDAM] += 200 + rnd(200);
     99 		lprcat("\nYou feel a sickness coming on");
    100 	} else if (x < 13)
    101 		quaffpotion(23);	/* see invisible */
    102 	else if (x < 45)
    103 		lprcat("\nnothing seems to have happened");
    104 	else if (rnd(3) != 2)
    105 		fntchange(1);	/* change char levels upward	 */
    106 	else
    107 		fntchange(-1);	/* change char levels
    108 				 * downward	 */
    109 	if (rnd(12) < 3) {
    110 		lprcat("\nThe fountains bubbling slowly quiets");
    111 		item[playerx][playery] = ODEADFOUNTAIN;	/* dead fountain */
    112 		know[playerx][playery] = 0;
    113 	}
    114 }
    115 
    116 /*
    117  * Code to perform the action of washing at a fountain.  Assumes that
    118  * cursors() has already been called and that a check has been made
    119  * that the player is actually standing at a live fountain.
    120  */
    121 void
    122 act_wash_fountain(void)
    123 {
    124 	int x;
    125 
    126 	if (rnd(100) < 11) {
    127 		x = rnd((level << 2) + 2);
    128 		lprintf("\nOh no!  The water was foul!  You suffer %ld hit points!", (long) x);
    129 		lastnum = 273;
    130 		losehp(x);
    131 		bottomline();
    132 		cursors();
    133 	} else if (rnd(100) < 29)
    134 		lprcat("\nYou got the dirt off!");
    135 	else if (rnd(100) < 31)
    136 		lprcat("\nThis water seems to be hard water!  The dirt didn't come off!");
    137 	else if (rnd(100) < 34)
    138 		createmonster(WATERLORD);	/* make water lord		 */
    139 	else
    140 		lprcat("\nnothing seems to have happened");
    141 }
    142 
    143 /*
    144  * Perform the actions associated with altar desecration.
    145  */
    146 void
    147 act_desecrate_altar(void)
    148 {
    149 	if (rnd(100) < 60) {
    150 		createmonster(makemonst(level + 2) + 8);
    151 		c[AGGRAVATE] += 2500;
    152 	} else if (rnd(101) < 30) {
    153 		lprcat("\nThe altar crumbles into a pile of dust before your eyes");
    154 		forget();	/* remember to destroy
    155 				 * the altar	 */
    156 	} else
    157 		lprcat("\nnothing happens");
    158 }
    159 
    160 /*
    161  * Perform the actions associated with praying at an altar and giving
    162  * a donation.
    163  */
    164 void
    165 act_donation_pray(void)
    166 {
    167 	long amt;
    168 
    169 	lprcat("\n\n");
    170 	cursor(1, 24);
    171 	cltoeoln();
    172 	cursor(1, 23);
    173 	cltoeoln();
    174 	lprcat("how much do you donate? ");
    175 	amt = readnum((long) c[GOLD]);
    176 	if (amt < 0 || c[GOLD] < amt) {
    177 		lprcat("\nYou don't have that much!");
    178 		return;
    179 	}
    180 	c[GOLD] -= amt;
    181 	if (amt < c[GOLD] / 10 || amt < rnd(50)) {
    182 		createmonster(makemonst(level + 1));
    183 		c[AGGRAVATE] += 200;
    184 	} else if (rnd(101) > 50) {
    185 		ohear();
    186 		return;
    187 	} else if (rnd(43) == 5) {
    188 		if (c[WEAR])
    189 			lprcat("\nYou feel your armor vibrate for a moment");
    190 		enchantarmor();
    191 		return;
    192 	} else if (rnd(43) == 8) {
    193 		if (c[WIELD])
    194 			lprcat("\nYou feel your weapon vibrate for a moment");
    195 		enchweapon();
    196 		return;
    197 	} else
    198 		lprcat("\nThank You.");
    199 	bottomline();
    200 }
    201 
    202 /*
    203  *  Performs the actions associated with 'just praying' at the altar.  Called
    204  *  when the user responds 'just pray' when in prompt mode, or enters 0 to
    205  *  the money prompt when praying.
    206  *
    207  *  Assumes cursors(), and that any leading \n have been printed.
    208  */
    209 void
    210 act_just_pray(void)
    211 {
    212 	if (rnd(100) < 75)
    213 		lprcat("\nnothing happens");
    214 	else if (rnd(13) < 4)
    215 		ohear();
    216 	else if (rnd(43) == 10) {
    217 		if (c[WEAR])
    218 			lprcat("\nYou feel your armor vibrate for a moment");
    219 		enchantarmor();
    220 		return;
    221 	} else if (rnd(43) == 10) {
    222 		if (c[WIELD])
    223 			lprcat("\nYou feel your weapon vibrate for a moment");
    224 		enchweapon();
    225 		return;
    226 	} else
    227 		createmonster(makemonst(level + 1));
    228 }
    229 
    230 /*
    231  * Function to cast a +3 protection on the player
    232  */
    233 static void
    234 ohear(void)
    235 {
    236 	lprcat("\nYou have been heard!");
    237 	if (c[ALTPRO] == 0)
    238 		c[MOREDEFENSES] += 3;
    239 	c[ALTPRO] += 500;	/* protection field */
    240 	bottomline();
    241 }
    242 
    243 /*
    244  * Performs the act of ignoring an altar.
    245  *
    246  * Assumptions:  cursors() has been called.
    247  */
    248 void
    249 act_ignore_altar(void)
    250 {
    251 	if (rnd(100) < 30) {
    252 		createmonster(makemonst(level + 1));
    253 		c[AGGRAVATE] += rnd(450);
    254 	} else
    255 		lprcat("\nnothing happens");
    256 }
    257 
    258 /*
    259  * Performs the act of opening a chest.
    260  *
    261  * Parameters:   x,y location of the chest to open.
    262  * Assumptions:  cursors() has been called previously
    263  */
    264 void
    265 act_open_chest(int x, int y)
    266 {
    267 	int i, k;
    268 
    269 	k = rnd(101);
    270 	if (k < 40) {
    271 		lprcat("\nThe chest explodes as you open it");
    272 		beep();
    273 		i = rnd(10);
    274 		lastnum = 281;	/* in case he dies */
    275 		lprintf("\nYou suffer %ld hit points damage!", (long) i);
    276 		checkloss(i);
    277 		switch (rnd(10)) {	/* see if he gets a
    278 					 * curse */
    279 		case 1:
    280 			c[ITCHING] += rnd(1000) + 100;
    281 			lprcat("\nYou feel an irritation spread over your skin!");
    282 			beep();
    283 			break;
    284 
    285 		case 2:
    286 			c[CLUMSINESS] += rnd(1600) + 200;
    287 			lprcat("\nYou begin to lose hand to eye coordination!");
    288 			beep();
    289 			break;
    290 
    291 		case 3:
    292 			c[HALFDAM] += rnd(1600) + 200;
    293 			beep();
    294 			lprcat("\nA sickness engulfs you!");
    295 			break;
    296 		};
    297 		item[x][y] = know[x][y] = 0;
    298 		if (rnd(100) < 69)
    299 			creategem();	/* gems from the chest */
    300 		dropgold(rnd(110 * iarg[x][y] + 200));
    301 		for (i = 0; i < rnd(4); i++)
    302 			something(iarg[x][y] + 2);
    303 	} else
    304 		lprcat("\nnothing happens");
    305 }
    306