Beispiel #1
0
/*-----------------------------------------------------------------------------
    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;
    }
}
Beispiel #3
0
/*-----------------------------------------------------------------------------
    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;
    }
}
Beispiel #4
0
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);
    }
}
Beispiel #5
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;
    }
}
Beispiel #6
0
/*-----------------------------------------------------------------------------
    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;
    }
}
Beispiel #7
0
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);
    }
}
Beispiel #8
0
/*-----------------------------------------------------------------------------
    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;
        }

    }

}
Beispiel #12
0
/*-----------------------------------------------------------------------------
    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;
}
Beispiel #13
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;
    }
}