//mxd
        private void CreateTiles()
        {
            Point               lt        = TileForPoint(mapbounds.Left - Tile.TILE_SIZE, mapbounds.Top - Tile.TILE_SIZE);
            Point               rb        = TileForPoint(mapbounds.Right + Tile.TILE_SIZE, mapbounds.Bottom + Tile.TILE_SIZE);
            Rectangle           tilesrect = new Rectangle(lt.X, lt.Y, rb.X - lt.X, rb.Y - lt.Y);
            NearestLineBlockmap blockmap  = new NearestLineBlockmap(tilesrect);

            for (int x = tilesrect.X; x <= tilesrect.Right; x += Tile.TILE_SIZE)
            {
                for (int y = tilesrect.Y; y <= tilesrect.Bottom; y += Tile.TILE_SIZE)
                {
                    // If the tile is obviously outside the map, don't create it
                    Vector2D pc         = new Vector2D(x + (Tile.TILE_SIZE >> 1), y + (Tile.TILE_SIZE >> 1));
                    Linedef  ld         = MapSet.NearestLinedef(blockmap.GetBlockAt(pc).Lines, pc);
                    double   distancesq = ld.DistanceToSq(pc, true);
                    if (distancesq > (Tile.TILE_SIZE * Tile.TILE_SIZE))
                    {
                        double side = ld.SideOfLine(pc);
                        if ((side > 0.0f) && (ld.Back == null))
                        {
                            continue;
                        }
                    }

                    Point tp = new Point(x, y);
                    tiles.Add(tp, new Tile(tp));
                }
            }
        }
Exemple #2
0
 // This returns the camera sector from linedef
 private Sector GetCameraSectorFromLinedef(Linedef ld)
 {
     if (ld.SideOfLine(General.Map.VisualCamera.Position) < 0)
     {
         if (ld.Front != null)
         {
             return(ld.Front.Sector);
         }
         else
         {
             return(null);
         }
     }
     else
     {
         if (ld.Back != null)
         {
             return(ld.Back.Sector);
         }
         else
         {
             return(null);
         }
     }
 }
        // This highlights a new region
        private void Highlight(bool buttonspressed)
        {
            // Mouse inside?
            if (mouseinside)
            {
                // Highlighting from a new sidedef?
                Linedef nl = General.Map.Map.NearestLinedef(mousemappos);
                if (nl != null)
                {
                    bool        front      = (nl.SideOfLine(mousemappos) <= 0.0f);         //mxd
                    LinedefSide newnearest = new LinedefSide(nl, front);
                    if (newnearest != nearestside)
                    {
                        // Only change when buttons are not pressed
                        if (!buttonspressed || (editside == newnearest))
                        {
                            // Find new sector
                            nearestside = newnearest;
                            allsides    = Tools.FindPotentialSectorAt(nl, front);                          //mxd
                            if (allsides != null)
                            {
                                alllines = new List <Linedef>(allsides.Count);
                                foreach (LinedefSide sd in allsides)
                                {
                                    alllines.Add(sd.Line);
                                }
                            }
                            else
                            {
                                alllines = null;
                            }
                        }
                        else
                        {
                            // Don't highlight this one
                            nearestside = null;
                            allsides    = null;
                            alllines    = null;
                        }

                        // Redraw overlay
                        DrawGeometry();
                        DrawOverlay();                         //mxd
                        renderer.Present();
                    }
                }
            }
            else
            {
                // No valid region
                nearestside = null;
                allsides    = null;
                alllines    = null;

                // Redraw overlay
                DrawGeometry();
                renderer.Present();
            }
        }
Exemple #4
0
 // This tests on which side of the line the given coordinates are
 // returns < 0 for front (right) side, > 0 for back (left) side and 0 if on the line
 public float SideOfLine(LuaVector2D p)
 {
     if (linedef.IsDisposed)
     {
         throw new ScriptRuntimeException("Linedef has been disposed, can't SideOfLine.");
     }
     return(linedef.SideOfLine(p.vec));
 }
        // This returns the camera sector from linedef
        private static Sector GetCameraSectorFromLinedef(Linedef ld)
        {
            if (ld.SideOfLine(General.Map.VisualCamera.Position) < 0)
            {
                return(ld.Front != null ? ld.Front.Sector : null);
            }

            return(ld.Back != null ? ld.Back.Sector : null);
        }
Exemple #6
0
        public Sector GetSectorAt(Vector2D pos)
        {
            List <Sector> sectors = new List <Sector>(1);

            foreach (VisualBlockEntry e in GetBlocks(pos))
            {
                foreach (Sector s in e.Sectors)
                {
                    if (s.Intersect(pos))
                    {
                        sectors.Add(s);
                    }
                }
            }

            if (sectors.Count == 0)
            {
                return(null);
            }
            else if (sectors.Count == 1)
            {
                return(sectors[0]);
            }
            else
            {
                // Having multiple intersections indicates that there are self-referencing sectors in this spot.
                // In this case we have to check which side of the nearest linedef pos is on, and then use that sector
                HashSet <Linedef> linedefs = new HashSet <Linedef>(sectors[0].Sidedefs.Count * sectors.Count);

                foreach (Sector s in sectors)
                {
                    foreach (Sidedef sd in s.Sidedefs)
                    {
                        linedefs.Add(sd.Line);
                    }
                }

                Linedef nearest = MapSet.NearestLinedef(linedefs, pos);
                double  d       = nearest.SideOfLine(pos);

                if (d <= 0.0 && nearest.Front != null)
                {
                    return(nearest.Front.Sector);
                }
                else if (nearest.Back != null)
                {
                    return(nearest.Back.Sector);
                }
            }

            return(null);
        }
        // Mouse moves
        public override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            // Find the nearest linedef within highlight range
            Linedef l = General.Map.Map.NearestLinedef(mousemappos);

            // Check on which side of the linedef the mouse is
            float side = l.SideOfLine(mousemappos);

            if (side > 0)
            {
                // Is there a sidedef here?
                if (l.Back != null)
                {
                    // Highlight if not the same
                    if (l.Back.Sector != highlighted)
                    {
                        Highlight(l.Back.Sector);
                    }
                }
                else
                {
                    // Highlight nothing
                    if (highlighted != null)
                    {
                        Highlight(null);
                    }
                }
            }
            else
            {
                // Is there a sidedef here?
                if (l.Front != null)
                {
                    // Highlight if not the same
                    if (l.Front.Sector != highlighted)
                    {
                        Highlight(l.Front.Sector);
                    }
                }
                else
                {
                    // Highlight nothing
                    if (highlighted != null)
                    {
                        Highlight(null);
                    }
                }
            }
        }
        //mxd
        private static Linedef FindPotentialLine(Vector2D target, Vector2D center)
        {
            // Target position on top of existing vertex?
            Vertex v = General.Map.Map.NearestVertex(target);

            if (v == null)
            {
                return(null);
            }

            Linedef result = null;

            if (v.Position == target)
            {
                float mindistance = float.MaxValue;
                foreach (Linedef l in v.Linedefs)
                {
                    if (result == null)
                    {
                        result      = l;
                        mindistance = Vector2D.DistanceSq(l.GetCenterPoint(), center);
                    }
                    else
                    {
                        float curdistance = Vector2D.DistanceSq(l.GetCenterPoint(), center);
                        if (curdistance < mindistance)
                        {
                            mindistance = curdistance;
                            result      = l;
                        }
                    }
                }
            }
            else
            {
                // Result position will split a line?
                result = General.Map.Map.NearestLinedef(target);
                if (result.SideOfLine(target) != 0)
                {
                    return(null);
                }
            }

            return(result);
        }
        //mxd
        private static bool CanFinishDrawing(Vector2D start, Vector2D end, Vector2D center)
        {
            Linedef startline = FindPotentialLine(start, center);

            if (startline == null)
            {
                return(false);
            }

            Linedef endline = FindPotentialLine(end, center);

            if (endline == null)
            {
                return(false);
            }

            // Can finish drawing if a path between startline and endline exists
            return(Tools.FindClosestPath(startline, startline.SideOfLine(center) < 0.0f, endline, endline.SideOfLine(center) < 0.0f, true) != null);
        }
Exemple #10
0
        // Mouse moves
        public override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            // Not holding any buttons?
            if (e.Button == MouseButtons.None)
            {
                // Find the nearest items within highlight range
                Vertex  v = General.Map.Map.NearestVertexSquareRange(mousemappos, VERTEX_HIGHLIGHT_RANGE / renderer.Scale);
                Thing   t = General.Map.Map.NearestThingSquareRange(mousemappos, THING_HIGHLIGHT_RANGE / renderer.Scale);
                Linedef l = General.Map.Map.NearestLinedef(mousemappos);
                Sector  s;

                // Check on which side of the linedef the mouse is
                float side = l.SideOfLine(mousemappos);
                if (side > 0)
                {
                    // Is there a sidedef here?
                    if (l.Back != null)
                    {
                        s = l.Back.Sector;
                    }
                    else
                    {
                        s = null;
                    }
                }
                else
                {
                    // Is there a sidedef here?
                    if (l.Front != null)
                    {
                        s = l.Front.Sector;
                    }
                    else
                    {
                        s = null;
                    }
                }

                // Both a vertex and thing in range?
                if ((v != null) && (t != null))
                {
                    // Highlight closest
                    float vd = v.DistanceToSq(mousemappos);
                    float td = t.DistanceToSq(mousemappos);
                    if (vd < td)
                    {
                        Highlight(v);
                    }
                    else
                    {
                        Highlight(t);
                    }
                }
                // Vertex in range?
                else if (v != null)
                {
                    // Highlight vertex
                    Highlight(v);
                }
                // Thing in range?
                else if (t != null)
                {
                    // Highlight thing
                    Highlight(t);
                }
                else
                {
                    // Linedef within in range?
                    float ld = l.DistanceTo(mousemappos, true);
                    if (ld < (LINEDEF_HIGHLIGHT_RANGE / renderer.Scale))
                    {
                        // Highlight line
                        Highlight(l);
                    }
                    // Mouse inside a sector?
                    else if (s != null)
                    {
                        // Highlight sector
                        Highlight(s);
                    }
                    else
                    {
                        // Highlight nothing
                        Highlight(null);
                    }
                }
            }
        }
Exemple #11
0
        // Mode engages
        public override void OnEngage()
        {
            base.OnEngage();

            // We don't want to record this for undoing while we move the geometry around.
            // This will be set back to normal when we're done.
            General.Map.UndoRedo.IgnorePropChanges = true;

            // Presentation
            renderer.SetPresentation(Presentation.Standard);

            // Selection
            General.Map.Map.ConvertSelection(SelectionType.Sectors);
            General.Map.Map.SelectionType = SelectionType.Sectors;
            if (General.Map.Map.SelectedSectorsCount == 0)
            {
                // Find the nearest linedef within highlight range
                Linedef l = General.Map.Map.NearestLinedef(mousemappos);
                if (l != null)
                {
                    Sector selectsector = null;

                    // Check on which side of the linedef the mouse is and which sector there is
                    float side = l.SideOfLine(mousemappos);
                    if ((side > 0) && (l.Back != null))
                    {
                        selectsector = l.Back.Sector;
                    }
                    else if ((side <= 0) && (l.Front != null))
                    {
                        selectsector = l.Front.Sector;
                    }

                    // Select the sector!
                    if (selectsector != null)
                    {
                        selectsector.Selected = true;
                        foreach (Sidedef sd in selectsector.Sidedefs)
                        {
                            sd.Line.Selected = true;
                        }
                    }
                }
            }

            // Get sector selection
            selection = General.Map.Map.GetSelectedSectors(true);
            if (selection.Count == 0)
            {
                General.Interface.MessageBeep(MessageBeepType.Default);
                General.Interface.DisplayStatus(StatusType.Action, "A selected sector is required for this action.");
                General.Editing.CancelMode();
                return;
            }
            editsector = General.GetByIndex(selection, 0);

            // Get the texture
            texture = GetTexture(editsector);
            if ((texture == null) || (texture == General.Map.Data.WhiteTexture) ||
                (texture.Width <= 0) || (texture.Height <= 0) || !texture.IsImageLoaded)
            {
                General.Interface.MessageBeep(MessageBeepType.Default);
                General.Interface.DisplayStatus(StatusType.Action, "The selected sector must have a loaded texture to align.");
                General.Editing.CancelMode();
                return;
            }

            // Cache the transformation values
            sectorinfo = new List <SectorInfo>(selection.Count);
            foreach (Sector s in selection)
            {
                SectorInfo si;
                si.rotation = Angle2D.DegToRad(s.Fields.GetValue(RotationName, 0.0f));
                si.scale.x  = s.Fields.GetValue(XScaleName, 1.0f);
                si.scale.y  = s.Fields.GetValue(YScaleName, 1.0f);
                si.offset.x = s.Fields.GetValue(XOffsetName, 0.0f);
                si.offset.y = -s.Fields.GetValue(YOffsetName, 0.0f);
                sectorinfo.Add(si);
            }

            // We want the texture corner nearest to the center of the sector
            Vector2D fp;

            fp.x = (editsector.BBox.Left + editsector.BBox.Right) / 2;
            fp.y = (editsector.BBox.Top + editsector.BBox.Bottom) / 2;

            // Transform the point into texture space
            fp = WorldToTex(fp);

            // Snap to the nearest left-top corner
            fp.x = (float)Math.Floor(fp.x / texture.ScaledWidth) * texture.ScaledWidth;
            fp.y = (float)Math.Ceiling(fp.y / texture.ScaledHeight) * texture.ScaledHeight;

            // Now move the offset so that the 0,0 point is at this location
            // We want to work with the 0,0 location because it makes things easier.
            SectorInfo si0 = sectorinfo[0];

            si0.offset   -= fp / si0.scale;
            sectorinfo[0] = si0;

            UpdateRectangleComponents();
            UpdateSectors();
        }
        // This runs the check
        public override void Run()
        {
            BlockMap <BlockEntry> blockmap = BuilderPlug.Me.ErrorCheckForm.BlockMap;
            int   progress     = 0;
            int   stepprogress = 0;
            float maxradius    = 0;
            Dictionary <int, HashSet <int> > processedthingpairs = new Dictionary <int, HashSet <int> >();       //mxd

            foreach (ThingTypeInfo tti in General.Map.Data.ThingTypes)
            {
                if (tti.Radius > maxradius)
                {
                    maxradius = tti.Radius;
                }
            }

            // Go for all the things
            foreach (Thing t in General.Map.Map.Things)
            {
                ThingTypeInfo info  = General.Map.Data.GetThingInfo(t.Type);
                bool          stuck = false;

                // Check this thing for getting stuck?
                if ((info.ErrorCheck == ThingTypeInfo.THING_ERROR_INSIDE_STUCK) &&
                    (info.Blocking > ThingTypeInfo.THING_BLOCKING_NONE))
                {
                    // Make square coordinates from thing
                    float    blockingsize = t.Size - ALLOWED_STUCK_DISTANCE;
                    Vector2D lt           = new Vector2D(t.Position.x - blockingsize, t.Position.y - blockingsize);
                    Vector2D rb           = new Vector2D(t.Position.x + blockingsize, t.Position.y + blockingsize);
                    Vector2D bmlt         = new Vector2D(t.Position.x - maxradius, t.Position.y - maxradius);
                    Vector2D bmrb         = new Vector2D(t.Position.x + maxradius, t.Position.y + maxradius);

                    // Go for all the lines to see if this thing is stuck
                    List <BlockEntry>             blocks         = blockmap.GetSquareRange(new RectangleF(bmlt.x, bmlt.y, (bmrb.x - bmlt.x), (bmrb.y - bmlt.y)));
                    Dictionary <Linedef, Linedef> doneblocklines = new Dictionary <Linedef, Linedef>(blocks.Count * 3);

                    foreach (BlockEntry b in blocks)
                    {
                        foreach (Linedef l in b.Lines)
                        {
                            // Only test when sinlge-sided, two-sided + impassable and not already checked
                            if (((l.Back == null) || l.IsFlagSet(General.Map.Config.ImpassableFlag)) && !doneblocklines.ContainsKey(l))
                            {
                                // Test if line ends are inside the thing
                                if (PointInRect(lt, rb, l.Start.Position) || PointInRect(lt, rb, l.End.Position))
                                {
                                    // Thing stuck in line!
                                    stuck = true;
                                    SubmitResult(new ResultStuckThingInLine(t, l));
                                }
                                // Test if the line intersects the square
                                else if (Line2D.GetIntersection(l.Start.Position, l.End.Position, lt.x, lt.y, rb.x, lt.y) ||
                                         Line2D.GetIntersection(l.Start.Position, l.End.Position, rb.x, lt.y, rb.x, rb.y) ||
                                         Line2D.GetIntersection(l.Start.Position, l.End.Position, rb.x, rb.y, lt.x, rb.y) ||
                                         Line2D.GetIntersection(l.Start.Position, l.End.Position, lt.x, rb.y, lt.x, lt.y))
                                {
                                    // Thing stuck in line!
                                    stuck = true;
                                    SubmitResult(new ResultStuckThingInLine(t, l));
                                }

                                // Checked
                                doneblocklines.Add(l, l);
                            }
                        }

                        // Check if thing is stuck in other things
                        if (info.Blocking != ThingTypeInfo.THING_BLOCKING_NONE)
                        {
                            foreach (Thing ot in b.Things)
                            {
                                // Don't compare the thing with itself
                                if (t.Index == ot.Index)
                                {
                                    continue;
                                }

                                // mxd. Don't compare already processed stuff
                                if (processedthingpairs.ContainsKey(t.Index) && processedthingpairs[t.Index].Contains(ot.Index))
                                {
                                    continue;
                                }

                                // Only check of items that can block
                                if (General.Map.Data.GetThingInfo(ot.Type).Blocking == ThingTypeInfo.THING_BLOCKING_NONE)
                                {
                                    continue;
                                }

                                // need to compare the flags
                                if (FlagsOverlap(t, ot) && ThingsOverlap(t, ot))
                                {
                                    stuck = true;
                                    SubmitResult(new ResultStuckThingInThing(t, ot));
                                }

                                //mxd. Prepare collections
                                if (!processedthingpairs.ContainsKey(t.Index))
                                {
                                    processedthingpairs.Add(t.Index, new HashSet <int>());
                                }
                                if (!processedthingpairs.ContainsKey(ot.Index))
                                {
                                    processedthingpairs.Add(ot.Index, new HashSet <int>());
                                }

                                //mxd. Add both ways
                                processedthingpairs[t.Index].Add(ot.Index);
                                processedthingpairs[ot.Index].Add(t.Index);
                            }
                        }
                    }
                }

                // Check this thing for being outside the map?
                if (!stuck && info.ErrorCheck >= ThingTypeInfo.THING_ERROR_INSIDE)
                {
                    // Get the nearest line to see if the thing is outside the map
                    bool    outside;
                    Linedef l = General.Map.Map.NearestLinedef(t.Position);
                    if (l.SideOfLine(t.Position) <= 0)
                    {
                        outside = (l.Front == null);
                    }
                    else
                    {
                        outside = (l.Back == null);
                    }

                    // Outside the map?
                    if (outside)
                    {
                        // Make result
                        SubmitResult(new ResultThingOutside(t));
                    }
                }

                // Handle thread interruption
                try { Thread.Sleep(0); }
                catch (ThreadInterruptedException) { return; }

                // We are making progress!
                if ((++progress / PROGRESS_STEP) > stepprogress)
                {
                    stepprogress = (progress / PROGRESS_STEP);
                    AddProgress(1);
                }
            }
        }
        // Mouse moves
        public override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            // Not holding any buttons?
            if (e.Button == MouseButtons.None)
            {
                General.Interface.SetCursor(Cursors.Default);

                // Find the nearest linedef within highlight range
                Linedef l = General.Map.Map.NearestLinedef(mousemappos);
                if (l != null)
                {
                    // Check on which side of the linedef the mouse is
                    float side = l.SideOfLine(mousemappos);
                    if (side > 0)
                    {
                        // Is there a sidedef here?
                        if (l.Back != null)
                        {
                            // Highlight if not the same
                            if (l.Back.Sector != highlighted)
                            {
                                Highlight(l.Back.Sector);
                            }
                        }
                        else if (highlighted != null)
                        {
                            // Highlight nothing
                            Highlight(null);
                        }
                    }
                    else
                    {
                        // Is there a sidedef here?
                        if (l.Front != null)
                        {
                            // Highlight if not the same
                            if (l.Front.Sector != highlighted)
                            {
                                Highlight(l.Front.Sector);
                            }
                        }
                        else if (highlighted != null)
                        {
                            // Highlight nothing
                            Highlight(null);
                        }
                    }
                }
                else if (highlighted != null)
                {
                    // Highlight nothing
                    Highlight(null);
                }

                //mxd. Find the nearest linedef within default highlight range
                l = General.Map.Map.NearestLinedefRange(mousemappos, 20 / renderer.Scale);
                //mxd. We are not interested in single-sided lines, unless they have zoneboundary flag...
                if (l != null && ((l.Front == null || l.Back == null) && !l.IsFlagSet(ZoneBoundaryFlag)))
                {
                    l = null;
                }

                //mxd. Set as highlighted
                bool redrawrequired = false;
                if (highlightedline != l)
                {
                    highlightedline = l;
                    redrawrequired  = true;
                }

                //mxd. Highlighted environment changed?
                if (oldhighlightedsoundenvironment != highlightedsoundenvironment)
                {
                    oldhighlightedsoundenvironment = highlightedsoundenvironment;
                    redrawrequired = true;
                }

                //mxd. Find the nearest thing within default highlight range
                if (highlightedline == null && highlightedsoundenvironment != null)
                {
                    Thing t = MapSet.NearestThingSquareRange(highlightedsoundenvironment.Things, mousemappos, 10 / renderer.Scale);
                    if (highlightedthing != t)
                    {
                        highlightedthing = t;
                        redrawrequired   = true;
                    }
                }
                else if (highlightedthing != null)
                {
                    highlightedthing = null;
                    redrawrequired   = true;
                }

                //mxd
                if (redrawrequired)
                {
                    // Show highlight info
                    if (highlightedline != null && !highlightedline.IsDisposed)
                    {
                        General.Interface.ShowLinedefInfo(highlightedline);
                    }
                    else if (highlighted != null && !highlighted.IsDisposed)
                    {
                        General.Interface.ShowSectorInfo(highlighted);
                    }
                    else
                    {
                        General.Interface.HideInfo();
                    }

                    // Redraw display
                    General.Interface.RedrawDisplay();
                }
            }
        }
        // This makes sure we are updated with the source linedef information
        public override void Update()
        {
            if (l.Front == null || l.Back == null)
            {
                return;                                               //mxd
            }
            // Find the vertex furthest from the line
            Vertex foundv    = null;
            float  founddist = -1.0f;

            foreach (Sidedef sd in data.Sector.Sidedefs)
            {
                Vertex v = sd.IsFront ? sd.Line.Start : sd.Line.End;
                float  d = l.DistanceToSq(v.Position, false);
                if (d > founddist)
                {
                    foundv    = v;
                    founddist = d;
                }
            }

            if (foundv == null)
            {
                return;                            //mxd
            }
            bool updatesides = false;

            // Align floor with back of line
            if ((l.Args[0] == 1) && (l.Front.Sector == data.Sector))
            {
                Vector3D v1 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Back.Sector.FloorHeight);
                Vector3D v2 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Back.Sector.FloorHeight);
                Vector3D v3 = new Vector3D(foundv.Position.x, foundv.Position.y, data.Sector.FloorHeight);
                data.Floor.plane = (l.SideOfLine(v3) < 0.0f ? new Plane(v1, v2, v3, true) : new Plane(v2, v1, v3, true));

                //mxd. Update only when actually changed
                if (storedfloor != data.Floor.plane)
                {
                    storedfloor = data.Floor.plane;
                    updatesides = true;
                }
            }
            // Align floor with front of line
            else if ((l.Args[0] == 2) && (l.Back.Sector == data.Sector))
            {
                Vector3D v1 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Front.Sector.FloorHeight);
                Vector3D v2 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Front.Sector.FloorHeight);
                Vector3D v3 = new Vector3D(foundv.Position.x, foundv.Position.y, data.Sector.FloorHeight);
                data.Floor.plane = (l.SideOfLine(v3) < 0.0f ? new Plane(v1, v2, v3, true) : new Plane(v2, v1, v3, true));

                //mxd. Update only when actually changed
                if (storedfloor != data.Floor.plane)
                {
                    storedfloor = data.Floor.plane;
                    updatesides = true;
                }
            }

            // Align ceiling with back of line
            if ((l.Args[1] == 1) && (l.Front.Sector == data.Sector))
            {
                Vector3D v1 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Back.Sector.CeilHeight);
                Vector3D v2 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Back.Sector.CeilHeight);
                Vector3D v3 = new Vector3D(foundv.Position.x, foundv.Position.y, data.Sector.CeilHeight);
                data.Ceiling.plane = (l.SideOfLine(v3) > 0.0f ? new Plane(v1, v2, v3, false) : new Plane(v2, v1, v3, false));

                //mxd. Update only when actually changed
                if (storedceiling != data.Ceiling.plane)
                {
                    storedceiling = data.Ceiling.plane;
                    updatesides   = true;
                }
            }
            // Align ceiling with front of line
            else if ((l.Args[1] == 2) && (l.Back.Sector == data.Sector))
            {
                Vector3D v1 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Front.Sector.CeilHeight);
                Vector3D v2 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Front.Sector.CeilHeight);
                Vector3D v3 = new Vector3D(foundv.Position.x, foundv.Position.y, data.Sector.CeilHeight);
                data.Ceiling.plane = (l.SideOfLine(v3) > 0.0f ? new Plane(v1, v2, v3, false) : new Plane(v2, v1, v3, false));

                //mxd. Update only when actually changed
                if (storedceiling != data.Ceiling.plane)
                {
                    storedceiling = data.Ceiling.plane;
                    updatesides   = true;
                }
            }

            //mxd. 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);
                }
            }
        }
        // This makes sure we are updated with the source linedef information
        public override void Update()
        {
            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.Tag == 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 #16
0
        // Mode starts
        public override void OnEngage()
        {
            Cursor.Current = Cursors.WaitCursor;
            base.OnEngage();
            General.Interface.DisplayStatus(StatusType.Busy, "Setting up test environment...");

            CleanUp();

            BuilderPlug.InterfaceForm.AddToInterface();
            lastviewstats = BuilderPlug.InterfaceForm.ViewStats;

            // Export the current map to a temporary WAD file
            tempfile = BuilderPlug.MakeTempFilename(".wad");
            General.Map.ExportToFile(tempfile);

            // Load the map in VPO_DLL
            BuilderPlug.VPO.Start(tempfile, General.Map.Options.LevelName);

            // Determine map boundary
            mapbounds = Rectangle.Round(MapSet.CreateArea(General.Map.Map.Vertices));

            // Create tiles for all points inside the map
            Point               lt        = TileForPoint(mapbounds.Left - Tile.TILE_SIZE, mapbounds.Top - Tile.TILE_SIZE);
            Point               rb        = TileForPoint(mapbounds.Right + Tile.TILE_SIZE, mapbounds.Bottom + Tile.TILE_SIZE);
            Rectangle           tilesrect = new Rectangle(lt.X, lt.Y, rb.X - lt.X, rb.Y - lt.Y);
            NearestLineBlockmap blockmap  = new NearestLineBlockmap(tilesrect);

            for (int x = tilesrect.X; x <= tilesrect.Right; x += Tile.TILE_SIZE)
            {
                for (int y = tilesrect.Y; y <= tilesrect.Bottom; y += Tile.TILE_SIZE)
                {
                    // If the tile is obviously outside the map, don't create it
                    Vector2D pc         = new Vector2D(x + (Tile.TILE_SIZE >> 1), y + (Tile.TILE_SIZE >> 1));
                    Linedef  ld         = MapSet.NearestLinedef(blockmap.GetBlockAt(pc).Lines, pc);
                    float    distancesq = ld.DistanceToSq(pc, true);
                    if (distancesq > (Tile.TILE_SIZE * Tile.TILE_SIZE))
                    {
                        float side = ld.SideOfLine(pc);
                        if ((side > 0.0f) && (ld.Back == null))
                        {
                            continue;
                        }
                    }

                    Point tp = new Point(x, y);
                    tiles.Add(tp, new Tile(tp));
                }
            }

            QueuePoints(0);

            // Make an image to draw on.
            // The BitmapImage for Doom Builder's resources must be Format32bppArgb and NOT using color correction,
            // otherwise DB will make a copy of the bitmap when LoadImage() is called! This is normally not a problem,
            // but we want to keep drawing to the same bitmap.
            int width  = General.NextPowerOf2(General.Interface.Display.ClientSize.Width);
            int height = General.NextPowerOf2(General.Interface.Display.ClientSize.Height);

            canvas = new Bitmap(width, height, PixelFormat.Format32bppArgb);
            image  = new DynamicBitmapImage(canvas, "_CANVAS_");
            image.UseColorCorrection = false;
            image.MipMapLevels       = 1;
            image.LoadImage();
            image.CreateTexture();

            // Make custom presentation
            CustomPresentation p = new CustomPresentation();

            p.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Mask, 1f, false));
            p.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
            p.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
            renderer.SetPresentation(p);

            // Setup processing
            nextupdate = DateTime.Now + new TimeSpan(0, 0, 0, 0, 100);
            General.Interface.EnableProcessing();
            processingenabled = true;

            RedrawAllTiles();
            Cursor.Current = Cursors.Default;
            General.Interface.SetCursor(Cursors.Cross);
            General.Interface.DisplayReady();
        }
		// Mouse moves
		public override void OnMouseMove(MouseEventArgs e)
		{
			base.OnMouseMove(e);

			// Not holding any buttons?
			if(e.Button == MouseButtons.None)
			{
				General.Interface.SetCursor(Cursors.Default);

				//mxd. Find the nearest linedef within default highlight range
				Linedef nl = General.Map.Map.NearestLinedefRange(mousemappos, 20 / renderer.Scale);
				//mxd. We are not interested in single-sided lines (unless they have "blocksound" flag set)...
				if(nl != null && (nl.Front == null || nl.Back == null) && !nl.IsFlagSet(BlockSoundFlag)) nl = null;

				//mxd. Set as highlighted
				bool redrawrequired = (highlightedline != nl);
				highlightedline = nl;
				
				// Find the nearest linedef within highlight range
				Linedef l = General.Map.Map.NearestLinedef(mousemappos);
				if(l != null)
				{
					// Check on which side of the linedef the mouse is
					double side = l.SideOfLine(mousemappos);
					if(side > 0)
					{
						// Is there a sidedef here?
						if(l.Back != null)
						{
							// Highlight if not the same
							if(l.Back.Sector != highlighted)
							{
								Highlight(l.Back.Sector);
								redrawrequired = true; //mxd
							}
						}
						else if(highlighted != null)
						{
							// Highlight nothing
							Highlight(null);
							redrawrequired = true; //mxd
						}
					}
					else
					{
						// Is there a sidedef here?
						if(l.Front != null)
						{
							// Highlight if not the same
							if(l.Front.Sector != highlighted)
							{
								Highlight(l.Front.Sector);
								redrawrequired = true; //mxd
							}
						}
						else if(highlighted != null)
						{
							// Highlight nothing
							Highlight(null);
							redrawrequired = true; //mxd
						}
					}
				}
				else if(highlighted != null)
				{
					// Highlight nothing
					Highlight(null);
					redrawrequired = true; //mxd
				}

				//mxd
				if(redrawrequired)
				{
					// Show highlight info
					if(highlightedline != null && !highlightedline.IsDisposed)
						General.Interface.ShowLinedefInfo(highlightedline);
					else if(highlighted != null && !highlighted.IsDisposed)
						General.Interface.ShowSectorInfo(highlighted);
					else
						General.Interface.HideInfo();
					
					// Redraw display
					General.Interface.RedrawDisplay();
				}
			}
		}
        // Mouse moves
        public override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            // Not in any editing mode?
            if ((mode == ModifyMode.None) && (e.Button == MouseButtons.None))
            {
                // Find the nearest linedef within highlight range
                Linedef l = General.Map.Map.NearestLinedef(mousemappos);
                if (l != null)
                {
                    // Check on which side of the linedef the mouse is
                    float side = l.SideOfLine(mousemappos);
                    if (side > 0)
                    {
                        // Is there a sidedef here?
                        if (l.Back != null)
                        {
                            // Highlight if not the same
                            if (l.Back.Sector != highlighted)
                            {
                                Highlight(l.Back.Sector);
                            }
                        }
                        else
                        {
                            // Highlight nothing
                            if (highlighted != null)
                            {
                                Highlight(null);
                            }
                        }
                    }
                    else
                    {
                        // Is there a sidedef here?
                        if (l.Front != null)
                        {
                            // Highlight if not the same
                            if (l.Front.Sector != highlighted)
                            {
                                Highlight(l.Front.Sector);
                            }
                        }
                        else
                        {
                            // Highlight nothing
                            if (highlighted != null)
                            {
                                Highlight(null);
                            }
                        }
                    }
                }
                else
                {
                    // Highlight nothing
                    if (highlighted != null)
                    {
                        Highlight(null);
                    }
                }
            }
            // Adjusting mode?
            else if (mode == ModifyMode.Adjusting)
            {
                // Calculate change in position
                Point delta = Cursor.Position - new Size(editstartpos);

                if (General.Interface.ShiftState)
                {
                    // Adjust selected sectors
                    int index = 0;
                    ICollection <Sector> orderedselection = General.Map.Map.GetSelectedSectors(true);
                    foreach (Sector s in orderedselection)
                    {
                        int basebrightness = sectorbrightness[index];

                        // Adjust brightness
                        s.Brightness = basebrightness - delta.Y;
                        if (s.Brightness > 255)
                        {
                            s.Brightness = 255;
                        }
                        if (s.Brightness < 0)
                        {
                            s.Brightness = 0;
                        }
                        index++;
                    }
                }
                else
                {
                    // Adjust selected sectors
                    int index = 0;
                    ICollection <Sector> orderedselection = General.Map.Map.GetSelectedSectors(true);
                    foreach (Sector s in orderedselection)
                    {
                        int basebrightness = sectorbrightness[index];

                        // Adjust brightness
                        s.Brightness = General.Map.Config.BrightnessLevels.GetNearest(basebrightness - delta.Y);
                        index++;
                    }
                }

                // Update
                General.Interface.RefreshInfo();
                UpdateSelectedLabels();
                UpdateOverlay();
                renderer.Present();
            }
        }
        // This highlights a new region
        protected void Highlight(bool buttonspressed)
        {
            LinedefSide newnearest;

            // Mouse inside?
            if (mouseinside)
            {
                // Highlighting from a new sidedef?
                Linedef nl = General.Map.Map.NearestLinedef(mousemappos);
                if (nl != null)
                {
                    float side = nl.SideOfLine(mousemappos);
                    newnearest = new LinedefSide(nl, (side <= 0.0f));
                    if (newnearest != nearestside)
                    {
                        // Only change when buttons are not pressed
                        if (!buttonspressed || (editside == newnearest))
                        {
                            // Find new sector
                            General.Interface.SetCursor(Cursors.AppStarting);
                            nearestside = newnearest;
                            allsides    = Tools.FindPotentialSectorAt(mousemappos);
                            if (allsides != null)
                            {
                                alllines = new List <Linedef>(allsides.Count);
                                foreach (LinedefSide sd in allsides)
                                {
                                    alllines.Add(sd.Line);
                                }
                            }
                            else
                            {
                                alllines = null;
                            }
                            General.Interface.SetCursor(Cursors.Default);
                        }
                        else
                        {
                            // Don't highlight this one
                            nearestside = null;
                            allsides    = null;
                            alllines    = null;
                        }

                        // Redraw overlay
                        DrawGeometry();
                        renderer.Present();
                    }
                }
            }
            else
            {
                // No valid region
                nearestside = null;
                allsides    = null;
                alllines    = null;

                // Redraw overlay
                DrawGeometry();
                renderer.Present();
            }
        }
        // Mode is engaged
        public override void OnEngage()
        {
            base.OnEngage();

            // Update projection (mxd)
            General.Map.CRenderer3D.CreateProjection();

            // Update the used textures
            General.Map.Data.UpdateUsedTextures();

            // Fill the blockmap
            FillBlockMap();

            //mxd. Synch camera position to cursor position or center of the screen in 2d-mode
            if (General.Settings.GZSynchCameras)
            {
                // Keep previous camera position if Control is held and camera was previously moved in Visual mode
                if (!General.Interface.CtrlState || General.Map.VisualCamera.Position.GetLengthSq() == 0)
                {
                    //If initial position is inside or nearby a sector - adjust camera.z accordingly
                    float  posz          = General.Map.VisualCamera.Position.z;
                    Sector nearestsector = General.Map.Map.GetSectorByCoordinates(initialcameraposition, blockmap);

                    if (nearestsector == null)
                    {
                        Linedef nearestline = MapSet.NearestLinedef(General.Map.Map.Linedefs, initialcameraposition);
                        if (nearestline != null)
                        {
                            float   side        = nearestline.SideOfLine(initialcameraposition);
                            Sidedef nearestside = (side < 0.0f ? nearestline.Front : nearestline.Back) ?? (side < 0.0f ? nearestline.Back : nearestline.Front);
                            if (nearestside != null)
                            {
                                nearestsector = nearestside.Sector;
                            }
                        }
                    }

                    if (nearestsector != null)
                    {
                        int sectorheight = nearestsector.CeilHeight - nearestsector.FloorHeight;
                        if (sectorheight < 41)
                        {
                            posz = nearestsector.FloorHeight + Math.Max(16, sectorheight / 2);
                        }
                        else if (General.Map.VisualCamera.Position.z < nearestsector.FloorHeight + 41)
                        {
                            posz = nearestsector.FloorHeight + 41;                             // same as in doom
                        }
                        else if (General.Map.VisualCamera.Position.z > nearestsector.CeilHeight)
                        {
                            posz = nearestsector.CeilHeight - 4;
                        }
                    }

                    General.Map.VisualCamera.Position = new Vector3D(initialcameraposition.x, initialcameraposition.y, posz);
                }
            }
            else
            {
                General.Map.VisualCamera.PositionAtThing();
            }

            // Start special input mode
            General.Interface.EnableProcessing();
            General.Interface.StartExclusiveMouseInput();
        }
        //mxd
        protected void AlignTextureToClosestLine(bool alignx, bool aligny)
        {
            if (!(mode.HighlightedObject is BaseVisualSector))
            {
                return;
            }

            // Do we need to align this? (and also grab texture scale while we are at it)
            float scaleX, scaleY;
            bool  isFloor = (geometrytype == VisualGeometryType.FLOOR);

            if (mode.HighlightedTarget is VisualFloor)
            {
                Sector      target;
                VisualFloor vf = (VisualFloor)mode.HighlightedTarget;

                // Use the control sector if the floor belongs to a 3D floor
                if (vf.ExtraFloor == null)
                {
                    target = vf.Sector.Sector;
                }
                else
                {
                    target = vf.GetControlSector();
                }

                // Check texture
                if (target.FloorTexture != (isFloor ? Sector.Sector.FloorTexture : Sector.Sector.CeilTexture))
                {
                    return;
                }

                scaleX = target.Fields.GetValue("xscalefloor", 1.0f);
                scaleY = target.Fields.GetValue("yscalefloor", 1.0f);
            }
            else
            {
                Sector        target;
                VisualCeiling vc = (VisualCeiling)mode.HighlightedTarget;

                // Use the control sector if the ceiling belongs to a 3D floor
                if (vc.ExtraFloor == null)
                {
                    target = vc.Sector.Sector;
                }
                else
                {
                    target = vc.GetControlSector();
                }

                // Check texture
                if (target.CeilTexture != (isFloor ? Sector.Sector.FloorTexture : Sector.Sector.CeilTexture))
                {
                    return;
                }

                scaleX = target.Fields.GetValue("xscaleceiling", 1.0f);
                scaleY = target.Fields.GetValue("yscaleceiling", 1.0f);
            }

            //find a linedef to align to
            Vector2D hitpos = mode.GetHitPosition();

            if (!hitpos.IsFinite())
            {
                return;
            }

            //align to line of highlighted sector, which is closest to hitpos
            Sector         highlightedSector = ((BaseVisualSector)mode.HighlightedObject).Sector;
            List <Linedef> lines             = new List <Linedef>();

            foreach (Sidedef side in highlightedSector.Sidedefs)
            {
                lines.Add(side.Line);
            }

            Linedef targetLine = MapSet.NearestLinedef(lines, hitpos);

            if (targetLine == null)
            {
                return;
            }

            bool isFront = targetLine.SideOfLine(hitpos) > 0;

            Sector.Sector.Fields.BeforeFieldsChange();

            //find an angle to rotate texture
            float sourceAngle = (float)Math.Round(General.ClampAngle(isFront ? -Angle2D.RadToDeg(targetLine.Angle) + 90 : -Angle2D.RadToDeg(targetLine.Angle) - 90), 1);

            if (!isFront)
            {
                sourceAngle = General.ClampAngle(sourceAngle + 180);
            }

            //update angle
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "rotationfloor" : "rotationceiling"), sourceAngle, 0f);

            // Scale texture if it's a slope and the appropriate option is set
            if (level.plane.Normal.z != 1.0f && BuilderPlug.Me.ScaleTexturesOnSlopes != 2)
            {
                Vector2D basescale = new Vector2D(1.0f, 1.0f);

                // User wants to use the current scale as a base?
                if (BuilderPlug.Me.ScaleTexturesOnSlopes == 1)
                {
                    basescale.x = scaleX;
                    basescale.y = scaleY;
                }

                // Create a unit vector of the direction of the target line in 3D space
                Vector3D targetlinevector = new Line3D(new Vector3D(targetLine.Start.Position, level.plane.GetZ(targetLine.Start.Position)), new Vector3D(targetLine.End.Position, level.plane.GetZ(targetLine.End.Position))).GetDelta().GetNormal();

                // Get a perpendicular vector of the target line in 3D space. This is used to get the slope angle relative to the target line
                Vector3D targetlineperpendicular = Vector3D.CrossProduct(targetlinevector, level.plane.Normal);

                if (alignx)
                {
                    scaleX = Math.Abs(basescale.x * (1.0f / (float)Math.Cos(targetlinevector.GetAngleZ())));
                }

                if (aligny)
                {
                    scaleY = Math.Abs(basescale.y * (1.0f / (float)Math.Cos(targetlineperpendicular.GetAngleZ())));
                }
            }

            //set scale
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xscalefloor" : "xscaleceiling"), scaleX, 1.0f);
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "yscalefloor" : "yscaleceiling"), scaleY, 1.0f);

            //update offset
            float    distToStart = Vector2D.Distance(hitpos, targetLine.Start.Position);
            float    distToEnd   = Vector2D.Distance(hitpos, targetLine.End.Position);
            Vector2D offset      = (distToStart < distToEnd ? targetLine.Start.Position : targetLine.End.Position).GetRotated(Angle2D.DegToRad(sourceAngle));

            if (alignx)
            {
                if (Texture != null && Texture.IsImageLoaded)
                {
                    offset.x %= Texture.Width / scaleX;
                }
                UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f);
            }

            if (aligny)
            {
                if (Texture != null && Texture.IsImageLoaded)
                {
                    offset.y %= Texture.Height / scaleY;
                }
                UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f);
            }

            //update geometry
            Sector.UpdateSectorGeometry(false);
        }
Exemple #22
0
        // Mouse moving
        public override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (selecting)
            {
                ClearHighlighted();
                RenderMultiSelection();
            }
            else
            {
                // ano - a lot of this is from codeimp's buildermodes plugins
                if (e.Button == MouseButtons.None)
                {
                    Linedef l = General.Map.Map.NearestLinedefRange(
                        mousemappos,
                        HIGHLIGHT_RANGE / renderer.Scale);

                    Thing t = MapSet.NearestThingSquareRange(
                        General.Map.ThingsFilter.VisibleThings,
                        mousemappos,
                        HIGHLIGHT_THINGS_RANGE / renderer.Scale);

                    Vertex v = General.Map.Map.NearestVertexSquareRange(
                        mousemappos,
                        HIGHLIGHT_VERTICES_RANGE / renderer.Scale);

                    Sector  s  = null;
                    Linedef ls = l;
                    if (ls == null)
                    {
                        ls = General.Map.Map.NearestLinedef(mousemappos);
                    }

                    if (ls != null)
                    {
                        // Check on which side of the linedef the mouse is
                        float side = ls.SideOfLine(mousemappos);

                        if (side > 0)
                        {
                            // Is there a sidedef here?
                            if (ls.Back != null)
                            {
                                s = ls.Back.Sector;
                            }
                        }
                        else if (ls.Front != null)
                        {
                            s = ls.Front.Sector;
                        }
                    }

                    HighlightType htype = HighlightType.Null;

                    if (v != null)
                    {
                        htype = HighlightType.Vertex;
                    }


                    if (t != null)
                    {
                        if (htype == HighlightType.Null)
                        {
                            htype = HighlightType.Thing;
                        }
                        else if (htype == HighlightType.Vertex &&
                                 v.DistanceToSq(mousemappos) > t.DistanceToSq(mousemappos))
                        {
                            // figure out which is closer and highlight that one
                            htype = HighlightType.Thing;
                        }
                    }


                    if (l != null)
                    {
                        switch (htype)
                        {
                        case HighlightType.Vertex:
                            break;

                        case HighlightType.Thing:
                            if (l.SafeDistanceToSq(mousemappos, false) < t.DistanceToSq(mousemappos))
                            {
                                // figure out which is closer and highlight that one
                                htype = HighlightType.Linedef;
                            }
                            break;

                        default:
                            htype = HighlightType.Linedef;
                            break;
                        }
                    }

                    if (htype == HighlightType.Null && s != null)
                    {
                        htype = HighlightType.Sector;
                    }

                    switch (htype)
                    {
                    case HighlightType.Linedef:
                        HighlightLinedef(l);
                        break;

                    case HighlightType.Sector:
                        HighlightSector(s);
                        break;

                    case HighlightType.Vertex:
                        HighlightVertex(v);
                        break;

                    case HighlightType.Thing:
                        HighlightThing(t);
                        break;

                    case HighlightType.Null:
                    default:
                        // highlight nothing
                        ClearHighlighted();
                        renderer.Present();
                        break;
                    } // switch
                }

                if (renderer.StartOverlay(true))
                {
                    DrawCursor();

                    renderer.Finish();
                    renderer.Present();
                }
            }
        }
Exemple #23
0
        //mxd
        protected void AlignTextureToClosestLine(bool alignx, bool aligny)
        {
            if (!(mode.HighlightedObject is BaseVisualSector))
            {
                return;
            }

            // Do we need to align this? (and also grab texture scale while we are at it)
            float scaleX, scaleY;
            bool  isFloor = (geometrytype == VisualGeometryType.FLOOR);

            if (mode.HighlightedTarget is VisualFloor)
            {
                VisualFloor target = (VisualFloor)mode.HighlightedTarget;

                // Check texture
                if (target.Sector.Sector.FloorTexture != (isFloor ? Sector.Sector.FloorTexture : Sector.Sector.CeilTexture))
                {
                    return;
                }

                scaleX = target.Sector.Sector.Fields.GetValue("xscalefloor", 1.0f);
                scaleY = target.Sector.Sector.Fields.GetValue("yscalefloor", 1.0f);
            }
            else
            {
                VisualCeiling target = (VisualCeiling)mode.HighlightedTarget;

                // Check texture
                if (target.Sector.Sector.CeilTexture != (isFloor ? Sector.Sector.FloorTexture : Sector.Sector.CeilTexture))
                {
                    return;
                }

                scaleX = target.Sector.Sector.Fields.GetValue("xscaleceiling", 1.0f);
                scaleY = target.Sector.Sector.Fields.GetValue("yscaleceiling", 1.0f);
            }

            //find a linedef to align to
            Vector2D hitpos = mode.GetHitPosition();

            if (!hitpos.IsFinite())
            {
                return;
            }

            //align to line of highlighted sector, which is closest to hitpos
            Sector         highlightedSector = ((BaseVisualSector)mode.HighlightedObject).Sector;
            List <Linedef> lines             = new List <Linedef>();

            foreach (Sidedef side in highlightedSector.Sidedefs)
            {
                lines.Add(side.Line);
            }

            Linedef targetLine = MapSet.NearestLinedef(lines, hitpos);

            if (targetLine == null)
            {
                return;
            }

            bool isFront = targetLine.SideOfLine(hitpos) > 0;

            Sector.Sector.Fields.BeforeFieldsChange();

            //find an angle to rotate texture
            float sourceAngle = (float)Math.Round(General.ClampAngle(isFront ? -Angle2D.RadToDeg(targetLine.Angle) + 90 : -Angle2D.RadToDeg(targetLine.Angle) - 90), 1);

            if (!isFront)
            {
                sourceAngle = General.ClampAngle(sourceAngle + 180);
            }

            //update angle
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "rotationfloor" : "rotationceiling"), sourceAngle, 0f);

            //set scale
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xscalefloor" : "xscaleceiling"), scaleX, 1.0f);
            UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "yscalefloor" : "yscaleceiling"), scaleY, 1.0f);

            //update offset
            float    distToStart = Vector2D.Distance(hitpos, targetLine.Start.Position);
            float    distToEnd   = Vector2D.Distance(hitpos, targetLine.End.Position);
            Vector2D offset      = (distToStart < distToEnd ? targetLine.Start.Position : targetLine.End.Position).GetRotated(Angle2D.DegToRad(sourceAngle));

            if (alignx)
            {
                if (Texture != null && Texture.IsImageLoaded)
                {
                    offset.x %= Texture.Width / scaleX;
                }
                UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f);
            }

            if (aligny)
            {
                if (Texture != null && Texture.IsImageLoaded)
                {
                    offset.y %= Texture.Height / scaleY;
                }
                UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f);
            }

            //update geometry
            Sector.UpdateSectorGeometry(false);
        }
Exemple #24
0
        // Mouse moves
        public override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (selectpressed && !editpressed && !selecting)
            {
                // Check if moved enough pixels for multiselect
                Vector2D delta = mousedownpos - mousepos;
                if ((Math.Abs(delta.x) > 2) || (Math.Abs(delta.y) > 2))
                {
                    // Start multiselecting
                    StartMultiSelection();
                }
            }
            else if (e.Button == MouseButtons.None)
            {
                SlopeVertex oldhighlight         = highlightedslope;
                Sector      oldhighlightedsector = highlightedsector;

                float distance = float.MaxValue;
                float d;

                highlightedslope = null;

                foreach (SlopeVertexGroup svg in BuilderPlug.Me.SlopeVertexGroups)
                {
                    foreach (SlopeVertex sv in svg.Vertices)
                    {
                        d = Vector2D.Distance(sv.Pos, mousemappos);

                        if (d <= BuilderModes.BuilderPlug.Me.HighlightRange / renderer.Scale && d < distance)
                        {
                            distance         = d;
                            highlightedslope = sv;
                        }
                    }
                }

                // If no slope vertex is highlighted, check if a sector should be
                if (highlightedslope == null)
                {
                    // Find the nearest linedef within highlight range
                    Linedef l = General.Map.Map.NearestLinedef(mousemappos);
                    if (l != null)
                    {
                        // Check on which side of the linedef the mouse is
                        float side = l.SideOfLine(mousemappos);
                        if (side > 0)
                        {
                            // Is there a sidedef here?
                            if (l.Back != null)
                            {
                                // Highlight if not the same
                                if (l.Back.Sector != highlightedsector)
                                {
                                    HighlightSector(l.Back.Sector);
                                }
                            }
                            else
                            {
                                // Highlight nothing
                                if (highlightedsector != null)
                                {
                                    HighlightSector(null);
                                }
                            }
                        }
                        else
                        {
                            // Is there a sidedef here?
                            if (l.Front != null)
                            {
                                // Highlight if not the same
                                if (l.Front.Sector != highlightedsector)
                                {
                                    HighlightSector(l.Front.Sector);
                                }
                            }
                            else
                            {
                                // Highlight nothing
                                if (highlightedsector != null)
                                {
                                    HighlightSector(null);
                                }
                            }
                        }
                    }
                }
                else
                {
                    HighlightSector(null);
                }

                if (highlightedslope != oldhighlight)
                {
                    updateOverlaySurfaces();
                    UpdateOverlay();
                    General.Interface.RedrawDisplay();
                }
            }
            else if (dragging && highlightedslope != null)
            {
                Vector2D newpos = SnapToNearest(mousemappos);
                Vector2D offset = highlightedslope.Pos - newpos;

                foreach (SlopeVertex sl in GetSelectedSlopeVertices())
                {
                    sl.Pos -= offset;
                }

                highlightedslope.Pos = newpos;

                General.Map.IsChanged = true;

                updateOverlaySurfaces();
                UpdateOverlay();
                General.Interface.RedrawDisplay();
            }
            else if (selecting)
            {
                UpdateOverlay();
                General.Interface.RedrawDisplay();
            }
        }
        // This runs the check
        public override void Run()
        {
            BlockMap <BlockEntry> blockmap = BuilderPlug.Me.ErrorCheckForm.BlockMap;
            int progress     = 0;
            int stepprogress = 0;

            // Go for all the things
            foreach (Thing t in General.Map.Map.Things)
            {
                ThingTypeInfo info    = General.Map.Data.GetThingInfo(t.Type);
                bool          stucked = false;

                // Check this thing for getting stucked?
                if ((info.ErrorCheck == ThingTypeInfo.THING_ERROR_INSIDE_STUCKED) &&
                    (info.Blocking > ThingTypeInfo.THING_BLOCKING_NONE))
                {
                    // Make square coordinates from thing
                    float    blockingsize = t.Size - ALLOWED_STUCK_DISTANCE;
                    Vector2D lt           = new Vector2D(t.Position.x - blockingsize, t.Position.y - blockingsize);
                    Vector2D rb           = new Vector2D(t.Position.x + blockingsize, t.Position.y + blockingsize);

                    // Go for all the lines to see if this thing is stucked
                    List <BlockEntry>             blocks         = blockmap.GetSquareRange(new RectangleF(lt.x, lt.y, (rb.x - lt.x), (rb.y - lt.y)));
                    Dictionary <Linedef, Linedef> doneblocklines = new Dictionary <Linedef, Linedef>(blocks.Count * 3);
                    foreach (BlockEntry b in blocks)
                    {
                        foreach (Linedef l in b.Lines)
                        {
                            // Only test when sinlge-sided and not already checked
                            if ((l.Back == null) && !doneblocklines.ContainsKey(l))
                            {
                                // Test if line ends are inside the thing
                                if (PointInRect(lt, rb, l.Start.Position) ||
                                    PointInRect(lt, rb, l.End.Position))
                                {
                                    // Thing stucked in line!
                                    stucked = true;
                                }
                                // Test if the line intersects the square
                                else if (Line2D.GetIntersection(l.Start.Position, l.End.Position, lt.x, lt.y, rb.x, lt.y) ||
                                         Line2D.GetIntersection(l.Start.Position, l.End.Position, rb.x, lt.y, rb.x, rb.y) ||
                                         Line2D.GetIntersection(l.Start.Position, l.End.Position, rb.x, rb.y, lt.x, rb.y) ||
                                         Line2D.GetIntersection(l.Start.Position, l.End.Position, lt.x, rb.y, lt.x, lt.y))
                                {
                                    // Thing stucked in line!
                                    stucked = true;
                                }

                                // Checked
                                doneblocklines.Add(l, l);
                            }
                        }
                    }
                }

                // Stucked?
                if (stucked)
                {
                    // Make result
                    SubmitResult(new ResultStuckedThing(t));
                }
                else
                {
                    // Check this thing for being outside the map?
                    if (info.ErrorCheck >= ThingTypeInfo.THING_ERROR_INSIDE)
                    {
                        // Get the nearest line to see if the thing is outside the map
                        bool    outside = false;
                        Linedef l       = General.Map.Map.NearestLinedef(t.Position);
                        if (l.SideOfLine(t.Position) <= 0)
                        {
                            outside = (l.Front == null);
                        }
                        else
                        {
                            outside = (l.Back == null);
                        }

                        // Outside the map?
                        if (outside)
                        {
                            // Make result
                            SubmitResult(new ResultThingOutside(t));
                        }
                    }
                }

                // Handle thread interruption
                try { Thread.Sleep(0); }
                catch (ThreadInterruptedException) { return; }

                // We are making progress!
                if ((++progress / PROGRESS_STEP) > stepprogress)
                {
                    stepprogress = (progress / PROGRESS_STEP);
                    AddProgress(1);
                }
            }
        }
Exemple #26
0
        // This makes sure we are updated with the source linedef information
        public override void Update()
        {
            Linedef l = linedef;

            // Find the vertex furthest from the line
            Vertex foundv    = null;
            float  founddist = -1.0f;

            foreach (Sidedef sd in data.Sector.Sidedefs)
            {
                Vertex v = sd.IsFront ? sd.Line.Start : sd.Line.End;
                float  d = l.DistanceToSq(v.Position, false);
                if (d > founddist)
                {
                    foundv    = v;
                    founddist = d;
                }
            }

            // Align floor with back of line
            if ((l.Args[0] == 1) && (l.Front.Sector == data.Sector) && (l.Back != null))
            {
                Vector3D v1 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Back.Sector.FloorHeight);
                Vector3D v2 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Back.Sector.FloorHeight);
                Vector3D v3 = new Vector3D(foundv.Position.x, foundv.Position.y, data.Sector.FloorHeight);
                if (l.SideOfLine(v3) < 0.0f)
                {
                    data.Floor.plane = new Plane(v1, v2, v3, true);
                }
                else
                {
                    data.Floor.plane = new Plane(v2, v1, v3, true);
                }
                SectorData sd = data.Mode.GetSectorData(l.Back.Sector);
                sd.AddUpdateSector(data.Sector, true);
            }
            // Align floor with front of line
            else if ((l.Args[0] == 2) && (l.Back.Sector == data.Sector) && (l.Front != null))
            {
                Vector3D v1 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Front.Sector.FloorHeight);
                Vector3D v2 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Front.Sector.FloorHeight);
                Vector3D v3 = new Vector3D(foundv.Position.x, foundv.Position.y, data.Sector.FloorHeight);
                if (l.SideOfLine(v3) < 0.0f)
                {
                    data.Floor.plane = new Plane(v1, v2, v3, true);
                }
                else
                {
                    data.Floor.plane = new Plane(v2, v1, v3, true);
                }
                SectorData sd = data.Mode.GetSectorData(l.Front.Sector);
                sd.AddUpdateSector(data.Sector, true);
            }

            // Align ceiling with back of line
            if ((l.Args[1] == 1) && (l.Front.Sector == data.Sector) && (l.Back != null))
            {
                Vector3D v1 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Back.Sector.CeilHeight);
                Vector3D v2 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Back.Sector.CeilHeight);
                Vector3D v3 = new Vector3D(foundv.Position.x, foundv.Position.y, data.Sector.CeilHeight);
                if (l.SideOfLine(v3) > 0.0f)
                {
                    data.Ceiling.plane = new Plane(v1, v2, v3, false);
                }
                else
                {
                    data.Ceiling.plane = new Plane(v2, v1, v3, false);
                }
                SectorData sd = data.Mode.GetSectorData(l.Back.Sector);
                sd.AddUpdateSector(data.Sector, true);
            }
            // Align ceiling with front of line
            else if ((l.Args[1] == 2) && (l.Back.Sector == data.Sector) && (l.Front != null))
            {
                Vector3D v1 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Front.Sector.CeilHeight);
                Vector3D v2 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Front.Sector.CeilHeight);
                Vector3D v3 = new Vector3D(foundv.Position.x, foundv.Position.y, data.Sector.CeilHeight);
                if (l.SideOfLine(v3) > 0.0f)
                {
                    data.Ceiling.plane = new Plane(v1, v2, v3, false);
                }
                else
                {
                    data.Ceiling.plane = new Plane(v2, v1, v3, false);
                }
                SectorData sd = data.Mode.GetSectorData(l.Front.Sector);
                sd.AddUpdateSector(data.Sector, true);
            }
        }