1 /* $NetBSD: events.c,v 1.10 2009/05/24 21:44:56 dholland Exp $ */
4 * Copyright (c) 1980, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "@(#)events.c 8.1 (Berkeley) 5/31/93";
37 __RCSID("$NetBSD: events.c,v 1.10 2009/05/24 21:44:56 dholland Exp $");
48 ** CAUSE TIME TO ELAPSE
50 ** This routine does a hell of a lot. It elapses time, eats up
51 ** energy, regenerates energy, processes any events that occur,
54 ** 'timewarp' is set if called in a time warp.
67 struct event
*ev
= NULL
;
74 /* if nothing happened, just allow for any Klingons killed */
75 if (Move
.time
<= 0.0) {
76 Now
.time
= Now
.resource
/ Now
.klings
;
80 /* indicate that the cloaking device is now working */
83 /* idate is the initial date */
86 /* schedule attacks if resting too long */
87 if (Move
.time
> 0.5 && Move
.resting
)
88 schedule(E_ATTACK
, 0.5, 0, 0, 0);
90 /* scan the event list */
94 /* xdate is the date of the current event */
95 xdate
= idate
+ Move
.time
;
97 /* find the first event that has happened */
98 for (i
= 0; i
< MAXEVENTS
; i
++) {
100 if (e
->evcode
== 0 || (e
->evcode
& E_GHOST
))
102 if (e
->date
< xdate
) {
110 /* find the time between events */
111 rtime
= xdate
- Now
.date
;
113 /* decrement the magic "Federation Resources" pseudo-variable */
114 Now
.resource
-= Now
.klings
* rtime
;
115 /* and recompute the time left */
116 Now
.time
= Now
.resource
/ Now
.klings
;
118 /* move us up to the next date */
121 /* check for out of time */
125 if (evnum
>= 0 && Trace
)
126 printf("xdate = %.2f, evcode %d params %d %d %d\n",
127 xdate
, e
->evcode
, e
->x
, e
->y
, e
->systemname
);
130 /* if evnum < 0, no events occurred */
134 /* otherwise one did. Find out what it is */
135 switch (e
->evcode
& E_EVENT
) {
137 case E_SNOVA
: /* supernova */
138 /* cause the supernova to happen */
140 /* and schedule the next one */
141 xresched(e
, E_SNOVA
, 1);
144 case E_LRTB
: /* long range tractor beam */
145 /* schedule the next one */
146 xresched(e
, E_LRTB
, Now
.klings
);
147 /* LRTB cannot occur if we are docked */
148 if (Ship
.cond
!= DOCKED
) {
149 /* pick a new quadrant */
150 i
= ranf(Now
.klings
) + 1;
151 for (ix
= 0; ix
< NQUADS
; ix
++) {
152 for (iy
= 0; iy
< NQUADS
; iy
++) {
163 /* test for LRTB to same quadrant */
164 if (Ship
.quadx
== ix
&& Ship
.quady
== iy
)
167 /* nope, dump him in the new quadrant */
170 printf("\n%s caught in long range tractor "
173 printf("*** Pulled to quadrant %d,%d\n",
174 Ship
.quadx
, Ship
.quady
);
175 Ship
.sectx
= ranf(NSECTS
);
176 Ship
.secty
= ranf(NSECTS
);
178 /* truncate the move time */
179 Move
.time
= xdate
- idate
;
183 case E_KATSB
: /* Klingon attacks starbase */
184 /* if out of bases, forget it */
185 if (Now
.bases
<= 0) {
190 /* check for starbase and Klingons in same quadrant */
191 for (i
= 0; i
< Now
.bases
; i
++) {
194 /* see if a Klingon exists in this quadrant */
199 /* see if already distressed */
200 for (j
= 0; j
< MAXEVENTS
; j
++) {
202 if ((e
->evcode
& E_EVENT
) != E_KDESB
)
204 if (e
->x
== ix
&& e
->y
== iy
)
210 /* got a potential attack */
214 if (i
>= Now
.bases
) {
216 * not now; wait a while and see if
217 * some Klingons move in
219 reschedule(e
, 0.5 + 3.0 * franf());
223 * schedule a new attack, and a destruction of
226 xresched(e
, E_KATSB
, 1);
227 e
= xsched(E_KDESB
, 1, ix
, iy
, 0);
229 /* report it if we can */
230 if (!damaged(SSRADIO
)) {
231 printf("\nUhura: Captain, we have received a "
232 "distress signal\n");
233 printf(" from the starbase in quadrant "
239 * SSRADIO out, make it so we can't see the
240 * distress call but it's still there!!!
242 e
->evcode
|= E_HIDDEN
;
246 case E_KDESB
: /* Klingon destroys starbase */
248 q
= &Quad
[e
->x
][e
->y
];
250 * if the base has mysteriously gone away, or if the
251 * Klingon got tired and went home, ignore this event
253 if (q
->bases
<=0 || q
->klings
<= 0)
255 /* are we in the same quadrant? */
256 if (e
->x
== Ship
.quadx
&& e
->y
== Ship
.quady
) {
257 /* yep, kill one in this quadrant */
259 killb(Ship
.quadx
, Ship
.quady
);
261 /* kill one in some other quadrant */
266 case E_ISSUE
: /* issue a distress call */
267 xresched(e
, E_ISSUE
, 1);
268 /* if we already have too many, throw this one away */
269 if (Ship
.distressed
>= MAXDISTR
)
271 /* try a bunch of times to find something suitable */
272 for (i
= 0; i
< 100; i
++) {
277 * need a quadrant which is not the current
278 * one, which has some inhabited stars which
279 * are not already under attack, which is not
280 * supernova'ed, and which has some Klingons
283 if (!((ix
== Ship
.quadx
&& iy
== Ship
.quady
) ||
285 (q
->qsystemname
& Q_DISTRESSED
) ||
286 (q
->qsystemname
& Q_SYSTEM
) == 0 ||
291 /* can't seem to find one; ignore this call */
294 /* got one!! Schedule its enslavement */
296 e
= xsched(E_ENSLV
, 1, ix
, iy
, q
->qsystemname
);
297 q
->qsystemname
= (e
- Event
) | Q_DISTRESSED
;
299 /* tell the captain about it if we can */
300 if (!damaged(SSRADIO
)) {
301 printf("\nUhura: Captain, starsystem %s in "
302 "quadrant %d,%d is under attack\n",
303 Systemname
[e
->systemname
], ix
, iy
);
306 /* if we can't tell him, make it invisible */
307 e
->evcode
|= E_HIDDEN
;
311 case E_ENSLV
: /* starsystem is enslaved */
313 /* see if current distress call still active */
314 q
= &Quad
[e
->x
][e
->y
];
315 if (q
->klings
<= 0) {
316 /* no Klingons, clean up */
317 /* restore the system name */
318 q
->qsystemname
= e
->systemname
;
322 /* play stork and schedule the first baby */
323 e
= schedule(E_REPRO
, Param
.eventdly
[E_REPRO
] * franf(),
324 e
->x
, e
->y
, e
->systemname
);
326 /* report the disaster if we can */
327 if (!damaged(SSRADIO
)) {
328 printf("\nUhura: We've lost contact with "
330 Systemname
[e
->systemname
]);
331 printf(" in quadrant %d,%d.\n",
334 e
->evcode
|= E_HIDDEN
;
337 case E_REPRO
: /* Klingon reproduces */
338 /* see if distress call is still active */
339 q
= &Quad
[e
->x
][e
->y
];
340 if (q
->klings
<= 0) {
342 q
->qsystemname
= e
->systemname
;
345 xresched(e
, E_REPRO
, 1);
346 /* reproduce one Klingon */
349 if (Now
.klings
== 127) {
353 if (q
->klings
>= MAXKLQUAD
) {
354 /* this quadrant not ok, pick an adjacent one */
355 for (i
= ix
- 1; i
<= ix
+ 1; i
++) {
356 if (i
< 0 || i
>= NQUADS
)
358 for (j
= iy
- 1; j
<= iy
+ 1; j
++) {
359 if (j
< 0 || j
>= NQUADS
)
363 * check for this quad ok (not
366 if (q
->klings
>= MAXKLQUAD
||
375 /* cannot create another yet */
380 /* deliver the child */
383 if (ix
== Ship
.quadx
&& iy
== Ship
.quady
) {
384 /* we must position Klingon */
386 Sect
[ix
][iy
] = KLINGON
;
387 k
= &Etc
.klingon
[Etc
.nkling
++];
390 k
->power
= Param
.klingpwr
;
392 compkldist(Etc
.klingon
[0].dist
==
393 Etc
.klingon
[0].avgdist
? 0 : 1);
396 /* recompute time left */
397 Now
.time
= Now
.resource
/ Now
.klings
;
400 case E_SNAP
: /* take a snapshot of the galaxy */
401 xresched(e
, E_SNAP
, 1);
402 p
= (char *) Etc
.snapshot
;
403 memcpy(p
, Quad
, sizeof (Quad
));
405 memcpy(p
, Event
, sizeof (Event
));
407 memcpy(p
, &Now
, sizeof (Now
));
411 case E_ATTACK
: /* Klingons attack during rest period */
424 /* de-damage the device */
425 printf("%s reports repair work on the %s finished.\n",
426 Device
[i
].person
, Device
[i
].name
);
428 /* handle special processing upon fix */
432 Ship
.reserves
= Param
.reserves
;
436 if (Ship
.cond
== DOCKED
)
438 printf("Spock has tried to recalibrate your "
439 "Space Internal Navigation System,\n");
440 printf(" but he has no standard base to "
441 "calibrate to. Suggest you get\n");
442 printf(" to a starbase immediately so that "
443 "you can properly recalibrate.\n");
448 restcancel
= dumpssradio();
457 if (restcancel
&& Move
.resting
&&
458 getynpar("Spock: Shall we cancel our rest period"))
459 Move
.time
= xdate
- idate
;
463 /* unschedule an attack during a rest period */
464 if ((e
= Now
.eventptr
[E_ATTACK
]) != NULL
)
468 /* eat up energy if cloaked */
470 Ship
.energy
-= Param
.cloakenergy
* Move
.time
;
472 /* regenerate resources */
473 rtime
= 1.0 - exp(-Param
.regenfac
* Move
.time
);
474 Ship
.shield
+= (Param
.shield
- Ship
.shield
) * rtime
;
475 Ship
.energy
+= (Param
.energy
- Ship
.energy
) * rtime
;
477 /* decrement life support reserves */
478 if (damaged(LIFESUP
) && Ship
.cond
!= DOCKED
)
479 Ship
.reserves
-= Move
.time
;