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