/*----------------------------------------------------------------------------- Name : tmLeave Description : Callback function to close the trade manager Inputs : Outputs : Deletes all regions associated with trade manager Return : ----------------------------------------------------------------------------*/ void tmLeave(char *string, featom *atom) { //close the construction manager #if TM_VERBOSE_LEVEL >= 1 dbgMessagef("Close trade manager."); #endif feScreenDeleteFlags(tmBaseRegion,FE_DONT_DELETE_REGION_IF_SCREEN_NOT_FOUND); tmBaseRegion = NULL; if (tmIoSaveState) ioEnable(); // enable rendering of main game screen mrRenderMainScreen = TRUE; /* play the exit sound */ soundEvent(NULL, UI_ManagerExit); //restart the sound of space ambient soundEvent(NULL, UI_SoundOfSpace); spUnlockout(); bitClear(tbDisable,TBDISABLE_TRADEMGR_USE); tmReset(); tmTradeActive = FALSE; svClose(); }
/*----------------------------------------------------------------------------- Name : gcProcessGameChatPacket Description : this function processes the chat packet recieved from the game. Inputs : Outputs : Return : void ----------------------------------------------------------------------------*/ void gcProcessGameChatPacket(struct ChatPacket *packet) { udword mask; gcLockGameChat(); strcpy(threadtransfer[numnewchat].chatstring,packet->message); strcpy(threadtransfer[numnewchat].userName, playerNames[packet->packetheader.frame]); threadtransfer[numnewchat].playerindex = packet->packetheader.frame; mask = PLAYER_MASK(sigsPlayerIndex); mask &= packet->users; if (mask==packet->users) threadtransfer[numnewchat].messageType = GC_WHISPEREDMESSAGE; else threadtransfer[numnewchat].messageType = GC_NORMALMESSAGE; numnewchat++; soundEvent(NULL, UI_ChatMessage); gcUnLockGameChat(); }
/*----------------------------------------------------------------------------- Name : madLinkInUpdateMeshAnimations Description : starts,stops and does whatever needs to be done for mesh animations based on code given cues. Inputs : Ship to have animation updated Outputs : Return : ----------------------------------------------------------------------------*/ void madLinkInUpdateMeshAnimations(Ship *ship) { if(bitTest(ship->madAnimationFlags,MAD_NEED_TO_START_NEW_ANIMATION)) { //we need to switch to a new animation for some odd reason if(ship->madBindings->nCurrentAnim != MAD_NoAnimation) { if(ship->madBindings->bPaused) { //animation is paused...well,unpause it //so as to fix a bug in lukes code! madAnimationPause(ship,!ship->madBindings->bPaused); } madAnimationStop(ship); } madAnimationStart(ship, ship->cuedAnimationIndex); //start 0th cued animation /* play special animation sound here */ soundEvent(ship, ship->soundEventAnimationTypeFlag); bitClear(ship->madAnimationFlags,MAD_NEED_TO_START_NEW_ANIMATION); if(ship->shiptype == Mothership) { MothershipDoorUpKeep(ship); } return; } //time to start animation if(madAnimationUpdate(ship, universe.phystimeelapsed)) { #if DEBUG_MESH_ANIMATIONS dbgMessagef("Animation Finished."); #endif //start and pause poo here for pooeyness...(wings just closed, gotta stay closed...etc.. //cleanup ended animation switch(ship->cuedAnimationType) { case MAD_ANIMATION_GUN_OPENING: ship->cuedAnimationType = MAD_ANIMATION_NOTHING; ship->madGunStatus = MAD_STATUS_GUNS_OPEN; break; case MAD_ANIMATION_GUN_CLOSING: ship->cuedAnimationType = MAD_ANIMATION_NOTHING; ship->madGunStatus = MAD_STATUS_GUNS_CLOSED; //setup closed gun hack... madAnimationStart(ship, ship->staticinfo->madStatic->gunOpenIndexes[0]); //start 0th animation madAnimationPause(ship,!ship->madBindings->bPaused); break; case MAD_ANIMATION_WINGS_OPENING: ship->cuedAnimationType = MAD_ANIMATION_NOTHING; ship->madWingStatus = MAD_STATUS_WINGS_OPEN; break; case MAD_ANIMATION_WINGS_CLOSING: ship->cuedAnimationType = MAD_ANIMATION_NOTHING; ship->madWingStatus = MAD_STATUS_WINGS_CLOSED; //setup closed gun hack... madAnimationStart(ship, ship->staticinfo->madStatic->PostDockIndexes[0]); //start 0th animation madAnimationPause(ship,!ship->madBindings->bPaused); break; case MAD_ANIMATION_DOOR_OPENING: ship->cuedAnimationType = MAD_ANIMATION_NOTHING; ship->madDoorStatus = MAD_STATUS_DOOR_OPEN; madAnimationStart(ship, ship->staticinfo->madStatic->DoorCloseIndexes[0]); //start 0th animaiton madAnimationPause(ship,!ship->madBindings->bPaused); break; case MAD_ANIMATION_DOOR_CLOSING: ship->cuedAnimationType = MAD_ANIMATION_NOTHING; ship->madDoorStatus = MAD_STATUS_DOOR_CLOSED; // play the mothership door closed sound (big Ka-chunk) // this is in addition to the closing sound which is triggered at the start of closing soundEvent(ship, Ship_MoshipDoorClosed); break; case MAD_ANIMATION_SPECIAL_OPENING: ship->cuedAnimationType = MAD_ANIMATION_NOTHING; ship->madSpecialStatus = MAD_STATUS_SPECIAL_OPEN; break; case MAD_ANIMATION_SPECIAL_CLOSING: ship->cuedAnimationType = MAD_ANIMATION_NOTHING; ship->madSpecialStatus = MAD_STATUS_SPECIAL_CLOSED; madAnimationStart(ship, ship->staticinfo->madStatic->specialOpenIndexes[0]); //start 0th animaiton madAnimationPause(ship,!ship->madBindings->bPaused); break; } bitClear(ship->madAnimationFlags,MAD_ANIMATION_NEED_PROC); //play animations that are waiting... if(ship->nextAnim != 0) { switch(ship->nextAnim) { case MAD_ANIMATION_GUN_OPENING: madOpenGunsShip(ship); break; case MAD_ANIMATION_GUN_CLOSING: madLinkInCloseGunsShip(ship); break; case MAD_ANIMATION_WINGS_OPENING: madLinkInPostDockingShip(ship); break; case MAD_ANIMATION_WINGS_CLOSING: madLinkInPreDockingShip(ship); break; case MAD_ANIMATION_DOOR_OPENING: madLinkInOpenDoor(ship); break; case MAD_ANIMATION_DOOR_CLOSING: madLinkInCloseDoor(ship); break; case MAD_ANIMATION_SPECIAL_OPENING: madLinkInOpenSpecialShip(ship); break; case MAD_ANIMATION_SPECIAL_CLOSING: madLinkInCloseSpecialShip(ship); break; default: dbgFatalf(DBG_Loc,"\nUnknown animation in nextAnim variable."); break; } ship->nextAnim = 0; } } if(ship->shiptype == Mothership) { MothershipDoorUpKeep(ship); } }
sdword tmTradeBegin(regionhandle region, sdword ID, udword event, udword data) { sdword status = 0; sdword i; //if disabled, just return if ((tmTradeDisabled) || (playPackets) || (universePause) || (tmTradeActive)) { return 0; } // disbale rendering of main screen mrRenderMainScreen = FALSE; // clear the screen rndClear(); tmTradeActive = TRUE; tmTechListFont = frFontRegister(TM_TechListFont); tmFont = frFontRegister(TM_Font); tmCurrentSelect = 0; tmDialogPhrase = DialogWelcome; if (piePointSpecMode != PSM_Idle) { piePointModeOnOff(); } if (!tmScreensHandle) { feCallbackAddMultiple(tmCallback); //add in the callbacks feDrawCallbackAddMultiple(tmDrawCallback); tmScreensHandle = feScreensLoad(TM_FIBFile); //load in the screen } soundEventStopSFX(0.5f); /* play the intro sound */ soundEvent(NULL, UI_ManagerIntro); /* play the build manager ambient */ soundEvent(NULL, UI_Trading); tmBaseRegion = feScreenStart(region, TM_TradeScreen);//add new regions as siblings of current one tmIoSaveState = ioDisable(); tmTechSelected = -1; for (i = 0; i < TM_NUM_TECHS; i++) { if (tmTechForSale[i] == TM_TECH_IS_FOR_SALE) { tmTechSelected = i; tmtechinfo = i; tmDirtyTechInfo(); break; } } mouseCursorShow(); bitSet(tbDisable,TBDISABLE_TRADEMGR_USE); return(status); }
void DDDFrigateHousekeep(Ship *ship) { DDDFrigateSpec *spec = (DDDFrigateSpec *)ship->ShipSpecifics; DroneSpec *dronespec; DDDFrigateStatics *dddstat = ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; real32 regeneraterate = (spec->DDDstate == DDDSTATE_ALLINSIDE) ? dddstat->internalRegenerateRate : dddstat->externalRegenerateRate; if ((universe.totaltimeelapsed - spec->lasttimeRegenerated) > regeneraterate) { udword i; spec->lasttimeRegenerated = universe.totaltimeelapsed; // regenerate a drone, if one has been destroyed for (i=0;i<MAX_NUM_DRONES;i++) { if (spec->DronePtrs[i] == NULL) { // found a dead drone, so let's create a new one. spec->DronePtrs[i] = CreateDroneInside(ship,i); switch (spec->DDDstate) { case DDDSTATE_ALLINSIDE: // all inside, so don't have to do anything case DDDSTATE_DOCKTHEM: // docking, so no need to launch and then dock case DDDSTATE_DOCKING: // docking, so no need to launch and then dock case DDDSTATE_LAUNCHTHEM: // going to launch everything, so no action needed break; case DDDSTATE_LAUNCHING: // we just created a drone, which is inside. // we need to prepare it so it can launch too. LaunchDrone(ship,spec->DronePtrs[i]); break; case DDDSTATE_ALLOUTSIDE: spec->DDDstate = DDDSTATE_LAUNCHTHEM; // launch regenerated drone break; } break; } } } switch (spec->DDDstate) { case DDDSTATE_ALLINSIDE: break; case DDDSTATE_LAUNCHTHEM: { // for all the drones inside, ShipsInsideMe *shipsInsideMe = ship->shipsInsideMe; Node *node = shipsInsideMe->insideList.head; InsideShip *insideShip; if (node == NULL) { // no Drones, so just return spec->DDDstate = DDDSTATE_ALLINSIDE; return; } soundEvent(ship, Ship_DroneLaunch); do { insideShip = (InsideShip *)listGetStructOfNode(node); LaunchDrone(ship,insideShip->ship); node = node->next; } while (node != NULL); spec->DDDstate = DDDSTATE_LAUNCHING; } break; case DDDSTATE_LAUNCHING: { // for all of the DDD's Drones, udword i; Ship *drone; bool alllaunched = TRUE; for (i=0;i<MAX_NUM_DRONES;i++) { drone = spec->DronePtrs[i]; if (drone != NULL) { dronespec = (DroneSpec *)drone->ShipSpecifics; dbgAssert(dronespec->droneNumber == i); switch (dronespec->droneState) { case DRONESTATE_LAUNCHING: alllaunched = FALSE; if (LaunchShipFromDDDF(drone,ship)) { RemoveShipFromLaunching(drone); dronespec->droneState = DRONESTATE_LAUNCHED; } break; case DRONESTATE_LAUNCHED: break; } } } if (alllaunched) { SelectCommand *droneselect; SelectCommand selectone; sdword numShipsToLaunch = 0; droneselect = memAlloc(sizeofSelectCommand(MAX_NUM_DRONES),"DroneSelLaunch",0); for (i=0;i<MAX_NUM_DRONES;i++) { drone = spec->DronePtrs[i]; if (drone != NULL) { dbgAssert(((DroneSpec *)drone->ShipSpecifics)->droneState == DRONESTATE_LAUNCHED); droneselect->ShipPtr[numShipsToLaunch++] = drone; } } if (numShipsToLaunch == 0) { memFree(droneselect); // all ships are launched, but there are none so consider them inside spec->DDDstate = DDDSTATE_ALLINSIDE; return; } droneselect->numShips = numShipsToLaunch; dbgAssert(numShipsToLaunch <= MAX_NUM_DRONES); selectone.ShipPtr[0] = ship; selectone.numShips = 1; // put all ships in formation, and guarding DDDF clFormation(&universe.mainCommandLayer,droneselect,SPHERE_FORMATION); clProtect(&universe.mainCommandLayer,droneselect,&selectone); memFree(droneselect); spec->DDDstate = DDDSTATE_ALLOUTSIDE; } } break; case DDDSTATE_ALLOUTSIDE: break; case DDDSTATE_DOCKTHEM: { sdword i; Ship *drone; SelectCommand *droneselect; sdword numShipsToDock = 0; DroneSpec *dronespec; droneselect = memAlloc(sizeofSelectCommand(MAX_NUM_DRONES),"DroneSelection",0); // remove drones from doing other stuff for (i=0;i<MAX_NUM_DRONES;i++) { drone = spec->DronePtrs[i]; if (drone != NULL) { dbgAssert(((DroneSpec *)drone->ShipSpecifics)->droneState == DRONESTATE_LAUNCHED); droneselect->ShipPtr[numShipsToDock++] = drone; } } if (numShipsToDock == 0) { memFree(droneselect); spec->DDDstate = DDDSTATE_ALLINSIDE; return; } droneselect->numShips = numShipsToDock; dbgAssert(numShipsToDock <= MAX_NUM_DRONES); // remove ships from sphere formation and protecting RemoveShipsFromDoingStuff(&universe.mainCommandLayer,droneselect); // initialize each drone for docking for (i=0;i<numShipsToDock;i++) { drone = droneselect->ShipPtr[i]; dronespec = (DroneSpec *)drone->ShipSpecifics; dockPrepareDroneForDocking(drone,ship); dronespec->droneState = DRONESTATE_DOCKING; } memFree(droneselect); spec->DDDstate = DDDSTATE_DOCKING; } break; case DDDSTATE_DOCKING: { sdword i; Ship *drone; DroneSpec *dronespec; bool allDocked = TRUE; // for each drone in DRONESTATE_Docking, call DroneDocksAtDDDF for (i=0;i<MAX_NUM_DRONES;i++) { drone = spec->DronePtrs[i]; if (drone != NULL) { dronespec = (DroneSpec *)drone->ShipSpecifics; if (dronespec->droneState == DRONESTATE_DOCKING) { allDocked = FALSE; if (DroneDocksAtDDDF(drone,ship)) { soundEvent(ship, Ship_DroneAcquire); RemoveShipFromDocking(drone); dronespec->droneState = DRONESTATE_DORMANT; } } } } if (allDocked) { spec->DDDstate = DDDSTATE_ALLINSIDE; } } break; } }
/*----------------------------------------------------------------------------- Name : pingListDraw Description : Draw all pings from farthest to nearest. Inputs : camera - the camera we're rendering from modelView, projection - current matrices viewPort - rectangle we're rending in, for the TO legend Outputs : Return : Note : The renderer should be in 2D mode at this point. ----------------------------------------------------------------------------*/ void pingListDraw(Camera *camera, hmatrix *modelView, hmatrix *projection, rectangle *viewPort) { real32 pingAge, pingCycle, pingMod, pingSize; real32 x, y, radius; Node *thisNode, *nextNode; ping *thisPing; vector distSquared; sdword nSegments, index, rowHeight, xScreen, yScreen; oval o; udword TOFlags = 0; fonthandle fhSave; toicon *icon; color col; real32 realMargin; ShipClass shipClass; static real32 lastProximityPing = REALlyBig; static real32 lastAnomolyPing = REALlyBig; static real32 lastBattlePing = REALlyBig; static real32 lastHyperspacePing = REALlyBig; static real32 lastNewshipPing = REALlyBig; bool pingset; //start by sorting the ping list from farthest to nearest thisNode = pingList.head; while (thisNode != NULL) { //scan all pings nextNode = thisNode->next; thisPing = listGetStructOfNode(thisNode); if (thisPing->owner != NULL) { thisPing->centre = thisPing->owner->posinfo.position; } vecSub(distSquared, camera->eyeposition, thisPing->centre); thisPing->cameraDistanceSquared = vecMagnitudeSquared(distSquared); TOFlags |= thisPing->TOMask; thisNode = nextNode; } listMergeSortGeneral(&pingList, pingListSortCallback); //now the list is sorted; proceed to draw all the pings thisNode = pingList.head; pingset = FALSE; while (thisNode != NULL) { //scan all pings nextNode = thisNode->next; thisPing = listGetStructOfNode(thisNode); pingCycle = thisPing->pingDuration + thisPing->interPingPause; pingAge = universe.totaltimeelapsed - thisPing->creationTime; pingMod = (real32)fmod((double)pingAge, (double)pingCycle); if (pingMod <= thisPing->pingDuration) { pingSize = (thisPing->size - thisPing->minSize) * pingMod / thisPing->pingDuration + thisPing->minSize; selCircleComputeGeneral(modelView, projection, &thisPing->centre, max(thisPing->size,thisPing->minSize), &x, &y, &radius); if (radius > 0.0f) { radius = max(radius, thisPing->minScreenSize); radius *= pingSize / max(thisPing->size,thisPing->minSize); o.centreX = primGLToScreenX(x); o.centreY = primGLToScreenY(y); o.radiusX = o.radiusY = primGLToScreenScaleX(radius); nSegments = pieCircleSegmentsCompute(radius); primOvalArcOutline2(&o, 0.0f, 2*PI, 1, nSegments, thisPing->c); /* starting to draw a new ping so play the sound */ if (!smZoomingIn && !smZoomingOut && !pingset) { switch (thisPing->TOMask) { case PTOM_Anomaly: if (pingSize <=lastAnomolyPing) { soundEvent(NULL, UI_SensorsPing); pingset = TRUE; lastAnomolyPing = pingSize; } break; case PTOM_Battle: if (pingSize <= lastBattlePing) { soundEvent(NULL, UI_PingBattle); pingset = TRUE; lastBattlePing = pingSize; } break; case PTOM_Hyperspace: if (pingSize <= lastHyperspacePing) { soundEvent(NULL, UI_PingHyperspace); pingset = TRUE; lastHyperspacePing = pingSize; } break; case PTOM_Proximity: if (pingSize <= lastProximityPing) { soundEvent(NULL, UI_PingProximity); pingset = TRUE; lastProximityPing = pingSize; } break; case PTOM_NewShips: if (pingSize <= lastNewshipPing) { soundEvent(NULL, UI_PingNewShips); pingset = TRUE; lastNewshipPing = pingSize; } break; default: break; } } } } thisNode = nextNode; } //draw the blip TO if (smTacticalOverlay) { realMargin = primScreenToGLScaleX(viewPort->x0); fhSave = fontCurrentGet(); //save the current font fontMakeCurrent(selGroupFont2); // use a common, fairly small font rowHeight = fontHeight("M"); // used to space the legend yScreen = viewPort->y0 + rowHeight; //leave some space at the top to start radius = primScreenToGLScaleX(rowHeight)/2; xScreen = viewPort->x0 + (sdword)(rowHeight * 2.5); for (index = 0; index < PTO_NumberTOs; index++) { if ((TOFlags & pingTOList[index].bitMask)) { // fontPrint(xScreen, yScreen, *pingTOList[index].c, "O"); pingTOList[index].lastTimeDrawn = universe.totaltimeelapsed; } if (universe.totaltimeelapsed - pingTOList[index].lastTimeDrawn <= pingTOLingerTime) { o.centreX = viewPort->x0 + rowHeight * 3 / 2; o.centreY = yScreen + rowHeight / 2; o.radiusX = o.radiusY = rowHeight / 2; primOvalArcOutline2(&o, 0.0f, TWOPI, 1, pingTONSegments, *pingTOList[index].c); fontPrint(xScreen, yScreen, TO_TextColor, strGetString(pingTOList[index].stringEnum)); yScreen += rowHeight + 1; } } for (shipClass = 0; shipClass < NUM_CLASSES; shipClass++) { if (!toClassUsed[shipClass][0]) { continue; } icon = toClassIcon[shipClass]; fontPrint(xScreen, yScreen + (rowHeight>>2), TO_TextColor, ShipClassToNiceStr(shipClass)); #if TO_STANDARD_COLORS col = teFriendlyColor; #else col = teColorSchemes[universe.curPlayerIndex].tacticalColor; #endif col = colRGB(colRed(col)/TO_IconColorFade, colGreen(col)/TO_IconColorFade, colBlue(col)/TO_IconColorFade); primLineLoopStart2(1, col); for (index = icon->nPoints - 1; index >= 0; index--) { primLineLoopPoint3F(realMargin + primScreenToGLX(rowHeight*1.5) + icon->loc[index].x * radius, primScreenToGLY(yScreen + rowHeight/2) + icon->loc[index].y * radius); } primLineLoopEnd2(); yScreen += rowHeight + 1; } fontMakeCurrent(fhSave); } }