public void RefreshTile(Vector2Int tileXY)
        {
            // Cache calculated CellTypes
            CellTypeMap cellTypeMap = new CellTypeMap(UserData.current.map, UserData.current.GetCombinedMission());

            RefreshTile(cellTypeMap, tileXY);
        }
        public void RefreshTiles(RectInt area)
        {
            // Cache calculated CellTypes
            CellTypeMap cellTypeMap = new CellTypeMap(UserData.current.map, UserData.current.GetCombinedMission());

            for (int x = area.xMin; x < area.xMax; ++x)
            {
                for (int y = area.yMin; y < area.yMax; ++y)
                {
                    RefreshTile(cellTypeMap, new Vector2Int(x, y));
                }
            }
        }
Beispiel #3
0
        private ulong GetTileMappingIndex(Map map, CellTypeMap cellTypeMap, Vector2Int tileXY)
        {
            ulong x = (ulong)tileXY.x;
            ulong y = (ulong)tileXY.y;

            // Get default mapping index
            ulong mappingIndex = map.GetTileMappingIndex(x, y);

            // If no cell type map, return the map index. This will happen if there isn't any .opm mission file.
            if (cellTypeMap == null)
            {
                return(mappingIndex);
            }

            // Get TerrainType for mapping index, if available
            TerrainType terrainType;

            if (!GetTerrainTypeForMappingIndex(map, mappingIndex, out terrainType))
            {
                return(mappingIndex);
            }

            // Predict starting CellType and remap to terrain type
            int wallTubeIndex;

            switch (TileMapData.GetWallTubeIndexForTile(cellTypeMap, tileXY, out wallTubeIndex))
            {
            case CellType.DozedArea:                mappingIndex = terrainType.bulldozedTileMappingIndex;                                           break;

            case CellType.NormalWall:               mappingIndex = terrainType.wallTileMappingIndexes[2 * 16 + wallTubeIndex];          break;

            case CellType.LavaWall:                 mappingIndex = terrainType.wallTileMappingIndexes[wallTubeIndex];                       break;

            case CellType.MicrobeWall:              mappingIndex = terrainType.wallTileMappingIndexes[1 * 16 + wallTubeIndex];          break;

            case CellType.Tube0:
            case CellType.Tube1:
            case CellType.Tube2:
            case CellType.Tube3:
            case CellType.Tube4:
            case CellType.Tube5:
                mappingIndex = terrainType.tubeTileMappingIndexes[wallTubeIndex];
                break;
            }

            return(mappingIndex);
        }
        private void RefreshTile(CellTypeMap cellTypeMap, Vector2Int tileXY)
        {
            int x = tileXY.x;
            int y = tileXY.y;

            int tileMappingIndex = GetTileMappingIndex(cellTypeMap, tileXY);

            OP2UtilityDotNet.OP2Map.TileMapping mapping = UserData.current.map.tileMappings[tileMappingIndex];

            int tileSetIndex   = mapping.tilesetIndex;
            int tileImageIndex = mapping.tileGraphicIndex;

            string tileSetPath     = UserData.current.map.tilesetSources[tileSetIndex].tilesetFilename;
            int    tileSetNumTiles = (int)UserData.current.map.tilesetSources[tileSetIndex].numTiles;

            // Get tile texture
            Texture2D texture = TextureManager.LoadTileset(tileSetPath);

            if (texture == null)
            {
                throw new System.Exception("Could not find resource: " + tileSetPath);
            }

            // Get image offset
            int tileSize         = texture.height / tileSetNumTiles;
            int inverseTileIndex = tileSetNumTiles - tileImageIndex - 1;
            int texOffset        = inverseTileIndex * tileSize;

            // Load tile into tile map
            TileBase   tile         = LoadTile(tileSetPath, texOffset);
            Vector3Int cellPosition = new Vector3Int((int)x, m_Tilemap.size.y - (int)y - 1, 0);

            // Set minimap pixel
            Texture2D mTexture = TextureManager.LoadMinimapTileset(tileSetPath, tileSetNumTiles);
            Color     color    = mTexture.GetPixel(0, inverseTileIndex);

            minimapTexture.SetPixel(cellPosition.x, cellPosition.y, color);

            // Set tiles
            m_Tilemap.SetTile(cellPosition, tile);
            m_CellTypeMap.SetTile(cellPosition, m_CellTypeCache[(int)UserData.current.map.GetCellType(x, y)]);
            minimapTexture.Apply();
        }
        private int GetTileMappingIndex(CellTypeMap cellTypeMap, Vector2Int tileXY)
        {
            int x = tileXY.x;
            int y = tileXY.y;

            // Get default mapping index
            int mappingIndex = UserData.current.map.GetTileMappingIndex(x, y);

            // Get TerrainType for mapping index, if available
            OP2UtilityDotNet.OP2Map.TerrainType terrainType;
            if (!GetTerrainTypeForMappingIndex(mappingIndex, out terrainType))
            {
                return(mappingIndex);
            }

            // Predict starting CellType and remap to terrain type
            int wallTubeIndex;

            switch (TileMapData.GetWallTubeIndexForTile(cellTypeMap, tileXY, out wallTubeIndex))
            {
            case OP2UtilityDotNet.OP2Map.CellType.DozedArea:                        mappingIndex = terrainType.bulldozedTileMappingIndex;                                           break;

            case OP2UtilityDotNet.OP2Map.CellType.NormalWall:                       mappingIndex = terrainType.wallTileMappingIndexes[2, wallTubeIndex];            break;

            case OP2UtilityDotNet.OP2Map.CellType.LavaWall:                         mappingIndex = terrainType.wallTileMappingIndexes[0, wallTubeIndex];            break;

            case OP2UtilityDotNet.OP2Map.CellType.MicrobeWall:                      mappingIndex = terrainType.wallTileMappingIndexes[1, wallTubeIndex];            break;

            case OP2UtilityDotNet.OP2Map.CellType.Tube0:
            case OP2UtilityDotNet.OP2Map.CellType.Tube1:
            case OP2UtilityDotNet.OP2Map.CellType.Tube2:
            case OP2UtilityDotNet.OP2Map.CellType.Tube3:
            case OP2UtilityDotNet.OP2Map.CellType.Tube4:
            case OP2UtilityDotNet.OP2Map.CellType.Tube5:
                mappingIndex = terrainType.tubeTileMappingIndexes[wallTubeIndex];
                break;
            }

            return(mappingIndex);
        }
Beispiel #6
0
        /// <summary>
        /// Generates a minimap texture and assigns it as an image.
        /// </summary>
        /// <param name="map">The map to to generate a minimap from.</param>
        /// <param name="missionVariant">The mission variant to generate a minimap from. (optional)</param>
        public void SetMap(Map map, MissionVariant missionVariant = null)
        {
            uint mapWidth  = map.GetWidthInTiles();
            uint mapHeight = map.GetHeightInTiles();

            // Create minimap texture
            Texture2D minimapTexture = new Texture2D((int)mapWidth * TextureManager.minimapScale, (int)mapHeight * TextureManager.minimapScale, TextureFormat.ARGB32, false);

            CellTypeMap cellTypeMap = new CellTypeMap(map, missionVariant);

            for (uint x = 0; x < mapWidth; ++x)
            {
                for (uint y = 0; y < mapHeight; ++y)
                {
                    ulong       tileMappingIndex = GetTileMappingIndex(map, cellTypeMap, new Vector2Int((int)x, (int)y));
                    TileMapping mapping          = map.GetTileMapping(tileMappingIndex);

                    ulong tileSetIndex   = mapping.tilesetIndex;
                    int   tileImageIndex = mapping.tileGraphicIndex;

                    string tileSetPath     = map.GetTilesetSourceFilename(tileSetIndex);
                    int    tileSetNumTiles = (int)map.GetTilesetSourceNumTiles(tileSetIndex);

                    // Get image offset
                    int inverseTileIndex = tileSetNumTiles - tileImageIndex - 1;

                    Vector3Int cellPosition = new Vector3Int((int)x, (int)(mapHeight - y - 1), 0);

                    ++cellPosition.y;

                    // Set minimap pixel
                    Texture2D mTexture = TextureManager.LoadMinimapTileset(tileSetPath, tileSetNumTiles);
                    for (int my = 0; my < TextureManager.minimapScale; ++my)
                    {
                        for (int mx = 0; mx < TextureManager.minimapScale; ++mx)
                        {
                            Color color = mTexture.GetPixel(mx, inverseTileIndex * TextureManager.minimapScale + my);
                            minimapTexture.SetPixel(cellPosition.x * TextureManager.minimapScale + mx, cellPosition.y * TextureManager.minimapScale + my - 1, color);
                        }
                    }
                }
            }

            // Apply mission units to minimap
            if (missionVariant != null)
            {
                foreach (GameData.Beacon beacon in missionVariant.tethysGame.beacons)
                {
                    SetMinimapTile(minimapTexture, new Vector2Int(beacon.position.x, beacon.position.y) - Vector2Int.one, Color.white);
                }

                foreach (GameData.Marker marker in missionVariant.tethysGame.markers)
                {
                    SetMinimapTile(minimapTexture, new Vector2Int(marker.position.x, marker.position.y) - Vector2Int.one, Color.white);
                }

                foreach (GameData.Wreckage wreckage in missionVariant.tethysGame.wreckage)
                {
                    SetMinimapTile(minimapTexture, new Vector2Int(wreckage.position.x, wreckage.position.y) - Vector2Int.one, Color.white);
                }

                foreach (PlayerData player in missionVariant.players)
                {
                    foreach (UnitData unit in player.resources.units)
                    {
                        RectInt unitArea = StructureData.GetStructureArea(new Vector2Int(unit.position.x, unit.position.y) - Vector2Int.one, unit.typeID);

                        for (int x = unitArea.xMin; x < unitArea.xMax; ++x)
                        {
                            for (int y = unitArea.yMin; y < unitArea.yMax; ++y)
                            {
                                SetMinimapTile(minimapTexture, new Vector2Int(x, y), GetPlayerColor(player));
                            }
                        }
                    }
                }
            }

            // Apply minimap texture
            minimapTexture.Apply();

            // Update image
            RefreshImage(map, minimapTexture);
        }
        private IEnumerator _Refresh(System.Action onCompleteCB)
        {
            // Create grid overlay tile
            Tile gridOverlayTile = ScriptableObject.CreateInstance <Tile>();

            gridOverlayTile.sprite = m_GridOverlayTile;
            gridOverlayTile.color  = Color.white;

            m_Tilemap.ClearAllTiles();
            m_GridOverlay.ClearAllTiles();
            m_CellTypeMap.ClearAllTiles();

            m_TileCache.Clear();

            // Cache calculated CellTypes
            onMapRefreshProgressCB?.Invoke(this, "Calculating Cell Types", 0.0f);
            yield return(null);

            CellTypeMap cellTypeMap = new CellTypeMap(UserData.current.map, UserData.current.GetCombinedMission());

            int mapWidth  = (int)UserData.current.map.WidthInTiles();
            int mapHeight = (int)UserData.current.map.HeightInTiles();

            minimapTexture = new Texture2D((int)mapWidth * TextureManager.minimapScale, (int)mapHeight * TextureManager.minimapScale, TextureFormat.ARGB32, false);

            Vector3Int[] cellPositions = new Vector3Int[(int)(mapWidth * mapHeight)];
            TileBase[]   cellTiles     = new TileBase[(int)(mapWidth * mapHeight)];
            TileBase[]   cellTypes     = new TileBase[(int)(mapWidth * mapHeight)];
            int          index         = 0;

            int updateFrequency = 5;

            for (int x = 0; x < mapWidth; ++x)
            {
                if (index % updateFrequency == 0)
                {
                    onMapRefreshProgressCB?.Invoke(this, "Reading tiles", (float)(x * mapHeight) / (mapWidth * mapHeight));
                    yield return(null);
                }

                for (int y = 0; y < mapHeight; ++y)
                {
                    int tileMappingIndex = GetTileMappingIndex(cellTypeMap, new Vector2Int(x, y));
                    OP2UtilityDotNet.OP2Map.TileMapping mapping = UserData.current.map.tileMappings[tileMappingIndex];

                    int tileSetIndex   = mapping.tilesetIndex;
                    int tileImageIndex = mapping.tileGraphicIndex;

                    string tileSetPath     = UserData.current.map.tilesetSources[tileSetIndex].tilesetFilename;
                    int    tileSetNumTiles = (int)UserData.current.map.tilesetSources[tileSetIndex].numTiles;

                    // Get tile texture
                    Texture2D texture = TextureManager.LoadTileset(tileSetPath);
                    if (texture == null)
                    {
                        onCompleteCB?.Invoke();
                        onMapRefreshedCB?.Invoke(this);
                        throw new System.Exception("Could not find resource: " + tileSetPath);
                    }

                    // Get image offset
                    int tileSize         = texture.height / tileSetNumTiles;
                    int inverseTileIndex = tileSetNumTiles - tileImageIndex - 1;
                    int texOffset        = inverseTileIndex * tileSize;

                    // Load tile into tile map
                    TileBase   tile         = LoadTile(tileSetPath, texOffset);
                    Vector3Int cellPosition = new Vector3Int((int)x, (int)(mapHeight - y - 1), 0);

                    cellPositions[index] = cellPosition;
                    cellTiles[index]     = tile;
                    cellTypes[index]     = m_CellTypeCache[(int)UserData.current.map.GetCellType(x, y)];

                    ++cellPosition.y;

                    // Set minimap pixel
                    Texture2D mTexture = TextureManager.LoadMinimapTileset(tileSetPath, tileSetNumTiles);
                    for (int my = 0; my < TextureManager.minimapScale; ++my)
                    {
                        for (int mx = 0; mx < TextureManager.minimapScale; ++mx)
                        {
                            Color color = mTexture.GetPixel(mx, inverseTileIndex * TextureManager.minimapScale + my);
                            minimapTexture.SetPixel(cellPosition.x * TextureManager.minimapScale + mx, cellPosition.y * TextureManager.minimapScale + my - 1, color);
                        }
                    }

                    ++index;
                }
            }

            m_GridOverlay.color = UserPrefs.gridOverlayColor;
            m_GridOverlay.gameObject.SetActive(UserPrefs.isGridOverlayVisible);

            onMapRefreshProgressCB?.Invoke(this, "Setting tiles", 1);
            yield return(null);

            // Set tiles
            m_Tilemap.SetTiles(cellPositions, cellTiles);

            // Create cell types
            onMapRefreshProgressCB?.Invoke(this, "Setting cell types", 1);
            yield return(null);

            m_CellTypeMap.SetTiles(cellPositions, cellTypes);

            // Create grid
            onMapRefreshProgressCB?.Invoke(this, "Creating grid", 1);
            yield return(null);

            TileBase[] overlayTiles = new TileBase[cellPositions.Length];
            for (int i = 0; i < overlayTiles.Length; ++i)
            {
                overlayTiles[i] = gridOverlayTile;
            }

            m_GridOverlay.SetTiles(cellPositions, overlayTiles);

            // Apply minimap texture
            minimapTexture.Apply();

            onMapRefreshProgressCB?.Invoke(this, "Creating units", 1);
            yield return(null);

            // Create units
            m_UnitRenderer.Refresh(() =>
            {
                // Inform listeners that we are done
                onCompleteCB?.Invoke();
                onMapRefreshedCB?.Invoke(this);
            });
        }