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