* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
static char sccsid
[] = "@(#)events.c 5.1 (Berkeley) %G%";
** This routine does a hell of a lot. It elapses time, eats up
** energy, regenerates energy, processes any events that occur,
int warp
; /* set if called in a time warp */
struct event
*ev
, *xsched(), *schedule();
register struct event
*e
;
/* if nothing happened, just allow for any Klingons killed */
Now
.time
= Now
.resource
/ Now
.klings
;
/* indicate that the cloaking device is now working */
/* idate is the initial date */
/* schedule attacks if resting too long */
if (Move
.time
> 0.5 && Move
.resting
)
schedule(E_ATTACK
, 0.5, 0, 0, 0);
/* scan the event list */
/* xdate is the date of the current event */
xdate
= idate
+ Move
.time
;
/* find the first event that has happened */
for (i
= 0; i
< MAXEVENTS
; i
++)
if (e
->evcode
== 0 || (e
->evcode
& E_GHOST
))
/* find the time between events */
rtime
= xdate
- Now
.date
;
/* decrement the magic "Federation Resources" pseudo-variable */
Now
.resource
-= Now
.klings
* rtime
;
/* and recompute the time left */
Now
.time
= Now
.resource
/ Now
.klings
;
/* move us up to the next date */
/* check for out of time */
printf("xdate = %.2f, evcode %d params %d %d %d\n",
xdate
, e
->evcode
, e
->x
, e
->y
, e
->systemname
);
/* if evnum < 0, no events occurred */
/* otherwise one did. Find out what it is */
switch (e
->evcode
& E_EVENT
)
case E_SNOVA
: /* supernova */
/* cause the supernova to happen */
/* and schedule the next one */
case E_LRTB
: /* long range tractor beam */
/* schedule the next one */
xresched(e
, E_LRTB
, Now
.klings
);
/* LRTB cannot occur if we are docked */
/* pick a new quadrant */
i
= ranf(Now
.klings
) + 1;
for (ix
= 0; ix
< NQUADS
; ix
++)
for (iy
= 0; iy
< NQUADS
; iy
++)
if ((i
-= q
->klings
) <= 0)
/* test for LRTB to same quadrant */
if (Ship
.quadx
== ix
&& Ship
.quady
== iy
)
/* nope, dump him in the new quadrant */
printf("\n%s caught in long range tractor beam\n", Ship
.shipname
);
printf("*** Pulled to quadrant %d,%d\n", Ship
.quadx
, Ship
.quady
);
Ship
.sectx
= ranf(NSECTS
);
Ship
.secty
= ranf(NSECTS
);
/* truncate the move time */
Move
.time
= xdate
- idate
;
case E_KATSB
: /* Klingon attacks starbase */
/* if out of bases, forget it */
/* check for starbase and Klingons in same quadrant */
for (i
= 0; i
< Now
.bases
; i
++)
/* see if a Klingon exists in this quadrant */
/* see if already distressed */
for (j
= 0; j
< MAXEVENTS
; j
++)
if ((e
->evcode
& E_EVENT
) != E_KDESB
)
if (e
->x
== ix
&& e
->y
== iy
)
/* got a potential attack */
/* not now; wait a while and see if some Klingons move in */
reschedule(e
, 0.5 + 3.0 * franf());
/* schedule a new attack, and a destruction of the base */
e
= xsched(E_KDESB
, 1, ix
, iy
, 0);
/* report it if we can */
printf("\nUhura: Captain, we have recieved a distress signal\n");
printf(" from the starbase in quadrant %d,%d.\n",
/* SSRADIO out, make it so we can't see the distress call */
/* but it's still there!!! */
case E_KDESB
: /* Klingon destroys starbase */
/* if the base has mysteriously gone away, or if the Klingon
got tired and went home, ignore this event */
if (q
->bases
<=0 || q
->klings
<= 0)
/* are we in the same quadrant? */
if (e
->x
== Ship
.quadx
&& e
->y
== Ship
.quady
)
/* yep, kill one in this quadrant */
killb(Ship
.quadx
, Ship
.quady
);
/* kill one in some other quadrant */
case E_ISSUE
: /* issue a distress call */
/* if we already have too many, throw this one away */
if (Ship
.distressed
>= MAXDISTR
)
/* try a whole bunch of times to find something suitable */
for (i
= 0; i
< 100; i
++)
/* need a quadrant which is not the current one,
which has some stars which are inhabited and
not already under attack, which is not
supernova'ed, and which has some Klingons in it */
if (!((ix
== Ship
.quadx
&& iy
== Ship
.quady
) || q
->stars
< 0 ||
(q
->qsystemname
& Q_DISTRESSED
) ||
(q
->qsystemname
& Q_SYSTEM
) == 0 || q
->klings
<= 0))
/* can't seem to find one; ignore this call */
/* got one!! Schedule its enslavement */
e
= xsched(E_ENSLV
, 1, ix
, iy
, q
->qsystemname
);
q
->qsystemname
= (e
- Event
) | Q_DISTRESSED
;
/* tell the captain about it if we can */
printf("\nUhura: Captain, starsystem %s in quadrant %d,%d is under attack\n",
Systemname
[e
->systemname
], ix
, iy
);
/* if we can't tell him, make it invisible */
case E_ENSLV
: /* starsystem is enslaved */
/* see if current distress call still active */
/* no Klingons, clean up */
/* restore the system name */
q
->qsystemname
= e
->systemname
;
/* play stork and schedule the first baby */
e
= schedule(E_REPRO
, Param
.eventdly
[E_REPRO
] * franf(), e
->x
, e
->y
, e
->systemname
);
/* report the disaster if we can */
printf("\nUhura: We've lost contact with starsystem %s\n",
Systemname
[e
->systemname
]);
printf(" in quadrant %d,%d.\n",
case E_REPRO
: /* Klingon reproduces */
/* see if distress call is still active */
q
->qsystemname
= e
->systemname
;
/* reproduce one Klingon */
break; /* full right now */
if (q
->klings
>= MAXKLQUAD
)
/* this quadrant not ok, pick an adjacent one */
for (i
= ix
- 1; i
<= ix
+ 1; i
++)
if (i
< 0 || i
>= NQUADS
)
for (j
= iy
- 1; j
<= iy
+ 1; j
++)
if (j
< 0 || j
>= NQUADS
)
/* check for this quad ok (not full & no snova) */
if (q
->klings
>= MAXKLQUAD
|| q
->stars
< 0)
/* cannot create another yet */
if (ix
== Ship
.quadx
&& iy
== Ship
.quady
)
/* we must position Klingon */
k
= &Etc
.klingon
[Etc
.nkling
++];
k
->power
= Param
.klingpwr
;
compkldist(Etc
.klingon
[0].dist
== Etc
.klingon
[0].avgdist
? 0 : 1);
/* recompute time left */
Now
.time
= Now
.resource
/ Now
.klings
;
case E_SNAP
: /* take a snapshot of the galaxy */
i
= bmove(Quad
, i
, sizeof (Quad
));
i
= bmove(Event
, i
, sizeof (Event
));
i
= bmove(&Now
, i
, sizeof (Now
));
case E_ATTACK
: /* Klingons attack during rest period */
/* de-damage the device */
printf("%s reports repair work on the %s finished.\n",
Device
[i
].person
, Device
[i
].name
);
/* handle special processing upon fix */
Ship
.reserves
= Param
.reserves
;
printf("Spock has tried to recalibrate your Space Internal Navigation System,\n");
printf(" but he has no standard base to calibrate to. Suggest you get\n");
printf(" to a starbase immediately so that you can properly recalibrate.\n");
restcancel
= dumpssradio();
if (restcancel
&& Move
.resting
&& getynpar("Spock: Shall we cancel our rest period"))
Move
.time
= xdate
- idate
;
/* unschedule an attack during a rest period */
if (e
= Now
.eventptr
[E_ATTACK
])
/* eat up energy if cloaked */
Ship
.energy
-= Param
.cloakenergy
* Move
.time
;
/* regenerate resources */
rtime
= 1.0 - exp(-Param
.regenfac
* Move
.time
);
Ship
.shield
+= (Param
.shield
- Ship
.shield
) * rtime
;
Ship
.energy
+= (Param
.energy
- Ship
.energy
) * rtime
;
/* decrement life support reserves */
if (damaged(LIFESUP
) && Ship
.cond
!= DOCKED
)
Ship
.reserves
-= Move
.time
;