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