/// <summary> /// Load an uncached IGlobalModData instance directly from the manifest yaml. /// This should only be used by external mods that want to query data from this mod. /// </summary> /// <returns>The get.</returns> /// <param name="oc">Oc.</param> /// <typeparam name="T">The 1st type parameter.</typeparam> public T Get <T>(ObjectCreator oc) where T : IGlobalModData { MiniYaml data; var t = typeof(T); if (!yaml.TryGetValue(t.Name, out data)) { return((T)oc.CreateBasic(t)); } IGlobalModData module; var ctor = t.GetConstructor(new[] { typeof(MiniYaml) }); if (ctor != null) { module = (IGlobalModData)ctor.Invoke(new object[] { data.Value }); } else { module = oc.CreateObject <IGlobalModData>(t.Name); FieldLoader.Load(module, data); } return((T)module); }
/// <summary> /// 加载自定义YAML Data /// </summary> /// <param name="oc"></param> public void LoadCustomData(ObjectCreator oc) { foreach (var kv in yaml) { if (reservedModuleNames.Contains(kv.Key)) { continue; } var t = oc.FindType(kv.Key); if (t == null || !typeof(IGlobalModData).IsAssignableFrom(t)) { throw new InvalidOperationException("'{0}' is not a valid mod manifest entry.".F(kv.Key)); } IGlobalModData module; var ctor = t.GetConstructor(new[] { typeof(MiniYaml) }); if (ctor != null) { module = (IGlobalModData)ctor.Invoke(new object[] { kv.Value }); } else { module = oc.CreateObject <IGlobalModData>(kv.Key); FieldLoader.Load(module, kv.Value); } modules.Add(module); } customDataLoaded = true; }
/// <summary> /// /// </summary> /// <param name="creator"></param> /// <param name="traitName"></param> /// <param name="my"></param> /// <returns></returns> static ITraitInfo LoadTraitInfo(ObjectCreator creator, string traitName, MiniYaml my) { if (!string.IsNullOrEmpty(my.Value)) { throw new Exception("junk value '{0}' on trait node {1}".F(my.Value, traitName)); } var info = creator.CreateObject <ITraitInfo>(traitName + "Info"); try { FieldLoader.Load(info, my); } catch (FieldLoader.MissingFieldsException e) { var header = "Trait name " + traitName + ": " + (e.Missing.Length > 1 ? "Required properties missing" : "Required property missing"); throw new FieldLoader.MissingFieldsException(e.Missing, header); } return(info); }
public ModData(Manifest mod, InstalledMods mods, bool useLoadScreen = false) { Languages = new string[0]; //local copy of the manifest Manifest = new Manifest(mod.Id, mod.Package); ObjectCreator = new ObjectCreator(Manifest, mods); PackageLoaders = ObjectCreator.GetLoaders <IPackageLoader>(Manifest.PackageFormats, "package"); ModFiles = new FileSystem.FileSystem(mods, PackageLoaders); ModFiles.LoadFromManifest(Manifest); Manifest.LoadCustomData(ObjectCreator); if (useLoadScreen) { LoadScreen = ObjectCreator.CreateObject <ILoadScreen>(Manifest.LoadScreen.Value); LoadScreen.Init(this, Manifest.LoadScreen.ToDictionary(my => my.Value)); LoadScreen.Display(); } WidgetLoader = new WidgetLoader(this); MapCache = new MapCache(this); SoundLoaders = ObjectCreator.GetLoaders <ISoundLoader>(Manifest.SoundFormats, "sound"); SpriteLoaders = ObjectCreator.GetLoaders <ISpriteLoader>(Manifest.SpriteFormats, "sprite"); var sequenceFormat = Manifest.Get <SpriteSequenceFormat>(); var sequenceLoader = ObjectCreator.FindType(sequenceFormat.Type + "Loader"); var sequenceCtor = sequenceLoader != null?sequenceLoader.GetConstructor(new[] { typeof(ModData) }) : null; if (sequenceLoader == null || !sequenceLoader.GetInterfaces().Contains(typeof(ISpriteSequenceLoader)) || sequenceCtor == null) { throw new InvalidOperationException("Unable to find a sequence loader for type '{0}'.".F(sequenceFormat.Type)); } SpriteSequenceLoader = (ISpriteSequenceLoader)sequenceCtor.Invoke(new[] { this }); SpriteSequenceLoader.OnMissingSpriteError = s => { Console.WriteLine(s); }; var modelFormat = Manifest.Get <ModelSequenceFormat>(); var modelLoader = ObjectCreator.FindType(modelFormat.Type + "Loader"); var modelCtor = modelLoader != null?modelLoader.GetConstructor(new[] { typeof(ModData) }) : null; if (modelCtor == null || !modelLoader.GetInterfaces().Contains(typeof(IModelSequenceLoader)) || modelCtor == null) { throw new InvalidOperationException("Unable to find a model loader for type '{0}'".F(modelFormat.Type)); } ModelSequenceLoader = (IModelSequenceLoader)modelCtor.Invoke(new[] { this }); ModelSequenceLoader.OnMissingModelError = s => { }; defaultRules = Exts.Lazy(() => Ruleset.LoadDefaults(this)); //地形贴片集 defaultTileSets = Exts.Lazy(() => { var items = new Dictionary <string, TileSet>(); foreach (var file in Manifest.TileSets) { var t = new TileSet(DefaultFileSystem, file); items.Add(t.Id, t); } return((IReadOnlyDictionary <string, TileSet>)(new ReadOnlyDictionary <string, TileSet>(items))); }); //序列集 defaultSequences = Exts.Lazy(() => { var items = DefaultTileSets.ToDictionary(t => t.Key, t => new SequenceProvider(DefaultFileSystem, this, t.Value, null)); return((IReadOnlyDictionary <string, SequenceProvider>)(new ReadOnlyDictionary <string, SequenceProvider>(items))); }); initialThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId; }