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