diff --git a/planet/System.ocg/LanguageDE.txt b/planet/System.ocg/LanguageDE.txt
index 29c53a4cc..72f3f7525 100644
--- a/planet/System.ocg/LanguageDE.txt
+++ b/planet/System.ocg/LanguageDE.txt
@@ -523,6 +523,7 @@ IDS_MNU_DEFAULTRESOLUTION=Bildschirm
IDS_MNU_DELETE=Löschen
IDS_MNU_DUPLICATE=Duplizieren
IDS_MNU_EXPLOREUSERPATH=Benutzerpfad anzeigen
+IDS_MNU_EXPORTSCENARIOPACKED=Gepackt exportieren...
IDS_MNU_FILE=Datei
IDS_MNU_FOCUSGLOBALSCRIPTBOX=Eingabefokus auf Scripteingabe (global)
IDS_MNU_FOCUSOBJECTSCRIPTBOX=Eingabefokus auf Scripteingabe (Objekt)
diff --git a/planet/System.ocg/LanguageUS.txt b/planet/System.ocg/LanguageUS.txt
index a504ddfc3..f87a76394 100644
--- a/planet/System.ocg/LanguageUS.txt
+++ b/planet/System.ocg/LanguageUS.txt
@@ -523,6 +523,7 @@ IDS_MNU_DEFAULTRESOLUTION=Screen
IDS_MNU_DELETE=Delete
IDS_MNU_DUPLICATE=Duplicate
IDS_MNU_EXPLOREUSERPATH=Open user path
+IDS_MNU_EXPORTSCENARIOPACKED=Pack and export...
IDS_MNU_FILE=File
IDS_MNU_FOCUSGLOBALSCRIPTBOX=Focus script box (global)
IDS_MNU_FOCUSOBJECTSCRIPTBOX=Focus script box (object)
diff --git a/src/editor/C4Console.cpp b/src/editor/C4Console.cpp
index b40a42291..75976cde1 100644
--- a/src/editor/C4Console.cpp
+++ b/src/editor/C4Console.cpp
@@ -151,12 +151,33 @@ bool C4Console::SaveGame(const char * path)
return fOkay;
}
-bool C4Console::SaveScenario(const char * path)
+bool C4Console::SaveScenario(const char * path, bool export_packed)
{
- // Open new scenario file
- if (path)
+ C4Group *save_target_group = &Game.ScenarioFile;
+ C4Group export_group;
+ if (export_packed)
{
- // Close current scenario file
+ // Export to packed file: Delete existing
+ if (FileExists(path))
+ {
+ if (ItemIdentical(Game.ScenarioFilename, path) || !EraseItem(path))
+ {
+ Message(FormatString(LoadResStr("IDS_CNS_SAVEASERROR"), path).getData());
+ return false;
+ }
+ }
+ // Write into new, packed copy
+ if (!C4Group_PackDirectoryTo(Game.ScenarioFilename, path) || !export_group.Open(path))
+ {
+ Message(FormatString(LoadResStr("IDS_CNS_SAVEASERROR"), path).getData());
+ return false;
+ }
+ save_target_group = &export_group;
+ }
+ else if (path)
+ {
+ // Open new scenario file
+ // Close current scenario file to allow re-opening at new path
Game.ScenarioFile.Close();
// Copy current scenario file to target
if (!C4Group_CopyItem(Game.ScenarioFilename,path))
@@ -164,6 +185,7 @@ bool C4Console::SaveScenario(const char * path)
Message(FormatString(LoadResStr("IDS_CNS_SAVEASERROR"),path).getData());
return false;
}
+ // Re-open at new path (unless exporting, in which case the export is just a copy)
SCopy(path, Game.ScenarioFilename, _MAX_PATH);
SetCaptionToFilename(Game.ScenarioFilename);
if (!Game.ScenarioFile.Open(Game.ScenarioFilename))
@@ -183,11 +205,11 @@ bool C4Console::SaveScenario(const char * path)
}
// Can't save to child groups
- if (Game.ScenarioFile.GetMother() && Game.ScenarioFile.GetMother()->IsPacked())
+ if (save_target_group->GetMother() && save_target_group->GetMother()->IsPacked())
{
StdStrBuf str;
str.Format(LoadResStr("IDS_CNS_NOCHILDSAVE"),
- GetFilename(Game.ScenarioFile.GetName()));
+ GetFilename(save_target_group->GetName()));
Message(str.getData());
return false;
}
@@ -197,15 +219,22 @@ bool C4Console::SaveScenario(const char * path)
bool fOkay=true;
C4GameSave *pGameSave = new C4GameSaveScenario(!Console.Active || ::Landscape.GetMode() == LandscapeMode::Exact, false);
- if (!pGameSave->Save(Game.ScenarioFile, false))
+ if (!pGameSave->Save(*save_target_group, false))
{ Out("Game::Save failed"); fOkay=false; }
delete pGameSave;
// Close and reopen scenario file to fix file changes
- if (!Game.ScenarioFile.Close())
- { Out("ScenarioFile::Close failed"); fOkay=false; }
- if (!Game.ScenarioFile.Open(Game.ScenarioFilename))
- { Out("ScenarioFile::Open failed"); fOkay=false; }
+ if (!export_packed)
+ {
+ if (!Game.ScenarioFile.Close())
+ {
+ Out("ScenarioFile::Close failed"); fOkay = false;
+ }
+ if (!Game.ScenarioFile.Open(Game.ScenarioFilename))
+ {
+ Out("ScenarioFile::Open failed"); fOkay = false;
+ }
+ }
SetCursor(C4ConsoleGUI::CURSOR_Normal);
@@ -215,7 +244,7 @@ bool C4Console::SaveScenario(const char * path)
StdStrBuf str(LoadResStr("IDS_CNS_SCRIPTCREATEDOBJECTS"));
str += LoadResStr("IDS_CNS_WARNDOUBLE");
Message(str.getData());
- Game.fScriptCreatedObjects=false;
+ Game.fScriptCreatedObjects = false;
}
// Status report
@@ -232,22 +261,27 @@ bool C4Console::FileSave()
return SaveScenario(nullptr);
}
-bool C4Console::FileSaveAs(bool fSaveGame)
+bool C4Console::FileSaveAs(bool fSaveGame, bool export_packed)
{
// Do save-as dialog
StdCopyStrBuf filename("");
filename.Copy(Game.ScenarioFile.GetName());
+ if (export_packed)
+ {
+ RemoveExtension(&filename);
+ filename.Append("_packed.ocs");
+ }
if (!FileSelect(&filename,
"OpenClonk Scenario\0*.ocs\0\0",
OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY,
true)) return false;
DefaultExtension(&filename,"ocs");
- ::Config.Developer.AddRecentlyEditedScenario(filename.getData());
+ if (!export_packed) ::Config.Developer.AddRecentlyEditedScenario(filename.getData());
if (fSaveGame)
// Save game
return SaveGame(filename.getData());
else
- return SaveScenario(filename.getData());
+ return SaveScenario(filename.getData(), export_packed);
}
bool C4Console::Message(const char *szMessage, bool fQuery)
diff --git a/src/editor/C4Console.h b/src/editor/C4Console.h
index a2283c252..75a995042 100644
--- a/src/editor/C4Console.h
+++ b/src/editor/C4Console.h
@@ -73,8 +73,8 @@ public:
void HelpAbout();
bool FileSelect(StdStrBuf *sFilename, const char *szFilter, DWORD dwFlags, bool fSave=false);
bool SaveGame(const char * path);
- bool SaveScenario(const char * path);
- bool FileSaveAs(bool fSaveGame);
+ bool SaveScenario(const char * path, bool export_packed=false);
+ bool FileSaveAs(bool fSaveGame, bool export_packed=false);
bool FileSave();
bool FileNew();
bool FileOpen(const char *filename=nullptr, bool host_in_network=false);
diff --git a/src/editor/C4ConsoleQtMainWindow.ui b/src/editor/C4ConsoleQtMainWindow.ui
index 5451cd436..bfd55089a 100644
--- a/src/editor/C4ConsoleQtMainWindow.ui
+++ b/src/editor/C4ConsoleQtMainWindow.ui
@@ -346,6 +346,7 @@
+
@@ -1259,6 +1260,20 @@
IDS_MNU_OPENNET
+
+
+ IDS_MNU_EXPORTSCENARIOPACKED
+
+
+ IDS_MNU_EXPORTSCENARIOPACKED
+
+
+ IDS_MNU_EXPORTSCENARIOPACKED
+
+
+ Ctrl+Shift+E
+
+
@@ -2016,6 +2031,22 @@
+
+ actionFileExportScenarioPacked
+ triggered()
+ MainWindow
+ FileExportPacked()
+
+
+ -1
+ -1
+
+
+ 477
+ 312
+
+
+
PlayPressed(bool)
@@ -2064,5 +2095,6 @@
GradeUp()
GradeDown()
FileOpenInNetwork()
+ FileExportPacked()
diff --git a/src/editor/C4ConsoleQtState.cpp b/src/editor/C4ConsoleQtState.cpp
index 403fbe9ca..d98008b5d 100644
--- a/src/editor/C4ConsoleQtState.cpp
+++ b/src/editor/C4ConsoleQtState.cpp
@@ -342,6 +342,7 @@ void C4ConsoleQtMainWindow::FileRecord() { ::Console.FileRecord(); }
void C4ConsoleQtMainWindow::FileSave() { ::Console.FileSave(); }
void C4ConsoleQtMainWindow::FileSaveAs() { ::Console.FileSaveAs(false); }
void C4ConsoleQtMainWindow::FileSaveGameAs() { ::Console.FileSaveAs(true); }
+void C4ConsoleQtMainWindow::FileExportPacked() { ::Console.FileSaveAs(false, true); }
void C4ConsoleQtMainWindow::FileClose() { ::Console.FileClose(); }
void C4ConsoleQtMainWindow::FileQuit() { ::Console.FileQuit(); }
diff --git a/src/editor/C4ConsoleQtState.h b/src/editor/C4ConsoleQtState.h
index 894435dfb..42a53c4d5 100644
--- a/src/editor/C4ConsoleQtState.h
+++ b/src/editor/C4ConsoleQtState.h
@@ -135,6 +135,7 @@ public slots:
void FileSave();
void FileSaveAs();
void FileSaveGameAs();
+ void FileExportPacked();
void FileClose();
void FileQuit();
void FileReInitScenario();