xref: /csrg-svn/games/trek/torped.c (revision 60859)
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