abstract
| - Below is the full text to worm.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/worm.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)worm.c 3.0 88/11/11 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 WORM 8. #include "wseg.h" 9. 10. struct wseg *wsegs[32] = DUMMY, *wheads[32] = DUMMY, *m_atseg = 0; 11. long wgrowtime[32] = DUMMY; 12. 13. int 14. getwn(mtmp) 15. struct monst *mtmp; 16. { 17. register int tmp; 18. 19. for(tmp = 1; tmp < 32; tmp++) 20. if(!wsegs[tmp]) { 21. mtmp->wormno = tmp; 22. return(1); 23. } 24. return(0); /* level infested with worms */ 25. } 26. 27. /* called to initialize a worm unless cut in half */ 28. void 29. initworm(mtmp) 30. struct monst *mtmp; 31. { 32. register struct wseg *wtmp; 33. register int tmp = mtmp->wormno; 34. 35. if(!tmp) return; 36. wheads[tmp] = wsegs[tmp] = wtmp = newseg(); 37. wgrowtime[tmp] = 0; 38. wtmp->wx = mtmp->mx; 39. wtmp->wy = mtmp->my; 40. /* wtmp->wdispl = 0; */ 41. wtmp->nseg = 0; 42. } 43. 44. static void 45. remseg(mtmp,wtmp) 46. struct monst *mtmp; 47. register struct wseg *wtmp; 48. { 49. if (mtmp->mx != wtmp->wx || mtmp->my != wtmp->wy) 50. levl[wtmp->wx][wtmp->wy].mmask = 0; 51. if(wtmp->wdispl) newsym(wtmp->wx, wtmp->wy); 52. free((genericptr_t) wtmp); 53. } 54. 55. void 56. worm_move(mtmp) 57. struct monst *mtmp; 58. { 59. register struct wseg *wtmp, *whd; 60. register int tmp = mtmp->wormno; 61. 62. wtmp = newseg(); 63. wtmp->wx = mtmp->mx; 64. wtmp->wy = mtmp->my; 65. wtmp->nseg = 0; 66. /* wtmp->wdispl = 0; */ 67. (whd = wheads[tmp])->nseg = wtmp; 68. wheads[tmp] = wtmp; 69. if(cansee(whd->wx,whd->wy)){ 70. unpmon(mtmp); 71. atl(whd->wx, whd->wy, S_WORM_TAIL); 72. whd->wdispl = 1; 73. } else whd->wdispl = 0; 74. if(wgrowtime[tmp] <= moves) { 75. if(!wgrowtime[tmp]) wgrowtime[tmp] = moves + rnd(5); 76. else wgrowtime[tmp] += 2+rnd(15); 77. mtmp->mhp += 3; 78. if (mtmp->mhp > MHPMAX) mtmp->mhp = MHPMAX; 79. if (mtmp->mhp > mtmp->mhpmax) mtmp->mhpmax = mtmp->mhp; 80. return; 81. } 82. whd = wsegs[tmp]; 83. wsegs[tmp] = whd->nseg; 84. remseg(mtmp, whd); 85. } 86. 87. void 88. worm_nomove(mtmp) 89. register struct monst *mtmp; 90. { 91. register int tmp; 92. register struct wseg *wtmp; 93. 94. tmp = mtmp->wormno; 95. wtmp = wsegs[tmp]; 96. if(wtmp == wheads[tmp]) return; 97. if(wtmp == 0 || wtmp->nseg == 0) panic("worm_nomove?"); 98. wsegs[tmp] = wtmp->nseg; 99. remseg(mtmp, wtmp); 100. if (mtmp->mhp > 3) mtmp->mhp -= 3; /* mhpmax not changed ! */ 101. else mtmp->mhp = 1; 102. } 103. 104. void 105. wormdead(mtmp) 106. register struct monst *mtmp; 107. { 108. register int tmp = mtmp->wormno; 109. register struct wseg *wtmp, *wtmp2; 110. 111. if(!tmp) return; 112. mtmp->wormno = 0; 113. for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2) { 114. wtmp2 = wtmp->nseg; 115. remseg(mtmp, wtmp); 116. } 117. wsegs[tmp] = 0; 118. } 119. 120. void 121. wormhit(mtmp) 122. register struct monst *mtmp; 123. { 124. register int tmp = mtmp->wormno; 125. register struct wseg *wtmp; 126. 127. if(!tmp) return; /* worm without tail */ 128. for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg) 129. if (dist(wtmp->wx, wtmp->wy) < 3) (void) mattacku(mtmp); 130. } 131. 132. void 133. wormsee(tmp) 134. register unsigned int tmp; 135. { 136. register struct wseg *wtmp = wsegs[tmp]; 137. 138. if(!wtmp) panic("wormsee: wtmp==0"); 139. 140. for(; wtmp->nseg; wtmp = wtmp->nseg) 141. if(!cansee(wtmp->wx,wtmp->wy) && wtmp->wdispl) { 142. newsym(wtmp->wx, wtmp->wy); 143. wtmp->wdispl = 0; 144. } 145. } 146. 147. void 148. cutworm(mtmp, x, y, weptyp) 149. register struct monst *mtmp; 150. register xchar x,y; 151. register unsigned weptyp; /* uwep->otyp or 0 */ 152. { 153. register struct wseg *wtmp, *wtmp2; 154. register struct monst *mtmp2; 155. register int tmp, tmp2; 156. 157. if(mtmp->mx == x && mtmp->my == y) return; /* hit headon */ 158. 159. /* cutting goes best with axe or sword */ 160. tmp = rnd(20); 161. if(weptyp >= SHORT_SWORD && weptyp <= KATANA || 162. weptyp == AXE) 163. tmp += 5; 164. 165. if(tmp < 12) return; 166. 167. /* if tail then worm just loses a tail segment */ 168. tmp = mtmp->wormno; 169. wtmp = wsegs[tmp]; 170. if(wtmp->wx == x && wtmp->wy == y){ 171. wsegs[tmp] = wtmp->nseg; 172. remseg(mtmp, wtmp); 173. return; 174. } 175. 176. /* cut the worm in two halves */ 177. mtmp2 = newmonst(0); 178. *mtmp2 = *mtmp; 179. mtmp2->mxlth = mtmp2->mnamelth = 0; 180. 181. /* sometimes the tail end dies */ 182. if(rn2(3) || !getwn(mtmp2)){ 183. monfree(mtmp2); 184. levl[mtmp2->mx][mtmp2->my].mmask = 1; 185. /* since mtmp is still on that spot */ 186. tmp2 = 0; 187. } else { 188. tmp2 = mtmp2->wormno; 189. wsegs[tmp2] = wsegs[tmp]; 190. wgrowtime[tmp2] = 0; 191. } 192. do { 193. if(wtmp->nseg->wx == x && wtmp->nseg->wy == y){ 194. if(tmp2) wheads[tmp2] = wtmp; 195. wsegs[tmp] = wtmp->nseg->nseg; 196. remseg(mtmp, wtmp->nseg); 197. wtmp->nseg = 0; 198. if(tmp2) { 199. You("cut the worm in half."); 200. /* devalue the monster level of both halves of the worm */ 201. mtmp->m_lev = (mtmp->m_lev <= 2) ? 2 : mtmp->m_lev - 2; 202. mtmp2->m_lev = mtmp->m_lev; 203. /* calculate the mhp on the new (lower) monster level */ 204. mtmp2->mhpmax = mtmp2->mhp = d((int)mtmp2->m_lev, 8); 205. mtmp2->mx = wtmp->wx; 206. mtmp2->my = wtmp->wy; 207. levl[mtmp2->mx][mtmp2->my].mmask = 1; 208. mtmp2->nmon = fmon; 209. fmon = mtmp2; 210. mtmp2->mdispl = 0; 211. pmon(mtmp2); 212. } else { 213. You("cut off part of the worm's tail."); 214. remseg(mtmp, wtmp); 215. } 216. mtmp->mhp /= 2; 217. return; 218. } 219. wtmp2 = wtmp->nseg; 220. if(!tmp2) remseg(mtmp, wtmp); 221. wtmp = wtmp2; 222. } while(wtmp->nseg); 223. panic("Cannot find worm segment"); 224. } 225. 226. #endif /* WORM /**/
|