void DeCloakAllObjects(Ship *ship) { CloakGeneratorSpec *spec = (CloakGeneratorSpec *)ship->ShipSpecifics; Node *cloaknode; CloakStruct *cloakstruct; cloaknode = spec->CloakList.head; while(cloaknode != NULL) { cloakstruct = (CloakStruct *)listGetStructOfNode(cloaknode); bitSet(cloakstruct->spaceobj->flags,SOF_DeCloaking); if(bitTest(cloakstruct->spaceobj->flags, SOF_Cloaked)) { bitClear(cloakstruct->spaceobj->flags,SOF_Cloaked); if(cloakstruct->spaceobj->objtype == OBJ_ShipType) { //if object was a ship set objects decloaking time for cloak advagtage effect SpawnCloakingEffect((Ship *)cloakstruct->spaceobj, etgSpecialPurposeEffectTable[EGT_CLOAK_OFF]); ((Ship *) (cloakstruct->spaceobj))->shipDeCloakTime = universe.totaltimeelapsed; } } bitClear(cloakstruct->spaceobj->flags,SOF_Cloaking); cloaknode = cloaknode->next; } }
/*----------------------------------------------------------------------------- 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); }
/*----------------------------------------------------------------------------- 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 DefenseFighterDied(Ship *ship) { DefenseFighterSpec *spec = (DefenseFighterSpec *)ship->ShipSpecifics; Node *bulletnode; Node *tempnode; DefenseStruct *defensestruct; bulletnode = spec->DefenseList.head; dbgMessagef("\nDefenseFighter 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("\nDefense Dead: Deleting Laser from existance"); soundEventBurstStop(ship, &ship->gunInfo->guns[0]); } tempnode = bulletnode->next; listDeleteNode(bulletnode); //dbgMessagef("\nDefense Dead: Deleting defense node."); bulletnode = tempnode; } }
void DefenseFighterBulletRemoval(Bullet *bullettogoByeBye) { Node *shipnode = universe.ShipList.head; Node *defnode; Ship *ship; DefenseFighterSpec *spec; DefenseStruct *defstruct; while(shipnode != NULL) { ship = (Ship *) listGetStructOfNode(shipnode); if(ship->shiptype == DefenseFighter) { //ship is a defensefighter spec= (DefenseFighterSpec *)ship->ShipSpecifics; defnode = spec->DefenseList.head; while(defnode != NULL) { defstruct = (DefenseStruct *)listGetStructOfNode(defnode); if(defstruct->bullet == bullettogoByeBye) { //bullet is being killed, so stop targetting if(defstruct->LaserDead != TRUE) { defstruct->laser->timelived = 10000.0f; //if laser isn't dead if(defstruct->laser->effect != NULL) { univRemoveObjFromRenderList((SpaceObj *) defstruct->laser->effect); } defstruct->laser = NULL; //remove pointer to laser... defstruct->LaserDead = TRUE; //signify dead laser!!!!!!!!!! //dbgMessagef("Defense Targetted Bullet Died...timing out laser."); } defstruct->CoolDown = TRUE; //Start or continue cool down process defstruct->bullet = NULL; //set target to NULL so it isn't referenced again! defstruct->CoolDownTime = 0.0f; break; //done for this defense fighter...maybe more so can't return } defnode=defnode->next; } } shipnode = shipnode->next; } }
void CloakAddObjectsInProximity(Ship *cloakship) { Player *playerowner = cloakship->playerowner; Node *objnode = universe.ShipList.head; udword num = universe.ShipList.num; CloakGeneratorStatics *cloakgeneratorstatics; CloakGeneratorSpec *spec = (CloakGeneratorSpec *)cloakship->ShipSpecifics; //maybe don't need Ship *spaceobj; real32 distanceSqr; vector diff; cloakgeneratorstatics = (CloakGeneratorStatics *) ((ShipStaticInfo *)(cloakship->staticinfo))->custstatinfo; while (objnode != NULL) { spaceobj = (Ship *)listGetStructOfNode(objnode); //Rejections... dbgAssert(spaceobj->objtype == OBJ_ShipType); if (spaceobj->playerowner != playerowner) { goto nextnode; // must be players ship inorder to cloak } if( spaceobj->shiptype == SalCapCorvette) { if(((SalCapCorvetteSpec *)spaceobj->ShipSpecifics)->tractorBeam) { goto nextnode; } } if (bitTest(spaceobj->flags,SOF_Cloaked)) { goto nextnode; // if object is cloaked } if(bitTest(spaceobj->flags,SOF_Dead)) { goto nextnode; } if(spaceobj->shiptype == Mothership || spaceobj->shiptype == Carrier) { goto nextnode; } //add more rejections...like collision model. vecSub(diff,spaceobj->posinfo.position,cloakship->posinfo.position); distanceSqr = diff.x*diff.x + diff.y*diff.y + diff.z*diff.z; if(distanceSqr <= cloakgeneratorstatics->CloakingRadiusSqr) { CloakGeneratorAddObj(cloakship, (SpaceObj *) spaceobj); } nextnode: objnode = objnode->next; } }
void CloakGenerator_Fix(Ship *ship) { CloakGeneratorSpec *spec = (CloakGeneratorSpec *)ship->ShipSpecifics; Node *node = spec->CloakList.head; CloakStruct *cloakStruct; while (node != NULL) { cloakStruct = (CloakStruct *)listGetStructOfNode(node); cloakStruct->spaceobj = SpaceObjRegistryGetObj((sdword)cloakStruct->spaceobj); node = node->next; } }
void DefenseFighter_Fix(Ship *ship) { DefenseFighterSpec *spec = (DefenseFighterSpec *)ship->ShipSpecifics; Node *node = spec->DefenseList.head; DefenseStruct *defenseStruct; while (node != NULL) { defenseStruct = (DefenseStruct *)listGetStructOfNode(node); defenseStruct->bullet = SpaceObjRegistryGetBullet((sdword)defenseStruct->bullet); defenseStruct->laser = SpaceObjRegistryGetBullet((sdword)defenseStruct->laser); node = node->next; } }
void make_all_slaves_moving(Ship *ship) { Node *slavenode; Ship *slave; dbgAssertOrIgnore(ship->flags & SOF_Slaveable); //ship should be slaveable slavenode = ship->slaveinfo->slaves.head; while (slavenode != NULL) { slave = (Ship *) listGetStructOfNode(slavenode); slave->posinfo.isMoving = ISMOVING_MOVING | ISMOVING_ROTATING; slavenode = slavenode->next; } }
void DefenseFighter_Save(Ship *ship) { DefenseFighterSpec *spec = (DefenseFighterSpec *)ship->ShipSpecifics; Node *node = spec->DefenseList.head; sdword cur = 0; SaveInfoNumber(spec->DefenseList.num); while (node != NULL) { cur++; SaveDefenseStruct((DefenseStruct *)listGetStructOfNode(node)); node = node->next; } dbgAssertOrIgnore(cur == spec->DefenseList.num); }
void CloakGenerator_Save(Ship *ship) { CloakGeneratorSpec *spec = (CloakGeneratorSpec *)ship->ShipSpecifics; Node *node = spec->CloakList.head; sdword cur = 0; SaveInfoNumber(spec->CloakList.num); while (node != NULL) { cur++; SaveCloakStruct((CloakStruct *)listGetStructOfNode(node)); node = node->next; } dbgAssert(cur == spec->CloakList.num); }
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; } }
/*----------------------------------------------------------------------------- Name : NumberOfEasilyAccesibleRUs Description : returns total number of easily accesible RU's to player Inputs : Outputs : Return : returns total number of easily accesible RU's to player ----------------------------------------------------------------------------*/ sdword NumberOfEasilyAccesibleRUs(Player *player) { // for now, just return the total number of RU's. Node *objnode = universe.ResourceList.head; Resource *resource; sdword numRUs = 0; while (objnode != NULL) { resource = (Resource *)listGetStructOfNode(objnode); dbgAssertOrIgnore(resource->flags & SOF_Resource); numRUs += resource->resourcevalue; objnode = objnode->next; } return numRUs; }
/*----------------------------------------------------------------------------- Name : pingFindByFunction Description : Find a ping in the ping list by function Inputs : evalueate - the evaluation function of the ping to find Outputs : Return : First ping in list with that evaluate function or NULL if none ----------------------------------------------------------------------------*/ ping *pingFindByFunction(pingeval evaluate) { Node *thisNode; ping *thisPing; thisNode = pingList.head; while (thisNode != NULL) { //scan all pings thisPing = listGetStructOfNode(thisNode); if (thisPing->evaluate == evaluate) { return(thisPing); } thisNode = thisNode->next;; } return(NULL); }
/*----------------------------------------------------------------------------- Name : Reseaching Description : checks to see if the passed in tech is currently being researched. Inputs : tech Outputs : true false Return : bool ----------------------------------------------------------------------------*/ ResearchTopic *Researching(Player *player, TechnologyType tech) { PlayerResearchInfo *research=&player->researchinfo; ResearchTopic *topic; Node *walk; walk = research->listoftopics.head; // walk through list of topics being researched while (walk != NULL) { topic = (ResearchTopic *)listGetStructOfNode(walk); if (topic->techresearch == tech) return(topic); walk = walk->next; } return(NULL); }
//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; }
void wkTradeInit(void) { sdword index; Node *objnode = universe.ShipList.head; Ship *ship; real32 mass; index = 0; while (objnode != NULL) { ship = (Ship *)listGetStructOfNode(objnode); dbgAssertOrIgnore(ship->objtype == OBJ_ShipType); wkTradeShips[index].ship = ship; mass = ship->staticinfo->staticheader.mass / WK_MASS_SCALE; wkTradeShips[index].x = 0.0f; wkTradeShips[index].y = 0.0f; wkTradeShips[index].vx = 0.0f; wkTradeShips[index].vy = 0.0f; wkTradeShips[index].ang = 0.0f; wkTradeShips[index].vang = 0.0f; wkTradeShips[index].vangacc = WK_ANGULAR_ACC / fsqrt(mass); wkTradeShips[index].vangmax = WK_ANGULAR_MAXVEL / fsqrt(fsqrt(mass)); wkTradeShips[index].acc = WK_LINEAR_ACC / fsqrt(mass); wkTradeShips[index].maxvel = WK_LINEAR_MAXVEL; wkTradeShips[index].revacc = WK_LINEAR_REVACC / fsqrt(mass); wkTradeShips[index].strafeacc = WK_STRAFE_ACC / fsqrt(mass); wkTradeShips[index].controlthrust = 0; wkTradeShips[index].controlrot = 0; wkTradeShips[index].controlstrafe = 0; wkTradeShips[index].controlfire = 0; index++; objnode = objnode->next; } wkTradeShips[index].ship = NULL; }
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); } }
bool isbulletbeingtargeted(Ship *ship, Bullet *bullet) { DefenseFighterSpec *spec = (DefenseFighterSpec *)ship->ShipSpecifics; Node *bulletnode; DefenseStruct *defensestruct; bulletnode = spec->DefenseList.head; while(bulletnode != NULL) { defensestruct = (DefenseStruct *)listGetStructOfNode(bulletnode); if(defensestruct->bullet == bullet) { //bullet is in list //do laser update stuff here return(TRUE); } bulletnode = bulletnode->next; } //bullet wasn't in list return(FALSE); }
/*----------------------------------------------------------------------------- Name : pingBattlePingsCreate Description : Create a list of attack pings from a blob list Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void pingBattlePingsCreate(LinkedList *blobList) { Node *thisNode; blob *thisBlob; if (pingFindByFunction(pingBattlePingEvaluate) != NULL) { //if there are already battle pings active return; //don't create any new ones } thisNode = blobList->head; while (thisNode != NULL) { thisBlob = listGetStructOfNode(thisNode); if (thisBlob->flags & BTM_PieceOfTheAction) { //if there's action in this blob pingAttackPingsCreate(thisBlob); } thisNode = thisNode->next; } }
void defenseFighterAdjustLaser(Bullet *laser) { //calculates laser direction n' such for rendering... DefenseFighterSpec *spec; // DefenseFighterStatics *defensefighterstatics; Node *bulletnode; DefenseStruct *defensestruct; Ship *ship; vector tempvec; GunStatic *gunstatic; Gun *gun; vector positionInWorldCoordSys; if(laser->owner == NULL) return; ship = laser->owner; gun = &ship->gunInfo->guns[0]; gunstatic = gun->gunstatic; spec= (DefenseFighterSpec *)ship->ShipSpecifics; // 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->LaserDead == TRUE) { bulletnode = bulletnode->next; continue; } if(laser == defensestruct->laser) { dbgAssertOrIgnore(defensestruct->bullet != NULL); matMultiplyMatByVec(&positionInWorldCoordSys,&ship->rotinfo.coordsys,&gunstatic->position); vecAdd(laser->posinfo.position,positionInWorldCoordSys,ship->posinfo.position); vecSub(laser->lengthvec, defensestruct->bullet->posinfo.position, 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)); } return; } bulletnode = bulletnode->next; } //we shouldn't get to this point :) //dbgMessagef("Laser Drawn doesn't exist in defense fighter records."); //on further reflection..if we kill the laster...but it doesn't go bye bye, we might get here... }
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 : gcChatTextDraw Description : draws the chat history window and prompts for text entry. Inputs : standard draw callbacks. Outputs : none Return : void ----------------------------------------------------------------------------*/ void gcChatTextDraw(featom *atom, regionhandle region) { fonthandle oldfont; sdword x,y=region->rect.y0,lines=0; char temp[512], *string; Node *walk=NULL; chathistory *chat; if (!mrRenderMainScreen) return; oldfont = fontMakeCurrent(chathistoryfont); fontShadowSet(FS_SE, colBlack); if (InChatMode) { switch (MessageToAllies) { case GC_ChatToAllies: //sprintf(temp,"To Allies: "); string = strGetString(strToAllies); break; case GC_ChatToAll: //sprintf(temp,"Say: "); string = strGetString(strSay); break; case GC_RUTransfer: //sprintf(temp,"RU Amount: "); string = strGetString(strRUAmount); break; } x = region->rect.x0; fontPrint(x,y,colWhite,string); y+= fontHeight(" "); lines++; } if (curPosition != NULL) { walk = curPosition; } if (walk!=NULL) { do { x = region->rect.x0; chat = listGetStructOfNode(walk); switch (chat->messageType) { case GC_NORMALMESSAGE: { sprintf(temp,"<%s>",playerNames[chat->playerindex]); fontPrint(x,y,tpGameCreated.playerInfo[chat->playerindex].baseColor,temp); x+=fontWidth(temp); sprintf(temp," %s",chat->chatstring); fontPrint(x,y,gcGameNormalChatColor,temp); } break; case GC_WHISPEREDMESSAGE: { sprintf(temp,"<%s>",playerNames[chat->playerindex]); fontPrint(x,y,tpGameCreated.playerInfo[chat->playerindex].baseColor,temp); x+=fontWidth(temp); sprintf(temp, strGetString(strWhisperedMessage)); fontPrint(x,y,gcGameWhisperedColor, temp); x+=fontWidth(temp); sprintf(temp," %s",chat->chatstring); fontPrint(x,y,gcGamePrivateChatColor,temp); } break; case GC_TEXTMESSAGE: { fontPrint(x,y,chat->col,chat->chatstring); } break; case GC_BUFFERSTART: { if (ViewingBuffer) { //sprintf(temp,"^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^"); fontPrint(x,y,gcGameNormalChatColor,strGetString(strStartOfBuffer)); } } break; case GC_BUFFEREND: { if (ViewingBuffer) { //sprintf(temp,"v v v v v v v v v v v v v v v v v v v v v v v v"); fontPrint(x,y,gcGameNormalChatColor,strGetString(strEndOfBuffer)); } } break; case GC_WRAPMESSAGE: { x+= chat->indent; fontPrint(x,y,chat->col,chat->chatstring); } break; } y += fontHeight(" "); lines++; walk = walk->next; } while ((walk!=NULL) && (lines < maxlines)); if ((ScrollDownAutoBaby==NULL) && (!ViewingBuffer) && (curPosition->next != NULL)) { ScrollDownAutoBaby = taskCallBackRegister(gcScrollDownAuto, 0, NULL, GC_SCROLL_TIME); } } fontShadowSet(FS_NONE, colBlack); fontMakeCurrent(oldfont); }
/*----------------------------------------------------------------------------- Name : rmUpdateResearch Description : updates all research Inputs : none Outputs : none Return : void ----------------------------------------------------------------------------*/ void rmUpdateResearch(void) { sdword index, labindex, i; ResearchLab *lab; PlayerResearchInfo *research; ResearchTopic *topic; Node *walk; LinkedList deletelist; bool shipcanbuild[STD_LAST_SHIP]; listInit(&deletelist); // search through list of players for (index=0; index<universe.numPlayers; index++) { research = &universe.players[index].researchinfo; if (research->CanDoResearch) { walk = research->listoftopics.head; // walk through list of topics being researched while (walk != NULL) { topic = (ResearchTopic *)listGetStructOfNode(walk); topic->timeleft -= labdec[topic->numlabsresearching]; if (topic->timeleft < 0) { for (i = 0; i < STD_LAST_SHIP; i++) { shipcanbuild[i] = rmCanBuildShip(&(universe.players[index]), i); } // Insert sound for technology completed if (universe.players[index].race == R1) { speechEventFleet(STAT_F_Research_R1_Completed, topic->techresearch, index); } else if (universe.players[index].race == R2) { speechEventFleet(STAT_F_Research_R2_Completed, topic->techresearch, index); } topic->timeleft = 0; research->HasTechnology |= TechToBit(topic->techresearch); listRemoveNode(&topic->link); listAddNode(&deletelist,&topic->link,topic); for (labindex=0; labindex<NUM_RESEARCHLABS; labindex++) { lab = &research->researchlabs[labindex]; if (lab->topic==topic) { lab->labstatus = LS_NORESEARCHITEM; lab->topic = NULL; if (rmGUIActive) rmClearLab(labindex); } } for (i = 0; i < STD_LAST_SHIP; i++) { if (shipcanbuild[i] != rmCanBuildShip(&(universe.players[index]), i)) { speechEventFleet(STAT_F_Research_CompletedShip, i, index); if (cmActive) { cmUpdateShipsAvailable(); } } } if (singlePlayerGame && (index == 0)) { tmTechForSale[topic->techresearch] = TM_TECH_IS_ALREADY_OWNED; } if (rmGUIActive) rmUpdateTechList(); } walk = walk->next; } listDeleteAll(&deletelist); } } }
void ResearchShipDied(Ship *ship) { ResearchShipSpec *spec = (ResearchShipSpec *)ship->ShipSpecifics; Node *shipnode = universe.ShipList.head; Ship *obj; MaxSelection selection; //need to slow down/stop first research ship and turn it into a new master! if(ship->dockvars.reserveddocking != -1) { sdword dockpointindex; CommandToDo *command = getShipAndItsCommand(&universe.mainCommandLayer,ship); if(command != NULL) { if(command->ordertype.order == COMMAND_DOCK) { if(command->dock.dockType != DOCK_FOR_RETIRE) { dockpointindex = ship->dockvars.dockstaticpoint->dockindex; dbgAssertOrIgnore(ship->dockvars.reserveddocking == (sbyte)dockpointindex); ship->dockvars.reserveddocking = -1; if(spec->dockwith != NULL) { dbgAssertOrIgnore(spec->dockwith->dockInfo->dockpoints[dockpointindex].thisDockBusy > 0); spec->dockwith->dockInfo->dockpoints[dockpointindex].thisDockBusy--; } } } } } if(spec->dockwith != NULL) { if(ship->shiprace == R1) { ((ResearchShipSpec *)spec->dockwith->ShipSpecifics)->seed = TRUE; //set correct seeding ((ResearchShipSpec *)spec->dockwith->ShipSpecifics)->done = FALSE; } else { ((ResearchShipSpec *)spec->dockwith->ShipSpecifics)->seed = TRUE; //set correct seeding ((ResearchShipSpec *)spec->dockwith->ShipSpecifics)->done = FALSE; } } selection.numShips = 0; if(ship->flags & SOF_Slaveable) { //ship is slaved if(ship->slaveinfo->flags & SF_MASTER) { //ship is a master //ship that died is a master! no worries while(shipnode != NULL) { obj = (Ship *) listGetStructOfNode(shipnode); if(obj->shiptype == ResearchShip) { if(obj->playerowner == ship->playerowner) { if(!bitTest(obj->flags,SOF_Slaveable)) { if(obj != ship) { CommandToDo *command = getShipAndItsCommand(&universe.mainCommandLayer,obj); if(command != NULL && command->ordertype.order == COMMAND_DOCK && (command->dock.dockType & DOCK_FOR_RETIRE||command->dock.dockType & DOCK_PERMANENTLY)) { //don't reorder a dock for research } else if(obj->flags & SOF_Dead) { } else if(!bitTest(obj->flags,SOF_Dead)) { //as long as ship isn't considered dead //need better method CleanResearchShip(obj); selection.ShipPtr[selection.numShips] = obj; selection.numShips++; } } } } } shipnode = shipnode->next; } } else { //ship that died isn't a master } } else { while(shipnode != NULL) { obj = (Ship *) listGetStructOfNode(shipnode); if(obj->shiptype == ResearchShip) { if(obj->playerowner == ship->playerowner) { if(obj != ship) { if(((ResearchShipSpec *) obj->ShipSpecifics)->dockordernumber > spec->dockordernumber) { CommandToDo *command = getShipAndItsCommand(&universe.mainCommandLayer,obj); if(command != NULL && command->ordertype.order == COMMAND_DOCK && (command->dock.dockType & DOCK_FOR_RETIRE||command->dock.dockType & DOCK_PERMANENTLY)) { //don't reorder a dock for research } else if(obj->flags & SOF_Dead) { } else { if(obj->dockvars.reserveddocking != -1) { sdword dockpointindex; dockpointindex = obj->dockvars.dockstaticpoint->dockindex; dbgAssertOrIgnore(obj->dockvars.reserveddocking == (sbyte)dockpointindex); obj->dockvars.reserveddocking = -1; //dbgAssertOrIgnore(((ResearchShipSpec *) obj->ShipSpecifics)->dockwith->dockInfo->dockpoints[dockpointindex].thisDockBusy > 0); if (((ResearchShipSpec *) obj->ShipSpecifics)->dockwith) // Bryce did I fix this right by putting in this check dockwith != NULL ((ResearchShipSpec *) obj->ShipSpecifics)->dockwith->dockInfo->dockpoints[dockpointindex].thisDockBusy = 0; } CleanResearchShip(obj); dbgAssertOrIgnore(selection.numShips < COMMAND_MAX_SHIPS); selection.ShipPtr[selection.numShips] = obj; selection.numShips++; //ship->dockInfo->dockpoints[shippointindex].thisDockBusy = 0; //artificially busy point //selection.ShipPtr[selection.numShips] = obj; //selection.numShips++; } } } } } shipnode = shipnode->next; } } if(selection.numShips >= 1) { clDock(&universe.mainCommandLayer, (SelectCommand *)&selection, DOCK_FOR_RESEARCH, NULL); } }
/*----------------------------------------------------------------------------- Name : aihHarassNumbersLowHandler Description : Handles the harass team being decimated Inputs : team - the team being decimated Outputs : Return : void ----------------------------------------------------------------------------*/ void aihHarassNumbersLowHandler(AITeam *team) { AITeamMove *thisMove = team->curMove, *newMove; AlternativeShips alternatives; vector gathering_point; vector origin = ORIGIN_VECTOR; //commented code is the reinforce type numbers low handler /* udword i; for (i = 0; i < aiCurrentAIPlayer->numGuardTeams; i++) { //later need to actually remove team from guardTeams array if (bitTest(aiCurrentAIPlayer->guardTeams[i]->teamFlags, FAST_ROVING_GUARD) && (aiCurrentAIPlayer->guardTeams[i]->shipList.selection->numShips)) { bitClear(aiCurrentAIPlayer->guardTeams[i]->teamFlags, FAST_ROVING_GUARD); aiCurrentAIPlayer->guardTeams[i]->curMove = aimCreateReinforce(aiCurrentAIPlayer->guardTeams[i], team, TRUE, FALSE); aimCreateMoveDone(aiCurrentAIPlayer->guardTeams[i], FALSE, FALSE); return; } } */ //later maybe change to "reinforce" move, maybe along with harass team getting out //of there to attack someone else. //later - very important to get the same ships that were requested in the first place // this isn't all that "generic" if (aiCurrentAIPlayer->player->PlayerMothership) { gathering_point = aiCurrentAIPlayer->player->PlayerMothership->posinfo.position; } else { vecZeroVector(gathering_point); } while ((thisMove->type == MOVE_ATTACK) || (thisMove->type == MOVE_ADVANCEDATTACK)) { if (thisMove->remove) { aitDeleteCurrentMove(team); } else { team->curMove = (AITeamMove *)listGetStructOfNode(team->curMove->listNode.next); } thisMove = team->curMove; dbgAssert(thisMove); } gathering_point = aiuFindRangeStandoffPoint(gathering_point,origin, AIH_HARASS_NUMLOW_STANDOFF_DIST); thisMove->processing = FALSE; thisMove->events.numbersLow.triggered = FALSE; //add a move, getships, formation newMove = aimCreateMoveTeamNoAdd(team, gathering_point, AIH_HARASS_NUMLOW_FORMATION, FALSE, TRUE); //band-aid solution... change moveteam move so that tactics are there... newMove->tactics = Evasive; aitAddmoveBeforeAndMakeCurrent(team, newMove, thisMove); SetNumAlternatives(alternatives,2); SetAlternative(alternatives,0,HeavyInterceptor,HARASS_HEAVYINT_EQUIVNUM); SetAlternative(alternatives,1,AttackBomber, HARASS_BOMBER_EQUIVNUM); newMove = aimCreateFancyGetShipsNoAdd(team, LightInterceptor, 16, &alternatives, REQUESTSHIPS_HIPRI, TRUE, TRUE); listAddNodeBefore(&(thisMove->listNode), &(newMove->listNode), newMove); bitClear(team->teamFlags, TEAM_NEEDS_SUPPORT); }
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 wkTradeUpdate(void) { Ship *ship; Resource *resource; wkTradeType *trader; real32 vel; vector vect; //sword index; Node *objnode; objnode = universe.ShipList.head; if (wkTradeControlShip) { wkTradeControl(); trader = wkTradeControlShip; ship = trader->ship; //dbgAssertOrIgnore(ship->objtype == OBJ_ShipType); if (ship->objtype != OBJ_ShipType) { //ship has exploded wkTradeControlShip = NULL; } if (trader->controlthrust) { if (trader->controlthrust > 0) { trader->vx += fcos(trader->ang)*trader->acc; trader->vy += fsin(trader->ang)*trader->acc; } else { trader->vx -= fcos(trader->ang)*trader->revacc; trader->vy -= fsin(trader->ang)*trader->revacc; } } if (trader->controlstrafe) { trader->vx += fsin(trader->ang) *trader->acc*trader->controlstrafe; trader->vy += fcos(trader->ang) *trader->acc*trader->controlstrafe; } if (trader->controlfire) { Ship *ship = trader->ship; ShipStaticInfo *shipstatic = (ShipStaticInfo *)ship->staticinfo; if (shipstatic->custshipheader.CustShipFire != NULL) { shipstatic->custshipheader.CustShipFire(ship,NULL); } } vel = fsqrt(trader->vx*trader->vx + trader->vy*trader->vy); if (vel > trader->maxvel) { trader->vx *= trader->maxvel/vel; trader->vy *= trader->maxvel/vel; } trader->x += trader->vx; trader->y += trader->vy; trader->ang += trader->vang; if (trader->controlrot) { trader->vang += trader->controlrot*trader->vangacc; if (ABS(trader->vang) > trader->vangmax) { if (trader->vang>0) trader->vang = trader->vangmax; else trader->vang = -trader->vangmax; } } else { if (ABS(trader->vang) < trader->vangacc) { trader->vang = 0.0f; } else { if (trader->vang > 0) trader->vang -= trader->vangacc; else trader->vang += trader->vangacc; } } ship->posinfo.position.x = trader->x; ship->posinfo.position.y = trader->y; ship->posinfo.position.z = 0.0f; ship->posinfo.velocity.x = trader->vx*WK_VEL_SCALE; ship->posinfo.velocity.y = trader->vy*WK_VEL_SCALE; vect.x = fcos(trader->ang); vect.y = fsin(trader->ang); vect.z = 0; matCreateCoordSysFromHeading(&ship->rotinfo.coordsys,&vect); } //now update all ships objnode = universe.ShipList.head; while (objnode != NULL) { ship = (Ship *)listGetStructOfNode(objnode); dbgAssertOrIgnore(ship->objtype == OBJ_ShipType); ship->posinfo.position.z = 0.0f; objnode = objnode->next; } //resources objnode = universe.ResourceList.head; while (objnode != NULL) { resource = (Resource *)listGetStructOfNode(objnode); dbgAssertOrIgnore(resource->flags & SOF_Resource); resource->posinfo.position.z = 0.0f; objnode = objnode->next; } }