Home | History | Annotate | Line # | Download | only in huntd
execute.c revision 1.7
      1  1.7  dholland /*	$NetBSD: execute.c,v 1.7 2009/07/04 01:01:18 dholland Exp $	*/
      2  1.1       mrg /*
      3  1.3       wiz  * Copyright (c) 1983-2003, Regents of the University of California.
      4  1.3       wiz  * All rights reserved.
      5  1.3       wiz  *
      6  1.3       wiz  * Redistribution and use in source and binary forms, with or without
      7  1.3       wiz  * modification, are permitted provided that the following conditions are
      8  1.3       wiz  * met:
      9  1.3       wiz  *
     10  1.3       wiz  * + Redistributions of source code must retain the above copyright
     11  1.3       wiz  *   notice, this list of conditions and the following disclaimer.
     12  1.3       wiz  * + Redistributions in binary form must reproduce the above copyright
     13  1.3       wiz  *   notice, this list of conditions and the following disclaimer in the
     14  1.3       wiz  *   documentation and/or other materials provided with the distribution.
     15  1.3       wiz  * + Neither the name of the University of California, San Francisco nor
     16  1.3       wiz  *   the names of its contributors may be used to endorse or promote
     17  1.3       wiz  *   products derived from this software without specific prior written
     18  1.3       wiz  *   permission.
     19  1.3       wiz  *
     20  1.3       wiz  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     21  1.3       wiz  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  1.3       wiz  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     23  1.3       wiz  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     24  1.3       wiz  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     25  1.3       wiz  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     26  1.3       wiz  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  1.3       wiz  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  1.3       wiz  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  1.3       wiz  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     30  1.3       wiz  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  1.1       mrg  */
     32  1.1       mrg 
     33  1.2     lukem #include <sys/cdefs.h>
     34  1.2     lukem #ifndef lint
     35  1.7  dholland __RCSID("$NetBSD: execute.c,v 1.7 2009/07/04 01:01:18 dholland Exp $");
     36  1.2     lukem #endif /* not lint */
     37  1.2     lukem 
     38  1.2     lukem # include	<stdlib.h>
     39  1.1       mrg # include	"hunt.h"
     40  1.1       mrg 
     41  1.4       jsm static	void	cloak(PLAYER *);
     42  1.5  dholland static	void	turn_player(PLAYER *, int);
     43  1.4       jsm static	void	fire(PLAYER *, int);
     44  1.4       jsm static	void	fire_slime(PLAYER *, int);
     45  1.4       jsm static	void	move_player(PLAYER *, int);
     46  1.4       jsm static	void	pickup(PLAYER *, int, int, int, int);
     47  1.4       jsm static	void	scan(PLAYER *);
     48  1.2     lukem 
     49  1.2     lukem 
     50  1.1       mrg # ifdef MONITOR
     51  1.1       mrg /*
     52  1.1       mrg  * mon_execute:
     53  1.1       mrg  *	Execute a single monitor command
     54  1.1       mrg  */
     55  1.2     lukem void
     56  1.1       mrg mon_execute(pp)
     57  1.2     lukem 	PLAYER	*pp;
     58  1.1       mrg {
     59  1.2     lukem 	char	ch;
     60  1.1       mrg 
     61  1.1       mrg 	ch = pp->p_cbuf[pp->p_ncount++];
     62  1.1       mrg 	switch (ch) {
     63  1.1       mrg 	  case CTRL('L'):
     64  1.1       mrg 		sendcom(pp, REDRAW);
     65  1.1       mrg 		break;
     66  1.1       mrg 	  case 'q':
     67  1.1       mrg 		(void) strcpy(pp->p_death, "| Quit |");
     68  1.1       mrg 		break;
     69  1.1       mrg 	}
     70  1.1       mrg }
     71  1.1       mrg # endif
     72  1.1       mrg 
     73  1.1       mrg /*
     74  1.1       mrg  * execute:
     75  1.1       mrg  *	Execute a single command
     76  1.1       mrg  */
     77  1.2     lukem void
     78  1.1       mrg execute(pp)
     79  1.2     lukem 	PLAYER	*pp;
     80  1.1       mrg {
     81  1.2     lukem 	char	ch;
     82  1.1       mrg 
     83  1.1       mrg 	ch = pp->p_cbuf[pp->p_ncount++];
     84  1.1       mrg 
     85  1.1       mrg # ifdef	FLY
     86  1.1       mrg 	if (pp->p_flying >= 0) {
     87  1.1       mrg 		switch (ch) {
     88  1.1       mrg 		  case CTRL('L'):
     89  1.1       mrg 			sendcom(pp, REDRAW);
     90  1.1       mrg 			break;
     91  1.1       mrg 		  case 'q':
     92  1.1       mrg 			(void) strcpy(pp->p_death, "| Quit |");
     93  1.1       mrg 			break;
     94  1.1       mrg 		}
     95  1.1       mrg 		return;
     96  1.1       mrg 	}
     97  1.1       mrg # endif
     98  1.1       mrg 
     99  1.1       mrg 	switch (ch) {
    100  1.1       mrg 	  case CTRL('L'):
    101  1.1       mrg 		sendcom(pp, REDRAW);
    102  1.1       mrg 		break;
    103  1.1       mrg 	  case 'h':
    104  1.1       mrg 		move_player(pp, LEFTS);
    105  1.1       mrg 		break;
    106  1.1       mrg 	  case 'H':
    107  1.5  dholland 		turn_player(pp, LEFTS);
    108  1.1       mrg 		break;
    109  1.1       mrg 	  case 'j':
    110  1.1       mrg 		move_player(pp, BELOW);
    111  1.1       mrg 		break;
    112  1.1       mrg 	  case 'J':
    113  1.5  dholland 		turn_player(pp, BELOW);
    114  1.1       mrg 		break;
    115  1.1       mrg 	  case 'k':
    116  1.1       mrg 		move_player(pp, ABOVE);
    117  1.1       mrg 		break;
    118  1.1       mrg 	  case 'K':
    119  1.5  dholland 		turn_player(pp, ABOVE);
    120  1.1       mrg 		break;
    121  1.1       mrg 	  case 'l':
    122  1.1       mrg 		move_player(pp, RIGHT);
    123  1.1       mrg 		break;
    124  1.1       mrg 	  case 'L':
    125  1.5  dholland 		turn_player(pp, RIGHT);
    126  1.1       mrg 		break;
    127  1.1       mrg 	  case 'f':
    128  1.1       mrg 	  case '1':
    129  1.1       mrg 		fire(pp, 0);		/* SHOT */
    130  1.1       mrg 		break;
    131  1.1       mrg 	  case 'g':
    132  1.1       mrg 	  case '2':
    133  1.1       mrg 		fire(pp, 1);		/* GRENADE */
    134  1.1       mrg 		break;
    135  1.1       mrg 	  case 'F':
    136  1.1       mrg 	  case '3':
    137  1.1       mrg 		fire(pp, 2);		/* SATCHEL */
    138  1.1       mrg 		break;
    139  1.1       mrg 	  case 'G':
    140  1.1       mrg 	  case '4':
    141  1.1       mrg 		fire(pp, 3);		/* 7x7 BOMB */
    142  1.1       mrg 		break;
    143  1.1       mrg 	  case '5':
    144  1.1       mrg 		fire(pp, 4);		/* 9x9 BOMB */
    145  1.1       mrg 		break;
    146  1.1       mrg 	  case '6':
    147  1.1       mrg 		fire(pp, 5);		/* 11x11 BOMB */
    148  1.1       mrg 		break;
    149  1.1       mrg 	  case '7':
    150  1.1       mrg 		fire(pp, 6);		/* 13x13 BOMB */
    151  1.1       mrg 		break;
    152  1.1       mrg 	  case '8':
    153  1.1       mrg 		fire(pp, 7);		/* 15x15 BOMB */
    154  1.1       mrg 		break;
    155  1.1       mrg 	  case '9':
    156  1.1       mrg 		fire(pp, 8);		/* 17x17 BOMB */
    157  1.1       mrg 		break;
    158  1.1       mrg 	  case '0':
    159  1.1       mrg 		fire(pp, 9);		/* 19x19 BOMB */
    160  1.1       mrg 		break;
    161  1.1       mrg 	  case '@':
    162  1.1       mrg 		fire(pp, 10);		/* 21x21 BOMB */
    163  1.1       mrg 		break;
    164  1.1       mrg # ifdef	OOZE
    165  1.1       mrg 	  case 'o':
    166  1.1       mrg 		fire_slime(pp, 0);	/* SLIME */
    167  1.1       mrg 		break;
    168  1.1       mrg 	  case 'O':
    169  1.1       mrg 		fire_slime(pp, 1);	/* SSLIME */
    170  1.1       mrg 		break;
    171  1.1       mrg 	  case 'p':
    172  1.1       mrg 		fire_slime(pp, 2);
    173  1.1       mrg 		break;
    174  1.1       mrg 	  case 'P':
    175  1.1       mrg 		fire_slime(pp, 3);
    176  1.1       mrg 		break;
    177  1.1       mrg # endif
    178  1.1       mrg 	  case 's':
    179  1.1       mrg 		scan(pp);
    180  1.1       mrg 		break;
    181  1.1       mrg 	  case 'c':
    182  1.1       mrg 		cloak(pp);
    183  1.1       mrg 		break;
    184  1.1       mrg 	  case 'q':
    185  1.1       mrg 		(void) strcpy(pp->p_death, "| Quit |");
    186  1.1       mrg 		break;
    187  1.1       mrg 	}
    188  1.1       mrg }
    189  1.1       mrg 
    190  1.1       mrg /*
    191  1.1       mrg  * move_player:
    192  1.1       mrg  *	Execute a move in the given direction
    193  1.1       mrg  */
    194  1.2     lukem static void
    195  1.1       mrg move_player(pp, dir)
    196  1.2     lukem 	PLAYER	*pp;
    197  1.2     lukem 	int	dir;
    198  1.1       mrg {
    199  1.2     lukem 	PLAYER	*newp;
    200  1.2     lukem 	int	x, y;
    201  1.2     lukem 	FLAG	moved;
    202  1.2     lukem 	BULLET	*bp;
    203  1.1       mrg 
    204  1.1       mrg 	y = pp->p_y;
    205  1.1       mrg 	x = pp->p_x;
    206  1.1       mrg 
    207  1.1       mrg 	switch (dir) {
    208  1.1       mrg 	  case LEFTS:
    209  1.1       mrg 		x--;
    210  1.1       mrg 		break;
    211  1.1       mrg 	  case RIGHT:
    212  1.1       mrg 		x++;
    213  1.1       mrg 		break;
    214  1.1       mrg 	  case ABOVE:
    215  1.1       mrg 		y--;
    216  1.1       mrg 		break;
    217  1.1       mrg 	  case BELOW:
    218  1.1       mrg 		y++;
    219  1.1       mrg 		break;
    220  1.1       mrg 	}
    221  1.1       mrg 
    222  1.1       mrg 	moved = FALSE;
    223  1.1       mrg 	switch (Maze[y][x]) {
    224  1.1       mrg 	  case SPACE:
    225  1.1       mrg # ifdef RANDOM
    226  1.1       mrg 	  case DOOR:
    227  1.1       mrg # endif
    228  1.1       mrg 		moved = TRUE;
    229  1.1       mrg 		break;
    230  1.1       mrg 	  case WALL1:
    231  1.1       mrg 	  case WALL2:
    232  1.1       mrg 	  case WALL3:
    233  1.1       mrg # ifdef REFLECT
    234  1.1       mrg 	  case WALL4:
    235  1.1       mrg 	  case WALL5:
    236  1.1       mrg # endif
    237  1.1       mrg 		break;
    238  1.1       mrg 	  case MINE:
    239  1.1       mrg 	  case GMINE:
    240  1.1       mrg 		if (dir == pp->p_face)
    241  1.1       mrg 			pickup(pp, y, x, 2, Maze[y][x]);
    242  1.1       mrg 		else if (opposite(dir, pp->p_face))
    243  1.1       mrg 			pickup(pp, y, x, 95, Maze[y][x]);
    244  1.1       mrg 		else
    245  1.1       mrg 			pickup(pp, y, x, 50, Maze[y][x]);
    246  1.1       mrg 		Maze[y][x] = SPACE;
    247  1.1       mrg 		moved = TRUE;
    248  1.1       mrg 		break;
    249  1.1       mrg 	  case SHOT:
    250  1.1       mrg 	  case GRENADE:
    251  1.1       mrg 	  case SATCHEL:
    252  1.1       mrg 	  case BOMB:
    253  1.1       mrg # ifdef OOZE
    254  1.1       mrg 	  case SLIME:
    255  1.1       mrg # endif
    256  1.1       mrg # ifdef DRONE
    257  1.1       mrg 	  case DSHOT:
    258  1.1       mrg # endif
    259  1.1       mrg 		bp = is_bullet(y, x);
    260  1.1       mrg 		if (bp != NULL)
    261  1.1       mrg 			bp->b_expl = TRUE;
    262  1.1       mrg 		Maze[y][x] = SPACE;
    263  1.1       mrg 		moved = TRUE;
    264  1.1       mrg 		break;
    265  1.1       mrg 	  case LEFTS:
    266  1.1       mrg 	  case RIGHT:
    267  1.1       mrg 	  case ABOVE:
    268  1.1       mrg 	  case BELOW:
    269  1.1       mrg 		if (dir != pp->p_face)
    270  1.1       mrg 			sendcom(pp, BELL);
    271  1.1       mrg 		else {
    272  1.1       mrg 			newp = play_at(y, x);
    273  1.1       mrg 			checkdam(newp, pp, pp->p_ident, STABDAM, KNIFE);
    274  1.1       mrg 		}
    275  1.1       mrg 		break;
    276  1.1       mrg # ifdef FLY
    277  1.1       mrg 	  case FLYER:
    278  1.1       mrg 		newp = play_at(y, x);
    279  1.1       mrg 		message(newp, "Oooh, there's a short guy waving at you!");
    280  1.1       mrg 		message(pp, "You couldn't quite reach him!");
    281  1.1       mrg 		break;
    282  1.1       mrg # endif
    283  1.1       mrg # ifdef BOOTS
    284  1.1       mrg 	  case BOOT:
    285  1.1       mrg 	  case BOOT_PAIR:
    286  1.1       mrg 		if (Maze[y][x] == BOOT)
    287  1.1       mrg 			pp->p_nboots++;
    288  1.1       mrg 		else
    289  1.1       mrg 			pp->p_nboots += 2;
    290  1.1       mrg 		for (newp = Boot; newp < &Boot[NBOOTS]; newp++) {
    291  1.1       mrg 			if (newp->p_flying < 0)
    292  1.1       mrg 				continue;
    293  1.1       mrg 			if (newp->p_y == y && newp->p_x == x) {
    294  1.1       mrg 				newp->p_flying = -1;
    295  1.1       mrg 				if (newp->p_undershot)
    296  1.1       mrg 					fixshots(y, x, newp->p_over);
    297  1.1       mrg 			}
    298  1.1       mrg 		}
    299  1.1       mrg 		if (pp->p_nboots == 2)
    300  1.1       mrg 			message(pp, "Wow!  A pair of boots!");
    301  1.1       mrg 		else
    302  1.1       mrg 			message(pp, "You can hobble around on one boot.");
    303  1.1       mrg 		Maze[y][x] = SPACE;
    304  1.1       mrg 		moved = TRUE;
    305  1.1       mrg 		break;
    306  1.1       mrg # endif
    307  1.1       mrg 	}
    308  1.1       mrg 	if (moved) {
    309  1.1       mrg 		if (pp->p_ncshot > 0)
    310  1.1       mrg 			if (--pp->p_ncshot == MAXNCSHOT) {
    311  1.1       mrg 				cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
    312  1.1       mrg 				outstr(pp, " ok", 3);
    313  1.1       mrg 			}
    314  1.1       mrg 		if (pp->p_undershot) {
    315  1.1       mrg 			fixshots(pp->p_y, pp->p_x, pp->p_over);
    316  1.1       mrg 			pp->p_undershot = FALSE;
    317  1.1       mrg 		}
    318  1.1       mrg 		drawplayer(pp, FALSE);
    319  1.1       mrg 		pp->p_over = Maze[y][x];
    320  1.1       mrg 		pp->p_y = y;
    321  1.1       mrg 		pp->p_x = x;
    322  1.1       mrg 		drawplayer(pp, TRUE);
    323  1.1       mrg 	}
    324  1.1       mrg }
    325  1.1       mrg 
    326  1.1       mrg /*
    327  1.5  dholland  * turn_player:
    328  1.1       mrg  *	Change the direction the player is facing
    329  1.1       mrg  */
    330  1.2     lukem static void
    331  1.5  dholland turn_player(pp, dir)
    332  1.2     lukem 	PLAYER	*pp;
    333  1.2     lukem 	int	dir;
    334  1.1       mrg {
    335  1.1       mrg 	if (pp->p_face != dir) {
    336  1.1       mrg 		pp->p_face = dir;
    337  1.1       mrg 		drawplayer(pp, TRUE);
    338  1.1       mrg 	}
    339  1.1       mrg }
    340  1.1       mrg 
    341  1.1       mrg /*
    342  1.1       mrg  * fire:
    343  1.1       mrg  *	Fire a shot of the given type in the given direction
    344  1.1       mrg  */
    345  1.2     lukem static void
    346  1.1       mrg fire(pp, req_index)
    347  1.2     lukem 	PLAYER	*pp;
    348  1.2     lukem 	int	req_index;
    349  1.1       mrg {
    350  1.1       mrg 	if (pp == NULL)
    351  1.1       mrg 		return;
    352  1.1       mrg # ifdef DEBUG
    353  1.1       mrg 	if (req_index < 0 || req_index >= MAXBOMB)
    354  1.1       mrg 		message(pp, "What you do?");
    355  1.1       mrg # endif
    356  1.1       mrg 	while (req_index >= 0 && pp->p_ammo < shot_req[req_index])
    357  1.1       mrg 		req_index--;
    358  1.1       mrg 	if (req_index < 0) {
    359  1.1       mrg 		message(pp, "Not enough charges.");
    360  1.1       mrg 		return;
    361  1.1       mrg 	}
    362  1.1       mrg 	if (pp->p_ncshot > MAXNCSHOT)
    363  1.1       mrg 		return;
    364  1.1       mrg 	if (pp->p_ncshot++ == MAXNCSHOT) {
    365  1.1       mrg 		cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
    366  1.1       mrg 		outstr(pp, "   ", 3);
    367  1.1       mrg 	}
    368  1.1       mrg 	pp->p_ammo -= shot_req[req_index];
    369  1.6  dholland 	(void) snprintf(Buf, sizeof(Buf), "%3d", pp->p_ammo);
    370  1.1       mrg 	cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
    371  1.1       mrg 	outstr(pp, Buf, 3);
    372  1.1       mrg 
    373  1.1       mrg 	add_shot(shot_type[req_index], pp->p_y, pp->p_x, pp->p_face,
    374  1.1       mrg 		shot_req[req_index], pp, FALSE, pp->p_face);
    375  1.1       mrg 	pp->p_undershot = TRUE;
    376  1.1       mrg 
    377  1.1       mrg 	/*
    378  1.1       mrg 	 * Show the object to everyone
    379  1.1       mrg 	 */
    380  1.1       mrg 	showexpl(pp->p_y, pp->p_x, shot_type[req_index]);
    381  1.1       mrg 	for (pp = Player; pp < End_player; pp++)
    382  1.1       mrg 		sendcom(pp, REFRESH);
    383  1.1       mrg # ifdef MONITOR
    384  1.1       mrg 	for (pp = Monitor; pp < End_monitor; pp++)
    385  1.1       mrg 		sendcom(pp, REFRESH);
    386  1.1       mrg # endif
    387  1.1       mrg }
    388  1.1       mrg 
    389  1.1       mrg # ifdef	OOZE
    390  1.1       mrg /*
    391  1.1       mrg  * fire_slime:
    392  1.1       mrg  *	Fire a slime shot in the given direction
    393  1.1       mrg  */
    394  1.2     lukem static void
    395  1.1       mrg fire_slime(pp, req_index)
    396  1.2     lukem 	PLAYER	*pp;
    397  1.2     lukem 	int	req_index;
    398  1.1       mrg {
    399  1.1       mrg 	if (pp == NULL)
    400  1.1       mrg 		return;
    401  1.1       mrg # ifdef DEBUG
    402  1.1       mrg 	if (req_index < 0 || req_index >= MAXSLIME)
    403  1.1       mrg 		message(pp, "What you do?");
    404  1.1       mrg # endif
    405  1.1       mrg 	while (req_index >= 0 && pp->p_ammo < slime_req[req_index])
    406  1.1       mrg 		req_index--;
    407  1.1       mrg 	if (req_index < 0) {
    408  1.1       mrg 		message(pp, "Not enough charges.");
    409  1.1       mrg 		return;
    410  1.1       mrg 	}
    411  1.1       mrg 	if (pp->p_ncshot > MAXNCSHOT)
    412  1.1       mrg 		return;
    413  1.1       mrg 	if (pp->p_ncshot++ == MAXNCSHOT) {
    414  1.1       mrg 		cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
    415  1.1       mrg 		outstr(pp, "   ", 3);
    416  1.1       mrg 	}
    417  1.1       mrg 	pp->p_ammo -= slime_req[req_index];
    418  1.6  dholland 	(void) snprintf(Buf, sizeof(Buf), "%3d", pp->p_ammo);
    419  1.1       mrg 	cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
    420  1.1       mrg 	outstr(pp, Buf, 3);
    421  1.1       mrg 
    422  1.1       mrg 	add_shot(SLIME, pp->p_y, pp->p_x, pp->p_face,
    423  1.1       mrg 		slime_req[req_index] * SLIME_FACTOR, pp, FALSE, pp->p_face);
    424  1.1       mrg 	pp->p_undershot = TRUE;
    425  1.1       mrg 
    426  1.1       mrg 	/*
    427  1.1       mrg 	 * Show the object to everyone
    428  1.1       mrg 	 */
    429  1.1       mrg 	showexpl(pp->p_y, pp->p_x, SLIME);
    430  1.1       mrg 	for (pp = Player; pp < End_player; pp++)
    431  1.1       mrg 		sendcom(pp, REFRESH);
    432  1.1       mrg # ifdef MONITOR
    433  1.1       mrg 	for (pp = Monitor; pp < End_monitor; pp++)
    434  1.1       mrg 		sendcom(pp, REFRESH);
    435  1.1       mrg # endif
    436  1.1       mrg }
    437  1.1       mrg # endif
    438  1.1       mrg 
    439  1.1       mrg /*
    440  1.1       mrg  * add_shot:
    441  1.1       mrg  *	Create a shot with the given properties
    442  1.1       mrg  */
    443  1.2     lukem void
    444  1.1       mrg add_shot(type, y, x, face, charge, owner, expl, over)
    445  1.1       mrg int	type;
    446  1.1       mrg int	y, x;
    447  1.1       mrg char	face;
    448  1.1       mrg int	charge;
    449  1.1       mrg PLAYER	*owner;
    450  1.1       mrg int	expl;
    451  1.1       mrg char	over;
    452  1.1       mrg {
    453  1.2     lukem 	BULLET	*bp;
    454  1.2     lukem 	int	size;
    455  1.1       mrg 
    456  1.1       mrg 	switch (type) {
    457  1.1       mrg 	  case SHOT:
    458  1.1       mrg 	  case MINE:
    459  1.1       mrg 		size = 1;
    460  1.1       mrg 		break;
    461  1.1       mrg 	  case GRENADE:
    462  1.1       mrg 	  case GMINE:
    463  1.1       mrg 		size = 2;
    464  1.1       mrg 		break;
    465  1.1       mrg 	  case SATCHEL:
    466  1.1       mrg 		size = 3;
    467  1.1       mrg 		break;
    468  1.1       mrg 	  case BOMB:
    469  1.1       mrg 		for (size = 3; size < MAXBOMB; size++)
    470  1.1       mrg 			if (shot_req[size] >= charge)
    471  1.1       mrg 				break;
    472  1.1       mrg 		size++;
    473  1.1       mrg 		break;
    474  1.1       mrg 	  default:
    475  1.1       mrg 		size = 0;
    476  1.1       mrg 		break;
    477  1.1       mrg 	}
    478  1.1       mrg 
    479  1.1       mrg 	bp = create_shot(type, y, x, face, charge, size, owner,
    480  1.1       mrg 		(owner == NULL) ? NULL : owner->p_ident, expl, over);
    481  1.1       mrg 	bp->b_next = Bullets;
    482  1.1       mrg 	Bullets = bp;
    483  1.1       mrg }
    484  1.1       mrg 
    485  1.1       mrg BULLET *
    486  1.1       mrg create_shot(type, y, x, face, charge, size, owner, score, expl, over)
    487  1.2     lukem 	int	type;
    488  1.2     lukem 	int	y, x;
    489  1.2     lukem 	char	face;
    490  1.2     lukem 	int	charge;
    491  1.2     lukem 	int	size;
    492  1.2     lukem 	PLAYER	*owner;
    493  1.2     lukem 	IDENT	*score;
    494  1.2     lukem 	int	expl;
    495  1.2     lukem 	char	over;
    496  1.1       mrg {
    497  1.2     lukem 	BULLET	*bp;
    498  1.1       mrg 
    499  1.7  dholland 	bp = malloc(sizeof(*bp));
    500  1.1       mrg 	if (bp == NULL) {
    501  1.1       mrg 		if (owner != NULL)
    502  1.1       mrg 			message(owner, "Out of memory");
    503  1.1       mrg 		return NULL;
    504  1.1       mrg 	}
    505  1.1       mrg 
    506  1.1       mrg 	bp->b_face = face;
    507  1.1       mrg 	bp->b_x = x;
    508  1.1       mrg 	bp->b_y = y;
    509  1.1       mrg 	bp->b_charge = charge;
    510  1.1       mrg 	bp->b_owner = owner;
    511  1.1       mrg 	bp->b_score = score;
    512  1.1       mrg 	bp->b_type = type;
    513  1.1       mrg 	bp->b_size = size;
    514  1.1       mrg 	bp->b_expl = expl;
    515  1.1       mrg 	bp->b_over = over;
    516  1.1       mrg 	bp->b_next = NULL;
    517  1.1       mrg 
    518  1.1       mrg 	return bp;
    519  1.1       mrg }
    520  1.1       mrg 
    521  1.1       mrg /*
    522  1.1       mrg  * cloak:
    523  1.1       mrg  *	Turn on or increase length of a cloak
    524  1.1       mrg  */
    525  1.2     lukem static void
    526  1.1       mrg cloak(pp)
    527  1.2     lukem 	PLAYER	*pp;
    528  1.1       mrg {
    529  1.1       mrg 	if (pp->p_ammo <= 0) {
    530  1.1       mrg 		message(pp, "No more charges");
    531  1.1       mrg 		return;
    532  1.1       mrg 	}
    533  1.1       mrg # ifdef BOOTS
    534  1.1       mrg 	if (pp->p_nboots > 0) {
    535  1.1       mrg 		message(pp, "Boots are too noisy to cloak!");
    536  1.1       mrg 		return;
    537  1.1       mrg 	}
    538  1.1       mrg # endif
    539  1.6  dholland 	(void) snprintf(Buf, sizeof(Buf), "%3d", --pp->p_ammo);
    540  1.1       mrg 	cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
    541  1.1       mrg 	outstr(pp, Buf, 3);
    542  1.1       mrg 
    543  1.1       mrg 	pp->p_cloak += CLOAKLEN;
    544  1.1       mrg 
    545  1.1       mrg 	if (pp->p_scan >= 0)
    546  1.1       mrg 		pp->p_scan = -1;
    547  1.1       mrg 
    548  1.1       mrg 	showstat(pp);
    549  1.1       mrg }
    550  1.1       mrg 
    551  1.1       mrg /*
    552  1.1       mrg  * scan:
    553  1.1       mrg  *	Turn on or increase length of a scan
    554  1.1       mrg  */
    555  1.2     lukem static void
    556  1.1       mrg scan(pp)
    557  1.2     lukem 	PLAYER	*pp;
    558  1.1       mrg {
    559  1.1       mrg 	if (pp->p_ammo <= 0) {
    560  1.1       mrg 		message(pp, "No more charges");
    561  1.1       mrg 		return;
    562  1.1       mrg 	}
    563  1.6  dholland 	(void) snprintf(Buf, sizeof(Buf), "%3d", --pp->p_ammo);
    564  1.1       mrg 	cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
    565  1.1       mrg 	outstr(pp, Buf, 3);
    566  1.1       mrg 
    567  1.1       mrg 	pp->p_scan += SCANLEN;
    568  1.1       mrg 
    569  1.1       mrg 	if (pp->p_cloak >= 0)
    570  1.1       mrg 		pp->p_cloak = -1;
    571  1.1       mrg 
    572  1.1       mrg 	showstat(pp);
    573  1.1       mrg }
    574  1.1       mrg 
    575  1.1       mrg /*
    576  1.1       mrg  * pickup:
    577  1.1       mrg  *	check whether the object blew up or whether he picked it up
    578  1.1       mrg  */
    579  1.2     lukem void
    580  1.1       mrg pickup(pp, y, x, prob, obj)
    581  1.2     lukem 	PLAYER	*pp;
    582  1.2     lukem 	int	y, x;
    583  1.2     lukem 	int	prob;
    584  1.2     lukem 	int	obj;
    585  1.1       mrg {
    586  1.2     lukem 	int	req;
    587  1.1       mrg 
    588  1.1       mrg 	switch (obj) {
    589  1.1       mrg 	  case MINE:
    590  1.1       mrg 		req = BULREQ;
    591  1.1       mrg 		break;
    592  1.1       mrg 	  case GMINE:
    593  1.1       mrg 		req = GRENREQ;
    594  1.1       mrg 		break;
    595  1.1       mrg 	  default:
    596  1.1       mrg 		abort();
    597  1.1       mrg 	}
    598  1.1       mrg 	if (rand_num(100) < prob)
    599  1.1       mrg 		add_shot(obj, y, x, LEFTS, req, (PLAYER *) NULL,
    600  1.1       mrg 			TRUE, pp->p_face);
    601  1.1       mrg 	else {
    602  1.1       mrg 		pp->p_ammo += req;
    603  1.6  dholland 		(void) snprintf(Buf, sizeof(Buf), "%3d", pp->p_ammo);
    604  1.1       mrg 		cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
    605  1.1       mrg 		outstr(pp, Buf, 3);
    606  1.1       mrg 	}
    607  1.1       mrg }
    608