Beispiel #1
0
    public static bool InLos(TacticsTerrainMesh mesh, Vector2Int at, Vector2Int to, float range)
    {
        if (at == to)
        {
            return(true);
        }
        Vector3 at3   = new Vector3(at.x + 0.5f, mesh.HeightAt(at.x, at.y) + 1.5f, at.y + 0.5f);
        Vector3 to3   = new Vector3(to.x + 0.5f, mesh.HeightAt(to.x, to.y) + 1.5f, to.y + 0.5f);
        Vector3 delta = (to3 - at3);

        if (delta.sqrMagnitude > range * range)
        {
            return(false);
        }
        Vector3 planar = Vector3.Cross(delta, new Vector3(0, 1, 0)).normalized;

        if (ClearRayExists(mesh, at3 + planar * 0.4f, to3 + planar * 0.4f))
        {
            return(true);
        }
        else if (ClearRayExists(mesh, at3 - planar * 0.5f, to3 - planar * 0.5f))
        {
            return(true);
        }
        else
        {
            return(false);
        }
    }
Beispiel #2
0
    public bool CanSeeLocation(TacticsTerrainMesh mesh, Vector2Int to)
    {
        LineOfSightEffect los = battle.GetComponent <LineOfSightEffect>();

        if (los.sitemap == null)
        {
            los.RegenSitemap(mesh);
        }
        if (sight == 0)
        {
            sight = unit.Get(StatTag.SIGHT);
        }
        //return MathHelper3D.InLos(mesh, this.location, location, sight);
        Vector2Int at    = location;
        Vector3    at3   = new Vector3(at.x + 0.5f, mesh.HeightAt(at.x, at.y) + 1.5f, at.y + 0.5f);
        Vector3    to3   = new Vector3(to.x + 0.5f, mesh.HeightAt(to.x, to.y) + 1.5f, to.y + 0.5f);
        Vector3    delta = (to3 - at3);

        if (delta.sqrMagnitude > sight * sight)
        {
            return(false);
        }
        else
        {
            return(los.sitemap[
                       to.y * (mesh.size.x * mesh.size.y * mesh.size.x) +
                       to.x * (mesh.size.x * mesh.size.y) +
                       at.y * (mesh.size.x) +
                       at.x]);
        }
    }
Beispiel #3
0
    public void FillWithVault(TacticsTerrainMesh mesh)
    {
        if (RandUtils.Chance(0.4f))
        {
            return;
        }
        if (vaults == null)
        {
            vaults = Resources.Load <VaultList>(VaultsPath);
        }
        bool flipX = RandUtils.Flip();
        bool flipY = RandUtils.Flip();
        TacticsTerrainMesh vault = vaults.vaults[Random.Range(0, vaults.vaults.Count)];

        for (int trueY = 0; trueY < cell.sizeY; trueY += 1)
        {
            for (int trueX = 0; trueX < cell.sizeX; trueX += 1)
            {
                int x = flipX ? trueX : (cell.sizeX - 1 - trueX);
                int y = flipY ? trueY : (cell.sizeY - 1 - trueY);
                mesh.SetHeight(cell.startX + x, cell.startY + y,
                               mesh.HeightAt(cell.startX + x, cell.startY + y) + vault.HeightAt(x, y) - 1.0f);
                Tile topTile = vault.TileAt(x, y);
                if (topTile != mesh.defaultTopTile)
                {
                    mesh.SetTile(cell.startX + x, cell.startY + y, topTile);
                }
                for (float h = 0.0f; h < vault.HeightAt(x, y); h += 0.5f)
                {
                    foreach (OrthoDir dir in System.Enum.GetValues(typeof(OrthoDir)))
                    {
                        Tile t = vault.TileAt(x, y, h, dir);
                        if (t != mesh.defaultFaceTile)
                        {
                            mesh.SetTile(cell.startX + x, cell.startY + y, mesh.HeightAt(x, y) - 1 + h, dir, t);
                        }
                    }
                }
            }
        }
    }
Beispiel #4
0
    public static bool ClearRayExists(TacticsTerrainMesh mesh, Vector3 start, Vector3 end)
    {
        Vector3 slope   = (end - start).normalized;
        float   atX     = start.x;
        float   atY     = start.y;
        float   atZ     = start.z;
        float   totalM  = 0.0f;
        float   targetM = (end - start).sqrMagnitude;

        for (int tries = 0; tries < 10000; tries += 1)
        {
            float toNextX = slope.x > 0 ? (1.0f - atX % 1) : (atX % 1);
            float mToX    = toNextX < float.Epsilon ? float.MaxValue : Mathf.Abs(toNextX / slope.x);
            float toNextY = slope.y > 0 ? (1.0f - atY % 1) : (atY % 1);
            float mToY    = toNextY < float.Epsilon ? float.MaxValue : Mathf.Abs(toNextY / slope.y);
            float toNextZ = slope.z > 0 ? (1.0f - atZ % 1) : (atZ % 1);
            float mToZ    = toNextZ < float.Epsilon ? float.MaxValue : Mathf.Abs(toNextZ / slope.z);
            float nextM;
            if (!float.IsInfinity(mToX) && mToX < mToY && mToX < mToZ)
            {
                nextM = mToX;
            }
            else if (!float.IsInfinity(mToY) && mToY < mToZ && mToY < mToZ)
            {
                nextM = mToY;
            }
            else
            {
                nextM = mToZ;
            }
            atX    += nextM * slope.x;
            atY    += nextM * slope.y;
            atZ    += nextM * slope.z;
            totalM += nextM;

            if (totalM * totalM > targetM)
            {
                return(true);
            }
            if (mesh.HeightAt(Mathf.FloorToInt(atX), Mathf.FloorToInt(atZ)) > atY)
            {
                // translucency would go here but, no
                if (Math.Abs(Mathf.Floor(atX) - Mathf.Floor(start.x)) > 0.0f ||
                    Math.Abs(Mathf.Floor(atZ) - Mathf.Floor(start.z)) > 0.0f)
                {
                    return(false);
                }
            }
        }
        Debug.LogError("major fuckup");
        return(true);
    }
Beispiel #5
0
    private void Rebuild(bool regenMesh)
    {
        TacticsTerrainMesh terrain = (TacticsTerrainMesh)target;

        PrefabStage prefabStage = PrefabStageUtility.GetPrefabStage(terrain.gameObject);

        if (prefabStage != null)
        {
            EditorSceneManager.MarkSceneDirty(prefabStage.scene);
        }

        MeshFilter filter = terrain.GetComponent <MeshFilter>();
        Mesh       mesh   = filter.sharedMesh;

        if (mesh == null)
        {
            mesh = new Mesh();
            AssetDatabase.CreateAsset(mesh, "Assets/Resources/TacticsMaps/Meshes/" + terrain.gameObject.name + ".asset");
            filter.sharedMesh = mesh;
        }

        quads    = new Dictionary <Vector3, Dictionary <Vector3, TerrainQuad> >();
        vertices = new List <Vector3>();
        uvs      = new List <Vector2>();
        tris     = new List <int>();
        for (int z = 0; z < terrain.size.y; z += 1)
        {
            for (int x = 0; x < terrain.size.x; x += 1)
            {
                // top vertices
                float height = terrain.HeightAt(x, z);
                AddQuad(new Vector3(x, height, z), new Vector3(x + 1, height, z + 1), terrain.TileAt(x, z),
                        new Vector3(x, height, z), new Vector3(0, 1, 0));

                // side vertices
                foreach (OrthoDir dir in Enum.GetValues(typeof(OrthoDir)))
                {
                    float currentHeight  = terrain.HeightAt(x, z);
                    float neighborHeight = terrain.HeightAt(x + dir.Px3DX(), z + dir.Px3DZ());
                    if (currentHeight > neighborHeight)
                    {
                        Vector2 off1 = Vector2.zero, off2 = Vector2.zero;
                        switch (dir)
                        {
                        case OrthoDir.South:
                            off1 = new Vector2(0, 0);
                            off2 = new Vector2(1, 0);
                            break;

                        case OrthoDir.East:
                            off1 = new Vector2(1, 1);
                            off2 = new Vector2(1, 0);
                            break;

                        case OrthoDir.North:
                            off1 = new Vector2(1, 1);
                            off2 = new Vector2(0, 1);
                            break;

                        case OrthoDir.West:
                            off1 = new Vector2(0, 0);
                            off2 = new Vector2(0, 1);
                            break;
                        }
                        for (float y = neighborHeight; y < currentHeight; y += 0.5f)
                        {
                            AddQuad(new Vector3(x + off1.x, y, z + off1.y),
                                    new Vector3(x + off2.x, y + 0.5f, z + off2.y),
                                    terrain.TileAt(x, z, y, dir),
                                    new Vector3(x, y + 0.5f, z), dir.Px3D());
                        }
                    }
                }
            }
        }

        if (regenMesh)
        {
            selectedQuads.Clear();
            mesh.Clear();

            mesh.vertices  = vertices.ToArray();
            mesh.triangles = tris.ToArray();
            mesh.uv        = uvs.ToArray();

            mesh.RecalculateBounds();
            mesh.RecalculateNormals();
        }
    }
Beispiel #6
0
    private void HandleLeftclick(EventType typeForControl, int controlId)
    {
        TacticsTerrainMesh terrain = (TacticsTerrainMesh)target;

        switch (typeForControl)
        {
        case EventType.MouseDown:
            switch (tool)
            {
            case SelectionTool.HeightAdjust:
                if (selectedQuads.Count > 0 && selectedQuads[0].normal.y > 0.0f)
                {
                    ConsumeEvent(controlId);
                    mode = EditMode.AdjustingHeight;
                    Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                    selectedHeight = 0.0f;
                }
                break;

            case SelectionTool.Paint:
                if (selectedQuads.Count > 0)
                {
                    ConsumeEvent(controlId);
                    PaintTileIfNeeded();
                    mode           = EditMode.Painting;
                    paintingNormal = primarySelection.normal;
                }
                break;

            case SelectionTool.Select:
                ConsumeEvent(controlId);
                if (mode == EditMode.Selected)
                {
                    TerrainQuad newQuad = GetSelectedQuad();
                    if (newQuad == null || newQuad == primarySelection)
                    {
                        primarySelection = null;
                    }
                    else
                    {
                        primarySelection = newQuad;
                        CaptureSelection(primarySelection);
                    }
                }
                mode = primarySelection == null ? EditMode.None : EditMode.Selected;
                break;
            }
            break;

        case EventType.MouseDrag:
            switch (mode)
            {
            case EditMode.AdjustingHeight:
                ConsumeEvent(controlId);
                selectedHeight = MathHelper3D.GetHeightAtMouse(primarySelection);
                break;

            case EditMode.Painting:
                ConsumeEvent(controlId);
                primarySelection = GetSelectedQuad();
                CaptureSelection(primarySelection);
                PaintTileIfNeeded();
                break;
            }
            break;

        case EventType.MouseUp:
            switch (mode)
            {
            case EditMode.AdjustingHeight:
                mode = EditMode.None;
                bool dirty = false;

                float height = MathHelper3D.GetHeightAtMouse(primarySelection);
                foreach (TerrainQuad quad in selectedQuads)
                {
                    int x = Mathf.RoundToInt(quad.pos.x);
                    int y = Mathf.RoundToInt(quad.pos.z);
                    if (terrain.HeightAt(x, y) != height)
                    {
                        terrain.SetHeight(x, y, height);
                        dirty = true;
                    }
                }
                if (dirty)
                {
                    Rebuild(true);
                }
                break;

            case EditMode.Painting:
                mode = EditMode.None;
                break;
            }
            break;

        case EventType.ScrollWheel:
            if (mode == EditMode.None && selectedQuads.Count > 0)
            {
                GUIUtility.hotControl = 0;
                Event.current.Use();
                float maxSelection = Mathf.Max(selectionSize.x, selectionSize.y);
                maxSelection += -1.0f * Event.current.delta.y / 5.0f;
                selectionSize = new Vector2(maxSelection, maxSelection);
                if (Mathf.RoundToInt(selectionSize.x) < 1)
                {
                    selectionSize.x = 1;
                }
                if (Mathf.RoundToInt(selectionSize.y) < 1)
                {
                    selectionSize.y = 1;
                }
                CaptureSelection(primarySelection);
                SceneView.RepaintAll();
            }
            break;
        }

        if (selectedHeight >= 0.0f && mode == EditMode.AdjustingHeight)
        {
            int   x = Mathf.RoundToInt(primarySelection.pos.x);
            int   y = Mathf.RoundToInt(primarySelection.pos.z);
            float h = terrain.HeightAt(x, y);
            foreach (TerrainQuad quad in selectedQuads)
            {
                float z = MathHelper3D.GetHeightAtMouse(primarySelection);
                for (; Mathf.Abs(z - h) > 0.1f; z += 0.5f * Mathf.Sign(h - z))
                {
                    Handles.DrawWireCube(new Vector3(quad.pos.x + 0.5f, z + 0.25f * Mathf.Sign(h - z), quad.pos.z + 0.5f),
                                         new Vector3(1.0f, 0.5f, 1.0f));
                }
            }
        }
    }
Beispiel #7
0
    public void ConfigureNewGrid(Vector2Int at, Vector2Int size, TacticsTerrainMesh terrain,
                                 Func <Vector2Int, bool> rangeRule, Func <Vector2Int, bool> selectRule)
    {
        transform.position = new Vector3(0.0f, 0.0f, 0.0f);
        LineOfSightEffect los = terrain.GetComponent <LineOfSightEffect>();

        MeshFilter filter = this.mesh;

        if (filter.mesh != null)
        {
            Destroy(filter.mesh);
        }
        Mesh mesh = new Mesh();

        filter.mesh = mesh;

        List <Vector3> vertices = new List <Vector3>();
        List <Vector2> uvs      = new List <Vector2>();
        List <int>     tris     = new List <int>();

        for (int y = at.y; y < at.y + size.y; y += 1)
        {
            for (int x = at.x; x < at.x + size.x; x += 1)
            {
                if (terrain.HeightAt(x, y) == 0.0f || !los.CachedIsVisible(new Vector2Int(x, y)))
                {
                    continue;
                }
                bool selectable = selectRule(new Vector2Int(x, y));
                bool rangeable  = rangeRule(new Vector2Int(x, y));
                if (selectable || rangeable)
                {
                    int   vertIndex = vertices.Count;
                    float height    = terrain.HeightAt(x, y);
                    for (int i = 0; i < 4; i += 1)
                    {
                        if (selectable)
                        {
                            uvs.Add(new Vector2(
                                        i % 2 == 0 ? .5f : 0,
                                        i < 2 ? .5f : 0));
                        }
                        else if (rangeable)
                        {
                            uvs.Add(new Vector2(
                                        i % 2 == 0 ? 1 : .5f,
                                        i < 2 ? .5f : 0));
                        }
                        vertices.Add(new Vector3(
                                         x + (i % 2 == 0 ? 1 : 0),
                                         height,
                                         y + (i < 2 ? 1 : 0)));
                    }
                    tris.Add(vertIndex);
                    tris.Add(vertIndex + 2);
                    tris.Add(vertIndex + 1);
                    tris.Add(vertIndex + 1);
                    tris.Add(vertIndex + 2);
                    tris.Add(vertIndex + 3);
                }
            }
        }

        mesh.vertices  = vertices.ToArray();
        mesh.uv        = uvs.ToArray();
        mesh.triangles = tris.ToArray();
        mesh.RecalculateNormals();
    }