Source:NetHack 3.1.0/dokick.c

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

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

1.   /*	SCCS Id: @(#)dokick.c	3.1	92/10/06	*/ 2.   /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include	"hack.h"  6.    #include	"eshk.h"  7. 8.   #ifndef POLYSELF 9.   # define martial	(pl_character[0] == 'S' || pl_character[0] == 'P') 10.  #else 11.  # define is_bigfoot(x)	((x) == &mons[PM_SASQUATCH]) 12.  # define martial	(pl_character[0] == 'S' || pl_character[0] == 'P' \  13.   			 || is_bigfoot(uasmon)) 14.  #endif 15.   16.   static struct rm NEARDATA *maploc; 17.   18.   extern boolean notonhead;	/* for long worms */ 19.   20.   static void FDECL(kickdmg, (struct monst *, BOOLEAN_P)); 21.  static void FDECL(kick_monster, (XCHAR_P, XCHAR_P)); 22.  static int FDECL(kick_object, (XCHAR_P, XCHAR_P)); 23.  static char *NDECL(kickstr); 24.  static void FDECL(otransit_msg, (struct obj *, XCHAR_P, BOOLEAN_P, int)); 25.  static const char *FDECL(gate_str, (XCHAR_P)); 26.  static void FDECL(drop_to, (coord *, XCHAR_P)); 27.   28.   static struct obj NEARDATA *kickobj; 29.   30.   #define IS_SHOP(x)	(rooms[x].rtype >= SHOPBASE) 31.   32.   static void 33.  kickdmg(mon, clumsy) 34.  register struct monst *mon; 35.  register boolean clumsy; 36.  {  37.   	register int mdx, mdy; 38.  	register int dmg = ( ACURRSTR + ACURR(A_DEX) + ACURR(A_CON) )/ 15; 39.   40.   	/* excessive wt affects dex, so it affects dmg */ 41.  	if(clumsy) dmg = dmg/2; 42.   43.   	/* kicking a dragon or an elephant will not harm it */ 44.  	if(thick_skinned(mon->data)) dmg = 0; 45.   46.   	/* a good kick exercises your dex */ 47.  	exercise(A_DEX, TRUE); 48.   49.   	/* squeeze some guilt feelings... */ 50.   	if(mon->mtame) { 51.  #ifdef SOUNDS 52.  	    if (rn2(10)) yelp(mon); 53.  	    else growl(mon); /* give them a moment's worry */ 54.  #endif 55.  	    mon->mtame--; 56.  	    if(!mon->mtame) newsym(mon->mx, mon->my); 57.  	    mon->mflee = mon->mtame ? 1 : 0; 58.   #ifdef HISX 59.  	    mon->mfleetim = mon->mfleetim + (dmg ? rnd(dmg) : 1); 60.  #else 61.  	    mon->mfleetim += (dmg ? rnd(dmg) : 1); 62.  #endif 63.  	}  64.    65.   	if (dmg) 66.  		mon->mhp -= (!martial ? rnd(dmg) :  67.   			rnd(dmg)+rnd(ACURR(A_DEX)/2)); 68.  	if(mon->mhp < 1) { 69.  		(void) passive(mon, TRUE, 0, TRUE); 70.  		killed(mon); 71.  		return; 72.  	}  73.   	if(martial && !bigmonst(mon->data) && !rn2(3) && mon->mcanmove) { 74.  		/* see if the monster has a place to move into */ 75.  		mdx = mon->mx + u.dx; 76.  		mdy = mon->my + u.dy; 77.  		if(goodpos(mdx, mdy, mon, mon->data)) { 78.  			pline("%s reels from the blow.", Monnam(mon)); 79.  			remove_monster(mon->mx, mon->my); 80.  			place_monster(mon, mdx, mdy); 81.  			newsym(mon->mx, mon->my); 82.  			set_apparxy(mon); 83.  		}  84.   	}  85.   	(void) passive(mon, FALSE, 1, TRUE); 86.   87.   /*	it is unchivalrous to attack the defenseless or from behind */ 88.  	if (pl_character[0] == 'K' &&  89.   		u.ualign.type == A_LAWFUL && u.ualign.record > -10 &&  90.   		(!mon->mcanmove || mon->msleep || mon->mflee)) 91.  		adjalign(-1); 92.   93.   }  94.    95.   static void 96.  kick_monster(x, y)  97. register xchar x, y; 98. { 99.   	register boolean clumsy = FALSE; 100. 	register struct monst *mon = m_at(x, y); 101. 	register int i, j;  102. 103. 	bhitpos.x = x;  104. bhitpos.y = y; 105. if(special_case(mon)) return; 106. 	setmangry(mon); 107. #ifdef POLYSELF 108. 	/* Kick attacks by kicking monsters are normal attacks, not special. 109. 	 * If you have >1 kick attack, you get all of them. 110. 	 */  111.  	if (attacktype(uasmon, AT_KICK)) { 112. 	    schar tmp = find_roll_to_hit(mon); 113. 	    for(i=0; imattk[i].aatyp == AT_KICK && multi >= 0) { 115. 		    /* check multi; maybe they had 2 kicks and the first */ 116. 		    /* was a kick against a floating eye */ 117. 		    if (tmp > rnd(20)) { 118. 			int sum; 119.  120.  			You("kick %s.", mon_nam(mon)); 121. 			sum = damageum(mon, &(uasmon->mattk[i])); 122. 			if (sum == 2) 123. 				(void)passive(mon, 1, 0, TRUE); 124. 			else (void)passive(mon, sum, 1, TRUE); 125. 		    } else { 126. 			missum(mon, &(uasmon->mattk[i])); 127. 			(void)passive(mon, 0, 1, TRUE); 128. 		    }  129.  		}  130.  	    }  131.  	    return; 132. 	}  133.  #endif 134.  135.  	/* no need to check POLYSELF since only ghosts, which you can't turn */ 136. 	/* into, are noncorporeal */ 137. 	if(noncorporeal(mon->data)) { 138. 		Your("kick passes through!"); 139. 		return; 140. 	}  141.   142.  	if(Levitation && !rn2(3) && verysmall(mon->data) &&  143.  	   !is_flyer(mon->data)) { 144. 		pline("Floating in the air, you miss wildly!"); 145. 		exercise(A_DEX, FALSE); 146. 		(void) passive(mon, FALSE, 1, TRUE); 147. 		return; 148. 	}  149.   150.  	i = -inv_weight; 151. 	j = weight_cap; 152.  153.  	if(i < (j*3)/10) { 154. 		if(!rn2((i < j/10) ? 2 : (i < j/5) ? 3 : 4)) { 155.  			if(martial && !rn2(2)) goto doit; 156. 			Your("clumsy kick does no damage."); 157. 			(void) passive(mon, FALSE, 1, TRUE); 158. 			return; 159. 		}  160.  		if(i < j/10) clumsy = TRUE; 161. 		else if(!rn2((i < j/5) ? 2 : 3)) clumsy = TRUE; 162. 	}  163.   164.  	if(Fumbling) clumsy = TRUE; 165.  166.  	else if(uarm && objects[uarm->otyp].oc_bulky && ACURR(A_DEX) < rnd(25)) 167. 		clumsy = TRUE; 168. doit: 169. 	You("kick %s.", mon_nam(mon)); 170. 	if(!rn2(clumsy ? 3 : 4) && (clumsy || !bigmonst(mon->data)) && 171.  	   mon->mcansee && !mon->mtrapped && !thick_skinned(mon->data) &&  172.  	   mon->data->mlet != S_EEL && haseyes(mon->data) && mon->mcanmove &&  173.  	   !mon->mstun && !mon->mconf && !mon->msleep &&  174.  	   mon->data->mmove >= 12) { 175. 		if(!nohands(mon->data) && !rn2(martial ? 5 : 3)) { 176.  		    pline("%s blocks your %skick.", Monnam(mon),  177.  				clumsy ? "clumsy " : ""); 178. 		    (void) passive(mon, FALSE, 1, TRUE); 179. 		    return; 180. 		} else { 181. 		    mnexto(mon); 182. 		    if(mon->mx != x || mon->my != y) { 183. 			pline("%s %s, %s evading your %skick.", Monnam(mon),  184.  				(can_teleport(mon->data) ? "teleports" : 185. 				 is_floater(mon->data) ? "floats" : 186. 				 is_flyer(mon->data) ? "flutters" : 187. 				 nolimbs(mon->data) ? "slides" : 188. 				 "jumps"),  189.  				clumsy ? "easily" : "nimbly",  190.  				clumsy ? "clumsy " : ""); 191. 			(void) passive(mon, FALSE, 1, TRUE); 192. 			return; 193. 		    }  194.  		}  195.  	}  196.  	kickdmg(mon, clumsy); 197. }  198.   199.  /*  200.   *  Return TRUE if caught (the gold taken care of), FALSE otherwise. 201.  *  The gold object is *not* attached to the fobj chain! 202.  */  203.  boolean 204. ghitm(mtmp, gold) 205. register struct monst *mtmp; 206. register struct obj *gold; 207. {  208.  	if(!likes_gold(mtmp->data) && !mtmp->isshk && !mtmp->ispriest  209.  #ifdef ARMY  210.  		&& !is_mercenary(mtmp->data)  211.  #endif  212.  		) { 213. 		wakeup(mtmp); 214. 	} else if (!mtmp->mcanmove) { 215. 		/* too light to do real damage */ 216. 		if (canseemon(mtmp)) 217. 		    pline("The gold hits %s.", mon_nam(mtmp)); 218. 	} else { 219. 		mtmp->msleep = 0; 220. 		mtmp->meating = 0; 221. 		if(!rn2(4)) setmangry(mtmp); /* not always pleasing */ 222.  223.  		/* greedy monsters catch gold */ 224. 		if (cansee(mtmp->mx, mtmp->my)) 225. 		    pline("%s catches the gold.", Monnam(mtmp)); 226. 		mtmp->mgold += gold->quan; 227. 		if (mtmp->isshk) { 228. 			long robbed = ESHK(mtmp)->robbed; 229.  230.  			if (robbed) { 231. 				robbed -= gold->quan; 232. 				if (robbed < 0) robbed = 0; 233. 				pline("The amount %scovers %s recent losses.",  234.  					!robbed ? "" : "partially ",  235.  					mtmp->female ? "her" : "his"); 236. 				ESHK(mtmp)->robbed = robbed; 237. 				if(!robbed) 238. 					make_happy_shk(mtmp, FALSE); 239. 			} else { 240. 				if(mtmp->mpeaceful) { 241. 				    ESHK(mtmp)->credit += gold->quan; 242. 				    You("have %ld zorkmid%s in credit.",  243.  					ESHK(mtmp)->credit,  244.  					plur(ESHK(mtmp)->credit)); 245. 				} else verbalize("Thanks, scum!"); 246. 			}  247.  		}  248.  		else if(mtmp->ispriest) { 249. 			if(mtmp->mpeaceful) 250. 			    verbalize("Thank you for your contribution."); 251. 			else verbalize("Thanks, scum!"); 252. 		}  253.  		else if(is_mercenary(mtmp->data)) { 254. 		    if(rn2(3)) { 255. 			if(mtmp->data == &mons[PM_SOLDIER]) { 256. 			   if(gold->quan > 100 + (u.ugold + (u.ulevel*rn2(5)))  257.  					    /ACURR(A_CHA)) 258. 			    mtmp->mpeaceful = 1; 259. 			    }  260.  			if(mtmp->data == &mons[PM_SERGEANT]) { 261. 			   if(gold->quan > 250 + (u.ugold + (u.ulevel*rn2(5)))  262.  					    /ACURR(A_CHA)) 263. 			    mtmp->mpeaceful = 1; 264. 			    }  265.  			if(mtmp->data == &mons[PM_LIEUTENANT]) { 266. 			   if(gold->quan > 500 + (u.ugold + (u.ulevel*rn2(5)))  267.  					    /ACURR(A_CHA)) 268. 			    mtmp->mpeaceful = 1; 269. 			    }  270.  			if(mtmp->data == &mons[PM_CAPTAIN]) { 271. 			   if(gold->quan > 750 + (u.ugold + (u.ulevel*rn2(5)))  272.  					    /ACURR(A_CHA)) 273. 			    mtmp->mpeaceful = 1; 274. 			    }  275.  		     }  276.  		     if(mtmp->mpeaceful) 277. 			    verbalize("That should do.  Now beat it!"); 278. 		     else verbalize("That's not enough, coward!"); 279. 		     }  280.   281.  		dealloc_obj(gold); 282. 		return(1); 283. 	}  284.  	return(0); 285. }  286.   287.  static int 288. kick_object(x, y)  289. xchar x, y; 290. { 291.  	int range; 292. 	register struct monst *mon, *shkp; 293. 	register struct obj *otmp; 294. 	struct trap *trap; 295. 	boolean costly, insider, shipit; 296. 	boolean isgold; 297.  298.  	/* if a pile, the "top" object gets kicked */ 299. 	kickobj = level.objects[x][y]; 300.  301.  	/* kickobj should always be set due to conditions of call */ 302. 	if(!kickobj || kickobj->otyp == BOULDER  303.  			|| kickobj == uball || kickobj == uchain) 304. 		return(0); 305.  306.  	if((trap = t_at(x,y)) && trap->tseen) { 307. 		if (((trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) 308. #ifdef POLYSELF 309. 			&& !passes_walls(uasmon) 310. #endif 311. 			) || trap->ttyp == WEB) { 312. 			You("can't kick something that's in a %s!",  313.  				trap->ttyp == WEB ? "web" : "pit"); 314. 			return(1); 315. 		}  316.  	}  317.   318.  	if(Fumbling && !rn2(3)) { 319. 		Your("clumsy kick missed."); 320. 		return(1); 321. 	}  322.   323.  	/* range < 2 means the object will not move. */ 324.  	/* maybe dexterity should also figure here. */ 325.  	range = (int)((ACURRSTR)/2 - kickobj->owt/40); 326.  327.  	if(martial) range += rnd(3); 328.  329.  	/* Mjollnir is magically too heavy to kick */ 330. 	if(kickobj->oartifact == ART_MJOLLNIR) range = 1; 331.  332.  	/* see if the object has a place to move into */ 333. 	if(!ZAP_POS(levl[x+u.dx][y+u.dy].typ) || closed_door(x+u.dx, y+u.dy)) 334. 		range = 1; 335.  336.  	costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) &&  337.  		                     costly_spot(x, y)); 338. 	insider = (*u.ushops && inside_shop(u.ux, u.uy) &&  339.  				    *in_rooms(x, y, SHOPBASE) == *u.ushops); 340.  341.  	/* a box gets a chance of breaking open here */ 342. 	if(Is_box(kickobj)) { 343. 		boolean otrp = kickobj->otrapped; 344. 		struct obj *otmp2, *probj = (struct obj *) 0, *temp; 345. 		long loss = 0L; 346.  347.  		if(range < 2) pline("THUD!"); 348.  349.  		for(otmp = kickobj->cobj; otmp; otmp = otmp2) { 350. 			otmp2 = otmp->nobj; 351. 			if (objects[otmp->otyp].oc_material == GLASS  352.  								&& !rn2(3)) { 353. 				You("hear a muffled shatter."); 354. 				if(costly) loss += stolen_value(otmp, x, y,  355.  					    (boolean)shkp->mpeaceful, TRUE); 356. 				if (otmp->quan > 1L) 357. 					useup(otmp); 358. 				else { 359. 					temp = otmp; 360. 					if (otmp == kickobj->cobj) { 361. 						kickobj->cobj = otmp->nobj; 362. 						otmp = (struct obj *) 0; 363. 					} else { 364. 						probj->nobj = otmp->nobj; 365. 						otmp = probj; 366. 					}  367.  					obfree(temp, (struct obj *) 0); 368. 				}  369.  			}  370.  			probj = otmp; 371. 		}  372.  		if(costly && loss) { 373. 		    if(!insider) { 374.   		        You("caused %ld zorkmids worth of damage!", loss); 375. 			make_angry_shk(shkp, x, y); 376. 		    } else 377. 		        You("owe %s %ld zorkmids for objects destroyed.",  378.  			         mon_nam(shkp), loss); 379. 		}  380.   381.  		if (kickobj->olocked) { 382. 		    if (!rn2(5) || (martial && !rn2(2))) { 383. 			You("break open the lock!"); 384. 			kickobj->olocked = 0; 385. 			kickobj->obroken = 1; 386. 			if (otrp) (void) chest_trap(kickobj, LEG, FALSE); 387. 			return(1); 388. 		    }  389.  		} else { 390. 		    if (!rn2(3) || (martial && !rn2(2))) { 391. 			pline("The lid slams open, then falls shut."); 392. 			if (otrp) (void) chest_trap(kickobj, LEG, FALSE); 393. 			return(1); 394. 		    }  395.  		}  396.  		if(range < 2) return(1); 397. 		/* else let it fall through to the next cases... */ 398.  	}  399.   400.  	/* fragile objects should not be kicked */ 401. 	if (breaks(kickobj, FALSE)) return(1); 402.  403.  	/* potions get a chance of breaking here */ 404. 	if(kickobj->oclass == POTION_CLASS) { 405. 		if(rn2(2)) { 406. 		    You("smash %s %s!",  407.  			  kickobj->quan == 1L ? "the" : "a", xname(kickobj)); 408. 		    potionbreathe(kickobj); 409. 		    if(costly) { 410. 		        long loss = stolen_value(kickobj, kickobj->ox,  411.  				   kickobj->oy, (boolean)shkp->mpeaceful, TRUE); 412. 			if(loss) { 413. 			    if(insider) 414. 			      You("owe %ld zorkmids for objects destroyed.",  415.  				                              loss); 416. 			    else { 417.   		           You("caused %ld zorkmids worth of damage!", loss); 418. 			          make_angry_shk(shkp, kickobj->ox,  419.  						                kickobj->oy); 420. 			    }  421.  			}  422.  		    }  423.  		    useupf(kickobj); 424. 		    return(1); 425. 		}  426.  	}  427.   428.  	if(IS_ROCK(levl[x][y].typ)) { 429. 		if ((!martial && rn2(20) > ACURR(A_DEX))  430.  #ifdef POLYSELF  431.  				|| IS_ROCK(levl[u.ux][u.uy].typ)  432.  #endif  433.  								) { 434. 			if (Blind) pline("It doesn't come loose."); 435. 			else pline("%s do%sn't come loose.",  436.  				The(distant_name(kickobj, xname)),  437.  				(kickobj->quan == 1L) ? "es" : ""); 438. 			return(!rn2(3) || martial); 439. 		}  440.  		if (Blind) pline("It comes loose."); 441. 		else pline("%s come%s loose.",  442.  			   The(distant_name(kickobj, xname)),  443.  			   (kickobj->quan == 1L) ? "s" : ""); 444. 		remove_object(kickobj); 445. 		newsym(x, y); 446. 		if (costly && (!costly_spot(u.ux, u.uy) 447. 			       || !index(u.urooms, *in_rooms(x, y, SHOPBASE)))) 448. 			addtobill(kickobj, FALSE, FALSE, FALSE); 449. 		if(!flooreffects(kickobj,u.ux,u.uy,"fall")) { 450. 		    place_object(kickobj, u.ux, u.uy); 451. 		    stackobj(kickobj); 452. 		    newsym(u.ux, u.uy); 453. 		}  454.  		return(1); 455. 	}  456.   457.  	isgold = (kickobj->otyp == GOLD_PIECE); 458.  459.  	/* too heavy to move. range is calculated as potential distance from 460. 	 * player, so range == 2 means the object may move up to one square 461. 	 * from its current position 462. 	 */  463.  	if(range < 2 || (isgold && kickobj->quan > 300L)) { 464. 	    if(!Is_box(kickobj)) pline("Thump!"); 465. 	    return(!rn2(3) || martial); 466. 	}  467.   468.  	if (kickobj->quan > 1L && !isgold) (void) splitobj(kickobj, 1L); 469.  470.  	freeobj(kickobj); 471. 	newsym(x, y); 472. 	mon = bhit(u.dx, u.dy, range, KICKED_WEAPON,  473.  		   (int (*)) 0, (int (*)) 0, kickobj); 474.  475.  	/* a flag to "drop" the object to the next level */ 476. 	shipit = (!mon && down_gate(bhitpos.x, bhitpos.y) != -1); 477.  478.  	if(mon) { 479. 	    notonhead = (mon->mx != bhitpos.x || mon->my != bhitpos.y); 480. 	    /* awake monster if sleeping */ 481. 	    wakeup(mon); 482. 	    if(isgold ? ghitm(mon, kickobj) :	/* caught? */  483.  	       thitmonst(mon, kickobj))		/* hit? */ 484.  		return(1); 485. 	}  486.  	if(costly &&  487.  	   (!costly_spot(bhitpos.x,bhitpos.y) || shipit || 488. 	    *in_rooms(bhitpos.x, bhitpos.y, 0) != *in_rooms(x, y, 0))) { 489.  490.  	    if(shipit && ship_object(kickobj, bhitpos.x, bhitpos.y, costly)) 491. 		return(1); 492.  493.  	    if(isgold) 494. 		costly_gold(x, y, kickobj->quan); 495. 	    else if(costly_spot(u.ux, u.uy) &&  496.  		    index(u.urooms, *in_rooms(x, y, 0))) 497. 		addtobill(kickobj, FALSE, FALSE, FALSE); 498. 	    else (void)stolen_value(kickobj, x, y, FALSE, FALSE); 499. 	}  500.   501.  	if(shipit && ship_object(kickobj, bhitpos.x, bhitpos.y, costly)) 502. 		return(1); 503. 	if(flooreffects(kickobj,bhitpos.x,bhitpos.y,"fall")) return(1); 504. 	kickobj->nobj = fobj; 505. 	fobj = kickobj; 506. 	place_object(kickobj, bhitpos.x, bhitpos.y); 507. 	stackobj(kickobj); 508. 	newsym(kickobj->ox, kickobj->oy); 509. 	return(1); 510. }  511.   512.  static char * 513. kickstr 514. {  515.  	static char NEARDATA buf[BUFSZ]; 516.  517.  	if (kickobj) Sprintf(buf, "kicking %s", doname(kickobj)); 518. 	else { 519. 	  Strcpy(buf, "kicking "); 520. 	  if (IS_STWALL(maploc->typ)) Strcat(buf, "a wall"); 521. 	  else if (IS_ROCK(maploc->typ)) Strcat(buf, "a rock"); 522. 	  else if (IS_THRONE(maploc->typ)) Strcat(buf, "a throne"); 523. #ifdef SINKS 524. 	  else if (IS_SINK(maploc->typ)) Strcat(buf, "a sink"); 525. #endif 526. 	  else if (IS_ALTAR(maploc->typ)) Strcat(buf, "an altar"); 527. 	  else if (IS_DRAWBRIDGE(maploc->typ)) Strcat(buf, "the drawbridge"); 528. 	  else { 529. 		switch (maploc->typ) { 530. 		case STAIRS: 531. 			Strcat(buf, "the stairs"); 532. 			break; 533. 		case LADDER: 534. 			Strcat(buf, "a ladder"); 535. 			break; 536. 		default: 537. 			Strcat(buf, "something wierd"); 538. 			break; 539. 		}  540.  	  }  541.  	}  542.  	return buf; 543. }  544.   545.  int 546. dokick 547. {  548.  	register int x, y;  549. register int avrg_attrib = (ACURRSTR+ACURR(A_DEX)+ACURR(A_CON))/3; 550.  551.  #ifdef POLYSELF 552. 	if(nolimbs(uasmon)) { 553. 		You("have no legs to kick with."); 554. 		return(0); 555. 	}  556.  	if(verysmall(uasmon)) { 557. 		You("are too small to do any kicking."); 558. 		return(0); 559. 	}  560.  #endif 561. 	if(Wounded_legs) { 562. 		Your("%s %s in no shape for kicking.",  563.  		      ((Wounded_legs & BOTH_SIDES)==BOTH_SIDES)  564.  			? (const char *)makeplural(body_part(LEG)) : body_part(LEG),  565.  		      ((Wounded_legs & BOTH_SIDES)==BOTH_SIDES) ? "are" : "is"); 566. 		return(0); 567. 	}  568.   569.  	if(near_capacity > SLT_ENCUMBER) { 570. 		Your("load is too heavy to balance yourself for a kick."); 571. 		return(0); 572. 	}  573.   574.  	if(u.uinwater && !rn2(2)) { 575. 		Your("slow motion kick doesn't hit anything."); 576. 		return(0); 577. 	}  578.   579.  	if(u.utrap) { 580. 		switch (u.utraptype) { 581. 		    case TT_PIT: 582. 			pline("There's nothing to kick down here."); 583. 		    case TT_WEB: 584. 		    case TT_BEARTRAP: 585. 			You("can't move your %s!", body_part(LEG)); 586. 		}  587.  		return(0); 588. 	}  589.   590.  	if(!getdir(NULL)) return(0); 591. 	if(!u.dx && !u.dy) return(0); 592.  593.  	x = u.ux + u.dx; 594. 	y = u.uy + u.dy; 595.  596.  	if(u.uswallow) { 597. 		switch(rn2(3)) { 598. 		case 0:  You("can't move your %s!", body_part(LEG)); 599. 			 break; 600. 		case 1:  if (is_animal(u.ustuck->data)) { 601. 				pline("%s burps loudly.", Monnam(u.ustuck)); 602. 				break; 603. 			 }  604.  		default: Your("feeble kick has no effect."); break; 605. 		}  606.  		return(1); 607. 	}  608.   609.  	wake_nearby; 610. 	u_wipe_engr(2); 611.  612.  	maploc = &levl[x][y]; 613.  614.  	/* The next four tests should stay in      */ 615. 	/* their present order: monsters, objects, */ 616. 	/* non-doors, doors. */ 617.   618.  	if(MON_AT(x, y)) { 619. 		kick_monster(x, y); 620. 		if((Is_airlevel(&u.uz) || Levitation) && flags.move) { 621. 		    int range; 622. 		    struct monst *mon; 623.  624.  		    mon = m_at(x,y); 625. 		    range = (3*(int)mon->data->cwt) / 626. 			((int)uasmon->cwt + (weight_cap + inv_weight)); 627. 		    if(range < 1) range = 1; 628. 		    hurtle(-u.dx, -u.dy, range); 629. 		}  630.  		return(1); 631. 	}  632.   633.  	kickobj = (struct obj *)0; 634. 	if (OBJ_AT(x, y) &&  635.  	    (!Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) 636. 	     || sobj_at(BOULDER,x,y))) { 637. 		if(kick_object(x, y)) { 638. 		    if(Is_airlevel(&u.uz)) 639. 			hurtle(-u.dx, -u.dy, 1); /* assume it's light */ 640. 		    return(1); 641. 		}  642.  		goto ouch; 643. 	}  644.   645.  	if(!IS_DOOR(maploc->typ)) { 646. 		if(maploc->typ == SDOOR) { 647. 		    if(!Levitation && rn2(30) < avrg_attrib) { 648. 			pline("Crash!  You kick open a secret door!"); 649. 			exercise(A_DEX, TRUE); 650. 			maploc->typ = DOOR; 651. 			if(maploc->doormask & D_TRAPPED) { 652. 			    b_trapped("door"); 653. 			    maploc->doormask = D_NODOOR; 654. 			} else 655. 			    maploc->doormask = D_ISOPEN; 656. 			if (Blind) 657. 			    feel_location(x,y);	/* we know its gone */ 658. 			else 659. 			    newsym(x,y); 660. 			unblock_point(x,y);	/* vision */ 661. 			return(1); 662. 		    } else goto ouch; 663. 		}  664.  		if(maploc->typ == SCORR) { 665. 		    if(!Levitation && rn2(30) < avrg_attrib) { 666. 			pline("Crash!  You kick open a secret passage!"); 667. 			exercise(A_DEX, TRUE); 668. 			maploc->typ = CORR; 669. 			if (Blind) 670. 			    feel_location(x,y);	/* we known its gone */ 671. 			else 672. 			    newsym(x,y); 673. 			unblock_point(x,y);	/* vision */ 674. 			return(1); 675. 		    } else goto ouch; 676. 		}  677.  		if(IS_THRONE(maploc->typ)) { 678. 		    register int i;  679. if(Levitation) goto dumb; 680. 		    if((Luck < 0 || maploc->doormask) && !rn2(3)) { 681. 			maploc->typ = ROOM; 682. 			maploc->doormask = 0; /* don't leave loose ends.. */ 683.  			mkgold((long)rnd(200), x, y); 684. 			if (Blind) 685. 			    pline("CRASH!  You destroy it."); 686. 			else { 687. 			    pline("CRASH!  You destroy the throne."); 688. 			    newsym(x, y); 689. 			}  690.  			exercise(A_DEX, TRUE); 691. 			return(1); 692. 		    } else if(Luck > 0 && !rn2(3) && !maploc->looted) { 693. 			mkgold((long) rn1(201, 300), x, y); 694. 			i = Luck + 1; 695. 			if(i > 6) i = 6; 696. 			while(i--) (void) mkobj_at(GEM_CLASS, x, y, TRUE); 697. 			if (Blind) 698. 			    You("kick something loose!"); 699. 			else { 700. 			    You("kick loose some ornamental coins and gems!"); 701. 			    newsym(x, y); 702. 			}  703.  			/* prevent endless milking */ 704. 			maploc->looted = T_LOOTED; 705. 			return(1); 706. 		    } else if (!rn2(4)) { 707. 			if(dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)) { 708. 			    fall_through(FALSE); 709. 			    return(1); 710. 			} else goto ouch; 711. 		    }  712.  		    goto ouch; 713. 		}  714.  		if(IS_ALTAR(maploc->typ)) { 715. 		    if(Levitation) goto dumb; 716. 		    You("kick %s.",(Blind ? "something" : "the altar")); 717. 		    if(!rn2(3)) goto ouch; 718. 		    altar_wrath(x, y); 719. 		    exercise(A_DEX, TRUE); 720. 		    return(1); 721. 		}  722.  #ifdef SINKS 723. 		if(IS_SINK(maploc->typ)) { 724. 		    if(Levitation) goto dumb; 725. 		    if(rn2(5)) { 726. 			if(flags.soundok) 727. 			    pline("Klunk!  The pipes vibrate noisily."); 728. 			else pline("Klunk!"); 729. 			exercise(A_DEX, TRUE); 730. 			return(1); 731. 		    } else if(!(maploc->looted & S_LPUDDING) && !rn2(3) &&  732.  			  !(mons[PM_BLACK_PUDDING].geno & 733. 				(G_GENOD | G_EXTINCT))) { 734. 			if (Blind) 735. 			    You("hear a gushing sound."); 736. 			else 737. 			    pline("A %s ooze gushes up from the drain!",  738.  					  Hallucination ? hcolor : Black); 739. 			(void) makemon(&mons[PM_BLACK_PUDDING], x, y); 740. 			exercise(A_DEX, TRUE); 741. 			newsym(x,y); 742. 			maploc->looted |= S_LPUDDING; 743. 			return(1); 744. 		    } else if(!(maploc->looted & S_LDWASHER) && !rn2(3) &&  745.  # ifndef POLYSELF  746.  			      poly_gender != 2 &&  747.  # endif  748.  			      !(mons[poly_gender == 1 ? 749. 				      PM_INCUBUS : PM_SUCCUBUS].geno & 750. 				  (G_GENOD | G_EXTINCT))) { 751. 			/* can't resist... */ 752.  			pline("%s returns!", (Blind ? "Something" : 753. 							"The dish washer")); 754. 			if (makemon(&mons[poly_gender == 1 ? 755. 				PM_INCUBUS : PM_SUCCUBUS], x, y)) newsym(x,y); 756. 			maploc->looted |= S_LDWASHER; 757. 			exercise(A_DEX, TRUE); 758. 			return(1); 759. 		    } else if(!rn2(3)) { 760. 			pline("Flupp!  %s.", (Blind ? 761. 				      "You hear a sloshing sound" : 762. 				      "Muddy waste pops up from the drain")); 763. 			if(!(maploc->looted & S_LRING)) { /* once per sink */ 764. 			    if (!Blind) 765. 				You("see a ring shining in its midst."); 766. 			    (void) mkobj_at(RING_CLASS, x, y, TRUE); 767. 			    newsym(x, y); 768. 			    exercise(A_DEX, TRUE); 769. 			    exercise(A_WIS, TRUE);	/* a discovery! */ 770.  			    maploc->looted |= S_LRING; 771. 			}  772.  			return(1); 773. 		    }  774.  		    goto ouch; 775. 		}  776.  #endif 777. 		if (maploc->typ == STAIRS || maploc->typ == LADDER ||  778.  						    IS_STWALL(maploc->typ)) { 779. 		    if(!IS_STWALL(maploc->typ) && maploc->ladder == LA_DOWN) 780. 			goto dumb; 781. ouch: 782. 		    pline("Ouch!  That hurts!"); 783. 		    exercise(A_DEX, FALSE); 784. 		    exercise(A_STR, FALSE); 785. 		    if (Blind) feel_location(x,y); /* we know we hit it */ 786. 		    if(!rn2(3)) set_wounded_legs(RIGHT_SIDE, 5 + rnd(5)); 787. 		    losehp(rnd(ACURR(A_CON) > 15 ? 3 : 5), kickstr, 788.  			KILLED_BY); 789. 		    if(Is_airlevel(&u.uz) || Levitation) 790. 			hurtle(-u.dx, -u.dy, rn1(2,4)); /* assume it's heavy */ 791. 		    return(1); 792. 		}  793.  		if (is_drawbridge_wall(x,y) >= 0) { 794. 		    pline("The drawbridge is unaffected."); 795. 		    if(Levitation) 796. 			hurtle(-u.dx, -u.dy, rn1(2,4)); /* it's heavy */ 797. 		    return(1); 798. 		}  799.  		goto dumb; 800. 	}  801.   802.  	if(maploc->doormask == D_ISOPEN ||  803.  	   maploc->doormask == D_BROKEN ||  804.  	   maploc->doormask == D_NODOOR) { 805. dumb: 806. 		exercise(A_DEX, FALSE); 807. 		if (martial || ACURR(A_DEX) >= 16 || rn2(3)) { 808. 			You("kick at empty space."); 809. 		} else { 810. 			pline("Dumb move!  You strain a muscle."); 811. 			exercise(A_STR, FALSE); 812. 			set_wounded_legs(RIGHT_SIDE, 5 + rnd(5)); 813. 		}  814.  		if(Is_airlevel(&u.uz) || Levitation) 815. 		    hurtle(-u.dx, -u.dy, rn2(2)); 816. 		return(0); 817. 	}  818.   819.  	/* not enough leverage to kick open doors while levitating */ 820. 	if(Levitation) goto ouch; 821.  822.  	exercise(A_DEX, TRUE); 823. 	/* door is known to be CLOSED or LOCKED */ 824. 	if(rnl(35) < avrg_attrib + (!martial ? 0 : ACURR(A_DEX))) { 825. 		/* break the door */ 826. 		if(maploc->doormask & D_TRAPPED) { 827. 		    pline("As you kick the door, it explodes!"); 828. 		    exercise(A_STR, FALSE); 829. 		    b_trapped("door"); 830. 		    maploc->doormask = D_NODOOR; 831. 		} else if(ACURR(A_STR) > 18 && !rn2(5) &&  832.  			  !*in_rooms(x, y, SHOPBASE)) { 833. 		    pline("As you kick the door, it shatters to pieces!"); 834. 		    exercise(A_STR, TRUE); 835. 		    maploc->doormask = D_NODOOR; 836. 		} else { 837. 		    pline("As you kick the door, it crashes open!"); 838. 		    exercise(A_STR, TRUE); 839. 		    if(*in_rooms(x, y, SHOPBASE)) { 840. 			add_damage(x, y, 400L); 841. 			pay_for_damage("break"); 842. 		    }  843.  		    maploc->doormask = D_BROKEN; 844. 		}  845.  		if (Blind) 846. 		    feel_location(x,y);		/* we know we broke it */ 847. 		else 848. 		    newsym(x,y); 849. 		unblock_point(x,y);		/* vision */ 850. 	} else { 851. 	    if (Blind) feel_location(x,y);	/* we know we hit it */ 852. 	    exercise(A_STR, TRUE); 853. 	    pline("WHAMMM!!!"); 854. 	}  855.  	return(1); 856. }  857.   858.  static const char * 859. gate_str(gate) 860. register xchar gate; 861. {  862.  	const char *optr; 863.  864.  	switch(gate) { 865. 	    case 0: 866. 	    case 4:  optr = "through the trap door."; break; 867. 	    case 1: 868. 	    case 3:  optr = "down the stairs."; break; 869. 	    case 2:  optr = "down the ladder."; break; 870. 	    default: optr = "down out of sight."; break; 871. 	}  872.  	return(optr); 873. }  874.   875.  static 876. void 877. drop_to(cc, loc) 878. coord *cc; 879. register xchar loc; 880. {  881.  	switch(loc) { 882. 	    case 0: if(In_endgame(&u.uz) || (Is_botlevel(&u.uz) && 883. 			      !Is_stronghold(&u.uz))) { 884. 			cc->y = 0; 885. 			return; 886. 		    }  887.  		    if(Is_stronghold(&u.uz)) { 888. 			cc->x = valley_level.dnum; 889. 			cc->y = valley_level.dlevel; 890. 			break; 891. 		    } /* else fall to the next cases */ 892. 	    case 1: 893. 	    case 2: 894. 		    cc->x = u.uz.dnum; 895. 		    cc->y = u.uz.dlevel + 1; 896. 		    break; 897. 	    case 3: 898. 		    cc->x = sstairs.tolev.dnum; 899. 		    cc->y = sstairs.tolev.dlevel; 900. 		    break; 901. 	    default: 902. 		    cc->y = 0; 903. 	}  904.  }  905.   906.  void 907. impact_drop(missile, x, y, dlev) 908. register struct obj *missile; 909. register xchar x, y, dlev; 910. {  911.  	xchar toloc; 912. 	register struct obj *obj, *obj2; 913. 	register struct monst *shkp; 914. 	long oct, dct, price, debit, robbed; 915. 	boolean angry, costly, isrock; 916. 	coord cc; 917.  918.  	if(!OBJ_AT(x, y)) return; 919.  920.  	toloc = down_gate(x, y); 921. 	drop_to(&cc, toloc); 922. 	if (!cc.y) return; 923.  924.  	if (dlev) { 925. 		/* send objects next to player falling through trap door. 926. 		 * checked in obj_delivery. 927. 		 */  928.  		toloc = 4; 929. 		cc.y = dlev; 930. 	}  931.   932.  	costly = costly_spot(x, y); 933. 	price = debit = robbed = 0L; 934. 	angry = FALSE; 935. 	shkp = (struct monst *) 0; 936. 	/* if 'costly', we must keep a record of ESHK(shkp) before 937. 	 * it undergoes changes through the calls to stolen_value. 938. 	 * the angry bit must be reset, if needed, in this fn, since 939. 	 * stolen_value is called under the 'silent' flag to avoid 940. 	 * unsavory pline repetitions. 941. 	 */  942.  	if(costly) { 943. 	    if((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) !=  944.  	                                           (struct monst *)0) { 945. 		debit	= ESHK(shkp)->debit; 946. 		robbed	= ESHK(shkp)->robbed; 947. 		angry	= !shkp->mpeaceful; 948. 	    }  949.  	}  950.   951.  	isrock = (missile && missile->otyp == ROCK); 952. 	oct = dct = 0L; 953. 	for(obj = level.objects[x][y]; obj; obj = obj2) { 954. 		obj2 = obj->nexthere; 955. 		if(obj == missile) continue; 956. 		/* number of objects in the pile */ 957. 		oct += obj->quan; 958. 		/* boulders can fall too, but rarely & never due to rocks */ 959. 		if((isrock && obj->otyp == BOULDER) ||  960.  		   rn2(obj->otyp == BOULDER ? 30 : 3)) continue; 961. 		freeobj(obj); 962.  963.  		if(costly) { 964. 		    price += stolen_value(obj, x, y,  965.  				(costly_spot(u.ux, u.uy) && 966. 				 index(u.urooms, *in_rooms(x, y, SHOPBASE))),  967.  				TRUE); 968. 		    /* set obj->no_charge to 0 */ 969. 		    if(Is_container(obj)) 970. 		        picked_container(obj); /* does the right thing */ 971. 		    if(obj->otyp != GOLD_PIECE) 972. 		        obj->no_charge = 0; 973. 		}  974.  		obj->nobj = migrating_objs; 975. 		migrating_objs = obj; 976.  977.  		obj->ox = cc.x;  978. obj->oy = cc.y; 979. obj->owornmask = (long)toloc; 980.  981.  		/* number of fallen objects */ 982. 		dct += obj->quan; 983. 	}  984.   985.  	if (dct) {	/* at least one object fell */ 986. 	    const char *what = (dct == 1L ? "object falls" : "objects fall"); 987. 	    if (missile) 988. 		pline("From the impact, %sother %s.",  989.  			dct == oct ? "the " : dct == 1L ? "an" : "", what); 990. 	    else 991. 		pline("%s adjacent %s %s",  992.  			oct == dct ? (dct > 1L ? "All the" : "The") : 993.  			    (dct == 1L ? "One of the" : "Some of the"), 994.  			what, gate_str(toloc)); 995. 	}  996.   997.  	if(costly && shkp && price) { 998. 		if(ESHK(shkp)->robbed > robbed) { 999. 		    You("removed %ld zorkmids worth of goods!", price); 1000. 		   if(cansee(shkp->mx, shkp->my)) { 1001. 			if(ESHK(shkp)->customer[0] == 0) 1002. 			   (void) strncpy(ESHK(shkp)->customer,  1003. 					   plname, PL_NSIZ); 1004. 			if(angry) 1005. 			   pline("%s is infuriated!", Monnam(shkp)); 1006. 			else pline("\"%s, you are a thief!\"", plname); 1007. 		   } else  You("hear a scream, \"Thief!\""); 1008. 		   hot_pursuit(shkp); 1009. 		   (void) angry_guards(FALSE); 1010. 		   return; 1011. 		} 1012. 		if(ESHK(shkp)->debit > debit) 1013. 		   You("owe %s %ld zorkmids for goods lost.",  1014. 			Monnam(shkp),  1015. 			(ESHK(shkp)->debit - debit)); 1016. 	} 1017.  1018. }  1019.  1020. /* NOTE: ship_object assumes otmp was FREED from fobj or invent. 1021. *  is the point of drop. otmp is _not_ an  resident: 1022. * otmp is either a kicked, dropped, or thrown object. 1023. */  1024. boolean 1025. ship_object(otmp, x, y, shop_floor_obj) 1026. register xchar x, y;  1027. register struct obj *otmp; 1028. register boolean shop_floor_obj; 1029. { 1030. 	register xchar ox, oy; 1031. 	register xchar toloc = down_gate(x, y); 1032. 	/* toloc -- destination location: */ 1033. 		/*	0: rnd loc, 1034. 		 *	1: <, 1035. 		 *	2: < ladder, 1036. 		 *	3: sstairs up 1037. *	4: near player (trapdoor) 1038. 		 */ 1039. 	coord cc; 1040. 	/* objects always fall down ladder, a chance of stay otherwise */ 1041. 	register boolean nodrop = (toloc != 2 && rn2(3)); 1042. 	register boolean unpaid, container, impact = FALSE; 1043. 	int n = 0; 1044. 1045. 	if(!otmp) return(FALSE); 1046. 	if(toloc == -1) return(FALSE); 1047. 1048. 	drop_to(&cc, toloc); 1049. 	if(!cc.y) return(FALSE); 1050. 1051. 	container = Is_container(otmp); 1052. 1053. 	unpaid = (otmp->unpaid || (container && count_unpaid(otmp->cobj))); 1054. 1055. 	if(OBJ_AT(x, y)) { 1056. 	   register struct obj *obj; 1057. 1058. 	    for(obj = level.objects[x][y]; obj; obj = obj->nexthere) 1059. 		if(obj != otmp) n++; 1060. 	   if(n) impact = TRUE; 1061. 	} 1062.  1063. 	otransit_msg(otmp, toloc, nodrop, n); 1064. 1065. 	if(nodrop) { 1066. 	   otmp->nobj = fobj; 1067. 	   fobj = otmp; 1068. 	   place_object(otmp, x, y); 1069. 	   stackobj(otmp); 1070. 	   newsym(otmp->ox, otmp->oy); 1071. 	   if(impact) goto chain_reaction; 1072. 	   else return(TRUE); 1073. 	} 1074.  1075. 	if(unpaid || shop_floor_obj) { 1076. 	   if(unpaid) { 1077. 		subfrombill(otmp, shop_keeper(*u.ushops)); 1078. 		(void)stolen_value(otmp, u.ux, u.uy, TRUE, FALSE); 1079. 	   } else { 1080. 	       ox = otmp->ox; 1081. 		oy = otmp->oy; 1082. 		(void)stolen_value(otmp, ox, oy, 1083. 			  (costly_spot(u.ux, u.uy) && 1084. 			     index(u.urooms, *in_rooms(ox, oy, SHOPBASE))),  1085. 			  FALSE); 1086. 	   }  1087. 	    /* set otmp->no_charge to 0 */ 1088. 	   if(container) 1089. 	       picked_container(otmp); /* happens to do the right thing */ 1090. 	   if(otmp->otyp != GOLD_PIECE) 1091. 	       otmp->no_charge = 0; 1092. 	} 1093.  1094. 	otmp->nobj = migrating_objs; 1095. 	migrating_objs = otmp; 1096. 1097. 	otmp->ox = cc.x;  1098. otmp->oy = cc.y; 1099. otmp->owornmask = (long)toloc; 1100. chain_reaction: 1101. 	if(impact) { 1102. 	   /* the objs impacted may be in a shop other than 1103. 	    * the one in which the hero is located. another 1104. 	    * check for a shk is made in impact_drop. it is, e.g., 1105. 	    * possible to kick/throw an object belonging to one 1106. 	    * shop into another shop through a gap in the wall, 1107. 	    * and cause objects belonging to the other shop to  1108. * fall down a trapdoor--thereby getting two shopkeepers 1109. 	    * angry at the hero in one shot. 1110. 	    */  1111. 	    impact_drop(otmp, x, y, 0); 1112. 	   newsym(x,y); 1113. 	} 1114. 	return(TRUE); 1115. } 1116.  1117. void 1118. obj_delivery 1119. { 1120. 	register struct obj *otmp, *otmp0 = (struct obj *)0, *otmp2; 1121. 1122. 	for(otmp = migrating_objs; otmp; otmp = otmp2) { 1123. 1124. 	    otmp2 = otmp->nobj; 1125. 1126. 	    if(otmp->ox == u.uz.dnum && otmp->oy == u.uz.dlevel) { 1127. 		if(otmp == migrating_objs) 1128. 		   migrating_objs = otmp->nobj; 1129. 		else 1130. 		   otmp0->nobj = otmp->nobj; 1131. 		otmp->nobj = fobj; 1132. 		fobj = otmp; 1133. 1134. 		switch((xchar)otmp->owornmask) { 1135. 		   xchar *xlocale, *ylocale; 1136. 1137. 		    case 1: xlocale = &xupstair; ylocale = &yupstair; 1138. 			   goto common; 1139. 		   case 2: xlocale = &xupladder; ylocale = &yupladder; 1140. 			   goto common; 1141. 		   case 3: xlocale = &sstairs.sx; ylocale = &sstairs.sy; 1142. 			   goto common; 1143. 		   case 4: { /* hero falls down trapdoor with objects */ 1144. 			     xchar nx, ny; 1145. 			     int cnt = 0; 1146. 1147. 			      do { 1148. 				 nx = u.ux - 1 + rn2(3); 1149. 				 ny = u.uy - 1 + rn2(3); 1150. 			     } while((nx < 1 || nx > COLNO-2 || 1151. 				      ny < 1 || ny > ROWNO-2 || 1152. 				      is_pool(nx,ny) || is_lava(nx,ny) || 1153. 				      !ACCESSIBLE(levl[nx][ny].typ) || 1154. 				      closed_door(nx, ny) 1155. 				     ) && cnt++ <= 50); 1156. 1157. 			      if(cnt >= 50) goto scatter; /* safety */ 1158. 			     xlocale = &nx; 1159. 			     ylocale = &ny; 1160. 			   }  1161. common: 1162. 			   if (*xlocale && *ylocale) { 1163. 				place_object(otmp, *xlocale, *ylocale); 1164. 				stackobj(otmp); 1165. 				break; 1166. 			   } /* else fall through */ 1167. 		   default: 1168. scatter: 1169. 			   rloco(otmp); 1170. 			   break; 1171. 		} 1172. 		otmp->owornmask = 0L; 1173. 	   } else 1174. 		otmp0 = otmp; 1175. 	} 1176. }  1177.  1178. static void 1179. otransit_msg(otmp, loc, nodrop, num) 1180. register struct obj *otmp; 1181. register xchar loc; 1182. register boolean nodrop; 1183. int num; 1184. { 1185. 	char obuf[BUFSZ]; 1186. 1187. 	Sprintf(obuf, "%s%s",  1188. 		 (otmp->otyp == CORPSE && 1189. 			type_is_pname(&mons[otmp->corpsenm])) ? "" : "The ", 1190. 		 xname(otmp)); 1191. 1192. 	if(num) { /* means: other objects are impacted */ 1193. 	   Sprintf(eos(obuf), " hit%s %s object%s",  1194. 		      otmp->quan == 1L ? "s" : "",  1195. 		      num == 1 ? "another" : "other",  1196. 		      num > 1 ? "s" : ""); 1197. 	   if(nodrop) 1198. 		Sprintf(eos(obuf), " and stop%s.", 1199. 				 otmp->quan == 1L ? "s" : ""); 1200. 	   else 1201. 		Sprintf(eos(obuf), " and fall%s %s", 1202. 				otmp->quan == 1L ? "s" : "", gate_str(loc)); 1203. 	   pline(obuf); 1204. 	} else if(!nodrop) 1205. 	   pline("%s fall%s %s", obuf,  1206. 		  otmp->quan == 1L ? "s" : "",  1207. 		  gate_str(loc)); 1208. } 1209.  1210. xchar 1211. down_gate(x, y) 1212. xchar x, y; 1213. { 1214. 	register struct trap *ttmp = t_at(x, y); 1215. 1216. 	if(ttmp && ttmp->ttyp == TRAPDOOR && ttmp->tseen) return 0; 1217. 	if(xdnstair == x && ydnstair == y) return 1; 1218. 	if(xdnladder == x && ydnladder == y) return 2; 1219. 	if(sstairs.sx == x && sstairs.sy == y && !sstairs.up) return 3; 1220. 	return -1; 1221. } 1222.  1223. /*dokick.c*/