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.c,v 1.6 2003/04/02 18:36:35 jsm Exp $");
67: #endif
68:
69: #include "hack.h"
70: #include "extern.h"
71:
72:
73:
74:
75:
76: void
77: unsee()
78: {
79: int x, y;
80: struct rm *lev;
81:
82:
83:
84:
85:
86:
87:
88: #ifndef QUEST
89: if (seehx) {
90: seehx = 0;
91: } else
92: #endif
93: for (x = u.ux - 1; x < u.ux + 2; x++)
94: for (y = u.uy - 1; y < u.uy + 2; y++) {
95: if (!isok(x, y))
96: continue;
97: lev = &levl[x][y];
98: if (!lev->lit && lev->scrsym == '.') {
99: lev->scrsym = ' ';
100: lev->new = 1;
101: on_scr(x, y);
102: }
103: }
104: }
105:
106:
107:
108:
109:
110:
111:
112:
113: void
114: seeoff(mode)
115: int mode;
116:
117: {
118: int x, y;
119: struct rm *lev;
120:
121: if (u.udispl && mode) {
122: u.udispl = 0;
123: levl[u.udisx][u.udisy].scrsym = news0(u.udisx, u.udisy);
124: }
125: #ifndef QUEST
126: if (seehx) {
127: seehx = 0;
128: } else
129: #endif
130: if (!mode) {
131: for (x = u.ux - 1; x < u.ux + 2; x++)
132: for (y = u.uy - 1; y < u.uy + 2; y++) {
133: if (!isok(x, y))
134: continue;
135: lev = &levl[x][y];
136: if (!lev->lit && lev->scrsym == '.')
137: lev->seen = 0;
138: }
139: }
140: }
141:
142: void
143: domove()
144: {
145: xchar oldx, oldy;
146: struct monst *mtmp = NULL;
147: struct rm *tmpr, *ust;
148: struct trap *trap = NULL;
149: struct obj *otmp = NULL;
150:
151: u_wipe_engr(rnd(5));
152:
153: if (inv_weight() > 0) {
154: pline("You collapse under your load.");
155: nomul(0);
156: return;
157: }
158: if (u.uswallow) {
159: u.dx = u.dy = 0;
160: u.ux = u.ustuck->mx;
161: u.uy = u.ustuck->my;
162: } else {
163: if (Confusion) {
164: do {
165: confdir();
166: } while (!isok(u.ux + u.dx, u.uy + u.dy) ||
167: IS_ROCK(levl[u.ux + u.dx][u.uy + u.dy].typ));
168: }
169: if (!isok(u.ux + u.dx, u.uy + u.dy)) {
170: nomul(0);
171: return;
172: }
173: }
174:
175: ust = &levl[u.ux][u.uy];
176: oldx = u.ux;
177: oldy = u.uy;
178: if (!u.uswallow && (trap = t_at(u.ux + u.dx, u.uy + u.dy)) && trap->tseen)
179: nomul(0);
180: if (u.ustuck && !u.uswallow && (u.ux + u.dx != u.ustuck->mx ||
181: u.uy + u.dy != u.ustuck->my)) {
182: if (dist(u.ustuck->mx, u.ustuck->my) > 2) {
183:
184: u.ustuck = 0;
185: } else {
186: if (Blind)
187: pline("You cannot escape from it!");
188: else
189: pline("You cannot escape from %s!",
190: monnam(u.ustuck));
191: nomul(0);
192: return;
193: }
194: }
195: if (u.uswallow || (mtmp = m_at(u.ux + u.dx, u.uy + u.dy))) {
196:
197:
198: nomul(0);
199: gethungry();
200: if (multi < 0)
201: return;
202:
203:
204: if (attack(u.uswallow ? u.ustuck : mtmp))
205: return;
206: }
207:
208: if (u.utrap) {
209: if (u.utraptype == TT_PIT) {
210: pline("You are still in a pit.");
211: u.utrap--;
212: } else {
213: pline("You are caught in a beartrap.");
214: if ((u.dx && u.dy) || !rn2(5))
215: u.utrap--;
216: }
217: return;
218: }
219: tmpr = &levl[u.ux + u.dx][u.uy + u.dy];
220: if (IS_ROCK(tmpr->typ) ||
221: (u.dx && u.dy && (tmpr->typ == DOOR || ust->typ == DOOR))) {
222: flags.move = 0;
223: nomul(0);
224: return;
225: }
226: while ((otmp = sobj_at(ENORMOUS_ROCK, u.ux + u.dx, u.uy + u.dy)) != NULL){
227: xchar rx = u.ux + 2 * u.dx, ry = u.uy + 2 * u.dy;
228: struct trap *ttmp;
229: nomul(0);
230: if (isok(rx, ry) && !IS_ROCK(levl[rx][ry].typ) &&
231: (levl[rx][ry].typ != DOOR || !(u.dx && u.dy)) &&
232: !sobj_at(ENORMOUS_ROCK, rx, ry)) {
233: if (m_at(rx, ry)) {
234: pline("You hear a monster behind the rock.");
235: pline("Perhaps that's why you cannot move it.");
236: goto cannot_push;
237: }
238: if ((ttmp = t_at(rx, ry)) != NULL)
239: switch (ttmp->ttyp) {
240: case PIT:
241: pline("You push the rock into a pit!");
242: deltrap(ttmp);
243: delobj(otmp);
244: pline("It completely fills the pit!");
245: continue;
246: case TELEP_TRAP:
247: pline("You push the rock and suddenly it disappears!");
248: delobj(otmp);
249: continue;
250: }
251: if (levl[rx][ry].typ == POOL) {
252: levl[rx][ry].typ = ROOM;
253: mnewsym(rx, ry);
254: prl(rx, ry);
255: pline("You push the rock into the water.");
256: pline("Now you can cross the water!");
257: delobj(otmp);
258: continue;
259: }
260: otmp->ox = rx;
261: otmp->oy = ry;
262:
263: if (cansee(rx, ry))
264: atl(rx, ry, otmp->olet);
265: if (Invisible)
266: newsym(u.ux + u.dx, u.uy + u.dy);
267:
268: {
269: static long lastmovetime;
270:
271:
272:
273:
274: if (moves > lastmovetime + 2 || moves < lastmovetime)
275: pline("With great effort you move the enormous rock.");
276: lastmovetime = moves;
277: }
278: } else {
279: pline("You try to move the enormous rock, but in vain.");
280: cannot_push:
281: if ((!invent || inv_weight() + 90 <= 0) &&
282: (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy + u.dy].typ)
283: && IS_ROCK(levl[u.ux + u.dx][u.uy].typ)))) {
284: pline("However, you can squeeze yourself into a small opening.");
285: break;
286: } else
287: return;
288: }
289: }
290: if (u.dx && u.dy && IS_ROCK(levl[u.ux][u.uy + u.dy].typ) &&
291: IS_ROCK(levl[u.ux + u.dx][u.uy].typ) &&
292: invent && inv_weight() + 40 > 0) {
293: pline("You are carrying too much to get through.");
294: nomul(0);
295: return;
296: }
297: if (Punished &&
298: DIST(u.ux + u.dx, u.uy + u.dy, uchain->ox, uchain->oy) > 2) {
299: if (carried(uball)) {
300: movobj(uchain, u.ux, u.uy);
301: goto nodrag;
302: }
303: if (DIST(u.ux + u.dx, u.uy + u.dy, uball->ox, uball->oy) < 3) {
304:
305: movobj(uchain, uball->ox, uball->oy);
306: goto nodrag;
307: }
308: if (inv_weight() + (int) uball->owt / 2 > 0) {
309: pline("You cannot %sdrag the heavy iron ball.",
310: invent ? "carry all that and also " : "");
311: nomul(0);
312: return;
313: }
314: movobj(uball, uchain->ox, uchain->oy);
315: unpobj(uball);
316: uchain->ox = u.ux;
317: uchain->oy = u.uy;
318: nomul(-2);
319: nomovemsg = "";
320: nodrag: ;
321: }
322: u.ux += u.dx;
323: u.uy += u.dy;
324: if (flags.run) {
325: if (tmpr->typ == DOOR ||
326: (xupstair == u.ux && yupstair == u.uy) ||
327: (xdnstair == u.ux && ydnstair == u.uy))
328: nomul(0);
329: }
330: if (tmpr->typ == POOL && !Levitation)
331: drown();
332:
333:
334:
335:
336:
337:
338:
339: if (!Blind) {
340: #ifdef QUEST
341: setsee();
342: #else
343: if (ust->lit) {
344: if (tmpr->lit) {
345: if (tmpr->typ == DOOR)
346: prl1(u.ux + u.dx, u.uy + u.dy);
347: else if (ust->typ == DOOR)
348: nose1(oldx - u.dx, oldy - u.dy);
349: } else {
350: unsee();
351: prl1(u.ux + u.dx, u.uy + u.dy);
352: }
353: } else {
354: if (tmpr->lit)
355: setsee();
356: else {
357: prl1(u.ux + u.dx, u.uy + u.dy);
358: if (tmpr->typ == DOOR) {
359: if (u.dy) {
360: prl(u.ux - 1, u.uy);
361: prl(u.ux + 1, u.uy);
362: } else {
363: prl(u.ux, u.uy - 1);
364: prl(u.ux, u.uy + 1);
365: }
366: }
367: }
368: nose1(oldx - u.dx, oldy - u.dy);
369: }
370: #endif
371: } else {
372: pru();
373: }
374: if (!flags.nopick)
375: pickup(1);
376: if (trap)
377: dotrap(trap);
378: (void) inshop();
379: if (!Blind)
380: read_engr_at(u.ux, u.uy);
381: }
382:
383: void
384: movobj(obj, ox, oy)
385: struct obj *obj;
386: int ox, oy;
387: {
388:
389: freeobj(obj);
390: unpobj(obj);
391: obj->nobj = fobj;
392: fobj = obj;
393: obj->ox = ox;
394: obj->oy = oy;
395: }
396:
397: int
398: dopickup()
399: {
400: if (!g_at(u.ux, u.uy) && !o_at(u.ux, u.uy)) {
401: pline("There is nothing here to pick up.");
402: return (0);
403: }
404: if (Levitation) {
405: pline("You cannot reach the floor.");
406: return (1);
407: }
408: pickup(0);
409: return (1);
410: }
411:
412: void
413: pickup(int all)
414: {
415: struct gold *gold;
416: struct obj *obj, *obj2;
417: int wt;
418:
419: if (Levitation)
420: return;
421: while ((gold = g_at(u.ux, u.uy)) != NULL) {
422: pline("%ld gold piece%s.", gold->amount, plur(gold->amount));
423: u.ugold += gold->amount;
424: flags.botl = 1;
425: freegold(gold);
426: if (flags.run)
427: nomul(0);
428: if (Invisible)
429: newsym(u.ux, u.uy);
430: }
431:
432:
433: if (!all) {
434: int ct = 0;
435:
436: for (obj = fobj; obj; obj = obj->nobj)
437: if (obj->ox == u.ux && obj->oy == u.uy)
438: if (!Punished || obj != uchain)
439: ct++;
440: if (ct < 2)
441: all++;
442: else
443: pline("There are several objects here.");
444: }
445: for (obj = fobj; obj; obj = obj2) {
446: obj2 = obj->nobj;
447: if (obj->ox == u.ux && obj->oy == u.uy) {
448: if (flags.run)
449: nomul(0);
450:
451:
452: if (Punished && obj == uchain)
453: continue;
454:
455: if (!all) {
456: char c;
457:
458: pline("Pick up %s ? [ynaq]", doname(obj));
459: while (!strchr("ynaq ", (c = readchar())))
460: bell();
461: if (c == 'q')
462: return;
463: if (c == 'n')
464: continue;
465: if (c == 'a')
466: all = 1;
467: }
468: if (obj->otyp == DEAD_COCKATRICE && !uarmg) {
469: pline("Touching the dead cockatrice is a fatal mistake.");
470: pline("You turn to stone.");
471: killer = "cockatrice cadaver";
472: done("died");
473: }
474: if (obj->otyp == SCR_SCARE_MONSTER) {
475: if (!obj->spe)
476: obj->spe = 1;
477: else {
478:
479:
480:
481:
482:
483:
484:
485: pline("The scroll turns to dust as you pick it up.");
486: delobj(obj);
487: continue;
488: }
489: }
490: wt = inv_weight() + obj->owt;
491: if (wt > 0) {
492: if (obj->quan > 1) {
493:
494: int savequan = obj->quan;
495: int iw = inv_weight();
496: int qq;
497: for (qq = 1; qq < savequan; qq++) {
498: obj->quan = qq;
499: if (iw + weight(obj) > 0)
500: break;
501: }
502: obj->quan = savequan;
503: qq--;
504:
505: if (!qq)
506: goto too_heavy;
507: pline("You can only carry %s of the %s lying here.",
508: (qq == 1) ? "one" : "some",
509: doname(obj));
510: (void) splitobj(obj, qq);
511:
512:
513:
514:
515:
516:
517:
518: goto lift_some;
519: }
520: too_heavy:
521: pline("There %s %s here, but %s.",
522: (obj->quan == 1) ? "is" : "are",
523: doname(obj),
524: !invent ? "it is too heavy for you to lift"
525: : "you cannot carry anymore");
526: break;
527: }
528: lift_some:
529: if (inv_cnt() >= 52) {
530: pline("Your knapsack cannot accomodate anymore items.");
531: break;
532: }
533: if (wt > -5)
534: pline("You have a little trouble lifting");