]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.engrave.c
Generate <>& symbolically. I'm avoiding .../dist/... directories for now.
[bsdgames-darwin.git] / hack / hack.engrave.c
1 /* $NetBSD: hack.engrave.c,v 1.5 2001/03/25 20:44:00 jsm Exp $ */
2
3 /*
4 * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
5 */
6
7 #include <sys/cdefs.h>
8 #ifndef lint
9 __RCSID("$NetBSD: hack.engrave.c,v 1.5 2001/03/25 20:44:00 jsm Exp $");
10 #endif /* not lint */
11
12 #include <stdlib.h>
13 #include "hack.h"
14 #include "extern.h"
15
16 struct engr {
17 struct engr *nxt_engr;
18 char *engr_txt;
19 xchar engr_x, engr_y;
20 unsigned engr_lth; /* for save & restore; not length of
21 * text */
22 long engr_time; /* moment engraving was (will be)
23 * finished */
24 xchar engr_type;
25 #define DUST 1
26 #define ENGRAVE 2
27 #define BURN 3
28 } *head_engr;
29
30 struct engr *
31 engr_at(x, y)
32 xchar x, y;
33 {
34 struct engr *ep = head_engr;
35 while (ep) {
36 if (x == ep->engr_x && y == ep->engr_y)
37 return (ep);
38 ep = ep->nxt_engr;
39 }
40 return ((struct engr *) 0);
41 }
42
43 int
44 sengr_at(s, x, y)
45 const char *s;
46 xchar x, y;
47 {
48 struct engr *ep = engr_at(x, y);
49 char *t;
50 int n;
51 if (ep && ep->engr_time <= moves) {
52 t = ep->engr_txt;
53 /*
54 if(!strcmp(s,t)) return(1);
55 */
56 n = strlen(s);
57 while (*t) {
58 if (!strncmp(s, t, n))
59 return (1);
60 t++;
61 }
62 }
63 return (0);
64 }
65
66 void
67 u_wipe_engr(cnt)
68 int cnt;
69 {
70 if (!u.uswallow && !Levitation)
71 wipe_engr_at(u.ux, u.uy, cnt);
72 }
73
74 void
75 wipe_engr_at(x, y, cnt)
76 xchar x, y, cnt;
77 {
78 struct engr *ep = engr_at(x, y);
79 int lth, pos;
80 char ch;
81 if (ep) {
82 if ((ep->engr_type != DUST) || Levitation) {
83 cnt = rn2(1 + 50 / (cnt + 1)) ? 0 : 1;
84 }
85 lth = strlen(ep->engr_txt);
86 if (lth && cnt > 0) {
87 while (cnt--) {
88 pos = rn2(lth);
89 if ((ch = ep->engr_txt[pos]) == ' ')
90 continue;
91 ep->engr_txt[pos] = (ch != '?') ? '?' : ' ';
92 }
93 }
94 while (lth && ep->engr_txt[lth - 1] == ' ')
95 ep->engr_txt[--lth] = 0;
96 while (ep->engr_txt[0] == ' ')
97 ep->engr_txt++;
98 if (!ep->engr_txt[0])
99 del_engr(ep);
100 }
101 }
102
103 void
104 read_engr_at(x, y)
105 int x, y;
106 {
107 struct engr *ep = engr_at(x, y);
108 if (ep && ep->engr_txt[0]) {
109 switch (ep->engr_type) {
110 case DUST:
111 pline("Something is written here in the dust.");
112 break;
113 case ENGRAVE:
114 pline("Something is engraved here on the floor.");
115 break;
116 case BURN:
117 pline("Some text has been burned here in the floor.");
118 break;
119 default:
120 impossible("Something is written in a very strange way.");
121 }
122 pline("You read: \"%s\".", ep->engr_txt);
123 }
124 }
125
126 void
127 make_engr_at(x, y, s)
128 int x, y;
129 const char *s;
130 {
131 struct engr *ep;
132
133 if ((ep = engr_at(x, y)) != NULL)
134 del_engr(ep);
135 ep = (struct engr *)
136 alloc((unsigned) (sizeof(struct engr) + strlen(s) + 1));
137 ep->nxt_engr = head_engr;
138 head_engr = ep;
139 ep->engr_x = x;
140 ep->engr_y = y;
141 ep->engr_txt = (char *) (ep + 1);
142 (void) strcpy(ep->engr_txt, s);
143 ep->engr_time = 0;
144 ep->engr_type = DUST;
145 ep->engr_lth = strlen(s) + 1;
146 }
147
148 int
149 doengrave()
150 {
151 int len;
152 char *sp;
153 struct engr *ep, *oep = engr_at(u.ux, u.uy);
154 char buf[BUFSZ];
155 xchar type;
156 int spct; /* number of leading spaces */
157 struct obj *otmp;
158 multi = 0;
159
160 if (u.uswallow) {
161 pline("You're joking. Hahaha!"); /* riv05!a3 */
162 return (0);
163 }
164 /* one may write with finger, weapon or wand */
165 otmp = getobj("#-)/", "write with");
166 if (!otmp)
167 return (0);
168
169 if (otmp == &zeroobj)
170 otmp = 0;
171 if (otmp && otmp->otyp == WAN_FIRE && otmp->spe) {
172 type = BURN;
173 otmp->spe--;
174 } else {
175 /* first wield otmp */
176 if (otmp != uwep) {
177 if (uwep && uwep->cursed) {
178 /* Andreas Bormann */
179 pline("Since your weapon is welded to your hand,");
180 pline("you use the %s.", aobjnam(uwep, (char *) 0));
181 otmp = uwep;
182 } else {
183 if (!otmp)
184 pline("You are now empty-handed.");
185 else if (otmp->cursed)
186 pline("The %s %s to your hand!",
187 aobjnam(otmp, "weld"),
188 (otmp->quan == 1) ? "itself" : "themselves");
189 else
190 pline("You now wield %s.", doname(otmp));
191 setuwep(otmp);
192 }
193 }
194 if (!otmp)
195 type = DUST;
196 else if (otmp->otyp == DAGGER || otmp->otyp == TWO_HANDED_SWORD ||
197 otmp->otyp == CRYSKNIFE ||
198 otmp->otyp == LONG_SWORD || otmp->otyp == AXE) {
199 type = ENGRAVE;
200 if ((int) otmp->spe <= -3) {
201 type = DUST;
202 pline("Your %s too dull for engraving.",
203 aobjnam(otmp, "are"));
204 if (oep && oep->engr_type != DUST)
205 return (1);
206 }
207 } else
208 type = DUST;
209 }
210 if (Levitation && type != BURN) { /* riv05!a3 */
211 pline("You can't reach the floor!");
212 return (1);
213 }
214 if (oep && oep->engr_type == DUST) {
215 pline("You wipe out the message that was written here.");
216 del_engr(oep);
217 oep = 0;
218 }
219 if (type == DUST && oep) {
220 pline("You cannot wipe out the message that is %s in the rock.",
221 (oep->engr_type == BURN) ? "burned" : "engraved");
222 return (1);
223 }
224 pline("What do you want to %s on the floor here? ",
225 (type == ENGRAVE) ? "engrave" : (type == BURN) ? "burn" : "write");
226 getlin(buf);
227 clrlin();
228 spct = 0;
229 sp = buf;
230 while (*sp == ' ')
231 spct++, sp++;
232 len = strlen(sp);
233 if (!len || *buf == '\033') {
234 if (type == BURN)
235 otmp->spe++;
236 return (0);
237 }
238 switch (type) {
239 case DUST:
240 case BURN:
241 if (len > 15) {
242 multi = -(len / 10);
243 nomovemsg = "You finished writing.";
244 }
245 break;
246 case ENGRAVE: /* here otmp != 0 */
247 {
248 int len2 = (otmp->spe + 3) * 2 + 1;
249
250 pline("Your %s dull.", aobjnam(otmp, "get"));
251 if (len2 < len) {
252 len = len2;
253 sp[len] = 0;
254 otmp->spe = -3;
255 nomovemsg = "You cannot engrave more.";
256 } else {
257 otmp->spe -= len / 2;
258 nomovemsg = "You finished engraving.";
259 }
260 multi = -len;
261 }
262 break;
263 }
264 if (oep)
265 len += strlen(oep->engr_txt) + spct;
266 ep = (struct engr *) alloc((unsigned) (sizeof(struct engr) + len + 1));
267 ep->nxt_engr = head_engr;
268 head_engr = ep;
269 ep->engr_x = u.ux;
270 ep->engr_y = u.uy;
271 sp = (char *) (ep + 1); /* (char *)ep + sizeof(struct engr) */
272 ep->engr_txt = sp;
273 if (oep) {
274 (void) strcpy(sp, oep->engr_txt);
275 (void) strcat(sp, buf);
276 del_engr(oep);
277 } else
278 (void) strcpy(sp, buf);
279 ep->engr_lth = len + 1;
280 ep->engr_type = type;
281 ep->engr_time = moves - multi;
282
283 /* kludge to protect pline against excessively long texts */
284 if (len > BUFSZ - 20)
285 sp[BUFSZ - 20] = 0;
286
287 return (1);
288 }
289
290 void
291 save_engravings(fd)
292 int fd;
293 {
294 struct engr *ep = head_engr;
295 while (ep) {
296 if (!ep->engr_lth || !ep->engr_txt[0]) {
297 ep = ep->nxt_engr;
298 continue;
299 }
300 bwrite(fd, (char *) &(ep->engr_lth), sizeof(ep->engr_lth));
301 bwrite(fd, (char *) ep, sizeof(struct engr) + ep->engr_lth);
302 ep = ep->nxt_engr;
303 }
304 bwrite(fd, (char *) nul, sizeof(unsigned));
305 head_engr = 0;
306 }
307
308 void
309 rest_engravings(fd)
310 int fd;
311 {
312 struct engr *ep;
313 unsigned lth;
314 head_engr = 0;
315 while (1) {
316 mread(fd, (char *) &lth, sizeof(unsigned));
317 if (lth == 0)
318 return;
319 ep = (struct engr *) alloc(sizeof(struct engr) + lth);
320 mread(fd, (char *) ep, sizeof(struct engr) + lth);
321 ep->nxt_engr = head_engr;
322 ep->engr_txt = (char *) (ep + 1); /* Andreas Bormann */
323 head_engr = ep;
324 }
325 }
326
327 void
328 del_engr(ep)
329 struct engr *ep;
330 {
331 struct engr *ept;
332 if (ep == head_engr)
333 head_engr = ep->nxt_engr;
334 else {
335 for (ept = head_engr; ept; ept = ept->nxt_engr) {
336 if (ept->nxt_engr == ep) {
337 ept->nxt_engr = ep->nxt_engr;
338 goto fnd;
339 }
340 }
341 impossible("Error in del_engr?");
342 return;
343 fnd: ;
344 }
345 free((char *) ep);
346 }