Beispiel #1
0
    void Awake()
    {
        Application.targetFrameRate = -1;
        m_solid_simulation          = new SolidSimulation(new Vector3Int(m_grid_width_in_voxels, m_grid_height_in_voxels, m_grid_depth_in_voxels), m_voxel_size_in_meters, m_solid_voxel_chunk_dimenions);
        var solid_layers = m_solid_simulation.GetLayers();

        var water_plane_layer = (int)(m_water_height / m_voxel_size_in_meters.y) + 1;

        m_liquid_simulation = new LiquidSimulation(new Vector3Int(m_grid_width_in_voxels, m_grid_height_in_voxels, m_grid_depth_in_voxels), m_voxel_size_in_meters, m_liquid_voxel_chunk_dimenions, solid_layers, m_solid_iso_level, m_min_density_to_allow_flow, water_plane_layer, m_liquid_tuning);
        var liquid_layers = m_liquid_simulation.GetLayers();

        m_liquid_simulation.SetSimulationEnabled(m_liquid_sim_enabled_on_startup);

        m_solid_brush  = SolidLayeredBrush.LoadBrush("SolidMaterials");
        m_liquid_brush = new LiquidLayeredBrush(Resources.Load <Material>("LiquidMaterials/Liquid"));

        m_solid_mesher  = CreateSolidMesher(solid_layers, m_solid_brush);
        m_liquid_mesher = CreateLiquidMesher(m_liquid_simulation.GetLayers(), m_liquid_brush);

        CreateGroundPlane(m_solid_brush);

        m_water = GameObject.Instantiate(m_water);

        m_water.transform.position = new Vector3(0, m_water_height, 0);

        SetRoomId("quicksave_12345");

        ProcessCommandLineFile();

        GenerateWorld(solid_layers, liquid_layers);

        Instance = this;
    }
 public Renderer(Mesher mesher, TriRunner settings)
 {
     _mesher      = mesher;
     _settings    = settings;
     _vertexColor = settings.VertexColoredMat;
     _textured    = settings.TexturedMat;
 }
Beispiel #3
0
    void Start()
    {
        mr.GetPropertyBlock(materialProperties);
        GetComponent <MeshFilter>().mesh = Mesher.CreateBillboardMesh(1, 1, .5f, 0f);

        if (idleAnimation.Length > 0)
        {
            currentFrame = idleAnimation[0];
            SetSprite();
        }

        if (muzzleAnimation.Length > 0)
        {
            muzzleObject = new GameObject("Muzzle");
            muzzleObject.SetActive(false);
            muzzleObject.transform.SetParent(transform);
            muzzleObject.transform.localRotation = Quaternion.identity;

            Mesh mesh = Mesher.CreateBillboardMesh(1, 1, .5f, 0f);
            muzzleObject.AddComponent <MeshFilter>().mesh = mesh;
            muzzlemr          = muzzleObject.AddComponent <MeshRenderer>();
            muzzlemr.material = MaterialManager.Instance.transparentAxisBillboardMaterial;

            muzzleproperties = new MaterialPropertyBlock();
            muzzlemr.GetPropertyBlock(muzzleproperties);
            SetMuzzleSprite(frames[muzzleAnimation[0]].texture);
        }

        if (frames.Length == 0)
        {
            enabled = false;
        }
    }
    public void initMesh(int JSteps, int NSteps)
    {
        N = NSteps;
        J = JSteps;
        k = taxis.spread / N;
        h = xaxis.spread / J;

        h2 = h * h;

        // Other numbers
        DN  = N;
        DJ  = J;
        DJJ = J * J;

        // Allow range[ A, B ] in x direction and [ t1, T ] in t direction; create mesh arrays
        m    = new Mesher(xaxis.low, xaxis.high, taxis.low, taxis.high);
        xarr = m.xarr(J);
        tarr = m.yarr(N);

        tarr[tarr.MinIndex] = 0.0;
        tarr[tarr.MaxIndex] = taxis.high;

        for (int n = tarr.MinIndex + 1; n < tarr.MaxIndex - 1; n++)
        {
            tarr[n] = tarr[n - 1] + k;
        }

        // The 3 data structures should be 'compatible' with each other, indices
        vecOld = new Vector <double>(J + 1, 1);
        vecNew = new Vector <double>(J + 1, 1);
        res    = new NumericMatrix <double>(N + 1, J + 1, 1, 1);
    }
Beispiel #5
0
    public override void OnInspectorGUI()
    {
        RoadNetwork roadNetwork = (RoadNetwork)target;

        if (GUILayout.Button("Build Random Road Network"))
        {
            roadNetwork.BuildRandom();
        }

        jsonOutputPath = GUILayout.TextField(jsonOutputPath, 100);
        if (GUILayout.Button("Save to json file"))
        {
            string jsonOutput = roadNetwork.ToJson(true);
            File.WriteAllText(jsonOutputPath, jsonOutput);
        }

        if (GUILayout.Button("Load from json file"))
        {
            roadNetwork.FromJsonOverwrite(roadNetwork.inputJsonFile.text);
        }

        if (GUILayout.Button("Build Road Mesh"))
        {
            ProBuilderMesh roadMesh = Mesher.MeshRoadNetwork(roadNetwork);
            roadMesh.GetComponent <MeshRenderer>().sharedMaterial = roadNetwork.roadMaterial;
            roadMesh.transform.position = roadNetwork.transform.position;
            roadMesh.transform.rotation = roadNetwork.transform.rotation;
        }

        DrawDefaultInspector();
    }
    public void initMesh(int JSteps, int NSteps)
    {
        N = NSteps;
        J = JSteps;
        k = taxis.spread / N;
        h = xaxis.spread / J;

        h2 = h * h;

        // Other numbers
        DN  = N;
        DJ  = J;
        DJJ = J * J;

        // Allow range[ A, B ] in x direction and [ t1, T ] in t direction; create mesh arrays
        m    = new Mesher(xaxis.low, xaxis.high, taxis.low, taxis.high);
        xarr = m.xarr(J);
        tarr = m.yarr(N);

        // The 3 data structures should be 'compatible' with each other, indices
        vecOld = new Vector <double>(xarr.Size, xarr.MinIndex);
        vecNew = new Vector <double>(xarr.Size, xarr.MinIndex);

        res = new NumericMatrix <double>(tarr.Size, xarr.Size, tarr.MinIndex, xarr.MinIndex);
    }
        private void do_BuildMesh()
        {
            SimpleMesh Mesh;

            Mesher.GenerateMesh(dataSource, RenderBounds, out Mesh);

            UnityThreadHelper.Dispatcher.Dispatch(() => MeshDone(Mesh));
        }
Beispiel #8
0
    Mesher CreateLiquidMesher(float[][] layers, LayeredBrush brush)
    {
        var liquid_mesher    = new Mesher();
        var prepass_material = Resources.Load <Material>("LiquidMaterials/LiquidPrepass");

        liquid_mesher.Init("Liquid", layers, m_grid_width_in_voxels, m_grid_height_in_voxels, m_grid_depth_in_voxels, m_voxel_size_in_meters, m_liquid_voxel_chunk_dimenions, false, m_liquid_iso_level, 1f, brush, false, true, prepass_material, m_bevel_tuning);

        return(liquid_mesher);
    }
Beispiel #9
0
        static void TestVoxelSimplify()
        {
            var m = MagicaFile.Load(@"..\..\..\..\Assets\VoxModels\cathedral-2.vox");

            var ms = Mesher.VoxelsToMesh(m[0]);

            ms.PrintStats();
            ms.SaveToObj("voxels_simplified.obj");
        }
Beispiel #10
0
    private object AsyncProcess(IProcessable c, string tag, int thread)
    {
        var container = c as VoxelContainer;
        Dictionary <long, int> Voxels = null;

        if (tag == "Terrain")
        {
            Voxels = container.Solid;
        }
        else if (tag == "Liquid")
        {
            Voxels = container.Liquid;
        }

        if (Voxels.Count == 0)
        {
            return(null);
        }

        int vcount = 0;
        int icount = 0;
        int texw   = 0;
        int texh   = 0;

        var keys = Voxels.Keys.ToArray();
        var vals = Voxels.Values.ToArray();
        var data = datas[thread];

        Stopwatch watch = new Stopwatch();

        watch.Start();
        Mesher.MeshVoxels(Voxels.Count, keys, vals,
                          data.Vertices, data.Normals, data.UVs, data.Tris, ref vcount, ref icount, data.Tex, ref texw, ref texh, tag == "Liquid");
        watch.Stop();
        UnityEngine.Debug.Log(watch.Elapsed);

        if (tag == "Terrain")
        {
            var cs = WorldGenerator.ChunkSize;
            container.aocol = new Color[cs * cs * cs];
            for (int la = 0; la < cs * cs * cs; la++)
            {
                int x = la % cs;
                int y = (la / cs) % cs;
                int z = (la / (cs * cs));

                float val = container.CalcAO(x, y, z);
                //float val = 1;
                //val = z/15f;
                //float val = (x == 0 && y == 0 && z == 0) || (x == 1 && y==1 && z==1) ? 1 : 0;
                container.aocol[la] = new Color(val, val, val);
            }
        }

        return(new object[] { data.GetVertices(vcount), data.GetNormals(vcount), data.GetUVs(vcount), data.GetTris(icount), texw, texh, data.GetTex(texw, texh) });
    }
Beispiel #11
0
    Mesher CreateSolidMesher(float[][] layers, LayeredBrush brush)
    {
        var solid_mesher = new Mesher();

        solid_mesher.Init("Solid", layers, m_grid_width_in_voxels, m_grid_height_in_voxels, m_grid_depth_in_voxels, m_voxel_size_in_meters, m_solid_voxel_chunk_dimenions, true, m_solid_iso_level, 0f, brush, true, false, null, m_bevel_tuning);

        //solid_mesher.enabled = false;

        return(solid_mesher);
    }
Beispiel #12
0
    // Update is called once per frame
    void Update()
    {
        Mesher.meshLoop();
        _mapHandler.update();

        // Save the game manually
        if (Input.GetKeyDown(KeyCode.P))
        {
            // _mapHandler.saveAllSectors();
        }
    }
    private IEnumerator <WaitForSeconds> DressTemplate(Mesher template, int idT)
    {
        _templateReady[idT] = false;
        IEnumerator <WaitForSeconds> ie = DressTemplate(template, 1f);

        while (ie.MoveNext())
        {
            yield return(ie.Current);
        }
        _templateReady[idT] = true;
    }
Beispiel #14
0
    public WorldGenerator(SolidSimulation solid_simulation, Mesher solid_mesher, Mesher liquid_mesher)
    {
        m_solid_mesher        = solid_mesher;
        m_liquid_mesher       = liquid_mesher;
        m_dimensions_in_cells = solid_simulation.GetDimensionsInCells();

        m_solid_mesher.SetCollisionGenerationEnabled(false);
        m_solid_mesher.UpdateDensitySamples();
        m_liquid_mesher.UpdateDensitySamples();

        m_layer_idx = 0;
    }
Beispiel #15
0
    void Awake()
    {
        //  MapLoader.loadSector(new Vector2I(0, 0));
        //SaveGame.Instance.RefreshScene();
        instance    = this;
        _properties = Resources.Load <WorldProperties>("World Properties");

        _chunkPool = new Pool <ChunkWorldObject>();

        Atlas.initialize();
        ItemStore.initialize();
        EntityStore.initialize();
        RecipeManager.loadRecipes();
        CollisionGrid.initialize(this, _properties.worldDimension * _properties.chunkDimension);
        TileStore.initialize();
        Mesher.initialize();

        int half = (_properties.worldDimension - 1) / 2;

        Vector2I spawnPos = new Vector2I(3, 3);

        _position = spawnPos - new Vector2I(half, half);

        // Create and initialize the map handler behaviour
        _mapHandler = new MapHandler(this, spawnPos);

        //_mapHandler.setPosition(new Vector2I(0, 0));
        //_mapHandler.populateSectors();

        //_mapHandler.updatePosition(new Vector2I(0, 0));

        createWorld();
        createLoader(spawnPos);
        //createLoader(spawnPos);
        if (SaveGame.Instance.IsSaveGame)
        {
            getPlayerPos();
        }
        // TEMP
        CollisionGrid.rebuildMap();

        return;

        for (int i = 0; i < 4; i++)
        {
            EntityItem entity = (EntityItem)EntityStore.createEntity(0);
            entity.itemID             = i;
            entity.transform.position = new Vector3(5 + i, 10, 5);
        }
    }
Beispiel #16
0
        static void TestVoxelSimplify2()
        {
            var m  = MagicaFile.Load(@"..\..\..\..\Assets\VoxModels\Wall_07.vox");
            var ms = Mesher.VoxelsToMeshFull(m[0]);

            ms.SaveToObj("voxels_pre_91.obj");
            ms.Collapse(43);
            ms.Collapse(54);
            ms.Collapse(61);
            ms.Collapse(91);
            ms.Compact();
            ms.PrintStats();
            ms.SaveToObj("voxels_post_91.obj");
        }
Beispiel #17
0
    protected override void CreateBillboard()
    {
        if (!string.IsNullOrEmpty(spriteName))
        {
            Texture tex = TextureLoader.Instance.GetSpriteTexture(spriteName);
            materialProperties.SetFloat("_ScaleX", (float)tex.width / MapLoader.sizeDividor);
            materialProperties.SetFloat("_ScaleY", (float)tex.height / MapLoader.sizeDividor);
            Mesh mesh = Mesher.CreateBillboardMesh(1, 1, .5f, 0);
            GetComponent <MeshFilter>().mesh = mesh;

            materialProperties.SetTexture("_MainTex", tex);
            mr.SetPropertyBlock(materialProperties);
        }
    }
Beispiel #18
0
    void Update()
    {
        // Only perform update logic if a chunk is attached
        if (_chunk != null)
        {
            if (_chunk.dirty) // If the chunk has been flagged for meshing, queue it and unflag
            {
                Mesher.queueMeshingTask(_chunk);
                _chunk.setDirtyState(false);

                // TEMP
                // Update the collider
                _collider.setData(chunk.tiles);
            }
        }
    }
    protected virtual void CreateBillboard()
    {
        if (mr == null)
        {
            return;
        }

        if (!string.IsNullOrEmpty(spriteName))
        {
            Texture tex  = TextureLoader.Instance.GetSpriteTexture(spriteName);
            Mesh    mesh = Mesher.CreateBillboardMesh((float)tex.width / MapLoader.sizeDividor, (float)tex.height / MapLoader.sizeDividor, pivot.x, pivot.y);
            GetComponent <MeshFilter>().mesh = mesh;

            materialProperties.SetTexture("_MainTex", tex);
            mr.SetPropertyBlock(materialProperties);
        }
    }
    public IEnumerator <WaitForSeconds> DressTemplate(Mesher template, float globalScale)
    {
        float scaler        = BuildTemplateLvl.GetComponent <CircleCollider2D>().radius * 2f;
        Mesh  m             = template.GetComponent <MeshFilter>().mesh;
        bool  nonCollidable = template.gameObject.layer == LayerMask.NameToLayer("Non-collidables");

        if (debug)
        {
            Debug.Log(string.Format("Dressing {0}", template, scaler));
        }

        if (!m)
        {
            Debug.LogError(string.Format("Template {0} lacks mesh", template));
        }
        else
        {
            float Aref = scaler * BuildTemplateLvl.transform.lossyScale.magnitude;
            //Debug.Log(string.Format("Builder {0}x{1} scale {2}", refV.x, refV.y, BuildTemplate.transform.lossyScale.magnitude));
            List <Vector3> verts   = template.vertices;
            int[]          tris    = template.GenerateTris();
            bool[]         allDone = new bool[tris.Count() / 3];

            if (!template.rigidbody2D)
            {
                template.gameObject.AddComponent <Rigidbody2D>();
                template.rigidbody2D.isKinematic = true;
            }


            for (int i = 0, l = tris.Length; i < l; i += 3)
            {
                StartCoroutine(DressTri(verts[tris[i]], verts[tris[i + 1]], verts[tris[i + 2]], template.gameObject, Aref, nonCollidable, allDone, i / 3, globalScale, BuildTemplateLvl));
            }

            while (allDone.Any(e => !e))
            {
                yield return(new WaitForSeconds(interOrderDelay));
            }
        }
    }
Beispiel #21
0
    void Update()
    {
        //skip frames are used to easen up Time.deltaTime after loading
        if (ready)
        {
            if (skipFrames > 0)
            {
                skipFrames--;

                if (skipFrames == 0)
                {
                    paused = false;
                }
            }
        }

        if (!string.IsNullOrEmpty(ChangeMap))
        {
            paused = true;

            skipFrames = 5;
            ready      = false;

            MapLoader.Unload();
            if (MapLoader.Load(ChangeMap))
            {
                TheGrid.Init();

                Mesher.CreateMeshes();
                MapLoader.ApplyLinedefBehavior();
                ThingManager.Instance.CreateThings(false);

                AI.CreateHeatmap();
                //DebugObjects.DrawHeatmap();

                Init();
            }

            ChangeMap = "";
        }
    }
Beispiel #22
0
        static void TestSimplify4()
        {
            //var voxels = MagicaFile.Load(@"C:\Projects\FloofBox\uRogue\Assets\VoxModels\cathedral-2.vox");
            var voxels = MagicaFile.Load(@"..\..\..\..\Assets\Vox\TransparencyTest.vox");

            var boxes = BoxMaker.MakeBoxes(voxels[0]);

            Console.WriteLine("{0} boxes made", boxes.Count);

            MeshSimplifier ms = Mesher.VoxelsToMeshFull(voxels[0]);

            Console.WriteLine("Triangles before reduction: " + (ms.Edges.Length / 3));
            ms.Simplify();
            ms.Compact();
            Console.WriteLine("Triangles after reduction: " + (ms.Edges.Length / 3));
            int[]   tris;
            Vec3f[] rawPos;
            Vec3f[] rawNormals;
            Vec2f[] rawUvs;

            VoxelSet <Vec4b> atlas;

            ms.GetMesh(voxels[0], out tris, out rawPos, out rawNormals, out rawUvs, out atlas);

            Bitmap bmp = new Bitmap(atlas.Size.x, atlas.Size.y);

            for (int y = 0; y < atlas.Size.y; ++y)
            {
                for (int x = 0; x < atlas.Size.x; ++x)
                {
                    bmp.SetPixel(x, y, Color.FromArgb(
                                     atlas[x, y, 0].x,
                                     atlas[x, y, 0].y,
                                     atlas[x, y, 0].z
                                     ));
                }
            }

            bmp.Save("Atlas.png");
        }
Beispiel #23
0
    private void Initialize(Fractal parent, int childIndex)
    {
        transformer  = parent.transformer;
        materialer   = parent.materialer;
        probabiliter = parent.probabiliter;
        mesher       = parent.mesher;

        // Init fractal attributes
        mesh     = mesher.GetMesh(parent, childIndex);
        material = parent.material;
        maxDepth = parent.maxDepth;
        depth    = parent.depth + 1;
        minTimeBetweenChildCreation = parent.minTimeBetweenChildCreation;
        maxTimeBetweenChildCreation = parent.maxTimeBetweenChildCreation;
        spawnProbability            = probabiliter.GetSpawningProbability(parent, childIndex);
        childrenTransforms          = parent.childrenTransforms;

        // Init game object
        transform.parent        = parent.transform;
        transform.localScale    = transformer.GetLocalScale(parent, childIndex, childrenTransforms);
        transform.localPosition = transformer.GetLocalPosition(parent, childIndex, childrenTransforms);
        transform.localRotation = transformer.GetLocalRotation(parent, childIndex, childrenTransforms);
        material = materialer.GetMaterial(parent, childIndex);
    }
    private void _SetTemplates()
    {
//		_templates.AddRange(GameObject.FindGameObjectsWithTag(buildTag));
        foreach (GameObject t in GameObject.FindGameObjectsWithTag("TemplateLevel"))
        {
            Destroy(t.gameObject);
        }

        _templates.Clear();
        _templates.AddRange(_groundStitcher.interactables);
        _templates.AddRange(_groundDecorator.interactables);

        _templateReady = new bool[_templates.Count];

        foreach (Mesher m in _templates)
        {
            m.renderer.enabled = false;
        }

        if (debug)
        {
            Debug.Log(string.Format("Found {0} interactables", _templates.Count));
        }

        switch (buildOrder)
        {
        case BuildOrder.RANDOM:
            for (int i = 0; i < _templates.Count; i++)
            {
                Mesher m           = _templates[i];
                int    randomIndex = Random.Range(i, _templates.Count);
                _templates[i]           = _templates[randomIndex];
                _templates[randomIndex] = m;
            }
            break;

        case BuildOrder.X:
            _templates.Sort((A, B) => A.transform.position.x.CompareTo(B.transform.position.x));
            break;

        case BuildOrder.X_REV:
            _templates.Sort((A, B) => B.transform.position.x.CompareTo(A.transform.position.x));
            break;

        case BuildOrder.Y:
            _templates.Sort((A, B) => A.transform.position.y.CompareTo(B.transform.position.y));
            break;

        case BuildOrder.Y_REV:
            _templates.Sort((A, B) => B.transform.position.y.CompareTo(A.transform.position.y));
            break;

        case BuildOrder.Z:
            _templates.Sort((A, B) => A.transform.position.z.CompareTo(B.transform.position.z));
            break;

        case BuildOrder.Z_REV:
            _templates.Sort((A, B) => B.transform.position.z.CompareTo(A.transform.position.z));
            break;

        default:
            break;
        }
    }
Beispiel #25
0
 void Awake()
 {
     Instance = this;
 }
    // Use this for initialization
    void Start()
    {
        numValuePoints = chunkSize + 1;
        valuePoints    = new float[numValuePoints, numValuePoints, numValuePoints];
        for (int y = 0; y < numValuePoints; y++)
        {
            for (int z = 0; z < numValuePoints; z++)
            {
                for (int x = 0; x < numValuePoints; x++)
                {
                    Vector3 realPos = new Vector3(x + transform.position.x, y + transform.position.y, z + transform.position.z);
                    valuePoints[x, y, z] = Noise.Generate(realPos.x * 0.02f, realPos.y * 0.02f, realPos.z * 0.02f);
                }
            }
        }

        meshRenderer = gameObject.AddComponent <MeshRenderer>();
        meshFilter   = gameObject.AddComponent <MeshFilter>();
        mesh         = new Mesh();

        meshRenderer.sharedMaterial = chunkMaterial;

        int            initialSize = chunkSize * 5 * 3;
        List <Vector3> verts       = new List <Vector3>(initialSize);
        List <int>     indices     = new List <int>(initialSize);
        List <Vector2> uvs         = new List <Vector2>(initialSize);

        int numVerts = 0;

        cells = new Mesher.GridCell[chunkSize, chunkSize, chunkSize];
        for (int y = 0; y < chunkSize; y++)
        {
            for (int z = 0; z < chunkSize; z++)
            {
                for (int x = 0; x < chunkSize; x++)
                {
                    Mesher.GridCell currCell = generateCell(x, y, z);

                    Mesher.Triangle[] tris = new Mesher.Triangle[5];
                    int numTris            = Mesher.Polygonize(currCell, 0.1f, tris);

                    for (int i = 0; i < numTris; i++)
                    {
                        verts.Add(tris[i].triPoints[0]);
                        verts.Add(tris[i].triPoints[1]);
                        verts.Add(tris[i].triPoints[2]);

                        indices.Add(numVerts);
                        indices.Add(numVerts + 1);
                        indices.Add(numVerts + 2);

                        numVerts += 3;

                        // uvs dont matter right now
                        uvs.Add(Vector2.zero);
                        uvs.Add(Vector2.zero);
                        uvs.Add(Vector2.zero);
                    }
                }
            }
        }

        mesh.vertices  = verts.ToArray();
        mesh.triangles = indices.ToArray();
        mesh.uv        = uvs.ToArray();

        mesh.Optimize();
        mesh.RecalculateBounds();
        mesh.RecalculateNormals();

        meshFilter.sharedMesh = mesh;
    }
Beispiel #27
0
    public static void ApplyLinedefBehavior()
    {
        Transform holder = new GameObject("DynamicMeshes").transform;

        holder.transform.SetParent(GameManager.Instance.transform);

        int index = -1;

        foreach (Linedef l in linedefs)
        {
            index++;

            if (l.lineType == 0)
            {
                continue;
            }

            switch (l.lineType)
            {
            default:
                Debug.Log("Linedef " + index + " has unknown type (" + l.lineType + ")");
                break;

            //common door
            case 1:
            case 26:     //keycard doors
            case 27:
            case 28:
            {
                if (l.TopFrontObject == null)
                {
                    break;
                }

                if (l.Back == null)
                {
                    break;
                }

                l.Back.Sector.ceilingObject.transform.SetParent(holder);

                Door1Controller lc = l.TopFrontObject.AddComponent <Door1Controller>();

                if (l.lineType == 26)
                {
                    lc.requiresKeycard = 0;
                }
                if (l.lineType == 27)
                {
                    lc.requiresKeycard = 1;
                }
                if (l.lineType == 28)
                {
                    lc.requiresKeycard = 2;
                }

                SlowRepeatableDoorController sc = l.Back.Sector.ceilingObject.GetComponent <SlowRepeatableDoorController>();
                if (sc == null)
                {
                    sc = l.Back.Sector.ceilingObject.AddComponent <SlowRepeatableDoorController>();
                }

                sc.Init(l.Back.Sector);
                lc.sectorController = sc;

                l.Back.Sector.Dynamic = true;
            }
            break;

            //single use door, walk trigger
            case 2:
            {
                if (!Sector.TaggedSectors.ContainsKey(l.lineTag))
                {
                    break;
                }

                List <SlowOneshotDoorController> linked = new List <SlowOneshotDoorController>();
                foreach (Sector sector in Sector.TaggedSectors[l.lineTag])
                {
                    sector.ceilingObject.transform.SetParent(holder);

                    SlowOneshotDoorController sc = sector.ceilingObject.GetComponent <SlowOneshotDoorController>();
                    if (sc == null)
                    {
                        sc = sector.ceilingObject.gameObject.AddComponent <SlowOneshotDoorController>();
                        sc.Init(sector);
                    }
                    linked.Add(sc);

                    sector.Dynamic = true;
                }

                BoxCollider mc = Mesher.CreateLineTriggerCollider(
                    l,
                    Mathf.Min(l.Front.Sector.minimumFloorHeight, l.Back.Sector.minimumFloorHeight),
                    Mathf.Max(l.Front.Sector.maximumCeilingHeight, l.Back.Sector.maximumCeilingHeight),
                    "Tag_" + l.lineTag + "_trigger",
                    holder
                    );

                if (mc == null)
                {
                    Debug.LogError("Linedef " + index + " could not create trigger. Type(" + l.lineType + ")");
                    break;
                }

                mc.isTrigger = true;

                LineTrigger lt = mc.gameObject.AddComponent <LineTrigger>();
                lt.TriggerAction = (c) =>
                {
                    PlayerThing player = c.GetComponent <PlayerThing>();

                    if (player == null)
                    {
                        return;
                    }

                    foreach (SlowOneshotDoorController lc in linked)
                    {
                        if (lc.CurrentState == SlowOneshotDoorController.State.Closed)
                        {
                            lc.CurrentState = SlowOneshotDoorController.State.Opening;
                        }
                    }
                };
            }
            break;

            //stairbuilder, walktrigger
            case 8:
            {
                if (!Sector.TaggedSectors.ContainsKey(l.lineTag))
                {
                    break;
                }

                List <StairbuilderSlow> linked = new List <StairbuilderSlow>();
                foreach (Sector sector in Sector.TaggedSectors[l.lineTag])
                {
                    sector.floorObject.transform.SetParent(holder);

                    List <Sector> stairSectors = new List <Sector>();
                    Sector        targetSector = sector;

                    int  count  = 0;
                    bool failed = false;
                    while (!failed)
                    {
                        count++;
                        stairSectors.Add(targetSector);
                        targetSector.Dynamic = true;
                        targetSector.floorObject.transform.SetParent(holder);

                        failed = true;
                        foreach (Sidedef s in targetSector.Sidedefs)
                        {
                            if (s.Line.Back == null)
                            {
                                continue;
                            }

                            if (s.Line.Back.Sector == targetSector)
                            {
                                continue;
                            }

                            if (s.Line.Back.Sector.floorTexture != targetSector.floorTexture)
                            {
                                continue;
                            }

                            if (stairSectors.Contains(s.Line.Back.Sector))
                            {
                                continue;
                            }

                            targetSector = s.Line.Back.Sector;
                            failed       = false;
                        }
                    }

                    StairbuilderSlow sc = sector.floorObject.GetComponent <StairbuilderSlow>();
                    if (sc == null)
                    {
                        sc = sector.floorObject.gameObject.AddComponent <StairbuilderSlow>();
                        sc.Init(stairSectors);
                    }
                    linked.Add(sc);
                }

                BoxCollider mc = Mesher.CreateLineTriggerCollider(
                    l,
                    Mathf.Min(l.Front.Sector.minimumFloorHeight, l.Back.Sector.minimumFloorHeight),
                    Mathf.Max(l.Front.Sector.maximumCeilingHeight, l.Back.Sector.maximumCeilingHeight),
                    "Tag_" + l.lineTag + "_trigger",
                    holder
                    );

                if (mc == null)
                {
                    Debug.LogError("Linedef " + index + " could not create trigger. Type(" + l.lineType + ")");
                    break;
                }

                mc.isTrigger = true;

                LineTrigger lt = mc.gameObject.AddComponent <LineTrigger>();
                lt.TriggerAction = (c) =>
                {
                    PlayerThing player = c.GetComponent <PlayerThing>();

                    if (player == null)
                    {
                        return;
                    }

                    foreach (StairbuilderSlow lc in linked)
                    {
                        if (lc.CurrentState == StairbuilderSlow.State.Waiting)
                        {
                            lc.CurrentState = StairbuilderSlow.State.Active;
                        }
                    }
                };
            }
            break;

            //donut, switch
            case 9:
            {
                if (!Sector.TaggedSectors.ContainsKey(l.lineTag))
                {
                    break;
                }

                List <Sector> sectors = Sector.TaggedSectors[l.lineTag];
                if (sectors.Count == 0)
                {
                    break;
                }

                sectors[0].floorObject.transform.SetParent(holder);

                Sector ringSector = null;
                foreach (Sidedef s in sectors[0].Sidedefs)
                {
                    if (s.Line.Back == null)
                    {
                        continue;
                    }

                    if (s.Line.Front.Sector == sectors[0])
                    {
                        ringSector = s.Line.Back.Sector;
                        ringSector.floorObject.transform.SetParent(holder);
                        break;
                    }

                    if (s.Line.Back.Sector == sectors[0])
                    {
                        ringSector = s.Line.Front.Sector;
                        ringSector.floorObject.transform.SetParent(holder);
                        break;
                    }
                }

                if (ringSector == null)
                {
                    Debug.LogError("MapLoader: Donut9Controller: No ring sector found!");
                }

                Donut9SectorController sc = sectors[0].floorObject.gameObject.AddComponent <Donut9SectorController>();

                Donut9LinedefController script = null;
                if (l.BotFrontObject != null)
                {
                    script = l.BotFrontObject.AddComponent <Donut9LinedefController>();
                }
                else if (l.MidFrontObject != null)
                {
                    script = l.MidFrontObject.AddComponent <Donut9LinedefController>();
                }

                if (script != null)
                {
                    script.sectorController = sc;
                    sc.Init(sectors[0], ringSector);
                }

                sectors[0].Dynamic = true;
                ringSector.Dynamic = true;
            }
            break;

            //level end switch
            case 11:
            {
                if (l.BotFrontObject != null)
                {
                    End11LinedefController lc = l.BotFrontObject.AddComponent <End11LinedefController>();
                    lc.CurrentTexture = l.Front.tLow;
                    l.BotFrontObject.transform.SetParent(holder);
                }
                else if (l.MidFrontObject != null)
                {
                    End11LinedefController lc = l.MidFrontObject.AddComponent <End11LinedefController>();
                    lc.CurrentTexture = l.Front.tMid;
                    l.MidFrontObject.transform.SetParent(holder);
                }
            }
            break;

            //raise floor to next, one use
            case 20:
            {
                List <Floor20SectorController> linked = new List <Floor20SectorController>();
                foreach (Sector sector in Sector.TaggedSectors[l.lineTag])
                {
                    sector.floorObject.transform.SetParent(holder);

                    Floor20SectorController sc = sector.floorObject.GetComponent <Floor20SectorController>();
                    if (sc == null)
                    {
                        sc = sector.floorObject.gameObject.AddComponent <Floor20SectorController>();
                        sc.Init(sector);
                    }

                    linked.Add(sc);

                    sector.Dynamic = true;
                }

                if (l.BotFrontObject != null)
                {
                    if (index == 1020)
                    {
                        l.BotFrontObject.transform.SetParent(GameManager.Instance.TemporaryObjectsHolder);
                    }

                    Floor20LinedefController lc = l.BotFrontObject.AddComponent <Floor20LinedefController>();
                    lc.sectorControllers = linked;
                    lc.CurrentTexture    = l.Front.tLow;
                    l.BotFrontObject.transform.SetParent(holder);
                }
                else if (l.MidFrontObject != null)
                {
                    Floor20LinedefController lc = l.MidFrontObject.AddComponent <Floor20LinedefController>();
                    lc.sectorControllers = linked;
                    lc.CurrentTexture    = l.Front.tMid;
                    l.MidFrontObject.transform.SetParent(holder);
                }
            }
            break;

            //single use door, pokeable
            case 31:
            {
                if (l.TopFrontObject == null)
                {
                    break;
                }

                if (l.Back == null)
                {
                    break;
                }

                l.Back.Sector.ceilingObject.transform.SetParent(holder);

                Door31Controller          lc = l.TopFrontObject.AddComponent <Door31Controller>();
                SlowOneshotDoorController sc = l.Back.Sector.ceilingObject.GetComponent <SlowOneshotDoorController>();
                if (sc == null)
                {
                    sc = l.Back.Sector.ceilingObject.AddComponent <SlowOneshotDoorController>();
                }

                sc.Init(l.Back.Sector);
                lc.sectorController = sc;

                l.Back.Sector.Dynamic = true;
            }
            break;

            //make sectors dark, walktrigger
            case 35:
            {
                if (!Sector.TaggedSectors.ContainsKey(l.lineTag))
                {
                    break;
                }

                BoxCollider mc = Mesher.CreateLineTriggerCollider(
                    l,
                    Mathf.Min(l.Front.Sector.minimumFloorHeight, l.Back.Sector.minimumFloorHeight),
                    Mathf.Max(l.Front.Sector.maximumCeilingHeight, l.Back.Sector.maximumCeilingHeight),
                    "Tag_" + l.lineTag + "_trigger",
                    holder
                    );

                if (mc == null)
                {
                    Debug.LogError("Linedef " + index + " could not create trigger. Type(" + l.lineType + ")");
                    break;
                }

                mc.isTrigger = true;

                LineTrigger lt = mc.gameObject.AddComponent <LineTrigger>();
                lt.TriggerAction = (c) =>
                {
                    if (c.GetComponent <PlayerThing>() == null)
                    {
                        return;
                    }

                    foreach (Sector sector in Sector.TaggedSectors[l.lineTag])
                    {
                        sector.brightness = (float)35 / 255f;
                        sector.floorObject.ChangeBrightness(sector.brightness);
                    }
                };
            }
            break;

            //single use floor lower, walktrigger
            case 36:
            {
                if (!Sector.TaggedSectors.ContainsKey(l.lineTag))
                {
                    break;
                }

                List <Floor36Controller> linked = new List <Floor36Controller>();
                foreach (Sector sector in Sector.TaggedSectors[l.lineTag])
                {
                    sector.floorObject.transform.SetParent(holder);

                    Floor36Controller sc = sector.floorObject.GetComponent <Floor36Controller>();
                    if (sc == null)
                    {
                        sc = sector.floorObject.gameObject.AddComponent <Floor36Controller>();
                        sc.Init(sector);
                    }
                    linked.Add(sc);

                    sector.Dynamic = true;
                }

                BoxCollider mc = Mesher.CreateLineTriggerCollider(
                    l,
                    Mathf.Min(l.Front.Sector.minimumFloorHeight, l.Back.Sector.minimumFloorHeight),
                    Mathf.Max(l.Front.Sector.maximumCeilingHeight, l.Back.Sector.maximumCeilingHeight),
                    "Tag_" + l.lineTag + "_trigger",
                    holder
                    );

                if (mc == null)
                {
                    Debug.LogError("Linedef " + index + " could not create trigger. Type(" + l.lineType + ")");
                    break;
                }

                mc.isTrigger = true;

                LineTrigger lt = mc.gameObject.AddComponent <LineTrigger>();
                lt.TriggerAction = (c) =>
                {
                    PlayerThing player = c.GetComponent <PlayerThing>();

                    if (player == null)
                    {
                        return;
                    }

                    foreach (Floor36Controller lc in linked)
                    {
                        if (lc.CurrentState == Floor36Controller.State.AtTop)
                        {
                            lc.CurrentState = Floor36Controller.State.Lowering;
                        }
                    }
                };
            }
            break;

            //single use door, shootable
            case 46:
            {
                if (l.TopFrontObject == null)
                {
                    break;
                }

                if (l.Back == null)
                {
                    break;
                }

                l.Back.Sector.ceilingObject.transform.SetParent(GameManager.Instance.transform);

                Door46Controller          lc = l.TopFrontObject.AddComponent <Door46Controller>();
                SlowOneshotDoorController sc = l.Back.Sector.ceilingObject.GetComponent <SlowOneshotDoorController>();
                if (sc == null)
                {
                    sc = l.Back.Sector.ceilingObject.AddComponent <SlowOneshotDoorController>();
                }

                sc.Init(l.Back.Sector);
                lc.sectorController = sc;

                l.Back.Sector.Dynamic = true;
            }
            break;

            //scroll animation, left
            case 48:
            {
                foreach (GameObject g in l.gameObjects)
                {
                    if (g != null)
                    {
                        g.AddComponent <ScrollLeftAnimation>();
                    }
                }
            }
            break;

            //secret level end switch
            case 51:
            {
                if (l.BotFrontObject != null)
                {
                    End51LinedefController lc = l.BotFrontObject.AddComponent <End51LinedefController>();
                    lc.CurrentTexture = l.Front.tLow;
                    l.BotFrontObject.transform.SetParent(holder);
                }
                else if (l.MidFrontObject != null)
                {
                    End51LinedefController lc = l.MidFrontObject.AddComponent <End51LinedefController>();
                    lc.CurrentTexture = l.Front.tMid;
                    l.MidFrontObject.transform.SetParent(holder);
                }
            }
            break;

            //common lift, pokeable
            case 62:
            {
                if (!Sector.TaggedSectors.ContainsKey(l.lineTag))
                {
                    break;
                }

                if (l.BotFrontObject == null)
                {
                    break;
                }

                List <Slow3sLiftController> linked = new List <Slow3sLiftController>();
                foreach (Sector sector in Sector.TaggedSectors[l.lineTag])
                {
                    sector.floorObject.transform.SetParent(holder);

                    Slow3sLiftController script = sector.floorObject.GetComponent <Slow3sLiftController>();
                    if (script == null)
                    {
                        script = sector.floorObject.gameObject.AddComponent <Slow3sLiftController>();
                        script.Init(sector);
                    }

                    linked.Add(script);

                    sector.Dynamic = true;
                }

                Lift62Controller lc = l.BotFrontObject.AddComponent <Lift62Controller>();
                lc.liftControllers = linked;
            }
            break;

            //repeatable door, switch
            case 63:
            {
                if (!Sector.TaggedSectors.ContainsKey(l.lineTag))
                {
                    break;
                }

                List <SlowRepeatableDoorController> linked = new List <SlowRepeatableDoorController>();
                foreach (Sector sector in Sector.TaggedSectors[l.lineTag])
                {
                    sector.ceilingObject.transform.SetParent(holder);

                    SlowRepeatableDoorController sc = sector.ceilingObject.GetComponent <SlowRepeatableDoorController>();
                    if (sc == null)
                    {
                        sc = sector.ceilingObject.AddComponent <SlowRepeatableDoorController>();
                        sc.Init(sector);
                    }

                    linked.Add(sc);

                    sector.Dynamic = true;
                }

                if (l.BotFrontObject != null)
                {
                    Door63Controller lc = l.BotFrontObject.AddComponent <Door63Controller>();
                    lc.sectorControllers = linked;
                    lc.CurrentTexture    = l.Front.tLow;
                    l.BotFrontObject.transform.SetParent(holder);
                }
                else if (l.MidFrontObject != null)
                {
                    Door63Controller lc = l.MidFrontObject.AddComponent <Door63Controller>();
                    lc.sectorControllers = linked;
                    lc.CurrentTexture    = l.Front.tMid;
                    l.MidFrontObject.transform.SetParent(holder);
                }
            }
            break;

            //common lift, walktrigger
            case 88:
            {
                if (!Sector.TaggedSectors.ContainsKey(l.lineTag))
                {
                    break;
                }

                List <Slow3sLiftController> linked = new List <Slow3sLiftController>();
                foreach (Sector sector in Sector.TaggedSectors[l.lineTag])
                {
                    sector.floorObject.transform.SetParent(holder);

                    Slow3sLiftController sc = sector.floorObject.GetComponent <Slow3sLiftController>();
                    if (sc == null)
                    {
                        sc = sector.floorObject.gameObject.AddComponent <Slow3sLiftController>();
                        sc.Init(sector);
                    }

                    linked.Add(sc);

                    sector.Dynamic = true;
                }

                BoxCollider mc = Mesher.CreateLineTriggerCollider(
                    l,
                    Mathf.Min(l.Front.Sector.minimumFloorHeight, l.Back.Sector.minimumFloorHeight),
                    Mathf.Max(l.Front.Sector.maximumCeilingHeight, l.Back.Sector.maximumCeilingHeight),
                    "Tag_" + l.lineTag + "_trigger",
                    holder
                    );

                if (mc == null)
                {
                    Debug.LogError("Linedef " + index + " could not create trigger. Type(" + l.lineType + ")");
                    break;
                }

                mc.isTrigger = true;

                LineTrigger lt = mc.gameObject.AddComponent <LineTrigger>();
                lt.TriggerAction = (c) =>
                {
                    foreach (Slow3sLiftController lc in linked)
                    {
                        if (lc.CurrentState == Slow3sLiftController.State.AtTop)
                        {
                            lc.CurrentState = Slow3sLiftController.State.Lowering;
                        }
                    }
                };
            }
            break;

            //repeatable door, walktrigger
            case 90:
            {
                if (!Sector.TaggedSectors.ContainsKey(l.lineTag))
                {
                    break;
                }

                List <SlowRepeatableDoorController> linked = new List <SlowRepeatableDoorController>();
                foreach (Sector sector in Sector.TaggedSectors[l.lineTag])
                {
                    sector.ceilingObject.transform.SetParent(holder);

                    SlowRepeatableDoorController sc = sector.ceilingObject.GetComponent <SlowRepeatableDoorController>();
                    if (sc == null)
                    {
                        sc = sector.ceilingObject.gameObject.AddComponent <SlowRepeatableDoorController>();
                        sc.Init(sector);
                    }
                    linked.Add(sc);

                    sector.Dynamic = true;
                }

                BoxCollider mc = Mesher.CreateLineTriggerCollider(
                    l,
                    Mathf.Min(l.Front.Sector.minimumFloorHeight, l.Back.Sector.minimumFloorHeight),
                    Mathf.Max(l.Front.Sector.maximumCeilingHeight, l.Back.Sector.maximumCeilingHeight),
                    "Tag_" + l.lineTag + "_trigger",
                    holder
                    );

                if (mc == null)
                {
                    Debug.LogError("Linedef " + index + " could not create trigger. Type(" + l.lineType + ")");
                    break;
                }

                mc.isTrigger = true;

                LineTrigger lt = mc.gameObject.AddComponent <LineTrigger>();
                lt.TriggerAction = (c) =>
                {
                    PlayerThing player = c.GetComponent <PlayerThing>();

                    if (player == null)
                    {
                        return;
                    }

                    foreach (SlowRepeatableDoorController lc in linked)
                    {
                        if (lc.CurrentState == SlowRepeatableDoorController.State.Closed)
                        {
                            lc.CurrentState = SlowRepeatableDoorController.State.Opening;
                        }
                    }
                };
            }
            break;

            //single use door, switch
            case 103:
            {
                if (!Sector.TaggedSectors.ContainsKey(l.lineTag))
                {
                    break;
                }

                List <SlowOneshotDoorController> linked = new List <SlowOneshotDoorController>();
                foreach (Sector sector in Sector.TaggedSectors[l.lineTag])
                {
                    sector.ceilingObject.transform.SetParent(holder);

                    SlowOneshotDoorController sc = sector.ceilingObject.GetComponent <SlowOneshotDoorController>();
                    if (sc == null)
                    {
                        sc = sector.ceilingObject.AddComponent <SlowOneshotDoorController>();
                        sc.Init(sector);
                    }

                    linked.Add(sc);

                    sector.Dynamic = true;
                }

                if (l.BotFrontObject != null)
                {
                    Door103Controller lc = l.BotFrontObject.AddComponent <Door103Controller>();
                    lc.sectorControllers = linked;
                    lc.CurrentTexture    = l.Front.tLow;
                    l.BotFrontObject.transform.SetParent(holder);
                }
                else if (l.MidFrontObject != null)
                {
                    Door103Controller lc = l.MidFrontObject.AddComponent <Door103Controller>();
                    lc.sectorControllers = linked;
                    lc.CurrentTexture    = l.Front.tMid;
                    l.MidFrontObject.transform.SetParent(holder);
                }
            }
            break;
            }
        }
    }