1 /* SCCS Id: @(#)write.c 3.4 2001/11/29 */
2 /* NetHack may be freely redistributed. See license for details. */
6 STATIC_DCL int FDECL(cost,(struct obj *));
9 * returns basecost of a scroll or a spellbook
13 register struct obj *otmp;
16 if (otmp->oclass == SPBOOK_CLASS)
17 return(10 * objects[otmp->otyp].oc_level);
26 case SCR_GOLD_DETECTION:
27 case SCR_FOOD_DETECTION:
28 case SCR_MAGIC_MAPPING:
34 case SCR_DESTROY_ARMOR:
35 case SCR_CREATE_MONSTER:
39 case SCR_CONFUSE_MONSTER:
45 case SCR_ENCHANT_ARMOR:
46 case SCR_REMOVE_CURSE:
47 case SCR_ENCHANT_WEAPON:
51 case SCR_SCARE_MONSTER:
52 case SCR_STINKING_CLOUD:
54 case SCR_TELEPORTATION:
62 impossible("You can't write such a weird scroll!");
67 static NEARDATA const char write_on[] = { SCROLL_CLASS, SPBOOK_CLASS, 0 };
71 register struct obj *pen;
73 register struct obj *paper;
74 char namebuf[BUFSZ], *nm, *bp;
75 register struct obj *new_obj;
76 int basecost, actualcost;
80 boolean by_descr = FALSE;
83 if (nohands(youmonst.data)) {
84 You("need hands to be able to write!");
87 pline("%s from your %s.",
88 Tobjnam(pen, "slip"), makeplural(body_part(FINGER)));
93 /* get paper to write on */
94 paper = getobj(write_on,"write on");
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);
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);
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])
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;
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 */
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;
131 if (!strcmpi(OBJ_NAME(objects[i]), nm))
133 if (!strcmpi(OBJ_DESCR(objects[i]), nm)) {
139 There("is no such %s!", typeword);
143 if (i == SCR_BLANK_PAPER || i == SPE_BLANK_PAPER) {
144 You_cant("write that!");
145 pline("It's obscene!");
147 } else if (i == SPE_BOOK_OF_THE_DEAD) {
148 pline("No mere dungeon adventurer could write that.");
150 } else if (by_descr && paper->oclass == SPBOOK_CLASS &&
151 !objects[i].oc_name_known) {
152 /* can't write unknown spellbooks by description */
154 "Unfortunately you don't have enough information to go on.");
159 u.uconduct.literate++;
161 new_obj = mksobj(i, FALSE, FALSE);
162 new_obj->bknown = (paper->bknown && pen->bknown);
164 /* shk imposes a flat rate per use, not based on actual charges used */
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);
175 /* we're really going to write now, so calculate cost
177 actualcost = rn1(basecost/2,basecost/2);
178 curseval = bcsign(pen) + bcsign(paper);
179 exercise(A_WIS, TRUE);
181 if (pen->spe < actualcost) {
183 Your("marker dries out!");
184 /* scrolls disappear, spellbooks don't */
185 if (paper->oclass == SPBOOK_CLASS) {
187 "spellbook is left unfinished and your writing fades.");
188 update_inventory(); /* pen charges */
190 pline_The("scroll is now useless and disappears!");
193 obfree(new_obj, (struct obj *) 0);
196 pen->spe -= actualcost;
198 /* can't write if we don't know it - unless we're lucky */
199 if(!(objects[new_obj->otyp].oc_name_known) &&
200 !(objects[new_obj->otyp].oc_uname) &&
201 (rnl(Role_if(PM_WIZARD) ? 3 : 15))) {
202 You("%s to write that!", by_descr ? "fail" : "don't know how");
203 /* scrolls disappear, spellbooks don't */
204 if (paper->oclass == SPBOOK_CLASS) {
206 "write in your best handwriting: \"My Diary\", but it quickly fades.");
207 update_inventory(); /* pen charges */
210 Strcpy(namebuf, OBJ_DESCR(objects[new_obj->otyp]));
211 wipeout_text(namebuf, (6+MAXULEV - u.ulevel)/6, 0);
213 Sprintf(namebuf, "%s was here!", plname);
214 You("write \"%s\" and the scroll disappears.", namebuf);
217 obfree(new_obj, (struct obj *) 0);
221 /* useup old scroll / spellbook */
225 if (new_obj->oclass == SPBOOK_CLASS) {
226 /* acknowledge the change in the object's description... */
227 pline_The("spellbook warps strangely, then turns %s.",
228 OBJ_DESCR(objects[new_obj->otyp]));
230 new_obj->blessed = (curseval > 0);
231 new_obj->cursed = (curseval < 0);
233 if (new_obj->otyp == SCR_MAIL) new_obj->spe = 1;
235 new_obj = hold_another_object(new_obj, "Oops! %s out of your grasp!",
236 The(aobjnam(new_obj, "slip")),