mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Fix hard crash when terrain is missing from map
Previously, opening a map that referenced a deleted or missing terrain caused a severe crash with multiple error dialogs, forcing users to kill the process. This change restores the previous behavior where missing terrains are gracefully handled: a warning is logged and the terrain is substituted with a fallback placeholder (ErrorTexture from TextureManager). This significantly improves UX for developers and modders working with outdated or broken maps, aligning behavior with expectations from earlier versions of the editor.
This commit is contained in:
parent
9dfc638b80
commit
81dfd51eb3
4 changed files with 59 additions and 16 deletions
|
|
@ -137,8 +137,8 @@ CTerrainTextureEntry::CTerrainTextureEntry(CTerrainPropertiesPtr properties, con
|
|||
if (CRenderer::IsInitialised())
|
||||
m_TerrainAlpha = g_TexMan.LoadAlphaMap(alphamap);
|
||||
|
||||
float texAngle = 0.f;
|
||||
float texSize = 1.f;
|
||||
float texAngle{0.f};
|
||||
float texSize{1.f};
|
||||
|
||||
if (m_pProperties)
|
||||
{
|
||||
|
|
@ -146,19 +146,33 @@ CTerrainTextureEntry::CTerrainTextureEntry(CTerrainPropertiesPtr properties, con
|
|||
texAngle = m_pProperties->GetTextureAngle();
|
||||
texSize = m_pProperties->GetTextureSize();
|
||||
}
|
||||
|
||||
m_TextureMatrix.SetZero();
|
||||
m_TextureMatrix._11 = cosf(texAngle) / texSize;
|
||||
m_TextureMatrix._13 = -sinf(texAngle) / texSize;
|
||||
m_TextureMatrix._21 = -sinf(texAngle) / texSize;
|
||||
m_TextureMatrix._23 = -cosf(texAngle) / texSize;
|
||||
m_TextureMatrix._44 = 1.f;
|
||||
GenerateTextureMatrix(texAngle, texSize);
|
||||
|
||||
GroupVector::iterator it=m_Groups.begin();
|
||||
for (;it!=m_Groups.end();++it)
|
||||
(*it)->AddTerrain(this);
|
||||
}
|
||||
|
||||
CTerrainTextureEntry::CTerrainTextureEntry(const CStr tag):
|
||||
m_pProperties(nullptr),
|
||||
m_BaseColor(0),
|
||||
m_BaseColorValid(false),
|
||||
m_DiffuseTexturePath(""),
|
||||
m_Tag(tag)
|
||||
{
|
||||
if (!CRenderer::IsInitialised())
|
||||
return;
|
||||
|
||||
const VfsPath alphamap{"standard"};
|
||||
const VfsPath mat{VfsPath{"art/materials"} / "terrain_norm_spec.xml"};
|
||||
m_Material = g_Renderer.GetSceneRenderer().GetMaterialManager().LoadMaterial(mat);
|
||||
const CTexturePtr texptr{g_Renderer.GetTextureManager().GetErrorTexture()};
|
||||
m_Material.AddSampler(CMaterial::TextureSampler{str_baseTex, texptr});
|
||||
m_TerrainAlpha = g_TexMan.LoadAlphaMap(alphamap);
|
||||
|
||||
GenerateTextureMatrix(0.0f, 1.f);
|
||||
}
|
||||
|
||||
CTerrainTextureEntry::~CTerrainTextureEntry()
|
||||
{
|
||||
for (GroupVector::iterator it=m_Groups.begin();it!=m_Groups.end();++it)
|
||||
|
|
@ -184,3 +198,13 @@ void CTerrainTextureEntry::BuildBaseColor()
|
|||
m_BaseColorValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CTerrainTextureEntry::GenerateTextureMatrix(const float texAngle, const float texSize)
|
||||
{
|
||||
m_TextureMatrix.SetZero();
|
||||
m_TextureMatrix._11 = cosf(texAngle) / texSize;
|
||||
m_TextureMatrix._13 = -sinf(texAngle) / texSize;
|
||||
m_TextureMatrix._21 = -sinf(texAngle) / texSize;
|
||||
m_TextureMatrix._23 = -cosf(texAngle) / texSize;
|
||||
m_TextureMatrix._44 = 1.f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2022 Wildfire Games.
|
||||
/* Copyright (C) 2025 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -37,6 +37,19 @@ public:
|
|||
// Most of the texture's data is delay-loaded, so after the constructor has
|
||||
// been called, the texture entry is ready to be used.
|
||||
CTerrainTextureEntry(CTerrainPropertiesPtr props, const VfsPath& path);
|
||||
|
||||
/**
|
||||
* @brief Constructs a terrain texture entry with the given tag.
|
||||
*
|
||||
* This constructor creates a placeholder (dummy) texture entry,
|
||||
* allowing the system to handle missing terrain textures gracefully.
|
||||
* It ensures stability by avoiding crashes when a texture file is
|
||||
* not found.
|
||||
*
|
||||
* @param tag The identifier for the terrain texture entry.
|
||||
*/
|
||||
CTerrainTextureEntry(const CStr tag);
|
||||
|
||||
~CTerrainTextureEntry();
|
||||
|
||||
const CStr& GetTag() const { return m_Tag; }
|
||||
|
|
@ -67,6 +80,7 @@ public:
|
|||
CTerrainTextureManager::TerrainAlphaMap::iterator m_TerrainAlpha;
|
||||
|
||||
private:
|
||||
void GenerateTextureMatrix(const float texAngle, const float texSize);
|
||||
// Tag = file name stripped of path and extension (grass_dark_1)
|
||||
CStr m_Tag;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2024 Wildfire Games.
|
||||
/* Copyright (C) 2025 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -67,7 +67,7 @@ void CTerrainTextureManager::UnloadTerrainTextures()
|
|||
m_LastGroupIndex = 0;
|
||||
}
|
||||
|
||||
CTerrainTextureEntry* CTerrainTextureManager::FindTexture(const CStr& tag_) const
|
||||
CTerrainTextureEntry* CTerrainTextureManager::FindTexture(const CStr& tag_)
|
||||
{
|
||||
CStr tag = tag_.BeforeLast("."); // Strip extension
|
||||
|
||||
|
|
@ -75,8 +75,13 @@ CTerrainTextureEntry* CTerrainTextureManager::FindTexture(const CStr& tag_) cons
|
|||
if (te->GetTag() == tag)
|
||||
return te;
|
||||
|
||||
LOGWARNING("CTerrainTextureManager: Couldn't find terrain %s", tag.c_str());
|
||||
return 0;
|
||||
LOGWARNING("CTerrainTextureManager: Couldn't find terrain %s using fallback texture", tag.c_str());
|
||||
|
||||
// If the texture is not found, return a default texture.
|
||||
// This is a fallback texture, so it should not be used in the editor.
|
||||
CTerrainTextureEntry* fallback{new CTerrainTextureEntry{tag}};
|
||||
m_TextureEntries.push_back(fallback);
|
||||
return fallback;
|
||||
}
|
||||
|
||||
CTerrainTextureEntry* CTerrainTextureManager::AddTexture(const CTerrainPropertiesPtr& props, const VfsPath& path)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2023 Wildfire Games.
|
||||
/* Copyright (C) 2025 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -103,7 +103,7 @@ public:
|
|||
|
||||
void UnloadTerrainTextures();
|
||||
|
||||
CTerrainTextureEntry* FindTexture(const CStr& tag) const;
|
||||
CTerrainTextureEntry* FindTexture(const CStr& tag);
|
||||
|
||||
// Create a texture object for a new terrain texture at path, using the
|
||||
// property sheet props.
|
||||
|
|
|
|||
Loading…
Reference in a new issue