/*----------------------------------------------------------------------------- Name : gcStartup Description : This initializes the game chatting system, adding its regions to the game etc. Inputs : Outputs : Return : void ----------------------------------------------------------------------------*/ void gcStartup(void) { chathistory *dummy; chathistoryfont = frFontRegister(chathistoryfontname); listInit(&chathistorylist); dummy = memAlloc(sizeof(chathistory), "DummyChatThing", NonVolatile); dummy->messageType = GC_BUFFERSTART; listAddNode(&chathistorylist,&dummy->link,dummy); dummy = memAlloc(sizeof(chathistory), "DummyChatThing", NonVolatile); dummy->messageType = GC_BUFFEREND; listAddNode(&chathistorylist,&dummy->link,dummy); curPosition = &dummy->link; chatmutex = (void *)CreateMutex(NULL,FALSE,NULL); if (chatdrawregion!=NULL) { regChildInsert(chatdrawregion, ghMainRegion); } else { feScreensLoad(GC_FIBFile); feCallbackAddMultiple(gcCallBack); feDrawCallbackAddMultiple(gcDrawCallback); gcScreenHandle = feScreenFind("Say_Chatting_Screen"); chatdrawatom.x = gcScreenHandle->atoms[0].x; chatdrawatom.y = gcScreenHandle->atoms[0].y; chatdrawatom.width = gcScreenHandle->atoms[0].width; chatdrawatom.height = gcScreenHandle->atoms[0].height; chatdrawatom.pData = (char *)gcChatTextDraw; chatwidth = chatdrawatom.width; textentrypos.x0 = gcScreenHandle->atoms[1].x; textentrypos.y0 = gcScreenHandle->atoms[1].y; textentrypos.x1 = gcScreenHandle->atoms[1].x+gcScreenHandle->atoms[1].width; textentrypos.y1 = gcScreenHandle->atoms[1].y+gcScreenHandle->atoms[1].height; chatdrawregion = regChildAlloc(ghMainRegion, (sdword)&chatdrawatom, chatdrawatom.x, chatdrawatom.y, chatdrawatom.width, chatdrawatom.height, 0, 0); chatdrawatom.region = (void*)chatdrawregion; regDrawFunctionSet(chatdrawregion, feUserRegionDraw); chatdrawregion->drawstyle[0] = chatdrawatom.drawstyle[0]; chatdrawregion->drawstyle[1] = chatdrawatom.drawstyle[1]; chatdrawregion->atom = &chatdrawatom; } gcRunning=TRUE; }
/*----------------------------------------------------------------------------- Name : pingCreate Description : Create a ping Inputs : loc - location to create the ping at. Ping will not move owner - optional object about which to postion a ping. Ping will move with the object. May be NULL. evaluate - function to evaluate the ping. userDataSize - extra memory to allocate for user data, such as a ship list. userID - number to pass back to evaluation function. Outputs : userData - pointer to extra memory as allocated with the ping structure. Return : Pointer to newly allocated ping structure. ----------------------------------------------------------------------------*/ ping *pingCreate(vector *loc, SpaceObj *owner, pingeval evaluate, ubyte **userData, sdword userDataSize, udword userID) { ping *newPing; newPing = memAlloc(sizeof(ping) + userDataSize, "Ping!", Pyrophoric); listAddNode(&pingList, &newPing->link, newPing); newPing->c = colWhite; newPing->size = 1.0f; newPing->minScreenSize = 10; newPing->minSize = 0.0f; if (owner == NULL) { newPing->centre = *loc; } else { newPing->centre = owner->posinfo.position; } newPing->owner = owner; newPing->creationTime = universe.totaltimeelapsed; newPing->pingDuration = 1.0f; newPing->interPingPause = 0.0f; newPing->evaluatePeriod = PNG_TaskPeriod; newPing->lastEvaluateTime = universe.totaltimeelapsed; newPing->evaluate = evaluate; newPing->userDataSize = userDataSize; newPing->userID = userID; newPing->TOMask = 0; if (userData != NULL) { *userData = (ubyte *)(newPing + 1); } return(newPing); }
void graphLinkVertices(Graph *G, GVertex *source, GVertex *destination, int weight, Generic ExtraInfo) { GEdge *a=NULL; NodeList *pNodo=NULL; a = (GEdge *)malloc(sizeof(GEdge)); if(a) { a->source = source; a->destination = destination; a->weight = weight; a->ExtraInfo = ExtraInfo; pNodo=nodeListNew(a); if(pNodo) { listAddNode(source->LAdjacents, pNodo); } else { free(a); a = NULL; } } }
AITeamMove *aimCreateGuardCooperatingTeam(AITeam *team, bool8 wait, bool8 remove) { AITeamMove *newMove = aimCreateGuardCooperatingTeamNoAdd(team, wait, remove); listAddNode(&(team->moves), &(newMove->listNode), newMove); return newMove; }
void listAddNext(List *L, NodeList *p, NodeList *newNode){ if(!listNodeExists(L, p)) return; else if(p == L->last) listAddNode(L, newNode); else{ newNode->next = p->next; p->next = newNode; } }
AITeamMove *aimCreateLaunch(AITeam *team, bool8 wait, bool8 remove) { AITeamMove *newMove; newMove = aimCreateLaunchNoAdd(team, wait, remove); listAddNode(&(team->moves), &(newMove->listNode), newMove); return newMove; }
void graphAddVertex(Graph *G, GVertex *v) { NodeList *pNode=NULL; pNode = nodeListNew(v); if(pNode) { listAddNode(G, pNode); } }
AITeamMove *aimCreateFormation(AITeam *team, TypeOfFormation formationtype, bool8 wait, bool8 remove) { AITeamMove *newMove; newMove = aimCreateFormationNoAdd(team, formationtype, wait, remove); listAddNode(&(team->moves), &(newMove->listNode), newMove); return newMove; }
AITeamMove *aimCreateSpecial(AITeam *team, SelectCommand *targets,TypeOfFormation formation, TacticsType tactics, bool8 wait, bool8 remove) { AITeamMove *newMove; newMove = aimCreateSpecialNoAdd(team, targets, formation, tactics, wait, remove); listAddNode(&(team->moves), &(newMove->listNode), newMove); return newMove; }
AITeamMove *aimCreateKamikaze(AITeam *team, SelectCommand *targets,TypeOfFormation formation, bool8 wait, bool8 remove) { AITeamMove *newMove; newMove = aimCreateKamikazeNoAdd(team, targets, formation, wait, remove); listAddNode(&(team->moves), &(newMove->listNode), newMove); return newMove; }
AITeamMove *aimCreateFancyGetShips(AITeam *team, ShipType shiptype, sbyte num_ships, AlternativeShips *alternatives, sdword priority, bool8 wait, bool8 remove) { AITeamMove *newMove; dbgAssert(num_ships > 0); newMove = aimCreateFancyGetShipsNoAdd(team, shiptype, num_ships, alternatives, priority, wait, remove); listAddNode(&(team->moves), &(newMove->listNode), newMove); return newMove; }
List *listReadFile(char *fileName, readfn readLine){ List *L = listNew(); FILE *F = fopen(fileName, "r"); if (F==NULL) return(NULL); while(!feof(F)){ Generic g; g = readLine(F); if(!feof(F)) listAddNode(L, nodeListNew(g)); } return L; }
AITeamMove *aimCreateMoveDone(AITeam *team, bool8 wait, bool8 remove) { TypeOfFormation formation = SAME_FORMATION; AITeamMove *newMove = (AITeamMove *)memAlloc(sizeof(AITeamMove), "movedone", 0); InitNewMove(newMove,MOVE_DONE,wait,remove,formation,Neutral,aimProcessMoveDone,NULL,NULL); // aiplayerLog((aiIndex,"Created Move Done Move")); listAddNode(&(team->moves), &(newMove->listNode), newMove); return newMove; }
long DLLCALL listAddNodes(link_list_t* list, void** data, list_node_tag_t* tag, list_node_t* after) { long i; list_node_t* node=NULL; if(data==NULL) return(-1); for(i=0; data[i]!=NULL ; i++) if((node=listAddNode(list,data[i],tag==NULL ? LIST_NODE_TAG_DEFAULT : *(tag++),node==NULL ? after:node))==NULL) return(i); return(i); }
BabyCallBack *taskCallBackRegister(babyFuncCB callback, udword num, void *data, real32 callintime) { BabyCallBack *baby; //(maybe do check of time to see if it is volatile?) baby = memAlloc(sizeof(BabyCallBack), "BabyCallBack", Volatile); baby->babyCallBackFunc = callback; baby->numparm = num; baby->dataparm = data; baby->timeToExecute = callintime; baby->timeStarted = taskTimeElapsed; listAddNode(&callbacks.babies, &baby->babylink,baby); return(baby); }
void pingLoad(void) { sdword i; sdword num; ping *tping; num = LoadInfoNumber(); dbgAssert(pingList.num == 0); for (i=0;i<num;i++) { tping = LoadAndFixAnomalyPing(); listAddNode(&pingList, &tping->link, tping); } }
long DLLCALL listAddNodeList(link_list_t* list, const link_list_t* src, list_node_t* after) { long count=0; list_node_t* node=NULL; list_node_t* src_node; if(src==NULL) return(-1); for(src_node=src->first; src_node!=NULL; src_node=src_node->next, count++) { if((node=listAddNode(list, src_node->data, src_node->tag, node==NULL ? after:node))==NULL) return(count); node->flags = src_node->flags; } return(count); }
void DefenseFighter_Load(Ship *ship) { DefenseFighterSpec *spec = (DefenseFighterSpec *)ship->ShipSpecifics; sdword num; sdword i; DefenseStruct *defenseStruct; num = LoadInfoNumber(); listInit(&spec->DefenseList); for (i=0;i<num;i++) { defenseStruct = LoadDefenseStruct(); listAddNode(&spec->DefenseList,&defenseStruct->bulletnode,defenseStruct); } }
void CloakGenerator_Load(Ship *ship) { CloakGeneratorSpec *spec = (CloakGeneratorSpec *)ship->ShipSpecifics; sdword num; sdword i; CloakStruct *cloakStruct; num = LoadInfoNumber(); listInit(&spec->CloakList); for (i=0;i<num;i++) { cloakStruct = LoadCloakStruct(); listAddNode(&spec->CloakList,&cloakStruct->cloaknode,cloakStruct); } }
list_node_t* DLLCALL listAddNodeData(link_list_t* list, const void* data, size_t length, list_node_tag_t tag, list_node_t* after) { list_node_t* node; void* buf; if((buf=malloc(length))==NULL) return(NULL); memcpy(buf,data,length); if((node=listAddNode(list,buf,tag,after))==NULL) { free(buf); return(NULL); } node->flags |= LINK_LIST_MALLOC; return(node); }
link_list_t* DLLCALL listExtract(link_list_t* dest_list, const list_node_t* node, long max) { long count; link_list_t* list; if(node==NULL || node->list==NULL) return(NULL); if((list=listInit(dest_list, node->list->flags))==NULL) return(NULL); for(count=0; count<max && node!=NULL; node=node->next) { listAddNode(list, node->data, node->tag, list->last); count++; } return(list); }
list_node_t* DLLCALL listAddNodeString(link_list_t* list, const char* str, list_node_tag_t tag, list_node_t* after) { list_node_t* node; char* buf; if(str==NULL) return(NULL); if((buf=strdup(str))==NULL) return(NULL); if((node=listAddNode(list,buf,tag,after))==NULL) { free(buf); return(NULL); } node->flags |= LINK_LIST_MALLOC; return(node); }
/*----------------------------------------------------------------------------- Name : rmAssignPlayersLabToResearch Description : assigns a lab to a certain research item Inputs : Lab number, research topic number Outputs : none Return : void ----------------------------------------------------------------------------*/ void rmAssignPlayersLabToResearch(Player *player, sdword labnumber, TechnologyType tech) { ResearchTopic *topic; if ((topic=Researching(player, tech))!=NULL) { player->researchinfo.researchlabs[labnumber].labstatus = LS_RESEARCHITEM; player->researchinfo.researchlabs[labnumber].topic = topic; topic->numlabsresearching++; } else { topic = (ResearchTopic *)memAlloc(sizeof(ResearchTopic),"ResearchTopic",NonVolatile); listAddNode(&player->researchinfo.listoftopics, &topic->link, topic); player->researchinfo.researchlabs[labnumber].labstatus = LS_RESEARCHITEM; player->researchinfo.researchlabs[labnumber].topic = topic; topic->numlabsresearching = 1; topic->techresearch = tech; topic->timeleft = (real32)player->researchinfo.techstat->TimeToComplete[tech]; } if ((player == universe.curPlayerPtr)&&(rmGUIActive)) rmUpdateTechList(); }
void CloakGeneratorAddObj(Ship *ship, SpaceObj *objtoadd) { //Adds shiptoadd to 'ship's cloaklist CloakGeneratorSpec *spec = (CloakGeneratorSpec *)ship->ShipSpecifics; CloakStruct *newcloakstruct; if (bitTest(objtoadd->flags,SOF_Cloaked) || bitTest(objtoadd->flags, SOF_Cloaking) || bitTest(objtoadd->flags, SOF_DeCloaking)) { //if object is cloaked, don't add it...don't even think about it. return; } newcloakstruct = memAlloc(sizeof(CloakStruct),"CloakStruct",0); newcloakstruct->CloakStatus = 0.0f; newcloakstruct->spaceobj = objtoadd; listAddNode(&spec->CloakList,&newcloakstruct->cloaknode,newcloakstruct); //temporary...later make 'cloaking' bitSet(objtoadd->flags, SOF_Cloaking); bitSet(objtoadd->flags, SOF_CloakGenField); //indicate object is in cloak field //should not have to clear the cloaked flag bitClear(objtoadd->flags, SOF_Cloaked); // bitClear(objtoadd->flags, SOF_DeCloaking); }
/*----------------------------------------------------------------------------- Name : primCreateNewCircleVerticeArray Description : Creates a set of vertices defining a unit circle around the axis given Inputs : nSlices - the number of polygons in the unit circle, axis - the axis around which the circle is drawn Outputs : Allocates some memory and stuff Return : the new vertice array ----------------------------------------------------------------------------*/ vertice_array *primCreateNewCircleVerticeArray(sdword nSlices, uword axis) { udword i; double theta = 0.0; vertice_array *vertices = (vertice_array *)memAlloc(sizeofverticearray(nSlices+1), "circle_vertices", NonVolatile); vertices->num_vertices = nSlices + 1; vertices->axis = axis; for (i = 0; i < vertices->num_vertices; i++) { switch (axis) { case X_AXIS: vertices->vertice[i].x = 0.0; vertices->vertice[i].y = (real32)(cos(theta)); vertices->vertice[i].z = (real32)(sin(theta)); break; case Y_AXIS: vertices->vertice[i].x = (real32)(sin(theta)); vertices->vertice[i].y = 0.0; vertices->vertice[i].z = (real32)(cos(theta)); break; case Z_AXIS: vertices->vertice[i].x = (real32)(sin(theta)); vertices->vertice[i].y = (real32)(cos(theta)); vertices->vertice[i].z = 0.0; break; } theta += 2.0 * PI / (double)nSlices; } listAddNode(&CircleList, &vertices->node, vertices); return vertices; }
bool MinelayerCorvetteStaticMineDrop(Ship *ship,SpaceObjRotImpTarg *target) { MinelayerCorvetteStatics *minelayercorvettestatics; MinelayerCorvetteSpec *spec = (MinelayerCorvetteSpec *)ship->ShipSpecifics; sdword flag; GunInfo *guninfo = ship->gunInfo; Gun *gun0,*gun1; real32 time; sdword maxmis; minelayercorvettestatics = (MinelayerCorvetteStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; gun0 = ((Gun *) &(ship->gunInfo->guns[0])); maxmis = gun0->gunstatic->maxMissiles; if(ship->gunInfo->numGuns > 1) { //ship has 2 guns (race 1) gun1 = ((Gun *) &(ship->gunInfo->guns[1])); if(gun0->numMissiles == 0 && gun1->numMissiles == 0) return FALSE; if((universe.totaltimeelapsed - gun1->lasttimefired) < minelayercorvettestatics->gunReFireTime && (universe.totaltimeelapsed - gun0->lasttimefired) < minelayercorvettestatics->gunReFireTime) { return(FALSE); } maxmis += gun1->gunstatic->maxMissiles; } else { if(gun0->numMissiles == 0) return FALSE; if((universe.totaltimeelapsed - gun0->lasttimefired) < minelayercorvettestatics->gunReFireTime) return(FALSE); } switch(spec->MiningStatus) { case FIRST_OFF: ////////////////////// //speech event for forcedropped mines //event num: COMM_MLVette_ForceDrop //use battle chatter if(ship->playerowner->playerIndex == universe.curPlayerIndex) { if (battleCanChatterAtThisTime(BCE_COMM_MLVette_ForceDrop, ship)) { battleChatterAttempt(SOUND_EVENT_DEFAULT, BCE_COMM_MLVette_ForceDrop, ship, SOUND_EVENT_DEFAULT); } } ///////////////////////// spec->MiningStatus = FIRST_OFF2; case FIRST_OFF2: if(aitrackZeroRotationAnywhere(ship)) { flag = 2; } if(aitrackZeroVelocity(ship)) { if(flag == 2) { //we're ready for next step MineFormationInfo *mineformationinfo; aitrackForceSteadyShip(ship); //stop movement, stop rotation spec->MiningStatus = BEGIN_WALL_DROP_RIGHT; spec->MiningSideMax = 1; spec->MiningSideCount = 0; matGetVectFromMatrixCol1(spec->formation_up,ship->rotinfo.coordsys); matGetVectFromMatrixCol2(spec->formation_right,ship->rotinfo.coordsys); vecScalarMultiply(spec->formation_up, spec->formation_up, minelayercorvettestatics->MineSpacing); vecScalarMultiply(spec->formation_down, spec->formation_up, -1.0f); vecScalarMultiply(spec->formation_right,spec->formation_right,minelayercorvettestatics->MineSpacing); vecScalarMultiply(spec->formation_left,spec->formation_right,-1.0f); matGetVectFromMatrixCol3(spec->formation_heading,ship->rotinfo.coordsys); vecScalarMultiply(spec->formation_heading,spec->formation_heading,-minelayercorvettestatics->MineDropDistance); //Create Formation Entity Here mineformationinfo = memAlloc(sizeof(MineFormationInfo),"MineFormationInfo",NonVolatile); listAddNode(&universe.MineFormationList,&(mineformationinfo->FormLink),mineformationinfo); listInit(&mineformationinfo->MineList); mineformationinfo->playerowner = ship->playerowner; mineformationinfo->FULL = FALSE; mineformationinfo->wallstate = PULSE_START; mineformationinfo->effect = NULL; spec->mineforminfo = mineformationinfo; time = 29.0; spec->mineforminfo->waittime = time; //set wait time for each pulse spec->formation_number_X = 0; spec->formation_number_Y = 0; vecAdd(spec->formation_position,ship->posinfo.position,spec->formation_heading); spec->mineaistate = MINE_DROP_FORMATION; MinelayerCorvetteFire(ship,target); spec->MineDropNumber = 1; } } break; case BEGIN_WALL_DROP_RIGHT: vecAddTo(spec->formation_position,spec->formation_right); spec->mineaistate = MINE_DROP_FORMATION; MinelayerCorvetteFire(ship,target); spec->MineDropNumber++; spec->formation_number_X++; spec->MiningSideCount++; if(spec->MiningSideCount == spec->MiningSideMax) { spec->MiningSideCount = 0; spec->MiningStatus = BEGIN_WALL_DROP_UP; } break; case BEGIN_WALL_DROP_UP: vecAddTo(spec->formation_position,spec->formation_up); spec->mineaistate = MINE_DROP_FORMATION; MinelayerCorvetteFire(ship,target); spec->MineDropNumber++; spec->formation_number_Y++; spec->MiningSideCount++; if(spec->MiningSideCount == spec->MiningSideMax) { spec->MiningSideMax++; spec->MiningSideCount = 0; spec->MiningStatus = BEGIN_WALL_DROP_LEFT; } break; case BEGIN_WALL_DROP_LEFT: vecAddTo(spec->formation_position,spec->formation_left); spec->mineaistate = MINE_DROP_FORMATION; MinelayerCorvetteFire(ship,target); spec->MineDropNumber++; spec->formation_number_X--; spec->MiningSideCount++; if(spec->MiningSideCount == spec->MiningSideMax) { spec->MiningSideCount = 0; spec->MiningStatus = BEGIN_WALL_DROP_DOWN; } break; case BEGIN_WALL_DROP_DOWN: vecAddTo(spec->formation_position,spec->formation_down); spec->mineaistate = MINE_DROP_FORMATION; MinelayerCorvetteFire(ship,target); spec->MineDropNumber++; spec->formation_number_Y--; spec->MiningSideCount++; if(spec->MiningSideCount == spec->MiningSideMax) { spec->MiningSideMax++; spec->MiningSideCount = 0; spec->MiningStatus = BEGIN_WALL_DROP_RIGHT; } break; case DONE_WAIT: spec->mineaistate = MINE_DROP_ATTACK; return TRUE; break; } if(spec->MineDropNumber == minelayercorvettestatics->NumMinesInSide*minelayercorvettestatics->NumMinesInSide) { if(spec->mineforminfo != NULL) { spec->mineforminfo->FULL = TRUE; spec->mineforminfo = NULL; } spec->mineaistate=MINE_DROP_ATTACK; spec->MiningStatus = DONE_WAIT; spec->MineDropNumber = 0; return(TRUE); //finished Wall } return(FALSE); }
/*----------------------------------------------------------------------------- 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 defensefightertargetbullet(Ship *ship, Bullet *bullettotarget) { DefenseFighterSpec *spec = (DefenseFighterSpec *)ship->ShipSpecifics; DefenseFighterStatics *defensefighterstatics; DefenseStruct *newdefensestruct; Bullet *laser; GunStatic *gunstatic; Gun *gun; ShipStaticInfo *shipstatic; vector positionInWorldCoordSys,tempvec; real32 floatDamage; udword intDamage; udword intVelocity; udword intLength; etgeffectstatic *stat; etglod *etgLOD; sdword LOD; Effect *newEffect; #ifdef HW_BUILD_FOR_DEBUGGING /* dbgMessagef("B: %d %x %x %f %f %f %x %f %x",universe.univUpdateCounter, bullettotarget->flags, bullettotarget->owner, bullettotarget->timelived, bullettotarget->damage, bullettotarget->damageFull, bullettotarget->SpecialEffectFlag, bullettotarget->BulletSpeed, bullettotarget); */ #endif gun = &ship->gunInfo->guns[0]; gunstatic = gun->gunstatic; shipstatic = (ShipStaticInfo *)ship->staticinfo; defensefighterstatics = (DefenseFighterStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; bitSet(bullettotarget->SpecialEffectFlag, 0x0002); //set the flag laser = memAlloc(sizeof(Bullet),"Bullet",0); memset(laser,0,sizeof(Bullet)); // for safety laser->objtype = OBJ_BulletType; laser->flags = 0; laser->staticinfo = NULL; ClearNode(laser->renderlink); laser->currentLOD = ship->currentLOD; laser->cameraDistanceSquared = ship->cameraDistanceSquared; laser->soundType = gunstatic->gunsoundtype; laser->bulletType = BULLET_Laser; laser->owner = ship; laser->gunowner = gun; laser->target = NULL; laser->bulletColor = etgBulletColor[shipstatic->shiprace][laser->soundType]; laser->bulletmass = 0.0f; //gunstatic->bulletmass; laser->lengthmag = 600.0f; laser->damage = frandombetween(defensefighterstatics->DamageReductionLow, defensefighterstatics->DamageReductionHigh); laser->timelived = 0.0f; laser->totallifetime = 100.0f; //laser will only live for a sec anyways... laser->SpecialEffectFlag = 0; laser->traveldist = gunstatic->bulletlength; laser->beamtraveldist = gunstatic->bulletlength; //SET_MOVING_LINEARLY(laser->posinfo.isMoving); //laser->posinfo.haventCalculatedDist = TRUE; laser->DFGFieldEntryTime = 0.0f; matMultiplyMatByVec(&positionInWorldCoordSys,&ship->rotinfo.coordsys,&gunstatic->position); vecAdd(laser->posinfo.position,positionInWorldCoordSys,ship->posinfo.position); vecSub(laser->lengthvec, bullettotarget->posinfo.position, laser->posinfo.position); // heading tempvec = laser->lengthvec; vecNormalize(&tempvec); //matMultiplyMatByVec(&gunheadingInWorldCoordSys, &ship->rotinfo.coordsys, &tempvec); //laser->bulletheading = gunheadingInWorldCoordSys; laser->bulletheading = tempvec; matCreateCoordSysFromHeading(&laser->rotinfo.coordsys,&tempvec); vecZeroVector(laser->posinfo.velocity); //Laser effect... floatDamage = (real32)laser->damage; intDamage = TreatAsUdword(floatDamage); intVelocity = TreatAsUdword(gunstatic->bulletspeed); intLength = TreatAsUdword(gunstatic->bulletlength); //create an effect for bullet, if applicable etgLOD = etgGunEventTable[shipstatic->shiprace][gunstatic->gunsoundtype][EGT_GunBullet];//get pointer to bullet effect //etgLOD = etgGunEventTable[0][gunstatic->gunsoundtype][EGT_GunBullet];//get pointer to bullet effect //in future change back to proper one above... if (etgLOD != NULL) { if (bullettotarget != NULL) { LOD = min(ship->currentLOD, bullettotarget->currentLOD); } else { LOD = ship->currentLOD; } if (LOD >= etgLOD->nLevels) { stat = NULL; } else { stat = etgLOD->level[LOD]; } } else { stat = NULL; } #if ETG_DISABLEABLE if (stat != NULL && etgBulletEffectsEnabled && etgEffectsEnabled && !etgFrequencyExceeded(stat)) #else if (stat != NULL && etgBulletEffectsEnabled && !etgFrequencyExceeded(stat)) #endif { laser->effect = etgEffectCreate(stat, laser, NULL, NULL, NULL, 1.0f, EAF_AllButNLips, 3, intDamage, intVelocity, intLength); // univAddObjToRenderListIf((SpaceObj *)laser->effect,(SpaceObj *)ship); // add to render list if parent ship is in render list //do length calculations :) ((real32 *)laser->effect->variable)[ETG_LengthVariable] = fsqrt(vecMagnitudeSquared(laser->lengthvec)); } else { laser->effect = NULL; //play no effect for this bullet } // laser->effect = NULL; //need for render...add later? laser->hitEffect = etgGunEventTable[shipstatic->shiprace][bullettotarget->gunowner->gunstatic->gunsoundtype][EGT_BulletDestroyed];//get pointer to bullet effect if (ship->soundevent.burstHandle < 0) { soundEventBurstFire(ship, gun); } etgLOD = etgGunEventTable[shipstatic->shiprace][gunstatic->gunsoundtype][EGT_GunFire];//get pointer to bullet effect if (etgLOD != NULL) { LOD = ship->currentLOD; if (LOD >= etgLOD->nLevels) { stat = NULL; } else { stat = etgLOD->level[LOD]; } } else { stat = NULL; } #if ETG_DISABLEABLE if (stat != NULL && etgEffectsEnabled && etgFireEffectsEnabled && !etgFrequencyExceeded(stat)) #else if (stat != NULL && etgFireEffectsEnabled && !etgFrequencyExceeded(stat)) #endif { //if there is a gun fire effect newEffect = etgEffectCreate(stat, laser, NULL, NULL, NULL, 1.0f, EAF_AllButNLips, 1, intDamage); // univAddObjToRenderListIf((SpaceObj *)newEffect,(SpaceObj *)ship); // add to render list if parent ship is in render list } /* //spawn bullet hitting effect etgLOD = etgTractorBeamEffectTable[ship->shiprace]; //etgLOD = etgGunEventTable[shipstatic->shiprace][gunstatic->gunsoundtype][EGT_GunFire];//get pointer to bullet effect if (etgLOD != NULL) { LOD = ship->currentLOD; if (LOD >= etgLOD->nLevels) { stat = NULL; } else { stat = etgLOD->level[LOD]; } } else { stat = NULL; } #if ETG_DISABLEABLE if (stat != NULL && etgEffectsEnabled) #else if (stat != NULL) #endif { //if there is a gun fire effect // size = etgEffectSize(stat->nParticleBlocks);//compute size of effect size = stat->effectSize; newEffect = memAlloc(size, "DefenseFHittingEffect", 0); //allocate the new effect newEffect->objtype = OBJ_EffectType; newEffect->flags = SOF_Rotatable | SOF_AttachVelocity | SOF_AttachPosition | SOF_AttachCoordsys; newEffect->staticinfo = (StaticInfo *)stat; ClearNode(newEffect->renderlink); newEffect->currentLOD = LOD; newEffect->cameraDistanceSquared = ship->cameraDistanceSquared; newEffect->timeElapsed = 0.0f; //brand new heavies floatDamage = 30.0f; intDamage = TreatAsUdword(floatDamage); newEffect->rotinfo.coordsys = bullettotarget->rotinfo.coordsys; newEffect->posinfo.position = bullettotarget->posinfo.position; //start at same spot as bullet newEffect->posinfo.velocity = bullettotarget->posinfo.velocity; //start at same spot as bullet etgEffectCodeStart(stat, newEffect, 1, intDamage);//get the code a-runnin' SET_MOVING_IMMOBILE(newEffect->posinfo.isMoving); newEffect->posinfo.haventCalculatedDist = TRUE; univUpdateObjRotInfo((SpaceObjRot *)newEffect); // newEffect->owner = NULL; // nothing owns this effect newEffect->owner = (Ship *) bullettotarget; listAddNode(&universe.SpaceObjList,&(newEffect->objlink),newEffect); univAddObjToRenderListIf((SpaceObj *)newEffect,(SpaceObj *)ship); // add to render list if parent ship is in render list } */ //Not sure If I need to add... listAddNode(&universe.SpaceObjList,&(laser->objlink),laser); listAddNode(&universe.BulletList,&(laser->bulletlink),laser); univAddObjToRenderListIf((SpaceObj *)laser,(SpaceObj *)ship); // add to render list if parent ship is in render list newdefensestruct = memAlloc(sizeof(DefenseStruct),"DS(DefenseStruct)",Pyrophoric); newdefensestruct->bullet = bullettotarget; newdefensestruct->CoolDown = FALSE; newdefensestruct->CoolDownTime = 0.0f; newdefensestruct->LaserDead = FALSE; listAddNode(&spec->DefenseList,&newdefensestruct->bulletnode,newdefensestruct); newdefensestruct->laser = laser; if(bitTest(ship->flags,SOF_CloakGenField)) { bitSet(ship->flags,SOF_DeCloaking); bitClear(ship->flags,SOF_Cloaked); bitClear(ship->flags,SOF_Cloaking); } }