bool CclusterIGC::IsFriendlyCluster(IsideIGC* pside, ClusterQuality cqlty) //Spunky #288 { int balanceOfPower = 0; //carrier or ASS in sector = not friendly - Spunky #290 ShipLinkIGC* pshipl = GetShips()->first(); if (pshipl) { do { IshipIGC* pship = pshipl->data(); if (pship->GetParentShip() == NULL) if (pship->GetSide() != pside && pship->SeenBySide(pside) && !IsideIGC::AlliedSides(pside, pship->GetSide())) { if (pship->GetHullType()->HasCapability(c_habmIsRipcordTarget | c_habmIsLtRipcordTarget)) return false; if (pship->GetBaseHullType()->GetScannerRange() > 800 && cqlty & cqNoEye) return false; balanceOfPower--; } else if (pship->GetSide() == pside || IsideIGC::AlliedSides(pside, pship->GetSide())) balanceOfPower++; pshipl = pshipl->next(); } while (pshipl); } if (balanceOfPower < 0 && cqlty & cqPositiveBOP) return false; //Spunky #333 StationLinkIGC* psl = GetStations()->first(); bool ourBaseInCluster = false; if (psl) { do { IstationIGC* ps = psl->data(); if (!ps->GetStationType()->HasCapability(c_sabmPedestal) && ps->SeenBySide(pside)) { if (pside != ps->GetSide() && !IsideIGC::AlliedSides(pside, ps->GetSide())) // #ALLY FIXED 7/10/09 imago return false; else ourBaseInCluster = true; } psl = psl->next(); } while (psl != NULL); } if (cqlty & cqIncludeNeutral || ourBaseInCluster) return true; else return false; }
void CFSShip::ShipStatusSpotted(IsideIGC* pside) { SideID sideID = pside->GetObjectID(); SectorID sectorID; { IclusterIGC* pcluster = GetIGCShip()->GetCluster(); if (pcluster == NULL) { IstationIGC* pstation = GetIGCShip()->GetStation(); assert (pstation); pcluster = pstation->GetCluster(); } sectorID = pcluster->GetObjectID(); } ShipStatus* pss = &m_rgShipStatus[sideID]; pss->SetStateTime(g.timeNow.clock()); pss->SetState(c_ssFlying); pss->SetParentID(NA); pss->SetHullID(GetIGCShip()->GetHullType()->GetObjectID()); pss->SetSectorID(sectorID); //Flag that we have been detected as well IsideIGC* mySide = GetSide(); SideID mySideID = mySide->GetObjectID(); if (mySide != pside && !mySide->AlliedSides(mySide, pside)) //#ALLY -was: mySide != pside (Imago fixed 7/8/09) m_rgShipStatus[mySideID].SetDetected(true); //Adjust the ship status for all of the children as well { for (ShipLinkIGC* psl = GetIGCShip()->GetChildShips()->first(); (psl != NULL); psl = psl->next()) { IshipIGC* pship = psl->data(); CFSShip* pfsship = ((CFSShip*)(pship->GetPrivateData())); ShipStatus* pss = pfsship->GetShipStatus(sideID); pss->SetState((pship->GetTurretID() == NA) ? c_ssObserver : c_ssTurret); pss->SetHullID(NA); pss->SetSectorID(sectorID); pss->SetParentID(GetShipID()); if (mySide != pside && !mySide->AlliedSides(mySide, pside)) //#ALLY -was != (Imago fixed 7/8/09) pfsship->GetShipStatus(mySideID)->SetDetected(true); } } }
static bool CanKeepCurrentShip(ImodelIGC* pmodel) { if (pmodel->GetObjectType() == OT_ship) { // they can keep their ship only if they don't have one or are in a lifepod return trekClient.GetShip()->GetParentShip() != NULL || trekClient.GetShip()->GetBaseHullType()->HasCapability(c_habmLifepod); } else { IstationIGC* pstation; CastTo(pstation, pmodel); IhullTypeIGC* pht = trekClient.GetShip()->GetBaseHullType(); // they can keep their current ship if they are already in this station or // if the station can build the hull which they currently have. return trekClient.GetShip()->GetStation() == pstation || pht && pstation->CanBuy(pht); } }
void RebuildList(ImodelIGC* pmodelExclude = NULL) { TRef<TListListWrapper<ImodelIGC*> > plistNew = new TListListWrapper<ImodelIGC*>(); IsideIGC* pside = trekClient.GetSide(); if (pside && trekClient.GetSideID() != SIDE_TEAMLOBBY) { for (ShipLinkIGC* pshiplink = pside->GetShips()->first(); (pshiplink != NULL); pshiplink = pshiplink->next()) { IshipIGC* pship = pshiplink->data(); if (pship != pmodelExclude && CanBoard(pship)) { plistNew->PushEnd(pship); } } for (StationLinkIGC* pstationlink = pside->GetStations()->first(); (pstationlink != NULL); pstationlink = pstationlink->next()) { IstationIGC* pstation = pstationlink->data(); if (pstation != pmodelExclude && pstation->GetBaseStationType()->HasCapability(c_sabmRestart)) { plistNew->PushEnd(pstation); } } } m_plistDestinations = plistNew; m_plistPaneDestinations->SetList(m_plistDestinations); }
void CclusterIGC::Update(Time now) { if (now > m_lastUpdate) { float dt = now - m_lastUpdate; bool bStarted = m_pMission->GetMissionStage() == STAGE_STARTED; if (bStarted) { { //Have any stations launch docked drones for (StationLinkIGC* l = m_stations.first(); (l != NULL); l = l->next()) { IstationIGC* pstation = l->data(); ShipLinkIGC* pslNext; for (ShipLinkIGC* psl = pstation->GetShips()->first(); (psl != NULL); psl = pslNext) { IshipIGC* pship = psl->data(); pslNext = psl->next(); //Get the next link now since the ship may launch // const MissionParams* pmp = m_pMission->GetMissionParams(); 04/08 commented out as not needed // mmf 10/07 added so we can get at bExperimental game type if (pship->GetAutopilot() && (pship->GetPilotType() < c_ptPlayer)) { //Docked non-players on autopilot never are observers/parents assert (pship->GetParentShip() == NULL); assert (pship->GetChildShips()->n() == 0); // mmf/yp 10/07 added this so drones launch when ordered to even if OkToLaunch might be false // intentionally left c_cidMine out of the list otherwise miners would launch with their AI // 'order' to mine if (pship->OkToLaunch(now) || (pship->GetCommandID(c_cmdAccepted) == c_cidGoto) || (pship->GetCommandID(c_cmdAccepted) == c_cidBuild) ) pship->SetStation(NULL); // if (pship->OkToLaunch(now)) // mmf orig code // pship->SetStation(NULL); } } //Are any ships buzzing around the stations that a side has yet to eye? #121 #120 Imago 8/10 if (GetShips()->n() > 0 && pstation->GetRoidID() != NA) { Vector pos = pstation->GetRoidPos(); float Sig = pstation->GetRoidSig(); float Radius = pstation->GetRoidRadius(); if (Sig != 0.0f && Radius != 0.0f) { //check if they have a ship eying where the rock would be for (ShipLinkIGC* psl1 = GetShips()->first(); (psl1 != NULL); psl1 = psl1->next()) { IshipIGC* pship = psl1->data(); if (pship->GetParentShip() || pship->GetSide()->GetObjectID() == pstation->GetSide()->GetObjectID() || pstation->SeenBySide(pship->GetSide()) || !pstation->GetRoidSide(pship->GetSide()->GetObjectID())) continue; bool bEye = bSimpleEye(pship->GetHullType()->GetScannerRange(),GetMission()->GetModel(OT_ship,pship->GetObjectID()),Sig,pstation->GetSide()->GetGlobalAttributeSet().GetAttribute(c_gaSignature),Radius,pos); if (bEye) { //Turkey 3/13 #353: kill asteroids for all sides in that alliance. IsideIGC* pside1 = pship->GetSide(); for (SideLinkIGC* sl = m_pMission->GetSides()->first(); sl != NULL; sl = sl->next()) { IsideIGC* pside2 = sl->data(); if (pside1->AlliedSides(pside1, pside2)) { pstation->SetRoidSide(pside2->GetObjectID(),false); GetMission()->GetIgcSite()->KillAsteroidEvent(pstation->GetRoidID(),GetObjectID(),pside2); } } } } } } } } { m_fCost = m_pMission->GetFloatConstant(c_fcidBaseClusterCost); float costLifepod = m_pMission->GetFloatConstant(c_fcidLifepodCost); float costTurret = m_pMission->GetFloatConstant(c_fcidTurretCost); float costPlayer = m_pMission->GetFloatConstant(c_fcidPlayerCost); float costDrone = m_pMission->GetFloatConstant(c_fcidDroneCost); //Have miners and builders do any pre-plotted moves. Allow ships to suicide. ShipLinkIGC* lNext; for (ShipLinkIGC* l = m_ships.first(); (l != NULL); l = lNext) { IshipIGC* s = l->data(); lNext = l->next(); if (s->GetPilotType() < c_ptPlayer) m_fCost += costDrone; else if (s->GetParentShip() != NULL) m_fCost += costTurret; else { IhullTypeIGC* pht = s->GetBaseHullType(); assert (pht); m_fCost += pht->HasCapability(c_habmLifepod) ? costLifepod : costPlayer; } s->PreplotShipMove(now); } if (m_fCost > 0.0f) { m_fCost *= dt / m_pMission->GetFloatConstant(c_fcidClusterDivisor); } { //Have all ships on autopilot plot their moves. Allow ships to suicide. ShipLinkIGC* lNext; for (ShipLinkIGC* l = m_ships.first(); (l != NULL); l = lNext) { IshipIGC* s = l->data(); lNext = l->next(); s->PlotShipMove(now); } } } { //Have all ships execute their moves for (ShipLinkIGC* l = m_ships.first(); (l != NULL); l = l->next()) { IshipIGC* s = l->data(); if (s->GetParentShip() == NULL) { s->ExecuteShipMove(now); } } } } else m_fCost = 0.0f; { //Call the update method on all the contained models //models might self-terminate in the update and nuke earlier models in the update loop //NYI debugging variables //ObjectType oldObjectType = NA; //ObjectType newObjectType = NA; ModelLinkIGC* lNext; for (ModelLinkIGC* l = m_models.first(); (l != NULL); l = lNext) { //oldObjectType = newObjectType; //newObjectType = l->data()->GetObjectType(); lNext = l->next(); l->data()->Update(now); } } if (m_data.activeF && bStarted) { { //Update the bounding boxes for all moving objects & projectiles for (ModelLinkIGC* l = m_models.first(); (l != NULL); l = l->next()) { l->data()->SetBB(m_lastUpdate, now, dt); } m_tMax = dt; } m_kdrStatic.update(); m_kdrMoving.update(); { //Cast rays through the KD tree for each object for (ModelLinkIGC* l = m_modelsCastRay.first(); (l != NULL); l = l->next()) { ImodelIGC* m = l->data(); HitTest* ht = m->GetHitTest(); if (!ht->GetDeadF()) { m_kdrStatic.test(ht, &m_collisions); m_kdrMoving.test(ht, &m_collisions); } } } //Sort the collisions by the time they occur m_collisions.sort(0); //Process each collision (in order) { m_tOffset = 0.0f; for (m_collisionID = 0; (m_collisionID < m_collisions.n()); m_collisionID++) { const CollisionEntry& entry = m_collisions[m_collisionID]; if (!(entry.m_pHitTest1->GetDeadF() || entry.m_pHitTest2->GetDeadF())) { Time timeCollision = m_lastUpdate + (m_tOffset + entry.m_tCollision); ImodelIGC* pModelHitTest1 = (ImodelIGC*)(entry.m_pHitTest1->GetData()); assert (pModelHitTest1); ImodelIGC* pModelHitTest2 = (ImodelIGC*)(entry.m_pHitTest2->GetData()); assert (pModelHitTest2); //Give each participant in the collision a chance to handle the collision //but give the "1st" model first dibs. if ((pModelHitTest1->GetCluster() == this) && (pModelHitTest2->GetCluster() == this)) { pModelHitTest1->HandleCollision(timeCollision, entry.m_tCollision, entry, pModelHitTest2); } } } m_collisions.purge(); } { //Apply any damage from mines //Kids always follow parents in the ship list, so go from back to front //so that the killing a parent doesn't mean hitting dead elements in the list ShipLinkIGC* lTxen; for (ShipLinkIGC* l = m_ships.last(); (l != NULL); l = lTxen) { IshipIGC* s = l->data(); lTxen = l->txen(); s->ApplyMineDamage(); } } //Move each object & projectile { for (ModelLinkIGC* l = m_models.first(); (l != NULL); l = l->next()) { l->data()->Move(); } } if ((m_nPass++) % c_nPassesPerUpdate == 0) { for (ModelLinkIGC* l = m_models.first(); (l != NULL); l = l->next()) { l->data()->UpdateSeenBySide(); } m_pMission->GetIgcSite()->ClusterUpdateEvent(this); } } //Draw and resolve any explosions if (m_nExplosions != 0) { const int c_maxDmgs = 500; IdamageIGC* pdmgs[c_maxDmgs]; int nDmgs = 0; //Copy the list of models in the sector that can be damaged into for (ModelLinkIGC* l = m_modelsPickable.first(); (l != NULL); l = l->next()) { ImodelIGC* pmodel = l->data(); ObjectType type = pmodel->GetObjectType(); //Not everything that can take damage can be affected by an explosion. if ((type == OT_ship) || (type == OT_asteroid) || (type == OT_station) || (type == OT_missile) || (type == OT_probe)) { pmodel->AddRef(); pdmgs[nDmgs++] = (IdamageIGC*)pmodel; if (nDmgs == c_maxDmgs) break; } } ImineIGC* pmines[c_maxDmgs]; int nMines = 0; { for (MineLinkIGC* l = m_mines.first(); (l != NULL); l = l->next()) { ImineIGC* pm = l->data(); pm->AddRef(); pmines[nMines++] = pm; if (nMines == c_maxDmgs) break; } } int i = 0; do { ExplosionData& e = m_explosions[i]; m_pClusterSite->AddExplosion(e.position, e.radius, e.explosionType); float dt = (e.time - m_lastUpdate) - m_tOffset; //Now, the painful part: applying damage to everything in the sector that could be hit { for (int j = 0; (j < nDmgs); j++) { IdamageIGC* pTarget = pdmgs[j]; if (pTarget->GetCluster() == this) //Make sure it wasn't already destroyed { //The target is still around Vector p = pTarget->GetPosition() + dt * pTarget->GetVelocity(); float d = (e.position - p).Length() - pTarget->GetRadius(); if (d < e.radius) { float amount = e.amount; if (d > 0.0f) { float f = 1.0f - (d / e.radius); amount *= f * f; } pTarget->ReceiveDamage(e.damageType | c_dmgidNoWarn | c_dmgidNoDebris, amount, e.time, p, e.position, e.launcher); } } } } { for (int j = 0; (j < nMines); j++) { ImineIGC* pTarget = pmines[j]; if (pTarget->GetCluster() == this) //Make sure it wasn't already destroyed { //The target is still around const Vector& p = pTarget->GetPosition(); float d = (e.position - p).Length() - pTarget->GetRadius(); if (d < e.radius) { float amount = e.amount; if (d > 0.0f) { float f = 1.0f - (d / e.radius); amount *= f * f; } pTarget->ReduceStrength(amount); } } } } if (e.launcher) e.launcher->Release(); } while (++i < m_nExplosions); //Release all the cached pointers { while (--nDmgs >= 0) pdmgs[nDmgs]->Release(); } { while (--nMines >= 0) pmines[nMines]->Release(); } m_nExplosions = 0; } m_lastUpdate = now; } }
//------------------------------------------------------------------------------ Condition* Mission5::CreateMission (void) { GoalList* pGoalList = new GoalList; Goal* pGoal = new Goal (pGoalList); ImissionIGC* pMission = trekClient.GetCore (); IstationIGC* pStationNeptune = pMission->GetStation (1050); IstationIGC* pStationMars = pMission->GetStation (1052); IwarpIGC* pAlephNeptune = pMission->GetWarp (1050); IwarpIGC* pAlephMars = pMission->GetWarp (1052); // generate ship ids that we'll be using throughout the mission m_enemyScoutID = pMission->GenerateNewShipID (); m_miner1ID = pMission->GenerateNewShipID (); m_miner2ID = pMission->GenerateNewShipID (); m_miner3ID = pMission->GenerateNewShipID (); m_miner4ID = pMission->GenerateNewShipID (); m_scoutID = pMission->GenerateNewShipID (); m_builder1ID = pMission->GenerateNewShipID (); m_builder2ID = pMission->GenerateNewShipID (); m_builder3ID = pMission->GenerateNewShipID (); // add the goals to the list pGoalList->AddGoal (CreateGoal01 ()); pGoalList->AddGoal (CreateGoal02 ()); pGoalList->AddGoal (CreateGoal03 ()); pGoalList->AddGoal (CreateGoal04 ()); pGoalList->AddGoal (CreateGoal05 ()); // create the tower builder drones Vector pos = pStationNeptune->GetPosition () + Vector (random(-300.0f, 300.0f), random(-300.0f, 300.0f), random(-300.0f, 300.0f)); CreateDroneAction* pCreateDroneAction = new CreateDroneAction ("Tower Layer 01", m_builder1ID, 418, 0, c_ptLayer); pCreateDroneAction->SetExpendableType (431); pCreateDroneAction->SetCreatedLocation (GetStartSectorID (), pos); pGoal->AddStartAction (pCreateDroneAction); pos = pStationNeptune->GetPosition () + Vector (random(-300.0f, 300.0f), random(-300.0f, 300.0f), random(-300.0f, 300.0f)); pCreateDroneAction = new CreateDroneAction ("Tower Layer 02", m_builder2ID, 418, 0, c_ptLayer); pCreateDroneAction->SetExpendableType (431); pCreateDroneAction->SetCreatedLocation (GetStartSectorID (), pos); pGoal->AddStartAction (pCreateDroneAction); pos = pStationNeptune->GetPosition () + Vector (random(-300.0f, 300.0f), random(-300.0f, 300.0f), random(-300.0f, 300.0f)); pCreateDroneAction = new CreateDroneAction ("Tower Layer 03", m_builder3ID, 418, 0, c_ptLayer); pCreateDroneAction->SetExpendableType (431); pCreateDroneAction->SetCreatedLocation (GetStartSectorID (), pos); pGoal->AddStartAction (pCreateDroneAction); // create the miners pos = pStationNeptune->GetPosition () + Vector (random(-600.0f, 600.0f), random(-600.0f, 600.0f), random(-300.0f, 300.0f)); pCreateDroneAction = new CreateDroneAction ("Miner 01", m_miner1ID, 438, 0, c_ptMiner); pCreateDroneAction->SetCreatedLocation (GetStartSectorID (), pos); pGoal->AddStartAction (pCreateDroneAction); pos = pStationMars->GetPosition () + Vector (random(-600.0f, 600.0f), random(-600.0f, 600.0f), random(-300.0f, 300.0f)); pCreateDroneAction = new CreateDroneAction ("Miner 02", m_miner2ID, 438, 0, c_ptMiner); pCreateDroneAction->SetCreatedLocation (GetStartSectorID () + 1, pos); pGoal->AddStartAction (pCreateDroneAction); pos = pStationMars->GetPosition () + Vector (random(-600.0f, 600.0f), random(-600.0f, 600.0f), random(-300.0f, 300.0f)); pCreateDroneAction = new CreateDroneAction ("Miner 03", m_miner3ID, 438, 0, c_ptMiner); pCreateDroneAction->SetCreatedLocation (GetStartSectorID () + 1, pos); pGoal->AddStartAction (pCreateDroneAction); pos = pStationMars->GetPosition () + Vector (random(-600.0f, 600.0f), random(-600.0f, 600.0f), random(-300.0f, 300.0f)); pCreateDroneAction = new CreateDroneAction ("Miner 04", m_miner4ID, 438, 0, c_ptMiner); pCreateDroneAction->SetCreatedLocation (GetStartSectorID () + 1, pos); pGoal->AddStartAction (pCreateDroneAction); // create the scout pos = pStationMars->GetPosition () + ((pAlephMars->GetPosition () - pStationMars->GetPosition ()) * random (0.5f, 0.75f)); pCreateDroneAction = new CreateDroneAction ("Stealth Fighter", m_scoutID, 411, 0, c_ptWingman); pCreateDroneAction->SetCreatedLocation (GetStartSectorID () + 1, pos); pGoal->AddStartAction (pCreateDroneAction); // tell all of these guys to do nothing pGoal->AddStartAction (new SetCommandAction (m_scoutID, c_cmdAccepted, NULL, c_cidDoNothing)); pGoal->AddStartAction (new SetCommandAction (m_scoutID, c_cmdCurrent, NULL, c_cidDoNothing)); pGoal->AddStartAction (new SetCommandAction (m_miner2ID, c_cmdAccepted, NULL, c_cidDoNothing)); pGoal->AddStartAction (new SetCommandAction (m_miner2ID, c_cmdCurrent, NULL, c_cidDoNothing)); pGoal->AddStartAction (new SetCommandAction (m_miner3ID, c_cmdAccepted, NULL, c_cidDoNothing)); pGoal->AddStartAction (new SetCommandAction (m_miner3ID, c_cmdCurrent, NULL, c_cidDoNothing)); pGoal->AddStartAction (new SetCommandAction (m_miner4ID, c_cmdAccepted, NULL, c_cidDoNothing)); pGoal->AddStartAction (new SetCommandAction (m_miner4ID, c_cmdCurrent, NULL, c_cidDoNothing)); pGoal->AddStartAction (new SetCommandAction (m_builder1ID, c_cmdAccepted, NULL, c_cidDoNothing)); pGoal->AddStartAction (new SetCommandAction (m_builder1ID, c_cmdCurrent, NULL, c_cidDoNothing)); pGoal->AddStartAction (new SetCommandAction (m_builder2ID, c_cmdAccepted, NULL, c_cidDoNothing)); pGoal->AddStartAction (new SetCommandAction (m_builder2ID, c_cmdCurrent, NULL, c_cidDoNothing)); pGoal->AddStartAction (new SetCommandAction (m_builder3ID, c_cmdAccepted, NULL, c_cidDoNothing)); pGoal->AddStartAction (new SetCommandAction (m_builder3ID, c_cmdCurrent, NULL, c_cidDoNothing)); return pGoal; }
void Paint(ItemID pitemArg, Surface* psurface, bool bSelected, bool bFocus) { ImodelIGC* pDestination = (ImodelIGC*)pitemArg; IshipIGC* pship = NULL; IstationIGC* pstation = NULL; if (pDestination == NULL || trekClient.MyMission() == NULL) return; if (pDestination->GetObjectType() == OT_ship) { CastTo(pship, pDestination); } else { assert(pDestination->GetObjectType() == OT_station); CastTo(pstation, pDestination); } // draw the selection bar if (bSelected) { psurface->FillRect( WinRect(0, 0, GetXSize(), GetYSize()), Color::Red() ); } TRef<IEngineFont> pfont; // show the place we currently are in bold if (pship && pship == trekClient.GetShip()->GetParentShip() || pstation && pstation == trekClient.GetShip()->GetStation()) { pfont = TrekResources::SmallBoldFont(); } else { pfont = TrekResources::SmallFont(); } Color color; if (CanKeepCurrentShip(pDestination)) { color = Color::White(); } else { color = 0.75f * Color::White(); } // draw the name psurface->DrawString( pfont, color, WinPoint(0, 0), pship ? pship->GetName() : pstation->GetName() ); // draw the ship type (if any) if (pship) { psurface->DrawString( pfont, color, WinPoint(m_viColumns[0], 0), HullName(pDestination) ); } // draw the cluster psurface->DrawString( pfont, color, WinPoint(m_viColumns[1] + 2, 0), SectorName(pDestination) ); // draw the total number of turrets (if appropriate) if (pship && NumTurrets(pship)) { int nNumTurrets = NumTurrets(pship); if (nNumTurrets != 0) { psurface->DrawString( pfont, color, WinPoint(m_viColumns[2] + 2, 0), ZString((int)MannedTurrets(pship)) + ZString("/") + ZString(nNumTurrets) ); } } }
bool OnButtonTeleport() { ImodelIGC* pDestination = (ImodelIGC*)(m_plistPaneDestinations->GetSelection()); IstationIGC* pstation = NULL; if (pDestination == NULL || trekClient.MyMission() == NULL || trekClient.GetShip()->GetCluster() != NULL) return true; if (pDestination->GetObjectType() == OT_ship) { // if this is a ship, try boarding it. IshipIGC* pship; CastTo(pship, pDestination); if (trekClient.GetShip()->GetParentShip() != NULL) { trekClient.DisembarkAndBoard(pship); } else { trekClient.BoardShip(pship); } trekClient.PlaySoundEffect(personalJumpSound); } else { // try teleporting to that station IstationIGC* pstation; CastTo(pstation, pDestination); if (trekClient.GetShip()->GetParentShip() != NULL) { // if they are already there, just get off of the ship if (pstation == trekClient.GetShip()->GetParentShip()->GetStation()) { trekClient.BoardShip(NULL); } else { trekClient.DisembarkAndTeleport(pstation); } } else { if (pstation != trekClient.GetShip()->GetStation()) { trekClient.SetMessageType(BaseClient::c_mtGuaranteed); BEGIN_PFM_CREATE(trekClient.m_fm, pfmDocked, C, DOCKED) END_PFM_CREATE pfmDocked->stationID = pstation->GetObjectID(); trekClient.StartLockDown( "Teleporting to " + ZString(pstation->GetName()) + "....", BaseClient::lockdownTeleporting); } } } // dismiss the teleport pane. GetWindow()->TurnOffOverlayFlags(ofTeleportPane); return true; }
//This should only be called from the ChangeCluster() callback. void CFSPlayer::SetCluster(IclusterIGC* pcluster, bool bViewOnly) { CFSShip::SetCluster(pcluster, bViewOnly); if (pcluster) { SetDPGroup((CFSCluster*)(pcluster->GetPrivateData()), true); IshipIGC* pshipParent = GetIGCShip()->GetParentShip(); if ((pshipParent == NULL) || bViewOnly) { ShipID shipID = GetIGCShip()->GetObjectID(); assert(0 == g.fm.CbUsedSpaceInOutbox()); if (!bViewOnly) { //Move the player to his destination BEGIN_PFM_CREATE(g.fm, pfmSetCluster, S, SET_CLUSTER) END_PFM_CREATE pfmSetCluster->sectorID = pcluster->GetObjectID(); //Send the position of the parent ship if we are a child, otherwise our position IshipIGC* pshipSource = pshipParent ? pshipParent : GetIGCShip(); pshipSource->ExportShipUpdate(&(pfmSetCluster->shipupdate)); pfmSetCluster->cookie = NewCookie(); } { for (ShipLinkIGC* pshiplink = pcluster->GetShips()->first(); pshiplink; pshiplink = pshiplink->next()) { IshipIGC * pshipExist = pshiplink->data(); if ((pshipExist != GetIGCShip()) && (pshipExist != pshipParent)) { IshipIGC* pshipExistParent = pshipExist->GetParentShip(); //Tell the new player where the existing ship is/was //provided the existing ship is not the child of some other ship //and is not the parent of the new ship if (pshipExistParent == NULL) { CFSShip * pfsShipExist = (CFSShip *) pshipExist->GetPrivateData(); pfsShipExist->QueueLoadoutChange(); BEGIN_PFM_CREATE(g.fm, pfmSSU, S, SINGLE_SHIP_UPDATE) END_PFM_CREATE //Always use the ship update based on the server's current view of the universe //(this shouldn't be a lot worse than anything the player sent and it is easier) pshipExist->ExportShipUpdate(&(pfmSSU->shipupdate)); { ImodelIGC* pmodelTarget = pshipExist->GetCommandTarget(c_cmdCurrent); if (pmodelTarget) { pfmSSU->otTarget = pmodelTarget->GetObjectType(); pfmSSU->oidTarget = pmodelTarget->GetObjectID(); } else { pfmSSU->otTarget = NA; pfmSSU->oidTarget = NA; } } pfmSSU->bIsRipcording = pshipExist->fRipcordActive(); } } } } { // Let's build up a list of station updates so we can batch 'em down IsideIGC* pside = GetIGCShip()->GetSide(); { const StationListIGC * pstnlist = pcluster->GetStations(); int nStations = 0; { //Count the number of visible stations for (StationLinkIGC* pstnlink = pstnlist->first(); pstnlink; pstnlink = pstnlink->next()) { IstationIGC* pstation = pstnlink->data(); if (pstation->SeenBySide(pside)) nStations++; } } if (nStations != 0) { // tell the client what happened BEGIN_PFM_CREATE(g.fm, pfmStationsUpdate, S, STATIONS_UPDATE) FM_VAR_PARM(NULL, nStations * sizeof(StationState)) END_PFM_CREATE StationState* pss = (StationState*)(FM_VAR_REF(pfmStationsUpdate, rgStationStates)); for (StationLinkIGC* pstnlink = pstnlist->first(); pstnlink; pstnlink = pstnlink->next()) { IstationIGC * pstation = pstnlink->data(); if (pstation->SeenBySide(pside)) { pss->stationID = pstation->GetObjectID(); pss->bpHullFraction = pstation->GetFraction(); (pss++)->bpShieldFraction = pstation->GetShieldFraction(); } } } } { //Let's build up a list of probe updates and batch them on down (only damage & visible probes) const ProbeListIGC * pprblist = pcluster->GetProbes(); int nProbes = 0; { for (ProbeLinkIGC* pprblink = pprblist->first(); pprblink; pprblink = pprblink->next()) { if (pprblink->data()->SeenBySide(pside)) nProbes++; } } if (nProbes != 0) { BEGIN_PFM_CREATE(g.fm, pfmProbesUpdate, S, PROBES_UPDATE) FM_VAR_PARM(NULL, nProbes * sizeof(ProbeState)) END_PFM_CREATE ProbeState* pps = (ProbeState*)(FM_VAR_REF(pfmProbesUpdate, rgProbeStates)); for (ProbeLinkIGC* pprblink = pprblist->first(); pprblink; pprblink = pprblink->next()) { IprobeIGC * pprobe = pprblink->data(); if (pprobe->SeenBySide(pside)) { pps->probeID = pprobe->GetObjectID(); (pps++)->bpFraction = pprobe->GetFraction(); } } } } { //Let's build up a list of asteroid updates and batch them on down const AsteroidListIGC * pastlist = pcluster->GetAsteroids(); int nAsteroids = 0; { for (AsteroidLinkIGC* pastlink = pastlist->first(); pastlink; pastlink = pastlink->next()) { if (pastlink->data()->SeenBySide(pside)) nAsteroids++; } } if (nAsteroids != 0) { BEGIN_PFM_CREATE(g.fm, pfmAsteroidsUpdate, S, ASTEROIDS_UPDATE) FM_VAR_PARM(NULL, nAsteroids * sizeof(AsteroidState)) END_PFM_CREATE AsteroidState* pas = (AsteroidState*)(FM_VAR_REF(pfmAsteroidsUpdate, rgAsteroidStates)); for (AsteroidLinkIGC* pastlink = pastlist->first(); pastlink; pastlink = pastlink->next()) { IasteroidIGC * pasteroid = pastlink->data(); if (pasteroid->SeenBySide(pside)) { pas->asteroidID = pasteroid->GetObjectID(); pas->ore = short(pasteroid->GetOre()); pas->co.Set(pasteroid->GetOrientation()); (pas++)->bpFraction = pasteroid->GetFraction(); } } } } } //Also send the identical message to all of the ship's children] if (!bViewOnly) //TheRock 4-1-2010 fixed ships overlaying in f3 while on a turret { for (ShipLinkIGC* psl = GetIGCShip()->GetChildShips()->first(); (psl != NULL); psl = psl->next()) { CFSShip* pfsShip = (CFSShip*)(psl->data()->GetPrivateData()); assert (pfsShip->IsPlayer()); pfsShip->GetPlayer()->ResetLastUpdate(); g.fm.SendMessages(pfsShip->GetPlayer()->GetConnection(), FM_GUARANTEED, FM_DONT_FLUSH); } } g.fm.SendMessages(GetConnection(), FM_GUARANTEED, FM_FLUSH); } } else if (bViewOnly) { IstationIGC* pstation = GetIGCShip()->GetStation(); assert (pstation); CFSCluster* pfsCluster = (CFSCluster*)(pstation->GetCluster()->GetPrivateData()); SetDPGroup(pfsCluster, false); } else SetDPGroup(NULL, false); }