Пример #1
0
        public void write(string mapName, MapSet map, XmlWriter writer)
        {
            writer.WriteStartElement("map");
            writer.WriteAttributeString("name", mapName);

            writeSectors(map, writer);
            writeLines(map, writer);
            writeSides(map, writer);
            writeThings(map, writer);

            writer.WriteEndElement();
        }
Пример #2
0
        void writeLines(MapSet map, XmlWriter writer)
        {
            writer.WriteStartElement("lines");

            foreach (Linedef l in map.Linedefs) {
                writer.WriteStartElement("line");

                writer.WriteAttributeString("idx", l.Index.ToString());
                writer.WriteAttributeString("action", l.Action.ToString());
                writer.WriteAttributeString("tag", l.Tag.ToString());
                writer.WriteAttributeString("activate", l.Activate.ToString());
                if (l.Args.Length > 0) {
                    StringBuilder sb = new StringBuilder();
                    bool any = false;
                    foreach (int i in l.Args) {
                        if (any)
                            sb.Append(",");
                        sb.Append(i.ToString());
                        any = true;
                    }
                    writer.WriteAttributeString("action-args", sb.ToString());
                }

                MapWriter.writeVertex(writer, l.Line.v1);
                MapWriter.writeVertex(writer, l.Line.v2);

                writer.WriteStartElement("flags");
                foreach (String str in l.GetFlags().Keys) {
                    bool value = l.GetFlags()[str];
                    if (value == false)
                        continue;
                    writer.WriteStartElement("flag");
                    writer.WriteAttributeString("name",str);
                    writer.WriteAttributeString("value", value.ToString());
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();

                writeFields(l.Fields, writer);

                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }
Пример #3
0
        // Disposer
        public override void Dispose()
        {
            // Not already disposed?
            if (!isdisposed)
            {
                // Already set isdisposed so that changes can be prohibited
                isdisposed = true;

                if (map == General.Map.Map)
                {
                    General.Map.UndoRedo.RecRemThing(this);
                }

                // Remove from main list
                map.RemoveThing(listindex);

                // Clean up
                map    = null;
                sector = null;

                // Dispose base
                base.Dispose();
            }
        }
Пример #4
0
        public void MapSelect(int SelectItemPosition)
        {
            if (SelectItemPosition >= 0 && ExamContext != null)
            {
                //通过对应的KeyValue 里面进行取值

                var SelectMapItem = lstMapLine[SelectItemPosition];
                //var SelectMapItem = dataService.GetAllMapLines().Where(x=>x.Id== SelectItemPosition).FirstOrDefault();
                if (SelectItemPosition == 0)
                {
                    dataService.SaveDefaultMapId(0);
                    return;
                }
                if (SelectMapItem.Points != null)
                {
                    var mapSet = new MapSet(SelectMapItem.Points.ToMapPoints());
                    //把地图选择信息保存起来后续需要可以直接取
                    MapName         = SelectMapItem.Name;
                    ExamContext.Map = mapSet;
                    dataService.SaveDefaultMapId(SelectMapItem.Id);
                    Logger.InfoFormat("##保存地图取出序号:{0},{1}", SelectMapItem.Id, MapName);
                }
            }
        }
Пример #5
0
        private static void CreateSprites(MapSet map, List <BuildSprite> buildsprites, List <BuildSector> sectors)
        {
            // Create sprites
            map.SetCapacity(0, 0, 0, 0, map.Things.Count + buildsprites.Count);

            for (int i = 0; i < buildsprites.Count; i++)
            {
                var bs = buildsprites[i];

                // Link sector
                if (bs.SectorIndex < sectors.Count)
                {
                    bs.Sector = sectors[bs.SectorIndex].Sector;
                }
                else
                {
                    General.ErrorLogger.Add(ErrorType.Warning, "Sprite " + i + " references non-existing sector " + bs.SectorIndex);
                }

                // Create new item
                Thing t = map.CreateThing();
                t.Update(bs);
            }
        }
Пример #6
0
 // After deserialization
 internal void PostDeserialize(MapSet map)
 {
     triangles.PostDeserialize(map);
     updateneeded        = true;
     triangulationneeded = true;
 }
        // This moves the selected geometry relatively
        // Returns true when geometry has actually moved
        private bool MoveGeometryRelative(Vector2D offset, bool snapgrid, bool snapnearest)
        {
            Vector2D oldpos = dragitem.Position;
            Vector2D anchorpos = dragitemposition + offset;
            Vector2D tl, br;

            // don't move if the offset contains invalid data
            if (!offset.IsFinite())
            {
                return(false);
            }

            // Find the outmost vertices
            tl = br = oldpositions[0];
            for (int i = 0; i < oldpositions.Count; i++)
            {
                if (oldpositions[i].x < tl.x)
                {
                    tl.x = (int)oldpositions[i].x;
                }
                if (oldpositions[i].x > br.x)
                {
                    br.x = (int)oldpositions[i].x;
                }
                if (oldpositions[i].y > tl.y)
                {
                    tl.y = (int)oldpositions[i].y;
                }
                if (oldpositions[i].y < br.y)
                {
                    br.y = (int)oldpositions[i].y;
                }
            }

            // Snap to nearest?
            if (snapnearest)
            {
                // Find nearest unselected vertex within range
                Vertex nv = MapSet.NearestVertexSquareRange(unselectedverts, anchorpos, BuilderPlug.Me.StitchRange / renderer.Scale);
                if (nv != null)
                {
                    // Move the dragged item
                    dragitem.Move(nv.Position);

                    // Adjust the offset
                    offset = nv.Position - dragitemposition;

                    // Do not snap to grid!
                    snapgrid = false;
                }
                else
                {
                    // Find the nearest unselected line within range
                    Linedef nl = MapSet.NearestLinedefRange(snaptolines, anchorpos, BuilderPlug.Me.StitchRange / renderer.Scale);
                    if (nl != null)
                    {
                        // Snap to grid?
                        if (snaptogrid)
                        {
                            // Get grid intersection coordinates
                            List <Vector2D> coords = nl.GetGridIntersections();

                            // Find nearest grid intersection
                            float    found_distance = float.MaxValue;
                            Vector2D found_coord    = new Vector2D();
                            foreach (Vector2D v in coords)
                            {
                                Vector2D delta = anchorpos - v;
                                if (delta.GetLengthSq() < found_distance)
                                {
                                    found_distance = delta.GetLengthSq();
                                    found_coord    = v;
                                }
                            }

                            // Move the dragged item
                            dragitem.Move(found_coord);

                            // Align to line here
                            offset = found_coord - dragitemposition;

                            // Do not snap to grid anymore
                            snapgrid = false;
                        }
                        else
                        {
                            // Move the dragged item
                            dragitem.Move(nl.NearestOnLine(anchorpos));

                            // Align to line here
                            offset = nl.NearestOnLine(anchorpos) - dragitemposition;
                        }
                    }
                }
            }

            // Snap to grid?
            if (snapgrid)
            {
                // Move the dragged item
                dragitem.Move(anchorpos);

                // Snap item to grid
                dragitem.SnapToGrid();

                // Adjust the offset
                offset += dragitem.Position - anchorpos;
            }

            // Make sure the offset is inside the map boundaries
            if (offset.x + tl.x < General.Map.FormatInterface.LeftBoundary)
            {
                offset.x = General.Map.FormatInterface.LeftBoundary - tl.x;
            }
            if (offset.x + br.x > General.Map.FormatInterface.RightBoundary)
            {
                offset.x = General.Map.FormatInterface.RightBoundary - br.x;
            }
            if (offset.y + tl.y > General.Map.FormatInterface.TopBoundary)
            {
                offset.y = General.Map.FormatInterface.TopBoundary - tl.y;
            }
            if (offset.y + br.y < General.Map.FormatInterface.BottomBoundary)
            {
                offset.y = General.Map.FormatInterface.BottomBoundary - br.y;
            }

            // Drag item moved?
            if (!snapgrid || (dragitem.Position != oldpos))
            {
                int i = 0;

                // Move selected geometry
                foreach (Vertex v in selectedverts)
                {
                    // Move vertex from old position relative to the
                    // mouse position change since drag start
                    v.Move(oldpositions[i] + offset);

                    // Next
                    i++;
                }

                // Update labels
                int index = 0;
                foreach (Linedef l in unstablelines)
                {
                    labels[index++].Move(l.Start.Position, l.End.Position);
                }

                // Moved
                return(true);
            }
            else
            {
                // No changes
                return(false);
            }
        }
Пример #8
0
        // This writes the LINEDEFS to WAD file
        private void WriteLinedefs(MapSet map, int position, Dictionary <string, MapLumpInfo> maplumps, IDictionary <Sidedef, int> sidedefids, IDictionary <Vertex, int> vertexids)
        {
            // Create memory to write to
            MemoryStream mem    = new MemoryStream();
            BinaryWriter writer = new BinaryWriter(mem, WAD.ENCODING);

            // Go for all lines
            foreach (Linedef l in map.Linedefs)
            {
                // Convert flags
                int flags = 0;
                foreach (KeyValuePair <string, bool> f in l.Flags)
                {
                    int fnum;
                    if (f.Value && int.TryParse(f.Key, out fnum))
                    {
                        flags |= fnum;
                    }
                }

                // Add activates to flags
                flags |= (l.Activate & manager.Config.LinedefActivationsFilter);

                // Write properties to stream
                writer.Write((UInt16)vertexids[l.Start]);
                writer.Write((UInt16)vertexids[l.End]);
                writer.Write((UInt16)flags);
                writer.Write((Byte)l.Action);
                writer.Write((Byte)l.Args[0]);
                writer.Write((Byte)l.Args[1]);
                writer.Write((Byte)l.Args[2]);
                writer.Write((Byte)l.Args[3]);
                writer.Write((Byte)l.Args[4]);

                // Front sidedef
                ushort sid = (l.Front == null ? ushort.MaxValue : (UInt16)sidedefids[l.Front]);
                writer.Write(sid);

                // Back sidedef
                sid = (l.Back == null ? ushort.MaxValue : (UInt16)sidedefids[l.Back]);
                writer.Write(sid);
            }

            // Find insert position and remove old lump
            int insertpos = MapManager.RemoveSpecificLump(wad, "LINEDEFS", position, MapManager.TEMP_MAP_HEADER, maplumps);

            if (insertpos == -1)
            {
                insertpos = position + 1;
            }
            if (insertpos > wad.Lumps.Count)
            {
                insertpos = wad.Lumps.Count;
            }

            // Create the lump from memory
            Lump lump = wad.Insert("LINEDEFS", insertpos, (int)mem.Length);

            lump.Stream.Seek(0, SeekOrigin.Begin);
            mem.WriteTo(lump.Stream);
        }
 // This writes the structures to a stream
 // writenamespace may be null to omit writing the namespace to the stream
 public void Write(MapSet map, Stream stream, string writenamespace)
 {
     Write(map.Vertices, map.Linedefs, map.Sidedefs, map.Sectors, map.Things, stream, writenamespace);
 }
Пример #10
0
 void writeVertices(MapSet map, XmlWriter writer)
 {
     writer.WriteStartElement("vertices");
     foreach (Vertex vert in map.Vertices) {
         writer.WriteStartElement("v");
         writer.WriteAttributeString("idx", vert.Index.ToString());
         writer.WriteAttributeString("x", vert.Position.x.ToString());
         writer.WriteAttributeString("y", vert.Position.y.ToString());
         writeFields(vert.Fields, writer);
         writer.WriteEndElement();
     }
     writer.WriteEndElement();
 }
Пример #11
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();
        }
Пример #12
0
        // This reads the sectors
        private Dictionary <int, Sector> ReadSectors(MapSet map, UniversalParser textmap)
        {
            // Get list of entries
            List <UniversalCollection> collections = GetNamedCollections(textmap.Root, "sector");

            // Create lookup table
            Dictionary <int, Sector> link = new Dictionary <int, Sector>(collections.Count);

            // Go for all collections
            map.SetCapacity(0, 0, 0, map.Sectors.Count + collections.Count, 0);
            char[] splitter = new[] { ' ' };             //mxd
            for (int i = 0; i < collections.Count; i++)
            {
                // Read fields
                UniversalCollection c = collections[i];
                string where = "sector " + i;
                int    hfloor  = GetCollectionEntry(c, "heightfloor", false, 0, where);
                int    hceil   = GetCollectionEntry(c, "heightceiling", false, 0, where);
                string tfloor  = GetCollectionEntry(c, "texturefloor", true, "-", where);
                string tceil   = GetCollectionEntry(c, "textureceiling", true, "-", where);
                int    bright  = GetCollectionEntry(c, "lightlevel", false, 160, where);
                int    special = GetCollectionEntry(c, "special", false, 0, where);
                int    tag     = GetCollectionEntry(c, "id", false, 0, where);

                //mxd. MoreIDs
                List <int> tags = new List <int> {
                    tag
                };
                string moreids = GetCollectionEntry(c, "moreids", false, string.Empty, where);
                if (!string.IsNullOrEmpty(moreids))
                {
                    string[] moreidscol = moreids.Split(splitter, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string sid in moreidscol)
                    {
                        int id;
                        if (int.TryParse(sid.Trim(), out id) && id != 0 && !tags.Contains(id))
                        {
                            tags.Add(id);
                        }
                    }
                }
                if (tag == 0 && tags.Count > 1)
                {
                    tags.RemoveAt(0);
                }

                //mxd. Read slopes
                float fslopex = GetCollectionEntry(c, "floorplane_a", false, 0.0f, where);
                float fslopey = GetCollectionEntry(c, "floorplane_b", false, 0.0f, where);
                float fslopez = GetCollectionEntry(c, "floorplane_c", false, 0.0f, where);
                float foffset = GetCollectionEntry(c, "floorplane_d", false, float.NaN, where);

                float cslopex = GetCollectionEntry(c, "ceilingplane_a", false, 0.0f, where);
                float cslopey = GetCollectionEntry(c, "ceilingplane_b", false, 0.0f, where);
                float cslopez = GetCollectionEntry(c, "ceilingplane_c", false, 0.0f, where);
                float coffset = GetCollectionEntry(c, "ceilingplane_d", false, float.NaN, where);

                //mxd. Read flags
                Dictionary <string, bool> stringflags = new Dictionary <string, bool>(StringComparer.Ordinal);
                foreach (KeyValuePair <string, string> flag in General.Map.Config.SectorFlags)
                {
                    stringflags[flag.Key] = GetCollectionEntry(c, flag.Key, false, false, where);
                }
                foreach (KeyValuePair <string, string> flag in General.Map.Config.CeilingPortalFlags)
                {
                    stringflags[flag.Key] = GetCollectionEntry(c, flag.Key, false, false, where);
                }
                foreach (KeyValuePair <string, string> flag in General.Map.Config.FloorPortalFlags)
                {
                    stringflags[flag.Key] = GetCollectionEntry(c, flag.Key, false, false, where);
                }

                // Create new item
                Sector s = map.CreateSector();
                if (s != null)
                {
                    s.Update(hfloor, hceil, tfloor, tceil, special, stringflags, tags, bright, foffset, new Vector3D(fslopex, fslopey, fslopez).GetNormal(), coffset, new Vector3D(cslopex, cslopey, cslopez).GetNormal());

                    // Custom fields
                    ReadCustomFields(c, s, "sector");

                    // Add it to the lookup table
                    link.Add(i, s);
                }
            }

            // Return lookup table
            return(link);
        }
        private void BuildMaterialsWithNormalMaps(string[] assetGUIDs, Material materialTemplate, string outputPathAssetsRelativeTrimmed)
        {
            // Assume a list size of half the assetGUIDs length, but add a small buffer in case not all textures have proper normals for them
            List <MapSet>           textureSets      = new List <MapSet>((assetGUIDs.Length + 2) / 2);
            List <AssetNameDetails> assetNameDetails = new List <AssetNameDetails>(assetGUIDs.Length);
            bool wereTextureImportSettingsEdited     = false;

            foreach (string guid in assetGUIDs)
            {
                string           assetPath                    = AssetDatabase.GUIDToAssetPath(guid);
                string           assetName                    = EditorHelpUtilities.GetAssetNameFromPath(assetPath);
                string           assetNameLowerCase           = assetName.ToLower();
                int              assetNameLastDotIndex        = assetName.LastIndexOf('.');
                string           assetNameNoFileTypeLowerCase = assetNameLowerCase.Substring(0, assetNameLastDotIndex);
                AssetNameDetails nameDetails                  = new AssetNameDetails(assetPath, assetName, assetNameLowerCase, assetNameNoFileTypeLowerCase);
                assetNameDetails.Add(nameDetails);
            }

            foreach (AssetNameDetails nameDetails in assetNameDetails)
            {
                bool isNormalMap = false;
                foreach (string normalSuffix in normalMapSuffixes)
                {
                    if (nameDetails.AssetNameNoFileTypeLowerCase.EndsWith(normalSuffix))
                    {
                        // Found normal map, continue search for albedo maps only
                        isNormalMap = true;
                        continue;
                    }
                }
                if (isNormalMap)
                {
                    continue;
                }
                Texture2D albedoTexture = AssetDatabase.LoadAssetAtPath(nameDetails.AssetPath, typeof(Texture2D)) as Texture2D;
                if (albedoTexture == null)
                {
                    continue;
                }
                if (overrideAlphaIsTransparency)
                {
                    albedoTexture.alphaIsTransparency = alphaIsTransparencyNew;
                    TextureImporter textureImporter = AssetImporter.GetAtPath(nameDetails.AssetPath) as TextureImporter;
                    if (textureImporter.alphaIsTransparency != alphaIsTransparencyNew)
                    {
                        wereTextureImportSettingsEdited     = true;
                        textureImporter.alphaIsTransparency = alphaIsTransparencyNew;
                    }
                }
                Texture2D normalTexture      = null;
                string    normalMapAssetPath = FindNormalMapAssetPathForTextureName(assetNameDetails, nameDetails.AssetNameNoFileTypeLowerCase);
                if (normalMapAssetPath != null)
                {
                    TextureImporter normalTextureImporter = AssetImporter.GetAtPath(normalMapAssetPath) as TextureImporter;
                    if (normalTextureImporter.textureType != TextureImporterType.NormalMap)
                    {
                        normalTextureImporter.textureType = TextureImporterType.NormalMap;
                        wereTextureImportSettingsEdited   = true;
                    }
                    normalTexture = AssetDatabase.LoadAssetAtPath(normalMapAssetPath, typeof(Texture2D)) as Texture2D;
                }
                MapSet textureCombination = new MapSet(albedoTexture, normalTexture, nameDetails.AssetPath);
                textureSets.Add(textureCombination);
            }
            // Apply the changes to the normal map texture settings to the project, if there were any:
            if (wereTextureImportSettingsEdited)
            {
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }

            foreach (MapSet textureSet in textureSets)
            {
                try
                {
                    Material currentMaterial = new Material(baseMaterial); // copies all properties
                    SetAlbedoMapInMaterial(currentMaterial, textureSet.AlbedoMap);
                    SetNormalMapInMaterial(currentMaterial, textureSet.NormalMap);

                    string textureName  = textureSet.AlbedoMap.name;
                    string fileName     = GetSanitizedMaterialFileName(textureName);
                    string fullSavePath = outputPathAssetsRelativeTrimmed + "/" + fileName;

                    if (!overrideExistingMaterials && !string.IsNullOrEmpty(AssetDatabase.AssetPathToGUID(fullSavePath)))
                    {
                        // if we don't allow material overwriting and there is an asset at our path (AssetDatabase.AssetPathToGUID not returning null)
                        // just omit the asset creation
                        Destroy(currentMaterial);
                        continue;
                    }
                    // CreateAsset remark: If an asset already exists at path it will be deleted prior to creating a new asset.
                    AssetDatabase.CreateAsset(currentMaterial, fullSavePath);
                }
                catch (System.Exception e)
                {
                    Debug.LogError(string.Format("Something has gone wrong while processing texture set with albedo map at path {0}: {1}", textureSet.AlbedoMapAssetPath, e));
                }
            }
        }
Пример #14
0
        // This reads the things
        private void ReadThings(MapSet map, UniversalParser textmap)
        {
            // Get list of entries
            List <UniversalCollection> collections = GetNamedCollections(textmap.Root, "thing");

            // Go for all collections
            map.SetCapacity(0, 0, 0, 0, map.Things.Count + collections.Count);
            for (int i = 0; i < collections.Count; i++)
            {
                // Read fields
                UniversalCollection c = collections[i];
                int[] args            = new int[Linedef.NUM_ARGS];
                string where = "thing " + i;
                float x        = GetCollectionEntry(c, "x", true, 0.0f, where);
                float y        = GetCollectionEntry(c, "y", true, 0.0f, where);
                float height   = GetCollectionEntry(c, "height", false, 0.0f, where);
                int   tag      = GetCollectionEntry(c, "id", false, 0, where);
                int   angledeg = GetCollectionEntry(c, "angle", false, 0, where);
                int   pitch    = GetCollectionEntry(c, "pitch", false, 0, where);          //mxd
                int   roll     = GetCollectionEntry(c, "roll", false, 0, where);           //mxd
                float scaleX   = GetCollectionEntry(c, "scalex", false, 1.0f, where);      //mxd
                float scaleY   = GetCollectionEntry(c, "scaley", false, 1.0f, where);      //mxd
                float scale    = GetCollectionEntry(c, "scale", false, 0f, where);         //mxd
                int   type     = GetCollectionEntry(c, "type", true, 0, where);
                int   special  = GetCollectionEntry(c, "special", false, 0, where);
                args[0] = GetCollectionEntry(c, "arg0", false, 0, where);
                args[1] = GetCollectionEntry(c, "arg1", false, 0, where);
                args[2] = GetCollectionEntry(c, "arg2", false, 0, where);
                args[3] = GetCollectionEntry(c, "arg3", false, 0, where);
                args[4] = GetCollectionEntry(c, "arg4", false, 0, where);

                if (scale != 0)                //mxd
                {
                    scaleX = scale;
                    scaleY = scale;
                }

                // Flags
                Dictionary <string, bool> stringflags = new Dictionary <string, bool>(StringComparer.Ordinal);
                foreach (KeyValuePair <string, string> flag in General.Map.Config.ThingFlags)
                {
                    stringflags[flag.Key] = GetCollectionEntry(c, flag.Key, false, false, where);
                }
                foreach (FlagTranslation ft in General.Map.Config.ThingFlagsTranslation)
                {
                    foreach (string field in ft.Fields)
                    {
                        stringflags[field] = GetCollectionEntry(c, field, false, false, where);
                    }
                }

                // Create new item
                Thing t = map.CreateThing();
                if (t != null)
                {
                    t.Update(type, x, y, height, angledeg, pitch, roll, scaleX, scaleY, stringflags, tag, special, args);

                    // Custom fields
                    ReadCustomFields(c, t, "thing");
                }
            }
        }
Пример #15
0
        // This reads the linedefs and sidedefs
        private void ReadLinedefs(MapSet map, UniversalParser textmap,
                                  Dictionary <int, Vertex> vertexlink, Dictionary <int, Sector> sectorlink)
        {
            // Get list of entries
            List <UniversalCollection> linescolls = GetNamedCollections(textmap.Root, "linedef");
            List <UniversalCollection> sidescolls = GetNamedCollections(textmap.Root, "sidedef");

            // Go for all lines
            map.SetCapacity(0, map.Linedefs.Count + linescolls.Count, map.Sidedefs.Count + sidescolls.Count, 0, 0);
            char[] splitter = { ' ' };             //mxd
            for (int i = 0; i < linescolls.Count; i++)
            {
                // Read fields
                UniversalCollection lc = linescolls[i];
                int[] args             = new int[Linedef.NUM_ARGS];
                string where = "linedef " + i;
                int v1 = GetCollectionEntry(lc, "v1", true, 0, where);
                int v2 = GetCollectionEntry(lc, "v2", true, 0, where);

                if (!vertexlink.ContainsKey(v1) || !vertexlink.ContainsKey(v2))
                {                 //mxd
                    General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references one or more invalid vertices. Linedef has been removed.");
                    continue;
                }

                int tag     = GetCollectionEntry(lc, "id", false, 0, where);
                int special = GetCollectionEntry(lc, "special", false, 0, where);
                args[0] = GetCollectionEntry(lc, "arg0", false, 0, where);
                args[1] = GetCollectionEntry(lc, "arg1", false, 0, where);
                args[2] = GetCollectionEntry(lc, "arg2", false, 0, where);
                args[3] = GetCollectionEntry(lc, "arg3", false, 0, where);
                args[4] = GetCollectionEntry(lc, "arg4", false, 0, where);
                int s1 = GetCollectionEntry(lc, "sidefront", false, -1, where);
                int s2 = GetCollectionEntry(lc, "sideback", false, -1, where);

                //mxd. MoreIDs
                List <int> tags = new List <int> {
                    tag
                };
                string moreids = GetCollectionEntry(lc, "moreids", false, string.Empty, where);
                if (!string.IsNullOrEmpty(moreids))
                {
                    string[] moreidscol = moreids.Split(splitter, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string sid in moreidscol)
                    {
                        int id;
                        if (int.TryParse(sid.Trim(), out id) && id != 0 && !tags.Contains(id))
                        {
                            tags.Add(id);
                        }
                    }
                }
                if (tag == 0 && tags.Count > 1)
                {
                    tags.RemoveAt(0);
                }

                // Flags
                Dictionary <string, bool> stringflags = new Dictionary <string, bool>(StringComparer.Ordinal);
                foreach (KeyValuePair <string, string> flag in General.Map.Config.LinedefFlags)
                {
                    stringflags[flag.Key] = GetCollectionEntry(lc, flag.Key, false, false, where);
                }
                foreach (FlagTranslation ft in General.Map.Config.LinedefFlagsTranslation)
                {
                    foreach (string field in ft.Fields)
                    {
                        stringflags[field] = GetCollectionEntry(lc, field, false, false, where);
                    }
                }

                // Activations
                foreach (LinedefActivateInfo activate in General.Map.Config.LinedefActivates)
                {
                    stringflags[activate.Key] = GetCollectionEntry(lc, activate.Key, false, false, where);
                }

                // Check if not zero-length
                if (Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f)
                {
                    // Create new linedef
                    Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]);
                    if (l != null)
                    {
                        l.Update(stringflags, 0, tags, special, args);
                        l.UpdateCache();

                        // Custom fields
                        ReadCustomFields(lc, l, "linedef");

                        // Read sidedefs and connect them to the line
                        if (s1 > -1)
                        {
                            if (s1 < sidescolls.Count)
                            {
                                ReadSidedef(map, sidescolls[s1], l, true, sectorlink, s1);
                            }
                            else
                            {
                                General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid front sidedef " + s1 + ". Sidedef has been removed.");
                            }
                        }

                        if (s2 > -1)
                        {
                            if (s2 < sidescolls.Count)
                            {
                                ReadSidedef(map, sidescolls[s2], l, false, sectorlink, s2);
                            }
                            else
                            {
                                General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid back sidedef " + s1 + ". Sidedef has been removed.");
                            }
                        }
                    }
                }
                else
                {
                    General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " is zero-length. Linedef has been removed.");
                }
            }
        }
Пример #16
0
        // This performs the copy. Returns false when copy was cancelled.
        private static bool DoCopySelection(string desc)
        {
            // Check if possible to copy/paste
            if (General.Editing.Mode.Attributes.AllowCopyPaste)
            {
                // Let the plugins know
                if (General.Plugins.OnCopyBegin())
                {
                    // Ask the editing mode to prepare selection for copying.
                    // The edit mode should mark all vertices, lines and sectors
                    // that need to be copied.
                    if (General.Editing.Mode.OnCopyBegin())
                    {
                        General.MainWindow.DisplayStatus(StatusType.Action, desc);

                        // Copy the marked geometry
                        // This links sidedefs that are not linked to a marked sector to a virtual sector
                        MapSet copyset = General.Map.Map.CloneMarked();

                        // Convert flags and activations to UDMF fields, if needed
                        if (!(General.Map.FormatInterface is UniversalMapSetIO))
                        {
                            copyset.TranslateToUDMF(General.Map.FormatInterface.GetType());
                        }

                        // Write data to stream
                        MemoryStream          memstream = new MemoryStream();
                        ClipboardStreamWriter writer    = new ClipboardStreamWriter();                      //mxd
                        writer.Write(copyset, memstream);

                        try
                        {
                            //mxd. Set on clipboard
                            DataObject copydata = new DataObject();
                            copydata.SetData(CLIPBOARD_DATA_FORMAT, memstream);
                            Clipboard.SetDataObject(copydata, true, 5, 200);
                        }
                        catch (ExternalException)
                        {
                            General.Interface.DisplayStatus(StatusType.Warning, "Failed to perform a Clipboard operation...");
                            memstream.Dispose();
                            return(false);
                        }

                        // Done
                        memstream.Dispose();
                        General.Editing.Mode.OnCopyEnd();
                        General.Plugins.OnCopyEnd();
                        return(true);
                    }
                }
            }
            else
            {
                // Copy not allowed
                General.MessageBeep(MessageBeepType.Warning);
            }

            // Aborted
            return(false);
        }
Пример #17
0
        // Constructor to start dragging immediately
        public DuplicateThingsMode(EditMode basemode, Vector2D dragstartmappos)
        {
            // Initialize
            this.dragstartmappos = dragstartmappos;
            this.basemode        = basemode;

            Cursor.Current = Cursors.AppStarting;

            // Make undo for the dragging
            General.Map.UndoRedo.CreateUndo("Duplicate things");

            // Mark what we are dragging
            General.Map.Map.ClearAllMarks(false);
            General.Map.Map.MarkSelectedThings(true, true);

            // Get selected things
            List <Thing> oldthings = General.Map.Map.GetMarkedThings(true);

            selectedthings = new List <Thing>(oldthings.Count);

            foreach (Thing t in oldthings)
            {
                Thing newt = General.Map.Map.CreateThing();
                t.CopyPropertiesTo(newt);
                t.Selected = false;
                t.Marked   = false;
                selectedthings.Add(newt);
                newt.Marked = true;
                newt.Marked = true;
            }

            unselectedthings = new List <Thing>();
            foreach (Thing t in General.Map.ThingsFilter.VisibleThings)
            {
                if (!t.Marked)
                {
                    unselectedthings.Add(t);
                }
            }

            // Get the nearest thing for snapping
            dragitem = MapSet.NearestThing(selectedthings, dragstartmappos);

            // Make old positions list
            // We will use this as reference to move the vertices, or to move them back on cancel
            oldpositions = new List <Vector2D>(selectedthings.Count);
            foreach (Thing t in selectedthings)
            {
                oldpositions.Add(t.Position);
            }

            // Also keep old position of the dragged item
            dragitemposition = dragitem.Position;

            // Keep view information
            lastoffsetx = renderer.OffsetX;
            lastoffsety = renderer.OffsetY;
            lastscale   = renderer.Scale;

            Cursor.Current = Cursors.Default;

            // We have no destructor
            GC.SuppressFinalize(this);
        }
        //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);
        }
Пример #19
0
        void writeSides(MapSet map, XmlWriter writer)
        {
            writer.WriteStartElement("sides");
            foreach (Sidedef s in map.Sidedefs) {
                writer.WriteStartElement("side");
                writer.WriteAttributeString("idx", s.Index.ToString());
                writer.WriteAttributeString("line", s.Line.Index.ToString());
                if (!s.HighTexture.Equals("-"))
                    writer.WriteElementString("high-tex", s.HighTexture);
                if (!s.LowTexture.Equals("-"))
                    writer.WriteElementString("low-tex", s.LowTexture);
                if (!s.MiddleTexture.Equals("-"))
                    writer.WriteElementString("middle-tex", s.MiddleTexture);
                writer.WriteElementString("offset-x", s.OffsetX.ToString());
                writer.WriteElementString("offset-y", s.OffsetY.ToString());
                writer.WriteElementString("front", s.IsFront.ToString());

                writeFields(s.Fields, writer);

                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }
Пример #20
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);
        }
Пример #21
0
        void writeThings(MapSet map, XmlWriter writer)
        {
            writer.WriteStartElement("things");
            foreach (Thing t in map.Things) {
                writer.WriteStartElement("thing");
                writer.WriteAttributeString("idx", t.Index.ToString());
                writer.WriteAttributeString("tag", t.Tag.ToString());
                writer.WriteAttributeString("type", t.Type.ToString());
                writer.WriteAttributeString("action", t.Action.ToString());

                writer.WriteStartElement("pos");
                writer.WriteAttributeString("x", t.Position.x.ToString());
                writer.WriteAttributeString("y", t.Position.y.ToString());
                writer.WriteAttributeString("z", t.Position.z.ToString());
                writer.WriteAttributeString("angle-float", t.Angle.ToString());
                writer.WriteAttributeString("angle-int", t.AngleDoom.ToString());
                writer.WriteEndElement();

                writer.WriteStartElement("flags");
                foreach (String str in t.GetFlags().Keys) {
                    writer.WriteStartElement("flag");
                    writer.WriteAttributeString("name", str);
                    writer.WriteAttributeString("value", t.GetFlags()[str].ToString());
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();

                writeFields(t.Fields, writer);

                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }
        // Mode starts
        public override void OnEngage()
        {
            Cursor.Current = Cursors.WaitCursor;
            base.OnEngage();
            General.Interface.DisplayStatus(StatusType.Busy, "Setting up test environment...");

            BuilderPlug.InitVPO();             //mxd

            CleanUp();

            BuilderPlug.InterfaceForm.AddToInterface();
            BuilderPlug.InterfaceForm.OnOpenDoorsChanged += OnOpenDoorsChanged;             //mxd
            lastviewstats = BuilderPlug.InterfaceForm.ViewStats;

            // Export the current map to a temporary WAD file
            tempfile = BuilderPlug.MakeTempFilename(".wad");
            if (!General.Map.ExportToFile(tempfile))
            {
                //mxd. Abort on export fail
                Cursor.Current = Cursors.Default;
                General.Interface.DisplayStatus(StatusType.Warning, "Unable to set test environment...");
                OnCancel();
                return;
            }

            // 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
            CreateTiles();             //mxd

            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.LoadImageNow();

            // 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 = Clock.CurrentTime + 100;
            General.Interface.EnableProcessing();
            processingenabled = true;

            RedrawAllTiles();
            Cursor.Current = Cursors.Default;
            General.Interface.SetCursor(Cursors.Cross);
            General.Interface.DisplayReady();
        }
Пример #23
0
        // This updates the selection
        private void Update()
        {
            // Not in any modifying mode?
            if (mode == ModifyMode.None)
            {
                Vector2D prevdragoffset = alignoffset;
                alignoffset     = new Vector2D(float.MinValue, float.MinValue);
                showalignoffset = false;

                // Check what grip the mouse is over
                // and change cursor accordingly
                Grip mousegrip = CheckMouseGrip();
                switch (mousegrip)
                {
                case Grip.Main:
                    int   closestcorner = -1;
                    float cornerdist    = float.MaxValue;
                    for (int i = 0; i < 4; i++)
                    {
                        Vector2D delta = corners[i] - mousemappos;
                        float    d     = delta.GetLengthSq();
                        if (d < cornerdist)
                        {
                            closestcorner = i;
                            cornerdist    = d;
                        }
                    }
                    switch (closestcorner)
                    {
                    // TODO:
                    case 0: alignoffset = new Vector2D(0f, 0f); break;

                    case 1: alignoffset = new Vector2D(texture.ScaledWidth, 0f); break;

                    case 2: alignoffset = new Vector2D(texture.ScaledWidth, -texture.ScaledHeight); break;

                    case 3: alignoffset = new Vector2D(0f, -texture.ScaledHeight); break;
                    }
                    showalignoffset = true;
                    General.Interface.SetCursor(Cursors.Hand);
                    break;

                case Grip.RotateLB:
                case Grip.RotateRT:
                    alignoffset     = new Vector2D(0f, 0f);
                    showalignoffset = true;
                    General.Interface.SetCursor(Cursors.Cross);
                    break;

                case Grip.SizeH:
                case Grip.SizeV:
                    alignoffset     = new Vector2D(0f, 0f);
                    showalignoffset = true;
                    // Pick the best matching cursor depending on rotation and side
                    float resizeangle = -(rotation + sectorinfo[0].rotation);
                    if (mousegrip == Grip.SizeH)
                    {
                        resizeangle += Angle2D.PIHALF;
                    }
                    resizeangle = Angle2D.Normalized(resizeangle);
                    if (resizeangle > Angle2D.PI)
                    {
                        resizeangle -= Angle2D.PI;
                    }
                    resizeangle = Math.Abs(resizeangle + Angle2D.PI / 8.000001f);
                    int cursorindex = (int)Math.Floor((resizeangle / Angle2D.PI) * 4.0f) % 4;
                    General.Interface.SetCursor(RESIZE_CURSORS[cursorindex]);
                    break;

                default:
                    General.Interface.SetCursor(Cursors.Default);
                    break;
                }

                if (prevdragoffset != alignoffset)
                {
                    General.Interface.RedrawDisplay();
                }
            }
            else
            {
                Vector2D snappedmappos = mousemappos;
                bool     dosnaptogrid  = snaptogrid;

                // Options
                snaptogrid    = General.Interface.ShiftState ^ General.Interface.SnapToGrid;
                snaptonearest = General.Interface.CtrlState ^ General.Interface.AutoMerge;

                // Change to crosshair cursor so we can clearly see around the mouse cursor
                General.Interface.SetCursor(Cursors.Cross);

                // Check what modifying mode we are in
                switch (mode)
                {
                case ModifyMode.Dragging:

                    offset = -mousemappos - dragoffset;
                    Vector2D transformedpos = TexToWorld(alignoffset);

                    // Snap to nearest vertex?
                    if (snaptonearest)
                    {
                        float vrange = BuilderPlug.Me.StitchRange / renderer.Scale;

                        // Try the nearest vertex
                        Vertex nv = MapSet.NearestVertexSquareRange(General.Map.Map.Vertices, transformedpos, vrange);
                        if (nv != null)
                        {
                            // Change offset to snap to target
                            offset      -= nv.Position - transformedpos;
                            dosnaptogrid = false;
                        }
                        else
                        {
                            // Find the nearest line within range
                            Linedef nl = MapSet.NearestLinedefRange(General.Map.Map.Linedefs, transformedpos, vrange);
                            if (nl != null)
                            {
                                // Snap to grid?
                                if (dosnaptogrid)
                                {
                                    // Get grid intersection coordinates
                                    List <Vector2D> coords = nl.GetGridIntersections();

                                    // Find nearest grid intersection
                                    float    found_distance = float.MaxValue;
                                    Vector2D found_pos      = new Vector2D(float.NaN, float.NaN);
                                    foreach (Vector2D v in coords)
                                    {
                                        Vector2D dist = transformedpos - v;
                                        if (dist.GetLengthSq() < found_distance)
                                        {
                                            // Found a better match
                                            found_distance = dist.GetLengthSq();
                                            found_pos      = v;

                                            // Do not snap to grid anymore
                                            dosnaptogrid = false;
                                        }
                                    }

                                    // Found something?
                                    if (!float.IsNaN(found_pos.x))
                                    {
                                        // Change offset to snap to target
                                        offset -= found_pos - transformedpos;
                                    }
                                }
                                else
                                {
                                    // Change offset to snap onto the line
                                    offset -= nl.NearestOnLine(transformedpos) - transformedpos;
                                }
                            }
                        }
                    }

                    // Snap to grid?
                    if (dosnaptogrid)
                    {
                        // Change offset to align to grid
                        offset -= General.Map.Grid.SnappedToGrid(transformedpos) - transformedpos;
                    }

                    break;

                case ModifyMode.Resizing:

                    // Snap to nearest vertex?
                    if (snaptonearest)
                    {
                        float vrange = BuilderPlug.Me.StitchRange / renderer.Scale;

                        // Try the nearest vertex
                        Vertex nv = MapSet.NearestVertexSquareRange(General.Map.Map.Vertices, snappedmappos, vrange);
                        if (nv != null)
                        {
                            snappedmappos = nv.Position;
                            dosnaptogrid  = false;
                        }
                    }

                    // Snap to grid?
                    if (dosnaptogrid)
                    {
                        // Aligned to grid
                        snappedmappos = General.Map.Grid.SnappedToGrid(snappedmappos);
                    }

                    float newscale = 1f / resizeaxis.GetNearestOnLine(snappedmappos);
                    if (float.IsInfinity(newscale) || float.IsNaN(newscale))
                    {
                        newscale = 99999f;
                    }
                    scale = (newscale * resizefilter) + scale * (1.0f - resizefilter);
                    if (float.IsInfinity(scale.x) || float.IsNaN(scale.x))
                    {
                        scale.x = 99999f;
                    }
                    if (float.IsInfinity(scale.y) || float.IsNaN(scale.y))
                    {
                        scale.y = 99999f;
                    }

                    // Show the extension line so that the user knows what it is aligning to
                    UpdateRectangleComponents();
                    Line2D edgeline;
                    if (resizefilter.x > resizefilter.y)
                    {
                        edgeline = new Line2D(corners[1], corners[2]);
                    }
                    else
                    {
                        edgeline = new Line2D(corners[3], corners[2]);
                    }
                    float nearestonedge = edgeline.GetNearestOnLine(snappedmappos);
                    if (nearestonedge > 0.5f)
                    {
                        extensionline = new Line2D(edgeline.v1, snappedmappos);
                    }
                    else
                    {
                        extensionline = new Line2D(edgeline.v2, snappedmappos);
                    }

                    break;

                case ModifyMode.Rotating:

                    // Snap to nearest vertex?
                    extensionline = new Line2D();
                    if (snaptonearest)
                    {
                        float vrange = BuilderPlug.Me.StitchRange / renderer.Scale;

                        // Try the nearest vertex
                        Vertex nv = MapSet.NearestVertexSquareRange(General.Map.Map.Vertices, snappedmappos, vrange);
                        if (nv != null)
                        {
                            snappedmappos = nv.Position;
                            dosnaptogrid  = false;

                            // Show the extension line so that the user knows what it is aligning to
                            extensionline = new Line2D(corners[0], snappedmappos);
                        }
                    }

                    Vector2D delta      = snappedmappos - rotationcenter;
                    float    deltaangle = -delta.GetAngle();

                    // Snap to grid?
                    if (dosnaptogrid)
                    {
                        // We make 8 vectors that the rotation can snap to
                        float founddistance = float.MaxValue;
                        float foundrotation = rotation;
                        for (int i = 0; i < 8; i++)
                        {
                            // Make the vectors
                            float    angle   = (float)i * Angle2D.PI * 0.25f;
                            Vector2D gridvec = Vector2D.FromAngle(angle);
                            Vector3D rotvec  = Vector2D.FromAngle(deltaangle + rotationoffset);

                            // Check distance
                            float dist = 2.0f - Vector2D.DotProduct(gridvec, rotvec);
                            if (dist < founddistance)
                            {
                                foundrotation = angle;
                                founddistance = dist;
                            }
                        }

                        // Keep rotation
                        rotation = foundrotation - sectorinfo[0].rotation;
                    }
                    else
                    {
                        rotation = deltaangle + rotationoffset - sectorinfo[0].rotation;
                    }
                    break;
                }

                UpdateSectors();
                General.Interface.RedrawDisplay();
            }
        }
Пример #24
0
        // This moves the selected things relatively
        // Returns true when things has actually moved
        private bool MoveThingsRelative(Vector2D offset, bool snapgrid, bool snapgridincrement, bool snapnearest, bool snapcardinal)
        {
            //mxd. If snap to cardinal directions is enabled, modify the offset
            if (snapcardinal)
            {
                float angle = Angle2D.DegToRad((General.ClampAngle((int)Angle2D.RadToDeg(offset.GetAngle()) + 44)) / 90 * 90);
                offset            = new Vector2D(0, -offset.GetLength()).GetRotated(angle);
                snapgridincrement = true;                 // We don't want to move Things away from the cardinal directions
            }

            Vector2D oldpos = dragitem.Position;
            Vector2D tl, br;

            // don't move if the offset contains invalid data
            if (!offset.IsFinite())
            {
                return(false);
            }

            // Find the outmost things
            tl = br = oldpositions[0];
            for (int i = 0; i < oldpositions.Count; i++)
            {
                if (oldpositions[i].x < tl.x)
                {
                    tl.x = (int)oldpositions[i].x;
                }
                if (oldpositions[i].x > br.x)
                {
                    br.x = (int)oldpositions[i].x;
                }
                if (oldpositions[i].y > tl.y)
                {
                    tl.y = (int)oldpositions[i].y;
                }
                if (oldpositions[i].y < br.y)
                {
                    br.y = (int)oldpositions[i].y;
                }
            }

            // Snap to nearest?
            if (snapnearest)
            {
                // Find nearest unselected item within selection range
                Thing nearest = MapSet.NearestThingSquareRange(unselectedthings, mousemappos, BuilderPlug.Me.StitchRange / renderer.Scale);
                if (nearest != null)
                {
                    // Move the dragged item
                    dragitem.Move((Vector2D)nearest.Position);

                    // Adjust the offset
                    offset = (Vector2D)nearest.Position - dragitemposition;

                    // Do not snap to grid!
                    snapgrid          = false;
                    snapgridincrement = false;                     //mxd
                }
            }

            // Snap to grid?
            if (snapgrid || snapgridincrement)
            {
                // Move the dragged item
                dragitem.Move(dragitemposition + offset);

                // Snap item to grid increment (mxd)
                if (snapgridincrement)
                {
                    dragitem.Move(General.Map.Grid.SnappedToGrid(dragitemposition + offset) - dragstartoffset);
                }
                else                 // Or to the grid itself
                {
                    dragitem.SnapToGrid();
                }

                // Adjust the offset
                offset += (Vector2D)dragitem.Position - (dragitemposition + offset);
            }

            // Make sure the offset is inside the map boundaries
            if (offset.x + tl.x < General.Map.Config.LeftBoundary)
            {
                offset.x = General.Map.Config.LeftBoundary - tl.x;
            }
            if (offset.x + br.x > General.Map.Config.RightBoundary)
            {
                offset.x = General.Map.Config.RightBoundary - br.x;
            }
            if (offset.y + tl.y > General.Map.Config.TopBoundary)
            {
                offset.y = General.Map.Config.TopBoundary - tl.y;
            }
            if (offset.y + br.y < General.Map.Config.BottomBoundary)
            {
                offset.y = General.Map.Config.BottomBoundary - br.y;
            }

            // Drag item moved?
            if ((!snapgrid && !snapgridincrement) || ((Vector2D)dragitem.Position != oldpos))
            {
                int i = 0;

                // Move selected geometry
                foreach (Thing t in selectedthings)
                {
                    // Move vertex from old position relative to the
                    // mouse position change since drag start
                    t.Move(oldpositions[i] + offset);

                    // Next
                    i++;
                }

                // Moved
                return(true);
            }
            else
            {
                // No changes
                return(false);
            }
        }
Пример #25
0
        void writeSectors(MapSet map, XmlWriter writer)
        {
            writer.WriteStartElement("sectors");
            foreach (Sector s in map.Sectors) {
                writer.WriteStartElement("sector");
                writer.WriteAttributeString("idx", s.Index.ToString());
                writer.WriteAttributeString("tag", s.Tag.ToString());
                writer.WriteAttributeString("ceiling-height", s.CeilHeight.ToString());
                writer.WriteAttributeString("floor-height", s.FloorHeight.ToString());
                writer.WriteAttributeString("ceiling-tex", s.CeilTexture);
                writer.WriteAttributeString("floor-tex", s.FloorTexture);
                writer.WriteAttributeString("lighting", s.Brightness.ToString());
                writer.WriteAttributeString("special", s.Effect.ToString());

                StringBuilder sb = new StringBuilder();
                bool anyWritten = false;
                foreach (Sidedef side in s.Sidedefs) {
                    if (anyWritten)
                        sb.Append(",");
                    sb.Append(side.Index.ToString());
                    anyWritten = true;
                }
                writer.WriteElementString("sides", sb.ToString());

                writeFields(s.Fields, writer);

                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }
Пример #26
0
        // 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();
        }
Пример #27
0
        public JitterThingsForm(string editingModeName)
        {
            this.editingModeName = editingModeName;
            this.HelpRequested  += JitterThingsForm_HelpRequested;

            InitializeComponent();

            //have thing height?
            heightJitterAmmount.Enabled = General.Map.FormatInterface.HasThingHeight;
            bUpdateHeight.Enabled       = General.Map.FormatInterface.HasThingHeight;

            //disable pitch/roll/scale?
            if (!General.Map.UDMF)
            {
                pitchAmmount.Enabled    = false;
                rollAmmount.Enabled     = false;
                bUpdatePitch.Enabled    = false;
                bUpdateRoll.Enabled     = false;
                scalegroup.Enabled      = false;
                cbRelativePitch.Enabled = false;
                cbRelativeRoll.Enabled  = false;
                cbNegativePitch.Enabled = false;
                cbNegativeRoll.Enabled  = false;
            }

            //get selection
            selection = new List <Thing>();

            if (editingModeName == "BaseVisualMode")
            {
                visualSelection = ((VisualMode)General.Editing.Mode).GetSelectedVisualThings(false);
                foreach (VisualThing t in visualSelection)
                {
                    selection.Add(t.Thing);
                }
            }
            else
            {
                ICollection <Thing> list = General.Map.Map.GetSelectedThings(true);
                foreach (Thing t in list)
                {
                    selection.Add(t);
                }
            }

            //update window header
            this.Text = "Randomize " + selection.Count + (selection.Count > 1 ? " things" : " thing");

            //store intial properties
            thingData = new List <ThingData>();

            foreach (Thing t in selection)
            {
                ThingData d = new ThingData();

                Thing closest = MapSet.NearestThing(General.Map.Map.Things, t);

                if (closest != null)
                {
                    d.SafeDistance = (int)Math.Round(Vector2D.Distance(t.Position, closest.Position));
                }
                else
                {
                    d.SafeDistance = 512;
                }

                if (d.SafeDistance > 0)
                {
                    d.SafeDistance /= 2;
                }
                if (MaxSafeDistance < d.SafeDistance)
                {
                    MaxSafeDistance = d.SafeDistance;
                }
                d.Position = t.Position;
                d.Angle    = t.AngleDoom;
                d.Pitch    = t.Pitch;
                d.Roll     = t.Roll;
                d.ScaleX   = t.ScaleX;
                d.ScaleY   = t.ScaleY;

                if (General.Map.FormatInterface.HasThingHeight)
                {
                    if (t.Sector == null)
                    {
                        t.DetermineSector();
                    }
                    if (t.Sector != null)
                    {
                        d.SectorHeight = Math.Max(0, t.Sector.CeilHeight - (int)t.Height - t.Sector.FloorHeight);
                        if (MaxSafeHeightDistance < d.SectorHeight)
                        {
                            MaxSafeHeightDistance = d.SectorHeight;
                        }
                        d.ZOffset = (int)t.Position.z;
                    }
                }

                thingData.Add(d);
            }

            positionJitterAmmount.Maximum = MaxSafeDistance;
            heightJitterAmmount.Maximum   = MaxSafeHeightDistance;

            //create undo
            General.Map.UndoRedo.ClearAllRedos();
            General.Map.UndoRedo.CreateUndo("Randomize " + selection.Count + (selection.Count > 1 ? " things" : " thing"));

            //update controls
            UpdateOffsetAngles();
            UpdateHeights();
            UpdateRotationAngles();
            UpdatePitchAngles();
            UpdateRollAngles();
            UpdateScaleX();
            UpdateScaleY();

            //apply settings
            cbRelativeScale.Checked  = relativeScale;
            cbUniformScale.Checked   = uniformScale;
            cbNegativeScaleX.Checked = allowNegativeScaleX;
            cbNegativeScaleY.Checked = allowNegativeScaleY;
            cbRelativePitch.Checked  = relativePitch;
            cbRelativeRoll.Checked   = relativeRoll;
            cbNegativePitch.Checked  = allowNegativePitch;
            cbNegativeRoll.Checked   = allowNegativeRoll;


            //add event listeners
            cbRelativeScale.CheckedChanged  += cbRelativeScale_CheckedChanged;
            cbUniformScale.CheckedChanged   += cbUniformScale_CheckedChanged;
            cbNegativeScaleX.CheckedChanged += cbNegativeScaleX_CheckedChanged;
            cbNegativeScaleY.CheckedChanged += cbNegativeScaleY_CheckedChanged;
            cbRelativePitch.CheckedChanged  += cbRelativePitch_CheckedChanged;
            cbRelativeRoll.CheckedChanged   += cbRelativeRoll_CheckedChanged;
            cbNegativePitch.CheckedChanged  += cbNegativePitch_CheckedChanged;
            cbNegativeRoll.CheckedChanged   += cbNegativeRoll_CheckedChanged;

            //disable controls if necessary
            if (uniformScale)
            {
                cbUniformScale_CheckedChanged(cbUniformScale, EventArgs.Empty);
            }

            //tricky way to actually store undo information...
            foreach (Thing t in selection)
            {
                t.Move(t.Position);
            }
        }
Пример #28
0
        private static Dictionary <int, Sector> ReadSectors(MapSet map, BinaryReader reader)
        {
            int count = reader.ReadInt32();

            // Create lookup table
            Dictionary <int, Sector> link = new Dictionary <int, Sector>(count);

            // Go for all collections
            map.SetCapacity(0, 0, 0, map.Sectors.Count + count, 0);

            for (int i = 0; i < count; i++)
            {
                int effect = reader.ReadInt32();
                int hfloor = reader.ReadInt32();
                int hceil  = reader.ReadInt32();
                int bright = reader.ReadInt32();

                //mxd. Tags
                int        numtags = reader.ReadInt32();          //mxd
                List <int> tags    = new List <int>(numtags);     //mxd
                for (int a = 0; a < numtags; a++)
                {
                    tags.Add(reader.ReadInt32());                                              //mxd
                }
                string tfloor = ReadString(reader);
                string tceil  = ReadString(reader);

                //mxd. Slopes
                float    foffset = reader.ReadSingle();
                Vector3D fslope  = new Vector3D(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                float    coffset = reader.ReadSingle();
                Vector3D cslope  = new Vector3D(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                //flags
                Dictionary <string, bool> stringflags = new Dictionary <string, bool>(StringComparer.Ordinal);
                int numFlags = reader.ReadInt32();
                for (int f = 0; f < numFlags; f++)
                {
                    stringflags.Add(ReadString(reader), reader.ReadBoolean());
                }

                //add missing flags
                foreach (KeyValuePair <string, string> flag in General.Map.Config.SectorFlags)
                {
                    if (stringflags.ContainsKey(flag.Key))
                    {
                        continue;
                    }
                    stringflags.Add(flag.Key, false);
                }

                // Create new item
                Dictionary <string, UniValue> fields = ReadCustomFields(reader);
                Sector s = map.CreateSector();
                if (s != null)
                {
                    s.Update(hfloor, hceil, tfloor, tceil, effect, stringflags, tags, bright, foffset, fslope, coffset, cslope);

                    // Add custom fields
                    s.Fields.BeforeFieldsChange();
                    foreach (KeyValuePair <string, UniValue> group in fields)
                    {
                        s.Fields.Add(group.Key, group.Value);
                    }

                    // Add it to the lookup table
                    link.Add(i, s);
                }
            }

            // Return lookup table
            return(link);
        }
Пример #29
0
        // This reads the LINEDEFS and SIDEDEFS from WAD file
        private void ReadLinedefs(MapSet map, int firstindex,
                                  Dictionary <int, Vertex> vertexlink, Dictionary <int, Sector> sectorlink)
        {
            int[] args = new int[Linedef.NUM_ARGS];

            // Get the linedefs lump from wad file
            Lump linedefslump = wad.FindLump("LINEDEFS", firstindex);

            if (linedefslump == null)
            {
                throw new Exception("Could not find required lump LINEDEFS!");
            }

            // Get the sidedefs lump from wad file
            Lump sidedefslump = wad.FindLump("SIDEDEFS", firstindex);

            if (sidedefslump == null)
            {
                throw new Exception("Could not find required lump SIDEDEFS!");
            }

            // Prepare to read the items
            MemoryStream linedefsmem = new MemoryStream(linedefslump.Stream.ReadAllBytes());
            MemoryStream sidedefsmem = new MemoryStream(sidedefslump.Stream.ReadAllBytes());
            int          num         = (int)linedefslump.Stream.Length / 16;
            int          numsides    = (int)sidedefslump.Stream.Length / 30;
            BinaryReader readline    = new BinaryReader(linedefsmem);
            BinaryReader readside    = new BinaryReader(sidedefsmem);

            // Read items from the lump
            map.SetCapacity(0, map.Linedefs.Count + num, map.Sidedefs.Count + numsides, 0, 0);
            for (int i = 0; i < num; i++)
            {
                // Read properties from stream
                int v1     = readline.ReadUInt16();
                int v2     = readline.ReadUInt16();
                int flags  = readline.ReadUInt16();
                int action = readline.ReadByte();
                args[0] = readline.ReadByte();
                args[1] = readline.ReadByte();
                args[2] = readline.ReadByte();
                args[3] = readline.ReadByte();
                args[4] = readline.ReadByte();
                int s1 = readline.ReadUInt16();
                int s2 = readline.ReadUInt16();

                // Make string flags
                Dictionary <string, bool> stringflags = new Dictionary <string, bool>(StringComparer.Ordinal);
                foreach (string f in manager.Config.SortedLinedefFlags)
                {
                    int fnum;
                    if (int.TryParse(f, out fnum))
                    {
                        stringflags[f] = ((flags & fnum) == fnum);
                    }
                }

                // Create new linedef
                if (vertexlink.ContainsKey(v1) && vertexlink.ContainsKey(v2))
                {
                    // Check if not zero-length
                    if (Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f)
                    {
                        Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]);
                        l.Update(stringflags, (flags & manager.Config.LinedefActivationsFilter), new List <int> {
                            0
                        }, action, args);
                        l.UpdateCache();

                        Sidedef s;
                        string  thigh, tmid, tlow;
                        int     offsetx, offsety, sc;

                        // Line has a front side?
                        if (s1 != ushort.MaxValue)
                        {
                            // Read front sidedef
                            sidedefsmem.Seek(s1 * 30, SeekOrigin.Begin);
                            if ((s1 * 30L) <= (sidedefsmem.Length - 30L))
                            {
                                offsetx = readside.ReadInt16();
                                offsety = readside.ReadInt16();
                                thigh   = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                tlow    = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                tmid    = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                sc      = readside.ReadUInt16();

                                // Create front sidedef
                                if (sectorlink.ContainsKey(sc))
                                {
                                    s = map.CreateSidedef(l, true, sectorlink[sc]);
                                    s.Update(offsetx, offsety, thigh, tmid, tlow);
                                }
                                else
                                {
                                    General.ErrorLogger.Add(ErrorType.Warning, "Sidedef " + s1 + " references invalid sector " + sc + ". Sidedef has been removed.");
                                }
                            }
                            else
                            {
                                General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid sidedef " + s1 + ". Sidedef has been removed.");
                            }
                        }

                        // Line has a back side?
                        if (s2 != ushort.MaxValue)
                        {
                            // Read back sidedef
                            sidedefsmem.Seek(s2 * 30, SeekOrigin.Begin);
                            if ((s2 * 30L) <= (sidedefsmem.Length - 30L))
                            {
                                offsetx = readside.ReadInt16();
                                offsety = readside.ReadInt16();
                                thigh   = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                tlow    = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                tmid    = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING);
                                sc      = readside.ReadUInt16();

                                // Create back sidedef
                                if (sectorlink.ContainsKey(sc))
                                {
                                    s = map.CreateSidedef(l, false, sectorlink[sc]);
                                    s.Update(offsetx, offsety, thigh, tmid, tlow);
                                }
                                else
                                {
                                    General.ErrorLogger.Add(ErrorType.Warning, "Sidedef " + s2 + " references invalid sector " + sc + ". Sidedef has been removed.");
                                }
                            }
                            else
                            {
                                General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid sidedef " + s2 + ". Sidedef has been removed.");
                            }
                        }
                    }
                    else
                    {
                        General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " is zero-length. Linedef has been removed.");
                    }
                }
                else
                {
                    General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references one or more invalid vertices. Linedef has been removed.");
                }
            }

            // Done
            linedefsmem.Dispose();
            sidedefsmem.Dispose();
        }
Пример #30
0
        // This reads the linedefs and sidedefs
        private static void ReadLinedefs(MapSet map, BinaryReader reader, Dictionary <int, Vertex> vertexlink, Dictionary <int, Sector> sectorlink, Dictionary <int, SidedefData> sidedeflink)
        {
            int count = reader.ReadInt32();

            // Go for all lines
            map.SetCapacity(0, map.Linedefs.Count + count, map.Sidedefs.Count + sidedeflink.Count, 0, 0);
            for (int i = 0; i < count; i++)
            {
                int[] args    = new int[Linedef.NUM_ARGS];
                int   v1      = reader.ReadInt32();
                int   v2      = reader.ReadInt32();
                int   s1      = reader.ReadInt32();
                int   s2      = reader.ReadInt32();
                int   special = reader.ReadInt32();
                for (int a = 0; a < Linedef.NUM_ARGS; a++)
                {
                    args[a] = reader.ReadInt32();
                }
                int        numtags = reader.ReadInt32();          //mxd
                List <int> tags    = new List <int>(numtags);     //mxd
                for (int a = 0; a < numtags; a++)
                {
                    tags.Add(reader.ReadInt32());                                              //mxd
                }
                //flags
                Dictionary <string, bool> stringflags = new Dictionary <string, bool>(StringComparer.Ordinal);
                int numFlags = reader.ReadInt32();
                for (int f = 0; f < numFlags; f++)
                {
                    stringflags.Add(ReadString(reader), reader.ReadBoolean());
                }

                //add missing flags
                foreach (KeyValuePair <string, string> flag in General.Map.Config.LinedefFlags)
                {
                    if (stringflags.ContainsKey(flag.Key))
                    {
                        continue;
                    }
                    stringflags.Add(flag.Key, false);
                }

                //add missing activations
                foreach (LinedefActivateInfo activate in General.Map.Config.LinedefActivates)
                {
                    if (stringflags.ContainsKey(activate.Key))
                    {
                        continue;
                    }
                    stringflags.Add(activate.Key, false);
                }

                // Read custom fields
                Dictionary <string, UniValue> fields = ReadCustomFields(reader);

                // Check if not zero-length
                if (Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f)
                {
                    // Create new linedef
                    Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]);
                    if (l != null)
                    {
                        l.Update(stringflags, 0, tags, special, args);
                        l.UpdateCache();

                        // Add custom fields
                        l.Fields.BeforeFieldsChange();
                        foreach (KeyValuePair <string, UniValue> group in fields)
                        {
                            l.Fields.Add(group.Key, group.Value);
                        }

                        // Connect sidedefs to the line
                        if (s1 > -1)
                        {
                            if (s1 < sidedeflink.Count)
                            {
                                AddSidedef(map, sidedeflink[s1], l, true, sectorlink);
                            }
                            else
                            {
                                General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid front sidedef " + s1 + ". Sidedef has been removed.");
                            }
                        }

                        if (s2 > -1)
                        {
                            if (s2 < sidedeflink.Count)
                            {
                                AddSidedef(map, sidedeflink[s2], l, false, sectorlink);
                            }
                            else
                            {
                                General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid back sidedef " + s1 + ". Sidedef has been removed.");
                            }
                        }
                    }
                }
                else
                {
                    General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " is zero-length. Linedef has been removed.");
                }
            }
        }
Пример #31
0
        // This preforms visibility culling
        protected void DoCulling()
        {
            HashSet <Linedef> visiblelines = new HashSet <Linedef>();
            Vector2D          campos2d     = General.Map.VisualCamera.Position;

            // Make collections
            visiblesectors  = new Dictionary <Sector, VisualSector>(visiblesectors.Count);
            visiblegeometry = new List <VisualGeometry>(visiblegeometry.Capacity);
            visiblethings   = new List <VisualThing>(visiblethings.Capacity);

            // Get the blocks within view range
            visibleblocks = blockmap.GetFrustumRange(renderer.Frustum2D);

            // Fill collections with geometry and things
            foreach (VisualBlockEntry block in visibleblocks)
            {
                if (processgeometry)
                {
                    // Lines
                    foreach (Linedef ld in block.Lines)
                    {
                        // Line not already processed?
                        if (!visiblelines.Contains(ld))
                        {
                            // Add line if not added yet
                            visiblelines.Add(ld);

                            // Which side of the line is the camera on?
                            if (ld.SideOfLine(campos2d) < 0)
                            {
                                // Do front of line
                                if (ld.Front != null)
                                {
                                    ProcessSidedefCulling(ld.Front);
                                }
                            }
                            else
                            {
                                // Do back of line
                                if (ld.Back != null)
                                {
                                    ProcessSidedefCulling(ld.Back);
                                }
                            }
                        }
                    }
                }

                if (processthings)
                {
                    // Things
                    foreach (Thing t in block.Things)
                    {
                        // Not filtered out?
                        if (General.Map.ThingsFilter.IsThingVisible(t))
                        {
                            VisualThing vt;
                            if (allthings.ContainsKey(t))
                            {
                                vt = allthings[t];
                            }
                            else
                            {
                                // Create new visual thing
                                vt = CreateVisualThing(t);
                                allthings.Add(t, vt);
                            }

                            if (vt != null)
                            {
                                visiblethings.Add(vt);
                            }
                        }
                    }
                }
            }

            if (processgeometry)
            {
                // Find camera sector
                Linedef nld = MapSet.NearestLinedef(visiblelines, campos2d);
                if (nld != null)
                {
                    General.Map.VisualCamera.Sector = GetCameraSectorFromLinedef(nld);
                }
                else
                {
                    // Exceptional case: no lines found in any nearby blocks!
                    // This could happen in the middle of an extremely large sector and in this case
                    // the above code will not have found any sectors/sidedefs for rendering.
                    // Here we handle this special case with brute-force. Let's find the sector
                    // the camera is in by searching the entire map and render that sector only.
                    nld = General.Map.Map.NearestLinedef(campos2d);
                    if (nld != null)
                    {
                        General.Map.VisualCamera.Sector = GetCameraSectorFromLinedef(nld);
                        if (General.Map.VisualCamera.Sector != null)
                        {
                            foreach (Sidedef sd in General.Map.VisualCamera.Sector.Sidedefs)
                            {
                                float side = sd.Line.SideOfLine(campos2d);
                                if (((side < 0) && sd.IsFront) ||
                                    ((side > 0) && !sd.IsFront))
                                {
                                    ProcessSidedefCulling(sd);
                                }
                            }
                        }
                        else
                        {
                            // Too far away from the map to see anything
                            General.Map.VisualCamera.Sector = null;
                        }
                    }
                    else
                    {
                        // Map is empty
                        General.Map.VisualCamera.Sector = null;
                    }
                }
            }
        }
Пример #32
0
        private static void ProcessNodeClick(TreeNode node)
        {
            if (node == null)
            {
                return;
            }

            List <Vector2D> points = new List <Vector2D>();
            RectangleF      area   = MapSet.CreateEmptyArea();

            if (node.Parent == null)
            {
                if (node.Tag is SoundEnvironment)
                {
                    SoundEnvironment se = (SoundEnvironment)node.Tag;

                    foreach (Sector s in se.Sectors)
                    {
                        foreach (Sidedef sd in s.Sidedefs)
                        {
                            points.Add(sd.Line.Start.Position);
                            points.Add(sd.Line.End.Position);
                        }
                    }
                }
                else
                {
                    // Don't zoom if the wrong nodes are selected
                    return;
                }
            }
            else
            {
                if (node.Tag is Thing)
                {
                    Thing t = (Thing)node.Tag;

                    // We don't want to be zoomed too closely, so add somepadding
                    points.Add(t.Position - 200);
                    points.Add(t.Position + 200);
                }
                else if (node.Tag is Linedef)
                {
                    Linedef ld = (Linedef)node.Tag;

                    points.Add(ld.Start.Position);
                    points.Add(ld.End.Position);
                }
                else
                {
                    // Don't zoom if the wrong nodes are selected
                    return;
                }
            }

            area = MapSet.IncreaseArea(area, points);

            // Add padding
            area.Inflate(100f, 100f);

            // Zoom to area
            ClassicMode editmode = (General.Editing.Mode as ClassicMode);

            editmode.CenterOnArea(area, 0.0f);
        }
 public void Write(MapSet map, Stream stream)
 {
     Write(map.Vertices, map.Linedefs, map.Sidedefs, map.Sectors, map.Things, stream);
 }
        // This moves the selected things relatively
        // Returns true when things has actually moved
        private bool MoveThingsRelative(Vector2D offset, bool snapgrid, bool snapnearest)
        {
            Vector2D oldpos = dragitem.Position;
            Vector2D tl, br;

            // don't move if the offset contains invalid data
            if (!offset.IsFinite())
            {
                return(false);
            }

            // Find the outmost things
            tl = br = oldpositions[0];
            for (int i = 0; i < oldpositions.Count; i++)
            {
                if (oldpositions[i].x < tl.x)
                {
                    tl.x = (int)oldpositions[i].x;
                }
                if (oldpositions[i].x > br.x)
                {
                    br.x = (int)oldpositions[i].x;
                }
                if (oldpositions[i].y > tl.y)
                {
                    tl.y = (int)oldpositions[i].y;
                }
                if (oldpositions[i].y < br.y)
                {
                    br.y = (int)oldpositions[i].y;
                }
            }

            // Snap to nearest?
            if (snapnearest)
            {
                // Find nearest unselected item within selection range
                Thing nearest = MapSet.NearestThingSquareRange(unselectedthings, mousemappos, BuilderPlug.Me.StitchRange / renderer.Scale);
                if (nearest != null)
                {
                    // Move the dragged item
                    dragitem.Move((Vector2D)nearest.Position);

                    // Adjust the offset
                    offset = (Vector2D)nearest.Position - dragitemposition;

                    // Do not snap to grid!
                    snapgrid = false;
                }
            }

            // Snap to grid?
            if (snapgrid)
            {
                // Move the dragged item
                dragitem.Move(dragitemposition + offset);

                // Snap item to grid
                dragitem.SnapToGrid();

                // Adjust the offset
                offset += (Vector2D)dragitem.Position - (dragitemposition + offset);
            }

            // Make sure the offset is inside the map boundaries
            if (offset.x + tl.x < General.Map.FormatInterface.LeftBoundary)
            {
                offset.x = General.Map.FormatInterface.LeftBoundary - tl.x;
            }
            if (offset.x + br.x > General.Map.FormatInterface.RightBoundary)
            {
                offset.x = General.Map.FormatInterface.RightBoundary - br.x;
            }
            if (offset.y + tl.y > General.Map.FormatInterface.TopBoundary)
            {
                offset.y = General.Map.FormatInterface.TopBoundary - tl.y;
            }
            if (offset.y + br.y < General.Map.FormatInterface.BottomBoundary)
            {
                offset.y = General.Map.FormatInterface.BottomBoundary - br.y;
            }

            // Drag item moved?
            if (!snapgrid || ((Vector2D)dragitem.Position != oldpos))
            {
                int i = 0;

                // Move selected geometry
                foreach (Thing t in selectedthings)
                {
                    // Move vertex from old position relative to the
                    // mouse position change since drag start
                    t.Move(oldpositions[i] + offset);

                    // Next
                    i++;
                }

                // Moved
                return(true);
            }
            else
            {
                // No changes
                return(false);
            }
        }
 public ListItem(MapSet imap)
 {
     map = imap;
 }
Пример #36
0
        // Call this to zoom in on the given selection
        public void ZoomToObject()
        {
            List <Vector2D> points = new List <Vector2D>();
            RectangleF      area   = MapSet.CreateEmptyArea();

            // Add all points to a list
            foreach (MapElement obj in viewobjects)
            {
                if (obj is Vertex)
                {
                    points.Add((obj as Vertex).Position);
                }
                else if (obj is Linedef)
                {
                    points.Add((obj as Linedef).Start.Position);
                    points.Add((obj as Linedef).End.Position);
                }
                else if (obj is Sidedef)
                {
                    points.Add((obj as Sidedef).Line.Start.Position);
                    points.Add((obj as Sidedef).Line.End.Position);
                }
                else if (obj is Sector)
                {
                    Sector s = (obj as Sector);
                    foreach (Sidedef sd in s.Sidedefs)
                    {
                        points.Add(sd.Line.Start.Position);
                        points.Add(sd.Line.End.Position);
                    }
                }
                else if (obj is Thing)
                {
                    Thing    t = (obj as Thing);
                    Vector2D p = (Vector2D)t.Position;
                    points.Add(p);
                    points.Add(p + new Vector2D(t.Size * 2.0f, t.Size * 2.0f));
                    points.Add(p + new Vector2D(t.Size * 2.0f, -t.Size * 2.0f));
                    points.Add(p + new Vector2D(-t.Size * 2.0f, t.Size * 2.0f));
                    points.Add(p + new Vector2D(-t.Size * 2.0f, -t.Size * 2.0f));
                }
                else
                {
                    General.Fail("Unknown object given to zoom in on.");
                }
            }

            // Make a view area from the points
            foreach (Vector2D p in points)
            {
                area = MapSet.IncreaseArea(area, p);
            }

            // Make the area square, using the largest side
            if (area.Width > area.Height)
            {
                float delta = area.Width - area.Height;
                area.Y      -= delta * 0.5f;
                area.Height += delta;
            }
            else
            {
                float delta = area.Height - area.Width;
                area.X     -= delta * 0.5f;
                area.Width += delta;
            }

            // Add padding
            area.Inflate(100f, 100f);

            // Zoom to area
            ClassicMode editmode = (General.Editing.Mode as ClassicMode);

            editmode.CenterOnArea(area, 0.6f);
        }