Source:NetHack 3.4.0/steed.c

Below is the full text to steed.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.0/steed.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)steed.c	3.4	2002/03/09	*/ 2.   /* Copyright (c) Kevin Hugo, 1998-1999. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6. 7.    8.    #ifdef STEED 9.    10.   /* Monsters that might be ridden */ 11.  static NEARDATA const char steeds[] = { 12.  	S_QUADRUPED, S_UNICORN, S_ANGEL, S_CENTAUR, S_DRAGON, S_JABBERWOCK, '\0' 13.  };  14.    15.   STATIC_DCL boolean FDECL(landing_spot, (coord *, int)); 16.   17.   /*** Putting the saddle on ***/ 18.   19.   /* Can this monster wear a saddle? */ 20.   boolean 21.  can_saddle(mtmp) 22.  	struct monst *mtmp; 23.  {  24.   	struct permonst *ptr = mtmp->data; 25.   26.   	return (index(steeds, ptr->mlet) && (ptr->msize >= MZ_MEDIUM) &&  27.   			(!humanoid(ptr) || ptr->mlet == S_CENTAUR) &&  28.   			!amorphous(ptr) && !noncorporeal(ptr) &&  29.   			!is_whirly(ptr) && !unsolid(ptr)); 30.  }  31.    32.    33.   int 34.  use_saddle(otmp) 35.  	struct obj *otmp; 36.  {  37.   	struct monst *mtmp; 38.  	struct permonst *ptr; 39.  	int chance; 40.  	const char *s; 41.   42.    43.   	/* Can you use it? */ 44.   	if (nohands(youmonst.data)) { 45.  		You("have no hands!");	/* not `body_part(HAND)' */ 46.  		return 0; 47.  	} else if (!freehand) { 48.  		You("have no free %s.", body_part(HAND)); 49.  		return 0; 50.  	}  51.    52.   	/* Select an animal */ 53.  	if (u.uswallow || Underwater || !getdir((char *)0)) { 54.  	    pline(Never_mind); 55.  	    return 0; 56.  	}  57.   	if (!u.dx && !u.dy) { 58.  	    pline("Saddle yourself?  Very funny..."); 59.  	    return 0; 60.  	}  61.   	if (!isok(u.ux+u.dx, u.uy+u.dy) ||  62.   			!(mtmp = m_at(u.ux+u.dx, u.uy+u.dy)) ||  63.   			!canspotmon(mtmp)) { 64.  	    pline("I see nobody there."); 65.  	    return 1; 66.  	}  67.    68.   	/* Is this a valid monster? */ 69.   	if (mtmp->misc_worn_check & W_SADDLE ||  70.   			which_armor(mtmp, W_SADDLE)) { 71.  	    pline("%s doesn't need another one.", Monnam(mtmp)); 72.  	    return 1; 73.  	}  74.   	ptr = mtmp->data; 75.  	if (touch_petrifies(ptr) && !Stone_resistance) { 76.  	    char kbuf[BUFSZ]; 77.   78.   	    You("touch %s.", mon_nam(mtmp)); 79.   	    if (!(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))) { 80.  			Sprintf(kbuf, "attempting to saddle %s", a_monnam(mtmp)); 81.  			instapetrify(kbuf); 82.   	    }  83.   	}  84.   	if (ptr == &mons[PM_INCUBUS] || ptr == &mons[PM_SUCCUBUS]) { 85.  	    pline("Shame on you!"); 86.  	    exercise(A_WIS, FALSE); 87.  	    return 1; 88.  	}  89.   	if (mtmp->isminion || mtmp->isshk || mtmp->ispriest ||  90.   			mtmp->isgd || mtmp->iswiz) { 91.  	    pline("I think %s would mind.", mon_nam(mtmp)); 92.  	    return 1; 93.  	}  94.   	if (!can_saddle(mtmp)) { 95.  		You_cant("saddle such a creature."); 96.  		return 1; 97.  	}  98.    99.   	/* Calculate your chance */ 100. 	chance = ACURR(A_DEX) + ACURR(A_CHA)/2 + 2*mtmp->mtame; 101. 	chance += u.ulevel * (mtmp->mtame ? 20 : 5); 102. 	if (!mtmp->mtame) chance -= 10*mtmp->m_lev; 103. 	if (Role_if(PM_KNIGHT)) 104. 	    chance += 20; 105. 	switch (P_SKILL(P_RIDING)) { 106. 	case P_ISRESTRICTED: 107. 	case P_UNSKILLED: 108. 	default: 109. 	    chance -= 20;	break; 110. 	case P_BASIC: 111. 	    break; 112. 	case P_SKILLED: 113. 	    chance += 15;	break; 114. 	case P_EXPERT: 115. 	    chance += 30;	break; 116. 	}  117.  	if (Confusion || Fumbling || Glib) 118. 	    chance -= 20; 119. 	else if (uarmg &&  120.  		(s = OBJ_DESCR(objects[uarmg->otyp])) != (char *)0 &&  121.  		!strncmp(s, "riding ", 7)) 122. 	    /* Bonus for wearing "riding" (but not fumbling) gloves */ 123. 	    chance += 10; 124. 	else if (uarmf &&  125.  		(s = OBJ_DESCR(objects[uarmf->otyp])) != (char *)0 &&  126.  		!strncmp(s, "riding ", 7)) 127. 	    /* ... or for "riding boots" */ 128. 	    chance += 10; 129. 	if (otmp->cursed) 130. 	    chance -= 50; 131.  132.  	/* Make the attempt */ 133. 	if (rn2(100) < chance) { 134. 	    You("put the saddle on %s.", mon_nam(mtmp)); 135. 	    freeinv(otmp); 136. 	    /* mpickobj may free otmp it if merges, but we have already 137. 	       checked for a saddle above, so no merger should happen */ 138. 	    (void) mpickobj(mtmp, otmp); 139. 	    mtmp->misc_worn_check |= W_SADDLE; 140. 	    otmp->owornmask = W_SADDLE; 141. 	    otmp->leashmon = mtmp->m_id; 142. 	    update_mon_intrinsics(mtmp, otmp, TRUE); 143. 	} else 144. 	    pline("%s resists!", Monnam(mtmp)); 145. 	return 1; 146. }  147.   148.   149.  /*** Riding the monster ***/ 150.  151.  /* Can we ride this monster? Caller should also check can_saddle */ 152. boolean 153. can_ride(mtmp) 154. 	struct monst *mtmp; 155. {  156.  	return (mtmp->mtame && humanoid(youmonst.data) &&  157.  			!verysmall(youmonst.data) && !bigmonst(youmonst.data) &&  158.  			(!Underwater || is_swimmer(mtmp->data))); 159. }  160.   161.   162.  int 163. doride 164. {  165.  	boolean forcemount = FALSE; 166.  167.  	if (u.usteed) 168. 	    dismount_steed(DISMOUNT_BYCHOICE); 169. 	else if (getdir((char *)0) && isok(u.ux+u.dx, u.uy+u.dy)) { 170. #ifdef WIZARD 171. 	if (wizard && yn("Force the mount to succeed?") == 'y') 172. 		forcemount = TRUE; 173. #endif 174. 	    return (mount_steed(m_at(u.ux+u.dx, u.uy+u.dy), forcemount)); 175. 	} else 176. 	    return 0; 177. 	return 1; 178. }  179.   180.   181.  /* Start riding, with the given monster */ 182. boolean 183. mount_steed(mtmp, force) 184. 	struct monst *mtmp;	/* The animal */ 185. 	boolean force;		/* Quietly force this animal */ 186. {  187.  	struct obj *otmp; 188. 	char buf[BUFSZ]; 189. 	struct permonst *ptr; 190.  191.   192.  	/* Sanity checks */ 193. 	if (u.usteed) { 194. 	    if (!force) 195. 	    	You("are already riding %s.", mon_nam(u.usteed)); 196. 	    return (FALSE); 197. 	}  198.   199.  	/* Is the player in the right form? */ 200.  	if (Hallucination && !force) { 201. 	    pline("Maybe you should find a designated driver."); 202. 	    return (FALSE); 203. 	}  204.  	/* While riding Wounded_legs refers to the steed's,  205. * not the hero's legs. 206. 	 * That opens up a potential abuse where the player 207. 	 * can mount a steed, then dismount immediately to  208. * heal leg damage, because leg damage is always 209. 	 * healed upon dismount (Wounded_legs context switch). 210. 	 * By preventing a hero with Wounded_legs from 211. 	 * mounting a steed, the potential for abuse is  212. * minimized, if not eliminated altogether. 213. 	 */  214.  	if (Wounded_legs) { 215. 	    Your("%s are in no shape for riding.", makeplural(body_part(LEG))); 216. #ifdef WIZARD 217. 	    if (force && wizard && yn("Heal your legs?") == 'y') 218. 		HWounded_legs = EWounded_legs = 0; 219. 	    else 220. #endif 221. 	    return (FALSE); 222. 	}  223.  	  224.  	if (Upolyd && (!humanoid(youmonst.data) || verysmall(youmonst.data) || 225. 			bigmonst(youmonst.data))) { 226. 	    if (!force) 227. 	    	You("won't fit on a saddle."); 228. 	    return (FALSE); 229. 	}  230.  	if(!force && (near_capacity > SLT_ENCUMBER)) { 231. 	    You_cant("do that while carrying so much stuff."); 232. 	    return (FALSE); 233. 	}  234.   235.  	/* Can the player reach and see the monster? */ 236.      if (u.uswallow || u.ustuck || u.utrap || Punished) { 237.         if (!force) { 238. 		if (Punished) 239. 			You("are unable to swing your %s over.",  240.  				body_part(LEG)); 241. 		else 242.         		You("are stuck here for now."); 243. 	}  244.          return (FALSE); 245.     }  246.  	if (!mtmp || (!force && ((Blind && !Blind_telepat) ||  247.  		mtmp->mundetected ||  248.  		mtmp->m_ap_type == M_AP_FURNITURE ||  249.  		mtmp->m_ap_type == M_AP_OBJECT))) { 250. 	    if (!force) 251. 	    	pline("I see nobody there."); 252. 	    return (FALSE); 253. 	}  254.   255.  	/* Is this a valid monster? */ 256.  	otmp = which_armor(mtmp, W_SADDLE); 257. 	if (!otmp) { 258. 	    pline("%s is not saddled.", Monnam(mtmp)); 259. 	    return (FALSE); 260. 	}  261.  	ptr = mtmp->data; 262. 	if (touch_petrifies(ptr) && !Stone_resistance) { 263. 	    char kbuf[BUFSZ]; 264.  265.  	    You("touch %s.", mon_nam(mtmp)); 266.  	    Sprintf(kbuf, "attempting to ride %s", an(mtmp->data->mname)); 267. 	    instapetrify(kbuf); 268. 	}  269.  	if (!mtmp->mtame || mtmp->isminion) { 270. 	    if (!force) 271. 	    	pline("I think %s would mind.", mon_nam(mtmp)); 272. 	    return (FALSE); 273. 	}  274.  	if (!force && !Role_if(PM_KNIGHT) && !(--mtmp->mtame)) { 275. 	    /* no longer tame */ 276. 	    newsym(mtmp->mx, mtmp->my); 277. 	    pline("%s resists%s!", Monnam(mtmp),  278.  		  mtmp->mleashed ? " and its leash comes off" : ""); 279. 	    if (mtmp->mleashed) m_unleash(mtmp, FALSE); 280. 	    return (FALSE); 281. 	}  282.  	if (!force && Underwater && !is_swimmer(ptr)) { 283. 	    You_cant("ride that creature while under water."); 284. 	    return (FALSE); 285. 	}  286.  	if (!can_saddle(mtmp) || !can_ride(mtmp)) { 287. 	    if (!force) 288. 	    	You_cant("ride such a creature."); 289. 	    return (0); 290. 	}  291.   292.  	/* Is the player impaired? */ 293.  	if (!force && !is_floater(ptr) && !is_flyer(ptr) &&  294.  			Levitation && !Lev_at_will) { 295. 	    You("cannot reach %s.", mon_nam(mtmp)); 296. 	    return (FALSE); 297. 	}  298.  	if (!force && uarm && is_metallic(uarm) &&  299.  			greatest_erosion(uarm)) { 300. 	    Your("%s armor is too stiff to be able to mount %s.",  301.  			uarm->oeroded ? "rusty" : "corroded",  302.  			mon_nam(mtmp)); 303. 	    return (FALSE); 304. 	}  305.  	if (!force && (Confusion || Fumbling || Glib || Wounded_legs || 306. 		otmp->cursed || (u.ulevel+mtmp->mtame < rnd(MAXULEV/2+5)))) { 307. 	    if (Levitation) { 308. 		pline("%s slips away from you.", Monnam(mtmp)); 309. 		return FALSE; 310. 	    }  311.  	    You("slip while trying to get on %s.", mon_nam(mtmp)); 312.  313.  	    /* Unfortunately we don't have a version of the monster-naming 314. 	     * function that works well with "a" and "the" but ignores 315. 	     * hallucination. Fortunately, we know the monster must be saddled 316. 	     * at this point, and that it can't have type_is_pname, so we  317. * don't need to worry about the special cases such a function 318. 	     * would have to consider. 319. 	     */  320.  	    Sprintf(buf, "slipped while mounting a saddled %s",  321.  		    m_monnam(mtmp)); 322. 	    losehp(rn1(5,10), buf, NO_KILLER_PREFIX); 323. 	    return (FALSE); 324. 	}  325.   326.  	/* Success */ 327. 	if (!force) { 328. 	    if (Levitation && !is_floater(ptr) && !is_flyer(ptr)) 329. 	    	/* Must have Lev_at_will at this point */ 330. 	    	pline("%s magically floats up!", Monnam(mtmp)); 331. 	    You("mount %s.", mon_nam(mtmp)); 332. 	}  333.  	u.usteed = mtmp; 334. 	remove_monster(mtmp->mx, mtmp->my); 335. 	teleds(mtmp->mx, mtmp->my); 336. 	return (TRUE); 337. }  338.   339.   340.  /* You and your steed have moved */ 341. void 342. exercise_steed 343. {  344.  	if (!u.usteed) 345. 		return; 346.  347.  	/* It takes many turns of riding to exercise skill */ 348. 	if (u.urideturns++ >= 100) { 349. 	    u.urideturns = 0; 350. 	    use_skill(P_RIDING, 1); 351. 	}  352.  	return; 353. }  354.   355.   356.  /* The player kicks or whips the steed */ 357. void 358. kick_steed 359. {  360.  	char He[4]; 361. 	if (!u.usteed) 362. 	    return; 363.  364.  	/* [ALI] Various effects of kicking sleeping/paralyzed steeds */ 365. 	if (u.usteed->msleeping || !u.usteed->mcanmove) { 366. 	    /* We assume a message has just been output of the form 367. 	     * "You kick ." 368. 	     */  369.  	    Strcpy(He, mhe(u.usteed)); 370. 	    *He = highc(*He); 371. 	    if ((u.usteed->mcanmove || u.usteed->mfrozen) && !rn2(2)) { 372. 		if (u.usteed->mcanmove) 373. 		    u.usteed->msleeping = 0; 374. 		else if (u.usteed->mfrozen > 2) 375. 		    u.usteed->mfrozen -= 2; 376. 		else { 377. 		    u.usteed->mfrozen = 0; 378. 		    u.usteed->mcanmove = 1; 379. 		}  380.  		if (u.usteed->msleeping || !u.usteed->mcanmove) 381. 		    pline("%s stirs.", He); 382. 		else 383. 		    pline("%s rouses %sself!", He, mhim(u.usteed)); 384. 	    } else 385. 		pline("%s does not respond.", He); 386. 	    return; 387. 	}  388.   389.  	/* Make the steed less tame and check if it resists */ 390. 	if (u.usteed->mtame) u.usteed->mtame--; 391. 	if (!u.usteed->mtame && u.usteed->mleashed) m_unleash(u.usteed, TRUE); 392. 	if (!u.usteed->mtame || (u.ulevel+u.usteed->mtame < rnd(MAXULEV/2+5))) { 393. 	    newsym(u.usteed->mx, u.usteed->my); 394. 	    dismount_steed(DISMOUNT_THROWN); 395. 	    return; 396. 	}  397.   398.  	pline("%s gallops!", Monnam(u.usteed)); 399. 	u.ugallop += rn1(20, 30); 400. 	return; 401. }  402.   403.  /*  404.   * Try to find a dismount point adjacent to the steed's location. 405.  * If all else fails, try enexto. Use enexto as a last resort because 406.  * enexto chooses its point randomly, possibly even outside the 407.  * room's walls, which is not what we want. 408.  * Adapted from mail daemon code. 409.  */  410.  STATIC_OVL boolean 411. landing_spot(spot, forceit) 412. coord *spot;	/* landing position (we fill it in) */ 413. int forceit; 414. {  415.      int x, y, distance, min_distance = -1; 416.     boolean found = FALSE; 417.      418.      for (x = u.ux-1; x <= u.ux+1; x++) 419.   	for (y = u.uy-1; y <= u.uy+1; y++) { 420. 	    if (!isok(x, y) || (x == u.ux && y == u.uy)) continue; 421.  422.  	    if (ACCESSIBLE(levl[x][y].typ) &&  423.  			!MON_AT(x,y) && !closed_door(x,y)) { 424. 		distance = distu(x,y); 425. 		if (min_distance < 0 || distance < min_distance ||  426.  			(distance == min_distance && rn2(2))) { 427. 		    spot->x = x;  428. spot->y = y; 429. min_distance = distance; 430. 		    found = TRUE; 431. 		}  432.  	    }  433.  	}  434.       435.      /* If we didn't find a good spot and forceit is on, try enexto. */ 436.      if (forceit && min_distance < 0 &&  437.  		!enexto(spot, u.ux, u.uy, youmonst.data)) 438. 	return FALSE; 439.  440.      return found; 441. }  442.   443.  /* Stop riding the current steed */ 444. void 445. dismount_steed(reason) 446. 	int reason;		/* Player was thrown off etc. */ 447. {  448.  	struct monst *mtmp; 449. 	struct obj *otmp; 450. 	coord cc; 451. 	const char *verb = "fall"; 452. 	boolean repair_leg_damage = TRUE; 453. 	unsigned save_utrap = u.utrap; 454. 	boolean have_spot = landing_spot(&cc,0); 455. 	  456.  	mtmp = u.usteed;		/* make a copy of steed pointer */ 457. 	/* Sanity check */ 458. 	if (!mtmp)		/* Just return silently */ 459. 	    return; 460.  461.  	/* Check the reason for dismounting */ 462. 	otmp = which_armor(mtmp, W_SADDLE); 463. 	switch (reason) { 464. 	    case DISMOUNT_THROWN: 465. 		verb = "are thrown"; 466. 	    case DISMOUNT_FELL: 467. 		You("%s off of %s!", verb, mon_nam(mtmp)); 468. 		if (!have_spot) have_spot = landing_spot(&cc,1); 469. 		losehp(rn1(10,10), "riding accident", KILLED_BY_AN); 470. 		set_wounded_legs(BOTH_SIDES, (int)HWounded_legs + rn1(5,5)); 471. 		repair_leg_damage = FALSE; 472. 		break; 473. 	    case DISMOUNT_POLY: 474. 		You("can no longer ride %s.", mon_nam(u.usteed)); 475. 		if (!have_spot) have_spot = landing_spot(&cc,1); 476. 		break; 477. 	    case DISMOUNT_ENGULFED: 478. 		/* caller displays message */ 479. 		break; 480. 	    case DISMOUNT_BONES: 481. 		/* hero has just died... */ 482.  		break; 483. 	    case DISMOUNT_GENERIC: 484. 		/* no messages, just make it so */ 485. 		break; 486. 	    case DISMOUNT_BYCHOICE: 487. 	    default: 488. 		if (otmp && otmp->cursed) { 489. 		    You("can't.  The saddle seems to be cursed."); 490. 		    otmp->bknown = TRUE; 491. 		    return; 492. 		}  493.  		if (!have_spot) { 494. 		    You("can't. There isn't anywhere for you to stand."); 495. 		    return; 496. 		}  497.  		if (!mtmp->mnamelth) { 498. 			pline("You've been through the dungeon on %s with no name.",  499.  				an(mtmp->data->mname)); 500. 			if (Hallucination) 501. 				pline("It felt good to get out of the rain."); 502. 		} else 503. 			You("dismount %s.", mon_nam(mtmp)); 504. 	}  505.  	/* While riding these refer to the steed's legs 506. 	 * so after dismounting they refer to the player's  507. * legs once again. 508. 	 */  509.  	if (repair_leg_damage) HWounded_legs = EWounded_legs = 0; 510.  511.  	/* Release the steed and saddle */ 512. 	u.usteed = 0; 513. 	u.ugallop = 0L; 514.  515.  	/* Set player and steed's position. Try moving the player first 516. 	   unless we're in the midst of creating a bones file. */ 517.  	if (reason == DISMOUNT_BONES) { 518. 	    /* move the steed to an adjacent square */ 519. 	    if (enexto(&cc, u.ux, u.uy, mtmp->data)) 520. 		rloc_to(mtmp, cc.x, cc.y); 521. 	    else	/* evidently no room nearby; move steed elsewhere */ 522. 		rloc(mtmp); 523. 	    return; 524. 	}  525.  	if (!DEADMONSTER(mtmp)) { 526. 	    place_monster(mtmp, u.ux, u.uy); 527. 	    if (!u.uswallow && !u.ustuck && have_spot) { 528. 		struct permonst *mdat = mtmp->data; 529.  530.  		/* The steed may drop into water/lava */ 531. 		if (!is_flyer(mdat) && !is_floater(mdat) && !is_clinger(mdat)) { 532. 		    if (is_pool(u.ux, u.uy)) { 533. 			if (!Underwater) 534. 			    pline("%s falls into the %s!", Monnam(mtmp),  535.  							surface(u.ux, u.uy)); 536. 			if (!is_swimmer(mdat) && !amphibious(mdat)) { 537. 			    killed(mtmp); 538. 			    adjalign(-1); 539. 			}  540.  		    } else if (is_lava(u.ux, u.uy)) { 541. 			pline("%s is pulled into the lava!", Monnam(mtmp)); 542. 			if (!likes_lava(mdat)) { 543. 			    killed(mtmp); 544. 			    adjalign(-1); 545. 			}  546.  		    }  547.  		}  548.  	    /* Steed dismounting consists of two steps: being moved to another 549. 	     * square, and descending to the floor. We have functions to do 550. * each of these activities, but they're normally called 551. 	     * individually and include an attempt to look at or pick up the 552. 	     * objects on the floor: 553. 	     * teleds --> spoteffects --> pickup 554. 	     * float_down --> pickup 555. 	     * We use this kludge to make sure there is only one such attempt. 556. 	     *  557.  	     * Clearly this is not the best way to do it. A full fix would 558. 	     * involve having these functions not call pickup at all, instead 559. 	     * calling them first and calling pickup afterwards. But it 560. * would take a lot of work to keep this change from having any 561. 	     * unforseen side effects (for instance, you would no longer be  562.  	     * able to walk onto a square with a hole, and autopickup before  563.  	     * falling into the hole). 564. 	     */  565.  		/* [ALI] No need to move the player if the steed died. */ 566.  		if (!DEADMONSTER(mtmp)) { 567. 		    /* Keep steed here, move the player to cc; 568. 		     * teleds clears u.utrap 569. 		     */  570.  		    in_steed_dismounting = TRUE; 571. 		    teleds(cc.x, cc.y); 572. 		    in_steed_dismounting = FALSE; 573.  574.  		    /* Put your steed in your trap */ 575. 		    if (save_utrap) 576. 			(void) mintrap(mtmp); 577. 		}  578.  	    /* Couldn't... try placing the steed */ 579. 	    } else if (enexto(&cc, u.ux, u.uy, mtmp->data)) { 580. 		/* Keep player here, move the steed to cc */ 581. 		rloc_to(mtmp, cc.x, cc.y); 582. 		/* Player stays put */ 583. 	    /* Otherwise, kill the steed */ 584. 	    } else { 585. 		killed(mtmp); 586. 		adjalign(-1); 587. 	    }  588.  	}  589.   590.  	/* Return the player to the floor */ 591. 	in_steed_dismounting = TRUE; 592. 	(void) float_down(0L, W_SADDLE); 593. 	in_steed_dismounting = FALSE; 594. 	flags.botl = 1; 595. 	if (reason != DISMOUNT_ENGULFED) { 596. 		(void)encumber_msg; 597. 		vision_full_recalc = 1; 598. 	}  599.  	return; 600. }  601.   602.  void 603. place_monster(mon, x, y)  604. struct monst *mon; 605. int x, y;  606. { 607.      if (mon == u.usteed ||  608.  	    /* special case is for convoluted vault guard handling */  609.  	    (DEADMONSTER(mon) && !(mon->isgd && x == 0 && y == 0))) { 610. 	impossible("placing %s onto map?",  611.  		   (mon == u.usteed) ? "steed" : "defunct monster"); 612. 	return; 613.     }  614.      mon->mx = x, mon->my = y;  615. level.monsters[x][y] = mon; 616. }  617.   618.  #endif /* STEED */ 619.  620.  /*steed.c*/