]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.apply.c
Ixfay iticalcray ugsbay! Eservepray artstay-ofway-ordway andway
[bsdgames-darwin.git] / hack / hack.apply.c
1 /*
2 * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
3 */
4
5 #ifndef lint
6 static char rcsid[] = "$NetBSD: hack.apply.c,v 1.4 1995/03/23 08:29:47 cgd Exp $";
7 #endif /* not lint */
8
9 #include "hack.h"
10 #include "def.edog.h"
11 #include "def.mkroom.h"
12 static struct monst *bchit();
13 extern struct obj *addinv();
14 extern struct trap *maketrap();
15 extern int (*occupation)();
16 extern char *occtxt;
17 extern char quitchars[];
18 extern char pl_character[];
19
20 static void use_camera(), use_ice_box(), use_whistle(), use_magic_whistle();
21 static int use_pick_axe();
22
23 doapply() {
24 register struct obj *obj;
25 register int res = 1;
26
27 obj = getobj("(", "use or apply");
28 if(!obj) return(0);
29
30 switch(obj->otyp){
31 case EXPENSIVE_CAMERA:
32 use_camera(obj); break;
33 case ICE_BOX:
34 use_ice_box(obj); break;
35 case PICK_AXE:
36 res = use_pick_axe(obj);
37 break;
38
39 case MAGIC_WHISTLE:
40 if(pl_character[0] == 'W' || u.ulevel > 9) {
41 use_magic_whistle(obj);
42 break;
43 }
44 /* fall into next case */
45 case WHISTLE:
46 use_whistle(obj);
47 break;
48
49 case CAN_OPENER:
50 if(!carrying(TIN)) {
51 pline("You have no can to open.");
52 goto xit;
53 }
54 pline("You cannot open a tin without eating its contents.");
55 pline("In order to eat, use the 'e' command.");
56 if(obj != uwep)
57 pline("Opening the tin will be much easier if you wield the can-opener.");
58 goto xit;
59
60 default:
61 pline("Sorry, I don't know how to use that.");
62 xit:
63 nomul(0);
64 return(0);
65 }
66 nomul(0);
67 return(res);
68 }
69
70 /* ARGSUSED */
71 static void
72 use_camera(obj) /* register */ struct obj *obj; {
73 register struct monst *mtmp;
74 if(!getdir(1)){ /* ask: in what direction? */
75 flags.move = multi = 0;
76 return;
77 }
78 if(u.uswallow) {
79 pline("You take a picture of %s's stomach.", monnam(u.ustuck));
80 return;
81 }
82 if(u.dz) {
83 pline("You take a picture of the %s.",
84 (u.dz > 0) ? "floor" : "ceiling");
85 return;
86 }
87 if(mtmp = bchit(u.dx, u.dy, COLNO, '!')) {
88 if(mtmp->msleep){
89 mtmp->msleep = 0;
90 pline("The flash awakens %s.", monnam(mtmp)); /* a3 */
91 } else
92 if(mtmp->data->mlet != 'y')
93 if(mtmp->mcansee || mtmp->mblinded){
94 register int tmp = dist(mtmp->mx,mtmp->my);
95 register int tmp2;
96 if(cansee(mtmp->mx,mtmp->my))
97 pline("%s is blinded by the flash!", Monnam(mtmp));
98 setmangry(mtmp);
99 if(tmp < 9 && !mtmp->isshk && rn2(4)) {
100 mtmp->mflee = 1;
101 if(rn2(4)) mtmp->mfleetim = rnd(100);
102 }
103 if(tmp < 3) mtmp->mcansee = mtmp->mblinded = 0;
104 else {
105 tmp2 = mtmp->mblinded;
106 tmp2 += rnd(1 + 50/tmp);
107 if(tmp2 > 127) tmp2 = 127;
108 mtmp->mblinded = tmp2;
109 mtmp->mcansee = 0;
110 }
111 }
112 }
113 }
114
115 static
116 struct obj *current_ice_box; /* a local variable of use_ice_box, to be
117 used by its local procedures in/ck_ice_box */
118 static
119 in_ice_box(obj) register struct obj *obj; {
120 if(obj == current_ice_box ||
121 (Punished && (obj == uball || obj == uchain))){
122 pline("You must be kidding.");
123 return(0);
124 }
125 if(obj->owornmask & (W_ARMOR | W_RING)) {
126 pline("You cannot refrigerate something you are wearing.");
127 return(0);
128 }
129 if(obj->owt + current_ice_box->owt > 70) {
130 pline("It won't fit.");
131 return(1); /* be careful! */
132 }
133 if(obj == uwep) {
134 if(uwep->cursed) {
135 pline("Your weapon is welded to your hand!");
136 return(0);
137 }
138 setuwep((struct obj *) 0);
139 }
140 current_ice_box->owt += obj->owt;
141 freeinv(obj);
142 obj->o_cnt_id = current_ice_box->o_id;
143 obj->nobj = fcobj;
144 fcobj = obj;
145 obj->age = moves - obj->age; /* actual age */
146 return(1);
147 }
148
149 static
150 ck_ice_box(obj) register struct obj *obj; {
151 return(obj->o_cnt_id == current_ice_box->o_id);
152 }
153
154 static
155 out_ice_box(obj) register struct obj *obj; {
156 register struct obj *otmp;
157 if(obj == fcobj) fcobj = fcobj->nobj;
158 else {
159 for(otmp = fcobj; otmp->nobj != obj; otmp = otmp->nobj)
160 if(!otmp->nobj) panic("out_ice_box");
161 otmp->nobj = obj->nobj;
162 }
163 current_ice_box->owt -= obj->owt;
164 obj->age = moves - obj->age; /* simulated point of time */
165 (void) addinv(obj);
166 }
167
168 static void
169 use_ice_box(obj) register struct obj *obj; {
170 register int cnt = 0;
171 register struct obj *otmp;
172 current_ice_box = obj; /* for use by in/out_ice_box */
173 for(otmp = fcobj; otmp; otmp = otmp->nobj)
174 if(otmp->o_cnt_id == obj->o_id)
175 cnt++;
176 if(!cnt) pline("Your ice-box is empty.");
177 else {
178 pline("Do you want to take something out of the ice-box? [yn] ");
179 if(readchar() == 'y')
180 if(askchain(fcobj, (char *) 0, 0, out_ice_box, ck_ice_box, 0))
181 return;
182 pline("That was all. Do you wish to put something in? [yn] ");
183 if(readchar() != 'y') return;
184 }
185 /* call getobj: 0: allow cnt; #: allow all types; %: expect food */
186 otmp = getobj("0#%", "put in");
187 if(!otmp || !in_ice_box(otmp))
188 flags.move = multi = 0;
189 }
190
191 static
192 struct monst *
193 bchit(ddx,ddy,range,sym) register int ddx,ddy,range; char sym; {
194 register struct monst *mtmp = (struct monst *) 0;
195 register int bchx = u.ux, bchy = u.uy;
196
197 if(sym) Tmp_at(-1, sym); /* open call */
198 while(range--) {
199 bchx += ddx;
200 bchy += ddy;
201 if(mtmp = m_at(bchx,bchy))
202 break;
203 if(!ZAP_POS(levl[bchx][bchy].typ)) {
204 bchx -= ddx;
205 bchy -= ddy;
206 break;
207 }
208 if(sym) Tmp_at(bchx, bchy);
209 }
210 if(sym) Tmp_at(-1, -1);
211 return(mtmp);
212 }
213
214 /* ARGSUSED */
215 static void
216 use_whistle(obj) struct obj *obj; {
217 register struct monst *mtmp = fmon;
218 pline("You produce a high whistling sound.");
219 while(mtmp) {
220 if(dist(mtmp->mx,mtmp->my) < u.ulevel*20) {
221 if(mtmp->msleep)
222 mtmp->msleep = 0;
223 if(mtmp->mtame)
224 EDOG(mtmp)->whistletime = moves;
225 }
226 mtmp = mtmp->nmon;
227 }
228 }
229
230 /* ARGSUSED */
231 static void
232 use_magic_whistle(obj) struct obj *obj; {
233 register struct monst *mtmp = fmon;
234 pline("You produce a strange whistling sound.");
235 while(mtmp) {
236 if(mtmp->mtame) mnexto(mtmp);
237 mtmp = mtmp->nmon;
238 }
239 }
240
241 static int dig_effort; /* effort expended on current pos */
242 static uchar dig_level;
243 static coord dig_pos;
244 static boolean dig_down;
245
246 static
247 dig() {
248 register struct rm *lev;
249 register dpx = dig_pos.x, dpy = dig_pos.y;
250
251 /* perhaps a nymph stole his pick-axe while he was busy digging */
252 /* or perhaps he teleported away */
253 if(u.uswallow || !uwep || uwep->otyp != PICK_AXE ||
254 dig_level != dlevel ||
255 ((dig_down && (dpx != u.ux || dpy != u.uy)) ||
256 (!dig_down && dist(dpx,dpy) > 2)))
257 return(0);
258
259 dig_effort += 10 + abon() + uwep->spe + rn2(5);
260 if(dig_down) {
261 if(!xdnstair) {
262 pline("The floor here seems too hard to dig in.");
263 return(0);
264 }
265 if(dig_effort > 250) {
266 dighole();
267 return(0); /* done with digging */
268 }
269 if(dig_effort > 50) {
270 register struct trap *ttmp = t_at(dpx,dpy);
271
272 if(!ttmp) {
273 ttmp = maketrap(dpx,dpy,PIT);
274 ttmp->tseen = 1;
275 pline("You have dug a pit.");
276 u.utrap = rn1(4,2);
277 u.utraptype = TT_PIT;
278 return(0);
279 }
280 }
281 } else
282 if(dig_effort > 100) {
283 register char *digtxt;
284 register struct obj *obj;
285
286 lev = &levl[dpx][dpy];
287 if(obj = sobj_at(ENORMOUS_ROCK, dpx, dpy)) {
288 fracture_rock(obj);
289 digtxt = "The rock falls apart.";
290 } else if(!lev->typ || lev->typ == SCORR) {
291 lev->typ = CORR;
292 digtxt = "You succeeded in cutting away some rock.";
293 } else if(lev->typ == HWALL || lev->typ == VWALL
294 || lev->typ == SDOOR) {
295 lev->typ = xdnstair ? DOOR : ROOM;
296 digtxt = "You just made an opening in the wall.";
297 } else
298 digtxt = "Now what exactly was it that you were digging in?";
299 mnewsym(dpx, dpy);
300 prl(dpx, dpy);
301 pline(digtxt); /* after mnewsym & prl */
302 return(0);
303 } else {
304 if(IS_WALL(levl[dpx][dpy].typ)) {
305 register int rno = inroom(dpx,dpy);
306
307 if(rno >= 0 && rooms[rno].rtype >= 8) {
308 pline("This wall seems too hard to dig into.");
309 return(0);
310 }
311 }
312 pline("You hit the rock with all your might.");
313 }
314 return(1);
315 }
316
317 /* When will hole be finished? Very rough indication used by shopkeeper. */
318 holetime() {
319 return( (occupation == dig) ? (250 - dig_effort)/20 : -1);
320 }
321
322 dighole()
323 {
324 register struct trap *ttmp = t_at(u.ux, u.uy);
325
326 if(!xdnstair) {
327 pline("The floor here seems too hard to dig in.");
328 } else {
329 if(ttmp)
330 ttmp->ttyp = TRAPDOOR;
331 else
332 ttmp = maketrap(u.ux, u.uy, TRAPDOOR);
333 ttmp->tseen = 1;
334 pline("You've made a hole in the floor.");
335 if(!u.ustuck) {
336 if(inshop())
337 shopdig(1);
338 pline("You fall through ...");
339 if(u.utraptype == TT_PIT) {
340 u.utrap = 0;
341 u.utraptype = 0;
342 }
343 goto_level(dlevel+1, FALSE);
344 }
345 }
346 }
347
348 static
349 use_pick_axe(obj)
350 struct obj *obj;
351 {
352 char dirsyms[12];
353 extern char sdir[];
354 register char *dsp = dirsyms, *sdp = sdir;
355 register struct monst *mtmp;
356 register struct rm *lev;
357 register int rx, ry, res = 0;
358
359 if(obj != uwep) {
360 if(uwep && uwep->cursed) {
361 /* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */
362 pline("Since your weapon is welded to your hand,");
363 pline("you cannot use that pick-axe.");
364 return(0);
365 }
366 pline("You now wield %s.", doname(obj));
367 setuwep(obj);
368 res = 1;
369 }
370 while(*sdp) {
371 (void) movecmd(*sdp); /* sets u.dx and u.dy and u.dz */
372 rx = u.ux + u.dx;
373 ry = u.uy + u.dy;
374 if(u.dz > 0 || (u.dz == 0 && isok(rx, ry) &&
375 (IS_ROCK(levl[rx][ry].typ)
376 || sobj_at(ENORMOUS_ROCK, rx, ry))))
377 *dsp++ = *sdp;
378 sdp++;
379 }
380 *dsp = 0;
381 pline("In what direction do you want to dig? [%s] ", dirsyms);
382 if(!getdir(0)) /* no txt */
383 return(res);
384 if(u.uswallow && attack(u.ustuck)) /* return(1) */;
385 else
386 if(u.dz < 0)
387 pline("You cannot reach the ceiling.");
388 else
389 if(u.dz == 0) {
390 if(Confusion)
391 confdir();
392 rx = u.ux + u.dx;
393 ry = u.uy + u.dy;
394 if((mtmp = m_at(rx, ry)) && attack(mtmp))
395 return(1);
396 if(!isok(rx, ry)) {
397 pline("Clash!");
398 return(1);
399 }
400 lev = &levl[rx][ry];
401 if(lev->typ == DOOR)
402 pline("Your %s against the door.",
403 aobjnam(obj, "clang"));
404 else if(!IS_ROCK(lev->typ)
405 && !sobj_at(ENORMOUS_ROCK, rx, ry)) {
406 /* ACCESSIBLE or POOL */
407 pline("You swing your %s through thin air.",
408 aobjnam(obj, (char *) 0));
409 } else {
410 if(dig_pos.x != rx || dig_pos.y != ry
411 || dig_level != dlevel || dig_down) {
412 dig_down = FALSE;
413 dig_pos.x = rx;
414 dig_pos.y = ry;
415 dig_level = dlevel;
416 dig_effort = 0;
417 pline("You start digging.");
418 } else
419 pline("You continue digging.");
420 occupation = dig;
421 occtxt = "digging";
422 }
423 } else if(Levitation) {
424 pline("You cannot reach the floor.");
425 } else {
426 if(dig_pos.x != u.ux || dig_pos.y != u.uy
427 || dig_level != dlevel || !dig_down) {
428 dig_down = TRUE;
429 dig_pos.x = u.ux;
430 dig_pos.y = u.uy;
431 dig_level = dlevel;
432 dig_effort = 0;
433 pline("You start digging in the floor.");
434 if(inshop())
435 shopdig(0);
436 } else
437 pline("You continue digging in the floor.");
438 occupation = dig;
439 occtxt = "digging";
440 }
441 return(1);
442 }