Exemple #1
0
        private static void ReadSidesOrThrow(MapData map, MapComponents components)
        {
            ByteReader reader = ByteReader.From(ByteOrder.Little, components.Sidedefs.Value.Data);

            int count = reader.Length / BytesPerSide;

            for (int index = 0; index < count; index++)
            {
                MapSidedef sidedef = new MapSidedef(index)
                {
                    Offset        = new Vec2I(reader.Short(), reader.Short()),
                    UpperTexture  = reader.StringWithoutNulls(8),
                    LowerTexture  = reader.StringWithoutNulls(8),
                    MiddleTexture = reader.StringWithoutNulls(8),
                    SectorID      = reader.UShort()
                };

                if (!sidedef.SectorID.InRangeExclusive(0, map.Sectors.Count))
                {
                    throw new Exception($"Sidedef {index} has out of range sector: {sidedef.SectorID}");
                }

                map.Sidedefs.Add(sidedef);
            }
        }
Exemple #2
0
        /// <summary>
        /// Reads the map components and tries to generate the map.
        /// </summary>
        /// <param name="components">The map components.</param>
        /// <param name="map">The map that was generated, or null if this
        /// returns false.</param>
        /// <returns>True on success, false on failure.</returns>
        public static bool TryRead(MapComponents components, out MapData map)
        {
            switch (components.MapType)
            {
            case MapType.Doom:
                if (DoomMapReader.TryRead(components, out map))
                {
                    return(true);
                }
                break;

            case MapType.Hexen:
                // TODO
                break;

            case MapType.UDMF:
                // TODO
                break;

            default:
                Debug.Assert(false, $"Unknown map type: {components.MapType}");
                break;
            }

            map = null;
            return(false);
        }
Exemple #3
0
        /// <summary>
        /// Reads the map components and tries to parse a doom map.
        /// </summary>
        /// <param name="components">The map components.</param>
        /// <param name="map">The map that was generated, or null if this
        /// returns false.</param>
        /// <returns>True on success, false on failure.</returns>
        public static bool TryRead(MapComponents components, out MapData map)
        {
            if (!components.IsValid() || components.MapType != MapType.Doom)
            {
                map = null;
                return(false);
            }

            try
            {
                map = new MapData(components.Name);
                ReadVerticesOrThrow(map, components);
                ReadSectorsOrThrow(map, components);
                ReadSidesOrThrow(map, components);
                ReadLinesOrThrow(map, components);
                ReadThingsOrThrow(map, components);

                return(true);
            }
            catch
            {
                map = null;
                return(false);
            }
        }
    static GameObject CreateFromResource(string itemName, string holderName, bool unique = false)
    {
        if (unique)
        {
            GameObject o = GameObject.Find(MapComponents.FixName(itemName));
            if (o != null)
            {
                Debug.LogError(itemName + " already exists!");
                Selection.activeGameObject = o;
                return(null);
            }
        }

        GameObject obj = Instantiate(Resources.Load <GameObject>(itemName));

        obj.name = itemName;
        obj.transform.position = GetSpawnPos();
        if (holderName != null && holderName.Length > 0)
        {
            GameObject holder = GameObject.Find(holderName);
            if (holder == null)
            {
                holder = new GameObject(holderName);
            }

            obj.transform.SetParent(holder.transform);
        }
        Selection.activeGameObject = obj;
        return(obj);
    }
    static GameObject Create(string itemName, string icon, string holderName, bool unique = false)
    {
        if (unique)
        {
            GameObject o = MapComponents.FindFixed(itemName);
            if (o != null)
            {
                Debug.LogError(itemName + " already exists!");
                Selection.activeGameObject = o;
                return(null);
            }
        }

        GameObject obj = new GameObject(itemName);

        obj.transform.position = GetSpawnPos();
        SetIcon(obj, icon);
        if (holderName != null && holderName.Length > 0)
        {
            GameObject holder = GameObject.Find(holderName);
            if (holder == null)
            {
                holder = new GameObject(holderName);
            }

            obj.transform.SetParent(holder.transform);
        }
        Selection.activeGameObject = obj;
        return(obj);
    }
    void CoreUI()
    {
        GUILayout.Space(5);
        if (MapComponents.FindFixed("StartPad") == null)
        {
            if (FoldoutButton("Start Pad", 1))
            {
                CreateStartPad();
            }
        }
        else
        {
            FoldoutLabel("<color=green>Start Pad in Scene.</color>", 1);
        }

        if (MapComponents.FindFixed("EndPad") == null)
        {
            if (FoldoutButton("End Pad", 1))
            {
                CreateEndPad();
            }
        }
        else
        {
            FoldoutLabel("<color=green>End Pad in Scene.</color>", 1);
        }

        if (MapComponents.FindFixed("LevelBounds") == null)
        {
            if (FoldoutButton("Level Bounds", 1))
            {
                CreateLvlBounds();
            }
        }
        else
        {
            if (FoldoutButton("Recalculate Level Bounds", 1))
            {
                UpdateLevelBounds();
            }
        }

        if (FindObjectOfType <LevelTiming>() == null)
        {
            if (FoldoutButton("Level Timing", 1))
            {
                CreateTimingObj();
            }
        }
        else
        {
            FoldoutLabel("<color=green>Level Timing in Scene.</color>", 1);
        }
        GUILayout.Space(5);
    }
Exemple #7
0
        private static void ReadVerticesOrThrow(MapData map, MapComponents components)
        {
            ByteReader reader = ByteReader.From(ByteOrder.Little, components.Vertices.Value.Data);

            int count = reader.Length / BytesPerVertex;

            for (int index = 0; index < count; index++)
            {
                MapVertex vertex = new MapVertex(index, reader.Short(), reader.Short());
                map.Vertices.Add(vertex);
            }
        }
 bool EnsureMapComponentsLoaded()
 {
     if (mapComp == null)
     {
         mapComp = Resources.Load <MapComponents>("MapComponents");
     }
     if (mapComp == null)
     {
         Debug.Log("Could not find MapComponent in Resources folder");
         return(false);
     }
     return(true);
 }
    void GameplayUI()
    {
        int gemCount = MapComponents.GetNumOf("Gem");

        FoldoutLabel("Pickups", 1);
        GUILayout.Space(2);
        if (FoldoutButton("Gem", 1))
        {
            CreateGem();
        }
        if (FoldoutButton("Super Jump", 1))
        {
            CreateSJ();
        }
        if (FoldoutButton("Super Speed", 1))
        {
            CreateSS();
        }
        if (FoldoutButton("Feather Fall", 1))
        {
            CreateFF();
        }
        if (FoldoutButton("Time Travel", 1))
        {
            CreateTT();
        }
        if (FoldoutButton("Trophy", 1))
        {
            CreateTrophy();
        }
        GUILayout.Space(2);
        FoldoutLabel("Gems: <color=#0085ff>" + gemCount + "</color>", 1);
        GUILayout.Space(10);
        FoldoutLabel("Interactive", 1);
        GUILayout.Space(2);
        if (FoldoutButton("Bumper", 1))
        {
            CreateBumper();
        }
        if (FoldoutButton("Checkpoint", 1))
        {
            CreateCheckpoint();
        }
        if (FoldoutButton("Tutorial", 1))
        {
            CreateTutorial();
        }
        GUILayout.Space(5);
    }
Exemple #10
0
        private static void ReadLinesOrThrow(MapData map, MapComponents components)
        {
            ByteReader reader = ByteReader.From(ByteOrder.Little, components.Linedefs.Value.Data);

            int count = reader.Length / BytesPerLine;

            for (int index = 0; index < count; index++)
            {
                MapLinedef linedef = new MapLinedef(index)
                {
                    StartVertex = reader.UShort(),
                    EndVertex   = reader.UShort()
                };

                ushort flags     = reader.UShort();
                ushort type      = reader.UShort();
                ushort sectorTag = reader.UShort();
                SetLineSpecial(linedef, flags, type, sectorTag);

                linedef.FrontSide = reader.UShort();
                int backID = reader.UShort();
                if (backID != NoSidedef)
                {
                    linedef.BackSide = backID;
                }

                if (!linedef.StartVertex.InRangeExclusive(0, map.Vertices.Count))
                {
                    throw new Exception($"Line {index} has out of range start vertex: {linedef.StartVertex}");
                }
                if (!linedef.EndVertex.InRangeExclusive(0, map.Vertices.Count))
                {
                    throw new Exception($"Line {index} has out of range start vertex: {linedef.EndVertex}");
                }
                if (!linedef.FrontSide.InRangeExclusive(0, map.Sidedefs.Count))
                {
                    throw new Exception($"Line {index} has out of range front sidedef: {linedef.FrontSide}");
                }
                if (linedef.BackSide != null && !linedef.FrontSide.InRangeExclusive(0, map.Sidedefs.Count))
                {
                    throw new Exception($"Line {index} has out of range back sidedef: {linedef.BackSide.Value}");
                }

                map.Linedefs.Add(linedef);
            }
        }
Exemple #11
0
        private static void ReadThingsOrThrow(MapData map, MapComponents components)
        {
            ByteReader reader = ByteReader.From(ByteOrder.Little, components.Things.Value.Data);

            int count = reader.Length / BytesPerThing;

            for (int index = 0; index < count; index++)
            {
                MapThing thing = new MapThing(index);
                float    x     = new Fixed(reader.Short(), 0).Float();
                float    y     = new Fixed(reader.Short(), 0).Float();
                thing.Position     = (x, y);
                thing.AngleDegrees = reader.UShort();
                thing.EditorID     = reader.UShort();
                SetThingFlags(thing, reader.UShort());

                map.Things.Add(thing);
            }
        }
    static void UpdateLevelBounds()
    {
        BoxCollider bc     = null;
        GameObject  bounds = MapComponents.FindFixed("LevelBounds");

        if (bounds != null)
        {
            bc = bounds.GetComponent <BoxCollider>();
        }
        if (bc != null)
        {
            Bounds b = new Bounds(Vector3.zero, Vector3.zero);
            foreach (Collider r in FindObjectsOfType <MeshCollider>())
            {
                b.Encapsulate(r.bounds);
            }
            bounds.transform.position = b.center + (Vector3.up * 10);
            bc.center = Vector3.zero;
            bc.size   = b.size + new Vector3(10, 20, 10);
        }
    }
Exemple #13
0
        private static void ReadSectorsOrThrow(MapData map, MapComponents components)
        {
            ByteReader reader = ByteReader.From(ByteOrder.Little, components.Sectors.Value.Data);

            int count = reader.Length / BytesPerSector;

            for (int index = 0; index < count; index++)
            {
                MapSector sector = new MapSector(index)
                {
                    FloorHeight    = reader.Short(),
                    CeilingHeight  = reader.Short(),
                    FloorTexture   = reader.StringWithoutNulls(8).ToUpper(),
                    CeilingTexture = reader.StringWithoutNulls(8).ToUpper(),
                    LightLevel     = reader.Short()
                };
                SetSpecialBits(sector, reader.UShort());
                sector.Tag = reader.UShort();

                map.Sectors.Add(sector);
            }
        }
    // Serialize prefab state; return true if we did it because we can skip
    // the rest of normal processing in that case.
    bool SerializePrefab(GameObject go, LevelObject lo)
    {
        if (IsSafeToBake(go))
        {
            return(false);
        }

        // If it only has one component which is a light, we can bail - it's the
        // sun which is extracted in another way.
        if (go.GetComponents <Component>().Length == 2 && go.GetComponent <Light>() != null)
        {
            return(false);
        }

        if (MapComponents.FixName(go.name) == "CheckPoint" || MapComponents.FixName(go.name) == "LevelBounds" || go.GetComponent <TutorialMessage>() != null)
        {
            lo.prefabItem = GetPrefabID(MapComponents.FixName(go.name), null);
            return(true);
        }

        int validChildren = 0;

        for (int i = 0; i < go.transform.childCount; i++)
        {
            if (go.transform.GetChild(i).GetComponent <IgnoreObject>() == null)
            {
                validChildren++;
            }
        }

        if (validChildren == 0 && go.GetComponents <Component>().Length < 2)
        {
            lo.prefabItem = GetPrefabID(go.name, null);
            return(true);
        }
        return(false);
    }
    LevelObject SerializeGameObject(GameObject go, bool rejectStatic = true)
    {
        var lo = new LevelObject();

        lo.name = MapComponents.FixName(go.name);
        go.name = lo.name;
        SerializeTransform(go, lo);

        SerializeTutorial(go, lo);
        SerializeBoxCollider(go, lo);
        SerializeMisc(go, lo);
        SerializeMover(go, lo);

        if (SerializePrefab(go, lo))
        {
            return(lo);
        }

        SerializeMesh(go, lo, rejectStatic);

        bool skipChildren;
        bool doKeep = SerializeKnownComponents(go, lo, out skipChildren);

        lo.LargestChildVertexCount = lo.mesh != null ? lo.mesh.vertexCount : 0;

        for (var i = 0; i < go.transform.childCount; i++)
        {
            var child = go.transform.GetChild(i);

            if (skipChildren)
            {
                continue;
            }

            if (child.gameObject.activeInHierarchy == false)
            {
                continue;
            }

            if (IsGameObjectPrunable(child.gameObject))
            {
                continue;
            }

            var result = SerializeGameObject(go.transform.GetChild(i).gameObject);
            if (result == null)
            {
                continue;
            }

            lo.children.Add(result);
            lo.LargestChildVertexCount = Mathf.Max(lo.LargestChildVertexCount, lo.LargestChildVertexCount);
        }

        // Bail if we are empty and have no children.
        if (lo.children.Count == 0 &&
            lo.mesh.vertexCount == 0 &&
            (lo.prefabItem == null || lo.prefabItem == "") &&
            !doKeep)
        {
            return(null);
        }

        return(lo);
    }
        public IEnumerator <MapComponents> GetEnumerator()
        {
            IEntry        lastEntry  = null;
            bool          makingMap  = false;
            MapComponents components = new MapComponents(mapName);

            foreach (IEntry entry in wad)
            {
                bool isMapEntry = IsMapEntry(entry.Path.Name);

                if (makingMap)
                {
                    if (isMapEntry)
                    {
                        components.Track(entry);
                    }
                    else
                    {
                        makingMap = false;

                        if (components.IsValid())
                        {
                            yield return(components);
                        }

                        components  = new MapComponents(mapName);
                        glLevelName = "";
                    }
                }
                else if (isMapEntry)
                {
                    if (lastEntry != null)
                    {
                        glLevelName = $"GL_{lastEntry.Path.Name}";

                        // This is a way of checking if our 'hacky override' to
                        // support external map naming should be done or not. If
                        // there is no level name to override (empty string for the
                        // name) then we know we should use the marker name.
                        if (mapName.Empty)
                        {
                            components = new MapComponents(lastEntry.Path.Name);
                        }
                    }

                    // It is the case that we could have a map with no marker
                    // entry at the beginning. Such a case is a malformed map
                    // and the builder will know what to do here if the last
                    // entry is null.
                    components.TrackMapMarker(lastEntry);
                    components.Track(entry);
                    makingMap = true;
                }

                lastEntry = entry;
            }

            // If we run out of entries but have a map that is potentially done
            // yet not processed, return it.
            if (components.IsValid())
            {
                yield return(components);
            }
        }
    public static void BakeScene()
    {
        hasResult = false;
        var assembly = Assembly.GetAssembly(typeof(SceneView));
        var type     = assembly.GetType("UnityEditor.LogEntries");
        var method   = type.GetMethod("Clear");

        method.Invoke(new object(), null);
        LevelSerializer.failCause = "";
        Debug.Log("Starting Level Export");

        if (MapComponents.GetNumOf("SpawnPoint") == 0)
        {
            if (MapComponents.GetNumOf("StartPad") != 1)
            {
                LevelSerializer.failCause = "Singleplayer Level needs one StartPad!";
            }
            if (MapComponents.GetNumOf("EndPad") != 1)
            {
                LevelSerializer.failCause = "Singleplayer Level needs one EndPad!";
            }
            if (FindObjectsOfType <LevelTiming>().Length != 1)
            {
                LevelSerializer.failCause = "Singleplayer Level needs one Level Times object!";
            }
        }
        else
        {
            if (MapComponents.GetNumOf("StartPad") > 0)
            {
                LevelSerializer.failCause = "Multiplayer Maps can't have StartPads.";
            }
            if (MapComponents.GetNumOf("EndPad") > 0)
            {
                LevelSerializer.failCause = "Multiplayer Maps can't have EndPads.";
            }
            if (FindObjectsOfType <LevelTiming>().Length > 0)
            {
                LevelSerializer.failCause = "Multiplayer Maps can't have timers.";
            }
        }

        if (MapComponents.GetNumOf("LevelBounds") != 1)
        {
            LevelSerializer.failCause = "Level needs one Level Bounds!";
        }
        else
        {
            GameObject  bounds = MapComponents.FindFixed("LevelBounds");
            BoxCollider box    = bounds.GetComponent <BoxCollider>();
            if (box.size.x > 4096 || box.size.y > 4096 || box.size.z > 4096)
            {
                LevelSerializer.failCause = "Map is too large! Ensure leve bounds dimensions are under 4096.";
            }
        }

        var        serializer = new LevelSerializer();
        ByteStream levelBits  = new ByteStream();

        if (LevelSerializer.failCause.Length == 0)
        {
            serializer.Serialize(ref levelBits);
        }

        if (LevelSerializer.failCause.Length == 0)
        {
            string filePath = "Assets/" + LevelSerializer.GetCurrentSceneLevelId() + ".level";

            FileStream file;
            if (!File.Exists(filePath))
            {
                file = File.Create(filePath);
            }
            else
            {
                file = File.Open(filePath, FileMode.Truncate, FileAccess.Write);
            }
            file.Write(levelBits.Buffer, 0, levelBits.Position);
            file.Close();

            Debug.Log("<color=green>Level Exported:</color> " + filePath);
        }
        else
        {
            Debug.Log("<color=#ff3232>Export Failed:</color> " + LevelSerializer.failCause);
        }
        hasResult = true;
    }