Renderer now works much faster in 2D modes.

Textures now load up to 2x faster when "mix textures and flats" flag is set in game configuration.
TEXTUREx/TEXTURES: texture will now be created if at least one of it's patches is loaded.
Visual mode: fixed a crash when "Slope floor to here" (9500) or "Slope ceiling to here" (9501) things were not inside sector.
Fixed: flats were not loaded form wads inside Directory and PK3/PK7 resources.
Sector Info Panel, Linedef Info Panel: texture size was shown for unknown textures.
This commit is contained in:
MaxED 2013-07-29 08:50:50 +00:00
parent b3713489d3
commit cf3d416967
48 changed files with 518 additions and 512 deletions

View file

@ -754,7 +754,8 @@
<Compile Include="GZBuilder\Data\LinedefColorPreset.cs" />
<Compile Include="GZBuilder\Data\LinksCollector.cs" />
<Compile Include="GZBuilder\Data\MapInfo.cs" />
<Compile Include="GZBuilder\Data\ModeldefEntry.cs" />
<Compile Include="GZBuilder\Data\ModelData.cs" />
<Compile Include="GZBuilder\Data\ModelLoadState.cs" />
<Compile Include="GZBuilder\Data\ScriptItem.cs" />
<Compile Include="GZBuilder\Data\ScriptType.cs" />
<Compile Include="GZBuilder\Data\SharpCompressHelper.cs" />

View file

@ -41,7 +41,7 @@ namespace CodeImp.DoomBuilder.Config
#region ================== Properties
public ICollection<ImageData> Textures { get { return textures.Values; } }
public ICollection<ImageData> Flats { get { return flats.Values; } }
public ICollection<ImageData> Flats { get { return General.Map.Config.MixTexturesFlats ? textures.Values : flats.Values; } }
public DataLocation Location { get { return location; } }
#endregion
@ -86,28 +86,20 @@ namespace CodeImp.DoomBuilder.Config
// Check if this set has a flat
internal bool FlatExists(ImageData image)
{
if(General.Map.Config.MixTexturesFlats) return textures.ContainsKey(image.LongName); //mxd
return flats.ContainsKey(image.LongName);
}
// Mix the textures and flats
internal void MixTexturesAndFlats()
{
// Make a copy of the flats only
Dictionary<long, ImageData> flatsonly = new Dictionary<long, ImageData>(flats);
// Add textures to flats
foreach(KeyValuePair<long, ImageData> t in textures)
{
if(!flats.ContainsKey(t.Key))
flats.Add(t.Key, t.Value);
}
// Add flats to textures
foreach(KeyValuePair<long, ImageData> f in flatsonly)
{
foreach(KeyValuePair<long, ImageData> f in flats) {
if(!textures.ContainsKey(f.Key))
textures.Add(f.Key, f.Value);
}
flats.Clear(); //mxd
}
#endregion

View file

@ -50,7 +50,7 @@ namespace CodeImp.DoomBuilder.Controls
{
ImageData texture = General.Map.Data.GetFlatImage(imagename); //mxd
if(string.IsNullOrEmpty(texture.FullName)) DisplayImageSize(0, 0); //mxd
if(string.IsNullOrEmpty(texture.FullName) || texture is UnknownImage) DisplayImageSize(0, 0); //mxd
else DisplayImageSize(texture.ScaledWidth, texture.ScaledHeight); //mxd
// Set the image

View file

@ -445,7 +445,7 @@ namespace CodeImp.DoomBuilder.Controls
{
//mxd
ImageData texture = General.Map.Data.GetTextureImage(name);
if(General.Settings.ShowTextureSizes && texture.ImageState == ImageLoadState.Ready) {
if(General.Settings.ShowTextureSizes && texture.ImageState == ImageLoadState.Ready && !(texture is UnknownImage)) {
label.Visible = true;
label.Text = texture.ScaledWidth + "x" + texture.ScaledHeight;
} else {

View file

@ -221,7 +221,7 @@ namespace CodeImp.DoomBuilder.Controls
}
protected void DisplayTextureSize(Label label, ImageData texture) {
if(General.Settings.ShowTextureSizes && texture.ImageState == ImageLoadState.Ready && !string.IsNullOrEmpty(texture.Name)) {
if(General.Settings.ShowTextureSizes && texture.ImageState == ImageLoadState.Ready && !string.IsNullOrEmpty(texture.Name) && !(texture is UnknownImage)) {
label.Visible = true;
label.Text = texture.ScaledWidth + "x" + texture.ScaledHeight;
} else {

View file

@ -60,7 +60,7 @@ namespace CodeImp.DoomBuilder.Controls
{
ImageData texture = General.Map.Data.GetTextureImage(imagename); //mxd
if(string.IsNullOrEmpty(texture.FullName)) DisplayImageSize(0, 0); //mxd
if(string.IsNullOrEmpty(texture.FullName) || texture is UnknownImage) DisplayImageSize(0, 0); //mxd
else DisplayImageSize(texture.ScaledWidth, texture.ScaledHeight); //mxd
// Set the image

View file

@ -62,8 +62,8 @@ namespace CodeImp.DoomBuilder.Data
private AllTextureSet alltextures;
//mxd
private Dictionary<int, ModeldefEntry> modeldefEntries; //Thing.Type, Model entry
private Dictionary<int, GZDoomLight> gldefsEntries; //Thing.Type, Light entry
private Dictionary<int, ModelData> modeldefEntries; //Thing.Type, Model entry
private Dictionary<int, DynamicLightData> gldefsEntries; //Thing.Type, Light entry
private MapInfo mapInfo; //mapinfo
// Background loading
@ -82,8 +82,6 @@ namespace CodeImp.DoomBuilder.Data
private ImageData crosshair;
private ImageData crosshairbusy;
private Dictionary<string, ImageData> internalsprites;
//mxd
//private ImageData thingbox;
private ImageData whitetexture;
// Used images
@ -107,16 +105,16 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Properties
//mxd
internal Dictionary<int, ModeldefEntry> ModeldefEntries { get { return modeldefEntries; } }
internal Dictionary<int, GZDoomLight> GldefsEntries { get { return gldefsEntries; } }
internal Dictionary<int, ModelData> ModeldefEntries { get { return modeldefEntries; } }
internal Dictionary<int, DynamicLightData> GldefsEntries { get { return gldefsEntries; } }
internal MapInfo MapInfo { get { return mapInfo; } }
public Playpal Palette { get { return palette; } }
public PreviewManager Previews { get { return previews; } }
public ICollection<ImageData> Textures { get { return textures.Values; } }
public ICollection<ImageData> Flats { get { return flats.Values; } }
public ICollection<ImageData> Flats { get { return (General.Map.Config.MixTexturesFlats ? textures.Values : flats.Values); } } //mxd
public List<string> TextureNames { get { return texturenames; } }
public List<string> FlatNames { get { return flatnames; } }
public List<string> FlatNames { get { return (General.Map.Config.MixTexturesFlats ? texturenames : flatnames); } } //mxd
public bool IsDisposed { get { return isdisposed; } }
public ImageData MissingTexture3D { get { return missingtexture3d; } }
public ImageData UnknownTexture3D { get { return unknowntexture3d; } }
@ -136,15 +134,10 @@ namespace CodeImp.DoomBuilder.Data
get
{
if(imageque != null)
{
return (backgroundloader != null) && backgroundloader.IsAlive && ((imageque.Count > 0) || previews.IsLoading);
}
else
{
return false;
}
}
}
#endregion
@ -156,6 +149,10 @@ namespace CodeImp.DoomBuilder.Data
// We have no destructor
GC.SuppressFinalize(this);
//mxd.
modeldefEntries = new Dictionary<int, ModelData>();
gldefsEntries = new Dictionary<int, DynamicLightData>();
// Load special images
missingtexture3d = new ResourceImage("CodeImp.DoomBuilder.Resources.MissingTexture3D.png");
missingtexture3d.LoadImage();
@ -167,9 +164,6 @@ namespace CodeImp.DoomBuilder.Data
crosshair.LoadImage();
crosshairbusy = new ResourceImage("CodeImp.DoomBuilder.Resources.CrosshairBusy.png");
crosshairbusy.LoadImage();
//mxd
//thingbox = new ResourceImage("CodeImp.DoomBuilder.Resources.ThingBox.png");
//thingbox.LoadImage();
whitetexture = new ResourceImage("CodeImp.DoomBuilder.Resources.White.png");
whitetexture.UseColorCorrection = false;
whitetexture.LoadImage();
@ -194,18 +188,9 @@ namespace CodeImp.DoomBuilder.Data
crosshair = null;
crosshairbusy.Dispose();
crosshairbusy = null;
//mxd
//thingbox.Dispose();
//thingbox = null;
whitetexture.Dispose();
whitetexture = null;
//mxd
if (modeldefEntries != null) {
foreach (KeyValuePair<int, ModeldefEntry> group in modeldefEntries)
group.Value.Dispose();
modeldefEntries = null;
}
modeldefEntries = null;//mxd
mapInfo = null;
// Done
@ -363,16 +348,6 @@ namespace CodeImp.DoomBuilder.Data
// Mixed textures and flats?
if(General.Map.Config.MixTexturesFlats)
{
// Add textures to flats
foreach(KeyValuePair<long, ImageData> t in texturesonly)
{
if(!flats.ContainsKey(t.Key))
{
flats.Add(t.Key, t.Value);
flatnames.Add(t.Value.Name);
}
}
// Add flats to textures
foreach(KeyValuePair<long, ImageData> f in flatsonly)
{
@ -383,6 +358,9 @@ namespace CodeImp.DoomBuilder.Data
}
}
flats.Clear(); //mxd
flatnames.Clear(); //mxd
// Do the same on the data readers
foreach(DataReader dr in containers)
dr.TextureSet.MixTexturesAndFlats();
@ -401,10 +379,9 @@ namespace CodeImp.DoomBuilder.Data
// Add texture names to texture sets
foreach(KeyValuePair<long, ImageData> img in textures)
{
// Add to all sets where it matches
bool matchfound = false;
// Add to all sets
foreach(MatchingTextureSet ms in texturesets)
matchfound |= ms.AddTexture(img.Value);
ms.AddTexture(img.Value);
// Add to all
alltextures.AddTexture(img.Value);
@ -413,10 +390,9 @@ namespace CodeImp.DoomBuilder.Data
// Add flat names to texture sets
foreach(KeyValuePair<long, ImageData> img in flats)
{
// Add to all sets where it matches
bool matchfound = false;
// Add to all sets
foreach(MatchingTextureSet ms in texturesets)
matchfound |= ms.AddFlat(img.Value);
ms.AddFlat(img.Value);
// Add to all
alltextures.AddFlat(img.Value);
@ -426,7 +402,7 @@ namespace CodeImp.DoomBuilder.Data
StartBackgroundLoader();
// Output info
General.WriteLogLine("Loaded " + texcount + " textures, " + flatcount + " flats, " + colormapcount + " colormaps, " + spritecount + " sprites, " + thingcount + " decorate things, " + modeldefEntries.Count + " model deinitions, " + gldefsEntries.Count + " gl definitions");
General.WriteLogLine("Loaded " + texcount + " textures, " + flatcount + " flats, " + colormapcount + " colormaps, " + spritecount + " sprites, " + thingcount + " decorate things, " + modeldefEntries.Count + " model deinitions, " + gldefsEntries.Count + " dynamic light definitions");
}
// This unloads all data
@ -450,9 +426,8 @@ namespace CodeImp.DoomBuilder.Data
//mxd
if (modeldefEntries != null) {
foreach (KeyValuePair<int, ModeldefEntry> group in modeldefEntries) {
foreach (KeyValuePair<int, ModelData> group in modeldefEntries)
group.Value.Dispose();
}
}
// Dispose containers
@ -696,6 +671,20 @@ namespace CodeImp.DoomBuilder.Data
General.SendMessage(General.MainWindow.Handle, (int)MainForm.ThreadMessages.UpdateStatus, 0, 0);
}
//mxd. This loads a model
internal void ProcessModel(int type) {
if(modeldefEntries[type].LoadState != ModelLoadState.None) return;
//create models
ModelReader.Load(modeldefEntries[type], containers, General.Map.Graphics.Device);
if(modeldefEntries[type].Model != null) {
modeldefEntries[type].LoadState = ModelLoadState.Ready;
} else {
modeldefEntries.Remove(type);
}
}
// This updates the used-in-map status on all textures and flats
private void BackgroundUpdateUsedTextures()
{
@ -709,11 +698,12 @@ namespace CodeImp.DoomBuilder.Data
}
// Set used on all flats
foreach(KeyValuePair<long, ImageData> i in flats)
{
if(!General.Map.Config.MixTexturesFlats) {
foreach(KeyValuePair<long, ImageData> i in flats) {
i.Value.SetUsedInMap(usedimages.ContainsKey(i.Key));
if(i.Value.IsImageLoaded != i.Value.IsReferenced) ProcessImage(i.Value);
}
}
// Done
updatedusedtextures = false;
@ -851,7 +841,7 @@ namespace CodeImp.DoomBuilder.Data
Stream patch;
// Go for all opened containers
for(int i = containers.Count - 1; i >= 0; i--)
for(int i = containers.Count - 1; i > -1; i--)
{
// This contain provides this patch?
patch = containers[i].GetPatchData(pname);
@ -984,13 +974,13 @@ namespace CodeImp.DoomBuilder.Data
public bool GetFlatExists(string name)
{
long longname = Lump.MakeLongName(name);
return flats.ContainsKey(longname);
return General.Map.Config.MixTexturesFlats ? textures.ContainsKey(longname) : flats.ContainsKey(longname);
}
// This checks if a flat is known
public bool GetFlatExists(long longname)
{
return flats.ContainsKey(longname);
return General.Map.Config.MixTexturesFlats ? textures.ContainsKey(longname) : flats.ContainsKey(longname);
}
// This returns an image by string
@ -1004,24 +994,26 @@ namespace CodeImp.DoomBuilder.Data
// This returns an image by long
public ImageData GetFlatImage(long longname)
{
if(General.Map.Config.MixTexturesFlats) { //mxd
// Does this flat exist?
if(flats.ContainsKey(longname))
{
if(textures.ContainsKey(longname)) {
// Return flat
return textures[longname];
}
} else if(flats.ContainsKey(longname)) { // Does this flat exist?
// Return flat
return flats[longname];
}
else
{
// Return null image
return new UnknownImage(Properties.Resources.UnknownImage);
}
}
// This returns an image by long and doesn't check if it exists
public ImageData GetFlatImageKnown(long longname)
{
// Return flat
return flats[longname];
return General.Map.Config.MixTexturesFlats ? textures[longname] : flats[longname]; //mxd
}
#endregion
@ -1382,39 +1374,7 @@ namespace CodeImp.DoomBuilder.Data
#endregion
#region ================== Modeldef, Gldefs, Mapinfo and models loading
//mxd
public void LoadModels() {
General.MainWindow.DisplayStatus(StatusType.Busy, "Loading models...");
foreach (Thing t in General.Map.Map.Things)
t.IsModel = LoadModelForThing(t);
General.MainWindow.RedrawDisplay();
}
//mxd
public bool LoadModelForThing(Thing t) {
if (modeldefEntries.ContainsKey(t.Type)) {
if (modeldefEntries[t.Type].Model == null) {
//load models and textures
ModeldefEntry mde = modeldefEntries[t.Type];
//create models
ModelReader.Load(ref mde, containers, General.Map.Graphics.Device);
if (mde.Model != null) {
return true;
} else {
modeldefEntries.Remove(t.Type);
return false;
}
}
return true;
}
return false;
}
#region ================== mxd. Modeldef, Gldefs, Mapinfo
//mxd. This creates <Actor Class, Thing.Type> dictionary. Should be called after all DECORATE actors are parsed
private Dictionary<string, int> createActorsByClassList() {
@ -1442,13 +1402,14 @@ namespace CodeImp.DoomBuilder.Data
//mxd
public void ReloadModeldef() {
if (modeldefEntries != null) {
foreach (KeyValuePair<int, ModeldefEntry> group in modeldefEntries)
foreach (KeyValuePair<int, ModelData> group in modeldefEntries)
group.Value.Dispose();
}
General.MainWindow.DisplayStatus(StatusType.Busy, "Reloading model definitions...");
loadModeldefs(createActorsByClassList());
LoadModels();
foreach(Thing t in General.Map.Map.Things) t.UpdateModelStatus();
//rebuild geometry if in Visual mode
if (General.Editing.Mode != null && General.Editing.Mode.GetType().Name == "BaseVisualMode") {
@ -1486,17 +1447,13 @@ namespace CodeImp.DoomBuilder.Data
//mxd. This parses modeldefs. Should be called after all DECORATE actors are parsed and actorsByClass dictionary created
private void loadModeldefs(Dictionary<string, int> actorsByClass) {
modeldefEntries = new Dictionary<int, ModeldefEntry>(); //create it in all cases, so we don't have to check if it's null every time we need to access it
//if no actors defined in DECORATE or game config...
if (actorsByClass == null || actorsByClass.Count == 0) {
General.ErrorLogger.Add(ErrorType.Warning, "Warning: current game has no Actors!");
return;
}
foreach(Thing t in General.Map.Map.Things) t.IsModel = false; //drop model flag
Dictionary<string, ModeldefEntry> modelDefEntriesByName = new Dictionary<string, ModeldefEntry>();
Dictionary<string, ModelData> modelDefEntriesByName = new Dictionary<string, ModelData>();
ModeldefParser mdeParser = new ModeldefParser();
foreach (DataReader dr in containers) {
@ -1506,7 +1463,7 @@ namespace CodeImp.DoomBuilder.Data
foreach (KeyValuePair<string, Stream> group in streams) {
// Parse the data
if (mdeParser.Parse(group.Value, currentreader.Location.location + "\\" + group.Key)) {
foreach (KeyValuePair<string, ModeldefEntry> g in mdeParser.ModelDefEntries) {
foreach (KeyValuePair<string, ModelData> g in mdeParser.ModelDefEntries) {
modelDefEntriesByName.Add(g.Key, g.Value);
}
}
@ -1515,18 +1472,18 @@ namespace CodeImp.DoomBuilder.Data
currentreader = null;
foreach (KeyValuePair<string, ModeldefEntry> e in modelDefEntriesByName) {
foreach (KeyValuePair<string, ModelData> e in modelDefEntriesByName) {
if (actorsByClass.ContainsKey(e.Key))
modeldefEntries[actorsByClass[e.Key]] = modelDefEntriesByName[e.Key];
else if(!invalidDecorateActors.Contains(e.Key))
General.ErrorLogger.Add(ErrorType.Warning, "Got MODELDEF override for class '" + e.Key + "', but haven't found such class in Decorate");
}
foreach(Thing t in General.Map.Map.Things) t.UpdateModelStatus();
}
//mxd. This parses gldefs. Should be called after all DECORATE actors are parsed and actorsByClass dictionary created
private void loadGldefs(Dictionary<string, int> actorsByClass, bool loadDefaultDefinitions) {
gldefsEntries = new Dictionary<int, GZDoomLight>();//create it in all cases, so we don't have to check if it's null every time we need to access it
//if no actors defined in DECORATE or game config...
if (actorsByClass == null || actorsByClass.Count == 0) {
General.ErrorLogger.Add(ErrorType.Warning, "Warning: current game has no Actors!");

View file

@ -72,7 +72,7 @@ namespace CodeImp.DoomBuilder.Data
// Find in any of the wad files
// Note the backward order, because the last wad's images have priority
for(int i = wads.Count - 1; i >= 0; i--)
for(int i = wads.Count - 1; i > -1; i--)
{
Stream data = wads[i].GetPatchData(pname);
if(data != null) return data;
@ -80,14 +80,12 @@ namespace CodeImp.DoomBuilder.Data
try
{
// Find in patches directory
//string path = Path.Combine(PATCHES_DIR, Path.GetDirectoryName(pname));
//string filename = FindFirstFile(path, Path.GetFileName(pname), true);
//mxd. Find in directories ZDoom expects them to be
foreach(string location in PatchLocations){
string path = Path.Combine(location, Path.GetDirectoryName(pname));
string filename = FindFirstFile(path, Path.GetFileName(pname), true);
//mxd. ZDoom can load them from anywhere, so shall we
string filename = FindFirstFile(Path.GetDirectoryName(pname), Path.GetFileName(pname), true);
if((filename != null) && FileExists(filename))
{
if(!string.IsNullOrEmpty(filename) && FileExists(filename))
return LoadFile(filename);
}
}

View file

@ -28,7 +28,6 @@ namespace CodeImp.DoomBuilder.Data
{
#region ================== Variables
//private string filepathname;
private int probableformat;
#endregion
@ -39,9 +38,8 @@ namespace CodeImp.DoomBuilder.Data
public FileImage(string name, string filepathname, bool asflat)
{
// Initialize
//this.filepathname = filepathname;
this.fullName = filepathname; //mxd
SetName(name);
this.fullName = filepathname; //mxd
if(asflat)
{
@ -92,30 +90,29 @@ namespace CodeImp.DoomBuilder.Data
{
// Load file data
if(bitmap != null) bitmap.Dispose(); bitmap = null;
if(!File.Exists(fullName)) { //mxd
General.ErrorLogger.Add(ErrorType.Error, "Image file '" + fullName + "' could not be read: no such file.");
loadfailed = true;
} else {
MemoryStream filedata = new MemoryStream(File.ReadAllBytes(fullName));
// Get a reader for the data
IImageReader reader = ImageDataFormat.GetImageReader(filedata, probableformat, General.Map.Data.Palette);
if(!(reader is UnknownImageReader))
{
if(!(reader is UnknownImageReader)) {
// Load the image
filedata.Seek(0, SeekOrigin.Begin);
try { bitmap = reader.ReadAsBitmap(filedata); }
catch(InvalidDataException)
{
try { bitmap = reader.ReadAsBitmap(filedata); } catch(InvalidDataException) {
// Data cannot be read!
bitmap = null;
}
}
// Not loaded?
if(bitmap == null)
{
if(bitmap == null) {
General.ErrorLogger.Add(ErrorType.Error, "Image file '" + fullName + "' data format could not be read, while loading image '" + this.Name + "'. Is this a valid picture file at all?");
loadfailed = true;
}
else
{
} else {
// Get width and height
width = bitmap.Size.Width;
height = bitmap.Size.Height;
@ -126,6 +123,7 @@ namespace CodeImp.DoomBuilder.Data
base.LocalLoadImage();
}
}
}
#endregion
}

View file

@ -104,6 +104,8 @@ namespace CodeImp.DoomBuilder.Data
loadfailed = true;
}
int failCount = 0; //mxd
if(!loadfailed)
{
// Go for all patches
@ -126,7 +128,7 @@ namespace CodeImp.DoomBuilder.Data
{
// Data is in an unknown format!
General.ErrorLogger.Add(ErrorType.Error, "Patch lump '" + p.lumpname + "' data format could not be read, while loading texture '" + this.Name + "'");
loadfailed = true;
failCount++; //mxd
}
else
{
@ -138,7 +140,7 @@ namespace CodeImp.DoomBuilder.Data
{
// Data cannot be read!
General.ErrorLogger.Add(ErrorType.Error, "Patch lump '" + p.lumpname + "' data format could not be read, while loading texture '" + this.Name + "'");
loadfailed = true;
failCount++; //mxd
}
if(patchbmp != null)
{
@ -192,9 +194,9 @@ namespace CodeImp.DoomBuilder.Data
float bb = p.blend.b * PixelColor.BYTE_TO_FLOAT;
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--) {
cp->r = (byte)((((float)cp->r * PixelColor.BYTE_TO_FLOAT) * br) * 255.0f);
cp->g = (byte)((((float)cp->g * PixelColor.BYTE_TO_FLOAT) * bg) * 255.0f);
cp->b = (byte)((((float)cp->b * PixelColor.BYTE_TO_FLOAT) * bb) * 255.0f);
cp->r = (byte)(((cp->r * PixelColor.BYTE_TO_FLOAT) * br) * 255.0f);
cp->g = (byte)(((cp->g * PixelColor.BYTE_TO_FLOAT) * bg) * 255.0f);
cp->b = (byte)(((cp->b * PixelColor.BYTE_TO_FLOAT) * bb) * 255.0f);
}
} else if(p.blendstyle == TexturePathBlendStyle.Tint) {
float tintammount = p.tintammount - 0.1f;
@ -206,9 +208,9 @@ namespace CodeImp.DoomBuilder.Data
float invTint = 1.0f - tintammount;
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--) {
cp->r = (byte)((((float)cp->r * PixelColor.BYTE_TO_FLOAT) * invTint + br) * 255.0f);
cp->g = (byte)((((float)cp->g * PixelColor.BYTE_TO_FLOAT) * invTint + bg) * 255.0f);
cp->b = (byte)((((float)cp->b * PixelColor.BYTE_TO_FLOAT) * invTint + bb) * 255.0f);
cp->r = (byte)(((cp->r * PixelColor.BYTE_TO_FLOAT) * invTint + br) * 255.0f);
cp->g = (byte)(((cp->g * PixelColor.BYTE_TO_FLOAT) * invTint + bg) * 255.0f);
cp->b = (byte)(((cp->b * PixelColor.BYTE_TO_FLOAT) * invTint + bb) * 255.0f);
}
}
}
@ -216,7 +218,7 @@ namespace CodeImp.DoomBuilder.Data
//mxd. apply RenderStyle
if(p.style == TexturePathRenderStyle.Blend) {
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--)
cp->a = (byte)((((float)cp->a * PixelColor.BYTE_TO_FLOAT) * p.alpha) * 255.0f);
cp->a = (byte)(((cp->a * PixelColor.BYTE_TO_FLOAT) * p.alpha) * 255.0f);
//mxd. we need a copy of underlying part of texture for these styles
} else if(p.style != TexturePathRenderStyle.Copy) {
@ -239,7 +241,6 @@ namespace CodeImp.DoomBuilder.Data
if(texturebmpdata != null) {
PixelColor* texturepixels = (PixelColor*)(texturebmpdata.Scan0.ToPointer());
int numtexpixels = texturebmpdata.Width * texturebmpdata.Height;
PixelColor* tcp = texturepixels + numpixels - 1;
if(p.style == TexturePathRenderStyle.Add) {
@ -305,16 +306,17 @@ namespace CodeImp.DoomBuilder.Data
{
// Missing a patch lump!
General.ErrorLogger.Add(ErrorType.Error, "Missing patch lump '" + p.lumpname + "' while loading texture '" + this.Name + "'");
loadfailed = true;
failCount++; //mxd
}
}
}
// Dispose bitmap if load failed
if(loadfailed && (bitmap != null))
if((bitmap != null) && (loadfailed || failCount >= patches.Count)) //mxd. We can still display texture if at least one of the patches was loaded
{
bitmap.Dispose();
bitmap = null;
loadfailed = true;
}
// Pass on to base

View file

@ -177,9 +177,7 @@ namespace CodeImp.DoomBuilder.Data
{
this.name = name;
this.longname = Lump.MakeLongName(name);
//mxd
if (this.fullName == null)
this.fullName = name;
fullName = name; //mxd
}
// This unloads the image

View file

@ -33,7 +33,6 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Variables
private DirectoryFilesList files;
//private IArchive archive;//mxd
private ArchiveType archiveType; //mxd
private static Dictionary<string, byte[]> sevenZipEntries; //mxd
@ -123,11 +122,10 @@ namespace CodeImp.DoomBuilder.Data
if(data != null) return data;
}
// Find in patches directory
//string filename = FindFirstFile(PATCHES_DIR, pname, true);
string filename = FindFirstFile("", pname, true); //mxd. ZDoom can load them from anywhere, so shall we
//mxd. Find in directories ZDoom expects them to be
foreach(string location in PatchLocations) {
string filename = FindFirstFile(location, pname, true);
if((filename != null) && FileExists(filename))
{
return LoadFile(filename);
}

View file

@ -52,6 +52,8 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Properties
protected string[] PatchLocations = { PATCHES_DIR, TEXTURES_DIR, FLATS_DIR }; //mxd. Because ZDoom looks for patches in these folders
#endregion
#region ================== Constructor / Disposer
@ -327,6 +329,22 @@ namespace CodeImp.DoomBuilder.Data
return new List<ImageData>(images.Values);
}
//mxd.
public override Stream GetFlatData(string pname) {
// Error when suspended
if(issuspended) throw new Exception("Data reader is suspended");
// Find in any of the wad files
// Note the backward order, because the last wad's images have priority
for(int i = wads.Count - 1; i > -1; i--) {
Stream data = wads[i].GetFlatData(pname);
if(data != null) return data;
}
// Nothing found
return null;
}
#endregion
#region ================== Sprites

View file

@ -33,7 +33,6 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Variables
private List<TexturePatch> patches;
private bool gotFullName;//mxd
#endregion
@ -63,12 +62,6 @@ namespace CodeImp.DoomBuilder.Data
{
// Add it
patches.Add(patch);
//mxd. Get full name from first patch
if (!gotFullName) {
fullName = General.Map.Data.GetPatchLocation(patch.lumpname);
gotFullName = true;
}
}
// This loads the image
@ -103,6 +96,8 @@ namespace CodeImp.DoomBuilder.Data
loadfailed = true;
}
int failCount = 0; //mxd
if(!loadfailed)
{
// Go for all patches
@ -126,6 +121,7 @@ namespace CodeImp.DoomBuilder.Data
// Data is in an unknown format!
General.ErrorLogger.Add(ErrorType.Error, "Patch lump '" + p.lumpname + "' data format could not be read, while loading texture '" + this.Name + "'. Does this lump contain valid picture data at all?");
loadfailed = true;
failCount++; //mxd
}
else
{
@ -137,6 +133,7 @@ namespace CodeImp.DoomBuilder.Data
// Data cannot be read!
General.ErrorLogger.Add(ErrorType.Error, "Patch lump '" + p.lumpname + "' data format could not be read, while loading texture '" + this.Name + "'. Does this lump contain valid picture data at all?");
loadfailed = true;
failCount++; //mxd
}
}
@ -148,6 +145,7 @@ namespace CodeImp.DoomBuilder.Data
// Missing a patch lump!
General.ErrorLogger.Add(ErrorType.Error, "Missing patch lump '" + p.lumpname + "' while loading texture '" + this.Name + "'. Did you forget to include required resources?");
loadfailed = true;
failCount++; //mxd
}
}
@ -156,10 +154,11 @@ namespace CodeImp.DoomBuilder.Data
}
// Dispose bitmap if load failed
if(loadfailed && (bitmap != null))
if((bitmap != null) && (loadfailed || failCount >= patches.Count)) //mxd. We can still display texture if at least one of the patches was loaded
{
bitmap.Dispose();
bitmap = null;
loadfailed = true;
}
// Pass on to base

View file

@ -691,7 +691,7 @@ namespace CodeImp.DoomBuilder.Editing
General.Map.ThingsFilter.Update();
General.Map.Data.UpdateUsedTextures();
General.MainWindow.RefreshInfo();
General.MainWindow.RedrawDisplay();
//General.MainWindow.RedrawDisplay();
// Map changed!
General.Map.IsChanged = true;
@ -701,6 +701,7 @@ namespace CodeImp.DoomBuilder.Editing
General.Plugins.OnUndoEnd();
// Update interface
General.MainWindow.RedrawDisplay(); //mxd
dobackgroundwork = true;
General.MainWindow.UpdateInterface();
}
@ -833,7 +834,7 @@ namespace CodeImp.DoomBuilder.Editing
General.Map.ThingsFilter.Update();
General.Map.Data.UpdateUsedTextures();
General.MainWindow.RefreshInfo();
General.MainWindow.RedrawDisplay();
//General.MainWindow.RedrawDisplay();
// Map changed!
General.Map.IsChanged = true;
@ -843,6 +844,7 @@ namespace CodeImp.DoomBuilder.Editing
General.Plugins.OnRedoEnd();
// Update interface
General.MainWindow.RedrawDisplay(); //mxd
dobackgroundwork = true;
General.MainWindow.UpdateInterface();
}

View file

@ -2,8 +2,8 @@
namespace CodeImp.DoomBuilder.GZBuilder.Data
{
public sealed class GZDoomLight {
public int Type; //holds GZDoomLightType
public sealed class DynamicLightData {
public DynamicLightType Type; //holds DynamicLightType
public Color3 Color;
public int PrimaryRadius;
public int SecondaryRadius;
@ -12,14 +12,15 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
public bool Subtractive;
public bool DontLightSelf;
public GZDoomLight() {
public DynamicLightData() {
Color = new Color3();
Offset = new Vector3();
}
}
public enum GZDoomLightType
public enum DynamicLightType
{
NONE = -1,
NORMAL = 0,
PULSE = 1,
FLICKER = 2,
@ -30,7 +31,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
}
//divide these by 100 to get light color alpha
public enum GZDoomLightRenderStyle
public enum DynamicLightRenderStyle
{
NONE = 0,
NORMAL = 99,

View file

@ -2,17 +2,43 @@
using SlimDX;
using SlimDX.Direct3D9;
using CodeImp.DoomBuilder.GZBuilder.MD3;
using CodeImp.DoomBuilder.Data;
using System.IO;
using System;
using System.Text;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.IO;
using System.Drawing;
using System.Drawing.Imaging;
namespace CodeImp.DoomBuilder.GZBuilder.Data
{
internal sealed class ModeldefEntry
internal sealed class ModelData
{
private const float VERTICAL_STRETCH = 1 / 1.2f;
private class MD3LoadResult
{
public List<string> Skins;
public List<Mesh> Meshes;
public string Errors;
public MD3LoadResult() {
Skins = new List<string>();
Meshes = new List<Mesh>();
}
}
internal string ClassName;
internal List<string> ModelNames;
internal List<string> TextureNames;
internal GZModel Model;
private ModelLoadState loadstate;
public ModelLoadState LoadState { get { return loadstate; } internal set { loadstate = value; } }
internal Vector3 Scale;
internal float zOffset;
@ -20,7 +46,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
internal float PitchOffset; //in radians
internal float RollOffset; //in radians
internal ModeldefEntry() {
internal ModelData() {
ModelNames = new List<string>();
TextureNames = new List<string>();
}
@ -32,6 +58,8 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
foreach (Texture t in Model.Textures)
t.Dispose();
loadstate = ModelLoadState.None;
}
}
}

View file

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CodeImp.DoomBuilder.GZBuilder.Data
{
public enum ModelLoadState
{
None,
Loading,
Ready
}
}

View file

@ -11,10 +11,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
public delegate void IncludeDelegate(GldefsParser parser, string includefile);
public IncludeDelegate OnInclude;
private Dictionary<string, GZDoomLight> lightsByName; //LightName, light definition
private Dictionary<string, DynamicLightData> lightsByName; //LightName, light definition
private Dictionary<string, string> objects; //ClassName, LightName
public Dictionary<string, GZDoomLight> LightsByName { get { return lightsByName; } }
public Dictionary<string, DynamicLightData> LightsByName { get { return lightsByName; } }
public Dictionary<string, string> Objects { get { return objects; } }
private List<string> parsedLumps;
@ -26,12 +26,12 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
public const string FLICKER2 = "flickerlight2";
public const string SECTOR = "sectorlight";
public static Dictionary<string, int> GLDEFS_TO_GZDOOM_LIGHT_TYPE = new Dictionary<string, int>() { { POINT, 0 }, { PULSE, 1 }, { FLICKER, 2 }, { FLICKER2, 4 }, { SECTOR, 3 } };
public static Dictionary<string, DynamicLightType> GLDEFS_TO_GZDOOM_LIGHT_TYPE = new Dictionary<string, DynamicLightType>() { { POINT, DynamicLightType.NORMAL }, { PULSE, DynamicLightType.PULSE }, { FLICKER, DynamicLightType.FLICKER }, { FLICKER2, DynamicLightType.RANDOM }, { SECTOR, DynamicLightType.SECTOR } };
}
public GldefsParser() {
parsedLumps = new List<string>();
lightsByName = new Dictionary<string, GZDoomLight>(); //LightName, Light params
lightsByName = new Dictionary<string, DynamicLightData>(); //LightName, Light params
objects = new Dictionary<string, string>(); //ClassName, LightName
}
@ -60,7 +60,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
bool gotErrors = false;
string lightType = token;
GZDoomLight light = new GZDoomLight();
DynamicLightData light = new DynamicLightData();
light.Type = GldefsLightType.GLDEFS_TO_GZDOOM_LIGHT_TYPE[lightType];
//find classname
@ -295,14 +295,14 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
}
//light-type specific checks
if (light.Type == (int)GZDoomLightType.NORMAL) {
if (light.Type == DynamicLightType.NORMAL) {
if (light.PrimaryRadius == 0) {
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": light Size is 0. It won't be shown in GZDoom!");
gotErrors = true;
}
}
if (light.Type == (int)GZDoomLightType.FLICKER || light.Type == (int)GZDoomLightType.PULSE || light.Type == (int)GZDoomLightType.RANDOM) {
if (light.Type == DynamicLightType.FLICKER || light.Type == DynamicLightType.PULSE || light.Type == DynamicLightType.RANDOM) {
if (light.PrimaryRadius == 0 && light.SecondaryRadius == 0) {
General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": 'Size' and 'SecondarySize' are 0. This light won't be shown in GZDoom!");
gotErrors = true;

View file

@ -6,22 +6,18 @@ using CodeImp.DoomBuilder.GZBuilder.Data;
namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
internal class ModeldefParser : ZDTextParser {
private Dictionary<string, ModeldefEntry> modelDefEntries; //classname, entry
internal Dictionary<string, ModeldefEntry> ModelDefEntries { get { return modelDefEntries; } }
private List<string> classNames;
private Dictionary<string, ModelData> modelDefEntries; //classname, entry
internal Dictionary<string, ModelData> ModelDefEntries { get { return modelDefEntries; } }
internal string Source { get { return sourcename; } }
internal ModeldefParser() {
modelDefEntries = new Dictionary<string, ModeldefEntry>();
classNames = new List<string>();
modelDefEntries = new Dictionary<string, ModelData>();
}
//should be called after all decorate actors are parsed
public override bool Parse(Stream stream, string sourcefilename) {
base.Parse(stream, sourcefilename);
modelDefEntries = new Dictionary<string, ModeldefEntry>();
modelDefEntries = new Dictionary<string, ModelData>();
// Continue until at the end of the stream
while (SkipWhitespace(true)) {
@ -36,8 +32,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
string className = StripTokenQuotes(ReadToken()).ToLowerInvariant();
if (!string.IsNullOrEmpty(className)) {
if (classNames.IndexOf(className) != -1)
continue; //already got this class; continue to next one
if(modelDefEntries.ContainsKey(className)) continue; //already got this class; continue to next one
//now find opening brace
SkipWhitespace(true);
@ -48,11 +43,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
}
ModeldefStructure mds = new ModeldefStructure();
ModeldefEntry mde = mds.Parse(this);
ModelData mde = mds.Parse(this);
if (mde != null) {
mde.ClassName = className;
modelDefEntries.Add(className, mde);
classNames.Add(mde.ClassName);
}
}

View file

@ -9,7 +9,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
internal sealed class ModeldefStructure {
private const int MAX_MODELS = 4; //maximum models per modeldef entry, zero-based
internal ModeldefEntry Parse(ModeldefParser parser) {
internal ModelData Parse(ModeldefParser parser) {
string[] textureNames = new string[4];
string[] modelNames = new string[4];
string path = "";
@ -311,7 +311,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
if (gotErrors) return null;
//classname is set in ModeldefParser
ModeldefEntry mde = new ModeldefEntry();
ModelData mde = new ModelData();
mde.Scale = scale;
mde.zOffset = zOffset;
mde.AngleOffset = Angle2D.DegToRad(angleOffset);// *(float)Math.PI / 180.0f;

View file

@ -14,7 +14,7 @@ namespace CodeImp.DoomBuilder.GZBuilder
public static int[] GZ_LIGHTS { get { return gzLights; } }
private static int[] gzLightTypes = { 5, 10, 15 }; //these are actually offsets in gz_lights
public static int[] GZ_LIGHT_TYPES { get { return gzLightTypes; } }
private static int[] gzAnimatedLightTypes = { (int)GZDoomLightType.FLICKER, (int)GZDoomLightType.RANDOM, (int)GZDoomLightType.PULSE };
private static int[] gzAnimatedLightTypes = { (int)DynamicLightType.FLICKER, (int)DynamicLightType.RANDOM, (int)DynamicLightType.PULSE };
public static int[] GZ_ANIMATED_LIGHT_TYPES { get { return gzAnimatedLightTypes; } }
//asc script action specials

View file

@ -31,7 +31,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
}
}
public static void Load(ref ModeldefEntry mde, List<DataReader> containers, Device device) {
public static void Load(ModelData mde, List<DataReader> containers, Device device) {
mde.Model = new GZModel();
BoundingBoxSizes bbs = new BoundingBoxSizes();
MD3LoadResult result = new MD3LoadResult();
@ -142,7 +142,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
mde.Model.BoundingBox = BoundingBoxTools.CalculateBoundingBox(bbs);
}
private static MD3LoadResult ReadMD3Model(ref BoundingBoxSizes bbs, ModeldefEntry mde, bool useSkins, MemoryStream s, Device device) {
private static MD3LoadResult ReadMD3Model(ref BoundingBoxSizes bbs, ModelData mde, bool useSkins, MemoryStream s, Device device) {
long start = s.Position;
MD3LoadResult result = new MD3LoadResult();
@ -224,7 +224,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
return result;
}
private static string ReadSurface(ref BoundingBoxSizes bbs, ref string skin, BinaryReader br, List<int> polyIndecesList, List<WorldVertex> vertList, ModeldefEntry mde) {
private static string ReadSurface(ref BoundingBoxSizes bbs, ref string skin, BinaryReader br, List<int> polyIndecesList, List<WorldVertex> vertList, ModelData mde) {
int vertexOffset = vertList.Count;
long start = br.BaseStream.Position;
string magic = ReadString(br, 4);
@ -352,7 +352,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
result.Meshes.Add(mesh);
}
private static MD3LoadResult ReadMD2Model(ref BoundingBoxSizes bbs, ModeldefEntry mde, MemoryStream s, Device D3DDevice) {
private static MD3LoadResult ReadMD2Model(ref BoundingBoxSizes bbs, ModelData mde, MemoryStream s, Device D3DDevice) {
long start = s.Position;
MD3LoadResult result = new MD3LoadResult();
@ -552,8 +552,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
ms.Close();
ms.Dispose();
if(bitmap == null) return null;
if(bitmap != null) {
BitmapData bmlock = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
texture = new Texture(device, bitmap.Width, bitmap.Height, 1, Usage.None, Format.A8R8G8B8, Pool.Managed);
@ -562,14 +561,13 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
bitmap.UnlockBits(bmlock);
texture.UnlockRectangle(0);
return texture;
}
} else {
texture = Texture.FromStream(device, ms);
ms.Close();
ms.Dispose();
}
return texture;
}

View file

@ -297,11 +297,8 @@ namespace CodeImp.DoomBuilder {
map.Update();
thingsfilter.Update();
//mxd. load models
data.LoadModels();
//mxd
namedScripts = new List<ScriptItem>();
numberedScripts = new List<ScriptItem>();
namedScripts = new List<ScriptItem>(); //mxd
numberedScripts = new List<ScriptItem>(); //mxd
// Bind any methods
General.Actions.BindMethods(this);
@ -360,8 +357,7 @@ namespace CodeImp.DoomBuilder {
#if DEBUG
tempwad = new WAD(tempfile);
#else
try { tempwad = new WAD(tempfile); }
catch(Exception e)
try { tempwad = new WAD(tempfile); } catch(Exception e)
{
General.ShowErrorMessage("Error while creating a temporary wad file:\n" + e.GetType().Name + ": " + e.Message, MessageBoxButtons.OK);
return false;
@ -373,8 +369,7 @@ namespace CodeImp.DoomBuilder {
#if DEBUG
mapwad = new WAD(filepathname, true);
#else
try { mapwad = new WAD(filepathname, true); }
catch(Exception e)
try { mapwad = new WAD(filepathname, true); } catch(Exception e)
{
General.ShowErrorMessage("Error while opening source wad file:\n" + e.GetType().Name + ": " + e.Message, MessageBoxButtons.OK);
return false;
@ -397,8 +392,7 @@ namespace CodeImp.DoomBuilder {
#if DEBUG
map = io.Read(map, TEMP_MAP_HEADER);
#else
try { map = io.Read(map, TEMP_MAP_HEADER); }
catch(Exception e)
try { map = io.Read(map, TEMP_MAP_HEADER); } catch(Exception e)
{
General.ErrorLogger.Add(ErrorType.Error, "Unable to read the map data structures with the specified configuration. " + e.GetType().Name + ": " + e.Message);
General.ShowErrorMessage("Unable to read the map data structures with the specified configuration.", MessageBoxButtons.OK);
@ -423,8 +417,6 @@ namespace CodeImp.DoomBuilder {
map.Update();
thingsfilter.Update();
//mxd. load models
data.LoadModels();
//mxd. check script names
UpdateScriptNames();

View file

@ -104,6 +104,7 @@ namespace CodeImp.DoomBuilder.Map
internal bool FrontInterior { get { return frontinterior; } set { frontinterior = value; } }
internal bool ImpassableFlag { get { return impassableflag; } }
internal int ColorPresetIndex { get { return colorPresetIndex; } } //mxd
internal bool ExtraFloorFlag; //mxd
#endregion
@ -287,7 +288,6 @@ namespace CodeImp.DoomBuilder.Map
l.updateneeded = true;
l.activate = activate;
l.impassableflag = impassableflag;
//l.blocksoundflag = blocksoundflag;
l.UpdateColorPreset();//mxd
base.CopyPropertiesTo(l);
}
@ -812,6 +812,7 @@ namespace CodeImp.DoomBuilder.Map
SetEndVertex(v);
nl.Selected = this.Selected;
nl.marked = this.marked;
nl.ExtraFloorFlag = this.ExtraFloorFlag; //mxd
// Copy front sidedef if exists
if(front != null)

View file

@ -77,7 +77,7 @@ namespace CodeImp.DoomBuilder.Map
private int numthings;
//mxd
private Sector[] newSectors;
private Dictionary<int, int> newSectorLineIndices; //line index, sector order
private GroupInfo[] groupInfos;
// Behavior
@ -160,7 +160,7 @@ namespace CodeImp.DoomBuilder.Map
internal bool AutoRemove { get { return autoremove; } set { autoremove = value; } }
public Sector[] NewSectors { get { return newSectors; } } //mxd
public Dictionary<int, int> NewSectorLineIndices { get { return newSectorLineIndices; } } //mxd
public GroupInfo[] GroupInfos { get { return groupInfos; } } //mxd
@ -184,7 +184,6 @@ namespace CodeImp.DoomBuilder.Map
indexholes = new List<int>();
lastsectorindex = 0;
autoremove = true;
newSectors = new Sector[0]; //mxd
groupInfos = new GroupInfo[10]; //mxd
// We have no destructor
@ -207,7 +206,6 @@ namespace CodeImp.DoomBuilder.Map
indexholes = new List<int>();
lastsectorindex = 0;
autoremove = true;
newSectors = new Sector[0]; //mxd
groupInfos = new GroupInfo[10]; //mxd
// Deserialize
@ -258,7 +256,6 @@ namespace CodeImp.DoomBuilder.Map
sel_sectors = null;
sel_things = null;
indexholes = null;
newSectors = null; //mxd
groupInfos = null; //mxd
// Done
@ -3043,8 +3040,19 @@ namespace CodeImp.DoomBuilder.Map
//mxd
private void updateNewSectors() {
int n = sectors.Length < General.Settings.GZNewSectorsCount ? sectors.Length : General.Settings.GZNewSectorsCount;
newSectors = new Sector[n];
Sector[] newSectors = new Sector[n];
Array.Copy(sectors, sectors.Length - n, newSectors, 0, n);
List<int> newLineIndices = new List<int>();
newSectorLineIndices = new Dictionary<int, int>();
for(int i = newSectors.Length-1; i > -1; i--) {
foreach (Sidedef side in newSectors[i].Sidedefs){
if(newLineIndices.Contains(side.Line.Index)) continue;
newLineIndices.Add(side.Line.Index);
newSectorLineIndices.Add(side.Line.Index, i);
}
}
}
#endregion

View file

@ -23,6 +23,7 @@ using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.VisualModes;
using CodeImp.DoomBuilder.GZBuilder.Data;
#endregion
@ -56,7 +57,8 @@ namespace CodeImp.DoomBuilder.Map
private int tag;
private int action;
private int[] args;
protected float scale; //mxd. Used in model rendering
private float scale; //mxd. Used in model rendering
private bool isModel; //mxd
// Configuration
private float size;
@ -69,7 +71,7 @@ namespace CodeImp.DoomBuilder.Map
#region ================== Properties
public MapSet Map { get { return map; } }
public int Type { get { return type; } set { BeforePropsChange(); type = value; } }
public int Type { get { return type; } set { BeforePropsChange(); type = value; UpdateModelStatus(); } } //mxd
public Vector3D Position { get { return pos; } }
public float Scale { get { return scale; } } //mxd
public float Angle { get { return anglerad; } }
@ -83,8 +85,7 @@ namespace CodeImp.DoomBuilder.Map
public bool FixedSize { get { return fixedsize; } }
public int Tag { get { return tag; } set { BeforePropsChange(); tag = value; if((tag < General.Map.FormatInterface.MinTag) || (tag > General.Map.FormatInterface.MaxTag)) throw new ArgumentOutOfRangeException("Tag", "Invalid tag number"); } }
public Sector Sector { get { return sector; } }
//mxd
public bool IsModel;
public bool IsModel { get { return isModel; } } //mxd
#endregion
@ -182,8 +183,10 @@ namespace CodeImp.DoomBuilder.Map
s.rwInt(ref action);
for(int i = 0; i < NUM_ARGS; i++) s.rwInt(ref args[i]);
if(!s.IsWriting)
if(!s.IsWriting) {
anglerad = Angle2D.DoomToReal(angledoom);
UpdateModelStatus(); //mxd
}
}
// This copies all properties to another thing
@ -193,6 +196,7 @@ namespace CodeImp.DoomBuilder.Map
// Copy properties
t.type = type;
t.UpdateModelStatus();
t.anglerad = anglerad;
t.angledoom = angledoom;
t.pos = pos;
@ -235,6 +239,20 @@ namespace CodeImp.DoomBuilder.Map
}
}
//mxd. This checks if the thing has model override
internal void UpdateModelStatus() {
if(General.Map.Data == null) {
isModel = false;
return;
}
isModel = General.Map.Data.ModeldefEntries.ContainsKey(type);
if(!isModel) return;
if(General.Map.Data.ModeldefEntries[type].LoadState == ModelLoadState.None)
General.Map.Data.ProcessModel(type);
}
// This translates the flags into UDMF fields
internal void TranslateToUDMF()
{
@ -405,6 +423,7 @@ namespace CodeImp.DoomBuilder.Map
this.args = new int[NUM_ARGS];
args.CopyTo(this.args, 0);
this.Move(x, y, zoffset);
UpdateModelStatus(); //mxd
}
// This updates the settings from configuration

View file

@ -48,7 +48,7 @@ namespace CodeImp.DoomBuilder.Rendering
PixelColor DetermineThingColor(Thing t);
int DetermineVertexColor(Vertex v);
int CalculateBrightness(int level);
void Update3dFloorTagsList(); //mxd
void UpdateExtraFloorFlag(); //mxd
// Rendering management methods
bool StartPlotter(bool clear);

View file

@ -39,7 +39,7 @@ namespace CodeImp.DoomBuilder.Rendering
* PresentationLayer(s) to specify how to present these layers.
*/
internal unsafe sealed class Renderer2D : Renderer, IRenderer2D
internal sealed class Renderer2D : Renderer, IRenderer2D
{
#region ================== Constants
@ -49,7 +49,7 @@ namespace CodeImp.DoomBuilder.Rendering
private const float THING_CIRCLE_SIZE = 1f;
private const float THING_CIRCLE_SHRINK = 0f;
private const int THING_BUFFER_SIZE = 100;
//private const float THINGS_BACK_ALPHA = 0.3f;
private const float MINIMUM_THING_RADIUS = 1.5f; //mxd
private const string FONT_NAME = "Verdana";
private const int FONT_WIDTH = 0;
@ -128,8 +128,7 @@ namespace CodeImp.DoomBuilder.Rendering
private Presentation present;
//mxd
private Dictionary<Vector2D, Thing> thingsWithModel;
private List<int> tagsOf3DFloors;
private Dictionary<int, Dictionary<Vector2D, Thing>> thingsWithModel; //model index, list of thing positions in screen space, thing
#endregion
@ -165,7 +164,6 @@ namespace CodeImp.DoomBuilder.Rendering
// Create surface manager
surfaces = new SurfaceManager();
tagsOf3DFloors = new List<int>(); //mxd
// Create rendertargets
CreateRendertargets();
@ -203,7 +201,7 @@ namespace CodeImp.DoomBuilder.Rendering
}
// This draws the image on screen
public void Present()
public unsafe void Present()
{
General.Plugins.OnPresentDisplayBegin();
@ -398,7 +396,7 @@ namespace CodeImp.DoomBuilder.Rendering
}
// Allocates new image memory to render on
public void CreateRendertargets()
public unsafe void CreateRendertargets()
{
SurfaceDescription sd;
DataStream stream;
@ -581,16 +579,17 @@ namespace CodeImp.DoomBuilder.Rendering
public PixelColor DetermineThingColor(Thing t)
{
// Determine color
if (t.Selected) {
return General.Colors.Selection;
if (t.Selected) return General.Colors.Selection;
//mxd. if thing is light, set it's color to light color:
}else if(Array.IndexOf(GZBuilder.GZGeneral.GZ_LIGHTS, t.Type) != -1){
if(Array.IndexOf(GZBuilder.GZGeneral.GZ_LIGHTS, t.Type) != -1){
if (t.Type == 1502) //vavoom light
return new PixelColor(255, 255, 255, 255);
if (t.Type == 1503) //vavoom colored light
return new PixelColor(255, (byte)t.Args[1], (byte)t.Args[2], (byte)t.Args[3]);
return new PixelColor(255, (byte)t.Args[0], (byte)t.Args[1], (byte)t.Args[2]);
}
return t.Color;
}
@ -605,12 +604,10 @@ namespace CodeImp.DoomBuilder.Rendering
// This returns the color for a linedef
public PixelColor DetermineLinedefColor(Linedef l)
{
if(l.Selected)
return General.Colors.Selection;
if(l.Selected) return General.Colors.Selection;
if(l.ImpassableFlag)
{
//mxd. Impassable lines
if(l.ImpassableFlag) {
if(l.ColorPresetIndex != -1)
return General.Map.ConfigSettings.LinedefColorPresets[l.ColorPresetIndex].Color;
return General.Colors.Linedefs;
@ -622,18 +619,34 @@ namespace CodeImp.DoomBuilder.Rendering
return General.Colors.Linedefs.WithAlpha(General.Settings.DoubleSidedAlphaByte);
}
//mxd
public void Update3dFloorTagsList() {
//mxd. Collect 3d-floors tags
tagsOf3DFloors = new List<int>();
//mxd. This collects indices of linedefs, which are parts of sectors with 3d floors
public void UpdateExtraFloorFlag() {
List<int> tagList = new List<int>();
//find lines with 3d floor action and collect sector tags
foreach(Linedef l in General.Map.Map.Linedefs){
if(l.Action == 160) {
int sectortag = (l.Args[1] & 8) != 0 ? l.Args[0] : l.Args[0] + (l.Args[4] << 8);
if(sectortag != 0 && !tagsOf3DFloors.Contains(sectortag))
tagsOf3DFloors.Add(sectortag);
if(sectortag != 0) tagList.Add(sectortag);
}
}
tagList.Sort();
int[] tags = tagList.ToArray();
//find lines, which are related to sectors with 3d floors, and collect their valuable indices
foreach(Linedef l in General.Map.Map.Linedefs) {
if(l.Front != null && l.Front.Sector != null && l.Front.Sector.Tag != 0 && Array.BinarySearch(tags, l.Front.Sector.Tag) > -1) {
l.ExtraFloorFlag = true;
continue;
}
if(l.Back != null && l.Back.Sector != null && l.Back.Sector.Tag != 0 && Array.BinarySearch(tags, l.Back.Sector.Tag) > -1) {
l.ExtraFloorFlag = true;
continue;
}
l.ExtraFloorFlag = false;
}
}
#endregion
@ -643,10 +656,7 @@ namespace CodeImp.DoomBuilder.Rendering
// This begins a drawing session
public unsafe bool StartPlotter(bool clear)
{
if(renderlayer != RenderLayers.None) {
//throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!");
return false; //mxd. Can't render. Most probably because previous frame or render layer wasn't finished yet.
}
if(renderlayer != RenderLayers.None) return false; //mxd. Can't render. Most probably because previous frame or render layer wasn't finished yet.
renderlayer = RenderLayers.Plotter;
try { graphics.Device.SetRenderState(RenderState.FogEnable, false); } catch(Exception) { }
@ -672,21 +682,16 @@ namespace CodeImp.DoomBuilder.Rendering
UpdateTransformations();
return true;
}
else
{
// Can't render!
Finish();
return false;
}
}
// This begins a drawing session
public unsafe bool StartThings(bool clear)
public bool StartThings(bool clear)
{
if(renderlayer != RenderLayers.None) {
//throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!");
return false; //mxd. Can't render. Most probably because previous frame or render layer wasn't finished yet.
}
if(renderlayer != RenderLayers.None) return false; //mxd. Can't render. Most probably because previous frame or render layer wasn't finished yet.
renderlayer = RenderLayers.Things;
try { graphics.Device.SetRenderState(RenderState.FogEnable, false); } catch(Exception) { }
@ -702,29 +707,21 @@ namespace CodeImp.DoomBuilder.Rendering
UpdateTransformations();
return true;
}
else
{
// Can't render!
Finish();
return false;
}
}
else
{
// Can't render!
Finish();
return false;
}
}
// This begins a drawing session
public unsafe bool StartOverlay(bool clear)
public bool StartOverlay(bool clear)
{
if(renderlayer != RenderLayers.None) {
//throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!");
return false; //mxd. Can't render. Most probably because previous frame or render layer wasn't finished yet.
}
if(renderlayer != RenderLayers.None) throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!");
renderlayer = RenderLayers.Overlay;
try { graphics.Device.SetRenderState(RenderState.FogEnable, false); } catch(Exception) { }
@ -739,20 +736,16 @@ namespace CodeImp.DoomBuilder.Rendering
UpdateTransformations();
return true;
}
else
{
// Can't render!
Finish();
return false;
}
}
else
{
// Can't render!
Finish();
return false;
}
}
// This ends a drawing session
public void Finish()
@ -794,8 +787,8 @@ namespace CodeImp.DoomBuilder.Rendering
private void SetupBackground()
{
Vector2D ltpos, rbpos;
Vector2D backoffset = new Vector2D((float)General.Map.Grid.BackgroundX, (float)General.Map.Grid.BackgroundY);
Vector2D backimagesize = new Vector2D((float)General.Map.Grid.Background.ScaledWidth, (float)General.Map.Grid.Background.ScaledHeight);
Vector2D backoffset = new Vector2D(General.Map.Grid.BackgroundX, General.Map.Grid.BackgroundY);
Vector2D backimagesize = new Vector2D(General.Map.Grid.Background.ScaledWidth, General.Map.Grid.Background.ScaledHeight);
Vector2D backimagescale = new Vector2D(General.Map.Grid.BackgroundScaleX, General.Map.Grid.BackgroundScaleY);
// Scale the background image size
@ -835,7 +828,7 @@ namespace CodeImp.DoomBuilder.Rendering
}
// This renders all grid
private void RenderBackgroundGrid()
private unsafe void RenderBackgroundGrid()
{
Plotter gridplotter;
DataRectangle lockedrect;
@ -951,9 +944,10 @@ namespace CodeImp.DoomBuilder.Rendering
// Returns false when not on the screen
private bool CreateThingVerts(Thing t, ref FlatVertex[] verts, int offset, PixelColor c)
{
if(t.Size * scale < MINIMUM_THING_RADIUS) return false; //mxd. Don't render tiny little things
float circlesize;
float arrowsize;
int color;
// Transform to screen coordinates
Vector2D screenpos = ((Vector2D)t.Position).GetTransformed(translatex, translatey, scale, -scale);
@ -971,20 +965,24 @@ namespace CodeImp.DoomBuilder.Rendering
}
// Check if the thing is actually on screen
if(((screenpos.x + circlesize) > 0.0f) && ((screenpos.x - circlesize) < (float)windowsize.Width) &&
((screenpos.y + circlesize) > 0.0f) && ((screenpos.y - circlesize) < (float)windowsize.Height))
if(((screenpos.x + circlesize) > 0.0f) && ((screenpos.x - circlesize) < windowsize.Width) &&
((screenpos.y + circlesize) > 0.0f) && ((screenpos.y - circlesize) < windowsize.Height))
{
//mxd. Collect things with models for rendering
if (General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected)) {
Dictionary<int, ModeldefEntry> mde = General.Map.Data.ModeldefEntries;
if (mde != null && mde.ContainsKey(t.Type)) {
thingsWithModel[screenpos] = t;
}
if(t.IsModel && General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected)) {
if(!thingsWithModel.ContainsKey(t.Type)) {
thingsWithModel.Add(t.Type, new Dictionary<Vector2D, Thing>());
}
if(thingsWithModel[t.Type].ContainsKey(screenpos)) {
thingsWithModel[t.Type][screenpos] = t;
} else {
thingsWithModel[t.Type].Add(screenpos, t);
}
}
// Get integral color
color = c.ToInt();
int color = c.ToInt();
// Setup fixed rect for circle
verts[offset].x = screenpos.x - circlesize;
@ -1051,12 +1049,10 @@ namespace CodeImp.DoomBuilder.Rendering
// Done
return true;
}
else
{
// Not on screen
return false;
}
}
// This draws a set of things
private void RenderThingsBatch(ICollection<Thing> things, float alpha, bool fixedcolor, PixelColor c)
@ -1099,7 +1095,7 @@ namespace CodeImp.DoomBuilder.Rendering
FlatVertex[] verts = new FlatVertex[THING_BUFFER_SIZE * 12];
//mxd
thingsWithModel = new Dictionary<Vector2D, Thing>();
thingsWithModel = new Dictionary<int, Dictionary<Vector2D, Thing>>();
// Go for all things
int buffercount = 0;
@ -1152,25 +1148,28 @@ namespace CodeImp.DoomBuilder.Rendering
graphics.Device.SetRenderState(RenderState.FillMode, FillMode.Wireframe);
graphics.Shaders.Things2D.BeginPass(1);
foreach(KeyValuePair<Vector2D, Thing> group in thingsWithModel){
ModeldefEntry mde = General.Map.Data.ModeldefEntries[group.Value.Type];
if (mde.Model != null) {//render model
//wire color
graphics.Shaders.Things2D.FillColor = group.Value.Selected ? General.Colors.Selection.ToColorValue() : General.Colors.ModelWireframe.ToColorValue();
Color4 cSel = General.Colors.Selection.ToColorValue();
Color4 cWire = General.Colors.ModelWireframe.ToColorValue();
ModelData mde;
foreach(KeyValuePair<int, Dictionary<Vector2D, Thing>> group in thingsWithModel) {
lock(General.Map.Data.ModeldefEntries[group.Key]) {
mde = General.Map.Data.ModeldefEntries[group.Key];
foreach(KeyValuePair<Vector2D, Thing> thingData in group.Value) {
graphics.Shaders.Things2D.FillColor = thingData.Value.Selected ? cSel : cWire;
for(int i = 0; i < mde.Model.Meshes.Count; i++) {
graphics.Shaders.Things2D.SetTransformSettings(group.Key, group.Value.Angle, scale * group.Value.Scale);
graphics.Shaders.Things2D.SetTransformSettings(thingData.Key, thingData.Value.Angle, scale * thingData.Value.Scale);
graphics.Shaders.Things2D.ApplySettings();
// Draw
mde.Model.Meshes[i].DrawSubset(0);
}
}
}
}
} else {
group.Value.IsModel = General.Map.Data.LoadModelForThing(group.Value);
}
}
graphics.Shaders.Things2D.EndPass();
graphics.Device.SetRenderState(RenderState.FillMode, FillMode.Solid);
@ -1201,9 +1200,7 @@ namespace CodeImp.DoomBuilder.Rendering
// This redraws the surface
public void RedrawSurface()
{
//mxd...
//if(renderlayer != RenderLayers.None) throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!");
if(renderlayer != RenderLayers.None) return;
if(renderlayer != RenderLayers.None) return; //mxd
renderlayer = RenderLayers.Surface;
// Rendertargets available?
@ -1597,33 +1594,20 @@ namespace CodeImp.DoomBuilder.Rendering
Vector2D v2 = l.End.Position.GetTransformed(translatex, translatey, scale, -scale);
//mxd. Newly created sectors colouring
if(General.Settings.GZNewSectorsCount > 0 && c.r == 255 && c.g == 255 && c.b == 255){
int frontIndex = -1;
int backIndex = -1;
if(l.Front != null)
frontIndex = Array.IndexOf(General.Map.Map.NewSectors, l.Front.Sector);
if(l.Back != null)
backIndex = Array.IndexOf(General.Map.Map.NewSectors, l.Back.Sector);
if(frontIndex != -1 || backIndex != -1){
if(General.Settings.GZNewSectorsCount > 0 && l.ColorPresetIndex == -1){
if(General.Map.Map.NewSectorLineIndices.ContainsKey(l.Index)){
int index = General.Map.Map.NewSectorLineIndices[l.Index];
PixelColor highlight = General.Colors.NewSector;
if(frontIndex > backIndex)
highlight.a = (byte)(255 * (1.0f - (float)(frontIndex + 1) / General.Map.Map.NewSectors.Length));
else
highlight.a = (byte)(255 * (1.0f - (float)(backIndex + 1) / General.Map.Map.NewSectors.Length));
float ba = (float)highlight.a * PixelColor.BYTE_TO_FLOAT;
c.r = (byte)Math.Min(255, ((float)highlight.r * (1f - ba) + (float)c.r * ba));
c.g = (byte)Math.Min(255, ((float)highlight.g * (1f - ba) + (float)c.g * ba));
c.b = (byte)Math.Min(255, ((float)highlight.b * (1f - ba) + (float)c.b * ba));
highlight.a = (byte)(255 * (1.0f - (float)(index + 1) / General.Settings.GZNewSectorsCount));
float ha = highlight.a * PixelColor.BYTE_TO_FLOAT;
c.r = (byte)Math.Min(255, (highlight.r * (1f - ha) + c.r * ha));
c.g = (byte)Math.Min(255, (highlight.g * (1f - ha) + c.g * ha));
c.b = (byte)Math.Min(255, (highlight.b * (1f - ha) + c.b * ha));
}
}
// Draw line. mxd: added 3d-floor indication
if((l.Front != null && l.Front.Sector != null && tagsOf3DFloors.Contains(l.Front.Sector.Tag)) ||
(l.Back != null && l.Back.Sector != null && tagsOf3DFloors.Contains(l.Back.Sector.Tag))) {
if(l.ExtraFloorFlag) {
plotter.DrawLine3DFloor(v1, v2, ref c, General.Colors.ThreeDFloor);
} else {
plotter.DrawLineSolid((int)v1.x, (int)v1.y, (int)v2.x, (int)v2.y, ref c);

View file

@ -74,7 +74,7 @@ namespace CodeImp.DoomBuilder.Rendering
private List<VisualThing> thingsWithLight;
private int[] lightOffsets;
private Dictionary<Texture, List<VisualGeometry>> litGeometry;
private Dictionary<ModeldefEntry, List<VisualThing>> thingsWithModel;
private Dictionary<ModelData, List<VisualThing>> thingsWithModel;
// Crosshair
private FlatVertex[] crosshairverts;
@ -418,7 +418,7 @@ namespace CodeImp.DoomBuilder.Rendering
things = new Dictionary<ImageData, List<VisualThing>>[RENDER_PASSES];
thingsbydistance = new BinaryHeap<VisualThing>();
//mxd
thingsWithModel = new Dictionary<ModeldefEntry, List<VisualThing>>();
thingsWithModel = new Dictionary<ModelData, List<VisualThing>>();
litGeometry = new Dictionary<Texture, List<VisualGeometry>>();
for(int i = 0; i < RENDER_PASSES; i++)
@ -537,9 +537,9 @@ namespace CodeImp.DoomBuilder.Rendering
lightOffsets = new int[3];
foreach (VisualThing t in thingsWithLight) {
//add light to apropriate array.
if (t.LightRenderStyle == (int)GZDoomLightRenderStyle.NORMAL || t.LightRenderStyle == (int)GZDoomLightRenderStyle.VAVOOM)
if (t.LightRenderStyle == DynamicLightRenderStyle.NORMAL || t.LightRenderStyle == DynamicLightRenderStyle.VAVOOM)
lightOffsets[0]++;
else if (t.LightRenderStyle == (int)GZDoomLightRenderStyle.ADDITIVE)
else if (t.LightRenderStyle == DynamicLightRenderStyle.ADDITIVE)
lightOffsets[1]++;
else
lightOffsets[2]++;
@ -857,7 +857,7 @@ namespace CodeImp.DoomBuilder.Rendering
foreach(VisualThing t in group.Value)
{
//mxd
if (General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected) && t.Thing.IsModel)
if (t.Thing.IsModel && General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected))
continue;
// Update buffer if needed
@ -1028,7 +1028,7 @@ namespace CodeImp.DoomBuilder.Rendering
// Begin rendering with this shader
graphics.Shaders.World3D.BeginPass(currentshaderpass);
foreach (KeyValuePair<ModeldefEntry, List<VisualThing>> group in thingsWithModel) {
foreach (KeyValuePair<ModelData, List<VisualThing>> group in thingsWithModel) {
foreach (VisualThing t in group.Value) {
t.Update();
@ -1110,7 +1110,7 @@ namespace CodeImp.DoomBuilder.Rendering
radius = thingsWithLight[i].LightRadius;
radiusSquared = radius * radius;
if (distSquared < radiusSquared) {
sign = thingsWithLight[i].LightRenderStyle == (int)GZDoomLightRenderStyle.NEGATIVE ? -1 : 1;
sign = thingsWithLight[i].LightRenderStyle == DynamicLightRenderStyle.NEGATIVE ? -1 : 1;
scaler = 1 - distSquared / radiusSquared * thingsWithLight[i].LightColor.Alpha;
litColor.Red += thingsWithLight[i].LightColor.Red * scaler * sign;
litColor.Green += thingsWithLight[i].LightColor.Green * scaler * sign;
@ -1196,7 +1196,7 @@ namespace CodeImp.DoomBuilder.Rendering
public void AddThingGeometry(VisualThing t)
{
//mxd. gater lights
if (General.Settings.GZDrawLights && !fullbrightness && t.LightType != -1) {
if (General.Settings.GZDrawLights && !fullbrightness && t.LightType != DynamicLightType.NONE) {
t.UpdateLightRadius();
if (t.LightRadius > 0) {
@ -1210,15 +1210,14 @@ namespace CodeImp.DoomBuilder.Rendering
}
}
if (!isThingOnScreen(t.BoundingBox)) {
return;
}
if (!isThingOnScreen(t.BoundingBox)) return;
//mxd. gather models
if (General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected) && t.Thing.IsModel) {
ModeldefEntry mde = General.Map.Data.ModeldefEntries[t.Thing.Type];
if(t.Thing.IsModel && General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected)) {
ModelData mde = General.Map.Data.ModeldefEntries[t.Thing.Type];
if (!thingsWithModel.ContainsKey(mde))
thingsWithModel.Add(mde, new List<VisualThing>());
thingsWithModel.Add(mde, new List<VisualThing>() { t });
else
thingsWithModel[mde].Add(t);
}

View file

@ -75,8 +75,8 @@ namespace CodeImp.DoomBuilder.VisualModes
protected Matrix scale; //mxd. Used in model rendering
//mxd. light properties
private int lightType;
private int lightRenderStyle;
private DynamicLightType lightType;
private DynamicLightRenderStyle lightRenderStyle;
private Color4 lightColor;
private float lightRadius; //current radius. used in light animation
private float lightPrimaryRadius;
@ -118,9 +118,9 @@ namespace CodeImp.DoomBuilder.VisualModes
public Vector3 PositionV3 { get { return position_v3; } }
public Vector3[] BoundingBox { get { return boundingBox; } }
//mxd. light properties
public int LightType { get { return lightType; } }
public DynamicLightType LightType { get { return lightType; } }
public float LightRadius { get { return lightRadius; } }
public int LightRenderStyle { get { return lightRenderStyle; } }
public DynamicLightRenderStyle LightRenderStyle { get { return lightRenderStyle; } }
public Color4 LightColor { get { return lightColor; } }
/// <summary>
@ -171,8 +171,8 @@ namespace CodeImp.DoomBuilder.VisualModes
this.scale = Matrix.Identity; //mxd
//mxd
lightType = -1;
lightRenderStyle = -1;
lightType = DynamicLightType.NONE;
lightRenderStyle = DynamicLightRenderStyle.NONE;
lightPrimaryRadius = -1;
lightSecondaryRadius = -1;
lightInterval = -1;
@ -265,7 +265,7 @@ namespace CodeImp.DoomBuilder.VisualModes
//mxd. update bounding box
if (thing.IsModel) {
updateBoundingBoxForModel();
} else if (lightType != -1 && lightRadius > thing.Size) {
} else if (lightType != DynamicLightType.NONE && lightRadius > thing.Size) {
updateBoundingBox(lightRadius, lightRadius * 2);
} else {
updateBoundingBox((int)thing.Size, thingHeight);
@ -301,9 +301,6 @@ namespace CodeImp.DoomBuilder.VisualModes
// Do we need to update the geometry buffer?
if (updategeo)
{
//mxd. check if thing is model
checkModelState();
// Trash geometry buffer
if (geobuffer != null) geobuffer.Dispose();
geobuffer = null;
@ -316,7 +313,7 @@ namespace CodeImp.DoomBuilder.VisualModes
// Fill the buffer
DataStream bufferstream = geobuffer.Lock(0, WorldVertex.Stride * vertices.Length, LockFlags.Discard);
bufferstream.WriteRange<WorldVertex>(vertices);
bufferstream.WriteRange(vertices);
geobuffer.Unlock();
bufferstream.Dispose();
}
@ -329,18 +326,6 @@ namespace CodeImp.DoomBuilder.VisualModes
}
}
//mxd
protected void checkModelState() {
if (General.Map.Data.ModeldefEntries.ContainsKey(thing.Type)) {
if (General.Map.Data.ModeldefEntries[thing.Type].Model == null)
thing.IsModel = General.Map.Data.LoadModelForThing(thing);
else
thing.IsModel = true;
} else {
thing.IsModel = false;
}
}
//mxd
protected void checkLightState() {
//mxd. Check if thing is light
@ -362,11 +347,11 @@ namespace CodeImp.DoomBuilder.VisualModes
} else {
updateBoundingBox((int)thing.Size, thingHeight);
}
lightType = -1;
lightType = DynamicLightType.NONE;
lightRadius = -1;
lightPrimaryRadius = -1;
lightSecondaryRadius = -1;
lightRenderStyle = -1;
lightRenderStyle = DynamicLightRenderStyle.NONE;
lightInterval = -1;
isGldefsLight = false;
}
@ -389,21 +374,21 @@ namespace CodeImp.DoomBuilder.VisualModes
int n;
if (light_id < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[0]) {
n = 0;
lightRenderStyle = (int)GZDoomLightRenderStyle.NORMAL;
lightRenderStyle = DynamicLightRenderStyle.NORMAL;
//lightColor.Alpha used in shader to perform some calculations based on light type
lightColor = new Color4((float)lightRenderStyle / 100.0f, (float)thing.Args[0] / scaled_intensity, (float)thing.Args[1] / scaled_intensity, (float)thing.Args[2] / scaled_intensity);
} else if (light_id < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[1]) {
n = 10;
lightRenderStyle = (int)GZDoomLightRenderStyle.ADDITIVE;
lightRenderStyle = DynamicLightRenderStyle.ADDITIVE;
lightColor = new Color4((float)lightRenderStyle / 100.0f, (float)thing.Args[0] / scaled_intensity, (float)thing.Args[1] / scaled_intensity, (float)thing.Args[2] / scaled_intensity);
} else {
n = 20;
lightRenderStyle = (int)GZDoomLightRenderStyle.NEGATIVE;
lightRenderStyle = DynamicLightRenderStyle.NEGATIVE;
lightColor = new Color4((float)lightRenderStyle / 100.0f, (float)thing.Args[0] / scaled_intensity, (float)thing.Args[1] / scaled_intensity, (float)thing.Args[2] / scaled_intensity);
}
lightType = thing.Type - 9800 - n;
lightType = (DynamicLightType)(thing.Type - 9800 - n);
if (lightType == (int)GZDoomLightType.SECTOR) {
if (lightType == DynamicLightType.SECTOR) {
int scaler = 1;
if (thing.Sector != null)
scaler = thing.Sector.Brightness / 4;
@ -414,9 +399,9 @@ namespace CodeImp.DoomBuilder.VisualModes
lightSecondaryRadius = (float)(thing.Args[4] * 2) * General.Settings.GZDynamicLightRadius;
}
} else { //it's one of vavoom lights
lightRenderStyle = (int)GZDoomLightRenderStyle.VAVOOM;
lightType = thing.Type;
if (lightType == (int)GZDoomLightType.VAVOOM_COLORED)
lightRenderStyle = DynamicLightRenderStyle.VAVOOM;
lightType = (DynamicLightType)thing.Type;
if (lightType == DynamicLightType.VAVOOM_COLORED)
lightColor = new Color4((float)lightRenderStyle / 100.0f, (float)thing.Args[1] / scaled_intensity, (float)thing.Args[2] / scaled_intensity, (float)thing.Args[3] / scaled_intensity);
else
lightColor = new Color4((float)lightRenderStyle / 100.0f, General.Settings.GZDynamicLightIntensity, General.Settings.GZDynamicLightIntensity, General.Settings.GZDynamicLightIntensity);
@ -427,17 +412,17 @@ namespace CodeImp.DoomBuilder.VisualModes
//mxd
private void updateGldefsLight() {
GZDoomLight light = General.Map.Data.GldefsEntries[thing.Type];
DynamicLightData light = General.Map.Data.GldefsEntries[thing.Type];
float intensity_mod = General.Settings.GZDynamicLightIntensity;
float scale_mod = General.Settings.GZDynamicLightRadius;
//apply settings
lightRenderStyle = light.Subtractive ? (int)GZDoomLightRenderStyle.NEGATIVE : (int)GZDoomLightRenderStyle.NORMAL;
lightRenderStyle = light.Subtractive ? DynamicLightRenderStyle.NEGATIVE : DynamicLightRenderStyle.NORMAL;
lightColor = new Color4((float)lightRenderStyle / 100.0f, light.Color.Red * intensity_mod, light.Color.Green * intensity_mod, light.Color.Blue * intensity_mod);
lightOffset = light.Offset;
lightType = light.Type;
if (lightType == (int)GZDoomLightType.SECTOR) {
if (lightType == DynamicLightType.SECTOR) {
lightPrimaryRadius = light.Interval * thing.Sector.Brightness / 5;
} else {
lightPrimaryRadius = light.PrimaryRadius * scale_mod;
@ -456,7 +441,7 @@ namespace CodeImp.DoomBuilder.VisualModes
//mxd
private void updateLightRadius(int interval) {
if (lightType == -1) {
if (lightType == DynamicLightType.NONE) {
General.ErrorLogger.Add(ErrorType.Error, "Please check that thing is light before accessing it's PositionAndRadius! You can use lightType, which is -1 if thing isn't light");
return;
}
@ -473,11 +458,11 @@ namespace CodeImp.DoomBuilder.VisualModes
float diff = rMax - rMin;
//pulse
if (lightType == (int)GZDoomLightType.PULSE) {
if (lightType == DynamicLightType.PULSE) {
lightDelta = ((float)Math.Sin(time / (interval * 4.0f)) + 1.0f) / 2.0f; //just playing by the eye here... in [0.0 ... 1.0] interval
lightRadius = rMin + diff * lightDelta;
//flicker
} else if (lightType == (int)GZDoomLightType.FLICKER) {
} else if (lightType == DynamicLightType.FLICKER) {
float delta = (float)Math.Sin(time / 0.1f); //just playing by the eye here...
if (Math.Sign(delta) != Math.Sign(lightDelta)) {
lightDelta = delta;
@ -487,7 +472,7 @@ namespace CodeImp.DoomBuilder.VisualModes
lightRadius = rMin;
}
//random
} else if (lightType == (int)GZDoomLightType.RANDOM) {
} else if (lightType == DynamicLightType.RANDOM) {
float delta = (float)Math.Sin(time / (interval * 9.0f)); //just playing by the eye here...
if (Math.Sign(delta) != Math.Sign(lightDelta))
lightRadius = rMin + (float)(new Random().Next(0, (int)(diff * 10))) / 10.0f;
@ -500,7 +485,7 @@ namespace CodeImp.DoomBuilder.VisualModes
//updateBoundingBox(lightRadius, lightRadius * 2f);
if (thing.IsModel) {
updateBoundingBoxForModel();
} else if (lightType != -1 && lightRadius > thing.Size) {
} else if (lightType != DynamicLightType.NONE && lightRadius > thing.Size) {
updateBoundingBox(lightRadius, lightRadius * 2);
} else {
updateBoundingBox((int)thing.Size, thingHeight);
@ -525,7 +510,7 @@ namespace CodeImp.DoomBuilder.VisualModes
//mxd. update bounding box from model bounding box
private void updateBoundingBoxForModel() {
ModeldefEntry mde = General.Map.Data.ModeldefEntries[thing.Type];
ModelData mde = General.Map.Data.ModeldefEntries[thing.Type];
int len = mde.Model.BoundingBox.Length;
boundingBox = new Vector3[len];
for (int i = 0; i < len; i++) {

View file

@ -3084,11 +3084,11 @@ namespace CodeImp.DoomBuilder.Windows
if(warningsCount > 0) {
if(!warnsLabel.Font.Bold){
warnsLabel.Font = new Font(warnsLabel.Font, FontStyle.Bold);
warnsLabel.Image = global::CodeImp.DoomBuilder.Properties.Resources.Warning;
warnsLabel.Image = Resources.Warning;
}
} else {
warnsLabel.Font = new Font(warnsLabel.Font, FontStyle.Regular);
warnsLabel.Image = global::CodeImp.DoomBuilder.Properties.Resources.WarningOff;
warnsLabel.Image = Resources.WarningOff;
warnsLabel.BackColor = SystemColors.Control;
}
@ -3107,11 +3107,11 @@ namespace CodeImp.DoomBuilder.Windows
private void blink() {
if(warnsLabel.BackColor == Color.Red) {
warnsLabel.Font = new Font(warnsLabel.Font, FontStyle.Regular);
warnsLabel.Image = global::CodeImp.DoomBuilder.Properties.Resources.WarningOff;
warnsLabel.Image = Resources.WarningOff;
warnsLabel.BackColor = SystemColors.Control;
} else {
warnsLabel.Font = new Font(warnsLabel.Font, FontStyle.Bold);
warnsLabel.Image = global::CodeImp.DoomBuilder.Properties.Resources.Warning;
warnsLabel.Image = Resources.Warning;
warnsLabel.BackColor = Color.Red;
}
}

View file

@ -97,7 +97,7 @@ namespace CodeImp.DoomBuilder.ZDoom
{
// Add the texture
textures[tx.Name] = tx;
flats[tx.Name] = tx;
if(!General.Map.Config.MixTexturesFlats) flats[tx.Name] = tx; //mxd. If MixTexturesFlats is set, textures and flats will be mixed in DataManager anyway
}
}
else if(objdeclaration == "sprite")

View file

@ -99,7 +99,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
General.Map.Map.ClearAllSelected();
General.Map.Map.SelectMarkedGeometry(true, true);
General.Map.Renderer2D.Update3dFloorTagsList(); //mxd
General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd
// Switch to EditSelectionMode
EditSelectionMode editmode = new EditSelectionMode();
@ -144,12 +144,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd
public override void OnUndoEnd() {
General.Map.Renderer2D.UpdateExtraFloorFlag();
base.OnUndoEnd();
updateSelectionInfo();
}
//mxd
public override void OnRedoEnd() {
General.Map.Renderer2D.UpdateExtraFloorFlag();
base.OnRedoEnd();
updateSelectionInfo();
}

View file

@ -117,6 +117,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.ClassicModes {
// Mouse moves
public override void OnMouseMove(MouseEventArgs e) {
base.OnMouseMove(e);
if(panning) return; //mxd. Skip all this jass while panning
if (curControlHandle != -1) {
ControlHandle handle = controlHandles[curControlHandle];

View file

@ -443,6 +443,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if(panning) return; //mxd. Skip all this jass while panning
// Not in any editing mode?
if(mode == ModifyMode.None) {

View file

@ -555,6 +555,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if(panning) return; //mxd. Skip all this jass while panning
Update();
}
// When a key is released

View file

@ -541,6 +541,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if(panning) return; //mxd. Skip all this jass while panning
Update();
}

View file

@ -1381,7 +1381,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if(panning) return; //mxd. Skip all this jass while panning
Update();
}

View file

@ -735,7 +735,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if(panning) return; //mxd. Skip all this jass while panning
Update();
}

View file

@ -321,10 +321,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(renderer.StartPlotter(true))
{
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
if(!panning) //mxd
for(int i = 0; i < Linedef.NUM_ARGS; i++) BuilderPlug.Me.PlotAssociations(renderer, association[i]);
if((highlighted != null) && !highlighted.IsDisposed)
{
BuilderPlug.Me.PlotReverseAssociations(renderer, highlightasso);
if(!panning) BuilderPlug.Me.PlotReverseAssociations(renderer, highlightasso); //mxd
renderer.PlotLinedef(highlighted, General.Colors.Highlight);
}
renderer.PlotVerticesSet(General.Map.Map.Vertices);
@ -342,8 +343,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Render selection
if(renderer.StartOverlay(true))
{
if(!panning) //mxd
for(int i = 0; i < Linedef.NUM_ARGS; i++) BuilderPlug.Me.RenderAssociations(renderer, association[i]);
if((highlighted != null) && !highlighted.IsDisposed) BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso);
if(!panning && (highlighted != null) && !highlighted.IsDisposed) BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso); //mxd
if(selecting) RenderMultiSelection();
renderer.Finish();
}
@ -473,7 +475,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(selected.Count == 1) General.Map.Map.ClearSelectedLinedefs();
// Update entire display
General.Map.Renderer2D.Update3dFloorTagsList(); //mxd
General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd
General.Interface.RedrawDisplay();
}
}
@ -489,6 +491,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if(panning) return; //mxd. Skip all this jass while panning
//mxd
if(selectpressed && !editpressed && !selecting) {
@ -767,6 +770,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Update and redraw
General.Map.IsChanged = true;
General.Interface.RefreshInfo();
General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd
General.Interface.RedrawDisplay();
}
}
@ -896,7 +900,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
OnMouseMove(e);
// Redraw screen
General.Map.Renderer2D.Update3dFloorTagsList(); //mxd
//General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd
General.Interface.RedrawDisplay();
}
}

View file

@ -455,6 +455,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if(panning) return; //mxd. Skip all this jass while panning
// Highlight the region
Highlight((e.Button != MouseButtons.None));

View file

@ -481,7 +481,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
if((highlighted != null) && !highlighted.IsDisposed)
{
renderer.PlotSector(highlighted, General.Colors.Highlight);
BuilderPlug.Me.PlotReverseAssociations(renderer, highlightasso);
if(!panning) BuilderPlug.Me.PlotReverseAssociations(renderer, highlightasso); //mxd
}
renderer.Finish();
}
@ -497,7 +497,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Render selection
if(renderer.StartOverlay(true))
{
if((highlighted != null) && !highlighted.IsDisposed) BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso);
if(!panning && highlighted != null && !highlighted.IsDisposed) BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso); //mxd
if(selecting) RenderMultiSelection();
renderer.Finish();
}
@ -628,6 +628,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Interface.ShowEditSectors(selected);
General.Interface.OnEditFormValuesChanged -= sectorEditForm_OnValuesChanged;
General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd
// When a single sector was selected, deselect it now
if(selected.Count == 1)
{
@ -649,7 +651,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
private void sectorEditForm_OnValuesChanged(object sender, EventArgs e) {
// Update entire display
General.Map.Map.Update();
General.Map.Renderer2D.Update3dFloorTagsList();
//General.Map.Renderer2D.UpdateExtraFloorFlag();
General.Interface.RedrawDisplay();
}
@ -657,6 +659,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if(panning) return; //mxd. Skip all this jass while panning
//mxd
if(selectpressed && !editpressed && !selecting) {
@ -1121,6 +1124,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Update and redraw
General.Map.IsChanged = true;
General.Interface.RefreshInfo();
General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd
General.Interface.RedrawDisplay();
}
}
@ -1368,7 +1372,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
UpdateSelectedLabels();
// Redraw screen
General.Map.Renderer2D.Update3dFloorTagsList(); //mxd
//General.Map.Renderer2D.Update3dFloorIndicators(); //mxd
General.Interface.RedrawDisplay();
}
}

View file

@ -147,8 +147,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
renderer.PlotVerticesSet(General.Map.Map.Vertices);
if (!panning) { //mxd
for (int i = 0; i < Thing.NUM_ARGS; i++) BuilderPlug.Me.PlotAssociations(renderer, association[i]);
if ((highlighted != null) && !highlighted.IsDisposed) BuilderPlug.Me.PlotReverseAssociations(renderer, highlightasso);
}
renderer.Finish();
}
@ -157,10 +159,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, Presentation.THINGS_HIDDEN_ALPHA);
renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, 1.0f);
if(!panning) //mxd
for(int i = 0; i < Thing.NUM_ARGS; i++) BuilderPlug.Me.RenderAssociations(renderer, association[i]);
if((highlighted != null) && !highlighted.IsDisposed)
{
BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso);
if(!panning) BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso); //mxd
renderer.RenderThing(highlighted, General.Colors.Highlight, 1.0f);
}
@ -442,6 +445,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if(panning) return; //mxd. Skip all this jass while panning
//mxd
if(selectpressed && !editpressed && !selecting) {

View file

@ -428,7 +428,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
private void vertexEditForm_OnValuesChanged(object sender, EventArgs e) {
// Update entire display
General.Map.Map.Update();
General.Map.Renderer2D.Update3dFloorTagsList();
//General.Map.Renderer2D.Update3dFloorIndicators();
General.Interface.RedrawDisplay();
}
@ -436,6 +436,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if(panning) return; //mxd. Skip all this jass while panning
//mxd
if(selectpressed && !editpressed && !selecting) {
@ -880,6 +881,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
OnMouseMove(e);
// Redraw screen
General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd
General.Interface.RedrawDisplay();
}

View file

@ -467,7 +467,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
drawRectModeMenuItem.Enabled = true;
drawEllipseModeMenuItem.Enabled = true;
General.Map.Renderer2D.Update3dFloorTagsList(); //mxd
General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd
}
// Map closed

View file

@ -197,16 +197,20 @@ namespace CodeImp.DoomBuilder.BuilderModes
Vector3D pos = Thing.Position;
if(Thing.Type == 9501)
{
if(Thing.Sector != null) { //mxd
// This is a special thing that needs special positioning
SectorData sd = mode.GetSectorData(Thing.Sector);
pos.z = sd.Ceiling.sector.CeilHeight + Thing.Position.z;
}
}
else if(Thing.Type == 9500)
{
if(Thing.Sector != null) { //mxd
// This is a special thing that needs special positioning
SectorData sd = mode.GetSectorData(Thing.Sector);
pos.z = sd.Floor.sector.FloorHeight + Thing.Position.z;
}
}
else if(info.AbsoluteZ)
{
// Absolute Z position

View file

@ -1,10 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Controls;
using CodeImp.DoomBuilder.Editing;
using CodeImp.DoomBuilder.Plugins;
namespace CodeImp.DoomBuilder.TagExplorer