Exemple #1
0
    public void RenderTerrain(MapGenerator gen, TacticsTerrainMesh mesh)
    {
        switch (type)
        {
        case CellType.Hall:
            RenderHall(gen, mesh);
            break;

        case CellType.Stairway:
            RenderStairway(gen, mesh);
            break;

        case CellType.Switchback:
            RenderSwitchback(gen, mesh);
            break;

        case CellType.Pillar:
            RenderPillar(gen, mesh);
            break;

        case CellType.Room:
            RenderRoom(gen, mesh);
            break;
        }
    }
    private void UpdateTile(TerrainQuad quad, Tile tile)
    {
        TacticsTerrainMesh terrain = (TacticsTerrainMesh)target;

        quad.UpdateTile(tile, tileset, 0.0f);
        terrain.SetTile((int)quad.pos.x, (int)quad.pos.z, tile);
    }
Exemple #3
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]);
        }
    }
    private void UpdateTile(TerrainQuad quad, OrthoDir dir, Tile tile)
    {
        TacticsTerrainMesh terrain = (TacticsTerrainMesh)target;

        quad.UpdateTile(tile, tileset, quad.pos.y);
        terrain.SetTile((int)quad.pos.x, (int)quad.pos.z, quad.pos.y - 0.5f, dir, tile);
    }
Exemple #5
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);
        }
    }
    private void AddEvent(MapEvent3D mapEvent)
    {
        TacticsTerrainMesh terrain = (TacticsTerrainMesh)target;
        Map map = terrain.GetComponent <Map>();

        GameObjectUtility.SetParentAndAlign(mapEvent.gameObject, map.objectLayer.gameObject);
        Undo.RegisterCreatedObjectUndo(mapEvent, "Create " + mapEvent.name);
        mapEvent.SetLocation(new Vector2Int((int)primarySelection.pos.x, (int)primarySelection.pos.z));
        Selection.activeObject = mapEvent.gameObject;
    }
Exemple #7
0
 private void RenderPillar(MapGenerator gen, TacticsTerrainMesh mesh)
 {
     for (int y = startY; y < startY + sizeY; y += 1)
     {
         for (int x = startX; x < startX + sizeX; x += 1)
         {
             mesh.SetHeight(x, y, pillarZ);
         }
     }
 }
Exemple #8
0
    private void RenderRoom(MapGenerator gen, TacticsTerrainMesh mesh)
    {
        RoomInfo room = gen.rooms[x / 2, y / 2];

        for (int y = startY; y < startY + sizeY; y += 1)
        {
            for (int x = startX; x < startX + sizeX; x += 1)
            {
                mesh.SetHeight(x, y, room.z);
            }
        }
    }
Exemple #9
0
    private void PaintTileIfNeeded()
    {
        TacticsTerrainMesh terrain = (TacticsTerrainMesh)target;

        foreach (TerrainQuad quad in selectedQuads)
        {
            if (quad.normal.y > 0.0f)
            {
                int  originX = (int)primarySelection.pos.x - Mathf.FloorToInt(Mathf.RoundToInt(selectionSize.x) / 2.0f);
                int  originY = (int)primarySelection.pos.z - Mathf.FloorToInt(Mathf.RoundToInt(selectionSize.y) / 2.0f);
                Tile tile    = TileForSelection((int)(quad.pos.x - originX), (int)(quad.pos.z - originY));
                UpdateTile(quad, tile);
            }
            else
            {
                Tile tile;
                if (quad.normal.x != 0.0f)
                {
                    int originX = (int)primarySelection.pos.z - Mathf.FloorToInt(Mathf.RoundToInt(selectionSize.x) / 2.0f);
                    int originY = (int)primarySelection.pos.y - Mathf.FloorToInt(Mathf.RoundToInt(selectionSize.y) / 2.0f);
                    tile = TileForSelection((int)(quad.pos.z - originX), (int)(quad.pos.y - originY));
                }
                else
                {
                    int originX = (int)primarySelection.pos.x - Mathf.FloorToInt(Mathf.RoundToInt(selectionSize.x) / 2.0f);
                    int originY = (int)primarySelection.pos.y - Mathf.FloorToInt(Mathf.RoundToInt(selectionSize.y) / 2.0f);
                    tile = TileForSelection((int)(quad.pos.x - originX), (int)(quad.pos.y - originY));
                }
                if (wraparoundPaintMode)
                {
                    foreach (OrthoDir dir in Enum.GetValues(typeof(OrthoDir)))
                    {
                        UpdateTile(quad, dir, tile);
                    }
                }
                else
                {
                    UpdateTile(quad, OrthoDirExtensions.DirectionOf3D(quad.normal), tile);
                }
            }
        }
        RepaintMesh();
        primarySelection = GetSelectedQuad();
        CaptureSelection(primarySelection);

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

        if (prefabStage != null)
        {
            EditorSceneManager.MarkSceneDirty(prefabStage.scene);
        }
    }
Exemple #10
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);
    }
Exemple #11
0
    private void RenderSwitchback(MapGenerator gen, TacticsTerrainMesh mesh)
    {
        RoomInfo lowRoom, highRoom;

        if (this.x % 2 == 1)
        {
            lowRoom  = gen.rooms[(this.x - 1) / 2, this.y / 2];
            highRoom = gen.rooms[(this.x + 1) / 2, this.y / 2];
        }
        else
        {
            lowRoom  = gen.rooms[this.x / 2, (this.y - 1) / 2];
            highRoom = gen.rooms[this.x / 2, (this.y + 1) / 2];
        }
        if (lowRoom.z > highRoom.z)
        {
            RoomInfo temp = lowRoom;
            lowRoom  = highRoom;
            highRoom = temp;
        }
        float deltaZ = highRoom.z - lowRoom.z;

        float d        = (float)deltaZ / (sizeX * sizeY);
        bool  switched = false;
        int   x        = 0;
        int   y        = 0;

        for (int i = 0; i < sizeX * sizeY; i += 1)
        {
            mesh.SetHeight(startX + x, startY + y, lowRoom.z + Mathf.RoundToInt(d * i * 2.0f) / 2.0f);
            if (this.x % 2 == 1)
            {
                y += switched ? -1 : 1;
                if (y >= sizeY || y < 0)
                {
                    switched = !switched;
                    x       += 1;
                    y        = Math.Min(Math.Max(y, 0), sizeY - 1);
                }
            }
            else
            {
                x += switched ? -1 : 1;
                if (x >= sizeX || x < 0)
                {
                    switched = !switched;
                    y       += 1;
                    x        = Math.Min(Math.Max(x, 0), sizeX - 1);
                }
            }
        }
    }
Exemple #12
0
    private void UpdateWithPalette(GridPalette newPalette)
    {
        tileSelectRect    = new Rect(0, 0, 1, 1);
        paletteBufferSize = Vector2Int.zero;
        TacticsTerrainMesh terrain = (TacticsTerrainMesh)target;

        palette             = newPalette;
        terrain.paletteName = palette.name;
        string     palettePath   = "Assets/Tilesets/Palettes/" + palette.name + ".prefab";
        GameObject tilesetObject = AssetDatabase.LoadAssetAtPath <GameObject>(palettePath);

        tileset = tilesetObject.transform.GetChild(0).GetComponent <Tilemap>();
    }
Exemple #13
0
    // selects a square to be targeted by the acting unit, might be canceled
    public IEnumerator SelectTargetDirRoutine(Result <EightDir> result,
                                              BattleUnit actingUnit,
                                              List <EightDir> allowedDirs,
                                              bool canCancel = true)
    {
        actor = actingUnit.battler;

        gameObject.SetActive(true);
        actingUnit.battle.cursor.DisableReticules();

        SelectionGrid      grid    = actingUnit.battle.SpawnSelectionGrid();
        TacticsTerrainMesh terrain = actingUnit.battle.map.terrain;

        grid.ConfigureNewGrid(actingUnit.location, 1, terrain, (Vector2Int loc) => {
            return((loc.x + loc.y + actingUnit.location.x + actingUnit.location.y) % 2 < 2);
        }, (Vector2Int loc) => {
            return(allowedDirs.Contains(actingUnit.battler.GetComponent <MapEvent>().DirectionTo(loc)));
        });
        if (allowedDirs.Count > 0)
        {
            AttemptSetDirection(allowedDirs[0]);
        }
        else
        {
            GetComponent <MapEvent>().SetLocation(actor.location);
        }

        while (!result.finished)
        {
            Result <EightDir> dirResult = new Result <EightDir>();
            yield return(AwaitSelectionRoutine(actor, dirResult));

            if (dirResult.canceled)
            {
                if (canCancel)
                {
                    result.Cancel();
                    break;
                }
            }
            else
            {
                result.value = dirResult.value;
            }
        }

        Destroy(grid.gameObject);
        actingUnit.battle.cursor.EnableReticules();
        gameObject.SetActive(false);
    }
Exemple #14
0
    private void RenderHall(MapGenerator gen, TacticsTerrainMesh mesh)
    {
        List <RoomInfo> rooms = AdjacentRooms(gen);
        float           z     = rooms[0].z < rooms[1].z ? rooms[0].z : rooms[1].z;
        RoomInfo        room  = gen.rooms[x / 2, y / 2];

        for (int y = startY; y < startY + sizeY; y += 1)
        {
            for (int x = startX; x < startX + sizeX; x += 1)
            {
                mesh.SetHeight(x, y, z);
            }
        }
    }
Exemple #15
0
    private void RepaintMesh()
    {
        TacticsTerrainMesh terrain = (TacticsTerrainMesh)target;

        Vector2[] uvArray = new Vector2[terrain.GetComponent <MeshFilter>().sharedMesh.uv.Length];
        foreach (Dictionary <Vector3, TerrainQuad> quadDictionary in quads.Values)
        {
            foreach (TerrainQuad quad in quadDictionary.Values)
            {
                quad.CopyUVs(uvArray);
            }
        }

        terrain.GetComponent <MeshFilter>().sharedMesh.uv = uvArray;
        uvs = new List <Vector2>(uvArray);
    }
Exemple #16
0
    public void OnSceneGUI()
    {
        TacticsTerrainMesh terrain = (TacticsTerrainMesh)target;

        if (quads == null)
        {
            Rebuild(false);
        }

        int       controlId      = GUIUtility.GetControlID(FocusType.Passive);
        EventType typeForControl = Event.current.GetTypeForControl(controlId);

        switch (Event.current.button)
        {
        case 0:
            HandleLeftclick(typeForControl, controlId);
            break;

        case 1:
            HandleRightclick(typeForControl, controlId);
            break;
        }

        TerrainQuad quad = GetSelectedQuad();

        switch (typeForControl)
        {
        case EventType.MouseMove:
            switch (mode)
            {
            case EditMode.None:
            case EditMode.Painting:
                if (quad != primarySelection)
                {
                    CaptureSelection(quad);
                    primarySelection = quad;
                    SceneView.RepaintAll();
                }
                break;
            }
            break;
        }

        MathHelper3D.DrawQuads(selectedQuads, Color.white);
    }
Exemple #17
0
    private Tile TileForSelection(int x, int y)
    {
        TacticsTerrainMesh terrain = (TacticsTerrainMesh)target;

        if (paletteBufferSize == Vector2.zero)
        {
            return(terrain.tileset.GetTile <Tile>(new Vector3Int(
                                                      (int)tileSelectRect.x + (x % (int)tileSelectRect.width),
                                                      (int)tileSelectRect.y + (y % (int)tileSelectRect.height),
                                                      0)));
        }
        else
        {
            return(paletteBuffer[
                       (x % paletteBufferSize.x) +
                       (y % paletteBufferSize.y) * (paletteBufferSize.x)]);
        }
    }
Exemple #18
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);
                        }
                    }
                }
            }
        }
    }
Exemple #19
0
    private void AssignCommonShaderVariables()
    {
        Material material = FindMaterial();

        if (Application.isPlaying)
        {
            if (pc == null || pc.GetComponent <BattleEvent>() == null)
            {
                return;
            }
            TacticsTerrainMesh mesh = GetComponent <TacticsTerrainMesh>();

            material.SetFloat("_CellResolutionX", mesh.size.x);
            material.SetFloat("_CellResolutionY", mesh.size.y);
            material.SetTexture("_VisibilityTex", losTexture);
            material.SetFloat("_VisibilityBlend", visBlend);
            material.SetVector("_HeroPos", heroPos);
            material.SetFloat("_SightRange", pc.GetComponent <BattleEvent>().unit.Get(StatTag.SIGHT));
            if (oldLosTexture != null)
            {
                material.SetTexture("_OldVisibilityTex", oldLosTexture);
            }
            else
            {
                material.SetTexture("_OldVisibilityTex", losTexture);
            }
            if (oldHeroPos == Vector3.zero)
            {
                material.SetVector("_OldHeroPos", heroPos);
            }
            else
            {
                material.SetVector("_OldHeroPos", oldHeroPos);
            }
        }
        else
        {
            material.SetFloat("_SightRange", 1000.0f);
        }
    }
Exemple #20
0
    private void Rebuild(bool regenMesh)
    {
        TacticsTerrainMesh terrain = (TacticsTerrainMesh)target;

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

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

        MeshGenerationResult result = terrain.Rebuild(regenMesh);

        quads    = result.quads;
        tris     = result.tris;
        uvs      = result.uvs;
        vertices = result.vertices;

        if (regenMesh)
        {
            selectedQuads.Clear();
        }
    }
Exemple #21
0
    // SITEMAP GARBAGE ==============

    public void RegenSitemap(TacticsTerrainMesh mesh)
    {
        Vector3 v1 = new Vector3();
        Vector3 v2 = new Vector3();

        sitemap = new BitArray(mesh.size.x * mesh.size.y * mesh.size.x * mesh.size.y);
        for (int y1 = 0; y1 < mesh.size.y; y1 += 1)
        {
            for (int x1 = 0; x1 < mesh.size.x; x1 += 1)
            {
                for (int y2 = 0; y2 < mesh.size.y; y2 += 1)
                {
                    for (int x2 = 0; x2 < mesh.size.x; x2 += 1)
                    {
                        bool res = false;
                        int  dx  = x1 - x2;
                        int  dy  = y1 - y2;
                        if (dx * dx + dy * dy < 10 * 10)
                        {
                            v1.x = x1;
                            v1.y = mesh.heights[y1 * mesh.size.x + x1] + 1.0f;
                            v1.z = y1;
                            v2.x = x2;
                            v2.y = mesh.heights[y2 * mesh.size.x + x2] + 1.0f;
                            v2.z = y2;
                            res  = MathHelper3D.ClearRayExists(mesh, v1, v2);
                        }
                        sitemap[
                            y2 * (mesh.size.x * mesh.size.y * mesh.size.x) +
                            x2 * (mesh.size.x * mesh.size.y) +
                            y1 * (mesh.size.x) +
                            x1] = res;
                    }
                }
            }
        }
    }
Exemple #22
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();
        }
    }
Exemple #23
0
    public void RecalculateVisibilityMap()
    {
        Profiler.BeginSample("los");
        mesh = GetComponent <TacticsTerrainMesh>();

        if (seenMap == null)
        {
            seenMap = new bool[mesh.size.x, mesh.size.y];
            for (int y = 0; y < mesh.size.y; y += 1)
            {
                for (int x = 0; x < mesh.size.x; x += 1)
                {
                    seenMap[x, y] = false;
                }
            }
            if (Application.isPlaying)
            {
                pc = Global.Instance().Maps.pc;
            }
            if (pc == null)
            {
                pc = FindObjectOfType <PCEvent>();
            }
        }

        if (oldLosTexture != null)
        {
            Destroy(oldLosTexture);
        }
        oldLosTexture         = losTexture;
        oldHeroPos            = heroPos;
        losTexture            = new Texture2D(mesh.size.x, mesh.size.y, TextureFormat.ARGB32, false);
        losTexture.filterMode = FilterMode.Point;
        losTexture.wrapMode   = TextureWrapMode.Clamp;
        heroPos  = pc.GetComponent <MapEvent3D>().TileToWorldCoords(pc.GetComponent <MapEvent>().location);
        heroPos += new Vector3(0.5f, 1.5f, 0.5f);

        map = new Color[mesh.size.x * mesh.size.y];
        BattleEvent battler = pc.GetComponent <BattleEvent>();
        Vector2Int  v       = new Vector2Int();

        for (int y = 0; y < mesh.size.y; y += 1)
        {
            for (int x = 0; x < mesh.size.x; x += 1)
            {
                float r = 1.0f;
                float b = 1.0f;
                v.x = x;
                v.y = y;
                if (battler.CanSeeLocation(mesh, v))
                {
                    seenMap[x, y] = true;
                }
                else
                {
                    r = 0.0f;
                    b = seenMap[x, y] ? 1.0f : 0.0f;
                }
                map[y * mesh.size.x + x] = new Color(r, 0.0f, b);
            }
        }
        losTexture.SetPixels(0, 0, mesh.size.x, mesh.size.y, map);
        losTexture.Apply();

        foreach (PCVisibility vis in GetComponent <Map>().GetEvents <PCVisibility>())
        {
            Vector2Int location = vis.GetComponent <MapEvent>().location;
            vis.SetVisibleByPC(CachedIsVisible(location));
        }

        Profiler.EndSample();
    }
Exemple #24
0
    public void GenerateMesh(MapGenerator lastMap = null)
    {
        TacticsTerrainMesh mesh = GetComponent <TacticsTerrainMesh>();

        // copy oldbie values if needed
        if (lastMap != null)
        {
            sizeInRoomsMin    = lastMap.sizeInRoomsMin;
            sizeInRoomsMax    = lastMap.sizeInRoomsMax;
            stairLength       = lastMap.stairLength;
            startEventPrefab  = lastMap.startEventPrefab;
            endEventPrefab    = lastMap.endEventPrefab;
            impassEventPrefab = lastMap.impassEventPrefab;
            defaultImpassTile = lastMap.defaultImpassTile;
            chestEventPrefab  = lastMap.chestEventPrefab;
            targetPrefab      = lastMap.targetPrefab;
            finalLevel        = lastMap.finalLevel;
            finalLevelPrefab  = lastMap.finalLevelPrefab;
            table             = lastMap.table;
            level             = lastMap.level + 1;
        }

        if (level == finalLevel)
        {
            Map other = Instantiate(finalLevelPrefab);
            Global.Instance().Maps.activeMap = other;
            return;
        }

        // wipe what's already there

        mesh.ClearTiles();
        foreach (MapEvent toRemove in GetComponent <Map>().GetEvents <MapEvent>())
        {
            if (toRemove.GetComponent <PCEvent>() == null)
            {
                if (toRemove.GetComponent <BattleEvent>() && Application.isPlaying)
                {
                    GetComponent <BattleController>().RemoveUnit(toRemove.GetComponent <BattleEvent>().unit);
                }
                GetComponent <Map>().RemoveEvent(toRemove, true);
            }
        }

        // work out some constants
        if (Flip())
        {
            sizeInRooms = new Vector2Int(sizeInRoomsMin.x, sizeInRoomsMax.y);
        }
        else
        {
            sizeInRooms = new Vector2Int(sizeInRoomsMax.x, sizeInRoomsMin.y);
        }
        int seed = (int)DateTime.Now.Ticks;

        Random.InitState(seed);
        Debug.Log("using seed " + seed);
        rooms       = new RoomInfo[sizeInRooms.x, sizeInRooms.y];
        sizeInCells = sizeInRooms * 2 - new Vector2Int(1, 1);
        cells       = new CellInfo[sizeInCells.x, sizeInCells.y];

        // are we going to add the starting stairwell on the left or right?
        if (lastMap != null)
        {
            if (lastMap.endStairsNW)
            {
                entryRoomCoords = new Vector2Int(Random.Range(0, 2), 0);
                startStairsSW   = false;
            }
            else
            {
                entryRoomCoords = new Vector2Int(0, Random.Range(0, 2));
                startStairsSW   = true;
            }
            exitRoomCoords = new Vector2Int(sizeInRooms.x - 1, sizeInRooms.y - 1);
            if (Flip())
            {
                exitRoomCoords.x -= Random.Range(0, 2);
            }
            else
            {
                exitRoomCoords.y -= Random.Range(0, 2);
            }
        }
        else
        {
            if (entryRoomCoords == Vector2Int.zero)
            {
                startStairsSW = Flip();
            }
            else if (entryRoomCoords.y > 0)
            {
                startStairsSW = true;
            }
            else
            {
                startStairsSW = false;
            }
        }
        if (exitRoomCoords == new Vector2Int(sizeInRooms.x - 1, sizeInRooms.y - 1))
        {
            endStairsNW = Flip();
        }
        else if (exitRoomCoords.x < sizeInRooms.x - 1)
        {
            endStairsNW = true;
        }
        else
        {
            endStairsNW = false;
        }

        // set the size and start of each room and hallway
        cells   = new CellInfo[sizeInCells.x, sizeInCells.y];
        widths  = new int[sizeInCells.x];
        heights = new int[sizeInCells.y];
        for (int y = 0; y < sizeInCells.y; y += 1)
        {
            if (y % 2 == 1)
            {
                heights[y] = RandomHallSize();
            }
            else
            {
                heights[y] = RandomRoomSize();
            }
        }
        for (int x = 0; x < sizeInCells.x; x += 1)
        {
            if (x % 2 == 1)
            {
                widths[x] = RandomHallSize();
            }
            else
            {
                widths[x] = RandomRoomSize();
            }
        }
        for (int y = 0; y < sizeInCells.y; y += 1)
        {
            for (int x = 0; x < sizeInCells.x; x += 1)
            {
                cells[x, y] = new CellInfo(x, y, widths[x], heights[y]);
                if (x % 2 == 1 || y % 2 == 1)
                {
                    if (x % 2 == 1 && y % 2 == 1)
                    {
                        cells[x, y].type = CellInfo.CellType.Pillar;
                    }
                    else
                    {
                        cells[x, y].type = CellInfo.CellType.Hall;
                    }
                }
                else
                {
                    cells[x, y].type = CellInfo.CellType.Room;
                }
                if (x == 0)
                {
                    cells[x, y].startX = startStairsSW ? stairLength : 0;
                }
                else
                {
                    cells[x, y].startX = cells[x - 1, y].startX + widths[x - 1];
                }
                if (y == 0)
                {
                    cells[x, y].startY = startStairsSW ? 0 : stairLength;
                }
                else
                {
                    cells[x, y].startY = cells[x, y - 1].startY + heights[y - 1];
                }
            }
        }

        // set the elevation of each room
        for (int diag = 0; diag < sizeInRooms.x + sizeInRooms.y; diag += 1)
        {
            int x = diag;
            int y = 0;
            while (x >= 0)
            {
                if (x < sizeInRooms.x && y < sizeInRooms.y)
                {
                    float z;
                    if (x == 0 && y == 0)
                    {
                        z = stairLength / 2.0f + 0.5f;
                    }
                    else
                    {
                        float oldZ;
                        if (y == 0)
                        {
                            oldZ = rooms[x - 1, y].z;
                        }
                        else if (x == 0)
                        {
                            oldZ = rooms[x, y - 1].z;
                        }
                        else
                        {
                            oldZ = Math.Max(rooms[x, y - 1].z, rooms[x - 1, y].z);
                        }
                        z = RandomNewZ(oldZ);
                    }
                    rooms[x, y] = new RoomInfo(cells[x * 2, y * 2], z);
                }
                x -= 1;
                y += 1;
            }
        }

        // determine the initial passability map
        cells[0, 0].connected = true;
        UpdatePassability();

        // knock down walls until all rooms are accessible
        List <RoomInfo> roomsToGo = new List <RoomInfo>();

        for (int x = 0; x < sizeInRooms.x; x += 1)
        {
            for (int y = 0; y < sizeInRooms.y; y += 1)
            {
                roomsToGo.Add(rooms[x, y]);
            }
        }
        while (roomsToGo.Count > 0)
        {
            int      index = Random.Range(0, roomsToGo.Count);
            RoomInfo room  = roomsToGo[index];
            if (room.cell.connected)
            {
                roomsToGo.RemoveAt(index);
                continue;
            }
            List <RoomInfo> adjacents = room.cell.AdjacentRooms(this);
            RandUtils.Shuffle(adjacents);
            RoomInfo adj = null;
            foreach (RoomInfo adj2 in adjacents)
            {
                if (!adj2.cell.connected)
                {
                    continue;
                }
                CellInfo connector = cells[(room.cell.x + adj2.cell.x) / 2, (room.cell.y + adj2.cell.y) / 2];
                if (Mathf.Abs(adj2.z - room.z) / (widths[connector.x] * heights[connector.y]) > 2)
                {
                    continue;
                }
                adj = adj2;
                break;
            }
            if (adj == null)
            {
                continue;
            }
            roomsToGo.RemoveAt(index);
            cells[(room.cell.x + adj.cell.x) / 2, (room.cell.y + adj.cell.y) / 2].connected = true;
            room.cell.connected = adj.cell.connected;

            if (adj.cell.connected)
            {
                UpdatePassability();
            }
        }

        // convert halls into stairways as needed
        for (int y = 0; y < sizeInCells.y; y += 1)
        {
            for (int x = 0; x < sizeInCells.x; x += 1)
            {
                CellInfo cell = cells[x, y];
                if (cell.type == CellInfo.CellType.Hall && cell.connected)
                {
                    List <RoomInfo> rooms  = cell.AdjacentRooms(this);
                    float           deltaZ = Math.Abs(rooms[0].z - rooms[1].z);
                    if (deltaZ > 1)
                    {
                        if (deltaZ > cell.sizeX / 2 && deltaZ > cell.sizeY / 2)
                        {
                            cell.type = CellInfo.CellType.Switchback;
                        }
                        else
                        {
                            cell.type = CellInfo.CellType.Stairway;
                        }
                    }
                }
            }
        }

        // set pillar heights to sane values
        for (int y = 0; y < sizeInCells.y; y += 1)
        {
            for (int x = 0; x < sizeInCells.x; x += 1)
            {
                CellInfo cell = cells[x, y];
                if (cell.type == CellInfo.CellType.Pillar)
                {
                    CellInfo n = cells[x, y + 1];
                    CellInfo e = cells[x + 1, y];
                    CellInfo s = cells[x, y - 1];
                    CellInfo w = cells[x - 1, y];
                    if (n.type == CellInfo.CellType.Stairway && e.type == CellInfo.CellType.Stairway)
                    {
                        cell.pillarZ        = rooms[(x + 1) / 2, (y + 1) / 2].z;
                        e.stairAnchoredHigh = true;
                        n.stairAnchoredHigh = true;
                    }
                    else if (s.type == CellInfo.CellType.Switchback && s.sizeX > 1)
                    {
                        cell.pillarZ = (s.AdjacentRooms(this)[0].z + s.AdjacentRooms(this)[1].z) / 2.0f;
                    }
                    else if (w.type == CellInfo.CellType.Switchback && s.sizeY > 1)
                    {
                        cell.pillarZ = (w.AdjacentRooms(this)[0].z + w.AdjacentRooms(this)[1].z) / 2.0f;
                    }
                    else
                    {
                        cell.pillarZ = rooms[(x - 1) / 2, (y - 1) / 2].z;
                    }
                }
            }
        }

        // decorator fringe
        RoomInfo cornerRoom = rooms[sizeInRooms.x - 1, sizeInRooms.y - 1];
        int      wallX      = cornerRoom.cell.startX + cornerRoom.cell.sizeX + 1;
        int      wallY      = cornerRoom.cell.startY + cornerRoom.cell.sizeY + 1;

        mesh.Resize(new Vector2Int(
                        wallX + (endStairsNW ? 0 : stairLength),
                        wallY + (endStairsNW ? stairLength : 0)),
                    0.0f);
        for (int x = startStairsSW ? stairLength : 0; x < wallX; x += 1)
        {
            mesh.SetHeight(x, wallY - 1, cornerRoom.z + MaxHeightDelta + 1);
            mesh.SetTile(x, wallY - 1, defaultImpassTile);
        }
        for (int y = startStairsSW ? 0 : stairLength; y < wallY; y += 1)
        {
            mesh.SetHeight(wallX - 1, y, cornerRoom.z + MaxHeightDelta + 1);
            mesh.SetTile(wallX - 1, y, defaultImpassTile);
        }

        // render terrain
        for (int y = 0; y < sizeInCells.y; y += 1)
        {
            for (int x = 0; x < sizeInCells.x; x += 1)
            {
                CellInfo cell = cells[x, y];
                if (cell.type != CellInfo.CellType.Pillar)
                {
                    cell.RenderTerrain(this, mesh);
                }
            }
        }
        for (int y = 0; y < sizeInCells.y; y += 1)
        {
            for (int x = 0; x < sizeInCells.x; x += 1)
            {
                CellInfo cell = cells[x, y];
                if (cell.type == CellInfo.CellType.Pillar)
                {
                    cell.RenderTerrain(this, mesh);
                }
            }
        }

        // render rooms
        for (int x = 0; x < sizeInRooms.x; x += 1)
        {
            for (int y = 0; y < sizeInRooms.y; y += 1)
            {
                rooms[x, y].FillWithVault(mesh);
            }
        }

        // add the starter stairs
        RoomInfo startRoom = rooms[entryRoomCoords.x, entryRoomCoords.y];
        int      stairX, stairZ;

        if (startStairsSW)
        {
            stairX = startRoom.cell.startX - 1;
            stairZ = startRoom.cell.startY + (startRoom.cell.sizeY / 2);
        }
        else
        {
            stairX = startRoom.cell.startX + (startRoom.cell.sizeX / 2);
            stairZ = startRoom.cell.startY - 1;
        }
        float stairY = startRoom.z - 0.5f;

        for (int i = 0; i < stairLength; i += 1)
        {
            mesh.SetHeight(stairX, stairZ, stairY);
            MapEvent3D ev;
            if (i == 0)
            {
                ev = Instantiate(startEventPrefab);
            }
            else
            {
                ev = Instantiate(impassEventPrefab);
            }
            GetComponent <Map>().AddEvent(ev);
            ev.SetLocation(new Vector2Int(stairX, stairZ));
            stairY -= 0.5f;
            stairX += startStairsSW ? -1 : 0;
            stairZ += startStairsSW ? 0 : -1;
        }

        // add the end stairs
        RoomInfo endRoom = rooms[exitRoomCoords.x, exitRoomCoords.y];

        if (endStairsNW)
        {
            stairX = endRoom.cell.startX + (endRoom.cell.sizeX / 2);
            stairZ = endRoom.cell.startY + endRoom.cell.sizeY;
        }
        else
        {
            stairX = endRoom.cell.startX + endRoom.cell.sizeX;
            stairZ = endRoom.cell.startY + (endRoom.cell.sizeY / 2);
        }
        stairY = endRoom.z + 0.5f;
        for (int i = 0; i < stairLength; i += 1)
        {
            MapEvent3D ev;
            if (i == 0)
            {
                ev = Instantiate(endEventPrefab);
            }
            else
            {
                ev = Instantiate(impassEventPrefab);
            }
            GetComponent <Map>().AddEvent(ev);
            ev.SetLocation(new Vector2Int(stairX, stairZ));
            mesh.SetHeight(stairX, stairZ, stairY);
            stairY += 0.5f;
            stairX += endStairsNW ? 0 : 1;
            stairZ += endStairsNW ? 1 : 0;
        }

        // add the zoom target
        MapEvent3D zoom = Instantiate(targetPrefab);

        GetComponent <Map>().AddEvent(zoom);
        zoom.SetLocation(new Vector2Int(mesh.size.x / 2, mesh.size.y / 2));

        // generate the encounters
        List <RoomInfo> validRooms = new List <RoomInfo>();

        for (int x = 0; x < sizeInRooms.x; x += 1)
        {
            for (int y = 0; y < sizeInRooms.y; y += 1)
            {
                if (x != entryRoomCoords.x || y != entryRoomCoords.y)
                {
                    validRooms.Add(rooms[x, y]);
                }
            }
        }
        List <Encounter> encounters = table.GenerateEncounters(level);

        foreach (Encounter encounter in encounters)
        {
            RoomInfo   room = validRooms[Random.Range(0, validRooms.Count)];
            Vector2Int loc  = new Vector2Int(
                Random.Range(room.cell.startX, room.cell.startX + room.cell.sizeX),
                Random.Range(room.cell.startY, room.cell.startY + room.cell.sizeY));
            encounter.PlaceAt(GetComponent <Map>(), loc);
        }

        // generate the chests
        List <Item> items = table.GenerateItems(level);

        foreach (Item item in items)
        {
            ChestEvent chest = Instantiate(chestEventPrefab);
            GetComponent <Map>().AddEvent(chest.GetComponent <MapEvent>());
            Vector2Int loc;
            do
            {
                RoomInfo room = validRooms[Random.Range(0, validRooms.Count)];
                loc = new Vector2Int(
                    Random.Range(room.cell.startX + 1, room.cell.startX + room.cell.sizeX - 1),
                    Random.Range(room.cell.startY + 1, room.cell.startY + room.cell.sizeY - 1));
            } while (!chest.GetComponent <MapEvent>().CanPassAt(loc));
            chest.PopulateAndPlace(item, loc);
        }

        mesh.Rebuild(true);
    }
Exemple #25
0
    private void RenderStairway(MapGenerator gen, TacticsTerrainMesh mesh)
    {
        RoomInfo lowRoom, highRoom;

        if (x % 2 == 1)
        {
            lowRoom  = gen.rooms[(x - 1) / 2, y / 2];
            highRoom = gen.rooms[(x + 1) / 2, y / 2];
        }
        else
        {
            lowRoom  = gen.rooms[x / 2, (y - 1) / 2];
            highRoom = gen.rooms[x / 2, (y + 1) / 2];
        }
        if (lowRoom.z > highRoom.z)
        {
            RoomInfo temp = lowRoom;
            lowRoom  = highRoom;
            highRoom = temp;
        }
        float deltaZ = highRoom.z - lowRoom.z;

        int w = 3;

        if (!stairAnchoredHigh && !stairAnchoredLow &&
            ((x % 2 == 1 && sizeX >= deltaZ * 2) || (y % 2 == 1 && sizeY >= deltaZ * 2)))
        {
            // we're eligible for a straight staircase
            for (int y = 0; y < sizeY; y += 1)
            {
                for (int x = 0; x < sizeX; x += 1)
                {
                    mesh.SetHeight(startX + x, startY + y, lowRoom.z);
                }
            }
            for (float i = 0.0f; i < deltaZ; i += 0.5f)
            {
                for (int j = 0; j < w; j += 1)
                {
                    if (x % 2 == 1)
                    {
                        mesh.SetHeight(
                            startX + sizeX - (int)(i * 2),
                            startY + j + (sizeY - w) / 2,
                            lowRoom.z + deltaZ - i);
                    }
                    else
                    {
                        mesh.SetHeight(
                            startX + j + (sizeX - w) / 2,
                            startY + sizeY - (int)(i * 2),
                            lowRoom.z + deltaZ - i);
                    }
                }
            }
        }
        else
        {
            // a normal side staircase
            bool heightSwap = gen.Flip();
            for (int y = 0; y < sizeY; y += 1)
            {
                for (int x = 0; x < sizeX; x += 1)
                {
                    if (stairAnchoredLow && stairAnchoredHigh)
                    {
                        // stretch across the entire room
                        heightSwap = false;
                        float t;
                        if (this.x % 2 == 1)
                        {
                            t = (float)x / sizeX;
                        }
                        else
                        {
                            t = (float)y / sizeY;
                        }
                        mesh.SetHeight(startX + x, startY + y, lowRoom.z + Mathf.RoundToInt(t * deltaZ));
                    }
                    else
                    {
                        float h;
                        if (stairAnchoredLow)
                        {
                            heightSwap = false;
                            if (this.x % 2 == 1)
                            {
                                h = Mathf.Min(highRoom.z, lowRoom.z + (y + 1) * 0.5f);
                            }
                            else
                            {
                                h = Mathf.Min(highRoom.z, lowRoom.z + (x + 1) * 0.5f);
                            }
                        }
                        else if (stairAnchoredHigh)
                        {
                            heightSwap = false;
                            if (this.x % 2 == 1)
                            {
                                h = Mathf.Max(lowRoom.z, highRoom.z - (y + 1) * 0.5f);
                            }
                            else
                            {
                                h = Mathf.Max(lowRoom.z, highRoom.z - (x + 1) * 0.5f);
                            }
                        }
                        else
                        {
                            if (this.x % 2 == 1)
                            {
                                h = Mathf.Max(lowRoom.z, Mathf.Min(highRoom.z, lowRoom.z + (deltaZ * 0.5f) + (y - sizeY / 2) * 0.5f));
                            }
                            else
                            {
                                h = Mathf.Max(lowRoom.z, Mathf.Min(highRoom.z, lowRoom.z + (deltaZ * 0.5f) + (x - sizeX / 2) * 0.5f));
                            }
                        }
                        mesh.SetHeight(startX + x, startY + y, heightSwap ? lowRoom.z + (highRoom.z - h) : h);
                    }
                }
            }
        }
    }
Exemple #26
0
 // set up a new grid with the given size in tiles and rule for turning location into whether a
 // tile is part of the selection grid or not
 public void ConfigureNewGrid(Vector2Int at, int range, TacticsTerrainMesh terrain,
                              Func <Vector2Int, bool> rangeRule, Func <Vector2Int, bool> selectRule)
 {
     ConfigureNewGrid(at - new Vector2Int(range, range), new Vector2Int(range * 2 + 1, range * 2 + 1), terrain,
                      rangeRule, selectRule);
 }
Exemple #27
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();
    }
Exemple #28
0
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        TacticsTerrainMesh terrain = (TacticsTerrainMesh)target;

        GUILayout.Space(20.0f);
        if (GUILayout.Button("Rebuild"))
        {
            Rebuild(true);
        }
        Vector2Int newSize = EditorGUILayout.Vector2IntField("Size", terrain.size);

        if (newSize != terrain.size)
        {
            terrain.Resize(newSize);
            Rebuild(true);
        }
        GUILayout.Space(20.0f);
        Vector2Int flooredSelection = new Vector2Int(Mathf.FloorToInt(selectionSize.x), Mathf.FloorToInt(selectionSize.y));
        Vector2Int newSelectionSize = EditorGUILayout.Vector2IntField("Brush size", flooredSelection);

        if (newSelectionSize != flooredSelection)
        {
            selectionSize = new Vector2(Mathf.Max(1.0f, newSelectionSize.x), Mathf.Max(1.0f, newSelectionSize.y));
        }

        if (palette == null)
        {
            if (terrain.paletteName != null && terrain.paletteName.Length > 0)
            {
                string paletteName = "Assets/Tilesets/Palettes/" + terrain.paletteName + ".prefab";
                UpdateWithPalette(AssetDatabase.LoadAssetAtPath <GridPalette>(paletteName));
            }
        }
        GridPalette newPalette = (GridPalette)EditorGUILayout.ObjectField("Tileset", palette, typeof(GridPalette), false);

        if (newPalette != palette)
        {
            UpdateWithPalette(newPalette);
        }

        SelectionTool[] ordinals = new SelectionTool[] {
            SelectionTool.Select, SelectionTool.Paint, SelectionTool.HeightAdjust
        };
        string[] names          = new string[] { "Select", "Paint", "HeightAdjust" };
        int      selectionIndex = GUILayout.SelectionGrid(ArrayUtility.IndexOf(ordinals, tool), names, names.Length);

        tool = ordinals[selectionIndex];

        int       controlId      = GUIUtility.GetControlID(FocusType.Passive);
        EventType typeForControl = Event.current.GetTypeForControl(controlId);
        Vector2   mousePos       = Event.current.mousePosition;

        GUIStyle style = new GUIStyle();

        style.padding = new RectOffset(0, 0, 0, 0);

        if (tileset != null && tool == SelectionTool.Paint)
        {
            wraparoundPaintMode = EditorGUILayout.Toggle("Paint all faces", wraparoundPaintMode);
            Texture2D backer = AssetDatabase.LoadAssetAtPath <Texture2D>("Assets/Resources/Textures/White.png");
            for (int y = tileset.size.y - 1; y >= 0; y -= 1)
            {
                EditorGUILayout.BeginHorizontal();

                for (int x = 0; x < tileset.size.x; x += 1)
                {
                    Rect selectRect = EditorGUILayout.BeginHorizontal(GUILayout.Width(Map.TileSizePx), GUILayout.Height(Map.TileSizePx));
                    Tile tile       = tileset.GetTile <Tile>(new Vector3Int(x, y, 0));

                    GUILayout.Box("", style, GUILayout.Width(Map.TileSizePx), GUILayout.Height(Map.TileSizePx));
                    Rect r = GUILayoutUtility.GetLastRect();

                    if (r.Contains(Event.current.mousePosition))
                    {
                        switch (Event.current.type)
                        {
                        case EventType.MouseDown:
                            mode = EditMode.PaletteTileDrag;
                            selectedTileStart = new Vector2(x, y);
                            tileSelectRect    = new Rect(x, y, 1, 1);
                            paletteBufferSize = Vector2Int.zero;
                            break;

                        case EventType.MouseDrag:
                            if (mode == EditMode.PaletteTileDrag)
                            {
                                int minX = (int)Mathf.Min(selectedTileStart.x, x);
                                int minY = (int)Mathf.Min(selectedTileStart.y, y);
                                tileSelectRect = new Rect(minX, minY,
                                                          (int)Mathf.Max(selectedTileStart.x, x) + 1 - minX,
                                                          (int)Mathf.Max(selectedTileStart.y, y) + 1 - minY);
                                selectionSize = new Vector2(tileSelectRect.width, tileSelectRect.height);
                            }
                            break;

                        case EventType.MouseUp:
                            mode = EditMode.None;
                            break;
                        }
                    }

                    Rect rect = new Rect(tile.sprite.uv[0].x, tile.sprite.uv[3].y,
                                         tile.sprite.uv[3].x - tile.sprite.uv[0].x,
                                         tile.sprite.uv[0].y - tile.sprite.uv[3].y);

                    GUI.DrawTextureWithTexCoords(r, tile.sprite.texture, rect, true);
                    if (r.Contains(Event.current.mousePosition))
                    {
                        GUI.DrawTexture(r, backer, ScaleMode.StretchToFill, true, 0.0f, new Color(1, 0, 0, 0.5f), 0.0f, 0.0f);
                    }
                    else if (paletteBufferSize == Vector2Int.zero && tileSelectRect.Contains(new Vector2(x, y)))
                    {
                        GUI.DrawTexture(r, backer, ScaleMode.StretchToFill, true, 0.0f, new Color(1, 1, 1, 0.8f), 0.0f, 0.0f);
                    }

                    EditorGUILayout.EndHorizontal();
                }
                EditorGUILayout.EndHorizontal();
            }
        }
        if (tool == SelectionTool.Select)
        {
            EditorGUI.BeginDisabledGroup(mode != EditMode.Selected);
            if (GUILayout.Button("Create MapEvent3D"))
            {
                GameObject prefab   = AssetDatabase.LoadAssetAtPath <GameObject>(GenericPrefabPath);
                MapEvent3D mapEvent = Instantiate(prefab).GetComponent <MapEvent3D>();
                mapEvent.name = "Event" + Random.Range(1000000, 9999999);
                AddEvent(mapEvent);
            }
            if (GUILayout.Button("Create Tactics Doll"))
            {
                GameObject prefab   = AssetDatabase.LoadAssetAtPath <GameObject>(TacticsPrefabPath);
                MapEvent3D mapEvent = ((GameObject)PrefabUtility.InstantiatePrefab(prefab)).GetComponent <MapEvent3D>();
                mapEvent.name = "Doll" + Random.Range(1000000, 9999999);
                AddEvent(mapEvent);
            }
            EditorGUI.EndDisabledGroup();
        }
    }
Exemple #29
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));
                }
            }
        }
    }
Exemple #30
0
    private void HandleRightclick(EventType typeForControl, int controlId)
    {
        TacticsTerrainMesh terrain = (TacticsTerrainMesh)target;

        switch (typeForControl)
        {
        case EventType.MouseDown:
            if (tool != SelectionTool.Select)
            {
                TerrainQuad quad = GetSelectedQuad();
                if (quad != null)
                {
                    ConsumeEvent(controlId);
                    primarySelection = quad;
                    selectionSize    = new Vector2(1.0f, 1.0f);
                    CaptureSelection(quad);
                    tool = SelectionTool.Paint;
                    mode = EditMode.RlickDrag;
                }
            }
            break;

        case EventType.MouseDrag:
            if (mode == EditMode.RlickDrag)
            {
                ConsumeEvent(controlId);
                TerrainQuad quad = GetSelectedQuad();
                if (quad != null && quad.normal == primarySelection.normal)
                {
                    selectedQuads = MathHelper3D.GetQuadsInRect(quads, quad, primarySelection);
                }
            }
            break;

        case EventType.MouseUp:
            switch (mode)
            {
            case EditMode.Selected:
                mode = EditMode.None;
                break;

            case EditMode.RlickDrag:
                mode = EditMode.None;
                TerrainQuad quad = GetSelectedQuad();
                if (quad != null && quad.normal == primarySelection.normal)
                {
                    selectedQuads = MathHelper3D.GetQuadsInRect(quads, quad, primarySelection);
                    Vector3 v1 = quad.pos;
                    Vector3 v2 = primarySelection.pos;
                    float   x1 = Mathf.Min(v1.x, v2.x);
                    float   x2 = Mathf.Max(v1.x, v2.x);
                    float   y1 = Mathf.Min(v1.y, v2.y);
                    float   y2 = Mathf.Max(v1.y, v2.y);
                    float   z1 = Mathf.Min(v1.z, v2.z);
                    float   z2 = Mathf.Max(v1.z, v2.z);
                    if (z1 != z2 && y1 != y2)
                    {
                        paletteBufferSize = new Vector2Int((int)(z2 - z1 + 1), (int)((y2 - y1 + 0.5f) * 2.0f));
                        paletteBuffer     = new Tile[paletteBufferSize.x * paletteBufferSize.y];
                        for (float z = z1; z <= z2; z += 1.0f)
                        {
                            for (float y = y1; y <= y2; y += 0.5f)
                            {
                                TerrainQuad at = quads[new Vector3(v1.x, y, z)][quad.normal];
                                paletteBuffer[(int)(paletteBufferSize.x * (2.0f * (y - y1)) + (z - z1))] = at.tile;
                            }
                        }
                    }
                    else if (x1 != x2 && y1 != y2)
                    {
                        paletteBufferSize = new Vector2Int((int)(x2 - x1 + 1), (int)((y2 - y1 + 0.5f) * 2.0f));
                        paletteBuffer     = new Tile[paletteBufferSize.x * paletteBufferSize.y];
                        for (float x = x1; x <= x2; x += 1.0f)
                        {
                            for (float y = y1; y <= y2; y += 0.5f)
                            {
                                TerrainQuad at = quads[new Vector3(x, y, v1.z)][quad.normal];
                                paletteBuffer[(int)(paletteBufferSize.x * (2.0f * (y - y1)) + (x - x1))] = at.tile;
                            }
                        }
                    }
                    else
                    {
                        paletteBufferSize = new Vector2Int((int)(x2 - x1 + 1), (int)(z2 - z1 + 1));
                        paletteBuffer     = new Tile[paletteBufferSize.x * paletteBufferSize.y];
                        for (float x = x1; x <= x2; x += 1.0f)
                        {
                            for (float z = z1; z <= z2; z += 1.0f)
                            {
                                TerrainQuad at = quads[new Vector3(x, v1.y, z)][quad.normal];
                                paletteBuffer[(int)(paletteBufferSize.x * (z - z1) + (x - x1))] = at.tile;
                            }
                        }
                    }
                    selectionSize = paletteBufferSize;
                }
                break;
            }
            break;
        }
    }