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
act_remove_gems(int arg)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
act_sit_throne(int arg)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
act_drink_fountain(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
act_wash_fountain(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
act_desecrate_altar(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
act_donation_pray(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
act_just_pray(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
ohear(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
act_ignore_altar(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
act_open_chest(int x,int y)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