/*----------------------------------------------------------------------------- Name : pingAnomalyPingRemove Description : Remove all pings of a given name from the ping list Inputs : Outputs : Return : number of pings removed ----------------------------------------------------------------------------*/ sdword pingAnomalyPingRemove(char *pingName) { Node *thisNode, *nextNode; ping *thisPing; char *name; SelectCommand *selection; sdword nRemoved = 0; thisNode = pingList.head; while (thisNode != NULL) { //scan all pings nextNode = thisNode->next; thisPing = listGetStructOfNode(thisNode); if (thisPing->evaluate == pingAnomalyPingTimeout) { selection = (SelectCommand *)(thisPing + 1); name = (char *)selection + selSelectionSize(selection->numShips ); if (!strcmp(pingName, name)) { //if names match listDeleteNode(thisNode); //kill it if it did nRemoved++; //inc number removed } } thisNode = nextNode; } return(nRemoved); }
void DefenseFighterDied(Ship *ship) { DefenseFighterSpec *spec = (DefenseFighterSpec *)ship->ShipSpecifics; Node *bulletnode; Node *tempnode; DefenseStruct *defensestruct; bulletnode = spec->DefenseList.head; dbgMessagef("DefenseFighter Died: Cleaning up."); while(bulletnode != NULL) { defensestruct = (DefenseStruct *)listGetStructOfNode(bulletnode); if(defensestruct->LaserDead != TRUE) { //listRemoveNode(&defensestruct->laser->bulletlink); //removefrom bullet list too? if (defensestruct->laser != NULL) { univRemoveObjFromRenderList((SpaceObj *) defensestruct->laser); defensestruct->laser->timelived = 10000.0f; bitSet(defensestruct->laser->flags,SOF_Hide); } //listDeleteNode(&defensestruct->laser->objlink); //dbgMessagef("Defense Dead: Deleting Laser from existance"); soundEventBurstStop(ship, &ship->gunInfo->guns[0]); } tempnode = bulletnode->next; listDeleteNode(bulletnode); //dbgMessagef("Defense Dead: Deleting defense node."); bulletnode = tempnode; } }
/*----------------------------------------------------------------------------- Name : pingObjectDied Description : Called when an object dies, removes references of said object from all ping structures. Inputs : obj - object that just died Outputs : Return : void ----------------------------------------------------------------------------*/ void pingObjectDied(SpaceObj *obj) { Node *thisNode, *nextNode; ping *thisPing; pingDyingObject = obj; thisNode = pingList.head; while (thisNode != NULL) { //scan all pings nextNode = thisNode->next; thisPing = listGetStructOfNode(thisNode); if (thisPing->owner == obj) { //if this ping centered on object thisPing->centre = obj->posinfo.position; thisPing->owner = NULL; //remove object from reference } if (thisPing->userID != 0 || thisPing->userDataSize != 0) { //see if there's anything in the user data if (thisPing->evaluate(thisPing, thisPing->userID, (char *)(thisPing + 1), TRUE)) { //did this ping just expire? listDeleteNode(thisNode); //kill it if it did } } thisNode = nextNode; } }
void pingUpdateTask(void) { static Node *thisNode, *nextNode; static ping *thisPing; taskYield(0); while (1) { taskStackSaveCond(0); thisNode = pingList.head; //... code to go here... while (thisNode != NULL) { //scan all pings nextNode = thisNode->next; thisPing = listGetStructOfNode(thisNode); if (universe.totaltimeelapsed - thisPing->lastEvaluateTime >= thisPing->evaluatePeriod) { //if time to evaluate a ping thisPing->lastEvaluateTime = universe.totaltimeelapsed; if (thisPing->evaluate(thisPing, thisPing->userID, (char *)(thisPing + 1), FALSE)) { //did this ping just expire? listDeleteNode(thisNode); //kill it if so } } thisNode = nextNode; } taskStackRestoreCond(); taskYield(0); } }
void taskCallBackRemove(BabyCallBack *babytogobyebye) { BabyCallBack *baby; Node *babynode; babynode = callbacks.babies.head; while(babynode != NULL) { baby = (BabyCallBack *) listGetStructOfNode(babynode); if(baby == babytogobyebye) { //returned TRUE, so delete listDeleteNode(babynode); return; } babynode = babynode->next; } }
/*----------------------------------------------------------------------------- Name : pingRemovePingByOwner Description : removes a ping based on its owner Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void pingRemovePingByOwner(SpaceObj *owner) { Node *node = pingList.head; ping *thisPing; while (node != NULL) { thisPing = listGetStructOfNode(node); if (thisPing->owner == owner) { listDeleteNode(node); return; } node = node->next; } }
void CloakGeneratorRemoveShipReferences(Ship *ship,Ship *shiptoremove) { CloakGeneratorSpec *spec = (CloakGeneratorSpec *)ship->ShipSpecifics; Node *cloaknode; CloakStruct *cloakstruct; SpaceObj *objtoremove = (SpaceObj *)shiptoremove; cloaknode = spec->CloakList.head; if (bitTest(objtoremove->flags,SOF_Cloaked) || //if object inquestion isn't cloaked, cloaking bitTest(objtoremove->flags,SOF_Cloaking) || //or decloaking, then we don't walk this list bitTest(objtoremove->flags,SOF_DeCloaking)) //If a cloaked fighter is passed, and it isn't in the list, it will waste time, but this is good enough :) { while(cloaknode != NULL) { cloakstruct = (CloakStruct *)listGetStructOfNode(cloaknode); if (cloakstruct->spaceobj == objtoremove) { listDeleteNode(cloaknode); //delete nodes memory...may not work as I think...ask gary.. break; //done so break and return } cloaknode = cloaknode->next; } if(bitTest(objtoremove->flags, SOF_Cloaked)) { bitClear(objtoremove->flags,SOF_Cloaked); if(objtoremove->objtype == OBJ_ShipType) { //if object was a ship set objects decloaking time for cloak advagtage effect SpawnCloakingEffect((Ship *)objtoremove, etgSpecialPurposeEffectTable[EGT_CLOAK_OFF]); ((Ship *) (objtoremove))->shipDeCloakTime = universe.totaltimeelapsed; } } bitClear(objtoremove->flags,SOF_Cloaking); bitClear(objtoremove->flags,SOF_DeCloaking); bitClear(objtoremove->flags,SOF_CloakGenField); } }
/*----------------------------------------------------------------------------- Name : rmClearResearchlab Description : Clears the specified labs research status. Inputs : lab to clear, and player Outputs : none Return : void ----------------------------------------------------------------------------*/ void rmClearResearchlab(Player *player, sdword labnumber) { ResearchLab *lab = &player->researchinfo.researchlabs[labnumber]; ResearchTopic *topic = player->researchinfo.researchlabs[labnumber].topic; if (lab->labstatus==LS_RESEARCHITEM) { if (topic->numlabsresearching==1) { lab->topic = NULL; listDeleteNode(&topic->link); lab->labstatus = LS_NORESEARCHITEM; } else { lab->topic = NULL; lab->labstatus = LS_NORESEARCHITEM; topic->numlabsresearching--; } if ((player == universe.curPlayerPtr)&&(rmGUIActive)) rmUpdateTechList(); } }
void stopRepairEffect(Ship *ship) { #ifdef HW_BUILD_FOR_DEBUGGING //make sure we only entered here if effect was playing! dbgAssertOrIgnore(ship->rceffect != NULL); #endif if (bitTest(((etgeffectstatic *)ship->rceffect->staticinfo)->specialOps, ESO_SelfDeleting)) { //if the effect will delete itself ((real32 *)ship->rceffect->variable)[ETG_ResourceDurationParam] = ship->rceffect->timeElapsed; //time it out } else { //else it's a free-running effect... delete it etgEffectDelete(ship->rceffect); univRemoveObjFromRenderList((SpaceObj *)ship->rceffect); listDeleteNode(&ship->rceffect->objlink); } //soundEventStop(ship->soundevent.specialHandle); ship->rceffect = NULL; }
void univUpdateMineWallFormations() { Node *node,*minenode,*tempnode; //Missile *mine, *mineend = NULL, *minestart, *mineendtemp; MineFormationInfo *mineformationinfo; Missile *minestart; vector tempvec; node = universe.MineFormationList.head; while(node != NULL) { mineformationinfo = (MineFormationInfo *) listGetStructOfNode(node); if(mineformationinfo->MineList.num == 9) //use another number other than 0 later..maybe 8? Tunable { //no more mines in formation so destroy this here formation //destroy any effects that are still going //here re-task mines (make not Force Dropped...) if(mineformationinfo->FULL) { //no more mines are going to be added... minenode = mineformationinfo->MineList.head; //set formationinfo to NULL while(minenode != NULL) { minestart = (Missile *) listGetStructOfNode(minenode); minestart->formationinfo = NULL; minenode = minenode->next; } listRemoveAll(&mineformationinfo->MineList); //removes all mine links tempnode = node->next; listDeleteNode(node); //destroys mineformation node = tempnode; continue; } } else { //mines exist in formation if(mineformationinfo->FULL) { minenode = mineformationinfo->MineList.head; while(minenode != NULL) { minestart = (Missile *) listGetStructOfNode(minenode); vecSub(tempvec, minestart->posinfo.position, minestart->formation_position); if(vecMagnitudeSquared(tempvec) > MINE_GONE_TOO_FAR_SQR) { tempnode = minenode->next; minestart->formationinfo = NULL; listRemoveNode(&minestart->formationLink); minenode = tempnode; continue; } minenode = minenode->next; } } } ret: node = node->next; } }
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; } } }
/*----------------------------------------------------------------------------- Name : gcAddChatItemToList Description : this function adds a chat item to the chat history list Inputs : chat item to add. Outputs : none Return : none ----------------------------------------------------------------------------*/ void gcAddChatItemToList(chathistory *chat) { sdword width, nCharacters, addwidth, length; char temp[256]; chathistory *wrap; color col; switch (chat->messageType) { case GC_NORMALMESSAGE: { sprintf(temp,"<%s> ",playerNames[chat->playerindex]); width = fontWidth(temp); col = gcGameNormalChatColor; } break; case GC_WHISPEREDMESSAGE: { sprintf(temp,"<%s>%s ",playerNames[chat->playerindex], strGetString(strWhisperedMessage)); width = fontWidth(temp); col = gcGamePrivateChatColor; } break; case GC_WRAPMESSAGE: { width = chat->indent; col = chat->col; } break; case GC_TEXTMESSAGE: { width = 0; col = chat->col; } break; default: { width = 0; } break; } if (width+fontWidth(chat->chatstring) > chatwidth) { wrap = (chathistory *)memAlloc(sizeof(chathistory),"InGameChat",NonVolatile); strcpy(wrap->userName, chat->userName); wrap->playerindex = chat->playerindex; wrap->messageType = GC_WRAPMESSAGE; wrap->col = col; wrap->indent = 0; nCharacters = strlen(chat->chatstring); addwidth = fontWidth(chat->chatstring); while (nCharacters>0 && width + addwidth > chatwidth) { addwidth = fontWidthN(chat->chatstring,nCharacters); nCharacters--; } length = nCharacters; while ((chat->chatstring[nCharacters] != ' ') && (nCharacters > 0) ) { nCharacters--; } if (nCharacters == 0) { strcpy(wrap->chatstring, chat->chatstring + length); chat->chatstring[length] = 0; } else { strcpy(wrap->chatstring, chat->chatstring + nCharacters + 1); chat->chatstring[nCharacters] = 0; } listAddNodeBefore(chathistorylist.tail, &chat->link, chat); if (curPosition==chathistorylist.tail) { curPosition = curPosition->prev; } if (chathistorylist.num>GC_ChatHistoryMax) { if (curPosition == chathistorylist.head) { curPosition = curPosition->next; } listDeleteNode(chathistorylist.head); } gcAddChatItemToList(wrap); } else { listAddNodeBefore(chathistorylist.tail, &chat->link, chat); } if (curPosition==chathistorylist.tail) { curPosition = curPosition->prev; } if (chathistorylist.num>GC_ChatHistoryMax) { if (curPosition == chathistorylist.head) { curPosition = curPosition->next; } listDeleteNode(chathistorylist.head); } // reset = TRUE; }
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; } }