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 CSystemManager::CheckFamine(const CSystem& system) { const int food_prod = system.GetProduction()->GetFoodProd(); if(food_prod >= 0) return false; const int food_store = system.GetFoodStore(); return food_store + food_prod < 0; }
void Finish() const { AssertBotE(m_WorkersLeftToSet >= 0); #ifdef CONSISTENCY_CHECKS AssertBotE(m_pSystem->SanityCheckWorkers()); #endif m_pSystem->CalculateVariables(); }
//puts an additional worker into industry, to prevent not finishing the project because //industry prod decreased due to loss of moral void SafeMoral() { const CAssemblyList& assembly_list = *m_pSystem->GetAssemblyList(); AssertBotE(m_WorkersLeftToSet >= 0); if(assembly_list.IsEmpty() || m_WorkersLeftToSet == 0) return; const int max_buildings = m_pSystem->GetNumberOfWorkbuildings(WORKER::INDUSTRY_WORKER, 0); if(m_pSystem->GetWorker(WORKER::INDUSTRY_WORKER) < max_buildings) SetWorker(WORKER::INDUSTRY_WORKER, CSystem::SET_WORKER_MODE_INCREMENT); }
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; }
//fills all remaining empty buildings of the given cathegory, only considering available workers and buildings bool FillRemainingSlots(WORKER::Typ type) { AssertBotE(m_WorkersLeftToSet >= 0); if(m_WorkersLeftToSet == 0) return false; m_WorkersLeftToSet += m_pSystem->GetWorker(type); m_pSystem->SetWorker(type, CSystem::SET_WORKER_MODE_SET, 0); const int buildings = m_pSystem->GetNumberOfWorkbuildings(type, 0); const int to_set = min(buildings, m_WorkersLeftToSet); SetWorker(type, CSystem::SET_WORKER_MODE_SET,to_set); return true; }
void CPlayerGameStats::OnKeyEvent (EEventTypes iType, CSpaceObject *pObj, DWORD dwCauseUNID) // OnKeyEvent // // Adds a key event involving an object { ASSERT(pObj); CSystem *pSystem = pObj->GetSystem(); if (pSystem == NULL) return; // Get the NodeID where the event happened CTopologyNode *pNode = pSystem->GetTopology(); if (pNode == NULL) return; const CString &sNodeID = pNode->GetID(); // Get the object's type CDesignType *pType = pObj->GetType(); if (pType == NULL) return; // Get the object's name DWORD dwNameFlags; CString sName = pObj->GetName(&dwNameFlags); // If the object name is the same as the type name then we don't bother // storing it in the event (to save memory) if (strEquals(sName, pType->GetTypeName())) { sName = NULL_STR; dwNameFlags = 0; } // Look for the list of events for this NodeID TArray<SKeyEventStats> *pEventList = m_KeyEventStats.Set(sNodeID); SKeyEventStats *pStats = pEventList->Insert(); pStats->iType = iType; pStats->dwTime = g_pUniverse->GetTicks(); pStats->dwObjUNID = pObj->GetType()->GetUNID(); pStats->sObjName = sName; pStats->dwObjNameFlags = dwNameFlags; pStats->dwCauseUNID = dwCauseUNID; }
int main(void) { int testCase = 0; // 测试用例数 cin >> testCase; for(int t = 0; t < testCase; t++) { int eqNum = 0; // 设备数 cin >> eqNum; CSystem* cSystem = new CSystem(eqNum); cSystem->init(); // 初始化路由系统参数 cSystem->solve(); // 使用DP计算路由系统各种设备组合下的性价比 cSystem->print(); // 打印结果(最优性价比) delete cSystem; } return 0; }
//removes workers from factories until they are the minimum number to finish the current project //in still the same number of turns (as at the start of the function) int DecrementDueToWastedIndustry(bool max_industry) { m_pSystem->CalculateVariables(); const CAssemblyList& assembly_list = *m_pSystem->GetAssemblyList(); int unset = 0; if(assembly_list.IsEmpty() || assembly_list.GetWasBuildingBought()) return unset; const int min_rounds = m_pSystem->NeededRoundsToBuild(0, true); AssertBotE(min_rounds >= 1); if(max_industry && min_rounds > 1 || m_pSystem->GetWorker(WORKER::INDUSTRY_WORKER) == 0) return unset; while(true) { SetWorker(WORKER::INDUSTRY_WORKER, CSystem::SET_WORKER_MODE_DECREMENT); ++unset; m_pSystem->CalculateVariables(); const int current_rounds = m_pSystem->NeededRoundsToBuild(0, true, false); if(m_pSystem->GetWorker(WORKER::INDUSTRY_WORKER) == 0) { if(min_rounds < current_rounds) OnBestIndustryWorkerCountFound(unset); return unset; } if(min_rounds < current_rounds) { OnBestIndustryWorkerCountFound(unset); return unset; } } }
bool CheckShips(const std::map<CString, CShipMap>& ships) const { const int scan_power = m_pSystem->GetScanPower(m_pSystem->OwnerID(), true); for(std::map<CString, CShipMap>::const_iterator race = ships.begin(); race != ships.end(); ++race) for(CShipMap::const_iterator ship = race->second.begin(); ship != race->second.end(); ++ship) { if(ship->second->GetTorpedoWeapons()->IsEmpty()) { const boost::shared_ptr<CMajor> owner = boost::dynamic_pointer_cast<CMajor>(ship->second->Owner()); if(owner && !owner->IsHumanPlayer()) continue; } if(!ship->second->GetCloak() && m_pSystem->GetNeededScanPower(ship->second->OwnerID()) <= scan_power) return true; } return false; }
// Actualizar el sistema (emuladores) void CSystem::update(CSystem& p_system){ Gtk::TreeModel::iterator l_iter; CEmulator l_emulator; GELIDE_DEBUG("System " << getName().data() << ": Updating..."); // Intentamos añadir cada uno de los emuladores del sistema for(l_iter = p_system.getEmulatorList()->children().begin(); l_iter != p_system.getEmulatorList()->children().end(); l_iter++){ l_emulator.setId(0); l_emulator.setIconFile((*l_iter)[m_emulator_columns.m_icon_file]); l_emulator.setName((*l_iter)[m_emulator_columns.m_name]); l_emulator.setDescription((*l_iter)[m_emulator_columns.m_description]); l_emulator.setVersion((*l_iter)[m_emulator_columns.m_version]); l_emulator.setAuthor((*l_iter)[m_emulator_columns.m_author]); l_emulator.setHomepage((*l_iter)[m_emulator_columns.m_homepage]); l_emulator.setPath((*l_iter)[m_emulator_columns.m_path]); l_emulator.setParams((*l_iter)[m_emulator_columns.m_params]); addEmulator(l_emulator); } }
//Indreases workers in cathegories energy and food until we produce enough to suffice for the consumption we have bool IncreaseWorkersUntilSufficient(WORKER::Typ type, bool allow_insufficient) { AssertBotE(type == WORKER::ENERGY_WORKER || type == WORKER::FOOD_WORKER); if(m_pSystem->GetDisabledProductions()[type]) return true; while(true) { const int value = (type == WORKER::ENERGY_WORKER) ? m_pProd->GetEnergyProd() : m_pProd->GetFoodProd(); if(value >= 0) return true; if(m_WorkersLeftToSet <= 0) return allow_insufficient; const int number_of_buildings = m_pSystem->GetNumberOfWorkbuildings(type, 0); const int workers_set = m_pSystem->GetWorker(type); AssertBotE(workers_set <= number_of_buildings); if(workers_set == number_of_buildings) return allow_insufficient; SetWorker(type, CSystem::SET_WORKER_MODE_INCREMENT); m_pSystem->CalculateVariables(); } }
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()); }
//worker setting function which makes according changes to m_WorkersLeftToSet, tracking how many //we still have to distribute at all void SetWorker(WORKER::Typ type, CSystem::SetWorkerMode mode, int value = -1) { if(mode == CSystem::SET_WORKER_MODE_INCREMENT) { AssertBotE(value == -1); m_pSystem->SetWorker(type, mode); --m_WorkersLeftToSet; } else if(mode == CSystem::SET_WORKER_MODE_DECREMENT) { AssertBotE(value == -1); m_pSystem->SetWorker(type, mode); ++m_WorkersLeftToSet; } else if(mode == CSystem::SET_WORKER_MODE_SET) { AssertBotE(value >= 0); m_pSystem->SetWorker(type, mode, value); m_WorkersLeftToSet -= value; } AssertBotE(m_WorkersLeftToSet >= 0); }
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow) { #if _DEBUG AllocConsole(); freopen("CONOUT$", "w", stdout); #endif CSystem system; // 초기화에 실패하면? if (!(system.Init())) system.Release(); // 루프 if (DataManager->bIsGameRun) system.MessageLoop(); // 초기화 system.Release(); }
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; }
//distributes workers onto priorities remaining after max priorities have been processed //workers that cannot be set because of number of buildings are tried to be set into //the cathegory with next less workers void DoPriorities(const std::map<WORKER::Typ, int>& priorities, bool max_industry, bool safe_moral) { SafeMoralWorkerReserve reserve(*this, safe_moral); std::map<WORKER::Typ, int> prios(priorities); DoMaxPriorities(prios, max_industry); DefaultDistributionCalculator decalc(m_WorkersLeftToSet, prios); const std::vector<DistributionElem>& result = decalc.Calc(); int failed_to_set = 0; for(std::vector<DistributionElem>::const_iterator it = result.begin(); it != result.end(); ++it) { const int buildings = m_pSystem->GetNumberOfWorkbuildings(it->m_Type, 0); if(buildings >= it->m_iCount) { int try_set = it->m_iCount; if(it->m_Type != WORKER::INDUSTRY_WORKER) try_set += failed_to_set; if(buildings >= try_set) { if(it->m_Type != WORKER::INDUSTRY_WORKER) failed_to_set = 0; SetWorker(it->m_Type, CSystem::SET_WORKER_MODE_SET, try_set); } else { if(it->m_Type != WORKER::INDUSTRY_WORKER) failed_to_set -= buildings -it->m_iCount; SetWorker(it->m_Type, CSystem::SET_WORKER_MODE_SET, buildings); } } else { failed_to_set += it->m_iCount - buildings; SetWorker(it->m_Type, CSystem::SET_WORKER_MODE_SET, buildings); } AssertBotE(m_WorkersLeftToSet >= 0 && failed_to_set >= 0); failed_to_set += DecrementDueToFullStore(it->m_Type); if(it->m_Type == WORKER::INDUSTRY_WORKER) { failed_to_set += DecrementDueToWastedIndustry(max_industry); } } }
//removes workers from a cathegory which has a store until production + store <= store, //so that nothing will be wasted on next turn change int DecrementDueToFullStore(WORKER::Typ type) { int unset = 0; if(!m_pSystem->HasStore(type)) return unset; const int store = m_pSystem->GetResourceStore(type); while(true) { const int workers = m_pSystem->GetWorker(type); if(workers == 0) break; m_pSystem->CalculateVariables(); const int prod = m_pSystem->GetProduction()->GetXProd(type); if(store + prod <= m_pSystem->GetXStoreMax(type)) break; SetWorker(type, CSystem::SET_WORKER_MODE_DECREMENT); ++unset; } return unset; }
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]); } }
void GenerateEncounterCount (CUniverse &Universe, CXMLElement *pCmdLine) { int i, j, k, l; // Options int iSystemSample = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("count"), 1, -1, 1); bool bLogo = !pCmdLine->GetAttributeBool(CONSTLIT("noLogo")); bool bAll = pCmdLine->GetAttributeBool(CONSTLIT("all")); // Additional columns TArray<CString> Cols; for (i = 0; i < pCmdLine->GetAttributeCount(); i++) { CString sAttrib = pCmdLine->GetAttributeName(i); if (!IsMainCommandParam(sAttrib) && !strEquals(sAttrib, CONSTLIT("count")) && !strEquals(sAttrib, CONSTLIT("encountercount"))) { CString sValue = pCmdLine->GetAttribute(i); if (!strEquals(sValue, CONSTLIT("true"))) Cols.Insert(strPatternSubst(CONSTLIT("%s:%s"), sAttrib, sValue)); else Cols.Insert(sAttrib); } } // Generate systems for multiple games TSortMap<CString, SNodeDesc> NodeTable; for (i = 0; i < iSystemSample; i++) { if (bLogo) printf("pass %d...\n", i+1); // Initialize the game CString sError; if (Universe.InitGame(0, &sError) != NOERROR) { printf("%s\n", sError.GetASCIIZPointer()); return; } for (j = 0; j < Universe.GetTopologyNodeCount(); j++) { CTopologyNode *pNode = Universe.GetTopologyNode(j); if (pNode->IsEndGame()) continue; // Create the system CSystem *pSystem; if (Universe.CreateStarSystem(pNode, &pSystem) != NOERROR) { printf("ERROR: Unable to create star system.\n"); return; } // Create a sort string for this system CString sSort = strPatternSubst(CONSTLIT("%02d-%s"), pSystem->GetLevel(), pNode->GetID()); // Get the table bool bNew; SNodeDesc *pResult = NodeTable.SetAt(sSort, &bNew); if (bNew) { pResult->iLevel = pNode->GetLevel(); pResult->sNodeID = pNode->GetID(); } // Accumulate data AddSystemData(pSystem, bAll, pResult); // Done with old system Universe.DestroySystem(pSystem); } Universe.Reinit(); } // Header printf("Level\tNode\tSystemType\tCategory\tSovereign\tEncounter\tCount"); for (i = 0; i < Cols.GetCount(); i++) printf("\t%s", Cols[i].GetASCIIZPointer()); printf("\n"); // Output all rows for (i = 0; i < NodeTable.GetCount(); i++) { for (j = 0; j < NodeTable[i].Table.GetCount(); j++) { CCountTable &Encounters = NodeTable[i].Table[j]; for (k = 0; k < Encounters.GetCount(); k++) { int iCount = Encounters[k] / iSystemSample; int iCountFrac = 1000 * (Encounters[k] % iSystemSample) / iSystemSample; CStationType *pEncounterType = Universe.FindStationType(Encounters.GetKey(k)); if (pEncounterType == NULL) continue; CSovereign *pSovereign = pEncounterType->GetControllingSovereign(); CString sSovereign = (pSovereign ? pSovereign->GetTypeName() : CONSTLIT("(Unknown)")); printf("%d\t%s\t0x%08x\t%s\t%s\t%s\t%d.%03d", NodeTable[i].iLevel, NodeTable[i].sNodeID.GetASCIIZPointer(), NodeTable[i].Table.GetKey(j), pEncounterType->GetDataField(CONSTLIT("category")).GetASCIIZPointer(), sSovereign.GetASCIIZPointer(), pEncounterType->GetName().GetASCIIZPointer(), iCount, iCountFrac); for (l = 0; l < Cols.GetCount(); l++) { CString sValue = pEncounterType->GetDataField(Cols[l]); printf("\t%s", sValue.GetASCIIZPointer()); } printf("\n"); } } } }
void GenerateSnapshot (CUniverse &Universe, CXMLElement *pCmdLine) { ALERROR error; int i; // Get some parameters int iInitialUpdateTime = 10; int iUpdateTime = pCmdLine->GetAttributeInteger(CONSTLIT("wait")); // Criteria CString sNode = pCmdLine->GetAttribute(CONSTLIT("node")); CString sCriteria = pCmdLine->GetAttribute(CONSTLIT("criteria")); // Output int cxWidth; int cyHeight; if (pCmdLine->FindAttributeInteger(CONSTLIT("size"), &cxWidth)) { cyHeight = cxWidth; } else { cxWidth = 1024; cyHeight = 1024; } // Paint flags DWORD dwPaintFlags = 0; if (pCmdLine->GetAttributeBool(CONSTLIT("noStars"))) dwPaintFlags |= CSystem::VWP_NO_STAR_FIELD; // Output file CString sFilespec = pCmdLine->GetAttribute(CONSTLIT("output")); if (!sFilespec.IsBlank()) sFilespec = pathAddExtensionIfNecessary(sFilespec, CONSTLIT(".bmp")); // Update context SSystemUpdateCtx Ctx; Ctx.bForceEventFiring = true; Ctx.bForcePainted = true; // Loop over all systems until we find what we're looking for int iLoops = 20; int iNodeIndex = 0; CTopologyNode *pNode = Universe.GetTopologyNode(iNodeIndex); while (true) { // Create the system CSystem *pSystem; if (error = Universe.CreateStarSystem(pNode, &pSystem)) { printf("ERROR: Unable to create star system.\n"); return; } // If this is the node we want, then search CSpaceObject *pTarget; if (sNode.IsBlank() || strEquals(sNode, pNode->GetID())) { printf("Searching %s...\n", pNode->GetSystemName().GetASCIIZPointer()); // Set the POV CSpaceObject *pPOV = pSystem->GetObject(0); Universe.SetPOV(pPOV); pSystem->SetPOVLRS(pPOV); // Prepare system Universe.UpdateExtended(); Universe.GarbageCollectLibraryBitmaps(); // Update for a while for (i = 0; i < iInitialUpdateTime; i++) Universe.Update(Ctx); // Compose the criteria CSpaceObject::Criteria Criteria; CSpaceObject::ParseCriteria(pPOV, sCriteria, &Criteria); // Get the list of all objects in the system that match the criteria CSpaceObject::SCriteriaMatchCtx Ctx(Criteria); TArray<CSpaceObject *> Results; for (i = 0; i < pSystem->GetObjectCount(); i++) { CSpaceObject *pObj = pSystem->GetObject(i); if (pObj && pObj->MatchesCriteria(Ctx, Criteria)) Results.Insert(pObj); } // Pick the appropriate object from the list if (Results.GetCount() == 0) pTarget = NULL; else if (Criteria.bNearestOnly || Criteria.bFarthestOnly) pTarget = Ctx.pBestObj; else pTarget = Results[mathRandom(0, Results.GetCount() - 1)]; } else pTarget = NULL; // If we found the target, then output if (pTarget) { // If we found the target, take a snapshot printf("Found %s.\n", pTarget->GetNounPhrase(0).GetASCIIZPointer()); // Wait a bit for (i = 0; i < iUpdateTime; i++) { if ((i % 100) == 99) printf("."); Universe.Update(Ctx); } if (iUpdateTime >= 99) printf("\n"); // Paint CG16bitImage Output; Output.CreateBlank(cxWidth, cyHeight, false); RECT rcViewport; rcViewport.left = 0; rcViewport.top = 0; rcViewport.right = cxWidth; rcViewport.bottom = cyHeight; pSystem->PaintViewport(Output, rcViewport, pTarget, dwPaintFlags); // Write to file if (!sFilespec.IsBlank()) { CFileWriteStream OutputFile(sFilespec); if (OutputFile.Create() != NOERROR) { printf("ERROR: Unable to create '%s'\n", sFilespec.GetASCIIZPointer()); return; } Output.WriteToWindowsBMP(&OutputFile); OutputFile.Close(); printf("%s\n", sFilespec.GetASCIIZPointer()); } // Otherwise, clipboard else { if (error = Output.CopyToClipboard()) { printf("ERROR: Unable to copy image to clipboard.\n"); return; } printf("Image copied to clipboard.\n"); } // Done break; } // Done with old system Universe.DestroySystem(pSystem); // Loop to the next node do { iNodeIndex = ((iNodeIndex + 1) % Universe.GetTopologyNodeCount()); pNode = Universe.GetTopologyNode(iNodeIndex); } while (pNode == NULL || pNode->IsEndGame()); // If we're back to the first node again, restart if (iNodeIndex == 0) { if (--iLoops > 0) { Universe.Reinit(); iNodeIndex = 0; pNode = Universe.GetTopologyNode(iNodeIndex); } else { printf("ERROR: Specified target could not be found.\n"); return; } } } }
EResults RunEncounter (CUniverse &Universe, CSimViewer &Viewer, CStationType *pDefenderType, CShipClass *pAttackerClass, CSovereign *pAttackerSovereign) { int iTimeOut = DEFAULT_TIME_OUT; // Make sure the universe is clean CString sError; if (Universe.InitGame(0, &sError) != NOERROR) { printf("ERROR: %s", sError.GetASCIIZPointer()); return resultError; } // Create an empty system CSystem *pSystem; if (Universe.CreateEmptyStarSystem(&pSystem) != NOERROR) { printf("ERROR: Unable to create empty star system.\n"); return resultError; } // Create a station in the center of the system CSpaceObject *pStation; if (pSystem->CreateStation(pDefenderType, NULL, CVector(), &pStation) != NOERROR) { printf("ERROR: Unable to create station.\n"); return resultError; } // Set the POV Universe.SetPOV(pStation); pSystem->SetPOVLRS(pStation); // Prepare system Universe.UpdateExtended(); Universe.GarbageCollectLibraryBitmaps(); Universe.StartGame(true); // Now create an attacker some distance away CVector vPos = PolarToVector(mathRandom(0, 359), INITIAL_DISTANCE); CShip *pAttacker; if (pSystem->CreateShip(pAttackerClass->GetUNID(), NULL, NULL, pAttackerSovereign, vPos, CVector(), 0, NULL, NULL, &pAttacker) != NOERROR) { printf("ERROR: Unable to create attacking ship.\n"); return resultError; } // Set the attacker to attack the station IShipController *pController = pAttacker->GetController(); if (pController == NULL) { printf("ERROR: No controller for ship.\n"); return resultError; } pController->AddOrder(IShipController::orderAttackStation, pStation, IShipController::SData()); // Watch the attacker Universe.SetPOV(pAttacker); pSystem->SetPOVLRS(pAttacker); // Update context SSystemUpdateCtx Ctx; Ctx.bForceEventFiring = true; Ctx.bForcePainted = true; // Now keep updating until either the station is destroyed, the ship is destroyed, or we time-out int iTime = 0; int iDestroyedTime = (Viewer.IsEmpty() ? 0 : DESTROY_TIME); bool bDestroyed = false; EResults iResult = resultTimeout; while (iTime < iTimeOut && (!bDestroyed || iDestroyedTime > 0)) { iTime++; Universe.Update(Ctx); if (!Viewer.IsEmpty()) Viewer.PaintViewport(Universe); if (bDestroyed) iDestroyedTime--; else if (pStation->IsDestroyed() || pStation->IsAbandoned()) { bDestroyed = true; iResult = resultDefenderDestroyed; } else if (pAttacker->IsDestroyed()) { bDestroyed = true; iResult = resultAttackerDestroyed; } } // Done return iResult; }
// Funktion löscht einen Eintrag aus der Bauliste, wenn das Gebäude fertig wurde oder wir den ersten // Eintrag manuell löschen möchten. Nach Aufruf dieser Funktion muß unbedingt die Funktion // CalculateVariables() aufgerufen werden. void CAssemblyList::ClearAssemblyList(const CPoint &ko, std::vector<CSystem>& systems) { // Alle prozentualen Anteile eines womöglich früheren Bauauftrages aus den Ressourcenrouten löschen CSystem* system = &systems.at(ko.x+(ko.y)*STARMAP_SECTORS_HCOUNT); CArray<CPoint> routesFrom; ULONG resourcesFromRoutes[DERITIUM + 1]; ULONG nResInDistSys[DERITIUM + 1]; CPoint ptResourceDistributorKOs[DERITIUM + 1]; for (int i = 0; i <= DERITIUM; i++) { resourcesFromRoutes[i] = 0; nResInDistSys[i] = 0; ptResourceDistributorKOs[i] = CPoint(-1,-1); } // Ressourcenrouten durchgehen und womöglich die möglichen max. zusätzlichen Ressourcen erfragen for (int y = 0; y < STARMAP_SECTORS_VCOUNT; y++) { for (int x = 0; x < STARMAP_SECTORS_HCOUNT; x++) { if (systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetOwnerOfSystem() == system->GetOwnerOfSystem() && CPoint(x,y) != ko) { for (int i = 0; i < systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->GetSize(); i++) { if (systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->GetAt(i).GetKO() == ko) { // prozentualen Anteil vom alten Auftrag zurücksetzen systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->ElementAt(i).SetPercent(0); // Ressourcen über Route holen if (systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetBlockade() == NULL && systems.at(ko.x+(ko.y)*STARMAP_SECTORS_HCOUNT).GetBlockade() == NULL) { routesFrom.Add(CPoint(x,y)); BYTE res = systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->GetAt(i).GetResource(); resourcesFromRoutes[res] += systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetResourceStore(res); } } } // gilt nicht bei Blockaden if (systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetBlockade() == NULL && systems.at(ko.x+(ko.y)*STARMAP_SECTORS_HCOUNT).GetBlockade() == NULL) { for (int res = TITAN; res <= DERITIUM; res++) { if (systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetProduction()->GetResourceDistributor(res)) { ptResourceDistributorKOs[res] = CPoint(x,y); nResInDistSys[res] = systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetResourceStore(res); } } } } } } // AssemblyList Eintrag des gebauten Gebäudes/Updates/Schiffes löschen, wenn wir noch den // Eintrag an der nächsten Stelle haben (sprich AssemblyList[1] != 0), dann alle // anderen Einträge um eins nach vorn verschieben -> letzter wird frei m_iEntry[0] = 0; m_iNeededIndustryInAssemblyList[0] = 0; m_iNeededTitanInAssemblyList[0] = 0; m_iNeededDeuteriumInAssemblyList[0]= 0; m_iNeededDuraniumInAssemblyList[0] = 0; m_iNeededCrystalInAssemblyList[0] = 0; m_iNeededIridiumInAssemblyList[0] = 0; m_iNeededDeritiumInAssemblyList[0]= 0; for (int i = 0; i < ALE - 1; i++) { // wenn der nächste Eintrag ungleich 0 ist if (m_iEntry[i + 1] != 0) { m_iEntry[i] = m_iEntry[i + 1]; m_iNeededIndustryInAssemblyList[i] = m_iNeededIndustryInAssemblyList[i + 1]; m_iNeededTitanInAssemblyList[i] = m_iNeededTitanInAssemblyList[i + 1]; m_iNeededDeuteriumInAssemblyList[i]= m_iNeededDeuteriumInAssemblyList[i + 1]; m_iNeededDuraniumInAssemblyList[i] = m_iNeededDuraniumInAssemblyList[i + 1]; m_iNeededCrystalInAssemblyList[i] = m_iNeededCrystalInAssemblyList[i + 1]; m_iNeededIridiumInAssemblyList[i] = m_iNeededIridiumInAssemblyList[i + 1]; m_iNeededDeritiumInAssemblyList[i]= m_iNeededDeritiumInAssemblyList[i + 1]; // den Nachfolger überall auf NULL setzen m_iEntry[i + 1] = 0; m_iNeededIndustryInAssemblyList[i + 1] = 0; m_iNeededTitanInAssemblyList[i + 1] = 0; m_iNeededDeuteriumInAssemblyList[i + 1]= 0; m_iNeededDuraniumInAssemblyList[i + 1] = 0; m_iNeededCrystalInAssemblyList[i + 1] = 0; m_iNeededIridiumInAssemblyList[i + 1] = 0; } else break; } // Checken, ob der nächste Eintrag auch baubar ist -> genügend RES im Lager // normalerweise kann man in der Bauliste ja nur Einträge vornehmen, wenn // man genügend RES hat. Also sollte er auch baubar sein, wenn die IP // erbracht wurden. Aber durch Zufallsereignisse oder Börsenverkäufe von RES // kann man später ja zu wening davon haben. Und weil die RES erst abgezogen // wird, wenn das Gebäude an erster Stelle in der Bauliste rückt, müssen // wird das überprüfen. Haben wir nicht genug RES, wird der Bauauftrag // gecancelt // Überprüfen, ob wir genügend Rohstoffe in dem Lager haben for (int res = TITAN; res <= DERITIUM; res++) { UINT nNeededRes = this->GetNeededResourceInAssemblyList(0, res); if (*system->GetResourceStorages(res) + resourcesFromRoutes[res] < nNeededRes && nResInDistSys[res] < nNeededRes) { // Wenn nicht -> dann Eintrag wieder entfernen ClearAssemblyList(ko, systems); return; } } // Wenn er baubar ist, dann die Ressourcen entfernen for (int res = TITAN; res <= DERITIUM; res++) { UINT nNeededRes = this->GetNeededResourceInAssemblyList(0, res); if (nNeededRes > 0) { // Ressource wird aus eigenem System bzw. über Ressourcenroute geholt if (*system->GetResourceStorages(res) + resourcesFromRoutes[res] >= nNeededRes) RemoveResourceFromStorage(res, ko, systems, &routesFrom); // reicht das nicht, so wird Ressource aus dem Verteiler geholt else { CArray<CPoint> vNullRoutes; RemoveResourceFromStorage(res, ptResourceDistributorKOs[res], systems, &vNullRoutes); } } } }
BOOLEAN CAssemblyList::MakeEntry(int runningNumber, const CPoint &ko, std::vector<CSystem>& systems, bool bOnlyTest) { // Die Assemblylist durchgehen, ob wir einen Eintrag finden, der noch 0 ist // dort können wir den nächsten speichern, gibt es keinen, dann ist die // Bauliste voll int entry = -1; if (!bOnlyTest) { for (int i = 0; i < ALE; i++) { if (m_iEntry[i] == 0) { entry = i; break; } } // prüfen ob Bauliste schon voll! if (entry == -1) return FALSE; } CSystem* system = &systems.at(ko.x+(ko.y)*STARMAP_SECTORS_HCOUNT); // Ressourcenrouten durchgehen und womöglich die möglichen max. zusätzlichen Ressourcen erfragen CArray<CPoint> routesFrom; ULONG resourcesFromRoutes[DERITIUM + 1]; ULONG nResInDistSys[DERITIUM + 1]; CPoint ptResourceDistributorKOs[DERITIUM + 1]; for (int i = 0; i <= DERITIUM; i++) { resourcesFromRoutes[i] = 0; nResInDistSys[i] = 0; ptResourceDistributorKOs[i] = CPoint(-1,-1); } for (int y = 0; y < STARMAP_SECTORS_VCOUNT; y++) { for (int x = 0; x < STARMAP_SECTORS_HCOUNT; x++) { if (systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetOwnerOfSystem() == system->GetOwnerOfSystem() && CPoint(x,y) != ko) { for (int i = 0; i < systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->GetSize(); i++) { if (systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->GetAt(i).GetKO() == ko) { if (systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetBlockade() == NULL && systems.at(ko.x+(ko.y)*STARMAP_SECTORS_HCOUNT).GetBlockade() == NULL) { routesFrom.Add(CPoint(x,y)); BYTE res = systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->GetAt(i).GetResource(); resourcesFromRoutes[res] += systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetResourceStore(res); } } } // gilt nicht bei Blockaden if (systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetBlockade() == NULL && systems.at(ko.x+(ko.y)*STARMAP_SECTORS_HCOUNT).GetBlockade() == NULL) { for (int res = TITAN; res <= DERITIUM; res++) { if (systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetProduction()->GetResourceDistributor(res)) { ptResourceDistributorKOs[res] = CPoint(x,y); nResInDistSys[res] = systems.at(x+(y)*STARMAP_SECTORS_HCOUNT).GetResourceStore(res); } } } } } } // Überprüfen, ob wir genügend Rohstoffe in dem Lager haben for (int res = TITAN; res <= DERITIUM; res++) { UINT nNeededRes = this->GetNeededResourceForBuild(res); if (*system->GetResourceStorages(res) + resourcesFromRoutes[res] < nNeededRes && nResInDistSys[res] < nNeededRes) return FALSE; } if (bOnlyTest) return TRUE; // Ansonsten gibt es genügend Rohstoffe m_iEntry[entry] = runningNumber; // Was wir für das notwendige Projekt alles so brauchen speichern m_iNeededIndustryInAssemblyList[entry] = m_iNeededIndustryForBuild; m_iNeededTitanInAssemblyList[entry] = m_iNeededTitanForBuild; m_iNeededDeuteriumInAssemblyList[entry]= m_iNeededDeuteriumForBuild; m_iNeededDuraniumInAssemblyList[entry] = m_iNeededDuraniumForBuild; m_iNeededCrystalInAssemblyList[entry] = m_iNeededCrystalForBuild; m_iNeededIridiumInAssemblyList[entry] = m_iNeededIridiumForBuild; m_iNeededDeritiumInAssemblyList[entry]= m_iNeededDeritiumForBuild; // Nur wenn es der erste Eintrag im Baumenü ist wird alles abgezogen // ansonsten erst, nachdem das Projekt im ersten Eintrag fertig ist if (entry == 0) { for (int res = TITAN; res <= DERITIUM; res++) { UINT nNeededRes = this->GetNeededResourceForBuild(res); if (nNeededRes > 0) { // Ressource wird aus eigenem System bzw. über Ressourcenroute geholt if (*system->GetResourceStorages(res) + resourcesFromRoutes[res] >= nNeededRes) RemoveResourceFromStorage(res, ko, systems, &routesFrom); // reicht das nicht, so wird Ressource aus dem Verteier geholt else { CArray<CPoint> vNullRoutes; RemoveResourceFromStorage(res, ptResourceDistributorKOs[res], systems, &vNullRoutes); } } } } // Eintrag konnte gesetzt werden return TRUE; }
// Diese Funktion entfernt die benötigten Ressourcen aus dem lokalen Lager des Systems und falls Ressourcenrouten // bestehen auch die Ressourcen in den Startsystemen der Route. Aber nur falls dies auch notwendig sein sollte. void CAssemblyList::RemoveResourceFromStorage(BYTE res, const CPoint &ko, std::vector<CSystem>& systems, CArray<CPoint>* routesFrom) { if (ko == CPoint(-1,-1)) return; CSystem *system = &systems.at(ko.x+(ko.y)*STARMAP_SECTORS_HCOUNT); // für Deritium gibt es keine Ressourcenroute if (res != DERITIUM) { // zuerst wird immer versucht, die Ressourcen aus dem lokalen Lager zu nehmen long remainingRes = GetNeededResourceInAssemblyList(0, res) - system->GetResourceStore(res); // werden zusätzliche Ressourcen aus anderen Lagern benötigt, so kann das lokale Lager // auf NULL gesetzt werden if (remainingRes > 0) { *system->GetResourceStorages(res) = NULL; // zusätzliche Ressourcen müssen aus den Lagern der Systeme mit den Ressourcenrouten // bezogen werden. Dafür ein Feld anlegen, indem alle Startsysteme mit der zur Ressouce passenden // Ressourcenroute beinhaltet sind. struct ROUTELIST { CResourceRoute *route; CPoint fromSystem; ROUTELIST() : route(0), fromSystem(0) {} ROUTELIST(CResourceRoute *_route, CPoint _fromSystem) : route(_route), fromSystem(_fromSystem) {} }; CArray<ROUTELIST> routes; for (int j = 0; j < routesFrom->GetSize(); j++) { CPoint p = routesFrom->GetAt(j); for (int k = 0; k < systems.at(p.x+(p.y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->GetSize(); k++) { // Stimmt die Ressource überein= if (systems.at(p.x+(p.y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->GetAt(k).GetResource() == res) { // Stimmt das Zielsystem mit unserem überein? if (systems.at(p.x+(p.y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->GetAt(k).GetKO() == ko) { // prüfen das die Route nicht schon verwendet wird bool bUsed = false; for (int l = 0; l < routes.GetSize(); l++) if (routes.GetAt(l).fromSystem == p) { bUsed = true; break; } if (!bUsed) routes.Add(ROUTELIST(&systems.at(p.x+(p.y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->GetAt(k), p)); } } } } // in routes sind nun die Zeiger auf die richtigen Ressourcenrouten, also die Routen, welche auch den // passenden Rohstoff liefern könnten. while (routes.GetSize()) { // zufällig eine Route aus den möglichen auswählen, damit nicht immer das gleiche System zuerst // die Rohstoffe liefern muss, falls mehrere Routen der selben Art ins System eingehen. int random = rand()%routes.GetSize(); int percent = 0; CPoint start = routes.GetAt(random).fromSystem; // sind im jeweiligen Lager des Startsystem genügend Rohstoffe vorhanden if (systems.at(start.x+(start.y)*STARMAP_SECTORS_HCOUNT).GetResourceStore(res) >= (ULONG)remainingRes) { *systems.at(start.x+(start.y)*STARMAP_SECTORS_HCOUNT).GetResourceStorages(res) -= remainingRes; if (GetNeededResourceInAssemblyList(0, res) > NULL) percent = 100 * remainingRes / GetNeededResourceInAssemblyList(0, res); CResourceRoute* pResRoute = routes.GetAt(random).route; pResRoute->SetPercent((BYTE)percent); remainingRes = 0; } else { remainingRes -= systems.at(start.x+(start.y)*STARMAP_SECTORS_HCOUNT).GetResourceStore(res); if (GetNeededResourceInAssemblyList(0, res) > NULL) percent = 100 * systems.at(start.x+(start.y)*STARMAP_SECTORS_HCOUNT).GetResourceStore(res) / GetNeededResourceInAssemblyList(0, res); CResourceRoute* pResRoute = routes.GetAt(random).route; pResRoute->SetPercent((BYTE)percent); *systems.at(start.x+(start.y)*STARMAP_SECTORS_HCOUNT).GetResourceStorages(res) = NULL; } // ROUTELIST Eintrag entfernen, wenn dieser abgearbeitet wurde routes.RemoveAt(random); // werden keine Ressourcen mehr benötigt, so kann abgebrochen werden if (remainingRes == 0) { routes.RemoveAll(); break; } } ASSERT(remainingRes == 0); } // anderenfalls werden nur die benötigten Ressourcen aus dem lokalen Lager abgezogen else *system->GetResourceStorages(res) -= GetNeededResourceInAssemblyList(0, res); } else *system->GetResourceStorages(res) -= m_iNeededDeritiumInAssemblyList[0]; }
void GenerateSimTables (CUniverse &Universe, CXMLElement *pCmdLine) { ALERROR error; int i, j; int iSystemSample = pCmdLine->GetAttributeInteger(CONSTLIT("count")); if (iSystemSample == 0) iSystemSample = DEFAULT_SYSTEM_SAMPLE; // Generate systems for multiple games CSymbolTable AllSystems(TRUE, TRUE); for (i = 0; i < iSystemSample; i++) { printf("sample %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; } // Find this system in the table. SystemInfo *pSystemEntry; if (error = AllSystems.Lookup(pNode->GetSystemName(), (CObject **)&pSystemEntry)) { pSystemEntry = new SystemInfo; pSystemEntry->sName = pNode->GetSystemName(); pSystemEntry->iLevel = pNode->GetLevel(); pSystemEntry->dwSystemType = pNode->GetSystemDescUNID(); pSystemEntry->iCount = 1; AllSystems.AddEntry(pSystemEntry->sName, pSystemEntry); } else pSystemEntry->iCount++; // 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 CStationType *pType; if (pType = pObj->GetEncounterInfo()) { CString sKey = strFromInt(pType->GetUNID(), false); // See if we have this type in the table StationInfo *pEntry; if (error = pSystemEntry->Stations.Lookup(sKey, (CObject **)&pEntry)) { pEntry = new StationInfo; pEntry->pType = pType; pEntry->iSystemCount = 0; pEntry->iTotalCount = 1; pSystemEntry->Stations.AddEntry(sKey, pEntry); } else pEntry->iTotalCount++; } // 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()) { CString sKey = strFromInt(Item.GetType()->GetUNID(), false); // Find the item type in the table ItemInfo *pEntry; if (error = pSystemEntry->Items.Lookup(sKey, (CObject **)&pEntry)) { pEntry = new ItemInfo; pEntry->pType = Item.GetType(); pEntry->iTotalCount = Item.GetCount(); pSystemEntry->Items.AddEntry(sKey, pEntry); } else pEntry->iTotalCount += Item.GetCount(); } } } } // 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(); } // Output if (error = OutputItemTable(AllSystems, iSystemSample)) return; if (error = OutputEncounterTable(AllSystems, iSystemSample)) return; // Create a table with the sum of all items for the game printf("Total count statistic computed.\n"); }
void Run (CUniverse &Universe, CXMLElement *pCmdLine) { ALERROR error; int i; CCodeChain &CC = g_pUniverse->GetCC(); bool bNoLogo = pCmdLine->GetAttributeBool(NO_LOGO_SWITCH); // Prepare the universe CTopologyNode *pNode = g_pUniverse->GetFirstTopologyNode(); if (pNode == NULL) { printf("ERROR: No topology node found.\n"); return; } CSystem *pSystem; if (error = g_pUniverse->CreateStarSystem(pNode, &pSystem)) { printf("ERROR: Unable to create star system.\n"); return; } // Set the POV CSpaceObject *pPOV = pSystem->GetObject(0); g_pUniverse->SetPOV(pPOV); pSystem->SetPOVLRS(pPOV); // Prepare system g_pUniverse->UpdateExtended(); g_pUniverse->GarbageCollectLibraryBitmaps(); CString sCommand = pCmdLine->GetAttribute(RUN_SWITCH); CString sRunFile = pCmdLine->GetAttribute(RUN_FILE_SWITCH); // If this is a run file, then we parse it and run it if (!sRunFile.IsBlank() && !strEquals(sRunFile, CONSTLIT("true"))) { TArray<CString> Files; ParseStringList(sRunFile, PSL_FLAG_ALLOW_WHITESPACE, &Files); for (i = 0; i < Files.GetCount(); i++) RunFile(Files[i], bNoLogo); } // If we have a command, invoke it else if (!sCommand.IsBlank() && !strEquals(sCommand, CONSTLIT("True"))) { CCodeChainCtx Ctx; ICCItem *pCode = Ctx.Link(sCommand, 0, NULL); ICCItem *pResult = Ctx.Run(pCode); CString sOutput; if (pResult->IsIdentifier()) sOutput = pResult->Print(&CC, PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY); else sOutput = CC.Unlink(pResult); Ctx.Discard(pResult); Ctx.Discard(pCode); // Output result printf("%s\n", sOutput.GetASCIIZPointer()); } // Otherwise, we enter a command loop else { // Welcome if (!bNoLogo) { printf("(help) for function help.\n"); printf("\\q to quit.\n\n"); } // Loop while (true) { char szBuffer[1024]; if (!bNoLogo) printf(": "); gets_s(szBuffer, sizeof(szBuffer)-1); CString sCommand(szBuffer); // Escape codes if (*sCommand.GetASCIIZPointer() == '\\') { // Quit command if (strStartsWith(sCommand, CONSTLIT("\\q"))) break; else if (strStartsWith(sCommand, CONSTLIT("\\?")) || strStartsWith(sCommand, CONSTLIT("\\h"))) { printf("TLisp Shell\n\n"); printf("\\h Show this help\n"); printf("\\q Quit\n"); printf("\n(help) for function help.\n"); } } // Null command else if (sCommand.IsBlank()) NULL; // Command else { CCodeChainCtx Ctx; ICCItem *pCode = Ctx.Link(sCommand, 0, NULL); ICCItem *pResult = Ctx.Run(pCode); CString sOutput; if (pResult->IsIdentifier()) sOutput = pResult->Print(&CC, PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY); else sOutput = CC.Unlink(pResult); Ctx.Discard(pResult); Ctx.Discard(pCode); // Output result printf("%s\n", sOutput.GetASCIIZPointer()); } } } }
void GenerateStationPlaceSim (CUniverse &Universe, CXMLElement *pCmdLine) { ALERROR error; int i, j, k; CSovereign *pPlayer = Universe.FindSovereign(g_PlayerSovereignUNID); int iSystemSample = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("count"), 1, -1, 1); bool bLogo = !pCmdLine->GetAttributeBool(NO_LOGO_SWITCH); // Generate systems for multiple games CSymbolTable AllSystems(TRUE, TRUE); 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; } // Find this system in the table. SPSimSystemInfo *pSystemEntry; if (error = AllSystems.Lookup(pNode->GetSystemName(), (CObject **)&pSystemEntry)) { pSystemEntry = new SPSimSystemInfo; pSystemEntry->sName = pNode->GetSystemName(); pSystemEntry->iLevel = pNode->GetLevel(); pSystemEntry->dwSystemType = pNode->GetSystemTypeUNID(); pSystemEntry->iCount = 1; for (j = 0; j < DIST_BUCKET_COUNT; j++) pSystemEntry->iEnemies[j] = 0; AllSystems.AddEntry(pSystemEntry->sName, pSystemEntry); } else pSystemEntry->iCount++; // For all active stations in the system, count the number of enemy stations // within certain distance buckets for (j = 0; j < pSystem->GetObjectCount(); j++) { CSpaceObject *pObj = pSystem->GetObject(j); // Find any objects that are lootable by the player if (pObj && pObj->GetCategory() == CSpaceObject::catStation && pObj->CanAttack()) { // Count to see how many enemy stations are in range for (k = 0; k < pSystem->GetObjectCount(); k++) { CSpaceObject *pEnemy = pSystem->GetObject(k); if (pEnemy && pEnemy->GetCategory() == CSpaceObject::catStation && pEnemy->CanAttack() && (pEnemy->IsEnemy(pObj) || pObj->IsEnemy(pEnemy))) { Metric rDist = pObj->GetDistance(pEnemy); int iDist = DistToBucketIndex(rDist); if (iDist != -1) { ASSERT(iDist < DIST_BUCKET_COUNT && iDist >= 0); pSystemEntry->iEnemies[iDist]++; int iLSDist = (int)((rDist / LIGHT_SECOND) + 0.5); if (iLSDist < 30) { printf("%s: %s (%x) and %s (%x) within %d ls\n", pSystem->GetName().GetASCIIZPointer(), pObj->GetNounPhrase().GetASCIIZPointer(), pObj->GetID(), pEnemy->GetNounPhrase().GetASCIIZPointer(), pEnemy->GetID(), iLSDist); } } } } } } // 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 SYSTEM STATISTICS\n\n"); // Output total value stats printf("Level\tSystem\t<10 ls\t<25 ls\t<50ls\t<100 ls\n"); int iTotals[DIST_BUCKET_COUNT]; for (i = 0; i < DIST_BUCKET_COUNT; i++) iTotals[i] = 0; for (i = 0; i < AllSystems.GetCount(); i++) { SPSimSystemInfo *pSystemEntry = (SPSimSystemInfo *)AllSystems.GetValue(i); printf("%d\t%s", pSystemEntry->iLevel, pSystemEntry->sName.GetASCIIZPointer()); for (j = 0; j < DIST_BUCKET_COUNT; j++) { printf("\t%.2f", (double)pSystemEntry->iEnemies[j] / (double)pSystemEntry->iCount); iTotals[j] += pSystemEntry->iEnemies[j]; } printf("\n"); } // Totals printf("\n"); printf("Within 10 ls: %.2f\n", iTotals[0] / (double)iSystemSample); printf("Within 25 ls: %.2f\n", iTotals[1] / (double)iSystemSample); printf("Within 50 ls: %.2f\n", iTotals[2] / (double)iSystemSample); printf("Within 100 ls: %.2f\n", iTotals[3] / (double)iSystemSample); printf("\n"); }
void GenerateWeaponEffectChart (CUniverse &Universe, CXMLElement *pCmdLine) { int i; // Compute the list of weapons to show, making sure we filter to weapons // and missiles only. CItemTypeTable Selection; if (!Selection.Filter(pCmdLine->GetAttribute(CRITERIA_ATTRIB)) || (Selection.IsAll() && !Selection.Filter(CONSTLIT("wm")))) { printf("No entries match criteria.\n"); return; } Selection.Sort(); // Ship to use DWORD dwPlatformUNID; if (!pCmdLine->FindAttributeInteger(SHIP_UNID_ATTRIB, (int *)&dwPlatformUNID)) dwPlatformUNID = WEAPON_PLATFORM_UNID; // Compute some metrics int iFramesPerItem = 10; int cxFrameHorzMargin = 10; int cxMaxDistPerTick = (int)(STD_SECONDS_PER_UPDATE * (LIGHT_SECOND / g_KlicksPerPixel)); int cyFrame = 64; int cxFrame = (2 * cxFrameHorzMargin) + (iFramesPerItem * cxMaxDistPerTick); int iHitEffectFramesPerItem = 5; int cxHitEffect = 128; int cyHitEffect = 128; int cyRowTitle = 20; int cyRow = cyRowTitle + Max(ITEM_ICON_HEIGHT, cyFrame * iFramesPerItem); int cxRow = ITEM_ICON_WIDTH + cxFrame; int iColumns = Max(1, mathSqrt(Selection.GetCount())); int iRows = (Selection.GetCount() + (iColumns - 1)) / iColumns; int cxImage = cxRow * iColumns; int cyImage = cyRow * iRows; // Initialize the output COutputChart Output; Output.SetContentSize(cxImage, cyImage); Output.SetOutputFilespec(pCmdLine->GetAttribute(CONSTLIT("output"))); // Initialize fonts Output.SetStyleFont(STYLE_TITLE, pCmdLine->GetAttribute(CONSTLIT("font"))); Output.SetStyleColor(STYLE_TITLE, CG32bitPixel(0xFF, 0xFF, 0xFF)); // Prepare the universe CSystem *pSystem; if (Universe.CreateEmptyStarSystem(&pSystem) != NOERROR) { printf("ERROR: Unable to create empty star system.\n"); return; } // Create a target in the center of the system CSpaceObject *pStation; CStationType *pTargetType = Universe.FindStationType(TARGET_UNID); if (pTargetType == NULL || pSystem->CreateStation(pTargetType, NULL, CVector(), &pStation) != NOERROR) { printf("ERROR: Unable to create station.\n"); return; } // Create the weapon platform some distance away CSovereign *pPlatformSovereign = Universe.FindSovereign(PLAYER_SOVEREIGN_UNID); CShip *pPlatform; if (pPlatformSovereign == NULL || pSystem->CreateShip(dwPlatformUNID, NULL, NULL, pPlatformSovereign, CVector(-5.0 * LIGHT_SECOND, 0.), CVector(), 0, NULL, NULL, &pPlatform) != NOERROR) { printf("ERROR: Unable to create weapons platform.\n"); return; } // Set the attacker to hold IShipController *pController = pPlatform->GetController(); if (pController == NULL) { printf("ERROR: No controller for ship.\n"); return; } pController->AddOrder(IShipController::orderHold, NULL, IShipController::SData()); pPlatform->SetControllerEnabled(false); // Install the largest possible reactor on the ship CItemType *pReactorType = Universe.FindItemType(REACTOR_UNID); if (pReactorType) { CItem ReactorItem(pReactorType, 1); CItemListManipulator ItemList(pPlatform->GetItemList()); ItemList.AddItem(ReactorItem); pPlatform->OnComponentChanged(comCargo); pPlatform->ItemsModified(); pPlatform->InvalidateItemListAddRemove(); pPlatform->InstallItemAsDevice(ItemList); } // Set the POV Universe.SetPOV(pStation); pSystem->SetPOVLRS(pStation); // Prepare system Universe.UpdateExtended(); Universe.GarbageCollectLibraryBitmaps(); Universe.StartGame(true); // Output each weapon int xOrigin; int yOrigin; CG32bitImage &Image = Output.GetOutputImage(&xOrigin, &yOrigin); const CG16bitFont &TitleFont = Output.GetStyleFont(STYLE_TITLE); CG32bitPixel rgbTitleColor = Output.GetStyleColor(STYLE_TITLE); for (i = 0; i < Selection.GetCount(); i++) { CItemType *pType = Selection.GetItemType(i); // Compute the metrics of this row int xRow = xOrigin + (i % iColumns) * cxRow; int yRow = yOrigin + (i / iColumns) * cyRow; // Paint the weapon title Image.Fill(xRow, yRow, cxRow, cyRow, CG32bitPixel(0x40, 0x40, 0x40)); TitleFont.DrawText(Image, xRow + 8, yRow, rgbTitleColor, pType->GetNounPhrase()); // Paint the frames PaintWeaponFrames(Image, pType, pPlatform, iFramesPerItem, xRow + ITEM_ICON_WIDTH + cxFrameHorzMargin, yRow + cyRowTitle, cxMaxDistPerTick, cyFrame); } // Done Output.Output(); }
void GenerateSnapshot (CUniverse &Universe, CXMLElement *pCmdLine) { ALERROR error; int i; // Get some parameters int iInitialUpdateTime = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("initialUpdate"), 0, -1, 10); int iUpdateTime = pCmdLine->GetAttributeInteger(CONSTLIT("wait")); bool bObjOnly = pCmdLine->GetAttributeBool(CONSTLIT("objOnly")); // Criteria CString sNode = pCmdLine->GetAttribute(CONSTLIT("node")); CString sCriteria = pCmdLine->GetAttribute(CONSTLIT("criteria")); // Number of snapshots int iTotalCount = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("count"), 1, -1, 1); // Output int cxWidth; int cyHeight; if (pCmdLine->FindAttributeInteger(CONSTLIT("size"), &cxWidth)) { cyHeight = cxWidth; } else { cxWidth = 1024; cyHeight = 1024; } // Paint flags DWORD dwPaintFlags = 0; if (pCmdLine->GetAttributeBool(CONSTLIT("noStars"))) dwPaintFlags |= CSystem::VWP_NO_STAR_FIELD; // Output file CString sFilespec = pCmdLine->GetAttribute(CONSTLIT("output")); if (!sFilespec.IsBlank()) sFilespec = pathStripExtension(sFilespec); // Output image CG32bitImage Output; Output.Create(cxWidth, cyHeight); // Update context SSystemUpdateCtx Ctx; Ctx.bForceEventFiring = true; Ctx.bForcePainted = true; RECT rcViewport; rcViewport.left = 0; rcViewport.top = 0; rcViewport.right = cxWidth; rcViewport.bottom = cyHeight; // Loop over all systems until we find what we're looking for int iLoops = 20; int iNodeIndex = 0; int iSnapshotIndex = 0; CTopologyNode *pNode = Universe.GetTopologyNode(iNodeIndex); while (true) { // Create the system CSystem *pSystem; if (error = Universe.CreateStarSystem(pNode, &pSystem)) { printf("ERROR: Unable to create star system.\n"); return; } // If this is the node we want, then search CSpaceObject *pTarget; if (sNode.IsBlank() || strEquals(sNode, pNode->GetID())) { printf("Searching %s...\n", pNode->GetSystemName().GetASCIIZPointer()); // Set the POV CSpaceObject *pPOV = pSystem->GetObject(0); Universe.SetPOV(pPOV); pSystem->SetPOVLRS(pPOV); // Prepare system Universe.UpdateExtended(); Universe.GarbageCollectLibraryBitmaps(); // Update for a while for (i = 0; i < iInitialUpdateTime; i++) { Universe.Update(Ctx); Universe.PaintPOV(Output, rcViewport, 0); } // Compose the criteria CSpaceObject::Criteria Criteria; CSpaceObject::ParseCriteria(pPOV, sCriteria, &Criteria); // Get the list of all objects in the system that match the criteria CSpaceObject::SCriteriaMatchCtx Ctx(Criteria); TArray<CSpaceObject *> Results; for (i = 0; i < pSystem->GetObjectCount(); i++) { CSpaceObject *pObj = pSystem->GetObject(i); if (pObj && pObj->MatchesCriteria(Ctx, Criteria)) Results.Insert(pObj); } // Pick the appropriate object from the list if (Results.GetCount() == 0) pTarget = NULL; else if (Criteria.bNearestOnly || Criteria.bFarthestOnly) pTarget = Ctx.pBestObj; else pTarget = Results[mathRandom(0, Results.GetCount() - 1)]; } else pTarget = NULL; // If we found the target, then output if (pTarget) { Universe.SetPOV(pTarget); // Wait a bit // // NOTE: After we update, pTarget could be invalid (i.e., destroyed) // so we can't use it again. CString sTargetName = pTarget->GetNounPhrase(0); for (i = 0; i < iUpdateTime; i++) { if ((i % 100) == 99) printf("."); Universe.Update(Ctx); Universe.PaintPOV(Output, rcViewport, 0); } if (iUpdateTime >= 99) printf("\n"); // Paint if (bObjOnly) { SViewportPaintCtx Ctx; Ctx.pObj = Universe.GetPOV(); Ctx.XForm = ViewportTransform(Universe.GetPOV()->GetPos(), g_KlicksPerPixel, cxWidth / 2, cyHeight / 2); Ctx.XFormRel = Ctx.XForm; Ctx.fNoRecon = true; Ctx.fNoDockedShips = true; Ctx.fNoSelection = true; Ctx.fNoStarfield = true; CSpaceObject *pPOV = pSystem->GetObject(0); CSpaceObject::Criteria Criteria; CSpaceObject::ParseCriteria(pPOV, sCriteria, &Criteria); // Paint all objects that match the criteria CSpaceObject::SCriteriaMatchCtx CriteriaCtx(Criteria); for (i = 0; i < pSystem->GetObjectCount(); i++) { CSpaceObject *pObj = pSystem->GetObject(i); if (pObj && pObj->MatchesCriteria(CriteriaCtx, Criteria)) { Ctx.pObj = pObj; int xObj; int yObj; Ctx.XForm.Transform(pObj->GetPos(), &xObj, &yObj); pObj->Paint(Output, xObj, yObj, Ctx); } } } else { Universe.PaintPOV(Output, rcViewport, 0); } // Write to file if (!sFilespec.IsBlank()) { CString sBmpFilespec; if (iTotalCount > 100) sBmpFilespec = pathAddExtensionIfNecessary(strPatternSubst(CONSTLIT("%s%03d"), sFilespec, iSnapshotIndex + 1), CONSTLIT(".bmp")); else if (iTotalCount > 1) sBmpFilespec = pathAddExtensionIfNecessary(strPatternSubst(CONSTLIT("%s%02d"), sFilespec, iSnapshotIndex + 1), CONSTLIT(".bmp")); else sBmpFilespec = pathAddExtensionIfNecessary(sFilespec, CONSTLIT(".bmp")); CFileWriteStream OutputFile(sBmpFilespec); if (OutputFile.Create() != NOERROR) { printf("ERROR: Unable to create '%s'\n", sBmpFilespec.GetASCIIZPointer()); return; } Output.WriteToWindowsBMP(&OutputFile); OutputFile.Close(); printf("Found %s: Saved to %s\n", sTargetName.GetASCIIZPointer(), sBmpFilespec.GetASCIIZPointer()); } // Otherwise, clipboard else { if (error = Output.CopyToClipboard()) { printf("ERROR: Unable to copy image to clipboard.\n"); return; } printf("Found %s: Copied to clipboard.\n", sTargetName.GetASCIIZPointer()); } // Reset maximum loops iLoops = 20; // Done iSnapshotIndex++; if (iSnapshotIndex >= iTotalCount) break; } // Done with old system Universe.DestroySystem(pSystem); // Loop to the next node do { iNodeIndex = ((iNodeIndex + 1) % Universe.GetTopologyNodeCount()); pNode = Universe.GetTopologyNode(iNodeIndex); } while (pNode == NULL || pNode->IsEndGame()); // If we're back to the first node again, restart if (iNodeIndex == 0) { if (--iLoops > 0) { // Reinitialize Universe.Reinit(); CString sError; if (Universe.InitGame(0, &sError) != NOERROR) { printf("ERROR: %s\n", sError.GetASCIIZPointer()); return; } iNodeIndex = 0; pNode = Universe.GetTopologyNode(iNodeIndex); } else { printf("ERROR: Specified target could not be found.\n"); return; } } } }