xref: /netbsd/games/larn/action.c (revision 6550d01e)
1 /*	$NetBSD: action.c,v 1.1 2008/02/19 06:05:26 dholland 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.1 2008/02/19 06:05:26 dholland 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