mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-31 04:40:55 +00:00
Added, Classic modes: thing sprites are now angle-dependent.
This commit is contained in:
parent
a06f44ce19
commit
42607f704f
8 changed files with 444 additions and 191 deletions
|
@ -18,18 +18,25 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.GZBuilder.Data;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.ZDoom;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using System.Drawing;
|
||||
using CodeImp.DoomBuilder.ZDoom;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.Config
|
||||
{
|
||||
public struct SpriteFrameInfo //mxd
|
||||
{
|
||||
public string Sprite;
|
||||
public long SpriteLongName;
|
||||
public bool Mirror;
|
||||
}
|
||||
|
||||
public class ThingTypeInfo : INumberedTitle, IComparable<ThingTypeInfo>
|
||||
{
|
||||
#region ================== Constants
|
||||
|
@ -50,9 +57,9 @@ namespace CodeImp.DoomBuilder.Config
|
|||
private readonly int index;
|
||||
private string title;
|
||||
private string sprite;
|
||||
private SpriteFrameInfo[] spriteframe; //mxd. All rotations for given sprite. Currently contains either 1 or 8 frames
|
||||
private ActorStructure actor;
|
||||
private string classname; //mxd
|
||||
private long spritelongname;
|
||||
private int color;
|
||||
private float alpha; //mxd
|
||||
private byte alphabyte; //mxd
|
||||
|
@ -88,8 +95,8 @@ namespace CodeImp.DoomBuilder.Config
|
|||
public int Index { get { return index; } }
|
||||
public string Title { get { return title; } }
|
||||
public string Sprite { get { return sprite; } }
|
||||
public SpriteFrameInfo[] SpriteFrame { get { return spriteframe; } }
|
||||
public ActorStructure Actor { get { return actor; } }
|
||||
public long SpriteLongName { get { return spritelongname; } }
|
||||
public int Color { get { return color; } }
|
||||
public float Alpha { get { return alpha; } } //mxd
|
||||
public byte AlphaByte { get { return alphabyte; } } //mxd
|
||||
|
@ -147,7 +154,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
this.spritescale = new SizeF(1.0f, 1.0f);
|
||||
this.fixedsize = false;
|
||||
this.fixedrotation = false; //mxd
|
||||
this.spritelongname = long.MaxValue;
|
||||
this.spriteframe = new[] { new SpriteFrameInfo { Sprite = sprite, SpriteLongName = Lump.MakeLongName(sprite, true) } }; //mxd
|
||||
this.args = new ArgumentInfo[Linedef.NUM_ARGS];
|
||||
this.isknown = false;
|
||||
this.absolutez = false;
|
||||
|
@ -200,11 +207,8 @@ namespace CodeImp.DoomBuilder.Config
|
|||
if(this.radius < 4f || this.fixedsize) this.radius = THING_FIXED_SIZE;
|
||||
if(this.hangs && this.absolutez) this.hangs = false; //mxd
|
||||
|
||||
// Make long name for sprite lookup
|
||||
if(this.sprite.Length <= 8)
|
||||
this.spritelongname = Lump.MakeLongName(this.sprite);
|
||||
else
|
||||
this.spritelongname = long.MaxValue;
|
||||
//mxd. Create sprite frame
|
||||
this.spriteframe = new[] { new SpriteFrameInfo { Sprite = sprite, SpriteLongName = Lump.MakeLongName(sprite, true) } };
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
|
@ -246,11 +250,8 @@ namespace CodeImp.DoomBuilder.Config
|
|||
if(this.radius < 4f || this.fixedsize) this.radius = THING_FIXED_SIZE;
|
||||
if(this.hangs && this.absolutez) this.hangs = false; //mxd
|
||||
|
||||
// Make long name for sprite lookup
|
||||
if(this.sprite.Length <= 8)
|
||||
this.spritelongname = Lump.MakeLongName(this.sprite);
|
||||
else
|
||||
this.spritelongname = long.MaxValue;
|
||||
//mxd. Create sprite frame
|
||||
this.spriteframe = new[] { new SpriteFrameInfo { Sprite = sprite, SpriteLongName = Lump.MakeLongName(sprite, true) } };
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
|
@ -293,6 +294,9 @@ namespace CodeImp.DoomBuilder.Config
|
|||
// Apply settings from actor
|
||||
ModifyByDecorateActor(actor);
|
||||
|
||||
//mxd. Create sprite frame
|
||||
this.spriteframe = new[] { new SpriteFrameInfo { Sprite = sprite, SpriteLongName = Lump.MakeLongName(sprite, true) } };
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
@ -313,6 +317,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
|
||||
// Read properties
|
||||
this.sprite = cat.Sprite;
|
||||
this.spriteframe = new[] { new SpriteFrameInfo { Sprite = sprite, SpriteLongName = Lump.MakeLongName(sprite, true), } }; //mxd
|
||||
this.color = cat.Color;
|
||||
this.alpha = cat.Alpha; //mxd
|
||||
this.alphabyte = (byte)(this.alpha * 255); //mxd
|
||||
|
@ -334,6 +339,9 @@ namespace CodeImp.DoomBuilder.Config
|
|||
// Apply settings from actor
|
||||
ModifyByDecorateActor(actor);
|
||||
|
||||
//mxd. Create sprite frame
|
||||
this.spriteframe = new[] { new SpriteFrameInfo { Sprite = sprite, SpriteLongName = Lump.MakeLongName(sprite, true) } };
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
@ -354,6 +362,8 @@ namespace CodeImp.DoomBuilder.Config
|
|||
|
||||
// Copy properties
|
||||
this.sprite = other.sprite;
|
||||
this.spriteframe = new SpriteFrameInfo[other.spriteframe.Length]; //mxd
|
||||
other.spriteframe.CopyTo(this.spriteframe, 0); //mxd
|
||||
this.color = other.color;
|
||||
this.alpha = other.alpha; //mxd
|
||||
this.alphabyte = other.alphabyte; //mxd
|
||||
|
@ -443,10 +453,8 @@ namespace CodeImp.DoomBuilder.Config
|
|||
else if(string.IsNullOrEmpty(sprite))//mxd
|
||||
sprite = DataManager.INTERNAL_PREFIX + "unknownthing";
|
||||
|
||||
if(this.sprite.Length < 9)
|
||||
this.spritelongname = Lump.MakeLongName(this.sprite);
|
||||
else
|
||||
this.spritelongname = long.MaxValue;
|
||||
//mxd. Create sprite frame
|
||||
this.spriteframe = new[] { new SpriteFrameInfo { Sprite = sprite, SpriteLongName = Lump.MakeLongName(sprite, true) } };
|
||||
|
||||
// Set sprite scale (mxd. Scale is translated to xscale and yscale in ActorStructure)
|
||||
if(actor.HasPropertyWithValue("xscale"))
|
||||
|
@ -501,6 +509,134 @@ namespace CodeImp.DoomBuilder.Config
|
|||
if(blocking > THING_BLOCKING_NONE) errorcheck = THING_ERROR_INSIDE_STUCK;
|
||||
}
|
||||
|
||||
//mxd. This tries to find all possible sprite rotations
|
||||
internal void SetupSpriteFrame()
|
||||
{
|
||||
// Empty or internal sprites don't have rotations
|
||||
if(string.IsNullOrEmpty(sprite) || sprite.StartsWith(DataManager.INTERNAL_PREFIX)) return;
|
||||
|
||||
// Skip sprites with strange names
|
||||
if(sprite.Length != 6 && sprite.Length != 8)
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ". Unsupported sprite name fromat: \"" + sprite + "\"");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get sprite angle
|
||||
string anglestr = sprite.Substring(5, 1);
|
||||
int sourceangle;
|
||||
if(!int.TryParse(anglestr, NumberStyles.Integer, CultureInfo.InvariantCulture, out sourceangle))
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ". Unable to get sprite angle from sprite \"" + sprite + "\"");
|
||||
return;
|
||||
}
|
||||
|
||||
if(sourceangle < 0 || sourceangle > 8)
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ", sprite \"" + sprite + "\". Sprite angle must be in [0..8] range");
|
||||
return;
|
||||
}
|
||||
|
||||
// No rotations?
|
||||
if(sourceangle == 0) return;
|
||||
|
||||
// Gather rotations
|
||||
string[] frames = new string[8];
|
||||
bool[] mirror = new bool[8];
|
||||
int processedcount = 0;
|
||||
string sourcename = sprite.Substring(0, 4);
|
||||
IEnumerable<string> spritenames = General.Map.Data.GetSpriteNames(sourcename);
|
||||
|
||||
// Process gathered sprites
|
||||
char sourceframe = sprite[4];
|
||||
foreach(string s in spritenames)
|
||||
{
|
||||
//Check first frame block
|
||||
char targetframe = s[4];
|
||||
if(targetframe == sourceframe)
|
||||
{
|
||||
// Check angle
|
||||
int targetangle;
|
||||
anglestr = s.Substring(5, 1);
|
||||
if(!int.TryParse(anglestr, NumberStyles.Integer, CultureInfo.InvariantCulture, out targetangle))
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ". Unable to get sprite angle from sprite \"" + s + "\"");
|
||||
return;
|
||||
}
|
||||
|
||||
if(targetangle < 0 || targetangle > 8)
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ", sprite \"" + s + "\". Sprite angle must be in [0..8] range");
|
||||
return;
|
||||
}
|
||||
|
||||
// Add to collection
|
||||
frames[targetangle - 1] = s;
|
||||
processedcount++;
|
||||
}
|
||||
|
||||
// Check second frame block?
|
||||
if(s.Length == 6) continue;
|
||||
|
||||
targetframe = s[6];
|
||||
if(targetframe == sourceframe)
|
||||
{
|
||||
// Check angle
|
||||
int targetangle;
|
||||
anglestr = s.Substring(7, 1);
|
||||
if(!int.TryParse(anglestr, NumberStyles.Integer, CultureInfo.InvariantCulture, out targetangle))
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ". Unable to get sprite angle from sprite \"" + s + "\"");
|
||||
return;
|
||||
}
|
||||
|
||||
if(targetangle < 0 || targetangle > 8)
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ", sprite \"" + s + "\". Sprite angle must be in [0..8] range");
|
||||
return;
|
||||
}
|
||||
|
||||
// Add to collections
|
||||
frames[targetangle - 1] = s;
|
||||
mirror[targetangle - 1] = true;
|
||||
processedcount++;
|
||||
}
|
||||
|
||||
// Gathered all sprites?
|
||||
if(processedcount == 8) break;
|
||||
}
|
||||
|
||||
// Check collected data
|
||||
if(processedcount != 8)
|
||||
{
|
||||
// Check which angles are missing
|
||||
List<string> missingangles = new List<string>();
|
||||
for(int i = 0; i < frames.Length; i++)
|
||||
{
|
||||
if(string.IsNullOrEmpty(frames[i]))
|
||||
missingangles.Add((i + 1).ToString());
|
||||
}
|
||||
|
||||
// Assemble angles to display
|
||||
string ma = string.Join(", ", missingangles.ToArray());
|
||||
if(missingangles.Count > 2)
|
||||
{
|
||||
int pos = ma.LastIndexOf(",", StringComparison.Ordinal);
|
||||
if(pos != -1) ma = ma.Remove(pos, 1).Insert(pos, " and");
|
||||
}
|
||||
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ". Sprite rotations " + ma + " for sprite " + sourcename + ", frame " + sourceframe + " are missing");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create collection
|
||||
spriteframe = new SpriteFrameInfo[frames.Length];
|
||||
for(int i = 0; i < frames.Length; i++)
|
||||
{
|
||||
spriteframe[i] = new SpriteFrameInfo { Sprite = frames[i], SpriteLongName = Lump.MakeLongName(frames[i]), Mirror = mirror[i] };
|
||||
}
|
||||
}
|
||||
|
||||
// This is used for sorting
|
||||
public int CompareTo(ThingTypeInfo other)
|
||||
{
|
||||
|
|
|
@ -41,6 +41,7 @@ namespace CodeImp.DoomBuilder
|
|||
|
||||
private DebugMessageType filters;
|
||||
private static long starttime = -1;
|
||||
private static long storedtime;
|
||||
private static int counter;
|
||||
private static DebugConsole me;
|
||||
|
||||
|
@ -144,11 +145,18 @@ namespace CodeImp.DoomBuilder
|
|||
starttime = SlimDX.Configuration.Timer.ElapsedMilliseconds;
|
||||
}
|
||||
|
||||
public static void PauseTimer()
|
||||
{
|
||||
if(starttime == -1) throw new InvalidOperationException("DebugConsole.StartTimer() must be called before DebugConsole.PauseTimer()!");
|
||||
|
||||
storedtime += SlimDX.Configuration.Timer.ElapsedMilliseconds - starttime;
|
||||
}
|
||||
|
||||
public static void StopTimer(string message)
|
||||
{
|
||||
if(starttime == -1) throw new InvalidOperationException("DebugConsole.StartTimer() must be called before DebugConsole.StopTimer()!");
|
||||
|
||||
long duration = SlimDX.Configuration.Timer.ElapsedMilliseconds - starttime;
|
||||
long duration = SlimDX.Configuration.Timer.ElapsedMilliseconds - starttime + storedtime;
|
||||
|
||||
if(message.Contains("%"))
|
||||
message = message.Replace("%", duration.ToString(CultureInfo.InvariantCulture));
|
||||
|
@ -158,6 +166,7 @@ namespace CodeImp.DoomBuilder
|
|||
WriteLine(DebugMessageType.SPECIAL, message);
|
||||
|
||||
starttime = -1;
|
||||
storedtime = 0;
|
||||
}
|
||||
|
||||
public static void IncrementCounter() { IncrementCounter(1); }
|
||||
|
|
|
@ -66,6 +66,9 @@ namespace CodeImp.DoomBuilder.Data
|
|||
public const int CLASIC_IMAGE_NAME_LENGTH = 8; //mxd
|
||||
private const int MAX_SKYTEXTURE_SIZE = 2048; //mxd
|
||||
|
||||
private long UNKNOWN_THING; //mxd
|
||||
private long MISSING_THING; //mxd
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
@ -121,7 +124,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
private ImageData hourglass3d;
|
||||
private ImageData crosshair;
|
||||
private ImageData crosshairbusy;
|
||||
private Dictionary<string, ImageData> internalsprites;
|
||||
private Dictionary<string, long> internalspriteslookup; //mxd
|
||||
private ImageData whitetexture;
|
||||
private ImageData blacktexture; //mxd
|
||||
private ImageData thingtexture; //mxd
|
||||
|
@ -323,7 +326,6 @@ namespace CodeImp.DoomBuilder.Data
|
|||
texturesets = new List<MatchingTextureSet>();
|
||||
usedtextures = new Dictionary<long, bool>(); //mxd
|
||||
usedflats = new Dictionary<long, bool>(); //mxd
|
||||
internalsprites = new Dictionary<string, ImageData>(StringComparer.Ordinal);
|
||||
thingcategories = General.Map.Config.GetThingCategories();
|
||||
thingtypes = General.Map.Config.GetThingTypes();
|
||||
|
||||
|
@ -586,7 +588,6 @@ namespace CodeImp.DoomBuilder.Data
|
|||
foreach(KeyValuePair<long, ImageData> i in textures) i.Value.Dispose();
|
||||
foreach(KeyValuePair<long, ImageData> i in flats) i.Value.Dispose();
|
||||
foreach(KeyValuePair<long, ImageData> i in sprites) i.Value.Dispose();
|
||||
foreach(KeyValuePair<string, ImageData> i in internalsprites) i.Value.Dispose(); //mxd
|
||||
palette = null;
|
||||
|
||||
//mxd. Dispose models
|
||||
|
@ -615,7 +616,6 @@ namespace CodeImp.DoomBuilder.Data
|
|||
texturenames = null;
|
||||
flatnames = null;
|
||||
imageque = null;
|
||||
internalsprites = null;
|
||||
mapinfo = null; //mxd
|
||||
}
|
||||
|
||||
|
@ -1499,19 +1499,25 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Valid sprite name?
|
||||
if(ti.Sprite.Length == 0 || ti.Sprite.Length > CLASIC_IMAGE_NAME_LENGTH) continue; //mxd
|
||||
|
||||
//mxd. Find all sprite angles
|
||||
ti.SetupSpriteFrame();
|
||||
|
||||
//mxd. Load them all
|
||||
foreach(SpriteFrameInfo info in ti.SpriteFrame)
|
||||
{
|
||||
ImageData image = null;
|
||||
|
||||
// Sprite not in our collection yet?
|
||||
if(!sprites.ContainsKey(ti.SpriteLongName))
|
||||
if(!sprites.ContainsKey(info.SpriteLongName))
|
||||
{
|
||||
//mxd. Go for all opened containers
|
||||
bool spritefound = false;
|
||||
if(!string.IsNullOrEmpty(ti.Sprite))
|
||||
if(!string.IsNullOrEmpty(info.Sprite))
|
||||
{
|
||||
for(int i = containers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
// This contain provides this sprite?
|
||||
if(containers[i].GetSpriteExists(ti.Sprite))
|
||||
if(containers[i].GetSpriteExists(info.Sprite))
|
||||
{
|
||||
spritefound = true;
|
||||
break;
|
||||
|
@ -1522,30 +1528,31 @@ namespace CodeImp.DoomBuilder.Data
|
|||
if(spritefound)
|
||||
{
|
||||
// Make new sprite image
|
||||
image = new SpriteImage(ti.Sprite);
|
||||
image = new SpriteImage(info.Sprite);
|
||||
|
||||
// Add to collection
|
||||
sprites.Add(ti.SpriteLongName, image);
|
||||
sprites.Add(info.SpriteLongName, image);
|
||||
}
|
||||
else
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Missing sprite lump \"" + ti.Sprite + "\". Forgot to include required resources?");
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Missing sprite lump \"" + info.Sprite + "\". Forgot to include required resources?");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
image = sprites[ti.SpriteLongName];
|
||||
image = sprites[info.SpriteLongName];
|
||||
}
|
||||
|
||||
// Add to preview manager
|
||||
if(image != null) previews.AddImage(image);
|
||||
}
|
||||
}
|
||||
|
||||
// Output info
|
||||
return sprites.Count;
|
||||
}
|
||||
|
||||
// This returns a specific patch stream
|
||||
// This returns a specific sprite stream
|
||||
internal Stream GetSpriteData(string pname, ref string spritelocation)
|
||||
{
|
||||
if(!string.IsNullOrEmpty(pname))
|
||||
|
@ -1553,13 +1560,13 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Go for all opened containers
|
||||
for(int i = containers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
// This contain provides this patch?
|
||||
// This contain provides this sprite?
|
||||
Stream spritedata = containers[i].GetSpriteData(pname, ref spritelocation);
|
||||
if(spritedata != null) return spritedata;
|
||||
}
|
||||
}
|
||||
|
||||
// No such patch found
|
||||
// No such sprite found
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1574,12 +1581,12 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Go for all opened containers
|
||||
for(int i = containers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
// This contain provides this patch?
|
||||
// This contain provides this sprite?
|
||||
if(containers[i].GetSpriteExists(pname)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
// No such patch found
|
||||
// No such sprite found
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1587,39 +1594,54 @@ namespace CodeImp.DoomBuilder.Data
|
|||
private void LoadInternalSprites()
|
||||
{
|
||||
// Add sprite icon files from directory
|
||||
string name;
|
||||
string[] files = Directory.GetFiles(General.SpritesPath, "*.png", SearchOption.TopDirectoryOnly);
|
||||
internalspriteslookup = new Dictionary<string, long>(files.Length + 2); //mxd
|
||||
foreach(string spritefile in files)
|
||||
{
|
||||
ImageData img = new FileImage(Path.GetFileNameWithoutExtension(spritefile).ToLowerInvariant(), spritefile);
|
||||
img.LoadImage();
|
||||
img.AllowUnload = false;
|
||||
internalsprites.Add(img.Name, img);
|
||||
name = INTERNAL_PREFIX + img.Name;
|
||||
long hash = Lump.MakeLongName(name, true); //mxd
|
||||
sprites[hash] = img; //mxd
|
||||
internalspriteslookup[name] = hash; //mxd
|
||||
}
|
||||
|
||||
// Add some internal resources
|
||||
if(!internalsprites.ContainsKey("nothing"))
|
||||
// Add some internal resources.
|
||||
// mxd. Doesn't seem to be used anywhere
|
||||
/*name = INTERNAL_PREFIX + "nothing";
|
||||
if(!internalspriteslookup.ContainsKey(name))
|
||||
{
|
||||
ImageData img = new ResourceImage("CodeImp.DoomBuilder.Resources.Nothing.png");
|
||||
img.LoadImage();
|
||||
img.AllowUnload = false;
|
||||
internalsprites.Add("nothing", img);
|
||||
}
|
||||
long hash = Lump.MakeLongName(name, true); //mxd
|
||||
sprites[hash] = img; //mxd
|
||||
internalspriteslookup[name] = hash; //mxd
|
||||
}*/
|
||||
|
||||
if(!internalsprites.ContainsKey("unknownthing"))
|
||||
name = INTERNAL_PREFIX + "unknownthing";
|
||||
UNKNOWN_THING = Lump.MakeLongName(name, true);
|
||||
if(!internalspriteslookup.ContainsKey(name))
|
||||
{
|
||||
ImageData img = new ResourceImage("CodeImp.DoomBuilder.Resources.UnknownThing.png");
|
||||
img.LoadImage();
|
||||
img.AllowUnload = false;
|
||||
internalsprites.Add("unknownthing", img);
|
||||
sprites[UNKNOWN_THING] = img; //mxd
|
||||
internalspriteslookup[name] = UNKNOWN_THING; //mxd
|
||||
}
|
||||
|
||||
//mxd
|
||||
if(!internalsprites.ContainsKey("missingthing"))
|
||||
name = INTERNAL_PREFIX + "missingthing";
|
||||
MISSING_THING = Lump.MakeLongName(name, true);
|
||||
if(!internalspriteslookup.ContainsKey(name))
|
||||
{
|
||||
ImageData img = new ResourceImage("CodeImp.DoomBuilder.Resources.MissingThing.png");
|
||||
img.LoadImage();
|
||||
img.AllowUnload = false;
|
||||
internalsprites.Add("missingthing", img);
|
||||
sprites[MISSING_THING] = img; //mxd
|
||||
internalspriteslookup[name] = MISSING_THING; //mxd
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1630,11 +1652,11 @@ namespace CodeImp.DoomBuilder.Data
|
|||
if((name.Length > INTERNAL_PREFIX.Length) && name.ToLowerInvariant().StartsWith(INTERNAL_PREFIX))
|
||||
{
|
||||
// Get the internal sprite
|
||||
string internalname = name.Substring(INTERNAL_PREFIX.Length).ToLowerInvariant();
|
||||
if(internalsprites.ContainsKey(internalname))
|
||||
return internalsprites[internalname];
|
||||
string internalname = name.ToLowerInvariant();
|
||||
if(internalspriteslookup.ContainsKey(internalname)) //mxd
|
||||
return sprites[internalspriteslookup[internalname]];
|
||||
|
||||
return internalsprites["unknownthing"]; //mxd
|
||||
return sprites[UNKNOWN_THING]; //mxd
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1678,7 +1700,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
else //mxd
|
||||
{
|
||||
ImageData img = string.IsNullOrEmpty(name) ? internalsprites["unknownthing"] : internalsprites["missingthing"];
|
||||
ImageData img = string.IsNullOrEmpty(name) ? sprites[UNKNOWN_THING] : sprites[MISSING_THING];
|
||||
|
||||
// Add to collection
|
||||
sprites.Add(longname, img);
|
||||
|
@ -1690,6 +1712,17 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
}
|
||||
|
||||
//mxd. Returns all sprite names, which start with given string
|
||||
internal IEnumerable<string> GetSpriteNames(string startswith)
|
||||
{
|
||||
HashSet<string> result = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach(DataReader reader in containers)
|
||||
result.UnionWith(reader.GetSpriteNames(startswith));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Things
|
||||
|
|
|
@ -210,6 +210,9 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// When implemented, this checks if the given sprite lump exists
|
||||
public abstract bool GetSpriteExists(string pname);
|
||||
|
||||
//mxd. When implemented, returns all sprites, which name starts with given string
|
||||
public abstract HashSet<string> GetSpriteNames(string startswith);
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Decorate, Modeldef, Mapinfo, Gldefs, etc...
|
||||
|
|
|
@ -377,15 +377,15 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
#region ================== Sprites
|
||||
|
||||
// This loads the textures
|
||||
// This loads the sprites
|
||||
public override IEnumerable<ImageData> LoadSprites(Dictionary<string, TexturesParser> cachedparsers)
|
||||
{
|
||||
Dictionary<long, ImageData> images = new Dictionary<long, ImageData>();
|
||||
List<ImageData> imgset = new List<ImageData>();
|
||||
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
Dictionary<long, ImageData> images = new Dictionary<long, ImageData>();
|
||||
List<ImageData> imgset = new List<ImageData>();
|
||||
|
||||
// Load from wad files
|
||||
// Note the backward order, because the last wad's images have priority
|
||||
for(int i = wads.Count - 1; i >= 0; i--)
|
||||
|
@ -422,6 +422,31 @@ namespace CodeImp.DoomBuilder.Data
|
|||
return new List<ImageData>(images.Values);
|
||||
}
|
||||
|
||||
//mxd. Returns all sprites, which name starts with given string
|
||||
public override HashSet<string> GetSpriteNames(string startswith)
|
||||
{
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
HashSet<string> result = new HashSet<string>();
|
||||
|
||||
// Load from wad files
|
||||
// Note the backward order, because the last wad's images have priority
|
||||
for(int i = wads.Count - 1; i >= 0; i--)
|
||||
{
|
||||
result.UnionWith(wads[i].GetSpriteNames(startswith));
|
||||
}
|
||||
|
||||
// Load from out own files
|
||||
string[] files = GetAllFilesWhichTitleStartsWith(SPRITES_DIR, startswith, true);
|
||||
foreach(string file in files)
|
||||
{
|
||||
result.Add(Path.GetFileNameWithoutExtension(file).ToUpperInvariant());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Colormaps
|
||||
|
@ -429,12 +454,12 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// This loads the textures
|
||||
public override ICollection<ImageData> LoadColormaps()
|
||||
{
|
||||
Dictionary<long, ImageData> images = new Dictionary<long, ImageData>();
|
||||
ICollection<ImageData> collection;
|
||||
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
Dictionary<long, ImageData> images = new Dictionary<long, ImageData>();
|
||||
ICollection<ImageData> collection;
|
||||
|
||||
// Load from wad files
|
||||
// Note the backward order, because the last wad's images have priority
|
||||
for(int i = wads.Count - 1; i >= 0; i--)
|
||||
|
@ -448,8 +473,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
AddImagesToList(images, collection);
|
||||
|
||||
// Add images to the container-specific texture set
|
||||
foreach(ImageData img in images.Values)
|
||||
textureset.AddFlat(img);
|
||||
foreach(ImageData img in images.Values) textureset.AddFlat(img);
|
||||
|
||||
return new List<ImageData>(images.Values);
|
||||
}
|
||||
|
|
|
@ -880,6 +880,28 @@ namespace CodeImp.DoomBuilder.Data
|
|||
return false;
|
||||
}
|
||||
|
||||
//mxd. Returns all sprites, which name starts with given string
|
||||
public override HashSet<string> GetSpriteNames(string startswith)
|
||||
{
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
HashSet<string> result = new HashSet<string>();
|
||||
if(startswith.Length > 8) return result;
|
||||
|
||||
startswith = startswith.ToUpperInvariant();
|
||||
foreach(LumpRange range in spriteranges)
|
||||
{
|
||||
for(int i = range.start; i < range.end + 1; i++)
|
||||
{
|
||||
if(file.Lumps[i].Name.StartsWith(startswith))
|
||||
result.Add(file.Lumps[i].Name);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Voxels (mxd)
|
||||
|
|
|
@ -1083,25 +1083,28 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
}
|
||||
|
||||
//mxd
|
||||
private static void CreateThingSpriteVerts(Vector2D screenpos, float width, float height, ref FlatVertex[] verts, int offset, int color)
|
||||
private static void CreateThingSpriteVerts(Vector2D screenpos, float width, float height, ref FlatVertex[] verts, int offset, int color, bool mirror)
|
||||
{
|
||||
float ul = (mirror ? 1f : 0f);
|
||||
float ur = (mirror ? 0f : 1f);
|
||||
|
||||
// Setup fixed rect for circle
|
||||
verts[offset].x = screenpos.x - width;
|
||||
verts[offset].y = screenpos.y - height;
|
||||
verts[offset].c = color;
|
||||
verts[offset].u = 0;
|
||||
verts[offset].u = ul;
|
||||
verts[offset].v = 0;
|
||||
offset++;
|
||||
verts[offset].x = screenpos.x + width;
|
||||
verts[offset].y = screenpos.y - height;
|
||||
verts[offset].c = color;
|
||||
verts[offset].u = 1;
|
||||
verts[offset].u = ur;
|
||||
verts[offset].v = 0;
|
||||
offset++;
|
||||
verts[offset].x = screenpos.x - width;
|
||||
verts[offset].y = screenpos.y + height;
|
||||
verts[offset].c = color;
|
||||
verts[offset].u = 0;
|
||||
verts[offset].u = ul;
|
||||
verts[offset].v = 1;
|
||||
offset++;
|
||||
verts[offset] = verts[offset - 2];
|
||||
|
@ -1111,7 +1114,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
verts[offset].x = screenpos.x + width;
|
||||
verts[offset].y = screenpos.y + height;
|
||||
verts[offset].c = color;
|
||||
verts[offset].u = 1;
|
||||
verts[offset].u = ur;
|
||||
verts[offset].v = 1;
|
||||
}
|
||||
|
||||
|
@ -1232,7 +1235,29 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// Find sprite texture
|
||||
if(info.Sprite.Length == 0) continue;
|
||||
|
||||
ImageData sprite = General.Map.Data.GetSpriteImage(info.Sprite);
|
||||
// Sort by sprite angle...
|
||||
Dictionary<int, List<Thing>> thingsbyangle = new Dictionary<int, List<Thing>>(group.Value.Count);
|
||||
if(info.SpriteFrame.Length == 8)
|
||||
{
|
||||
foreach(Thing t in group.Value)
|
||||
{
|
||||
// Choose which sprite angle to show
|
||||
int spriteangle = General.ClampAngle(-t.AngleDoom + 270) / 45; // Convert to [0..7] range
|
||||
|
||||
// Add to collection
|
||||
if(!thingsbyangle.ContainsKey(spriteangle)) thingsbyangle.Add(spriteangle, new List<Thing>());
|
||||
thingsbyangle[spriteangle].Add(t);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thingsbyangle[0] = group.Value;
|
||||
}
|
||||
|
||||
foreach(KeyValuePair<int, List<Thing>> framegroup in thingsbyangle)
|
||||
{
|
||||
SpriteFrameInfo sfi = info.SpriteFrame[framegroup.Key];
|
||||
ImageData sprite = General.Map.Data.GetSpriteImage(sfi.Sprite);
|
||||
if(sprite == null) continue;
|
||||
if(!sprite.IsImageLoaded)
|
||||
{
|
||||
|
@ -1245,16 +1270,17 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.Shaders.Things2D.ApplySettings();
|
||||
|
||||
// Determine next lock size
|
||||
locksize = (group.Value.Count > THING_BUFFER_SIZE) ? THING_BUFFER_SIZE : group.Value.Count;
|
||||
locksize = (framegroup.Value.Count > THING_BUFFER_SIZE) ? THING_BUFFER_SIZE : framegroup.Value.Count;
|
||||
verts = new FlatVertex[THING_BUFFER_SIZE * 6];
|
||||
|
||||
// Go for all things
|
||||
buffercount = 0;
|
||||
totalcount = 0;
|
||||
|
||||
foreach(Thing t in group.Value)
|
||||
foreach(Thing t in framegroup.Value)
|
||||
{
|
||||
if(t.IsModel && ((General.Settings.GZDrawModelsMode == ModelRenderMode.SELECTION && t.Selected) || (General.Settings.GZDrawModelsMode == ModelRenderMode.ACTIVE_THINGS_FILTER && alpha == 1.0f))) continue;
|
||||
if(t.IsModel && ((General.Settings.GZDrawModelsMode == ModelRenderMode.SELECTION && t.Selected) || (General.Settings.GZDrawModelsMode == ModelRenderMode.ACTIVE_THINGS_FILTER && alpha == 1.0f)))
|
||||
continue;
|
||||
|
||||
bool forcespriterendering;
|
||||
float spritewidth, spriteheight, spritescale;
|
||||
|
@ -1306,7 +1332,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
continue;
|
||||
}
|
||||
|
||||
CreateThingSpriteVerts(thingsByPosition[t], spritewidth, spriteheight, ref verts, buffercount * 6, (t.Selected ? selectionColor : 0xFFFFFF));
|
||||
CreateThingSpriteVerts(thingsByPosition[t], spritewidth, spriteheight, ref verts, buffercount * 6, (t.Selected ? selectionColor : 0xFFFFFF), sfi.Mirror);
|
||||
buffercount++;
|
||||
totalcount++;
|
||||
|
||||
|
@ -1325,7 +1351,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
buffercount = 0;
|
||||
|
||||
// Determine next lock size
|
||||
locksize = ((group.Value.Count - totalcount) > THING_BUFFER_SIZE) ? THING_BUFFER_SIZE : (group.Value.Count - totalcount);
|
||||
locksize = ((framegroup.Value.Count - totalcount) > THING_BUFFER_SIZE) ? THING_BUFFER_SIZE : (framegroup.Value.Count - totalcount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1336,8 +1362,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
stream.Dispose();
|
||||
|
||||
// Draw what's still remaining
|
||||
if(buffercount > 0)
|
||||
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2);
|
||||
if(buffercount > 0) graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Done
|
||||
|
|
|
@ -144,10 +144,10 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
TextureStructure tx = new TextureStructure(this, "sprite", virtualpath);
|
||||
if(this.HasError) return false;
|
||||
|
||||
// if a limit for the sprite name length is set make sure that it's not exceeded
|
||||
if(tx.Name.Length > DataManager.CLASIC_IMAGE_NAME_LENGTH)
|
||||
//mxd. Sprite name length must be either 6 or 8 chars
|
||||
if(tx.Name.Length != 6 && tx.Name.Length != 8)
|
||||
{
|
||||
ReportError("Sprite name \"" + tx.Name + "\" too long. Sprite names must have a length of " + DataManager.CLASIC_IMAGE_NAME_LENGTH + " characters or less");
|
||||
ReportError("Sprite name \"" + tx.Name + "\" is incorrect. Sprite names must have a length of 6 or 8 characters");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue