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