Source:NetHack 3.3.0/write.c

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