Source:SLASH'EM 0.0.7E7F2/write.c

From NetHackWiki
Jump to: navigation, search

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.


The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

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, " armor")) != 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*/