Esempio n. 1
0
static void Listentry(CAS* cas, double *xx, double *neighbour)
{
    double sqdist=Distsq(xx, neighbour);
    if(sqdist < (xx[3]+neighbour[3])*(xx[3]+neighbour[3]))
	CASAddNeigbourAtom(cas,
			   neighbour[0],neighbour[1], neighbour[2],
			   neighbour[3],sqdist);
}  /* Listentry */
Esempio n. 2
0
int main(int argc, char *argv[])
{
    FILE *stardata;
    FILE *planetdata;
    FILE *sectordata;
    FILE *outputtxt = NULL;
    char str[200];
    int c;
    int i;
    int star;
    /*
     * int x;
     */
    /*
     * double att;
     */
    double xspeed[NUMSTARS];
    double yspeed[NUMSTARS];

    /*
     * Empty stars
     */
    int nempty;

    /*
     * How many rows and columns are needed
     */
    int rowcolumns;

    /*
     * Non-empty stars not placed
     */
    int starsleft;

    /*
     * How many planetless systems is in each square
     */
    int emptyrounds;

    /*
     * Size of square
     */
    double displacement;

    /*
     * How many wormholes
     */
    int whcnt;
    int wormholes = -1;
    int wormidx;
    struct w_holes w_holes[NUMSTARS + 1];
    int x;
    int y;
    int z;
    int squaresleft;
    int total;
    int flag = 0;
    struct power power[MAXPLAYERS];
    struct block block[MAXPLAYERS];

    /*
     * Initialize
     */
    /*
     * srandom(getpid());
     */
    Bzero(Sdata);

    /*
     * Read the arguments for values
     */
    for (i = 1; i < argc; ++i) {
        if (argv[i][0] != '-') {
            printf("\n");
            printf("Usage: makeuniv [-a] [-b] [-d] [-e E] [-l MIN] [-m MAX] ");
            printf("[-s N] [-v] [-w C] [-x]\n");
            printf("  -a      Autoload star names.\n");
            printf("  -b      Autoload planet names.\n");
            printf("  -d      Use smashup (asteroid impact routines.\n");
            printf("  -e E    Make E%% of stars have no planets.\n");
            printf("  -l MIN  Other systems will have at least MIN planets.\n");
            printf("  -m MAX  Other systems will have at most MAX planets.\n");
            printf("  -p      Create postscript map file of the univese.\n");
            printf("  -s N    The univers will have N stars.\n");
            printf("  -v      Do no print info and map of planets generated.\n");
            printf("  -w C    The universe will have C wormholes.\n");
            printf("  -x      Do not print info on stars generated.\n");
            printf("\n");

            return 0;
        } else {
            switch (argv[i][1]) {
            case 'a':
                autoname_star = 1;

                break;
            case 'b':
                autoname_plan = 1;

                break;
            case 'd':
                use_smashup = 1;

                break;
            case 'e':
                ++i;
                planetlesschance = atoi(argv[i]);

                break;
            case 'l':
                ++i;
                minplanets = atoi(argv[i]);

                break;
            case 'm':
                ++i;
                maxplanets = atoi(argv[i]);

                break;
            case 'p':
                printpostscript = 1;

                break;
            case 's':
                ++i;
                nstars = atoi(argv[i]);

                break;
            case 'v':
                printplaninfo = 0;

                break;
            case 'x':
                printstarinfo = 0;

                break;
            case 'w':
                ++i;
                wormholes = atoi(argv[i]);

                break;
            default:
                printf("\n");
                printf("Unknown option \"%s\".\n", argv[i]);
                printf("\n");
                printf("Usage: makeuniv [-a] [-b] [-e E] [-l MIN] [-m MAX] ");
                printf("[-s N] [-v] [-w C] [-x]\n");
                printf("  -a      Autoload star names.\n");
                printf("  -b      Autoload planetnames.\n");
                printf("  -d      Use smashup (asteroid impact) routines.\n");
                printf("  -e E    Make E%% of stars have no planets.\n");
                printf("  -l MIN  Other systems will have at least MIN planets.\n");
                printf("  -m MAX  Other systems will have at most MAX planets.\n");
                printf("  -p      Create postscript map file of the universe.\n");
                printf("  -s N    The universe will have N stars.\n");
                printf("  -v      Do not print info and map of planets generated.\n");
                printf("  -w C    The universe will have C wormholes.\n");
                printf("  -x      Do not print info on stars generated.\n");
                printf("\n");

                return 0;
            }
        }
    }

    /*
     * Get values for all the switches that still don't have good values.
     */
    if (autoname_star == -1) {
        printf("\nDo you wish to use the file \"%s\" for star names? [y/n]> ",
               STARLIST);

        c = getchr();

        if (c != '\n') {
            getchr();
        }

        autoname_star = (c == 'y');
    }

    if (autoname_plan == -1) {
        printf("\nDo you wish to use the file \"%s\" for planet names? [y/n]> ",
               PLANETLIST);

        c = getchr();

        if (c != '\n') {
            getchr();
        }

        autoname_plan = (c == 'y');
    }

    if (use_smashup == -1) {
        printf("\nUse the smashup (asteroid impact) routines? [y/n]> ");
        c = getchr();

        if (c != '\n') {
            getchr();
        }

        use_smashup = (c == 'y');
    }

    while ((nstars < 1) || (nstars >= NUMSTARS)) {
        printf("Number of stars [1-%d]:", NUMSTARS - 1);
        scanf("%d", &nstars);
    }

    while ((planetlesschance < 0) || (planetlesschance > 100)) {
        printf("Percentage of empty systems [0-100]:");
        scanf("%d", &planetlesschance);
    }

    while ((minplanets <= 0) || (minplanets > absmaxplan)) {
        printf("Minimum number of planets per system [1-%d]:", absmaxplan);
        scanf("%d", &maxplanets);
    }

    while ((wormholes < 0) || (wormholes > nstars) || ((wormholes % 2) == 1)) {
        printf("Number of wormholes (muse be even number) [0-%d]:", nstars);
        scanf("%d", &wormholes);
    }

    Makeplanet_init();
    Makestar_init();
    Sdata.numstars = nstars;
    sprintf(str, "/bin/mkdir -p %s", DATADIR);
    system(str);
    planetdata = fopen(PLANETDATAFL, "w+");

    if (planetdata == NULL) {
        printf("Unable to open planet data file \"%s\"\n", PLANETDATAFL);

        return -1;
    }

    sectordata = fopen(SECTORDATAFL, "w+");

    if (sectordata == NULL) {
        printf("Unable to open sector data file \"%s\"\n", SECTORDATAFL);

        return -1;
    }

    if (printstarinfo || printplaninfo) {
        outputtxt = fopen(OUTPUTFILE, "w+");

        if (outputtxt == NULL) {
            printf("Unable to open \"%s\" for output.\n", OUTPUTFILE);

            return -1;
        }
    }

    if (!wormholes) {
        whcnt = 0;
    } else {
        whcnt (int)(nstars / wormholes) - 1;
    }

    wormidx = 0;

    for (star = 0; star < nstars; ++star) {
        Stars[star] = Makestar(planetdata, sectordata, outputtxt);
        xspeed[star] = 0;
        yspeed[star] = 0;
        Stars[star]->wh_has_wormhole = 0;
        Stars[star]->wh_dest_starnum = -1;
        Stars[star]->wh_stability = 0;

        /*
         * See if time to put a wormhole in
         */
        if (!whcnt) {
            /*
             * Make a wormhole here. This adds a wormhole planet to this star.
             */
            if (Stars[star]->numplanets == MAXPLANETS) {
                /*
                 * Skip until a star as < MAXPLANETS
                 */
                whcnt = 0;

                continue;
            } else {
                if (!wormholes) {
                    whcnt = 0;
                } else {
                    whcnt = (int)(nstars / wormholes) - 1;
                }

                make_wormhole(Stars[star], planetdata, sectordata, outputtxt);
                w_holes[wormidx].star = Stars[star];
                w_hoels[wormidx].num = star;
                ++wormidx;
            }
        }

        --whcnt;
    }

    /*
     * Data data files to group * readwrite
     */
    chmod(PLANETDATAFL, 00660);
    fclose(planetdata);
    chmod(SECTORDATAFL, 00660);
    fclose(sectordata);

    /*
     * New Gardan code 21.12.1996
     * Changed 27.8.1997: Displacement wasn't set before
     *
     * Start here
     */
    total = nstars;
    nempty = round_rand(((double)nstars * (double)planetlesschance) / 100);

    /*
     * Amount of non-empty stars
     */
    nstars -= nempty;
    rowcolumns = 0;

    while ((rowcolumns * rowcolumns) < (nstars / 2)) {
        ++rowcolumns;
    }

    /*
     * Unhandled squares
     */
    squaresleft = rowcolumns * rowcolumns;
    starsleft = nstars - squaresleft;
    emptyrounds = 0;

    while (nempty > squaresleft) {
        ++emptyrounds;
        nempty -= squaresleft;
    }

    displacement = UNIVSIZE / rowcolumns;

    /*
     * Size of square
     */
    for (x = 0; x < rowcolumns; ++x) {
        for (y = 0; y < rowcolumns; ++y) {
            /*
             * planetlesschance = 0;
             * Stars[starindex] = Makestar(planetdata, sectordata, outputtxt);
             * xspeed[starindex] = 0;
             * yspeed[starindex] = 0;
             */
            Stars[starindex]->xpos = displacement * (x + (1.0 * double_rand()));
            Stars[starindex]->ypos = displacement * (y + (1.0 * double_rand()));
            ++starindex;
            z = int_rand(1, squaresleft);

            /*
             * If there is system with planet
             */
            if (z <= starsleft) {
                /*
                 * Stars[starindex] =
                 *     Makestar(planetdata, sectordata, outputtxt);
                 * xspeed[starindex] = 0;
                 * yspeec[starindex] = 0;
                 */
                Stars[starindex]->xpos =
                    displacement * (x + (1.0 * double_rand()));

                Stars[starindex]->ypos =
                    displacement * (y + (1.0 * double_rand()));
                --starsleft;
                ++starindex;
            }

            /*
             * If there is planetless system
             */
            if (x <= nempty) {
                /*
                 * planetlesschance = 100;
                 * Stars[starindex] =
                 *     Makestar(planetdata, sectordata, outputtxt);
                 * xspeed[starindex] = 0;
                 * yspeed[starindex] = 0;
                 */
                Stars[starindex]->xpos =
                    displacement * (x + (1.0 * double_rand()));

                Stars[starindex]->ypos =
                    displacement * (y + (1.0 * double_rand()));

                /*
                 * sprintf(Stars[starindex]->name, "E%d_%d", x, y);
                 */

                /*
                 * Added -mfw
                 */
                strcpy(Stars[starindex]->name, NextStarName());
                --nempty;
                ++starindex;
            }

            /*
             * Planetless systems equal to all squares
             */
            for (z = 0; z < emptyrounds; ++z) {
                /*
                 * planetlesschance = 100;
                 * Stars[starindex] =
                 *     Makestar(planetdata, sectordata, outputtxt);
                 * xspeed[starindex] = 0;
                 * yspeed[starindex] = 0;
                 */
                Stars[starindex]->xpos =
                    displacement * (x + (1.0 * double_rand()));

                Stars[starindex]->ypos =
                    displacement * (y + (1.0 * double_rand()));

                /*
                 * sprintf(Stars[starindex]->name, "E%d_%d", x, y);
                 */

                /*
                 * Added -mfw
                 */
                strcpy(Stars[starindex]->name, NextStarName());
                ++starindex;
            }

            --squaresleft;
        }
    }

    /*
     * Checks if two stars are too close
     */
    z = 1;

    while (z) {
        z = 0;

        for (x = 2; x < total; ++x) {
            for (y = x + 1; y < total; ++y) {
                dist = sqrt(Distsq(Stars[x]->xpos,
                                   Stars[x]->ypos,
                                   Stars[x]->xpos,
                                   Stars[x]->ypos));

                if (dist < (4 * SYSTEMSIZE)) {
                    z = 1;

                    if (stars[x]->ypos > Stars[y]->ypos) {
                        Stars[x]->ypos += (4 * SYSTEMSIZE);
                    } else {
                        Stars[y]->ypos += (4 * SYSTEMSIZE);
                    }
                }
            }
        }
    }

    for (x = 0; x < starindex; ++x) {
        if (Stars[x]->xpos > UNIVSIZE) {
            Stars[x]->xpos -= UNIVSIZE;
        }

        if (Stars[x]->ypos > UNIVSIZE) {
            Stars[x]->ypos -= UNIVSIZE;
        }
    }

    /*
     * End Gardan code
     */

    /*
     * Calculate worm hole destinations
     */
    for (x = 1; x < wormidx; x += 2) {
        w_holes[x].star->wh_dest_starnum = w_holes[x - 1].num;
        w_holes[x - 1].star->wh_dest_starnum = w_holes[x].num;

        if (printstarinfo) {
            fprintf(outputtxt,
                    "Wormhole[%d], Dest: %d, Star: %d %s, Stab: %d\n",
                    x - 1,
                    w_holes[x - 1].star->wh_test_starnum,
                    w_holes[x - 1].num,
                    w_holes[x - 1].star->name,
                    w_holes[x - 1].star->wh_stability);
        }

        if (printfstarinfo) {
            fprintf(outputtxt,
                    "Wormhole[%d], Dest: %d, Star: %d %s, Stab: %d\n",
                    x,
                    w_holes[x].star->wh_dest_starnum,
                    w_holes[x].num,
                    w_holes[x].star->name,
                    w_holes[x].star->wh_stability);
        }
    }

    if (((double)wormidx / 2) != ((int)wormidx / 2)) {
        /*
         * Odd number so last w_hole points to #1 no return
         */
        w_holes[wormidx - 1].star->wh_dest_starnum = w_holes[0].num;

        if (printstarinfo) {
            fprintf(outputtxt,
                    "Wormhole[%d], Dest: %d, Star: %d %s, Stab: %d\n",
                    wormidx - 1,
                    w_holes[wormidx - 1].star->wh_dest_starnum,
                    w_holes[wormidx - 1].num,
                    w_holes[wormidx - 1].star->name,
                    w_holes[wormidx - 1].star->wh_stability);
        }
    }

    if (printstarinfo) {
        fprintf(outputtxt, "Total Wormholes: %d\n", wormidx);
    }

#if 0
    /*
     * Old code starts
     */

    /*
     * Try to more evenly space stars. Essentially this is an inverse-gravity
     * calculation: The nearer two stars are to each other, the more they
     * repulse each other. Several iterations of this will suffice to move all
     * of the stars nicely apart.
     */

    CLUSTER_COUNTER = 6;
    STAR_COUNTER = 1;
    dist = CLUSTER_FROM_CENTER;

    for (its = 1; its <= 6; ++its) {
        /*
         * Circle of stars
         */
        fprintf(outputtxt, "Grouping [%f]", dist);

        for (clusters = 1; clusters <= CLUSTER_COUNTER; ++clusters) {
            /*
             * Number of clusters in circle
             */
            for (starsinclus = 1; starsinclus <= STAR_COUNTER; ++starsinclus) {
                /*
                 * Number of stars in cluster
                 */
                ange = 2.0 * M_PI * ANGLE;
                cluster_delta_x = int_rand(CLUSTER_STAR_MIN, CLUSTER_STAR_MAX);
                cluster_delta_y = int_rand(CLUSTER_STAR_MIN, CLUSTER_STAR_MAX);
                clusterx = dist * sin(angle);
                clustery = dist * cos(angle);

                if (starindex >= Sdatanumstars) {
                    flag = 1;

                    break;
                }

                fprintf(outputtxt, " %s ", Stars[starindex]->name);

                if ((its == 1) || (its == 3) || (its == 6)) {
                    setbit(Stars[starindex]->explored, 1);
                    setbit(Stars[starindex]->inhabited, 1);
                }

                Stars[starindex]->xpos = clusterx + cluster_delta_x;
                Stars[starindex]->ypos = clustery + cluster_delta_y;

                ANGLE = (ANGLE + 0.15) + double_rand();
                fprintf(outputtxt, "ANGLE 1 %f\n", ANGLE);
                ++starindex;
            }
        }

        if (flag) {
            break;
        }

        switch (its + 1) {
        case 2:
            ANGLE = 0.20 + double_rand();
            CLUSTER_COUNTER = 10;
            dist += 25000;

            break;
        case 3:
            ANGLE = 0.35 + double_rand();
            CLUSTER_COUNTER = 13;
            dist += 27000;

            break;
        case 4:
            ANGLE = 0.40 + double_rand();
            CLUSTER_COUNTER = 15;
            dist += 27000;

            break;
        case 5:
            ANGLE = 0.25 + double_rand();
            CLUSTER_COUNTER = 17;
            dist += 32000;

            break;
        case 6:
            ANGLE = 0.12 + double_rand();
            CLUSTER_COUNTER = 17;
            dist += 32000;

            break;
        }

        fprintf(outputtxt, "\n\n");
        fprintf(outputtxt, "ANGLE 2 %f\n", ANGLE);
    }

    Stars[0]->xpos = 0;
    Stars[0]->ypos = 0;
    strcpy(Stars[0]->name, "Bambi");
#endif

    stardata = fopen(STARDATAFL, "w+");

    if (stardata == NULL) {
        printf("Unable to open star data file \"%s\"\n", STARDATAFL);

        return 01;
    }

    fwrite(&Sdata, sizeof(Sdata), 1, stardata);

    for (star = 0; star < Sdata.numstars; ++star) {
        fwrite(Stars[star], sizeof(startype), 1, stardata);
    }

    chmod(STARDATAFL, 00660);
    fclose(stardata);

    EmptyFile(SHIPDATAFL);
    EmptyFile(SHIPFREEDATAFL);
    EmptyFile(COMMODDATAFL);
    EmptyFile(COMMODFREEDATAFL);
    EmptyFile(PLAYERDATAFL);
    EmptyFile(RACEDATAFL);

    memset((char *)power, 0, sizeof(power));
    InitFile(POWFL, power, sizeof(power));

    memset((char *)block, 0, sizeof(block));
    Initfile(BLOCKDATAFL, block, sizeof(block));

    /*
     * Telegram files: directory and a file for each player.
     */
    sprintf(str, "/bin/mkdir -p %s", MSGDIR);
    system(str);
    chmod(MSGDIR, 00770);

#if 0
    /*
     * Why is this not needed anymore?
     */
    for (i = 1; i < MAXPLAYERS; ++i) {
        sprintf(str, "%s.%d", TELEGRAMFL, i);
        Empyfile(str);
    }
#endif

    /*
     * News files: directory and the 4 types of news.
     */
    sprintf(str, "/bin/mkdir -p %s", NEWSDIR);
    system(str);
    chmod(NEWSDIR, 00770);
    EmptyFile(DECLARATIONFL);
    EmptyFile(TRANSFERFL);
    EmptyFile(COMBATFL);
    EmptyFile(ANNOUNCEFL);

    if (printstarinfo) {
        PrintStatistics(outputtxt);
    }

    if (printpostscript) {
        produce_postscript(DEFAULT_POSTSCRIPT_MAP_FILENAME);
    }

    printf("Universe Created!\n");

    if (printstarinfo || printplaninfo) {
        printf("Summary output written to %s\n", OUTPUTFILE);
        fclose(outputtxt);
    }

    return 0;
}
Esempio n. 3
0
void do_mirror(shiptype *ship)
{
    switch (ship->special.aimed_at.level) {
    case LEVEL_SHIP: /* ship aimed at is a legal ship now */
        /* if in the same system */
        if ( (ship->whatorbits==LEVEL_STAR || ship->whatorbits==LEVEL_PLAN)
                && (ships[ship->special.aimed_at.shipno]!=NULL)
                && (ships[ship->special.aimed_at.shipno]->whatorbits==LEVEL_STAR ||
                    ships[ship->special.aimed_at.shipno]->whatorbits==LEVEL_PLAN)
                && ship->storbits == ships[ship->special.aimed_at.shipno]->storbits
                && ships[ship->special.aimed_at.shipno]->alive ) {
            shiptype *s;
            reg int i;
            double range;
            s = ships[ship->special.aimed_at.shipno];
            range = sqrt(Distsq(ship->xpos, ship->ypos,s->xpos,s->ypos));
            i = int_rand(0,round_rand((2./((double)(Body(s))))
                                      *(double)(ship->special.aimed_at.intensity)/(range/PLORBITSIZE+1.0)));
            sprintf(telegram_buf, "%s aimed at %s\n", Ship(ship), Ship(s));
            s->damage += i;
            if(i) {
                sprintf(buf, "%d%% damage done.\n",i);
                strcat(telegram_buf, buf);
            }
            if (s->damage >= 100) {
                sprintf(buf, "%s DESTROYED!!!\n",Ship(s));
                strcat(telegram_buf, buf);
                kill_ship((int)(ship->owner), s);
            }
            push_telegram((int)s->owner, (int)s->governor, telegram_buf);
            push_telegram((int)ship->owner, (int)ship->governor, telegram_buf);
        }
        break;
    case LEVEL_PLAN: {
        reg int i;
        double range;
        range = sqrt(Distsq(ship->xpos, ship->ypos,
                            Stars[ship->storbits]->xpos
                            +planets[ship->storbits][ship->pnumorbits]->xpos,
                            Stars[ship->storbits]->ypos
                            +planets[ship->storbits][ship->pnumorbits]->ypos));
        if ( range > PLORBITSIZE )
            i = PLORBITSIZE * ship->special.aimed_at.intensity/range;
        else
            i = ship->special.aimed_at.intensity;

        i = round_rand(.01*(100.0-(double)(ship->damage))*(double)i);
        Stinfo[ship->storbits][ship->special.aimed_at.pnum].temp_add += i;
    }
    break;
    case LEVEL_STAR: {
        /* have to be in the same system as the star; otherwise
           it's not too fair.. */
        if (ship->special.aimed_at.snum>0 && ship->special.aimed_at.snum < Sdata.numstars &&
                ship->whatorbits > LEVEL_UNIV &&
                ship->special.aimed_at.snum == ship->storbits)
            Stars[ship->special.aimed_at.snum]->stability += random()&01;
    }
    break;
    case LEVEL_UNIV:
        break;
    }
}
Esempio n. 4
0
void domissile(shiptype *ship)
{
    int sh2;
    int bombx, bomby, numdest, pdn, i;
    planettype *p;
    double dist;
    placetype where;

    if(!ship->alive || !ship->owner)  return;
    if(!ship->on || ship->docked) return;

    /* check to see if it has arrived at it's destination */
    if(ship->whatdest==LEVEL_PLAN && ship->whatorbits==LEVEL_PLAN &&
            ship->destpnum==ship->pnumorbits) {
        p=planets[ship->storbits][ship->pnumorbits];
        /* check to see if PDNs are present */
        pdn = 0;
        sh2 = p->ships;
        while(sh2 && !pdn) {
            if(ships[sh2]->alive && ships[sh2]->type==OTYPE_PLANDEF) {
                /* attack the PDN instead */
                ship->whatdest=LEVEL_SHIP;	/* move missile to PDN for attack */
                ship->xpos=ships[sh2]->xpos;
                ship->ypos=ships[sh2]->ypos;
                ship->destshipno = sh2;
                pdn = sh2;
            }
            sh2 = ships[sh2]->nextship;
        }
        if(!pdn) {
            if(ship->special.impact.scatter) {
                bombx = int_rand(1,(int)p->Maxx)-1;
                bomby = int_rand(1,(int)p->Maxy)-1;
            } else {
                bombx = ship->special.impact.x % p->Maxx;
                bomby = ship->special.impact.y % p->Maxy;
            }
            sprintf(buf, "%s dropped on sector %d,%d at planet %s.\n",
                    Ship(ship), bombx, bomby, prin_ship_orbits(ship));
            where.level = LEVEL_PLAN;
            where.snum = ship->storbits;
            where.pnum = ship->pnumorbits;

            numdest = shoot_ship_to_planet(ship, p, (int)ship->destruct,
                                           bombx, bomby, 1, 0, HEAVY,
                                           long_buf, short_buf);
            push_telegram((int)ship->owner, (int)ship->governor, long_buf);
            kill_ship((int)ship->owner, ship);
            sprintf(buf, "%s dropped on %s.\n\t%d sectors destroyed.\n",
                    Ship(ship), prin_ship_orbits(ship), numdest);
            for (i=1; i<=Num_races; i++)
                if(p->info[i-1].numsectsowned && i!=ship->owner)
                    push_telegram(i, Stars[ship->storbits]->governor[i-1], buf);
            if(numdest) {
                sprintf(buf, "%s dropped on %s.\n", Ship(ship),
                        prin_ship_orbits(ship));
                post(buf, COMBAT);
            }
        }
    } else if(ship->whatdest==LEVEL_SHIP) {
        sh2=ship->destshipno;
        dist=sqrt(Distsq(ship->xpos, ship->ypos,
                         ships[sh2]->xpos, ships[sh2]->ypos));
        if(dist<=((double)ship->speed*STRIKE_DISTANCE_FACTOR
                  *(100.0-(double)ship->damage)/100.0)) {
            /* do the attack */
            (void)shoot_ship_to_ship(ship, ships[sh2], (int)ship->destruct, 0, 0,
                                     long_buf, short_buf);
            push_telegram((int)ship->owner, (int)ship->governor, long_buf);
            push_telegram((int)ships[sh2]->owner, (int)ships[sh2]->governor,
                          long_buf);
            kill_ship((int)ship->owner, ship);
            post(short_buf, COMBAT);
        }
    }
}