Wikia

Wikihack

Source:Dbridge.c

2,032pages on
this wiki
Talk0

Below is the full text to src/dbridge.c from NetHack 3.4.3. To link to a particular line, write [[dbridge.c#line123]], for example.

Top of file Edit

1.    /*	SCCS Id: @(#)dbridge.c	3.4	2003/02/08	*/
2.    /*	Copyright (c) 1989 by Jean-Christophe Collet		  */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
5.    /*
6.     * This file contains the drawbridge manipulation (create, open, close,
7.     * destroy).
8.     *
9.     * Added comprehensive monster-handling, and the "entity" structure to
10.    * deal with players as well. - 11/89
11.    */
12.   
13.   #include "hack.h"
14.   
15.   #ifdef OVLB
16.   STATIC_DCL void FDECL(get_wall_for_db, (int *, int *));
17.   STATIC_DCL struct entity *FDECL(e_at, (int, int));
18.   STATIC_DCL void FDECL(m_to_e, (struct monst *, int, int, struct entity *));
19.   STATIC_DCL void FDECL(u_to_e, (struct entity *));
20.   STATIC_DCL void FDECL(set_entity, (int, int, struct entity *));
21.   STATIC_DCL const char *FDECL(e_nam, (struct entity *));
22.   #ifdef D_DEBUG
23.   static const char *FDECL(Enam, (struct entity *)); /* unused */
24.   #endif
25.   STATIC_DCL const char *FDECL(E_phrase, (struct entity *, const char *));
26.   STATIC_DCL boolean FDECL(e_survives_at, (struct entity *, int, int));
27.   STATIC_DCL void FDECL(e_died, (struct entity *, int, int));
28.   STATIC_DCL boolean FDECL(automiss, (struct entity *));
29.   STATIC_DCL boolean FDECL(e_missed, (struct entity *, BOOLEAN_P));
30.   STATIC_DCL boolean FDECL(e_jumps, (struct entity *));
31.   STATIC_DCL void FDECL(do_entity, (struct entity *));
32.   #endif /* OVLB */
33.   

is_pool Edit

is_pool() takes two numbers, an x,y coordinate, and returns TRUE if the terrain at that coordinate is pool of water (even if it is under a drawbridge), FALSE otherwise.

34.   #ifdef OVL0
35.   
36.   boolean
37.   is_pool(x,y)
38.   int x,y;
39.   {
40.       schar ltyp;
41.   
42.       if (!isok(x,y)) return FALSE;
43.       ltyp = levl[x][y].typ;
44.       if (ltyp == POOL || ltyp == MOAT || ltyp == WATER) return TRUE;
45.       if (ltyp == DRAWBRIDGE_UP &&
46.   	(levl[x][y].drawbridgemask & DB_UNDER) == DB_MOAT) return TRUE;
47.       return FALSE;
48.   }
49.   

is_lava Edit

50.   boolean
51.   is_lava(x,y)
52.   int x,y;
53.   {
54.       schar ltyp;
55.   
56.       if (!isok(x,y)) return FALSE;
57.       ltyp = levl[x][y].typ;
58.       if (ltyp == LAVAPOOL
59.   	|| (ltyp == DRAWBRIDGE_UP
60.   	    && (levl[x][y].drawbridgemask & DB_UNDER) == DB_LAVA)) return TRUE;
61.       return FALSE;
62.   }
63.   

is_ice Edit

64.   boolean
65.   is_ice(x,y)
66.   int x,y;
67.   {
68.       schar ltyp;
69.   
70.       if (!isok(x,y)) return FALSE;
71.       ltyp = levl[x][y].typ;
72.       if (ltyp == ICE
73.   	|| (ltyp == DRAWBRIDGE_UP
74.   	    && (levl[x][y].drawbridgemask & DB_UNDER) == DB_ICE)) return TRUE;
75.       return FALSE;
76.   }
77.   
78.   #endif /* OVL0 */
79.   

is_drawbridge_wall Edit

80.   #ifdef OVL1
81.   
82.   /*
83.    * We want to know whether a wall (or a door) is the portcullis (passageway)
84.    * of an eventual drawbridge.
85.    *
86.    * Return value:  the direction of the drawbridge.
87.    */
88.   
89.   int
90.   is_drawbridge_wall(x,y)
91.   int x,y;
92.   {
93.   	struct rm *lev;
94.   
95.   	lev = &levl[x][y];
96.   	if (lev->typ != DOOR && lev->typ != DBWALL)
97.   		return (-1);
98.   
99.   	if (IS_DRAWBRIDGE(levl[x+1][y].typ) &&
100.  	    (levl[x+1][y].drawbridgemask & DB_DIR) == DB_WEST)
101.  		return (DB_WEST);
102.  	if (IS_DRAWBRIDGE(levl[x-1][y].typ) &&
103.  	    (levl[x-1][y].drawbridgemask & DB_DIR) == DB_EAST)
104.  		return (DB_EAST);
105.  	if (IS_DRAWBRIDGE(levl[x][y-1].typ) &&
106.  	    (levl[x][y-1].drawbridgemask & DB_DIR) == DB_SOUTH)
107.  		return (DB_SOUTH);
108.  	if (IS_DRAWBRIDGE(levl[x][y+1].typ) &&
109.  	    (levl[x][y+1].drawbridgemask & DB_DIR) == DB_NORTH)
110.  		return (DB_NORTH);
111.  
112.  	return (-1);
113.  }
114.  

is_db_wall Edit

115.  /*
116.   * Use is_db_wall where you want to verify that a
117.   * drawbridge "wall" is UP in the location x, y
118.   * (instead of UP or DOWN, as with is_drawbridge_wall).
119.   */
120.  boolean
121.  is_db_wall(x,y)
122.  int x,y;
123.  {
124.  	return((boolean)( levl[x][y].typ == DBWALL ));
125.  }
126.  
127.  

find_drawbridge Edit

128.  /*
129.   * Return true with x,y pointing to the drawbridge if x,y initially indicate
130.   * a drawbridge or drawbridge wall.
131.   */
132.  boolean
133.  find_drawbridge(x,y)
134.  int *x,*y;
135.  {
136.  	int dir;
137.  
138.  	if (IS_DRAWBRIDGE(levl[*x][*y].typ))
139.  		return TRUE;
140.  	dir = is_drawbridge_wall(*x,*y);
141.  	if (dir >= 0) {
142.  		switch(dir) {
143.  			case DB_NORTH: (*y)++; break;
144.  			case DB_SOUTH: (*y)--; break;
145.  			case DB_EAST:  (*x)--; break;
146.  			case DB_WEST:  (*x)++; break;
147.  		}
148.  		return TRUE;
149.  	}
150.  	return FALSE;
151.  }
152.  
153.  #endif /* OVL1 */

get_wall_for_db Edit

154.  #ifdef OVLB
155.  
156.  /*
157.   * Find the drawbridge wall associated with a drawbridge.
158.   */
159.  STATIC_OVL void
160.  get_wall_for_db(x,y)
161.  int *x,*y;
162.  {
163.  	switch (levl[*x][*y].drawbridgemask & DB_DIR) {
164.  		case DB_NORTH: (*y)--; break;
165.  		case DB_SOUTH: (*y)++; break;
166.  		case DB_EAST:  (*x)++; break;
167.  		case DB_WEST:  (*x)--; break;
168.  	}
169.  }
170.  

create_drawbridge Edit

171.  /*
172.   * Creation of a drawbridge at pos x,y.
173.   *     dir is the direction.
174.   *     flag must be put to TRUE if we want the drawbridge to be opened.
175.   */
176.  
177.  boolean
178.  create_drawbridge(x,y,dir,flag)
179.  int x,y,dir;
180.  boolean flag;
181.  {
182.  	int x2,y2;
183.  	boolean horiz;
184.  	boolean lava = levl[x][y].typ == LAVAPOOL; /* assume initialized map */
185.  
186.  	x2 = x; y2 = y;
187.  	switch(dir) {
188.  		case DB_NORTH:
189.  			horiz = TRUE;
190.  			y2--;
191.  			break;
192.  		case DB_SOUTH:
193.  			horiz = TRUE;
194.  			y2++;
195.  			break;
196.  		case DB_EAST:
197.  			horiz = FALSE;
198.  			x2++;
199.  			break;
200.  		default:
201.  			impossible("bad direction in create_drawbridge");
202.  			/* fall through */
203.  		case DB_WEST:
204.  			horiz = FALSE;
205.  			x2--;
206.  			break;
207.  	}
208.  	if (!IS_WALL(levl[x2][y2].typ))
209.  		return(FALSE);
210.  	if (flag) {             /* We want the bridge open */
211.  		levl[x][y].typ = DRAWBRIDGE_DOWN;
212.  		levl[x2][y2].typ = DOOR;
213.  		levl[x2][y2].doormask = D_NODOOR;
214.  	} else {
215.  		levl[x][y].typ = DRAWBRIDGE_UP;
216.  		levl[x2][y2].typ = DBWALL;
217.  		/* Drawbridges are non-diggable. */
218.  		levl[x2][y2].wall_info = W_NONDIGGABLE;
219.  	}
220.  	levl[x][y].horizontal = !horiz;
221.  	levl[x2][y2].horizontal = horiz;
222.  	levl[x][y].drawbridgemask = dir;
223.  	if(lava) levl[x][y].drawbridgemask |= DB_LAVA;
224.  	return(TRUE);
225.  }
226.  

e_at Edit

227.  struct entity {
228.  	struct monst *emon;	  /* youmonst for the player */
229.  	struct permonst *edata;   /* must be non-zero for record to be valid */
230.  	int ex, ey;
231.  };
232.  
233.  #define ENTITIES 2
234.  
235.  static NEARDATA struct entity occupants[ENTITIES];
236.  
237.  STATIC_OVL
238.  struct entity *
239.  e_at(x, y)
240.  int x, y;
241.  {
242.  	int entitycnt;
243.  
244.  	for (entitycnt = 0; entitycnt < ENTITIES; entitycnt++)
245.  		if ((occupants[entitycnt].edata) &&
246.  		    (occupants[entitycnt].ex == x) &&
247.  		    (occupants[entitycnt].ey == y))
248.  			break;
249.  #ifdef D_DEBUG
250.  	pline("entitycnt = %d", entitycnt);
251.  	wait_synch();
252.  #endif
253.  	return((entitycnt == ENTITIES)?
254.  	       (struct entity *)0 : &(occupants[entitycnt]));
255.  }
256.  

m_to_e Edit

257.  STATIC_OVL void
258.  m_to_e(mtmp, x, y, etmp)
259.  struct monst *mtmp;
260.  int x, y;
261.  struct entity *etmp;
262.  {
263.  	etmp->emon = mtmp;
264.  	if (mtmp) {
265.  		etmp->ex = x;
266.  		etmp->ey = y;
267.  		if (mtmp->wormno && (x != mtmp->mx || y != mtmp->my))
268.  			etmp->edata = &mons[PM_LONG_WORM_TAIL];
269.  		else
270.  			etmp->edata = mtmp->data;
271.  	} else
272.  		etmp->edata = (struct permonst *)0;
273.  }
274.  

u_to_e Edit

275.  STATIC_OVL void
276.  u_to_e(etmp)
277.  struct entity *etmp;
278.  {
279.  	etmp->emon = &youmonst;
280.  	etmp->ex = u.ux;
281.  	etmp->ey = u.uy;
282.  	etmp->edata = youmonst.data;
283.  }
284.  

set_entity Edit

285.  STATIC_OVL void
286.  set_entity(x, y, etmp)
287.  int x, y;
288.  struct entity *etmp;
289.  {
290.  	if ((x == u.ux) && (y == u.uy))
291.  		u_to_e(etmp);
292.  	else if (MON_AT(x, y))
293.  		m_to_e(m_at(x, y), x, y, etmp);
294.  	else
295.  		etmp->edata = (struct permonst *)0;
296.  }
297.  

e_nam Edit

298.  #define is_u(etmp) (etmp->emon == &youmonst)
299.  #define e_canseemon(etmp) (is_u(etmp) ? (boolean)TRUE : canseemon(etmp->emon))
300.  
301.  /*
302.   * e_strg is a utility routine which is not actually in use anywhere, since
303.   * the specialized routines below suffice for all current purposes.
304.   */
305.  
306.  /* #define e_strg(etmp, func) (is_u(etmp)? (char *)0 : func(etmp->emon)) */
307.  
308.  STATIC_OVL const char *
309.  e_nam(etmp)
310.  struct entity *etmp;
311.  {
312.  	return(is_u(etmp)? "you" : mon_nam(etmp->emon));
313.  }
314.  

Enam Edit

315.  #ifdef D_DEBUG
316.  /*
317.   * Enam is another unused utility routine:  E_phrase is preferable.
318.   */
319.  
320.  static const char *
321.  Enam(etmp)
322.  struct entity *etmp;
323.  {
324.  	return(is_u(etmp)? "You" : Monnam(etmp->emon));
325.  }
326.  #endif /* D_DEBUG */
327.  

E_phrase Edit

328.  /*
329.   * Generates capitalized entity name, makes 2nd -> 3rd person conversion on
330.   * verb, where necessary.
331.   */
332.  
333.  STATIC_OVL const char *
334.  E_phrase(etmp, verb)
335.  struct entity *etmp;
336.  const char *verb;
337.  {
338.  	static char wholebuf[80];
339.  
340.  	Strcpy(wholebuf, is_u(etmp) ? "You" : Monnam(etmp->emon));
341.  	if (!*verb) return(wholebuf);
342.  	Strcat(wholebuf, " ");
343.  	if (is_u(etmp))
344.  	    Strcat(wholebuf, verb);
345.  	else
346.  	    Strcat(wholebuf, vtense((char *)0, verb));
347.  	return(wholebuf);
348.  }
349.  

e_survives_at Edit

350.  /*
351.   * Simple-minded "can it be here?" routine
352.   */
353.  
354.  STATIC_OVL boolean
355.  e_survives_at(etmp, x, y)
356.  struct entity *etmp;
357.  int x, y;
358.  {
359.  	if (noncorporeal(etmp->edata))
360.  		return(TRUE);
361.  	if (is_pool(x, y))
362.  		return (boolean)((is_u(etmp) &&
363.  				(Wwalking || Amphibious || Swimming ||
364.  				Flying || Levitation)) ||
365.  			is_swimmer(etmp->edata) || is_flyer(etmp->edata) ||
366.  			is_floater(etmp->edata));
367.  	/* must force call to lava_effects in e_died if is_u */
368.  	if (is_lava(x, y))
369.  		return (boolean)((is_u(etmp) && (Levitation || Flying)) ||
370.  			    likes_lava(etmp->edata) || is_flyer(etmp->edata));
371.  	if (is_db_wall(x, y))
372.  		return((boolean)(is_u(etmp) ? Passes_walls :
373.  			passes_walls(etmp->edata)));
374.  	return(TRUE);
375.  }
376.  

e_died Edit

377.  STATIC_OVL void
378.  e_died(etmp, dest, how)
379.  struct entity *etmp;
380.  int dest, how;
381.  {
382.  	if (is_u(etmp)) {
383.  		if (how == DROWNING) {
384.  			killer = 0;	/* drown() sets its own killer */
385.  			(void) drown();
386.  		} else if (how == BURNING) {
387.  			killer = 0;	/* lava_effects() sets its own killer */
388.  			(void) lava_effects();
389.  		} else {
390.  			coord xy;
391.  
392.  			/* use more specific killer if specified */
393.  			if (!killer) {
394.  			    killer_format = KILLED_BY_AN;
395.  			    killer = "falling drawbridge";
396.  			}
397.  			done(how);
398.  			/* So, you didn't die */
399.  			if (!e_survives_at(etmp, etmp->ex, etmp->ey)) {
400.  			    if (enexto(&xy, etmp->ex, etmp->ey, etmp->edata)) {
401.  				pline("A %s force teleports you away...",
402.  				      Hallucination ? "normal" : "strange");
403.  				teleds(xy.x, xy.y, FALSE);
404.  			    }
405.  			    /* otherwise on top of the drawbridge is the
406.  			     * only viable spot in the dungeon, so stay there
407.  			     */
408.  			}
409.  		}
410.  		/* we might have crawled out of the moat to survive */
411.  		etmp->ex = u.ux,  etmp->ey = u.uy;
412.  	} else {
413.  		int entitycnt;
414.  
415.  		killer = 0;
416.  		/* fake "digested to death" damage-type suppresses corpse */
417.  #define mk_message(dest) ((dest & 1) ? "" : (char *)0)
418.  #define mk_corpse(dest)  ((dest & 2) ? AD_DGST : AD_PHYS)
419.  		/* if monsters are moving, one of them caused the destruction */
420.  		if (flags.mon_moving)
421.  		    monkilled(etmp->emon, mk_message(dest), mk_corpse(dest));
422.  		else		/* you caused it */
423.  		    xkilled(etmp->emon, dest);
424.  		etmp->edata = (struct permonst *)0;
425.  
426.  		/* dead long worm handling */
427.  		for (entitycnt = 0; entitycnt < ENTITIES; entitycnt++) {
428.  		    if (etmp != &(occupants[entitycnt]) &&
429.  			etmp->emon == occupants[entitycnt].emon)
430.  			occupants[entitycnt].edata = (struct permonst *)0;
431.  		}
432.  #undef mk_message
433.  #undef mk_corpse
434.  	}
435.  }
436.  
437.  

automiss Edit

438.  /*
439.   * These are never directly affected by a bridge or portcullis.
440.   */
441.  
442.  STATIC_OVL boolean
443.  automiss(etmp)
444.  struct entity *etmp;
445.  {
446.  	return (boolean)((is_u(etmp) ? Passes_walls :
447.  			passes_walls(etmp->edata)) || noncorporeal(etmp->edata));
448.  }
449.  

e_missed Edit

450.  /*
451.   * Does falling drawbridge or portcullis miss etmp?
452.   */
453.  
454.  STATIC_OVL boolean
455.  e_missed(etmp, chunks)
456.  struct entity *etmp;
457.  boolean chunks;
458.  {
459.  	int misses;
460.  
461.  #ifdef D_DEBUG
462.  	if (chunks)
463.  		pline("Do chunks miss?");
464.  #endif
465.  	if (automiss(etmp))
466.  		return(TRUE);
467.  
468.  	if (is_flyer(etmp->edata) &&
469.  	    (is_u(etmp)? !Sleeping :
470.  	     (etmp->emon->mcanmove && !etmp->emon->msleeping)))
471.  						 /* flying requires mobility */
472.  		misses = 5;	/* out of 8 */
473.  	else if (is_floater(etmp->edata) ||
474.  		    (is_u(etmp) && Levitation))	 /* doesn't require mobility */
475.  		misses = 3;
476.  	else if (chunks && is_pool(etmp->ex, etmp->ey))
477.  		misses = 2;				    /* sitting ducks */
478.  	else
479.  		misses = 0;
480.  
481.  	if (is_db_wall(etmp->ex, etmp->ey))
482.  		misses -= 3;				    /* less airspace */
483.  
484.  #ifdef D_DEBUG
485.  	pline("Miss chance = %d (out of 8)", misses);
486.  #endif
487.  
488.  	return((boolean)((misses >= rnd(8))? TRUE : FALSE));
489.  }
490.  

e_jumps Edit

491.  /*
492.   * Can etmp jump from death?
493.   */
494.  
495.  STATIC_OVL boolean
496.  e_jumps(etmp)
497.  struct entity *etmp;
498.  {
499.  	int tmp = 4;		/* out of 10 */
500.  
501.  	if (is_u(etmp)? (Sleeping || Fumbling) :
502.  		        (!etmp->emon->mcanmove || etmp->emon->msleeping ||
503.  			 !etmp->edata->mmove   || etmp->emon->wormno))
504.  		return(FALSE);
505.  
506.  	if (is_u(etmp)? Confusion : etmp->emon->mconf)
507.  		tmp -= 2;
508.  
509.  	if (is_u(etmp)? Stunned : etmp->emon->mstun)
510.  		tmp -= 3;
511.  
512.  	if (is_db_wall(etmp->ex, etmp->ey))
513.  		tmp -= 2;			    /* less room to maneuver */
514.  
515.  #ifdef D_DEBUG
516.  	pline("%s to jump (%d chances in 10)", E_phrase(etmp, "try"), tmp);
517.  #endif
518.  	return((boolean)((tmp >= rnd(10))? TRUE : FALSE));
519.  }
520.  

do_entity Edit

521.  STATIC_OVL void
522.  do_entity(etmp)
523.  struct entity *etmp;
524.  {
525.  	int newx, newy, at_portcullis, oldx, oldy;
526.  	boolean must_jump = FALSE, relocates = FALSE, e_inview;
527.  	struct rm *crm;
528.  
529.  	if (!etmp->edata)
530.  		return;
531.  
532.  	e_inview = e_canseemon(etmp);
533.  	oldx = etmp->ex;
534.  	oldy = etmp->ey;
535.  	at_portcullis = is_db_wall(oldx, oldy);
536.  	crm = &levl[oldx][oldy];
537.  
538.  	if (automiss(etmp) && e_survives_at(etmp, oldx, oldy)) {
539.  		if (e_inview && (at_portcullis || IS_DRAWBRIDGE(crm->typ)))
540.  			pline_The("%s passes through %s!",
541.  			      at_portcullis ? "portcullis" : "drawbridge",
542.  			      e_nam(etmp));
543.  		if (is_u(etmp)) spoteffects(FALSE);
544.  		return;
545.  	}
546.  	if (e_missed(etmp, FALSE)) {
547.  		if (at_portcullis)
548.  			pline_The("portcullis misses %s!",
549.  			      e_nam(etmp));
550.  #ifdef D_DEBUG
551.  		else
552.  			pline_The("drawbridge misses %s!",
553.  			      e_nam(etmp));
554.  #endif
555.  		if (e_survives_at(etmp, oldx, oldy))
556.  			return;
557.  		else {
558.  #ifdef D_DEBUG
559.  			pline("Mon can't survive here");
560.  #endif
561.  			if (at_portcullis)
562.  				must_jump = TRUE;
563.  			else
564.  				relocates = TRUE; /* just ride drawbridge in */
565.  		}
566.  	} else {
567.  		if (crm->typ == DRAWBRIDGE_DOWN) {
568.  			pline("%s crushed underneath the drawbridge.",
569.  			      E_phrase(etmp, "are"));		  /* no jump */
570.  			e_died(etmp, e_inview? 3 : 2, CRUSHING);/* no corpse */
571.  			return;   /* Note: Beyond this point, we know we're  */
572.  		}		  /* not at an opened drawbridge, since all  */
573.  		must_jump = TRUE; /* *missable* creatures survive on the     */
574.  	}			  /* square, and all the unmissed ones die.  */
575.  	if (must_jump) {
576.  	    if (at_portcullis) {
577.  		if (e_jumps(etmp)) {
578.  		    relocates = TRUE;
579.  #ifdef D_DEBUG
580.  		    pline("Jump succeeds!");
581.  #endif
582.  		} else {
583.  		    if (e_inview)
584.  			pline("%s crushed by the falling portcullis!",
585.  			      E_phrase(etmp, "are"));
586.  		    else if (flags.soundok)
587.  			You_hear("a crushing sound.");
588.  		    e_died(etmp, e_inview? 3 : 2, CRUSHING);
589.  		    /* no corpse */
590.  		    return;
591.  		}
592.  	    } else { /* tries to jump off bridge to original square */
593.  		relocates = !e_jumps(etmp);
594.  #ifdef D_DEBUG
595.  		pline("Jump %s!", (relocates)? "fails" : "succeeds");
596.  #endif
597.  	    }
598.  	}
599.  
600.  /*
601.   * Here's where we try to do relocation.  Assumes that etmp is not arriving
602.   * at the portcullis square while the drawbridge is falling, since this square
603.   * would be inaccessible (i.e. etmp started on drawbridge square) or
604.   * unnecessary (i.e. etmp started here) in such a situation.
605.   */
606.  #ifdef D_DEBUG
607.  	pline("Doing relocation.");
608.  #endif
609.  	newx = oldx;
610.  	newy = oldy;
611.  	(void)find_drawbridge(&newx, &newy);
612.  	if ((newx == oldx) && (newy == oldy))
613.  		get_wall_for_db(&newx, &newy);
614.  #ifdef D_DEBUG
615.  	pline("Checking new square for occupancy.");
616.  #endif
617.  	if (relocates && (e_at(newx, newy))) {
618.  
619.  /*
620.   * Standoff problem:  one or both entities must die, and/or both switch
621.   * places.  Avoid infinite recursion by checking first whether the other
622.   * entity is staying put.  Clean up if we happen to move/die in recursion.
623.   */
624.  		struct entity *other;
625.  
626.  		other = e_at(newx, newy);
627.  #ifdef D_DEBUG
628.  		pline("New square is occupied by %s", e_nam(other));
629.  #endif
630.  		if (e_survives_at(other, newx, newy) && automiss(other)) {
631.  			relocates = FALSE;	      /* "other" won't budge */
632.  #ifdef D_DEBUG
633.  			pline("%s suicide.", E_phrase(etmp, "commit"));
634.  #endif
635.  		} else {
636.  
637.  #ifdef D_DEBUG
638.  			pline("Handling %s", e_nam(other));
639.  #endif
640.  			while ((e_at(newx, newy) != 0) &&
641.  			       (e_at(newx, newy) != etmp))
642.  				do_entity(other);
643.  #ifdef D_DEBUG
644.  			pline("Checking existence of %s", e_nam(etmp));
645.  			wait_synch();
646.  #endif
647.  			if (e_at(oldx, oldy) != etmp) {
648.  #ifdef D_DEBUG
649.  			    pline("%s moved or died in recursion somewhere",
650.  				  E_phrase(etmp, "have"));
651.  			    wait_synch();
652.  #endif
653.  			    return;
654.  			}
655.  		}
656.  	}
657.  	if (relocates && !e_at(newx, newy)) {/* if e_at() entity = worm tail */
658.  #ifdef D_DEBUG
659.  		pline("Moving %s", e_nam(etmp));
660.  #endif
661.  		if (!is_u(etmp)) {
662.  			remove_monster(etmp->ex, etmp->ey);
663.  			place_monster(etmp->emon, newx, newy);
664.  			update_monster_region(etmp->emon);
665.  		} else {
666.  			u.ux = newx;
667.  			u.uy = newy;
668.  		}
669.  		etmp->ex = newx;
670.  		etmp->ey = newy;
671.  		e_inview = e_canseemon(etmp);
672.  	}
673.  #ifdef D_DEBUG
674.  	pline("Final disposition of %s", e_nam(etmp));
675.  	wait_synch();
676.  #endif
677.  	if (is_db_wall(etmp->ex, etmp->ey)) {
678.  #ifdef D_DEBUG
679.  		pline("%s in portcullis chamber", E_phrase(etmp, "are"));
680.  		wait_synch();
681.  #endif
682.  		if (e_inview) {
683.  			if (is_u(etmp)) {
684.  				You("tumble towards the closed portcullis!");
685.  				if (automiss(etmp))
686.  					You("pass through it!");
687.  				else
688.  					pline_The("drawbridge closes in...");
689.  			} else
690.  				pline("%s behind the drawbridge.",
691.  				      E_phrase(etmp, "disappear"));
692.  		}
693.  		if (!e_survives_at(etmp, etmp->ex, etmp->ey)) {
694.  			killer_format = KILLED_BY_AN;
695.  			killer = "closing drawbridge";
696.  			e_died(etmp, 0, CRUSHING);	       /* no message */
697.  			return;
698.  		}
699.  #ifdef D_DEBUG
700.  		pline("%s in here", E_phrase(etmp, "survive"));
701.  #endif
702.  	} else {
703.  #ifdef D_DEBUG
704.  		pline("%s on drawbridge square", E_phrase(etmp, "are"));
705.  #endif
706.  		if (is_pool(etmp->ex, etmp->ey) && !e_inview)
707.  			if (flags.soundok)
708.  				You_hear("a splash.");
709.  		if (e_survives_at(etmp, etmp->ex, etmp->ey)) {
710.  			if (e_inview && !is_flyer(etmp->edata) &&
711.  			    !is_floater(etmp->edata))
712.  				pline("%s from the bridge.",
713.  				      E_phrase(etmp, "fall"));
714.  			return;
715.  		}
716.  #ifdef D_DEBUG
717.  		pline("%s cannot survive on the drawbridge square",Enam(etmp));
718.  #endif
719.  		if (is_pool(etmp->ex, etmp->ey) || is_lava(etmp->ex, etmp->ey))
720.  		    if (e_inview && !is_u(etmp)) {
721.  			/* drown() will supply msgs if nec. */
722.  			boolean lava = is_lava(etmp->ex, etmp->ey);
723.  
724.  			if (Hallucination)
725.  			    pline("%s the %s and disappears.",
726.  				  E_phrase(etmp, "drink"),
727.  				  lava ? "lava" : "moat");
728.  			else
729.  			    pline("%s into the %s.",
730.  				  E_phrase(etmp, "fall"),
731.  				  lava ? "lava" : "moat");
732.  		    }
733.  		killer_format = NO_KILLER_PREFIX;
734.  		killer = "fell from a drawbridge";
735.  		e_died(etmp, e_inview ? 3 : 2,      /* CRUSHING is arbitrary */
736.  		       (is_pool(etmp->ex, etmp->ey)) ? DROWNING :
737.  		       (is_lava(etmp->ex, etmp->ey)) ? BURNING :
738.  						       CRUSHING); /*no corpse*/
739.  		return;
740.  	}
741.  }
742.  

close_drawbridge Edit

743.  /*
744.   * Close the drawbridge located at x,y
745.   */
746.  
747.  void
748.  close_drawbridge(x,y)
749.  int x,y;
750.  {
751.  	register struct rm *lev1, *lev2;
752.  	struct trap *t;
753.  	int x2, y2;
754.  
755.  	lev1 = &levl[x][y];
756.  	if (lev1->typ != DRAWBRIDGE_DOWN) return;
757.  	x2 = x; y2 = y;
758.  	get_wall_for_db(&x2,&y2);
759.  	if (cansee(x,y) || cansee(x2,y2))
760.  		You("see a drawbridge %s up!",
761.  		    (((u.ux == x || u.uy == y) && !Underwater) ||
762.  		     distu(x2,y2) < distu(x,y)) ? "coming" : "going");
763.  	lev1->typ = DRAWBRIDGE_UP;
764.  	lev2 = &levl[x2][y2];
765.  	lev2->typ = DBWALL;
766.  	switch (lev1->drawbridgemask & DB_DIR) {
767.  		case DB_NORTH:
768.  		case DB_SOUTH:
769.  			lev2->horizontal = TRUE;
770.  			break;
771.  		case DB_WEST:
772.  		case DB_EAST:
773.  			lev2->horizontal = FALSE;
774.  			break;
775.  	}
776.  	lev2->wall_info = W_NONDIGGABLE;
777.  	set_entity(x, y, &(occupants[0]));
778.  	set_entity(x2, y2, &(occupants[1]));
779.  	do_entity(&(occupants[0]));		/* Do set_entity after first */
780.  	set_entity(x2, y2, &(occupants[1]));	/* do_entity for worm tail */
781.  	do_entity(&(occupants[1]));
782.  	if(OBJ_AT(x,y) && flags.soundok)
783.  	    You_hear("smashing and crushing.");
784.  	(void) revive_nasty(x,y,(char *)0);
785.  	(void) revive_nasty(x2,y2,(char *)0);
786.  	delallobj(x, y);
787.  	delallobj(x2, y2);
788.  	if ((t = t_at(x, y)) != 0) deltrap(t);
789.  	if ((t = t_at(x2, y2)) != 0) deltrap(t);
790.  	newsym(x, y);
791.  	newsym(x2, y2);
792.  	block_point(x2,y2);	/* vision */
793.  }
794.  

open_drawbridge Edit

795.  /*
796.   * Open the drawbridge located at x,y
797.   */
798.  
799.  void
800.  open_drawbridge(x,y)
801.  int x,y;
802.  {
803.  	register struct rm *lev1, *lev2;
804.  	struct trap *t;
805.  	int x2, y2;
806.  
807.  	lev1 = &levl[x][y];
808.  	if (lev1->typ != DRAWBRIDGE_UP) return;
809.  	x2 = x; y2 = y;
810.  	get_wall_for_db(&x2,&y2);
811.  	if (cansee(x,y) || cansee(x2,y2))
812.  		You("see a drawbridge %s down!",
813.  		    (distu(x2,y2) < distu(x,y)) ? "going" : "coming");
814.  	lev1->typ = DRAWBRIDGE_DOWN;
815.  	lev2 = &levl[x2][y2];
816.  	lev2->typ = DOOR;
817.  	lev2->doormask = D_NODOOR;
818.  	set_entity(x, y, &(occupants[0]));
819.  	set_entity(x2, y2, &(occupants[1]));
820.  	do_entity(&(occupants[0]));		/* do set_entity after first */
821.  	set_entity(x2, y2, &(occupants[1]));	/* do_entity for worm tails */
822.  	do_entity(&(occupants[1]));
823.  	(void) revive_nasty(x,y,(char *)0);
824.  	delallobj(x, y);
825.  	if ((t = t_at(x, y)) != 0) deltrap(t);
826.  	if ((t = t_at(x2, y2)) != 0) deltrap(t);
827.  	newsym(x, y);
828.  	newsym(x2, y2);
829.  	unblock_point(x2,y2);	/* vision */
830.  	if (Is_stronghold(&u.uz)) u.uevent.uopened_dbridge = TRUE;
831.  }
832.  

destroy_drawbridge Edit

833.  /*
834.   * Let's destroy the drawbridge located at x,y
835.   */
836.  
837.  void
838.  destroy_drawbridge(x,y)
839.  int x,y;
840.  {
841.  	register struct rm *lev1, *lev2;
842.  	struct trap *t;
843.  	int x2, y2;
844.  	boolean e_inview;
845.  	struct entity *etmp1 = &(occupants[0]), *etmp2 = &(occupants[1]);
846.  
847.  	lev1 = &levl[x][y];
848.  	if (!IS_DRAWBRIDGE(lev1->typ))
849.  		return;
850.  	x2 = x; y2 = y;
851.  	get_wall_for_db(&x2,&y2);
852.  	lev2 = &levl[x2][y2];
853.  	if ((lev1->drawbridgemask & DB_UNDER) == DB_MOAT ||
854.  	    (lev1->drawbridgemask & DB_UNDER) == DB_LAVA) {
855.  		struct obj *otmp;
856.  		boolean lava = (lev1->drawbridgemask & DB_UNDER) == DB_LAVA;
857.  		if (lev1->typ == DRAWBRIDGE_UP) {
858.  			if (cansee(x2,y2))
859.  			    pline_The("portcullis of the drawbridge falls into the %s!",
860.  				  lava ? "lava" : "moat");
861.  			else if (flags.soundok)
862.  				You_hear("a loud *SPLASH*!");
863.  		} else {
864.  			if (cansee(x,y))
865.  			    pline_The("drawbridge collapses into the %s!",
866.  				  lava ? "lava" : "moat");
867.  			else if (flags.soundok)
868.  				You_hear("a loud *SPLASH*!");
869.  		}
870.  		lev1->typ = lava ? LAVAPOOL : MOAT;
871.  		lev1->drawbridgemask = 0;
872.  		if ((otmp = sobj_at(BOULDER,x,y)) != 0) {
873.  		    obj_extract_self(otmp);
874.  		    (void) flooreffects(otmp,x,y,"fall");
875.  		}
876.  	} else {
877.  		if (cansee(x,y))
878.  			pline_The("drawbridge disintegrates!");
879.  		else
880.  			You_hear("a loud *CRASH*!");
881.  		lev1->typ =
882.  			((lev1->drawbridgemask & DB_ICE) ? ICE : ROOM);
883.  		lev1->icedpool =
884.  			((lev1->drawbridgemask & DB_ICE) ? ICED_MOAT : 0);
885.  	}
886.  	wake_nearto(x, y, 500);
887.  	lev2->typ = DOOR;
888.  	lev2->doormask = D_NODOOR;
889.  	if ((t = t_at(x, y)) != 0) deltrap(t);
890.  	if ((t = t_at(x2, y2)) != 0) deltrap(t);
891.  	newsym(x,y);
892.  	newsym(x2,y2);
893.  	if (!does_block(x2,y2,lev2)) unblock_point(x2,y2);	/* vision */
894.  	if (Is_stronghold(&u.uz)) u.uevent.uopened_dbridge = TRUE;
895.  
896.  	set_entity(x2, y2, etmp2); /* currently only automissers can be here */
897.  	if (etmp2->edata) {
898.  		e_inview = e_canseemon(etmp2);
899.  		if (!automiss(etmp2)) {
900.  			if (e_inview)
901.  				pline("%s blown apart by flying debris.",
902.  				      E_phrase(etmp2, "are"));
903.  			killer_format = KILLED_BY_AN;
904.  			killer = "exploding drawbridge";
905.  			e_died(etmp2, e_inview? 3 : 2, CRUSHING); /*no corpse*/
906.  		}	     /* nothing which is vulnerable can survive this */
907.  	}
908.  	set_entity(x, y, etmp1);
909.  	if (etmp1->edata) {
910.  		e_inview = e_canseemon(etmp1);
911.  		if (e_missed(etmp1, TRUE)) {
912.  #ifdef D_DEBUG
913.  			pline("%s spared!", E_phrase(etmp1, "are"));
914.  #endif
915.  		} else {
916.  			if (e_inview) {
917.  			    if (!is_u(etmp1) && Hallucination)
918.  				pline("%s into some heavy metal!",
919.  				      E_phrase(etmp1, "get"));
920.  			    else
921.  				pline("%s hit by a huge chunk of metal!",
922.  				      E_phrase(etmp1, "are"));
923.  			} else {
924.  			    if (flags.soundok && !is_u(etmp1) && !is_pool(x,y))
925.  				You_hear("a crushing sound.");
926.  #ifdef D_DEBUG
927.  			    else
928.  				pline("%s from shrapnel",
929.  				      E_phrase(etmp1, "die"));
930.  #endif
931.  			}
932.  			killer_format = KILLED_BY_AN;
933.  			killer = "collapsing drawbridge";
934.  			e_died(etmp1, e_inview? 3 : 2, CRUSHING); /*no corpse*/
935.  			if(lev1->typ == MOAT) do_entity(etmp1);
936.  		}
937.  	}
938.  }
939.  
940.  #endif /* OVLB */
941.  
942.  /*dbridge.c*/

Around Wikia's network

Random Wiki