abstract
| - Below is the full text to hack.fight.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/hack.fight.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ 2. 3. #include "hack.h" 4. extern struct permonst li_dog, dog, la_dog; 5. extern char *exclam(), *xname(); 6. 7. static boolean far_noise; 8. static long noisetime; 9. 10. /* hitmm returns 0 (miss), 1 (hit), or 2 (kill) */ 11. hitmm(magr,mdef) register struct monst *magr,*mdef; { 12. register struct permonst *pa = magr->data, *pd = mdef->data; 13. int hit; 14. schar tmp; 15. boolean vis; 16. if(index("Eauy", pa->mlet)) return(0); 17. tmp = pd->ac + pa->mlevel; 18. if(mdef->mconf || mdef->mfroz || mdef->msleep){ 19. tmp += 4; 20. if(mdef->msleep) mdef->msleep = 0; 21. } 22. hit = (tmp > rnd(20)); 23. if(hit) mdef->msleep = 0; 24. vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my)); 25. if(vis){ 26. char buf[BUFSZ]; 27. if(mdef->mimic) seemimic(mdef); 28. if(magr->mimic) seemimic(magr); 29. (void) sprintf(buf,"%s %s", Monnam(magr), 30. hit ? "hits" : "misses"); 31. pline("%s %s.", buf, monnam(mdef)); 32. } else { 33. boolean far = (dist(magr->mx, magr->my) > 15); 34. if(far != far_noise || moves-noisetime > 10) { 35. far_noise = far; 36. noisetime = moves; 37. pline("You hear some noises%s.", 38. far ? " in the distance" : ""); 39. } 40. } 41. if(hit){ 42. if(magr->data->mlet == 'c' && !magr->cham) { 43. magr->orig_hp += 3; 44. if(vis) pline("%s is turned to stone!", Monnam(mdef)); 45. else if(mdef->mtame) 46. pline("You have a peculiarly sad feeling for a moment, then it passes."); 47. monstone(mdef); 48. hit = 2; 49. } else 50. if((mdef->mhp -= d(pa->damn,pa->damd)) < 1) { 51. magr->orig_hp += 1 + rn2(pd->mlevel+1); 52. if(magr->mtame && magr->orig_hp > 8*pa->mlevel){ 53. if(pa == &li_dog) magr->data = pa = &dog; 54. else if(pa == &dog) magr->data = pa = &la_dog; 55. } 56. if(vis) pline("%s is killed!", Monnam(mdef)); 57. else if(mdef->mtame) 58. pline("You have a sad feeling for a moment, then it passes."); 59. mondied(mdef); 60. hit = 2; 61. } 62. } 63. return(hit); 64. } 65. 66. /* drop (perhaps) a cadaver and remove monster */ 67. mondied(mdef) register struct monst *mdef; { 68. register struct permonst *pd = mdef->data; 69. if(letter(pd->mlet) && rn2(3)){ 70. mksobj_at(pd->mlet,CORPSE,mdef->mx,mdef->my); 71. if(cansee(mdef->mx,mdef->my)){ 72. unpmon(mdef); 73. atl(mdef->mx,mdef->my,fobj->olet); 74. } 75. stackobj(fobj); 76. } 77. mondead(mdef); 78. } 79. 80. /* drop a rock and remove monster */ 81. monstone(mdef) register struct monst *mdef; { 82. extern char mlarge[]; 83. if(index(mlarge, mdef->data->mlet)) 84. mksobj_at(ROCK_SYM, ENORMOUS_ROCK, mdef->mx, mdef->my); 85. else 86. mksobj_at(WEAPON_SYM, ROCK, mdef->mx, mdef->my); 87. if(cansee(mdef->mx, mdef->my)){ 88. unpmon(mdef); 89. atl(mdef->mx,mdef->my,fobj->olet); 90. } 91. mondead(mdef); 92. } 93. 94. 95. fightm(mtmp) register struct monst *mtmp; { 96. register struct monst *mon; 97. for(mon = fmon; mon; mon = mon->nmon) if(mon != mtmp) { 98. if(DIST(mon->mx,mon->my,mtmp->mx,mtmp->my) < 3) 99. if(rn2(4)) 100. return(hitmm(mtmp,mon)); 101. } 102. return(-1); 103. } 104. 105. hitu(mtmp,dam) 106. register struct monst *mtmp; 107. register dam; 108. { 109. register tmp; 110. 111. if(mtmp->mhide && mtmp->mundetected) { 112. mtmp->mundetected = 0; 113. if(!Blind) { 114. register struct obj *obj; 115. extern char * Xmonnam(); 116. if(obj = o_at(mtmp->mx,mtmp->my)) 117. pline("%s was hidden under %s!", 118. Xmonnam(mtmp), doname(obj)); 119. } 120. } 121. 122. tmp = u.uac; 123. /* give people with Ac = -10 at least some vulnerability */ 124. if(tmp < 0) { 125. dam += tmp; /* decrease damage */ 126. if(dam <= 0) dam = 1; 127. tmp = -rn2(-tmp); 128. } 129. tmp += mtmp->data->mlevel; 130. if(multi < 0) tmp += 4; 131. if(Invis || !mtmp->mcansee) tmp -= 2; 132. if(mtmp->mtrapped) tmp -= 2; 133. if(tmp <= rnd(20)) { 134. if(Blind) pline("It misses."); 135. else pline("%s misses.",Monnam(mtmp)); 136. return(0); 137. } 138. if(Blind) pline("It hits!"); 139. else pline("%s hits!",Monnam(mtmp)); 140. losehp_m(dam, mtmp); 141. return(1); 142. } 143. 144. /* u is hit by sth, but not a monster */ 145. thitu(tlev,dam,name) 146. register tlev,dam; 147. register char *name; 148. { 149. char buf[BUFSZ]; 150. setan(name,buf); 151. if(u.uac + tlev <= rnd(20)) { 152. if(Blind) pline("It misses."); 153. else pline("You are almost hit by %s!", buf); 154. return(0); 155. } else { 156. if(Blind) pline("You are hit!"); 157. else pline("You are hit by %s!", buf); 158. losehp(dam,name); 159. return(1); 160. } 161. } 162. 163. char mlarge[] = "bCDdegIlmnoPSsTUwY~,&"; 164. 165. boolean 166. hmon(mon,obj,thrown) /* return TRUE if mon still alive */ 167. register struct monst *mon; 168. register struct obj *obj; 169. register thrown; 170. { 171. register tmp; 172. 173. if(!obj){ 174. tmp = rnd(2); /* attack with bare hands */ 175. if(mon->data->mlet == 'c' && !uarmg){ 176. pline("You hit the cockatrice with your bare hands"); 177. pline("You turn to stone ..."); 178. done_in_by(mon); 179. } 180. } else if(obj->olet == WEAPON_SYM) { 181. if(obj == uwep && (obj->otyp > SPEAR || obj->otyp < BOOMERANG)) 182. tmp = rnd(2); 183. else { 184. if(index(mlarge, mon->data->mlet)) { 185. tmp = rnd(objects[obj->otyp].wldam); 186. if(obj->otyp == TWO_HANDED_SWORD) tmp += d(2,6); 187. else if(obj->otyp == FLAIL) tmp += rnd(4); 188. } else { 189. tmp = rnd(objects[obj->otyp].wsdam); 190. } 191. tmp += obj->spe; 192. if(!thrown && obj == uwep && obj->otyp == BOOMERANG 193. && !rn2(3)){ 194. pline("As you hit %s, the boomerang breaks into splinters.", 195. monnam(mon)); 196. freeinv(obj); 197. setworn((struct obj *) 0, obj->owornmask); 198. obfree(obj, (struct obj *) 0); 199. tmp++; 200. } 201. } 202. if(mon->data->mlet == 'O' && !strcmp(ONAME(obj), "Orcrist")) 203. tmp += rnd(10); 204. } else switch(obj->otyp) { 205. case HEAVY_IRON_BALL: 206. tmp = rnd(25); break; 207. case EXPENSIVE_CAMERA: 208. pline("You succeed in destroying your camera. Congratulations!"); 209. freeinv(obj); 210. if(obj->owornmask) 211. setworn((struct obj *) 0, obj->owornmask); 212. obfree(obj, (struct obj *) 0); 213. return(TRUE); 214. case DEAD_COCKATRICE: 215. pline("You hit %s with the cockatrice corpse", 216. monnam(mon)); 217. pline("%s is turned to stone!", Monnam(mon)); 218. killed(mon); 219. return(FALSE); 220. case CLOVE_OF_GARLIC: 221. if(index(" VWZ", mon->data->mlet)) 222. mon->mflee = 1; 223. tmp = 1; 224. break; 225. default: 226. /* non-weapons can damage because of their weight */ 227. /* (but not too much) */ 228. tmp = obj->owt/10; 229. if(tmp < 1) tmp = 1; 230. else tmp = rnd(tmp); 231. if(tmp > 6) tmp = 6; 232. } 233. 234. /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) */ 235. 236. tmp += u.udaminc + dbon(); 237. if(u.uswallow) 238. if(mon->data->mlet == 'P') { 239. if((tmp -= u.uswldtim) <= 0) { 240. pline("Your arms are no longer able to hit."); 241. return(TRUE); 242. } 243. } 244. if(tmp < 1) tmp = 1; 245. mon->mhp -= tmp; 246. if(mon->mhp < 1) { 247. killed(mon); 248. return(FALSE); 249. } 250. 251. if(thrown) { /* this assumes that we cannot throw plural things */ 252. hit( xname(obj) /* or: objects[obj->otyp].oc_name */, 253. mon, exclam(tmp) ); 254. return(TRUE); 255. } 256. if(Blind) pline("You hit it."); 257. else pline("You hit %s%s", monnam(mon), exclam(tmp)); 258. 259. if(u.umconf) { 260. if(!Blind) { 261. pline("Your hands stop glowing blue."); 262. if(!mon->mfroz && !mon->msleep) 263. pline("%s appears confused.",Monnam(mon)); 264. } 265. mon->mconf = 1; 266. u.umconf = 0; 267. } 268. return(TRUE); /* mon still alive */ 269. }
|