// This makes sure we are updated with the source linedef information
        public override void Update()
        {
            SectorData sd = data.Mode.GetSectorData(linedef.Front.Sector);

            if (!sd.Updated)
            {
                sd.Update();
            }
            sd.AddUpdateSector(data.Sector, false);

            // Transfer ceiling brightness, keep sector color
            PixelColor lightcolor = PixelColor.FromInt(data.Sector.Fields.GetValue("lightcolor", -1));
            PixelColor brightness = PixelColor.FromInt(General.Map.Renderer3D.CalculateBrightness(sd.Sector.Brightness));

            data.Ceiling.color = PixelColor.Modulate(lightcolor, brightness).WithAlpha(255).ToInt();
        }
        // This makes sure we are updated with the source linedef information
        public override void Update()
        {
            //mxd. Skip if arg0 is 0.
            if (thing.Args[0] == 0)
            {
                return;
            }

            ThingData td = data.Mode.GetThingData(thing);
            Thing     t  = thing;
            Linedef   ld = sidedef.Line;

            if (ld != null)
            {
                if (t.Type == 9500)
                {
                    SectorData sd = data.Mode.GetSectorData(sidedef.Sector);
                    Vector3D   v1 = new Vector3D(ld.Start.Position.x, ld.Start.Position.y, sd.Floor.plane.GetZ(ld.Start.Position));
                    Vector3D   v2 = new Vector3D(ld.End.Position.x, ld.End.Position.y, sd.Floor.plane.GetZ(ld.End.Position));
                    Vector3D   v3 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + sd.Floor.plane.GetZ(t.Position));
                    sd.AddUpdateSector(data.Sector, true);
                    if (!sd.Updated)
                    {
                        sd.Update();
                    }
                    td.AddUpdateSector(sidedef.Sector, true);
                    sd.Floor.plane = new Plane(v1, v2, v3, true);
                }
                else if (t.Type == 9501)
                {
                    SectorData sd = data.Mode.GetSectorData(sidedef.Sector);
                    Vector3D   v1 = new Vector3D(ld.Start.Position.x, ld.Start.Position.y, sd.Ceiling.plane.GetZ(ld.Start.Position));
                    Vector3D   v2 = new Vector3D(ld.End.Position.x, ld.End.Position.y, sd.Ceiling.plane.GetZ(ld.End.Position));
                    Vector3D   v3 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + sd.Ceiling.plane.GetZ(t.Position));
                    sd.AddUpdateSector(data.Sector, true);
                    if (!sd.Updated)
                    {
                        sd.Update();
                    }
                    td.AddUpdateSector(sidedef.Sector, true);
                    sd.Ceiling.plane = new Plane(v1, v2, v3, false);
                }
            }
        }
        // This makes sure we are updated with the source linedef information
        public override void Update()
        {
            SectorData sd = data.Mode.GetSectorData(linedef.Front.Sector);

            if (!sd.Updated)
            {
                sd.Update();
            }
            sd.AddUpdateSector(data.Sector, false);

            // Create top level?
            if (toplevel == null)
            {
                toplevel = new SectorLevel(sd.Ceiling);
                data.AddSectorLevel(toplevel);
            }

            // Update top level
            sd.Ceiling.CopyProperties(toplevel);
            toplevel.lighttype = (LightLevelType)General.Clamp(linedef.Args[1], 0, 2);             //mxd
            toplevel.type      = SectorLevelType.Light;

            //mxd. Create bottom level?
            if (toplevel.lighttype == LightLevelType.TYPE1)
            {
                // Create bottom level? Skip this step if there's a different light level between toplevel and bottomlevel
                if (bottomlevel == null)
                {
                    bottomlevel = new SectorLevel(data.Ceiling);
                    data.AddSectorLevel(bottomlevel);
                }

                // Update bottom level
                data.Ceiling.CopyProperties(bottomlevel);
                bottomlevel.type      = SectorLevelType.Light;
                bottomlevel.lighttype = LightLevelType.TYPE1_BOTTOM;
                bottomlevel.plane     = sd.Floor.plane.GetInverted();
            }
        }
Exemple #4
0
        // This makes sure we are updated with the source linedef information
        public override void Update()
        {
            // Find tagged sector
            Sector sourcesector = null;

            foreach (Sector s in General.Map.Map.Sectors)
            {
                if (s.Tags.Contains(thing.Args[0]))
                {
                    sourcesector = s;
                    break;
                }
            }

            if (sourcesector != null)
            {
                SectorData sourcesectordata = data.Mode.GetSectorData(sourcesector);
                if (!sourcesectordata.Updated)
                {
                    sourcesectordata.Update();
                }

                switch (thing.Type)
                {
                case 9510:
                    data.Floor.plane = sourcesectordata.Floor.plane;
                    break;

                case 9511:
                    data.Ceiling.plane = sourcesectordata.Ceiling.plane;
                    break;
                }

                sourcesectordata.AddUpdateSector(data.Sector, true);
            }
        }
        // This builds the geometry. Returns false when no geometry created.
        public override bool Setup()
        {
            //mxd
            if (Sidedef.LongMiddleTexture == MapSet.EmptyLongName)
            {
                base.SetVertices(null);
                return(false);
            }

            Vector2D vl, vr;

            //mxd. lightfog flag support
            int  lightvalue;
            bool lightabsolute;

            GetLightValue(out lightvalue, out lightabsolute);

            Vector2D tscale = new Vector2D(Sidedef.Fields.GetValue("scalex_mid", 1.0f),
                                           Sidedef.Fields.GetValue("scaley_mid", 1.0f));
            Vector2D tscaleAbs = new Vector2D(Math.Abs(tscale.x), Math.Abs(tscale.y));
            Vector2D toffset   = new Vector2D(Sidedef.Fields.GetValue("offsetx_mid", 0.0f),
                                              Sidedef.Fields.GetValue("offsety_mid", 0.0f));

            // Left and right vertices for this sidedef
            if (Sidedef.IsFront)
            {
                vl = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y);
                vr = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y);
            }
            else
            {
                vl = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y);
                vr = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y);
            }

            // Load sector data
            SectorData sd  = mode.GetSectorData(Sidedef.Sector);
            SectorData osd = mode.GetSectorData(Sidedef.Other.Sector);

            if (!osd.Updated)
            {
                osd.Update();
            }

            // Load texture
            if (Sidedef.LongMiddleTexture != MapSet.EmptyLongName)
            {
                base.Texture = General.Map.Data.GetTextureImage(Sidedef.LongMiddleTexture);
                if (base.Texture == null || base.Texture is UnknownImage)
                {
                    base.Texture         = General.Map.Data.UnknownTexture3D;
                    setuponloadedtexture = Sidedef.LongMiddleTexture;
                }
                else if (!base.Texture.IsImageLoaded)
                {
                    setuponloadedtexture = Sidedef.LongMiddleTexture;
                }
            }
            else
            {
                // Use missing texture
                base.Texture         = General.Map.Data.MissingTexture3D;
                setuponloadedtexture = 0;
            }

            // Get texture scaled size
            Vector2D tsz = new Vector2D(base.Texture.ScaledWidth, base.Texture.ScaledHeight);

            tsz = tsz / tscale;

            // Get texture offsets
            Vector2D tof = new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);

            tof = tof + toffset;
            tof = tof / tscaleAbs;
            if (General.Map.Config.ScaledTextureOffsets && !base.Texture.WorldPanning)
            {
                tof = tof * base.Texture.Scale;
            }

            // Determine texture coordinates plane as they would be in normal circumstances.
            // We can then use this plane to find any texture coordinate we need.
            // The logic here is the same as in the original VisualMiddleSingle (except that
            // the values are stored in a TexturePlane)
            // NOTE: I use a small bias for the floor height, because if the difference in
            // height is 0 then the TexturePlane doesn't work!
            TexturePlane tp        = new TexturePlane();
            float        floorbias = (Sidedef.Sector.CeilHeight == Sidedef.Sector.FloorHeight) ? 1.0f : 0.0f;
            float        geotop    = Math.Min(Sidedef.Sector.CeilHeight, Sidedef.Other.Sector.CeilHeight);
            float        geobottom = Math.Max(Sidedef.Sector.FloorHeight, Sidedef.Other.Sector.FloorHeight);
            float        zoffset   = Sidedef.Sector.CeilHeight - Sidedef.Other.Sector.CeilHeight;    //mxd

            // When lower unpegged is set, the middle texture is bound to the bottom
            if (Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
            {
                tp.tlt.y = tsz.y - (geotop - geobottom);
            }

            if (zoffset > 0)
            {
                tp.tlt.y -= zoffset;                                      //mxd
            }
            tp.trb.x = tp.tlt.x + (float)Math.Round(Sidedef.Line.Length); //mxd. (G)ZDoom snaps texture coordinates to integral linedef length
            tp.trb.y = tp.tlt.y + (Sidedef.Sector.CeilHeight - (Sidedef.Sector.FloorHeight + floorbias));

            // Apply texture offset
            tp.tlt += tof;
            tp.trb += tof;

            // Transform pixel coordinates to texture coordinates
            tp.tlt /= tsz;
            tp.trb /= tsz;

            // Left top and right bottom of the geometry that
            tp.vlt = new Vector3D(vl.x, vl.y, Sidedef.Sector.CeilHeight);
            tp.vrb = new Vector3D(vr.x, vr.y, Sidedef.Sector.FloorHeight + floorbias);

            // Make the right-top coordinates
            tp.trt = new Vector2D(tp.trb.x, tp.tlt.y);
            tp.vrt = new Vector3D(tp.vrb.x, tp.vrb.y, tp.vlt.z);

            // Keep top and bottom planes for intersection testing
            top    = sd.Ceiling.plane;
            bottom = sd.Floor.plane;

            // Create initial polygon, which is just a quad between floor and ceiling
            WallPolygon poly = new WallPolygon();

            poly.Add(new Vector3D(vl.x, vl.y, sd.Floor.plane.GetZ(vl)));
            poly.Add(new Vector3D(vl.x, vl.y, sd.Ceiling.plane.GetZ(vl)));
            poly.Add(new Vector3D(vr.x, vr.y, sd.Ceiling.plane.GetZ(vr)));
            poly.Add(new Vector3D(vr.x, vr.y, sd.Floor.plane.GetZ(vr)));

            // Determine initial color
            int lightlevel = lightabsolute ? lightvalue : sd.Ceiling.brightnessbelow + lightvalue;

            //mxd. This calculates light with doom-style wall shading
            PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightlevel, Sidedef));
            PixelColor wallcolor      = PixelColor.Modulate(sd.Ceiling.colorbelow, wallbrightness);

            fogfactor  = CalculateFogFactor(lightlevel);
            poly.color = wallcolor.WithAlpha(255).ToInt();

            // Cut off the part below the other floor and above the other ceiling
            CropPoly(ref poly, osd.Ceiling.plane, true);
            CropPoly(ref poly, osd.Floor.plane, true);

            // Determine if we should repeat the middle texture
            repeatmidtex = Sidedef.IsFlagSet("wrapmidtex") || Sidedef.Line.IsFlagSet("wrapmidtex");             //mxd
            if (!repeatmidtex)
            {
                // First determine the visible portion of the texture
                float textop;

                // Determine top portion height
                if (Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
                {
                    textop = geobottom + tof.y + Math.Abs(tsz.y);
                }
                else
                {
                    textop = geotop + tof.y;
                }

                // Calculate bottom portion height
                float texbottom = textop - Math.Abs(tsz.y);

                // Create crop planes (we also need these for intersection testing)
                topclipplane    = new Plane(new Vector3D(0, 0, -1), textop);
                bottomclipplane = new Plane(new Vector3D(0, 0, 1), -texbottom);

                // Crop polygon by these heights
                CropPoly(ref poly, topclipplane, true);
                CropPoly(ref poly, bottomclipplane, true);
            }

            //mxd. In(G)ZDoom, middle sidedef parts are not clipped by extrafloors of any type...
            List <WallPolygon> polygons = new List <WallPolygon> {
                poly
            };

            //ClipExtraFloors(polygons, sd.ExtraFloors, true); //mxd
            //ClipExtraFloors(polygons, osd.ExtraFloors, true); //mxd

            //if(polygons.Count > 0)
            //{
            // Keep top and bottom planes for intersection testing
            top    = osd.Ceiling.plane;
            bottom = osd.Floor.plane;

            // Process the polygon and create vertices
            List <WorldVertex> verts = CreatePolygonVertices(polygons, tp, sd, lightvalue, lightabsolute);

            if (verts.Count > 2)
            {
                // Apply alpha to vertices
                byte alpha = SetLinedefRenderstyle(true);
                if (alpha < 255)
                {
                    for (int i = 0; i < verts.Count; i++)
                    {
                        WorldVertex v = verts[i];
                        v.c      = PixelColor.FromInt(v.c).WithAlpha(alpha).ToInt();
                        verts[i] = v;
                    }
                }

                base.SetVertices(verts);
                return(true);
            }
            //}

            base.SetVertices(null);             //mxd
            return(false);
        }
        // This builds the geometry. Returns false when no geometry created.
        public override bool Setup()
        {
            if (!IsFogBoundary())
            {
                return(false);
            }

            //mxd. lightfog flag support
            int  lightvalue;
            bool lightabsolute;

            GetLightValue(out lightvalue, out lightabsolute);

            // Left and right vertices for this sidedef
            Vector2D vl, vr;

            if (Sidedef.IsFront)
            {
                vl = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y);
                vr = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y);
            }
            else
            {
                vl = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y);
                vr = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y);
            }

            // Load sector data
            SectorData sd  = mode.GetSectorData(Sidedef.Sector);
            SectorData osd = mode.GetSectorData(Sidedef.Other.Sector);

            if (!osd.Updated)
            {
                osd.Update();
            }

            // Set texture
            base.Texture = General.Map.Data.BlackTexture;

            // Determine texture coordinates plane as they would be in normal circumstances.
            TexturePlane tp        = new TexturePlane();
            float        floorbias = (Sidedef.Sector.CeilHeight == Sidedef.Sector.FloorHeight) ? 1.0f : 0.0f;
            float        zoffset   = Sidedef.Sector.CeilHeight - Sidedef.Other.Sector.CeilHeight;    //mxd

            if (zoffset > 0)
            {
                tp.tlt.y -= zoffset;                         //mxd
            }
            tp.trb.x = tp.tlt.x + Sidedef.Line.Length;
            tp.trb.y = tp.tlt.y + (Sidedef.Sector.CeilHeight - (Sidedef.Sector.FloorHeight + floorbias));

            // Left top and right bottom of the geometry that
            tp.vlt = new Vector3D(vl.x, vl.y, Sidedef.Sector.CeilHeight);
            tp.vrb = new Vector3D(vr.x, vr.y, Sidedef.Sector.FloorHeight + floorbias);

            // Make the right-top coordinates
            tp.trt = new Vector2D(tp.trb.x, tp.tlt.y);
            tp.vrt = new Vector3D(tp.vrb.x, tp.vrb.y, tp.vlt.z);

            // Keep top and bottom planes for intersection testing
            top    = sd.Ceiling.plane;
            bottom = sd.Floor.plane;

            // Create initial polygon, which is just a quad between floor and ceiling
            WallPolygon poly = new WallPolygon();

            poly.Add(new Vector3D(vl.x, vl.y, sd.Floor.plane.GetZ(vl)));
            poly.Add(new Vector3D(vl.x, vl.y, sd.Ceiling.plane.GetZ(vl)));
            poly.Add(new Vector3D(vr.x, vr.y, sd.Ceiling.plane.GetZ(vr)));
            poly.Add(new Vector3D(vr.x, vr.y, sd.Floor.plane.GetZ(vr)));

            // Determine initial color
            int lightlevel = sd.Ceiling.brightnessbelow + lightvalue;

            // Calculate fog density
            fogfactor  = CalculateFogFactor(lightlevel);
            poly.color = PixelColor.INT_WHITE;

            // Cut off the part below the other floor and above the other ceiling
            CropPoly(ref poly, osd.Ceiling.plane, true);
            CropPoly(ref poly, osd.Floor.plane, true);

            List <WallPolygon> polygons = new List <WallPolygon> {
                poly
            };

            // Keep top and bottom planes for intersection testing
            top    = osd.Ceiling.plane;
            bottom = osd.Floor.plane;

            // Process the polygon and create vertices
            List <WorldVertex> verts = CreatePolygonVertices(polygons, tp, sd, lightvalue, lightabsolute);

            if (verts.Count > 2)
            {
                base.SetVertices(verts);
                return(true);
            }

            base.SetVertices(null);
            return(false);
        }
        // This builds the geometry. Returns false when no geometry created.
        public override bool Setup()
        {
            Vector2D vl, vr;

            // Left and right vertices for this sidedef
            if (Sidedef.IsFront)
            {
                vl = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y);
                vr = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y);
            }
            else
            {
                vl = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y);
                vr = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y);
            }

            // Load sector data
            SectorData sd  = Sector.GetSectorData();
            SectorData osd = mode.GetSectorData(Sidedef.Other.Sector);

            if (!osd.Updated)
            {
                osd.Update();
            }

            //mxd
            float vlzc = sd.Ceiling.plane.GetZ(vl);
            float vrzc = sd.Ceiling.plane.GetZ(vr);

            //mxd. Side is visible when our sector's ceiling is higher than the other's at any vertex
            if (!(vlzc > osd.Ceiling.plane.GetZ(vl) || vrzc > osd.Ceiling.plane.GetZ(vr)))
            {
                base.SetVertices(null);
                return(false);
            }

            //mxd. Apply sky hack?
            UpdateSkyRenderFlag();

            //mxd. lightfog flag support
            int  lightvalue;
            bool lightabsolute;

            GetLightValue(out lightvalue, out lightabsolute);

            Vector2D tscale = new Vector2D(Sidedef.Fields.GetValue("scalex_top", 1.0f),
                                           Sidedef.Fields.GetValue("scaley_top", 1.0f));
            Vector2D tscaleAbs = new Vector2D(Math.Abs(tscale.x), Math.Abs(tscale.y));
            Vector2D toffset   = new Vector2D(Sidedef.Fields.GetValue("offsetx_top", 0.0f),
                                              Sidedef.Fields.GetValue("offsety_top", 0.0f));

            // Texture given?
            if ((Sidedef.LongHighTexture != MapSet.EmptyLongName))
            {
                // Load texture
                base.Texture = General.Map.Data.GetTextureImage(Sidedef.LongHighTexture);
                if (base.Texture == null || base.Texture is UnknownImage)
                {
                    base.Texture         = General.Map.Data.UnknownTexture3D;
                    setuponloadedtexture = Sidedef.LongHighTexture;
                }
                else if (!base.Texture.IsImageLoaded)
                {
                    setuponloadedtexture = Sidedef.LongHighTexture;
                }
            }
            else
            {
                // Use missing texture
                base.Texture         = General.Map.Data.MissingTexture3D;
                setuponloadedtexture = 0;
            }

            // Get texture scaled size
            Vector2D tsz = new Vector2D(base.Texture.ScaledWidth, base.Texture.ScaledHeight);

            tsz = tsz / tscale;

            // Get texture offsets
            Vector2D tof = new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);

            tof = tof + toffset;

            // biwa. Also take the ForceWorldPanning MAPINFO entry into account
            if (General.Map.Config.ScaledTextureOffsets && (!base.Texture.WorldPanning && !General.Map.Data.MapInfo.ForceWorldPanning))
            {
                tof = tof / tscaleAbs;
                tof = tof * base.Texture.Scale;
            }

            // Determine texture coordinates plane as they would be in normal circumstances.
            // We can then use this plane to find any texture coordinate we need.
            // The logic here is the same as in the original VisualMiddleSingle (except that
            // the values are stored in a TexturePlane)
            // NOTE: I use a small bias for the floor height, because if the difference in
            // height is 0 then the TexturePlane doesn't work!
            TexturePlane tp       = new TexturePlane();
            float        ceilbias = (Sidedef.Other.Sector.CeilHeight == Sidedef.Sector.CeilHeight) ? 1.0f : 0.0f;

            if (!Sidedef.Line.IsFlagSet(General.Map.Config.UpperUnpeggedFlag))
            {
                // When lower unpegged is set, the lower texture is bound to the bottom
                tp.tlt.y = tsz.y - ((float)Sidedef.Sector.CeilHeight - Sidedef.Other.Sector.CeilHeight);
            }
            tp.trb.x = tp.tlt.x + (float)Math.Round(Sidedef.Line.Length);             //mxd. (G)ZDoom snaps texture coordinates to integral linedef length
            tp.trb.y = tp.tlt.y + (Sidedef.Sector.CeilHeight - (Sidedef.Other.Sector.CeilHeight + ceilbias));

            // Apply texture offset
            tp.tlt += tof;
            tp.trb += tof;

            // Transform pixel coordinates to texture coordinates
            tp.tlt /= tsz;
            tp.trb /= tsz;

            // Left top and right bottom of the geometry that
            tp.vlt = new Vector3D(vl.x, vl.y, Sidedef.Sector.CeilHeight);
            tp.vrb = new Vector3D(vr.x, vr.y, Sidedef.Other.Sector.CeilHeight + ceilbias);

            // Make the right-top coordinates
            tp.trt = new Vector2D(tp.trb.x, tp.tlt.y);
            tp.vrt = new Vector3D(tp.vrb.x, tp.vrb.y, tp.vlt.z);

            // Create initial polygon, which is just a quad between floor and ceiling
            WallPolygon poly = new WallPolygon();

            poly.Add(new Vector3D(vl.x, vl.y, sd.Floor.plane.GetZ(vl)));
            poly.Add(new Vector3D(vl.x, vl.y, vlzc));
            poly.Add(new Vector3D(vr.x, vr.y, vrzc));
            poly.Add(new Vector3D(vr.x, vr.y, sd.Floor.plane.GetZ(vr)));

            // Determine initial color
            int lightlevel = lightabsolute ? lightvalue : sd.Ceiling.brightnessbelow + lightvalue;

            //mxd. This calculates light with doom-style wall shading
            PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightlevel, Sidedef));
            PixelColor wallcolor      = PixelColor.Modulate(sd.Ceiling.colorbelow, wallbrightness);

            fogfactor  = CalculateFogFactor(lightlevel);
            poly.color = wallcolor.WithAlpha(255).ToInt();

            // Cut off the part below the other ceiling
            CropPoly(ref poly, osd.Ceiling.plane, false);

            // Cut out pieces that overlap 3D floors in this sector
            List <WallPolygon> polygons = new List <WallPolygon> {
                poly
            };

            ClipExtraFloors(polygons, sd.ExtraFloors, false);             //mxd

            if (polygons.Count > 0)
            {
                // Keep top and bottom planes for intersection testing
                Vector2D linecenter = Sidedef.Line.GetCenterPoint();                 //mxd. Our sector's floor can be higher than the other sector's ceiling!
                top    = sd.Ceiling.plane;
                bottom = (osd.Ceiling.plane.GetZ(linecenter) > sd.Floor.plane.GetZ(linecenter) ? osd.Ceiling.plane : sd.Floor.plane);

                // Process the polygon and create vertices
                List <WorldVertex> verts = CreatePolygonVertices(polygons, tp, sd, lightvalue, lightabsolute);
                if (verts.Count > 2)
                {
                    base.SetVertices(verts);
                    return(true);
                }
            }

            base.SetVertices(null);             //mxd
            return(false);
        }
Exemple #8
0
        // This makes sure we are updated with the source linedef information
        public override void Update()
        {
            ThingData td = data.Mode.GetThingData(thing);
            Thing     t  = thing;

            // Floor slope thing
            if (t.Type == 9502)
            {
                t.DetermineSector(data.Mode.BlockMap);
                if (t.Sector != null)
                {
                    //mxd. Vertex zheight overrides this effect
                    if (General.Map.UDMF && t.Sector.Sidedefs.Count == 3)
                    {
                        foreach (Sidedef side in t.Sector.Sidedefs)
                        {
                            if (!double.IsNaN(side.Line.Start.ZFloor) || !double.IsNaN(side.Line.End.ZFloor))
                            {
                                return;
                            }
                        }
                    }

                    double   angle         = Angle2D.DoomToReal((int)Angle2D.RadToDeg(t.Angle));
                    double   vangle        = Angle2D.DegToRad(General.Clamp(t.Args[0], 0, 180));            //mxd. Don't underestimate user stupidity (or curiosity)!
                    Vector2D point         = new Vector2D(t.Position.x + Math.Cos(angle) * Math.Sin(vangle), t.Position.y + Math.Sin(angle) * Math.Sin(vangle));
                    Vector2D perpendicular = new Line2D(t.Position, point).GetPerpendicular();

                    Vector3D v1 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + t.Sector.FloorHeight);

                    Vector3D v2 = new Vector3D(
                        point.x + perpendicular.x,
                        point.y + perpendicular.y,
                        t.Position.z + t.Sector.FloorHeight + Math.Cos(vangle)
                        );

                    Vector3D v3 = new Vector3D(
                        point.x - perpendicular.x,
                        point.y - perpendicular.y,
                        t.Position.z + t.Sector.FloorHeight + Math.Cos(vangle)
                        );

                    SectorData sd = data.Mode.GetSectorData(t.Sector);
                    sd.AddUpdateSector(data.Sector, true);
                    if (!sd.Updated)
                    {
                        sd.Update();
                    }
                    td.AddUpdateSector(t.Sector, true);
                    sd.Floor.plane = new Plane(v1, v2, v3, true);
                }
            }
            // Ceiling slope thing
            else if (t.Type == 9503)
            {
                t.DetermineSector(data.Mode.BlockMap);
                if (t.Sector != null)
                {
                    //mxd. Vertex zheight overrides this effect
                    if (General.Map.UDMF && t.Sector.Sidedefs.Count == 3)
                    {
                        foreach (Sidedef side in t.Sector.Sidedefs)
                        {
                            if (!double.IsNaN(side.Line.Start.ZCeiling) || !double.IsNaN(side.Line.End.ZCeiling))
                            {
                                return;
                            }
                        }
                    }

                    double   angle         = Angle2D.DoomToReal((int)Angle2D.RadToDeg(t.Angle));
                    double   vangle        = Angle2D.DegToRad(General.Clamp(t.Args[0], 0, 180));            //mxd. Don't underestimate user stupidity (or curiosity)!
                    Vector2D point         = new Vector2D(t.Position.x + Math.Cos(angle) * Math.Sin(vangle), t.Position.y + Math.Sin(angle) * Math.Sin(vangle));
                    Vector2D perpendicular = new Line2D(t.Position, point).GetPerpendicular();

                    Vector3D v1 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + t.Sector.CeilHeight);

                    Vector3D v2 = new Vector3D(
                        point.x + perpendicular.x,
                        point.y + perpendicular.y,
                        t.Position.z + t.Sector.CeilHeight + Math.Cos(vangle)
                        );

                    Vector3D v3 = new Vector3D(
                        point.x - perpendicular.x,
                        point.y - perpendicular.y,
                        t.Position.z + t.Sector.CeilHeight + Math.Cos(vangle)
                        );

                    SectorData sd = data.Mode.GetSectorData(t.Sector);
                    sd.AddUpdateSector(data.Sector, true);
                    if (!sd.Updated)
                    {
                        sd.Update();
                    }
                    td.AddUpdateSector(t.Sector, true);
                    sd.Ceiling.plane = new Plane(v1, v2, v3, false);
                }
            }
        }
Exemple #9
0
        // This makes sure we are updated with the source linedef information
        public override void Update()
        {
            Sector     sourcesector     = null;
            SectorData sourcesectordata = null;
            bool       updatesides      = false;

            // Copy slopes from tagged sectors
            //check which arguments we must use
            int floorArg   = (front ? 0 : 2);
            int ceilingArg = (front ? 1 : 3);

            //find sector to align floor to
            if (linedef.Args[floorArg] > 0)
            {
                foreach (Sector s in General.Map.Map.Sectors)
                {
                    if (s.Tags.Contains(linedef.Args[floorArg]))
                    {
                        sourcesector = s;
                        break;
                    }
                }

                if (sourcesector != null)
                {
                    sourcesectordata = data.Mode.GetSectorData(sourcesector);
                    if (!sourcesectordata.Updated)
                    {
                        sourcesectordata.Update();
                    }

                    data.Floor.plane = sourcesectordata.Floor.plane;
                    sourcesectordata.AddUpdateSector(data.Sector, true);

                    updatesides = true;
                }
            }

            if (linedef.Args[ceilingArg] > 0)
            {
                //find sector to align ceiling to
                if (linedef.Args[ceilingArg] != linedef.Args[floorArg])
                {
                    sourcesector = null;

                    foreach (Sector s in General.Map.Map.Sectors)
                    {
                        if (s.Tags.Contains(linedef.Args[ceilingArg]))
                        {
                            sourcesector = s;
                            break;
                        }
                    }

                    if (sourcesector != null)
                    {
                        sourcesectordata = data.Mode.GetSectorData(sourcesector);
                        if (!sourcesectordata.Updated)
                        {
                            sourcesectordata.Update();
                        }

                        data.Ceiling.plane = sourcesectordata.Ceiling.plane;
                        sourcesectordata.AddUpdateSector(data.Sector, true);

                        updatesides = true;
                    }
                }
                else if (sourcesector != null)                //ceiling uses the same sector as floor
                {
                    data.Ceiling.plane = sourcesectordata.Ceiling.plane;
                }
            }

            //check the flags...
            bool copyFloor   = false;
            bool copyCeiling = false;

            if (linedef.Args[4] > 0 && linedef.Args[4] != 3 && linedef.Args[4] != 12)
            {
                if (front)
                {
                    copyFloor   = (linedef.Args[4] & 2) == 2;
                    copyCeiling = (linedef.Args[4] & 8) == 8;
                }
                else
                {
                    copyFloor   = (linedef.Args[4] & 1) == 1;
                    copyCeiling = (linedef.Args[4] & 4) == 4;
                }
            }

            // Copy slope across the line
            if ((copyFloor || copyCeiling) && linedef.Front != null && linedef.Back != null)
            {
                // Get appropriate source sector data
                sourcesectordata = data.Mode.GetSectorData(front ? linedef.Back.Sector : linedef.Front.Sector);
                if (!sourcesectordata.Updated)
                {
                    sourcesectordata.Update();
                }

                //copy floor slope?
                if (copyFloor)
                {
                    data.Floor.plane = sourcesectordata.Floor.plane;
                    sourcesectordata.AddUpdateSector(data.Sector, true);
                }

                //copy ceiling slope?
                if (copyCeiling)
                {
                    data.Ceiling.plane = sourcesectordata.Ceiling.plane;
                    sourcesectordata.AddUpdateSector(data.Sector, true);
                }

                updatesides = true;
            }

            // Update outer sidedef geometry
            if (updatesides)
            {
                UpdateSectorSides(data.Sector);

                // Update sectors with PlaneCopySlope Effect...
                List <SectorData> toupdate = new List <SectorData>();
                foreach (Sector s in data.UpdateAlso.Keys)
                {
                    SectorData osd = data.Mode.GetSectorDataEx(s);
                    if (osd == null)
                    {
                        continue;
                    }
                    foreach (SectorEffect e in osd.Effects)
                    {
                        if (e is EffectPlaneCopySlope)
                        {
                            toupdate.Add(osd);
                            break;
                        }
                    }
                }

                // Do it in 2 steps, because SectorData.Reset() may change SectorData.UpdateAlso collection...
                foreach (SectorData sd in toupdate)
                {
                    // Update PlaneCopySlope Effect...
                    sd.Reset(false);

                    // Update outer sides...
                    UpdateSectorSides(sd.Sector);
                }
            }
        }
Exemple #10
0
        // This makes sure we are updated with the source linedef information
        public override void Update()
        {
            //mxd. Skip if arg0 is 0.
            if (thing.Args[0] == 0)
            {
                return;
            }

            ThingData td = data.Mode.GetThingData(thing);
            Thing     t  = thing;

            // Find the tagged line
            Linedef ld = null;

            foreach (Linedef l in General.Map.Map.Linedefs)
            {
                if (l.Tags.Contains(t.Args[0]))
                {
                    ld = l;
                    break;
                }
            }

            if (ld != null)
            {
                if (t.Type == 9500)
                {
                    // Slope the floor from the linedef to thing
                    t.DetermineSector(data.Mode.BlockMap);
                    if (t.Sector != null)
                    {
                        Vector3D v3 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + t.Sector.FloorHeight);
                        if (ld.SideOfLine(t.Position) < 0.0f)
                        {
                            Vector3D   v1 = new Vector3D(ld.Start.Position.x, ld.Start.Position.y, ld.Front.Sector.FloorHeight);
                            Vector3D   v2 = new Vector3D(ld.End.Position.x, ld.End.Position.y, ld.Front.Sector.FloorHeight);
                            SectorData sd = data.Mode.GetSectorData(ld.Front.Sector);
                            sd.AddUpdateSector(data.Sector, true);
                            if (!sd.Updated)
                            {
                                sd.Update();
                            }
                            td.AddUpdateSector(ld.Front.Sector, true);
                            sd.Floor.plane = new Plane(v1, v2, v3, true);
                        }
                        else
                        {
                            Vector3D   v1 = new Vector3D(ld.Start.Position.x, ld.Start.Position.y, ld.Back.Sector.FloorHeight);
                            Vector3D   v2 = new Vector3D(ld.End.Position.x, ld.End.Position.y, ld.Back.Sector.FloorHeight);
                            SectorData sd = data.Mode.GetSectorData(ld.Back.Sector);
                            sd.AddUpdateSector(data.Sector, true);
                            if (!sd.Updated)
                            {
                                sd.Update();
                            }
                            td.AddUpdateSector(ld.Back.Sector, true);
                            sd.Floor.plane = new Plane(v2, v1, v3, true);
                        }
                    }
                }
                else if (t.Type == 9501)
                {
                    // Slope the ceiling from the linedef to thing
                    t.DetermineSector(data.Mode.BlockMap);
                    if (t.Sector != null)
                    {
                        td.AddUpdateSector(t.Sector, true);
                        Vector3D v3 = new Vector3D(t.Position.x, t.Position.y, t.Position.z + t.Sector.CeilHeight);
                        if (ld.SideOfLine(t.Position) < 0.0f)
                        {
                            Vector3D   v1 = new Vector3D(ld.Start.Position.x, ld.Start.Position.y, ld.Front.Sector.CeilHeight);
                            Vector3D   v2 = new Vector3D(ld.End.Position.x, ld.End.Position.y, ld.Front.Sector.CeilHeight);
                            SectorData sd = data.Mode.GetSectorData(ld.Front.Sector);
                            sd.AddUpdateSector(data.Sector, true);
                            td.AddUpdateSector(ld.Front.Sector, true);
                            if (!sd.Updated)
                            {
                                sd.Update();
                            }
                            sd.Ceiling.plane = new Plane(v1, v2, v3, false);
                        }
                        else
                        {
                            Vector3D   v1 = new Vector3D(ld.Start.Position.x, ld.Start.Position.y, ld.Back.Sector.CeilHeight);
                            Vector3D   v2 = new Vector3D(ld.End.Position.x, ld.End.Position.y, ld.Back.Sector.CeilHeight);
                            SectorData sd = data.Mode.GetSectorData(ld.Back.Sector);
                            sd.AddUpdateSector(data.Sector, true);
                            td.AddUpdateSector(ld.Back.Sector, true);
                            if (!sd.Updated)
                            {
                                sd.Update();
                            }
                            sd.Ceiling.plane = new Plane(v2, v1, v3, false);
                        }
                    }
                }
            }
        }
Exemple #11
0
        // This (re)builds the visual sector, calculating all geometry from scratch
        public void Rebuild()
        {
            // Forget old geometry
            base.ClearGeometry();

            // Get sector data
            SectorData data = GetSectorData();

            if (!data.Updated)
            {
                data.Update();
            }

            // Create floor
            floor = (floor ?? new VisualFloor(mode, this));
            if (floor.Setup(data.Floor, null))
            {
                AddGeometry(floor);
            }

            // Create ceiling
            ceiling = (ceiling ?? new VisualCeiling(mode, this));
            if (ceiling.Setup(data.Ceiling, null))
            {
                AddGeometry(ceiling);
            }

            // Create 3D floors
            for (int i = 0; i < data.ExtraFloors.Count; i++)
            {
                Effect3DFloor ef              = data.ExtraFloors[i];
                bool          floorRequired   = ef.VavoomType;      //mxd
                bool          ceilingRequired = ef.VavoomType;      //mxd

                if (ef.VavoomType || !ef.IgnoreBottomHeight)
                {
                    //mxd. check if 3d floor is between real floor and ceiling
                    if (!ef.VavoomType)
                    {
                        if (ef.Ceiling.plane.GetInverted().Normal != floor.Level.plane.Normal ||
                            ef.Ceiling.plane.Normal != ceiling.Level.plane.Normal)
                        {
                            //mxd. check if at least one vertex of 3d floor is between floor and ceiling
                            floorRequired = Check3dFloorPlane(floor.Vertices, ceiling.Vertices, ef.Ceiling.plane);
                        }
                        //if floor, ceiling and 3d floor are not sloped, compare offsets
                        else if (-floor.Level.plane.Offset < ef.Ceiling.plane.Offset &&
                                 ceiling.Level.plane.Offset > ef.Ceiling.plane.Offset)
                        {
                            floorRequired = true;
                        }
                    }

                    //mxd. Create a floor
                    if (floorRequired && ef.Ceiling.sector.IsDisposed == false)
                    {
                        VisualFloor vf = (i < extrafloors.Count) ? extrafloors[i] : new VisualFloor(mode, this);
                        if (vf.Setup(ef.Ceiling, ef))
                        {
                            base.AddGeometry(vf);

                            //mxd. add backside as well
                            if (!ef.VavoomType && ef.RenderInside)
                            {
                                VisualFloor vfb = (i < extrabackfloors.Count) ? extrabackfloors[i] : new VisualFloor(mode, this);
                                if (vfb.Setup(ef.Ceiling, ef, true))
                                {
                                    base.AddGeometry(vfb);
                                }
                                if (i >= extrabackfloors.Count)
                                {
                                    extrabackfloors.Add(vfb);
                                }
                            }
                        }
                        if (i >= extrafloors.Count)
                        {
                            extrafloors.Add(vf);
                        }
                    }
                }

                //mxd. check if 3d ceiling is between real floor and ceiling
                if (!ef.VavoomType)
                {
                    if (ef.Floor.plane.GetInverted().Normal != ceiling.Level.plane.Normal ||
                        ef.Floor.plane.Normal != floor.Level.plane.Normal)
                    {
                        //mxd. check if at least one vertex of 3d ceiling is between floor and ceiling
                        ceilingRequired = Check3dFloorPlane(floor.Vertices, ceiling.Vertices, ef.Floor.plane);
                    }
                    //if floor, ceiling and 3d ceiling are not sloped, compare offsets
                    else if (ceiling.Level.plane.Offset > -ef.Floor.plane.Offset &&
                             floor.Level.plane.Offset > ef.Floor.plane.Offset)
                    {
                        ceilingRequired = true;
                    }
                }

                //mxd. Create a ceiling
                if (ceilingRequired && ef.Floor.sector.IsDisposed == false)
                {
                    VisualCeiling vc = (i < extraceilings.Count) ? extraceilings[i] : new VisualCeiling(mode, this);
                    if (vc.Setup(ef.Floor, ef))
                    {
                        base.AddGeometry(vc);

                        //mxd. add backside as well
                        if (!ef.VavoomType && (ef.RenderInside || ef.IgnoreBottomHeight))
                        {
                            VisualCeiling vcb = (i < extrabackceilings.Count) ? extrabackceilings[i] : new VisualCeiling(mode, this);
                            if (vcb.Setup(ef.Floor, ef, true))
                            {
                                base.AddGeometry(vcb);
                            }
                            if (i >= extrabackceilings.Count)
                            {
                                extrabackceilings.Add(vcb);
                            }
                        }
                    }
                    if (i >= extraceilings.Count)
                    {
                        extraceilings.Add(vc);
                    }
                }
            }

            // Go for all sidedefs
            Dictionary <Sidedef, VisualSidedefParts> oldsides = sides ?? new Dictionary <Sidedef, VisualSidedefParts>(1);

            sides = new Dictionary <Sidedef, VisualSidedefParts>(base.Sector.Sidedefs.Count);
            foreach (Sidedef sd in base.Sector.Sidedefs)
            {
                // VisualSidedef already exists?
                VisualSidedefParts parts = oldsides.ContainsKey(sd) ? oldsides[sd] : new VisualSidedefParts();

                // Doublesided or singlesided?
                if (sd.Other != null && sd.Line.IsFlagSet(General.Map.Config.DoubleSidedFlag))
                {
                    // Create upper part
                    VisualUpper vu = parts.upper ?? new VisualUpper(mode, this, sd);
                    if (vu.Setup())
                    {
                        base.AddGeometry(vu);
                    }

                    // Create lower part
                    VisualLower vl = parts.lower ?? new VisualLower(mode, this, sd);
                    if (vl.Setup())
                    {
                        base.AddGeometry(vl);
                    }

                    // Create middle part
                    VisualMiddleDouble vm = parts.middledouble ?? new VisualMiddleDouble(mode, this, sd);
                    if (vm.Setup())
                    {
                        base.AddGeometry(vm);
                    }

                    //mxd. Create fog boundary
                    VisualFogBoundary vb = parts.fogboundary ?? new VisualFogBoundary(mode, this, sd);
                    if (vb.Setup())
                    {
                        vm.FogFactor = 0;                         // Avoid double-fogging the middle part
                        base.AddGeometry(vb);
                    }

                    // Create 3D wall parts
                    SectorData osd = mode.GetSectorData(sd.Other.Sector);
                    if (!osd.Updated)
                    {
                        osd.Update();
                    }
                    List <VisualMiddle3D> middles = parts.middle3d ?? new List <VisualMiddle3D>(osd.ExtraFloors.Count);
                    for (int i = 0; i < osd.ExtraFloors.Count; i++)
                    {
                        Effect3DFloor ef = osd.ExtraFloors[i];
                        if (!ef.VavoomType && ef.IgnoreBottomHeight)
                        {
                            continue;                                                                 //mxd
                        }
                        VisualMiddle3D vm3 = (i < middles.Count) ? middles[i] : new VisualMiddle3D(mode, this, sd);
                        if (vm3.Setup(ef))
                        {
                            base.AddGeometry(vm3);
                        }
                        if (i >= middles.Count)
                        {
                            middles.Add(vm3);
                        }
                    }

                    //mxd. Create backsides
                    List <VisualMiddleBack> middlebacks = new List <VisualMiddleBack>();
                    for (int i = 0; i < data.ExtraFloors.Count; i++)
                    {
                        Effect3DFloor ef = data.ExtraFloors[i];

                        if (!ef.VavoomType && ef.RenderInside && !ef.IgnoreBottomHeight)
                        {
                            VisualMiddleBack vms = new VisualMiddleBack(mode, this, sd);
                            if (vms.Setup(ef))
                            {
                                base.AddGeometry(vms);
                            }
                            middlebacks.Add(vms);
                        }
                    }

                    // Store
                    sides.Add(sd, new VisualSidedefParts(vu, vl, vm, vb, middles, middlebacks));
                }
                else
                {
                    // Create middle part
                    VisualMiddleSingle vm = parts.middlesingle ?? new VisualMiddleSingle(mode, this, sd);
                    if (vm.Setup())
                    {
                        base.AddGeometry(vm);
                    }

                    // Store
                    sides.Add(sd, new VisualSidedefParts(vm));
                }
            }

            // Done
            changed = false;
        }
Exemple #12
0
        // This makes sure we are updated with the source linedef information
        public override void Update()
        {
            SectorData sd = data.Mode.GetSectorData(linedef.Front.Sector);

            if (!sd.Updated)
            {
                sd.Update();
            }
            sd.AddUpdateSector(data.Sector, true);

            if (floor == null)
            {
                floor = new SectorLevel(sd.Floor);
                data.AddSectorLevel(floor);
            }

            if (ceiling == null)
            {
                ceiling = new SectorLevel(sd.Ceiling);
                data.AddSectorLevel(ceiling);
            }

            // For non-vavoom types, we must switch the level types
            if (linedef.Args[1] != (int)FloorTypes.VavoomStyle)
            {
                //mxd. check for Swimmable/RenderInside/RenderAdditive flags
                renderadditive = (linedef.Args[2] & (int)Flags.RenderAdditive) == (int)Flags.RenderAdditive;
                renderinside   = ((((linedef.Args[1] & (int)FloorTypes.Swimmable) == (int)FloorTypes.Swimmable) && (linedef.Args[1] & (int)FloorTypes.NonSolid) != (int)FloorTypes.NonSolid)) ||
                                 ((linedef.Args[1] & (int)FloorTypes.RenderInside) == (int)FloorTypes.RenderInside);
                ignorebottomheight = ((linedef.Args[2] & (int)Flags.IgnoreBottomHeight) == (int)Flags.IgnoreBottomHeight);

                vavoomtype = false;
                alpha      = General.Clamp(linedef.Args[3], 0, 255);
                sd.Ceiling.CopyProperties(floor);
                sd.Floor.CopyProperties(ceiling);
                floor.type    = SectorLevelType.Floor;
                floor.plane   = sd.Ceiling.plane.GetInverted();
                ceiling.type  = SectorLevelType.Ceiling;
                ceiling.plane = (ignorebottomheight ? sd.Ceiling.plane : sd.Floor.plane.GetInverted());                 //mxd. Use upper plane when "ignorebottomheight" flag is set

                //mxd
                clipsides = (!renderinside && !renderadditive && alpha > 254 && !ignorebottomheight);

                // A 3D floor's color is always that of the sector it is placed in
                // (unless it's affected by glow) - mxd
                if (sd.CeilingGlow == null || !sd.CeilingGlow.Fullbright)
                {
                    floor.color = 0;
                }
            }
            else
            {
                vavoomtype     = true;
                renderadditive = false;           //mxd
                clipsides      = true;            //mxd
                floor.type     = SectorLevelType.Ceiling;
                floor.plane    = sd.Ceiling.plane;
                ceiling.type   = SectorLevelType.Floor;
                ceiling.plane  = sd.Floor.plane;
                alpha          = 255;

                // A 3D floor's color is always that of the sector it is placed in
                // (unless it's affected by glow) - mxd
                if (sd.FloorGlow == null || !sd.FloorGlow.Fullbright)
                {
                    ceiling.color = 0;
                }
            }

            // Apply alpha
            floor.alpha   = alpha;
            ceiling.alpha = alpha;

            //mxd
            floor.extrafloor   = true;
            ceiling.extrafloor = true;
            floor.splitsides   = !clipsides;
            ceiling.splitsides = (!clipsides && !ignorebottomheight);             // if "ignorebottomheight" flag is set, both ceiling and floor will be at the same level and sidedef clipping with floor level will fail resulting in incorrect light props transfer in some cases

            //mxd. Check slopes, cause GZDoom can't handle sloped translucent 3d floors...
            sloped3dfloor = ((alpha < 255 || renderadditive) &&
                             (Angle2D.RadToDeg(ceiling.plane.Normal.GetAngleZ()) != 270 ||
                              Angle2D.RadToDeg(floor.plane.Normal.GetAngleZ()) != 90));

            // Do not adjust light? (works only for non-vavoom types)
            if (!vavoomtype)
            {
                bool disablelighting  = ((linedef.Args[2] & (int)Flags.DisableLighting) == (int)Flags.DisableLighting);             //mxd
                bool restrictlighting = ((linedef.Args[2] & (int)Flags.RestrictLighting) == (int)Flags.RestrictLighting);           //mxd
                floor.resetlighting = ((linedef.Args[2] & (int)Flags.ResetLighting) == (int)Flags.ResetLighting);                   //mxd

                if (disablelighting || restrictlighting)
                {
                    floor.restrictlighting = restrictlighting; //mxd
                    floor.disablelighting  = disablelighting;  //mxd

                    if (disablelighting)                       //mxd
                    {
                        floor.color           = 0;
                        floor.brightnessbelow = -1;
                        floor.colorbelow      = PixelColor.FromInt(0);
                    }

                    ceiling.disablelighting  = disablelighting;                    //mxd
                    ceiling.restrictlighting = restrictlighting;                   //mxd

                    ceiling.color           = 0;
                    ceiling.brightnessbelow = -1;
                    ceiling.colorbelow      = PixelColor.FromInt(0);
                }
            }
        }