Пример #1
0
        public virtual JassCompilationUnitSyntax Build(Map map)
        {
            if (map is null)
            {
                throw new ArgumentNullException(nameof(map));
            }

            JassCommentDeclarationSyntax commentLine1 = new("===========================================================================");
            JassCommentDeclarationSyntax commentLine2 = new("***************************************************************************");
            JassCommentDeclarationSyntax commentLine3 = new("*");

            List <IDeclarationSyntax> declarations = new();
            var globalDeclarationList = new List <IDeclarationSyntax>();
            var generatedGlobals      = new List <JassGlobalDeclarationSyntax>();

            void AppendBanner(string bannerText)
            {
                declarations.Add(commentLine2);
                declarations.Add(commentLine3);
                declarations.Add(new JassCommentDeclarationSyntax($"*  {bannerText}"));
                declarations.Add(commentLine3);
                declarations.Add(commentLine2);
                declarations.Add(JassEmptyDeclarationSyntax.Value);
            }

            void AppendBannerAndFunction(string bannerText, Func <Map, JassFunctionDeclarationSyntax> function, Func <Map, bool> condition)
            {
                if (condition(map))
                {
                    AppendBanner(bannerText);
                    declarations.Add(function(map));
                    declarations.Add(JassEmptyDeclarationSyntax.Value);
                }
            }

            void AppendBannerAndFunctions(string bannerText, Func <Map, IEnumerable <IDeclarationSyntax> > functions, Func <Map, bool> condition)
            {
                if (condition(map))
                {
                    AppendBanner(bannerText);
                    foreach (var function in functions(map))
                    {
                        declarations.Add(function);
                        declarations.Add(JassEmptyDeclarationSyntax.Value);
                    }
                }
            }

            void AppendFunction(Func <Map, JassFunctionDeclarationSyntax> function, Func <Map, bool> condition)
            {
                if (condition(map))
                {
                    declarations.Add(commentLine1);
                    declarations.Add(function(map));
                    declarations.Add(JassEmptyDeclarationSyntax.Value);
                }
            }

            void AppendFunctionForIndex(int index, Func <Map, int, JassFunctionDeclarationSyntax> function, Func <Map, int, bool> condition)
            {
                if (condition(map, index))
                {
                    declarations.Add(commentLine1);
                    declarations.Add(function(map, index));
                    declarations.Add(JassEmptyDeclarationSyntax.Value);
                }
            }

            declarations.AddRange(GetMapScriptHeader(map));
            declarations.Add(JassEmptyDeclarationSyntax.Value);

            AppendBanner("Global Variables");
            generatedGlobals.AddRange(Regions(map));
            generatedGlobals.AddRange(Cameras(map));
            generatedGlobals.AddRange(Sounds(map));
            generatedGlobals.AddRange(Units(map));
            generatedGlobals.AddRange(RandomUnitTables(map));

            if (generatedGlobals.Any())
            {
                globalDeclarationList.Add(new JassCommentDeclarationSyntax(" Generated"));
                globalDeclarationList.AddRange(generatedGlobals);
            }

            declarations.Add(new JassGlobalDeclarationListSyntax(globalDeclarationList.ToImmutableArray()));
            declarations.Add(JassEmptyDeclarationSyntax.Value);

            AppendBanner("Custom Script Code");
            AppendBannerAndFunction("Random Groups", InitRandomGroups, InitRandomGroupsCondition);
            AppendBannerAndFunctions("Map Item Tables", MapItemTables, MapItemTablesCondition);
            AppendBannerAndFunction("Items", CreateAllItems, CreateAllItemsCondition);
            AppendBannerAndFunctions("Unit Item Tables", UnitItemTables, UnitItemTablesCondition);
            AppendBannerAndFunctions("Destructable Item Tables", DestructableItemTables, DestructableItemTablesCondition);
            AppendBannerAndFunction("Sounds", InitSounds, InitSoundsCondition);
            AppendBannerAndFunction("Destructable Objects", CreateAllDestructables, CreateAllDestructablesCondition);

            if (CreateAllUnitsCondition(map))
            {
                AppendBanner("Unit Creation");

                foreach (var i in Enumerable.Range(0, MaxPlayerSlots))
                {
                    AppendFunctionForIndex(i, CreateBuildingsForPlayer, CreateBuildingsForPlayerCondition);
                    AppendFunctionForIndex(i, CreateUnitsForPlayer, CreateUnitsForPlayerCondition);
                }

                AppendFunction(CreateNeutralHostile, CreateNeutralHostileCondition);
                AppendFunction(CreateNeutralPassiveBuildings, CreateNeutralPassiveBuildingsCondition);
                AppendFunction(CreateNeutralPassive, CreateNeutralPassiveCondition);
                AppendFunction(CreatePlayerBuildings, CreatePlayerBuildingsCondition);
                AppendFunction(CreatePlayerUnits, CreatePlayerUnitsCondition);
                AppendFunction(CreateNeutralUnits, CreateNeutralUnitsCondition);
                AppendFunction(CreateAllUnits, (map) => true);
            }

            AppendBannerAndFunction("Regions", CreateRegions, CreateRegionsCondition);
            AppendBannerAndFunction("Cameras", CreateCameras, CreateCamerasCondition);

            // TODO: triggers

            if (InitUpgradesCondition(map))
            {
                AppendBanner("Upgrades");

                foreach (var i in Enumerable.Range(0, MaxPlayerSlots))
                {
                    if (InitUpgrades_PlayerCondition(map, i))
                    {
                        declarations.Add(InitUpgrades_Player(map, i));
                        declarations.Add(JassEmptyDeclarationSyntax.Value);
                    }
                }

                declarations.Add(InitUpgrades(map));
                declarations.Add(JassEmptyDeclarationSyntax.Value);
            }

            if (InitTechTreeCondition(map))
            {
                AppendBanner("TechTree");

                foreach (var i in Enumerable.Range(0, MaxPlayerSlots))
                {
                    if (InitTechTree_PlayerCondition(map, i))
                    {
                        declarations.Add(InitTechTree_Player(map, i));
                        declarations.Add(JassEmptyDeclarationSyntax.Value);
                    }
                }

                declarations.Add(InitTechTree(map));
                declarations.Add(JassEmptyDeclarationSyntax.Value);
            }

            AppendBanner("Players");

            if (InitCustomPlayerSlotsCondition(map))
            {
                declarations.Add(InitCustomPlayerSlots(map));
                declarations.Add(JassEmptyDeclarationSyntax.Value);
            }

            if (InitCustomTeamsCondition(map))
            {
                declarations.Add(InitCustomTeams(map));
                declarations.Add(JassEmptyDeclarationSyntax.Value);
            }

            if (InitAllyPrioritiesCondition(map))
            {
                var ids = Enumerable.Range(0, MaxPlayerSlots).ToArray();
                if (map.Info.Players.Any(p => ids.Any(id => p.AllyLowPriorityFlags[id] || p.AllyHighPriorityFlags[id])))
                {
                    declarations.Add(InitAllyPriorities(map));
                    declarations.Add(JassEmptyDeclarationSyntax.Value);
                }
            }

            AppendBannerAndFunction("Main Initialization", main, mainCondition);
            AppendBannerAndFunction("Map Configuration", config, configCondition);

            return(SyntaxFactory.CompilationUnit(declarations));
        }