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