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; }
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; } }