Source:NetHack 3.0.0/attrib.c
(Redirected from NetHack 3.0.0/attrib.c)
Jump to navigation
Jump to search
Below is the full text to attrib.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/attrib.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, 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. /* 2. * attrib.c - attribute modification routines. 3. * 4. * Copyright 1988, M. Stephenson 5. */ 6. /* NetHack may be freely redistributed. See license for details. */ 7. 8. #include "hack.h" 9. 10. const char *plusattr[] = { /* part of the output on gain of attribute */ 11. 12. "strong", "smart", "wise", "agile", "tough", "charismatic" 13. }; 14. 15. const char *minusattr[] = { /* part of the output on loss of attribute */ 16. 17. "weak", "stupid", "foolish", "clumsy", "vulnerable", "ugly" 18. }; 19. 20. struct attribs attrmax = { /* max values for the attributes */ 21. 22. 118, 18, 18, 18, 18, 18 23. }, 24. attrmin = { /* min values for the attributes */ 25. 26. 3, 3, 3, 3, 3, 3 27. }; 28. 29. const struct innate { 30. 31. schar ulevel; 32. long *ability; 33. char *gainstr, *losestr; 34. } a_abil[] = { { 0, &(Stealth), "", "" }, 35. { 0, &(Fast), "", "" }, 36. { 10, &(Searching), "perceptive", "" }, 37. { 0, 0, 0, 0 } }, 38. 39. b_abil[] = { { 0, &(HPoison_resistance), "", "" }, 40. { 7, &(Fast), "quick", "slow" }, 41. { 15, &(Stealth), "stealthy", "" }, 42. { 0, 0, 0, 0 } }, 43. 44. c_abil[] = { { 7, &(Fast), "quick", "slow" }, 45. { 15, &(Warning), "sensitive", "" }, 46. { 0, 0, 0, 0 } }, 47. 48. e_abil[] = { { 0, &(Fast), "", "" }, 49. { 0, &(HSee_invisible), "", "" }, 50. { 0, &(Searching), "", "" }, 51. { 0, &(HSleep_resistance), "", "" }, 52. { 0, 0, 0, 0 } }, 53. 54. h_abil[] = { { 0, &(HPoison_resistance), "", "" }, 55. { 15, &(Warning), "sensitive", "" }, 56. { 0, 0, 0, 0 } }, 57. 58. k_abil[] = { { 7, &(Fast), "quick", "slow" }, 59. { 0, 0, 0, 0 } }, 60. 61. p_abil[] = { { 15, &(Warning), "sensitive", "" }, 62. { 20, &(HFire_resistance), "cool", "warmer" }, 63. { 0, 0, 0, 0 } }, 64. 65. r_abil[] = { { 0, &(Stealth), "", "" }, 66. { 10, &(Searching), "perceptive", "" }, 67. { 0, 0, 0, 0 } }, 68. 69. s_abil[] = { { 0, &(Fast), "", "" }, 70. { 15, &(Stealth), "stealthy", "" }, 71. { 0, 0, 0, 0 } }, 72. 73. t_abil[] = { { 10, &(Searching), "perceptive", "" }, 74. { 20, &(HPoison_resistance), "hardy", "" }, 75. { 0, 0, 0, 0 } }, 76. 77. v_abil[] = { { 0, &(HCold_resistance), "", "" }, 78. { 0, &(Stealth), "", "" }, 79. { 7, &(Fast), "quick", "slow" }, 80. { 0, 0, 0, 0 } }, 81. 82. w_abil[] = { { 15, &(Warning), "sensitive", "" }, 83. { 17, &(HTeleport_control), "controlled","uncontrolled" }, 84. { 0, 0, 0, 0 } }; 85. 86. const struct clattr { 87. 88. struct attribs base, dist; 89. schar align, aligntyp; 90. schar shp, hd, xlev, ndx; 91. /* According to AD&D, HD for some classes (i.e. Wizard) should be smaller 92. * (4-sided for wizards). But this is not AD&D, and using the AD&D 93. * rule here produces an unplayable character. This I have used a minimum 94. * of an 10-sided hit die for everything. Another AD&D change: wizards get 95. * a minimum strength of 6 since without one you can't teleport or cast 96. * spells. --KAA 97. */ 98. struct innate *abil; 99. } a_attr = { { 6, 9, 9, 6, 6, 6 }, /* Archeologist */ 100. { 20, 20, 20, 10, 20, 10 }, 101. 10, 1, 13, 10, 14, 2, a_abil }, 102. 103. b_attr = { { 15, 6, 6, 14, 15, 5 }, /* Barbarian */ 104. { 30, 6, 7, 20, 30, 7 }, 105. 10, -1, 16, 12, 10, 3, b_abil }, 106. 107. c_attr = { { 9, 6, 6, 6, 7, 5 }, /* Caveman (fighter) */ 108. { 30, 6, 7, 20, 30, 7 }, 109. 0, 1, 16, 10, 10, 3, c_abil }, 110. 111. /* 112. e_attr = { { 13, 13, 14, 6, 14, 6 }, 113. */ 114. e_attr = { { 12, 12, 12, 8, 12, 6 }, /* Elf (ranger) */ 115. { 30, 10, 10, 20, 20, 10 }, 116. 10, 1, 15, 10, 11, 2, e_abil }, 117. 118. h_attr = { { 6, 6, 12, 6, 10, 15 }, /* Healer (druid) */ 119. { 15, 20, 20, 15, 25, 10 }, 120. 10, 1, 13, 10, 20, 2, h_abil }, 121. 122. k_attr = { { 12, 6, 13, 6, 9, 17 }, /* Knight (paladin) */ 123. { 20, 15, 15, 10, 20, 10 }, 124. 10, 1, 16, 10, 10, 3, k_abil }, 125. 126. p_attr = { { 6, 6, 9, 6, 6, 6 }, /* Priest (cleric) */ 127. { 15, 10, 30, 15, 20, 10 }, 128. 0, 0, 14, 10, 10, 2, p_abil }, 129. 130. r_attr = { { 6, 6, 6, 9, 6, 5 }, /* Rogue (thief) */ 131. { 20, 10, 10, 30, 20, 10 }, 132. 10, -1, 12, 10, 11, 2, r_abil }, 133. 134. s_attr = { { 9, 6, 6, 9, 17, 5 }, /* Samurai (fighter/thief) */ 135. { 30, 10, 10, 30, 14, 10 }, 136. 10, 1, 15, 10, 11, 2, s_abil }, 137. 138. t_attr = { { 6, 9, 5, 6, 6, 9 }, /* Tourist */ 139. { 15, 10, 10, 15, 30, 20 }, 140. 0, 0, 10, 10, 14, 1, t_abil }, 141. 142. v_attr = { { 9, 6, 6, 6, 9, 6 }, /* Valkyrie (fighter) */ 143. { 30, 6, 7, 20, 30, 7 }, 144. 0, -1, 16, 10, 10, 3, v_abil }, 145. 146. w_attr = { { 6, 9, 6, 6, 6, 6 }, /* Wizard (magic-user) */ 147. { 10, 30, 10, 20, 20, 10 }, 148. 0, 0, 12, 10, 12, 1, w_abil }, 149. 150. X_attr = { { 3, 3, 3, 3, 3, 3 }, 151. { 20, 15, 15, 15, 20, 15 }, 152. 0, 0, 12, 10, 14, 1, 0 }; 153. 154. void 155. adjattrib(ndx, incr, silent) 156. 157. int ndx, incr; 158. boolean silent; 159. { 160. if(!incr) return; 161. 162. if(incr > 0) { 163. if((AMAX(ndx) >= attrmax.a[ndx]) && (ACURR(ndx) == AMAX(ndx))) { 164. 165. if(!silent && flags.verbose) 166. pline("You're already as %s as you can get.", 167. plusattr[ndx]); 168. ABASE(ndx) = AMAX(ndx) = attrmax.a[ndx]; /* just in case */ 169. return; 170. } 171. 172. ABASE(ndx) += incr; 173. if(ABASE(ndx) > AMAX(ndx)) { 174. incr = ABASE(ndx) - AMAX(ndx); 175. AMAX(ndx) += incr; 176. if(AMAX(ndx) > attrmax.a[ndx]) 177. AMAX(ndx) = attrmax.a[ndx]; 178. ABASE(ndx) = AMAX(ndx); 179. } 180. } else { 181. if((AMAX(ndx) <= attrmin.a[ndx]) && (ABASE(ndx) == AMAX(ndx))) { 182. if(!silent && flags.verbose) 183. pline("You're already as %s as you can get.", 184. minusattr[ndx]); 185. ABASE(ndx) = AMAX(ndx) = attrmin.a[ndx]; /* just in case */ 186. return; 187. } 188. 189. ABASE(ndx) += incr; 190. if(ABASE(ndx) < attrmin.a[ndx]) { 191. incr = ABASE(ndx) - attrmin.a[ndx]; 192. ABASE(ndx) = attrmin.a[ndx]; 193. AMAX(ndx) += incr; 194. if(AMAX(ndx) < attrmin.a[ndx]) 195. AMAX(ndx) = attrmin.a[ndx]; 196. } 197. } 198. if(!silent) 199. You("feel %s%s!", 200. (incr > 1) ? "very ": "", 201. (incr > 0) ? plusattr[ndx] : minusattr[ndx]); 202. flags.botl = 1; 203. return; 204. } 205. 206. void 207. gainstr(otmp, incr) 208. register struct obj *otmp; 209. register int incr; 210. { 211. int num = 1; 212. 213. if(incr) num = incr; 214. else { 215. if(ABASE(A_STR) < 18) num = (rn2(4) ? 1 : rnd(6) ); 216. else if (ABASE(A_STR) < 103) num = rnd(10); 217. } 218. adjattrib(A_STR, (otmp && otmp->cursed) ? -num : num, TRUE); 219. } 220. 221. void 222. losestr(num) /* may kill you; cause may be poison or monster like 'a' */ 223. register int num; 224. { 225. int ustr = ABASE(A_STR) - num; 226. 227. while(ustr < 3) { 228. ustr++; 229. num--; 230. u.uhp -= 6; 231. u.uhpmax -= 6; 232. } 233. adjattrib(A_STR, -num, TRUE); 234. } 235. 236. void 237. change_luck(n) 238. register schar n; 239. { 240. u.uluck += n; 241. if (u.uluck < 0 && u.uluck < LUCKMIN) u.uluck = LUCKMIN; 242. if (u.uluck > 0 && u.uluck > LUCKMAX) u.uluck = LUCKMAX; 243. } 244. 245. int 246. stone_luck(parameter) 247. boolean parameter; /* So I can't think up of a good name. So sue me. --KAA */ 248. { 249. register struct obj *otmp; 250. register int bonchance = 0; 251. 252. for(otmp = invent; otmp; otmp=otmp->nobj) 253. if(otmp->otyp == LUCKSTONE) { 254. if (otmp->cursed) bonchance -= otmp->quan; 255. else if (otmp->blessed) bonchance += otmp->quan; 256. else if (parameter) bonchance += otmp->quan; 257. } 258. 259. return sgn(bonchance); 260. } 261. 262. void 263. restore_attrib() { 264. 265. int i; 266. 267. for(i = 0; i < A_MAX; i++) { /* all temporary losses/gains */ 268. 269. if(ATEMP(i) && ATIME(i)) { 270. if(!(--(ATIME(i)))) { /* countdown for change */ 271. ATEMP(i) += ATEMP(i) > 0 ? -1 : 1; 272. 273. if(ATEMP(i)) /* reset timer */ 274. ATIME(i) = 100 / ACURR(A_CON); 275. } 276. } 277. } 278. } 279. 280. static struct clattr * 281. clx() { 282. 283. register struct clattr *attr; 284. 285. switch (pl_character[0]) { 286. 287. case 'A': attr = &a_attr; 288. break; 289. case 'B': attr = &b_attr; 290. break; 291. case 'C': attr = &c_attr; 292. break; 293. case 'E': attr = &e_attr; 294. break; 295. case 'H': attr = &h_attr; 296. break; 297. case 'K': attr = &k_attr; 298. break; 299. case 'P': attr = &p_attr; 300. break; 301. case 'R': attr = &r_attr; 302. break; 303. case 'S': attr = &s_attr; 304. break; 305. case 'T': attr = &t_attr; 306. break; 307. case 'V': attr = &v_attr; 308. break; 309. case 'W': attr = &w_attr; 310. break; 311. default: /* unknown type */ 312. attr = &X_attr; 313. break; 314. } 315. return(attr); 316. } 317. 318. static void 319. init_align() { /* called from newhp if u.ulevel is 0 */ 320. 321. register struct clattr *attr = clx(); 322. 323. u.ualign = (int)attr->align; 324. u.ualigntyp = attr->aligntyp; 325. } 326. 327. void 328. init_attr(np) 329. register int np; 330. { 331. register int i, x, tryct; 332. register struct clattr *attr = clx(); 333. 334. for(i = 0; i < A_MAX; i++) { 335. 336. ABASE(i) = AMAX(i) = attr->base.a[i]; 337. ATEMP(i) = ATIME(i) = 0; 338. np -= attr->base.a[i]; 339. } 340. 341. tryct = 0; 342. while(np > 0 && tryct < 100) { 343. 344. x = rn2(100); 345. for(i = 0; (i < A_MAX) && ((x -= attr->dist.a[i]) > 0); i++); 346. if(i >= A_MAX) continue; /* impossible */ 347. 348. if(ABASE(i) >= attrmax.a[i]) { 349. 350. tryct++; 351. continue; 352. } 353. tryct = 0; 354. ABASE(i)++; 355. AMAX(i)++; 356. np--; 357. } 358. 359. tryct = 0; 360. while(np < 0 && tryct < 100) { /* for redistribution */ 361. 362. x = rn2(100); 363. for(i = 0; (i < A_MAX) && ((x -= attr->dist.a[i]) > 0); i++); 364. if(i >= A_MAX) continue; /* impossible */ 365. 366. if(ABASE(i) <= attrmin.a[i]) { 367. 368. tryct++; 369. continue; 370. } 371. tryct = 0; 372. ABASE(i)--; 373. AMAX(i)--; 374. np++; 375. } 376. } 377. 378. #ifdef POLYSELF 379. void 380. redist_attr() { 381. 382. register int i, tmp; 383. 384. for(i = 0; i < A_MAX; i++) { 385. if (i==A_INT || i==A_WIS) continue; 386. /* Polymorphing doesn't change your mind */ 387. tmp = AMAX(i); 388. AMAX(i) += (rn2(5)-2); 389. if (AMAX(i) > attrmax.a[i]) AMAX(i) = attrmax.a[i]; 390. if (AMAX(i) < attrmin.a[i]) AMAX(i) = attrmin.a[i]; 391. ABASE(i) = ABASE(i) * AMAX(i) / tmp; 392. /* ABASE(i) > attrmax.a[i] is impossible */ 393. if (ABASE(i) < attrmin.a[i]) ABASE(i) = attrmin.a[i]; 394. } 395. } 396. #endif 397. 398. void 399. adjabil(flag) 400. 401. int flag; /* +ve/-ve = gain/lose */ 402. { 403. register struct clattr *attr = clx(); 404. register struct innate *abil = attr->abil; 405. 406. if(abil) { 407. 408. for(; abil->ability; abil++) { 409. if ((flag>0 && u.ulevel >= abil->ulevel) || 410. (flag<0 && u.ulevel < abil->ulevel)) { 411. if(flag > 0) { 412. if(!(*(abil->ability) & INTRINSIC)) { 413. *(abil->ability) |= INTRINSIC; 414. if(strlen(abil->gainstr)) 415. You("feel %s!", abil->gainstr); 416. } 417. } else { 418. if((*(abil->ability) & INTRINSIC)) { 419. *(abil->ability) &= ~INTRINSIC; 420. if(strlen(abil->losestr)) 421. You("feel %s!", abil->losestr); 422. else if(strlen(abil->gainstr)) 423. You("feel less %s!", abil->gainstr); 424. } 425. } 426. } 427. } 428. } 429. } 430. 431. int 432. newhp() { 433. register struct clattr *attr = clx(); 434. int hp, conplus; 435. 436. if(u.ulevel == 0) { 437. 438. hp = attr->shp; 439. init_align(); /* initialize alignment stuff */ 440. return hp; 441. } else { 442. 443. if(u.ulevel < attr->xlev) 444. hp = rnd(attr->hd); 445. else 446. hp = attr->ndx; 447. } 448. 449. switch(ACURR(A_CON)) { 450. case 3: conplus = -2; break; 451. case 4: 452. case 5: 453. case 6: conplus = -1; break; 454. case 15: 455. case 16: conplus = 1; break; 456. case 17: conplus = 2; break; 457. case 18: conplus = 3; break; 458. default: conplus = 0; 459. } 460. hp += conplus; 461. return((hp <= 0) ? 1 : hp); 462. } 463. 464. schar 465. acurr(x) { 466. register int tmp = (u.abon.a[x] + u.atemp.a[x] + u.acurr.a[x]); 467. 468. if (x == A_STR) { 469. if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER) return(125); 470. else return((tmp >= 125) ? 125 : (tmp <= 3) ? 3 : tmp); 471. } 472. else return((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp); 473. } 474. 475. /* avoid possible problems with alignment overflow, and provide a centralized 476. * location for any future alignment limits 477. */ 478. void 479. adjalign(n) 480. register int n; 481. { 482. register int newalign = u.ualign + n; 483. 484. if(n < 0) { 485. if(newalign < u.ualign) 486. u.ualign = newalign; 487. } else 488. if(newalign > u.ualign) 489. u.ualign = newalign; 490. }