Source:NetHack 1.3d/spell.c

From NetHackWiki
Revision as of 00:28, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 1.3d/spell.c moved to Source:NetHack 1.3d/spell.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

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

Screenshots and source code from Hack are used under the CWI license.

1.    /*	SCCS Id: @(#)spell.c	1.3	87/07/14
2.    /* hack.spell.c - version 1.0.1		M. Stephenson 07-04-86 */
3.    
4.    #include "hack.h"
5.    #ifdef SPELLS
6.    extern char *nomovemsg;
7.    
8.    doxcribe() {
9.    	register struct obj *book;
10.   	struct	 obj	*getobj();
11.   	register boolean confused = (Confusion != 0);
12.   	register boolean oops;
13.   	register schar	 delay;
14.   	register int   booktype;
15.   	register int	 i;
16.   
17.   	book = getobj("+", "transcribe");
18.   	if(!book) return(0);
19.   
20.   	if(Blind) {
21.   	    pline("Being blind, you cannot read the mystic runes.");
22.   	    useup(book);		/* well, if you are stupid... */
23.   	    return(0);
24.   	}
25.   
26.   	if(confused) {
27.   	    pline("Being confused, you cannot grasp the meaning of this tome.");
28.   	    useup(book);		/* and more stupidity... */
29.   	    return(0);
30.   	}
31.   	booktype = book->otyp;
32.   	oops = !rn2(u.ulevel - objects[booktype].spl_lev + 7);
33.   	switch(booktype)  {
34.   
35.   /* level 1 spells */
36.   	case SPE_HEALING:
37.   	case SPE_DETECT_MONSTERS:
38.   	case SPE_FORCE_BOLT:
39.   	case SPE_LIGHT:
40.   	case SPE_SLEEP:
41.   /* level 2 spells */
42.   	case SPE_MAGIC_MISSILE:
43.   	case SPE_CONFUSE_MONSTER:
44.   	case SPE_SLOW_MONSTER:
45.   	case SPE_CURE_BLINDNESS:
46.   	case SPE_CREATE_MONSTER:
47.   	case SPE_DETECT_FOOD:
48.   		delay = -objects[booktype].oc_delay;
49.   		break;
50.   /* level 3 spells */
51.   	case SPE_HASTE_SELF:
52.   	case SPE_CAUSE_FEAR:
53.   	case SPE_CURE_SICKNESS:
54.   	case SPE_DETECT_UNSEEN:
55.   	case SPE_EXTRA_HEALING:
56.   	case SPE_CHARM_MONSTER:
57.   /* level 4 spells */
58.   	case SPE_LEVITATION:
59.   	case SPE_RESTORE_STRENGTH:
60.   	case SPE_INVISIBILITY:
61.   	case SPE_FIREBALL:
62.   	case SPE_DETECT_TREASURE:
63.   		delay = -(objects[booktype].spl_lev - 1) * objects[booktype].oc_delay;
64.   		break;
65.   /* level 5 spells */
66.   	case SPE_REMOVE_CURSE:
67.   	case SPE_MAGIC_MAPPING:
68.   	case SPE_CONE_OF_COLD:
69.   	case SPE_IDENTIFY:
70.   	case SPE_DIG:
71.   /* level 6 spells */
72.   	case SPE_TURN_UNDEAD:
73.   	case SPE_POLYMORPH:
74.   	case SPE_CREATE_FAMILIAR:
75.   	case SPE_TELEPORT_AWAY:
76.   		delay = -objects[booktype].spl_lev * objects[booktype].oc_delay;
77.   		break;
78.   /* level 7 spells */
79.   	case SPE_CANCELLATION:
80.   	case SPE_FINGER_OF_DEATH:
81.   	case SPE_GENOCIDE:
82.   		delay = -8 * objects[booktype].oc_delay;
83.   		break;
84.   /* impossible */
85.   	default:
86.   		impossible("Unknown spell-book, %d;", booktype);
87.   		return(0);
88.   	}
89.   
90.   	pline("You begin to transcribe the spell.");
91.   	if(oops || book->cursed)  {
92.   		cursed_book(objects[booktype].spl_lev);
93.   		nomul(delay);			/* study time */
94.   	} else  {
95.   		nomul(delay);			/* study time */
96.   		for(i = 0; i < MAXSPELL; i++)  {
97.   			if(spl_book[i].sp_id == booktype)  {
98.   				nomovemsg = "Oh, you already know that one!";
99.   				useup(book);
100.  				return(1);
101.  			} else if (spl_book[i].sp_id == NO_SPELL)  {
102.  				spl_book[i].sp_id = booktype;
103.  				spl_book[i].sp_lev = objects[booktype].spl_lev;
104.  				spl_book[i].sp_flags = objects[booktype].bits;
105.  				nomovemsg = "You add the spell to your books.";
106.  				objects[booktype].oc_name_known = 1;
107.  				useup(book);
108.  				return(1);
109.  			}
110.  		}
111.  		impossible("Too many spells in spellbook!");
112.  	}
113.  	useup(book);
114.  	return(1);
115.  }
116.  
117.  cursed_book(level)
118.  	register int	level;
119.  {
120.  	register int	nobj, cnt, onum;
121.  	register struct obj	*otmp;
122.  
123.  	switch(rnd(level)) {
124.  	case 0:
125.  		pline("you feel a wrenching sensation.");
126.  		tele();		/* teleport him */
127.  		break;
128.  	case 1:
129.  		pline("you feel threatened.");
130.  		aggravate();
131.  		break;
132.  	case 2:
133.  		if(!Blind)	pline("a cloud of darkness falls upon you.");
134.  		Blind += rn1(100,250);
135.  		seeoff(0);
136.  		break;
137.  	case 3:
138.  		if (u.ugold <= 0)  {
139.  			pline("you feel a strange sensation.");
140.  		} else {
141.  			pline("you notice you have no gold!");
142.  			u.ugold = 0;
143.  			flags.botl = 1;
144.  		}
145.  		break;
146.  	case 4:
147.  		pline("These runes were just too much to comprehend.");
148.  		HConfusion += rn1(7,16);
149.  		break;
150.  	case 5:
151.  		pline("The book was coated with contact poison!");
152.  		if(Poison_resistance) {
153.  		    losestr(rn1(1,2));
154.  		    losehp(rnd(6), "contact poison");
155.  		} else {
156.  		    losestr(rn1(4,3));
157.  		    losehp(rnd(10), "contact poison");
158.  		}
159.  		break;
160.  	case 6:
161.  		pline("As you read the book, it explodes in your face!");
162.  		losehp (2*rnd(10)+5, "exploding rune");
163.  		break;
164.  	case 7:
165.  		/* curse a few inventory items at random! */
166.  		nobj = 0;
167.  		for (otmp = invent; otmp; otmp = otmp->nobj)  nobj++;
168.  
169.  		for (cnt = rnd(6); cnt > 0; cnt--)  {
170.  
171.  			onum = rn2(nobj);
172.  			for(otmp = invent; onum != 0; onum--) otmp = otmp->nobj;
173.  			otmp->cursed++;
174.  		}
175.  		break;
176.  	}
177.  	return(0);
178.  }
179.  
180.  docast()
181.  {
182.  	register int	 spell, energy;
183.  	register boolean confused = (Confusion != 0);
184.  	register struct  obj	*pseudo;
185.  	struct	 obj	 *mksobj();
186.  
187.  	spell = getspell();
188.  	if (!spell) return(0);
189.  	else  {
190.  
191.  		energy = spellev(spell);
192.  		if(energy > u.uen)  {
193.  			pline("You are too weak to cast that spell.");
194.  			return(0);
195.  		} else  if ((u.uhunger <= 100) || (u.ustr < 6))  {
196.  			pline("You miss the strength for that spell.");
197.  			return(0);
198.  		} else	{
199.  			morehungry(energy * 10);
200.  			u.uen -= energy;
201.  		}
202.  	}
203.  #ifdef HARD
204.  	if ((rn2(10) + u.ulevel + u.uluck - spellev(spell)) < 0) {
205.  
206.  		pline("Fizzle.....");
207.  		return(0);
208.  	}
209.  #endif
210.  
211.  /*	pseudo is a temporary "false" object containing the spell stats. */
212.  	pseudo = mksobj(spellid(spell));
213.  	pseudo->quan = 20;			/* do not let useup get it */
214.  	switch(pseudo->otyp)  {
215.  
216.  /* These spells are all duplicates of wand effects */
217.  	case SPE_FORCE_BOLT:
218.  	case SPE_SLEEP:
219.  	case SPE_MAGIC_MISSILE:
220.  	case SPE_SLOW_MONSTER:
221.  	case SPE_FIREBALL:
222.  	case SPE_CONE_OF_COLD:
223.  	case SPE_DIG:
224.  	case SPE_TURN_UNDEAD:
225.  	case SPE_POLYMORPH:
226.  	case SPE_TELEPORT_AWAY:
227.  	case SPE_CANCELLATION:
228.  	case SPE_FINGER_OF_DEATH:
229.  	case SPE_LIGHT:
230.  	case SPE_DETECT_UNSEEN:
231.  		if (!(objects[pseudo->otyp].bits & NODIR))	getdir(1);
232.  		weffects(pseudo);
233.  		break;
234.  /* These are all duplicates of scroll effects */
235.  	case SPE_CONFUSE_MONSTER:
236.  	case SPE_DETECT_FOOD:
237.  	case SPE_CAUSE_FEAR:
238.  	case SPE_CHARM_MONSTER:
239.  	case SPE_REMOVE_CURSE:
240.  	case SPE_MAGIC_MAPPING:
241.  	case SPE_CREATE_MONSTER:
242.  	case SPE_IDENTIFY:
243.  	case SPE_GENOCIDE:
244.  		seffects(pseudo);
245.  		break;
246.  	case SPE_HASTE_SELF:
247.  	case SPE_DETECT_TREASURE:
248.  	case SPE_DETECT_MONSTERS:
249.  	case SPE_LEVITATION:
250.  	case SPE_RESTORE_STRENGTH:
251.  	case SPE_INVISIBILITY:
252.  		peffects(pseudo);
253.  		break;
254.  	case SPE_HEALING:
255.  		pline("You feel a bit better.");
256.  		healup(rnd(8), 1, 0, 0);
257.  		break;
258.  	case SPE_CURE_BLINDNESS:
259.  		healup(0, 0, 0, 1);
260.  		break;
261.  	case SPE_CURE_SICKNESS:
262.  		pline("You are no longer ill.");
263.  		healup(0, 0, 1, 0);
264.  		break;
265.  	case SPE_EXTRA_HEALING:
266.  		pline("You feel a fair bit better.");
267.  		healup(d(2,8), 1, 0, 0);
268.  		break;
269.  	case SPE_CREATE_FAMILIAR:
270.  		{	register struct monst *mtmp;
271.  			struct   monst  *makedog();
272.  
273.  			mtmp = makedog();
274.  			if(mtmp) {
275.  				/* make it into something else */
276.  				(void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
277.  				if(confused)
278.  					mtmp->mtame = mtmp->mpeaceful = 0;
279.  			}
280.  		}
281.  		break;
282.  	default:
283.  		impossible("Unknown spell %d attempted.", spell);
284.  		obfree(pseudo, (struct obj *)0);
285.  		return(0);
286.  	}
287.  	flags.botl = 1;
288.  	obfree(pseudo, (struct obj *)0);	/* now, get rid of it */
289.  	return(1);
290.  }
291.  
292.  getspell()  {
293.  
294.  	register int	max, ilet, i;
295.  	char	 lets[BUFSZ], buf[BUFSZ];
296.  
297.  	if (spl_book[0].sp_id == NO_SPELL)  {
298.  
299.  		pline("You don't know any spells right now.");
300.  		return(0);
301.  	} else  {
302.  
303.  	    for(max = 1; (max < MAXSPELL) && (spl_book[max].sp_id != NO_SPELL); max++);
304.  	    if (max >= MAXSPELL)  {
305.  
306.  		impossible("Too many spells memorized.");
307.  		return(0);
308.  	    }
309.  
310.  	    for(i = 0; (i < max) && (i < 26); buf[++i] = 0)  buf[i] = 'a' + i;
311.  	    for(i = 26; (i < max) && (i < 52); buf[++i] = 0) buf[i] = 'A' + i - 26;
312.  
313.  	    if (max == 1)  strcpy(lets, "a");
314.  	    else if (max < 27)  sprintf(lets, "a-%c", 'a' + max - 1);
315.  	    else if (max == 27)  sprintf(lets, "a-z A");
316.  	    else sprintf(lets, "a-z A-%c", 'A' + max - 27);
317.  	    for(;;)  {
318.  
319.  		pline("Cast which spell [%s ?]: ", lets);
320.  		if ((ilet = readchar()) == '?')  {
321.  			dovspell();
322.  			continue;
323.  		} else if ((ilet == '\033')||(ilet == '\n')||(ilet == ' '))
324.  			return(0);
325.  		else for(i = 0; buf[i] != 0; i++)  if(ilet == buf[i])  return(++i);
326.  		pline("You don't know that spell.");
327.  	    }
328.  	}
329.  }
330.  
331.  losespells() {
332.  	register boolean confused = (Confusion != 0);
333.  	register int	 n, nzap, i;
334.  
335.  	for(n = 0;(spl_book[n].sp_id != NO_SPELL) && (n < MAXSPELL); n++);
336.  	if (!n) return;
337.  	if (n < MAXSPELL) {
338.  		nzap = rnd(n);
339.  		if (nzap < n) nzap += confused;
340.  		for (i = 0; i < nzap; i++) spl_book[n-i-1].sp_id = NO_SPELL;
341.  	} else impossible("Too many spells in spellbook!");
342.  	return;
343.  }
344.  
345.  dovspell() {
346.  
347.  	register int max, i, side;
348.  	char     buf[BUFSZ],
349.  		 *spellname();
350.  
351.  	if (spl_book[0].sp_id == NO_SPELL)  {
352.  
353.  		pline("You don't know any spells right now.");
354.  		return(0);
355.  	} else  {
356.  
357.  	    for(max = 1; (max < MAXSPELL) && (spl_book[max].sp_id != NO_SPELL); max++);
358.  	    if (max >= MAXSPELL)  {
359.  
360.  		impossible("Too many spells memorized.");
361.  		return(0);
362.  	    }
363.  	}
364.  	set_pager(0);
365.  	side = (max + 1) / 2;
366.  	if(page_line("Currently known spells:") || page_line(""))  goto quit;
367.  
368.  	for(i = 1; i <= side; i++) {
369.  
370.  		if((i < side) || !(max % 2))  {
371.  
372.  		    (void) sprintf(buf, "%c - (%d) %22s          %c - (%d) %22s",
373.  				   spellet(i), spellev(i), spellname(i),
374.  				   spellet(i + side), spellev(i + side), spellname(i + side));
375.  		} else {
376.  
377.  		    (void) sprintf(buf, "%c - (%d) %22s", spellet(i), spellev(i), spellname(i));
378.  		}
379.  		if(page_line(buf)) goto quit;
380.  	}
381.  
382.  	set_pager(1);
383.  	return(0);
384.  quit:
385.  	set_pager(2);
386.  	return(0);
387.  }
388.  
389.  spellet(spl)  {
390.  
391.  	if (spl < 27)	return('a' + spl - 1);
392.  	else		return('A' + spl - 27);
393.  }
394.  
395.  spellev(spl)  {
396.  
397.  	return(spl_book[spl-1].sp_lev);
398.  }
399.  
400.  char *
401.  spellname(spl)  {
402.  
403.  	return(objects[spl_book[spl-1].sp_id].oc_name);
404.  }
405.  
406.  spellid(spl)  {
407.  
408.  	return(spl_book[spl-1].sp_id);
409.  }
410.  
411.  #endif /* SPELLS /**/