Source:NetHack 3.3.0/dokick.c

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