Source:NetHack 1.3d/dogmove.c
Revision as of 23:44, 3 March 2008 by Kernigh bot (talk | contribs) (NetHack 1.3d/dogmove.c moved to Source:NetHack 1.3d/dogmove.c: Robot: moved page)
Below is the full text to dogmove.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/dogmove.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
Screenshots and source code from Hack are used under the CWI license.
1. /* SCCS Id: @(#)dogmove.c 1.3 87/07/14 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* dogmove.c - version 1.0 */ 4. 5. #include "hack.h" 6. #include "mfndpos.h" 7. #include "mkroom.h" 8. #include "edog.h" 9. 10. /* return 0 (no move), 1 (move) or 2 (dead) */ 11. dog_move(mtmp, after) register struct monst *mtmp; { 12. #ifndef REGBUG 13. register 14. #endif 15. int nx,ny,omx,omy,appr,nearer,j; 16. int udist,chi,i,whappr; 17. register struct monst *mtmp2; 18. register struct permonst *mdat = mtmp->data; 19. register struct edog *edog = EDOG(mtmp); 20. struct obj *obj; 21. struct trap *trap; 22. xchar cnt,chcnt,nix,niy; 23. schar dogroom,uroom; 24. xchar gx,gy,gtyp,otyp; /* current goal */ 25. coord poss[9]; 26. long info[9]; 27. #define GDIST(x,y) ((x-gx)*(x-gx) + (y-gy)*(y-gy)) 28. #define DDIST(x,y) ((x-omx)*(x-omx) + (y-omy)*(y-omy)) 29. 30. if(moves <= edog->eattime) return(0); /* dog is still eating */ 31. omx = mtmp->mx; 32. omy = mtmp->my; 33. whappr = (moves - EDOG(mtmp)->whistletime < 5); 34. if(moves > edog->hungrytime + 500 && !mtmp->mconf){ 35. mtmp->mconf = 1; 36. mtmp->mhpmax /= 3; 37. if(mtmp->mhp > mtmp->mhpmax) 38. mtmp->mhp = mtmp->mhpmax; 39. if(cansee(omx,omy)) 40. pline("%s is confused from hunger.", Monnam(mtmp)); 41. else pline("You feel worried about %s.", monnam(mtmp)); 42. } else 43. if(moves > edog->hungrytime + 750 || mtmp->mhp < 1){ 44. if(cansee(omx,omy)) 45. pline("%s dies from hunger.", Monnam(mtmp)); 46. else 47. #ifdef WALKIES 48. mtmp->mleashed = 0; 49. pline("Your leash goes slack..."); 50. #endif 51. pline("You have a sad feeling for a moment, then it passes."); 52. mondied(mtmp); 53. return(2); 54. } 55. dogroom = inroom(omx,omy); 56. uroom = inroom(u.ux,u.uy); 57. udist = dist(omx,omy); 58. 59. /* maybe we tamed him while being swallowed --jgm */ 60. if(!udist) return(0); 61. 62. /* if we are carrying sth then we drop it (perhaps near @) */ 63. /* Note: if apport == 1 then our behaviour is independent of udist */ 64. if(mtmp->minvent){ 65. if(!rn2(udist) || !rn2((int) edog->apport)) 66. if(rn2(10) < edog->apport){ 67. relobj(mtmp, (int) mtmp->minvis); 68. if(edog->apport > 1) edog->apport--; 69. edog->dropdist = udist; /* hpscdi!jon */ 70. edog->droptime = moves; 71. } 72. } else { 73. if(obj = o_at(omx,omy)) if(!index("0_", obj->olet)){ 74. if((otyp = dogfood(obj)) <= CADAVER){ 75. nix = omx; 76. niy = omy; 77. goto eatobj; 78. } 79. if(obj->owt < 10*mtmp->data->mlevel) 80. if(rn2(20) < edog->apport+3) 81. if(rn2(udist) || !rn2((int) edog->apport)){ 82. freeobj(obj); 83. unpobj(obj); 84. /* if(levl[omx][omy].scrsym == obj->olet) 85. newsym(omx,omy); */ 86. mpickobj(mtmp,obj); 87. } 88. } 89. } 90. 91. gtyp = UNDEF; /* no goal as yet */ 92. gx = gy = 0; /* suppress 'used before set' message */ 93. #ifdef WALKIES 94. /* If he's on a leash, he's not going anywhere. */ 95. if(mtmp->mleashed) { 96. 97. gtyp = APPORT; 98. gx = u.ux; 99. gy = u.uy; 100. } else 101. #endif 102. /* first we look for food */ 103. for(obj = fobj; obj; obj = obj->nobj) { 104. otyp = dogfood(obj); 105. if(otyp > gtyp || otyp == UNDEF) continue; 106. if(inroom(obj->ox,obj->oy) != dogroom) continue; 107. if(otyp < MANFOOD && 108. (dogroom >= 0 || DDIST(obj->ox,obj->oy) < 10)) { 109. if(otyp < gtyp || (otyp == gtyp && 110. DDIST(obj->ox,obj->oy) < DDIST(gx,gy))){ 111. gx = obj->ox; 112. gy = obj->oy; 113. gtyp = otyp; 114. } 115. } else 116. if(gtyp == UNDEF && dogroom >= 0 && 117. uroom == dogroom && 118. !mtmp->minvent && edog->apport > rn2(8)){ 119. gx = obj->ox; 120. gy = obj->oy; 121. gtyp = APPORT; 122. } 123. } 124. 125. if(gtyp == UNDEF || 126. (gtyp != DOGFOOD && gtyp != APPORT && moves < edog->hungrytime)){ 127. if(dogroom < 0 || dogroom == uroom){ 128. gx = u.ux; 129. gy = u.uy; 130. #ifndef QUEST 131. } else { 132. int tmp = rooms[dogroom].fdoor; 133. cnt = rooms[dogroom].doorct; 134. 135. gx = gy = FAR; /* random, far away */ 136. while(cnt--){ 137. if(dist(gx,gy) > 138. dist(doors[tmp].x, doors[tmp].y)){ 139. gx = doors[tmp].x; 140. gy = doors[tmp].y; 141. } 142. tmp++; 143. } 144. /* here gx == FAR e.g. when dog is in a vault */ 145. if(gx == FAR || (gx == omx && gy == omy)){ 146. gx = u.ux; 147. gy = u.uy; 148. } 149. #endif 150. } 151. appr = (udist >= 9) ? 1 : (mtmp->mflee) ? -1 : 0; 152. if(after && udist <= 4 && gx == u.ux && gy == u.uy) 153. return(0); 154. if(udist > 1){ 155. if(!IS_ROOM(levl[u.ux][u.uy].typ) || !rn2(4) || 156. whappr || 157. (mtmp->minvent && rn2((int) edog->apport))) 158. appr = 1; 159. } 160. /* if you have dog food he'll follow you more closely */ 161. if(appr == 0){ 162. obj = invent; 163. while(obj){ 164. if(obj->otyp == TRIPE_RATION){ 165. appr = 1; 166. break; 167. } 168. obj = obj->nobj; 169. } 170. } 171. } else appr = 1; /* gtyp != UNDEF */ 172. if(mtmp->mconf) appr = 0; 173. 174. if(gx == u.ux && gy == u.uy && (dogroom != uroom || dogroom < 0)) { 175. extern coord *gettrack(); 176. register coord *cp; 177. cp = gettrack(omx,omy); 178. if(cp){ 179. gx = cp->x; 180. gy = cp->y; 181. } 182. } 183. 184. nix = omx; 185. niy = omy; 186. cnt = mfndpos(mtmp,poss,info,ALLOW_M | ALLOW_TRAPS); 187. chcnt = 0; 188. chi = -1; 189. for(i=0; i<cnt; i++){ 190. nx = poss[i].x; 191. ny = poss[i].y; 192. #ifdef WALKIES 193. /* if leashed, we drag him along. */ 194. if(dist(nx, ny) > 4 && mtmp->mleashed) continue; 195. #endif 196. if(info[i] & ALLOW_M) { 197. mtmp2 = m_at(nx,ny); 198. if(mtmp2->data->mlevel >= mdat->mlevel+2 || 199. mtmp2->data->mlet == 'c') 200. continue; 201. if(after) return(0); /* hit only once each move */ 202. 203. if(hitmm(mtmp, mtmp2) == 1 && rn2(4) && 204. mtmp2->mlstmv != moves && 205. hitmm(mtmp2,mtmp) == 2) return(2); 206. return(0); 207. } 208. 209. /* dog avoids traps */ 210. /* but perhaps we have to pass a trap in order to follow @ */ 211. if((info[i] & ALLOW_TRAPS) && (trap = t_at(nx,ny))){ 212. if(!trap->tseen && rn2(40)) continue; 213. if(rn2(10)) continue; 214. } 215. 216. /* dog eschewes cursed objects */ 217. /* but likes dog food */ 218. obj = fobj; 219. while(obj){ 220. if(obj->ox != nx || obj->oy != ny) 221. goto nextobj; 222. if(obj->cursed) goto nxti; 223. if(obj->olet == FOOD_SYM && 224. (otyp = dogfood(obj)) < MANFOOD && 225. (otyp < ACCFOOD || edog->hungrytime <= moves)){ 226. /* Note: our dog likes the food so much that he 227. might eat it even when it conceals a cursed object */ 228. nix = nx; 229. niy = ny; 230. chi = i; 231. eatobj: 232. edog->eattime = 233. moves + obj->quan * objects[obj->otyp].oc_delay; 234. if(edog->hungrytime < moves) 235. edog->hungrytime = moves; 236. edog->hungrytime += 237. 5*obj->quan * objects[obj->otyp].nutrition; 238. mtmp->mconf = 0; 239. if(cansee(nix,niy)) 240. pline("%s ate %s.", Monnam(mtmp), doname(obj)); 241. /* perhaps this was a reward */ 242. if(otyp != CADAVER) 243. edog->apport += 200/(edog->dropdist+moves-edog->droptime); 244. delobj(obj); 245. goto newdogpos; 246. } 247. nextobj: 248. obj = obj->nobj; 249. } 250. 251. for(j=0; j<MTSZ && j<cnt-1; j++) 252. if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y) 253. if(rn2(4*(cnt-j))) goto nxti; 254. 255. /* Some stupid C compilers cannot compute the whole expression at once. */ 256. nearer = GDIST(nx,ny); 257. nearer -= GDIST(nix,niy); 258. nearer *= appr; 259. if((nearer == 0 && !rn2(++chcnt)) || nearer<0 || 260. (nearer > 0 && !whappr && 261. ((omx == nix && omy == niy && !rn2(3)) 262. || !rn2(12)) 263. )){ 264. nix = nx; 265. niy = ny; 266. if(nearer < 0) chcnt = 0; 267. chi = i; 268. } 269. nxti: ; 270. } 271. newdogpos: 272. if(nix != omx || niy != omy){ 273. if(info[chi] & ALLOW_U){ 274. (void) hitu(mtmp, d(mdat->damn, mdat->damd)+1); 275. return(0); 276. } 277. mtmp->mx = nix; 278. mtmp->my = niy; 279. for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1]; 280. mtmp->mtrack[0].x = omx; 281. mtmp->mtrack[0].y = omy; 282. } 283. #ifdef WALKIES 284. /* an incredible kluge, but the only way to keep pooch near 285. * after he spends time eating or in a trap, etc... 286. */ 287. else if(mtmp->mleashed && dist(omx, omy) > 4) mnexto(mtmp); 288. #endif 289. 290. if(mintrap(mtmp) == 2) { /* he died */ 291. #ifdef WALKIES 292. mtmp->mleashed = 0; 293. #endif 294. return(2); 295. } 296. pmon(mtmp); 297. return(1); 298. }