Source:SLASH'EM 0.0.7E7F2/dokick.c

Below is the full text to dokick.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/dokick.c#line123 ]], for example.

The latest source code for vanilla NetHack is at Source code.

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