Source:NetHack 3.2.0/write.c

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

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

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