//mxd private static bool GetLockColor(Linedef l, ref PixelColor lockcolor) { int locknum = 0; // Check locknumber property if (General.Map.UDMF) { locknum = UniFields.GetInteger(l.Fields, "locknumber"); } // Check action if (locknum == 0 && l.Action != 0 && General.Map.Data.LockableActions.ContainsKey(l.Action)) { locknum = l.Args[General.Map.Data.LockableActions[l.Action]]; } if (locknum != 0 && General.Map.Data.LockColors.ContainsKey(locknum)) { lockcolor = General.Map.Data.LockColors[locknum]; return(true); } // No dice return(false); }
public void SetValueFrom(UniFields fields, bool first) { blockevents = true; string colorval = String.Format("{0:X6}", UniFields.GetInteger(fields, field, defaultvalue)); if (first) { tbColor.Text = colorval; } else if (!string.IsNullOrEmpty(tbColor.Text) && colorval != tbColor.Text) { blockupdate = true; tbColor.Text = string.Empty; cpColor.Color = PixelColor.FromInt(defaultvalue).WithAlpha(255); blockupdate = false; CheckColor(); } blockevents = false; }
// This builds the thing geometry. Returns false when nothing was created. public bool Setup() { // Find the sector in which the thing resides Thing.DetermineSector(mode.BlockMap); //mxd. If the thing is inside a sector, apply DECORATE/UDMF alpha/renderstyle overrides byte alpha = 255; if (Thing.Sector != null) { string renderstyle = info.RenderStyle.ToLowerInvariant(); alpha = info.AlphaByte; if (General.Map.UDMF) { if (Thing.IsFlagSet("translucent")) { renderstyle = "translucent"; alpha = 64; } else if (Thing.IsFlagSet("invisible")) { renderstyle = "none"; alpha = 0; } else if (Thing.Fields.ContainsKey("renderstyle")) { renderstyle = Thing.Fields.GetValue("renderstyle", renderstyle).ToLowerInvariant(); } if ((renderstyle == "add" || renderstyle == "translucent" || renderstyle == "subtract" || renderstyle == "translucentstencil") && Thing.Fields.ContainsKey("alpha")) { alpha = (byte)(General.Clamp(Thing.Fields.GetValue("alpha", info.Alpha), 0.0, 1.0) * 255.0); } else if (renderstyle == "soultrans") { // Lost Soul trasparency is controlled by a CVAR (see https://zdoom.org/wiki/CVARs:Display#transsouls), let's use the default 0.75 here alpha = 192; } else if (renderstyle == "shadow") { alpha = 76; // about 0.3 stencilColor = PixelColor.FromInt(PixelColor.INT_BLACK); } if (renderstyle.EndsWith("stencil")) { stencilColor = PixelColor.FromInt(UniFields.GetInteger(Thing.Fields, "fillcolor", 0)); stencilColor.a = 255; // 0xFF alpha means nothing was read. 0x00 alpha means there was a valid fillcolor. } else if (renderstyle != "shadow") { stencilColor.a = 0; } } else if (General.Map.HEXEN) { if (Thing.IsFlagSet("2048")) { renderstyle = "translucent"; alpha = 64; } else if (Thing.IsFlagSet("4096")) { renderstyle = "none"; alpha = 0; } } // Set appropriate RenderPass switch (renderstyle) { case "translucent": case "subtract": case "soultrans": case "translucentstencil": case "shadow": RenderPass = RenderPass.Alpha; break; case "add": case "addstencil": RenderPass = RenderPass.Additive; break; case "none": RenderPass = RenderPass.Mask; alpha = 0; break; // Many render styles are not supported yet... default: RenderPass = RenderPass.Mask; alpha = 255; break; } } int sectorcolor = new PixelColor(alpha, 255, 255, 255).ToInt(); fogfactor = 0f; //mxd //mxd. Check thing size float thingradius = Thing.Size; // Thing.Size has ThingRadius arg override applied thingheight = Thing.Height; // Thing.Height has ThingHeight arg override applied if (thingradius < 0.1f || thingheight < 0.1f) { thingradius = FIXED_RADIUS; thingheight = FIXED_RADIUS; sizeless = true; } else { sizeless = false; } if (Thing.Sector != null) { SectorData sd = mode.GetSectorData(Thing.Sector); Plane floor = sd.Floor.plane; //mxd if (!info.Bright) { Vector3D thingpos = new Vector3D(Thing.Position.x, Thing.Position.y, Thing.Position.z + sd.Floor.plane.GetZ(Thing.Position)); SectorLevel level = sd.GetLevelAboveOrAt(thingpos); //mxd. Let's use point on floor plane instead of Thing.Sector.FloorHeight; if (nointeraction && level == null && sd.LightLevels.Count > 0) { level = sd.LightLevels[sd.LightLevels.Count - 1]; } //mxd. Use the light level of the highest surface when a thing is above highest sector level. if (level != null) { // TECH: In GZDoom, ceiling glow doesn't affect thing brightness // Use sector brightness for color shading int brightness = level.brightnessbelow; //mxd. Apply lightfloor value // According to Graf, this is incorrect behaviour... // TECH: In (G)ZDoom, this is ignored when ceiling texture is sky or a thing is below a 3D floor // It's probably more involved than this, but for now let's do it only when there are no 3d floors in Thing.Sector... /*if(General.Map.UDMF && sd.LightLevels.Count == 2 && Thing.Sector.CeilTexture != General.Map.Config.SkyFlatName) * { * if(sd.Sector.Fields.GetValue("lightfloorabsolute", false)) * brightness = UniFields.GetInteger(sd.Sector.Fields, "lightfloor"); * else * brightness += UniFields.GetInteger(sd.Sector.Fields, "lightfloor"); * }*/ // Level is glowing if (level.affectedbyglow && level.type == SectorLevelType.Floor) { // Extrafloor glow doesn't affect thing brightness if (level.sector == Thing.Sector) { double planez = level.plane.GetZ(thingpos); // Get glow brightness int glowbrightness = sd.FloorGlow.Brightness / 2; SectorLevel nexthigher = sd.GetLevelAbove(new Vector3D(thingpos, planez)); // Interpolate thing brightness between glow and regular ones if (nexthigher != null) { double higherz = nexthigher.plane.GetZ(thingpos); double delta = General.Clamp(1.0f - (thingpos.z - planez) / (higherz - planez), 0f, 1f); brightness = (int)((glowbrightness + level.sector.Brightness / 2) * delta + nexthigher.sector.Brightness * (1.0f - delta)); } } } // Level below this one is glowing. Only possible for floor glow(?) else if (level.type == SectorLevelType.Glow) { // Interpolate thing brightness between glow and regular ones if (sd.Floor != null && sd.FloorGlow != null) { // Get glow brightness double glowz = level.plane.GetZ(thingpos); double floorz = floor.GetZ(thingpos); double delta = General.Clamp((thingpos.z - floorz) / (glowz - floorz), 0f, 1f); brightness = (int)((sd.FloorGlow.Brightness / 2 + sd.Floor.sector.Brightness / 2) * (1.0f - delta) + sd.Floor.sector.Brightness * delta); } } PixelColor areabrightness = PixelColor.FromInt(mode.CalculateBrightness(brightness)); PixelColor areacolor = PixelColor.Modulate(level.colorbelow, areabrightness); // [ZZ] if sector is using Doom64 lighting, apply thing color here. sectorcolor = PixelColor.Modulate(sd.ColorSprites, areacolor).WithAlpha(alpha).ToInt(); //mxd. Calculate fogfactor fogfactor = VisualGeometry.CalculateFogFactor(level.sector, brightness); } } //TECH: even Bright Thing frames are affected by custom fade... else { Vector3D thingpos = new Vector3D(Thing.Position.x, Thing.Position.y, Thing.Position.z + sd.Floor.plane.GetZ(Thing.Position)); SectorLevel level = sd.GetLevelAboveOrAt(thingpos); if (level != null && level.sector.FogMode > SectorFogMode.CLASSIC) { //mxd. Calculate fogfactor fogfactor = VisualGeometry.CalculateFogFactor(level.sector, level.brightnessbelow); } } } //mxd. Create verts for all sprite angles WorldVertex[][] allverts = new WorldVertex[info.SpriteFrame.Length][]; Vector2D[] alloffsets = new Vector2D[info.SpriteFrame.Length]; base.textures = new ImageData[info.SpriteFrame.Length]; isloaded = true; for (int i = 0; i < sprites.Length; i++) { Vector2D offsets = new Vector2D(); // Check if the texture is loaded ImageData sprite = sprites[i]; if (!sprite.IsImageLoaded && !sprite.LoadFailed) { sprite.LoadImageNow(); } if (sprite.IsImageLoaded) { base.textures[i] = sprite; // Determine sprite size and offset float radius = sprite.ScaledWidth * 0.5f; float height = sprite.ScaledHeight; ISpriteImage spriteimg = sprite as ISpriteImage; if (spriteimg != null) { offsets.x = radius - spriteimg.OffsetX; offsets.y = spriteimg.OffsetY - height; } // Scale by thing type/actor scale // We do this after the offset x/y determination above, because that is entirely in sprite pixels space radius *= info.SpriteScale.Width; height *= info.SpriteScale.Height; offsets.x *= info.SpriteScale.Width; offsets.y *= info.SpriteScale.Height; // Make vertices WorldVertex[] verts = new WorldVertex[6]; //mxd. Sprite mirroring float ul = (info.SpriteFrame[i].Mirror ? 1f : 0f); float ur = (info.SpriteFrame[i].Mirror ? 0f : 1f); if (sizeless) //mxd { float hh = height / 2; verts[0] = new WorldVertex((float)(-radius + offsets.x), 0.0f, (float)(offsets.y - hh), sectorcolor, ul, 1.0f); verts[1] = new WorldVertex((float)(-radius + offsets.x), 0.0f, (float)(hh + offsets.y), sectorcolor, ul, 0.0f); verts[2] = new WorldVertex((float)(+radius + offsets.x), 0.0f, (float)(hh + offsets.y), sectorcolor, ur, 0.0f); verts[3] = verts[0]; verts[4] = verts[2]; verts[5] = new WorldVertex((float)(+radius + offsets.x), 0.0f, (float)(offsets.y - hh), sectorcolor, ur, 1.0f); } else { verts[0] = new WorldVertex((float)(-radius + offsets.x), 0.0f, (float)offsets.y, sectorcolor, ul, 1.0f); verts[1] = new WorldVertex((float)(-radius + offsets.x), 0.0f, (float)(height + offsets.y), sectorcolor, ul, 0.0f); verts[2] = new WorldVertex((float)(+radius + offsets.x), 0.0f, (float)(height + offsets.y), sectorcolor, ur, 0.0f); verts[3] = verts[0]; verts[4] = verts[2]; verts[5] = new WorldVertex((float)(+radius + offsets.x), 0.0f, (float)offsets.y, sectorcolor, ur, 1.0f); } allverts[i] = verts; } else { isloaded = false; base.textures[i] = sprite; // Determine sprite size float radius = Math.Min(thingradius, thingheight / 2f); float height = Math.Min(thingradius * 2f, thingheight); //mxd. Determine sprite offsets offsets.x = radius; offsets.y = height / 2; // Make vertices WorldVertex[] verts = new WorldVertex[6]; verts[0] = new WorldVertex(-radius, 0.0f, 0.0f, sectorcolor, 0.0f, 1.0f); verts[1] = new WorldVertex(-radius, 0.0f, height, sectorcolor, 0.0f, 0.0f); verts[2] = new WorldVertex(+radius, 0.0f, height, sectorcolor, 1.0f, 0.0f); verts[3] = verts[0]; verts[4] = verts[2]; verts[5] = new WorldVertex(+radius, 0.0f, 0.0f, sectorcolor, 1.0f, 1.0f); allverts[i] = verts; } //mxd. Store offsets alloffsets[i] = offsets; } //mxd SetVertices(allverts, alloffsets /*, floor, ceiling*/); // Determine position 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 pos.z = Thing.Position.z; } else if (info.Hangs) { // Hang from ceiling if (Thing.Sector != null) { SectorData sd = mode.GetSectorData(Thing.Sector); double maxz = sd.Ceiling.plane.GetZ(Thing.Position) - info.Height; pos.z = maxz; if (Thing.Position.z > 0 || nointeraction) { pos.z -= Thing.Position.z; } // Check if below floor if (!nointeraction) { double minz = sd.Floor.plane.GetZ(Thing.Position); if (pos.z < minz) { pos.z = Math.Min(minz, maxz); } } } } else { // Stand on floor if (Thing.Sector != null) { SectorData sd = mode.GetSectorData(Thing.Sector); double minz = sd.Floor.plane.GetZ(Thing.Position); pos.z = minz; if (Thing.Position.z > 0 || nointeraction) { pos.z += Thing.Position.z; } // Check if above ceiling if (!nointeraction) { double maxz = sd.Ceiling.plane.GetZ(Thing.Position) - info.Height; if (pos.z > maxz) { pos.z = Math.Max(minz, maxz); } } } } // Apply settings SetPosition(pos); SetCageColor(Thing.Color); // Keep info for object picking cageradius2 = thingradius * Angle2D.SQRT2; cageradius2 = cageradius2 * cageradius2; pos2d = pos; if (sizeless) //mxd { boxp1 = new Vector3D(pos.x - thingradius, pos.y - thingradius, pos.z - thingradius / 2); boxp2 = new Vector3D(pos.x + thingradius, pos.y + thingradius, pos.z + thingradius / 2); } else { boxp1 = new Vector3D(pos.x - thingradius, pos.y - thingradius, pos.z); boxp2 = new Vector3D(pos.x + thingradius, pos.y + thingradius, pos.z + thingheight); } // Done changed = false; return(true); }
public DirectionalShadingForm(IEnumerable <Sector> selectedsectors, IEnumerable <Sidedef> selectedsides, IEnumerable <VisualSector> selectedvisualsectors) { InitializeComponent(); // Store sectors, collect floor normals visualsectors = selectedvisualsectors; sectors = new Dictionary <Sector, Vector3D>(); sectorbrightness = new Dictionary <Sector, int>(); sectorcolors = new Dictionary <Sector, int>(); foreach (Sector s in selectedsectors) { sectors.Add(s, Sector.GetFloorPlane(s).Normal); sectorcolors[s] = UniFields.GetInteger(s.Fields, "lightcolor", PixelColor.INT_WHITE_NO_ALPHA); // Store initial brightness if (s.Fields.GetValue("lightfloorabsolute", false)) { sectorbrightness[s] = UniFields.GetInteger(s.Fields, "lightfloor"); } else { sectorbrightness[s] = s.Brightness; } } // Store sidedefs, collect side normals sides = new Dictionary <Sidedef, Vector3D>(); sidebrightness = new Dictionary <Sidedef, int>(); foreach (Sidedef sd in selectedsides) { Vector3D normal = Vector3D.FromAngleXY(sd.Line.Angle + Angle2D.PIHALF); if (sd == sd.Line.Front) { normal *= -1; } sides.Add(sd, normal); // Store initial brightness if (sd.Fields.GetValue("lightabsolute", false)) { sidebrightness[sd] = UniFields.GetInteger(sd.Fields, "light"); } else { sidebrightness[sd] = sd.Sector.Brightness; } } // Create undo string sectorscount = (sectors.Count > 0 ? (sectors.Count > 1 ? " sectors" : " sector") : ""); string sidescount = (!string.IsNullOrEmpty(sectorscount) ? " and " : ""); sidescount += (sides.Count > 0 ? (sides.Count > 1 ? " sidedefs" : " sidedef") : ""); General.Map.UndoRedo.ClearAllRedos(); General.Map.UndoRedo.CreateUndo("Apply directional shading to " + sectorscount + sidescount); // Prepare your fields! foreach (Sector s in sectors.Keys) { s.Fields.BeforeFieldsChange(); } foreach (Sidedef sd in sides.Keys) { sd.Fields.BeforeFieldsChange(); } // Load settings blockupdate = true; int angle = General.Settings.ReadPluginSetting("directionalshading.sunangle", 45); sunangle.Angle = angle; sunangletb.Text = angle.ToString(); lightamount.Value = General.Settings.ReadPluginSetting("directionalshading.lightamount", 64); lightcolor.Color = PixelColor.FromInt(General.Settings.ReadPluginSetting("directionalshading.lightcolor", 0xFDEBD7)); shadeamount.Value = General.Settings.ReadPluginSetting("directionalshading.shadeamount", 16); shadecolor.Color = PixelColor.FromInt(General.Settings.ReadPluginSetting("directionalshading.shadecolor", 0xABC8EB)); blockupdate = false; OnSunAngleChanged(); }