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