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