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