bool CDockingPorts::RequestDock (CSpaceObject *pOwner, CSpaceObject *pObj, int iPort) // RequestDock // // RequestDock { // If the requested dock is full, then we fail. if (iPort != -1 && m_pPort[iPort].iStatus != psEmpty) { pObj->SendMessage(pOwner, CONSTLIT("Docking port no longer available")); return false; } // Get the nearest free port int iEmptyPortsLeft; if (iPort == -1) iPort = FindNearestEmptyPort(pOwner, pObj, NULL, &iEmptyPortsLeft); else // If the caller specifies a port then it must be the player, so we // don't worry about leaving an empty port. iEmptyPortsLeft = 2; // If we could not find a free port then deny docking service if (iPort == -1) { pObj->SendMessage(pOwner, CONSTLIT("No docking ports available")); return false; } // If the requester is not the player and there is only one port left, then // fail (we always reserve one port for the player). // // [We also make an exception for any ship that the player is escorting.] CSpaceObject *pPlayer = g_pUniverse->GetPlayer(); if (iEmptyPortsLeft < 2 && pPlayer && pObj != pPlayer && pObj != pPlayer->GetDestination()) { pObj->SendMessage(pOwner, CONSTLIT("No docking ports available")); return false; } // Commence docking pObj->SendMessage(pOwner, CONSTLIT("Docking sequence engaged")); pObj->FreezeControls(); m_pPort[iPort].iStatus = psDocking; m_pPort[iPort].pObj = pObj; // Done return true; }
bool CDockingPorts::ShipsNearPort (CSpaceObject *pOwner, CSpaceObject *pRequestingObj, const CVector &vPortPos) // ShipsNearPort // // Returns TRUE if there are ships near the given port { int i; CSystem *pSystem = pOwner->GetSystem(); for (i = 0; i < pSystem->GetObjectCount(); i++) { CSpaceObject *pObj = pSystem->GetObject(i); if (pObj && pObj->GetCategory() == CSpaceObject::catShip && !pObj->IsInactive() && pObj != pRequestingObj) { Metric rDist2 = (pObj->GetPos() - vPortPos).Length2(); if (rDist2 < MIN_PORT_DISTANCE2 && !IsDockedOrDocking(pObj)) return true; } } return false; }
bool CMission::SetFailure (ICCItem *pData) // SetFailure // // Mission failed { // Must be in the right state if (m_iStatus != statusAccepted && m_iStatus != statusClosed && m_iStatus != statusOpen) return false; // Stop the mission if (m_iStatus != statusOpen) { FireOnStop(REASON_FAILURE, pData); CSpaceObject *pOwner = m_pOwner.GetObj(); if (pOwner) pOwner->FireOnMissionCompleted(this, REASON_FAILURE); } // Done CompleteMission(completeFailure); return true; }
bool CMission::SetSuccess (ICCItem *pData) // SetSuccess // // Mission succeeded { // Must be in the right state if (m_iStatus != statusAccepted && m_iStatus != statusClosed && m_iStatus != statusOpen) return false; // Stop the mission if (m_iStatus != statusOpen) { FireOnStop(REASON_SUCCESS, pData); CSpaceObject *pOwner = m_pOwner.GetObj(); if (pOwner) pOwner->FireOnMissionCompleted(this, REASON_SUCCESS); } // Done CompleteMission(completeSuccess); return true; }
void CMission::OnDestroyed (SDestroyCtx &Ctx) // OnDestroyed // // Mission is destroyed { if (m_fInOnCreate) return; // If the mission is running then we need to stop if (m_iStatus == statusClosed || m_iStatus == statusAccepted) { FireOnStop(REASON_DESTROYED, NULL); CSpaceObject *pOwner = m_pOwner.GetObj(); if (pOwner) pOwner->FireOnMissionCompleted(this, REASON_DESTROYED); } // Make sure the mission is completed CompleteMission(completeDestroyed); // Destroy the mission FireOnDestroy(Ctx); }
void CSovereign::InitEnemyObjectList (CSystem *pSystem) // InitEnemyObjectList // // Compiles and caches a list of enemy objects in the system { int i; if (m_pEnemyObjectsSystem != pSystem) { m_EnemyObjects.RemoveAll(); for (i = 0; i < pSystem->GetObjectCount(); i++) { CSpaceObject *pObj = pSystem->GetObject(i); if (pObj && pObj->ClassCanAttack() && IsEnemy(pObj->GetSovereign())) m_EnemyObjects.FastAdd(pObj); } m_pEnemyObjectsSystem = pSystem; } }
void CSpaceObjectList::NotifyOnObjDocked (CSpaceObject *pDockingObj, CSpaceObject *pDockTarget) // NotifyOnObjDocked // // Notify that an object docked. { int i; if (GetCount() > 0) { TArray<CSpaceObject *> List(m_List); for (i = 0; i < List.GetCount(); i++) { CSpaceObject *pObj = List[i]; // NOTE: We do not notify the dock target because it got notified // separately. if (!pObj->IsDestroyed() && pObj != pDockTarget && pObj->HasOnObjDockedEvent()) pObj->FireOnObjDocked(pDockingObj, pDockTarget); } } }
void AddSystemData (CSystem *pSystem, bool bAll, SNodeDesc *retResult) { int i; // Loop over all objects for (i = 0; i < pSystem->GetObjectCount(); i++) { CStationType *pType; CSpaceObject *pObj = pSystem->GetObject(i); if (pObj == NULL || pObj->IsDestroyed() || (pType = pObj->GetEncounterInfo()) == NULL) continue; // Skip if we're not interested in this encounter if (!bAll && !pType->CanBeEncounteredRandomly()) continue; // Get table CCountTable *pTable = retResult->Table.SetAt(pSystem->GetType()->GetUNID()); // Add to count bool bNew; int *pCount = pTable->SetAt(pType->GetUNID(), &bNew); if (bNew) *pCount = 1; else *pCount += 1; } }
bool CDeviceClass::AccumulateEnhancements (CItemCtx &Device, CInstalledDevice *pTarget, TArray<CString> &EnhancementIDs, CItemEnhancementStack *pEnhancements) // AccumulateEnhancements // // If this device can enhance pTarget, then we add to the list of enhancements. { int i; bool bEnhanced = false; CInstalledDevice *pDevice = Device.GetDevice(); CSpaceObject *pSource = Device.GetSource(); // See if we can enhance the target device if (pDevice == NULL || (pDevice->IsEnabled() && !pDevice->IsDamaged())) { for (i = 0; i < m_Enhancements.GetCount(); i++) { // If this type of enhancement has already been applied, skip it if (!m_Enhancements[i].sType.IsBlank() && EnhancementIDs.Find(m_Enhancements[i].sType)) continue; // If we don't match the criteria, skip it. if (pSource && pTarget && !pSource->GetItemForDevice(pTarget).MatchesCriteria(m_Enhancements[i].Criteria)) continue; // Add the enhancement pEnhancements->Insert(m_Enhancements[i].Enhancement); bEnhanced = true; // Remember that we added this enhancement class if (!m_Enhancements[i].sType.IsBlank()) EnhancementIDs.Insert(m_Enhancements[i].sType); } } // Let sub-classes add their own if (OnAccumulateEnhancements(Device, pTarget, EnhancementIDs, pEnhancements)) bEnhanced = true; // Done return bEnhanced; }
bool CFerianShipAI::InRangeOfThreat (CSpaceObject **retpThreat) // InRangeOfThreat // // Returns the nearest threat { if (m_pShip->IsDestinyTime(19)) { CSystem *pSystem = m_pShip->GetSystem(); int iDestiny = m_pShip->GetDestiny(); // Get the list of objects that intersect the object SSpaceObjectGridEnumerator i; pSystem->EnumObjectsInBoxStart(i, m_pShip->GetPos(), MAX_THREAT_DIST); // Loop over all objects Metric rNearestDist2 = MAX_THREAT_DIST * MAX_THREAT_DIST2; CSpaceObject *pNearestObj = NULL; while (pSystem->EnumObjectsInBoxHasMore(i)) { CSpaceObject *pObj = pSystem->EnumObjectsInBoxGetNext(i); // If the object is in the bounding box then remember // it so that we can do a more accurate calculation. if (pObj->GetCategory() == CSpaceObject::catShip && (!m_pShip->IsFriend(pObj) || pObj->GetDestiny() < iDestiny) && pObj->CanAttack()) { Metric rDist2 = m_pShip->GetDistance2(pObj); if (rDist2 < rNearestDist2) { pNearestObj = pObj; rNearestDist2 = rDist2; } } } // Done if (pNearestObj) { *retpThreat = pNearestObj; return true; } } return false; }
bool CWeaponFireDesc::FireOnFragment (const CDamageSource &Source, CSpaceObject *pShot, const CVector &vHitPos, CSpaceObject *pNearestObj, CSpaceObject *pTarget) // FireOnFragment // // Event fires when a shot fragments. If we return TRUE then we skip the default // fragmentation event. { SEventHandlerDesc Event; if (FindEventHandler(evtOnFragment, &Event)) { // Setup arguments CCodeChainCtx CCCtx; CCCtx.SaveAndDefineSourceVar(pShot); CCCtx.DefineSpaceObject(CONSTLIT("aNearestObj"), pNearestObj); CCCtx.DefineSpaceObject(CONSTLIT("aTargetObj"), pTarget); CCCtx.DefineVector(CONSTLIT("aHitPos"), vHitPos); CCCtx.DefineInteger(CONSTLIT("aHitDir"), (pShot ? pShot->GetRotation() : 0)); CCCtx.DefineItemType(CONSTLIT("aWeaponType"), GetWeaponType()); CCCtx.DefineString(CONSTLIT("aWeaponFragment"), m_sUNID); CSpaceObject *pAttacker = Source.GetObj(); CCCtx.DefineSpaceObject(CONSTLIT("aCause"), pShot); CCCtx.DefineSpaceObject(CONSTLIT("aAttacker"), pAttacker); CCCtx.DefineSpaceObject(CONSTLIT("aOrderGiver"), (pAttacker ? pAttacker->GetOrderGiver(Source.GetCause()) : NULL)); ICCItem *pResult = CCCtx.Run(Event); if (pResult->IsError()) pShot->ReportEventError(ON_FRAGMENT_EVENT, pResult); // If we return Nil, then we continue processing bool bResult; if (pResult->IsNil()) bResult = false; // Otherwise, we skip fragmentation else bResult = true; CCCtx.Discard(pResult); return bResult; } else return false; }
int GetValidObjCount (CSystem *pSystem) { int i; int iCount = 0; for (i = 0; i < pSystem->GetObjectCount(); i++) { CSpaceObject *pObj = pSystem->GetObject(i); if (pObj && !pObj->IsDestroyed()) iCount++; } return iCount; }
//----------------------------------------------------------------------------- // Проверяем все объекты, обновляем данные //----------------------------------------------------------------------------- void UpdateAllSpaceObject(float Time) { CSpaceObject *tmp = StartSpaceObject; while (tmp!=0) { CSpaceObject *tmp2 = tmp->Next; // делаем обновление данных по объекту if (!tmp->Update(Time)) { // если его нужно уничтожить - делаем это delete tmp; tmp = 0; } tmp = tmp2; } }
//----------------------------------------------------------------------------- // Прорисовываем все объекты //----------------------------------------------------------------------------- void DrawAllSpaceObject(bool VertexOnlyPass, unsigned int ShadowMap) { CSpaceObject *tmp = StartSpaceObject; while (tmp!=0) { CSpaceObject *tmp2 = tmp->Next; // планеты и астероиды рисуем до тайловой анимации в игре!!! if (tmp->ObjectType != 14 && !(tmp->ObjectType == 15 && (tmp->ObjectCreationType>10 && tmp->ObjectCreationType<20))) tmp->Draw(VertexOnlyPass, ShadowMap); tmp = tmp2; } }
CSpaceObject *CFerianShipAI::FindRandomAsteroid (void) // FindRandomAsteroid // // Returns a random asteroid within 60 light-seconds { int i; Metric rMaxDist2 = MAX_MINING_RANGE2; Metric rCloseDist2 = CLOSE_MINING_RANGE2; CSpaceObject *Table[MAX_RANDOM_COUNT]; int iCount = 0; for (i = 0; (i < m_pShip->GetSystem()->GetObjectCount() && iCount < MAX_RANDOM_COUNT); i++) { CSpaceObject *pObj = m_pShip->GetSystem()->GetObject(i); if (pObj && pObj->HasAttribute(ATTRIBUTE_ASTEROID)) { CVector vRange = pObj->GetPos() - m_pShip->GetPos(); Metric rDistance2 = vRange.Dot(vRange); // If we're within the max dist, add it to the list if (rDistance2 < rMaxDist2) Table[iCount++] = pObj; // If we're within 10 light-seconds, add it twice more (to increase // the probability) if (rDistance2 < rCloseDist2) { Table[iCount++] = pObj; Table[iCount++] = pObj; } } } // Pick a random entry from the list if (iCount == 0) return NULL; else return Table[mathRandom(0, iCount-1)]; }
bool CNavigationPath::PathIsClear (CSystem *pSystem, CSovereign *pSovereign, const CVector &vFrom, const CVector &vTo, CSpaceObject **retpEnemy, CVector *retvAway) // PathIsClear // // Returns TRUE if the path from vFrom to vTo is free from enemy stations. // If FALSE, retpEnemy is initialized with the enemy that is blocking the // path and retvAway is a unit vector away from the enemy that avoids it { int i; // Loop over all objects in the system CSpaceObject *pNearestEnemy = NULL; Metric rNearestDist = MAX_SAFE_DIST; CVector vNearestAway; for (i = 0; i < pSystem->GetObjectCount(); i++) { CSpaceObject *pObj = pSystem->GetObject(i); CSovereign *pObjSovereign; if (pObj && (pObj->GetScale() == scaleStructure || ((pObj->GetScale() == scaleShip) && (pObj->GetVel().Length2() < MIN_SPEED2))) && (pObjSovereign = pObj->GetSovereign()) && (pObjSovereign->IsEnemy(pSovereign)) && pObj->CanAttack()) { CVector vAway; Metric rDist = CalcDistanceToPath(pObj->GetPos(), vFrom, vTo, NULL, &vAway); if (rDist < rNearestDist) { rNearestDist = rDist; pNearestEnemy = pObj; vNearestAway = vAway; } } } // If we found a threatening object, return it if (pNearestEnemy) { if (retpEnemy) *retpEnemy = pNearestEnemy; if (retvAway) *retvAway = vNearestAway; return false; } // Otherwise, the path is OK return true; }
void CGalacticMapSession::OnPaint (CG32bitImage &Screen, const RECT &rcInvalid) // OnPaint // // Paint { int cxScreen = Screen.GetWidth(); int cyScreen = Screen.GetHeight(); const CVisualPalette &VI = m_HI.GetVisuals(); CG32bitPixel rgbBackgroundColor = VI.GetColor(colorAreaDeep); CG32bitPixel rgbLineColor = VI.GetColor(colorLineFrame); const CG16bitFont &HeaderFont = VI.GetFont(fontHeader); const CG16bitFont &MediumFont = VI.GetFont(fontMedium); // Paint the actual map if (m_pPainter) { m_pPainter->Paint(Screen); // Paint the ship CSpaceObject *pPlayer = g_pUniverse->GetPlayerShip(); if (pPlayer) { int xPos, yPos; g_pUniverse->GetCurrentSystem()->GetTopology()->GetDisplayPos(&xPos, &yPos); int xShip, yShip; m_pPainter->GalacticToView(xPos, yPos, m_xCenter, m_yCenter, m_Scale.GetScale(), &xShip, &yShip); pPlayer->PaintMap(CMapViewportCtx(), Screen, xShip, yShip); } } // Paint some help text m_HelpPainter.Paint(Screen, m_rcView.left + SCREEN_BORDER_X, m_rcView.bottom - (SCREEN_BORDER_Y + m_HelpPainter.GetHeight())); }
void CSpaceObjectList::RemoveSystemObjs (void) // RemoveSystemObjs // // Remove objects that are part of the current system. { int i; for (i = 0; i < m_List.GetCount(); i++) { CSpaceObject *pObj = m_List[i]; if (!pObj->IsNonSystemObj()) { Remove(i); i--; } } }
void CDamageSource::SetObj (CSpaceObject *pSource) // SetObj // // Sets the damage source { // If this is the player, remember it in case we lose the // source later. if (pSource) { CSpaceObject *pOrderGiver; if (pSource->IsPlayer()) { m_dwFlags |= FLAG_IS_PLAYER; m_dwFlags |= FLAG_IS_PLAYER_CAUSED; } else if ((pOrderGiver = pSource->GetOrderGiver()) && pOrderGiver->IsPlayer()) { m_dwFlags |= FLAG_IS_PLAYER_SUBORDINATE; m_dwFlags |= FLAG_IS_PLAYER_CAUSED; } } else m_dwFlags &= ~(FLAG_IS_PLAYER | FLAG_IS_PLAYER_SUBORDINATE | FLAG_IS_PLAYER_CAUSED); // If the source is already destroyed, then don't store it--just get the // name of the source. if (pSource && pSource->IsDestroyed()) { m_sSourceName = pSource->GetName(&m_dwSourceNameFlags); m_pSource = NULL; } // Otherwise, remember the source else m_pSource = pSource; }
void AccumulateSystem (CTopologyNode *pNode, CSystem *pSystem, TSortMap<DWORD, STypeInfo> &AllTypes) { int j; int iSystemLevel = pSystem->GetLevel(); // Add the encounters to the appropriate tables for (j = 0; j < pSystem->GetObjectCount(); j++) { CSpaceObject *pObj = pSystem->GetObject(j); if (pObj) { // Add this encounter to the table CDesignType *pType; if ((pType = pObj->GetEncounterInfo()) || (pType = pObj->GetType())) { STypeInfo *pInfo = AllTypes.SetAt(pType->GetUNID()); pInfo->iTotalCount++; pInfo->PerLevel[iSystemLevel]++; } // Enumerate the items in this object CItemListManipulator ItemList(pObj->GetItemList()); ItemList.ResetCursor(); while (ItemList.MoveCursorForward()) { const CItem &Item(ItemList.GetItemAtCursor()); if (!Item.IsInstalled() && !Item.IsDamaged()) { STypeInfo *pInfo = AllTypes.SetAt(Item.GetType()->GetUNID()); pInfo->iTotalCount += Item.GetCount(); pInfo->PerLevel[iSystemLevel] += Item.GetCount(); } } } } }
CVector CreateVectorFromList (CCodeChain &CC, ICCItem *pList) // CreateVectorFromList // // Creates a vector from a code chain list { CVector vVec; if (pList->IsList()) CreateBinaryFromList(CC, pList, &vVec); else if (pList->IsInteger()) { CSpaceObject *pObj = CreateObjFromItem(CC, pList); if (pObj) vVec = pObj->GetPos(); } return vVec; }
void CSpaceObjectList::NotifyOnObjEnteredGate (CSpaceObject *pGatingObj, CTopologyNode *pDestNode, const CString &sDestEntryPoint, CSpaceObject *pStargate) // NotifyOnObjEnteredGate // // Notify all objects in the list that the given object has entered a stargate. { int i; if (GetCount() > 0) { TArray<CSpaceObject *> List(m_List); for (i = 0; i < List.GetCount(); i++) { CSpaceObject *pObj = List[i]; if (!pObj->IsDestroyed()) pObj->FireOnObjEnteredGate(pGatingObj, pDestNode, sDestEntryPoint, pStargate); } } }
void CSpaceObjectList::NotifyOnPlayerBlacklisted (CSpaceObject *pBlacklistingObj) // NotifyOnPlayerBlacklisted // // Notify all objects that the player was blacklisted { int i; if (GetCount() > 0) { TArray<CSpaceObject *> List(m_List); for (i = 0; i < List.GetCount(); i++) { CSpaceObject *pObj = List[i]; if (!pObj->IsDestroyed()) pObj->FireOnObjBlacklistedPlayer(pBlacklistingObj); } } }
void CSpaceObjectList::NotifyOnObjReconned (CSpaceObject *pReconnedObj) // NotifyOnObjReconned // // Notify that an object was reconned { int i; if (GetCount() > 0) { TArray<CSpaceObject *> List(m_List); for (i = 0; i < List.GetCount(); i++) { CSpaceObject *pObj = List[i]; if (!pObj->IsDestroyed()) pObj->FireOnObjReconned(pReconnedObj); } } }
void CTranscendenceWnd::DestroyIntroShips (void) // DestroyIntroShips // // Destroys all ships of the same class as the POV { int i; CShip *pShip = g_pUniverse->GetPOV()->AsShip(); if (pShip == NULL) return; // Destroy all ships of the current class CSystem *pSystem = pShip->GetSystem(); CShipClass *pClassToDestroy = pShip->GetClass(); TArray<CSpaceObject *> ShipsToDestroy; CSpaceObject *pOtherShip = NULL; for (i = 0; i < pSystem->GetObjectCount(); i++) { CSpaceObject *pObj = pSystem->GetObject(i); CShip *pShip; if (pObj && !pObj->IsInactive() && !pObj->IsVirtual() && (pShip = pObj->AsShip())) { if (pShip->GetClass() == pClassToDestroy) ShipsToDestroy.Insert(pObj); else if (pOtherShip == NULL) pOtherShip = pObj; } } // Destroy ships for (i = 0; i < ShipsToDestroy.GetCount(); i++) ShipsToDestroy[i]->Destroy(removedFromSystem, CDamageSource()); }
void CAutoDefenseClass::Update (CInstalledDevice *pDevice, CSpaceObject *pSource, int iTick, bool *retbSourceDestroyed, bool *retbConsumedItems) // Update // // Update device { if (pDevice->IsReady() && pDevice->IsEnabled()) { int i; // Look for a target CSpaceObject *pBestTarget = NULL; Metric rBestDist2 = MAX_INTERCEPT_DISTANCE * MAX_INTERCEPT_DISTANCE; for (i = 0; i < pSource->GetSystem()->GetObjectCount(); i++) { CSpaceObject *pObj = pSource->GetSystem()->GetObject(i); if (pObj && pObj->GetCategory() == CSpaceObject::catMissile && pObj->GetSource() != pSource && (pObj->GetSource() == NULL || pSource->IsEnemy(pObj->GetSource()))) { CVector vRange = pObj->GetPos() - pSource->GetPos(); Metric rDistance2 = vRange.Dot(vRange); if (rDistance2 < rBestDist2) { pBestTarget = pObj; rBestDist2 = rDistance2; } } } // If we found a target, try to shoot at it if (pBestTarget) { CDeviceClass *pWeapon = GetWeapon(); if (pWeapon) { int iFireAngle; if (pWeapon->IsWeaponAligned(pSource, pDevice, pBestTarget, &iFireAngle)) { pDevice->SetFireAngle(iFireAngle); pWeapon->Activate(pDevice, pSource, pBestTarget, iFireAngle, retbSourceDestroyed, retbConsumedItems); pDevice->SetActivationDelay(m_iRechargeTicks); } } } } }
bool CMission::SetAccepted (void) // SetAccepted // // Player accepts a mission { // Must be available to player. if (m_iStatus != statusOpen) return false; // Player accepts the mission FireOnAccepted(); CSpaceObject *pOwner = m_pOwner.GetObj(); if (pOwner) pOwner->FireOnMissionAccepted(this); // If the above call changed anything, then we're done if (m_iStatus != statusOpen) return false; // Player has accepted m_iStatus = statusAccepted; // Start the mission FireOnStart(); // Set the player target FireOnSetPlayerTarget(REASON_ACCEPTED); return true; }
void CSpaceObjectList::NotifyOnObjDestroyed (SDestroyCtx &Ctx) // NotifyOnObjDestroyed // // Notify all objects in the list that another object was destroyed. { int i; if (GetCount() > 0) { // We make a copy of our list because an event might remove an object // from our list. TArray<CSpaceObject *> List(m_List); for (i = 0; i < List.GetCount(); i++) { CSpaceObject *pObj = List[i]; if (!pObj->IsDestroyed()) pObj->OnObjDestroyedNotify(Ctx); } } }
CSpaceObject *CDamageSource::GetObj (void) const // GetObj // // Returns the source object { CSpaceObject *pOrderGiver; // If the source is the player then always return the player // object (regardless of m_pSource). We do this in case // the player changes ships. if (m_dwFlags & FLAG_IS_PLAYER) { CSystem *pSystem = g_pUniverse->GetCurrentSystem(); return (pSystem ? pSystem->GetPlayer() : NULL); } // Otherwise, if we're a subordinate and our order giver // has changed, switch back to the player. else if ((m_dwFlags & FLAG_IS_PLAYER_SUBORDINATE) && (m_pSource == NULL || (pOrderGiver = m_pSource->GetOrderGiver()) == NULL || !pOrderGiver->IsPlayer())) { CSystem *pSystem = g_pUniverse->GetCurrentSystem(); return (pSystem ? pSystem->GetPlayer() : NULL); } // Otherwise, return the source (even if NULL) else return m_pSource; }
void DoTradeSim (CUniverse &Universe, CXMLElement *pCmdLine) { ALERROR error; int i, j; CSovereign *pPlayer = Universe.FindSovereign(g_PlayerSovereignUNID); int iSystemSample = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("count"), 1, -1, 1); bool bLogo = !pCmdLine->GetAttributeBool(NO_LOGO_SWITCH); // For each station type we keep track of the items that it sells and the // various prices that each instances charges. SStationData AllStations; // For each item type we keep track of the stations that sell and/or // buy it. SItemData AllItems; // Generate systems for multiple games for (i = 0; i < iSystemSample; i++) { if (bLogo) printf("pass %d...\n", i+1); CTopologyNode *pNode = Universe.GetFirstTopologyNode(); while (true) { // Create the system CSystem *pSystem; if (error = Universe.CreateStarSystem(pNode, &pSystem)) { printf("ERROR: Unable to create star system.\n"); return; } // For all active stations in the system, get their trading information for (j = 0; j < pSystem->GetObjectCount(); j++) { CSpaceObject *pObj = pSystem->GetObject(j); if (pObj && pObj->GetCategory() == CSpaceObject::catStation) CompileTradeData(pObj, &AllStations, &AllItems); } // Get the next node CString sEntryPoint; pNode = pSystem->GetStargateDestination(CONSTLIT("Outbound"), &sEntryPoint); if (pNode == NULL || pNode->IsEndGame()) break; // Done with old system Universe.DestroySystem(pSystem); } Universe.Reinit(); } if (bLogo) printf("FINAL STATISTICS\n\n"); // Loop over each item and output the best trading strategy printf("Item\tSeller\tSell Price\tBuyer\tBuy Price\tProfit\n"); for (i = 0; i < AllItems.GetCount(); i++) { ComputeAverages(&AllItems[i]); OutputTradingStrategy(AllItems[i]); } }