static void Prefix(PatrolArea __instance) { //Dbgl($"npc name: {__instance.actor.Value.ActorName}"); if (__instance.actor.Value.InstanceId != 4000044) { return; } int _ridableId = Module <RidableModuleManager> .Self.GetNpcRidableUID(__instance.actor.Value.InstanceId); Dbgl($"ridable id: {_ridableId}"); foreach (IRidable r in AccessTools.FieldRefAccess <RidableModuleManager, List <IRidable> >(Module <RidableModuleManager> .Self, "allRidable")) { Dbgl($"ridable id: {r.UID} name: {r.GetNickName()}, owner: {r.GetBelongRider().GetName()}"); } IRidable _ridable = Module <RidableModuleManager> .Self.GetRidable(_ridableId); if (_ridable == null) { Dbgl($"ridable is null"); return; } Dbgl($"PatrolArea OnStart: {_ridableId} {_ridable.GetNickName()}"); return; foreach (KeyValuePair <int, RidableTransactionSaveData> kvp in AccessTools.FieldRefAccess <RidableModuleManager, Dictionary <int, RidableTransactionSaveData> >(Module <RidableModuleManager> .Self, "ridableTransactionDataDic")) { int id = kvp.Key; Dbgl($"got dic entry {id} {kvp.Value.BelongActorID} ActorName: {__instance.actor.Value.ActorName} ActorId: {__instance.actor.Value.InstanceId}"); } }
private static void DoSaveFile(bool auto = false) { if (Player.Self == null || Module <Player> .Self == null || Module <Player> .Self.actor == null) { return; } string path = GetSavesPath(); Dbgl($"Checking directory {path}"); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } if (!Directory.Exists(path)) { Dbgl($"Directory {path} does not exist and could not be created!"); return; } isSaving = true; Dbgl("Building save file"); SummaryPlayerIdentity curPlayerIdentity = Module <SummaryModule> .Self.GetCurPlayerIdentity(); DateTime now = DateTime.Now; TimeSpan totalPlayTime = Module <SummaryModule> .Self.GetTotalPlayTime(); GameDateTime dateTime = Module <TimeManager> .Self.DateTime; //Dbgl("Building base name"); string fileName = (string)Singleton <Archive> .Instance.GetType().GetMethod("GenSaveFileName", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(Singleton <Archive> .Instance, new object[] { curPlayerIdentity, now, dateTime, totalPlayTime }); //Dbgl(fileName); string name = Module <Player> .Self.ActorName; //Dbgl(name); string timeOfDay = $"{dateTime.Hour}h{dateTime.Minute}m"; //Dbgl(timeOfDay); string sceneName = Module <ScenarioModule> .Self.CurrentScenarioName; //Dbgl(sceneName); string position = Module <Player> .Self.GamePos.ToString("F4").Trim(new char[] { '(', ')' }); fileName = $"{name}_{fileName}_{timeOfDay}_{sceneName}_{position}{(auto?"_auto":"")}"; //Dbgl(fileName); string filePath = Path.Combine(path, fileName); // meta file Quaternion playerRot = Player.Self.GameRot; List <NPCMeta> npcs = new List <NPCMeta>(); foreach (NpcData data in Module <NpcRepository> .Self.NpcInstanceDatas) { int instanceId = data.id; Actor actor = Module <ActorMgr> .Self.Get(instanceId); if (actor == null) { continue; } string scene = actor.SceneName; string pos = actor.gamePos.ToString().Trim(new char[] { '(', ')' }); NPCMeta npc = new NPCMeta(); npc.id = instanceId; npc.scene = scene; npc.pos = pos; npcs.Add(npc); } List <RideableMeta> rideables = new List <RideableMeta>(); foreach (int uid in Module <RidableModuleManager> .Self.GetAllRidableUid()) { IRidable r = Module <RidableModuleManager> .Self.GetRidable(uid); if (r == null) { continue; } string pos = r.GetPos().ToString().Trim(new char[] { '(', ')' }); RideableMeta rideable = new RideableMeta { id = uid, pos = pos, state = r.GetRidableState().ToString() }; rideables.Add(rideable); } List <StoreMeta> stores = new List <StoreMeta>(); foreach (Store store in AccessTools.FieldRefAccess <StoreManagerV40, List <Store> >(Module <StoreManagerV40> .Self, "storeList")) { stores.Add(new StoreMeta() { id = store.id, money = store.ownMoney, recycleCount = store.recycleCount }); } SaveMeta save = new SaveMeta(); save.playerRot = playerRot.ToString(); save.NPClist = npcs; save.RideableList = rideables; save.StoreList = stores; save.FishBowlConsumeHour = (int)typeof(FishBowl).GetField("consumeHour", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null); save.WeatherState = (int)Module <WeatherModule> .Self.CurWeatherState; save.CurPriceIndex = Module <StoreManagerV40> .Self.CurPriceIndex; System.Xml.Serialization.XmlSerializer writer = new System.Xml.Serialization.XmlSerializer(typeof(SaveMeta)); Dbgl("Saving file " + filePath); Singleton <Archive> .Instance.SaveArchive(filePath); var path2 = Path.Combine(GetSavesPath(), $"{fileName}.xml"); FileStream file = File.Create(path2); writer.Serialize(file, save); file.Close(); if (auto) { Dbgl("Getting old autosaves"); string createPlayerTime = (string)Singleton <Archive> .Instance.GetType().GetMethod("GenDateFilename", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(Singleton <Archive> .Instance, new object[] { curPlayerIdentity.createPlayerTime }); List <string> autoFiles = new List <string>(); foreach (CustomSaveFile csf in saveFiles) { if (csf.auto && createPlayerTime == csf.creationTime) { autoFiles.Add(Path.Combine(GetSavesPath(), $"{csf.fileName}")); } } int del = 0; while (autoFiles.Count - del >= settings.maxAutoSaves) { File.Delete(autoFiles[del]); File.Delete(autoFiles[del] + ".xml"); del++; } } DoBuildSaveList(); isSaving = false; resetLastSave(); }
private static void ReloadActorTextures() { foreach (KeyValuePair <int, Texture2D> kvp in customTextures) { Actor actor = Module <ActorMgr> .Self.Get(kvp.Key); if (actor == null) { continue; } NpcAppear appear = actor.GetComponent <NpcAppear>(); if (appear != null) { appear.RebuildMesh(); } else { SkinnedMeshRenderer[] smrs = actor.gameObject.GetComponentsInChildren <SkinnedMeshRenderer>(); for (int i = 0; i < smrs.Length; i++) { if (smrs[i].material?.HasProperty("_MainTex") == true && smrs[i].material.mainTexture != null) { smrs[i].material.mainTexture = kvp.Value; } } } } foreach (KeyValuePair <int, Dictionary <int, Texture2D> > kvp in customTexturesPartial) { Actor actor = Module <ActorMgr> .Self.Get(kvp.Key); if (actor == null) { continue; } NpcAppear appear = actor.GetComponent <NpcAppear>(); if (appear != null) { appear.RebuildMesh(); } } int[] rint = Module <RidableModuleManager> .Self.GetAllRidableUid(); foreach (int r in rint) { IRidable ridable = Module <RidableModuleManager> .Self.GetRidable(r); if (ridable == null) { continue; } string name = ridable.GetNickName(); Dbgl($"got horse '{name}'"); if (customTexturesHorse.ContainsKey(name)) { Dbgl($"got horse texture for {name}"); GameObject go = ridable.GetActor().gameObject; SkinnedMeshRenderer[] smrs = go.GetComponentsInChildren <SkinnedMeshRenderer>(); foreach (SkinnedMeshRenderer mr in smrs) { if (mr.material?.HasProperty("_MainTex") == true && mr.material.mainTexture != null) { Dbgl($"Changing smr texture for {mr.name}"); if (mr.name == "saddle") { Dbgl($"Changing saddle"); if (customTexturesMisc.ContainsKey($"Saddle_{name}")) { Texture2D tex = customTexturesMisc[$"Saddle_{name}"]; tex.name = $"Saddle_{name}.png"; mr.material.mainTexture = tex; } } else { Texture2D tex = customTexturesHorse[name]; tex.name = $"Horse_{name}.png"; mr.material.mainTexture = tex; } } } } } }
private static void OnSceneLoaded(ScenarioModule.Arg arg) { Module <ScenarioModule> .Self.EndLoadEventor -= OnSceneLoaded; if (!isLoading) { return; } Module <Player> .Self.GamePos = VectorFromString(lastLoadedSave.position); Dbgl("input solution: " + Module <InputSolutionModule> .Self.CurSolutionType + ""); Module <InputSolutionModule> .Self.Pop(); Module <InputSolutionModule> .Self.Push(SolutionType.Gaming); //Module<SleepModule>.Self.GetType().GetMethod("PlayerWakeUpAfterArchive", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(Module<SleepModule>.Self, new object[] { }); //Module<SleepModule>.Self.GetType().GetMethod("ShowSleepMask", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(Module<SleepModule>.Self, new object[] { false }); //MessageManager.Instance.Dispatch("WakeUpScreen", null, DispatchType.IMME, 2f); //Module<SleepModule>.Self.WakeUpScreenMaskFinishedEvent?.Invoke(); Singleton <SleepTipMgr> .Self.SleepState(false); Dbgl("Checking DLC"); // stuff that needs to be recreated after save GameDLCRewardsModule.Self.GetType().GetMethod("CheckAndOpenAllDlc", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(Module <GameDLCRewardsModule> .Self, new object[] { }); Dbgl("Checking Engagement"); if (Module <EGMgr> .Self.IsEngagement()) { Dbgl("Engagement is active"); EGDate date = AccessTools.FieldRefAccess <EGMgr, EGDate>(Module <EGMgr> .Self, "mDate"); GameDateTime dateBegin = AccessTools.FieldRefAccess <EGDate, GameDateTime>(date, "mBeginTimer"); if (Module <TimeManager> .Self.DateTime > dateBegin) { date.GetType().GetMethod("InitProjectMap", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(date, new object[] { }); Actor mActor = AccessTools.FieldRefAccess <EGDate, Actor>(date, "mActor"); AccessTools.FieldRefAccess <EGDate, Actor>(date, "mActor").SetBehaviorValue("EGActor", Module <Player> .Self.actor); AccessTools.FieldRefAccess <EGDate, Actor>(date, "mActor").SetBehaviorValue("EGDate", EGData.GetDatePlace(AccessTools.FieldRefAccess <EGDate, int>(date, "mDateID"))); AccessTools.FieldRefAccess <EGDate, SharedInt>(date, "mForceValue") = mActor.GetBehaviorVariable <SharedInt>("EGForce"); AccessTools.FieldRefAccess <EGDate, SharedInt>(date, "mMoodValue") = mActor.GetBehaviorVariable <SharedInt>("EGMood"); AccessTools.FieldRefAccess <EGDate, SharedIntList>(date, "mEventCount") = mActor.GetBehaviorVariable <SharedIntList>("EGEventIDs"); AccessTools.FieldRefAccess <EGDate, List <EGRoot> >(date, "mRoots") = mActor.behavior.FindTasks <EGRoot>(); date.Start(); Dbgl("Engagement starts with " + mActor.ActorName); } else if (Module <TimeManager> .Self.DateTime > dateBegin - EGConst.Spawn_Hour_1) { Dbgl("Less than one hour before engagement starts!"); date.GetType().GetMethod("InitProjectMap", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(date, new object[] { }); Actor mActor = AccessTools.FieldRefAccess <EGDate, Actor>(date, "mActor"); AccessTools.FieldRefAccess <EGDate, Actor>(date, "mActor").SetBehaviorValue("EGActor", Module <Player> .Self.actor); AccessTools.FieldRefAccess <EGDate, Actor>(date, "mActor").SetBehaviorValue("EGDate", EGData.GetDatePlace(AccessTools.FieldRefAccess <EGDate, int>(date, "mDateID"))); AccessTools.FieldRefAccess <EGDate, SharedInt>(date, "mForceValue") = mActor.GetBehaviorVariable <SharedInt>("EGForce"); AccessTools.FieldRefAccess <EGDate, SharedInt>(date, "mMoodValue") = mActor.GetBehaviorVariable <SharedInt>("EGMood"); AccessTools.FieldRefAccess <EGDate, SharedIntList>(date, "mEventCount") = mActor.GetBehaviorVariable <SharedIntList>("EGEventIDs"); AccessTools.FieldRefAccess <EGDate, List <EGRoot> >(date, "mRoots") = mActor.behavior.FindTasks <EGRoot>(); Singleton <TipsMgr> .Instance.SendSystemTip(string.Format(TextMgr.GetStr(100507, -1), TextMgr.GetStr(AccessTools.FieldRefAccess <EGDate, int>(date, "mTipTypeID"), -1)), SystemTipType.warning); } else if (Module <TimeManager> .Self.DateTime > dateBegin - EGConst.Spawn_Hour_2) { Dbgl("Less than two hours hour before engagement starts!"); date.GetType().GetMethod("InitProjectMap", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(date, new object[] { }); Actor mActor = AccessTools.FieldRefAccess <EGDate, Actor>(date, "mActor"); AccessTools.FieldRefAccess <EGDate, Actor>(date, "mActor").SetBehaviorValue("EGActor", Module <Player> .Self.actor); AccessTools.FieldRefAccess <EGDate, Actor>(date, "mActor").SetBehaviorValue("EGDate", EGData.GetDatePlace(AccessTools.FieldRefAccess <EGDate, int>(date, "mDateID"))); AccessTools.FieldRefAccess <EGDate, SharedInt>(date, "mForceValue") = mActor.GetBehaviorVariable <SharedInt>("EGForce"); AccessTools.FieldRefAccess <EGDate, SharedInt>(date, "mMoodValue") = mActor.GetBehaviorVariable <SharedInt>("EGMood"); AccessTools.FieldRefAccess <EGDate, SharedIntList>(date, "mEventCount") = mActor.GetBehaviorVariable <SharedIntList>("EGEventIDs"); AccessTools.FieldRefAccess <EGDate, List <EGRoot> >(date, "mRoots") = mActor.behavior.FindTasks <EGRoot>(); Singleton <TipsMgr> .Instance.SendSystemTip(string.Format(TextMgr.GetStr(100506, -1), TextMgr.GetStr(AccessTools.FieldRefAccess <EGDate, int>(date, "mTipTypeID"), -1)), SystemTipType.warning); } } if (arg.IsMain) { Dbgl("Checking Ridables"); Module <FarmModule> .Self.ForeachUnit(delegate(Unit unit, bool isFloor) { if (unit != null && unit is RidableTamingUnit) { RidableTamingUnit ru = unit as RidableTamingUnit; GameObject unitGameObjectByUnit = Module <FarmModule> .Self.GetUnitGameObjectByUnit(unit); if (unitGameObjectByUnit == null) { return; } RidableTamingUnitViewer uv = (RidableTamingUnitViewer)unitGameObjectByUnit.GetComponentInChildren <UnitViewer>(); AccessTools.FieldRefAccess <RidableTamingUnitViewer, List <IRidable> >(uv, "ridableList").Clear(); typeof(RidableTamingUnitViewer).GetMethod("CreateShit", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(uv, new object[] { }); typeof(RidableTamingUnitViewer).GetMethod("CreateAllWorkableRidable", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(uv as RidableTamingUnitViewer, new object[] { }); typeof(RidableTamingUnitViewer).GetMethod("UpdateAllRidableInfo", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(uv as RidableTamingUnitViewer, new object[] { }); } }); typeof(RidableModuleManager).GetMethod("InitIdGenerator", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(Module <RidableModuleManager> .Self, new object[] { }); Dictionary <int, RidableTransactionSaveData> rideDic = AccessTools.FieldRefAccess <RidableModuleManager, Dictionary <int, RidableTransactionSaveData> >(Module <RidableModuleManager> .Self, "ridableTransactionDataDic"); int[] rideKeys = new int[rideDic.Count]; rideDic.Keys.CopyTo(rideKeys, 0); foreach (int key in rideKeys) { if (rideDic[key].RidableSource == RidableSource.NPC) { AccessTools.FieldRefAccess <RidableModuleManager, Dictionary <int, RidableTransactionSaveData> >(Module <RidableModuleManager> .Self, "ridableTransactionDataDic").Remove(key); } } Scene sceneByName = SceneManager.GetSceneByName(arg.scenarioName); if (sceneByName.IsValid() && sceneByName.isLoaded) { GameObject[] gos = sceneByName.GetRootGameObjects(); foreach (GameObject go in gos) { Component co = go.GetComponentInChildren(typeof(NpcsRidableManager)); if (co != null) { Dbgl("Got NpcsRidableManager"); (co as NpcsRidableManager).DestoryAllRidable(); AccessTools.FieldRefAccess <RidableFences, Dictionary <IRidable, RidableFence> >((co as NpcsRidableManager), "ridableDic").Clear(); typeof(NpcsRidableManager).GetMethod("AfterPlayerWakeUpEvent", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(co as NpcsRidableManager, new object[] { }); } } } } Dbgl("Checking wishes"); AccessTools.FieldRefAccess <DynamicWishManager, List <int> >(Module <DynamicWishManager> .Self, "hasTalkToday").AddRange(from it in AccessTools.FieldRefAccess <DynamicWishManager, List <DoubleInt> >(Module <DynamicWishManager> .Self, "curWishData") select it.id0); //Module<RidableModuleManager>.Self.InitNpcRidableBehaviourValue(); // stuff that needs to be carried over but isnt, use meta file Dbgl("Loading Meta"); string filePath = Path.Combine(GetSavesPath(), $"{lastLoadedSave.fileName}.xml"); try { System.Xml.Serialization.XmlSerializer reader = new System.Xml.Serialization.XmlSerializer(typeof(SaveMeta)); StreamReader file = new StreamReader($"{filePath}"); SaveMeta save = (SaveMeta)reader.Deserialize(file); file.Close(); Dbgl("Loading Player Meta"); if (save.playerRot != null) { string[] rotStrings = save.playerRot.Replace("(", "").Replace(")", "").Replace(" ", "").Split(','); Quaternion rot = new Quaternion(float.Parse(rotStrings[0]), float.Parse(rotStrings[1]), float.Parse(rotStrings[2]), float.Parse(rotStrings[3])); Player.Self.GameRot = rot; } Dbgl("Loading NPC Meta"); foreach (NPCMeta npc in save.NPClist) { Actor actor = Module <ActorMgr> .Self.Get(npc.id); if (actor != null) { Module <ActorMgr> .Self.MoveToScenario(actor, npc.scene, VectorFromString(npc.pos)); } } Dbgl("Loading Ridable Meta"); if (save.RideableList != null) { foreach (RideableMeta r in save.RideableList) { IRidable rideable = Module <RidableModuleManager> .Self.GetRidable(r.id); if (rideable == null) { Dbgl("null rideable " + r.id); rideable = Module <RidableModuleManager> .Self.GetRidable(r.id); continue; } Dbgl("got rideable " + r.id); Actor actor = rideable.GetActor(); if (actor != null) { Dbgl("got rideable actor for " + rideable.GetNickName()); actor.gamePos = VectorFromString(r.pos); actor.RefreshPos(); } switch (r.state) { case "None": rideable.SetRidableState(RidableState.None); break; case "Idle": rideable.SetRidableState(RidableState.Idle); break; case "Ride": if (rideable.BelongToPlayer) { int otherNPCID = Module <EGMgr> .Self.GetEngagementStartNpcID(); if (RideUtils.TestRideWithNpcID > 0) { otherNPCID = RideUtils.TestRideWithNpcID; RideUtils.TestRideWithNpcID = -1; } Module <Player> .Self.RideRidable(rideable, otherNPCID); } else if (rideable.GetBelongRider() is ActorRiderAdapter) { Actor belongActor = (rideable.GetBelongRider() as ActorRiderAdapter).actor; RideController rideController = belongActor.RideController; rideController.RideOn(rideable); } break; case "Follow": rideable.SetRidableState(RidableState.Follow); break; case "Stay": rideable.SetRidableState(RidableState.Stay); break; } } } Dbgl("Loading Fishbowl Meta"); if (save.FishBowlConsumeHour != -1) { typeof(FishBowl).GetField("consumeHour", BindingFlags.NonPublic | BindingFlags.Static).SetValue(Module <FishBowl> .Self, save.FishBowlConsumeHour); } Dbgl("Loading Store Meta"); AccessTools.FieldRefAccess <StoreManagerV40, float>(Module <StoreManagerV40> .Self, "curPriceIndex") = save.CurPriceIndex; if (save.StoreList != null) { foreach (StoreMeta sMeta in save.StoreList) { Module <StoreManagerV40> .Self.GetStore(sMeta.id).recycleCount = sMeta.recycleCount; Module <StoreManagerV40> .Self.GetStore(sMeta.id).ownMoney = sMeta.money; } } Dbgl("Loading Weather Meta"); if (save.WeatherState != -1) { AccessTools.FieldRefAccess <WeatherModule, WeatherCtr>(Module <WeatherModule> .Self, "weatherCtr").SetWeather((WeatherState)save.WeatherState); } } catch (Exception ex) { Dbgl("Problem with meta file: " + ex); } isLoading = false; resetLastSave(); }