Source:NetHack 3.0.0/artifact.c

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

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

1.   /*	SCCS Id: @(#)artifact.c	3.0	88/07/27 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6. 7.   #ifdef NAMED_ITEMS 8.    9.    #include "artifact.h"  10. 11.  /* the artifacts (currently weapons only) */ 12.  static const struct artifact artilist[] = { 13.   14.   #define	    NO_ATTK	0, 0, 0, 0 15.   16.   { LONG_SWORD,	 "Excalibur",	(SPFX_NOGEN | SPFX_SEEK | SPFX_DEFN |  17.   								SPFX_SEARCH), 0, 18.    { 0, AD_PHYS, 5, 10 }, { 0, AD_DRLI, 0, 0} }, 19.   20.   { KATANA,	 "Snickersnee",	SPFX_RESTR, 0, 21.    { 0, AD_PHYS, 0, 8 }, NO_ATTK }, 22.   23.   /*	Ah, never shall I forget the cry, 24.   *		or the shriek that shrieked he, 25.   *	As I gnashed my teeth, and from my sheath 26.   *		I drew my Snickersnee! 27.   *  28.    *		--Koko, Lord high executioner of Titipu 29.   *		  (From Sir W.S. Gilbert's "The Mikado") 30.   */  31.    32.   { AXE,		 "Cleaver",	SPFX_RESTR, 0, 33.    { 0, AD_PHYS, 3, 12 }, NO_ATTK }, 34.   35.   /*  Special purpose swords - various types */ 36.   37.   { TWO_HANDED_SWORD, "Orcrist",	SPFX_DCLAS, S_ORC, 38.    { 0, AD_PHYS, 5, 0 }, NO_ATTK }, 39.   40.   #ifdef TOLKIEN 41.  { ELVEN_DAGGER,	 "Sting",	(SPFX_WARN | SPFX_DCLAS), S_ORC, 42.    { 0, AD_PHYS, 5, 0 }, NO_ATTK }, 43.  #else 44.  { DAGGER,	 "Sting",	(SPFX_WARN | SPFX_DCLAS), S_ORC, 45.    { 0, AD_PHYS, 5, 0 }, NO_ATTK }, 46.  #endif 47.   48.   { LONG_SWORD,	 "Frost Brand", (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0, 49.    { 0, AD_COLD, 5, 0 }, { 0, AD_COLD, 0, 0 } }, 50.   51.   { LONG_SWORD,	 "Fire Brand",	(SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0, 52.    { 0, AD_FIRE, 5, 0 }, { 0, AD_FIRE, 0, 0 } }, 53.   54.   /* Stormbringer only has a 2 because it can drain a level, providing 8 more */ 55.  { BROADSWORD,	 "Stormbringer", (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN |  56.   								SPFX_DRLI), 0, 57.    { 0, AD_DRLI, 5, 2 }, { 0, AD_DRLI, 0, 0 } }, 58.   59.   { LONG_SWORD,	 "Sunsword",	(SPFX_RESTR | SPFX_DCLAS), 0, /* undead */ 60.    { 0, AD_PHYS, 5, 0 }, NO_ATTK }, 61.   62.   { BROADSWORD,	 "Dragonbane",	(SPFX_RESTR | SPFX_DCLAS), S_DRAGON, 63.    { 0, AD_PHYS, 5, 0 }, NO_ATTK }, 64.   65.   { LONG_SWORD,	 "Demonbane",	(SPFX_RESTR | SPFX_DCLAS), 0, /* demons */ 66.    { 0, AD_PHYS, 5, 0 }, NO_ATTK }, 67.   68.   { LONG_SWORD,	 "Werebane",	(SPFX_RESTR | SPFX_DCLAS), 0, /* weres */ 69.    { 0, AD_PHYS, 5, 0 }, NO_ATTK }, 70.   71.   { LONG_SWORD,	 "Giantslayer", (SPFX_RESTR | SPFX_DCLAS), 0, /* giants */ 72.    { 0, AD_PHYS, 5, 0 }, NO_ATTK }, 73.   74.   { LUCERN_HAMMER, "Ogresmasher",	(SPFX_RESTR | SPFX_DCLAS),  S_OGRE, 75.    { 0, AD_PHYS, 5, 0 }, NO_ATTK }, 76.   77.   { LUCERN_HAMMER, "Thunderfist",	(SPFX_RESTR | SPFX_ATTK),  0, 78.    { 0, AD_ELEC, 5, 24 }, NO_ATTK }, 79.   80.   { MORNING_STAR,	 "Trollsbane", (SPFX_RESTR | SPFX_DCLAS), S_TROLL, 81.    { 0, AD_PHYS, 5, 0 }, NO_ATTK }, 82.   83.   /*	ARRAY TERMINATOR	*/ 84.  { 0,  "", 0, 0, NO_ATTK, NO_ATTK } 85.  };  86.    87.   void 88.  mkartifact(otmp1) 89.  struct obj **otmp1; 90.  {  91.   	register struct artifact *artif; 92.  	register struct obj *otmp = *otmp1; 93.  	register int n = 0; 94.   95.   	for(artif = artilist; artif->otyp; artif++) 96.  	    if(otmp->otyp == artif->otyp && !(artif->spfx & SPFX_NOGEN)) n++; 97.   98.   	if (n) { 99.  		n = rnd(n); 100. 		for(artif = artilist; artif->otyp && n > 0; ) { 101. 		    if(otmp->otyp == artif->otyp && !(artif->spfx & SPFX_NOGEN)) n--; 102. 		    if (n>0) artif++; 103. 		}  104.   105.  		if(artif->otyp) *otmp1 = oname(otmp, artif->name, 0); 106. 	}  107.  }  108.   109.  static struct artifact * 110. get_artifact(otmp) 111. struct obj *otmp; 112. {  113.  	register struct artifact *artif; 114.  115.  	if(otmp) 116. 	    if(strlen(ONAME(otmp))) 117. 		for(artif = artilist; artif->otyp; artif++) 118. 		    if(artif->otyp == otmp->otyp &&  119.  		       !strcmp(ONAME(otmp), artif->name)) return(artif); 120. 	return((struct artifact *)0); 121. }  122.   123.  boolean 124. is_artifact(otmp) 125. struct obj *otmp; 126. {  127.  	return(get_artifact(otmp) != (struct artifact *)0); 128. }  129.   130.  boolean 131. spec_ability(otmp, abil) 132. struct obj *otmp; 133. unsigned abil; 134. {  135.  	struct artifact *arti = get_artifact(otmp); 136. 	  137.  	return(arti && (arti->spfx & abil)); 138. }  139.   140.  int 141. restr_name(otmp, name)	/* returns 1 if name is restricted for otmp->otyp */ 142. register struct obj *otmp; 143. register char	*name; 144. {  145.  	register struct artifact *artif; 146.  147.  	if(!strlen(name)) return(0); 148.  149.  	for(artif = artilist; artif->otyp; artif++) 150. 	    if(artif->otyp == otmp->otyp) 151. 		if(artif->spfx & (SPFX_NOGEN | SPFX_RESTR)) 152. 		    if(!strcmp(artif->name, name)) return(1); 153.  154.  	return(0); 155. }  156.   157.  # if defined(THEOLOGY) && defined(ALTARS) 158. struct obj * 159. mk_aligned_artifact(align) 160. int align; 161. {  162.  	register struct artifact *artif; 163. 	register struct obj *otmp; 164. 	register int n = 0; 165.  166.  	for(artif = artilist; artif->otyp; artif++) 167. 	    if(align == artif->align && !(artif->spfx & SPFX_NOGEN)) n++; 168. 	if (n) { 169. 		n = rnd(n); 170. 		for(artif = artilist; artif->otyp && n > 0; ) { 171. 		    if(align == artif->align && !(artif->spfx & SPFX_NOGEN)) 172. 			n--; 173. 		    if (n > 0) artif++; 174. 		}  175.  		if(artif->otyp) { 176. 			otmp = mksobj((int)artif->otyp, FALSE); 177. 			otmp = oname(otmp, artif->name, 0); 178. 			return (otmp); 179. 		}  180.  	}  181.  	return ((struct obj *) 0); 182. }  183.  # endif 184.  185.  int 186. defends(adtyp, otmp) 187. register int adtyp; 188. register struct obj *otmp; 189. {  190.  	register struct artifact *weap; 191.  192.  	if(weap = get_artifact(otmp)) 193. 		return(weap->defn.adtyp == adtyp); 194. 	return(0); 195. }  196.   197.  static int 198. spec_applies(weap, ptr) 199. register struct artifact *weap; 200. struct permonst *ptr; 201. {  202.  	if(!(weap->spfx & (SPFX_DMONS | SPFX_DCLAS | SPFX_ATTK))) 203. 	    return(1); 204.  205.  	if(weap->spfx & SPFX_DMONS) 206. 	    return((ptr == &mons[weap->mtype])); 207. 	else if(weap->spfx & SPFX_DCLAS) { 208.  209.  	    if(weap->mtype) 210. 		return((weap->mtype == ptr->mlet)); 211. 	    else { 212. 		if(!strcmp(weap->name, "Sunsword")) 213. 		    return(is_undead(ptr)); 214. 		else if(!strcmp(weap->name, "Demonbane")) 215. 		    return(is_demon(ptr)); 216. 		else if(!strcmp(weap->name, "Werebane")) 217. 		    return(is_were(ptr)); 218. 		else if(!strcmp(weap->name, "Giantslayer")) 219. 		    return(is_giant(ptr)); 220. 		else impossible("Weird class specific weapon '%s'",  221.  				weap->name); 222. 	    }  223.  	} else if(weap->spfx & SPFX_ATTK) { 224. 	    switch(weap->attk.adtyp) { 225. 		case AD_FIRE:	return(!resists_fire(ptr)); 226. 		case AD_COLD:	return(!resists_cold(ptr)); 227. 		case AD_ELEC:	return(!resists_elec(ptr)); 228. 		case AD_DRLI:	return(!resists_drli(ptr)); 229. 		case AD_STON:	return(!resists_ston(ptr)); 230. 		default:	impossible("Weird special attack for '%s'",  231.  					   weap->name); 232. 	    }  233.  	}  234.  	return(0); 235. }  236.   237.  int 238. spec_abon(otmp, ptr) 239. struct obj *otmp; 240. struct permonst *ptr; 241. {  242.  	register struct artifact *weap; 243.  244.  	if((weap = get_artifact(otmp))) 245. 		if(spec_applies(weap, ptr)) 246. 		    return((weap->attk.damn) ? rnd((int)weap->attk.damn) : 0); 247. 	return(0); 248. }  249.   250.  int 251. spec_dbon(otmp, ptr, tmp) 252. register struct obj *otmp; 253. register struct permonst *ptr; 254. register int	tmp; 255. {  256.  	register struct artifact *weap; 257.  258.  	if((weap = get_artifact(otmp))) 259. 		if(spec_applies(weap, ptr)) 260. 		    return((weap->attk.damd) ? rnd((int)weap->attk.damd) : tmp); 261. 	return(0); 262. }  263.  #endif /* NAMED_ITEMS */