Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Generals/Code/Tools/WorldBuilder/include/WHeightMapEdit.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class WorldHeightMapEdit : public WorldHeightMap
WorldHeightMapEdit(ChunkInputStream *pStrm); ///< read from file.
virtual ~WorldHeightMapEdit() override; ///< destroy.

Bool canSaveCliffState() const;
void saveToFile(DataChunkOutput &chunkWriter);
WorldHeightMapEdit *duplicate();

Expand Down
19 changes: 19 additions & 0 deletions Generals/Code/Tools/WorldBuilder/src/WHeightMapEdit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,21 @@ void WorldHeightMapEdit::getTexClassNeighbors(Int xIndex, Int yIndex, Int textur



Bool WorldHeightMapEdit::canSaveCliffState() const
{
#if RTS_GENERALS && RETAIL_COMPATIBLE_DATA
const Int byteWidth = (m_width + 1) / 8;
if (byteWidth < m_flipStateWidth) {
for (Int j = 0; j < m_height; j++) {
if (m_cellCliffState[j * m_flipStateWidth + byteWidth] != 0) {
return false;
}
}
}
#endif
return true;
}

//
/// SaveToFile - saves a height map to a file.
// Format is
Expand All @@ -572,6 +587,10 @@ void WorldHeightMapEdit::getTexClassNeighbors(Int xIndex, Int yIndex, Int textur
//
void WorldHeightMapEdit::saveToFile(DataChunkOutput &chunkWriter)
{
if (!canSaveCliffState()) {
throw(ERROR_CORRUPT_FILE_FORMAT);
}

// This is the chunk writer stuff.
int i;

Expand Down
9 changes: 9 additions & 0 deletions Generals/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,11 @@ BOOL CWorldBuilderDoc::DoSave(LPCTSTR lpszPathName, BOOL bReplace)
// if 'bReplace' is TRUE will change file name if successful (SaveAs)
// if 'bReplace' is FALSE will not change path name (SaveCopyAs)
{
if (m_heightMap && !m_heightMap->canSaveCliffState()) {
::AfxMessageBox("Cannot save: the retail Generals map format cannot store cliff flags at the right edge of this map. Adjust the map width before saving.");
return FALSE;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Abort Jump to Game after rejecting the save

When an existing retail Generals map with a nonzero omitted cliff byte is launched through Ctrl+J, this new FALSE return reaches OnJumpToGame, whose call to DoFileSave() at line 620 ignores the result and still executes _spawnl at line 628. The editor therefore launches the previous on-disk map immediately after reporting that the current state cannot be saved, so a playtest can run against stale terrain; make that caller abort when the save fails.

Useful? React with 👍 / 👎.

}

CString newName = lpszPathName;
if (newName.IsEmpty())
{
Expand Down Expand Up @@ -796,6 +801,10 @@ Bool CWorldBuilderDoc::ParseWaypointData(DataChunkInput &file, DataChunkInfo *in

void CWorldBuilderDoc::autoSave()
{
if (m_heightMap && !m_heightMap->canSaveCliffState()) {
return;
Comment on lines +804 to +805

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Autosave reports false success

When canSaveCliffState() rejects a map, autoSave() returns without saving, but CMainFrame::OnTimer() still displays “Auto Save Complete.” Later attempts repeat that message while the backups stay unchanged. Return a save result and show a skipped-save message when cliff flags cannot be stored. Apply this to both source copies.

}

// srj sez: put autosave into our user data folder, not the ap dir
AsciiString autosave1 = TheGlobalData->getPath_UserData();
AsciiString autosave2 = TheGlobalData->getPath_UserData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class WorldHeightMapEdit : public WorldHeightMap
WorldHeightMapEdit(ChunkInputStream *pStrm); ///< read from file.
virtual ~WorldHeightMapEdit() override; ///< destroy.

Bool canSaveCliffState() const;
void saveToFile(DataChunkOutput &chunkWriter);
WorldHeightMapEdit *duplicate();

Expand Down
19 changes: 19 additions & 0 deletions GeneralsMD/Code/Tools/WorldBuilder/src/WHeightMapEdit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,21 @@ void WorldHeightMapEdit::getTexClassNeighbors(Int xIndex, Int yIndex, Int textur



Bool WorldHeightMapEdit::canSaveCliffState() const
{
#if RTS_GENERALS && RETAIL_COMPATIBLE_DATA
const Int byteWidth = (m_width + 1) / 8;
if (byteWidth < m_flipStateWidth) {
for (Int j = 0; j < m_height; j++) {
if (m_cellCliffState[j * m_flipStateWidth + byteWidth] != 0) {
return false;
}
}
}
#endif
return true;
}

//
/// SaveToFile - saves a height map to a file.
// Format is
Expand All @@ -572,6 +587,10 @@ void WorldHeightMapEdit::getTexClassNeighbors(Int xIndex, Int yIndex, Int textur
//
void WorldHeightMapEdit::saveToFile(DataChunkOutput &chunkWriter)
{
if (!canSaveCliffState()) {
throw(ERROR_CORRUPT_FILE_FORMAT);
}

// This is the chunk writer stuff.
int i;

Expand Down
9 changes: 9 additions & 0 deletions GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,11 @@ BOOL CWorldBuilderDoc::DoSave(LPCTSTR lpszPathName, BOOL bReplace)
// if 'bReplace' is TRUE will change file name if successful (SaveAs)
// if 'bReplace' is FALSE will not change path name (SaveCopyAs)
{
if (m_heightMap && !m_heightMap->canSaveCliffState()) {
::AfxMessageBox("Cannot save: the retail Generals map format cannot store cliff flags at the right edge of this map. Adjust the map width before saving.");
return FALSE;
}

CString newName = lpszPathName;
if (newName.IsEmpty())
{
Expand Down Expand Up @@ -852,6 +857,10 @@ Bool CWorldBuilderDoc::ParseWaypointData(DataChunkInput &file, DataChunkInfo *in

void CWorldBuilderDoc::autoSave()
{
if (m_heightMap && !m_heightMap->canSaveCliffState()) {
return;
}

// srj sez: put autosave into our user data folder, not the ap dir
AsciiString autosave1 = TheGlobalData->getPath_UserData();
AsciiString autosave2 = TheGlobalData->getPath_UserData();
Expand Down