xref: /original-bsd/games/trek/warp.c (revision 83e03edb)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)warp.c	5.3 (Berkeley) 06/18/88";
20 #endif /* not lint */
21 
22 # include	"trek.h"
23 
24 /*
25 **  MOVE UNDER WARP POWER
26 **
27 **	This is both the "move" and the "ram" commands, differing
28 **	only in the flag 'fl'.  It is also used for automatic
29 **	emergency override mode, when 'fl' is < 0 and 'c' and 'd'
30 **	are the course and distance to be moved.  If 'fl' >= 0,
31 **	the course and distance are asked of the captain.
32 **
33 **	The guts of this routine are in the routine move(), which
34 **	is shared with impulse().  Also, the working part of this
35 **	routine is very small; the rest is to handle the slight chance
36 **	that you may be moving at some riduculous speed.  In that
37 **	case, there is code to handle time warps, etc.
38 */
39 
40 warp(fl, c, d)
41 int	fl, c;
42 double	d;
43 {
44 	int			course;
45 	double			power;
46 	double			dist;
47 	double			time;
48 	double			speed;
49 	double			frac;
50 	register int		percent;
51 	register int		i;
52 	extern double		move();
53 
54 	if (Ship.cond == DOCKED)
55 		return (printf("%s is docked\n", Ship.shipname));
56 	if (damaged(WARP))
57 	{
58 		return (out(WARP));
59 	}
60 	if (fl < 0)
61 	{
62 		course = c;
63 		dist = d;
64 	}
65 	else
66 		if (getcodi(&course, &dist))
67 			return;
68 
69 	/* check to see that we are not using an absurd amount of power */
70 	power = (dist + 0.05) * Ship.warp3;
71 	percent = 100 * power / Ship.energy + 0.5;
72 	if (percent >= 85)
73 	{
74 		printf("Scotty: That would consume %d%% of our remaining energy.\n",
75 			percent);
76 		if (!getynpar("Are you sure that is wise"))
77 			return;
78 	}
79 
80 	/* compute the speed we will move at, and the time it will take */
81 	speed = Ship.warp2 / Param.warptime;
82 	time = dist / speed;
83 
84 	/* check to see that that value is not ridiculous */
85 	percent = 100 * time / Now.time + 0.5;
86 	if (percent >= 85)
87 	{
88 		printf("Spock: That would take %d%% of our remaining time.\n",
89 			percent);
90 		if (!getynpar("Are you sure that is wise"))
91 			return;
92 	}
93 
94 	/* compute how far we will go if we get damages */
95 	if (Ship.warp > 6.0 && ranf(100) < 20 + 15 * (Ship.warp - 6.0))
96 	{
97 		frac = franf();
98 		dist *= frac;
99 		time *= frac;
100 		damage(WARP, (frac + 1.0) * Ship.warp * (franf() + 0.25) * 0.20);
101 	}
102 
103 	/* do the move */
104 	Move.time = move(fl, course, time, speed);
105 
106 	/* see how far we actually went, and decrement energy appropriately */
107 	dist = Move.time * speed;
108 	Ship.energy -= dist * Ship.warp3 * (Ship.shldup + 1);
109 
110 	/* test for bizarre events */
111 	if (Ship.warp <= 9.0)
112 		return;
113 	printf("\n\n  ___ Speed exceeding warp nine ___\n\n");
114 	sleep(2);
115 	printf("Ship's safety systems malfunction\n");
116 	sleep(2);
117 	printf("Crew experiencing extreme sensory distortion\n");
118 	sleep(4);
119 	if (ranf(100) >= 100 * dist)
120 	{
121 		return (printf("Equilibrium restored -- all systems normal\n"));
122 	}
123 
124 	/* select a bizzare thing to happen to us */
125 	percent = ranf(100);
126 	if (percent < 70)
127 	{
128 		/* time warp */
129 		if (percent < 35 || !Game.snap)
130 		{
131 			/* positive time warp */
132 			time = (Ship.warp - 8.0) * dist * (franf() + 1.0);
133 			Now.date += time;
134 			printf("Positive time portal entered -- it is now Stardate %.2f\n",
135 				Now.date);
136 			for (i = 0; i < MAXEVENTS; i++)
137 			{
138 				percent = Event[i].evcode;
139 				if (percent == E_FIXDV || percent == E_LRTB)
140 					Event[i].date += time;
141 			}
142 			return;
143 		}
144 
145 		/* s/he got lucky: a negative time portal */
146 		time = Now.date;
147 		i = (int) Etc.snapshot;
148 		bmove(i, Quad, sizeof Quad);
149 		bmove(i += sizeof Quad, Event, sizeof Event);
150 		bmove(i += sizeof Event, &Now, sizeof Now);
151 		printf("Negative time portal entered -- it is now Stardate %.2f\n",
152 			Now.date);
153 		for (i = 0; i < MAXEVENTS; i++)
154 			if (Event[i].evcode == E_FIXDV)
155 				reschedule(&Event[i], Event[i].date - time);
156 		return;
157 	}
158 
159 	/* test for just a lot of damage */
160 	if (percent < 80)
161 		lose(L_TOOFAST);
162 	printf("Equilibrium restored -- extreme damage occured to ship systems\n");
163 	for (i = 0; i < NDEV; i++)
164 		damage(i, (3.0 * (franf() + franf()) + 1.0) * Param.damfac[i]);
165 	Ship.shldup = 0;
166 }
167