125995Smckusick /*
2*60859Sbostic * Copyright (c) 1980, 1993
3*60859Sbostic * The Regents of the University of California. All rights reserved.
434205Sbostic *
542606Sbostic * %sccs.include.redist.c%
625995Smckusick */
725995Smckusick
811701Smckusick #ifndef lint
9*60859Sbostic static char sccsid[] = "@(#)torped.c 8.1 (Berkeley) 05/31/93";
1034205Sbostic #endif /* not lint */
1111701Smckusick
1212738Slayer # include <stdio.h>
1311701Smckusick # include "trek.h"
1411701Smckusick
1511701Smckusick /*
1611701Smckusick ** PHOTON TORPEDO CONTROL
1711701Smckusick **
1811701Smckusick ** Either one or three photon torpedoes are fired. If three
1911701Smckusick ** are fired, it is called a "burst" and you also specify
2011701Smckusick ** a spread angle.
2111701Smckusick **
2211701Smckusick ** Torpedoes are never 100% accurate. There is always a random
2311701Smckusick ** cludge factor in their course which is increased if you have
2411701Smckusick ** your shields up. Hence, you will find that they are more
2511701Smckusick ** accurate at close range. However, they have the advantage that
2611701Smckusick ** at long range they don't lose any of their power as phasers
2711701Smckusick ** do, i.e., a hit is a hit is a hit, by any other name.
2811701Smckusick **
2911701Smckusick ** When the course spreads too much, you get a misfire, and the
3011701Smckusick ** course is randomized even more. You also have the chance that
3111701Smckusick ** the misfire damages your torpedo tubes.
3211701Smckusick */
3311701Smckusick
3411701Smckusick
torped()3511701Smckusick torped()
3611701Smckusick {
3711701Smckusick register int ix, iy;
3811701Smckusick double x, y, dx, dy;
3911701Smckusick double angle;
4011701Smckusick int course, course2;
4111701Smckusick register int k;
4211701Smckusick double bigger;
4311701Smckusick double sectsize;
4411701Smckusick int burst;
4511701Smckusick int n;
4611701Smckusick
4711701Smckusick if (Ship.cloaked)
4811701Smckusick {
4911701Smckusick return (printf("Federation regulations do not permit attack while cloaked.\n"));
5011701Smckusick }
5111701Smckusick if (check_out(TORPED))
5211701Smckusick return;
5311701Smckusick if (Ship.torped <= 0)
5411701Smckusick {
5511701Smckusick return (printf("All photon torpedos expended\n"));
5611701Smckusick }
5711701Smckusick
5811701Smckusick /* get the course */
5911701Smckusick course = getintpar("Torpedo course");
6011701Smckusick if (course < 0 || course > 360)
6111701Smckusick return;
6211701Smckusick burst = -1;
6311701Smckusick
6411701Smckusick /* need at least three torpedoes for a burst */
6511701Smckusick if (Ship.torped < 3)
6611701Smckusick {
6711701Smckusick printf("No-burst mode selected\n");
6811701Smckusick burst = 0;
6911701Smckusick }
7011701Smckusick else
7111701Smckusick {
7211701Smckusick /* see if the user wants one */
7311701Smckusick if (!testnl())
7411701Smckusick {
7512738Slayer k = ungetc(cgetc(0), stdin);
7611701Smckusick if (k >= '0' && k <= '9')
7711701Smckusick burst = 1;
7811701Smckusick }
7911701Smckusick }
8011701Smckusick if (burst < 0)
8111701Smckusick {
8211701Smckusick burst = getynpar("Do you want a burst");
8311701Smckusick }
8411701Smckusick if (burst)
8511701Smckusick {
8611701Smckusick burst = getintpar("burst angle");
8711701Smckusick if (burst <= 0)
8811701Smckusick return;
8911701Smckusick if (burst > 15)
9011701Smckusick return (printf("Maximum burst angle is 15 degrees\n"));
9111701Smckusick }
9211701Smckusick sectsize = NSECTS;
9311701Smckusick n = -1;
9411701Smckusick if (burst)
9511701Smckusick {
9611701Smckusick n = 1;
9712344Slayer course -= burst;
9811701Smckusick }
9911701Smckusick for (; n && n <= 3; n++)
10011701Smckusick {
10111701Smckusick /* select a nice random course */
10211701Smckusick course2 = course + randcourse(n);
10311701Smckusick angle = course2 * 0.0174532925; /* convert to radians */
10411701Smckusick dx = -cos(angle);
10511701Smckusick dy = sin(angle);
10611701Smckusick bigger = fabs(dx);
10711701Smckusick x = fabs(dy);
10811701Smckusick if (x > bigger)
10911701Smckusick bigger = x;
11012344Slayer dx /= bigger;
11112344Slayer dy /= bigger;
11211701Smckusick x = Ship.sectx + 0.5;
11311701Smckusick y = Ship.secty + 0.5;
11411701Smckusick if (Ship.cond != DOCKED)
11512344Slayer Ship.torped -= 1;
11611701Smckusick printf("Torpedo track");
11711701Smckusick if (n > 0)
11811701Smckusick printf(", torpedo number %d", n);
11911701Smckusick printf(":\n%6.1f\t%4.1f\n", x, y);
12011701Smckusick while (1)
12111701Smckusick {
12212344Slayer ix = x += dx;
12312344Slayer iy = y += dy;
12411701Smckusick if (x < 0.0 || x >= sectsize || y < 0.0 || y >= sectsize)
12511701Smckusick {
12611701Smckusick printf("Torpedo missed\n");
12711701Smckusick break;
12811701Smckusick }
12911701Smckusick printf("%6.1f\t%4.1f\n", x, y);
13011701Smckusick switch (Sect[ix][iy])
13111701Smckusick {
13211701Smckusick case EMPTY:
13311701Smckusick continue;
13411701Smckusick
13511701Smckusick case HOLE:
13611701Smckusick printf("Torpedo disappears into a black hole\n");
13711701Smckusick break;
13811701Smckusick
13911701Smckusick case KLINGON:
14011701Smckusick for (k = 0; k < Etc.nkling; k++)
14111701Smckusick {
14211701Smckusick if (Etc.klingon[k].x != ix || Etc.klingon[k].y != iy)
14311701Smckusick continue;
14412344Slayer Etc.klingon[k].power -= 500 + ranf(501);
14511701Smckusick if (Etc.klingon[k].power > 0)
14611701Smckusick {
14711701Smckusick printf("*** Hit on Klingon at %d,%d: extensive damages\n",
14811701Smckusick ix, iy);
14911701Smckusick break;
15011701Smckusick }
15111701Smckusick killk(ix, iy);
15211701Smckusick break;
15311701Smckusick }
15411701Smckusick break;
15511701Smckusick
15611701Smckusick case STAR:
15711701Smckusick nova(ix, iy);
15811701Smckusick break;
15911701Smckusick
16011701Smckusick case INHABIT:
16111701Smckusick kills(ix, iy, -1);
16211701Smckusick break;
16311701Smckusick
16411701Smckusick case BASE:
16511701Smckusick killb(Ship.quadx, Ship.quady);
16612344Slayer Game.killb += 1;
16711701Smckusick break;
16811701Smckusick default:
16911701Smckusick printf("Unknown object %c at %d,%d destroyed\n",
17011701Smckusick Sect[ix][iy], ix, iy);
17111701Smckusick Sect[ix][iy] = EMPTY;
17211701Smckusick break;
17311701Smckusick }
17411701Smckusick break;
17511701Smckusick }
17611701Smckusick if (damaged(TORPED) || Quad[Ship.quadx][Ship.quady].stars < 0)
17711701Smckusick break;
17812344Slayer course += burst;
17911701Smckusick }
18011701Smckusick Move.free = 0;
18111701Smckusick }
18211701Smckusick
18311701Smckusick
18411701Smckusick /*
18511701Smckusick ** RANDOMIZE COURSE
18611701Smckusick **
18711701Smckusick ** This routine randomizes the course for torpedo number 'n'.
18811701Smckusick ** Other things handled by this routine are misfires, damages
18911701Smckusick ** to the tubes, etc.
19011701Smckusick */
19111701Smckusick
randcourse(n)19211701Smckusick randcourse(n)
19311701Smckusick int n;
19411701Smckusick {
19511701Smckusick double r;
19611701Smckusick register int d;
19711701Smckusick
19811701Smckusick d = ((franf() + franf()) - 1.0) * 20;
19911701Smckusick if (abs(d) > 12)
20011701Smckusick {
20111701Smckusick printf("Photon tubes misfire");
20211701Smckusick if (n < 0)
20311701Smckusick printf("\n");
20411701Smckusick else
20511701Smckusick printf(" on torpedo %d\n", n);
20611701Smckusick if (ranf(2))
20711701Smckusick {
20811701Smckusick damage(TORPED, 0.2 * abs(d) * (franf() + 1.0));
20911701Smckusick }
21012344Slayer d *= 1.0 + 2.0 * franf();
21111701Smckusick }
21211701Smckusick if (Ship.shldup || Ship.cond == DOCKED)
21311701Smckusick {
21411701Smckusick r = Ship.shield;
21511701Smckusick r = 1.0 + r / Param.shield;
21611701Smckusick if (Ship.cond == DOCKED)
21711701Smckusick r = 2.0;
21812344Slayer d *= r;
21911701Smckusick }
22011701Smckusick return (d);
22111701Smckusick }
222