void SetAIVecHeading(Ship *ship, SpaceObjRotImpTarg *target, vector *trajectory)
{
    //real32 range;
    ShipStaticInfo *shipstaticinfo = (ShipStaticInfo *)ship->staticinfo;
    vector tmpvec;
    udword target_class;
    real32 randegf;
    sdword randeg;
    matrix tmpmat;
    vector targetheading;
    MinelayerCorvetteSpec *spec = (MinelayerCorvetteSpec *)ship->ShipSpecifics;
    MinelayerCorvetteStatics *minelayercorvettestatics;
    minelayercorvettestatics = (MinelayerCorvetteStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo;
    matGetVectFromMatrixCol3(targetheading,target->rotinfo.coordsys)

    if(target != NULL)
    {
        if(target->objtype == OBJ_ShipType)
            target_class = ((Ship *)target)->staticinfo->shipclass;
        else
            target_class = CLASS_NonCombat;
    }

    if (vecDotProduct(targetheading,*trajectory) > 0)
    {   //Attack accross front of ship :)
        vecAddTo(spec->aivec,targetheading);
        vecAddTo(spec->aivec,*trajectory);
        vecScalarMultiply(spec->aivec,spec->aivec,minelayercorvettestatics->FlyAwayDist[target_class]);
    }
    else
    {    //test
        if(randombetween(1,2) & 1)
        {
            vecCrossProduct(spec->aivec,*trajectory, targetheading);
        }
        else
        {
            vecCrossProduct(spec->aivec, targetheading, *trajectory);
        }
        vecAddTo(spec->aivec, *trajectory);
        vecScalarMultiply(spec->aivec,spec->aivec,minelayercorvettestatics->FlyAwayDist[target_class]);
    }
    if(!(target->posinfo.isMoving & ISMOVING_MOVING))
    {    //if target isn't moving, randomize trajectory
        randeg = randombetween(5,30);
        randegf = (real32) ((randeg & 1) ? randeg : -randeg);
        randegf = (real32) randeg;
        randegf = DEG_TO_RAD(randegf);

        matMakeRotAboutZ(&tmpmat,(real32)cos(randegf),(real32)sin(randegf));
        matMultiplyMatByVec(&tmpvec,&tmpmat,&spec->aivec);
        spec->aivec = tmpvec;
    }
    vecAddTo(spec->aivec,target->posinfo.position);

    //need change
    aishipFlyToPointAvoidingObjs(ship,&spec->aivec,AISHIP_FastAsPossible | AISHIP_PointInDirectionFlying,INTERCEPTORBREAK_MINVELOCITY);

}
void startRepairEffect(Ship *ship,SpaceObjRotImpTarg *target,vector *trajectory,real32 distance)
{
    ShipStaticInfo *shipstatic = (ShipStaticInfo *)ship->staticinfo;
    RepairNozzleStatic *repnozzlestatic = shipstatic->repairNozzleStatic;
    //TURN ON EFFECT HERE
    //
    //Use ship->rceffect, since ship isn't a resource collector,
    //the pointer isn't being used
    etglod *etgLOD = etgSpecialPurposeEffectTable[EGT_REPAIR_BEAM];

    etgeffectstatic *stat;
    sdword LOD;
    udword intLength;
    udword intWidth;
    matrix coordsys;
    real32 targetRadius = target->staticinfo->staticheader.staticCollInfo.collspheresize;
    vector repairBeamPosition;

    matMultiplyMatByVec(&repairBeamPosition,&ship->rotinfo.coordsys,&repnozzlestatic->position);

    matCreateCoordSysFromHeading(&coordsys,trajectory);

    intLength = TreatAsUdword(distance);
    intWidth = TreatAsUdword(targetRadius);

    vecAddTo(repairBeamPosition,ship->posinfo.position);

    //create an effect for bullet, if applicable
    if (etgLOD != NULL)
    {
        LOD = ship->currentLOD;
        if (LOD >= etgLOD->nLevels)
        {
            stat = NULL;
        }
        else
        {
            stat = etgLOD->level[LOD];
        }
    }
    else
    {
        stat = NULL;
    }
    #if ETG_DISABLEABLE
    if (stat != NULL && etgEffectsEnabled && !etgFrequencyExceeded(stat))
    #else
    if (stat != NULL && !etgFrequencyExceeded(stat))
    #endif
    {
        ship->rceffect = etgEffectCreate(stat, ship, &repairBeamPosition, &ship->posinfo.velocity, &coordsys, 1.0f, EAF_Velocity | EAF_NLips, 2, intLength, intWidth);
    }
    else
    {
        ship->rceffect = NULL;                              //play no effect
    }


}
示例#3
0
/*-----------------------------------------------------------------------------
    Name        : navLightBillboardEnable
    Description : setup modelview matrix for rendering billboarded sprites
    Inputs      : s - ship to obtain coordinate system from
                  nls - NAV Light static info
    Outputs     :
    Return      :
----------------------------------------------------------------------------*/
void navLightBillboardEnable(Ship *s, NAVLightStatic *nls)
{
    vector src, dst;

    //object -> worldspace
    src = nls->position;
    matMultiplyMatByVec(&dst, &s->rotinfo.coordsys, &src);
    vecAddTo(dst, s->posinfo.position);

    //setup billboarding
    glPushMatrix();
    rndBillboardEnable(&dst);
    glDisable(GL_CULL_FACE);
}
示例#4
0
bool madLinkInGetDoorInfo(Ship *ship, matrix *coordsys, vector *position)
{
    sdword madIndex, gunIndex;
    vector positiont;
    matrix coordsyst;

    madIndex = madBindingIndexFindByName(ship->staticinfo->madStatic->header, "Hangardoor");
    gunIndex = madGunBindingIndexFindByName(ship->staticinfo, "Hangardoor");
    dbgAssertOrIgnore(madIndex != -1);
    dbgAssertOrIgnore(gunIndex != -1);
    madAnimBindingMatrix(&coordsyst,&positiont,ship,gunIndex, madIndex);

    matMultiplyMatByMat(coordsys,&ship->rotinfo.coordsys,&coordsyst);
    //matMultiplyVecByMat(position,&positionSS,&ship->rotinfo.coordsys);
    matMultiplyMatByVec(position,&ship->rotinfo.coordsys,&positiont);
    vecAddTo(*position,ship->posinfo.position);
    return TRUE;
}
示例#5
0
//to OPTIMIZE THIS:  ONLY CALCULATE SLAVED SHIPS AVERAGE POSITION when slaves are added!
void toFakeOneShip(Ship *ship, vector *oldpos, real32 *oldradius)
{
    Node *slavenode;
    Ship *slave;
    vector newcenter;
    real32 newradius,tempreal;

    if(!(ship->flags & SOF_Slaveable))
        return;

    dbgAssertOrIgnore(ship->slaveinfo->flags & SF_MASTER);      //must be a master
    slavenode = ship->slaveinfo->slaves.head;

    newcenter = ship->collInfo.collPosition;

    while(slavenode != NULL)
    {   //add all slaves positions together
        slave = (Ship *) listGetStructOfNode(slavenode);
        vecAddTo(newcenter,slave->collInfo.collPosition);
        slavenode = slavenode->next;
    }
    vecDivideByScalar(newcenter,(float) ship->slaveinfo->slaves.num+1,tempreal);   //take average of slavemaster position

    if(ship->shiprace == R1)
    {
        newradius = ship->staticinfo->staticheader.staticCollInfo.approxcollspheresize*2.5f;
    }
    else
    {   //Must be R2
        newradius = (float) ship->slaveinfo->slaves.num+1;
        newradius = ship->staticinfo->staticheader.staticCollInfo.approxcollspheresize*(newradius/4.0f)*1.25f;

    }

    *oldpos = ship->collInfo.collPosition;
    *oldradius = ship->staticinfo->staticheader.staticCollInfo.approxcollspheresize;

    ship->staticinfo->staticheader.staticCollInfo.approxcollspheresize = newradius;

    ship->collInfo.collPosition = newcenter;

}
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);
}
void doKamikazeAttack(Ship *ship,SpaceObjRotImpTarg *target)
{
    real32 mag,dist,range,shipvel;
    vector destination,trajectory,heading,shipheading,EinsteinVelocity;
    ShipStaticInfo *shipstaticinfo = ship->staticinfo;

    vecSub(trajectory,target->collInfo.collPosition,ship->posinfo.position);
    mag = vecMagnitudeSquared(trajectory);
    dist = fsqrt(mag);

    destination = trajectory;
    vecNormalize(&destination);
    heading = destination;

    //this hokey fudge factor is needed so the kamikaze ship doesn't
    //slow down as it reaches its destination
    mag = dist + 500.0f;
    vecScalarMultiply(destination,destination,mag);
    vecAddTo(destination,target->collInfo.collPosition);

    range = RangeToTargetGivenDist(ship,target,dist);

    switch(ship->kamikazeState)
    {
    case K_Start:
        //if within a threshold range
        bitClear(ship->specialFlags,SPECIAL_KamikazeCrazyFast);
        if(range < 500.0f)
        {
            //calculate flyby dist
            matGetVectFromMatrixCol3(shipheading, ship->rotinfo.coordsys);
            vecScalarMultiply(shipheading,shipheading,kamikazeFlyByDist);
            vecAdd(ship->kamikazeVector,shipheading,target->collInfo.collPosition);
            ship->kamikazeState = K_TurnAround;
        }
        ship->kamikazeState = K_Ram;

        break;

    case K_Ram:
        if (range < 400.0f)
        {
            ship->kamikazeState = K_Yell;
        }
    case K_Ram2:
        //lets use...mmmmm..twister theor...no...relativity
        vecSub(EinsteinVelocity,ship->posinfo.velocity,target->posinfo.velocity);
        shipvel = fsqrt(vecMagnitudeSquared(EinsteinVelocity));
        if(ship->shiptype == MinelayerCorvette)
        {
            ((MinelayerCorvetteSpec *)(ship->ShipSpecifics))->mineaistate = MINE_DROP_ATTACK;
        }
        else if (ship->shiptype == DefenseFighter)
        {
            goto dontshoot;
        }

        if (isShipStaticInterceptor(shipstaticinfo))
        {
            if (range < shipstaticinfo->bulletRange[ship->tacticstype])
            {
                GenericInterceptorStatics *interceptorstat = (GenericInterceptorStatics *)shipstaticinfo->custstatinfo;
                uword targetIndex;

                if (target->objtype == OBJ_ShipType)
                {
                    targetIndex = (uword)((ShipStaticInfo *)target->staticinfo)->shipclass;
                }
                else
                {
                    targetIndex = (uword)NUM_CLASSES;
                }

                if (GenericInterceptorCanFire(ship,target,&trajectory,interceptorstat->triggerHappy[ship->tacticstype][targetIndex]))
                {
                    ship->staticinfo->custshipheader.CustShipFire(ship,target);
                }
            }
        }
        else
        {
            gunShootGunsAtTarget(ship,target,range,&trajectory);
        }
dontshoot:
        aishipFlyToPointAvoidingObjs(ship,&destination,AISHIP_PointInDirectionFlying | AISHIP_FirstPointInDirectionFlying | AISHIP_FastAsPossible,0.0f);
        if(range < 1500.0f)
        {
            bitSet(ship->specialFlags,SPECIAL_KamikazeCrazyFast);
        }
        else
        {
            bitClear(ship->specialFlags,SPECIAL_KamikazeCrazyFast);
        }

/*
        if(range < 400.0f && (shipvel < ship->staticinfo->staticheader.maxvelocity*0.7f ||
                   vecDotProduct(trajectory,heading) < 0))
        {
            //ship is inside 400.0f, and isn't faceing ship, or isn't
            //going fast enough

            //calculate flyby dist
            matGetVectFromMatrixCol3(shipheading, ship->rotinfo.coordsys);
            vecScalarMultiply(shipheading,shipheading,kamikazeFlyByDist);
            vecAdd(ship->kamikazeVector,shipheading,target->posinfo.position);
            ship->kamikazeState = K_TurnAround;
        }
*/
        break;
    case K_TurnAround:
        bitClear(ship->specialFlags,SPECIAL_KamikazeCrazyFast);
        aishipFlyToPointAvoidingObjs(ship,&ship->kamikazeVector,AISHIP_PointInDirectionFlying | AISHIP_FirstPointInDirectionFlying | AISHIP_FastAsPossible,0.0f);
        if(MoveReachedDestinationVariable(ship,&ship->kamikazeVector,300.0f))
            ship->kamikazeState = K_TurnAround2;
        break;
    case K_TurnAround2:
        bitClear(ship->specialFlags,SPECIAL_KamikazeCrazyFast);
        if(aitrackHeadingWithFlags(ship,&heading,0.90f,AITRACKHEADING_IGNOREUPVEC))
            ship->kamikazeState = K_Ram;
        break;
    case K_Yell:
//      speechEvent(ship, COMM_LInt_Kamikaze, 0);
        battleChatterAttempt(SOUND_EVENT_DEFAULT, BCE_Kamikaze, ship, SOUND_EVENT_DEFAULT);
        ship->kamikazeState = K_Ram2;
        break;
    }

        //fire guns here...
    //
    //
    //Sound note:   Could put in kamikaze state change here after
    //              getting to within a certain distance of target
    //
    //          ask bryce how to...
}
void DefenseFighterHouseKeep(Ship *ship)
{
    DefenseFighterSpec *spec = (DefenseFighterSpec *)ship->ShipSpecifics;
    DefenseFighterStatics *defensefighterstatics;
    Node *bulletnode;
    Node *tempnode;
    DefenseStruct *defensestruct;
    vector seperationvector;
    vector tempvec,rot_vector;
    GunStatic *gunstatic;
    Gun *gun;

    vector positionInWorldCoordSys;
    gun = &ship->gunInfo->guns[0];
    gunstatic = gun->gunstatic;

    defensefighterstatics = (DefenseFighterStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo;

    bulletnode = spec->DefenseList.head;

    while (bulletnode != NULL)
    {   //as long as theres a bullet to deal with
        defensestruct = (DefenseStruct *)listGetStructOfNode(bulletnode);

/*        if (defensestruct->bullet)
            dbgMessagef("DS: %d %f %d %f %d %d",
                        universe.univUpdateCounter,
                        defensestruct->bullet->collOptimizeDist,
                        defensestruct->laser ? 1:0,
                        defensestruct->CoolDownTime,
                        defensestruct->CoolDown ? 1:0,
                        defensestruct->LaserDead ? 1:0);
        else
            dbgMessagef("DS: %d N  %d %f %d %d",
                        universe.univUpdateCounter,
                        defensestruct->laser ? 1:0,
                        defensestruct->CoolDownTime,
                        defensestruct->CoolDown ? 1:0,
                        defensestruct->LaserDead ? 1:0);*/

        if(!defensestruct->CoolDown)
        {   //laser cannon isn't cooling down, so continue tracking
            if (defensestruct->bullet == NULL || defensestruct->bullet->damage <= 0)
            {    //bullet is already dead...don't kill it again
                defensestruct->bullet = NULL;   //destroy pointer...
                if (defensestruct->laser != NULL)
                {
                    defensestruct->laser->timelived =10000.0f; //kill laser
                }
                defensestruct->LaserDead = TRUE;    //set killed flag
                defensestruct->laser=NULL;
                defensestruct->CoolDown = TRUE;     //begin laser cooldown
                defensestruct->CoolDownTime = 0.0f;    //reset to 0 for cooldown count
                bulletnode=bulletnode->next;
                continue;
            }
            if((universe.univUpdateCounter & defensefighterstatics->DamageRate) == 0)
            {
                // Time to do damage...
                //Do damage to bullet
                defensestruct->bullet->damage = (defensestruct->bullet->damage - frandombetween(defensefighterstatics->DamageReductionLow,defensefighterstatics->DamageReductionHigh));
                if(defensestruct->bullet->damage <= 0)
                {
                    //bullet is destroyed
                    DefenseFighterDestroyedABullet(ship, defensestruct->bullet, defensestruct->laser);
                    defensestruct->bullet->damage = 0;      //cap at 0;
                    defensestruct->bullet = NULL;   //destroy pointer...
                    //dbgMessagef("Defense Fighter Destroyed A Bullet.");
                    if (defensestruct->laser != NULL)
                    {
                        defensestruct->laser->timelived =10000.0f; //kill laser
                    }
                    defensestruct->LaserDead = TRUE;    //set killed flag
                    if(defensestruct->laser->effect != NULL)
                    {
                        univRemoveObjFromRenderList((SpaceObj *) defensestruct->laser->effect);
                    }
                    defensestruct->laser=NULL;
                    defensestruct->CoolDown = TRUE;     //begin laser cooldown
                    defensestruct->CoolDownTime = 0.0f;    //reset to 0 for cooldown count
                }
            }
            if(defensestruct->laser != NULL)
            {
                //check if bullet is still in range and infront...
                if((universe.univUpdateCounter & defensefighterstatics->RangeCheckRate) == 0)
                {
                    //time to check if in front
                    vecSub(seperationvector, ship->posinfo.position, defensestruct->bullet->posinfo.position);
                    if(vecMagnitudeSquared(seperationvector) > ship->staticinfo->bulletRangeSquared[ship->tacticstype])
                    {
                        //bullet is out of range
                        defensestruct->laser->timelived =10000.0f; //kill laser
                        defensestruct->LaserDead = TRUE;    //set killed flag
                        if(defensestruct->laser->effect != NULL)
                        {
                            univRemoveObjFromRenderList((SpaceObj *) defensestruct->laser->effect);
                        }
                        defensestruct->laser=NULL;
                        //dbgMessagef("Bullet out of range.");
                        bitClear(defensestruct->bullet->SpecialEffectFlag,0x0002);
                        defensestruct->CoolDown = TRUE;     //begin laser cooldown
                        defensestruct->bullet = NULL;       //set target to NULL so it isn't referenced again!
                        defensestruct->CoolDownTime = 0.0f;    //reset to 0 for cooldown count
                    }
                    else if(!defensefighterCheckInFront(ship, defensestruct->bullet))
                    {
                        //if bullet ISN'T in front
                        defensestruct->laser->timelived =10000.0f; //kill laser
                        defensestruct->LaserDead = TRUE;    //set killed flag
                        if(defensestruct->laser->effect != NULL)
                        {
                            univRemoveObjFromRenderList((SpaceObj *) defensestruct->laser->effect);
                        }
                        defensestruct->laser=NULL;
                        //dbgMessagef("Bullet Not infront anymore...stop tracking.");
                        if(defensefighterstatics->MultipleTargettingofSingleBullet)
                        {
                            bitClear(defensestruct->bullet->SpecialEffectFlag,0x0002);
                        }
                        defensestruct->CoolDown = TRUE;     //begin laser cooldown
                        defensestruct->bullet = NULL;       //set target to NULL so it isn't referenced again!
                        defensestruct->CoolDownTime = 0.0f;    //reset to 0 for cooldown count
                    }

                }
            }
            //This code is for the sake of the visual effect which STILL won't work
            //properly!!!  So it is temperary only!
            if(defensestruct->laser != NULL)
            {   //update bullent info...for visual effect
                dbgAssertOrIgnore(defensestruct->bullet != NULL);
                matMultiplyMatByVec(&positionInWorldCoordSys,&ship->rotinfo.coordsys,&gunstatic->position);
                vecAdd(defensestruct->laser->posinfo.position,positionInWorldCoordSys,ship->posinfo.position);
                vecSub(defensestruct->laser->lengthvec, defensestruct->bullet->posinfo.position, defensestruct->laser->posinfo.position);

                // heading
                tempvec = defensestruct->laser->lengthvec;
                vecNormalize(&tempvec);

                //matMultiplyMatByVec(&gunheadingInWorldCoordSys, &ship->rotinfo.coordsys, &tempvec);
                //laser->bulletheading = gunheadingInWorldCoordSys;
                defensestruct->laser->bulletheading = tempvec;
                matCreateCoordSysFromHeading(&defensestruct->laser->rotinfo.coordsys,&tempvec);
                if(defensestruct->laser->effect != NULL)
                {    //adjust length
                    ((real32 *)defensestruct->laser->effect->variable)[ETG_LengthVariable] =
                        fsqrt(vecMagnitudeSquared(defensestruct->laser->lengthvec));
                }
            }

        }
        else
        {    //this laser cannon is cooling, so cool it
            defensestruct->CoolDownTime += universe.phystimeelapsed;
            if(defensestruct->CoolDownTime > defensefighterstatics->CoolDownTimePerLaser)
            {    //Laser Terminal has cooled down...so free it up
                tempnode = bulletnode->next;
                listDeleteNode(bulletnode);
                //dbgMessagef("Deleting defense node in CoolDown.");
                bulletnode = tempnode;
                continue;
            }
        }
        bulletnode = bulletnode->next;
    }

    if (spec->DefenseList.num == 0)
    {
        soundEventBurstStop(ship, gun);
    }

    //do special rotation if neccessary
    if(bitTest(ship->dontrotateever,1))
    {
        //matGetVectFromMatrixCol3(rot_vector,ship->rotinfo.coordsys);
        vecSet(rot_vector,100.0f,0.0f,0.0f);
        vecAddTo(ship->rotinfo.torque, rot_vector);
        vecCapVectorSloppy(&ship->rotinfo.rotspeed, defensefighterstatics->max_rot_speed );
        spec->rotate_time_counter -= universe.phystimeelapsed;
        if(spec->rotate_time_counter <= 0.0f)
        {
            bitClear(ship->dontrotateever,1);
            spec->DefenseFighterCanNowRotate = FALSE;
        }
    }
    else if (spec->DefenseFighterCanNowRotate == FALSE)
    {
        spec->rotate_time_counter += universe.phystimeelapsed;
        if(spec->rotate_time_counter >= defensefighterstatics->rotate_recover_time)
        {
            spec->DefenseFighterCanNowRotate = TRUE;
            spec->rotate_time_counter = defensefighterstatics->rotate_time;
        }

    }

}
示例#9
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 HeavyCorvetteSpecialTarget(Ship *ship, void *custom)
{
    HeavyCorvetteSpec *spec = (HeavyCorvetteSpec *)ship->ShipSpecifics;
    SelectAnyCommand *targets = (SelectAnyCommand *)custom;
    real32 tempreal;
    vector Av;
    sdword i,flag;

    if(spec->cooldown)
    {
        aitrackSteadyShip(ship);
        return FALSE;
    }

    if (targets->numTargets == 0)
    {
        return TRUE;
    }

    switch(spec->burstState)
    {
    case BURST_Begin:
        //get average position of targets
        vecSet(Av,0.0f,0.0f,0.0f);
        for(i=0;i<targets->numTargets;i++)
        {
            vecAddTo(Av,targets->TargetPtr[i]->collInfo.collPosition);
        }
        tempreal = 1.0f/((real32)i);
        vecScalarMultiply(spec->burstFireVector,Av,tempreal);

        ///////////////////////////////
        /////burst attack speech event!
        //event num: COMM_HVette_BurstAttack
        //use battle chatter
        if(ship->playerowner->playerIndex ==
           universe.curPlayerIndex)
        {
            if(ship->playerowner->playerIndex == universe.curPlayerIndex)
            {
                if (battleCanChatterAtThisTime(BCE_COMM_HVette_BurstAttack, ship))
                {
                    battleChatterAttempt(SOUND_EVENT_DEFAULT, BCE_COMM_HVette_BurstAttack, ship, SOUND_EVENT_DEFAULT);
                }
            }
        }

        ///////////////////////////////

        spec->burstState=BURST_FlyToFirePoint;
        break;
    case BURST_FlyToFirePoint:
        flag = 0;
        if(doBurstCharging(ship))
        {
            //ship is fully charged
            flag = 1;
        }
        if(flytoBurstPosition(ship))
        {
            //ship is in position fire
            if(flag == 1)
            {
                spec->burstState=BURST_Fire;
            }
        }
        break;
    case BURST_Fire:
        if(doBurstFire(ship))
        {
            spec->burstState = BURST_Begin;
            dbgMessagef("Firing Burst Fire.");
        }
        break;
    default:
        dbgFatalf(DBG_Loc,"\nUnknown BurstState %d for shiptype %d.",spec->burstState,ship->shiptype);
    }

    //perform burst attack AI here...

    return FALSE;
}