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)); }