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