|
|
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.