xref: /dragonfly/games/trek/torped.c (revision d4ef6694)
1 /*-
2  * Copyright (c) 1980, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * @(#)torped.c	8.1 (Berkeley) 5/31/93
30  * $FreeBSD: src/games/trek/torped.c,v 1.5 1999/11/30 03:49:55 billf Exp $
31  * $DragonFly: src/games/trek/torped.c,v 1.3 2006/09/07 21:19:44 pavalos Exp $
32  */
33 
34 #include "trek.h"
35 #include "getpar.h"
36 
37 static int randcourse(int);
38 
39 /*
40 **  PHOTON TORPEDO CONTROL
41 **
42 **	Either one or three photon torpedoes are fired.  If three
43 **	are fired, it is called a "burst" and you also specify
44 **	a spread angle.
45 **
46 **	Torpedoes are never 100% accurate.  There is always a random
47 **	cludge factor in their course which is increased if you have
48 **	your shields up.  Hence, you will find that they are more
49 **	accurate at close range.  However, they have the advantage that
50 **	at long range they don't lose any of their power as phasers
51 **	do, i.e., a hit is a hit is a hit, by any other name.
52 **
53 **	When the course spreads too much, you get a misfire, and the
54 **	course is randomized even more.  You also have the chance that
55 **	the misfire damages your torpedo tubes.
56 */
57 
58 void
59 torped(int v __unused)
60 {
61 	int		ix, iy;
62 	double		x, y, dx, dy;
63 	double		angle;
64 	int		course, course2;
65 	int		k;
66 	double		bigger;
67 	double		sectsize;
68 	int		burst;
69 	int		n;
70 
71 	if (Ship.cloaked) {
72 		printf("Federation regulations do not permit attack while cloaked.\n");
73 		return;
74 	}
75 	if (check_out(TORPED))
76 		return;
77 	if (Ship.torped <= 0) {
78 		printf("All photon torpedos expended\n");
79 		return;
80 	}
81 
82 	/* get the course */
83 	course = getintpar("Torpedo course");
84 	if (course < 0 || course > 360)
85 		return;
86 	burst = -1;
87 
88 	/* need at least three torpedoes for a burst */
89 	if (Ship.torped < 3) {
90 		printf("No-burst mode selected\n");
91 		burst = 0;
92 	} else {
93 		/* see if the user wants one */
94 		if (!testnl()) {
95 			k = ungetc(cgetc(0), stdin);
96 			if (k >= '0' && k <= '9')
97 				burst = 1;
98 		}
99 	}
100 	if (burst < 0) {
101 		burst = getynpar("Do you want a burst");
102 	}
103 	if (burst) {
104 		burst = getintpar("burst angle");
105 		if (burst <= 0)
106 			return;
107 		if (burst > 15) {
108 			printf("Maximum burst angle is 15 degrees\n");
109 			return;
110 		}
111 	}
112 	sectsize = NSECTS;
113 	n = -1;
114 	if (burst) {
115 		n = 1;
116 		course -= burst;
117 	}
118 	for (; n && n <= 3; n++) {
119 		/* select a nice random course */
120 		course2 = course + randcourse(n);
121 		angle = course2 * 0.0174532925;			/* convert to radians */
122 		dx = -cos(angle);
123 		dy =  sin(angle);
124 		bigger = fabs(dx);
125 		x = fabs(dy);
126 		if (x > bigger)
127 			bigger = x;
128 		dx /= bigger;
129 		dy /= bigger;
130 		x = Ship.sectx + 0.5;
131 		y = Ship.secty + 0.5;
132 		if (Ship.cond != DOCKED)
133 			Ship.torped -= 1;
134 		printf("Torpedo track");
135 		if (n > 0)
136 			printf(", torpedo number %d", n);
137 		printf(":\n%6.1f\t%4.1f\n", x, y);
138 		while (1) {
139 			ix = x += dx;
140 			iy = y += dy;
141 			if (x < 0.0 || x >= sectsize ||
142 			    y < 0.0 || y >= sectsize) {
143 				printf("Torpedo missed\n");
144 				break;
145 			}
146 			printf("%6.1f\t%4.1f\n", x, y);
147 			switch (Sect[ix][iy]) {
148 			  case EMPTY:
149 				continue;
150 
151 			  case HOLE:
152 				printf("Torpedo disappears into a black hole\n");
153 				break;
154 
155 			  case KLINGON:
156 				for (k = 0; k < Etc.nkling; k++) {
157 					if (Etc.klingon[k].x != ix || Etc.klingon[k].y != iy)
158 						continue;
159 					Etc.klingon[k].power -= 500 + ranf(501);
160 					if (Etc.klingon[k].power > 0) {
161 						printf("*** Hit on Klingon at %d,%d: extensive damages\n",
162 							ix, iy);
163 						break;
164 					}
165 					killk(ix, iy);
166 					break;
167 				}
168 				break;
169 
170 			  case STAR:
171 				nova(ix, iy);
172 				break;
173 
174 			  case INHABIT:
175 				kills(ix, iy, -1);
176 				break;
177 
178 			  case BASE:
179 				killb(Ship.quadx, Ship.quady);
180 				Game.killb += 1;
181 				break;
182 			  default:
183 				printf("Unknown object %c at %d,%d destroyed\n",
184 					Sect[ix][iy], ix, iy);
185 				Sect[ix][iy] = EMPTY;
186 				break;
187 			}
188 			break;
189 		}
190 		if (damaged(TORPED) || Quad[Ship.quadx][Ship.quady].stars < 0)
191 			break;
192 		course += burst;
193 	}
194 	Move.free = 0;
195 }
196 
197 
198 /*
199 **  RANDOMIZE COURSE
200 **
201 **	This routine randomizes the course for torpedo number 'n'.
202 **	Other things handled by this routine are misfires, damages
203 **	to the tubes, etc.
204 */
205 
206 static int
207 randcourse(int n)
208 {
209 	double			r;
210 	int		d;
211 
212 	d = ((franf() + franf()) - 1.0) * 20;
213 	if (abs(d) > 12) {
214 		printf("Photon tubes misfire");
215 		if (n < 0)
216 			printf("\n");
217 		else
218 			printf(" on torpedo %d\n", n);
219 		if (ranf(2)) {
220 			damage(TORPED, 0.2 * abs(d) * (franf() + 1.0));
221 		}
222 		d *= 1.0 + 2.0 * franf();
223 	}
224 	if (Ship.shldup || Ship.cond == DOCKED) {
225 		r = Ship.shield;
226 		r = 1.0 + r / Param.shield;
227 		if (Ship.cond == DOCKED)
228 			r = 2.0;
229 		d *= r;
230 	}
231 	return (d);
232 }
233