Пример #1
0
void addMonkeyResearchShipChangePosition(Ship *dockwith, Ship *ship,sdword dockindex)
{
    DockStaticPoint *dockwithstaticpoint;
    vector coneheadingInWorldCoordSysDockWith,DockWithHeading,destination,DockWithUp,destinationoffset;
    vector desiredHeading,desiredUp,conepositionInWorldCoordSysDockWith,tmpvec;
    real32 theta;
    matrix rotmatrix,tmpmat;

    ResearchShipStatics *resstatics;
    resstatics = (ResearchShipStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo;


    dbgAssertOrIgnore(dockwith != NULL);    //if we're calling this there should be another reserach station available somewhere

    if(ship->shiprace == R1)
    {
        dockwithstaticpoint = &dockwith->staticinfo->dockStaticInfo->dockstaticpoints[dockindex];

        matMultiplyMatByVec(&coneheadingInWorldCoordSysDockWith,&dockwith->rotinfo.coordsys,&dockwithstaticpoint->conenormal);
        matGetVectFromMatrixCol3(DockWithHeading,dockwith->rotinfo.coordsys)


        destinationoffset.x = coneheadingInWorldCoordSysDockWith.x*resstatics->R1final_dock_distance;
        destinationoffset.y = coneheadingInWorldCoordSysDockWith.y*resstatics->R1final_dock_distance;
        destinationoffset.z = coneheadingInWorldCoordSysDockWith.z*resstatics->R1final_dock_distance;
        vecAdd(destination,dockwith->posinfo.position, destinationoffset);
        if(((ResearchShipSpec *)ship->ShipSpecifics)->pie_plate_num == 0)
        {    //ship is docking on'a'top so add upwards factor
            matGetVectFromMatrixCol1(DockWithUp,dockwith->rotinfo.coordsys);
            vecScalarMultiply(DockWithUp,DockWithUp,resstatics->R1VerticalDockDistance);
            vecAdd(destination,destination,DockWithUp);
        }

        theta = DEG_TO_RAD(60);

        matMakeRotAboutX(&rotmatrix,(real32) cos(theta),(real32) sin(theta));
        matMultiplyMatByMat(&tmpmat, &dockwith->rotinfo.coordsys, &rotmatrix);

        //share a lot of these things...later...
        ship->rotinfo.coordsys = tmpmat;
        ship->posinfo.position = destination;
    }
    else
    {
        //r2 positioning
        dockwithstaticpoint = &dockwith->staticinfo->dockStaticInfo->dockstaticpoints[dockindex];

        matMultiplyMatByVec(&coneheadingInWorldCoordSysDockWith,&dockwith->rotinfo.coordsys,&dockwithstaticpoint->conenormal);
        matMultiplyMatByVec(&conepositionInWorldCoordSysDockWith,&dockwith->rotinfo.coordsys,&dockwithstaticpoint->position);
        vecAddTo(conepositionInWorldCoordSysDockWith,dockwith->posinfo.position);
        matGetVectFromMatrixCol3(DockWithHeading,dockwith->rotinfo.coordsys)

        destinationoffset.x = coneheadingInWorldCoordSysDockWith.x*resstatics->R2DockFinalDistance;
        destinationoffset.y = coneheadingInWorldCoordSysDockWith.y*resstatics->R2DockFinalDistance;
        destinationoffset.z = coneheadingInWorldCoordSysDockWith.z*resstatics->R2DockFinalDistance;
        vecAdd(destination,conepositionInWorldCoordSysDockWith, destinationoffset);

        desiredHeading = coneheadingInWorldCoordSysDockWith;
        if(dockindex == 0)
        {
            matGetVectFromMatrixCol3(desiredUp,dockwith->rotinfo.coordsys);
        }
        else if(dockindex == 1)
        {
            matGetVectFromMatrixCol3(desiredUp,dockwith->rotinfo.coordsys);
        }
        else if(dockindex == 2)
        {
            desiredUp = DockWithHeading;
        }
        else if(dockindex == 3)
        {
            theta = DEG_TO_RAD(60);
            matMakeRotAboutZ(&rotmatrix,(real32) cos(theta),(real32) sin(theta));
            matMultiplyMatByMat(&tmpmat, &dockwith->rotinfo.coordsys, &rotmatrix);
            matGetVectFromMatrixCol1(desiredUp,tmpmat);
        }
        else if(dockindex == 4)
        {
            destinationoffset.x = coneheadingInWorldCoordSysDockWith.x*100;
            destinationoffset.y = coneheadingInWorldCoordSysDockWith.y*100;
            destinationoffset.z = coneheadingInWorldCoordSysDockWith.z*100;
            vecAdd(destination,conepositionInWorldCoordSysDockWith, destinationoffset);

            matGetVectFromMatrixCol1(desiredUp,dockwith->rotinfo.coordsys);
            vecScalarMultiply(desiredHeading,desiredHeading,-1.0f);
        }
        else
        {
            dbgAssertOrIgnore(FALSE);       //shouldget here.
        }

        vecNormalize(&desiredUp);

        matPutVectIntoMatrixCol1(desiredUp,ship->rotinfo.coordsys);
        vecCrossProduct(tmpvec,desiredHeading,desiredUp);
        matPutVectIntoMatrixCol2(tmpvec,ship->rotinfo.coordsys);
        matPutVectIntoMatrixCol3(desiredHeading,ship->rotinfo.coordsys);

        ship->posinfo.position = destination;
        ship->posinfo.velocity.x = 0.0f;
        ship->posinfo.velocity.y = 0.0f;
        ship->posinfo.velocity.z = 0.0f;
    }
}
bool MinelayerCorvetteStaticMineDrop(Ship *ship,SpaceObjRotImpTarg *target)
{
    MinelayerCorvetteStatics *minelayercorvettestatics;
    MinelayerCorvetteSpec *spec = (MinelayerCorvetteSpec *)ship->ShipSpecifics;
    sdword flag;
    GunInfo *guninfo = ship->gunInfo;
    Gun *gun0,*gun1;
    real32 time;
    sdword maxmis;

    minelayercorvettestatics = (MinelayerCorvetteStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo;
    gun0 = ((Gun *) &(ship->gunInfo->guns[0]));

    maxmis = gun0->gunstatic->maxMissiles;

    if(ship->gunInfo->numGuns > 1)
    {    //ship has 2 guns (race 1)

        gun1 = ((Gun *) &(ship->gunInfo->guns[1]));

        if(gun0->numMissiles == 0 && gun1->numMissiles == 0)
            return FALSE;

        if((universe.totaltimeelapsed - gun1->lasttimefired) < minelayercorvettestatics->gunReFireTime
           && (universe.totaltimeelapsed - gun0->lasttimefired) < minelayercorvettestatics->gunReFireTime)
        {
            return(FALSE);
        }
        maxmis += gun1->gunstatic->maxMissiles;
    }
    else
    {
        if(gun0->numMissiles == 0)
            return FALSE;

        if((universe.totaltimeelapsed - gun0->lasttimefired) < minelayercorvettestatics->gunReFireTime)
            return(FALSE);
    }


    switch(spec->MiningStatus)
    {
    case FIRST_OFF:
        //////////////////////
        //speech event for forcedropped mines
        //event num: COMM_MLVette_ForceDrop
        //use battle chatter
        if(ship->playerowner->playerIndex == universe.curPlayerIndex)
        {
            if (battleCanChatterAtThisTime(BCE_COMM_MLVette_ForceDrop, ship))
            {
                battleChatterAttempt(SOUND_EVENT_DEFAULT, BCE_COMM_MLVette_ForceDrop, ship, SOUND_EVENT_DEFAULT);
            }
        }
        /////////////////////////

        spec->MiningStatus = FIRST_OFF2;
    case FIRST_OFF2:
        if(aitrackZeroRotationAnywhere(ship))
        {
            flag = 2;
        }

        if(aitrackZeroVelocity(ship))
        {
            if(flag == 2)
            {   //we're ready for next step
                MineFormationInfo *mineformationinfo;
                aitrackForceSteadyShip(ship);           //stop movement, stop rotation
                spec->MiningStatus = BEGIN_WALL_DROP_RIGHT;
                spec->MiningSideMax = 1;
                spec->MiningSideCount = 0;
                matGetVectFromMatrixCol1(spec->formation_up,ship->rotinfo.coordsys);
                matGetVectFromMatrixCol2(spec->formation_right,ship->rotinfo.coordsys);
                vecScalarMultiply(spec->formation_up, spec->formation_up, minelayercorvettestatics->MineSpacing);
                vecScalarMultiply(spec->formation_down, spec->formation_up, -1.0f);
                vecScalarMultiply(spec->formation_right,spec->formation_right,minelayercorvettestatics->MineSpacing);
                vecScalarMultiply(spec->formation_left,spec->formation_right,-1.0f);
                matGetVectFromMatrixCol3(spec->formation_heading,ship->rotinfo.coordsys);
                vecScalarMultiply(spec->formation_heading,spec->formation_heading,-minelayercorvettestatics->MineDropDistance);

                //Create Formation Entity Here

                mineformationinfo = memAlloc(sizeof(MineFormationInfo),"MineFormationInfo",NonVolatile);
                listAddNode(&universe.MineFormationList,&(mineformationinfo->FormLink),mineformationinfo);
                listInit(&mineformationinfo->MineList);
                mineformationinfo->playerowner = ship->playerowner;
                mineformationinfo->FULL = FALSE;
                mineformationinfo->wallstate = PULSE_START;
                mineformationinfo->effect = NULL;
                spec->mineforminfo = mineformationinfo;
                time = 29.0;
                spec->mineforminfo->waittime = time;     //set wait time for each pulse

                spec->formation_number_X = 0;
                spec->formation_number_Y = 0;

                vecAdd(spec->formation_position,ship->posinfo.position,spec->formation_heading);
                spec->mineaistate = MINE_DROP_FORMATION;
                MinelayerCorvetteFire(ship,target);
                spec->MineDropNumber = 1;
            }
        }
        break;
    case BEGIN_WALL_DROP_RIGHT:
        vecAddTo(spec->formation_position,spec->formation_right);
        spec->mineaistate = MINE_DROP_FORMATION;

        MinelayerCorvetteFire(ship,target);
        spec->MineDropNumber++;
        spec->formation_number_X++;
        spec->MiningSideCount++;
        if(spec->MiningSideCount == spec->MiningSideMax)
        {
            spec->MiningSideCount = 0;
            spec->MiningStatus = BEGIN_WALL_DROP_UP;
        }
        break;
    case BEGIN_WALL_DROP_UP:
        vecAddTo(spec->formation_position,spec->formation_up);
        spec->mineaistate = MINE_DROP_FORMATION;
        MinelayerCorvetteFire(ship,target);
        spec->MineDropNumber++;
        spec->formation_number_Y++;
        spec->MiningSideCount++;
        if(spec->MiningSideCount == spec->MiningSideMax)
        {
            spec->MiningSideMax++;
            spec->MiningSideCount = 0;
            spec->MiningStatus = BEGIN_WALL_DROP_LEFT;
        }
        break;
    case BEGIN_WALL_DROP_LEFT:
        vecAddTo(spec->formation_position,spec->formation_left);
        spec->mineaistate = MINE_DROP_FORMATION;
        MinelayerCorvetteFire(ship,target);
        spec->MineDropNumber++;
        spec->formation_number_X--;
        spec->MiningSideCount++;
        if(spec->MiningSideCount == spec->MiningSideMax)
        {
            spec->MiningSideCount = 0;
            spec->MiningStatus = BEGIN_WALL_DROP_DOWN;
        }
        break;
    case BEGIN_WALL_DROP_DOWN:
        vecAddTo(spec->formation_position,spec->formation_down);
        spec->mineaistate = MINE_DROP_FORMATION;
         MinelayerCorvetteFire(ship,target);
        spec->MineDropNumber++;
        spec->formation_number_Y--;
        spec->MiningSideCount++;
        if(spec->MiningSideCount == spec->MiningSideMax)
        {
            spec->MiningSideMax++;
            spec->MiningSideCount = 0;
            spec->MiningStatus = BEGIN_WALL_DROP_RIGHT;
        }
        break;
    case DONE_WAIT:
        spec->mineaistate = MINE_DROP_ATTACK;
        return TRUE;
        break;
    }
    if(spec->MineDropNumber == minelayercorvettestatics->NumMinesInSide*minelayercorvettestatics->NumMinesInSide)
    {
        if(spec->mineforminfo != NULL)
        {
            spec->mineforminfo->FULL = TRUE;
            spec->mineforminfo = NULL;
        }
        spec->mineaistate=MINE_DROP_ATTACK;
        spec->MiningStatus = DONE_WAIT;
        spec->MineDropNumber = 0;
        return(TRUE);                               //finished Wall
    }

    return(FALSE);
}
Пример #3
0
void ResearchShipHouseKeep(Ship *ship)
{
    ResearchShipSpec *spec = (ResearchShipSpec *)ship->ShipSpecifics;
    SelectCommand selection;
    vector up,destination,desiredheading,newup;
    vector univup = {0.0f,0.0f,1.0f};
    bool InParadeandMoving = FALSE;
    matrix rot_matrix,tmpmat,rotmat;
    real32 radangle;
    ResearchShipStatics *researchshipstatics;
    researchshipstatics = (ResearchShipStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo;

    if(bitTest(ship->specialFlags,SPECIAL_StopForResearchDocking))
    {
        vecScalarMultiply(ship->posinfo.velocity,ship->posinfo.velocity,0.94);
        vecScalarMultiply(ship->rotinfo.rotspeed,ship->rotinfo.rotspeed,0.94);
        bitSet(ship->dontapplyforceever,1);
        bitSet(ship->dontrotateever,1);
    }
    else
    {
        bitClear(ship->dontapplyforceever,1);
        bitClear(ship->dontrotateever,1);
    }

    if(ship->flags & SOF_Slaveable)
    {
        if(ship->slaveinfo->flags & SF_MASTER)
        {
            CommandToDo *command = getShipAndItsCommand(&universe.mainCommandLayer,ship);
            if(command != NULL)
            {
                //ship may be in parade...
                if(command->ordertype.order == COMMAND_MILITARY_PARADE)
                {
                    //ship is in parade
                    CommandToDo *ashipCom = getShipAndItsCommand(&universe.mainCommandLayer,command->militaryParade->aroundShip);
                    if(ashipCom != NULL)
                    {
                        //probably shouldn't be null regardless..should be equal to command..but ohwell
                        if(ashipCom->ordertype.order == COMMAND_MOVE ||
                           ashipCom->ordertype.order == COMMAND_ATTACK ||
                           ashipCom->ordertype.order == COMMAND_SPECIAL ||
                           ashipCom->ordertype.order == COMMAND_MP_HYPERSPACING)
                        {
                            InParadeandMoving = TRUE;
                            spec->rotate_state = ROTATE_WAIT;
                        }
                    }
                //in parade
                    if(!InParadeandMoving)
                    {
                        if(bitTest(ship->specialFlags,SPECIAL_ParadeNeedTomoveCloser))
                        {
                            InParadeandMoving = TRUE;
                            spec->rotate_state = ROTATE_WAIT;
                        }
                    }
                }
            }
        }
    }
    if(ship->flags & SOF_Slaveable)
    {    //ship is slaveable
        bitSet(ship->flags,SOF_DontDrawTrails);
        ship->autostabilizeship = FALSE;        // never have univupdate autostabilize research ships
        if(ship->slaveinfo->flags & SF_MASTER)
        {    //ship is a master
            if(!InParadeandMoving)
            {
                if(ship->shiprace == R1)
                {   //ship is a race 1 MASTER research ship...
                    //i.e. it controls the motion
                    switch(spec->rotate_state)
                    {
                    case ANGLE_ESTABLISH:       //establishes the angle at which the station is supposed to rotate at
                        break;
                    case ROTATE_WAIT:           //wait to rotate
                        if(ship->slaveinfo->slaves.num >= 5)
                        {   //correct # of ships...
                            if(!ship_is_moving(ship))
                            {
                                if(!spec->prepshipforanother)
                                {   //no ships are coming to dock
                                    //do up vector tracking!
                                    //Later Calculate this vector ONCE at code start up...Let Daly do it
                                    //and get as a static value

                                    radangle = DEG_TO_RAD(researchshipstatics->RotationAngle);
                                    matMakeRotAboutX(&rotmat,(real32) cos(radangle),(real32) sin(radangle));
                                    matMultiplyMatByVec(&newup, &rotmat, &univup);
                                    //matGetVectFromMatrixCol3(desiredHeading,ship->rotinfo.coordsys);
                                    if(aitrackHeadingWithFlags(ship,&newup,0.96f,AITRACKHEADING_IGNOREUPVEC))
                                    {
                                        spec->rotate_state = ROTATE_DO;
                                        getRotatePoint(ship, &spec->rotate_point,&spec->rotate_distance);
                                    }
                                }
                            }
                            if(!spec->have_removed_from_parade)
                            {
                                spec->have_removed_from_parade = TRUE;
                                selection.numShips = 1;
                                selection.ShipPtr[0] = ship;
                                //RemoveShipsFromDoingStuff(&universe.mainCommandLayer,&selection);
                                //clHalt(&universe.mainCommandLayer,&selection);
                            }
                        }
                        break;
                    case ROTATE_STOP:
                    case ROTATE_STOP_QUICK:
                    case ROTATE_DO:
                        ship->posinfo.isMoving = ISMOVING_MOVING | ISMOVING_ROTATING;
                        make_all_slaves_moving(ship);
                        if(ship->slaveinfo->slaves.num < 5)
                        {
                            //don't rotate anymore because slaves dropped below threhold for whatever reasons!
                            spec->rotate_state = ROTATE_STOP;
                            break;
                        }
                        if(spec->prepshipforanother)
                        {   //need to prep ship for a docking ship..
                            spec->rotate_state = ROTATE_STOP;
                        }
                        else if(ship_is_moving(ship))
                        {   //ship is being moved
                            spec->rotate_state = ROTATE_STOP_QUICK;
                        }
                        else
                        {
                            spec->rotate_state = ROTATE_DO;
                        }

                        //matGetVectFromMatrixCol3(heading,ship->rotinfo.coordsys);
                        matGetVectFromMatrixCol1(up,ship->rotinfo.coordsys);
                        //vecScalarMultiply(rotate_point, heading, -250.0f);
                        //vecAdd(rotate_point,rotate_point, ship->posinfo.position);

                        switch(spec->rotate_state)
                        {
                        case ROTATE_DO:
                            if(spec->theta >= researchshipstatics->max_rotate)
                                spec->theta = researchshipstatics->max_rotate;
                            else
                                spec->theta += researchshipstatics->rotate_acelleration;
                            break;
                        case ROTATE_STOP_QUICK:
                            spec->theta *= researchshipstatics->rotate_slow;
                            spec->theta *= researchshipstatics->rotate_slow;
                        case ROTATE_STOP:
                            if(spec->theta <= 0.00001f)
                            {
                                spec->theta = 0.0f;
                                spec->rotate_state = ROTATE_WAIT;
                                break;
                            }
                            else
                                spec->theta *= researchshipstatics->rotate_slow;
                            break;
                        default:
                            dbgAssertOrIgnore(FALSE);
                            break;
                        }
                        matMakeRotAboutX(&rot_matrix,(real32) cos(spec->theta),(real32) sin(spec->theta));
                        //matMultiplyMatByMat(&tmpmat, &rot_matrix, &ship->rotinfo.coordsys);
                        matMultiplyMatByMat(&tmpmat, &ship->rotinfo.coordsys, &rot_matrix);
                        //vecSub(tmpvec, ship->posinfo.position, spec->rotate_point);
                        //dist = vecMagnitudeSquared(tmpvec);
                        //dist = fsqrt(dist);

                        matGetVectFromMatrixCol3(desiredheading,tmpmat);
                        vecScalarMultiply(destination, desiredheading, spec->rotate_distance);      //old was dist
                        vecAdd(destination,destination,spec->rotate_point);

                        ship->posinfo.position = destination;
                        ship->rotinfo.coordsys = tmpmat;
                        univUpdateObjRotInfo((SpaceObjRot *)ship);
                        break;
                    default:
                        dbgMessagef("Shouldn't Get Here...unknown Research Ship Rotate State");
                        dbgAssertOrIgnore(FALSE);
                        break;
                    }


                }
                else
                {    //Ship is an R2 Master...so rotate differently
                    switch(spec->rotate_state)
                    {
                    case ANGLE_ESTABLISH:
                        break;
                    case ROTATE_WAIT:           //wait to rotate
                        if(ship->slaveinfo->slaves.num >= 3)
                        {   //correct # of ships...
                            if(!spec->prepshipforanother && !ship_is_moving(ship))
                            {   //no ships are coming to dock
                                radangle = DEG_TO_RAD(researchshipstatics->RotationAngle);
                                matMakeRotAboutX(&rotmat,(real32) cos(radangle),(real32) sin(radangle));
                                matMultiplyMatByVec(&newup, &rotmat, &univup);
                                if(aitrackHeadingWithFlags(ship,&newup,0.96f,AITRACKHEADING_IGNOREUPVEC))
                                {
                                    spec->rotate_state = ROTATE_DO;
                                }
                            }
                            else
                            {
                                vecSet(ship->rotinfo.rotspeed,0.0f,0.0f,0.0f);
                                vecSet(ship->rotinfo.torque,0.0f,0.0f,0.0f);
                            }
                        }
                        if(ship->slaveinfo->slaves.num >= 1)
                        {   //correct # of ships...
                            if(!spec->have_removed_from_parade)
                            {
                                spec->have_removed_from_parade = TRUE;
                                selection.numShips = 1;
                                selection.ShipPtr[0] = ship;
                                //RemoveShipsFromDoingStuff(&universe.mainCommandLayer,&selection);
                                //clHalt(&universe.mainCommandLayer,&selection);
                            }
                        }
                        break;
                    case ROTATE_STOP:
                    case ROTATE_STOP_QUICK:
                    case ROTATE_DO:
                        ship->posinfo.isMoving = ISMOVING_MOVING | ISMOVING_ROTATING;
                        make_all_slaves_moving(ship);
                        if(ship->slaveinfo->slaves.num < 3)
                        {
                            //don't rotate anymore because slaves dropped below threhold for whatever reasons!
                            spec->rotate_state = ROTATE_STOP;
                            break;
                        }
                        if(spec->prepshipforanother)
                        {   //need to prep ship for a docking ship..
                            spec->rotate_state = ROTATE_STOP;
                        }
                        if(ship_is_moving(ship))
                        {   //ship is being moved
                            spec->rotate_state = ROTATE_STOP_QUICK;
                        }
                        switch(spec->rotate_state)
                        {
                        case ROTATE_DO:
                            if(spec->theta >= researchshipstatics->max_rotate)
                                spec->theta = researchshipstatics->max_rotate;
                            else
                                spec->theta += researchshipstatics->rotate_acelleration;
                            break;
                        case ROTATE_STOP_QUICK:
                            spec->theta *= researchshipstatics->rotate_slow;
                            spec->theta *= researchshipstatics->rotate_slow;
                        case ROTATE_STOP:
                            if(spec->theta <= 0.00001f)
                                {
                                spec->theta = 0.0f;
                                spec->rotate_state = ROTATE_WAIT;
                                break;
                                }
                            else
                                spec->theta *= researchshipstatics->rotate_slow;
                            break;
                        default:
                            dbgAssertOrIgnore(FALSE);
                            break;
                        }
                        matMakeRotAboutZ(&rot_matrix,(real32) cos(spec->theta),(real32) sin(spec->theta));
                        tmpmat = ship->rotinfo.coordsys;
                        matMultiplyMatByMat(&ship->rotinfo.coordsys,&tmpmat,&rot_matrix);
                        univUpdateObjRotInfo((SpaceObjRot *)ship);
                        break;
                    default:
                        dbgMessagef("Shouldn't Get Here...unknown Research Ship Rotate State");
                        dbgAssertOrIgnore(FALSE);
                        break;
                    }
                }
            }
        }
        else
        {
            vecScalarMultiply(ship->posinfo.velocity,ship->posinfo.velocity, 0.0f);
        }

    }
}