xref: /dragonfly/games/trek/warp.c (revision 0085a56d)
1 /*	@(#)warp.c	8.1 (Berkeley) 5/31/93				*/
2 /*	$NetBSD: warp.c,v 1.11 2009/05/24 22:55:03 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 <math.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include "trek.h"
38 #include "getpar.h"
39 
40 /*
41 **  MOVE UNDER WARP POWER
42 **
43 **	This is both the "move" and the "ram" commands, differing
44 **	only in the flag 'fl'.  It is also used for automatic
45 **	emergency override mode, when 'fl' is < 0 and 'c' and 'd'
46 **	are the course and distance to be moved.  If 'fl' >= 0,
47 **	the course and distance are asked of the captain.
48 **
49 **	The guts of this routine are in the routine move(), which
50 **	is shared with impulse().  Also, the working part of this
51 **	routine is very small; the rest is to handle the slight chance
52 **	that you may be moving at some riduculous speed.  In that
53 **	case, there is code to handle time warps, etc.
54 */
55 
56 void
57 dowarp(int fl)
58 {
59 	int c;
60 	double d;
61 
62 	if (getcodi(&c, &d))
63 		return;
64 	warp(fl, c, d);
65 }
66 
67 void
68 warp(int fl, int c, double d)
69 {
70 	char	       *p;
71 	int		course;
72 	double		power;
73 	double		dist;
74 	double		time;
75 	double		speed;
76 	double		frac;
77 	int		percent;
78 	int		i;
79 	double repairs;
80 
81 	if (Ship.cond == DOCKED) {
82 		printf("%s is docked\n", Ship.shipname);
83 		return;
84 	}
85 	if (damaged(WARP)) {
86 		out(WARP);
87 		return;
88 	}
89 
90 	course = c;
91 	dist = d;
92 
93 	/* check to see that we are not using an absurd amount of power */
94 	power = (dist + 0.05) * Ship.warp3;
95 	percent = 100 * power / Ship.energy + 0.5;
96 	if (percent >= 85) {
97 		printf("Scotty: That would consume %d%% of our remaining "
98 		       "energy.\n",
99 			percent);
100 		if (!getynpar("Are you sure that is wise"))
101 			return;
102 	}
103 
104 	/* compute the speed we will move at, and the time it will take */
105 	speed = Ship.warp2 / Param.warptime;
106 	time = dist / speed;
107 
108 	/* check to see that that value is not ridiculous */
109 	percent = 100 * time / Now.time + 0.5;
110 	if (percent >= 85) {
111 		printf("Spock: That would take %d%% of our remaining time.\n",
112 			percent);
113 		if (!getynpar("Are you sure that is wise"))
114 			return;
115 	}
116 
117 	/* compute how far we will go if we get damages */
118 	if (Ship.warp > 6.0 && ranf(100) < 20 + 15 * (Ship.warp - 6.0)) {
119 		frac = franf();
120 		dist *= frac;
121 		time *= frac;
122 		repairs = (frac + 1.0) * Ship.warp * (franf() + 0.25) * 0.20;
123 		damage(WARP, repairs);
124 	}
125 
126 	/* do the move */
127 	Move.time = move(fl, course, time, speed);
128 
129 	/* see how far we actually went, and decrement energy appropriately */
130 	dist = Move.time * speed;
131 	Ship.energy -= dist * Ship.warp3 * (Ship.shldup + 1);
132 
133 	/* test for bizarre events */
134 	if (Ship.warp <= 9.0)
135 		return;
136 	printf("\n\n  ___ Speed exceeding warp nine ___\n\n");
137 	sleep(2);
138 	printf("Ship's safety systems malfunction\n");
139 	sleep(2);
140 	printf("Crew experiencing extreme sensory distortion\n");
141 	sleep(4);
142 	if (ranf(100) >= 100 * dist) {
143 		printf("Equilibrium restored -- all systems normal\n");
144 		return;
145 	}
146 
147 	/* select a bizzare thing to happen to us */
148 	percent = ranf(100);
149 	if (percent < 70) {
150 		/* time warp */
151 		if (percent < 35 || !Game.snap) {
152 			/* positive time warp */
153 			time = (Ship.warp - 8.0) * dist * (franf() + 1.0);
154 			Now.date += time;
155 			printf("Positive time portal entered -- "
156 			       "it is now Stardate %.2f\n",
157 				Now.date);
158 			for (i = 0; i < MAXEVENTS; i++) {
159 				percent = Event[i].evcode;
160 				if (percent == E_FIXDV || percent == E_LRTB)
161 					Event[i].date += time;
162 			}
163 			return;
164 		}
165 
166 		/* s/he got lucky: a negative time portal */
167 		time = Now.date;
168 		p = (char *) Etc.snapshot;
169 		memcpy(p, Quad, sizeof Quad);
170 		p += sizeof Quad;
171 		memcpy(p, Event, sizeof Event);
172 		p += sizeof Event;
173 		memcpy(p, &Now, sizeof Now);
174 		printf("Negative time portal entered -- "
175 		       "it is now Stardate %.2f\n",
176 			Now.date);
177 		for (i = 0; i < MAXEVENTS; i++)
178 			if (Event[i].evcode == E_FIXDV)
179 				reschedule(&Event[i], Event[i].date - time);
180 		return;
181 	}
182 
183 	/* test for just a lot of damage */
184 	if (percent < 80)
185 		lose(L_TOOFAST);
186 	printf("Equilibrium restored -- "
187 	       "extreme damage occurred to ship systems\n");
188 	for (i = 0; i < NDEV; i++)
189 		damage(i, (3.0 * (franf() + franf()) + 1.0) * Param.damfac[i]);
190 	Ship.shldup = 0;
191 }
192