Fixed an issue where wall textures and flats did not have the correct precedence. Fixes #710

This commit is contained in:
biwa 2022-03-05 16:57:23 +01:00
parent 69fb4ba413
commit f8bb87e143
22 changed files with 98 additions and 57 deletions

View file

@ -65,7 +65,7 @@ namespace CodeImp.DoomBuilder.Config
{
//mxd. Use short name when adding a texture with "classic" name to override same-named textures
// with textures loaded from directory/pk3 containters
textures[image.DisplayName.Length > 8 ? image.Name : image.ShortName] = image;
textures[/*image.DisplayName.Length > 8 ?*/ image.Name /*: image.ShortName*/] = image;
}
internal void AddFlat(ImageData image)

View file

@ -111,7 +111,7 @@ namespace CodeImp.DoomBuilder.Config
// Add textures to flats
foreach(KeyValuePair<long, ImageData> t in textures)
{
if(!flats.ContainsKey(t.Key)) flats.Add(t.Key, t.Value);
if(!flats.ContainsKey(t.Key) || t.Value.TextureNamespace == TextureNamespace.TEXTURE) flats[t.Key] = t.Value;
}
// Add flats to textures

View file

@ -661,9 +661,9 @@ namespace CodeImp.DoomBuilder.Controls
//if (!splitter.Panel2Collapsed)
{
if (texturetype == 0 && previtem != null && item.TextureName == previtem.TextureName) return false;
if (texturetype == 1 && item.Icon.IsFlat) return false;
if (texturetype == 2 && !item.Icon.IsFlat) return false;
if (texturetype == 3 && (browseflats != item.Icon.IsFlat)) return false;
if (texturetype == 1 && item.Icon.TextureNamespace == TextureNamespace.FLAT) return false;
if (texturetype == 2 && !(item.Icon.TextureNamespace == TextureNamespace.FLAT)) return false;
if (texturetype == 3 && (browseflats != (item.Icon.TextureNamespace == TextureNamespace.FLAT))) return false;
}
//else if (previtem != null && item.TextureName == previtem.TextureName) return false;

View file

@ -7,6 +7,7 @@ using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Data;
#endregion
@ -732,7 +733,7 @@ namespace CodeImp.DoomBuilder.Controls
private static Image GetPreview(ImageBrowserItem item, int imagesize)
{
if(!item.IsPreviewLoaded) return item.Icon.GetPreview();
Dictionary<int, Dictionary<long, Image>> cache = item.Icon.IsFlat ? flatcache : texturecache;
Dictionary<int, Dictionary<long, Image>> cache = (item.Icon.TextureNamespace == TextureNamespace.FLAT) ? flatcache : texturecache;
if(!cache.ContainsKey(imagesize)) cache.Add(imagesize, new Dictionary<long, Image>());

View file

@ -80,6 +80,8 @@ namespace CodeImp.DoomBuilder.Data
private List<MatchingTextureSet> texturesets;
private List<ResourceTextureSet> resourcetextures;
private AllTextureSet alltextures;
private AllTextureSet walltextureset;
private AllTextureSet flattextureset;
//mxd
private Dictionary<int, ModelData> modeldefentries; //Thing.Type, Model entry
@ -192,6 +194,8 @@ namespace CodeImp.DoomBuilder.Data
internal ICollection<MatchingTextureSet> TextureSets { get { return texturesets; } }
internal ICollection<ResourceTextureSet> ResourceTextureSets { get { return resourcetextures; } }
internal AllTextureSet AllTextureSet { get { return alltextures; } }
internal AllTextureSet WallTextureSet { get { return walltextureset; } }
internal AllTextureSet FlatTextureSet { get { return flattextureset; } }
public bool IsLoading
{
@ -364,6 +368,8 @@ namespace CodeImp.DoomBuilder.Data
// Special textures sets
alltextures = new AllTextureSet();
walltextureset = new AllTextureSet();
flattextureset = new AllTextureSet();
resourcetextures = new List<ResourceTextureSet>();
// Go for all locations
@ -511,7 +517,7 @@ namespace CodeImp.DoomBuilder.Data
if(t.Value.HasLongName) flatnames.Add(t.Value.ShortName);
flatnames.Add(t.Value.Name);
}
else if(t.Value is TEXTURESImage || t.Value is SimpleTextureImage) //mxd. Textures defined in TEXTURES or placed between TX_START and TX_END markers override "regular" flats in ZDoom
else if(t.Value.TextureNamespace == TextureNamespace.TEXTURE)
{
//TODO: check this!
flats[t.Key] = t.Value;
@ -533,8 +539,8 @@ namespace CodeImp.DoomBuilder.Data
textures.Add(f.Key, f.Value);
//mxd. Add both short and long names?
if(f.Value.HasLongName) texturenames.Add(f.Value.ShortName);
texturenames.Add(f.Value.Name);
if(f.Value.HasLongName && !texturenames.Contains(f.Value.ShortName)) texturenames.Add(f.Value.ShortName);
if(!texturenames.Contains(f.Value.Name)) texturenames.Add(f.Value.Name);
}
}
@ -582,6 +588,7 @@ namespace CodeImp.DoomBuilder.Data
// Add to all
alltextures.AddTexture(img.Value);
walltextureset.AddTexture(img.Value);
}
// Add flat names to texture sets
@ -593,6 +600,7 @@ namespace CodeImp.DoomBuilder.Data
// Add to all
alltextures.AddFlat(img.Value);
flattextureset.AddFlat(img.Value);
}
//mxd. Create skybox texture(s)
@ -1011,11 +1019,10 @@ namespace CodeImp.DoomBuilder.Data
public ImageData GetTextureImage(long longname)
{
// Does this texture exist?
if(textures.ContainsKey(longname)
&& (textures[longname] is TEXTURESImage || textures[longname] is HiResImage))
return textures[longname]; //TEXTURES and HiRes textures should still override regular ones...
if(texturenamesshorttofull.ContainsKey(longname)) return textures[texturenamesshorttofull[longname]]; //mxd
if(textures.ContainsKey(longname)) return textures[longname];
if (textures.ContainsKey(longname))
return textures[longname];
if (texturenamesshorttofull.ContainsKey(longname)) return textures[texturenamesshorttofull[longname]]; //mxd
if (textures.ContainsKey(longname)) return textures[longname];
// Return null image
return unknownimage; //mxd
@ -1214,13 +1221,13 @@ namespace CodeImp.DoomBuilder.Data
public ImageData GetFlatImage(long longname)
{
// Does this flat exist?
if(flats.ContainsKey(longname) && (flats[longname] is TEXTURESImage || flats[longname] is HiResImage))
if (flats.ContainsKey(longname) && (flats[longname] is TEXTURESImage || flats[longname] is HiResImage))
return flats[longname]; //TEXTURES and HiRes flats should still override regular ones...
if(flatnamesshorttofull.ContainsKey(longname))
return flats[flatnamesshorttofull[longname]]; //mxd
if (flats.ContainsKey(longname))
return flats[longname];
if (flatnamesshorttofull.ContainsKey(longname))
return flats[flatnamesshorttofull[longname]]; //mxd
if (flats.ContainsKey(longname))
return flats[longname];
// Return null image
return unknownimage; //mxd
}

View file

@ -40,7 +40,7 @@ namespace CodeImp.DoomBuilder.Data
public FileImage(string name, string filepathname, bool asflat)
{
// Initialize
this.isFlat = asflat; //mxd
this.texturenamespace = TextureNamespace.FLAT;
if (asflat)
{
@ -67,7 +67,7 @@ namespace CodeImp.DoomBuilder.Data
// Initialize
this.scale.x = scalex;
this.scale.y = scaley;
this.isFlat = asflat; //mxd
texturenamespace = TextureNamespace.FLAT;
probableformat = (asflat ? ImageDataFormat.DOOMFLAT : ImageDataFormat.DOOMPICTURE);

View file

@ -35,7 +35,7 @@ namespace CodeImp.DoomBuilder.Data
// Initialize
SetName(name);
virtualname = "[Flats]/" + this.name; //mxd
isFlat = true; //mxd
texturenamespace = TextureNamespace.FLAT;
// We have no destructor
GC.SuppressFinalize(this);

View file

@ -102,7 +102,7 @@ namespace CodeImp.DoomBuilder.Data
virtualname = overridden.VirtualName;
displayname = overridden.DisplayName;
isFlat = overridden.IsFlat;
texturenamespace = overridden.TextureNamespace;
hasLongName = overridden.HasLongName;
overridesettingsapplied = true;
@ -137,7 +137,7 @@ namespace CodeImp.DoomBuilder.Data
MemoryStream mem = new MemoryStream(membytes);
mem.Seek(0, SeekOrigin.Begin);
bitmap = ImageDataFormat.TryLoadImage(mem, (isFlat ? ImageDataFormat.DOOMFLAT : ImageDataFormat.DOOMPICTURE), General.Map.Data.Palette);
bitmap = ImageDataFormat.TryLoadImage(mem, (texturenamespace == TextureNamespace.FLAT) ? ImageDataFormat.DOOMFLAT : ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
// Not loaded?
if(bitmap == null)

View file

@ -55,7 +55,6 @@ namespace CodeImp.DoomBuilder.Data
protected string shortname; //mxd. Name in uppercase and clamped to DataManager.CLASIC_IMAGE_NAME_LENGTH
protected string virtualname; //mxd. Path of this name is used in TextureBrowserForm
protected string displayname; //mxd. Name to display in TextureBrowserForm
protected bool isFlat; //mxd. If false, it's a texture
protected bool istranslucent; //mxd. If true, has pixels with alpha > 0 && < 255
protected bool ismasked; //mxd. If true, has pixels with zero alpha
protected bool hasLongName; //mxd. Texture name is longer than DataManager.CLASIC_IMAGE_NAME_LENGTH
@ -63,6 +62,7 @@ namespace CodeImp.DoomBuilder.Data
protected int namewidth; // biwa
protected int shortnamewidth; // biwa
protected bool wantIndexed; // volte
protected TextureNamespace texturenamespace;
//mxd. Hashing
private static int hashcounter;
@ -103,7 +103,7 @@ namespace CodeImp.DoomBuilder.Data
public string FilePathName { get { return filepathname; } } //mxd
public string VirtualName { get { return virtualname; } } //mxd
public string DisplayName { get { return displayname; } } //mxd
public bool IsFlat { get { return isFlat; } } //mxd
public TextureNamespace TextureNamespace { get { return texturenamespace; } }
public bool IsTranslucent { get { return istranslucent; } } //mxd
public bool IsMasked { get { return ismasked; } } //mxd
public bool HasPatchWithSameName { get { return hasPatchWithSameName; } } //mxd

View file

@ -46,7 +46,7 @@ namespace CodeImp.DoomBuilder.Data
{
// Initialize
this.datareader = datareader;
this.isFlat = asflat; //mxd
texturenamespace = TextureNamespace.FLAT;
if(asflat)
{

View file

@ -245,6 +245,9 @@ namespace CodeImp.DoomBuilder.Data
// Make the textures
foreach(TextureStructure t in cachedparsers[fullpath].Textures)
imgset.Add(t.MakeImage());
foreach (TextureStructure t in cachedparsers[fullpath].WallTextures)
imgset.Add(t.MakeImage());
}
else
{

View file

@ -46,6 +46,7 @@ namespace CodeImp.DoomBuilder.Data
this.scale.x = scalex;
this.scale.y = scaley;
this.lumpname = lumpname;
texturenamespace = TextureNamespace.TEXTURE;
SetName(name);
virtualname = "[Textures]/" + this.name; //mxd

View file

@ -57,6 +57,8 @@ namespace CodeImp.DoomBuilder.Data
// Initialize
SetName(name);
texturenamespace = TextureNamespace.SPRITE;
AllowUnload = false;
// We have no destructor

View file

@ -30,6 +30,15 @@ using CodeImp.DoomBuilder.Rendering;
namespace CodeImp.DoomBuilder.Data
{
public enum TextureNamespace
{
TEXTURE,
WALLTEXTURE,
FLAT,
SPRITE,
PATCH
}
internal sealed unsafe class TEXTURESImage : ImageData
{
#region ================== Variables
@ -37,14 +46,14 @@ namespace CodeImp.DoomBuilder.Data
private readonly List<TexturePatch> patches; //mxd
private readonly bool optional; //mxd
private readonly bool nulltexture; //mxd
#endregion
#region ================== Constructor / Disposer
// Constructor
public TEXTURESImage(string name, string virtualpath, int width, int height, float scalex, float scaley,
bool worldpanning, bool isflat, bool optional, bool nulltexture)
bool worldpanning, TextureNamespace texturenamespace, bool optional, bool nulltexture)
{
// Initialize
this.width = width;
@ -55,11 +64,11 @@ namespace CodeImp.DoomBuilder.Data
this.optional = optional; //mxd
this.nulltexture = nulltexture; //mxd
this.patches = new List<TexturePatch>(1);
this.texturenamespace = texturenamespace;
//mxd
SetName(name);
this.virtualname = (!string.IsNullOrEmpty(virtualpath) ? virtualpath : "[TEXTURES]") + Path.AltDirectorySeparatorChar + this.name;
this.isFlat = isflat;
// We have no destructor
GC.SuppressFinalize(this);

View file

@ -48,6 +48,7 @@ namespace CodeImp.DoomBuilder.Data
this.scale.x = scalex;
this.scale.y = scaley;
this.worldpanning = worldpanning; //mxd
this.texturenamespace = TextureNamespace.WALLTEXTURE;
this.patches = new List<TexturePatch>();
SetName(name);
virtualname = "[" + group + "]/" + this.name; //mxd

View file

@ -470,6 +470,9 @@ namespace CodeImp.DoomBuilder.Data
// Make the textures
foreach(TextureStructure t in cachedparsers[fullpath].Textures)
images.Add(t.MakeImage());
foreach (TextureStructure t in cachedparsers[fullpath].WallTextures)
images.Add(t.MakeImage());
}
else
{

View file

@ -116,10 +116,11 @@ namespace CodeImp.DoomBuilder.Windows
}
//mxd. Add "All" texture set
count = (browseflats ? General.Map.Data.AllTextureSet.Flats.Count : General.Map.Data.AllTextureSet.Textures.Count);
item = tvTextureSets.Nodes.Add(General.Map.Data.AllTextureSet.Name + " [" + count + "]");
item.Name = General.Map.Data.AllTextureSet.Name;
item.Tag = new TreeNodeData { Set = General.Map.Data.AllTextureSet, FolderName = General.Map.Data.AllTextureSet.Name };
AllTextureSet alltextureset = browseflats ? General.Map.Data.FlatTextureSet : General.Map.Data.WallTextureSet;
count = (browseflats ? alltextureset.Flats.Count : alltextureset.Textures.Count);
item = tvTextureSets.Nodes.Add(alltextureset.Name + " [" + count + "]");
item.Name = alltextureset.Name;
item.Tag = new TreeNodeData { Set = alltextureset, FolderName = alltextureset.Name };
item.ImageIndex = 1;
item.SelectedImageIndex = item.ImageIndex;
@ -304,7 +305,7 @@ namespace CodeImp.DoomBuilder.Windows
if(i == parts.Length - 2)
{
ResourceTextureSet curTs = ((TreeNodeData)curNode.Tag).Set as ResourceTextureSet;
if(image.IsFlat)
if(image.TextureNamespace == TextureNamespace.FLAT)
curTs.AddFlat(image);
else
curTs.AddTexture(image);
@ -545,7 +546,7 @@ namespace CodeImp.DoomBuilder.Windows
else
{
// Add all available textures
foreach(ImageData img in set.Textures) browser.AddItem(img);
foreach (ImageData img in set.Textures) browser.AddItem(img);
}
browser.MakeTexturesUnique(); // biwa

View file

@ -84,7 +84,7 @@ namespace CodeImp.DoomBuilder.ZDoom
// First token is the class name
parser.SkipWhitespace(true);
if(!parser.ReadTextureName(out name, "patch")) return; //mxd
if(!parser.ReadTextureName(out name, TextureNamespace.PATCH)) return; //mxd
if(string.IsNullOrEmpty(name))
{
parser.ReportError("Expected patch name");

View file

@ -33,7 +33,7 @@ namespace CodeImp.DoomBuilder.ZDoom
#region ================== Variables
// Declaration
private readonly string typename;
private readonly TextureNamespace texturenamespace;
private readonly string name;
private readonly string virtualpath; //mxd
private readonly int width;
@ -55,7 +55,7 @@ namespace CodeImp.DoomBuilder.ZDoom
#region ================== Properties
public string TypeName { get { return typename; } }
public TextureNamespace TextureNamespace { get { return texturenamespace; } }
public string Name { get { return name; } }
public int Width { get { return width; } }
public int Height { get { return height; } }
@ -72,11 +72,11 @@ namespace CodeImp.DoomBuilder.ZDoom
#region ================== Constructor / Disposer
// Constructor
internal TextureStructure(TexturesParser parser, string typename, string virtualpath)
internal TextureStructure(TexturesParser parser, TextureNamespace texturenamespace, string virtualpath)
{
// Initialize
this.typename = typename;
this.virtualpath = virtualpath;
this.texturenamespace = texturenamespace;
patches = new List<PatchStructure>(4);
xscale = 0.0f;
yscale = 0.0f;
@ -86,19 +86,19 @@ namespace CodeImp.DoomBuilder.ZDoom
// First token is the texture name
parser.SkipWhitespace(true);
if(!parser.ReadTextureName(out name, typename)) return; //mxd
if(!parser.ReadTextureName(out name, texturenamespace)) return; //mxd
//mxd. It can also be "optional" keyword.
if(name.ToLowerInvariant() == "optional")
{
optional = true;
parser.SkipWhitespace(true);
if(!parser.ReadTextureName(out name, typename)) return; //mxd
if(!parser.ReadTextureName(out name, texturenamespace)) return; //mxd
}
if(string.IsNullOrEmpty(name))
{
parser.ReportError("Expected " + typename + " name");
parser.ReportError("Expected " + texturenamespace + " name");
return;
}
@ -249,7 +249,7 @@ namespace CodeImp.DoomBuilder.ZDoom
float scaley = ((yscale == 0.0f) ? General.Map.Config.DefaultTextureScale : 1f / yscale);
// Make texture
TEXTURESImage tex = new TEXTURESImage(name, virtualpath, width, height, scalex, scaley, worldpanning, typename == "flat", optional, nulltexture);
TEXTURESImage tex = new TEXTURESImage(name, virtualpath, width, height, scalex, scaley, worldpanning, texturenamespace, optional, nulltexture);
// Add patches
foreach(PatchStructure p in patches) tex.AddPatch(new TexturePatch(p));//mxd

View file

@ -39,6 +39,7 @@ namespace CodeImp.DoomBuilder.ZDoom
#region ================== Variables
private readonly Dictionary<string, TextureStructure> textures;
private readonly Dictionary<string, TextureStructure> walltextures;
private readonly Dictionary<string, TextureStructure> flats;
private readonly Dictionary<string, TextureStructure> sprites;
private readonly char[] pathtrimchars = {'_', '.', ' ', '-'}; //mxd
@ -50,6 +51,7 @@ namespace CodeImp.DoomBuilder.ZDoom
internal override ScriptType ScriptType { get { return ScriptType.TEXTURES; } } //mxd
public IEnumerable<TextureStructure> Textures { get { return textures.Values; } }
public IEnumerable<TextureStructure> WallTextures { get { return walltextures.Values; } }
public IEnumerable<TextureStructure> Flats { get { return flats.Values; } }
public IEnumerable<TextureStructure> Sprites { get { return sprites.Values; } }
@ -66,6 +68,7 @@ namespace CodeImp.DoomBuilder.ZDoom
// Initialize
textures = new Dictionary<string, TextureStructure>(StringComparer.Ordinal);
walltextures = new Dictionary<string, TextureStructure>(StringComparer.Ordinal);
flats = new Dictionary<string, TextureStructure>(StringComparer.Ordinal);
sprites = new Dictionary<string, TextureStructure>(StringComparer.Ordinal);
}
@ -115,7 +118,7 @@ namespace CodeImp.DoomBuilder.ZDoom
case "texture":
{
// Read texture structure
TextureStructure tx = new TextureStructure(this, "texture", virtualpath);
TextureStructure tx = new TextureStructure(this, TextureNamespace.TEXTURE, virtualpath);
if(this.HasError) return false;
// if a limit for the texture name length is set make sure that it's not exceeded
@ -141,7 +144,7 @@ namespace CodeImp.DoomBuilder.ZDoom
case "sprite":
{
// Read sprite structure
TextureStructure tx = new TextureStructure(this, "sprite", virtualpath);
TextureStructure tx = new TextureStructure(this, TextureNamespace.SPRITE, virtualpath);
if(this.HasError) return false;
//mxd. Sprite name length must be either 6 or 8 chars
@ -166,7 +169,7 @@ namespace CodeImp.DoomBuilder.ZDoom
case "walltexture":
{
// Read walltexture structure
TextureStructure tx = new TextureStructure(this, "walltexture", virtualpath);
TextureStructure tx = new TextureStructure(this, TextureNamespace.WALLTEXTURE, virtualpath);
if(this.HasError) return false;
// if a limit for the walltexture name length is set make sure that it's not exceeded
@ -184,15 +187,15 @@ namespace CodeImp.DoomBuilder.ZDoom
}
// Add the walltexture
if(!textures.ContainsKey(tx.Name) || (textures[tx.Name].TypeName != "texture"))
textures[tx.Name] = tx;
if(!walltextures.ContainsKey(tx.Name) /*|| (walltextures[tx.Name].TypeName != "texture") */)
walltextures[tx.Name] = tx;
}
break;
case "flat":
{
// Read flat structure
TextureStructure tx = new TextureStructure(this, "flat", virtualpath);
TextureStructure tx = new TextureStructure(this, TextureNamespace.FLAT, virtualpath);
if(this.HasError) return false;
// if a limit for the flat name length is set make sure that it's not exceeded
@ -210,7 +213,7 @@ namespace CodeImp.DoomBuilder.ZDoom
}
// Add the flat
if(!flats.ContainsKey(tx.Name) || (flats[tx.Name].TypeName != "texture"))
if(!flats.ContainsKey(tx.Name) /*|| (flats[tx.Name].TypeName != "texture") */)
flats[tx.Name] = tx;
}
break;
@ -250,6 +253,16 @@ namespace CodeImp.DoomBuilder.ZDoom
// Return true when no errors occurred
return (ErrorDescription == null);
}
public List<TextureStructure> GetMixedWallTextures()
{
Dictionary<string, TextureStructure> images = new Dictionary<string, TextureStructure>(walltextures);
foreach(string s in textures.Keys)
images[s] = textures[s];
return new List<TextureStructure>(images.Values);
}
#endregion
}

View file

@ -208,8 +208,8 @@ namespace CodeImp.DoomBuilder.ZDoom
}
//mxd
internal bool ReadTextureName(out string name) { return ReadTextureName(out name, "texture"); }
internal bool ReadTextureName(out string name, string elementname)
internal bool ReadTextureName(out string name) { return ReadTextureName(out name, TextureNamespace.WALLTEXTURE); }
internal bool ReadTextureName(out string name, TextureNamespace texturenamespace)
{
string token = ReadToken(false);
name = StripQuotes(token);
@ -218,7 +218,7 @@ namespace CodeImp.DoomBuilder.ZDoom
&& name.Length > DataManager.CLASIC_IMAGE_NAME_LENGTH
&& name.Length == token.Length)
{
ReportError("Long " + elementname + " names must be quoted. See \"" + token + "\"");
ReportError("Long " + texturenamespace.ToString() + " names must be quoted. See \"" + token + "\"");
return false;
}

View file

@ -96,7 +96,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
_width = image.Width;
_height = image.Height;
_scale = new Vector2DWrapper(image.Scale);
_isflat = image.IsFlat;
_isflat = image.TextureNamespace == TextureNamespace.FLAT;
}
#endregion