Source:NetHack 3.1.0/dokick.c

From NetHackWiki
Revision as of 06:18, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.1.0/dokick.c moved to Source:NetHack 3.1.0/dokick.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

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