1 /* @(#)events.c 8.1 (Berkeley) 5/31/93 */
2 /* $NetBSD: events.c,v 1.11 2009/05/24 22:55:03 dholland Exp $ */
5 * Copyright (c) 1980, 1993
6 * The Regents of the University of California. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 ** CAUSE TIME TO ELAPSE
42 ** This routine does a hell of a lot. It elapses time, eats up
43 ** energy, regenerates energy, processes any events that occur,
46 ** 'timewarp' is set if called in a time warp.
59 struct event
*ev
= NULL
;
66 /* if nothing happened, just allow for any Klingons killed */
67 if (Move
.time
<= 0.0) {
68 Now
.time
= Now
.resource
/ Now
.klings
;
72 /* indicate that the cloaking device is now working */
75 /* idate is the initial date */
78 /* schedule attacks if resting too long */
79 if (Move
.time
> 0.5 && Move
.resting
)
80 schedule(E_ATTACK
, 0.5, 0, 0, 0);
82 /* scan the event list */
86 /* xdate is the date of the current event */
87 xdate
= idate
+ Move
.time
;
89 /* find the first event that has happened */
90 for (i
= 0; i
< MAXEVENTS
; i
++) {
92 if (e
->evcode
== 0 || (e
->evcode
& E_GHOST
))
94 if (e
->date
< xdate
) {
102 /* find the time between events */
103 rtime
= xdate
- Now
.date
;
105 /* decrement the magic "Federation Resources" pseudo-variable */
106 Now
.resource
-= Now
.klings
* rtime
;
107 /* and recompute the time left */
108 Now
.time
= Now
.resource
/ Now
.klings
;
110 /* move us up to the next date */
113 /* check for out of time */
117 if (evnum
>= 0 && Trace
)
118 printf("xdate = %.2f, evcode %d params %d %d %d\n",
119 xdate
, e
->evcode
, e
->x
, e
->y
, e
->systemname
);
122 /* if evnum < 0, no events occurred */
126 /* otherwise one did. Find out what it is */
127 switch (e
->evcode
& E_EVENT
) {
129 case E_SNOVA
: /* supernova */
130 /* cause the supernova to happen */
132 /* and schedule the next one */
133 xresched(e
, E_SNOVA
, 1);
136 case E_LRTB
: /* long range tractor beam */
137 /* schedule the next one */
138 xresched(e
, E_LRTB
, Now
.klings
);
139 /* LRTB cannot occur if we are docked */
140 if (Ship
.cond
!= DOCKED
) {
141 /* pick a new quadrant */
142 i
= ranf(Now
.klings
) + 1;
143 for (ix
= 0; ix
< NQUADS
; ix
++) {
144 for (iy
= 0; iy
< NQUADS
; iy
++) {
155 /* test for LRTB to same quadrant */
156 if (Ship
.quadx
== ix
&& Ship
.quady
== iy
)
159 /* nope, dump him in the new quadrant */
162 printf("\n%s caught in long range tractor "
165 printf("*** Pulled to quadrant %d,%d\n",
166 Ship
.quadx
, Ship
.quady
);
167 Ship
.sectx
= ranf(NSECTS
);
168 Ship
.secty
= ranf(NSECTS
);
170 /* truncate the move time */
171 Move
.time
= xdate
- idate
;
175 case E_KATSB
: /* Klingon attacks starbase */
176 /* if out of bases, forget it */
177 if (Now
.bases
<= 0) {
182 /* check for starbase and Klingons in same quadrant */
183 for (i
= 0; i
< Now
.bases
; i
++) {
186 /* see if a Klingon exists in this quadrant */
191 /* see if already distressed */
192 for (j
= 0; j
< MAXEVENTS
; j
++) {
194 if ((e
->evcode
& E_EVENT
) != E_KDESB
)
196 if (e
->x
== ix
&& e
->y
== iy
)
202 /* got a potential attack */
206 if (i
>= Now
.bases
) {
208 * not now; wait a while and see if
209 * some Klingons move in
211 reschedule(e
, 0.5 + 3.0 * franf());
215 * schedule a new attack, and a destruction of
218 xresched(e
, E_KATSB
, 1);
219 e
= xsched(E_KDESB
, 1, ix
, iy
, 0);
221 /* report it if we can */
222 if (!damaged(SSRADIO
)) {
223 printf("\nUhura: Captain, we have received a "
224 "distress signal\n");
225 printf(" from the starbase in quadrant "
231 * SSRADIO out, make it so we can't see the
232 * distress call but it's still there!!!
234 e
->evcode
|= E_HIDDEN
;
238 case E_KDESB
: /* Klingon destroys starbase */
240 q
= &Quad
[e
->x
][e
->y
];
242 * if the base has mysteriously gone away, or if the
243 * Klingon got tired and went home, ignore this event
245 if (q
->bases
<=0 || q
->klings
<= 0)
247 /* are we in the same quadrant? */
248 if (e
->x
== Ship
.quadx
&& e
->y
== Ship
.quady
) {
249 /* yep, kill one in this quadrant */
251 killb(Ship
.quadx
, Ship
.quady
);
253 /* kill one in some other quadrant */
258 case E_ISSUE
: /* issue a distress call */
259 xresched(e
, E_ISSUE
, 1);
260 /* if we already have too many, throw this one away */
261 if (Ship
.distressed
>= MAXDISTR
)
263 /* try a bunch of times to find something suitable */
264 for (i
= 0; i
< 100; i
++) {
269 * need a quadrant which is not the current
270 * one, which has some inhabited stars which
271 * are not already under attack, which is not
272 * supernova'ed, and which has some Klingons
275 if (!((ix
== Ship
.quadx
&& iy
== Ship
.quady
) ||
277 (q
->qsystemname
& Q_DISTRESSED
) ||
278 (q
->qsystemname
& Q_SYSTEM
) == 0 ||
283 /* can't seem to find one; ignore this call */
286 /* got one!! Schedule its enslavement */
288 e
= xsched(E_ENSLV
, 1, ix
, iy
, q
->qsystemname
);
289 q
->qsystemname
= (e
- Event
) | Q_DISTRESSED
;
291 /* tell the captain about it if we can */
292 if (!damaged(SSRADIO
)) {
293 printf("\nUhura: Captain, starsystem %s in "
294 "quadrant %d,%d is under attack\n",
295 Systemname
[e
->systemname
], ix
, iy
);
298 /* if we can't tell him, make it invisible */
299 e
->evcode
|= E_HIDDEN
;
303 case E_ENSLV
: /* starsystem is enslaved */
305 /* see if current distress call still active */
306 q
= &Quad
[e
->x
][e
->y
];
307 if (q
->klings
<= 0) {
308 /* no Klingons, clean up */
309 /* restore the system name */
310 q
->qsystemname
= e
->systemname
;
314 /* play stork and schedule the first baby */
315 e
= schedule(E_REPRO
, Param
.eventdly
[E_REPRO
] * franf(),
316 e
->x
, e
->y
, e
->systemname
);
318 /* report the disaster if we can */
319 if (!damaged(SSRADIO
)) {
320 printf("\nUhura: We've lost contact with "
322 Systemname
[e
->systemname
]);
323 printf(" in quadrant %d,%d.\n",
326 e
->evcode
|= E_HIDDEN
;
329 case E_REPRO
: /* Klingon reproduces */
330 /* see if distress call is still active */
331 q
= &Quad
[e
->x
][e
->y
];
332 if (q
->klings
<= 0) {
334 q
->qsystemname
= e
->systemname
;
337 xresched(e
, E_REPRO
, 1);
338 /* reproduce one Klingon */
341 if (Now
.klings
== 127) {
345 if (q
->klings
>= MAXKLQUAD
) {
346 /* this quadrant not ok, pick an adjacent one */
347 for (i
= ix
- 1; i
<= ix
+ 1; i
++) {
348 if (i
< 0 || i
>= NQUADS
)
350 for (j
= iy
- 1; j
<= iy
+ 1; j
++) {
351 if (j
< 0 || j
>= NQUADS
)
355 * check for this quad ok (not
358 if (q
->klings
>= MAXKLQUAD
||
367 /* cannot create another yet */
372 /* deliver the child */
375 if (ix
== Ship
.quadx
&& iy
== Ship
.quady
) {
376 /* we must position Klingon */
378 Sect
[ix
][iy
] = KLINGON
;
379 k
= &Etc
.klingon
[Etc
.nkling
++];
382 k
->power
= Param
.klingpwr
;
384 compkldist(Etc
.klingon
[0].dist
==
385 Etc
.klingon
[0].avgdist
? 0 : 1);
388 /* recompute time left */
389 Now
.time
= Now
.resource
/ Now
.klings
;
392 case E_SNAP
: /* take a snapshot of the galaxy */
393 xresched(e
, E_SNAP
, 1);
394 p
= (char *) Etc
.snapshot
;
395 memcpy(p
, Quad
, sizeof (Quad
));
397 memcpy(p
, Event
, sizeof (Event
));
399 memcpy(p
, &Now
, sizeof (Now
));
403 case E_ATTACK
: /* Klingons attack during rest period */
416 /* de-damage the device */
417 printf("%s reports repair work on the %s finished.\n",
418 Device
[i
].person
, Device
[i
].name
);
420 /* handle special processing upon fix */
424 Ship
.reserves
= Param
.reserves
;
428 if (Ship
.cond
== DOCKED
)
430 printf("Spock has tried to recalibrate your "
431 "Space Internal Navigation System,\n");
432 printf(" but he has no standard base to "
433 "calibrate to. Suggest you get\n");
434 printf(" to a starbase immediately so that "
435 "you can properly recalibrate.\n");
440 restcancel
= dumpssradio();
449 if (restcancel
&& Move
.resting
&&
450 getynpar("Spock: Shall we cancel our rest period"))
451 Move
.time
= xdate
- idate
;
455 /* unschedule an attack during a rest period */
456 if ((e
= Now
.eventptr
[E_ATTACK
]) != NULL
)
460 /* eat up energy if cloaked */
462 Ship
.energy
-= Param
.cloakenergy
* Move
.time
;
464 /* regenerate resources */
465 rtime
= 1.0 - exp(-Param
.regenfac
* Move
.time
);
466 Ship
.shield
+= (Param
.shield
- Ship
.shield
) * rtime
;
467 Ship
.energy
+= (Param
.energy
- Ship
.energy
) * rtime
;
469 /* decrement life support reserves */
470 if (damaged(LIFESUP
) && Ship
.cond
!= DOCKED
)
471 Ship
.reserves
-= Move
.time
;