public void Check(List <string> mods, List <string> packagePaths)
        {
            Context = new StatLoadingContext();

            LoadStatDefinitions();
            Context.Definitions = Definitions;

            Loader = new StatLoader(Context);

            var visitor = new ModPathVisitor(Mods)
            {
                Game         = LSLib.LS.Story.Compiler.TargetGame.DOS2DE,
                CollectStats = true,
                LoadPackages = LoadPackages
            };

            visitor.Discover(GameDataPath);
            packagePaths.ForEach(path => visitor.DiscoverUserPackages(path));

            // Wildcard value "*" means "all mods"
            if (mods.Count == 1 && mods[0] == "*")
            {
                mods = Mods.Mods.Keys.ToList();
            }

            foreach (var modName in mods)
            {
                LoadMod(modName);
            }

            Loader.ResolveBaseClasses();
            Loader.InstantiateEntities();

            foreach (var message in Context.Errors)
            {
                CompilationDiagnostic(message);
            }
        }
Beispiel #2
0
        public bool Compile(string outputPath, string debugInfoPath, List <string> mods)
        {
            Logger.CompilationStarted();
            HasErrors     = false;
            Compiler.Game = Game;
            Compiler.AllowTypeCoercion = AllowTypeCoercion;

            if (mods.Count > 0)
            {
                Logger.TaskStarted("Discovering module files");
                var visitor = new ModPathVisitor(Mods)
                {
                    Game = Game,
                    CollectStoryGoals = true,
                    CollectGlobals    = CheckGameObjects,
                    CollectLevels     = CheckGameObjects,
                    LoadPackages      = LoadPackages
                };
                visitor.Discover(GameDataPath);
                Logger.TaskFinished();

                Logger.TaskStarted("Loading module files");
                if (CheckGameObjects)
                {
                    var nullGameObject = new GameObjectInfo
                    {
                        Name = "NULL_00000000-0000-0000-0000-000000000000",
                        Type = Compiler.Context.LookupType("GUIDSTRING")
                    };
                    Compiler.Context.GameObjects.Add("00000000-0000-0000-0000-000000000000", nullGameObject);
                }

                foreach (var modName in mods)
                {
                    LoadMod(modName);
                }

                AbstractFileInfo storyHeaderFile           = null;
                AbstractFileInfo typeCoercionWhitelistFile = null;
                var modsSearchPath = mods.ToList();
                modsSearchPath.Reverse();
                foreach (var modName in modsSearchPath)
                {
                    if (storyHeaderFile == null && Mods.Mods[modName].StoryHeaderFile != null)
                    {
                        storyHeaderFile = Mods.Mods[modName].StoryHeaderFile;
                    }

                    if (typeCoercionWhitelistFile == null && Mods.Mods[modName].TypeCoercionWhitelistFile != null)
                    {
                        typeCoercionWhitelistFile = Mods.Mods[modName].TypeCoercionWhitelistFile;
                    }
                }

                if (storyHeaderFile != null)
                {
                    var storyStream = storyHeaderFile.MakeStream();
                    LoadStoryHeaders(storyStream);
                    storyHeaderFile.ReleaseStream();
                }
                else
                {
                    Logger.CompilationDiagnostic(new Diagnostic(null, MessageLevel.Error, "X00", "Unable to locate story header file (story_header.div)"));
                    HasErrors = true;
                }

                if (typeCoercionWhitelistFile != null)
                {
                    var typeCoercionStream = typeCoercionWhitelistFile.MakeStream();
                    LoadTypeCoercionWhitelist(typeCoercionStream);
                    typeCoercionWhitelistFile.ReleaseStream();
                    Compiler.TypeCoercionWhitelist = TypeCoercionWhitelist;
                }

                Logger.TaskFinished();
            }

            if (CheckGameObjects)
            {
                Logger.TaskStarted("Loading game objects");
                LoadGlobals();
                Logger.TaskFinished();
            }
            else
            {
                Compiler.Context.Log.WarningSwitches[DiagnosticCode.UnresolvedGameObjectName] = false;
            }

            if (OsiExtender)
            {
                Logger.TaskStarted("Precompiling scripts");
                ParallelPreprocess();
                Logger.TaskFinished();
            }

            var asts       = new Dictionary <String, ASTGoal>();
            var goalLoader = new IRGenerator(Compiler.Context);

            Logger.TaskStarted("Generating IR");
            var orderedGoalAsts = ParallelBuildIR();

            foreach (var goal in orderedGoalAsts)
            {
                Compiler.AddGoal(goal);
            }
            Logger.TaskFinished();


            bool updated;
            var  iter = 1;

            do
            {
                Logger.TaskStarted($"Propagating rule types {iter}");
                updated = Compiler.PropagateRuleTypes();
                Logger.TaskFinished();

                if (iter++ > 10)
                {
                    Compiler.Context.Log.Error(null, DiagnosticCode.InternalError,
                                               "Maximal number of rule propagation retries exceeded");
                    break;
                }
            } while (updated);

            Logger.TaskStarted("Checking for unresolved references");
            Compiler.VerifyIR();
            Logger.TaskFinished();

            foreach (var message in Compiler.Context.Log.Log)
            {
                Logger.CompilationDiagnostic(message);
                if (message.Level == MessageLevel.Error)
                {
                    HasErrors = true;
                }
            }

            if (!HasErrors && !CheckOnly)
            {
                Logger.TaskStarted("Generating story nodes");
                var emitter = new StoryEmitter(Compiler.Context);
                if (debugInfoPath != null)
                {
                    emitter.EnableDebugInfo();
                }

                var story = emitter.EmitStory();
                Logger.TaskFinished();

                Logger.TaskStarted("Saving story binary");
                using (var file = new FileStream(outputPath, FileMode.Create, FileAccess.Write))
                {
                    var writer = new StoryWriter();
                    writer.Write(file, story);
                }
                Logger.TaskFinished();

                if (debugInfoPath != null)
                {
                    Logger.TaskStarted("Saving debug info");
                    using (var file = new FileStream(debugInfoPath, FileMode.Create, FileAccess.Write))
                    {
                        var writer = new DebugInfoSaver();
                        writer.Save(file, emitter.DebugInfo);
                    }
                    Logger.TaskFinished();
                }
            }

            Logger.CompilationFinished(!HasErrors);
            return(!HasErrors);
        }