Added, Visual mode: "Raise/Lower Floor/Ceiling to adjacent Sector" actions now take surrounding 3d floors into account.

Added, Visual mode: highlight/selection based on texture alpha now works on 3d floors.
Changed, Game configurations, TranslucentLine:208 action: renamed the second argument from "Translucency Amount" to "Opacity".
Internal, documentation: updated udmf_zdoom.txt.
This commit is contained in:
MaxED 2016-01-26 22:29:12 +00:00
parent 5d47e331d8
commit f9a7c22e03
11 changed files with 181 additions and 34 deletions

View file

@ -427,10 +427,10 @@ gzdoom_lights
default = 64;
}
}
9825 = "Vavoom Light";
9825 = "Vavoom Light (obsolete)";
1502
{
title = "Vavoom Light ";
title = "Vavoom Light";
arg0
{
title = "Radius";

View file

@ -3957,7 +3957,8 @@ zdoom
arg1
{
title = "Translucency Amount";
title = "Opacity";
default = 128;
}
arg2
{

View file

@ -27,7 +27,8 @@ II. Implementation Semantics
II.A : Storage and Retrieval of Data
------------------------------------
No changes.
Any TEXTMAP lump in the described namespaces must be encoded in ISO 8859-1 which
as of this writing is the only character encoding supported by ZDoom.
-----------------------------------
II.B : Storage Within Archive Files
@ -203,6 +204,17 @@ Note: All <bool> fields default to false unless mentioned otherwise.
hidden = <bool>; // if true this sector will not be drawn on the textured automap.
waterzone = <bool>; // Sector is under water and swimmable
moreids = <string>; // Additional sector IDs/tags, specified as a space separated list of numbers (e.g. "2 666 1003 4505")
damageamount = <int>; // Amount of damage inflicted by this sector, default = 0. If this is 0, all other damage properties will be ignored.
// Setting damage through these properties will override any damage set through 'special'.
// Setting damageamount to a negative value will create a healing sector.
damagetype = <string>; // Damage type for sector damage, Default = "None". (generic damage)
damageinterval = <int>; // Interval in tics between damage application, default = 32.
leakiness = <int>; // Probability of leaking through radiation suit (0 = never, 256 = always), default = 0.
damageterraineffect = <bool>; // Will spawn a terrain splash when damage is inflicted. Default = false.
damagehazard = <bool>; // Changes damage model to Strife's delayed damage for the given sector. Default = false.
floorterrain = <string>; // Sets the terrain for the sector's floor. Default = 'use the flat texture's terrain definition.'
ceilingterrain = <string>; // Sets the terrain for the sector's ceiling. Default = 'use the flat texture's terrain definition.'
* Note about dropactors
@ -376,6 +388,10 @@ Changed language describing the DIALOGUE lump to mention USDF as an option.
1.25 19.04.2015
Added 'moreids' for linedefs and sectors.
1.26 05.01.2016
added clarification about character encoding
added sector damage properties.
===============================================================================
EOF
===============================================================================

View file

@ -53,8 +53,9 @@ namespace CodeImp.DoomBuilder.Data
protected string shortname; //mxd. Name in uppercase and clamped to DataManager.CLASIC_IMAGE_NAME_LENGTH
protected string virtualname; //mxd. Path of this name is used in TextureBrowserForm
protected string displayname; //mxd. Name to display in TextureBrowserForm
protected bool isFlat; //mxd. if false, it's a texture
protected bool istranslucent; //mxd
protected bool isFlat; //mxd. If false, it's a texture
protected bool istranslucent; //mxd. If true, has pixels with alpha > 0 && < 255
protected bool ismasked; //mxd. If true, has pixels with zero alpha
protected bool hasLongName; //mxd. Texture name is longer than DataManager.CLASIC_IMAGE_NAME_LENGTH
protected bool hasPatchWithSameName; //mxd
protected int level; //mxd. Folder depth of this item
@ -97,6 +98,7 @@ namespace CodeImp.DoomBuilder.Data
public string DisplayName { get { return displayname; } } //mxd
public bool IsFlat { get { return isFlat; } } //mxd
public bool IsTranslucent { get { return istranslucent; } } //mxd
public bool IsMasked { get { return ismasked; } } //mxd
public bool HasPatchWithSameName { get { return hasPatchWithSameName; } } //mxd
internal bool HasLongName { get { return hasLongName; } } //mxd
public bool UseColorCorrection { get { return usecolorcorrection; } set { usecolorcorrection = value; } }
@ -364,6 +366,7 @@ namespace CodeImp.DoomBuilder.Data
// Also check alpha
if(cp->a > 0 && cp->a < 255) istranslucent = true;
else if(cp->a == 0) ismasked = true;
}
// Update glow data
@ -396,7 +399,7 @@ namespace CodeImp.DoomBuilder.Data
}
}
//mxd. Check if the texture is translucent
else
else if(!loadfailed)
{
BitmapData bmpdata = null;
try { bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); }
@ -410,11 +413,8 @@ namespace CodeImp.DoomBuilder.Data
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--)
{
// Check alpha
if(cp->a > 0 && cp->a < 255)
{
istranslucent = true;
break;
}
if(cp->a > 0 && cp->a < 255) istranslucent = true;
else if(cp->a == 0) ismasked = true;
}
// Release the data

View file

@ -1042,7 +1042,7 @@ namespace CodeImp.DoomBuilder.Windows
if(General.Colors != null)
e.Graphics.Clear(Color.FromArgb(General.Colors.Background.ToInt()));
else
e.Graphics.Clear(SystemColors.AppWorkspace);
e.Graphics.Clear(SystemColors.ControlDarkDark);
}
}
}

View file

@ -627,7 +627,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Sectors
// This gets sectors which surround given sectors
internal static IEnumerable<Sector> GetSectorsAround(IEnumerable<Sector> selected)
internal static IEnumerable<Sector> GetSectorsAround(BaseVisualMode mode, IEnumerable<Sector> selected)
{
HashSet<int> processedsectors = new HashSet<int>();
HashSet<Vertex> verts = new HashSet<Vertex>();
@ -651,11 +651,39 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
result.Add(l.Front.Sector);
processedsectors.Add(l.Front.Sector.Index);
// Add extrafloors as well
SectorData sd = mode.GetSectorDataEx(l.Front.Sector);
if(sd != null && sd.ExtraFloors.Count > 0)
{
foreach(Effect3DFloor effect in sd.ExtraFloors)
{
if(!processedsectors.Contains(effect.Linedef.Front.Sector.Index))
{
result.Add(effect.Linedef.Front.Sector);
processedsectors.Add(effect.Linedef.Front.Sector.Index);
}
}
}
}
if(l.Back != null && l.Back.Sector != null && !processedsectors.Contains(l.Back.Sector.Index))
{
result.Add(l.Back.Sector);
processedsectors.Add(l.Back.Sector.Index);
// Add extrafloors as well
SectorData sd = mode.GetSectorDataEx(l.Back.Sector);
if(sd != null && sd.ExtraFloors.Count > 0)
{
foreach(Effect3DFloor effect in sd.ExtraFloors)
{
if(!processedsectors.Contains(effect.Linedef.Front.Sector.Index))
{
result.Add(effect.Linedef.Front.Sector);
processedsectors.Add(effect.Linedef.Front.Sector.Index);
}
}
}
}
}
}

View file

@ -702,6 +702,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
return sectordata[s];
}
//mxd. This requests a sector's extra data or null if given sector doesn't have it
internal SectorData GetSectorDataEx(Sector s)
{
return (sectordata.ContainsKey(s) ? sectordata[s] : null);
}
// This requests a things's extra data
internal ThingData GetThingData(Thing t)
{
@ -2090,7 +2096,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
else
{
// Get next higher floor or ceiling from surrounding unselected sectors
foreach(Sector s in BuilderModesTools.GetSectorsAround(ceilings.Keys))
foreach(Sector s in BuilderModesTools.GetSectorsAround(this, ceilings.Keys))
{
if(s.FloorHeight < targetCeilingHeight && s.FloorHeight > maxSelectedHeight)
targetCeilingHeight = s.FloorHeight;
@ -2123,7 +2129,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
else
{
// Get next higher floor or ceiling from surrounding unselected sectors
foreach(Sector s in BuilderModesTools.GetSectorsAround(floors.Keys))
foreach(Sector s in BuilderModesTools.GetSectorsAround(this, floors.Keys))
{
if(s.FloorHeight > maxSelectedHeight && s.FloorHeight < targetFloorHeight && s.FloorHeight <= minSelectedCeilingHeight)
targetFloorHeight = s.FloorHeight;
@ -2290,7 +2296,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
else
{
// Get next lower ceiling or floor from surrounding unselected sectors
foreach(Sector s in BuilderModesTools.GetSectorsAround(floors.Keys))
foreach(Sector s in BuilderModesTools.GetSectorsAround(this, floors.Keys))
{
if(s.CeilHeight > targetFloorHeight && s.CeilHeight < minSelectedHeight)
targetFloorHeight = s.CeilHeight;
@ -2323,7 +2329,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
else
{
// Get next lower ceiling or floor from surrounding unselected sectors
foreach(Sector s in BuilderModesTools.GetSectorsAround(ceilings.Keys))
foreach(Sector s in BuilderModesTools.GetSectorsAround(this, ceilings.Keys))
{
if(s.CeilHeight > targetCeilingHeight && s.CeilHeight < minSelectedHeight && s.CeilHeight >= maxSelectedFloorHeight)
targetCeilingHeight = s.CeilHeight;

View file

@ -480,7 +480,40 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Check on which side of the nearest sidedef we are
Sidedef sd = MapSet.NearestSidedef(Sector.Sector.Sidedefs, pickintersect);
float side = sd.Line.SideOfLine(pickintersect);
return (((side <= 0.0f) && sd.IsFront) || ((side > 0.0f) && !sd.IsFront));
//mxd. Alpha based picking. Used only on extrafloors with transparent or masked textures
if((side <= 0.0f && sd.IsFront) || (side > 0.0f && !sd.IsFront))
{
if(!Texture.IsImageLoaded || extrafloor == null || RenderPass == RenderPass.Solid || (!Texture.IsTranslucent && !Texture.IsMasked))
return true;
// Fetch ZDoom fields
float rotate = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationceiling", 0.0f));
Vector2D offset = new Vector2D(level.sector.Fields.GetValue("xpanningceiling", 0.0f), level.sector.Fields.GetValue("ypanningceiling", 0.0f));
Vector2D scale = new Vector2D(level.sector.Fields.GetValue("xscaleceiling", 1.0f), level.sector.Fields.GetValue("yscaleceiling", 1.0f));
Vector2D texscale = new Vector2D(1.0f / Texture.ScaledWidth, 1.0f / Texture.ScaledHeight);
// Texture coordinates
Vector2D o = pickintersect;
o = o.GetRotated(rotate);
o.y = -o.y;
o = (o + offset) * scale * texscale;
o.x = (o.x * Texture.Width) % Texture.Width;
o.y = (o.y * Texture.Height) % Texture.Height;
// Make sure coordinates are inside of texture dimensions...
if(o.x < 0) o.x += Texture.Width;
if(o.y < 0) o.y += Texture.Height;
// Make final texture coordinates...
int ox = General.Clamp((int)Math.Floor(o.x), 0, Texture.Width - 1);
int oy = General.Clamp((int)Math.Floor(o.y), 0, Texture.Height - 1);
// Check pixel alpha
return (Texture.GetBitmap().GetPixel(ox, oy).A > 0);
}
return false;
}
// Return texture name

View file

@ -432,7 +432,40 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Check on which side of the nearest sidedef we are
Sidedef sd = MapSet.NearestSidedef(Sector.Sector.Sidedefs, pickintersect);
float side = sd.Line.SideOfLine(pickintersect);
return (((side <= 0.0f) && sd.IsFront) || ((side > 0.0f) && !sd.IsFront));
//mxd. Alpha based picking. Used only on extrafloors with transparent or masked textures
if((side <= 0.0f && sd.IsFront) || (side > 0.0f && !sd.IsFront))
{
if(!Texture.IsImageLoaded || extrafloor == null || RenderPass == RenderPass.Solid || (!Texture.IsTranslucent && !Texture.IsMasked))
return true;
// Fetch ZDoom fields
float rotate = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationfloor", 0.0f));
Vector2D offset = new Vector2D(level.sector.Fields.GetValue("xpanningfloor", 0.0f), level.sector.Fields.GetValue("ypanningfloor", 0.0f));
Vector2D scale = new Vector2D(level.sector.Fields.GetValue("xscalefloor", 1.0f), level.sector.Fields.GetValue("yscalefloor", 1.0f));
Vector2D texscale = new Vector2D(1.0f / Texture.ScaledWidth, 1.0f / Texture.ScaledHeight);
// Texture coordinates
Vector2D o = pickintersect;
o = o.GetRotated(rotate);
o.y = -o.y;
o = (o + offset) * scale * texscale;
o.x = (o.x * Texture.Width) % Texture.Width;
o.y = (o.y * Texture.Height) % Texture.Height;
// Make sure coordinates are inside of texture dimensions...
if(o.x < 0) o.x += Texture.Width;
if(o.y < 0) o.y += Texture.Height;
// Make final texture coordinates...
int ox = General.Clamp((int)Math.Floor(o.x), 0, Texture.Width - 1);
int oy = General.Clamp((int)Math.Floor(o.y), 0, Texture.Height - 1);
// Check pixel alpha
return (Texture.GetBitmap().GetPixel(ox, oy).A > 0);
}
return false;
}
// Return texture name

View file

@ -319,6 +319,36 @@ namespace CodeImp.DoomBuilder.BuilderModes
return base.PickFastReject(from, to, dir);
}
//mxd. Alpha based picking
public override bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref float u_ray)
{
if(!Texture.IsImageLoaded || (!Texture.IsTranslucent && !Texture.IsMasked)) return base.PickAccurate(from, to, dir, ref u_ray);
float u;
Sidedef sourceside = extrafloor.Linedef.Front;
new Line2D(from, to).GetIntersection(Sidedef.Line.Line, out u);
if(Sidedef != Sidedef.Line.Front) u = 1.0f - u;
// Get correct offset to texture space...
float texoffsetx = Sidedef.OffsetX + sourceside.OffsetX + UniFields.GetFloat(Sidedef.Fields, "offsetx_mid") + UniFields.GetFloat(sourceside.Fields, "offsetx_mid");
int ox = (int)Math.Floor((u * Sidedef.Line.Length * UniFields.GetFloat(sourceside.Fields, "scalex_mid", 1.0f) / Texture.Scale.x + texoffsetx) % Texture.Width);
float texoffsety = Sidedef.OffsetY + sourceside.OffsetY + UniFields.GetFloat(Sidedef.Fields, "offsety_mid") + UniFields.GetFloat(sourceside.Fields, "offsety_mid");
int oy = (int)Math.Ceiling(((pickintersect.z - sourceside.Sector.CeilHeight) * UniFields.GetFloat(sourceside.Fields, "scaley_mid", 1.0f) / Texture.Scale.y - texoffsety) % Texture.Height);
// Make sure offsets are inside of texture dimensions...
if(ox < 0) ox += Texture.Width;
if(oy < 0) oy += Texture.Height;
// Check pixel alpha
if(Texture.GetBitmap().GetPixel(General.Clamp(ox, 0, Texture.Width - 1), General.Clamp(Texture.Height - oy, 0, Texture.Height - 1)).A > 0)
{
return base.PickAccurate(from, to, dir, ref u_ray);
}
return false;
}
// Return texture name
public override string GetTextureName()
{

View file

@ -273,7 +273,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd. Alpha based picking
public override bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref float u_ray)
{
if(!Texture.IsImageLoaded) return base.PickAccurate(from, to, dir, ref u_ray);
if(!Texture.IsImageLoaded || (!Texture.IsTranslucent && !Texture.IsMasked)) return base.PickAccurate(from, to, dir, ref u_ray);
float u;
new Line2D(from, to).GetIntersection(Sidedef.Line.Line, out u);
@ -300,8 +300,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
// Make sure offsets are inside of texture dimensions...
while(ox < 0) ox += Texture.Width;
while(oy < 0) oy += Texture.Height;
if(ox < 0) ox += Texture.Width;
if(oy < 0) oy += Texture.Height;
// Check pixel alpha
if(Texture.GetBitmap().GetPixel(General.Clamp(ox, 0, Texture.Width - 1), General.Clamp(Texture.Height - oy, 0, Texture.Height - 1)).A > 0)