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