Source:Hack 1.0/hack.engrave.c

From NetHackWiki
Jump to: navigation, search

Below is the full text to hack.engrave.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/hack.engrave.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

Screenshots and source code from Hack are used under the CWI license.

1.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
2.    
3.    #include	"hack.h"
4.    extern char *nomovemsg;
5.    extern char nul[];
6.    struct engr {
7.    	struct engr *nxt_engr;
8.    	char *engr_txt;
9.    	xchar engr_x, engr_y;
10.   	unsigned engr_lth;	/* for save & restore; not length of text */
11.   	long engr_time;	/* moment engraving was (will be) finished */
12.   	xchar engr_type;
13.   #define	DUST	1
14.   #define	ENGRAVE	2
15.   #define	BURN	3
16.   } *head_engr;
17.   
18.   struct engr *
19.   engr_at(x,y) register xchar x,y; {
20.   register struct engr *ep = head_engr;
21.   	while(ep) {
22.   		if(x == ep->engr_x && y == ep->engr_y)
23.   			return(ep);
24.   		ep = ep->nxt_engr;
25.   	}
26.   	return((struct engr *) 0);
27.   }
28.   
29.   sengr_at(s,x,y) register char *s; register xchar x,y; {
30.   register struct engr *ep = engr_at(x,y);
31.   register char *t;
32.   register int n;
33.   	if(ep && ep->engr_time <= moves) {
34.   		t = ep->engr_txt;
35.   /*
36.   		if(!strcmp(s,t)) return(1);
37.   */
38.   		n = strlen(s);
39.   		while(*t) {
40.   			if(!strncmp(s,t,n)) return(1);
41.   			t++;
42.   		}
43.   	}
44.   	return(0);
45.   }
46.   
47.   wipe_engr_at(x,y,cnt) register xchar x,y,cnt; {
48.   register struct engr *ep = engr_at(x,y);
49.   register int lth,pos;
50.   char ch;
51.   	if(ep){
52.   		if(ep->engr_type != DUST) {
53.   			cnt = rn2(1 + 50/(cnt+1)) ? 0 : 1;
54.   		}
55.   		lth = strlen(ep->engr_txt);
56.   		if(lth && cnt > 0 ) {
57.   			while(cnt--) {
58.   				pos = rn2(lth);
59.   				if((ch = ep->engr_txt[pos]) == ' ')
60.   					continue;
61.   				ep->engr_txt[pos] = (ch != '?') ? '?' : ' ';
62.   			}
63.   		}
64.   		while(lth && ep->engr_txt[lth-1] == ' ')
65.   			ep->engr_txt[--lth] = 0;
66.   		while(ep->engr_txt[0] == ' ')
67.   			ep->engr_txt++;
68.   		if(!ep->engr_txt[0]) del_engr(ep);
69.   	}
70.   }
71.   
72.   read_engr_at(x,y) register int x,y; {
73.   register struct engr *ep = engr_at(x,y);
74.   	if(ep && ep->engr_txt[0]) {
75.   	    switch(ep->engr_type) {
76.   	    case DUST:
77.   		pline("Something is written here in the dust.");
78.   		break;
79.   	    case ENGRAVE:
80.   		pline("Something is engraved here on the floor.");
81.   		break;
82.   	    case BURN:
83.   		pline("Some text has been burned here in the floor.");
84.   		break;
85.   	    default:
86.   		pline("Something is written in a very strange way.");
87.   		impossible();
88.   	    }
89.   	    pline("You read: \"%s\".", ep->engr_txt);
90.   	}
91.   }
92.   
93.   doengrave(){
94.   register int len;
95.   register char *sp;
96.   register struct engr *ep, *oep = engr_at(u.ux,u.uy);
97.   char buf[BUFSZ];
98.   xchar type;
99.   int spct;		/* number of leading spaces */
100.  register struct obj *otmp;
101.  	multi = 0;
102.  
103.  	/* one may write with finger, weapon or wand */
104.  	otmp = getobj("#-)/", "write with");
105.  	if(!otmp) return(0);
106.  	if(otmp == (struct obj *)(-1))
107.  		type = DUST;
108.  	else if(otmp->otyp == WAN_FIRE && otmp->spe) {
109.  		type = BURN;
110.  		otmp->spe--;
111.  	} else if(otmp->otyp == DAGGER || otmp->otyp == TWO_HANDED_SWORD ||
112.  		otmp->otyp == CRYSKNIFE ||
113.  		otmp->otyp == LONG_SWORD || otmp->otyp == AXE){
114.  		type = ENGRAVE;
115.  		if((int)otmp->spe <= -3) {
116.  			type = DUST;
117.  			pline("Your %s too dull for engraving.",
118.  				aobjnam(otmp, "are"));
119.  			if(oep && oep->engr_type != DUST) return(1);
120.  		}
121.  	} else	type = DUST;
122.  	if(oep && oep->engr_type == DUST){
123.  		  pline("You wipe out the message that was written here.");
124.  		  del_engr(oep);
125.  		  oep = 0;
126.  	}
127.  	if(type == DUST && oep){
128.  	pline("You cannot wipe out the message that is %s in the rock.",
129.  		    (oep->engr_type == BURN) ? "burned" : "engraved");
130.  		  return(1);
131.  	}
132.  
133.  	pline("What do you want to %s on the floor here? ",
134.  	  (type == ENGRAVE) ? "engrave" : (type == BURN) ? "burn" : "write");
135.  	getlin(buf);
136.  	clrlin();
137.  	spct = 0;
138.  	sp = buf;
139.  	while(*sp == ' ') spct++, sp++;
140.  	len = strlen(sp);
141.  	if(!len) {
142.  		if(type == BURN) otmp->spe++;
143.  		return(0);
144.  	}
145.  	
146.  	switch(type) {
147.  	case DUST:
148.  	case BURN:
149.  		if(len > 15) {
150.  			multi = -(len/10);
151.  			nomovemsg = "You finished writing.";
152.  		}
153.  		break;
154.  	case ENGRAVE:
155.  		{	int len2 = (otmp->spe + 3) * 2 + 1;
156.  			char *bufp = doname(otmp);
157.  			if(digit(*bufp))
158.  				pline("Your %s get dull.", bufp);
159.  			else {
160.  				if(!strncmp(bufp,"a ",2))
161.  					bufp += 2;
162.  				else if(!strncmp(bufp,"an ",3))
163.  					bufp += 3;
164.  				pline("Your %s gets dull.", bufp);
165.  			}
166.  			if(len2 < len) {
167.  				len = len2;
168.  				sp[len] = 0;
169.  				otmp->spe = -3;
170.  				nomovemsg = "You cannot engrave more.";
171.  			} else {
172.  				otmp->spe -= len/2;
173.  				nomovemsg = "You finished engraving.";
174.  			}
175.  			multi = -len;
176.  		}
177.  		break;
178.  	}
179.  	if(oep) len += strlen(oep->engr_txt) + spct;
180.  	ep = (struct engr *) alloc((unsigned)(sizeof(struct engr) + len + 1));
181.  	ep->nxt_engr = head_engr;
182.  	head_engr = ep;
183.  	ep->engr_x = u.ux;
184.  	ep->engr_y = u.uy;
185.  	sp = (char *)(ep + 1);	/* (char *)ep + sizeof(struct engr) */
186.  	ep->engr_txt = sp;
187.  	if(oep) {
188.  		(void) strcpy(sp, oep->engr_txt);
189.  		(void) strcat(sp, buf);
190.  		del_engr(oep);
191.  	} else
192.  		(void) strcpy(sp, buf);
193.  	ep->engr_lth = len+1;
194.  	ep->engr_type = type;
195.  	ep->engr_time = moves-multi;
196.  
197.  	/* kludge to protect pline against excessively long texts */
198.  	if(len > BUFSZ-20) sp[BUFSZ-20] = 0;
199.  
200.  	return(1);
201.  }
202.  
203.  save_engravings(fd) int fd; {
204.  register struct engr *ep = head_engr;
205.  	while(ep) {
206.  		if(!ep->engr_lth || !ep->engr_txt[0]){
207.  			ep = ep->nxt_engr;
208.  			continue;
209.  		}
210.  		bwrite(fd, (char *) & (ep->engr_lth), sizeof(ep->engr_lth));
211.  		bwrite(fd, (char *) ep, sizeof(struct engr) + ep->engr_lth);
212.  		ep = ep->nxt_engr;
213.  	}
214.  	bwrite(fd, (char *) nul, sizeof(unsigned));
215.  }
216.  
217.  rest_engravings(fd) int fd; {
218.  register struct engr *ep;
219.  unsigned lth;
220.  	head_engr = 0;
221.  	while(1) {
222.  		mread(fd, (char *) &lth, sizeof(unsigned));
223.  		if(lth == 0) return;
224.  		ep = (struct engr *) alloc(sizeof(struct engr) + lth);
225.  		mread(fd, (char *) ep, sizeof(struct engr) + lth);
226.  		ep->nxt_engr = head_engr;
227.  		head_engr = ep;
228.  	}
229.  }
230.  
231.  del_engr(ep) register struct engr *ep; {
232.  register struct engr *ept;
233.  	if(ep == head_engr)
234.  		head_engr = ep->nxt_engr;
235.  	else {
236.  		for(ept = head_engr; ept; ept = ept->nxt_engr)
237.  			if(ept->nxt_engr == ep) {
238.  				ept->nxt_engr = ep->nxt_engr;
239.  				goto fnd;
240.  			}
241.  		pline("Error in del_engr?"); impossible();
242.  	fnd:	;
243.  	}
244.  	free((char *) ep);
245.  }