xref: /csrg-svn/games/trek/warp.c (revision 60859)
125996Smckusick /*
2*60859Sbostic  * Copyright (c) 1980, 1993
3*60859Sbostic  *	The Regents of the University of California.  All rights reserved.
434205Sbostic  *
542606Sbostic  * %sccs.include.redist.c%
625996Smckusick  */
725996Smckusick 
811704Smckusick #ifndef lint
9*60859Sbostic static char sccsid[] = "@(#)warp.c	8.1 (Berkeley) 05/31/93";
1034205Sbostic #endif /* not lint */
1111704Smckusick 
1211704Smckusick # include	"trek.h"
1311704Smckusick 
1411704Smckusick /*
1511704Smckusick **  MOVE UNDER WARP POWER
1611704Smckusick **
1711704Smckusick **	This is both the "move" and the "ram" commands, differing
1811704Smckusick **	only in the flag 'fl'.  It is also used for automatic
1911704Smckusick **	emergency override mode, when 'fl' is < 0 and 'c' and 'd'
2011704Smckusick **	are the course and distance to be moved.  If 'fl' >= 0,
2111704Smckusick **	the course and distance are asked of the captain.
2211704Smckusick **
2311704Smckusick **	The guts of this routine are in the routine move(), which
2411704Smckusick **	is shared with impulse().  Also, the working part of this
2511704Smckusick **	routine is very small; the rest is to handle the slight chance
2611704Smckusick **	that you may be moving at some riduculous speed.  In that
2711704Smckusick **	case, there is code to handle time warps, etc.
2811704Smckusick */
2911704Smckusick 
warp(fl,c,d)3011704Smckusick warp(fl, c, d)
3111704Smckusick int	fl, c;
3211704Smckusick double	d;
3311704Smckusick {
3411704Smckusick 	int			course;
3512738Slayer 	double			power;
3612738Slayer 	double			dist;
3712738Slayer 	double			time;
3812738Slayer 	double			speed;
3911704Smckusick 	double			frac;
4011704Smckusick 	register int		percent;
4111704Smckusick 	register int		i;
4212738Slayer 	extern double		move();
4311704Smckusick 
4411704Smckusick 	if (Ship.cond == DOCKED)
4511704Smckusick 		return (printf("%s is docked\n", Ship.shipname));
4611704Smckusick 	if (damaged(WARP))
4711704Smckusick 	{
4811704Smckusick 		return (out(WARP));
4911704Smckusick 	}
5011704Smckusick 	if (fl < 0)
5111704Smckusick 	{
5211704Smckusick 		course = c;
5311704Smckusick 		dist = d;
5411704Smckusick 	}
5511704Smckusick 	else
5611704Smckusick 		if (getcodi(&course, &dist))
5711704Smckusick 			return;
5811704Smckusick 
5911704Smckusick 	/* check to see that we are not using an absurd amount of power */
6011704Smckusick 	power = (dist + 0.05) * Ship.warp3;
6111704Smckusick 	percent = 100 * power / Ship.energy + 0.5;
6211704Smckusick 	if (percent >= 85)
6311704Smckusick 	{
6411704Smckusick 		printf("Scotty: That would consume %d%% of our remaining energy.\n",
6511704Smckusick 			percent);
6611704Smckusick 		if (!getynpar("Are you sure that is wise"))
6711704Smckusick 			return;
6811704Smckusick 	}
6911704Smckusick 
7011704Smckusick 	/* compute the speed we will move at, and the time it will take */
7111704Smckusick 	speed = Ship.warp2 / Param.warptime;
7211704Smckusick 	time = dist / speed;
7311704Smckusick 
7411704Smckusick 	/* check to see that that value is not ridiculous */
7511704Smckusick 	percent = 100 * time / Now.time + 0.5;
7611704Smckusick 	if (percent >= 85)
7711704Smckusick 	{
7811704Smckusick 		printf("Spock: That would take %d%% of our remaining time.\n",
7911704Smckusick 			percent);
8011704Smckusick 		if (!getynpar("Are you sure that is wise"))
8111704Smckusick 			return;
8211704Smckusick 	}
8311704Smckusick 
8411704Smckusick 	/* compute how far we will go if we get damages */
8511704Smckusick 	if (Ship.warp > 6.0 && ranf(100) < 20 + 15 * (Ship.warp - 6.0))
8611704Smckusick 	{
8711704Smckusick 		frac = franf();
8812738Slayer 		dist *= frac;
8912738Slayer 		time *= frac;
9011704Smckusick 		damage(WARP, (frac + 1.0) * Ship.warp * (franf() + 0.25) * 0.20);
9111704Smckusick 	}
9211704Smckusick 
9311704Smckusick 	/* do the move */
9411704Smckusick 	Move.time = move(fl, course, time, speed);
9511704Smckusick 
9611704Smckusick 	/* see how far we actually went, and decrement energy appropriately */
9711704Smckusick 	dist = Move.time * speed;
9812738Slayer 	Ship.energy -= dist * Ship.warp3 * (Ship.shldup + 1);
9911704Smckusick 
10011704Smckusick 	/* test for bizarre events */
10111704Smckusick 	if (Ship.warp <= 9.0)
10211704Smckusick 		return;
10311704Smckusick 	printf("\n\n  ___ Speed exceeding warp nine ___\n\n");
10411704Smckusick 	sleep(2);
10511704Smckusick 	printf("Ship's safety systems malfunction\n");
10611704Smckusick 	sleep(2);
10711704Smckusick 	printf("Crew experiencing extreme sensory distortion\n");
10811704Smckusick 	sleep(4);
10911704Smckusick 	if (ranf(100) >= 100 * dist)
11011704Smckusick 	{
11111704Smckusick 		return (printf("Equilibrium restored -- all systems normal\n"));
11211704Smckusick 	}
11311704Smckusick 
11411704Smckusick 	/* select a bizzare thing to happen to us */
11511704Smckusick 	percent = ranf(100);
11611704Smckusick 	if (percent < 70)
11711704Smckusick 	{
11811704Smckusick 		/* time warp */
11911704Smckusick 		if (percent < 35 || !Game.snap)
12011704Smckusick 		{
12111704Smckusick 			/* positive time warp */
12211704Smckusick 			time = (Ship.warp - 8.0) * dist * (franf() + 1.0);
12312738Slayer 			Now.date += time;
12411704Smckusick 			printf("Positive time portal entered -- it is now Stardate %.2f\n",
12511704Smckusick 				Now.date);
12611704Smckusick 			for (i = 0; i < MAXEVENTS; i++)
12711704Smckusick 			{
12811704Smckusick 				percent = Event[i].evcode;
12911704Smckusick 				if (percent == E_FIXDV || percent == E_LRTB)
13012738Slayer 					Event[i].date += time;
13111704Smckusick 			}
13211704Smckusick 			return;
13311704Smckusick 		}
13411704Smckusick 
13511704Smckusick 		/* s/he got lucky: a negative time portal */
13611704Smckusick 		time = Now.date;
13712738Slayer 		i = (int) Etc.snapshot;
13812738Slayer 		bmove(i, Quad, sizeof Quad);
13912738Slayer 		bmove(i += sizeof Quad, Event, sizeof Event);
14012738Slayer 		bmove(i += sizeof Event, &Now, sizeof Now);
14111704Smckusick 		printf("Negative time portal entered -- it is now Stardate %.2f\n",
14211704Smckusick 			Now.date);
14311704Smckusick 		for (i = 0; i < MAXEVENTS; i++)
14411704Smckusick 			if (Event[i].evcode == E_FIXDV)
14511704Smckusick 				reschedule(&Event[i], Event[i].date - time);
14611704Smckusick 		return;
14711704Smckusick 	}
14811704Smckusick 
14911704Smckusick 	/* test for just a lot of damage */
15011704Smckusick 	if (percent < 80)
15111704Smckusick 		lose(L_TOOFAST);
15211704Smckusick 	printf("Equilibrium restored -- extreme damage occured to ship systems\n");
15311704Smckusick 	for (i = 0; i < NDEV; i++)
15411704Smckusick 		damage(i, (3.0 * (franf() + franf()) + 1.0) * Param.damfac[i]);
15511704Smckusick 	Ship.shldup = 0;
15611704Smckusick }
157