Wikihack
Advertisement

Below is the full text to dbridge.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/dbridge.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.
1.    /*	SCCS Id: @(#)dbridge.c	3.0	88/18/12
2.    /* 	Copyright (c) 1989 by Jean-Christophe Collet */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    /*
6.     * This file contains the drawbridge manipulation (create, open, close,
7.     * destroy).
8.     */
9.    
10.   #include "hack.h"
11.   
12.   boolean
13.   is_pool(x,y)
14.   int x,y;
15.   {
16.   	if(levl[x][y].typ == POOL || levl[x][y].typ == MOAT) return TRUE;
17.   #ifdef STRONGHOLD
18.   	if(levl[x][y].typ == DRAWBRIDGE_UP &&
19.   		(levl[x][y].drawbridgemask & DB_UNDER) == DB_MOAT) return TRUE;
20.   #endif
21.   	return FALSE;
22.   }
23.   
24.   #ifdef STRONGHOLD
25.   void
26.   initsym(x,y)
27.   int x,y;
28.   {
29.   	char oldseen;
30.   	struct rm *crm = &levl[x][y];
31.   
32.   	oldseen = crm->seen;
33.   	crm->seen = 1;
34.   	crm->scrsym = news0(x,y);
35.   	crm->seen = oldseen;
36.   }
37.   
38.   static void
39.   redosym(x,y)
40.   int x,y;
41.   {
42.   	if(cansee(x,y)) {
43.   		if (Invisible || x != u.ux || y != u.uy)
44.   			newsym(x,y);
45.   	} else {
46.   		initsym(x,y);
47.   		levl[x][y].seen = 0;
48.   	}
49.   }
50.   
51.   /* 
52.    * We want to know whether a wall (or a door) is the portcullis (passageway)
53.    * of an eventual drawbridge.
54.    *
55.    * Return value: the direction of the drawbridge.
56.    */
57.   
58.   int
59.   is_drawbridge_wall(x,y)
60.   int x,y;
61.   {
62.   	struct rm *lev;
63.   
64.   	lev = &levl[x][y];
65.   	if ( lev->typ == VWALL || lev->typ == DOOR) {
66.   		if (IS_DRAWBRIDGE(levl[x+1][y].typ) && 
67.   		    (levl[x+1][y].drawbridgemask & DB_DIR) == DB_WEST)
68.   			return (DB_WEST);
69.   		if (IS_DRAWBRIDGE(levl[x-1][y].typ) && 
70.   		    (levl[x-1][y].drawbridgemask & DB_DIR) == DB_EAST)
71.   			return (DB_EAST);
72.   	}
73.   	if ( lev->typ == HWALL || lev->typ == DOOR) {
74.   		if (IS_DRAWBRIDGE(levl[x][y-1].typ) && 
75.   		    (levl[x][y-1].drawbridgemask & DB_DIR) == DB_SOUTH)
76.   			return (DB_SOUTH);
77.   		if (IS_DRAWBRIDGE(levl[x][y+1].typ) && 
78.   		    (levl[x][y+1].drawbridgemask & DB_DIR) == DB_NORTH)
79.   			return (DB_NORTH);
80.   	}
81.   	return (-1);
82.   }
83.   
84.   /*
85.   * Use is_db_wall where you want to verify that a
86.   *  drawbridge "wall" is UP in the location x, y
87.   *  (instead of UP or DOWN, as with is_drawbridge_wall). 
88.   */ 
89.   boolean
90.   is_db_wall(x,y)
91.   int x,y;
92.   {
93.   	return( (levl[x][y].typ == VWALL || levl[x][y].typ == HWALL) &&
94.   		levl[x][y].diggable & W_GATEWAY);
95.   }
96.   
97.   /*
98.    * Return true with x,y pointing to the drawbridge if x,y initially indicate
99.    * a drawbridge or drawbridge wall.
100.   */
101.  boolean
102.  find_drawbridge(x,y)
103.  int *x,*y;
104.  {
105.  	int dir;
106.  
107.  	if (IS_DRAWBRIDGE(levl[*x][*y].typ))
108.  		return TRUE;
109.  	dir = is_drawbridge_wall(*x,*y);
110.  	if (dir >= 0) {
111.  		switch(dir) {
112.  		      case DB_NORTH: (*y)++; break;
113.  		      case DB_SOUTH: (*y)--; break;
114.  		      case DB_EAST:  (*x)--; break;
115.  		      case DB_WEST:  (*x)++; break;
116.  		}
117.  		return TRUE;
118.  	}
119.  	return FALSE;
120.  }
121.  
122.  /* 
123.   * Find the drawbridge wall associated with a drawbridge.
124.   */
125.  static void
126.  get_wall_for_db(x,y)
127.  int *x,*y;
128.  {
129.  	switch (levl[*x][*y].drawbridgemask & DB_DIR) {
130.  	      case DB_NORTH: (*y)--; break;
131.  	      case DB_SOUTH: (*y)++; break;
132.  	      case DB_EAST:  (*x)++; break;
133.  	      case DB_WEST:  (*x)--; break;
134.  	}
135.  }
136.  
137.  /*
138.   * Creation of a drawbridge at pos x,y.
139.   *	dir is the direction.
140.   *	flag must be put to TRUE if we want the drawbridge to be opened.
141.   */
142.  
143.  boolean
144.  create_drawbridge(x,y,dir,flag)
145.  int x,y,dir;
146.  boolean flag;
147.  {
148.  	int x2,y2;
149.  	uchar wall;
150.  
151.  	x2 = x; y2 = y;
152.  	switch(dir) {
153.  		case DB_NORTH:
154.  			wall = HWALL;
155.  			y2--;
156.  			break;
157.  		case DB_SOUTH:
158.  			wall = HWALL;
159.  			y2++;
160.  			break;
161.  		case DB_EAST:
162.  			wall = VWALL;
163.  			x2++;
164.  			break;
165.  		case DB_WEST:
166.  			wall = VWALL;
167.  			x2--;
168.  			break;
169.  	}
170.  	if (!IS_WALL(levl[x2][y2].typ))
171.  		return(FALSE);
172.  	if (flag) {		/* We want the bridge open */
173.  		levl[x][y].typ = DRAWBRIDGE_DOWN;
174.  		levl[x2][y2].typ = DOOR;
175.  		levl[x2][y2].doormask = D_NODOOR;
176.  	} else {
177.  		levl[x][y].typ = DRAWBRIDGE_UP;
178.  		levl[x2][y2].typ = wall;
179.  		/* Beware, drawbridges are non-diggable. */
180.  		levl[x2][y2].diggable = (W_NONDIGGABLE | W_GATEWAY);
181.  	}
182.  	levl[x][y].drawbridgemask = dir;	/* always have DB_MOAT */
183.  	initsym(x,y);
184.  	initsym(x2,y2);
185.  	return(TRUE);		
186.  }
187.  
188.  /*
189.   * Close the drawbridge located at x,y
190.   */
191.  
192.  void
193.  close_drawbridge(x,y)
194.  int x,y;
195.  {
196.  	register struct rm *lev1, *lev2;
197.  	struct monst *mtmp;
198.  	struct obj *otmp, *otmp2;
199.  	int x2, y2;
200.  
201.  	lev1 = &levl[x][y];
202.  	if (lev1->typ != DRAWBRIDGE_DOWN) return;
203.  	if (cansee(x,y))
204.  		You("see a drawbridge going up!");
205.  	lev1->typ = DRAWBRIDGE_UP;
206.  	x2 = x; y2 = y;
207.  	get_wall_for_db(&x2,&y2);
208.  	lev2 = &levl[x2][y2];
209.  	switch (lev1->drawbridgemask & DB_DIR) {
210.  		case DB_NORTH:
211.  		case DB_SOUTH:
212.  			lev2->typ = HWALL;
213.  			break;
214.  		case DB_WEST:
215.  		case DB_EAST:
216.  			lev2->typ = VWALL;
217.  			break;
218.  	}
219.  	lev2->diggable = (W_NONDIGGABLE | W_GATEWAY);
220.  	if ((lev1->drawbridgemask & DB_UNDER) == DB_MOAT) {
221.  	    if (lev1->mmask && !is_flyer((mtmp = m_at(x,y))->data)) {
222.  		if (is_swimmer(mtmp->data)) {
223.  		    if (flags.soundok) You("hear a splash.");
224.  		} else {
225.  		    if (cansee(x,y))
226.  			pline("%s drowns.",Monnam(mtmp));
227.  		    else if (flags.soundok)
228.  			You("hear a splash!");
229.  		    xkilled(mtmp,2);
230.  		}
231.  	    }
232.  	    if (u.ux == x && u.uy == y &&
233.  		!(Levitation
234.  # ifdef POLYSELF
235.  		|| is_flyer(uasmon)
236.  # endif
237.  		)) {
238.  		    /* is the player *THAT* stupid ? */
239.  		    You("fall from the drawbridge.");
240.  		    if (!Wwalking) drown();
241.  	    }
242.  	}
243.  	if (lev2->mmask && !noncorporeal((mtmp = m_at(x2, y2))->data)) {
244.  		if (cansee(x2,y2))
245.  		    pline("%s is crushed by the portcullis.",Monnam(mtmp));
246.  		else if (flags.soundok)
247.  		    You("hear a crushing sound.");
248.  		xkilled(mtmp,2);
249.  	}
250.  	if (u.ux == x2 && u.uy == y2) {	/* More stupidity ? */
251.  		coord xy;
252.  
253.  		You("are crushed by a falling portcullis.");
254.  		killer = "closing drawbridge";
255.  		done("died");
256.  		/* So, you didn't die */
257.  		pline("A %s force teleports you away...",
258.  		      Hallucination ? "normal" : "strange");
259.  		enexto(&xy, x2, y2);
260.  		teleds(xy.x, xy.y);
261.  	}
262.  	redosym(x,y);
263.  	for (otmp=fobj;otmp;otmp = otmp2) {
264.  		otmp2 = otmp->nobj;
265.  		if ((otmp->ox == x && otmp->oy == y) || 
266.  		     (otmp->ox == x2 && otmp->oy == y2))
267.  		  delobj(otmp);
268.  	}
269.  	redosym(x2,y2);
270.  }
271.  
272.  /* 
273.   * Open the drawbridge located at x,y
274.   */
275.  
276.  void
277.  open_drawbridge(x,y)
278.  int x,y;
279.  {
280.  	register struct rm *lev1, *lev2;
281.  	int x2, y2;
282.  
283.  	lev1 = &levl[x][y];
284.  	if (lev1->typ != DRAWBRIDGE_UP) return;
285.  	if (cansee(x,y))
286.  		You("see a drawbridge coming down!");
287.  	lev1->typ = DRAWBRIDGE_DOWN;
288.  	x2 = x; y2 = y;
289.  	get_wall_for_db(&x2,&y2);
290.  	lev2 = &levl[x2][y2];
291.  	lev2->typ = DOOR;
292.  	lev2->doormask = D_NODOOR;
293.  	if (u.ux == x && u.uy == y) {
294.  		if (cansee(x2,y2))
295.  			newsym(x2,y2);
296.  		You("are hit by the descending drawbridge!");
297.  		killer = "descending drawbridge";
298.  		done("died");
299.  	}
300.  	redosym(x,y);
301.  	redosym(x2,y2);
302.  }
303.  
304.  /*
305.   * Let's destroy the drawbridge located at x,y
306.   */
307.  
308.  void
309.  destroy_drawbridge(x,y)
310.  int x,y;
311.  {
312.  	register struct rm *lev1, *lev2;
313.  	int x2, y2;
314.  
315.  	lev1 = &levl[x][y];
316.  	if (!IS_DRAWBRIDGE(lev1->typ))
317.  	  return;
318.  	x2 = x; y2 = y;
319.  	get_wall_for_db(&x2,&y2);
320.  	lev2 = &levl[x2][y2];
321.  	if ((lev1->drawbridgemask & DB_UNDER) == DB_MOAT) {
322.  	    if (lev1->typ == DRAWBRIDGE_UP) {
323.  		if (cansee(x2,y2))
324.  		    pline("The portcullis of the drawbridge falls into the moat!");
325.  		else if (flags.soundok)
326.  		    You("hear a big *SPLASH*!");
327.  	    } else {
328.  		if (cansee(x,y))
329.  		    pline("The drawbridge collapses into the moat!");
330.  		else if (flags.soundok)
331.  		    You("hear a big *SPLASH*!");
332.  	    }
333.  	    lev1->typ = MOAT;
334.  	    if (u.ux == x && u.uy == y && !(Levitation
335.  # ifdef POLYSELF
336.  		|| is_flyer(uasmon)
337.  # endif
338.  		)) {
339.  		    /* is the player *THAT* stupid ? */
340.  		    You("fall from the drawbridge.");
341.  		    if (!Wwalking) drown();
342.  	    }
343.  	} else {
344.  	    if (cansee(x,y))
345.  		pline("The drawbridge disintegrates!");
346.  	    else
347.  		You("hear a big *CRASH*!");
348.  	    lev1->typ = ROOM;
349.  	}
350.  	lev2->typ = DOOR;
351.  	lev2->doormask = D_NODOOR;
352.  	if (u.ux == x2 && u.uy == y2) {	/* More stupidity ? */
353.  		coord xy;
354.  
355.  		You("are crushed by a falling portcullis.");
356.  		killer = "collapsing drawbridge";
357.  		done("died");
358.  		/* So, you didn't die */
359.  		pline("A %s force teleports you away...",
360.  		      Hallucination ? "normal" : "strange");
361.  		enexto(&xy, x2, y2);
362.  		teleds(xy.x, xy.y);
363.  	}
364.  	redosym(x,y);
365.  	redosym(x2,y2);
366.  }
367.  
368.  #endif /* STRONGHOLD /**/
Advertisement