Пример #1
0
 internal static Team Parse(BinaryReader reader, MapParseContext context)
 {
     return(new Team
     {
         Properties = AssetPropertyCollection.Parse(reader, context)
     });
 }
Пример #2
0
 internal static WorldInfo Parse(BinaryReader reader, MapParseContext context)
 {
     return(ParseAsset(reader, context, version =>
     {
         return new WorldInfo
         {
             Properties = AssetPropertyCollection.Parse(reader, context)
         };
     }));
 }
Пример #3
0
        public static void SetupGameSides(
            Game game,
            MapFile mapFile,
            PlayerSetting[] playerSettings,
            GameType gameType,
            out Player[] mapPlayers,
            out Team[] mapTeams,
            out ScriptList[] mapScriptLists)
        {
            var tempMapPlayers     = new List <Player>();
            var tempMapTeams       = new List <Team>();
            var tempMapScriptLists = new List <ScriptList>();

            if (gameType == GameType.SinglePlayer)
            {
                SetupSinglePlayerGameSides(
                    mapFile,
                    tempMapPlayers,
                    tempMapTeams,
                    tempMapScriptLists);
            }
            else
            {
                SetupSkirmishGameSides(
                    game,
                    mapFile,
                    playerSettings,
                    gameType,
                    tempMapPlayers,
                    tempMapTeams,
                    tempMapScriptLists);
            }

            // TODO: Probably don't add replay observer player and team when viewing a replay?

            var replayObserverPlayerProperties = new AssetPropertyCollection();

            replayObserverPlayerProperties.AddAsciiString("playerFaction", "FactionObserver");
            replayObserverPlayerProperties.AddAsciiString("playerName", "ReplayObserver");
            replayObserverPlayerProperties.AddAsciiString("playerDisplayName", "Observer");
            replayObserverPlayerProperties.AddBoolean("playerIsHuman", false);
            replayObserverPlayerProperties.AddAsciiString("playerAllies", "");
            replayObserverPlayerProperties.AddAsciiString("playerEnemies", "");
            tempMapPlayers.Add(new Player
            {
                Properties = replayObserverPlayerProperties
            });

            tempMapScriptLists.Add(new ScriptList());

            mapPlayers     = tempMapPlayers.ToArray();
            mapTeams       = tempMapTeams.ToArray();
            mapScriptLists = tempMapScriptLists.ToArray();
        }
Пример #4
0
        private static Team CreateTeam(string name, string owner, bool isSingleton)
        {
            var properties = new AssetPropertyCollection();

            properties.AddAsciiString("teamName", name);
            properties.AddAsciiString("teamOwner", owner);
            properties.AddBoolean("teamIsSingleton", isSingleton);
            return(new Team
            {
                Properties = properties
            });
        }
Пример #5
0
 internal static MapObject Parse(BinaryReader reader, MapParseContext context)
 {
     return(ParseAsset(reader, context, version =>
     {
         return new MapObject
         {
             Position = reader.ReadVector3(),
             Angle = reader.ReadSingle(),
             RoadType = reader.ReadUInt32AsEnumFlags <RoadType>(),
             TypeName = reader.ReadUInt16PrefixedAsciiString(),
             Properties = AssetPropertyCollection.Parse(reader, context)
         };
     }));
 }
Пример #6
0
        internal static Player Parse(BinaryReader reader, MapParseContext context, ushort version)
        {
            var result = new Player
            {
                Properties = AssetPropertyCollection.Parse(reader, context)
            };

            var numBuildListItems = reader.ReadUInt32();
            var buildListItems    = new BuildListItem[numBuildListItems];

            for (var i = 0; i < numBuildListItems; i++)
            {
                buildListItems[i] = BuildListItem.Parse(reader, version);
            }

            result.BuildList = buildListItems;

            return(result);
        }
Пример #7
0
        private static void SetupSkirmishGameSides(
            Game game,
            MapFile mapFile,
            PlayerSetting[] playerSettings,
            GameType gameType,
            List <Player> mapPlayers,
            List <Team> mapTeams,
            List <ScriptList> mapScriptLists)
        {
            var originalMapPlayers = mapFile.SidesList.Players;

            // Neutral player.
            mapPlayers.Add(originalMapPlayers[0]);

            // Civilian player. It isn't necessarily the second player.
            // TODO: There might be more than one civilian player.
            mapPlayers.Add(originalMapPlayers.FirstOrDefault(x => (string)x.Properties["playerFaction"].Value == "FactionCivilian"));

            //var hasAIPlayer = false;
            for (var i = 0; i < playerSettings.Length; i++)
            {
                var playerSetting = playerSettings[i];

                var factionPlayer = originalMapPlayers.Single(x => (string)x.Properties["playerFaction"].Value == playerSetting.SideName);

                var isHuman = playerSetting.Owner == PlayerOwner.Player;

                var playerName = isHuman
                    ? $"player{i}"
                    : $"{factionPlayer.Properties["playerName"].Value}{i}";

                //if (!isHuman)
                //{
                //    hasAIPlayer = true;
                //}

                var playerProperties = new AssetPropertyCollection();
                playerProperties.AddAsciiString("playerFaction", (string)factionPlayer.Properties["playerFaction"].Value);
                playerProperties.AddAsciiString("playerName", playerName);
                playerProperties.AddAsciiString("playerDisplayName", (string)factionPlayer.Properties["playerDisplayName"].Value);
                playerProperties.AddBoolean("playerIsHuman", isHuman);
                playerProperties.AddInteger("playerColor", playerSetting.Color.ToUInt32());

                // TODO: Other player properties.

                mapPlayers.Add(new Player
                {
                    Properties = playerProperties,
                    BuildList  = factionPlayer.BuildList,
                });
            }

            // Setup player relationships.
            var playerAllies  = new string[playerSettings.Length];
            var playerEnemies = new string[playerSettings.Length];

            for (var i = 0; i < playerSettings.Length; i++)
            {
                playerAllies[i]  = "";
                playerEnemies[i] = "";
            }
            for (var i = 0; i < playerSettings.Length; i++)
            {
                var outerPlayer = playerSettings[i];

                for (var j = i + 1; j < playerSettings.Length; j++)
                {
                    var innerPlayer = playerSettings[j];
                    if (outerPlayer.Team == innerPlayer.Team && outerPlayer.Team != 0)
                    {
                        playerAllies[i] += mapPlayers[j + 2].Properties["playerName"].Value + " ";
                        playerAllies[j] += mapPlayers[i + 2].Properties["playerName"].Value + " ";
                    }
                    else
                    {
                        playerEnemies[i] += mapPlayers[j + 2].Properties["playerName"].Value + " ";
                        playerEnemies[j] += mapPlayers[i + 2].Properties["playerName"].Value + " ";
                    }
                }
            }
            for (var i = 0; i < playerSettings.Length; i++)
            {
                mapPlayers[i + 2].Properties.AddAsciiString("playerAllies", playerAllies[i]);
                mapPlayers[i + 2].Properties.AddAsciiString("playerEnemies", playerEnemies[i]);
            }

            var originalMapScriptLists = mapFile.SidesList.PlayerScripts.ScriptLists;

            var playerNames = mapPlayers
                              .Select(p => p.Properties.GetPropOrNull("playerName")?.Value.ToString())
                              .ToArray();

            while (mapScriptLists.Count < mapPlayers.Count)
            {
                mapScriptLists.Add(null);
            }

            // Copy neutral player scripts.
            var neutralPlayerName = (string)mapPlayers[0].Properties["playerName"].Value;

            CopyScripts(
                originalMapScriptLists,
                playerNames,
                neutralPlayerName,
                mapScriptLists,
                0,
                appendIndex: false);

            // Copy civilian player scripts.
            var civilianPlayerName = (string)mapPlayers[1].Properties["playerName"].Value;

            CopyScripts(
                originalMapScriptLists,
                playerNames,
                civilianPlayerName,
                mapScriptLists,
                1,
                appendIndex: false);

            var skirmishScriptsEntry = game.ContentManager.GetScriptEntry(@"Data\Scripts\SkirmishScripts.scb");

            // TODO: Generals and ZH use SkirmishScripts.scb,
            // but later games use "libraries".
            if (skirmishScriptsEntry != null)
            {
                using var stream = skirmishScriptsEntry.Open();
                var skirmishScripts = ScbFile.FromStream(stream);

                // This probably isn't right, but it does make the teams match those in .sav files.
                // We first add human player(s) teams, then the replay observer team,
                // then neutral and civilian teams, and then finally AI skirmish players.

                var skirmishScriptsPlayerNames = skirmishScripts.ScriptsPlayers.Players.Select(p => p.Name).ToArray();

                // Skip neutral and civilian players.
                for (var i = 2; i < mapPlayers.Count; i++)
                {
                    if ((bool)mapPlayers[i].Properties["playerIsHuman"].Value)
                    {
                        // Copy the scripts from the civilian player to all human players.
                        CopyScripts(
                            skirmishScripts.PlayerScripts.ScriptLists,
                            skirmishScriptsPlayerNames,
                            civilianPlayerName,
                            mapScriptLists,
                            i,
                            appendIndex: true);

                        mapTeams.Add(CreateDefaultTeam((string)mapPlayers[i].Properties["playerName"].Value));
                    }
                }

                mapTeams.Add(CreateDefaultTeam("ReplayObserver"));

                mapTeams.Add(CreateDefaultTeam(neutralPlayerName));
                mapTeams.Add(CreateDefaultTeam(civilianPlayerName));

                // Skip neutral and civilian players.
                for (var i = 2; i < mapPlayers.Count; i++)
                {
                    if (!(bool)mapPlayers[i].Properties["playerIsHuman"].Value)
                    {
                        var playerSide       = game.AssetStore.PlayerTemplates.GetByName(playerSettings[i - 2].SideName).Side;
                        var sourcePlayerName = $"Skirmish{playerSide}";

                        // Copy the scripts from the according skirmish player for all AI players.
                        CopyScripts(
                            skirmishScripts.PlayerScripts.ScriptLists,
                            skirmishScriptsPlayerNames,
                            sourcePlayerName,
                            mapScriptLists,
                            i,
                            appendIndex: true);

                        // TODO: Not sure about the order the teams are added.
                        foreach (var team in skirmishScripts.Teams.Teams)
                        {
                            var teamOwner = (string)team.Properties["teamOwner"].Value;
                            if (teamOwner == sourcePlayerName)
                            {
                                var teamName = $"{team.Properties["teamName"].Value}{i}";
                                mapTeams.Add(CreateTeam(
                                                 teamName,
                                                 (string)mapPlayers[i].Properties["playerName"].Value,
                                                 (bool)team.Properties["teamIsSingleton"].Value));
                            }
                        }
                    }
                }
            }

            if (playerSettings.Length > 1)
            {
                var multiplayerScriptsEntry = game.ContentManager.GetScriptEntry(@"Data\Scripts\MultiplayerScripts.scb");

                if (multiplayerScriptsEntry != null)
                {
                    using var stream = multiplayerScriptsEntry.Open();
                    var multiplayerScripts = ScbFile.FromStream(stream);

                    // TODO: This is a bit hardcoded.
                    mapScriptLists[0] = multiplayerScripts.PlayerScripts.ScriptLists[0];
                }
            }
        }
Пример #8
0
        private static void SetupSkirmishGameSides(
            Game game,
            MapFile mapFile,
            PlayerSetting[] playerSettings,
            GameType gameType,
            List <Player> mapPlayers,
            List <Team> mapTeams,
            List <ScriptList> mapScriptLists)
        {
            var originalMapPlayers = mapFile.SidesList.Players;

            // Neutral player.
            mapPlayers.Add(originalMapPlayers[0]);

            // Civilian player. It isn't necessarily the second player.
            // TODO: There might be more than one civilian player.
            mapPlayers.Add(originalMapPlayers.FirstOrDefault(x => (string)x.Properties["playerFaction"].Value == "FactionCivilian"));

            //var hasAIPlayer = false;
            for (var i = 0; i < playerSettings.Length; i++)
            {
                var playerSetting = playerSettings[i];

                var factionPlayer = originalMapPlayers.First(x => (string)x.Properties["playerFaction"].Value == playerSetting.SideName);

                var isHuman = playerSetting.Owner == PlayerOwner.Player;

                var playerName = isHuman
                    ? $"player{i}"
                    : $"{factionPlayer.Properties["playerName"].Value}{i}";

                //if (!isHuman)
                //{
                //    hasAIPlayer = true;
                //}

                var playerProperties = new AssetPropertyCollection();
                playerProperties.AddAsciiString("playerFaction", (string)factionPlayer.Properties["playerFaction"].Value);
                playerProperties.AddAsciiString("playerName", playerName);
                playerProperties.AddAsciiString("playerDisplayName", (string)factionPlayer.Properties["playerDisplayName"].Value);
                playerProperties.AddBoolean("playerIsHuman", isHuman);
                playerProperties.AddInteger("playerColor", playerSetting.Color.ToUInt32());

                // TODO: Other player properties.

                mapPlayers.Add(new Player
                {
                    Properties = playerProperties,
                    BuildList  = factionPlayer.BuildList,
                });
            }

            // Setup player relationships.
            var playerAllies  = new string[playerSettings.Length];
            var playerEnemies = new string[playerSettings.Length];

            for (var i = 0; i < playerSettings.Length; i++)
            {
                playerAllies[i]  = "";
                playerEnemies[i] = "";
            }
            for (var i = 0; i < playerSettings.Length; i++)
            {
                var outerPlayer = playerSettings[i];

                for (var j = i + 1; j < playerSettings.Length; j++)
                {
                    var innerPlayer = playerSettings[j];
                    if (outerPlayer.Team == innerPlayer.Team && outerPlayer.Team != 0)
                    {
                        playerAllies[i] += mapPlayers[j + 2].Properties["playerName"].Value + " ";
                        playerAllies[j] += mapPlayers[i + 2].Properties["playerName"].Value + " ";
                    }
                    else
                    {
                        playerEnemies[i] += mapPlayers[j + 2].Properties["playerName"].Value + " ";
                        playerEnemies[j] += mapPlayers[i + 2].Properties["playerName"].Value + " ";
                    }
                }
            }
            for (var i = 0; i < playerSettings.Length; i++)
            {
                mapPlayers[i + 2].Properties.AddAsciiString("playerAllies", playerAllies[i]);
                mapPlayers[i + 2].Properties.AddAsciiString("playerEnemies", playerEnemies[i]);
            }

            var originalMapScriptLists = mapFile.GetPlayerScriptsList().ScriptLists;

            var playerNames = mapPlayers
                              .Select(p => p.Properties.GetPropOrNull("playerName")?.Value.ToString())
                              .ToArray();

            while (mapScriptLists.Count < mapPlayers.Count)
            {
                mapScriptLists.Add(null);
            }

            // Copy neutral player scripts.
            var neutralPlayerName = (string)mapPlayers[0].Properties["playerName"].Value;

            CopyScripts(
                originalMapScriptLists,
                playerNames,
                neutralPlayerName,
                mapScriptLists,
                0,
                appendIndex: false);

            // Copy civilian player scripts.
            var civilianPlayerName = (string)mapPlayers[1].Properties["playerName"].Value;

            CopyScripts(
                originalMapScriptLists,
                playerNames,
                civilianPlayerName,
                mapScriptLists,
                1,
                appendIndex: false);

            switch (game.SageGame)
            {
            case SageGame.CncGenerals:
            case SageGame.CncGeneralsZeroHour:
                CreateTeamsFromScbFile(game, mapPlayers, mapTeams, mapScriptLists, playerSettings, neutralPlayerName, civilianPlayerName);
                break;

            case SageGame.Bfme:
            case SageGame.Bfme2:
            case SageGame.Bfme2Rotwk:
                mapTeams.AddRange(mapFile.GetTeams());
                break;
            }

            if (playerSettings.Length > 1)
            {
                var multiplayerScriptsEntry = game.ContentManager.GetScriptEntry(@"Data\Scripts\MultiplayerScripts.scb");

                if (multiplayerScriptsEntry != null)
                {
                    using var stream = multiplayerScriptsEntry.Open();
                    var multiplayerScripts = ScbFile.FromStream(stream);

                    // TODO: This is a bit hardcoded.
                    mapScriptLists[0] = multiplayerScripts.PlayerScripts.ScriptLists[0];
                }
            }
        }