Merge from vendor branch OPENSSH:
[dragonfly.git] / games / trek / warp.c
1 /*
2  * Copyright (c) 1980, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * @(#)warp.c   8.1 (Berkeley) 5/31/93
34  * $FreeBSD: src/games/trek/warp.c,v 1.4 1999/11/30 03:49:56 billf Exp $
35  * $DragonFly: src/games/trek/warp.c,v 1.2 2003/06/17 04:25:25 dillon Exp $
36  */
37
38 # include       "trek.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 warp(fl, c, d)
57 int     fl, c;
58 double  d;
59 {
60         int                     course;
61         double                  power;
62         double                  dist;
63         double                  time;
64         double                  speed;
65         double                  frac;
66         int             percent;
67         int             i;
68         extern double           move();
69
70         if (Ship.cond == DOCKED)
71                 return (printf("%s is docked\n", Ship.shipname));
72         if (damaged(WARP))
73         {
74                 return (out(WARP));
75         }
76         if (fl < 0)
77         {
78                 course = c;
79                 dist = d;
80         }
81         else
82                 if (getcodi(&course, &dist))
83                         return;
84
85         /* check to see that we are not using an absurd amount of power */
86         power = (dist + 0.05) * Ship.warp3;
87         percent = 100 * power / Ship.energy + 0.5;
88         if (percent >= 85)
89         {
90                 printf("Scotty: That would consume %d%% of our remaining energy.\n",
91                         percent);
92                 if (!getynpar("Are you sure that is wise"))
93                         return;
94         }
95
96         /* compute the speed we will move at, and the time it will take */
97         speed = Ship.warp2 / Param.warptime;
98         time = dist / speed;
99
100         /* check to see that that value is not ridiculous */
101         percent = 100 * time / Now.time + 0.5;
102         if (percent >= 85)
103         {
104                 printf("Spock: That would take %d%% of our remaining time.\n",
105                         percent);
106                 if (!getynpar("Are you sure that is wise"))
107                         return;
108         }
109
110         /* compute how far we will go if we get damages */
111         if (Ship.warp > 6.0 && ranf(100) < 20 + 15 * (Ship.warp - 6.0))
112         {
113                 frac = franf();
114                 dist *= frac;
115                 time *= frac;
116                 damage(WARP, (frac + 1.0) * Ship.warp * (franf() + 0.25) * 0.20);
117         }
118
119         /* do the move */
120         Move.time = move(fl, course, time, speed);
121
122         /* see how far we actually went, and decrement energy appropriately */
123         dist = Move.time * speed;
124         Ship.energy -= dist * Ship.warp3 * (Ship.shldup + 1);
125
126         /* test for bizarre events */
127         if (Ship.warp <= 9.0)
128                 return;
129         printf("\n\n  ___ Speed exceeding warp nine ___\n\n");
130         sleep(2);
131         printf("Ship's safety systems malfunction\n");
132         sleep(2);
133         printf("Crew experiencing extreme sensory distortion\n");
134         sleep(4);
135         if (ranf(100) >= 100 * dist)
136         {
137                 return (printf("Equilibrium restored -- all systems normal\n"));
138         }
139
140         /* select a bizzare thing to happen to us */
141         percent = ranf(100);
142         if (percent < 70)
143         {
144                 /* time warp */
145                 if (percent < 35 || !Game.snap)
146                 {
147                         /* positive time warp */
148                         time = (Ship.warp - 8.0) * dist * (franf() + 1.0);
149                         Now.date += time;
150                         printf("Positive time portal entered -- it is now Stardate %.2f\n",
151                                 Now.date);
152                         for (i = 0; i < MAXEVENTS; i++)
153                         {
154                                 percent = Event[i].evcode;
155                                 if (percent == E_FIXDV || percent == E_LRTB)
156                                         Event[i].date += time;
157                         }
158                         return;
159                 }
160
161                 /* s/he got lucky: a negative time portal */
162                 time = Now.date;
163                 i = (int) Etc.snapshot;
164                 bmove(i, Quad, sizeof Quad);
165                 bmove(i += sizeof Quad, Event, sizeof Event);
166                 bmove(i += sizeof Event, &Now, sizeof Now);
167                 printf("Negative time portal entered -- it is now Stardate %.2f\n",
168                         Now.date);
169                 for (i = 0; i < MAXEVENTS; i++)
170                         if (Event[i].evcode == E_FIXDV)
171                                 reschedule(&Event[i], Event[i].date - time);
172                 return;
173         }
174
175         /* test for just a lot of damage */
176         if (percent < 80)
177                 lose(L_TOOFAST);
178         printf("Equilibrium restored -- extreme damage occured to ship systems\n");
179         for (i = 0; i < NDEV; i++)
180                 damage(i, (3.0 * (franf() + franf()) + 1.0) * Param.damfac[i]);
181         Ship.shldup = 0;
182 }