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