BOOL C4GameObjects::Save(const char *szFilename, BOOL fSaveGame, bool fSaveInactive) { // Enumerate Enumerate(); InactiveObjects.Enumerate(); Game.ScriptEngine.Strings.EnumStrings(); // Decompile objects to buffer StdStrBuf Buffer; bool fSuccess = DecompileToBuf_Log<StdCompilerINIWrite>( mkParAdapt(*this, false, !fSaveGame), &Buffer, szFilename); // Decompile inactives if (fSaveInactive) { StdStrBuf InactiveBuffer; fSuccess &= DecompileToBuf_Log<StdCompilerINIWrite>( mkParAdapt(InactiveObjects, false, !fSaveGame), &InactiveBuffer, szFilename); Buffer.Append("\r\n"); Buffer.Append(InactiveBuffer); } // Denumerate InactiveObjects.Denumerate(); Denumerate(); // Error? if (!fSuccess) return FALSE; // Write return Buffer.SaveToFile(szFilename); }
bool C4TextureMap::SaveMap(C4Group &hGroup, const char *szEntryName) { #ifdef C4ENGINE // build file in memory StdStrBuf sTexMapFile; // add desc sTexMapFile.Append("# Automatically generated texture map" LineFeed); sTexMapFile.Append("# Contains material-texture-combinations added at runtime" LineFeed); // add overload-entries if (fOverloadMaterials) sTexMapFile.Append("# Import materials from global file as well" LineFeed "OverloadMaterials" LineFeed); if (fOverloadTextures) sTexMapFile.Append("# Import textures from global file as well" LineFeed "OverloadTextures" LineFeed); sTexMapFile.Append(LineFeed); // add entries for (int32_t i = 0; i < C4M_MaxTexIndex; i++) if (!Entry[i].isNull()) { // compose line sTexMapFile.AppendFormat("%d=%s-%s" LineFeed, i, Entry[i].GetMaterialName(), Entry[i].GetTextureName()); } // create new buffer allocated with new [], because C4Group cannot handle StdStrBuf-buffers size_t iBufSize = sTexMapFile.getLength(); BYTE *pBuf = new BYTE[iBufSize]; memcpy(pBuf, sTexMapFile.getData(), iBufSize); // add to group bool fSuccess = !!hGroup.Add(szEntryName, pBuf, iBufSize, false, true); if (!fSuccess) delete [] pBuf; // done return fSuccess; #else return FALSE; #endif }
bool C4DownloadDlg::DownloadFile(const char *szDLType, C4GUI::Screen *pScreen, const char *szURL, const char *szSaveAsFilename, const char *szNotFoundMessage) { // log it LogF(LoadResStr("IDS_PRC_DOWNLOADINGFILE"), szURL); // show download dialog C4DownloadDlg *pDlg = new C4DownloadDlg(szDLType); if (!pDlg->ShowModal(pScreen, szURL, szSaveAsFilename)) { // show an appropriate error const char *szError = pDlg->GetError(); if (!szError || !*szError) szError = LoadResStr("IDS_PRC_UNKOWNERROR"); StdStrBuf sError; sError.Format(LoadResStr("IDS_PRC_DOWNLOADERROR"), GetFilename(szURL), szError); // it's a 404: display extended message if (SSearch(szError, "404") && szNotFoundMessage) { sError.Append("|"); sError.Append(szNotFoundMessage); } // display message pScreen->ShowMessageModal(sError.getData(), FormatString(LoadResStr("IDS_CTL_DL_TITLE"), szDLType).getData(), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Error, NULL); delete pDlg; return false; } LogF(LoadResStr("IDS_PRC_DOWNLOADCOMPLETE"), szURL); delete pDlg; return true; }
void C4GameSave::WriteDescPlayers(StdStrBuf &sBuf, bool fByTeam, int32_t idTeam) { // write out all players; only if they match the given team if specified C4PlayerInfo *pPlr; bool fAnyPlrWritten = false; for (int i = 0; (pPlr = Game.PlayerInfos.GetPlayerInfoByIndex(i)); i++) if (pPlr->HasJoined() && !pPlr->IsRemoved() && !pPlr->IsInvisible()) { if (fByTeam) { if (idTeam) { // match team if (pPlr->GetTeam() != idTeam) continue; } else { // must be in no known team if (Game.Teams.GetTeamByID(pPlr->GetTeam())) continue; } } if (fAnyPlrWritten) sBuf.Append(", "); else if (fByTeam && idTeam) { C4Team *pTeam = Game.Teams.GetTeamByID(idTeam); if (pTeam) sBuf.AppendFormat("%s: ", pTeam->GetName()); } sBuf.Append(pPlr->GetName()); fAnyPlrWritten = true; } if (fAnyPlrWritten) WriteDescLineFeed(sBuf); }
void C4GameSave::WriteDescDefinitions(StdStrBuf &sBuf) { // Definition specs if (Game.DefinitionFilenames[0]) { char szDef[_MAX_PATH+1]; // Desc sBuf.Append(LoadResStr("IDS_DESC_DEFSPECS")); // Get definition modules for (int cnt=0; SGetModule(Game.DefinitionFilenames,cnt,szDef); cnt++) { // Get exe relative path StdStrBuf sDefFilename; sDefFilename.Copy(Config.AtRelativePath(szDef)); // Convert rtf backslashes sDefFilename.Replace("\\", "\\\\"); // Append comma if (cnt>0) sBuf.Append(", "); // Apend to desc sBuf.Append(sDefFilename); } // End of line WriteDescLineFeed(sBuf); } }
StdStrBuf C4FileSelDlg::GetSelection(const char *szFixedSelection, bool fFilenameOnly) const { StdStrBuf sResult; if (!IsMultiSelection()) { // get single selected file for single selection dlg if (pSelection) sResult.Copy(fFilenameOnly ? GetFilename(pSelection->GetFilename()) : pSelection->GetFilename()); } else { // force fixed selection first if (szFixedSelection) sResult.Append(szFixedSelection); // get ';'-seperated list for multi selection dlg for (ListItem *pFileItem = static_cast<ListItem *>(pFileListBox->GetFirst()); pFileItem; pFileItem = static_cast<ListItem *>(pFileItem->GetNext())) if (pFileItem->IsChecked()) { const char *szAppendFilename = pFileItem->GetFilename(); if (fFilenameOnly) szAppendFilename = GetFilename(szAppendFilename); // prevent adding entries twice (especially those from the fixed // selection list) if (!SIsModule(sResult.getData(), szAppendFilename)) { if (sResult.getLength()) sResult.AppendChar(';'); sResult.Append(szAppendFilename); } } } return sResult; }
void C4Def::LoadMeshMaterials(C4Group &hGroup, C4DefGraphicsPtrBackup *gfx_backup) { // Load all mesh materials from this folder C4DefAdditionalResourcesLoader loader(hGroup); hGroup.ResetSearch(); char MaterialFilename[_MAX_PATH + 1]; *MaterialFilename = 0; for (const auto &mat : mesh_materials) { ::MeshMaterialManager.Remove(mat, &gfx_backup->GetUpdater()); } mesh_materials.clear(); while (hGroup.FindNextEntry(C4CFN_DefMaterials, MaterialFilename, NULL, !!*MaterialFilename)) { StdStrBuf material; if (hGroup.LoadEntryString(MaterialFilename, &material)) { try { StdStrBuf buf; buf.Copy(hGroup.GetName()); buf.Append("/"); buf.Append(MaterialFilename); auto new_materials = ::MeshMaterialManager.Parse(material.getData(), buf.getData(), loader); mesh_materials.insert(new_materials.begin(), new_materials.end()); } catch (const StdMeshMaterialError& ex) { DebugLogF("Failed to read material script: %s", ex.what()); } } } }
bool C4GameSave::SaveDesc(C4Group &hToGroup) { // Unfortunately, there's no way to prealloc the buffer in an appropriate size StdStrBuf sBuffer; // Header sBuffer.AppendFormat("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1031{\\fonttbl {\\f0\\fnil\\fcharset%d Times New Roman;}}", 0 /*FIXME: a number for UTF-8 here*/); sBuffer.Append(LineFeed); // Scenario title sBuffer.AppendFormat("\\uc1\\pard\\ulnone\\b\\f0\\fs20 %s\\par",Game.ScenarioTitle.getData()); sBuffer.Append(LineFeed "\\b0\\fs16\\par" LineFeed); // OK; each specializations has its own desc format WriteDesc(sBuffer); // End of file sBuffer.Append(LineFeed "}" LineFeed); // Generate Filename StdStrBuf sFilename; char szLang[3]; SCopyUntil(Config.General.Language, szLang, ',', 2); sFilename.Format(C4CFN_ScenarioDesc,szLang); // Save to file return !!hToGroup.Add(sFilename.getData(),sBuffer,false,true); }
C4DefGraphicsPtrBackup::C4DefGraphicsPtrBackup(C4DefGraphics *pSourceGraphics): MeshMaterialUpdate(::MeshMaterialManager), pMeshUpdate(NULL) { // assign graphics + def pGraphicsPtr = pSourceGraphics; pDef = pSourceGraphics->pDef; // assign name const char *szName = pGraphicsPtr->GetName(); if (szName) SCopy(szName, Name, C4MaxName); else *Name=0; // Remove all mesh materials that were loaded from this definition for(StdMeshMatManager::Iterator iter = ::MeshMaterialManager.Begin(); iter != MeshMaterialManager.End(); ) { StdStrBuf Filename; Filename.Copy(pDef->Filename); Filename.Append("/"); Filename.Append(GetFilename(iter->FileName.getData())); if(Filename == iter->FileName) iter = ::MeshMaterialManager.Remove(iter, &MeshMaterialUpdate); else ++iter; } // assign mesh update if(pSourceGraphics->Type == C4DefGraphics::TYPE_Mesh) pMeshUpdate = new StdMeshUpdate(*pSourceGraphics->Mesh); // create next graphics recursively C4DefGraphics *pNextGfx = pGraphicsPtr->pNext; if (pNextGfx) pNext = new C4DefGraphicsPtrBackup(pNextGfx); else pNext = NULL; }
StdStrBuf C4Shader::Build(const ShaderSliceList &Slices, bool fDebug) { // At the start of the shader set the #version and number of // available uniforms StdStrBuf Buf; #ifndef USE_CONSOLE GLint iMaxFrags = 0, iMaxVerts = 0; glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &iMaxFrags); glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &iMaxVerts); #else int iMaxFrags = INT_MAX, iMaxVerts = INT_MAX; #endif Buf.Format("#version %d\n" "#define MAX_FRAGMENT_UNIFORM_COMPONENTS %d\n" "#define MAX_VERTEX_UNIFORM_COMPONENTS %d\n", C4Shader_Version, iMaxFrags, iMaxVerts); // Put slices int iPos = -1, iNextPos = -1; do { iPos = iNextPos; iNextPos = C4Shader_LastPosition+1; // Add all slices at the current level if (fDebug && iPos > 0) Buf.AppendFormat("\t// Position %d:\n", iPos); for (ShaderSliceList::const_iterator pSlice = Slices.begin(); pSlice != Slices.end(); pSlice++) { if (pSlice->Position < iPos) continue; if (pSlice->Position > iPos) { iNextPos = Min(iNextPos, pSlice->Position); continue; } // Same position - add slice! if (fDebug) { if (pSlice->Source.getLength()) Buf.AppendFormat("\t// Slice from %s:\n", pSlice->Source.getData()); else Buf.Append("\t// Built-in slice:\n"); } Buf.Append(pSlice->Text); if (Buf[Buf.getLength()-1] != '\n') Buf.AppendChar('\n'); } // Add seperator - only priority (-1) is top-level if (iPos == -1) { Buf.Append("void main() {\n"); } } while (iNextPos <= C4Shader_LastPosition); // Terminate Buf.Append("}\n"); return Buf; }
void C4GameSave::WriteDescNetworkClients(StdStrBuf &sBuf) { // Desc sBuf.Append(LoadResStr("IDS_DESC_CLIENTS")); // Client names for (C4Network2Client *pClient=::Network.Clients.GetNextClient(nullptr); pClient; pClient=::Network.Clients.GetNextClient(pClient)) { sBuf.Append(", "); sBuf.Append(pClient->getName()); } // End of line WriteDescLineFeed(sBuf); }
StdStrBuf C4Playback::ReWriteText() { // Would work, too, but is currently too slow due to bad buffering inside // StdCompilerINIWrite: // return // DecompileToBuf<StdCompilerINIWrite>(mkNamingAdapt(mkSTLContainerAdapt(chunks), // "Rec")); StdStrBuf Output; for (chunks_t::const_iterator i = chunks.begin(); i != chunks.end(); i++) { Output.Append( static_cast<const StdStrBuf &>(DecompileToBuf<StdCompilerINIWrite>( mkNamingAdapt(mkDecompileAdapt(*i), "Rec")))); Output.Append("\n\n"); } return Output; }
StdStrBuf C4MusicFileOgg::GetDebugInfo() const { StdStrBuf result; result.Append(FileName); result.AppendFormat("[%.0lf]", last_playback_pos_sec); result.AppendChar('['); bool sec = false; for (auto i = categories.cbegin(); i != categories.cend(); ++i) { if (sec) result.AppendChar(','); result.Append(i->getData()); sec = true; } result.AppendChar(']'); return result; }
bool C4PlayerInfoCore::Load(C4Group &hGroup) { // New version StdStrBuf Source; if (hGroup.LoadEntryString(C4CFN_PlayerInfoCore,&Source)) { // Compile StdStrBuf GrpName = hGroup.GetFullName(); GrpName.Append(DirSep C4CFN_PlayerInfoCore); if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(*this, Source, GrpName.getData())) return false; // Pref for AutoContextMenus is still undecided: default by player's control style if (OldPrefAutoContextMenu == -1) OldPrefAutoContextMenu = OldPrefControlStyle; // Determine true color from indexed pref color if (!PrefColorDw) PrefColorDw = GetPrefColorValue(PrefColor); // Validate colors PrefColorDw &= 0xffffff; PrefColor2Dw &= 0xffffff; // Validate name C4Markup::StripMarkup(PrefName); // Success return true; } // Old version no longer supported - sorry return false; }
void C4Console::PlayerJoin() { // Get player file name(s) StdCopyStrBuf c4pfile(""); if (!FileSelect(&c4pfile, "OpenClonk Player\0*.ocp\0\0", OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_EXPLORER )) return; // Multiple players if (DirectoryExists(c4pfile.getData())) { const char *cptr = c4pfile.getData() + SLen(c4pfile.getData()) + 1; while (*cptr) { StdStrBuf f; f.Copy(c4pfile.getData()); f.AppendBackslash(); f.Append(cptr); cptr += SLen(cptr)+1; ::Players.JoinNew(f.getData()); } } // Single player else { ::Players.JoinNew(c4pfile.getData()); } }
void C4GameSave::WriteDescPlayers(StdStrBuf &sBuf) { // New style using Game.PlayerInfos if (Game.PlayerInfos.GetPlayerCount()) { sBuf.Append(LoadResStr("IDS_DESC_PLRS")); if (Game.Teams.IsMultiTeams() && !Game.Teams.IsAutoGenerateTeams()) { // Teams defined: Print players sorted by teams WriteDescLineFeed(sBuf); C4Team *pTeam; int32_t i=0; while ((pTeam = Game.Teams.GetTeamByIndex(i++))) { WriteDescPlayers(sBuf, true, pTeam->GetID()); } // Finally, print out players outside known teams (those can only be achieved by script using SetPlayerTeam) WriteDescPlayers(sBuf, true, 0); } else { // No teams defined: Print all players that have ever joined WriteDescPlayers(sBuf, false, 0); } } }
void C4DefGraphicsPtrBackup::Add(C4DefGraphics* pGfx) { for(C4DefGraphics* pCur = pGfx; pCur != NULL; pCur = pCur->pNext) Entries.push_back(new C4DefGraphicsPtrBackupEntry(pCur)); // Remove all mesh materials that were loaded from this definition C4Def* pDef = pGfx->pDef; for(StdMeshMatManager::Iterator iter = ::MeshMaterialManager.Begin(); iter != MeshMaterialManager.End(); ) { StdStrBuf Filename; Filename.Copy(pDef->Filename); Filename.Append("/"); Filename.Append(GetFilename(iter->FileName.getData())); if(Filename == iter->FileName) iter = ::MeshMaterialManager.Remove(iter, &MeshMaterialUpdate); else ++iter; } }
bool C4Network2Res::SetByCore(const C4Network2ResCore &nCore, bool fSilent, const char *szAsFilename, int32_t iRecursion) // by main thread { StdStrBuf sFilename; // try open local file const char *szFilename = szAsFilename ? szAsFilename : GetC4Filename(nCore.getFileName()); if (SetByFile(szFilename, false, nCore.getType(), nCore.getID(), nCore.getFileName(), fSilent)) { // check contents checksum if (Core.getContentsCRC() == nCore.getContentsCRC()) { // set core fDirty = true; Core = nCore; // ok then return true; } } // get and search for filename without specified folder (e.g., Castle.ocs when the opened game is Easy.ocf\Castle.ocs) const char *szFilenameOnly = GetFilename(szFilename); const char *szFilenameC4 = GetC4Filename(szFilename); if (szFilenameOnly != szFilenameC4) { sFilename.Copy(szFilename, SLen(szFilename) - SLen(szFilenameC4)); sFilename.Append(szFilenameOnly); if (SetByCore(nCore, fSilent, szFilenameOnly, Config.Network.MaxResSearchRecursion)) return true; } // if it could still not be set, try within all folders of root (ignoring special folders), and try as file outside the folder // but do not recurse any deeper than set by config (default: One folder) if (iRecursion >= Config.Network.MaxResSearchRecursion) return false; StdStrBuf sSearchPath; const char *szSearchPath; if (!iRecursion) szSearchPath = Config.General.ExePath.getData(); else { sSearchPath.Copy(szFilename, SLen(szFilename) - SLen(szFilenameC4)); szSearchPath = sSearchPath.getData(); } StdStrBuf sNetPath; sNetPath.Copy(Config.Network.WorkPath); char *szNetPath = sNetPath.GrabPointer(); TruncateBackslash(szNetPath); sNetPath.Take(szNetPath); for (DirectoryIterator i(szSearchPath); *i; ++i) if (DirectoryExists(*i)) if (!*GetExtension(*i)) // directories without extension only if (!szNetPath || !*szNetPath || !ItemIdentical(*i, szNetPath)) // ignore network path { // search for complete name at subpath (e.g. MyFolder\Easy.ocf\Castle.ocs) sFilename.Format("%s%c%s", *i, DirectorySeparator, szFilenameC4); if (SetByCore(nCore, fSilent, sFilename.getData(), iRecursion + 1)) return true; } // file could not be found locally return false; }
bool C4GameSave::SaveDesc(C4Group &hToGroup) { // Unfortunately, there's no way to prealloc the buffer in an appropriate size StdStrBuf sBuffer; // Scenario title sBuffer.Append(Game.ScenarioTitle.getData()); sBuffer.Append("\n\n"); // OK; each specializations has its own desc format WriteDesc(sBuffer); // Generate Filename StdStrBuf sFilename; char szLang[3]; SCopyUntil(Config.General.Language, szLang, ',', 2); sFilename.Format(C4CFN_ScenarioDesc,szLang); // Save to file return !!hToGroup.Add(sFilename.getData(),sBuffer,false,true); }
bool C4VectorFont::Init(C4Group &hGrp, const char *szFilename, C4Config &rCfg) { // name by file Name.Copy(GetFilenameOnly(szFilename)); #if defined(_WIN32) && !defined(HAVE_FREETYPE) // check whether group is directory or packed if (!hGrp.IsPacked()) { // it's open: use the file directly SCopy(hGrp.GetFullName().getData(), FileName, _MAX_PATH); AppendBackslash(FileName); SAppend(szFilename, FileName); if (!FileExists(FileName)) { *FileName=0; return false; } fIsTempFile = false; } else { // it's packed: extract to temp path SCopy(rCfg.AtTempPath(szFilename), FileName, _MAX_PATH); // make sure the filename is not in use, in case multiple instances of the engine are run if (FileExists(FileName)) { RemoveExtension(FileName); StdStrBuf sNewFilename; for (int i=0; i<1000; ++i) { sNewFilename.Format("%s%x", FileName, (int)rand()); if (*GetExtension(szFilename)) { sNewFilename.AppendChar('.'); sNewFilename.Append(GetExtension(szFilename)); } if (!FileExists(sNewFilename.getData())) break; } SCopy(sNewFilename.getData(), FileName, _MAX_PATH); } if (!hGrp.ExtractEntry(szFilename, FileName)) { *FileName=0; return false; } fIsTempFile = true; } // add the font resource //if (!AddFontResourceEx(FileName, FR_PRIVATE, NULL)) requires win2k if (!AddFontResource(FileName)) { if (fIsTempFile) EraseFile(FileName); *FileName='\0'; return false; } #else if (!hGrp.LoadEntry(szFilename, Data)) return false; #endif // success return true; }
bool LogFatal(const char *szMessage) { if (!szMessage) szMessage = "(null)"; // add to fatal error message stack - if not already in there (avoid duplication) if (!SSearch(sFatalError.getData(), szMessage)) { if (!sFatalError.isNull()) sFatalError.AppendChar('|'); sFatalError.Append(szMessage); } // write to log - note that Log might overwrite a static buffer also used in szMessage return !!Log(FormatString(LoadResStr("IDS_ERR_FATAL"), szMessage).getData()); }
StdStrBuf C4PropListStatic::GetDataString() const { StdStrBuf r; if (Parent) { r.Take(Parent->GetDataString()); r.AppendChar('.'); } assert(ParentKeyName); if (ParentKeyName) r.Append(ParentKeyName->GetData()); return r; }
StdStrBuf C4KeyCodeEx::ToString(bool fHumanReadable, bool fShort) const { static StdStrBuf sResult; sResult.Clear(); // Add shift for (DWORD dwShiftCheck = KEYS_First; dwShiftCheck <= KEYS_Max; dwShiftCheck <<= 1) if (dwShiftCheck & dwShift) { sResult.Append(KeyShift2String((C4KeyShiftState) dwShiftCheck)); sResult.AppendChar('+'); } // Add key if (sResult.getLength()) { sResult.Append(KeyCode2String(Key, fHumanReadable, fShort)); return sResult; } else { return KeyCode2String(Key, fHumanReadable, fShort); } }
StdStrBuf C4ObjectList::GetNameList(C4DefList &rDefs) const { int cpos,idcount; C4ID c_id; C4Def *cdef; StdStrBuf Buf; for (cpos=0; (c_id=GetListID(C4D_All,cpos)); cpos++) if ((cdef=rDefs.ID2Def(c_id))) { idcount=ObjectCount(c_id); if (cpos>0) Buf.Append(", "); Buf.AppendFormat("%dx %s",idcount,cdef->GetName()); } return Buf; }
StdStrBuf C4Team::GetNameWithParticipants() const { // compose team name like "Team 1 (boni, GhostBear, Clonko)" // or just "Team 1" for empty team StdStrBuf sTeamName; sTeamName.Copy(GetName()); if (GetPlayerCount()) { sTeamName.Append(" ("); int32_t iTeamPlrCount=0; for (int32_t j=0; j<GetPlayerCount(); ++j) { int32_t iPlr = GetIndexedPlayer(j); C4PlayerInfo *pPlrInfo; if (iPlr) if ((pPlrInfo = Game.PlayerInfos.GetPlayerInfoByID(iPlr))) { if (iTeamPlrCount++) sTeamName.Append(", "); sTeamName.Append(pPlrInfo->GetName()); } } sTeamName.AppendChar(')'); } return sTeamName; }
void C4RTFFile::ParseChars(StdStrBuf &sResult, const char *szChars) { // route the characters to the appropriate destination stream. switch (pState->dest) { case dsNormal: // process characters: Append to result buffer sResult.Append(szChars); break; case dsSkip: // skip character break; } }
bool C4MusicSystem::InitForScenario(C4Group & hGroup) { // check if the scenario contains music bool fLocalMusic = false; StdStrBuf MusicDir; if (GrpContainsMusic(hGroup)) { // clear global songs ClearSongs(); fLocalMusic = true; // add songs MusicDir.Take(Game.ScenarioFile.GetFullName()); LoadDir(MusicDir.getData()); // log LogF(LoadResStr("IDS_PRC_LOCALMUSIC"), MusicDir.getData()); } // check for music folders in group set C4Group *pMusicFolder = NULL; while ((pMusicFolder = Game.GroupSet.FindGroup(C4GSCnt_Music, pMusicFolder))) { if (!fLocalMusic) { // clear global songs ClearSongs(); fLocalMusic = true; } // add songs MusicDir.Take(pMusicFolder->GetFullName()); MusicDir.AppendChar(DirectorySeparator); MusicDir.Append(C4CFN_Music); LoadDir(MusicDir.getData()); // log LogF(LoadResStr("IDS_PRC_LOCALMUSIC"), MusicDir.getData()); } // no music? if (!SongCount) return false; // set play list SetPlayList(0); // ok return true; }
void C4StartupNetListEntry::SetReference(C4Network2Reference *pRef) { // safety: clear previous ClearRef(); // set info this->pRef = pRef; int32_t iIcon = pRef->getIcon(); if (!Inside<int32_t>(iIcon, 0, C4StartupScenSel_IconCount-1)) iIcon = C4StartupScenSel_DefaultIcon_Scenario; pIcon->SetFacet(C4Startup::Get()->Graphics.fctScenSelIcons.GetPhase(iIcon)); pIcon->SetAnimated(false, 0); pIcon->SetBounds(rctIconSmall); int32_t iPlrCnt = pRef->isEditor() ? pRef->Parameters.PlayerInfos.GetActivePlayerCount(false) : pRef->Parameters.Clients.getClientCnt(); C4Client *pHost = pRef->Parameters.Clients.getHost(); sInfoText[0].Format(LoadResStr("IDS_NET_REFONCLIENT"), pRef->getTitle(), pHost ? pHost->getName() : "unknown"); if (pRef->isEditor()) { sInfoText[1].Format(LoadResStr("IDS_NET_INFOEDITOR"), (int)iPlrCnt, StdStrBuf(pRef->getGameStatus().getDescription(), true).getData()); } else { sInfoText[1].Format(LoadResStr("IDS_NET_INFOPLRSGOALDESC"), (int)iPlrCnt, (int)pRef->Parameters.MaxPlayers, pRef->getGameGoalString().getData(), StdStrBuf(pRef->getGameStatus().getDescription(), true).getData()); } if (pRef->getTime() > 0) { StdStrBuf strDuration; strDuration.Format("%02d:%02d:%02d", pRef->getTime()/3600, (pRef->getTime() % 3600) / 60, pRef->getTime() % 60); sInfoText[1].Append(" - "); sInfoText[1].Append(strDuration); } sInfoText[2].Format(LoadResStr("IDS_DESC_VERSION"), pRef->getGameVersion().GetString().getData()); sInfoText[3].Format("%s: %s", LoadResStr("IDS_CTL_COMMENT"), pRef->getComment()); StdStrBuf sAddress; for (int i=0; i<pRef->getAddrCnt(); ++i) { if (i) sAddress.Append(", "); sAddress.Append(pRef->getAddr(i).toString()); } // editor reference if (pRef->isEditor()) AddStatusIcon(C4GUI::Ico_Editor, LoadResStr("IDS_CNS_CONSOLE")); // password if (pRef->isPasswordNeeded()) AddStatusIcon(C4GUI::Ico_Ex_LockedFrontal, LoadResStr("IDS_NET_INFOPASSWORD")); // league if (pRef->Parameters.isLeague()) AddStatusIcon(C4GUI::Ico_Ex_League, pRef->Parameters.getLeague()); // lobby active if (pRef->getGameStatus().isLobbyActive()) AddStatusIcon(C4GUI::Ico_Lobby, LoadResStr("IDS_DESC_EXPECTING")); // game running if (pRef->getGameStatus().isPastLobby()) AddStatusIcon(C4GUI::Ico_GameRunning, LoadResStr("IDS_NET_INFOINPROGR")); // runtime join if (pRef->isJoinAllowed() && pRef->getGameStatus().isPastLobby()) // A little workaround to determine RuntimeJoin... AddStatusIcon(C4GUI::Ico_RuntimeJoin, LoadResStr("IDS_NET_RUNTIMEJOINFREE")); // official server if (pRef->isOfficialServer() && !Config.Network.UseAlternateServer) // Offical server icon is only displayed if references are obtained from official league server { fIsImportant = true; AddStatusIcon(C4GUI::Ico_OfficialServer, LoadResStr("IDS_NET_OFFICIALSERVER")); } // list participating player/client names if (pRef->isEditor()) { sInfoText[4].Format("%s%s", LoadResStr("IDS_DESC_CLIENTS"), iPlrCnt ? pRef->Parameters.Clients.GetAllClientNames().getData() : LoadResStr("IDS_CTL_NONE")); } else { sInfoText[4].Format("%s: %s", LoadResStr("IDS_CTL_PLAYER"), iPlrCnt ? pRef->Parameters.PlayerInfos.GetActivePlayerNames(false).getData() : LoadResStr("IDS_CTL_NONE")); } // disabled if join is not possible for some reason C4GameVersion verThis; if (!pRef->isJoinAllowed() || !(pRef->getGameVersion() == verThis)) { fIsEnabled = false; } // store sort order iSortOrder = pRef->getSortOrder(); // all references expire after a while SetTimeout(TT_Reference); UpdateSmallState(); UpdateText(); }
BOOL C4PropertyDlg::Update() { if (!Active) return FALSE; StdStrBuf Output; idSelectedDef = C4ID_None; // Compose info text by selected object(s) switch (Selection.ObjectCount()) { // No selection case 0: Output = LoadResStr("IDS_CNS_NOOBJECT"); break; // One selected object case 1: { C4Object *cobj = Selection.GetObject(); // Type Output.AppendFormat(LoadResStr("IDS_CNS_TYPE"), cobj->GetName(), C4IdText(cobj->Def->id)); // Owner if (ValidPlr(cobj->Owner)) { Output.Append(LineFeed); Output.AppendFormat(LoadResStr("IDS_CNS_OWNER"), Game.Players.Get(cobj->Owner)->GetName()); } // Contents if (cobj->Contents.ObjectCount()) { Output.Append(LineFeed); Output.Append(LoadResStr("IDS_CNS_CONTENTS")); Output.Append(static_cast<const StdStrBuf &>( cobj->Contents.GetNameList(Game.Defs))); } // Action if (cobj->Action.Act != ActIdle) { Output.Append(LineFeed); Output.Append(LoadResStr("IDS_CNS_ACTION")); Output.Append(cobj->Def->ActMap[cobj->Action.Act].Name); } // Locals int cnt; bool fFirstLocal = true; for (cnt = 0; cnt < cobj->Local.GetSize(); cnt++) if (!!cobj->Local[cnt]) { // Header if (fFirstLocal) { Output.Append(LineFeed); Output.Append(LoadResStr("IDS_CNS_LOCALS")); fFirstLocal = false; } Output.Append(LineFeed); // Append id Output.AppendFormat(" Local(%d) = ", cnt); // write value Output.Append( static_cast<const StdStrBuf &>(cobj->Local[cnt].GetDataString())); } // Locals (named) for (cnt = 0; cnt < cobj->LocalNamed.GetAnzItems(); cnt++) { // Header if (fFirstLocal) { Output.Append(LineFeed); Output.Append(LoadResStr("IDS_CNS_LOCALS")); fFirstLocal = false; } Output.Append(LineFeed); // Append name Output.AppendFormat(" %s = ", cobj->LocalNamed.pNames->pNames[cnt]); // write value Output.Append(static_cast<const StdStrBuf &>( cobj->LocalNamed.pData[cnt].GetDataString())); } // Effects for (C4Effect *pEffect = cobj->pEffects; pEffect; pEffect = pEffect->pNext) { // Header if (pEffect == cobj->pEffects) { Output.Append(LineFeed); Output.Append(LoadResStr("IDS_CNS_EFFECTS")); } Output.Append(LineFeed); // Effect name Output.AppendFormat(" %s: Interval %d", pEffect->Name, pEffect->iIntervall); } // Store selected def idSelectedDef = cobj->id; break; } // Multiple selected objects default: Output.Format(LoadResStr("IDS_CNS_MULTIPLEOBJECTS"), Selection.ObjectCount()); break; } // Update info edit control #ifdef WITH_DEVELOPER_MODE GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); gtk_text_buffer_set_text( buffer, C4Language::IconvUtf8(Output.getData()).getData(), -1); #endif return TRUE; }
void C4GameSave::WriteDescLineFeed(StdStrBuf &sBuf) { // paragraph end + cosmetics sBuf.Append("\n\n"); }