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