Source:NetHack 3.0.0/artifact.c
Jump to navigation
Jump to search
Below is the full text to artifact.c from the source code of NetHack 3.0.0.
Warning! This is the source code from an old release. For newer releases, see 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: @(#)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 */