1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.engrave.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.engrave.c,v 1.4 1999/11/16 02:57:04 billf Exp $ */
8 extern struct obj zeroobj
;
10 struct engr
*nxt_engr
;
13 unsigned engr_lth
; /* for save & restore; not length of text */
14 long engr_time
; /* moment engraving was (will be) finished */
21 static struct engr
*engr_at(xchar
, xchar
);
22 static void del_engr(struct engr
*);
25 engr_at(xchar x
, xchar y
)
27 struct engr
*ep
= head_engr
;
30 if (x
== ep
->engr_x
&& y
== ep
->engr_y
)
38 sengr_at(const char *s
, xchar x
, xchar y
)
40 struct engr
*ep
= engr_at(x
, y
);
44 if (ep
&& ep
->engr_time
<= moves
) {
48 if (!strncmp(s
, t
, n
))
59 if (!u
.uswallow
&& !Levitation
)
60 wipe_engr_at(u
.ux
, u
.uy
, cnt
);
64 wipe_engr_at(xchar x
, xchar y
, xchar cnt
)
66 struct engr
*ep
= engr_at(x
, y
);
71 if ((ep
->engr_type
!= DUST
) || Levitation
)
72 cnt
= rn2(1 + 50 / (cnt
+ 1)) ? 0 : 1;
73 lth
= strlen(ep
->engr_txt
);
77 if ((ch
= ep
->engr_txt
[pos
]) == ' ')
79 ep
->engr_txt
[pos
] = (ch
!= '?') ? '?' : ' ';
82 while (lth
&& ep
->engr_txt
[lth
- 1] == ' ')
83 ep
->engr_txt
[--lth
] = 0;
84 while (ep
->engr_txt
[0] == ' ')
92 read_engr_at(int x
, int y
)
94 struct engr
*ep
= engr_at(x
, y
);
96 if (ep
&& ep
->engr_txt
[0]) {
97 switch (ep
->engr_type
) {
99 pline("Something is written here in the dust.");
102 pline("Something is engraved here on the floor.");
105 pline("Some text has been burned here in the floor.");
108 impossible("Something is written in a very strange way.");
110 pline("You read: \"%s\".", ep
->engr_txt
);
115 make_engr_at(int x
, int y
, const char *s
)
119 if ((ep
= engr_at(x
, y
)))
121 ep
= alloc((unsigned)(sizeof(struct engr
) + strlen(s
) + 1));
122 ep
->nxt_engr
= head_engr
;
126 ep
->engr_txt
= (char *)(ep
+ 1);
127 strcpy(ep
->engr_txt
, s
);
129 ep
->engr_type
= DUST
;
130 ep
->engr_lth
= strlen(s
) + 1;
138 struct engr
*ep
, *oep
= engr_at(u
.ux
, u
.uy
);
141 int spct
; /* number of leading spaces */
146 pline("You're joking. Hahaha!"); /* riv05!a3 */
150 /* one may write with finger, weapon or wand */
151 otmp
= getobj("#-)/", "write with");
155 if (otmp
== &zeroobj
)
157 if (otmp
&& otmp
->otyp
== WAN_FIRE
&& otmp
->spe
) {
161 /* first wield otmp */
163 if (uwep
&& uwep
->cursed
) {
164 /* Andreas Bormann */
165 pline("Since your weapon is welded to your hand,");
166 pline("you use the %s.", aobjnam(uwep
, NULL
));
170 pline("You are now empty-handed.");
171 else if (otmp
->cursed
)
172 pline("The %s %s to your hand!",
173 aobjnam(otmp
, "weld"),
174 (otmp
->quan
== 1) ? "itself" : "themselves");
176 pline("You now wield %s.", doname(otmp
));
183 else if (otmp
->otyp
== DAGGER
|| otmp
->otyp
== TWO_HANDED_SWORD
||
184 otmp
->otyp
== CRYSKNIFE
||
185 otmp
->otyp
== LONG_SWORD
|| otmp
->otyp
== AXE
) {
187 if ((int)otmp
->spe
<= -3) {
189 pline("Your %s too dull for engraving.",
190 aobjnam(otmp
, "are"));
191 if (oep
&& oep
->engr_type
!= DUST
)
197 if (Levitation
&& type
!= BURN
) { /* riv05!a3 */
198 pline("You can't reach the floor!");
201 if (oep
&& oep
->engr_type
== DUST
) {
202 pline("You wipe out the message that was written here.");
206 if (type
== DUST
&& oep
) {
207 pline("You cannot wipe out the message that is %s in the rock.",
208 (oep
->engr_type
== BURN
) ? "burned" : "engraved");
212 pline("What do you want to %s on the floor here? ",
213 (type
== ENGRAVE
) ? "engrave" : (type
== BURN
) ? "burn" : "write");
223 if (!len
|| *buf
== '\033') {
234 nomovemsg
= "You finished writing.";
237 case ENGRAVE
: /* here otmp != 0 */
239 int len2
= (otmp
->spe
+ 3) * 2 + 1;
241 pline("Your %s dull.", aobjnam(otmp
, "get"));
246 nomovemsg
= "You cannot engrave more.";
248 otmp
->spe
-= len
/ 2;
249 nomovemsg
= "You finished engraving.";
256 len
+= strlen(oep
->engr_txt
) + spct
;
257 ep
= alloc((unsigned)(sizeof(struct engr
) + len
+ 1));
258 ep
->nxt_engr
= head_engr
;
262 sp
= (char *)(ep
+ 1); /* (char *)ep + sizeof(struct engr) */
265 strcpy(sp
, oep
->engr_txt
);
270 ep
->engr_lth
= len
+ 1;
271 ep
->engr_type
= type
;
272 ep
->engr_time
= moves
- multi
;
274 /* kludge to protect pline against excessively long texts */
275 if (len
> BUFSZ
- 20)
282 save_engravings(int fd
)
284 struct engr
*ep
= head_engr
;
287 if (!ep
->engr_lth
|| !ep
->engr_txt
[0]) {
291 bwrite(fd
, (char *)&(ep
->engr_lth
), sizeof(ep
->engr_lth
));
292 bwrite(fd
, (char *)ep
, sizeof(struct engr
) + ep
->engr_lth
);
295 bwrite(fd
, (char *)nul
, sizeof(unsigned));
300 rest_engravings(int fd
)
307 mread(fd
, (char *)<h
, sizeof(unsigned));
310 ep
= alloc(sizeof(struct engr
) + lth
);
311 mread(fd
, (char *)ep
, sizeof(struct engr
) + lth
);
312 ep
->nxt_engr
= head_engr
;
313 ep
->engr_txt
= (char *)(ep
+ 1); /* Andreas Bormann */
319 del_engr(struct engr
*ep
)
324 head_engr
= ep
->nxt_engr
;
326 for (ept
= head_engr
; ept
; ept
= ept
->nxt_engr
) {
327 if (ept
->nxt_engr
== ep
) {
328 ept
->nxt_engr
= ep
->nxt_engr
;
332 impossible("Error in del_engr?");