예제 #1
0
        /// <summary>
        /// Add new mission variant based on master variant.
        /// </summary>
        public void AddMissionVariant()
        {
            MissionVariant srcVariant = new MissionVariant(mission.masterVariant);

            srcVariant.layouts.Clear();
            srcVariant.name = "Variant " + mission.missionVariants.Count;
            srcVariant.tethysGame.beacons.Clear();
            srcVariant.tethysGame.markers.Clear();
            srcVariant.tethysGame.wreckage.Clear();

            foreach (GameData tethysGame in srcVariant.tethysDifficulties)
            {
                tethysGame.beacons.Clear();
                tethysGame.markers.Clear();
                tethysGame.wreckage.Clear();
            }

            foreach (PlayerData player in srcVariant.players)
            {
                ClearPlayerResourceData(player.resources);

                foreach (PlayerData.ResourceData resData in player.difficulties)
                {
                    ClearPlayerResourceData(resData);
                }
            }

            mission.missionVariants.Add(srcVariant);

            SetUnsaved();
        }
예제 #2
0
        private bool IsWallOnTile(Vector2Int tileXY)
        {
            // Add game coordinates
            tileXY += Vector2Int.one;

            MissionVariant variant = UserData.current.GetCombinedVariant();

            foreach (PlayerData player in variant.players)
            {
                foreach (WallTubeData wallTube in UserData.current.GetCombinedResourceData(player).wallTubes)
                {
                    if (wallTube.typeID != map_id.Wall && wallTube.typeID != map_id.LavaWall && wallTube.typeID != map_id.MicrobeWall)
                    {
                        continue;
                    }

                    if (wallTube.position.x == tileXY.x && wallTube.position.y == tileXY.y)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #3
0
        /// <summary>
        /// Gets the combined master variant (applies to all variants) and the selected variant.
        /// </summary>
        public MissionVariant GetCombinedVariant()
        {
            if (selectedVariantIndex < 0)
            {
                return(new MissionVariant(mission.masterVariant));
            }

            return(MissionVariant.Concat(mission.masterVariant, selectedVariant));
        }
예제 #4
0
        public void AddMissionVariant(int cloneIndex)
        {
            MissionVariant srcVariant = mission.missionVariants[cloneIndex];

            MissionVariant destVariant = new MissionVariant(srcVariant);

            destVariant.name = "Variant " + mission.missionVariants.Count;
            mission.missionVariants.Add(destVariant);

            SetUnsaved();
        }
예제 #5
0
        public GameData GetCombinedTethysGame(MissionVariant variant)
        {
            // If no difficulty selected, return base data
            if (selectedDifficultyIndex < 0)
            {
                return(variant.tethysGame);
            }

            // Return combined base and difficulty data
            variant.tethysGame.Concat(variant.tethysDifficulties[selectedDifficultyIndex]);
            return(variant.tethysGame);
        }
예제 #6
0
        /// <summary>
        /// Gets the combined master variant and difficulties
        /// </summary>
        /// <returns></returns>
        public MissionVariant GetCombinedMission()
        {
            MissionVariant variant = GetCombinedVariant();

            variant.tethysGame = GetCombinedTethysGame(variant);

            foreach (PlayerData player in variant.players)
            {
                player.resources = GetCombinedResourceData(player);
            }

            return(variant);
        }
예제 #7
0
        // Gets the final mission variant to use for the current game
        private static MissionVariant GetCombinedDifficultyVariant(MissionRoot root, int missionVariantIndex)
        {
            // Combine master variant with specified variant. The master variant is always used as a base.
            MissionVariant missionVariant = root.masterVariant;

            if (root.missionVariants.Count > 0)
            {
                missionVariant = MissionVariant.Concat(root.masterVariant, root.missionVariants[missionVariantIndex]);
            }

            // Startup Flags
            bool isMultiplayer   = (int)root.levelDetails.missionType <= -4 && (int)root.levelDetails.missionType >= -8;
            int  localDifficulty = SceneParameters.Players[SceneParameters.LocalPlayerID].Difficulty;

            // Combine master gaia resources with difficulty gaia resources
            if (!isMultiplayer && localDifficulty < missionVariant.tethysDifficulties.Count)
            {
                missionVariant.tethysGame = GameData.Concat(missionVariant.tethysGame, missionVariant.tethysDifficulties[localDifficulty]);
            }

            foreach (PlayerData data in missionVariant.players)
            {
                int difficulty = 0;
                SceneParameters.Player player = SceneParameters.Players.FirstOrDefault((scenePlayer) => scenePlayer.PlayerID == data.id);

                // Get difficulty
                if (player != null)
                {
                    difficulty = player.Difficulty;
                }

                // If playing single player, all players get assigned the local player's difficulty
                if (!isMultiplayer && data.id != SceneParameters.LocalPlayerID)
                {
                    difficulty = localDifficulty;
                }

                // Add difficulty resources
                if (difficulty < data.difficulties.Count)
                {
                    data.resources = PlayerData.ResourceData.Concat(data.resources, data.difficulties[difficulty]);
                }
            }

            return(missionVariant);
        }
예제 #8
0
        private bool AreUnitsInArea(RectInt area)
        {
            MissionVariant variant = UserData.current.GetCombinedVariant();

            foreach (PlayerData player in variant.players)
            {
                foreach (UnitData unit in UserData.current.GetCombinedResourceData(player).units)
                {
                    // Subtract game coordinates
                    RectInt otherArea = StructureData.GetStructureArea(new Vector2Int(unit.position.x - 1, unit.position.y - 1), unit.typeID);

                    if (RectIntersect(area, otherArea))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #9
0
        private bool AreUnitsOnTile(Vector2Int tileXY)
        {
            // Add game coordinates
            tileXY += Vector2Int.one;

            MissionVariant variant = UserData.current.GetCombinedVariant();

            foreach (PlayerData player in variant.players)
            {
                foreach (UnitData unit in UserData.current.GetCombinedResourceData(player).units)
                {
                    RectInt otherArea = StructureData.GetStructureArea(new Vector2Int(unit.position.x, unit.position.y), unit.typeID);
                    if (otherArea.Contains(tileXY))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #10
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);
        }
예제 #11
0
        public static bool Initialize(MissionRoot mission, int randomSeed, out string error)
        {
            string techTreeName = mission.levelDetails.techTreeName;

            // Read info sheets
            Dictionary <map_id, GlobalStructureInfo> buildingInfo = SheetReader.ReadBuildingSheet();
            Dictionary <map_id, GlobalVehicleInfo>   vehicleInfo  = SheetReader.ReadVehicleSheet();
            Dictionary <map_id, GlobalWeaponInfo>    weaponInfo   = SheetReader.ReadWeaponSheet();
            Dictionary <map_id, GlobalUnitInfo>      starshipInfo = SheetReader.ReadStarshipSheet();
            Dictionary <MineInfoKey, GlobalMineInfo> mineInfo     = SheetReader.ReadMineSheet();
            GlobalMoraleInfo moraleInfo = SheetReader.ReadMoraleSheet();
            Dictionary <int, GlobalTechInfo> techInfo = TechSheetReader.ReadTechSheet(techTreeName);

            if (buildingInfo == null || vehicleInfo == null || weaponInfo == null || starshipInfo == null || mineInfo == null || moraleInfo == null || techInfo == null)
            {
                error = "Failed to load sheets.";
                return(false);
            }

            StructureInfo = new ReadOnlyDictionary <map_id, GlobalStructureInfo>(buildingInfo);
            VehicleInfo   = new ReadOnlyDictionary <map_id, GlobalVehicleInfo>(vehicleInfo);
            WeaponInfo    = new ReadOnlyDictionary <map_id, GlobalWeaponInfo>(weaponInfo);
            StarshipInfo  = new ReadOnlyDictionary <map_id, GlobalUnitInfo>(starshipInfo);
            MineInfo      = new ReadOnlyDictionary <MineInfoKey, GlobalMineInfo>(mineInfo);
            MoraleInfo    = moraleInfo;
            TechInfo      = new ReadOnlyDictionary <int, GlobalTechInfo>(techInfo);

            // Initialize core
            _Random = new System.Random(randomSeed);

            // Select mission variant (random)
            int missionVariantIndex = GetRandom(0, mission.missionVariants.Count);

            // Combine master variant with selected variant. The master variant is always used as a base.
            MissionVariant missionVariant = GetCombinedDifficultyVariant(mission, missionVariantIndex);
            //GameData tethysGame = missionVariant.tethysGame;

            bool isMultiplayer = (int)mission.levelDetails.missionType <= -4 && (int)mission.levelDetails.missionType >= -8;

            // Initialize players
            Player[] players = new Player[missionVariant.players.Count];
            for (int i = 0; i < missionVariant.players.Count; ++i)
            {
                int playerId = missionVariant.players[i].id;

                // Find the player details for this slot
                SceneParameters.Player playerDetails = SceneParameters.Players.FirstOrDefault((scenePlayer) => scenePlayer.PlayerID == playerId);
                if (playerDetails != null)
                {
                    // Create player
                    int difficulty = playerDetails.Difficulty;
                    players[playerId] = new Player(playerId, difficulty, missionVariant.players[i]);
                }
                else if (!isMultiplayer)
                {
                    // For non-multiplayer games: If there aren't any player details for this slot, use the local player difficulty.
                    SceneParameters.Player localPlayerDetails = SceneParameters.Players.FirstOrDefault((scenePlayer) => scenePlayer.PlayerID == SceneParameters.LocalPlayerID);
                    int difficulty = localPlayerDetails.Difficulty;
                    players[playerId] = new Player(playerId, difficulty, missionVariant.players[i]);
                }
            }

            Players = new ReadOnlyCollection <Player>(players);

            error = null;
            return(true);
        }
예제 #12
0
        private void CreateUnitsForVariant(MissionVariant variant, bool isActiveVariant)
        {
            bool isDifficultySelected = UserData.current.selectedDifficultyIndex >= 0;

            // Get gaia unit tint
            Color multiplier   = new Color(0.7f, 0.7f, 0.7f, 1.0f);
            Color variantColor = Color.white;

            if (!isActiveVariant)
            {
                variantColor = multiplier;
            }
            if (isDifficultySelected)
            {
                variantColor = multiplier;
            }

            Color difficultyColor = Color.white;

            if (!isActiveVariant)
            {
                difficultyColor = multiplier;
            }

            // Create variant master gaia units
            CreateGameData(variant.tethysGame, variantColor);

            // Create variant difficulty gaia units
            if (isDifficultySelected)
            {
                CreateGameData(variant.tethysDifficulties[UserData.current.selectedDifficultyIndex], difficultyColor);
            }

            // Get player unit tint
            multiplier   = new Color(0.49f, 0.49f, 0.49f);
            variantColor = Color.white;
            if (!isActiveVariant)
            {
                variantColor = multiplier;
            }
            if (isDifficultySelected)
            {
                variantColor = multiplier;
            }

            difficultyColor = Color.white;
            if (!isActiveVariant)
            {
                difficultyColor = multiplier;
            }

            // Player data
            for (int i = 0; i < variant.players.Count; ++i)
            {
                PlayerData player = variant.players[i];

                // Set start location
                SetStartLocation(i, player);

                // Create units (difficulty invariant)
                foreach (UnitData unit in player.resources.units)
                {
                    AddUnit(player, unit, variantColor);
                }

                // Create units for selected difficulty
                if (isDifficultySelected)
                {
                    foreach (UnitData unit in player.difficulties[UserData.current.selectedDifficultyIndex].units)
                    {
                        AddUnit(player, unit, difficultyColor);
                    }
                }

                // Create walls and tubes
            }
        }
예제 #13
0
        /// <summary>
        /// Initializes the CellType map with mission data.
        /// </summary>
        public CellTypeMap(Map map, MissionVariant variant)
        {
            uint mapWidth  = map.GetWidthInTiles();
            uint mapHeight = map.GetHeightInTiles();

            m_Grid = new Tile[mapWidth, mapHeight];

            // Default CellTypes to map CellTypes
            for (uint x = 0; x < mapWidth; ++x)
            {
                for (uint y = 0; y < mapHeight; ++y)
                {
                    m_Grid[x, y].cellType = (CellType)map.GetCellType(x, y);
                }
            }

            // Loop through all units, walls, and tubes
            foreach (PlayerData player in variant.players)
            {
                // Get structure modifications
                foreach (UnitData unit in player.resources.units)
                {
                    if (!StructureData.IsStructure(unit.typeID))
                    {
                        continue;
                    }

                    RectInt area = StructureData.GetStructureArea(new Vector2Int(unit.position.x - 1, unit.position.y - 1), unit.typeID);

                    // Add bulldozed area
                    area.min -= Vector2Int.one;
                    area.max += Vector2Int.one;

                    SetAreaCellType(area, CellType.DozedArea, false);

                    // Add structure tubes
                    if (StructureData.HasTubes(unit.typeID))
                    {
                        m_Grid[unit.position.x - 1, area.max.y - 1].cellType = CellType.Tube0;
                        m_Grid[area.max.x - 1, unit.position.y - 1].cellType = CellType.Tube0;
                    }

                    // Remove bulldozed area
                    area.min += Vector2Int.one;
                    area.max -= Vector2Int.one;

                    SetAreaCellType(area, CellType.DozedArea, true);
                }

                // Get wall tube modifications
                foreach (WallTubeData wallTube in player.resources.wallTubes)
                {
                    CellType cellType = CellType.zPad20;

                    switch (wallTube.typeID)
                    {
                    case DotNetMissionSDK.map_id.Tube:                      cellType = CellType.Tube0;                      break;

                    case DotNetMissionSDK.map_id.Wall:                      cellType = CellType.NormalWall;         break;

                    case DotNetMissionSDK.map_id.LavaWall:          cellType = CellType.LavaWall;           break;

                    case DotNetMissionSDK.map_id.MicrobeWall:       cellType = CellType.MicrobeWall;        break;
                    }

                    m_Grid[wallTube.position.x - 1, wallTube.position.y - 1].cellType = cellType;
                }
            }             // foreach playerStates
        }