示例#1
0
bool CloakGeneratorSpecialActivate(Ship *ship)
{
    CloakGeneratorSpec *spec = (CloakGeneratorSpec *)ship->ShipSpecifics;
    CloakGeneratorStatics *cloakgeneratorstatics;

    if(spec->CloakOn == TRUE)
    {       //Ships cloak field is on...user wants it off...
        DeCloakAllObjects(ship);
        spec->CloakOn = FALSE;                  //Cloak Field goes off
        spec->CloakLowWarning = FALSE;  //reset flag
//        soundEvent(ship, PowerOff);
//        speechEvent(ship, COMM_Cloak_Decloak, 0);
        if (battleCanChatterAtThisTime(BCE_Decloaking, ship))
        {
            battleChatterAttempt(SOUND_EVENT_DEFAULT, BCE_Decloaking, ship, SOUND_EVENT_DEFAULT);
        }
        if(ship->playerowner->playerIndex !=
           universe.curPlayerIndex)
        {
            ///////////////
            //speech event for enemy cloakgen decloaking
            //event num: COMM_F_Cloakgen_Decloaking
            //battle chatter...camera distance important!
            //if (battleCanChatterAtThisTime(BCE_COMM_F_Cloakgen_Decloaking, ship))
            //{
            //    battleChatterAttempt(SOUND_EVENT_DEFAULT, BCE_COMM_F_Cloakgen_Decloaking, ship, SOUND_EVENT_DEFAULT);
            //}

            ///
        }
    }
    else
    {       //Ships cloakfield is off, user wants it on
        cloakgeneratorstatics = (CloakGeneratorStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo;
        if(spec->CloakStatus >= cloakgeneratorstatics->MinCharge)
        {       //Minimum power is available
            spec->CloakOn = TRUE;                   //Cloak Field goes on
//            soundEvent(ship, PowerOn);
//            speechEvent(ship, COMM_Cloak_CloakingOn, 0);
            if (battleCanChatterAtThisTime(BCE_CloakingOn, ship))
            {
                battleChatterAttempt(SOUND_EVENT_DEFAULT, BCE_CloakingOn, ship, SOUND_EVENT_DEFAULT);
            }
        }
        else
        {
//            speechEvent(ship, COMM_Cloak_InsufficientPower, 0);
            if (battleCanChatterAtThisTime(BCE_CloakingInsufficientPower, ship))
            {
                battleChatterAttempt(SOUND_EVENT_DEFAULT, BCE_CloakingInsufficientPower, ship, SOUND_EVENT_DEFAULT);
            }
        }
    }

    return TRUE;
}
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);
}
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;
}
示例#4
0
void CloakGeneratorHouseKeep(Ship *ship)
{
    CloakGeneratorSpec *spec = (CloakGeneratorSpec *)ship->ShipSpecifics;
    CloakGeneratorStatics *cloakgeneratorstatics;
    Node *cloaknode, *temp;
    SpaceObj *spaceobj;
    CloakStruct *cloakstruct;

    vector diff;
    real32  distanceSqr;

    cloakgeneratorstatics = (CloakGeneratorStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo;

    if(spec->CloakOn == TRUE)       //Cloaking Generator is On
    {
        //15th frame..so do a search on other ships within 'proximity'
        if ((universe.univUpdateCounter & CLOAKGENERATOR_CLOAKCHECK_RATE) == (ship->shipID.shipNumber & CLOAKGENERATOR_CLOAKCHECK_RATE))
        {
            CloakAddObjectsInProximity(ship);   //this opp is slow!  So maybe decrease frequency
        }

        //decrement functionality time
        spec->CloakStatus -= universe.phystimeelapsed;

        if ((spec->CloakStatus <= 10.0f) && !spec->CloakLowWarning)
        {
            spec->CloakLowWarning = TRUE;
//            speechEvent(ship, STAT_Cloak_CloakPowerLow, (sdword)spec->CloakStatus);
            if (battleCanChatterAtThisTime(BCE_CloakingPowerLow, ship))
            {
                battleChatterAttempt(SOUND_EVENT_DEFAULT, BCE_CloakingPowerLow, ship, (sdword)spec->CloakStatus);
            }
        }

        //Cloak Field has been on too long
        if(spec->CloakStatus <= 0.0f)
        {
            DeCloakAllObjects(ship);  //decloak everything
            spec->CloakOn = FALSE;    //reset flags
            spec->CloakStatus = 0.0f; //reset CloakStatus
            spec->CloakLowWarning = FALSE;  //reset flag
//            soundEvent(ship, PowerOff);
//            speechEvent(ship, COMM_Cloak_Decloak, 0);
            if (battleCanChatterAtThisTime(BCE_Decloaking, ship))
            {
                battleChatterAttempt(SOUND_EVENT_DEFAULT, BCE_Decloaking, ship, SOUND_EVENT_DEFAULT);
            }
        }
    }
    else        //cloak field is off
    {
        //recharge cloaking juice at tunable rate
        spec->CloakStatus +=  universe.phystimeelapsed*cloakgeneratorstatics->ReChargeRate;
        if(spec->CloakStatus >= cloakgeneratorstatics->MaxCloakingTime)
        {
            spec->CloakStatus = cloakgeneratorstatics->MaxCloakingTime; //cap max cloaking juice
        }
    }

    //perform maintainence on cloaked ships (cloaking,decloaking and continual cloak)
    cloaknode = spec->CloakList.head;
    while(cloaknode != NULL)
    {
        cloakstruct = (CloakStruct *)listGetStructOfNode(cloaknode);
        spaceobj = cloakstruct->spaceobj;

        // wierd crash ...

		if (spaceobj==NULL) 
		{
			temp = cloaknode;
			cloaknode = cloaknode->next;

			listDeleteNode(temp);
			continue;
		}
		
		//if spaceobj is dead for some reason, remove its references and stop bothering with it
        if (bitTest(spaceobj->flags,SOF_Dead))
        {   //dead so get rid of quickly...
            cloaknode=cloaknode->next;                  //we're about to delete this node so move to next
            CloakGeneratorRemoveShipReferences(ship,(Ship *)spaceobj);  //delete everything about it
            continue;
        }

        //perform a change check!
        //this seems like a waste because we are AGAIN calculating distances.  Do better later!
        if ((universe.univUpdateCounter & CLOAKGENERATOR_CLOAKCHECK_RATE) == (ship->shipID.shipNumber & CLOAKGENERATOR_CLOAKCHECK_RATE))
        {
            vecSub(diff,spaceobj->posinfo.position,ship->posinfo.position);
            distanceSqr = vecMagnitudeSquared(diff);

            if(distanceSqr > cloakgeneratorstatics->CloakingRadiusSqr)     //maybe add fuzzy logic so thing doesn't always pop in and out in and out in and out...
            {
                if(bitTest(spaceobj->flags,SOF_Cloaked))
                {
                    bitClear(spaceobj->flags,SOF_Cloaked);
                    if(spaceobj->objtype == OBJ_ShipType)
                    {
                        //if object was a ship set objects decloaking time for cloak advagtage effect
                        SpawnCloakingEffect((Ship *)spaceobj, etgSpecialPurposeEffectTable[EGT_CLOAK_OFF]);

                        ((Ship *) (spaceobj))->shipDeCloakTime = universe.totaltimeelapsed;
                    }
                }
                bitClear(spaceobj->flags,SOF_Cloaking);
                bitSet(spaceobj->flags,SOF_DeCloaking);
            }       //potential problem..ship flys into field..flys out..
                    //starts to decloak...flys back in, ship will decloak
                    //fully before recloaking...don't worry about since
                    //cloak times too fast too care
        }

        if(spaceobj->objtype == OBJ_ShipType)
        {
            if( ((Ship *)spaceobj)->shiptype == SalCapCorvette)
            {
                if(((SalCapCorvetteSpec *)((Ship *)spaceobj)->ShipSpecifics)->tractorBeam)
                {
                    //attached so decloak
                    if(bitTest(spaceobj->flags,SOF_Cloaked))
                    {
                        bitClear(spaceobj->flags,SOF_Cloaked);
                        if(spaceobj->objtype == OBJ_ShipType)
                        {
                            //if object was a ship set objects decloaking time for cloak advagtage effect
                            SpawnCloakingEffect((Ship *)spaceobj, etgSpecialPurposeEffectTable[EGT_CLOAK_OFF]);

                            ((Ship *) (spaceobj))->shipDeCloakTime = universe.totaltimeelapsed;
                        }
                    }
                    bitClear(spaceobj->flags,SOF_Cloaking);
                    bitSet(spaceobj->flags,SOF_DeCloaking);
                }
            }
        }

        //Case 1, object is cloaking
        if(bitTest(spaceobj->flags,SOF_Cloaking))
        {
            //object is cloaking..so keep cloaking it
/***** calculated the inverse of CloakingTime in CloakGeneratorStaticInit and multiply instead of divide *****/
            cloakstruct->CloakStatus += universe.phystimeelapsed*cloakgeneratorstatics->CloakingTime;
            if(cloakstruct->CloakStatus >= 1.0f)
            {
                //object is now cloaked...so stop cloaking it and make it fully 'cloaked'
                cloakstruct->CloakStatus = 1.0f;          //set for assurance
                bitSet(spaceobj->flags,SOF_Cloaked);      //make cloaked
                bitClear(spaceobj->flags,SOF_Cloaking);   //stop from cloaking
                if(spaceobj->objtype == OBJ_ShipType)
                {
                    shipHasJustCloaked((Ship *)spaceobj);
                    SpawnCloakingEffect((Ship *)spaceobj, etgSpecialPurposeEffectTable[EGT_CLOAK_ON]);
                    //RemoveShipFromBeingTargeted(&universe.mainCommandLayer,(Ship *)spaceobj,FALSE);
                }
                else if(spaceobj->objtype == OBJ_AsteroidType)
                {
                    //need to remove the asteroid from resource collectors
                    dbgMessagef("\nMake Bryce remove asteroids from game info since you just cloaked one.");
                }
            }
        }
        else if(bitTest(spaceobj->flags,SOF_DeCloaking))
        {
            //object is decloaking, so keep decloaking it
/***** calculated the inverse of DeCloakingTime in CloakGeneratorStaticInit and multiply instead of divide *****/
            cloakstruct->CloakStatus -= universe.phystimeelapsed*cloakgeneratorstatics->DeCloakingTime;
            if(cloakstruct->CloakStatus <= 0.0f)
            {
                //Object is now fully decloaked so stop decloaking it and remove it from the list
                cloaknode=cloaknode->next;                  //we're about to delete this node so move to next
                CloakGeneratorRemoveShipReferences(ship,(Ship *)spaceobj);  //delete everything about it
                continue;       //we now continue the loop rather than letting the other code continue :)
            }
        }
        cloaknode = cloaknode->next;
    }
}