V10/games/trek/events.c

Compare this file to the similar file:
Show the results in this format:

# include	"trek.h"

/**
 **	cause time to elapse
 **/

/* snapshot for time warps */
char	Snapshot[14 + sizeof Quad + sizeof Event + sizeof Base + sizeof Etc];

double randly(evname)
int	evname;
{
	return(Param.eventdly[evname] * franf());
}

double logdly(evname)
int	evname;
{
	double d;

	d = Param.eventdly[evname] * Initial.time * log(franf());
	if(evname==E_LRTB)	d =/ Status.kling;
	return(-d);
}

events()
{
	register int		i;
	int			j;
	int			restcancel;
	KLINGONS		*k;
	double			rtime;
	double			xdate;
	double			idate;
	EVENT			*ev;
	int			ix, iy;
	register QUAD		*q;
	register EVENT		*e;
	int			evnum;

	if (Move.delta <= 0.0)
	{
		Status.time = Status.resource / Status.kling;
		return;
	}
	idate = Status.date;
	if (Move.delta > 0.5 && Move.resting)
		schedule(E_ATTACK, 0.5, 0, 0, 0);
	while (1)
	{
		restcancel = 0;
		evnum = -1;
		xdate = idate + Move.delta;
		for (i = 0; i < MAXEVENTS; i++)
		{
			e = &Event[i];
			if (e->evcode < 0)
				continue;
			if (e->date < xdate)
			{
				xdate = e->date;
				ev = e;
				evnum = i;
			}
		}
		rtime = xdate - Status.date;
		Status.resource =- Status.kling * rtime;
		Status.time = Status.resource / Status.kling;
		Status.date = xdate;
		if (Status.time <= 0.0)
			lose(L_NOTIME);
		if (evnum < 0)
			break;
		e = ev;
		switch (e->evcode)
		{
		  case E_SNOVA:			/* supernova */
			snova(-1);
			reschedule(e, logdly(E_SNOVA));
			break;

		  case E_LRTB:			/* long range tractor beam */
			if (Status.cond != DOCKED && Nkling < 3)
			{
				i = ranf(Status.kling) + 1;
				for (ix = 0; ix < NQUADS; ix++)
				{
					for (iy = 0; iy < NQUADS; iy++)
						if (Quad[ix][iy].stars >= 0)
							if ((i =- Quad[ix][iy].qkling) <= 0)
								break;
					if (i <= 0)
						break;
				}
				Quadx = ix;
				Quady = iy;
				printf("%s caught in long range tractor beam", Status.shipname);
				printf("; pulled to quadrant %d,%d\n", Quadx, Quady);
				Sectx = ranf(NSECTS);
				Secty = ranf(NSECTS);
				initquad(0);
				Move.delta = xdate - idate;
			}
			reschedule(e, logdly(E_LRTB));
			break;

		  case E_KATSB:			/* Klingon attacks starbase */
			if (Status.bases <= 0)
			{
				unschedule(e);
				break;
			}
			i = 1;
			for (ix = 0; ix < NQUADS; ix++)
			{
				for (iy = 0; iy < NQUADS; iy++)
					if (Quad[ix][iy].bases > 0 && Quad[ix][iy].qkling > 0)
					{
						i = 0;
						break;
					}
				if (!i)
					break;
			}
			reschedule(e, logdly(E_KATSB));
			if (i)	break;
			e = schedule(E_KDESB, 0.5 + randly(E_KDESB), ix, iy, 0);
			if (!Damage[SSRADIO])
			{
				printf("Uhura:\tCaptain, we have recieved a distress signal\n");
				printf("\tfrom the starbase in quadrant %d,%d.\n",
					ix, iy);
				restcancel++;
			}
			else
				e->evdata = E_NREPORT;
			break;

		  case E_KDESB:			/* Klingon destroys starbase */
			unschedule(e);
			q = &Quad[e->x][e->y];
			if (q->bases <=0 || q->qkling <= 0)
				break;
			if (e->x == Quadx && e->y == Quady)
			{
				printf("\nSpock: ");
				killb(Quadx, Quady);
			}
			else
				killb(e->x, e->y);
			break;

		  case E_ISSUE:		/* issue a distress call */
			reschedule(e, logdly(E_ISSUE));
			if (Status.distressed >= MAXDISTR)
				break;
			for (i = 0; i < 100; i++)
			{
				ix = ranf(NQUADS);
				iy = ranf(NQUADS);
				q = &Quad[ix][iy];
				if (!((ix == Quadx && iy == Quady) || q->stars < 0 ||
				    q->systemname&(Q_DISTRESS|Q_GHOST) ||
				    q->systemname == 0 || q->qkling <= 0))
					break;
			}
			if (i >= 100)
				break;
			Status.distressed =+ 1;
			e = schedule(E_ENSLV, randly(E_ENSLV), ix, iy, q->systemname);
			q->systemname = (e - Event) | Q_DISTRESS;
			if (!Damage[SSRADIO])
			{
				printf("Uhura:\tCaptain, starsystem %s in quadrant %d,%d is under attack.\n",
					Systemname[e->evdata], ix, iy);
				restcancel++;
			}
			else
				e->evdata =| E_NREPORT;
			break;

		  case E_ENSLV:		/* starsystem is enslaved */
			unschedule(e);
			/* see if current distress call still active */
			q = &Quad[e->x][e->y];
			if (q->qkling <= 0)
			{
				e->evdata =& ~E_NREPORT;
				if(q->systemname&Q_DISTRESS)
					q->systemname = e->evdata;
				break;
			}
			else
				schedule(E_REPRO, randly(E_REPRO), e->x, e->y, e->evdata);
			if (!Damage[SSRADIO])
			{
				printf("Uhura:\tWe've lost contact with starsystem %s\n",
					Systemname[e->evdata]);
				printf("  in quadrant %d,%d.\n",
					e->x, e->y);
			}
			break;

		  case E_REPRO:		/* Klingon reproduces */
			/* see if distress call is still active */
			q = &Quad[e->x][e->y];
			if (q->qkling <= 0)
			{
				unschedule(e);
				if (q->systemname&Q_DISTRESS)
					q->systemname = e->evdata;
				break;
			}
			reschedule(e, randly(E_REPRO));
			/* reproduce one Klingon */
			ix = e->x;
			iy = e->y;
			if (Status.kling == 127)
				break;		/* full right now */
			if (q->qkling >= 9)
			{
				/* this quadrant not ok */
				for (i = ix - 1; i <= ix + 1; i++)
				{
					if (i < 0 || i >= NQUADS)
						continue;
					for (j = iy - 1; j <= iy + 1; j++)
					{
						if (j < 0 || j >= NQUADS)
							continue;
						q = &Quad[i][j];
						if (q->qkling >= 9 || q->stars < 0)
							continue;
						break;
					}
					if (j <= iy + 1)
						break;
				}
				if (j > iy + 1)
					/* cannot create another yet */
					break;
				ix = i;
				iy = j;
			}
			q->qkling =+ 1;
			Status.kling =+ 1;
			if (ix == Quadx && iy == Quady)
			{
				/* we must position Klingon */
				sector(&ix, &iy);
				Sect[ix][iy] = KLINGON;
				k = &Kling[Nkling++];
				k->x = ix;
				k->y = iy;
				k->power = Param.klingpwr;
				compkldist(Kling[0].dist == Kling[0].avgdist ? 0 : 1);
			}
			Status.time = Status.resource / Status.kling;
			break;

		  case E_SNAP:
			reschedule(e, logdly(E_SNAP));
			i = &Snapshot;
			i = bmove(&Status.bases, i, 2);
			i = bmove(&Status.date, i, 12);
			i = bmove(&Quad, i, sizeof Quad);
			i = bmove(&Event, i, sizeof Event);
			i = bmove(&Base, i, sizeof Base);
			i = bmove(&Etc, i, sizeof Etc);
			Game.snap = 1;
			break;

		  case E_ATTACK:	/* Klingons attack during rest period */
			if (!Move.resting)
			{
				unschedule(e);
				break;
			}
			attack(1);
			reschedule(e, 0.5);
			break;

		  case E_FIXDV:
			i = e->evdata;
			unschedule(e);
			Damage[i] = 0;
			printf("%s reports repair work on the %s finished.\n",
				Device[i].person, Device[i].name);
			switch (i)
			{
			  case LIFESUP:
				Status.reserves = Initial.reserves;
				break;

			  case SINS:
				if (Status.cond == DOCKED)
					break;
				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");
				Status.sinsbad = 1;
				break;

			  case SSRADIO:
				restcancel = dumpssradio();
				break;
			}
			break;

		  default:
			break;
		}

		if(Move.resting && restcancel && getynpar("Spock: Shall we cancel our rest period"))
			Move.delta = xdate - idate;
	}

	if (e = Etc.eventptr[E_ATTACK])
		unschedule(e);
	if (Status.cloaked)
		Status.energy =- Param.cloakenergy * Move.delta;
	rtime = 1.0 - exp(-Param.regenfac * Move.delta);
	Status.shield =+ (Initial.shield - Status.shield) * rtime;
	Status.energy =+ (Initial.energy - Status.energy) * rtime;
	if (Damage[LIFESUP] && Status.cond != DOCKED)
		Status.reserves =- Move.delta;
	return;
}