|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)events.c 4.2 (Berkeley) 5/27/83";
3: #endif not lint
4:
5: # include "trek.h"
6:
7: /*
8: ** CAUSE TIME TO ELAPSE
9: **
10: ** This routine does a hell of a lot. It elapses time, eats up
11: ** energy, regenerates energy, processes any events that occur,
12: ** and so on.
13: */
14:
15:
16: events(warp)
17: int warp; /* set if called in a time warp */
18: {
19: register int i;
20: int j;
21: struct kling *k;
22: double rtime;
23: double xdate;
24: double idate;
25: struct event *ev, *xsched(), *schedule();
26: int ix, iy;
27: register struct quad *q;
28: register struct event *e;
29: int evnum;
30: int restcancel;
31:
32: /* if nothing happened, just allow for any Klingons killed */
33: if (Move.time <= 0.0)
34: {
35: Now.time = Now.resource / Now.klings;
36: return (0);
37: }
38:
39: /* indicate that the cloaking device is now working */
40: Ship.cloakgood = 1;
41:
42: /* idate is the initial date */
43: idate = Now.date;
44:
45: /* schedule attacks if resting too long */
46: if (Move.time > 0.5 && Move.resting)
47: schedule(E_ATTACK, 0.5, 0, 0, 0);
48:
49: /* scan the event list */
50: while (1)
51: {
52: restcancel = 0;
53: evnum = -1;
54: /* xdate is the date of the current event */
55: xdate = idate + Move.time;
56:
57: /* find the first event that has happened */
58: for (i = 0; i < MAXEVENTS; i++)
59: {
60: e = &Event[i];
61: if (e->evcode == 0 || (e->evcode & E_GHOST))
62: continue;
63: if (e->date < xdate)
64: {
65: xdate = e->date;
66: ev = e;
67: evnum = i;
68: }
69: }
70: e = ev;
71:
72: /* find the time between events */
73: rtime = xdate - Now.date;
74:
75: /* decrement the magic "Federation Resources" pseudo-variable */
76: Now.resource -= Now.klings * rtime;
77: /* and recompute the time left */
78: Now.time = Now.resource / Now.klings;
79:
80: /* move us up to the next date */
81: Now.date = xdate;
82:
83: /* check for out of time */
84: if (Now.time <= 0.0)
85: lose(L_NOTIME);
86: # ifdef xTRACE
87: if (evnum >= 0 && Trace)
88: printf("xdate = %.2f, evcode %d params %d %d %d\n",
89: xdate, e->evcode, e->x, e->y, e->systemname);
90: # endif
91:
92: /* if evnum < 0, no events occurred */
93: if (evnum < 0)
94: break;
95:
96: /* otherwise one did. Find out what it is */
97: switch (e->evcode & E_EVENT)
98: {
99:
100: case E_SNOVA: /* supernova */
101: /* cause the supernova to happen */
102: snova(-1);
103: /* and schedule the next one */
104: xresched(e, E_SNOVA, 1);
105: break;
106:
107: case E_LRTB: /* long range tractor beam */
108: /* schedule the next one */
109: xresched(e, E_LRTB, Now.klings);
110: /* LRTB cannot occur if we are docked */
111: if (Ship.cond != DOCKED)
112: {
113: /* pick a new quadrant */
114: i = ranf(Now.klings) + 1;
115: for (ix = 0; ix < NQUADS; ix++)
116: {
117: for (iy = 0; iy < NQUADS; iy++)
118: {
119: q = &Quad[ix][iy];
120: if (q->stars >= 0)
121: if ((i -= q->klings) <= 0)
122: break;
123: }
124: if (i <= 0)
125: break;
126: }
127:
128: /* test for LRTB to same quadrant */
129: if (Ship.quadx == ix && Ship.quady == iy)
130: break;
131:
132: /* nope, dump him in the new quadrant */
133: Ship.quadx = ix;
134: Ship.quady = iy;
135: printf("\n%s caught in long range tractor beam\n", Ship.shipname);
136: printf("*** Pulled to quadrant %d,%d\n", Ship.quadx, Ship.quady);
137: Ship.sectx = ranf(NSECTS);
138: Ship.secty = ranf(NSECTS);
139: initquad(0);
140: /* truncate the move time */
141: Move.time = xdate - idate;
142: }
143: break;
144:
145: case E_KATSB: /* Klingon attacks starbase */
146: /* if out of bases, forget it */
147: if (Now.bases <= 0)
148: {
149: unschedule(e);
150: break;
151: }
152:
153: /* check for starbase and Klingons in same quadrant */
154: for (i = 0; i < Now.bases; i++)
155: {
156: ix = Now.base[i].x;
157: iy = Now.base[i].y;
158: /* see if a Klingon exists in this quadrant */
159: q = &Quad[ix][iy];
160: if (q->klings <= 0)
161: continue;
162:
163: /* see if already distressed */
164: for (j = 0; j < MAXEVENTS; j++)
165: {
166: e = &Event[j];
167: if ((e->evcode & E_EVENT) != E_KDESB)
168: continue;
169: if (e->x == ix && e->y == iy)
170: break;
171: }
172: if (j < MAXEVENTS)
173: continue;
174:
175: /* got a potential attack */
176: break;
177: }
178: e = ev;
179: if (i >= Now.bases)
180: {
181: /* not now; wait a while and see if some Klingons move in */
182: reschedule(e, 0.5 + 3.0 * franf());
183: break;
184: }
185: /* schedule a new attack, and a destruction of the base */
186: xresched(e, E_KATSB, 1);
187: e = xsched(E_KDESB, 1, ix, iy, 0);
188:
189: /* report it if we can */
190: if (!damaged(SSRADIO))
191: {
192: printf("\nUhura: Captain, we have recieved a distress signal\n");
193: printf(" from the starbase in quadrant %d,%d.\n",
194: ix, iy);
195: restcancel++;
196: }
197: else
198: /* SSRADIO out, make it so we can't see the distress call */
199: /* but it's still there!!! */
200: e->evcode |= E_HIDDEN;
201: break;
202:
203: case E_KDESB: /* Klingon destroys starbase */
204: unschedule(e);
205: q = &Quad[e->x][e->y];
206: /* if the base has mysteriously gone away, or if the Klingon
207: got tired and went home, ignore this event */
208: if (q->bases <=0 || q->klings <= 0)
209: break;
210: /* are we in the same quadrant? */
211: if (e->x == Ship.quadx && e->y == Ship.quady)
212: {
213: /* yep, kill one in this quadrant */
214: printf("\nSpock: ");
215: killb(Ship.quadx, Ship.quady);
216: }
217: else
218: /* kill one in some other quadrant */
219: killb(e->x, e->y);
220: break;
221:
222: case E_ISSUE: /* issue a distress call */
223: xresched(e, E_ISSUE, 1);
224: /* if we already have too many, throw this one away */
225: if (Ship.distressed >= MAXDISTR)
226: break;
227: /* try a whole bunch of times to find something suitable */
228: for (i = 0; i < 100; i++)
229: {
230: ix = ranf(NQUADS);
231: iy = ranf(NQUADS);
232: q = &Quad[ix][iy];
233: /* need a quadrant which is not the current one,
234: which has some stars which are inhabited and
235: not already under attack, which is not
236: supernova'ed, and which has some Klingons in it */
237: if (!((ix == Ship.quadx && iy == Ship.quady) || q->stars < 0 ||
238: (q->qsystemname & Q_DISTRESSED) ||
239: (q->qsystemname & Q_SYSTEM) == 0 || q->klings <= 0))
240: break;
241: }
242: if (i >= 100)
243: /* can't seem to find one; ignore this call */
244: break;
245:
246: /* got one!! Schedule its enslavement */
247: Ship.distressed++;
248: e = xsched(E_ENSLV, 1, ix, iy, q->qsystemname);
249: q->qsystemname = (e - Event) | Q_DISTRESSED;
250:
251: /* tell the captain about it if we can */
252: if (!damaged(SSRADIO))
253: {
254: printf("\nUhura: Captain, starsystem %s in quadrant %d,%d is under attack\n",
255: Systemname[e->systemname], ix, iy);
256: restcancel++;
257: }
258: else
259: /* if we can't tell him, make it invisible */
260: e->evcode |= E_HIDDEN;
261: break;
262:
263: case E_ENSLV: /* starsystem is enslaved */
264: unschedule(e);
265: /* see if current distress call still active */
266: q = &Quad[e->x][e->y];
267: if (q->klings <= 0)
268: {
269: /* no Klingons, clean up */
270: /* restore the system name */
271: q->qsystemname = e->systemname;
272: break;
273: }
274:
275: /* play stork and schedule the first baby */
276: e = schedule(E_REPRO, Param.eventdly[E_REPRO] * franf(), e->x, e->y, e->systemname);
277:
278: /* report the disaster if we can */
279: if (!damaged(SSRADIO))
280: {
281: printf("\nUhura: We've lost contact with starsystem %s\n",
282: Systemname[e->systemname]);
283: printf(" in quadrant %d,%d.\n",
284: e->x, e->y);
285: }
286: else
287: e->evcode |= E_HIDDEN;
288: break;
289:
290: case E_REPRO: /* Klingon reproduces */
291: /* see if distress call is still active */
292: q = &Quad[e->x][e->y];
293: if (q->klings <= 0)
294: {
295: unschedule(e);
296: q->qsystemname = e->systemname;
297: break;
298: }
299: xresched(e, E_REPRO, 1);
300: /* reproduce one Klingon */
301: ix = e->x;
302: iy = e->y;
303: if (Now.klings == 127)
304: break; /* full right now */
305: if (q->klings >= MAXKLQUAD)
306: {
307: /* this quadrant not ok, pick an adjacent one */
308: for (i = ix - 1; i <= ix + 1; i++)
309: {
310: if (i < 0 || i >= NQUADS)
311: continue;
312: for (j = iy - 1; j <= iy + 1; j++)
313: {
314: if (j < 0 || j >= NQUADS)
315: continue;
316: q = &Quad[i][j];
317: /* check for this quad ok (not full & no snova) */
318: if (q->klings >= MAXKLQUAD || q->stars < 0)
319: continue;
320: break;
321: }
322: if (j <= iy + 1)
323: break;
324: }
325: if (j > iy + 1)
326: /* cannot create another yet */
327: break;
328: ix = i;
329: iy = j;
330: }
331: /* deliver the child */
332: q->klings++;
333: Now.klings++;
334: if (ix == Ship.quadx && iy == Ship.quady)
335: {
336: /* we must position Klingon */
337: sector(&ix, &iy);
338: Sect[ix][iy] = KLINGON;
339: k = &Etc.klingon[Etc.nkling++];
340: k->x = ix;
341: k->y = iy;
342: k->power = Param.klingpwr;
343: k->srndreq = 0;
344: compkldist(Etc.klingon[0].dist == Etc.klingon[0].avgdist ? 0 : 1);
345: }
346:
347: /* recompute time left */
348: Now.time = Now.resource / Now.klings;
349: break;
350:
351: case E_SNAP: /* take a snapshot of the galaxy */
352: xresched(e, E_SNAP, 1);
353: i = (int) Etc.snapshot;
354: i = bmove(Quad, i, sizeof (Quad));
355: i = bmove(Event, i, sizeof (Event));
356: i = bmove(Now, i, sizeof (Now));
357: Game.snap = 1;
358: break;
359:
360: case E_ATTACK: /* Klingons attack during rest period */
361: if (!Move.resting)
362: {
363: unschedule(e);
364: break;
365: }
366: attack(1);
367: reschedule(e, 0.5);
368: break;
369:
370: case E_FIXDV:
371: i = e->systemname;
372: unschedule(e);
373:
374: /* de-damage the device */
375: printf("%s reports repair work on the %s finished.\n",
376: Device[i].person, Device[i].name);
377:
378: /* handle special processing upon fix */
379: switch (i)
380: {
381:
382: case LIFESUP:
383: Ship.reserves = Param.reserves;
384: break;
385:
386: case SINS:
387: if (Ship.cond == DOCKED)
388: break;
389: printf("Spock has tried to recalibrate your Space Internal Navigation System,\n");
390: printf(" but he has no standard base to calibrate to. Suggest you get\n");
391: printf(" to a starbase immediately so that you can properly recalibrate.\n");
392: Ship.sinsbad = 1;
393: break;
394:
395: case SSRADIO:
396: restcancel = dumpssradio();
397: break;
398: }
399: break;
400:
401: default:
402: break;
403: }
404:
405: if (restcancel && Move.resting && getynpar("Spock: Shall we cancel our rest period"))
406: Move.time = xdate - idate;
407:
408: }
409:
410: /* unschedule an attack during a rest period */
411: if (e = Now.eventptr[E_ATTACK])
412: unschedule(e);
413:
414: if (!warp)
415: {
416: /* eat up energy if cloaked */
417: if (Ship.cloaked)
418: Ship.energy -= Param.cloakenergy * Move.time;
419:
420: /* regenerate resources */
421: rtime = 1.0 - exp(-Param.regenfac * Move.time);
422: Ship.shield += (Param.shield - Ship.shield) * rtime;
423: Ship.energy += (Param.energy - Ship.energy) * rtime;
424:
425: /* decrement life support reserves */
426: if (damaged(LIFESUP) && Ship.cond != DOCKED)
427: Ship.reserves -= Move.time;
428: }
429: return (0);
430: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.