Source:Hack 1.0/hack.engrave.c

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

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. }