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

@ -40,7 +40,7 @@ gzdoom_lights
9801 9801
{ {
title = "Pulse Light"; title = "Pulse Light";
fixedrotation = true; fixedrotation = true;
arg0 arg0
{ {
title = "Red"; title = "Red";
@ -70,7 +70,7 @@ gzdoom_lights
9802 9802
{ {
title = "Flicker Light"; title = "Flicker Light";
fixedrotation = true; fixedrotation = true;
arg0 arg0
{ {
title = "Red"; title = "Red";
@ -124,7 +124,7 @@ gzdoom_lights
9804 9804
{ {
title = "Random Light"; title = "Random Light";
fixedrotation = true; fixedrotation = true;
arg0 arg0
{ {
title = "Red"; title = "Red";
@ -178,7 +178,7 @@ gzdoom_lights
9811 9811
{ {
title = "Additive Pulse Light"; title = "Additive Pulse Light";
fixedrotation = true; fixedrotation = true;
arg0 arg0
{ {
title = "Red"; title = "Red";
@ -208,7 +208,7 @@ gzdoom_lights
9812 9812
{ {
title = "Additive Flicker Light"; title = "Additive Flicker Light";
fixedrotation = true; fixedrotation = true;
arg0 arg0
{ {
title = "Red"; title = "Red";
@ -262,7 +262,7 @@ gzdoom_lights
9814 9814
{ {
title = "Additive Random Light"; title = "Additive Random Light";
fixedrotation = true; fixedrotation = true;
arg0 arg0
{ {
title = "Red"; title = "Red";
@ -316,7 +316,7 @@ gzdoom_lights
9821 9821
{ {
title = "Subtractive Pulse Light"; title = "Subtractive Pulse Light";
fixedrotation = true; fixedrotation = true;
arg0 arg0
{ {
title = "Red"; title = "Red";
@ -346,7 +346,7 @@ gzdoom_lights
9822 9822
{ {
title = "Subtractive Flicker Light"; title = "Subtractive Flicker Light";
fixedrotation = true; fixedrotation = true;
arg0 arg0
{ {
title = "Red"; title = "Red";
@ -400,7 +400,7 @@ gzdoom_lights
9824 9824
{ {
title = "Subtractive Random Light"; title = "Subtractive Random Light";
fixedrotation = true; fixedrotation = true;
arg0 arg0
{ {
title = "Red"; title = "Red";
@ -427,10 +427,10 @@ gzdoom_lights
default = 64; default = 64;
} }
} }
9825 = "Vavoom Light"; 9825 = "Vavoom Light (obsolete)";
1502 1502
{ {
title = "Vavoom Light "; title = "Vavoom Light";
arg0 arg0
{ {
title = "Radius"; title = "Radius";

View file

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

View file

@ -27,7 +27,8 @@ II. Implementation Semantics
II.A : Storage and Retrieval of Data 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 II.B : Storage Within Archive Files
@ -202,7 +203,18 @@ Note: All <bool> fields default to false unless mentioned otherwise.
// sound sequence thing in the sector will override this property. // sound sequence thing in the sector will override this property.
hidden = <bool>; // if true this sector will not be drawn on the textured automap. hidden = <bool>; // if true this sector will not be drawn on the textured automap.
waterzone = <bool>; // Sector is under water and swimmable 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") 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 * Note about dropactors
@ -376,6 +388,10 @@ Changed language describing the DIALOGUE lump to mention USDF as an option.
1.25 19.04.2015 1.25 19.04.2015
Added 'moreids' for linedefs and sectors. Added 'moreids' for linedefs and sectors.
1.26 05.01.2016
added clarification about character encoding
added sector damage properties.
=============================================================================== ===============================================================================
EOF 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 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 virtualname; //mxd. Path of this name is used in TextureBrowserForm
protected string displayname; //mxd. Name to display in TextureBrowserForm protected string displayname; //mxd. Name to display in TextureBrowserForm
protected bool isFlat; //mxd. if false, it's a texture protected bool isFlat; //mxd. If false, it's a texture
protected bool istranslucent; //mxd 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 hasLongName; //mxd. Texture name is longer than DataManager.CLASIC_IMAGE_NAME_LENGTH
protected bool hasPatchWithSameName; //mxd protected bool hasPatchWithSameName; //mxd
protected int level; //mxd. Folder depth of this item 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 string DisplayName { get { return displayname; } } //mxd
public bool IsFlat { get { return isFlat; } } //mxd public bool IsFlat { get { return isFlat; } } //mxd
public bool IsTranslucent { get { return istranslucent; } } //mxd public bool IsTranslucent { get { return istranslucent; } } //mxd
public bool IsMasked { get { return ismasked; } } //mxd
public bool HasPatchWithSameName { get { return hasPatchWithSameName; } } //mxd public bool HasPatchWithSameName { get { return hasPatchWithSameName; } } //mxd
internal bool HasLongName { get { return hasLongName; } } //mxd internal bool HasLongName { get { return hasLongName; } } //mxd
public bool UseColorCorrection { get { return usecolorcorrection; } set { usecolorcorrection = value; } } public bool UseColorCorrection { get { return usecolorcorrection; } set { usecolorcorrection = value; } }
@ -364,6 +366,7 @@ namespace CodeImp.DoomBuilder.Data
// Also check alpha // Also check alpha
if(cp->a > 0 && cp->a < 255) istranslucent = true; if(cp->a > 0 && cp->a < 255) istranslucent = true;
else if(cp->a == 0) ismasked = true;
} }
// Update glow data // Update glow data
@ -396,7 +399,7 @@ namespace CodeImp.DoomBuilder.Data
} }
} }
//mxd. Check if the texture is translucent //mxd. Check if the texture is translucent
else else if(!loadfailed)
{ {
BitmapData bmpdata = null; BitmapData bmpdata = null;
try { bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); } 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--) for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--)
{ {
// Check alpha // Check alpha
if(cp->a > 0 && cp->a < 255) if(cp->a > 0 && cp->a < 255) istranslucent = true;
{ else if(cp->a == 0) ismasked = true;
istranslucent = true;
break;
}
} }
// Release the data // Release the data

View file

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

View file

@ -627,7 +627,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Sectors #region ================== Sectors
// This gets sectors which surround given 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<int> processedsectors = new HashSet<int>();
HashSet<Vertex> verts = new HashSet<Vertex>(); HashSet<Vertex> verts = new HashSet<Vertex>();
@ -651,11 +651,39 @@ namespace CodeImp.DoomBuilder.BuilderModes
{ {
result.Add(l.Front.Sector); result.Add(l.Front.Sector);
processedsectors.Add(l.Front.Sector.Index); 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)) if(l.Back != null && l.Back.Sector != null && !processedsectors.Contains(l.Back.Sector.Index))
{ {
result.Add(l.Back.Sector); result.Add(l.Back.Sector);
processedsectors.Add(l.Back.Sector.Index); 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]; 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 // This requests a things's extra data
internal ThingData GetThingData(Thing t) internal ThingData GetThingData(Thing t)
{ {
@ -2090,7 +2096,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
else else
{ {
// Get next higher floor or ceiling from surrounding unselected sectors // 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) if(s.FloorHeight < targetCeilingHeight && s.FloorHeight > maxSelectedHeight)
targetCeilingHeight = s.FloorHeight; targetCeilingHeight = s.FloorHeight;
@ -2123,7 +2129,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
else else
{ {
// Get next higher floor or ceiling from surrounding unselected sectors // 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) if(s.FloorHeight > maxSelectedHeight && s.FloorHeight < targetFloorHeight && s.FloorHeight <= minSelectedCeilingHeight)
targetFloorHeight = s.FloorHeight; targetFloorHeight = s.FloorHeight;
@ -2290,7 +2296,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
else else
{ {
// Get next lower ceiling or floor from surrounding unselected sectors // 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) if(s.CeilHeight > targetFloorHeight && s.CeilHeight < minSelectedHeight)
targetFloorHeight = s.CeilHeight; targetFloorHeight = s.CeilHeight;
@ -2323,7 +2329,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
else else
{ {
// Get next lower ceiling or floor from surrounding unselected sectors // 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) if(s.CeilHeight > targetCeilingHeight && s.CeilHeight < minSelectedHeight && s.CeilHeight >= maxSelectedFloorHeight)
targetCeilingHeight = s.CeilHeight; targetCeilingHeight = s.CeilHeight;

View file

@ -480,7 +480,40 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Check on which side of the nearest sidedef we are // Check on which side of the nearest sidedef we are
Sidedef sd = MapSet.NearestSidedef(Sector.Sector.Sidedefs, pickintersect); Sidedef sd = MapSet.NearestSidedef(Sector.Sector.Sidedefs, pickintersect);
float side = sd.Line.SideOfLine(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 // Return texture name

View file

@ -432,7 +432,40 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Check on which side of the nearest sidedef we are // Check on which side of the nearest sidedef we are
Sidedef sd = MapSet.NearestSidedef(Sector.Sector.Sidedefs, pickintersect); Sidedef sd = MapSet.NearestSidedef(Sector.Sector.Sidedefs, pickintersect);
float side = sd.Line.SideOfLine(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 // Return texture name

View file

@ -319,6 +319,36 @@ namespace CodeImp.DoomBuilder.BuilderModes
return base.PickFastReject(from, to, dir); 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 // Return texture name
public override string GetTextureName() public override string GetTextureName()
{ {

View file

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