void CDesignCollection::CleanUp (void) // CleanUp // // Free all entries so that we don't hold on to any resources. { int i; // Some classes need to clean up global data // (But we need to do this before we destroy the types) CStationType::Reinit(); // Delete the base types m_Base.DeleteAll(); // Delete all extensions for (i = 0; i < GetExtensionCount(); i++) { SExtensionDesc *pEntry = GetExtension(i); pEntry->Table.DeleteAll(); delete pEntry; } m_Extensions.DeleteAll(); }
void CDesignCollection::SelectAdventure (DWORD dwUNID) // SelectAdventure // // Enable the given adventure and disable all other adventures { int i; for (i = 0; i < GetExtensionCount(); i++) { SExtensionDesc *pEntry = GetExtension(i); if (pEntry->iType == extAdventure) pEntry->bEnabled = (pEntry->dwUNID == dwUNID); } }
void CDesignCollection::GetEnabledExtensions (TArray<DWORD> *retExtensionList) // GetEnabledExtensions // // Returns the list of enabled extensions { int i; retExtensionList->DeleteAll(); for (i = 0; i < GetExtensionCount(); i++) { SExtensionDesc *pEntry = GetExtension(i); if (pEntry->iType == extExtension && pEntry->bEnabled) retExtensionList->Insert(pEntry->dwUNID); } }
void CDesignCollection::GetEnabledExtensions (TArray<CExtension *> *retExtensionList) // GetEnabledExtensions // // Returns the list of enabled extensions { int i; retExtensionList->DeleteAll(); for (i = 0; i < GetExtensionCount(); i++) { CExtension *pEntry = GetExtension(i); if (pEntry->GetType() == extExtension) retExtensionList->Insert(pEntry); } }
void CDesignCollection::RemoveAll (void) // RemoveAll // // Remove all entries { int i; // Delete the base types m_Base.DeleteAll(); // Delete all extensions for (i = 0; i < GetExtensionCount(); i++) { SExtensionDesc *pEntry = GetExtension(i); pEntry->Table.DeleteAll(); delete pEntry; } m_Extensions.RemoveAll(); }
ALERROR CDesignCollection::BindDesign (SDesignLoadCtx &Ctx) // BindDesign // // Bind the design collection so that design types point the appropriate // pointers by UNID { ALERROR error; int i, j; // Unbind everything for (i = 0; i < m_AllTypes.GetCount(); i++) m_AllTypes.GetEntry(i)->UnbindDesign(); m_AllTypes.DeleteAll(); // Reset the bind tables for (i = 0; i < designCount; i++) m_ByType[i].DeleteAll(); // We start with all the base types for (i = 0; i < m_Base.GetCount(); i++) m_AllTypes.AddEntry(m_Base.GetEntry(i)); // Start with base topology m_pTopology = &m_BaseTopology; m_pAdventureExtension = NULL; // Now add all enabled extensions for (i = 0; i < GetExtensionCount(); i++) { SExtensionDesc *pExtension = GetExtension(i); if (pExtension->bEnabled) { // Add design elements in extension for (j = 0; j < pExtension->Table.GetCount(); j++) { CDesignType *pEntry = pExtension->Table.GetEntry(j); m_AllTypes.AddOrReplaceEntry(pEntry); } // Handle adventure extensions if (pExtension->iType == extAdventure) { // Keep track of extension m_pAdventureExtension = pExtension; // Add topology m_pTopology = &pExtension->Topology; } } else { if (pExtension->iType == extAdventure) { DWORD dwCoverImage = 0; // Adventure desc elements are added even if not enabled for (j = 0; j < pExtension->Table.GetCount(); j++) { CDesignType *pEntry = pExtension->Table.GetEntry(j); if (pEntry->GetType() == designAdventureDesc) { m_AllTypes.AddOrReplaceEntry(pEntry); // Get the cover image used by the adventure, because // we need to load that too. CAdventureDesc *pDesc = CAdventureDesc::AsType(pEntry); dwCoverImage = pDesc->GetBackgroundUNID(); } } // Make sure we load the cover image if (dwCoverImage) { for (j = 0; j < pExtension->Table.GetCount(); j++) { CDesignType *pEntry = pExtension->Table.GetEntry(j); if (pEntry->GetUNID() == dwCoverImage) m_AllTypes.AddOrReplaceEntry(pEntry); } } } } } // If this is a new game, then create all the Template types if (Ctx.bNewGame) { m_DynamicUNIDs.DeleteAll(); m_DynamicTypes.DeleteAll(); if (error = FireOnGlobalTypesInit(Ctx)) return error; if (error = CreateTemplateTypes(Ctx)) return error; } // Add all the dynamic types. These came either from the saved game file or // from the Template types above. for (i = 0; i < m_DynamicTypes.GetCount(); i++) m_AllTypes.AddOrReplaceEntry(m_DynamicTypes.GetType(i)); // Initialize the byType lists for (i = 0; i < m_AllTypes.GetCount(); i++) { CDesignType *pEntry = m_AllTypes.GetEntry(i); m_ByType[pEntry->GetType()].AddEntry(pEntry); } // Set our adventure desc as current; since adventure descs are always // loaded this is the only thing that we can use to tell if we should // call global events. // // This must happen after Unbind (because that clears it) and before // PrepareBindDesign. // // NOTE: m_pAdventureDesc can be NULL (e.g., in the intro screen). if (m_pAdventureDesc) m_pAdventureDesc->SetCurrentAdventure(); // Cache a map between currency name and economy type // We need to do this before Bind because some types will lookup // a currency name during Bind. m_EconomyIndex.DeleteAll(); for (i = 0; i < GetCount(designEconomyType); i++) { CEconomyType *pEcon = CEconomyType::AsType(GetEntry(designEconomyType, i)); const CString &sName = pEcon->GetSID(); bool bUnique; CEconomyType **ppDest = m_EconomyIndex.SetAt(sName, &bUnique); if (!bUnique) return pEcon->ComposeLoadError(Ctx, CONSTLIT("Currency ID must be unique")); *ppDest = pEcon; } // Prepare to bind. This is used by design elements // that need two passes to bind. for (i = 0; i < m_AllTypes.GetCount(); i++) { CDesignType *pEntry = m_AllTypes.GetEntry(i); if (error = pEntry->PrepareBindDesign(Ctx)) return error; } // Now call Bind on all active design entries for (i = 0; i < evtCount; i++) m_EventsCache[i]->DeleteAll(); for (i = 0; i < m_AllTypes.GetCount(); i++) { CDesignType *pEntry = m_AllTypes.GetEntry(i); if (error = pEntry->BindDesign(Ctx)) return error; // Cache some global events. We keep track of the global events for // all types so that we can access them faster. CacheGlobalEvents(pEntry); } // Finish binding. This pass is used by design elements // that need to do stuff after all designs are bound. for (i = 0; i < m_AllTypes.GetCount(); i++) { CDesignType *pEntry = m_AllTypes.GetEntry(i); if (error = pEntry->FinishBindDesign(Ctx)) return error; } return NOERROR; }
ALERROR CDesignCollection::SelectExtensions (CAdventureDesc *pAdventure, TArray<DWORD> *pExtensionList, bool *retbBindNeeded, CString *retsError) // SelectExtensions // // Enables all extensions in pExtensionList and disables all others // (if pExtensionList == NULL then we enable all extensions). // // Returns an error if an extension on the list could not be found. { int i; bool bBindNeeded = false; TArray<bool> OldState; OldState.InsertEmpty(GetExtensionCount()); // Disable all extensions for (i = 0; i < GetExtensionCount(); i++) { SExtensionDesc *pEntry = GetExtension(i); if (pEntry->iType == extExtension) { OldState[i] = pEntry->bEnabled; pEntry->bEnabled = false; } } // Enable all extensions in the list if (pExtensionList) { for (i = 0; i < pExtensionList->GetCount(); i++) { SExtensionDesc *pEntry = FindExtension(pExtensionList->GetAt(i)); if (pEntry == NULL || pEntry->iType == extAdventure) { if (retsError) *retsError = strPatternSubst(CONSTLIT("Unable to find extension: %x"), pExtensionList->GetAt(i)); return ERR_NOTFOUND; } if (pEntry->iType == extExtension && IsExtensionCompatibleWithAdventure(pEntry, pAdventure)) pEntry->bEnabled = true; } } else { // Enable all extensions for (i = 0; i < GetExtensionCount(); i++) { SExtensionDesc *pEntry = GetExtension(i); if (pEntry->iType == extExtension && IsExtensionCompatibleWithAdventure(pEntry, pAdventure) && (!pEntry->bDebugOnly || g_pUniverse->InDebugMode())) pEntry->bEnabled = true; } } // See if we made any changes for (i = 0; i < GetExtensionCount(); i++) { SExtensionDesc *pEntry = GetExtension(i); if (pEntry->iType == extExtension && pEntry->bEnabled != OldState[i]) { bBindNeeded = true; break; } } // Done if (retbBindNeeded) *retbBindNeeded = bBindNeeded; return NOERROR; }
ALERROR CDesignCollection::BindDesign (SDesignLoadCtx &Ctx) // BindDesign // // Bind the design collection so that design types point the appropriate // pointers by UNID { ALERROR error; int i, j; // Reset the bind tables m_AllTypes.RemoveAll(); for (i = 0; i < designCount; i++) m_ByType[i].RemoveAll(); // We start with all the base types for (i = 0; i < m_Base.GetCount(); i++) m_AllTypes.AddEntry(m_Base.GetEntry(i)); // Start with base topology m_pTopology = &m_BaseTopology; m_pAdventureExtension = NULL; // Now add all enabled extensions for (i = 0; i < GetExtensionCount(); i++) { SExtensionDesc *pExtension = GetExtension(i); if (pExtension->bEnabled) { // Add design elements in extension for (j = 0; j < pExtension->Table.GetCount(); j++) m_AllTypes.AddOrReplaceEntry(pExtension->Table.GetEntry(j)); // Handle adventure extensions if (pExtension->iType == extAdventure) { // Keep track of extension m_pAdventureExtension = pExtension; // Add topology m_pTopology = &pExtension->Topology; } } else { if (pExtension->iType == extAdventure) { // Adventure desc elements are added even if not enabled for (j = 0; j < pExtension->Table.GetCount(); j++) { CDesignType *pEntry = pExtension->Table.GetEntry(j); if (pEntry->GetType() == designAdventureDesc) m_AllTypes.AddOrReplaceEntry(pEntry); } } } } // Initialize the byType lists for (i = 0; i < m_AllTypes.GetCount(); i++) { CDesignType *pEntry = m_AllTypes.GetEntry(i); m_ByType[pEntry->GetType()].AddEntry(pEntry); } // Now call Bind on all active design entries for (i = 0; i < m_AllTypes.GetCount(); i++) { CDesignType *pEntry = m_AllTypes.GetEntry(i); if (error = pEntry->BindDesign(Ctx)) return error; } // Check to make sure we have at least one topology node if (m_pTopology->GetRootNodeCount() == 0) { Ctx.sError = CONSTLIT("No topology nodes found"); return ERR_FAIL; } return NOERROR; }