123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441 |
- #include "pch.h"
- #include <limits.h>
- //
- // Helper function for handling ship updates.
- //
- //
- // Big function to handle default messaging.
- // Three possible return codes:
- // S_OK message handled
- // S_FALSE message not handled
- // E_FAIL error, abort
- HRESULT BaseClient::HandleMsg(FEDMESSAGE* pfm,
- Time lastUpdate, Time now)
- {
- HRESULT hr = S_OK; //handled by default
- #ifdef DUMPMSGS
- debugf("Received message type %d of length %d\n", pfm->fmid, pfm->cbmsg);
- #endif // DUMPMSGS
- // keep track of the last server message, but only count unreliable
- // messages while the client is in flight.
- if (!m_ship || !IsInGame() || GetCluster() == NULL || pfm->fmid == FM_CS_PING
- || pfm->fmid == FM_S_HEAVY_SHIPS_UPDATE || pfm->fmid == FM_S_LIGHT_SHIPS_UPDATE)
- {
- m_timeLastServerMessage = now;
- }
- switch(pfm->fmid)
- {
- case FM_S_LOGONACK:
- {
- CASTPFM(pfmLogonAck, S, LOGONACK, pfm);
- if (pfmLogonAck->fValidated)
- {
- debugf("I am ship %s, shipid=%d\n", FM_VAR_REF(pfmLogonAck, CharName_OR_FailureReason), pfmLogonAck->shipID);
- lstrcpy(m_szCharName, FM_VAR_REF(pfmLogonAck, CharName_OR_FailureReason)); // remember who we are
- m_fLoggedOn = true;
- SetCookie(pfmLogonAck->cookie);
- // set the client-server time offset properly
- {
- m_cUnansweredPings = 0;
- DWORD newLag = 100; // reasonable default value
- //Try a new way of doing the correction
- DWORD newOffset = pfmLogonAck->timeServer.clock() - now.clock() + newLag;
- m_serverOffsetValidF = true;
- m_serverLag = newLag;
- m_serverOffset = newOffset;
- m_timeLastPing = now;
- m_timeLastPingServer = pfmLogonAck->timeServer;
- }
- }
- //
- // If we need to download art files, then
- // don't ack logon until done
- //
- char * szFailureReason = pfmLogonAck->fValidated ? NULL : FM_VAR_REF(pfmLogonAck, CharName_OR_FailureReason);
- OnLogonAck(pfmLogonAck->fValidated, pfmLogonAck->fRetry, szFailureReason);
- }
- break;
- case FM_S_URLROOT:
- {
- CASTPFM(pfmUrlRoot, S, URLROOT, pfm);
- UTL::SetUrlRoot(FM_VAR_REF(pfmUrlRoot, UrlRoot));
- }
- break;
- case FM_S_EXPORT:
- {
- if (IsWaitingForGameRestart())
- break;
- CASTPFM(pfmExport, S, EXPORT, pfm);
- IObject* u = m_pCoreIGC->CreateObject(lastUpdate,
- pfmExport->objecttype,
- FM_VAR_REF(pfmExport, exportData),
- pfmExport->cbexportData);
- if (u)
- u->Release();
- else
- {
- //Station exports are allowed to "fail" because they may simply update an existing station.
- //Ships are allowed to fail because sometimes an existing ship will be updated.
- assert ((pfmExport->objecttype == OT_station) || (pfmExport->objecttype == OT_ship));
- }
- Sleep(0);
- }
- break;
- case FM_S_POSTER:
- {
- // I think this message is no longer used.
- assert(false);
- /*
- CASTPFM(pfmPoster, S, POSTER, pfm);
- IclusterIGC * cluster =
- m_pCoreIGC->GetCluster(pfmPoster->sectorID);
- if (cluster)
- {
- float cosLatr = cos(pfmPoster->latitude);
- Vector position(cosLatr * cos(pfmPoster->longitude),
- cosLatr * sin(pfmPoster->longitude),
- sin(pfmPoster->latitude));
- cluster->GetClusterSite()->AddPoster(
- pfmPoster->textureName,
- position,
- pfmPoster->radius);
- }
- */
- }
- break;
- case FM_S_RELAUNCH_SHIP:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmRelaunch, S, RELAUNCH_SHIP, pfm);
- IshipIGC* pShip = m_pCoreIGC->GetShip(pfmRelaunch->shipID);
- if (pShip)
- {
- IshipIGC* pshipParent = m_pCoreIGC->GetShip(pfmRelaunch->carrierID);
- assert (pshipParent);
- pShip->SetParentShip(NULL);
- pShip->ProcessShipLoadout(pfmRelaunch->cbloadout, (const ShipLoadout*)(FM_VAR_REF(pfmRelaunch, loadout)), true);
- pShip->SetAmmo(SHRT_MAX);
- pShip->SetFuel(FLT_MAX);
- pShip->SetEnergy(pShip->GetHullType()->GetMaxEnergy());
- pShip->SetPosition(pfmRelaunch->position);
- pShip->SetVelocity(pfmRelaunch->velocity);
- {
- Orientation o;
- pfmRelaunch->orientation.Export(&o);
- pShip->SetOrientation(o);
- }
- if (pShip == m_ship)
- {
- SetCookie(pfmRelaunch->cookie);
- PlayNotificationSound(salRepairedAtCarrierSound, GetShip());
- OverrideCamera(pshipParent);
- }
- }
- }
- break;
- case FM_S_EJECT:
- {
- if (!IsInGame())
- break;
- IclusterIGC* pcluster = GetCluster();
- if (pcluster)
- {
- CASTPFM(pfmEject, S, EJECT, pfm);
- IshipIGC* pShip = m_pCoreIGC->GetShip(pfmEject->shipID);
- if (pShip)
- {
- if (pShip->GetParentShip())
- {
- pShip->SetParentShip(NULL);
- m_pClientEventSource->OnBoardShip(pShip, NULL);
- }
- else
- {
- //Ship 'died' .
- assert (pShip->GetChildShips()->n() == 0);
- {
- const PartListIGC* plist = pShip->GetParts();
- PartLinkIGC* plink;
- while (plink = plist->first()) //Not ==
- plink->data()->Terminate();
- }
- //and fuel and ammo
- pShip->SetAmmo(0);
- pShip->SetFuel(0.0f);
- }
- {
- {
- for (MissileLinkIGC* pml = pcluster->GetMissiles()->first();
- (pml != NULL);
- pml = pml->next())
- {
- ImissileIGC* pmissile = pml->data();
- if (pmissile->GetTarget() == pShip)
- pmissile->SetTarget(NULL);
- }
- }
- //Eject the player
- pShip->SetBaseHullType(pShip->GetSide()->GetCivilization()->GetLifepod());
- //Put a spin on the ship as it leaves the bad guys.
- //Note ... this needs to match the code in fedsrv.cpp
- pShip->SetCurrentTurnRate(c_axisRoll, pi * 2.0f);
- pShip->SetPosition(pfmEject->position);
- pShip->SetVelocity(pfmEject->velocity);
- {
- Orientation o(pfmEject->forward);
- pShip->SetOrientation(o);
- }
- }
- if (pShip == m_ship)
- {
- SetCookie(pfmEject->cookie);
- ImodelIGC* pNearestBase = FindTarget (pShip, c_ttStation | c_ttFriendly | c_ttAnyCluster | c_ttProbe, pShip->GetCommandTarget (c_cmdCurrent), pcluster, &pfmEject->position, NULL, c_sabmRescue | c_sabmRescueAny | c_sabmLand);
- pShip->SetCommand (c_cmdCurrent, pNearestBase, c_cidGoto);
- SetAutoPilot (true);
- bInitTrekJoyStick = true;
- PlayNotificationSound(salAutopilotEngageSound, GetShip());
- }
- }
- }
- }
- break;
- case FM_S_DESTROY_TREASURE:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmTreasure, S, DESTROY_TREASURE, pfm);
- {
- IclusterIGC* c = m_pCoreIGC->GetCluster(pfmTreasure->sectorID);
- assert (c);
- ItreasureIGC* treasure = c->GetTreasure(pfmTreasure->treasureID);
- if (treasure)
- treasure->Terminate();
- }
- }
- break;
- case FM_S_ACQUIRE_TREASURE:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmTreasure, S, ACQUIRE_TREASURE, pfm);
- switch (pfmTreasure->treasureCode)
- {
- case c_tcPart:
- {
- SetMessageType(BaseClient::c_mtGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmAck, C, TREASURE_ACK)
- END_PFM_CREATE
- pfmAck->mountID = m_ship->HitTreasure(c_tcPart, pfmTreasure->treasureID, pfmTreasure->amount);
- }
- break;
- case c_tcPowerup:
- PlaySoundEffect(pickUpPowerupSound, GetShip());
- break;
- case c_tcDevelopment:
- PlaySoundEffect(pickUpDevelopmentSound, GetShip());
- break;
- case c_tcCash:
- {
- PlaySoundEffect(pickUpCashSound, GetShip());
- IshipIGC* pshipDonate = m_ship->GetAutoDonate();
- if (pshipDonate)
- PostText(false, "You donated your reward of $%d to %s.", pfmTreasure->amount, pshipDonate->GetName());
- else
- PostText(false, "You received a reward of $%d.", pfmTreasure->amount);
- }
- break;
- case c_tcFlag:
- PlaySoundEffect(pickUpDevelopmentSound, GetShip()); //NYI pickUpFlagSound
- break;
- }
- }
- break;
- case FM_S_PLAYER_RESCUED:
- {
- CASTPFM(pfmPlayerRescued, S, PLAYER_RESCUED, pfm);
- ShipID sid = GetShipID();
- if (pfmPlayerRescued->shipIDRescuer == sid)
- {
- // I just picked someone up.
- PlayerInfo* pplayerRescuee = FindPlayer(pfmPlayerRescued->shipIDRescuee);
-
- if (!pplayerRescuee)
- {
- assert(false);
- break;
- }
- PostText(false, "You rescued %s.", pplayerRescuee->CharacterName());
- PlaySoundEffect(rescuePlayerSound, GetShip());
- }
- else if (pfmPlayerRescued->shipIDRescuee == sid)
- {
- // I was just teleported back to base.
- PlayerInfo* pplayerRescuer = FindPlayer(pfmPlayerRescued->shipIDRescuer);
-
- if (!pplayerRescuer)
- {
- assert(false);
- break;
- }
- PostText(true, "%s rescued you.", pplayerRescuer->CharacterName());
- PlaySoundEffect(jumpSound);
- }
- }
- break;
- case FM_S_BALLOT:
- {
- CASTPFM(pfmBallot, S, BALLOT, pfm);
- // if I'm not the one who called this vote...
- if (!(pfmBallot->otInitiator == OT_ship && pfmBallot->oidInitiator == GetShipID())
- && !(pfmBallot->otInitiator == OT_side && pfmBallot->oidInitiator == GetSideID()))
- {
- // then propose the issue.
- m_listBallots.PushEnd(BallotInfo(
- (char*)(FM_VAR_REF(pfmBallot, BallotText)) + ZString("Press [Y] to vote yes, [N] to vote no."),
- pfmBallot->ballotID,
- ClientTimeFromServerTime(pfmBallot->timeExpiration)
- ));
- }
- }
- break;
- case FM_S_CANCEL_BALLOT:
- {
- CASTPFM(pfmCancelBallot, S, CANCEL_BALLOT, pfm);
- // destroy any ballot in the queue with this ID
- BallotList::Iterator iterBallot(m_listBallots);
- while (!iterBallot.End())
- {
- if (iterBallot.Value().GetBallotID() == pfmCancelBallot->ballotID)
- iterBallot.Remove();
- else
- iterBallot.Next();
- }
- }
- break;
- case FM_CS_PING:
- {
- CASTPFM(pfmPing, CS, PING, pfm);
- assert (now >= pfmPing->timeClient);
- //
- // Assume lag evenly split here to there & there to here.
- //
- DWORD newLag = (now.clock() - pfmPing->timeClient.clock()) >> 1;
- if (newLag < 1000)
- {
- m_cUnansweredPings = 0;
- //Try a new way of doing the correction
- //DWORD newOffset = pfmPing->timeServer.clock() - pfmPing->timeClient.clock();
- DWORD newOffset = pfmPing->timeServer.clock() - now.clock() + newLag;
- if (m_serverOffsetValidF)
- {
- float currentSync = float(now.clock() - m_timeLastPing.clock()) /
- float(pfmPing->timeServer.clock() - m_timeLastPingServer.clock());
- m_sync = m_sync * 3/4 + currentSync/4;
- if (newLag > m_serverLag)
- {
- //new lag is worse ... heavily weight the old lag
- m_serverOffset += ((int)(newOffset - m_serverOffset)) >> 3;
- m_serverLag = (m_serverLag * 7 + newLag) >> 3;
- }
- else
- {
- //new lag is better ... average the old & new
- m_serverOffset += ((int)(newOffset - m_serverOffset)) >> 1;
- m_serverLag = (m_serverLag + newLag) >> 1;
- }
- }
- else
- {
- m_serverOffsetValidF = true;
- m_serverLag = newLag;
- m_serverOffset = newOffset;
- }
- m_timeLastPing = now;
- m_timeLastPingServer = pfmPing->timeServer;
- }
- }
- break;
- case FM_S_VIEW_CLUSTER:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmViewCluster, S, VIEW_CLUSTER, pfm);
- IclusterIGC* pcluster = m_pCoreIGC->GetCluster(pfmViewCluster->clusterID);
- assert (pcluster);
- SetViewCluster(pcluster, pfmViewCluster->bUsePosition ? &(pfmViewCluster->position) : NULL);
- }
- break;
- case FM_S_SHIP_DELETE:
- {
- CASTPFM(pfmShipDelete, S, SHIP_DELETE, pfm);
- //
- // Which ship went away ...
- //
- if (pfmShipDelete->shipID != GetShipID())
- {
- IshipIGC* ship = m_pCoreIGC->GetShip(pfmShipDelete->shipID);
- if (ship)
- {
- //
- // Found a ship ... why'd it go?
- //
- switch (pfmShipDelete->sdr)
- {
- case SDR_TERMINATE:
- case SDR_KILLED:
- {
- ship->SetCluster(NULL);
- }
- break;
- default:
- {
- //
- // The ship is no longer visible to the player,
- // "cache" it by moving it the null sector.
- // Ignore for your parent ship since this is handled
- // by getting a docked or set cluster message for
- // the parent.
- if (m_ship->GetParentShip() != ship)
- ship->SetCluster(NULL);
- }
- }
- }
- if (pfmShipDelete->sdr == SDR_LOGGEDOFF)
- {
- //The player is gone ... nuke their player info (if it exists)
- PlayerLink* l = FindPlayerLink(pfmShipDelete->shipID);
- if (l)
- {
- PlayerInfo* pPlayerInfo = &(l->data());
- assert (pPlayerInfo);
- debugf("Logging off ship for %s, ID=%d\n",
- pPlayerInfo->CharacterName(), pPlayerInfo->ShipID());
- RemovePlayerFromSide(pPlayerInfo, QSR_Quit);
- RemovePlayerFromMission(pPlayerInfo, QSR_Quit);
- }
- }
- }
- }
- break;
- case FM_S_STATION_DESTROYED:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmStation, S, STATION_DESTROYED, pfm);
- IstationIGC * station = m_pCoreIGC->GetStation(
- pfmStation->stationID);
- if (station)
- {
- station->GetCluster()->GetClusterSite()->AddExplosion(station,
- station->GetStationType()->HasCapability(c_sabmFlag)
- ? c_etLargeStation
- : c_etSmallStation);
- if (pfmStation->launcher != NA)
- {
- IshipIGC * pship = GetCore()->GetShip(pfmStation->launcher);
- PostText(true, START_COLOR_STRING "%s" END_COLOR_STRING " destroyed " START_COLOR_STRING "%s's %s" END_COLOR_STRING " in %s.",
- (PCC) ConvertColorToString (pship ? pship->GetSide ()->GetColor () : Color::White ()),
- (pship ? pship->GetName() : "Unknown ship"),
- (PCC) ConvertColorToString (station->GetSide ()->GetColor ()),
- station->GetSide()->GetName(),
- station->GetName(),
- station->GetCluster()->GetName()
- );
- }
- else
- PostText(true, START_COLOR_STRING "%s's %s" END_COLOR_STRING " in %s was destroyed.",
- (PCC) ConvertColorToString (station->GetSide()->GetColor ()),
- station->GetSide()->GetName(),
- station->GetName(),
- station->GetCluster()->GetName());
- if (station->GetSide() == GetSide())
- PlaySoundEffect(station->GetStationType()->GetDestroyedSound());
- else
- PlaySoundEffect(station->GetStationType()->GetEnemyDestroyedSound());
- station->Terminate();
- }
- }
- break;
- case FM_S_STATIONS_UPDATE:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmStation, S, STATIONS_UPDATE, pfm);
- IclusterIGC* pcluster = GetChatCluster();
- if (pcluster)
- {
- for (int i = int(pfmStation->cbrgStationStates /
- sizeof(StationState)) - 1; (i >= 0); i--)
- {
- StationState* pss = ((StationState*)(FM_VAR_REF(pfmStation, rgStationStates))) + i;
- IstationIGC * station = pcluster->GetStation(pss->stationID);
- if (station)
- {
- station->SetFraction(pss->bpHullFraction);
- station->SetShieldFraction(pss->bpShieldFraction);
- }
- }
- }
- }
- break;
- case FM_S_PROBES_UPDATE:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmProbe, S, PROBES_UPDATE, pfm);
- IclusterIGC* pcluster = GetCluster();
- if (pcluster)
- {
- for (int i = int(pfmProbe->cbrgProbeStates /
- sizeof(ProbeState)) - 1; (i >= 0); i--)
- {
- ProbeState* pps = ((ProbeState*)(FM_VAR_REF(pfmProbe, rgProbeStates))) + i;
- IprobeIGC * probe = pcluster->GetProbe(pps->probeID);
- if (probe)
- probe->SetFraction(pps->bpFraction);
- }
- }
- }
- break;
- case FM_S_ASTEROIDS_UPDATE:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmAsteroids, S, ASTEROIDS_UPDATE, pfm);
- IclusterIGC* pcluster = GetCluster();
- if (pcluster)
- {
- for (int i = int(pfmAsteroids->cbrgAsteroidStates /
- sizeof(AsteroidState)) - 1; (i >= 0); i--)
- {
- AsteroidState* pas = ((AsteroidState*)(FM_VAR_REF(pfmAsteroids, rgAsteroidStates))) + i;
- IasteroidIGC* asteroid = pcluster->GetAsteroid(pas->asteroidID);
- if (asteroid)
- {
- Orientation o;
- pas->co.Export(&o);
- asteroid->SetOrientation(o);
- asteroid->SetOre(float(pas->ore));
- asteroid->SetFraction(pas->bpFraction);
- }
- }
- }
- }
- break;
- case FM_S_STATION_CAPTURE:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmStationCapture, S, STATION_CAPTURE, pfm);
- IstationIGC * station = m_pCoreIGC->GetStation(pfmStationCapture->stationID);
- if (station)
- {
- TRef<BucketStatusArray> prgStatus;
- /* NYI: Used to be ... is the new code still valid?
- if ((pfmStationCapture->iSide != GetSide()->GetObjectID()) &&
- m_mapBucketStatusArray.Find(pfmStationCapture->stationID, prgStatus))
- */
- if ((pfmStationCapture->sidOld == GetSide()->GetObjectID()) &&
- m_mapBucketStatusArray.Find(pfmStationCapture->stationID, prgStatus))
- {
- // we lost the station... purge the buckets
- m_mapBucketStatusArray.Remove(pfmStationCapture->stationID);
- }
- m_pClientEventSource->OnStationCaptured(pfmStationCapture->stationID, pfmStationCapture->sidNew);
- IsideIGC* psideNew = m_pCoreIGC->GetSide(pfmStationCapture->sidNew);
- PostText(true, START_COLOR_STRING "%s" END_COLOR_STRING " captured " START_COLOR_STRING "%s's %s" END_COLOR_STRING " in %s.",
- (PCC) ConvertColorToString (GetCore()->GetShip(pfmStationCapture->shipIDCredit)->GetSide ()->GetColor ()),
- GetCore()->GetShip(pfmStationCapture->shipIDCredit)->GetName(),
- (PCC) ConvertColorToString (station->GetSide()->GetColor ()),
- station->GetSide()->GetName(),
- station->GetName(),
- station->GetCluster()->GetName()
- );
- if (pfmStationCapture->sidOld == GetSideID())
- PlaySoundEffect(station->GetStationType()->GetCapturedSound());
- else if (pfmStationCapture->sidNew == GetSideID())
- PlaySoundEffect(station->GetStationType()->GetEnemyCapturedSound());
- station->SetSide(psideNew);
- }
- }
- break;
- case FM_S_LIGHT_SHIPS_UPDATE:
- {
- if (GetCluster())
- {
- CASTPFM(pfmLight, S, LIGHT_SHIPS_UPDATE, pfm);
- ShipID myShipID = m_ship->GetObjectID();
- ShipID* pitu = (ShipID*)(FM_VAR_REF(pfmLight, rgInactiveTurretUpdates));
- if (pitu)
- {
- ShipID* pituMax = (ShipID*)((char*)pitu + pfmLight->cbrgInactiveTurretUpdates);
- //Process the inactive turret updates ..
- while (pitu < pituMax)
- {
- ShipID shipID = *(pitu++);
- if (shipID != myShipID)
- {
- IshipIGC* pship = m_pCoreIGC->GetShip(shipID);
- //The following checks shouldn't be needed ... but since these messages
- //can arrive in any order, paranoia isn't bad
- if (pship && pship->GetParentShip() && pship->GetCluster())
- pship->SetStateM(0); //Stop shooting
- }
- }
- }
- ServerLightShipUpdate* plsu = (ServerLightShipUpdate*)(FM_VAR_REF(pfmLight, rgLightShipUpdates));
- if (plsu)
- {
- ServerLightShipUpdate* plsuMax = (ServerLightShipUpdate*)((char*)plsu + pfmLight->cbrgLightShipUpdates);
- //Process the light ship updates
- while (plsu < plsuMax)
- {
- ServerLightShipUpdate& lsu = *(plsu++);
- //Never get updates for yourself
- assert (lsu.shipID != myShipID);
- IshipIGC* pship = m_pCoreIGC->GetShip(lsu.shipID);
- if (pship && (pship->GetParentShip() == NULL) && pship->GetCluster())
- {
- pship->ProcessShipUpdate(lsu);
- }
- }
- }
- }
- }
- break;
- case FM_S_HEAVY_SHIPS_UPDATE:
- {
- if (GetCluster())
- {
- CASTPFM(pfmHeavy, S, HEAVY_SHIPS_UPDATE, pfm);
- if (m_pmodelServerTarget && m_pmodelServerTarget->GetCluster() && (pfmHeavy->bpTargetHull.GetChar() != 255))
- {
- switch(m_pmodelServerTarget->GetObjectType())
- {
- case OT_ship:
- {
- IshipIGC* pship = ((IshipIGC*)(ImodelIGC*)m_pmodelServerTarget)->GetSourceShip();
- pship->SetFraction(pfmHeavy->bpTargetHull);
- IshieldIGC* pshield = (IshieldIGC*)(pship->GetMountedPart(ET_Shield, 0));
- if (pshield)
- pshield->SetFraction(pfmHeavy->bpTargetShield);
- }
- break;
- case OT_station:
- {
- IstationIGC* pstation = (IstationIGC*)(ImodelIGC*)m_pmodelServerTarget;
- pstation->SetFraction(pfmHeavy->bpTargetHull);
- pstation->SetShieldFraction(pfmHeavy->bpTargetShield);
- }
- break;
- case OT_probe:
- case OT_asteroid:
- case OT_missile:
- {
- ((IdamageIGC*)(ImodelIGC*)m_pmodelServerTarget)->SetFraction(pfmHeavy->bpTargetHull);
- }
- }
- }
- ServerActiveTurretUpdate* patu = (ServerActiveTurretUpdate*)(FM_VAR_REF(pfmHeavy, rgActiveTurretUpdates));
- if (patu)
- {
- ServerActiveTurretUpdate* patuMax = (ServerActiveTurretUpdate*)((char*)patu + pfmHeavy->cbrgActiveTurretUpdates);
- //Process the active turret updates ..
- while (patu < patuMax)
- {
- ServerActiveTurretUpdate& atu= *(patu++);
- assert (atu.shipID != m_ship->GetObjectID());
- IshipIGC* pship = m_pCoreIGC->GetShip(atu.shipID);
- //The following checks shouldn't be needed ... but since these messages
- //can arrive in any order, paranoia isn't bad
- if (pship && pship->GetParentShip() && pship->GetCluster())
- {
- pship->ProcessShipUpdate(pfmHeavy->timeReference, atu);
- }
- }
- }
- ServerHeavyShipUpdate* phsu = (ServerHeavyShipUpdate*)(FM_VAR_REF(pfmHeavy, rgHeavyShipUpdates));
- if (phsu)
- {
- ServerHeavyShipUpdate* phsuMax = (ServerHeavyShipUpdate*)((char*)phsu + pfmHeavy->cbrgHeavyShipUpdates);
- //Process the heavy ship updates
- while (phsu < phsuMax)
- {
- ServerHeavyShipUpdate& hsu = *(phsu++);
- //Never get updates for yourself
- assert (hsu.shipID != m_ship->GetObjectID());
- IshipIGC* pship = m_pCoreIGC->GetShip(hsu.shipID);
- if (pship && (pship->GetParentShip() == NULL) && pship->GetCluster())
- {
- pship->ProcessShipUpdate(pfmHeavy->timeReference, pfmHeavy->positionReference, hsu);
- }
- }
- }
- m_ship->GetSourceShip()->ProcessFractions(pfmHeavy->fractions);
- }
- }
- break;
- case FM_S_PROMOTE:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmPromote, S, PROMOTE, pfm);
- IshipIGC* pship = m_pCoreIGC->GetShip(pfmPromote->shipidPromoted);
- assert (pship);
- IshipIGC* pshipParent = pship->GetParentShip();
- if (pshipParent)
- {
- pship->Promote();
- m_pClientEventSource->OnBoardShip(pship, NULL);
- m_pClientEventSource->OnBoardShip(pshipParent, pship);
-
- if (pshipParent == m_ship)
- PostText(true, "You have been demoted to a turret gunner");
- else if (pship == m_ship)
- PostText(true, "You have been promoted to pilot");
- }
- }
- break;
- case FM_S_WARP_BOMB:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmWarpBomb, S, WARP_BOMB, pfm);
- IwarpIGC* pwarp = m_pCoreIGC->GetWarp(pfmWarpBomb->warpidBombed);
- if (pwarp)
- {
- ImissileTypeIGC* pmt = (ImissileTypeIGC*)(m_pCoreIGC->GetExpendableType(pfmWarpBomb->expendableidMissile));
- assert (pmt);
- assert (pmt->GetObjectType() == OT_missileType);
- pwarp->AddBomb(ClientTimeFromServerTime(pfmWarpBomb->timeExplosion), pmt);
- IclusterIGC* pclusterMe = GetCluster();
- IclusterIGC* pc1 = pwarp->GetCluster();
- IclusterIGC* pc2 = pwarp->GetDestination()->GetCluster();
- if ((pclusterMe == pc1) || (pclusterMe == pc2))
- PostText(true, "Aleph to %s destabilized\n", (pclusterMe == pc1) ? pc2->GetName() : pc1->GetName());
- /*
- DamageTypeID dtid = pmt->GetDamageType();
- float p = pmt->GetPower();
- float r = pmt->GetBlastRadius();
- IclusterIGC* pcluster = pwarp->GetCluster();
- pcluster->CreateExplosion(dtid,
- p,
- r,
- c_etBigShip,
- pcluster->GetLastUpdate(),
- pwarp->GetPosition(),
- NULL);
- pwarp = pwarp->GetDestination();
- pcluster = pwarp->GetCluster();
- pcluster->CreateExplosion(dtid,
- p,
- r,
- c_etBigShip,
- pcluster->GetLastUpdate(),
- pwarp->GetPosition(),
- NULL);
- */
- }
- }
- break;
- case FM_S_RIPCORD_ACTIVATE:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmRipcordActivate, S, RIPCORD_ACTIVATE, pfm);
- IshipIGC* pshipSource = m_ship->GetSourceShip();
- if (pfmRipcordActivate->shipidRipcord == pshipSource->GetObjectID())
- {
- //We are ripcording
- ImodelIGC* pmodelRipcord = m_pCoreIGC->GetModel(pfmRipcordActivate->otRipcord,
- pfmRipcordActivate->oidRipcord);
- IclusterIGC* pclusterDesired = m_pCoreIGC->GetCluster(pfmRipcordActivate->sidRipcord);
- assert (pclusterDesired);
- assert (pmodelRipcord);
- IclusterIGC* pclusterRipcord = pmodelRipcord->GetCluster();
- if (pclusterRipcord == NULL)
- {
- assert (pmodelRipcord->GetObjectType() == OT_ship);
- PlayerInfo* ppi = (PlayerInfo*)(((IshipIGC*)pmodelRipcord)->GetPrivateData());
- assert (ppi->StatusIsCurrent());
- pclusterRipcord = m_pCoreIGC->GetCluster(ppi->LastSeenSector());
- assert (pclusterRipcord);
- }
- const char* name = pclusterRipcord->GetName();
- char bfr[100];
- if (pclusterRipcord != pclusterDesired)
- sprintf(bfr, "Ripcording to %s, which is closest to %s",
- name, pclusterDesired->GetName());
- else
- sprintf(bfr, "Ripcording to %s", name);
- PostText(true, bfr);
- if (pmodelRipcord != pshipSource->GetRipcordModel())
- {
- pshipSource->SetRipcordModel(pmodelRipcord);
- pshipSource->ResetRipcordTimeLeft();
- }
- // set up the ripcord effect
- pshipSource->GetThingSite ()->SetTimeUntilRipcord (pshipSource->GetRipcordTimeLeft ());
- }
- else
- {
- //Someone else is ripcording ... just set the model cause we
- //really don't care
- IshipIGC* pship = m_pCoreIGC->GetShip(pfmRipcordActivate->shipidRipcord);
- //We need a valid model that will stick around at least as long as the
- //ship. Hmmm ... lets see.
- pship->SetRipcordModel(pship);
- // set up the ripcord effect
- pship->ResetRipcordTimeLeft ();
- pship->GetThingSite ()->SetTimeUntilRipcord (pship->GetRipcordTimeLeft ());
- }
- }
- break;
- case FM_S_RIPCORD_DENIED:
- {
- if (!IsInGame())
- break;
- PlayNotificationSound(salNoRipcordSound, m_ship);
- }
- break;
- case FM_S_RIPCORD_ABORTED:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmRipcordAborted, S, RIPCORD_ABORTED, pfm);
- IshipIGC* pship = m_pCoreIGC->GetShip(pfmRipcordAborted->shipidRipcord);
- assert (pship);
- pship->SetRipcordModel(NULL);
- if (pship == m_ship->GetSourceShip())
- PlayNotificationSound(salRipcordAbortedSound, pship);
- // clear the ripcord effect
- pship->GetThingSite ()->SetTimeUntilRipcord (-1.0f);
- }
- break;
- case FM_S_SET_CLUSTER:
- {
- CASTPFM(pfmSetCluster, S, SET_CLUSTER, pfm);
- if (IsLockedDown())
- EndLockDown(lockdownLoadout | lockdownTeleporting);
- // cancel any pending disembarks (it's now a bad idea to step out of the airlock)
- m_bLaunchAfterDisembark = false;
- m_sidBoardAfterDisembark = NA;
- m_sidTeleportAfterDisembark = NA;
- IclusterIGC* pcluster = m_pCoreIGC->GetCluster(pfmSetCluster->sectorID);
- assert (pcluster);
- //The ship update is either for us or for our parent ship
- IshipIGC* pship = m_ship->GetSourceShip();
- //Pretend the server sends a ship delete message for everything the player could see
- {
- //We could use the old cluster ... but modifying the contents of a list
- const ShipListIGC* ships = m_pCoreIGC->GetShips();
- assert (ships);
- for (ShipLinkIGC* l = ships->first();
- (l != NULL);
- l = l->next())
- {
- IshipIGC* s = l->data();
- if ((s != pship) && (s != m_ship))
- s->SetCluster(NULL);
- }
- }
- {
- //Reset the ship's trail
- assert (pship->GetThingSite());
- pship->GetThingSite()->SetTrailColor(GetShip()->GetSide()->GetColor());
- IclusterIGC* pclusterOld;
- Orientation orientationOld;
- if (pship != m_ship)
- {
- pclusterOld = NULL;
- orientationOld = pship->GetOrientation();
- }
- Time time = pcluster->GetLastUpdate();
- pship->SetLastUpdate(time);
- pfmSetCluster->shipupdate.time = ClientTimeFromServerTime(pfmSetCluster->shipupdate.time);
- pship->ProcessShipUpdate(pfmSetCluster->shipupdate);
- if (m_ship->GetStation() != NULL)
- {
- assert (m_ship->GetCluster() == NULL);
- m_ship->SetStation(NULL); //This will call IIgcSite::ChangeStation()
- }
- else
- {
- pclusterOld = m_ship->GetCluster();
- if (pclusterOld != NULL)
- {
- //Hack ... play the sound effect for an aleph since the player
- //did not undock.
- PlaySoundEffect(jumpSound);
- }
- }
- assert (m_ship->GetStation() == NULL);
- if (pship == m_ship)
- {
- //Set the cookie
- SetCookie(pfmSetCluster->cookie);
- }
- else
- {
- //Adjust our orientation
- Mount tid = m_ship->GetTurretID();
- if (tid != NA)
- {
- if (pclusterOld == NULL)
- {
- Orientation oTurret = pship->GetHullType()->GetWeaponOrientation(tid) *
- pship->GetOrientation();
- m_ship->SetOrientation(oTurret);
- }
- else
- {
- //Preserve the old orientation relative to the ship
- m_ship->SetOrientation(pship->GetOrientation().TimesInverse(orientationOld) * m_ship->GetOrientation());
- }
- }
- }
- pship->SetCluster(pcluster);
- }
- }
- break;
- case FM_S_DOCKED:
- {
- CASTPFM(pfmDocked, S, DOCKED, pfm);
- //Pretend the server sends a ship delete message for everything the player could see
- {
- //We could use the old cluster ... but modifying the contents of a list
- const ShipListIGC* ships = m_pCoreIGC->GetShips();
- assert (ships);
- for (ShipLinkIGC* l = ships->first();
- (l != NULL);
- l = l->next())
- {
- IshipIGC* s = l->data();
- if (s != m_ship)
- s->SetCluster(NULL);
- }
- }
- m_ship->SetStation(m_pCoreIGC->GetStation(pfmDocked->stationID));
- assert (m_ship->GetCluster() == NULL);
- }
- break;
- case FM_S_SINGLE_SHIP_UPDATE:
- {
- if (IsWaitingForGameRestart())
- break;
- IclusterIGC* pcluster = GetCluster();
- if (pcluster)
- {
- CASTPFM(pfmSSU, S, SINGLE_SHIP_UPDATE, pfm);
- //Ignore single ship updates for ourself
- if (m_ship->GetObjectID() != pfmSSU->shipupdate.shipID)
- {
- //Ignore single shup updates for our parent (this data comes via SetCluster).
- IshipIGC* pshipParent = m_ship->GetParentShip();
- if ((pshipParent == NULL) ||
- (pshipParent->GetObjectID() != pfmSSU->shipupdate.shipID))
- {
- IshipIGC* ship = m_pCoreIGC->GetShip(pfmSSU->shipupdate.shipID);
- assert (ship);
- assert (ship->GetBaseHullType());
- //Never get single ship updates for passengers
- assert (ship->GetParentShip() == NULL);
- //Reset the ship's trail
- assert (ship->GetThingSite());
- ship->GetThingSite()->SetTrailColor(ship->GetSide()->GetColor());
- //Force the updates to be processed, even if it is out of sync with the local time
- Time time = pcluster->GetLastUpdate();
- ship->SetLastUpdate(time);
- pfmSSU->shipupdate.time = ClientTimeFromServerTime(pfmSSU->shipupdate.time);
- ship->ProcessShipUpdate(pfmSSU->shipupdate);
- ship->SetRipcordModel(pfmSSU->bIsRipcording ? ship : NULL); //Just has to be a valid pointer
- {
- ImodelIGC* pmodel = m_pCoreIGC->GetModel(pfmSSU->otTarget, pfmSSU->oidTarget);
- ship->SetCommand(c_cmdCurrent, pmodel, c_cidNone);
- }
- if (ship->GetCluster() == NULL)
- {
- // The ship has moved to the same cluster as the player
- debugf("Moving %s/%d to %s\n",
- ship->GetName(), ship->GetObjectID(),
- pcluster->GetName());
- ship->SetCluster(pcluster);
- ship->SetLastUpdate(time);
- }
- else
- assert (ship->GetCluster() == pcluster);
- }
- }
- }
- }
- break;
- case FM_S_SHIP_RESET:
- {
- CASTPFM(pfmShipReset, S, SHIP_RESET, pfm);
- if (m_ship->GetCluster() && (m_ship->GetParentShip() == NULL))
- {
- pfmShipReset->shipupdate.time = ClientTimeFromServerTime(pfmShipReset->shipupdate.time);
- m_ship->ProcessShipUpdate(pfmShipReset->shipupdate, false);
- SetCookie(pfmShipReset->cookie);
- }
- }
- break;
- case FM_S_AUTODONATE:
- {
- CASTPFM(pfmAutoDonate, S, AUTODONATE, pfm);
- IshipIGC* pshipBy = m_ship->GetSide()->GetShip(pfmAutoDonate->sidDonateBy);
- assert (pshipBy);
- IshipIGC* pshipTo = pfmAutoDonate->sidDonateTo == NA
- ? NULL
- : m_ship->GetSide()->GetShip(pfmAutoDonate->sidDonateTo);
- IshipIGC* pshipOld = pshipBy->GetAutoDonate();
- pshipBy->SetAutoDonate(pshipTo);
- if ((m_pCoreIGC->GetMissionStage() == STAGE_STARTED) && (pshipOld != pshipTo))
- {
- if (pshipBy == GetShip())
- {
- if (pshipTo)
- {
- char bfr[100];
- sprintf(bfr, "You have started donating your income to %s", pshipTo->GetName());
- PostText(true, bfr);
- }
- else
- {
- PostText(true, "You have stopped donating your income to %s", pshipOld->GetName());
- }
- }
- else if (pshipTo == GetShip())
- {
- char bfr[100];
- sprintf(bfr, "%s is now donating to you", pshipBy->GetName());
- PostText(true, bfr);
- // count donors, and play the designated investor sound if we've gone from 0 to 1
- int nNumDonors = 0;
- for (ShipLinkIGC* psl = GetSide()->GetShips()->first();
- (psl != NULL);
- psl = psl->next())
- {
- if (psl->data()->GetAutoDonate() == GetShip())
- nNumDonors++;
- }
- if (nNumDonors == 1)
- PlaySoundEffect(investorSound);
- }
- else if (pshipOld == GetShip())
- {
- char bfr[100];
- sprintf(bfr, "%s has stopped donating to you", pshipBy->GetName());
- PostText(true, bfr);
- }
- }
- if (pfmAutoDonate->amount != 0)
- {
- if (pshipTo)
- {
- //An autodonation to another player ... increase the target's money
- PlayerInfo* ppiTo = (PlayerInfo*)(pshipTo->GetPrivateData());
- ppiTo->SetMoney(ppiTo->GetMoney() + pfmAutoDonate->amount);
- m_pClientEventSource->OnMoneyChange(ppiTo);
- if (pshipBy != m_ship)
- {
- //Someone other than me autodonated ... subtract their money
- PlayerInfo* ppiBy = (PlayerInfo*)(pshipBy->GetPrivateData());
- ppiBy->SetMoney(ppiBy->GetMoney() - pfmAutoDonate->amount);
- m_pClientEventSource->OnMoneyChange(ppiBy);
- }
- }
- else if (pshipBy == m_ship)
- {
- //We made a request and it was denied ... get a refund.
- SetMoney(GetMoney() + pfmAutoDonate->amount);
- m_pClientEventSource->OnMoneyChange(m_pPlayerInfo);
- }
- }
- SideInfo* psideinfo = m_pMissionInfo->GetSideInfo(GetSideID());
- if (psideinfo)
- {
- psideinfo->GetMembers().GetSink()();
- }
- }
- break;
- case FM_S_PAYDAY:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmPayday, S, PAYDAY, pfm);
- Money moneyReceived = 0;
- for (ShipLinkIGC* psl = GetSide()->GetShips()->first();
- (psl != NULL);
- psl = psl->next())
- {
- IshipIGC* pship = psl->data();
- if (pship->GetPilotType() >= c_ptPlayer)
- {
- IshipIGC* pshipDonate = pship->GetAutoDonate();
- if (pshipDonate)
- {
- if (pshipDonate == m_ship)
- moneyReceived += pfmPayday->dMoney;
- }
- else
- pshipDonate = pship;
- PlayerInfo* ppi = (PlayerInfo*)(pshipDonate->GetPrivateData());
- ppi->SetMoney(ppi->GetMoney() + pfmPayday->dMoney);
- m_pClientEventSource->OnMoneyChange(ppi);
- }
- }
- m_pMissionInfo->GetSideInfo(GetSide()->GetObjectID())->GetMembers().GetSink()();
- PlaySoundEffect(paydaySound);
- {
- IshipIGC* pshipDonate = m_ship->GetAutoDonate();
- if (pshipDonate)
- PostText(false, "You donated your payday of $%d to %s.", pfmPayday->dMoney, pshipDonate->GetName());
- else if (moneyReceived == 0)
- PostText(false, "You received a payday of $%d.", pfmPayday->dMoney);
- else
- PostText(false, "You received $%d in pay and donations.", pfmPayday->dMoney + moneyReceived);
- }
- }
- break;
- case FM_S_MONEY_CHANGE:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmMoney, S, MONEY_CHANGE, pfm);
- //Ignore any transactions we initiated.
- ShipID sid = GetShipID();
- if (sid != pfmMoney->sidFrom)
- {
- IshipIGC* pshipTo = m_pCoreIGC->GetShip(pfmMoney->sidTo);
- assert (pshipTo);
- {
- PlayerInfo* ppiTo = (PlayerInfo*)(pshipTo->GetPrivateData());
- ppiTo->SetMoney(ppiTo->GetMoney() + pfmMoney->dMoney);
- m_pClientEventSource->OnMoneyChange(ppiTo);
- }
- if ((pfmMoney->sidTo != pfmMoney->sidFrom) && (pfmMoney->sidFrom != NA))
- {
- //This was a donation from one player to another
- IshipIGC* pshipFrom = m_pCoreIGC->GetShip(pfmMoney->sidFrom);
- assert (pshipFrom);
- {
- PlayerInfo* ppiFrom = (PlayerInfo*)(pshipFrom->GetPrivateData());
- ppiFrom->SetMoney(ppiFrom->GetMoney() - pfmMoney->dMoney);
- m_pClientEventSource->OnMoneyChange(ppiFrom);
- if (pfmMoney->sidTo == sid)
- PostText(false, "%s gave you $%d. You now have $%d.",
- ppiFrom->CharacterName(), pfmMoney->dMoney, MyPlayerInfo()->GetMoney());
- }
- }
- m_pMissionInfo->GetSideInfo(GetSide()->GetObjectID())->GetMembers().GetSink()();
- }
- }
- break;
- case FM_S_SET_MONEY:
- {
- CASTPFM(pfmMoney, S, SET_MONEY, pfm);
- IshipIGC* pship = m_pCoreIGC->GetShip(pfmMoney->shipID);
- assert (pship);
- {
- PlayerInfo* ppi = (PlayerInfo*)(pship->GetPrivateData());
- ppi->SetMoney(pfmMoney->money);
- m_pClientEventSource->OnMoneyChange(ppi);
- }
- m_pMissionInfo->GetSideInfo(GetSide()->GetObjectID())->GetMembers().GetSink()();
- }
- break;
- case FM_S_ADD_PART:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmAddPart, S, ADD_PART, pfm);
- if (pfmAddPart->shipID != m_ship->GetObjectID())
- {
- IshipIGC* pShip = m_pCoreIGC->GetShip(pfmAddPart->shipID);
- assert (pShip);
- assert (pShip->GetParentShip() == NULL);
- assert (pShip->GetBaseHullType());
- IpartTypeIGC* ppt = m_pCoreIGC->GetPartType(pfmAddPart->newPartData.partID);
- assert (ppt);
- IpartIGC* ppart = pShip->GetMountedPart(ppt->GetEquipmentType(), pfmAddPart->newPartData.mountID);
- if (ppart)
- {
- assert (ppart->GetPartType() == ppt);
- ppart->SetAmount(ppart->GetAmount() + pfmAddPart->newPartData.amount);
- }
- else
- pShip->CreateAndAddPart(ppt, pfmAddPart->newPartData.mountID, pfmAddPart->newPartData.amount);
- }
- }
- break;
- case FM_CS_DROP_PART:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmDropPart, CS, DROP_PART, pfm);
- if (pfmDropPart->shipID != m_ship->GetObjectID())
- {
- IshipIGC* pShip = m_pCoreIGC->GetShip(pfmDropPart->shipID);
- assert (pShip);
- assert (pShip->GetParentShip() == NULL);
- assert (pShip->GetBaseHullType());
- IpartIGC* ppart = pShip->GetMountedPart(pfmDropPart->et, pfmDropPart->mount);
- assert (ppart);
- ppart->Terminate();
- }
- }
- break;
- case FM_CS_SWAP_PART:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmSwapPart, CS, SWAP_PART, pfm);
- if (pfmSwapPart->shipID != m_ship->GetObjectID())
- {
- IshipIGC* pShip = m_pCoreIGC->GetShip(pfmSwapPart->shipID);
- assert (pShip);
- assert (pShip->GetParentShip() == NULL);
- assert (pShip->GetBaseHullType());
- assert (pfmSwapPart->mountNew >= -c_maxCargo);
- IpartIGC* ppart = pShip->GetMountedPart(pfmSwapPart->etOld, pfmSwapPart->mountOld);
- assert (ppart);
- IpartIGC* ppartNew = pShip->GetMountedPart(pfmSwapPart->etOld, pfmSwapPart->mountNew);
- if (ppartNew)
- {
- ppart->SetMountID(c_mountNA);
- ppartNew->SetMountID(pfmSwapPart->mountOld);
- }
- ppart->SetMountID(pfmSwapPart->mountNew);
- }
- }
- break;
- case FM_CS_RELOAD:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmReload, CS, RELOAD, pfm);
- if (pfmReload->shipID != m_ship->GetObjectID())
- {
- IshipIGC* pship = m_pCoreIGC->GetShip(pfmReload->shipID);
- assert (pship);
- ReloadData* prlNext = (ReloadData*)FM_VAR_REF(pfmReload, rgReloads);
- int nReloads = pfmReload->cbrgReloads / sizeof(ReloadData);
- ReloadData* prlStop = prlNext + nReloads;
- while (prlNext < prlStop)
- {
- assert (prlNext->mount < 0);
- assert (prlNext->mount >= -c_maxCargo);
- IpartIGC* ppart = pship->GetMountedPart(NA, prlNext->mount);
- ObjectType type = ppart->GetObjectType();
- if (type == OT_pack)
- {
- IpackIGC* ppack = (IpackIGC*)ppart;
- PackType packtype = ppack->GetPackType();
- short amount = ppack->GetAmount();
- if (prlNext->amountTransfered == NA)
- {
- OnReload(ppart, true);
- ppack->Terminate();
- }
- else
- {
- OnReload(ppart, false);
- assert (prlNext->amountTransfered > 0);
- assert (prlNext->amountTransfered < amount);
- ppack->SetAmount(amount - prlNext->amountTransfered);
- amount = prlNext->amountTransfered;
- }
- if (packtype == c_packAmmo)
- {
- pship->SetAmmo(pship->GetAmmo() + amount);
- //disable all mounted weapons that use ammo
- Mount maxWeapons = pship->GetHullType()->GetMaxWeapons();
- for (Mount i = 0; (i < maxWeapons); i++)
- {
- IweaponIGC* pw = (IweaponIGC*)(pship->GetMountedPart(ET_Weapon, i));
- if (pw && (pw->GetAmmoPerShot() != 0))
- pw->SetMountedFraction(0.0f);
- }
- }
- else
- {
- assert (packtype == c_packFuel);
- pship->SetFuel(pship->GetFuel() + float(amount));
- IpartIGC* pa = pship->GetMountedPart(ET_Afterburner, 0);
- if (pa)
- pa->SetMountedFraction(0.0f);
- }
- }
- else
- {
- assert (IlauncherIGC::IsLauncher(type));
- IlauncherIGC* plauncher = (IlauncherIGC*)ppart;
- IlauncherIGC* plauncherMounted = (IlauncherIGC*)(pship->GetMountedPart(plauncher->GetEquipmentType(), 0));
- if (prlNext->amountTransfered == NA)
- {
- OnReload(ppart, true);
- assert ((plauncherMounted == NULL) || (plauncherMounted->GetAmount() == 0));
- if (plauncherMounted)
- plauncherMounted->Terminate();
- plauncher->SetMountID(0);
- }
- else
- {
- assert (prlNext->amountTransfered <= plauncher->GetAmount());
- assert (plauncherMounted);
- short amount = plauncher->GetAmount();
- if (amount == prlNext->amountTransfered)
- {
- OnReload(ppart, true);
- plauncher->Terminate();
- }
- else
- {
- OnReload(ppart, false);
- plauncher->SetAmount(amount - prlNext->amountTransfered);
- }
- plauncherMounted->SetAmount(plauncherMounted->GetAmount() + prlNext->amountTransfered);
- plauncherMounted->SetMountedFraction(0.0f);
- plauncherMounted->ResetTimeLoaded();
- }
- }
- prlNext++;
- }
- }
- }
- break;
- case FM_CS_FIRE_MISSILE:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmFireMissile, CS, FIRE_MISSILE, pfm);
- DataMissileIGC dm;
- dm.pLauncher = m_pCoreIGC->GetShip(pfmFireMissile->launcherID);
- if (dm.pLauncher)
- {
- dm.pmissiletype = (ImissileTypeIGC*)(m_pCoreIGC->GetExpendableType(pfmFireMissile->missiletypeID));
- dm.pTarget = m_pCoreIGC->GetModel(pfmFireMissile->targetType, pfmFireMissile->targetID);
- dm.pCluster = m_pCoreIGC->GetCluster(pfmFireMissile->clusterID);
- dm.lock = pfmFireMissile->lock;
- Time timeFired = ClientTimeFromServerTime(pfmFireMissile->timeFired);
- int iNumMissiles = pfmFireMissile->cbmissileLaunchData / sizeof(MissileLaunchData);
- MissileLaunchData* pMissileLaunchData = (MissileLaunchData*) (FM_VAR_REF(pfmFireMissile, missileLaunchData));
- for (int i = 0; i < iNumMissiles; i++)
- {
- dm.position = pMissileLaunchData[i].vecPosition;
- dm.velocity = pMissileLaunchData[i].vecVelocity;
- dm.forward = pMissileLaunchData[i].vecForward;
- dm.missileID = pMissileLaunchData[i].missileID;
- dm.bDud = pfmFireMissile->bDud;
- ImissileIGC* m = (ImissileIGC*)(m_pCoreIGC->CreateObject(timeFired, OT_missile, &dm, sizeof(dm)));
- if (m)
- m->Release();
- }
- //The player immediately adjusts their own count on launching the missile so don't update
- //their count.
- if (pfmFireMissile->launcherID != m_ship->GetObjectID())
- {
- ImagazineIGC* pmagazine = (ImagazineIGC*)(dm.pLauncher->GetMountedPart(ET_Magazine, 0));
- if (pmagazine)
- {
- short amount = pmagazine->GetAmount() - iNumMissiles;
- assert (amount >= 0);
- pmagazine->SetAmount(amount);
- }
- }
- }
- }
- break;
- case FM_S_FIRE_EXPENDABLE:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmFireExpendable, S, FIRE_EXPENDABLE, pfm);
- //Ignore messages that you fired a mine since you already decremented the mine count
- if (pfmFireExpendable->launcherID != m_ship->GetObjectID())
- {
- IshipIGC* pshipLauncher = m_pCoreIGC->GetShip(pfmFireExpendable->launcherID);
- if (pshipLauncher)
- {
- IdispenserIGC* pdispenser = (IdispenserIGC*)(pshipLauncher->GetMountedPart(pfmFireExpendable->equipmentType, 0));
- if (pdispenser)
- {
- short amount = pdispenser->GetAmount() - 1;
- assert (amount >= 0);
- pdispenser->SetAmount(amount);
- }
- }
- }
- }
- break;
- case FM_S_CREATE_CHAFF:
- {
- CASTPFM(pfmChaff, S, CREATE_CHAFF, pfm);
- DataChaffIGC dc;
- if (GetCluster())
- {
- dc.time0 = pfmChaff->time0;
- dc.p0 = pfmChaff->p0;
- dc.v0 = pfmChaff->v0;
- dc.pchafftype = (IchaffTypeIGC*)(m_pCoreIGC->GetExpendableType(pfmChaff->etid));
- assert (dc.pchafftype->GetObjectType() == OT_chaffType);
- dc.pcluster = GetCluster();
- IchaffIGC* c = (IchaffIGC*)(m_pCoreIGC->CreateObject(lastUpdate, OT_chaff, &dc, sizeof(dc)));
- assert (c);
- m_pchaffLastCreated = c;
- c->Release();
- }
- }
- break;
- case FM_S_MISSILE_SPOOFED:
- {
- CASTPFM(pfmMissileSpoofed, S, MISSILE_SPOOFED, pfm);
- // need to make sure we have a cluster because of a race condition
- // when changing view clusters.
- if (GetCluster())
- {
- ImissileIGC* pmissile = GetCluster()->GetMissile(pfmMissileSpoofed->missileID);
- if (pmissile)
- {
- assert (m_pchaffLastCreated);
- pmissile->SetTarget(m_pchaffLastCreated);
- }
- }
- }
- break;
- case FM_S_END_SPOOFING:
- {
- m_pchaffLastCreated = NULL;
- }
- break;
- case FM_S_ASTEROID_DESTROYED:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmAD, S, ASTEROID_DESTROYED, pfm);
- IclusterIGC* pcluster = m_pCoreIGC->GetCluster(pfmAD->clusterID);
- assert (pcluster);
- IasteroidIGC* pasteroid = pcluster->GetAsteroid(pfmAD->asteroidID);
- if (pasteroid)
- {
- if (pfmAD->explodeF)
- pasteroid->GetCluster()->GetClusterSite()->AddExplosion(pasteroid, c_etAsteroid);
- else
- {
- //Pre-terminate the building effect so that terminating the asteroid does not terminate the effect
- //If the server is really lagged (30 seconds or more), the building effect will terminate locally
- //before we get the message. This isn't good, but we shouldn't crash.
- if (pasteroid->GetBuildingEffect())
- pasteroid->SetBuildingEffect(NULL);
- }
- pasteroid->Terminate();
- }
- }
- break;
- case FM_S_ASTEROID_DRAINED:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmAD, S, ASTEROID_DRAINED, pfm);
- IclusterIGC* pcluster = m_pCoreIGC->GetCluster(pfmAD->clusterID);
- assert (pcluster);
- IasteroidIGC* pasteroid = pcluster->GetAsteroid(pfmAD->asteroidID);
- if (pasteroid)
- {
- pasteroid->SetOre(0.0f);
- }
- }
- break;
- case FM_S_PROBE_DESTROYED:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmPD, S, PROBE_DESTROYED, pfm);
- IclusterIGC* pcluster = m_pCoreIGC->GetCluster(pfmPD->clusterID);
- assert (pcluster);
- IprobeIGC* pprobe = pcluster->GetProbe(pfmPD->probeID);
- if (pprobe)
- pprobe->Terminate();
- }
- break;
- case FM_S_BUILDINGEFFECT_DESTROYED:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmBED, S, BUILDINGEFFECT_DESTROYED, pfm);
- IasteroidIGC* pasteroid = m_pCoreIGC->GetAsteroid(pfmBED->asteroidID);
- if (pasteroid)
- {
- IbuildingEffectIGC* pbe = pasteroid->GetBuildingEffect();
- if (pbe)
- pbe->Terminate();
- }
- }
- break;
- case FM_S_MISSILE_DESTROYED:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmMD, S, MISSILE_DESTROYED, pfm);
- IclusterIGC* pcluster = m_pCoreIGC->GetCluster(pfmMD->clusterID);
- assert (pcluster);
- ImissileIGC* pmissile = pcluster->GetMissile(pfmMD->missileID);
- if (pmissile)
- {
- if (pfmMD->position != Vector::GetZero())
- pmissile->Explode(pfmMD->position);
- pmissile->Terminate();
- }
- }
- break;
- case FM_S_MINE_DESTROYED:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmMD, S, MINE_DESTROYED, pfm);
- IclusterIGC* pcluster = m_pCoreIGC->GetCluster(pfmMD->clusterID);
- assert (pcluster);
- ImineIGC* pmine = pcluster->GetMine(pfmMD->mineID);
- if (pmine)
- pmine->Terminate();
- }
- break;
- case FM_CS_ORDER_CHANGE:
- {
- if (!IsInGame())
- break;
- SideInfo* psideinfo = m_pMissionInfo->GetSideInfo(GetSideID());
- if (psideinfo)
- {
- CASTPFM(pfmOC, CS, ORDER_CHANGE, pfm);
- IshipIGC* pship = m_pCoreIGC->GetShip(pfmOC->shipID);
- if (pship)
- {
- ImodelIGC* pmodel = m_pCoreIGC->GetModel(pfmOC->objectType, pfmOC->objectID);
- if (pship != m_ship)
- pship->SetCommand(pfmOC->command, pmodel, pfmOC->commandID);
- else if (pfmOC->command == c_cmdCurrent)
- m_pmodelServerTarget = pmodel;
- psideinfo->GetMembers().GetSink()();
- }
- }
- }
- break;
- case FM_S_TELEPORT_ACK:
- {
- if (!IsInGame())
- break;
- if (IsLockedDown())
- EndLockDown(lockdownTeleporting);
- CASTPFM(pfmAck, S, TELEPORT_ACK, pfm);
- if (pfmAck->stationID != NA)
- {
- IstationIGC* pstation = m_pCoreIGC->GetStation(pfmAck->stationID);
- assert (pstation);
- m_ship->SetStation(pstation);
- if (pfmAck->bNewHull)
- {
- //If the ship had children, it doesn't now
- {
- const ShipListIGC* pshipsChildren = m_ship->GetChildShips();
- ShipLinkIGC* psl;
- while (psl = pshipsChildren->first()) //intentional assignment
- {
- IshipIGC* pshipChild = psl->data();
- pshipChild->SetParentShip(NULL);
- m_pClientEventSource->OnBoardShip(pshipChild, NULL);
- }
- }
- const PartListIGC* pparts = m_ship->GetParts();
- PartLinkIGC* ppl;
- while (ppl = pparts->first()) //Intentional
- ppl->data()->Terminate();
- ReplaceLoadout(pstation);
- }
- PlaySoundEffect(personalJumpSound);
- }
- }
- break;
- case FM_S_BOARD_NACK:
- {
- if (!IsInGame())
- break;
-
- if (IsLockedDown())
- EndLockDown(lockdownTeleporting);
- CASTPFM(pfmBoardNack, S, BOARD_NACK, pfm);
- IshipIGC* pshipRequestedParent = m_pCoreIGC->GetShip(pfmBoardNack->sidRequestedParent);
- m_pClientEventSource->OnBoardFailed(pshipRequestedParent);
- }
- break;
- case FM_S_LEAVE_SHIP:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmLeave, S, LEAVE_SHIP, pfm);
- IshipIGC* pshipChild = m_pCoreIGC->GetShip(pfmLeave->sidChild);
- assert (pshipChild);
- pshipChild->SetParentShip(NULL);
- m_pClientEventSource->OnBoardShip(pshipChild, NULL);
- if (pshipChild == m_ship)
- {
- assert (pshipChild->GetBaseHullType() == NULL);
- assert (pshipChild->GetParts()->n() == 0);
- if (IsLockedDown())
- EndLockDown(lockdownTeleporting);
- pshipChild->SetBaseHullType(pshipChild->GetSide()->GetCivilization()->GetLifepod());
- ReplaceLoadout(m_ship->GetStation(), m_bLaunchAfterDisembark);
- m_bLaunchAfterDisembark = false;
- }
- else if (pshipChild->GetParentShip() == m_ship)
- PostText(true, "%s has left your ship.", pshipChild->GetName());
- }
- break;
- case FM_S_ENTER_LIFEPOD:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmEnter, S, ENTER_LIFEPOD, pfm);
- /*
- IshipIGC* pship = m_pCoreIGC->GetShip(pfmEnter->shipID);
- assert (pship);
- */
- m_ship->SetParentShip(NULL);
- m_pClientEventSource->OnBoardShip(m_ship, NULL);
- //If the ship had children, it doesn't now
- {
- const ShipListIGC* pshipsChildren = m_ship->GetChildShips();
- ShipLinkIGC* psl;
- while (psl = pshipsChildren->first()) //intentional assignment
- {
- IshipIGC* pshipChild = psl->data();
- pshipChild->SetParentShip(NULL);
- m_pClientEventSource->OnBoardShip(pshipChild, NULL);
- }
- }
- {
- const PartListIGC* pparts = m_ship->GetParts();
- PartLinkIGC* ppl;
- while (ppl = pparts->first()) //Intentional
- ppl->data()->Terminate();
- }
- m_ship->SetBaseHullType(m_ship->GetSide()->GetCivilization()->GetLifepod());
- }
- break;
- case FM_CS_LOGOFF:
- {
- m_fLoggedOn = false;
- Disconnect(); // we could already be calling from Disconnect, if the user Alt-F4ed, but this is handled
- break;
- }
-
- case FM_S_LOADOUT_CHANGE:
- {
- if (IsWaitingForGameRestart())
- break;
- CASTPFM(pfmLC, S, LOADOUT_CHANGE, pfm);
- IshipIGC* pship = pfmLC->sidShip == NA
- ? m_ship
- : m_pCoreIGC->GetShip(pfmLC->sidShip);
- assert (pship);
- //debugf("Loadout change for %s/%d\n", pship->GetName(), pfmLC->sidShip);
- //If the ship was a passenger, now it is not
- pship->SetParentShip(NULL);
- m_pClientEventSource->OnBoardShip(pship, NULL);
- //If the ship had children, it doesn't now
- {
- const ShipListIGC* pshipsChildren = pship->GetChildShips();
- ShipLinkIGC* psl;
- while (psl = pshipsChildren->first()) //intentional assignment
- {
- IshipIGC* pshipChild = psl->data();
- pshipChild->SetParentShip(NULL);
- m_pClientEventSource->OnBoardShip(pshipChild, NULL);
- }
- }
- //Ignore most part changes for ourselves
- if (pfmLC->sidShip != GetShipID())
- {
- pship->ProcessShipLoadout(pfmLC->cbloadout,
- (const ShipLoadout*)(FM_VAR_REF(pfmLC, loadout)), (pship->GetCluster() == NULL));
- }
- //But always process the passenger data (even for ourself)
- {
- const PassengerData* ppassengersLC = (const PassengerData*)(FM_VAR_REF(pfmLC, rgPassengers));
- const PassengerData* pstop = (const PassengerData*)(((char*)ppassengersLC) + pfmLC->cbrgPassengers);
- for (const PassengerData* ppd = ppassengersLC; (ppd < pstop); ppd++)
- {
- IshipIGC* pshipChild = m_pCoreIGC->GetShip(ppd->shipID);
- assert (pshipChild);
- if (pshipChild == m_ship)
- {
- SetAutoPilot(false);
- if ((ppd->turretID != NA) && (m_ship->GetCluster() != NULL) && (pshipChild->GetTurretID() != ppd->turretID))
- {
- Orientation oTurret = pship->GetHullType()->GetWeaponOrientation(ppd->turretID) *
- pship->GetOrientation();
- pshipChild->SetOrientation(oTurret);
- }
- }
- else
- {
- assert (pshipChild->GetAutopilot() == false);
- }
- pshipChild->SetParentShip(pship);
- assert (pshipChild->GetBaseHullType() == NULL);
- assert (pshipChild->GetParts()->n() == 0);
- if (pship == m_ship && m_ship->GetCluster() == NULL)
- {
- if (ppd->turretID != NA)
- PostText(true, "%s has boarded your ship as a turret.", pshipChild->GetName());
- else
- PostText(true, "%s has boarded your ship as an observer.", pshipChild->GetName());
-
- PlaySoundEffect(boardSound);
- }
- pshipChild->SetTurretID(ppd->turretID);
- m_pClientEventSource->OnBoardShip(pshipChild, pship);
- if (pshipChild == m_ship && IsLockedDown())
- EndLockDown(lockdownTeleporting);
- }
- }
- //We were just out of a ship while at a station
- assert ((m_ship->GetParentShip() != NULL) || (m_ship->GetBaseHullType() != NULL));
- }
- break;
- /* NYI
- case FM_S_ACTIVE_TURRET_UPDATE:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmATU, S, ACTIVE_TURRET_UPDATE, pfm);
- if (m_ship->GetObjectID() != pfmATU->shipID)
- {
- Time time = ClientTimeFromServerTime(pfmATU->timeUpdate);
- IshipIGC* ship = m_pCoreIGC->GetShip(pfmATU->shipID);
- assert (ship);
- if (ship->GetTurretID() != NA)
- {
- assert (ship->GetParentShip());
- ship->ProcessShipUpdate(time, pfmATU->atu);
- }
- }
- }
- break;
- case FM_S_INACTIVE_TURRET_UPDATE:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmITU, S, INACTIVE_TURRET_UPDATE, pfm);
- if (m_ship->GetObjectID() != pfmITU->shipID)
- {
- IshipIGC* ship = m_pCoreIGC->GetShip(pfmITU->shipID);
- assert (ship);
- assert (ship->GetParentShip());
- ship->SetStateM(lastUpdate, 0);
- }
- }
- break;
- */
- case FM_CS_SET_WINGID:
- {
- CASTPFM(pfmSW, CS, SET_WINGID, pfm);
- IshipIGC* pship = m_ship->GetSide()->GetShip(pfmSW->shipID);
- assert (pship);
- if ((pship != m_ship) || pfmSW->bCommanded)
- {
- pship->SetWingID(pfmSW->wingID);
- if (pfmSW->bCommanded && (pship == m_ship))
- PostText(true, "You have been assigned to wing %s", c_pszWingName[pfmSW->wingID]);
- }
- m_pMissionInfo->GetSideInfo(pship->GetSide()->GetObjectID())->GetMembers().GetSink()();
- }
- break;
- case FM_S_JOINED_MISSION:
- {
- CASTPFM(pfmJoinedMission, S, JOINED_MISSION, pfm);
- assert(m_pMissionInfo != NULL);
- // make sure this was what we intended to join if we were joining from the lobby
- assert(m_dwCookieToJoin == pfmJoinedMission->dwCookie || !m_fmLobby.IsConnected());
- debugf("I am ship %d\n", pfmJoinedMission->shipID);
- // Make sure we have the right static core
- if (lstrcmp(m_pMissionInfo->GetIGCStaticFile(), m_szIGCStaticFile) != 0
- && !ResetStaticData(m_pMissionInfo->GetIGCStaticFile(), &m_pCoreIGC, now, GetIsZoneClub()))
- {
- // we have the wrong file - let's bail.
- Disconnect();
-
- // not logged on yet, so we have to do this part manually
- delete m_pMissionInfo;
- m_pMissionInfo = NULL;
- OnLogonAck(false, false, "The client and server data files are out of sync. Please restart and go to a games list to auto-update "
- "the latest files. If this doesn't work, try deleting the file 'filelist.txt' from the install directory and restarting the application.");
- }
- else
- {
- // update myself
- PlayerInfo* pPlayerInfo = m_pPlayerInfo;
- if (!pPlayerInfo)
- {
- PlayerLink* l = new PlayerLink;
- m_listPlayers.last(l);
- pPlayerInfo = &(l->data());
- }
- pPlayerInfo->SetMission(m_pCoreIGC);
- FMD_S_PLAYERINFO fmPlayerInfo;
- memset(&fmPlayerInfo, 0, sizeof(fmPlayerInfo));
- strcpy(fmPlayerInfo.CharacterName, "<error>");
- fmPlayerInfo.shipID = pfmJoinedMission->shipID;
- fmPlayerInfo.iSide = NA;
- pPlayerInfo->Set(&fmPlayerInfo);
- SetPlayerInfo(pPlayerInfo);
- assert (m_pPlayerInfo == pPlayerInfo);
- pPlayerInfo->SetShip(m_ship);
- ZAssert(m_pPlayerInfo);
- if (m_pPlayerInfo->ShipID() != pfmJoinedMission->shipID)
- SetPlayerInfo(FindPlayer(pfmJoinedMission->shipID));
- // we will be sent the list of players right after this message
- m_pMissionInfo->PurgePlayers();
- }
- break;
- }
- case FM_S_PLAYERINFO:
- {
- if (NULL == m_pCoreIGC->GetSide(SIDE_TEAMLOBBY))
- {
- assert(false);
- OnSessionLost("Unexpected message received.", &m_fm);
- }
- CASTPFM(pfmPlayerInfo, S, PLAYERINFO, pfm);
- PlayerLink* l = FindPlayerLink(pfmPlayerInfo->shipID);
- debugf("Got Player Info for %s\n", pfmPlayerInfo->CharacterName);
- // start with the player not on a side
- SideID sideID = pfmPlayerInfo->iSide;
- bool bReady = pfmPlayerInfo->fReady;
- pfmPlayerInfo->iSide = NA;
- if (l != NULL)
- l->data().Set(pfmPlayerInfo);
- else
- {
- l = new PlayerLink;
- l->data().Set(pfmPlayerInfo);
- m_listPlayers.last(l);
- }
- ZAssert(l);
-
- PlayerInfo* pPlayerInfo = &(l->data());
- pPlayerInfo->SetMission(m_pCoreIGC);
- {
- DataShipIGC ds;
- ds.hullID = NA;
- ds.shipID = pfmPlayerInfo->shipID;
- ds.nParts = 0;
- ds.sideID = NA;
- //ds.wingID = pfmPlayerInfo->wingID;
- ds.nDeaths = pfmPlayerInfo->nDeaths;
- ds.nEjections = pfmPlayerInfo->nEjections;
- ds.nKills = pfmPlayerInfo->nKills;
- ds.pilotType = pfmPlayerInfo->pilotType;
- ds.abmOrders = pfmPlayerInfo->abmOrders;
- ds.baseObjectID = pfmPlayerInfo->baseObjectID;
- strcpy(ds.name, pfmPlayerInfo->CharacterName);
- IshipIGC* pship = (IshipIGC*)(m_pCoreIGC->CreateObject(m_lastSend, OT_ship, &ds, sizeof(ds)));
- if (pship != NULL)
- {
- //Slightly bad form: releasing pship here and releasing it below but ships
- //are never deleted on their first release (since they added to the side and
- //mission lists)
- pship->Release();
- }
- else
- {
- //The ship must already exist ... get it for the player info
- //NYI does this happen for anything other than the player's ship?
- pship = m_pCoreIGC->GetShip(pfmPlayerInfo->shipID);
- assert (pship);
- }
- pPlayerInfo->SetShip(pship);
- pship->SetExperience(pfmPlayerInfo->fExperience);
- }
-
- // add this player to their team
- AddPlayerToMission(pPlayerInfo);
- if (sideID != SIDE_TEAMLOBBY)
- {
- AddPlayerToSide(pPlayerInfo, sideID);
- pPlayerInfo->SetReady(bReady);
- }
- debugf("PlayerInfo for %s, ship=%d, side=%d\n", pPlayerInfo->CharacterName(),
- pPlayerInfo->ShipID(), pPlayerInfo->SideID());
- break;
- }
- case FM_CS_PLAYER_READY:
- {
- ZAssert(m_pMissionInfo);
- CASTPFM(pfmPlayerReady, CS, PLAYER_READY, pfm);
- PlayerInfo* pPlayerInfo = FindPlayer(pfmPlayerReady->shipID);
- if (pPlayerInfo)
- {
- pPlayerInfo->Update(pfmPlayerReady);
- if (pPlayerInfo->IsHuman())
- m_pClientEventSource->OnPlayerStatusChange(m_pMissionInfo, pPlayerInfo->SideID(), pPlayerInfo);
- // mark the player list as having changed
- m_pMissionInfo->GetSideInfo(pPlayerInfo->SideID())->GetMembers().GetSink()();
- }
- break;
- }
- case FM_S_MISSION_STAGE:
- {
- CASTPFM(pfmMissionStage, S, MISSION_STAGE, pfm);
- m_pMissionInfo->SetStage(pfmMissionStage->stage);
- switch (pfmMissionStage->stage)
- {
- case STAGE_NOTSTARTED:
- {
- m_pMissionInfo->SetInProgress(false);
- m_pMissionInfo->SetCountdownStarted(false);
- m_bWaitingForGameRestart = false;
- m_pClientEventSource->OnMissionEnded(m_pMissionInfo);
- break;
- }
- case STAGE_STARTING:
- {
- m_pMissionInfo->SetCountdownStarted(true);
- m_pClientEventSource->OnMissionCountdown(m_pMissionInfo);
- break;
- }
- case STAGE_STARTED:
- {
- m_pMissionInfo->SetCountdownStarted(false);
- m_pMissionInfo->SetInProgress(true);
- assert (memcmp(m_pCoreIGC->GetMissionParams(),
- &m_pMissionInfo->GetMissionParams(),
- sizeof(m_pMissionInfo->GetMissionParams())) == 0);
- m_pCoreIGC->SetMissionStage(STAGE_STARTED);
- m_pClientEventSource->OnMissionStarted(m_pMissionInfo);
- break;
- }
- case STAGE_OVER:
- {
- m_pMissionInfo->SetInProgress(false);
- m_bWaitingForGameRestart = false;
- m_pClientEventSource->OnMissionEnded(m_pMissionInfo);
- break;
- }
- case STAGE_TERMINATE:
- {
- RemovePlayerFromSide(m_pPlayerInfo, QSR_Quit);
- RemovePlayerFromMission(m_pPlayerInfo, QSR_Quit);
- break;
- }
- default:
- {
- assert(false);
- }
- }
- m_mapMissions.GetSink()();
- break;
- }
- case FM_S_CREATE_BUCKETS:
- {
- m_pCoreIGC->SetMissionParams(&m_pMissionInfo->GetMissionParams());
- IsideIGC* pside = GetSide();
- assert (pside);
- assert (pside->GetObjectID() != SIDE_TEAMLOBBY);
- {
- //Hack copy side attributes over to lobby side
- m_pCoreIGC->GetSide(SIDE_TEAMLOBBY)->SetGlobalAttributeSet(pside->GetGlobalAttributeSet());
- CASTPFM(pfmCB, S, CREATE_BUCKETS, pfm);
- pside->SetDevelopmentTechs(pfmCB->ttbmDevelopments);
- pside->SetInitialTechs(pfmCB->ttbmInitial);
- pside->CreateBuckets();
- }
- }
- break;
- case FM_S_GAME_STATE:
- {
- CASTPFM(pfmGS, S, GAME_STATE, pfm);
- SideID sid = 0;
- for (SideLinkIGC* l = m_pCoreIGC->GetSides()->first(); (l != NULL); l = l->next())
- {
- assert (sid == l->data()->GetObjectID());
- l->data()->SetConquestPercent(pfmGS->conquest[sid]);
- l->data()->SetTerritoryCount(pfmGS->territory[sid]);
- l->data()->SetFlags(pfmGS->nFlags[sid]);
- l->data()->SetArtifacts(pfmGS->nArtifacts[sid++]);
- }
- }
- break;
- case FM_S_MISSIONDEF:
- {
- CASTPFM(pfmMissionDef, S, MISSIONDEF, pfm);
- pfmMissionDef->misparms.timeStart = ClientTimeFromServerTime(pfmMissionDef->misparms.timeStart);
- if (m_pMissionInfo == NULL)
- {
- m_pMissionInfo = new MissionInfo(pfmMissionDef->dwCookie);
- m_pMissionInfo->Update(pfmMissionDef);
- }
- else
- {
- m_pMissionInfo->Update(pfmMissionDef);
- m_pCoreIGC->SetMissionParams(&pfmMissionDef->misparms);
- m_pCoreIGC->UpdateSides(Time::Now(), &(m_pMissionInfo->GetMissionParams()), pfmMissionDef->rgszName);
- }
- m_pClientEventSource->OnAddMission(m_pMissionInfo);
- break;
- }
- case FM_S_SIDE_TECH_CHANGE:
- {
- CASTPFM(pfmSTC, S, SIDE_TECH_CHANGE, pfm);
- IsideIGC* pSide = m_pCoreIGC->GetSide(pfmSTC->sideID);
- assert (pSide);
- pSide->SetDevelopmentTechs(pfmSTC->ttbmDevelopments);
- }
- break;
- case FM_S_SIDE_ATTRIBUTE_CHANGE:
- {
- CASTPFM(pfmSAC, S, SIDE_ATTRIBUTE_CHANGE, pfm);
- IsideIGC* pSide = m_pCoreIGC->GetSide(pfmSAC->sideID);
- assert (pSide);
- pSide->SetGlobalAttributeSet(pfmSAC->gasAttributes);
- // HACK: copy the global attributes to the lobby side for loadout
- if (pSide == GetSide())
- GetCore()->GetSide(SIDE_TEAMLOBBY)->SetGlobalAttributeSet(pfmSAC->gasAttributes);
- }
- break;
- case FM_S_BUCKET_STATUS:
- {
- CASTPFM(pfmBucketStatus, S, BUCKET_STATUS, pfm);
- IsideIGC* pside = m_pCoreIGC->GetSide(pfmBucketStatus->sideID);
- assert (pside);
- IbucketIGC* b = pside->GetBucket(pfmBucketStatus->iBucket);
- if (b)
- b->SetTimeAndMoney(pfmBucketStatus->timeTotal,
- pfmBucketStatus->moneyTotal);
- break;
- }
- case FM_S_POSITIONREQ: // sent to team leader to request a pos
- {
- CASTPFM(pfmPosReq, S, POSITIONREQ, pfm);
- PlayerInfo* ppi = FindPlayer(pfmPosReq->shipID);
- m_pMissionInfo->AddRequest(pfmPosReq->iSide, pfmPosReq->shipID);
- m_pClientEventSource->OnAddRequest(m_pMissionInfo, pfmPosReq->iSide, ppi);
- if (MyPlayerInfo()->IsTeamLeader() && (pfmPosReq->iSide == GetSideID()))
- PostText(true, "%s wishes to join your team", ppi->CharacterName());
- PlaySoundEffect(salPlayerWaitingSound);
- break;
- }
- case FM_CS_DELPOSITIONREQ:
- {
- CASTPFM(pfmDelPositionReq, CS, DELPOSITIONREQ, pfm);
- PlayerInfo* pPlayerInfo = FindPlayer(pfmDelPositionReq->shipID);
- if (pPlayerInfo && pfmDelPositionReq->iSide < m_pMissionInfo->GetMissionParams().nTeams
- && m_pMissionInfo->FindRequest(pfmDelPositionReq->iSide, pfmDelPositionReq->shipID))
- {
- m_pMissionInfo->RemoveRequest(pfmDelPositionReq->iSide, pfmDelPositionReq->shipID);
- }
- m_pClientEventSource->OnDelRequest(m_pMissionInfo, pfmDelPositionReq->iSide, pPlayerInfo, pfmDelPositionReq->reason);
- break;
- }
- case FM_CS_QUIT_MISSION:
- {
- if (m_pMissionInfo)
- {
- // someone is quiting...
- CASTPFM(pfmQuitMission, CS, QUIT_MISSION, pfm);
- PlayerInfo* pPlayerInfo = FindPlayer(pfmQuitMission->shipID);
- if (!pPlayerInfo || pPlayerInfo->SideID() == NA)
- {
- assert(false);
- break;
- }
- if (pPlayerInfo->SideID() != SIDE_TEAMLOBBY)
- {
- assert(false);
- RemovePlayerFromSide(pPlayerInfo, QSR_Quit);
- }
- SideID sideIDOld = pPlayerInfo->SideID();
- RemovePlayerFromMission(pPlayerInfo, pfmQuitMission->reason, FM_VAR_REF(pfmQuitMission, szMessageParam));
- // review: use a new message
- m_pClientEventSource->OnDelRequest(m_pMissionInfo, sideIDOld, pPlayerInfo, DPR_Canceled);
- }
- break;
- }
- case FM_CS_CHANGE_TEAM_CIV:
- {
- CASTPFM(pfmChangeCiv, CS, CHANGE_TEAM_CIV, pfm);
- //m_pMissionInfo->SetSideCivID(pfmChangeCiv->iSide, pfmChangeCiv->civID);
- m_pCoreIGC->GetSide(pfmChangeCiv->iSide)->SetCivilization(m_pCoreIGC->GetCivilization(pfmChangeCiv->civID));
- m_pClientEventSource->OnTeamCivChange(m_pMissionInfo, pfmChangeCiv->iSide, pfmChangeCiv->civID);
- break;
- }
- case FM_CS_SET_TEAM_INFO:
- {
- CASTPFM(pfmSetTeamInfo, CS, SET_TEAM_INFO, pfm);
- IsideIGC* pside = m_pCoreIGC->GetSide(pfmSetTeamInfo->sideID);
- assert(pside);
- pside->SetSquadID(pfmSetTeamInfo->squadID);
- pside->SetName(pfmSetTeamInfo->SideName);
- m_pMissionInfo->SetSideName(pfmSetTeamInfo->sideID, pfmSetTeamInfo->SideName);
- m_pClientEventSource->OnTeamNameChange(m_pMissionInfo, pfmSetTeamInfo->sideID);
- break;
- }
- case FM_S_TEAM_READY:
- {
- CASTPFM(pfmTeamReady, S, TEAM_READY, pfm);
- m_pMissionInfo->SetSideReady(pfmTeamReady->iSide, pfmTeamReady->fReady);
- m_pClientEventSource->OnTeamReadyChange(m_pMissionInfo, pfmTeamReady->iSide, pfmTeamReady->fReady);
- break;
- }
- case FM_S_SIDE_INACTIVE:
- {
- CASTPFM(pfmSideInactive, S, SIDE_INACTIVE, pfm);
- debugf("Side inactive, side=%d\n", pfmSideInactive->sideID);
- m_pMissionInfo->SetSideActive(pfmSideInactive->sideID, false);
- m_pClientEventSource->OnTeamInactive(m_pMissionInfo, pfmSideInactive->sideID);
- m_mapMissions.GetSink()();
- break;
- }
- case FM_CS_FORCE_TEAM_READY:
- {
- CASTPFM(pfmTeamForceReady, CS, FORCE_TEAM_READY, pfm);
- m_pMissionInfo->SetSideForceReady(pfmTeamForceReady->iSide, pfmTeamForceReady->fForceReady);
- m_pClientEventSource->OnTeamForceReadyChange(m_pMissionInfo, pfmTeamForceReady->iSide, pfmTeamForceReady->fForceReady);
- }
- break;
- case FM_CS_AUTO_ACCEPT:
- {
- CASTPFM(pfmAutoAccept, CS, AUTO_ACCEPT, pfm);
- m_pMissionInfo->SetSideAutoAccept(pfmAutoAccept->iSide, pfmAutoAccept->fAutoAccept);
- m_pClientEventSource->OnTeamAutoAcceptChange(m_pMissionInfo, pfmAutoAccept->iSide, pfmAutoAccept->fAutoAccept);
- m_mapMissions.GetSink()();
- }
- break;
- case FM_CS_LOCK_LOBBY:
- {
- CASTPFM(pfmLockLobby, CS, LOCK_LOBBY, pfm);
- m_pMissionInfo->SetLockLobby(pfmLockLobby->fLock);
- m_pClientEventSource->OnLockLobby(pfmLockLobby->fLock);
- m_mapMissions.GetSink()();
- }
- break;
-
- case FM_CS_LOCK_SIDES:
- {
- CASTPFM(pfmLockSides, CS, LOCK_SIDES, pfm);
- m_pMissionInfo->SetLockSides(pfmLockSides->fLock);
- m_pClientEventSource->OnLockSides(pfmLockSides->fLock);
- m_mapMissions.GetSink()();
- }
- break;
-
- case FM_CS_REQUEST_MONEY:
- {
- CASTPFM(pfmRequest, CS, REQUEST_MONEY, pfm);
- IshipIGC* pship = m_ship->GetSide()->GetShip(pfmRequest->shipidRequest);
- if (pship)
- {
- GetMoneyRequest(pship, pfmRequest->amount, pfmRequest->hidFor);
- }
- }
- break;
- case FM_CS_CHATMESSAGE:
- {
- CASTPFM(pfmChat, CS, CHATMESSAGE, pfm);
- //Ignore chats we sent ... we will have already handled them when sent
- if (pfmChat->cd.sidSender != m_ship->GetObjectID())
- {
- ReceiveChat(m_pCoreIGC->GetShip(pfmChat->cd.sidSender),
- pfmChat->cd.chatTarget,
- pfmChat->cd.oidRecipient,
- pfmChat->cd.voiceOver,
- FM_VAR_REF(pfmChat, Message),
- pfmChat->cd.commandID,
- pfmChat->otTarget,
- pfmChat->oidTarget,
- NULL,
- pfmChat->cd.bObjectModel);
- }
- break;
- }
- case FM_CS_CHATBUOY:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmBuoy, CS, CHATBUOY, pfm);
- if (pfmBuoy->cd.sidSender != m_ship->GetObjectID())
- {
- //Create a buoy for this chat message
- IbaseIGC* b = m_pCoreIGC->CreateObject(lastUpdate, OT_buoy, &(pfmBuoy->db), sizeof(pfmBuoy->db));
- assert (b);
- ((IbuoyIGC*)b)->AddConsumer();
- ReceiveChat(m_pCoreIGC->GetShip(pfmBuoy->cd.sidSender),
- pfmBuoy->cd.chatTarget,
- pfmBuoy->cd.oidRecipient,
- pfmBuoy->cd.voiceOver,
- FM_VAR_REF(pfmBuoy, Message),
- pfmBuoy->cd.commandID,
- OT_buoy,
- b->GetObjectID(),
- (ImodelIGC*)b,
- pfmBuoy->cd.bObjectModel);
- ((IbuoyIGC*)b)->ReleaseConsumer();
- b->Release();
- }
- }
- break;
- case FM_CS_MISSIONPARAMS:
- {
- assert(false);
- CASTPFM(pfmMissionParams, CS, MISSIONPARAMS, pfm);
- pfmMissionParams->missionparams.timeStart = ClientTimeFromServerTime(pfmMissionParams->missionparams.timeStart);
- m_pCoreIGC->SetMissionParams(&(pfmMissionParams->missionparams));
- }
- break;
- case FM_S_SET_START_TIME:
- {
- CASTPFM(pfmStartTime, S, SET_START_TIME, pfm);
-
- ZAssert(MyMission());
- Time timeStart = ClientTimeFromServerTime(pfmStartTime->timeStart);
- MyMission()->UpdateStartTime(timeStart);
- m_pCoreIGC->SetStartTime(timeStart);
- }
- break;
- case FM_S_SHIP_STATUS:
- {
- if (IsWaitingForGameRestart())
- break;
- CASTPFM(pfmShipStatus, S, SHIP_STATUS, pfm);
- PlayerInfo* pPlayerInfo = FindPlayer(pfmShipStatus->shipID);
- if (pPlayerInfo && m_pMissionInfo)
- {
- if ((pfmShipStatus->status.GetSectorID() != NA) &&
- (pfmShipStatus->status.GetSectorID() != pPlayerInfo->LastSeenSector()))
- {
- ShipWarped(pPlayerInfo->GetShip(),
- pPlayerInfo->LastSeenSector(),
- pfmShipStatus->status.GetSectorID());
- }
- // update the last seen info
- pPlayerInfo->SetShipStatus(pfmShipStatus->status);
- // update any lists using this info
- m_pMissionInfo->GetSideInfo(pPlayerInfo->SideID())->GetMembers().GetSink()();
- m_pClientEventSource->OnShipStatusChange(pPlayerInfo);
- if ((pfmShipStatus->status.GetState() == c_ssTurret) !=
- (pPlayerInfo->LastSeenState() == c_ssTurret))
- {
- m_pClientEventSource->OnTurretStateChanging(pfmShipStatus->status.GetState() == c_ssTurret);
- }
- }
- break;
- }
- case FM_S_KILL_SHIP:
- {
- CASTPFM(pfmKillShip, S, KILL_SHIP, pfm);
- PlayerInfo* pPlayerInfo = FindPlayer(pfmKillShip->shipID);
- ZAssert(pPlayerInfo);
- ImodelIGC* pmodelKiller = m_pCoreIGC->GetModel(pfmKillShip->typeCredit, pfmKillShip->idCredit);
- PlayerInfo* pLauncherInfo = ((pfmKillShip->typeCredit == OT_ship) && pmodelKiller)
- ? (PlayerInfo*)(((IshipIGC*)pmodelKiller)->GetPrivateData())
- : NULL;
- IsideIGC* pside = GetSide();
- SideID sideID = pside->GetObjectID();
- ShipID shipID = GetShipID();
- IshipIGC* pship = pPlayerInfo->GetShip();
- assert (pship);
- TargetKilled(pship);
- if (pfmKillShip->bDeathCredit)
- {
- pPlayerInfo->AddDeath();
- pPlayerInfo->GetShip()->SetExperience(0.0f);
- }
- else
- pPlayerInfo->AddEjection();
- MyMission()->GetSideInfo(pPlayerInfo->SideID())->GetMembers().GetSink()();
- const char* pszVictim = pPlayerInfo->CharacterName();
- bool bConstructorOrMiner;
- {
- PilotType pt = pship->GetPilotType();
- bConstructorOrMiner = (pt == c_ptBuilder) ||
- (pt == c_ptMiner) ||
- (pt == c_ptCarrier);
- }
- if (!pLauncherInfo)
- {
- if (pfmKillShip->bKillCredit)
- {
- assert (pfmKillShip->typeCredit != NA);
- IsideIGC* pside = pmodelKiller ? pmodelKiller->GetSide() : m_pCoreIGC->GetSide(pfmKillShip->sideidKiller);
- assert (pside);
- pside->AddKill();
- }
- if (pfmKillShip->shipID == shipID)
- PostText(true, pfmKillShip->bDeathCredit ? "You were killed" : "You ejected");
- else if (bConstructorOrMiner)
- PostText(pPlayerInfo->SideID() == GetSideID(), START_COLOR_STRING "%s" END_COLOR_STRING " was killed", (PCC) ConvertColorToString (m_pCoreIGC->GetSide(pPlayerInfo->SideID())->GetColor ()), pszVictim);
- else
- PostText(false, pfmKillShip->bDeathCredit ? START_COLOR_STRING "%s" END_COLOR_STRING " was killed" : START_COLOR_STRING "%s" END_COLOR_STRING " ejected", (PCC) ConvertColorToString (m_pCoreIGC->GetSide(pPlayerInfo->SideID())->GetColor ()), pszVictim);
- }
- else
- {
- const char* pszLauncher = pLauncherInfo->CharacterName();
- if (pfmKillShip->bKillCredit)
- {
- pLauncherInfo->AddKill();
- if (pLauncherInfo->GetShip()->GetSide() != pship->GetSide())
- pLauncherInfo->GetShip()->AddExperience();
- }
- MyMission()->GetSideInfo(pLauncherInfo->SideID())->GetMembers().GetSink()();
- // if we can see the victim or if the perpatrator or victim
- // is on our side...
- if (pfmKillShip->shipID == shipID)
- PostText(true,
- pfmKillShip->bDeathCredit
- ? "You were killed by " START_COLOR_STRING "%s" END_COLOR_STRING
- : "You were forced to eject by " START_COLOR_STRING "%s" END_COLOR_STRING,
- (PCC) ConvertColorToString (pLauncherInfo->GetShip()->GetSide()->GetColor ()), pszLauncher);
- else if (pmodelKiller == m_ship)
- PostText(true,
- pfmKillShip->bDeathCredit
- ? "You killed " START_COLOR_STRING "%s" END_COLOR_STRING
- : "You forced " START_COLOR_STRING "%s" END_COLOR_STRING " to eject",
- (PCC) ConvertColorToString (pPlayerInfo->GetShip()->GetSide()->GetColor ()), pszVictim);
- else
- {
- if (bConstructorOrMiner && pPlayerInfo->SideID() != GetSideID())
- PostText(bConstructorOrMiner,
- pfmKillShip->bDeathCredit
- ? (START_COLOR_STRING "%s %s" END_COLOR_STRING " was killed by %s")
- : (START_COLOR_STRING "%s %s" END_COLOR_STRING " was forced to eject by %s"),
- (PCC) ConvertColorToString (pPlayerInfo->GetShip()->GetSide()->GetColor ()),
- pPlayerInfo->GetShip()->GetSide()->GetName(),
- pszVictim, pszLauncher);
- else
- PostText(bConstructorOrMiner,
- pfmKillShip->bDeathCredit
- ? "%s was killed by %s"
- : "%s was forced to eject by %s", pszVictim, pszLauncher);
- }
- }
- IclusterIGC * pCluster = pship->GetCluster();
- if (NULL != pCluster)
- {
- IhullTypeIGC* pht = pship->GetBaseHullType();
- if (pht)
- pCluster->GetClusterSite()->AddExplosion(pship,
- pht->HasCapability(c_habmFighter)
- ? c_etSmallShip
- : c_etBigShip);
- }
- // for drones, play the drone destruction sound
- if (!pPlayerInfo->IsHuman())
- {
- if (sideID == pPlayerInfo->SideID())
- {
- SoundID destroyedSound;
- switch (pship->GetPilotType())
- {
- case c_ptCarrier: //NYI need carrier destroyed sound
- destroyedSound = carrierDestroyedSound;
- break;
- case c_ptMiner:
- destroyedSound = minerDestroyedSound;
- break;
- case c_ptBuilder:
- destroyedSound =
- ((IstationTypeIGC*)(IbaseIGC*)(pship->GetBaseData()))
- ->GetConstructorDestroyedSound();
- break;
- case c_ptLayer:
- if (pship->GetBaseData()->GetObjectType() == OT_mineType)
- destroyedSound = minefieldLayerDestroyedSound;
- else
- destroyedSound = towerLayerDestroyedSound;
- break;
- default:
- assert(false);
- case c_ptWingman:
- destroyedSound = towerLayerDestroyedSound;
- break;
- }
- PlaySoundEffect(destroyedSound);
- }
- }
- else if ((pship == m_ship) && pfmKillShip->bDeathCredit)
- {
- //The player died ... set up the gloat camera
- EjectPlayer(m_pCoreIGC->GetModel(pfmKillShip->typeCredit, pfmKillShip->idCredit));
- }
- ChangeGameState();
- }
- break;
- case FM_S_JOIN_SIDE:
- {
- CASTPFM(pfmJoinSide, S, JOIN_SIDE, pfm);
- PlayerInfo* pplayer = FindPlayer(pfmJoinSide->shipID);
- AddPlayerToSide(pplayer, pfmJoinSide->sideID);
- }
- break;
- /*
- case FM_S_SET_EXPERIENCE:
- {
- CASTPFM(pfmSet, S, SET_EXPERIENCE, pfm);
- IshipIGC* pship = m_pCoreIGC->GetShip(pfmSet->shipID);
- assert (pship);
- pship->SetExperience(pfmSet->fExperience);
- }
- break;
- */
- case FM_CS_SET_TEAM_LEADER:
- {
- CASTPFM(pfmSetTeamLeader, CS, SET_TEAM_LEADER, pfm);
- PlayerInfo* pplayer = FindPlayer(pfmSetTeamLeader->shipID);
- // demote the previous team leader (if any)
- if (MyMission()->SideLeaderShipID(pplayer->SideID()) != NA)
- {
- PlayerInfo* pplayerOld = FindPlayer(MyMission()->SideLeaderShipID(pplayer->SideID()));
- pplayerOld->SetTeamLeader(false);
- pplayerOld->SetMissionOwner(false);
- m_pClientEventSource->OnPlayerStatusChange(MyMission(), pplayerOld->SideID(), pplayerOld);
- }
- pplayer->SetTeamLeader(true);
- pplayer->SetMissionOwner(MyMission()->MissionOwnerSideID() == pplayer->SideID());
- MyMission()->SetSideLeader(pplayer);
- if ((m_pCoreIGC->GetMissionStage() == STAGE_STARTED) &&
- pplayer->SideID() == MyPlayerInfo()->SideID())
- {
- //Leader on our team has switched
- if (pplayer == MyPlayerInfo())
- PostText(true, "You have become the team leader");
- else
- {
- char bfr[100];
- sprintf(bfr, "%s has become the team leader", pplayer->CharacterName());
- PostText(true, bfr);
- }
- }
- if (pplayer == MyPlayerInfo())
- PlaySoundEffect(commanderSound);
- m_pClientEventSource->OnPlayerStatusChange(MyMission(), pplayer->SideID(), pplayer);
- }
- break;
- case FM_CS_SET_MISSION_OWNER:
- {
- CASTPFM(pfmSetMissionOwner, CS, SET_MISSION_OWNER, pfm);
- // demote the previous mission owner (if any)
- if (MyMission()->MissionOwnerSideID() != NA)
- {
- PlayerInfo* pplayerOld = FindPlayer(MyMission()->MissionOwnerShipID());
- pplayerOld->SetMissionOwner(false);
- m_pClientEventSource->OnPlayerStatusChange(MyMission(), pplayerOld->SideID(), pplayerOld);
- }
- PlayerInfo* pplayer = FindPlayer(pfmSetMissionOwner->shipID);
- ZAssert(pplayer->IsTeamLeader());
- pplayer->SetMissionOwner(true);
- MyMission()->SetSideLeader(pplayer);
- m_pClientEventSource->OnPlayerStatusChange(MyMission(), pplayer->SideID(), pplayer);
- }
- break;
- case FM_CS_QUIT_SIDE:
- {
- if (m_pMissionInfo)
- {
- CASTPFM(pfmQuitSide, CS, QUIT_SIDE, pfm);
- PlayerInfo* pplayer = FindPlayer(pfmQuitSide->shipID);
- RemovePlayerFromSide(pplayer, pfmQuitSide->reason, FM_VAR_REF(pfmQuitSide, szMessageParam));
- }
- }
- break;
- case FM_S_SQUAD_INFO:
- case FM_S_SQUAD_DETAILS:
- case FM_S_SQUAD_DETAILS_PLAYER:
- case FM_S_SQUAD_LOG_INFO:
- case FM_S_SQUAD_DELETED:
- case FM_S_SQUAD_TEXT_MESSAGE:
- case FM_S_SQUAD_CREATE_ACK:
- {
- ForwardSquadMessage(pfm); // forward message to squads screen
- }
- break;
- case FM_S_CHARACTER_INFO_GENERAL:
- case FM_S_CHARACTER_INFO_BY_CIV:
- case FM_S_CHARACTER_INFO_MEDAL:
- {
- ForwardCharInfoMessage(pfm); // forward message to character info screen
- }
- break;
- case FM_S_SQUAD_INFO_DUDEX:
- {
- // forward messages that go to either of these screens
- ForwardSquadMessage(pfm);
- ForwardCharInfoMessage(pfm);
- }
- break;
- case FM_S_LEADER_BOARD_QUERY_FAIL:
- case FM_S_LEADER_BOARD_LIST:
- {
- ForwardLeaderBoardMessage(pfm); // forward message to leader board screen
- }
- break;
- case FM_S_ENTER_GAME:
- {
- ClearLoadout ();
- OnEnterGame();
- }
- break;
- case FM_S_GAME_OVER:
- {
- m_bInGame = false;
- m_bWaitingForGameRestart = true;
- m_strBriefingText.SetEmpty();
- m_bGenerateCivBriefing = false;
- CASTPFM(pfmGameOver, S, GAME_OVER, pfm);
- if (IsLockedDown())
- EndLockDown(lockdownDonating | lockdownLoadout | lockdownTeleporting);
- SetViewCluster(NULL);
- GetShip()->SetCluster(NULL);
-
- // set all of the players to unready with 0 money
- for (PlayerLink* ppl = GetPlayerList()->first();
- (ppl != NULL);
- ppl = ppl->next())
- {
- // review: since we are trying this silly away from keyboard thing,
- // set everyone as ready (= not away from keyboard)
- ppl->data().SetReady(true);
- ppl->data().Reset(true);
- }
- // set all of the sides to active and not forced ready
- for (SideID sid = 0; sid < MyMission()->NumSides(); sid++)
- {
- MyMission()->SetSideActive(sid, true);
- GetCore()->GetSide(sid)->SetActiveF(true);
- MyMission()->SetSideForceReady(sid, false);
- MyMission()->SetSideReady(sid, true);
- }
- // nuke any pending votes
- m_listBallots.SetEmpty();
- for (SideLinkIGC* psl = GetCore()->GetSides()->first(); (psl != NULL); psl = psl->next())
- psl->data()->Reset();
-
- GetCore()->ResetMission();
- }
- break;
- case FM_S_GAME_OVER_PLAYERS:
- {
- CASTPFM(pfmGameOverPlayers, S, GAME_OVER_PLAYERS, pfm);
- // update the scores of all of the players
- int cPlayerEndgameInfo = pfmGameOverPlayers->cbrgPlayerInfo / sizeof(PlayerEndgameInfo);
- PlayerEndgameInfo* vPlayerEndgameInfo
- = (PlayerEndgameInfo*)FM_VAR_REF(pfmGameOverPlayers, rgPlayerInfo);
- for (int i = 0; i < cPlayerEndgameInfo; i++)
- {
- PlayerInfo* pplayer = FindPlayer(vPlayerEndgameInfo[i].characterName);
- if (pplayer)
- pplayer->UpdateScore(vPlayerEndgameInfo[i].stats);
- }
- }
- break;
- case FM_S_GAIN_FLAG:
- {
- if (IsWaitingForGameRestart())
- break;
- CASTPFM(pfmGain, S, GAIN_FLAG, pfm);
- IshipIGC* pship = m_pCoreIGC->GetShip(pfmGain->shipidRecipient);
- assert (pship);
- assert ((pship->GetFlag() == NA) || (pfmGain->sideidFlag == NA));
- pship->SetFlag(pfmGain->sideidFlag);
- if (pfmGain->sideidFlag != NA)
- {
- if (pship->GetSide() == GetSide())
- {
- if (pfmGain->sideidFlag != SIDE_TEAMLOBBY)
- {
- PostText(true, "%s has stolen " START_COLOR_STRING "%s's" END_COLOR_STRING " flag.",
- pship->GetName(),
- (PCC) ConvertColorToString (GetCore()->GetSide(pfmGain->sideidFlag)->GetColor ()),
- GetCore()->GetSide(pfmGain->sideidFlag)->GetName()
- );
- PlaySoundEffect(enemyFlagLostSound);
- }
- else
- {
- PostText(true, "%s has found an artifact.",
- pship->GetName());
- PlaySoundEffect(artifactFoundSound);
- }
- }
- else if (pfmGain->sideidFlag > 0 && pfmGain->sideidFlag == GetSideID())
- {
- ZString color = ConvertColorToString (pship->GetSide()->GetColor ());
- PostText(true, START_COLOR_STRING "%s" END_COLOR_STRING " of " START_COLOR_STRING "%s" END_COLOR_STRING " has stolen our flag.",
- (PCC) color,
- pship->GetName(),
- (PCC) color,
- pship->GetSide()->GetName()
- );
- PlaySoundEffect(flagLostSound);
- }
- }
- }
- break;
- case FM_S_BUY_LOADOUT_ACK:
- {
- CASTPFM(pfmBuyLoadoutAck, S, BUY_LOADOUT_ACK, pfm);
- if (!pfmBuyLoadoutAck->fLaunch && IsLockedDown())
- EndLockDown(lockdownLoadout);
- m_ship->ProcessShipLoadout(pfmBuyLoadoutAck->cbloadout, (const ShipLoadout*)(FM_VAR_REF(pfmBuyLoadoutAck, loadout)), true);
- SaveLoadout();
- m_pClientEventSource->OnPurchaseCompleted(pfmBuyLoadoutAck->fBoughtEverything);
- // if they wanted to board a new ship after disembarking, we are
- // finally at a safe place to do so.
- if (m_sidBoardAfterDisembark != NA)
- {
- IshipIGC* pshipNewParent = FindPlayer(m_sidBoardAfterDisembark)->GetShip();
- if (pshipNewParent)
- {
- BoardShip(pshipNewParent);
- }
- m_sidBoardAfterDisembark = NA;
- }
- // otherwise, if they wanted to teleport we can do that now too.
- else if (m_sidTeleportAfterDisembark != NA)
- {
- IstationIGC* pstation = GetCore()->GetStation(m_sidTeleportAfterDisembark);
- if (pstation != GetShip()->GetStation())
- {
- SetMessageType(BaseClient::c_mtGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmDocked, C, DOCKED)
- END_PFM_CREATE
- pfmDocked->stationID = m_sidTeleportAfterDisembark;
- StartLockDown("Teleporting to " + ZString(pstation->GetName()) + "....", lockdownTeleporting);
- }
- m_sidTeleportAfterDisembark = NA;
- }
- }
- break;
- case FM_S_OBJECT_SPOTTED:
- {
- if (!IsInGame())
- break;
- CASTPFM(pfmObjectSpotted, S, OBJECT_SPOTTED, pfm);
- ZString strSpotterName;
- switch (pfmObjectSpotted->otSpotter)
- {
- case OT_station:
- strSpotterName = ZString("Your ")
- + GetCore()->GetStation(pfmObjectSpotted->oidSpotter)->GetName()
- + " has";
- break;
- case OT_probe:
- strSpotterName = "One of your team's probes has";
- break;
- case OT_ship:
- if (pfmObjectSpotted->oidSpotter == GetShipID())
- strSpotterName = "You've";
- else
- strSpotterName = GetCore()->GetShip(pfmObjectSpotted->oidSpotter)->GetName() + ZString(" has");
- break;
- default:
- assert(false);
- strSpotterName = "<bug> has";
- break;
- }
- switch (pfmObjectSpotted->otObject)
- {
- case OT_station:
- {
- IstationIGC* pstation = GetCore()->GetStation(pfmObjectSpotted->oidObject);
- assert(pstation);
- PostText(GetShip()->GetWingID() == 0, strSpotterName + " discovered an enemy " + pstation->GetName() + " in sector " + pstation->GetCluster()->GetName());
- }
- break;
- case OT_asteroid:
- {
- IasteroidIGC* pasteroid = GetCore()->GetAsteroid(pfmObjectSpotted->oidObject);
- assert(pasteroid);
- PostText(GetShip()->GetWingID() == 0, strSpotterName + " discovered a " + IasteroidIGC::GetTypeName(pasteroid->GetCapabilities()) + " asteroid in sector " + pasteroid->GetCluster()->GetName());
- }
- break;
- case OT_warp:
- {
- IwarpIGC* paleph = GetCore()->GetWarp(pfmObjectSpotted->oidObject);
- assert(paleph);
- PostText(GetShip()->GetWingID() == 0, strSpotterName + " discovered an aleph from sector " + paleph->GetCluster()->GetName() + " to sector " + paleph->GetDestination()->GetCluster()->GetName());
- }
- break;
- default:
- assert(false);
- break;
- }
- }
- break;
- case FM_S_DEV_COMPLETED:
- {
- CASTPFM(pfmDevelopmentCompleted, S, DEV_COMPLETED, pfm);
- IdevelopmentIGC* pdevelopment = GetCore()->GetDevelopment(pfmDevelopmentCompleted->devId);
- assert(pdevelopment);
- PostText(true, "%s research completed", pdevelopment->GetName());
- PlaySoundEffect(pdevelopment->GetCompletionSound());
- }
- break;
- case FM_S_SET_BRIEFING_TEXT:
- {
- CASTPFM(pfmSetBriefingText, S, SET_BRIEFING_TEXT, pfm);
- m_strBriefingText = FM_VAR_REF(pfmSetBriefingText, text);
- m_bGenerateCivBriefing = pfmSetBriefingText->fGenerateCivBriefing;
- }
- break;
- case FM_LS_SQUAD_MEMBERSHIPS:
- {
- CASTPFM(pfmSquadMemberships, LS, SQUAD_MEMBERSHIPS, pfm);
- SquadMembership* vSquadMemberships
- = (SquadMembership*)FM_VAR_REF(pfmSquadMemberships, squadMemberships);
- m_squadmemberships.SetEmpty();
- for (int iSquad = 0; iSquad < pfmSquadMemberships->cSquadMemberships; iSquad++)
- {
- m_squadmemberships.PushEnd(vSquadMemberships[iSquad]);
- }
- SaveSquadMemberships(m_szCharName);
- m_mapMissions.GetSink()();
- }
- break;
- case FM_S_STATIC_MAP_INFO:
- {
- CASTPFM(pfmStaticMapInfo, S, STATIC_MAP_INFO, pfm);
- // copy the new static map info into our internal table
- if (m_vStaticMapInfo)
- delete [] m_vStaticMapInfo;
- m_cStaticMapInfo = pfmStaticMapInfo->cbmaps / sizeof(StaticMapInfo);
-
- if (m_cStaticMapInfo > 0)
- {
- m_vStaticMapInfo = new StaticMapInfo[m_cStaticMapInfo];
- memcpy(m_vStaticMapInfo, FM_VAR_REF(pfmStaticMapInfo, maps), m_cStaticMapInfo * sizeof(StaticMapInfo));
- }
- else
- m_vStaticMapInfo = NULL;
- }
- break;
- case FM_S_RANK_INFO:
- {
- CASTPFM(pfmRankInfo, S, RANK_INFO, pfm);
- // copy the new rank info into our internal table
- if (m_vRankInfo)
- delete [] m_vRankInfo;
- m_cRankInfo = pfmRankInfo->cRanks;
- m_vRankInfo = new RankInfo[m_cRankInfo];
- memcpy(m_vRankInfo, FM_VAR_REF(pfmRankInfo, ranks), m_cRankInfo * sizeof(RankInfo));
- }
- break;
- case FM_S_CLUB_RANK_INFO:
- {
- CASTPFM(pfmRankInfo, S, CLUB_RANK_INFO, pfm);
- // copy the new rank info into our internal table
- if (m_vRankInfo)
- delete [] m_vRankInfo;
- m_cRankInfo = pfmRankInfo->cRanks;
- m_vRankInfo = new RankInfo[m_cRankInfo];
- memcpy(m_vRankInfo, FM_VAR_REF(pfmRankInfo, ranks), m_cRankInfo * sizeof(RankInfo));
- }
- break;
- // ************ Lobby Messages *************
- case FM_L_AUTO_UPDATE_INFO:
- {
- if (m_pAutoDownload == NULL)
- m_pAutoDownload = CreateAutoDownload();
- IAutoUpdateSink * pAutoUpdateSink = OnBeginAutoUpdate(NULL, true);
- assert(pAutoUpdateSink);
- CASTPFM(pfmServerInfo, L, AUTO_UPDATE_INFO, pfm);
- m_pAutoDownload->SetFTPSite(FM_VAR_REF(pfmServerInfo, FTPSite),
- FM_VAR_REF(pfmServerInfo, FTPInitialDirectory),
- FM_VAR_REF(pfmServerInfo, FTPAccount),
- FM_VAR_REF(pfmServerInfo, FTPPassword));
- m_pAutoDownload->SetOfficialFileListAttributes(pfmServerInfo->crcFileList,
- pfmServerInfo->nFileListSize);
- // Disconnect during download
- DisconnectLobby();
- m_pAutoDownload->SetArtPath(GetArtPath());
- //
- // Let's do it!
- //
- m_pAutoDownload->BeginUpdate(pAutoUpdateSink, ShouldCheckFiles(), false);
- // m_pAutoDownload could be NULL at this point, if the autodownload system decided
- // not to do a download after all. This can happen if there is an error or if
- // the client was already up-to-date.
- }
- break;
- case FM_L_CREATE_MISSION_ACK:
- {
- CASTPFM(pfmCreateMissionAck, L, CREATE_MISSION_ACK, pfm);
- // we remember it, so that if we're told to join a mission, we can be sure it's for the one we want to join,
- m_dwCookieToJoin = pfmCreateMissionAck->dwCookie;
- m_strPasswordToJoin[0] = '\0';
- }
- break;
- case FM_LS_LOBBYMISSIONINFO:
- {
- if (!LoggedOnToLobby())
- break;
- CASTPFM(pfmLobbyMissionInfo, LS, LOBBYMISSIONINFO, pfm);
- // The time offset may be off by as much as the maximum server
- // latency, but that's OK for just displaying a timer. Let's
- // make sure we never assume a starting time in the future, however.
- pfmLobbyMissionInfo->dwStartTime += m_lobbyServerOffset;
- if (now - Time(pfmLobbyMissionInfo->dwStartTime) < 0 && !pfmLobbyMissionInfo->fCountdownStarted)
- pfmLobbyMissionInfo->dwStartTime = now.clock();
- MissionInfo * pMissionInfo = GetLobbyMission(pfmLobbyMissionInfo->dwCookie);
- assert(pMissionInfo);
- pMissionInfo->Update(pfmLobbyMissionInfo);
- m_mapMissions.GetSink()();
- m_pClientEventSource->OnAddMission(pMissionInfo);
- break;
- }
- case FM_L_JOIN_MISSION:
- {
- CASTPFM(pfmJoinMission, L, JOIN_MISSION, pfm);
- if (m_dwCookieToJoin = pfmJoinMission->dwCookie) // this is our number--join up
- {
- m_ci.strServer = pfmJoinMission->szServer;
- m_ci.guidSession = GUID_NULL;
- ConnectToServer(m_ci, pfmJoinMission->dwCookie, now, m_strPasswordToJoin, false);
- }
- else
- {
- OnLogonAck(false, false, "<bug>: Received a spurious join request.");
- }
- break;
- }
- case FM_L_CREATE_MISSION_NACK:
- {
- OnLogonAck(false, false, "There are no available servers on which to create a game.");
- }
- break;
- case FM_L_JOIN_GAME_NACK:
- {
- OnLogonAck(false, false, "There is no more room on this server.");
- }
- break;
- case FM_LS_MISSION_GONE:
- {
- CASTPFM(pfmMissionGone, LS, MISSION_GONE, pfm);
- MissionInfo * pMission = GetLobbyMission(pfmMissionGone->dwCookie);
-
- if (m_pMissionInfo != NULL && pMission->GetCookie() == MyMission()->GetCookie())
- {
- if (GetSideID() != NA)
- {
- if (GetSideID() != SIDE_TEAMLOBBY)
- RemovePlayerFromSide(m_pPlayerInfo, QSR_Quit);
- RemovePlayerFromMission(m_pPlayerInfo, QSR_Quit);
- }
- else
- {
- delete m_pMissionInfo;
- m_pMissionInfo = NULL;
- }
- }
- m_pClientEventSource->OnDelMission(pMission);
- m_mapMissions.Remove(pfmMissionGone->dwCookie);
- delete pMission;
- }
- break;
- case FM_L_LOGON_ACK:
- {
- CASTPFM(pfmLogonAck, L, LOGON_ACK, pfm);
- m_fLoggedOnToLobby = true;
- m_lobbyServerOffset = pfmLogonAck->dwTimeOffset;
- OnLogonLobbyAck(true, false, NULL);
- }
- break;
- case FM_L_LOGON_NACK:
- {
- CASTPFM(pfmLogonNack, L, LOGON_NACK, pfm);
- OnLogonLobbyAck(false, pfmLogonNack->fRetry, FM_VAR_REF(pfmLogonNack, Reason));
- assert(m_fLoggedOnToLobby == false);
- m_szLobbyCharName[0] = '\0';
- }
- break;
- case FM_S_LOGON_CLUB_ACK:
- {
- CASTPFM(pfmLogonAck, S, LOGON_CLUB_ACK, pfm);
- SetZoneClubID(pfmLogonAck->nMemberID);
- m_fLoggedOnToClub = true;
- OnLogonClubAck(true, false, NULL);
- }
- break;
- case FM_S_LOGON_CLUB_NACK:
- {
- CASTPFM(pfmLogonNack, S, LOGON_CLUB_NACK, pfm);
- OnLogonClubAck(false, pfmLogonNack->fRetry, FM_VAR_REF(pfmLogonNack, Reason));
- assert(m_fLoggedOnToClub == false);
- m_szClubCharName[0] = '\0';
- }
- break;
- case FM_L_FOUND_PLAYER:
- {
- CASTPFM(pfmFoundPlayer, L, FOUND_PLAYER, pfm);
- MissionInfo* pMissionInfo;
- if (pfmFoundPlayer->dwCookie == NA)
- pMissionInfo = NULL;
- else
- pMissionInfo = GetLobbyMission(pfmFoundPlayer->dwCookie);
- m_pClientEventSource->OnFoundPlayer(pMissionInfo);
- }
- break;
- default:
- {
- // Note: we can't assert here because there are some messages
- // which are only handled in TrekWindowImpl::HandleMessage. TrekIGC.cpp
- // already asserts that one of the two handles the message, however.
- //ZError("unknown message");
- hr = S_FALSE;
- }
- }
- return (hr);
- }
|