|
|
1.1 root 1: char rcsid[] = "@(#)$Header: warp.c,v 7.0.1.3 86/12/12 17:07:44 lwall Exp $";
2:
3: /* warp -- a real-time space war program
4: * author: Larry Wall
5: * helpers: Jonathan and Mark Biggar, and Dan Faigin
6: * special thanks to my sweetie Gloria who suggested the Planet Crusher
7: *
8: * Copyright (C) 1986, Larry Wall
9: *
10: * This program may be copied as long as this copyright notice is
11: * included, and as long as it is not being copied for purposes
12: * of profit. If you want to modify this program in any way other
13: * than normal configuration changes, common decency would suggest
14: * that you also modify the name of the program so that my good name
15: * (what there is of it) is not impugned. (Calling it something like
16: * "warpx" or "superwarp" would be fine.) Also, give it another
17: * WARPDIR so that the scoreboards don't get confused.
18: *
19: * version 5.0 04/20/83
20: * 5.1 05/05/83 various tidbits
21: * 5.2 05/12/83 VAX -> vax, ifdef'ed a SIGCONT
22: * 5.3 05/24/83 RCS
23: *
24: * $Log: warp.c,v $
25: * Revision 7.0.1.3 86/12/12 17:07:44 lwall
26: * Baseline for net release.
27: *
28: * Revision 7.0.1.2 86/10/20 12:08:00 lwall
29: * Made all exits reset tty.
30: *
31: * Revision 7.0.1.1 86/10/16 10:54:13 lwall
32: * Added Damage. Fixed random bugs.
33: *
34: * Revision 7.0 86/10/08 15:14:47 lwall
35: * Split into separate files. Added amoebas and pirates.
36: *
37: * Revision 6.4 83/12/16 13:11:45 lwall
38: * Handled 15 bit random number generators.
39: *
40: * Fixed array overflow bug on multiple zaps.
41: *
42: * Multiple zaps now consolidated to minimize output.
43: *
44: * Tholian jackpot games outlawed under difficulty 15.
45: *
46: * Revision 6.3 83/08/24 11:17:49 lwall
47: * Fixed array overflow bug on multiple zap.
48: *
49: * Revision 6.2 83/08/23 18:06:37 lwall
50: * Added zap command.
51: * Warp -s should now work on dumb terminals
52: * Specifying difficulty >= 40 now just makes it a special game.
53: * SIGTTOU #ifdef'ed.
54: * No-delay read provided as alternative to FIONREAD.
55: * Warp won't report "-1 obsolete" when there are no Enterprises left.
56: * Some high-difficulty tuning.
57: *
58: * Revision 6.1 83/08/17 08:49:03 lwall
59: * Fixed obscure bug in storing UP that caused a %. in CM to occasionally
60: * foist garbage onto the screen.
61: *
62: * Revision 6.0 83/08/08 17:09:26 lwall
63: * New baseline version for net release.
64: *
65: * Revision 5.5 83/08/01 10:59:56 lwall
66: * Cloaking for the Enterprise.
67: * Difficulty now goes to 99, and many activities depending on difficulty
68: * have been adjusted in frequency.
69: * Simplified exit sequence, and reduced dependencies on control
70: * characters. You needn't see the scoreboard if you don't want to.
71: * Hitting i,w,c, or v switches to Enterprise. Hitting p switches to Base.
72: * Excessive use of q is not allowed.
73: * Excessive use of D is not allowed.
74: * Scoreboard may depend on either full name or login name.
75: * Integrated scoreboard lister. Login name now shows up on scoreboard.
76: * "Hidden" startup options are now upper case.
77: * Checks upon startup for no cursor movement, or screen too small.
78: * Checks upon startup that WARPDIR is correctly protected, and that warp
79: * is running setuid. As an additional bonus this prevents root from
80: * running warp, which mucks things up, UN*X be blessed.
81: * All gets's turned into fgets's for safety.
82: * Bonus Enterprises and Bases.
83: * Escalating bonuses for saving Base and Enterprise.
84: * Escalating Enterprise energy.
85: * Turbolasers decrease with distance.
86: * Really smart enemies can see through stars occasionally.
87: * Occasional Tholian jackpot waves. Tholians are a trifle nastier.
88: * Choleric Gorns.
89: * An O or o can miss seeing you. Enemies can avoid a stationary O, o, or X.
90: * Warp 3 enemies and other nastinesses are possible in massacre mode.
91: * Enemies that decide to navigate when they see you can do other things than
92: * just come toward you.
93: * Gorns occasionally launch a salvo for the fun of it.
94: * Only star and enemy explosions can keep the round going now.
95: * Bounces don't always go back to starting spot now.
96: * Better full name processing. USG quirks handled. & substitution also
97: * handled now (whoever dreamed up that one must have been in the middle
98: * of the night before the morning after).
99: * Catch ^D on fgets.
100: * Version number printer.
101: * Less signal catching during debugging.
102: *
103: * Revision 5.4 83/06/24 09:28:38 lwall
104: * 16 bit random number generators are now supported.
105: * Made warp not blow up on a null save file.
106: * Warp now prints E and B before the stars.
107: * Fixed bug which caused torp count to get decremented even when no torp
108: * was launched because of an obstacle.
109: * Put %<n>ld formats where appropriate.
110: * Fixed E: 0 0 bug on refresh.
111: *
112: * Revision 5.3 83/05/24 14:03:10 lwall
113: * Starting RCS
114: *
115: */
116:
117: #include "INTERN.h"
118: #include "warp.h"
119: #include "EXTERN.h"
120: #include "bang.h"
121: #include "init.h"
122: #include "intrp.h"
123: #include "object.h"
124: #include "move.h"
125: #include "play.h"
126: #include "score.h"
127: #include "sig.h"
128: #include "term.h"
129: #include "them.h"
130: #include "us.h"
131: #include "util.h"
132: #include "version.h"
133: #include "weapon.h"
134:
135: main(argc,argv)
136: int argc;
137: char *argv[];
138: {
139: char tmp, *s, *tcbuf;
140:
141: int i;
142:
143: FILE *savfil;
144:
145: #if RANDBITS > 16
146: for (i=100; i; i--)
147: if (rand() >= 65536)
148: goto rand_ok;
149: printf("Recompile with RANDBITS = 15 or 16.\n");
150: exit(1);
151: #else
152: #if RANDBITS > 15
153: for (i=100; i; i--) {
154: if (rand() >= 32768)
155: goto rand_ok;
156: }
157: printf("Recompile with RANDBITS = 15.\n");
158: exit(1);
159: #endif
160: #endif
161: rand_ok:
162:
163: #ifdef lint /* to suppress "defined but never used" */
164: # ifdef SIGTSTP
165: (void)stop_catcher();
166: # endif
167: # ifdef SIGCONT
168: (void)cont_catcher();
169: # endif
170: #endif
171:
172: while (--argc > 0 && (*++argv)[0] == '-')
173: for (s = argv[0]+1; *s != '\0'; s++)
174: switch (*s) {
175: case '&':
176: amoebaspec = TRUE;
177: beginner = TRUE;
178: break;
179: case 'A':
180: apolspec = TRUE;
181: beginner = TRUE;
182: break;
183: case 'b':
184: beginner = TRUE;
185: break;
186: case 'C':
187: crushspec = TRUE;
188: beginner = TRUE;
189: break;
190: case 'D':
191: debugging = TRUE;
192: #ifdef DEBUGGING
193: debug = atoi(++s);
194: #endif
195: s += strlen(s)-1;
196: break;
197: case 'd':
198: s++;
199: if (*s == '=') s++;
200: ismarts = atoi(s);
201: if (ismarts <= 0)
202: ismarts = 1;
203: if (ismarts > 99)
204: ismarts = 99;
205: if (ismarts > 40)
206: beginner = TRUE;
207: s += strlen(s)-1;
208: break;
209: case 'E':
210: klingspec = TRUE;
211: beginner = TRUE;
212: s++;
213: if (*s == '=') s++;
214: inumenemies = atoi(s);
215: s += strlen(s)-1;
216: break;
217: case 'F':
218: friendspec = TRUE;
219: beginner = TRUE;
220: s++;
221: if (*s == '=') s++;
222: inumfriends = atoi(s);
223: s += strlen(s)-1;
224: break;
225: case 'G':
226: gornspec = TRUE;
227: beginner = TRUE;
228: break;
229: case 'l':
230: lowspeed = TRUE;
231: break;
232: case 'm':
233: metakey = TRUE;
234: break;
235: case 'M':
236: massacre = TRUE;
237: break;
238: case 'P':
239: piratespec = TRUE;
240: beginner = TRUE;
241: s++;
242: if (*s == '=') s++;
243: inumpirates = atoi(s);
244: s += strlen(s)-1;
245: break;
246: case 'S':
247: prespec = TRUE;
248: beginner = TRUE;
249: s++;
250: if (*s == '=') s++;
251: if (*s)
252: prescene = atoi(s);
253: else
254: prescene = -1;
255: s += strlen(s)-1;
256: break;
257: case 'R':
258: romspec = TRUE;
259: beginner = TRUE;
260: break;
261: case '*':
262: starspec = TRUE;
263: beginner = TRUE;
264: s++;
265: if (*s == '=') s++;
266: inumstars = atoi(s);
267: s += strlen(s)-1;
268: break;
269: case 's':
270: scorespec = TRUE;
271: break;
272: case 'T':
273: tholspec = TRUE;
274: beginner = TRUE;
275: break;
276: case 'x':
277: experimenting = TRUE;
278: break;
279: case 'v':
280: version();
281: exit(0);
282: break;
283: default:
284: fprintf(stderr,"warp: illegal option %c\n", *s);
285: fprintf(stderr, "Usage: warp -dn -b -x -v -s\n");
286: exit(1);
287: }
288: if (argc != 0) {
289: fprintf(stderr, "Usage: warp -dn -b -x -v -s\n");
290: exit(1);
291: }
292: bang_init();
293: move_init();
294: object_init();
295: play_init();
296: them_init();
297: us_init();
298: util_init();
299: weapon_init();
300:
301: tcbuf = malloc(1024);
302: intrp_init(tcbuf);
303:
304: if (chdir(warplib) < 0)
305: fprintf(stderr,nocd,warplib);
306:
307: term_init();
308:
309: term_set(tcbuf);
310: free(tcbuf);
311:
312: umask(022); /* mustn't rely on incoming umask--could be 033 which */
313: /* would disable people from running wscore */
314:
315: score_init();
316:
317: sig_init();
318:
319: if (totalscore) {
320: clear();
321: mvaddstr(12,25,"*** restoring saved game ***");
322: roundsleep(1);
323: }
324:
325: srand(getpid());
326:
327: do {
328: for (keepgoing = TRUE;;) {
329: if (!experimenting) {
330: if ((savfil = fopen(savefilename,"w")) == NULL) {
331: resetty();
332: printf("Can't open savefile\r\n");
333: finalize(1);
334: }
335: fprintf(savfil,
336: "%-8s %10ld, %2d,%5d,%2d,%2d,%3d %c%c%c%c%c%c%c%c%c\n",
337: logname, totalscore, smarts, cumsmarts,
338: numents, numbases, wave,
339: apolspec ? 'a' : ' ',
340: beginner ? 'b' : ' ',
341: crushspec ? 'c' : ' ',
342: gornspec ? 'g' : ' ',
343: massacre ? 'm' : ' ',
344: romspec ? 'r' : ' ',
345: tholspec ? 't' : ' ',
346: lowspeed ? 'l' : ' ',
347: amoebaspec ? '&' : ' '
348: );
349: fprintf(savfil," running on %s, process #%d\n",
350: term+5,getpid());
351: Fclose(savfil);
352: }
353:
354: lastscore = totalscore;
355: initialize();
356: play();
357: cumsmarts += smarts;
358: wavescore();
359: if (numents<=0 && numbases<=0)
360: keepgoing = FALSE;
361: if (!keepgoing) break;
362: do {
363: if (experimenting) {
364: mvaddstr(23,15,
365: " [Hit space to continue, 'q' to quit] ");
366: }
367: else {
368: mvaddstr(23,15,
369: "[Hit space to continue, 's' to save, 'q' to quit]");
370: }
371: sleep(1);
372: Fflush(stdout);
373: eat_typeahead();
374: getcmd(&tmp);
375: if (tmp == BREAKCH || tmp == INTRCH) {
376: mvaddstr(23,15,
377: " ");
378: mvaddstr(23,33,
379: "Really quit? ");
380: getcmd(&tmp);
381: if (tmp == 'y' || tmp == 'Y')
382: tmp = 'q';
383: else
384: tmp = 1;
385: }
386: } while (tmp != INTRCH && tmp != BREAKCH && !index(" qQs",tmp));
387: if (tmp != ' ' && tmp != 's') break;
388: if (!beginner && smarts < 20)
389: smarts += 4;
390: else if (!beginner && smarts < 35)
391: smarts += 2;
392: else if (smarts < 99)
393: smarts++;
394: if (tmp == 's') save_game();
395: }
396: score();
397:
398: } while (justonemoretime);
399:
400: if (!experimenting)
401: unlink(savefilename);
402:
403: clear();
404: resetty();
405: exit(0);
406: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.