mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 14:31:50 +00:00
Updated, Textures Browser: texture name length is now taken into account when calculating the width of texture items.
Internal: moved thing helper shapes creation logic from ThingsMode to LinksCollector.
This commit is contained in:
parent
a41058bef9
commit
2b24ce3c25
10 changed files with 278 additions and 236 deletions
|
@ -1,6 +1,7 @@
|
|||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
|
||||
#endregion
|
||||
|
@ -12,6 +13,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
#region ================== Variables
|
||||
|
||||
private string groupname;
|
||||
private int groupnamewidth;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -19,6 +21,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
|
||||
public override bool IsPreviewLoaded { get { return true; } }
|
||||
public override string TextureName { get { return groupname; } }
|
||||
public override int TextureNameWidth { get { return groupnamewidth; } }
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -43,6 +46,9 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
default:
|
||||
throw new NotImplementedException("Unsupported ItemType");
|
||||
}
|
||||
|
||||
// Calculate name width
|
||||
this.groupnamewidth = (int)Math.Ceiling(General.Interface.MeasureString(this.groupname, SystemFonts.MessageBoxFont, 10000, StringFormat.GenericTypographic).Width);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -351,7 +351,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
objectname.CharacterCasing = (uselongtexturenames ? CharacterCasing.Normal : CharacterCasing.Upper);
|
||||
|
||||
foreach(var item in items) item.ShowFullName = uselongtexturenames;
|
||||
list.Refresh();
|
||||
list.UpdateRectangles();
|
||||
list.Focus();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
private bool showfullname;
|
||||
protected ImageBrowserItemType itemtype;
|
||||
private string tooltip;
|
||||
private int namewidth;
|
||||
private int shortnamewidth;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -39,6 +41,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
public virtual bool IsPreviewLoaded { get { return icon.IsPreviewLoaded; } }
|
||||
public bool ShowFullName { set { showfullname = value; } }
|
||||
public virtual string TextureName { get { return (showfullname ? icon.Name : icon.ShortName); } }
|
||||
public virtual int TextureNameWidth { get { return (showfullname ? namewidth : shortnamewidth); } }
|
||||
public string ToolTip { get { return tooltip; } }
|
||||
|
||||
#endregion
|
||||
|
@ -55,6 +58,10 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
this.showfullname = showfullname; //mxd
|
||||
this.imageloaded = icon.IsPreviewLoaded; //mxd
|
||||
this.tooltip = tooltip; //mxd
|
||||
|
||||
//mxd. Calculate names width
|
||||
this.namewidth = (int)Math.Ceiling(General.Interface.MeasureString(icon.Name, SystemFonts.MessageBoxFont, 10000, StringFormat.GenericTypographic).Width);
|
||||
this.shortnamewidth = (int)Math.Ceiling(General.Interface.MeasureString(icon.ShortName, SystemFonts.MessageBoxFont, 10000, StringFormat.GenericTypographic).Width);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -464,7 +464,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
if(selection.Count > 0) ScrollToItem(selection[0]);
|
||||
}
|
||||
|
||||
private void UpdateRectangles()
|
||||
internal void UpdateRectangles()
|
||||
{
|
||||
int w = ClientRectangle.Width - scrollbar.Width;
|
||||
const int pad = 2;
|
||||
|
@ -479,7 +479,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
Image preview = GetPreview(ti, imagesize);
|
||||
|
||||
int rw = w - cx;
|
||||
int wid = (imagesize > 0 ? imagesize : preview.Width) + pad + pad;
|
||||
int wid = Math.Max((imagesize > 0 ? imagesize : preview.Width), ti.TextureNameWidth) + pad + pad;
|
||||
int hei = (imagesize > 0 ? imagesize : preview.Height) + pad + pad + font;
|
||||
|
||||
if(rw < wid)
|
||||
|
|
|
@ -108,6 +108,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Load image if needed
|
||||
if(!img.IsImageLoaded) img.LoadImage();
|
||||
int imagewidth, imageheight;
|
||||
Bitmap image = img.GetBitmap(); //mxd
|
||||
if(!img.LoadFailed)
|
||||
{
|
||||
imagewidth = img.Width;
|
||||
|
@ -115,7 +116,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
else
|
||||
{
|
||||
Size size = img.GetBitmap().Size; //mxd
|
||||
Size size = image.Size; //mxd
|
||||
imagewidth = size.Width;
|
||||
imageheight = size.Height;
|
||||
}
|
||||
|
@ -129,31 +130,40 @@ namespace CodeImp.DoomBuilder.Data
|
|||
if(previewwidth < 1) previewwidth = 1;
|
||||
if(previewheight < 1) previewheight = 1;
|
||||
|
||||
// Make new image
|
||||
Bitmap preview = new Bitmap(previewwidth, previewheight, IMAGE_FORMAT);
|
||||
Graphics g = Graphics.FromImage(preview);
|
||||
g.PageUnit = GraphicsUnit.Pixel;
|
||||
//g.CompositingQuality = CompositingQuality.HighQuality; //mxd
|
||||
g.InterpolationMode = InterpolationMode.NearestNeighbor;
|
||||
//g.SmoothingMode = SmoothingMode.HighQuality; //mxd
|
||||
g.PixelOffsetMode = PixelOffsetMode.None;
|
||||
//g.Clear(Color.Transparent); //mxd
|
||||
|
||||
// Draw image onto atlas
|
||||
Rectangle atlasrect = new Rectangle(0, 0, previewwidth, previewheight);
|
||||
RectangleF imgrect = General.MakeZoomedRect(new Size(imagewidth, imageheight), atlasrect);
|
||||
if(imgrect.Width < 1.0f)
|
||||
//mxd. Expected and actual image sizes and format match?
|
||||
Bitmap preview;
|
||||
if(previewwidth == imagewidth && previewheight == imageheight && image.PixelFormat == IMAGE_FORMAT)
|
||||
{
|
||||
imgrect.X -= 0.5f - imgrect.Width * 0.5f;
|
||||
imgrect.Width = 1.0f;
|
||||
preview = new Bitmap(image);
|
||||
}
|
||||
if(imgrect.Height < 1.0f)
|
||||
else
|
||||
{
|
||||
imgrect.Y -= 0.5f - imgrect.Height * 0.5f;
|
||||
imgrect.Height = 1.0f;
|
||||
// Make new image
|
||||
preview = new Bitmap(previewwidth, previewheight, IMAGE_FORMAT);
|
||||
Graphics g = Graphics.FromImage(preview);
|
||||
g.PageUnit = GraphicsUnit.Pixel;
|
||||
//g.CompositingQuality = CompositingQuality.HighQuality; //mxd
|
||||
g.InterpolationMode = InterpolationMode.NearestNeighbor;
|
||||
//g.SmoothingMode = SmoothingMode.HighQuality; //mxd
|
||||
g.PixelOffsetMode = PixelOffsetMode.None;
|
||||
//g.Clear(Color.Transparent); //mxd
|
||||
|
||||
// Draw image onto atlas
|
||||
Rectangle atlasrect = new Rectangle(0, 0, previewwidth, previewheight);
|
||||
RectangleF imgrect = General.MakeZoomedRect(new Size(imagewidth, imageheight), atlasrect);
|
||||
if(imgrect.Width < 1.0f)
|
||||
{
|
||||
imgrect.X -= 0.5f - imgrect.Width * 0.5f;
|
||||
imgrect.Width = 1.0f;
|
||||
}
|
||||
if(imgrect.Height < 1.0f)
|
||||
{
|
||||
imgrect.Y -= 0.5f - imgrect.Height * 0.5f;
|
||||
imgrect.Height = 1.0f;
|
||||
}
|
||||
g.DrawImage(image, imgrect);
|
||||
g.Dispose();
|
||||
}
|
||||
g.DrawImage(img.GetBitmap(), imgrect);
|
||||
g.Dispose();
|
||||
|
||||
// Unload image if no longer needed
|
||||
if(!img.IsReferenced) img.UnloadImage();
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
|
@ -6,10 +8,14 @@ using CodeImp.DoomBuilder.Geometry;
|
|||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZBuilder.Data
|
||||
{
|
||||
public static class LinksCollector
|
||||
public static class LinksCollector
|
||||
{
|
||||
#region ================== SpecialThings
|
||||
|
||||
private class SpecialThings
|
||||
{
|
||||
public readonly Dictionary<int, List<Thing>> PatrolPoints; // PatrolPoint tag, list of PatrolPoints
|
||||
|
@ -34,6 +40,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== PathNode
|
||||
|
||||
private class PathNode
|
||||
{
|
||||
private readonly Thing thing;
|
||||
|
@ -74,7 +84,17 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<Line3D> MakeCircleLines(Vector3D pos, PixelColor color, float radius, int numsides)
|
||||
#endregion
|
||||
|
||||
#region ================== Constants
|
||||
|
||||
private const int CIRCLE_SIDES = 24;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Shape creation methods
|
||||
|
||||
private static IEnumerable<Line3D> MakeCircleLines(Vector3D pos, PixelColor color, float radius, int numsides)
|
||||
{
|
||||
List<Line3D> result = new List<Line3D>(numsides);
|
||||
Vector3D start = new Vector3D(pos.x, pos.y + radius, pos.z);
|
||||
|
@ -90,7 +110,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
return result;
|
||||
}
|
||||
|
||||
public static IEnumerable<Line3D> MakeRectangleLines(Vector3D pos, PixelColor color, float size)
|
||||
private static IEnumerable<Line3D> MakeRectangleLines(Vector3D pos, PixelColor color, float size)
|
||||
{
|
||||
float halfsize = size / 2;
|
||||
Vector3D tl = new Vector3D(pos.x - halfsize, pos.y - halfsize, pos.z);
|
||||
|
@ -105,15 +125,21 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
new Line3D(bl, br, color, false),
|
||||
new Line3D(bl, tl, color, false),
|
||||
};
|
||||
}
|
||||
|
||||
public static List<Line3D> GetThingLinks(IEnumerable<Thing> things) { return GetThingLinks(things, null); }
|
||||
public static List<Line3D> GetThingLinks(IEnumerable<Thing> things, VisualBlockMap blockmap)
|
||||
{
|
||||
return GetThingLinks(GetSpecialThings(things, blockmap), blockmap);
|
||||
}
|
||||
|
||||
private static SpecialThings GetSpecialThings(IEnumerable<Thing> things, VisualBlockMap blockmap)
|
||||
#endregion
|
||||
|
||||
#region ================== GetHelperShapes
|
||||
|
||||
public static List<Line3D> GetHelperShapes(ICollection<Thing> things) { return GetHelperShapes(things, null); }
|
||||
public static List<Line3D> GetHelperShapes(ICollection<Thing> things, VisualBlockMap blockmap)
|
||||
{
|
||||
var lines = GetHelperShapes(GetSpecialThings(things, blockmap), blockmap);
|
||||
lines.AddRange(GetThingArgumentShapes(things, blockmap, CIRCLE_SIDES));
|
||||
return lines;
|
||||
}
|
||||
|
||||
private static SpecialThings GetSpecialThings(ICollection<Thing> things, VisualBlockMap blockmap)
|
||||
{
|
||||
SpecialThings result = new SpecialThings();
|
||||
|
||||
|
@ -189,7 +215,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
return result;
|
||||
}
|
||||
|
||||
private static List<Line3D> GetThingLinks(SpecialThings result, VisualBlockMap blockmap)
|
||||
private static List<Line3D> GetHelperShapes(SpecialThings result, VisualBlockMap blockmap)
|
||||
{
|
||||
var lines = new List<Line3D>();
|
||||
var actormovertargets = new Dictionary<int, List<Thing>>();
|
||||
|
@ -403,9 +429,19 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
}
|
||||
}
|
||||
|
||||
// Process arg helpers
|
||||
const int numsides = 24;
|
||||
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
|
||||
return lines;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== GetThingArgumentShapes
|
||||
|
||||
// Create argument value/min/max shapes
|
||||
private static List<Line3D> GetThingArgumentShapes(ICollection<Thing> things, VisualBlockMap blockmap, int numsides)
|
||||
{
|
||||
var lines = new List<Line3D>();
|
||||
|
||||
foreach(Thing t in things)
|
||||
{
|
||||
if(t.Action != 0) continue;
|
||||
ThingTypeInfo tti = General.Map.Data.GetThingInfoEx(t.Type);
|
||||
|
@ -416,20 +452,27 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
|
||||
for(int i = 0; i < t.Args.Length; i++)
|
||||
{
|
||||
if(t.Args[i] != 0 && tti.Args[i].RenderStyle != ArgumentInfo.ArgumentRenderStyle.NONE)
|
||||
if(t.Args[i] == 0) continue; // Avoid visual noise
|
||||
var a = tti.Args[i]; //TODO: can this be null?
|
||||
|
||||
switch(a.RenderStyle)
|
||||
{
|
||||
switch(tti.Args[i].RenderStyle)
|
||||
{
|
||||
case ArgumentInfo.ArgumentRenderStyle.CIRCLE:
|
||||
lines.AddRange(MakeCircleLines(pos, tti.Args[i].RenderColor, t.Args[i], numsides));
|
||||
break;
|
||||
case ArgumentInfo.ArgumentRenderStyle.CIRCLE:
|
||||
lines.AddRange(MakeCircleLines(pos, a.RenderColor, t.Args[i], numsides));
|
||||
if(a.MinRange > 0) lines.AddRange(MakeCircleLines(pos, a.MinRangeColor, a.MinRange, numsides));
|
||||
if(a.MaxRange > 0) lines.AddRange(MakeCircleLines(pos, a.MaxRangeColor, a.MaxRange, numsides));
|
||||
break;
|
||||
|
||||
case ArgumentInfo.ArgumentRenderStyle.RECTANGLE:
|
||||
lines.AddRange(MakeRectangleLines(pos, tti.Args[i].RenderColor, t.Args[i]));
|
||||
break;
|
||||
case ArgumentInfo.ArgumentRenderStyle.RECTANGLE:
|
||||
lines.AddRange(MakeRectangleLines(pos, a.RenderColor, t.Args[i]));
|
||||
if(a.MinRange > 0) lines.AddRange(MakeRectangleLines(pos, a.MinRangeColor, a.MinRange));
|
||||
if(a.MaxRange > 0) lines.AddRange(MakeRectangleLines(pos, a.MaxRangeColor, a.MaxRange));
|
||||
break;
|
||||
|
||||
default: throw new NotImplementedException("Unknown ArgumentRenderStyle");
|
||||
}
|
||||
case ArgumentInfo.ArgumentRenderStyle.NONE:
|
||||
break;
|
||||
|
||||
default: throw new NotImplementedException("Unknown ArgumentRenderStyle");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -437,6 +480,150 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
return lines;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== GetDynamicLightShapes
|
||||
|
||||
public static List<Line3D> GetDynamicLightShapes(IEnumerable<Thing> things, bool highlight)
|
||||
{
|
||||
List<Line3D> circles = new List<Line3D>();
|
||||
if(General.Map.DOOM) return circles;
|
||||
|
||||
const int linealpha = 128;
|
||||
foreach(Thing t in things)
|
||||
{
|
||||
int lightid = Array.IndexOf(GZGeneral.GZ_LIGHTS, t.Type);
|
||||
if(lightid == -1) continue;
|
||||
|
||||
// TODO: this basically duplicates VisualThing.UpdateLight()...
|
||||
// Determine light radiii
|
||||
int primaryradius;
|
||||
int secondaryradius = 0;
|
||||
|
||||
if(lightid < GZGeneral.GZ_LIGHT_TYPES[2]) //if it's gzdoom light
|
||||
{
|
||||
int n;
|
||||
if(lightid < GZGeneral.GZ_LIGHT_TYPES[0]) n = 0;
|
||||
else if(lightid < GZGeneral.GZ_LIGHT_TYPES[1]) n = 10;
|
||||
else n = 20;
|
||||
DynamicLightType lightType = (DynamicLightType)(t.Type - 9800 - n);
|
||||
|
||||
if(lightType == DynamicLightType.SECTOR)
|
||||
{
|
||||
if(t.Sector == null) t.DetermineSector();
|
||||
int scaler = (t.Sector != null ? t.Sector.Brightness / 4 : 2);
|
||||
primaryradius = t.Args[3] * scaler;
|
||||
}
|
||||
else
|
||||
{
|
||||
primaryradius = t.Args[3] * 2; //works... that.. way in GZDoom
|
||||
if(lightType > 0) secondaryradius = t.Args[4] * 2;
|
||||
}
|
||||
}
|
||||
else //it's one of vavoom lights
|
||||
{
|
||||
primaryradius = t.Args[0] * 8;
|
||||
}
|
||||
|
||||
// Check radii...
|
||||
if(primaryradius < 1 && secondaryradius < 1) continue;
|
||||
|
||||
// Determine light color
|
||||
PixelColor color;
|
||||
if(highlight)
|
||||
{
|
||||
color = General.Colors.Highlight.WithAlpha(linealpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(t.Type)
|
||||
{
|
||||
case 1502: // Vavoom light
|
||||
color = new PixelColor(linealpha, 255, 255, 255);
|
||||
break;
|
||||
|
||||
case 1503: // Vavoom colored light
|
||||
color = new PixelColor(linealpha, (byte)t.Args[1], (byte)t.Args[2], (byte)t.Args[3]);
|
||||
break;
|
||||
|
||||
default:
|
||||
color = new PixelColor(linealpha, (byte)t.Args[0], (byte)t.Args[1], (byte)t.Args[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add lines if visible
|
||||
if(primaryradius > 0) circles.AddRange(MakeCircleLines(t.Position, color, primaryradius, CIRCLE_SIDES));
|
||||
if(secondaryradius > 0) circles.AddRange(MakeCircleLines(t.Position, color, secondaryradius, CIRCLE_SIDES));
|
||||
}
|
||||
|
||||
// Done
|
||||
return circles;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== GetAmbientSoundShapes
|
||||
|
||||
public static List<Line3D> GetAmbientSoundShapes(IEnumerable<Thing> things, bool highlight)
|
||||
{
|
||||
List<Line3D> circles = new List<Line3D>();
|
||||
const int linealpha = 128;
|
||||
|
||||
foreach(Thing t in things)
|
||||
{
|
||||
ThingTypeInfo info = General.Map.Data.GetThingInfoEx(t.Type);
|
||||
if(info == null) continue;
|
||||
|
||||
float minradius, maxradius;
|
||||
if(info.AmbientSound != null)
|
||||
{
|
||||
minradius = info.AmbientSound.MinimumRadius;
|
||||
maxradius = info.AmbientSound.MaximumRadius;
|
||||
}
|
||||
else if(!General.Map.DOOM && (info.ClassName == "AmbientSound" || info.ClassName == "AmbientSoundNoGravity"))
|
||||
{
|
||||
//arg0: ambient slot
|
||||
//arg1: (optional) sound volume, in percent. 1 is nearly silent, 100 and above are full volume. If left to zero, full volume is also used.
|
||||
//arg2: (optional) minimum distance, in map units, at which volume attenuation begins. Note that arg3 must also be set. If both are left to zero, normal rolloff is used instead.
|
||||
//arg3: (optional) maximum distance, in map units, at which the sound can be heard. If left to zero or lower than arg2, normal rolloff is used instead.
|
||||
//arg4: (optional) scalar by which to multiply the values of arg2 and arg3. If left to zero, no multiplication takes place.
|
||||
|
||||
if(t.Args[0] == 0 || !General.Map.Data.AmbientSounds.ContainsKey(t.Args[0]))
|
||||
continue;
|
||||
|
||||
// Use custom radii?
|
||||
if(t.Args[2] > 0 && t.Args[3] > 0 && t.Args[3] > t.Args[2])
|
||||
{
|
||||
minradius = t.Args[2] * (t.Args[4] != 0 ? t.Args[4] : 1.0f);
|
||||
maxradius = t.Args[3] * (t.Args[4] != 0 ? t.Args[4] : 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
minradius = General.Map.Data.AmbientSounds[t.Args[0]].MinimumRadius;
|
||||
maxradius = General.Map.Data.AmbientSounds[t.Args[0]].MaximumRadius;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Determine color
|
||||
PixelColor color = (highlight ? General.Colors.Highlight.WithAlpha(linealpha) : t.Color.WithAlpha(linealpha));
|
||||
|
||||
// Add lines if visible
|
||||
if(minradius > 0) circles.AddRange(MakeCircleLines(t.Position, color, minradius, CIRCLE_SIDES));
|
||||
if(maxradius > 0) circles.AddRange(MakeCircleLines(t.Position, color, maxradius, CIRCLE_SIDES));
|
||||
}
|
||||
|
||||
return circles;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Utility
|
||||
|
||||
// Taken from Xabis' "curved interpolation points paths" patch.
|
||||
private static float SplineLerp(float u, float p1, float p2, float p3, float p4)
|
||||
{
|
||||
|
@ -459,5 +646,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
if(thing.Sector != null) height += thing.Sector.FloorHeight;
|
||||
return height;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,6 +78,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
void SetCursor(Cursor cursor);
|
||||
void MessageBeep(MessageBeepType type);
|
||||
SizeF MeasureString(string text, Font font); //mxd
|
||||
SizeF MeasureString(string text, Font font, int width, StringFormat format); //mxd
|
||||
|
||||
/// <summary>
|
||||
/// This moves the focus to the editing display.
|
||||
|
|
|
@ -4393,6 +4393,11 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
return graphics.MeasureString(text, font);
|
||||
}
|
||||
|
||||
public SizeF MeasureString(string text, Font font, int width, StringFormat format)
|
||||
{
|
||||
return graphics.MeasureString(text, font, width, format);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -259,7 +259,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
{
|
||||
eventlines.AddRange(dynamiclightshapes);
|
||||
if(highlighted != null && !highlighted.IsDisposed)
|
||||
eventlines.AddRange(GetDynamicLightShapes(new List<Thing> { highlighted } ));
|
||||
eventlines.AddRange(LinksCollector.GetDynamicLightShapes(new List<Thing> { highlighted }, true));
|
||||
}
|
||||
|
||||
//mxd. Ambient sound radii
|
||||
|
@ -267,7 +267,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
{
|
||||
eventlines.AddRange(ambientsoundshapes);
|
||||
if(highlighted != null && !highlighted.IsDisposed)
|
||||
eventlines.AddRange(GetAmbientSoundShapes(new List<Thing> { highlighted }));
|
||||
eventlines.AddRange(LinksCollector.GetAmbientSoundShapes(new List<Thing> { highlighted }, true));
|
||||
}
|
||||
|
||||
//mxd
|
||||
|
@ -1073,190 +1073,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
//mxd
|
||||
private void UpdateHelperObjects()
|
||||
{
|
||||
// Update event lines
|
||||
persistenteventlines = LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings);
|
||||
// Update event lines and argument shapes
|
||||
persistenteventlines = LinksCollector.GetHelperShapes(General.Map.ThingsFilter.VisibleThings);
|
||||
|
||||
// Update light radii
|
||||
dynamiclightshapes = GetDynamicLightShapes(General.Map.Map.Things);
|
||||
dynamiclightshapes = LinksCollector.GetDynamicLightShapes(General.Map.ThingsFilter.VisibleThings, false);
|
||||
|
||||
// Update ambient sound radii
|
||||
ambientsoundshapes = GetAmbientSoundShapes(General.Map.Map.Things);
|
||||
|
||||
// Update argument range shapes
|
||||
persistenteventlines.AddRange(GetArgumentRangeShapes(General.Map.Map.Things));
|
||||
}
|
||||
|
||||
//mxd
|
||||
private List<Line3D> GetDynamicLightShapes(IEnumerable<Thing> things)
|
||||
{
|
||||
List<Line3D> circles = new List<Line3D>();
|
||||
if(General.Map.DOOM) return circles;
|
||||
|
||||
const int linealpha = 128;
|
||||
const int numsides = 24;
|
||||
foreach(Thing t in things)
|
||||
{
|
||||
int lightid = Array.IndexOf(GZBuilder.GZGeneral.GZ_LIGHTS, t.Type);
|
||||
if(lightid == -1) continue;
|
||||
|
||||
// TODO: this basically duplicates VisualThing.UpdateLight()...
|
||||
// Determine light radiii
|
||||
int primaryradius;
|
||||
int secondaryradius = 0;
|
||||
|
||||
if(lightid < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[2]) //if it's gzdoom light
|
||||
{
|
||||
int n;
|
||||
if(lightid < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[0]) n = 0;
|
||||
else if(lightid < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[1]) n = 10;
|
||||
else n = 20;
|
||||
DynamicLightType lightType = (DynamicLightType)(t.Type - 9800 - n);
|
||||
|
||||
if(lightType == DynamicLightType.SECTOR)
|
||||
{
|
||||
if(t.Sector == null) t.DetermineSector();
|
||||
int scaler = (t.Sector != null ? t.Sector.Brightness / 4 : 2);
|
||||
primaryradius = t.Args[3] * scaler;
|
||||
}
|
||||
else
|
||||
{
|
||||
primaryradius = t.Args[3] * 2; //works... that.. way in GZDoom
|
||||
if(lightType > 0) secondaryradius = t.Args[4] * 2;
|
||||
}
|
||||
}
|
||||
else //it's one of vavoom lights
|
||||
{
|
||||
primaryradius = t.Args[0] * 8;
|
||||
}
|
||||
|
||||
// Check radii...
|
||||
if(primaryradius < 1 && secondaryradius < 1) continue;
|
||||
|
||||
// Determine light color
|
||||
PixelColor color;
|
||||
if(t == highlighted)
|
||||
{
|
||||
color = General.Colors.Highlight.WithAlpha(linealpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(t.Type)
|
||||
{
|
||||
case 1502: // Vavoom light
|
||||
color = new PixelColor(linealpha, 255, 255, 255);
|
||||
break;
|
||||
|
||||
case 1503: // Vavoom colored light
|
||||
color = new PixelColor(linealpha, (byte)t.Args[1], (byte)t.Args[2], (byte)t.Args[3]);
|
||||
break;
|
||||
|
||||
default:
|
||||
color = new PixelColor(linealpha, (byte)t.Args[0], (byte)t.Args[1], (byte)t.Args[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add lines if visible
|
||||
if(primaryradius > 0) circles.AddRange(LinksCollector.MakeCircleLines(t.Position, color, primaryradius, numsides));
|
||||
if(secondaryradius > 0) circles.AddRange(LinksCollector.MakeCircleLines(t.Position, color, secondaryradius, numsides));
|
||||
}
|
||||
|
||||
// Done
|
||||
return circles;
|
||||
}
|
||||
|
||||
//mxd
|
||||
private List<Line3D> GetAmbientSoundShapes(IEnumerable<Thing> things)
|
||||
{
|
||||
List<Line3D> circles = new List<Line3D>();
|
||||
const int linealpha = 128;
|
||||
const int numsides = 24;
|
||||
|
||||
foreach(Thing t in things)
|
||||
{
|
||||
ThingTypeInfo info = General.Map.Data.GetThingInfoEx(t.Type);
|
||||
if(info == null) continue;
|
||||
|
||||
float minradius, maxradius;
|
||||
if(info.AmbientSound != null)
|
||||
{
|
||||
minradius = info.AmbientSound.MinimumRadius;
|
||||
maxradius = info.AmbientSound.MaximumRadius;
|
||||
}
|
||||
else if(!General.Map.DOOM && (info.ClassName == "AmbientSound" || info.ClassName == "AmbientSoundNoGravity"))
|
||||
{
|
||||
//arg0: ambient slot
|
||||
//arg1: (optional) sound volume, in percent. 1 is nearly silent, 100 and above are full volume. If left to zero, full volume is also used.
|
||||
//arg2: (optional) minimum distance, in map units, at which volume attenuation begins. Note that arg3 must also be set. If both are left to zero, normal rolloff is used instead.
|
||||
//arg3: (optional) maximum distance, in map units, at which the sound can be heard. If left to zero or lower than arg2, normal rolloff is used instead.
|
||||
//arg4: (optional) scalar by which to multiply the values of arg2 and arg3. If left to zero, no multiplication takes place.
|
||||
|
||||
if(t.Args[0] == 0 || !General.Map.Data.AmbientSounds.ContainsKey(t.Args[0]))
|
||||
continue;
|
||||
|
||||
// Use custom radii?
|
||||
if(t.Args[2] > 0 && t.Args[3] > 0 && t.Args[3] > t.Args[2])
|
||||
{
|
||||
minradius = t.Args[2] * (t.Args[4] != 0 ? t.Args[4] : 1.0f);
|
||||
maxradius = t.Args[3] * (t.Args[4] != 0 ? t.Args[4] : 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
minradius = General.Map.Data.AmbientSounds[t.Args[0]].MinimumRadius;
|
||||
maxradius = General.Map.Data.AmbientSounds[t.Args[0]].MaximumRadius;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Determine color
|
||||
PixelColor color = (t == highlighted ? General.Colors.Highlight.WithAlpha(linealpha) : t.Color.WithAlpha(linealpha));
|
||||
|
||||
// Add lines if visible
|
||||
if(minradius > 0) circles.AddRange(LinksCollector.MakeCircleLines(t.Position, color, minradius, numsides));
|
||||
if(maxradius > 0) circles.AddRange(LinksCollector.MakeCircleLines(t.Position, color, maxradius, numsides));
|
||||
}
|
||||
|
||||
return circles;
|
||||
}
|
||||
|
||||
private List<Line3D> GetArgumentRangeShapes(IEnumerable<Thing> things)
|
||||
{
|
||||
List<Line3D> lines = new List<Line3D>();
|
||||
const int numsides = 24;
|
||||
|
||||
foreach(Thing t in things)
|
||||
{
|
||||
ThingTypeInfo info = General.Map.Data.GetThingInfoEx(t.Type);
|
||||
if(info == null) continue;
|
||||
|
||||
// Process argument based range finders
|
||||
for(int i = 0; i < t.Args.Length; i++)
|
||||
{
|
||||
if(t.Args[i] == 0) continue; // Avoid visual noise
|
||||
|
||||
var a = info.Args[i];
|
||||
switch(a.RenderStyle)
|
||||
{
|
||||
case ArgumentInfo.ArgumentRenderStyle.CIRCLE:
|
||||
if(a.MinRange > 0) lines.AddRange(LinksCollector.MakeCircleLines(t.Position, a.MinRangeColor, a.MinRange, numsides));
|
||||
if(a.MaxRange > 0) lines.AddRange(LinksCollector.MakeCircleLines(t.Position, a.MaxRangeColor, a.MaxRange, numsides));
|
||||
break;
|
||||
|
||||
case ArgumentInfo.ArgumentRenderStyle.RECTANGLE:
|
||||
if(a.MinRange > 0) lines.AddRange(LinksCollector.MakeRectangleLines(t.Position, a.MinRangeColor, a.MinRange));
|
||||
if(a.MaxRange > 0) lines.AddRange(LinksCollector.MakeRectangleLines(t.Position, a.MaxRangeColor, a.MaxRange));
|
||||
break;
|
||||
|
||||
case ArgumentInfo.ArgumentRenderStyle.NONE:break;
|
||||
default: throw new NotImplementedException("Unknown ArgumentRenderStyle");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lines;
|
||||
ambientsoundshapes = LinksCollector.GetAmbientSoundShapes(General.Map.ThingsFilter.VisibleThings, false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -518,7 +518,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
|
||||
//mxd. Update event lines (still better than updating them on every frame redraw)
|
||||
renderer.SetEventLines(LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings, blockmap));
|
||||
renderer.SetEventLines(LinksCollector.GetHelperShapes(General.Map.ThingsFilter.VisibleThings, blockmap));
|
||||
}
|
||||
|
||||
//mxd
|
||||
|
@ -1062,7 +1062,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
RebuildElementData();
|
||||
|
||||
//mxd. Update event lines
|
||||
renderer.SetEventLines(LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings, blockmap));
|
||||
renderer.SetEventLines(LinksCollector.GetHelperShapes(General.Map.ThingsFilter.VisibleThings, blockmap));
|
||||
}
|
||||
|
||||
// When returning to another mode
|
||||
|
@ -3159,7 +3159,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
General.Map.ThingsFilter.Update();
|
||||
|
||||
// Update event lines
|
||||
renderer.SetEventLines(LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings, blockmap));
|
||||
renderer.SetEventLines(LinksCollector.GetHelperShapes(General.Map.ThingsFilter.VisibleThings, blockmap));
|
||||
}
|
||||
|
||||
//mxd. We'll just use currently selected objects
|
||||
|
|
Loading…
Reference in a new issue