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