Annotation of 43BSDReno/games/trek/phaser.c, revision 1.1

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[] = "@(#)phaser.c   5.4 (Berkeley) 6/1/90";
        !            22: #endif /* not lint */
        !            23: 
        !            24: # include      "trek.h"
        !            25: # include      "getpar.h"
        !            26: 
        !            27: /* factors for phaser hits; see description below */
        !            28: 
        !            29: # define       ALPHA           3.0             /* spread */
        !            30: # define       BETA            3.0             /* franf() */
        !            31: # define       GAMMA           0.30            /* cos(angle) */
        !            32: # define       EPSILON         150.0           /* dist ** 2 */
        !            33: # define       OMEGA           10.596          /* overall scaling factor */
        !            34: 
        !            35: /* OMEGA ~= 100 * (ALPHA + 1) * (BETA + 1) / (EPSILON + 1) */
        !            36: 
        !            37: /*
        !            38: **  Phaser Control
        !            39: **
        !            40: **     There are up to NBANKS phaser banks which may be fired
        !            41: **     simultaneously.  There are two modes, "manual" and
        !            42: **     "automatic".  In manual mode, you specify exactly which
        !            43: **     direction you want each bank to be aimed, the number
        !            44: **     of units to fire, and the spread angle.  In automatic
        !            45: **     mode, you give only the total number of units to fire.
        !            46: **
        !            47: **     The spread is specified as a number between zero and
        !            48: **     one, with zero being minimum spread and one being maximum
        !            49: **     spread.  You  will normally want zero spread, unless your
        !            50: **     short range scanners are out, in which case you probably
        !            51: **     don't know exactly where the Klingons are.  In that case,
        !            52: **     you really don't have any choice except to specify a
        !            53: **     fairly large spread.
        !            54: **
        !            55: **     Phasers spread slightly, even if you specify zero spread.
        !            56: **
        !            57: **     Uses trace flag 30
        !            58: */
        !            59: 
        !            60: struct cvntab  Matab[] =
        !            61: {
        !            62:        "m",            "anual",                (int (*)())1,           0,
        !            63:        "a",            "utomatic",             0,              0,
        !            64:        0
        !            65: };
        !            66: 
        !            67: struct banks
        !            68: {
        !            69:        int     units;
        !            70:        double  angle;
        !            71:        double  spread;
        !            72: };
        !            73: 
        !            74: 
        !            75: 
        !            76: phaser()
        !            77: {
        !            78:        register int            i;
        !            79:        int                     j;
        !            80:        register struct kling   *k;
        !            81:        double                  dx, dy;
        !            82:        double                  anglefactor, distfactor;
        !            83:        register struct banks   *b;
        !            84:        int                     manual, flag, extra;
        !            85:        int                     hit;
        !            86:        double                  tot;
        !            87:        int                     n;
        !            88:        int                     hitreqd[NBANKS];
        !            89:        struct banks            bank[NBANKS];
        !            90:        struct cvntab           *ptr;
        !            91: 
        !            92:        if (Ship.cond == DOCKED)
        !            93:                return(printf("Phasers cannot fire through starbase shields\n"));
        !            94:        if (damaged(PHASER))
        !            95:                return (out(PHASER));
        !            96:        if (Ship.shldup)
        !            97:                return (printf("Sulu: Captain, we cannot fire through shields.\n"));
        !            98:        if (Ship.cloaked)
        !            99:        {
        !           100:                printf("Sulu: Captain, surely you must realize that we cannot fire\n");
        !           101:                printf("  phasers with the cloaking device up.\n");
        !           102:                return;
        !           103:        }
        !           104: 
        !           105:        /* decide if we want manual or automatic mode */
        !           106:        manual = 0;
        !           107:        if (testnl())
        !           108:        {
        !           109:                if (damaged(COMPUTER))
        !           110:                {
        !           111:                        printf(Device[COMPUTER].name);
        !           112:                        manual++;
        !           113:                }
        !           114:                else
        !           115:                        if (damaged(SRSCAN))
        !           116:                        {
        !           117:                                printf(Device[SRSCAN].name);
        !           118:                                manual++;
        !           119:                        }
        !           120:                if (manual)
        !           121:                        printf(" damaged, manual mode selected\n");
        !           122:        }
        !           123: 
        !           124:        if (!manual)
        !           125:        {
        !           126:                ptr = getcodpar("Manual or automatic", Matab);
        !           127:                manual = (int) ptr->value;
        !           128:        }
        !           129:        if (!manual && damaged(COMPUTER))
        !           130:        {
        !           131:                printf("Computer damaged, manual selected\n");
        !           132:                skiptonl(0);
        !           133:                manual++;
        !           134:        }
        !           135: 
        !           136:        /* initialize the bank[] array */
        !           137:        flag = 1;
        !           138:        for (i = 0; i < NBANKS; i++)
        !           139:                bank[i].units = 0;
        !           140:        if (manual)
        !           141:        {
        !           142:                /* collect manual mode statistics */
        !           143:                while (flag)
        !           144:                {
        !           145:                        printf("%d units available\n", Ship.energy);
        !           146:                        extra = 0;
        !           147:                        flag = 0;
        !           148:                        for (i = 0; i < NBANKS; i++)
        !           149:                        {
        !           150:                                b = &bank[i];
        !           151:                                printf("\nBank %d:\n", i);
        !           152:                                hit = getintpar("units");
        !           153:                                if (hit < 0)
        !           154:                                        return;
        !           155:                                if (hit == 0)
        !           156:                                        break;
        !           157:                                extra += hit;
        !           158:                                if (extra > Ship.energy)
        !           159:                                {
        !           160:                                        printf("available energy exceeded.  ");
        !           161:                                        skiptonl(0);
        !           162:                                        flag++;
        !           163:                                        break;
        !           164:                                }
        !           165:                                b->units = hit;
        !           166:                                hit = getintpar("course");
        !           167:                                if (hit < 0 || hit > 360)
        !           168:                                        return;
        !           169:                                b->angle = hit * 0.0174532925;
        !           170:                                b->spread = getfltpar("spread");
        !           171:                                if (b->spread < 0 || b->spread > 1)
        !           172:                                        return;
        !           173:                        }
        !           174:                        Ship.energy -= extra;
        !           175:                }
        !           176:                extra = 0;
        !           177:        }
        !           178:        else
        !           179:        {
        !           180:                /* automatic distribution of power */
        !           181:                if (Etc.nkling <= 0)
        !           182:                        return (printf("Sulu: But there are no Klingons in this quadrant\n"));
        !           183:                printf("Phasers locked on target.  ");
        !           184:                while (flag)
        !           185:                {
        !           186:                        printf("%d units available\n", Ship.energy);
        !           187:                        hit = getintpar("Units to fire");
        !           188:                        if (hit <= 0)
        !           189:                                return;
        !           190:                        if (hit > Ship.energy)
        !           191:                        {
        !           192:                                printf("available energy exceeded.  ");
        !           193:                                skiptonl(0);
        !           194:                                continue;
        !           195:                        }
        !           196:                        flag = 0;
        !           197:                        Ship.energy -= hit;
        !           198:                        extra = hit;
        !           199:                        n = Etc.nkling;
        !           200:                        if (n > NBANKS)
        !           201:                                n = NBANKS;
        !           202:                        tot = n * (n + 1) / 2;
        !           203:                        for (i = 0; i < n; i++)
        !           204:                        {
        !           205:                                k = &Etc.klingon[i];
        !           206:                                b = &bank[i];
        !           207:                                distfactor = k->dist;
        !           208:                                anglefactor = ALPHA * BETA * OMEGA / (distfactor * distfactor + EPSILON);
        !           209:                                anglefactor *= GAMMA;
        !           210:                                distfactor = k->power;
        !           211:                                distfactor /= anglefactor;
        !           212:                                hitreqd[i] = distfactor + 0.5;
        !           213:                                dx = Ship.sectx - k->x;
        !           214:                                dy = k->y - Ship.secty;
        !           215:                                b->angle = atan2(dy, dx);
        !           216:                                b->spread = 0.0;
        !           217:                                b->units = ((n - i) / tot) * extra;
        !           218: #                              ifdef xTRACE
        !           219:                                if (Trace)
        !           220:                                {
        !           221:                                        printf("b%d hr%d u%d df%.2f af%.2f\n",
        !           222:                                                i, hitreqd[i], b->units,
        !           223:                                                distfactor, anglefactor);
        !           224:                                }
        !           225: #                              endif
        !           226:                                extra -= b->units;
        !           227:                                hit = b->units - hitreqd[i];
        !           228:                                if (hit > 0)
        !           229:                                {
        !           230:                                        extra += hit;
        !           231:                                        b->units -= hit;
        !           232:                                }
        !           233:                        }
        !           234: 
        !           235:                        /* give out any extra energy we might have around */
        !           236:                        if (extra > 0)
        !           237:                        {
        !           238:                                for (i = 0; i < n; i++)
        !           239:                                {
        !           240:                                        b = &bank[i];
        !           241:                                        hit = hitreqd[i] - b->units;
        !           242:                                        if (hit <= 0)
        !           243:                                                continue;
        !           244:                                        if (hit >= extra)
        !           245:                                        {
        !           246:                                                b->units += extra;
        !           247:                                                extra = 0;
        !           248:                                                break;
        !           249:                                        }
        !           250:                                        b->units = hitreqd[i];
        !           251:                                        extra -= hit;
        !           252:                                }
        !           253:                                if (extra > 0)
        !           254:                                        printf("%d units overkill\n", extra);
        !           255:                        }
        !           256:                }
        !           257:        }
        !           258: 
        !           259: #      ifdef xTRACE
        !           260:        if (Trace)
        !           261:        {
        !           262:                for (i = 0; i < NBANKS; i++)
        !           263:                {
        !           264:                        b = &bank[i];
        !           265:                        printf("b%d u%d", i, b->units);
        !           266:                        if (b->units > 0)
        !           267:                                printf(" a%.2f s%.2f\n", b->angle, b->spread);
        !           268:                        else
        !           269:                                printf("\n");
        !           270:                }
        !           271:        }
        !           272: #      endif
        !           273: 
        !           274:        /* actually fire the shots */
        !           275:        Move.free = 0;
        !           276:        for (i = 0; i < NBANKS; i++)
        !           277:        {
        !           278:                b = &bank[i];
        !           279:                if (b->units <= 0)
        !           280:                {
        !           281:                        continue;
        !           282:                }
        !           283:                printf("\nPhaser bank %d fires:\n", i);
        !           284:                n = Etc.nkling;
        !           285:                k = Etc.klingon;
        !           286:                for (j = 0; j < n; j++)
        !           287:                {
        !           288:                        if (b->units <= 0)
        !           289:                                break;
        !           290:                        /*
        !           291:                        ** The formula for hit is as follows:
        !           292:                        **
        !           293:                        **  zap = OMEGA * [(sigma + ALPHA) * (rho + BETA)]
        !           294:                        **      / (dist ** 2 + EPSILON)]
        !           295:                        **      * [cos(delta * sigma) + GAMMA]
        !           296:                        **      * hit
        !           297:                        **
        !           298:                        ** where sigma is the spread factor,
        !           299:                        ** rho is a random number (0 -> 1),
        !           300:                        ** GAMMA is a crud factor for angle (essentially
        !           301:                        **      cruds up the spread factor),
        !           302:                        ** delta is the difference in radians between the
        !           303:                        **      angle you are shooting at and the actual
        !           304:                        **      angle of the klingon,
        !           305:                        ** ALPHA scales down the significance of sigma,
        !           306:                        ** BETA scales down the significance of rho,
        !           307:                        ** OMEGA is the magic number which makes everything
        !           308:                        **      up to "* hit" between zero and one,
        !           309:                        ** dist is the distance to the klingon
        !           310:                        ** hit is the number of units in the bank, and
        !           311:                        ** zap is the amount of the actual hit.
        !           312:                        **
        !           313:                        ** Everything up through dist squared should maximize
        !           314:                        ** at 1.0, so that the distance factor is never
        !           315:                        ** greater than one.  Conveniently, cos() is
        !           316:                        ** never greater than one, but the same restric-
        !           317:                        ** tion applies.
        !           318:                        */
        !           319:                        distfactor = BETA + franf();
        !           320:                        distfactor *= ALPHA + b->spread;
        !           321:                        distfactor *= OMEGA;
        !           322:                        anglefactor = k->dist;
        !           323:                        distfactor /= anglefactor * anglefactor + EPSILON;
        !           324:                        distfactor *= b->units;
        !           325:                        dx = Ship.sectx - k->x;
        !           326:                        dy = k->y - Ship.secty;
        !           327:                        anglefactor = atan2(dy, dx) - b->angle;
        !           328:                        anglefactor = cos((anglefactor * b->spread) + GAMMA);
        !           329:                        if (anglefactor < 0.0)
        !           330:                        {
        !           331:                                k++;
        !           332:                                continue;
        !           333:                        }
        !           334:                        hit = anglefactor * distfactor + 0.5;
        !           335:                        k->power -= hit;
        !           336:                        printf("%d unit hit on Klingon", hit);
        !           337:                        if (!damaged(SRSCAN))
        !           338:                                printf(" at %d,%d", k->x, k->y);
        !           339:                        printf("\n");
        !           340:                        b->units -= hit;
        !           341:                        if (k->power <= 0)
        !           342:                        {
        !           343:                                killk(k->x, k->y);
        !           344:                                continue;
        !           345:                        }
        !           346:                        k++;
        !           347:                }
        !           348:        }
        !           349: 
        !           350:        /* compute overkill */
        !           351:        for (i = 0; i < NBANKS; i++)
        !           352:                extra += bank[i].units;
        !           353:        if (extra > 0)
        !           354:                printf("\n%d units expended on empty space\n", extra);
        !           355: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.