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.engrave.c,v 1.6 2003/04/02 18:36:36 jsm Exp $");
67: #endif
68:
69: #include <stdlib.h>
70: #include "hack.h"
71: #include "extern.h"
72:
73: struct engr {
74: struct engr *nxt_engr;
75: char *engr_txt;
76: xchar engr_x, engr_y;
77: unsigned engr_lth;
78:
79: long engr_time;
80:
81: xchar engr_type;
82: #define DUST 1
83: #define ENGRAVE 2
84: #define BURN 3
85: } *head_engr;
86:
87: struct engr *
88: engr_at(x, y)
89: xchar x, y;
90: {
91: struct engr *ep = head_engr;
92: while (ep) {
93: if (x == ep->engr_x && y == ep->engr_y)
94: return (ep);
95: ep = ep->nxt_engr;
96: }
97: return ((struct engr *) 0);
98: }
99:
100: int
101: sengr_at(s, x, y)
102: const char *s;
103: xchar x, y;
104: {
105: struct engr *ep = engr_at(x, y);
106: char *t;
107: int n;
108: if (ep && ep->engr_time <= moves) {
109: t = ep->engr_txt;
110:
111:
112:
113: n = strlen(s);
114: while (*t) {
115: if (!strncmp(s, t, n))
116: return (1);
117: t++;
118: }
119: }
120: return (0);
121: }
122:
123: void
124: u_wipe_engr(cnt)
125: int cnt;
126: {
127: if (!u.uswallow && !Levitation)
128: wipe_engr_at(u.ux, u.uy, cnt);
129: }
130:
131: void
132: wipe_engr_at(x, y, cnt)
133: xchar x, y, cnt;
134: {
135: struct engr *ep = engr_at(x, y);
136: int lth, pos;
137: char ch;
138: if (ep) {
139: if ((ep->engr_type != DUST) || Levitation) {
140: cnt = rn2(1 + 50 / (cnt + 1)) ? 0 : 1;
141: }
142: lth = strlen(ep->engr_txt);
143: if (lth && cnt > 0) {
144: while (cnt--) {
145: pos = rn2(lth);
146: if ((ch = ep->engr_txt[pos]) == ' ')
147: continue;
148: ep->engr_txt[pos] = (ch != '?') ? '?' : ' ';
149: }
150: }
151: while (lth && ep->engr_txt[lth - 1] == ' ')
152: ep->engr_txt[--lth] = 0;
153: while (ep->engr_txt[0] == ' ')
154: ep->engr_txt++;
155: if (!ep->engr_txt[0])
156: del_engr(ep);
157: }
158: }
159:
160: void
161: read_engr_at(x, y)
162: int x, y;
163: {
164: struct engr *ep = engr_at(x, y);
165: if (ep && ep->engr_txt[0]) {
166: switch (ep->engr_type) {
167: case DUST:
168: pline("Something is written here in the dust.");
169: break;
170: case ENGRAVE:
171: pline("Something is engraved here on the floor.");
172: break;
173: case BURN:
174: pline("Some text has been burned here in the floor.");
175: break;
176: default:
177: impossible("Something is written in a very strange way.");
178: }
179: pline("You read: \"%s\".", ep->engr_txt);
180: }
181: }
182:
183: void
184: make_engr_at(x, y, s)
185: int x, y;
186: const char *s;
187: {
188: struct engr *ep;
189:
190: if ((ep = engr_at(x, y)) != NULL)
191: del_engr(ep);
192: ep = (struct engr *)
193: alloc((unsigned) (sizeof(struct engr) + strlen(s) + 1));
194: ep->nxt_engr = head_engr;
195: head_engr = ep;
196: ep->engr_x = x;
197: ep->engr_y = y;
198: ep->engr_txt = (char *) (ep + 1);
199: (void) strcpy(ep->engr_txt, s);
200: ep->engr_time = 0;
201: ep->engr_type = DUST;
202: ep->engr_lth = strlen(s) + 1;
203: }
204:
205: int
206: doengrave()
207: {
208: int len;
209: char *sp;
210: struct engr *ep, *oep = engr_at(u.ux, u.uy);
211: char buf[BUFSZ];
212: xchar type;
213: int spct;
214: struct obj *otmp;
215: multi = 0;
216:
217: if (u.uswallow) {
218: pline("You're joking. Hahaha!");
219: return (0);
220: }
221:
222: otmp = getobj("#-)/", "write with");
223: if (!otmp)
224: return (0);
225:
226: if (otmp == &zeroobj)
227: otmp = 0;
228: if (otmp && otmp->otyp == WAN_FIRE && otmp->spe) {
229: type = BURN;
230: otmp->spe--;
231: } else {
232:
233: if (otmp != uwep) {
234: if (uwep && uwep->cursed) {
235:
236: pline("Since your weapon is welded to your hand,");
237: pline("you use the %s.", aobjnam(uwep, (char *) 0));
238: otmp = uwep;
239: } else {
240: if (!otmp)
241: pline("You are now empty-handed.");
242: else if (otmp->cursed)
243: pline("The %s %s to your hand!",
244: aobjnam(otmp, "weld"),
245: (otmp->quan == 1) ? "itself" : "themselves");
246: else
247: pline("You now wield %s.", doname(otmp));
248: setuwep(otmp);
249: }
250: }
251: if (!otmp)
252: type = DUST;
253: else if (otmp->otyp == DAGGER || otmp->otyp == TWO_HANDED_SWORD ||
254: otmp->otyp == CRYSKNIFE ||
255: otmp->otyp == LONG_SWORD || otmp->otyp == AXE) {
256: type = ENGRAVE;
257: if ((int) otmp->spe <= -3) {
258: type = DUST;
259: pline("Your %s too dull for engraving.",
260: aobjnam(otmp, "are"));
261: if (oep && oep->engr_type != DUST)
262: return (1);
263: }
264: } else
265: type = DUST;
266: }
267: if (Levitation && type != BURN) {
268: pline("You can't reach the floor!");
269: return (1);
270: }
271: if (oep && oep->engr_type == DUST) {
272: pline("You wipe out the message that was written here.");
273: del_engr(oep);
274: oep = 0;
275: }
276: if (type == DUST && oep) {
277: pline("You cannot wipe out the message that is %s in the rock.",
278: (oep->engr_type == BURN) ? "burned" : "engraved");
279: return (1);
280: }
281: pline("What do you want to %s on the floor here? ",
282: (type == ENGRAVE) ? "engrave" : (type == BURN) ? "burn" : "write");
283: getlin(buf);
284: clrlin();
285: spct = 0;
286: sp = buf;
287: while (*sp == ' ')
288: spct++, sp++;
289: len = strlen(sp);
290: if (!len || *buf == '\033') {
291: if (type == BURN)
292: otmp->spe++;
293: return (0);
294: }
295: switch (type) {
296: case DUST:
297: case BURN:
298: if (len > 15) {
299: multi = -(len / 10);
300: nomovemsg = "You finished writing.";
301: }
302: break;
303: case ENGRAVE:
304: {
305: int len2 = (otmp->spe + 3) * 2 + 1;
306:
307: pline("Your %s dull.", aobjnam(otmp, "get"));
308: if (len2 < len) {
309: len = len2;
310: sp[len] = 0;
311: otmp->spe = -3;
312: nomovemsg = "You cannot engrave more.";
313: } else {
314: otmp->spe -= len / 2;
315: nomovemsg = "You finished engraving.";
316: }
317: multi = -len;
318: }
319: break;
320: }
321: if (oep)
322: len += strlen(oep->engr_txt) + spct;
323: ep = (struct engr *) alloc((unsigned) (sizeof(struct engr) + len + 1));
324: ep->nxt_engr = head_engr;
325: head_engr = ep;
326: ep->engr_x = u.ux;
327: ep->engr_y = u.uy;
328: sp = (char *) (ep + 1);
329: ep->engr_txt = sp;
330: if (oep) {
331: (void) strcpy(sp, oep->engr_txt);
332: (void) strcat(sp, buf);
333: del_engr(oep);
334: } else
335: (void) strcpy(sp, buf);
336: ep->engr_lth = len + 1;
337: ep->engr_type = type;
338: ep->engr_time = moves - multi;
339:
340:
341: if (len > BUFSZ - 20)
342: sp[BUFSZ - 20] = 0;
343:
344: return (1);
345: }
346:
347: void
348: save_engravings(fd)
349: int fd;
350: {
351: struct engr *ep = head_engr;
352: while (ep) {
353: if (!ep->engr_lth || !ep->engr_txt[0]) {
354: ep = ep->nxt_engr;
355: continue;
356: }
357: bwrite(fd, (char *) &(ep->engr_lth), sizeof(ep->engr_lth));
358: bwrite(fd, (char *) ep, sizeof(struct engr) + ep->engr_lth);
359: ep = ep->nxt_engr;
360: }
361: bwrite(fd, (char *) nul, sizeof(unsigned));
362: head_engr = 0;
363: }
364:
365: void
366: rest_engravings(fd)
367: int fd;
368: {
369: struct engr *ep;
370: unsigned lth;
371: head_engr = 0;
372: while (1) {
373: mread(fd, (char *) <h, sizeof(unsigned));
374: if (lth == 0)
375: return;
376: ep = (struct engr *) alloc(sizeof(struct engr) + lth);
377: mread(fd, (char *) ep, sizeof(struct engr) + lth);
378: ep->nxt_engr = head_engr;
379: ep->engr_txt = (char *) (ep + 1);
380: head_engr = ep;
381: }
382: }
383:
384: void
385: del_engr(ep)
386: struct engr *ep;
387: {
388: struct engr *ept;
389: if (ep == head_engr)
390: head_engr = ep->nxt_engr;
391: else {
392: for (ept = head_engr; ept; ept = ept->nxt_engr) {
393: if (ept->nxt_engr == ep) {
394: ept->nxt_engr = ep->nxt_engr;
395: goto fnd;
396: }
397: }
398: impossible("Error in del_engr?");
399: return;
400: fnd: ;
401: }
402: free((char *) ep);
403: }