// Constructor
        public BaseVisualThing(BaseVisualMode mode, Thing t) : base(t)
        {
            this.mode = mode;

            // Find thing information
            info = General.Map.Data.GetThingInfo(Thing.Type);

            //mxd. When true, the thing can be moved below floor/above ceiling
            nointeraction = (info.Actor != null && info.Actor.GetFlagValue("nointeraction", false));

            //mxd. Find sprite textures
            sprites = new ImageData[info.SpriteFrame.Length];
            for (int i = 0; i < info.SpriteFrame.Length; i++)
            {
                sprites[i] = General.Map.Data.GetSpriteImage(info.SpriteFrame[i].Sprite);
                if (sprites[i] != null)
                {
                    sprites[i].AddReference();
                }
            }

            //mxd
            if (mode.UseSelectionFromClassicMode && t.Selected)
            {
                this.selected = true;
                mode.AddSelectedObject(this);
            }

            // We have no destructor
            GC.SuppressFinalize(this);
        }
Beispiel #2
0
        private static float GetAlignedThingZ(BaseVisualMode mode, Thing t, float targtthingheight)
        {
            ThingTypeInfo info = General.Map.Data.GetThingInfoEx(t.Type);

            if (info != null)
            {
                if (info.AbsoluteZ && info.Hangs)
                {
                    return(t.Position.z);                                             // Not sure what to do here...
                }
                if (info.AbsoluteZ)
                {
                    // Transform to floor-aligned position
                    SectorData nsd = mode.GetSectorData(t.Sector);
                    return(t.Position.z - nsd.Floor.plane.GetZ(t.Position) + t.Height);
                }

                if (info.Hangs)
                {
                    // Transform to floor-aligned position. Align top of target thing to the bottom of the hanging thing
                    SectorData nsd = mode.GetSectorData(t.Sector);
                    return((nsd.Ceiling.plane.GetZ(t.Position) - nsd.Floor.plane.GetZ(t.Position)) - t.Position.z - t.Height - targtthingheight);
                }
            }

            return(t.Position.z + t.Height);
        }
        public SlopeArcher(BaseVisualMode mode, List <IVisualEventReceiver> sectors, VisualSidedefSlope handle1, VisualSidedefSlope handle2, double theta, double offsetangle, double scale)
        {
            this.mode        = mode;
            this.sectors     = sectors;
            this.handle1     = handle1;
            this.handle2     = handle2;
            this.theta       = theta;
            this.offsetangle = offsetangle;
            this.scale       = scale;
            heightoffset     = 0.0;

            handleline = new Line2D(handle1.GetCenterPoint(), handle2.GetCenterPoint());
            length     = handleline.GetLength();

            if (handle1.Level.type == SectorLevelType.Ceiling)
            {
                baseheight = handle1.Level.extrafloor ? handle1.Level.sector.FloorHeight : handle1.Level.sector.CeilHeight;
            }
            else
            {
                baseheight = handle1.Level.extrafloor ? handle1.Level.sector.CeilHeight : handle1.Level.sector.FloorHeight;
            }

            baseheightoffset = 0.0;
        }
 // Constructor
 public ThingData(BaseVisualMode mode, Thing t)
 {
     // Initialize
     this.mode          = mode;
     this.thing         = t;
     this.updatesectors = new Dictionary <Sector, bool>(2);
 }
Beispiel #5
0
        // This adds the matching, unmarked sidedefs from a vertex for texture alignment
        private static void AddSidedefsForFloodfill(BaseVisualMode mode, Stack <Tools.SidedefFillJob> stack, Vertex v, bool forward, HashSet <long> texturelongnames)
        {
            foreach (Linedef ld in v.Linedefs)
            {
                Sidedef side1 = (forward ? ld.Front : ld.Back);
                Sidedef side2 = (forward ? ld.Back : ld.Front);

                // [ZZ] don't iterate the same linedef twice.
                //
                if ((side1 != null && side1.Marked) ||
                    (side2 != null && side2.Marked))
                {
                    continue;
                }

                if ((ld.Start == v) && (side1 != null) && !side1.Marked)
                {
                    if (SidedefTextureMatch(mode, side1, texturelongnames))
                    {
                        stack.Push(new Tools.SidedefFillJob {
                            forward = forward, sidedef = side1
                        });
                    }
                }
                else if ((ld.End == v) && (side2 != null) && !side2.Marked)
                {
                    if (SidedefTextureMatch(mode, side2, texturelongnames))
                    {
                        stack.Push(new Tools.SidedefFillJob {
                            forward = forward, sidedef = side2
                        });
                    }
                }
            }
        }
 // Constructor
 public VertexData(BaseVisualMode mode, Vertex v)
 {
     // Initialize
     this.mode          = mode;
     this.vertex        = v;
     this.updatesectors = new Dictionary <Sector, bool>(2);
 }
Beispiel #7
0
        // Constructor
        public VisualMiddleDouble(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s)
        {
            // Set render pass
            this.RenderPass = RenderPass.Mask;

            // We have no destructor
            GC.SuppressFinalize(this);
        }
Beispiel #8
0
        // Constructor
        public BaseVisualThing(BaseVisualMode mode, Thing t) : base(t)
        {
            this.mode = mode;

            Rebuild();

            // We have no destructor
            GC.SuppressFinalize(this);
        }
        // Constructor
        public VisualMiddle3D(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s)
        {
            //mxd
            geometrytype = VisualGeometryType.WALL_MIDDLE_3D;
            partname     = "mid";

            // We have no destructor
            GC.SuppressFinalize(this);
        }
        // Constructor
        public VisualUpper(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s)
        {
            //mxd
            geometrytype = VisualGeometryType.WALL_UPPER;
            partname     = "top";

            // We have no destructor
            GC.SuppressFinalize(this);
        }
Beispiel #11
0
        private bool innerside;         //mxd

        #endregion

        #region ================== Properties

        #endregion

        #region ================== Constructor / Setup

        // Constructor
        public VisualFloor(BaseVisualMode mode, VisualSector vs) : base(mode, vs)
        {
            //mxd
            geometrytype         = VisualGeometryType.FLOOR;
            partname             = "floor";
            performautoselection = mode.UseSelectionFromClassicMode && vs != null && vs.Sector.Selected && (General.Map.ViewMode == ViewMode.FloorTextures || General.Map.ViewMode == ViewMode.Normal);

            // We have no destructor
            GC.SuppressFinalize(this);
        }
Beispiel #12
0
        // Constructor
        public BaseVisualSector(BaseVisualMode mode, Sector s) : base(s)
        {
            this.mode = mode;

            // Initialize
            Rebuild();

            // We have no destructor
            GC.SuppressFinalize(this);
        }
Beispiel #13
0
 // Constructor for sidedefs
 public BaseVisualGeometrySidedef(BaseVisualMode mode, VisualSector vs, Sidedef sd) : base(vs, sd)
 {
     this.mode    = mode;
     this.deltaz  = new Vector3D(0.0f, 0.0f, 1.0f);
     this.deltaxy = (sd.Line.End.Position - sd.Line.Start.Position) * sd.Line.LengthInv;
     if (!sd.IsFront)
     {
         this.deltaxy = -this.deltaxy;
     }
 }
        // Constructor
        public VisualFogBoundary(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s)
        {
            //mxd
            geometrytype = VisualGeometryType.FOG_BOUNDARY;

            // Set render pass
            this.RenderPass = RenderPass.Additive;

            // We have no destructor
            GC.SuppressFinalize(this);
        }
        // Constructor
        public VisualMiddleDouble(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s)
        {
            //mxd
            geometrytype = VisualGeometryType.WALL_MIDDLE;
            partname     = "mid";

            // Set render pass
            this.RenderPass = RenderPass.Mask;

            // We have no destructor
            GC.SuppressFinalize(this);
        }
Beispiel #16
0
        //mxd. This checks if any of the sidedef texture match the given textures
        public static bool SidedefTextureMatch(BaseVisualMode mode, Sidedef sd, HashSet <long> texturelongnames)
        {
            if (!mode.VisualSectorExists(sd.Sector))
            {
                return(false);
            }
            VisualSidedefParts parts = ((BaseVisualSector)mode.GetVisualSector(sd.Sector)).GetSidedefParts(sd);

            return((texturelongnames.Contains(sd.LongHighTexture) && (parts.upper != null && parts.upper.Triangles > 0)) ||
                   (texturelongnames.Contains(sd.LongLowTexture) && (parts.lower != null && parts.lower.Triangles > 0)) ||
                   (texturelongnames.Contains(sd.LongMiddleTexture) &&
                    ((parts.middledouble != null && parts.middledouble.Triangles > 0) || (parts.middlesingle != null && parts.middlesingle.Triangles > 0))));
        }
Beispiel #17
0
        // Constructor
        public BaseVisualSector(BaseVisualMode mode, Sector s) : base(s)
        {
            this.mode              = mode;
            this.extrafloors       = new List <VisualFloor>(2);
            this.extraceilings     = new List <VisualCeiling>(2);
            this.extrabackfloors   = new List <VisualFloor>(2);          //mxd
            this.extrabackceilings = new List <VisualCeiling>(2);        //mxd

            // Initialize
            Rebuild();

            // We have no destructor
            GC.SuppressFinalize(this);
        }
Beispiel #18
0
        //mxd. Gets thing z next higher to target thing z
        private static double GetNextHigherThingZ(BaseVisualMode mode, IEnumerable <Thing> things, double thingz, double thingheight)
        {
            double higherthingz = double.MaxValue;

            foreach (Thing t in things)
            {
                double neighbourz = GetAlignedThingZ(mode, t, thingheight);
                if (neighbourz > thingz && neighbourz < higherthingz)
                {
                    higherthingz = neighbourz;
                }
            }
            return(higherthingz);
        }
Beispiel #19
0
        //mxd. Gets thing z next higher to target thing z
        private static float GetNextHigherThingZ(BaseVisualMode mode, IEnumerable <Thing> things, float thingz, float thingheight)
        {
            float higherthingz = float.MaxValue;

            foreach (Thing t in things)
            {
                float neighbourz = GetAlignedThingZ(mode, t, thingheight);
                if (neighbourz > thingz && neighbourz < higherthingz)
                {
                    higherthingz = neighbourz;
                }
            }
            return(higherthingz);
        }
        // Constructor
        public BaseVisualVertex(BaseVisualMode mode, Vertex v, bool ceilingVertex)
            : base(v, ceilingVertex)
        {
            this.mode   = mode;
            cageradius2 = DEFAULT_SIZE * General.Settings.GZVertexScale3D * Angle2D.SQRT2;
            cageradius2 = cageradius2 * cageradius2;

            // Synchronize selection?
            if (mode.UseSelectionFromClassicMode && v.Selected &&
                (General.Map.ViewMode == ViewMode.Normal ||
                 (!ceilingVertex && General.Map.ViewMode == ViewMode.FloorTextures) ||
                 (ceilingVertex && General.Map.ViewMode == ViewMode.CeilingTextures)))
            {
                this.selected = true;
                mode.AddSelectedObject(this);
            }

            changed = true;
            Update();
        }
Beispiel #21
0
        // Constructor
        public BaseVisualThing(BaseVisualMode mode, Thing t) : base(t)
        {
            this.mode = mode;

            // Find thing information
            info = General.Map.Data.GetThingInfo(Thing.Type);

            // Find sprite texture
            if (info.Sprite.Length > 0)
            {
                sprite = General.Map.Data.GetSpriteImage(info.Sprite);
                if (sprite != null)
                {
                    sprite.AddReference();
                }
            }

            // We have no destructor
            GC.SuppressFinalize(this);
        }
Beispiel #22
0
        // Constructor
        public SectorData(BaseVisualMode mode, Sector s)
        {
            // Initialize
            this.mode              = mode;
            this.sector            = s;
            this.updated           = false;
            this.floorchanged      = false;
            this.ceilingchanged    = false;
            this.lightlevels       = new List <SectorLevel>(2);
            this.extrafloors       = new List <Effect3DFloor>(1);
            this.alleffects        = new List <SectorEffect>(1);
            this.updatesectors     = new Dictionary <Sector, bool>(2);
            this.floor             = new SectorLevel(sector, SectorLevelType.Floor);
            this.floorbase         = new SectorLevel(sector, SectorLevelType.Floor);   //mxd
            this.ceiling           = new SectorLevel(sector, SectorLevelType.Ceiling);
            this.ceilingbase       = new SectorLevel(sector, SectorLevelType.Ceiling); //mxd
            this.glowingflateffect = new EffectGlowingFlat(this);                      //mxd

            // Add ceiling and floor
            lightlevels.Add(floor);
            lightlevels.Add(ceiling);

            BasicSetup();
        }
Beispiel #23
0
 // Constructor
 protected BaseVisualGeometrySector(BaseVisualMode mode, VisualSector vs) : base(vs)
 {
     this.mode = mode;
 }
Beispiel #24
0
 public static bool SidedefTextureMatch(BaseVisualMode mode, Sidedef sd, HashSet <long> texturelongnames)
 {
     return(SidedefTextureMatch(mode, sd, texturelongnames, false));
 }
Beispiel #25
0
        // This gets sectors which surround given sectors
        internal static IEnumerable <Sector> GetSectorsAround(BaseVisualMode mode, IEnumerable <Sector> selected)
        {
            HashSet <int>    processedsectors = new HashSet <int>();
            HashSet <Vertex> verts            = new HashSet <Vertex>();
            List <Sector>    result           = new List <Sector>();

            foreach (Sector s in selected)
            {
                processedsectors.Add(s.Index);
                foreach (Sidedef side in s.Sidedefs)
                {
                    if (!verts.Contains(side.Line.Start))
                    {
                        verts.Add(side.Line.Start);
                    }
                    if (!verts.Contains(side.Line.End))
                    {
                        verts.Add(side.Line.End);
                    }
                }
            }

            foreach (Vertex v in verts)
            {
                foreach (Linedef l in v.Linedefs)
                {
                    if (l.Front != null && l.Front.Sector != null && !processedsectors.Contains(l.Front.Sector.Index))
                    {
                        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);
                                }
                            }
                        }
                    }
                }
            }

            return(result);
        }
Beispiel #26
0
        internal static float GetLowerThingZ(BaseVisualMode mode, SectorData sd, VisualThing thing)
        {
            Vector3D pos         = thing.Thing.Position;
            float    thingheight = thing.Thing.Height;
            bool     absolute    = thing.Info.AbsoluteZ;
            bool     hangs       = thing.Info.Hangs;

            if (absolute && hangs)
            {
                General.Interface.DisplayStatus(StatusType.Warning, "Sorry, can't have both 'absolute' and 'hangs' flags...");
                return(pos.z);
            }

            // Get things, which bounding boxes intersect with target thing
            IEnumerable <Thing> intersectingthings = GetIntersectingThings(mode, thing.Thing);

            float fz = (absolute ? 0 : sd.Floor.plane.GetZ(pos));
            float cz = sd.Ceiling.plane.GetZ(pos);

            if (hangs)
            {
                // Transform to floor-aligned position
                Vector3D floorpos    = new Vector3D(pos, (cz - fz) - pos.z - thingheight);
                float    lowertingz  = GetNextLowerThingZ(mode, intersectingthings, floorpos.z, thingheight);
                float    lowerfloorz = float.MaxValue;

                // Do it only when there are extrafloors
                if (sd.LightLevels.Count > 2)
                {
                    // Unlike sd.ExtraFloors, these are sorted by height
                    for (int i = sd.LightLevels.Count - 1; i > -1; i--)
                    {
                        SectorLevel level = sd.LightLevels[i];
                        if (level.type == SectorLevelType.Light || level.type == SectorLevelType.Glow)
                        {
                            continue;                                                                                                   // Skip lights and glows
                        }
                        float z = level.plane.GetZ(floorpos) - fz;
                        if (level.type == SectorLevelType.Ceiling)
                        {
                            z -= thingheight;
                        }
                        if (z < floorpos.z)
                        {
                            lowerfloorz = z;
                            break;
                        }
                    }
                }

                float floorz = cz - fz;                 // Floor height when counted from ceiling

                if (lowerfloorz != float.MaxValue && lowertingz != float.MinValue)
                {
                    // Transform back to ceiling-aligned position
                    return(cz - fz - Math.Min(Math.Max(lowerfloorz, lowertingz), floorz) - thingheight);
                }

                if (lowerfloorz != float.MaxValue)
                {
                    // Transform back to ceiling-aligned position
                    return(cz - fz - Math.Min(lowerfloorz, floorz) - thingheight);
                }

                if (lowertingz != float.MinValue)
                {
                    // Transform back to ceiling-aligned position
                    return(cz - fz - Math.Min(lowertingz, floorz) - thingheight);
                }

                return(floorz - thingheight);                // Align to real floor
            }
            else
            {
                float lowertingz  = GetNextLowerThingZ(mode, intersectingthings, (absolute ? pos.z - fz : pos.z), thingheight);
                float lowerfloorz = float.MaxValue;

                // Do it only when there are extrafloors
                if (sd.LightLevels.Count > 2)
                {
                    // Unlike sd.ExtraFloors, these are sorted by height
                    for (int i = sd.LightLevels.Count - 1; i > -1; i--)
                    {
                        SectorLevel level = sd.LightLevels[i];
                        if (level.type == SectorLevelType.Light || level.type == SectorLevelType.Glow)
                        {
                            continue;                                                                                                   // Skip lights and glows
                        }
                        float z = level.plane.GetZ(pos) - fz;
                        if (level.type == SectorLevelType.Ceiling)
                        {
                            z -= thingheight;
                        }
                        if (z < pos.z)
                        {
                            lowerfloorz = z;
                            break;
                        }
                    }
                }

                float floorz   = sd.Floor.plane.GetZ(pos);               // Floor-aligned relative target thing z
                float floorpos = 0;

                if (lowerfloorz != float.MaxValue && lowertingz != float.MinValue)
                {
                    floorpos = Math.Max(Math.Max(lowerfloorz, lowertingz), floorz);
                }
                if (lowerfloorz != float.MaxValue)
                {
                    floorpos = Math.Max(lowerfloorz, floorz);
                }
                if (lowertingz != float.MinValue)
                {
                    floorpos = Math.Max(lowertingz, floorz);
                }

                return(absolute ? floorpos + floorz : floorpos);                  // Convert to absolute position if necessary
            }
        }
 // Constructor
 public VisualLower(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s)
 {
     // We have no destructor
     GC.SuppressFinalize(this);
 }
Beispiel #28
0
        // This performs texture floodfill along all walls that match with the same texture
        // NOTE: This method uses the sidedefs marking to indicate which sides have been filled
        // When resetsidemarks is set to true, all sidedefs will first be marked false (not aligned).
        // Setting resetsidemarks to false is usefull to fill only within a specific selection
        // (set the marked property to true for the sidedefs outside the selection)
        public static void FloodfillTextures(BaseVisualMode mode, Sidedef start, HashSet <long> originaltextures, string filltexture, bool resetsidemarks)
        {
            Stack <Tools.SidedefFillJob> todo = new Stack <Tools.SidedefFillJob>(50);

            // Mark all sidedefs false (they will be marked true when the texture is aligned)
            if (resetsidemarks)
            {
                General.Map.Map.ClearMarkedSidedefs(false);
            }

            // Begin with first sidedef
            if (SidedefTextureMatch(mode, start, originaltextures))
            {
                todo.Push(new Tools.SidedefFillJob {
                    sidedef = start, forward = true
                });
            }

            // Continue until nothing more to align
            while (todo.Count > 0)
            {
                // Get the align job to do
                Tools.SidedefFillJob j = todo.Pop();

                //mxd. Get visual parts
                if (mode.VisualSectorExists(j.sidedef.Sector))
                {
                    VisualSidedefParts parts = ((BaseVisualSector)mode.GetVisualSector(j.sidedef.Sector)).GetSidedefParts(j.sidedef);

                    // Apply texturing
                    if ((parts.upper != null && parts.upper.Triangles > 0) && originaltextures.Contains(j.sidedef.LongHighTexture))
                    {
                        j.sidedef.SetTextureHigh(filltexture);
                    }
                    if (((parts.middledouble != null && parts.middledouble.Triangles > 0) || (parts.middlesingle != null && parts.middlesingle.Triangles > 0)) && originaltextures.Contains(j.sidedef.LongMiddleTexture))
                    {
                        j.sidedef.SetTextureMid(filltexture);
                    }
                    if ((parts.lower != null && parts.lower.Triangles > 0) && originaltextures.Contains(j.sidedef.LongLowTexture))
                    {
                        j.sidedef.SetTextureLow(filltexture);
                    }
                }

                j.sidedef.Marked = true;

                if (j.forward)
                {
                    // Add sidedefs forward (connected to the right vertex)
                    Vertex v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start;
                    AddSidedefsForFloodfill(mode, todo, v, true, originaltextures);

                    // Add sidedefs backward (connected to the left vertex)
                    v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End;
                    AddSidedefsForFloodfill(mode, todo, v, false, originaltextures);
                }
                else
                {
                    // Add sidedefs backward (connected to the left vertex)
                    Vertex v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End;
                    AddSidedefsForFloodfill(mode, todo, v, false, originaltextures);

                    // Add sidedefs forward (connected to the right vertex)
                    v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start;
                    AddSidedefsForFloodfill(mode, todo, v, true, originaltextures);
                }
            }
        }
Beispiel #29
0
 // Constructor
 public VisualFloor(BaseVisualMode mode, VisualSector vs) : base(mode, vs)
 {
     // We have no destructor
     GC.SuppressFinalize(this);
 }
 // Constructor
 public VisualMiddleBack(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s)
 {
 }