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: }

Defined functions

events defined in line 22; used 2 times

Defined variables

sccsid defined in line 8; never used
Last modified: 1985-05-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2946
Valid CSS Valid XHTML 1.0 Strict