diff --git a/Build/Configurations/Includes/GZDoom_things.cfg b/Build/Configurations/Includes/GZDoom_things.cfg index 09cdb499..f813836f 100644 --- a/Build/Configurations/Includes/GZDoom_things.cfg +++ b/Build/Configurations/Includes/GZDoom_things.cfg @@ -40,7 +40,7 @@ gzdoom_lights 9801 { title = "Pulse Light"; - fixedrotation = true; + fixedrotation = true; arg0 { title = "Red"; @@ -70,7 +70,7 @@ gzdoom_lights 9802 { title = "Flicker Light"; - fixedrotation = true; + fixedrotation = true; arg0 { title = "Red"; @@ -124,7 +124,7 @@ gzdoom_lights 9804 { title = "Random Light"; - fixedrotation = true; + fixedrotation = true; arg0 { title = "Red"; @@ -178,7 +178,7 @@ gzdoom_lights 9811 { title = "Additive Pulse Light"; - fixedrotation = true; + fixedrotation = true; arg0 { title = "Red"; @@ -208,7 +208,7 @@ gzdoom_lights 9812 { title = "Additive Flicker Light"; - fixedrotation = true; + fixedrotation = true; arg0 { title = "Red"; @@ -262,7 +262,7 @@ gzdoom_lights 9814 { title = "Additive Random Light"; - fixedrotation = true; + fixedrotation = true; arg0 { title = "Red"; @@ -316,7 +316,7 @@ gzdoom_lights 9821 { title = "Subtractive Pulse Light"; - fixedrotation = true; + fixedrotation = true; arg0 { title = "Red"; @@ -346,7 +346,7 @@ gzdoom_lights 9822 { title = "Subtractive Flicker Light"; - fixedrotation = true; + fixedrotation = true; arg0 { title = "Red"; @@ -400,7 +400,7 @@ gzdoom_lights 9824 { title = "Subtractive Random Light"; - fixedrotation = true; + fixedrotation = true; arg0 { title = "Red"; @@ -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"; diff --git a/Build/Configurations/Includes/ZDoom_linedefs.cfg b/Build/Configurations/Includes/ZDoom_linedefs.cfg index b5f7f64b..9315c9f6 100644 --- a/Build/Configurations/Includes/ZDoom_linedefs.cfg +++ b/Build/Configurations/Includes/ZDoom_linedefs.cfg @@ -3957,7 +3957,8 @@ zdoom arg1 { - title = "Translucency Amount"; + title = "Opacity"; + default = 128; } arg2 { diff --git a/Documents/udmf_zdoom.txt b/Documents/udmf_zdoom.txt index d501cb88..611a667a 100644 --- a/Documents/udmf_zdoom.txt +++ b/Documents/udmf_zdoom.txt @@ -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 @@ -202,7 +203,18 @@ Note: All fields default to false unless mentioned otherwise. // sound sequence thing in the sector will override this property. hidden = ; // if true this sector will not be drawn on the textured automap. waterzone = ; // Sector is under water and swimmable - moreids = ; // Additional sector IDs/tags, specified as a space separated list of numbers (e.g. "2 666 1003 4505") + moreids = ; // Additional sector IDs/tags, specified as a space separated list of numbers (e.g. "2 666 1003 4505") + damageamount = ; // 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 = ; // Damage type for sector damage, Default = "None". (generic damage) + damageinterval = ; // Interval in tics between damage application, default = 32. + leakiness = ; // Probability of leaking through radiation suit (0 = never, 256 = always), default = 0. + damageterraineffect = ; // Will spawn a terrain splash when damage is inflicted. Default = false. + damagehazard = ; // Changes damage model to Strife's delayed damage for the given sector. Default = false. + floorterrain = ; // Sets the terrain for the sector's floor. Default = 'use the flat texture's terrain definition.' + ceilingterrain = ; // 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 =============================================================================== diff --git a/Source/Core/Data/ImageData.cs b/Source/Core/Data/ImageData.cs index 47bebab6..06e2cc87 100644 --- a/Source/Core/Data/ImageData.cs +++ b/Source/Core/Data/ImageData.cs @@ -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 diff --git a/Source/Core/Windows/MainForm.cs b/Source/Core/Windows/MainForm.cs index e94e3286..e0033320 100644 --- a/Source/Core/Windows/MainForm.cs +++ b/Source/Core/Windows/MainForm.cs @@ -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); } } } diff --git a/Source/Plugins/BuilderModes/General/BuilderModesTools.cs b/Source/Plugins/BuilderModes/General/BuilderModesTools.cs index c6f370aa..319f37d5 100644 --- a/Source/Plugins/BuilderModes/General/BuilderModesTools.cs +++ b/Source/Plugins/BuilderModes/General/BuilderModesTools.cs @@ -627,7 +627,7 @@ namespace CodeImp.DoomBuilder.BuilderModes #region ================== Sectors // This gets sectors which surround given sectors - internal static IEnumerable GetSectorsAround(IEnumerable selected) + internal static IEnumerable GetSectorsAround(BaseVisualMode mode, IEnumerable selected) { HashSet processedsectors = new HashSet(); HashSet verts = new HashSet(); @@ -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); + } + } + } } } } diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs index efb97a1c..d353e5b6 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs @@ -701,7 +701,13 @@ 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; diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs b/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs index 9881b21d..610c1b5a 100644 --- a/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs @@ -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 diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs b/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs index b6747cce..8da7e41b 100644 --- a/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs @@ -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 diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs b/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs index 2ff6ebc2..d922fa59 100644 --- a/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs @@ -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() { diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualMiddleDouble.cs b/Source/Plugins/BuilderModes/VisualModes/VisualMiddleDouble.cs index e6052403..070bb636 100644 --- a/Source/Plugins/BuilderModes/VisualModes/VisualMiddleDouble.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualMiddleDouble.cs @@ -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)