Source:SLASH'EM 0.0.7E7F2/write.c

Below is the full text to write.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/write.c#line123 ]], for example.

The latest source code for vanilla NetHack is at Source code.

1.   /*	SCCS Id: @(#)write.c	3.4	2001/11/29	*/ 2.   /* NetHack may be freely redistributed. See license for details. */ 3.     4.    #include "hack.h"  5. 6.   STATIC_DCL int FDECL(cost,(struct obj *)); 7.    8.    /*  9.     * returns basecost of a scroll or a spellbook 10.   */  11.   STATIC_OVL int 12.  cost(otmp) 13.  register struct obj *otmp; 14.  {  15.    16.   	if (otmp->oclass == SPBOOK_CLASS) 17.  		return(10 * objects[otmp->otyp].oc_level); 18.   19.   	/* KMH, balance patch -- restoration of marker charges */ 20.  	switch (otmp->otyp) { 21.  # ifdef MAIL 22.  	case SCR_MAIL: 23.  		return(2); 24.  /*		break; */ 25.  # endif 26.  	case SCR_LIGHT: 27.  	case SCR_GOLD_DETECTION: 28.  	case SCR_FOOD_DETECTION: 29.  	case SCR_MAGIC_MAPPING: 30.  	case SCR_AMNESIA: 31.  	case SCR_FIRE: 32.  	case SCR_EARTH: 33.  		return(8); 34.  /*		break; */ 35.  	case SCR_DESTROY_ARMOR: 36.  	case SCR_CREATE_MONSTER: 37.  	case SCR_PUNISHMENT: 38.  		return(10); 39.  /*		break; */ 40.  	case SCR_CONFUSE_MONSTER: 41.  		return(12); 42.  /*		break; */ 43.  	case SCR_IDENTIFY: 44.  	case SCR_SCARE_MONSTER: 45.  		return(14); 46.  /*		break; */ 47.  	case SCR_TAMING: 48.  	case SCR_TELEPORTATION: 49.  		return(20); 50.  /*		break; */ 51.  	/* KMH, balance patch -- more useful scrolls cost more */ 52.  	case SCR_STINKING_CLOUD: 53.  	case SCR_ENCHANT_ARMOR: 54.  	case SCR_REMOVE_CURSE: 55.  	case SCR_ENCHANT_WEAPON: 56.  	case SCR_CHARGING: 57.  		return(24); 58.  /*		break; */ 59.  	case SCR_GENOCIDE: 60.  		return(30); 61.  /*		break; */ 62.  	case SCR_BLANK_PAPER: 63.  	default: 64.  		impossible("You can't write such a weird scroll!"); 65.  	}  66.   	return(1000); 67.  }  68.    69.   static NEARDATA const char write_on[] = { SCROLL_CLASS, SPBOOK_CLASS, 0 }; 70.   71.   int 72.  dowrite(pen) 73.  register struct obj *pen; 74.  {  75.   	register struct obj *paper; 76.  	char namebuf[BUFSZ], *nm, *bp; 77.  	register struct obj *new_obj; 78.  	int basecost, actualcost; 79.  	int curseval; 80.  	char qbuf[QBUFSZ]; 81.  	int first, last, i;  82. boolean by_descr = FALSE; 83.  	const char *typeword; 84.   85.   	if (nohands(youmonst.data)) { 86.  	    You("need hands to be able to write!"); 87.  	    return 0; 88.  	} else if (Glib) { 89.  	    pline("%s from your %s.",  90.   		  Tobjnam(pen, "slip"), makeplural(body_part(FINGER))); 91.  	    dropx(pen); 92.  	    return 1; 93.  	}  94.    95.   	/* get paper to write on */ 96.  	paper = getobj(write_on,"write on"); 97.  	if(!paper) 98.  		return(0); 99.  	typeword = (paper->oclass == SPBOOK_CLASS) ? "spellbook" : "scroll"; 100. 	if(Blind && !paper->dknown) { 101. 		You("don't know if that %s is blank or not!", typeword); 102. 		return(1); 103. 	}  104.  	paper->dknown = 1; 105. 	if(paper->otyp != SCR_BLANK_PAPER && paper->otyp != SPE_BLANK_PAPER) { 106. 		pline("That %s is not blank!", typeword); 107. 		exercise(A_WIS, FALSE); 108. 		return(1); 109. 	}  110.   111.  	/* what to write */ 112. 	Sprintf(qbuf, "What type of %s do you want to write?", typeword); 113. 	getlin(qbuf, namebuf); 114. 	(void)mungspaces(namebuf);	/* remove any excess whitespace */ 115. 	if(namebuf[0] == '\033' || !namebuf[0]) 116. 		return(1); 117. 	nm = namebuf; 118. 	if (!strncmpi(nm, "scroll ", 7)) nm += 7; 119. 	else if (!strncmpi(nm, "spellbook ", 10)) nm += 10; 120. 	if (!strncmpi(nm, "of ", 3)) nm += 3; 121.  122.  	if ((bp = strstri(nm, " armour")) != 0) { 123. 		(void)strncpy(bp, " armor ", 7);	/* won't add '\0' */ 124. 		(void)mungspaces(bp + 1);	/* remove the extra space */ 125. 	}  126.   127.  	first = bases[(int)paper->oclass]; 128. 	last = bases[(int)paper->oclass + 1] - 1; 129. 	for (i = first; i <= last; i++) { 130. 		/* extra shufflable descr not representing a real object */ 131. 		if (!OBJ_NAME(objects[i])) continue; 132.  133.  		if (!strcmpi(OBJ_NAME(objects[i]), nm)) 134. 			goto found; 135. 		if (!strcmpi(OBJ_DESCR(objects[i]), nm)) { 136. 			by_descr = TRUE; 137. 			goto found; 138. 		}  139.  	}  140.   141.  	There("is no such %s!", typeword); 142. 	return 1; 143. found: 144.  145.  	if (i == SCR_BLANK_PAPER || i == SPE_BLANK_PAPER) { 146. 		You_cant("write that!"); 147. 		pline("It's obscene!"); 148. 		return 1; 149. 	} else if (i == SPE_BOOK_OF_THE_DEAD) { 150. 		pline("No mere dungeon adventurer could write that."); 151. 		return 1; 152. 	} else if (by_descr && paper->oclass == SPBOOK_CLASS &&  153.  		    !objects[i].oc_name_known) { 154. 		/* can't write unknown spellbooks by description */ 155. 		pline(  156.  		  "Unfortunately you don't have enough information to go on."); 157. 		return 1; 158. 	}  159.   160.  	/* KMH, conduct */ 161. 	u.uconduct.literate++; 162.  163.  	new_obj = mksobj(i, FALSE, FALSE); 164. 	new_obj->bknown = (paper->bknown && pen->bknown); 165. #ifdef INVISIBLE_OBJECTS 166. 	new_obj->oinvis = paper->oinvis; 167. #endif 168.  169.  	/* shk imposes a flat rate per use, not based on actual charges used */ 170. 	check_unpaid(pen); 171.  172.  	/* see if there's enough ink */ 173. 	basecost = cost(new_obj); 174. 	if(pen->spe < basecost/2)  { 175. 		Your("marker is too dry to write that!"); 176. 		obfree(new_obj, (struct obj *) 0); 177. 		return(1); 178. 	}  179.   180.  	/* we're really going to write now, so calculate cost 181. 	 */  182.  	actualcost = rn1(basecost/2,basecost/2); 183. 	curseval = bcsign(pen) + bcsign(paper); 184. 	exercise(A_WIS, TRUE); 185. 	/* dry out marker */ 186. 	if (pen->spe < actualcost) { 187. 		pen->spe = 0; 188. 		Your("marker dries out!"); 189. 		/* scrolls disappear, spellbooks don't */ 190. 		if (paper->oclass == SPBOOK_CLASS) { 191. 			pline_The(  192.  		       "spellbook is left unfinished and your writing fades."); 193. 			update_inventory;	/* pen charges */ 194. 		} else { 195. 			pline_The("scroll is now useless and disappears!"); 196. 			useup(paper); 197. 		}  198.  		obfree(new_obj, (struct obj *) 0); 199. 		return(1); 200. 	}  201.  	pen->spe -= actualcost; 202.  203.  	/* can't write if we don't know it - unless we're lucky */ 204. 	if(!(objects[new_obj->otyp].oc_name_known) &&  205.  	   !(objects[new_obj->otyp].oc_uname) &&  206.  	   (rnl(Role_if(PM_WIZARD) ? 3 : 15))) { 207. 		You("%s to write that!", by_descr ? "fail" : "don't know how"); 208. 		/* scrolls disappear, spellbooks don't */ 209. 		if (paper->oclass == SPBOOK_CLASS) { 210. 			You(  211.         "write in your best handwriting:  \"My Diary\", but it quickly fades."); 212. 			update_inventory;	/* pen charges */ 213. 		} else { 214. 			if (by_descr) { 215. 			    Strcpy(namebuf, OBJ_DESCR(objects[new_obj->otyp])); 216. 			    wipeout_text(namebuf, (6+MAXULEV - u.ulevel)/6, 0); 217. 			} else 218. 			    Sprintf(namebuf, "%s was here!", plname); 219. 			You("write \"%s\" and the scroll disappears.", namebuf); 220. 			useup(paper); 221. 		}  222.  		obfree(new_obj, (struct obj *) 0); 223. 		return(1); 224. 	}  225.   226.  	/* useup old scroll / spellbook */ 227. 	useup(paper); 228.  229.  	/* success */ 230. 	if (new_obj->oclass == SPBOOK_CLASS) { 231. 		/* acknowledge the change in the object's description... */ 232.  		pline_The("spellbook warps strangely, then turns %s.",  233.  		      OBJ_DESCR(objects[new_obj->otyp])); 234. 	}  235.  	new_obj->blessed = (curseval > 0); 236. 	new_obj->cursed = (curseval < 0); 237. #ifdef MAIL 238. 	if (new_obj->otyp == SCR_MAIL) new_obj->spe = 1; 239. #endif 240. 	new_obj = hold_another_object(new_obj, "Oops!  %s out of your grasp!",  241.  					       The(aobjnam(new_obj, "slip")),  242.  					       (const char *)0); 243. 	return(1); 244. }  245.   246.  /*write.c*/