Elin Decompiled Documentation EA 23.344.1 Nightly
Loading...
Searching...
No Matches
ModUtil.cs
Go to the documentation of this file.
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Diagnostics;
5using System.Diagnostics.CodeAnalysis;
6using System.IO;
7using System.Linq;
8using System.Reflection;
9using System.Text;
10using System.Text.RegularExpressions;
11using System.Threading;
12using NPOI.SS.UserModel;
13using NPOI.XSSF.UserModel;
14using Newtonsoft.Json;
15using ReflexCLI;
16using ReflexCLI.Attributes;
17using UnityEngine;
18using UnityEngine.Networking;
19
20[ConsoleCommandClassCustomizer("Mod")]
21public class ModUtil : EClass
22{
23 public static Dictionary<string, string> fallbackTypes = new Dictionary<string, string>();
24
25 private static readonly Dictionary<string, ICustomContent> _customContent = new Dictionary<string, ICustomContent>();
26
27 private static readonly List<Func<string, object, int>> _customCalcEvaluator = new List<Func<string, object, int>>();
28
29 private static readonly HashSet<Type> _checkedAttributedTypes = new HashSet<Type>();
30
31 private static readonly Dictionary<string, Texture2D> _cachedTextures = new Dictionary<string, Texture2D>();
32
33 private static Effect _rodTemplate;
34
35 public static SourceImporter sourceImporter = new SourceImporter(SourceMapping);
36
37 public static readonly List<ContextMenuProxy> contextMenuProxies = new List<ContextMenuProxy>();
38
39 public static IReadOnlyDictionary<string, SourceData> SourceMapping => (from f in typeof(SourceManager).GetFields()
40 where typeof(SourceData).IsAssignableFrom(f.FieldType)
41 select f).ToDictionary((FieldInfo f) => f.FieldType.Name, (FieldInfo f) => f.GetValue(EClass.sources) as SourceData);
42
43 public static void LoadTypeFallback()
44 {
45 string text = "type_resolver.txt";
46 string[] array = Array.Empty<string>();
47 if (File.Exists(CorePath.RootData + text))
48 {
49 array = IO.LoadTextArray(CorePath.RootData + text);
50 }
51 else
52 {
53 array = new string[2] { "TrueArena,ArenaWaveEvent,ZoneEvent", "Elin-GeneRecombinator,Elin_GeneRecombinator.IncubationSacrifice,Chara" };
54 IO.SaveTextArray(CorePath.RootData + text, array);
55 }
56 string[] array2 = array;
57 for (int i = 0; i < array2.Length; i++)
58 {
59 string[] array3 = array2[i].Split(',');
60 if (array3.Length >= 2)
61 {
62 RegisterSerializedTypeFallback(array3[0], array3[1], array3[2]);
63 }
64 }
65 }
66
67 public static void RegisterSerializedTypeFallback(string nameAssembly, string nameType, string nameFallbackType)
68 {
69 fallbackTypes[nameType] = nameFallbackType;
70 }
71
72 public static void LogModError(string message, BaseModPackage package = null)
73 {
74 string text = "#mod/" + package?.title + " (" + package?.id + ")\n" + message;
75 UnityEngine.Debug.LogWarning(text.RemoveAllTags());
76 if ((package != null && package.isInPackages && !package.builtin) || Application.isEditor)
77 {
78 EGui.CreatePopup(text);
79 }
80 }
81
82 public static void LogModError(string message, SourceData.BaseRow row)
83 {
84 LogModError(message, FindSourceRowPackage(row));
85 }
86
87 public static void LogModError(string message, Type type)
88 {
89 LogModError(message, FindFileProviderPackage(new FileInfo(type.Assembly.Location)));
90 }
91
92 public static void LogModError(string message, FileInfo file)
93 {
94 LogModError(message, FindFileProviderPackage(file));
95 }
96
97 public static void LogModError(string message, DirectoryInfo dir)
98 {
99 LogModError(message, FindDirectoryProviderPackage(dir));
100 }
101
102 public static ModPackage GetModPackage(string modId)
103 {
104 return ModManagerCore.Instance.MappedPackages.GetValueOrDefault(modId) as ModPackage;
105 }
106
107 public static ModPackage FindFileProviderPackage(FileInfo file)
108 {
109 string path = file.FullName.NormalizePath();
110 return ModManager.Instance.packages.LastOrDefault((BaseModPackage p) => path.StartsWith(p.dirInfo.FullName.NormalizePath())) as ModPackage;
111 }
112
113 public static ModPackage FindDirectoryProviderPackage(DirectoryInfo dir)
114 {
115 string path = dir.FullName.NormalizePath();
116 return ModManager.Instance.packages.LastOrDefault((BaseModPackage p) => path.StartsWith(p.dirInfo.FullName.NormalizePath())) as ModPackage;
117 }
118
119 public static ModPackage FindSourceRowPackage(SourceData.BaseRow row)
120 {
121 return ModManagerCore.Instance.packages.OfType<ModPackage>().LastOrDefault((ModPackage p) => p.sourceRows.Contains(row));
122 }
123
124 public static Zone FindZoneByFullName(string zoneFullName = "ntyris/0", bool useRandomFallback = false)
125 {
126 if (zoneFullName.IsEmpty())
127 {
128 return null;
129 }
130 var (zoneType, zoneId, destLv) = Zone.ParseZoneFullName(zoneFullName);
131 if (zoneId.IsEmpty())
132 {
133 return null;
134 }
135 Zone zone = EClass.game.spatials.Find((Zone z) => z.GetType().Name == zoneType || z.id == zoneId)?.FindOrCreateLevel(destLv);
136 if (zone == null && (zoneId == "*" || useRandomFallback))
137 {
138 zone = (from z in EClass.game.spatials.map.Values.OfType<Zone>()
139 where z.CanSpawnAdv
140 select z).RandomItem();
141 }
142 return zone;
143 }
144
145 public static void OnModsActivated()
146 {
147 CommandRegistry.assemblies.Add(typeof(EScript).Assembly);
148 SoundManager.current.soundLoaders.Add(LoadSoundData);
149 UIBook.topicLoaders.Add(LoadTopicFiles);
150 BookList.booklistLoaders.Add(LoadBookList);
151 Lang.excelDialogLoaders.Add(LoadExcelDialog);
152 LoadEffectTemplate();
153 DynamicAsset<Effect>.assetLoaders.Add(LoadEffect);
154 BaseModManager.SubscribeEvent<string>("elin.source.lang_set", OnSetLang);
155 BaseModManager.SubscribeEvent<List<Religion>>("elin.religion_importing", OnReligionImporting);
156 BaseModManager.SubscribeEvent("elin.source.importing", OnSourceImporting);
157 BaseModManager.SubscribeEvent("elin.source.imported", OnSourceImported);
158 BaseModManager.PublishEvent("elin.mods.activated");
159 RegisterElinEventAttributes();
160 CoroutineHelper.Deferred(RegisterElinEventAttributes);
161 }
162
163 private static void OnSourceImporting()
164 {
165 ExcelParser.allowTrimming = true;
166 ImportAllModSourceSheets();
167 }
168
169 private static void OnSourceImported()
170 {
171 _customContent.Clear();
172 foreach (EMod activatedUserMod in ModManager.Instance.ActivatedUserMods)
173 {
174 try
175 {
176 activatedUserMod.GenerateCustomContentProfiles();
177 foreach (ICustomContent item in activatedUserMod.customContent)
178 {
179 AddContent(item);
180 }
181 }
182 catch (Exception ex)
183 {
184 LogModError("exception while generating custom source profiles\n" + ex.Message, activatedUserMod);
185 UnityEngine.Debug.LogException(ex);
186 }
187 }
188 ImportAllGunEffectSettings();
189 CustomReligionContent.managed.Clear();
190 foreach (CustomReligionContent item2 in _customContent.Values.OfType<CustomReligionContent>())
191 {
192 item2.RegisterCustomReligion();
193 }
194 CustomReligionContent.Init();
195 SourceCache.FinalizeCache();
196 SourceCache.InvalidateCacheBlobs();
197 SourceCache.ClearDetail();
199 if (EClass.core.launchArgs.Contains("EXPORTSOURCE"))
200 {
201 string text = CorePath.rootExe + "/SourceExport/" + EClass.core.version.GetText();
202 ExportAllSourceDataCsv(text);
203 UnityEngine.Debug.Log("#source exported current version to " + text);
204 }
205 }
206
207 [ElinPreLoad]
208 private static void OnPreLoadInit(GameIOContext context)
209 {
210 }
211
212 [ElinPostLoad]
213 private static void OnPostLoadInit(GameIOContext context)
214 {
215 EClass.player.knownBGMs.RemoveWhere((int id) => !EClass.core.refs.dictBGM.ContainsKey(id));
216 KeyValuePair<int, Spatial>[] array = EClass.game.spatials.map.ToArray();
217 for (int num = 0; num < array.Length; num++)
218 {
219 KeyValuePair<int, Spatial> keyValuePair = array[num];
220 var (num3, spatial2) = (KeyValuePair<int, Spatial>)(ref keyValuePair);
221 if (spatial2.source == null)
222 {
223 spatial2.Destroy();
224 UnityEngine.Debug.LogWarning($"#mod-content removed invalid zone '{num3}', '{spatial2.id}', '{(spatial2 as Zone)?.ZoneFullName}'");
225 }
226 }
227 List<ICustomContent> contents = new List<ICustomContent>();
228 try
229 {
230 CustomReligionContent.LoadReligionData(context);
231 }
232 catch (Exception ex)
233 {
234 LogModError("exception while loading custom religion data\n" + ex.Message);
235 UnityEngine.Debug.LogException(ex);
236 }
237 LoadCustomContent<CustomZoneContent>();
238 LoadCustomContent<CustomCharaContent>();
239 LoadOtherCustomContent();
240 void LoadCustomContent<T>() where T : class, ICustomContent
241 {
242 UnityEngine.Debug.Log("#mod-content loading " + typeof(T).Name + "...");
243 foreach (T item in _customContent.Values.OfType<T>())
244 {
245 contents.Add(item);
246 try
247 {
248 item.OnGameLoad(context);
249 }
250 catch (Exception ex2)
251 {
252 LogModError("exception while loading custom content '" + item.ContentId + "'\n" + ex2.Message, item.Owner);
253 UnityEngine.Debug.LogException(ex2);
254 }
255 }
256 }
257 void LoadOtherCustomContent()
258 {
259 foreach (ICustomContent item2 in _customContent.Values.Except(contents))
260 {
261 try
262 {
263 item2.OnGameLoad(context);
264 }
265 catch (Exception ex2)
266 {
267 LogModError("exception while loading custom content '" + item2.ContentId + "'\n" + ex2.Message, item2.Owner);
268 UnityEngine.Debug.LogException(ex2);
269 }
270 }
271 }
272 }
273
274 [ElinPreSave]
275 private static void OnPreSaveInit(GameIOContext context)
276 {
277 }
278
279 [ElinPostSave]
280 private static void OnPostSaveInit(GameIOContext context)
281 {
282 try
283 {
284 CustomReligionContent.SaveReligionData(context);
285 }
286 catch (Exception ex)
287 {
288 LogModError("exception while saving custom religion data\n" + ex.Message);
289 UnityEngine.Debug.LogException(ex);
290 }
291 foreach (ICustomContent value in _customContent.Values)
292 {
293 try
294 {
295 value.OnGameSave(context);
296 }
297 catch (Exception ex2)
298 {
299 LogModError("exception while saving custom content '" + value.ContentId + "'\n" + ex2.Message, value.Owner);
300 UnityEngine.Debug.LogException(ex2);
301 }
302 }
303 }
304
305 private static void OnReligionImporting(List<Religion> list)
306 {
307 list.AddRange(CustomReligionContent.GetCustomReligions());
308 }
309
310 [ElinCharaOnCreate]
311 private static void OnCharaCreated(Chara chara)
312 {
313 if (TryGetContent<CustomCharaContent>("Chara/" + chara.id, out var content))
314 {
315 content.OnCharaCreated(chara);
316 }
317 if (TryGetContent<CustomBiographyContent>("Biography/" + chara.id, out var content2))
318 {
319 content2.RefreshCharaBio(chara);
320 }
321 }
322
323 [ElinThingOnCreate]
324 private static void OnThingCreated(Thing thing)
325 {
326 if (TryGetContent<CustomThingContent>("Thing/" + thing.id, out var content))
327 {
328 content.OnThingCreated(thing);
329 }
330 }
331
332 [ElinActPerform]
333 private static void OnActPerformed(Act act)
334 {
335 if (act.HasTag("godAbility"))
336 {
337 CustomReligionContent.managed.Values.FirstOrDefault((ReligionCustom r) => r.content.godAbilities.Contains(act.ID))?.Talk("ability");
338 }
339 }
340
341 private static void OnSetLang(string lang)
342 {
343 PackageIterator.ClearCache();
344 PackageIterator.RebuildAllMappings(lang);
345 SourceLocalization.SetLang(lang);
346 foreach (EMod activatedUserMod in ModManager.Instance.ActivatedUserMods)
347 {
348 if (activatedUserMod.IsSourceLocalizable && (activatedUserMod.isInPackages || Application.isEditor))
349 {
350 activatedUserMod.UpdateSourceLocalizationFile(lang);
351 }
352 }
353 AliasGen.list = null;
354 AliasGen.listMix.Clear();
355 AliasGen.listBuiltin.Clear();
356 WordGen.listMix.Clear();
357 WordGen.listBuiltin.Clear();
358 foreach (string item in LoadAlias())
359 {
361 }
362 NameGen.list = null;
363 foreach (string item2 in LoadName())
364 {
365 MOD.listName.Add(new ExcelData(item2));
366 }
367 foreach (string item3 in LoadGodTalk())
368 {
369 MOD.listGodTalk.Add(new ExcelData(item3));
370 }
371 foreach (string item4 in LoadCharaTalk())
372 {
373 MOD.listTalk.Add(new ExcelData(item4));
374 }
375 foreach (string item5 in LoadCharaTone())
376 {
377 MOD.tones.Add(new ExcelData(item5));
378 }
379 BookList.dict = null;
380 BottleMessageList.list = null;
381 Lang.excelDialog = null;
382 foreach (CustomFileContent item6 in _customContent.Values.OfType<CustomFileContent>())
383 {
384 item6.OnSetLang(lang);
385 }
386 }
387
388 public static bool TryGetContent<T>(string contentId, [NotNullWhen(true)] out T content) where T : class, ICustomContent
389 {
390 ICustomContent value;
391 bool num = _customContent.TryGetValue(contentId, out value);
392 content = value as T;
393 if (num)
394 {
395 return content != null;
396 }
397 return false;
398 }
399
400 public static bool HasContent(string contentId)
401 {
402 return _customContent.ContainsKey(contentId);
403 }
404
405 public static void AddContent(ICustomContent content)
406 {
407 UnityEngine.Debug.Log(_customContent.Remove(content.ContentId, out var value) ? ("#mod-content override '" + content.ContentId + "' from '" + value.Owner.id + "' to '" + content.Owner.id + "'") : ("#mod-content added '" + content.ContentId + "' from '" + content.Owner.id + "'"));
408 _customContent[content.ContentId] = content;
409 }
410
411 public static bool FixDefaultRenderRowPref(RenderRow r, string id)
412 {
413 FileInfo fileInfo = PackageIterator.GetFiles("Texture/" + id + ".pref").LastOrDefault();
414 if (fileInfo == null)
415 {
416 return false;
417 }
418 r.pref = SourcePref.ReadFromIni(fileInfo.FullName);
419 return true;
420 }
421
422 public static void FixDefaultCharaRowPref(SourceChara.Row r)
423 {
424 if (!r.tag.Contains("usePref") || !FixDefaultRenderRowPref(r, r.id))
425 {
426 r.pref = new SourcePref
427 {
428 pivotY = -10
429 };
430 }
431 }
432
433 public static void FixDefaultThingRowPref(SourceThing.Row r)
434 {
435 if (!r.tag.Contains("usePref") || !FixDefaultRenderRowPref(r, r.id))
436 {
437 r.pref = new SourcePref
438 {
439 shadow = 1
440 };
441 }
442 }
443
444 public static List<Thing> GenerateMerchantStock(Card owner, string stockId = null, bool forceRestock = false)
445 {
446 List<Thing> list = new List<Thing>();
447 if (stockId.IsEmpty())
448 {
449 stockId = owner.GetStr("merchant_override");
450 }
451 if (stockId.IsEmpty())
452 {
453 return list;
454 }
455 string[] array = stockId.Split('|');
456 HashSet<string> orCreate = EClass.player.noRestocks.GetOrCreate(owner.trait.IdNoRestock, () => new HashSet<string>());
457 string[] array2 = array;
458 foreach (string text in array2)
459 {
460 if (!TryGetContent<CustomMerchantStock>("MerchantStock/" + text, out var content))
461 {
462 continue;
463 }
464 foreach (Thing item in content.Generate(owner))
465 {
466 bool flag = item.GetBool(101);
467 if (!(!forceRestock && flag) || !orCreate.Contains(item.trait.IdNoRestock))
468 {
469 if (flag)
470 {
471 orCreate.Add(item.trait.IdNoRestock);
472 }
473 list.Add(item);
474 }
475 }
476 }
477 return list;
478 }
479
480 public static void RegisterElinEventAttributes()
481 {
482 ClassCache.modTypes.Add(typeof(ModUtil));
484 foreach (var item3 in ClassCache.modTypes.Except(_checkedAttributedTypes).MembersWith<ElinEventBaseAttribute>())
485 {
486 MemberInfo item = item3.member;
487 ElinEventBaseAttribute[] item2 = item3.attrs;
488 foreach (ElinEventBaseAttribute elinEventBaseAttribute in item2)
489 {
490 try
491 {
492 if (!(item is PropertyInfo property))
493 {
494 if (item is MethodInfo method)
495 {
496 elinEventBaseAttribute.Register(method);
497 }
498 }
499 else
500 {
501 elinEventBaseAttribute.Register(property);
502 }
503 }
504 catch (Exception ex)
505 {
506 LogModError("exception while registering attribute '" + elinEventBaseAttribute.GetType().Name + "' from '" + item.TryToString() + "'\n" + ex.Message, item.DeclaringType);
507 UnityEngine.Debug.LogException(ex);
508 }
509 }
510 }
511 _checkedAttributedTypes.UnionWith(ClassCache.modTypes);
512 }
513
514 public static List<string> LoadBookList()
515 {
516 List<string> list = new List<string>();
517 DirectoryInfo[] directories = PackageIterator.GetDirectories("Text");
518 foreach (DirectoryInfo directoryInfo in directories)
519 {
520 list.AddRange(Directory.GetDirectories(directoryInfo.FullName));
521 UnityEngine.Debug.Log("#mod-content loaded book list " + directoryInfo.ShortPath());
522 }
523 return list;
524 }
525
526 public static List<string> LoadTopicFiles()
527 {
528 List<string> list = new List<string>();
529 FileInfo[] files = PackageIterator.GetFiles("Text/Help/_topics.txt");
530 foreach (FileInfo fileInfo in files)
531 {
532 list.AddRange(IO.LoadTextArray(fileInfo.FullName));
533 UnityEngine.Debug.Log("#mod-content loaded book topics " + fileInfo.ShortPath());
534 }
535 return list;
536 }
537
538 public static List<string> LoadExcelDialog()
539 {
540 List<string> list = new List<string>();
541 FileInfo[] files = PackageIterator.GetFiles("Dialog/dialog.xlsx");
542 foreach (FileInfo fileInfo in files)
543 {
544 list.Add(fileInfo.FullName);
545 UnityEngine.Debug.Log("#mod-content loaded dialog " + fileInfo.ShortPath());
546 }
547 return list;
548 }
549
550 public static List<string> LoadAlias()
551 {
552 List<string> list = new List<string>();
553 FileInfo[] files = PackageIterator.GetFiles(Lang.langCode + "/Data/Alias.xlsx");
554 foreach (FileInfo fileInfo in files)
555 {
556 list.Add(fileInfo.FullName);
557 UnityEngine.Debug.Log("#mod-content loaded Alias " + fileInfo.ShortPath());
558 }
559 return list;
560 }
561
562 public static List<string> LoadName()
563 {
564 List<string> list = new List<string>();
565 FileInfo[] files = PackageIterator.GetFiles(Lang.langCode + "/Data/Name.xlsx");
566 foreach (FileInfo fileInfo in files)
567 {
568 list.Add(fileInfo.FullName);
569 UnityEngine.Debug.Log("#mod-content loaded Name " + fileInfo.ShortPath());
570 }
571 return list;
572 }
573
574 public static List<string> LoadCharaTalk()
575 {
576 List<string> list = new List<string>();
577 FileInfo[] files = PackageIterator.GetFiles("Data/chara_talk.xlsx");
578 foreach (FileInfo fileInfo in files)
579 {
580 list.Add(fileInfo.FullName);
581 UnityEngine.Debug.Log("#mod-content loaded chara talk " + fileInfo.ShortPath());
582 }
583 return list;
584 }
585
586 public static List<string> LoadCharaTone()
587 {
588 List<string> list = new List<string>();
589 FileInfo[] files = PackageIterator.GetFiles("Data/chara_tone.xlsx");
590 foreach (FileInfo fileInfo in files)
591 {
592 list.Add(fileInfo.FullName);
593 UnityEngine.Debug.Log("#mod-content loaded chara tone " + fileInfo.ShortPath());
594 }
595 return list;
596 }
597
598 public static Sprite LoadSprite(string spritePath, Vector2? pivot = null, string name = null, int resizeWidth = 0, int resizeHeight = 0)
599 {
600 if (spritePath.IsEmpty())
601 {
602 return null;
603 }
604 if (!spritePath.EndsWith(".png"))
605 {
606 if (SpriteReplacer.dictModItems.TryGetValue(spritePath, out var value))
607 {
608 spritePath = value;
609 }
610 spritePath += ".png";
611 }
612 if (!File.Exists(spritePath))
613 {
614 FileInfo[] files = PackageIterator.GetFiles(Path.Combine("Texture", spritePath));
615 if (files.IsEmpty())
616 {
617 return null;
618 }
619 spritePath = files[^1].FullName;
620 }
621 Vector2 valueOrDefault = pivot.GetValueOrDefault();
622 if (!pivot.HasValue)
623 {
624 valueOrDefault = new Vector2(0.5f, 0.5f);
625 pivot = valueOrDefault;
626 }
627 string text = $"{spritePath}/{pivot}/{resizeWidth}/{resizeHeight}";
628 if (name == null)
629 {
630 name = text;
631 }
632 try
633 {
634 if (!_cachedTextures.TryGetValue(text, out var value2))
635 {
636 value2 = IO.LoadPNG(spritePath);
637 if (value2 == null)
638 {
639 return null;
640 }
641 if (resizeWidth != 0 && resizeHeight != 0 && (value2.width != resizeWidth || value2.height != resizeHeight))
642 {
643 Texture2D texture2D = value2.Rescale(resizeWidth, resizeHeight);
644 UnityEngine.Object.Destroy(value2);
645 value2 = texture2D;
646 value2.name = text;
647 }
648 }
649 _cachedTextures[text] = value2;
650 }
651 catch (Exception arg)
652 {
653 UnityEngine.Debug.LogError($"#mod-content failed to load sprite {spritePath.ShortPath()}\n{arg}");
654 return null;
655 }
656 Texture2D texture2D2 = _cachedTextures[text];
657 Sprite sprite = Sprite.Create(texture2D2, new Rect(0f, 0f, texture2D2.width, texture2D2.height), pivot.Value, 100f, 0u, SpriteMeshType.FullRect);
658 sprite.name = name;
659 return sprite;
660 }
661
662 public static Sprite AppendSpriteSheet(string id, int resizeWidth = 0, int resizeHeight = 0, string pattern = "@")
663 {
664 Dictionary<string, string> dictModItems = SpriteReplacer.dictModItems;
665 if (!dictModItems.TryGetValue(id, out var value) && pattern != "")
666 {
667 value = dictModItems.Where((KeyValuePair<string, string> kv) => kv.Key.StartsWith(pattern)).FirstOrDefault((KeyValuePair<string, string> kv) => id.StartsWith(kv.Key[pattern.Length..])).Value;
668 }
669 string spritePath = value;
670 string name = id;
671 Sprite sprite = LoadSprite(spritePath, null, name, resizeWidth, resizeHeight);
672 if (sprite == null)
673 {
674 return null;
675 }
676 if (SpriteSheet.dict.TryGetValue(id, out var value2) && value2.texture.width == sprite.texture.width && value2.texture.height == sprite.texture.height)
677 {
678 return value2;
679 }
680 return SpriteSheet.dict[sprite.name] = sprite;
681 }
682
683 public static List<string> LoadGodTalk()
684 {
685 List<string> list = new List<string>();
686 FileInfo[] files = PackageIterator.GetFiles("Data/god_talk.xlsx");
687 foreach (FileInfo fileInfo in files)
688 {
689 list.Add(fileInfo.FullName);
690 UnityEngine.Debug.Log("#mod-content loaded god talk " + fileInfo.ShortPath());
691 }
692 return list;
693 }
694
695 public static Dictionary<string, CustomGunEffectData> LoadGunEffects()
696 {
697 Dictionary<string, CustomGunEffectData> dictionary = new Dictionary<string, CustomGunEffectData>();
698 (FileInfo, EMod)[] filesEx = PackageIterator.GetFilesEx("Data/EffectSetting.guns.json");
699 for (int i = 0; i < filesEx.Length; i++)
700 {
701 (FileInfo, EMod) tuple = filesEx[i];
702 FileInfo item = tuple.Item1;
703 EMod item2 = tuple.Item2;
705 _customContent[customGunEffectSetting.ContentId] = customGunEffectSetting;
706 }
707 foreach (CustomGunEffectSetting item3 in _customContent.Values.OfType<CustomGunEffectSetting>())
708 {
709 item3.Load();
710 dictionary.Merge(item3.items);
711 UnityEngine.Debug.Log($"#mod-content loaded {item3}");
712 }
713 return dictionary;
714 }
715
716 public static void ImportAllGunEffectSettings()
717 {
718 foreach (var (key, customGunEffectData2) in LoadGunEffects())
719 {
720 customGunEffectData2.ResolveSprite();
721 EClass.setting.effect.guns[key] = customGunEffectData2;
722 }
723 }
724
725 public static string ExportAllGunEffectSettings()
726 {
727 string text = CorePath.rootExe + "/guns.json";
728 Dictionary<string, GameSetting.EffectData> dictionary = new Dictionary<string, GameSetting.EffectData>();
729 foreach (KeyValuePair<string, GameSetting.EffectData> gun in EClass.setting.effect.guns)
730 {
731 gun.Deconstruct(out var key, out var value);
732 string key2 = key;
733 GameSetting.EffectData effectData = value;
734 GameSetting.EffectData effectData2 = effectData.Clone();
735 if (effectData2.idSprite.IsEmpty() && (bool)effectData.sprite)
736 {
737 effectData2.idSprite = effectData.sprite.name;
738 }
739 dictionary[key2] = effectData2;
740 }
741 File.WriteAllText(text, JsonConvert.SerializeObject(dictionary, Formatting.Indented, CustomGunEffectData.JsonSettings));
742 return $"dumped {dictionary.Count} guns data to {text}";
743 }
744
745 private static Effect LoadEffect(string id)
746 {
747 if (id.IsEmpty())
748 {
749 return null;
750 }
751 if (!_rodTemplate)
752 {
753 return null;
754 }
755 string effectId = id.Split('/')[^1];
756 Sprite sprite = LoadSprite(effectId);
757 if (!sprite)
758 {
759 return null;
760 }
761 Effect effect = UnityEngine.Object.Instantiate(_rodTemplate);
762 effect.name = effectId;
763 effect.sprites = Slice().ToArray();
764 UnityEngine.Object.DontDestroyOnLoad(effect);
765 UnityEngine.Debug.Log("#mod-content loaded custom effect '" + effectId + "'");
766 return effect;
767 IEnumerable<Sprite> Slice()
768 {
769 int height = (int)sprite.rect.height;
770 float frames = sprite.rect.width / (float)height;
771 if (frames != 0f)
772 {
773 int i = 0;
774 while ((float)i < frames)
775 {
776 Sprite sprite2 = Sprite.Create(rect: new Rect(i * height, 0f, height, height), texture: sprite.texture, pivot: new Vector2(0.5f, 0.5f * (128f / (float)height)), pixelsPerUnit: 100f, extrude: 0u, meshType: SpriteMeshType.FullRect);
777 sprite2.name = $"{effectId}{i:D4}";
778 yield return sprite2;
779 int num = i + 1;
780 i = num;
781 }
782 }
783 }
784 }
785
786 private static void LoadEffectTemplate()
787 {
788 _rodTemplate = Resources.Load<Effect>("Media/Effect/General/rod");
789 if (!_rodTemplate)
790 {
791 UnityEngine.Debug.LogWarning("#mod-content cannot initialize rod effect template");
792 }
793 }
794
795 public static DynamicInvoker Call(object instance, params string[] names)
796 {
797 return new DynamicInvoker(instance?.GetType(), instance, names);
798 }
799
800 public static DynamicInvoker Call(Type type, params string[] names)
801 {
802 return new DynamicInvoker(type, null, names);
803 }
804
805 public static DynamicInvoker Call<T>(params string[] names)
806 {
807 return new DynamicInvoker(typeof(T), null, names);
808 }
809
810 public static DynamicInvoker CallType(string typeName, params string[] names)
811 {
812 return new DynamicInvoker(DynamicReflection.FindType(typeName), null, names);
813 }
814
815 public static DynamicInvoker Construct(Type type)
816 {
817 return DynamicInvoker.Constructor(type);
818 }
819
820 public static DynamicInvoker Construct<T>()
821 {
822 return DynamicInvoker.Constructor(typeof(T));
823 }
824
825 public static DynamicInvoker ConstructType(string typeName)
826 {
827 return DynamicInvoker.Constructor(DynamicReflection.FindType(typeName));
828 }
829
830 public static DynamicAccessor Access(object instance, params string[] names)
831 {
832 return new DynamicAccessor(instance?.GetType(), instance, names);
833 }
834
835 public static DynamicAccessor Access(Type type, params string[] names)
836 {
837 return new DynamicAccessor(type, null, names);
838 }
839
840 public static DynamicAccessor Access<T>(params string[] names)
841 {
842 return new DynamicAccessor(typeof(T), null, names);
843 }
844
845 public static DynamicAccessor AccessType(string typeName, params string[] names)
846 {
847 return new DynamicAccessor(DynamicReflection.FindType(typeName), null, names);
848 }
849
850 public static DynamicTarget Target(Type type, params string[] names)
851 {
852 return new DynamicTarget(type, names);
853 }
854
855 public static DynamicTarget Target<T>(params string[] names)
856 {
857 return new DynamicTarget(typeof(T), names);
858 }
859
860 public static DynamicTarget TargetType(string typeName, params string[] names)
861 {
862 return new DynamicTarget(DynamicReflection.FindType(typeName), names);
863 }
864
865 public static MethodInfo FindMethod(Type type, params string[] names)
866 {
867 return new DynamicTarget(type, names).Get();
868 }
869
870 public static MethodInfo FindMethod<T>(params string[] names)
871 {
872 return new DynamicTarget(typeof(T), names).Get();
873 }
874
875 public static MethodInfo FindGetter(Type type, params string[] names)
876 {
877 return DynamicTarget.Accessor(type, names, setter: false);
878 }
879
880 public static MethodInfo FindGetter<T>(params string[] names)
881 {
882 return DynamicTarget.Accessor(typeof(T), names, setter: false);
883 }
884
885 public static MethodInfo FindSetter(Type type, params string[] names)
886 {
887 return DynamicTarget.Accessor(type, names, setter: true);
888 }
889
890 public static MethodInfo FindSetter<T>(params string[] names)
891 {
892 return DynamicTarget.Accessor(typeof(T), names, setter: true);
893 }
894
895 public static ConstructorInfo FindConstructor(Type type, params Type[] paramTypes)
896 {
897 return DynamicTarget.Constructor(type, paramTypes);
898 }
899
900 public static ConstructorInfo FindConstructor<T>(params Type[] paramTypes)
901 {
902 return DynamicTarget.Constructor(typeof(T), paramTypes);
903 }
904
905 public static Type FindType(string typeName)
906 {
907 return DynamicReflection.FindType(typeName);
908 }
909
910 public static T Coerce<T>(object value)
911 {
912 return DynamicReflection.Coerce<T>(value);
913 }
914
915 public static SerializableSoundData GetSoundMeta(string soundPath)
916 {
917 string path = Path.ChangeExtension(soundPath, ".json");
918 SerializableSoundData serializableSoundData;
919 if (File.Exists(path))
920 {
921 try
922 {
923 serializableSoundData = IO.LoadFile<SerializableSoundData>(path);
924 if (serializableSoundData.dataVersion == SerializableSoundData.SoundDataMetaVersion.V1)
925 {
926 return serializableSoundData;
927 }
928 }
929 catch
930 {
931 }
932 }
933 serializableSoundData = new SerializableSoundData();
934 if (soundPath.NormalizePath().Contains("/Sound/BGM/"))
935 {
936 serializableSoundData.type = SoundData.Type.BGM;
937 serializableSoundData.bgmDataOptional = new SerializableBGMData
938 {
939 parts = new List<BGMData.Part>
940 {
941 new BGMData.Part()
942 }
943 };
944 }
945 IO.SaveFile(path, serializableSoundData);
946 return serializableSoundData;
947 }
948
949 public static AudioType GetAudioType(string extension)
950 {
951 return extension.ToLowerInvariant().Trim() switch
952 {
953 ".acc" => AudioType.ACC,
954 ".mp3" => AudioType.MPEG,
955 ".ogg" => AudioType.OGGVORBIS,
956 ".wav" => AudioType.WAV,
957 _ => AudioType.UNKNOWN,
958 };
959 }
960
961 public static SoundData LoadSoundData(string soundId)
962 {
963 if (!MOD.sounds.TryGetValue(soundId, out var value) || !value.Exists)
964 {
965 return null;
966 }
967 return LoadSoundData(value);
968 }
969
970 public static SoundData LoadSoundData(FileInfo soundFile)
971 {
972 string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(soundFile.FullName);
973 string fullName = soundFile.FullName;
974 AudioType audioType = GetAudioType(soundFile.Extension);
975 bool stream = fullName.NormalizePath().Contains("/BGM/") && audioType == AudioType.OGGVORBIS;
976 using UnityWebRequest unityWebRequest = AudioClipStream.GetAudioClip("file://" + fullName, audioType, compressed: false, stream);
977 unityWebRequest.SendWebRequest();
978 Stopwatch stopwatch = Stopwatch.StartNew();
979 while (!unityWebRequest.isDone && stopwatch.ElapsedMilliseconds < 5000)
980 {
981 Thread.Sleep(1);
982 }
983 if (unityWebRequest.result != UnityWebRequest.Result.Success)
984 {
985 UnityEngine.Debug.LogError("#sound '" + fileNameWithoutExtension + "' failed to load: " + unityWebRequest.error.IsEmpty("timeout"));
986 return null;
987 }
988 AudioClip content = DownloadHandlerAudioClip.GetContent(unityWebRequest);
989 int? num = content?.samples;
990 if (!num.HasValue || num.GetValueOrDefault() <= 0)
991 {
992 UnityEngine.Debug.LogError($"#sound '{fileNameWithoutExtension}' sample is null: {audioType}");
993 return null;
994 }
995 content.name = fileNameWithoutExtension;
996 SoundData soundData = GetSoundMeta(fullName).ToSoundData();
997 if (soundData is BGMData bGMData)
998 {
999 bGMData._name = Path.GetFileNameWithoutExtension(fullName);
1000 if (bGMData.song == null)
1001 {
1002 bGMData.song = new BGMData.SongData();
1003 bGMData.song.parts.Add(new BGMData.Part());
1004 }
1005 }
1006 soundData.clip = content;
1007 soundData.name = fileNameWithoutExtension;
1008 UnityEngine.Debug.Log($"#sound '{fileNameWithoutExtension}' loaded: {audioType}/{content.length}s");
1009 SoundManager.current.dictData[fileNameWithoutExtension] = soundData;
1010 return soundData;
1011 }
1012
1013 public static void AddOrReplaceBGM(string bgmId)
1014 {
1015 List<BGMData> bgms = Core.Instance.refs.bgms;
1016 Dictionary<int, BGMData> dictBGM = Core.Instance.refs.dictBGM;
1017 BGMData bGMData = LoadSoundData(bgmId) as BGMData;
1018 if (bGMData == null)
1019 {
1020 return;
1021 }
1022 bGMData.name = bgmId.Replace("BGM/", "");
1023 if (bGMData.id <= 0)
1024 {
1025 Match match = Regex.Match(bGMData.name, "^(\\d+)(?:_(.*))?$");
1026 if (match.Success)
1027 {
1028 int id = match.Groups[1].Value.ToInt();
1029 string text = (match.Groups[2].Success ? match.Groups[2].Value : null);
1030 bGMData.id = id;
1031 if (!text.IsEmpty())
1032 {
1033 bGMData.name = text;
1034 }
1035 }
1036 else
1037 {
1038 bGMData.id = bgms.Count + 1;
1039 UnityEngine.Debug.Log($"#sound bgm unassigned/{bGMData.id}/{bGMData.name}");
1040 }
1041 }
1042 if (dictBGM.TryGetValue(bGMData.id, out var value))
1043 {
1044 value.clip = bGMData.clip;
1045 UnityEngine.Debug.Log($"#sound bgm replace/{bGMData.id}/{value.name}/>/{bGMData.name}");
1046 }
1047 else
1048 {
1049 bgms.Add(bGMData);
1050 dictBGM[bGMData.id] = bGMData;
1051 UnityEngine.Debug.Log($"#sound bgm addon/{bGMData.id}/{bGMData.name}");
1052 }
1053 }
1054
1055 public static ModPackage FindSoundPackage(string soundId)
1056 {
1057 return ModManagerCore.Instance.packages.OfType<ModPackage>().LastOrDefault((ModPackage p) => p.sounds.Keys.Contains(soundId));
1058 }
1059
1060 public static Playlist CreatePlaylist(ref List<int> bgmIds, Playlist mold = null)
1061 {
1062 Playlist playlist = EClass.Sound.plBlank.Instantiate();
1063 if (bgmIds.Count == 0 && (bool)mold)
1064 {
1065 bgmIds = mold.ToInts();
1066 playlist.shuffle = mold.shuffle;
1067 playlist.minSwitchTime = mold.minSwitchTime;
1068 playlist.nextBGMOnSwitch = mold.nextBGMOnSwitch;
1069 playlist.ignoreLoop = mold.ignoreLoop;
1070 playlist.keepBGMifSamePlaylist = mold.keepBGMifSamePlaylist;
1071 playlist.name = mold.name;
1072 }
1073 foreach (int bgmId in bgmIds)
1074 {
1075 if (EClass.core.refs.dictBGM.TryGetValue(bgmId, out var value))
1076 {
1077 playlist.list.Add(new Playlist.Item
1078 {
1079 data = value
1080 });
1081 }
1082 }
1083 return playlist;
1084 }
1085
1086 public static void SetBGMKnown(int bgmId, bool known = true)
1087 {
1088 known &= EClass.core.refs.dictBGM.ContainsKey(bgmId);
1089 if (known)
1090 {
1091 EClass.player.knownBGMs.Add(bgmId);
1092 }
1093 else
1094 {
1095 EClass.player.knownBGMs.Remove(bgmId);
1096 }
1097 }
1098
1099 [Obsolete("use ImportModSourceSheets for proper caching and localizaiton support")]
1100 public static void ImportExcel(string pathToExcelFile, string sheetName, SourceData source)
1101 {
1102 UnityEngine.Debug.Log("ImportExcel source:" + source?.ToString() + " Path:" + pathToExcelFile);
1103 using FileStream @is = File.Open(pathToExcelFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
1104 XSSFWorkbook xSSFWorkbook = new XSSFWorkbook((Stream)@is);
1105 for (int i = 0; i < xSSFWorkbook.NumberOfSheets; i++)
1106 {
1107 ISheet sheetAt = xSSFWorkbook.GetSheetAt(i);
1108 if (sheetAt.SheetName != sheetName)
1109 {
1110 continue;
1111 }
1112 UnityEngine.Debug.Log("Importing Sheet:" + sheetName);
1113 try
1114 {
1115 ExcelParser.path = pathToExcelFile;
1116 if (!source.ImportData(sheetAt, new FileInfo(pathToExcelFile).Name, overwrite: true))
1117 {
1118 UnityEngine.Debug.LogError(ERROR.msg);
1119 break;
1120 }
1121 UnityEngine.Debug.Log("Imported " + sheetAt.SheetName);
1122 source.Reset();
1123 }
1124 catch (Exception ex)
1125 {
1126 UnityEngine.Debug.LogError("[Error] Skipping import " + sheetAt.SheetName + " :" + ex.Message + "/" + ex.Source + "/" + ex.StackTrace);
1127 break;
1128 }
1129 }
1130 }
1131
1132 public static SourceData FindSourceByName(string sourceData)
1133 {
1134 return sourceImporter.FindSourceByName(sourceData);
1135 }
1136
1137 public static void ImportModSourceSheets(string modId)
1138 {
1139 try
1140 {
1141 SourceCache.InvalidateCacheVersion();
1142 EMod valueOrDefault = ModManager.Instance.MappedPackages.GetValueOrDefault(modId);
1143 if (valueOrDefault == null)
1144 {
1145 return;
1146 }
1147 List<string> list = new List<string>();
1148 foreach (FileInfo sourceSheet in valueOrDefault.Mapping.SourceSheets)
1149 {
1150 sourceImporter.fileProviders[sourceSheet.FullName] = valueOrDefault;
1151 list.Add(sourceSheet.FullName);
1152 }
1153 sourceImporter.ImportFilesCached(list);
1154 UnityEngine.Debug.Log("#source finished importing workbooks from " + modId);
1155 }
1156 catch (Exception exception)
1157 {
1158 UnityEngine.Debug.LogException(exception);
1159 }
1160 }
1161
1162 public static void ImportAllModSourceSheets()
1163 {
1164 try
1165 {
1166 SourceCache.InvalidateCacheVersion();
1168 {
1170 EClass.sources.materials
1171 });
1172 List<string> list = new List<string>();
1173 foreach (BaseModPackage package in ModManager.Instance.packages)
1174 {
1175 if (!(package is ModPackage modPackage) || !package.activated || package.id == null)
1176 {
1177 continue;
1178 }
1179 foreach (FileInfo sourceSheet in modPackage.Mapping.SourceSheets)
1180 {
1181 if (!sourceSheet.Name.StartsWith(".") && !sourceSheet.Name.Contains('~'))
1182 {
1183 sourceImporter.fileProviders[sourceSheet.FullName] = modPackage;
1184 list.Add(sourceSheet.FullName);
1185 }
1186 }
1187 }
1188 sourceImporter.ImportFilesCached(list);
1189 }
1190 catch (Exception exception)
1191 {
1192 UnityEngine.Debug.LogException(exception);
1193 }
1194 UnityEngine.Debug.Log("#source finished importing workbooks");
1195 }
1196
1197 public static string ExportSourceDataCsv(string sourceData, string delimiter = ",")
1198 {
1199 SourceData sourceData2 = FindSourceByName(sourceData);
1200 if (sourceData2 == null)
1201 {
1202 return "";
1203 }
1204 IReadOnlyDictionary<string, string> typeMapping = sourceData2.GetTypeMapping();
1205 (string, string)[] array = (from kv in sourceData2.GetRowMapping()
1206 orderby kv.Value
1207 select (column: kv.Key, type: typeMapping[kv.Key])).ToArray();
1208 StringBuilder stringBuilder = new StringBuilder();
1209 stringBuilder.AppendLine(string.Join(delimiter, array.Select(((string column, string type) p) => p.column)));
1210 stringBuilder.AppendLine(string.Join(delimiter, array.Select(((string column, string type) p) => p.type)));
1211 SourceData.BaseRow[] array2 = sourceData2.ExportRows();
1212 foreach (SourceData.BaseRow baseRow in array2)
1213 {
1214 List<string> list = new List<string>();
1215 (string, string)[] array3 = array;
1216 for (int num2 = 0; num2 < array3.Length; num2++)
1217 {
1218 (string, string) tuple = array3[num2];
1219 string item = tuple.Item1;
1220 string item2 = tuple.Item2;
1221 object value = baseRow.GetRowFields()[item].GetValue(baseRow);
1222 object obj = value;
1223 IEnumerable enumerable;
1224 if (!(obj is int[] array4))
1225 {
1226 if (!(obj is int key))
1227 {
1228 if (obj is string item3)
1229 {
1230 list.Add(item3);
1231 continue;
1232 }
1233 enumerable = obj as IEnumerable;
1234 if (enumerable != null)
1235 {
1236 goto IL_024a;
1237 }
1238 }
1239 else if (item2 == "element_id")
1240 {
1241 list.Add(EClass.sources.elements.map[key].alias);
1242 continue;
1243 }
1244 list.Add(value.ToString());
1245 continue;
1246 }
1247 if (!(item2 == "elements"))
1248 {
1249 enumerable = (IEnumerable)obj;
1250 goto IL_024a;
1251 }
1252 List<string> list2 = new List<string>();
1253 for (int num3 = 0; num3 < array4.Length - 1; num3 += 2)
1254 {
1255 string alias = EClass.sources.elements.map[array4[num3]].alias;
1256 string text = array4[num3 + 1].ToString();
1257 list2.Add(alias + "/" + text);
1258 }
1259 string item4 = string.Join(',', list2);
1260 list.Add(item4);
1261 continue;
1262 IL_024a:
1263 string item5 = string.Join(',', enumerable.OfType<object>());
1264 list.Add(item5);
1265 }
1266 IEnumerable<string> values = list.Select(delegate(string f)
1267 {
1268 string text2 = f.Replace("\r", "").Replace("\n", "\\n").Replace("\"", "\"\"");
1269 return (!text2.IsEmpty()) ? ("\"" + text2 + "\"") : "";
1270 });
1271 stringBuilder.AppendLine(string.Join(delimiter, values));
1272 }
1273 return stringBuilder.ToString();
1274 }
1275
1276 public static void ExportAllSourceDataCsv(string dir)
1277 {
1278 IO.CreateDirectory(dir);
1279 foreach (string key in SourceMapping.Keys)
1280 {
1281 File.WriteAllText(Path.Combine(dir, key + ".csv"), ExportSourceDataCsv(key));
1282 }
1283 }
1284
1285 public static string ExportSourceDataJson(string sourceData, Formatting format = Formatting.Indented)
1286 {
1287 SourceData sourceData2 = FindSourceByName(sourceData);
1288 if (sourceData2 == null)
1289 {
1290 return "";
1291 }
1292 return JsonConvert.SerializeObject(sourceData2.ExportRows(), format, GameIOContext.Settings);
1293 }
1294
1295 public static void ExportAllSourceDataJson(string dir)
1296 {
1297 IO.CreateDirectory(dir);
1298 foreach (string key in SourceMapping.Keys)
1299 {
1300 File.WriteAllText(Path.Combine(dir, key + ".json"), ExportSourceDataJson(key));
1301 }
1302 }
1303
1304 public static void AddContextMenuEntry(Action onClick, string menuEntry, string displayName = "")
1305 {
1306 if (onClick == null || menuEntry.IsEmpty())
1307 {
1308 return;
1309 }
1310 string[] array = menuEntry.Split('/', StringSplitOptions.RemoveEmptyEntries);
1311 List<ContextMenuProxy> children = contextMenuProxies;
1312 for (int i = 0; i < array.Length; i++)
1313 {
1314 bool flag = i < array.Length - 1;
1315 string part = array[i];
1316 ContextMenuProxy contextMenuProxy = children.Find((ContextMenuProxy p) => p.MenuEntry == part);
1317 if (contextMenuProxy == null)
1318 {
1319 contextMenuProxy = new ContextMenuProxy(flag ? part : displayName, part)
1320 {
1321 onClick = ((i == array.Length - 1 && flag) ? null : new Action(SafeInvoke)),
1322 isMenu = flag
1323 };
1324 children.Add(contextMenuProxy);
1325 }
1326 else if (contextMenuProxy.isMenu != flag)
1327 {
1328 UnityEngine.Debug.LogWarning("#mod-content attempt to add context menu entry with same name but different types\n" + part + " -> " + (contextMenuProxy.isMenu ? "submenu" : "button"));
1329 return;
1330 }
1331 children = contextMenuProxy.children;
1332 }
1333 UnityEngine.Debug.Log("#mod-content added context menu entry '" + menuEntry + "' from '" + onClick.Method.TryToString() + "'");
1334 void SafeInvoke()
1335 {
1336 try
1337 {
1338 onClick();
1339 }
1340 catch (Exception exception)
1341 {
1342 UnityEngine.Debug.LogException(exception);
1343 }
1344 }
1345 }
1346
1347 public static void RemoveContextMenuEntry(string entry)
1348 {
1349 string[] array = entry.Split('/', StringSplitOptions.RemoveEmptyEntries);
1350 if (array.Length == 0)
1351 {
1352 return;
1353 }
1354 List<ContextMenuProxy> children = contextMenuProxies;
1355 ContextMenuProxy contextMenuProxy = null;
1356 List<ContextMenuProxy> list = null;
1357 string[] array2 = array;
1358 foreach (string part in array2)
1359 {
1360 contextMenuProxy = children.Find((ContextMenuProxy p) => p.MenuEntry == part);
1361 if (contextMenuProxy == null)
1362 {
1363 return;
1364 }
1365 list = children;
1366 children = contextMenuProxy.children;
1367 }
1368 list?.Remove(contextMenuProxy);
1369 }
1370}
Definition: ACT.cs:62
virtual string ID
Definition: ACT.cs:99
Version version
Definition: BaseCore.cs:17
static void PublishEvent(string eventId, object data=null)
static void SubscribeEvent(string eventId, Action< object > handler)
DirectoryInfo dirInfo
static List< Func< List< string > > > booklistLoaders
Definition: BookList.cs:28
Definition: Card.cs:11
string id
Definition: Card.cs:36
string GetStr(string id, string defaultStr=null)
Definition: Card.cs:2595
Trait trait
Definition: Card.cs:54
Definition: Chara.cs:10
static HashSet< Type > modTypes
Definition: ClassCache.cs:58
readonly List< ContextMenuProxy > children
static string RootData
Definition: CorePath.cs:200
Dictionary< int, BGMData > dictBGM
Definition: CoreRef.cs:388
List< BGMData > bgms
Definition: CoreRef.cs:384
Definition: Core.cs:14
CoreRef refs
Definition: Core.cs:51
static new Core Instance
Definition: Core.cs:15
string[] launchArgs
Definition: Core.cs:78
string ContentId
Definition: CustomContent.cs:6
virtual void OnSetLang(string lang)
static readonly JsonSerializerSettings JsonSettings
Dictionary< string, CustomGunEffectData > items
static CustomGunEffectSetting CreateFromFile(FileInfo file, ModPackage owner=null)
static List< Func< string, T > > assetLoaders
Definition: DynamicAsset.cs:9
Definition: EClass.cs:6
static Game game
Definition: EClass.cs:9
static Core core
Definition: EClass.cs:7
static SourceManager sources
Definition: EClass.cs:43
static Player player
Definition: EClass.cs:13
static SoundManager Sound
Definition: EClass.cs:47
static GameSetting setting
Definition: EClass.cs:35
Definition: ERROR.cs:2
static string msg
Definition: ERROR.cs:3
Definition: Effect.cs:7
bool HasTag(string tag)
Definition: ELEMENT.cs:482
virtual void Register(MethodInfo method)
void Add(ExcelData data)
static void ClearStaticRows()
Definition: ExcelParser.cs:267
UD_String_EffectData guns
Definition: GameSetting.cs:279
EffectSetting effect
Definition: GameSetting.cs:344
SpatialManager spatials
Definition: Game.cs:153
Definition: IO.cs:10
static string[] LoadTextArray(string _path)
Definition: IO.cs:483
static void SaveTextArray(string path, string[] text)
Definition: IO.cs:110
static void CreateDirectory(string path)
Definition: IO.cs:384
static void SaveFile(string path, object obj, bool compress=false, JsonSerializerSettings setting=null)
Definition: IO.cs:88
static Texture2D LoadPNG(string _path, FilterMode filter=FilterMode.Point)
Definition: IO.cs:473
Definition: Lang.cs:7
static List< Func< List< string > > > excelDialogLoaders
Definition: Lang.cs:59
static string langCode
Definition: Lang.cs:29
Definition: MOD.cs:7
static TalkDataList listTalk
Definition: MOD.cs:14
static GodTalkDataList listGodTalk
Definition: MOD.cs:16
static ToneDataList tones
Definition: MOD.cs:18
static ExcelDataList listAlias
Definition: MOD.cs:10
static Dictionary< string, FileInfo > sounds
Definition: MOD.cs:30
static ExcelDataList listName
Definition: MOD.cs:12
static new ModManager Instance
Definition: ModManager.cs:59
HashSet< int > knownBGMs
Definition: Player.cs:1134
Dictionary< string, HashSet< string > > noRestocks
Definition: Player.cs:1197
CustomReligionContent content
string[] tag
Definition: RenderRow.cs:58
override bool ImportData(ISheet sheet, string bookname, bool overwrite=false)
Definition: SourceData.cs:137
virtual IReadOnlyDictionary< string, int > GetRowMapping()
Definition: SourceData.cs:962
override BaseRow[] ExportRows()
Definition: SourceData.cs:233
override void Reset()
Definition: SourceData.cs:116
virtual IReadOnlyDictionary< string, string > GetTypeMapping()
Definition: SourceData.cs:967
IEnumerable< SourceData > ImportFilesCached(IEnumerable< string > imports, bool resetData=true)
static void HotInit(IEnumerable< SourceData > sourceData)
Dictionary< string, EMod > fileProviders
SourceData FindSourceByName(string name)
SourceElement elements
static SourcePref ReadFromIni(string path)
Definition: SourcePref.cs:431
Zone Find(string id)
GlobalSpatialList map
virtual bool CanSpawnAdv
Definition: Spatial.cs:505
virtual string Name
Definition: Spatial.cs:509
string id
Definition: Spatial.cs:13
static Dictionary< string, string > dictModItems
static Dictionary< string, Sprite > dict
Definition: SpriteSheet.cs:6
Definition: Thing.cs:8
virtual string IdNoRestock
Definition: Trait.cs:373
Definition: UIBook.cs:9
static List< Func< List< string > > > topicLoaders
Definition: UIBook.cs:332
Definition: Zone.cs:12
static string string int zoneLv ParseZoneFullName(string zoneFullName)
Definition: Zone.cs:555
Zone FindOrCreateLevel(int destLv, string subId="")
Definition: Zone.cs:534
string GetText()
Definition: Version.cs:34