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