Commit | Line | Data |
---|---|---|
c77f0542 | 1 | #ifndef lint |
ac83b1e0 | 2 | static char *sccsid = "@(#)pl_1.c 1.4 83/05/19"; |
c77f0542 CL |
3 | #endif |
4 | #include "player.h" | |
5 | #include <sys/types.h> | |
6 | #include <sys/stat.h> | |
7 | ||
8 | WINDOW *view,*slot; | |
9 | /* int devestate; */ | |
10 | ||
11 | acceptcombat() | |
12 | { | |
13 | int crew[3], men = 0, rangeofshot, target, temp; | |
14 | int n, r, guns[2], load[2], car[2], roll[2]; | |
15 | int ready[2], index, rakehim, sternrake; | |
16 | int shootat[2], /*power,*/ hit[2], closest[2], ship; | |
17 | int hhits = 0, ghits = 0, rhits = 0, chits = 0; | |
18 | int buf; | |
19 | struct shipspecs *ptr; | |
20 | struct File *ptr1; | |
21 | ||
22 | ptr = &specs[scene[game].ship[player].shipnum]; | |
23 | ptr1 = scene[game].ship[player].file; | |
24 | crew[0] = ptr -> crew1; | |
25 | crew[1] = ptr -> crew2; | |
26 | crew[2] = ptr -> crew3; | |
27 | ready[0] = ptr1 -> readyL; | |
28 | ready[1] = ptr1 -> readyR; | |
29 | load[0] = ptr1 -> loadL; | |
30 | load[1] = ptr1 -> loadR; | |
31 | guns[0] = ptr -> gunL; | |
32 | guns[1] = ptr -> gunR; | |
33 | car[0] = ptr -> carL; | |
34 | car[1] = ptr -> carR; | |
35 | for (n = 0; n < 3; n++){ | |
36 | if (ptr1 -> OBP[n].turnsent) | |
37 | men += ptr1 -> OBP[n].mensent; | |
38 | } | |
39 | for (n = 0; n < 3; n++){ | |
40 | if (ptr1 -> DBP[n].turnsent) | |
41 | men += ptr1 -> DBP[n].mensent; | |
42 | } | |
43 | if (men) { | |
44 | crew[0] = men/100 ? 0 : crew[0] != 0; | |
45 | crew[1] = (men%100)/10 ? 0 : crew[1] != 0; | |
46 | crew[2] = men%10 ? 0 : crew[2] != 0; | |
47 | } | |
48 | for (r = 0; r < 2; r++) { | |
49 | if ((guns[r] || car[r]) && crew[2] && load[r] && | |
50 | ready[r] <= 0 && !ptr1 -> struck && | |
51 | ((closest[r] = closestenemy(player, (r ? 'r' : 'l'), 1)) != 30000)) { | |
52 | switch(load[r]) { | |
53 | case GRAPE: | |
54 | rangeofshot = 1; | |
55 | break; | |
56 | case CHAIN: | |
57 | rangeofshot = 3; | |
58 | break; | |
59 | case DOUBLE: | |
60 | rangeofshot = 1; | |
61 | break; | |
62 | case ROUND: | |
63 | rangeofshot = 10; | |
64 | break; | |
65 | } | |
66 | /* if (power) | |
67 | rangeofshot = 20; */ | |
68 | if ((target = range(player, closest[r])) <= rangeofshot && | |
69 | !scene[game].ship[closest[r]].file -> struck && | |
70 | (guns[r] || (car[r] && target < 3))) { | |
71 | Signal("%s (%c%c) within range of %s broadside.", closest[r], (r?"right":"left")); | |
72 | if (load[r] > CHAIN && target < 6) { | |
73 | Signal("Aim for hull or rigging? ", -1, 0); | |
74 | while ((buf = getch()) == EOF); | |
75 | addch(buf); | |
76 | if(buf == 'r') | |
77 | shootat[r] = RIGGING; | |
78 | else if (buf == 'h') | |
79 | shootat[r] = HULL; | |
80 | else { | |
81 | shootat[r] = -1; | |
82 | Signal("'Avast there! Hold your fire.'", -1, 0); | |
83 | } | |
84 | } else { | |
85 | shootat[r] = RIGGING; | |
86 | Signal("Fire? ", -1, 0); | |
87 | while((buf = getch()) == EOF); | |
88 | addch(buf); | |
89 | if (buf == 'n') { | |
90 | shootat[r] = -1; | |
91 | Signal("Belay that! Hold your fire.", -1, 0); | |
92 | } | |
93 | } | |
94 | if (shootat[r] != -1) { | |
95 | fired = 1; | |
96 | rakehim = gunsbear(player, closest[r]) && !gunsbear(closest[r], player); | |
97 | temp = portside(closest[r], player, 1) - pos[closest[r]].dir + 1; | |
98 | if (temp < 1) | |
99 | temp += 8; | |
100 | if (temp > 8) | |
101 | temp -= 8; | |
102 | sternrake = temp > 4 && temp < 6; | |
103 | /* if (power) { | |
104 | sternrake = 1; | |
105 | rakehim = 1; | |
106 | } */ | |
107 | if (rakehim && !sternrake) | |
108 | Signal("Raking the %s!", closest[r], 0); | |
109 | else if (rakehim && sternrake) | |
110 | Signal("Stern Rake! %s splintering!", closest[r], 0); | |
111 | index = guns[r]; | |
112 | if (target < 3) | |
113 | index += car[r]; | |
114 | index = (index - 1)/3; | |
115 | index = index > 8 ? 8 : index; | |
116 | if (!rakehim) | |
117 | hit[r] = HDT[index][target-1]; | |
118 | else | |
119 | hit[r] = HDTrake[index][target-1]; | |
120 | if (rakehim && sternrake) | |
121 | hit[r]++; | |
122 | hit[r] += QUAL[index][ptr -> qual-1]; | |
123 | for (n=0; n < 3 && ptr1 -> captured < 0; n++) | |
124 | if (!crew[n]) | |
125 | if (index <= 5) | |
126 | hit[r]--; | |
127 | else | |
128 | hit[r] -= 2; | |
129 | if (ready[r] <= -30000) | |
130 | if (index <= 3) | |
131 | hit[r]++; | |
132 | else | |
133 | hit[r] += 2; | |
134 | if (ptr1 -> captured > -1) | |
135 | if (index <= 1) | |
136 | hit[r]--; | |
137 | else | |
138 | hit[r] -= 2; | |
139 | hit[r] += AMMO[index][load[r] - 1]; | |
140 | if (((temp = ptr -> class) >= 5 || temp == 1) && windspeed == 5) | |
141 | hit[r]--; | |
142 | if (windspeed == 6 && temp == 4) | |
143 | hit[r] -= 2; | |
144 | if (windspeed == 6 && temp <= 3) | |
145 | hit[r]--; | |
146 | if (hit[r] >= 0) { | |
147 | roll[r] = die(); | |
148 | if (load[r] == GRAPE) | |
149 | chits = hit[r]; | |
150 | else { | |
151 | hit[r] = hit[r] > 10 ? 10 : hit[r]; | |
152 | chits = shootat[r] ? RigTable[hit[r]][roll[r]-1].C : HullTable[hit[r]][roll[r]-1].C; | |
153 | rhits = shootat[r] ? RigTable[hit[r]][roll[r]-1].R : HullTable[hit[r]][roll[r]-1].R; | |
154 | /* if (devestate && power) { | |
155 | hhits = 10; | |
156 | devestate = 0; | |
157 | } | |
158 | else */ | |
159 | hhits = shootat[r] ? RigTable[hit[r]][roll[r]-1].H : HullTable[hit[r]][roll[r]-1].H; | |
160 | ghits = shootat[r] ? RigTable[hit[r]][roll[r]-1].G : HullTable[hit[r]][roll[r]-1].G; | |
161 | if (scene[game].ship[closest[r]].file -> FS) | |
162 | rhits *= 2; | |
163 | if (load[r] == CHAIN) { | |
164 | ghits = 0; | |
165 | hhits = 0; | |
166 | } | |
167 | } | |
168 | /* if (power) | |
169 | table(shootat[r], load[r], 10, closest[r], player, 6); | |
170 | else */ | |
171 | table(shootat[r], load[r], hit[r], closest[r], player, roll[r]); | |
172 | } | |
173 | scroll = 18; | |
174 | move(scroll++, 0); | |
175 | clearline(); | |
176 | printw("Damage inflicted on the %s:", scene[game].ship[closest[r]].shipname); | |
177 | move(scroll++, 0); | |
178 | clearline(); | |
179 | printw("\t%d HULL, %d GUNS, %d CREW, %d RIGGING", hhits, ghits, chits, rhits); | |
180 | load[r] = 0; | |
181 | if (!r) { | |
182 | ptr1 -> loadL = 0; | |
183 | ptr1 -> readyL = 0; | |
184 | } else { | |
185 | ptr1 -> loadR = 0; | |
186 | ptr1 -> readyR = 0; | |
187 | } | |
188 | } | |
189 | } else { | |
190 | load[r] = 0; | |
191 | Signal("Unable to fire %s broadside", -1, (r?"right":"left")); | |
192 | } | |
193 | } else | |
194 | Signal("Unable to fire %s broadside", -1, (r?"right":"left")); | |
195 | } | |
196 | } | |
197 | ||
198 | leave(conditions) | |
199 | int conditions; | |
200 | { | |
201 | FILE *fp; | |
202 | int people; | |
203 | float net; | |
204 | char * capn; | |
205 | char message[60]; | |
206 | register int n; | |
207 | struct logs log[10], temp; | |
208 | ||
209 | signal(SIGHUP, SIG_IGN); | |
210 | signal(SIGINT, SIG_IGN); | |
211 | signal(SIGQUIT, SIG_IGN); | |
212 | signal(SIGALRM, SIG_IGN); | |
213 | ||
214 | if (conditions != -1) { | |
215 | capn = scene[game].ship[player].file -> captain; | |
216 | sprintf(message,"Captain %s relinquishing.",capn); | |
217 | Write(FILES + player, 1, 164, message); | |
218 | ||
219 | if (fp = fopen(LOGFILE, "r+")) { | |
220 | net = (float) (scene[game].ship[player].file -> points) / specs[scene[game].ship[player].shipnum].pts; | |
221 | people = getw(fp); | |
222 | n = fread(log, sizeof(struct logs), 10, fp); | |
223 | for (; n < 10; n++) | |
224 | log[n].fname[0] = log[n].uid = log[n].fshipnum = log[n].fgamenum = log[n].netpoints = 0; | |
225 | rewind(fp); | |
226 | if(people < 0) | |
227 | putw(1, fp); | |
228 | else | |
229 | putw(people+1, fp); | |
230 | for (n=0; n < 10; n++) | |
231 | if (net > (float) log[n].netpoints / specs[scene[log[n].fgamenum].ship[log[n].fshipnum].shipnum].pts) { | |
232 | fwrite(log, sizeof(struct logs), n, fp); | |
233 | strcpy(temp.fname, capn); | |
234 | temp.uid = getuid(); | |
235 | temp.fshipnum = player; | |
236 | temp.fgamenum = game; | |
237 | temp.netpoints = scene[game].ship[player].file -> points; | |
238 | fwrite(&temp, sizeof(struct logs), 1, fp); | |
239 | fwrite(log + n, sizeof(struct logs), 9 - n, fp); | |
240 | break; | |
241 | } | |
242 | fclose(fp); | |
243 | } | |
244 | Write(FILES + player, 1, 0, " "); | |
245 | Write(SCENARIO, 0, 8, scene[game].people - 1); | |
246 | screen(); | |
247 | fclose(syncfile); | |
248 | Signal("It looks like you've had it!", -1, 0); | |
249 | if (conditions == 1) | |
250 | Signal("Your ship was captured.", -1, 0); | |
251 | if (conditions == 2) | |
252 | Signal("No more enemies.", -1, 0); | |
253 | if (conditions == 3) | |
254 | Signal("Hurricane! All ships destroyed.", -1, 0); | |
255 | move(0, LINES-1); | |
256 | scroll = LINES; | |
257 | clearline(); | |
258 | refresh(); | |
259 | } | |
260 | nocrmode(); | |
261 | echo(); | |
262 | endwin(); | |
263 | exit(0); | |
264 | } | |
265 | ||
266 | choke() | |
267 | { | |
268 | leave(0); | |
269 | } | |
270 | ||
271 | grapungrap() | |
272 | { | |
273 | register int n, k, l, number, captured; | |
274 | int buf; | |
275 | ||
276 | for (n=0; n < scene[game].vessels ; n++) { | |
277 | if (n != player && (range(player, n) <= 1 || grapple(player, n))) { | |
278 | if ((captured = scene[game].ship[n].file -> captured) < 0) | |
279 | captured = n; | |
280 | Signal("Attempt to grapple or ungrapple %s (%c%c): ", n, 0); | |
281 | while((buf = getch()) == EOF); | |
282 | addch(buf); | |
283 | if (buf == 'g') { | |
284 | number = die() < 3; | |
285 | if (!number && scene[game].ship[player].nationality == scene[game].ship[captured].nationality) | |
286 | number = 1; | |
287 | if (number) { | |
288 | for (l=0; l < 10 && scene[game].ship[player].file -> grapples[l].turnfoul; l++); | |
289 | if (!scene[game].ship[player].file -> grapples[l].turnfoul) { | |
290 | Write(FILES + player, 0, 124 + l*4, turn); | |
291 | Write(FILES + player, 0, 124 + l*4 + 2, n); | |
292 | } | |
293 | for (l=0; l < 10 && scene[game].ship[n].file -> grapples[l].turnfoul; l++); | |
294 | if (!scene[game].ship[n].file -> grapples[l].turnfoul) { | |
295 | Write(FILES + n, 0, 124 + l*4, turn); | |
296 | Write(FILES + n, 0, 124 + l*4 + 2, player); | |
297 | } | |
298 | } | |
299 | if (number) { | |
300 | Signal("Attempt succeeds!", 0, 0); | |
301 | makesignal("grappled with %s (%c%c)", n, player); | |
302 | } else | |
303 | Signal("Attempt fails.", 0, 0); | |
304 | } | |
305 | if (buf == 'u'){ for (k=0; k < 10; k++) { | |
306 | if (scene[game].ship[player].file -> grapples[k].turnfoul && n == scene[game].ship[player].file -> grapples[k].toship) { | |
307 | if (die() < 3 || scene[game].ship[player].nationality == scene[game].ship[captured].nationality) { | |
308 | cleangrapple(player, n, k); | |
309 | Signal("Attempt succeeds!", 0, 0); | |
310 | makesignal("ungrappling with %s (%c%c)", n, player); | |
311 | } else | |
312 | Signal("Attempt fails.", 0, 0); | |
313 | } | |
314 | } | |
315 | } | |
316 | } | |
317 | } | |
318 | } | |
319 | ||
320 | unfoulplayer() | |
321 | { | |
322 | register int n, toship; | |
323 | int buf; | |
324 | ||
325 | for (n=0; n < 10; n++) { | |
326 | if (scene[game].ship[player].file -> fouls[n].turnfoul) { | |
327 | Signal("Attempt to unfoul with the %s (%c%c)? ", (toship = scene[game].ship[player].file -> fouls[n].toship), 0); | |
328 | while((buf = getch()) == EOF); | |
329 | addch(buf); | |
330 | if (buf == 'y' && die() < 3) { | |
331 | cleanfoul(player, toship, n); | |
332 | Signal("Attempt succeeds!", 0, 0); | |
333 | makesignal("unfouling %s (%c%c)", toship, player); | |
334 | } else if (buf == 'y') | |
335 | Signal("Attempt fails.", 0, 0); | |
336 | } | |
337 | } | |
338 | } | |
339 | ||
340 | initialize(nodriver, randomize) | |
341 | char randomize, nodriver; | |
342 | { | |
343 | char comm[80], num[5], file[25], capn; | |
344 | char message[60]; | |
345 | int load = ROUND, ready = -30000; | |
346 | int people = 0; | |
a2294d92 | 347 | int pid, omask; |
c77f0542 CL |
348 | register int n; |
349 | register int k; | |
350 | struct stat Stat; | |
351 | char *nameptr; | |
352 | ||
353 | srand(pid = getpid()); | |
c77f0542 CL |
354 | initscr(); |
355 | view = newwin(ROWSINVIEW, COLSINVIEW, 2, 1); | |
356 | slot = newwin(ROWSINVIEW, 3, 2, 1+COLSINVIEW); | |
357 | ||
358 | if (game < 0) { | |
359 | puts("Choose a scenario:\n"); | |
360 | puts("\n\tNUMBER\tSHIPS\tIN PLAY\tTITLE"); | |
361 | for (n=0; n < NUMOFSCENES; n++) { | |
362 | sprintf(file, "/tmp/.%d", n); | |
363 | printf("\t%d):\t%d", n, scene[n].vessels); | |
364 | if (stat(file, &Stat) >= 0) | |
365 | printf("\tYES"); | |
366 | else | |
367 | printf("\tno"); | |
368 | printf("\t%s\n", scene[n].name); | |
369 | } | |
370 | reprint: | |
371 | printf("\nScenario number? "); | |
372 | scanf("%d", &game); | |
373 | while (getchar() != '\n'); | |
374 | } | |
375 | if (game < 0 || game >= NUMOFSCENES) { | |
376 | puts("Very funny."); | |
377 | endwin(); | |
378 | exit(1); | |
379 | } | |
380 | sprintf(file, "/tmp/.%d", game); | |
a2294d92 CL |
381 | if (stat(file, &Stat) < 0 ) { |
382 | #ifdef SETUID | |
383 | omask = umask(077); | |
384 | #else | |
385 | omask = umask(011); | |
386 | #endif | |
c77f0542 | 387 | syncfile = fopen(file, "w+"); |
a2294d92 CL |
388 | umask(omask); |
389 | } else { | |
c77f0542 CL |
390 | syncfile = fopen(file, "r+"); |
391 | people = 1; | |
392 | } | |
393 | lastsync = 0; | |
394 | for (n=0; n < scene[game].vessels; n++) { | |
395 | nation[scene[game].ship[n].nationality + 1] = n + 1; | |
396 | if ((scene[game].ship[n].file = (struct File *) calloc(1, sizeof(struct File))) == NULL) { | |
397 | puts("OUT OF MEMORY"); | |
398 | endwin(); | |
399 | exit(0); | |
400 | } | |
401 | scene[game].ship[n].file -> captured = -1; | |
402 | } | |
403 | if (!nation[2]) | |
404 | nation[2] = nation[1]; | |
405 | if (!nation[3]) | |
406 | nation[3] = nation[2]; | |
407 | if (people > 0) { | |
408 | puts("Synchronizing with the other players..."); | |
409 | fflush(stdout); | |
410 | sync(); | |
411 | capn = 1; | |
412 | for (n=0; n < scene[game].vessels && capn; n++) { | |
413 | capn = scene[game].ship[n].file -> captain[0]; | |
414 | if (scene[game].ship[n].file -> struck || scene[game].ship[n].file -> captured > -1) | |
415 | capn = 1; | |
416 | } | |
417 | if (!capn) | |
418 | player = n-1; | |
419 | else { | |
420 | puts("All ships taken in that scenario."); | |
421 | for (n=0; n < scene[game].vessels; n++) | |
422 | free(scene[game].ship[n].file); | |
423 | people = 0; | |
424 | for (n=0; n < 5; n++) | |
425 | nation[n] = 0; | |
426 | goto reprint; | |
427 | } | |
428 | } else | |
429 | player = 0; | |
430 | while (randomize) { | |
431 | static char *color[] = | |
432 | { "(American)", "(British)", "(Spanish)", "(French)" }; | |
433 | ||
434 | puts(scene[game].name); | |
435 | putchar('\n'); | |
436 | for (n=0; n < scene[game].vessels; n++) { | |
437 | printf(" %2d: %-10s %-15s (%-2d pts) ", n, | |
438 | color[scene[game].ship[n].nationality], | |
439 | scene[game].ship[n].shipname, | |
440 | specs[scene[game].ship[n].shipnum].pts); | |
441 | if(scene[game].ship[n].file -> captain[0]) | |
442 | puts(scene[game].ship[n].file -> captain); | |
443 | else if (scene[game].ship[n].file -> struck) | |
444 | puts("(struck)"); | |
445 | else if(scene[game].ship[n].file -> captured > -1) | |
446 | puts("(captured)"); | |
447 | else | |
448 | puts("(available)"); | |
449 | } | |
450 | putchar('\n'); | |
451 | printf("Which ship do you want (0-%d)? ",scene[game].vessels-1); | |
452 | if (scanf("%d",&player) != 1 || player < 0 || player >= scene[game].vessels) { | |
453 | while (getchar() != '\n'); | |
454 | puts("Say what?"); | |
455 | } else { | |
456 | while (getchar() != '\n'); | |
457 | sync(); | |
458 | if (scene[game].ship[player].file -> captain[0] || scene[game].ship[player].file -> struck || scene[game].ship[player].file -> captured > -1) | |
459 | puts("Sorry, that ship is taken."); | |
460 | else | |
461 | break; | |
462 | } | |
463 | } | |
464 | signal(2, choke); | |
465 | signal(1, choke); | |
466 | Write(FILES + player, 1, 0, "begin"); /* he now exits */ | |
467 | if(people) | |
468 | Write(SCENARIO, 0, 8, scene[game].people + 1); | |
469 | sync(); | |
470 | printf("Your ship is the %s, a %s (%s crew).\n", scene[game].ship[player].shipname, info(player, message), quality(player)); | |
471 | if ((nameptr = (char *) getenv("NAME")) && *nameptr) | |
472 | strcpy(comm,nameptr); | |
473 | else { | |
474 | fputs("Your name, Captain? ", stdout); | |
475 | gets(comm); | |
476 | if (!*comm) strcpy(comm, "no name"); | |
477 | } | |
478 | comm[19] = '\0'; | |
479 | for (k=0; k < 2; k++) { | |
480 | printf("\nInitial broadside %s (grape, chain, round, double): ", (k ? "right" : "left")); | |
481 | scanf("%s", file); | |
482 | switch(*file) { | |
483 | case 'g': | |
484 | load = GRAPE; | |
485 | break; | |
486 | case 'c': | |
487 | load = CHAIN; | |
488 | break; | |
489 | case 'r': | |
490 | load = ROUND; | |
491 | break; | |
492 | case 'd': | |
493 | load = DOUBLE; | |
494 | break; | |
495 | } | |
496 | if (k) { | |
497 | scene[game].ship[player].file -> loadR = load; | |
498 | scene[game].ship[player].file -> readyR = ready; | |
499 | } else { | |
500 | scene[game].ship[player].file -> loadL = load; | |
501 | scene[game].ship[player].file -> readyL = ready; | |
502 | } | |
503 | } | |
504 | Write(FILES + player, 1, 0, comm); | |
505 | if (!people && !nodriver) { | |
506 | sprintf(num, "%d", game); | |
507 | if (!fork()) { | |
508 | execl(DRIVER, DRIVERNAME, num, 0); | |
509 | perror(DRIVER); | |
510 | kill(pid,9); | |
511 | exit(1); | |
512 | } | |
513 | } | |
514 | board(); | |
515 | sprintf(message, "Captain %s assuming command",comm); | |
516 | Write(FILES + player, 1, 164, message); | |
517 | windspeed = scene[game].windspeed; | |
518 | winddir = scene[game].winddir; | |
519 | turn = scene[game].turn; | |
520 | iplotships(); /* new turn */ | |
521 | } | |
522 | ||
523 | /* | |
524 | * Returns the NUMBER of the closest ship | |
525 | */ | |
526 | closestenemy(fromship, side, anyship) | |
527 | int fromship; | |
528 | char side, anyship; | |
529 | { | |
530 | register int n, olddist = 30000, ident, captured; | |
531 | register int dist, eclosest = 30000; | |
532 | ||
533 | if ((ident = scene[game].ship[fromship].file -> captured) < 0) | |
534 | ident = fromship; | |
535 | for (n=0; n < scene[game].vessels; n++) { | |
536 | if ((captured = scene[game].ship[n].file -> captured) < 0) | |
537 | captured = n; | |
538 | if (n != fromship && pos[n].dir && (scene[game].ship[ident].nationality != scene[game].ship[captured].nationality || anyship)) { | |
539 | if (!side || gunsbear(fromship, n) == side) { | |
540 | dist = range(fromship, n); | |
541 | if (dist < olddist){ | |
542 | eclosest = n; | |
543 | olddist = dist; | |
544 | } | |
545 | } | |
546 | } | |
547 | } | |
548 | if (!side && olddist == 30000) | |
549 | leave(2); | |
550 | return(eclosest); | |
551 | } | |
552 | ||
553 | finalexit() | |
554 | { | |
555 | endwin(); | |
556 | nocrmode(); | |
557 | echo(); | |
558 | exit(1); | |
559 | } | |
560 | ||
561 | main(argc, argv) | |
562 | int argc; | |
563 | char ** argv; | |
564 | { | |
e454b583 CL |
565 | register int crew, aheadfirst, ma, n; |
566 | int ta; | |
c77f0542 CL |
567 | char message[60], ch; |
568 | int uid; | |
569 | char nodrive = 0, randomize = 0, *badstring(); | |
570 | ||
571 | signal(SIGINT, finalexit); | |
572 | signal(SIGQUIT, finalexit); | |
573 | signal(SIGHUP, finalexit); | |
574 | ||
575 | if (timetoplay() != 0 && gooduid(uid) != 0) | |
576 | { | |
577 | printf("Sorry Captain, but since you are not an Admiral and this is\n"); | |
578 | printf("a weekday between %s, you are not permitted to\n",badstring()); | |
579 | printf("sail. Come back again some time when the harbor is open.\n"); | |
580 | exit(1); | |
581 | } | |
582 | ||
583 | while (*++argv && **argv == '-') | |
584 | switch (*++*argv) | |
585 | { | |
586 | case 'd': | |
587 | nodrive = 1; | |
588 | break; | |
589 | case 'x': | |
590 | randomize = 1; | |
591 | break; | |
592 | default: | |
593 | printf("Unknown flag '%s'\n",*argv); | |
594 | break; | |
595 | } | |
596 | if (*argv) | |
597 | game = atoi(*argv); | |
598 | else | |
599 | game = -1; | |
600 | initialize(nodrive, randomize); | |
601 | noecho(); | |
602 | crmode(); | |
603 | Signal("Aye aye, Sir", 0, 0); | |
604 | for(;;) | |
605 | { | |
606 | move(scroll++,0); | |
607 | clearline(); | |
608 | addch('~'); | |
609 | move(--scroll,0); | |
610 | refresh(); | |
611 | ch = getch(); | |
612 | switch(ch) | |
613 | { | |
614 | case 'm': | |
615 | crew = specs[scene[game].ship[player].shipnum].crew3; | |
616 | /* for (n=0; n < 3; n++) | |
617 | { | |
618 | if (ptr -> OBP[n].turnsent && ptr -> OBP[n].mensent % 10) | |
619 | crew = 0; | |
620 | } | |
621 | for (n=0; n < 3; n++) | |
622 | { | |
623 | if (ptr -> DBP[n].turnsent && ptr -> DBP[n].mensent % 10) | |
624 | crew = 0; | |
625 | } */ | |
626 | if (crew && !grappled(player) && !fouled(player) && windspeed) | |
627 | { | |
628 | ta = maxturns(player); | |
629 | aheadfirst = ta & 0100000; | |
630 | ma = maxmove(player, pos[player].dir, 0); | |
631 | ta &= 077777; | |
632 | acceptmove(ma, ta, aheadfirst); | |
633 | } | |
634 | else | |
635 | Signal("Unable to move", 0, 0); | |
636 | break; | |
637 | case 's': | |
638 | acceptsignal(); | |
639 | break; | |
640 | case 'g': | |
641 | grapungrap(); | |
642 | break; | |
643 | case 'u': | |
644 | unfoulplayer(); | |
645 | break; | |
2f14594b CL |
646 | case 'v': |
647 | version(); | |
648 | break; | |
c77f0542 CL |
649 | case 'b': |
650 | boarding(); | |
651 | break; | |
652 | /* case '[': | |
653 | devestate = 1; | |
654 | acceptcombat(); | |
655 | break; */ | |
656 | case 'f': | |
657 | acceptcombat(); | |
658 | break; | |
659 | case 'l': | |
660 | loadplayer(); | |
661 | break; | |
662 | case 'c': | |
663 | changesail(); | |
664 | break; | |
665 | case 'r': | |
666 | repair(); | |
667 | break; | |
668 | case 'B': | |
669 | Signal("'Hands to stations!'", 0, 0); | |
670 | unboard(player, player, 1); /* cancel DBP's */ | |
671 | unboard(player, player, 0); /* cancel offense */ | |
672 | break; | |
673 | case '\f': | |
674 | signal(SIGALRM, SIG_IGN); | |
675 | viewrow = pos[player].row - ROWSINVIEW / 2; | |
676 | viewcol = pos[player].col - COLSINVIEW / 2; | |
677 | board(); | |
678 | plotships(); /* don't create new turn */ | |
679 | break; | |
680 | case 'L': | |
681 | scene[game].ship[player].file -> loadL = 0; | |
682 | scene[game].ship[player].file -> loadR = 0; | |
683 | scene[game].ship[player].file -> readyL = 0; | |
684 | scene[game].ship[player].file -> readyR = 0; | |
685 | Signal("Broadsides unloaded", 0, 0); | |
686 | break; | |
687 | case 'q': | |
688 | Signal("Type 'Q' to quit", 0, 0); | |
689 | break; | |
690 | case 'Q': | |
691 | leave(0); | |
692 | break; | |
693 | case 'I': | |
694 | for (n = 0; n < scene[game].vessels; n++) | |
695 | eyeball(player, n); | |
696 | break; | |
697 | case 'i': | |
698 | n = closestenemy(player, 0, 1); | |
699 | eyeball(player, n); | |
700 | break; | |
701 | } | |
702 | signalflags(); | |
703 | lost(); | |
704 | } | |
705 | } | |
706 | ||
707 | char *saywhat(n) | |
708 | int n; | |
709 | { | |
710 | if(scene[game].ship[n].file -> captain[0]) | |
711 | return(scene[game].ship[n].file -> captain); | |
712 | else if (scene[game].ship[n].file -> struck) | |
713 | return("(struck)"); | |
714 | else if(scene[game].ship[n].file -> captured > -1) | |
715 | return("(captured)"); | |
716 | else | |
717 | return("(computer)"); | |
718 | } | |
719 | ||
720 | eyeball(player, n) | |
721 | int player, n; | |
722 | { | |
723 | char message[80]; | |
724 | register i; | |
725 | ||
726 | if (scene[game].ship[n].shipdir){ | |
727 | sprintf(message, "%d, %s", range(player, n), saywhat(n)); | |
728 | Signal("Sail ho! (range %s)", -1, message); | |
729 | switch(scene[game].ship[n].nationality) | |
730 | { | |
731 | case 0: | |
732 | strcpy(message, "American "); | |
733 | break; | |
734 | case 1: | |
735 | strcpy(message, "British "); | |
736 | break; | |
737 | case 2: | |
738 | strcpy(message, "Spanish "); | |
739 | break; | |
740 | case 3: | |
741 | strcpy(message, "French "); | |
742 | break; | |
743 | default: | |
744 | strcpy(message, "Gremlin "); | |
745 | break; | |
746 | } | |
747 | switch(specs[scene[game].ship[n].shipnum].class) | |
748 | { | |
749 | case 1: | |
750 | case 2: | |
751 | strcat(message, "Ship of the Line "); | |
752 | break; | |
753 | case 3: | |
754 | case 4: | |
755 | strcat(message, "Frigate "); | |
756 | break; | |
757 | case 5: | |
758 | case 6: | |
759 | strcat(message, "Sloop "); | |
760 | break; | |
761 | } | |
762 | switch(portside(player, n, 1) - pos[player].dir) | |
763 | { | |
764 | case -7: | |
765 | case 1: | |
766 | strcat(message, "off the starboard bow."); | |
767 | break; | |
768 | case -6: | |
769 | case 2: | |
770 | strcat(message, "off the starboard beam."); | |
771 | break; | |
772 | case -5: | |
773 | case 3: | |
774 | strcat(message, "off the starboard quarter."); | |
775 | break; | |
776 | case -4: | |
777 | case 4: | |
778 | strcat(message, "dead astern."); | |
779 | break; | |
780 | case -3: | |
781 | case 5: | |
782 | strcat(message, "off the port quarter."); | |
783 | break; | |
784 | case -2: | |
785 | case 6: | |
786 | strcat(message, "off the port beam."); | |
787 | break; | |
788 | case -1: | |
789 | case 7: | |
790 | strcat(message, "off the port bow."); | |
791 | break; | |
792 | case 0: | |
793 | strcat(message, "dead ahead."); | |
794 | break; | |
795 | } | |
796 | Signal(message, 0, 0); | |
797 | } | |
798 | } |