PropertyValue
rdfs:label
  • Source:NetHack 3.0.0/dog.c
rdfs:comment
  • Below is the full text to dog.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/dog.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code
dcterms:subject
dbkwik:nethack/property/wikiPageUsesTemplate
abstract
  • Below is the full text to dog.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/dog.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)dog.c 3.0 89/06/12 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #include "edog.h" 7. 8. char dogname[63] = DUMMY; 9. char catname[63] = DUMMY; 10. 11. #define domestic(mtmp) (mtmp->data->msound == MS_BARK || mtmp->data->msound == MS_MEW) 12. 13. void 14. initedog(mtmp) 15. register struct monst *mtmp; 16. { 17. mtmp->mtame = domestic(mtmp) ? 10 : 5; 18. mtmp->mpeaceful = 1; 19. mtmp->mleashed = 0; 20. mtmp->meating = 0; 21. EDOG(mtmp)->droptime = 0; 22. EDOG(mtmp)->dropdist = 10000; 23. EDOG(mtmp)->apport = 10; 24. EDOG(mtmp)->whistletime = 0; 25. EDOG(mtmp)->hungrytime = 1000 + moves; 26. } 27. 28. void 29. make_familiar(otmp) 30. register struct obj *otmp; 31. { 32. register struct monst *mtmp; 33. register struct permonst *pm; 34. 35. top: 36. if (otmp) pm = &mons[otmp->corpsenm]; /* Figurine; otherwise spell */ 37. else if (rn2(3)) { 38. if (!(pm = rndmonst())) { 39. pline("There seems to be nothing available for a familiar."); 40. return; 41. } 42. } 43. else if ((pl_character[0]=='W' || rn2(2)) && pl_character[0]!='C') 44. pm = &mons[PM_KITTEN]; 45. else pm = &mons[PM_LITTLE_DOG]; 46. 47. pm->pxlth += sizeof(struct edog); 48. mtmp = makemon(pm, u.ux, u.uy); 49. pm->pxlth -= sizeof(struct edog); 50. if (!mtmp) { /* monster was genocided */ 51. if (otmp) 52. pline("The figurine writhes and then shatters into pieces!"); 53. else goto top; 54. /* rndmonst() returns something not genocided always, so this 55. * means it was a cat or dog; loop back to try again until 56. * either rndmonst() is called, or if only one of cat/dog 57. * was genocided, they get the other. 58. */ 59. return; 60. } 61. initedog(mtmp); 62. if (otmp && otmp->cursed) { /* cursed figurine */ 63. You("get a bad feeling about this."); 64. mtmp->mtame = mtmp->mpeaceful = 0; 65. } 66. } 67. 68. struct monst * 69. makedog() { 70. register struct monst *mtmp; 71. register char *petname; 72. 73. if (pl_character[0]=='C' || (pl_character[0] != 'W' && rn2(2))) { 74. mons[PM_LITTLE_DOG].pxlth = sizeof(struct edog); 75. mtmp = makemon(&mons[PM_LITTLE_DOG], u.ux, u.uy); 76. mons[PM_LITTLE_DOG].pxlth = 0; 77. petname = dogname; 78. } else { 79. mons[PM_KITTEN].pxlth = sizeof(struct edog); 80. mtmp = makemon(&mons[PM_KITTEN], u.ux, u.uy); 81. mons[PM_KITTEN].pxlth = 0; 82. petname = catname; 83. } 84. 85. if(!mtmp) return((struct monst *) 0); /* dogs were genocided */ 86. 87. if (petname[0]) { 88. register struct monst *mtmp2; 89. 90. mtmp->mnamelth = strlen(petname) + 1; 91. mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth); 92. *mtmp2 = *mtmp; 93. 94. replmon(mtmp, mtmp2); 95. mtmp = mtmp2; 96. Strcpy(NAME(mtmp), petname); 97. petname[0] = '\0'; /* name first only; actually unnecessary */ 98. } 99. initedog(mtmp); 100. return(mtmp); 101. } 102. 103. /* attach the monsters that went down (or up) together with @ */ 104. struct monst *mydogs = 0; 105. /* monsters that fell through a trapdoor or stepped on a tele-trap. */ 106. /* 'down' is now true only of trapdooor falling, not for tele-trap. */ 107. struct monst *fallen_down = 0; 108. 109. void 110. losedogs(){ 111. register struct monst *mtmp,*mtmp0,*mtmp2; 112. 113. while(mtmp = mydogs){ 114. mydogs = mtmp->nmon; 115. mtmp->nmon = fmon; 116. fmon = mtmp; 117. mnexto(mtmp); 118. } 119. #ifdef LINT 120. mtmp0 = (struct monst *)0; 121. #endif 122. for(mtmp = fallen_down; mtmp; mtmp = mtmp2) { 123. mtmp2 = mtmp->nmon; 124. if(mtmp->mx == dlevel) { 125. mtmp->mx = 0; 126. if(mtmp == fallen_down) 127. fallen_down = mtmp->nmon; 128. else 129. mtmp0->nmon = mtmp->nmon; 130. mtmp->nmon = fmon; 131. fmon = mtmp; 132. if (mtmp->isshk) 133. home_shk(mtmp); 134. else 135. rloc(mtmp); 136. } else 137. mtmp0 = mtmp; 138. } 139. } 140. 141. void 142. keepdogs(){ 143. register struct monst *mtmp; 144. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 145. if(((dist(mtmp->mx,mtmp->my) < 3 && levl_follower(mtmp)) || 146. /* the wiz will level t-port from anywhere to chase 147. the amulet; if you don't have it, will chase you 148. only if in range. -3. */ 149. (u.uhave_amulet && mtmp->iswiz)) 150. && !mtmp->msleep && !mtmp->mfroz) { 151. #ifdef WORM 152. /* Bug "fix" for worm changing levels collapsing dungeon 153. */ 154. if (mtmp->data == &mons[PM_LONG_WORM]) { 155. if (canseemon(mtmp) || (Blind && Telepat)) 156. pline("The worm can't fit down the stairwell."); 157. # ifdef WALKIES 158. if (mtmp->mleashed) { 159. pline("The leash slides off the slimy worm."); 160. m_unleash(mtmp); 161. } 162. # endif 163. continue; 164. } 165. #endif 166. if (mon_has_amulet(mtmp)) { 167. pline("%s seems very disoriented for a moment.", 168. Monnam(mtmp)); 169. #ifdef WALKIES 170. if (mtmp->mleashed) { 171. pline("%s leash suddenly comes loose.", 172. is_female(mtmp) ? "Her" : 173. humanoid(mtmp->data) ? "His" : "Its"); 174. m_unleash(mtmp); 175. } 176. #endif 177. continue; 178. } 179. relmon(mtmp); 180. mtmp->mx = mtmp->my = 0; /* to avoid mnexto()/mmask problem */ 181. mtmp->nmon = mydogs; 182. mydogs = mtmp; 183. unpmon(mtmp); 184. keepdogs(); /* we destroyed the link, so use recursion */ 185. return; /* (admittedly somewhat primitive) */ 186. } 187. } 188. 189. void 190. fall_down(mtmp, tolev) 191. register struct monst *mtmp; 192. register int tolev; 193. { 194. relmon(mtmp); 195. mtmp->nmon = fallen_down; 196. fallen_down = mtmp; 197. #ifdef WALKIES 198. if (mtmp->mleashed) { 199. pline("The leash comes off!"); 200. m_unleash(mtmp); 201. } 202. #endif 203. unpmon(mtmp); 204. mtmp->mtame = 0; 205. mtmp->mx = tolev; 206. mtmp->my = 0; 207. /* make sure to reset mtmp->mx to 0 when releasing, */ 208. /* so rloc() on next level doesn't affect mmask */ 209. } 210. 211. /* return quality of food; the lower the better */ 212. /* fungi will eat even tainted food */ 213. int 214. dogfood(mon,obj) 215. struct monst *mon; 216. register struct obj *obj; 217. { 218. boolean carn = carnivorous(mon->data); 219. 220. switch(obj->olet) { 221. case FOOD_SYM: 222. if (obj->otyp == CORPSE && obj->corpsenm == PM_COCKATRICE && 223. !resists_ston(mon->data)) 224. return TABU; 225. 226. if (!carn && !herbivorous(mon->data)) 227. return (obj->cursed ? UNDEF : APPORT); 228. 229. switch (obj->otyp) { 230. case TRIPE_RATION: 231. return (carn ? DOGFOOD : MANFOOD); 232. case CORPSE: 233. case EGG: 234. if ((obj->age + 50 <= moves && mon->data->mlet != S_FUNGUS) || 235. (poisonous(&mons[obj->corpsenm]) && !resists_poison(mon->data)) || 236. (obj->corpsenm == PM_COCKATRICE && !resists_ston(mon->data))) 237. return POISON; 238. else return (carn ? CADAVER : MANFOOD); 239. case DEAD_LIZARD: 240. return (carn ? ACCFOOD : MANFOOD); 241. default: 242. return (obj->otyp < CARROT ? ACCFOOD : MANFOOD); 243. } 244. default: 245. if(!obj->cursed) return(APPORT); 246. /* fall into next case */ 247. case BALL_SYM: 248. case CHAIN_SYM: 249. case ROCK_SYM: 250. return(UNDEF); 251. } 252. } 253. 254. /* return roomnumber or -1 */ 255. int 256. inroom(x,y) xchar x,y; { 257. register struct mkroom *croom = &rooms[0]; 258. while(croom->hx >= 0){ 259. if(croom->hx >= x-1 && croom->lx <= x+1 && 260. croom->hy >= y-1 && croom->ly <= y+1) 261. return(croom - rooms); 262. croom++; 263. } 264. return(-1); /* not in room or on door */ 265. } 266. 267. int 268. tamedog(mtmp, obj) 269. register struct monst *mtmp; 270. register struct obj *obj; 271. { 272. register struct monst *mtmp2; 273. 274. /* worst case, at least he'll be peaceful. */ 275. mtmp->mpeaceful = 1; 276. if(flags.moonphase == FULL_MOON && night() && rn2(6) && obj 277. && mtmp->data->mlet == S_DOG) 278. return(0); 279. 280. /* If we cannot tame him, at least he's no longer afraid. */ 281. mtmp->mflee = 0; 282. mtmp->mfleetim = 0; 283. if(mtmp->mtame || mtmp->mfroz || 284. #ifdef WORM 285. mtmp->wormno || 286. #endif 287. mtmp->isshk || mtmp->isgd || 288. #if defined(ALTARS) && defined(THEOLOGY) 289. mtmp->ispriest || 290. #endif 291. #ifdef POLYSELF 292. is_human(mtmp->data) || (is_demon(mtmp->data) && !is_demon(uasmon))) 293. #else 294. is_human(mtmp->data) || is_demon(mtmp->data)) 295. #endif 296. return(0); 297. /* no tame long worms so they don't try to follow you down stairs 298. or get in your way */ 299. if(obj) { 300. if(dogfood(mtmp, obj) >= MANFOOD) return(0); 301. if(cansee(mtmp->mx,mtmp->my)){ 302. pline("%s devours the %s.", Monnam(mtmp), 303. objects[obj->otyp].oc_name); 304. } 305. obfree(obj, (struct obj *)0); 306. } 307. mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth); 308. *mtmp2 = *mtmp; 309. mtmp2->mxlth = sizeof(struct edog); 310. if(mtmp->mnamelth) Strcpy(NAME(mtmp2), NAME(mtmp)); 311. initedog(mtmp2); 312. replmon(mtmp,mtmp2); 313. return(1); 314. }