From 571826c3e0227a6b0c64f34612013a9f368e3ea5 Mon Sep 17 00:00:00 2001 From: Sweet Panda <76555779+RealSweetPanda@users.noreply.github.com> Date: Wed, 18 Jan 2023 21:09:54 +0200 Subject: [PATCH] Buff Saving (#3) --- Framework/Model/PlayerData.cs | 11 ++- Framework/NPCExtensions.cs | 146 ++++++++++++++++++--------------- Framework/NewShippingMenuV2.cs | 3 + Framework/SaveManager.cs | 100 +++++++++++++++++++++- SaveAnywhere.csproj | 2 +- manifest.json | 2 +- 6 files changed, 193 insertions(+), 71 deletions(-) diff --git a/Framework/Model/PlayerData.cs b/Framework/Model/PlayerData.cs index 8478b99..a102e96 100644 --- a/Framework/Model/PlayerData.cs +++ b/Framework/Model/PlayerData.cs @@ -1,7 +1,14 @@ -namespace SaveAnywhere.Framework.Model { +using StardewValley; + +namespace SaveAnywhere.Framework.Model { public class PlayerData { public int Time { get; init; } - + + public BuffData[] otherBuffs { get; init; } + + public BuffData drinkBuff { get; init; } + + public BuffData foodBuff { get; init; } public CharacterData[] Characters { get; init; } public bool IsCharacterSwimming { get; init; } diff --git a/Framework/NPCExtensions.cs b/Framework/NPCExtensions.cs index b2551f1..1778d2e 100644 --- a/Framework/NPCExtensions.cs +++ b/Framework/NPCExtensions.cs @@ -6,80 +6,94 @@ namespace SaveAnywhere.Framework { public static class NPCExtensions { public static void fillInSchedule(this NPC npc) { - if (npc.Schedule == null) - return; - var rawSchedule = GetRawSchedule(npc.Name); - if (rawSchedule == null) - return; - var scheduleKey = GetScheduleKey(npc); - string str; - rawSchedule.TryGetValue(scheduleKey, out str); - if (string.IsNullOrEmpty(str)) - return; - var strArray1 = str.Split('/'); - var source = new SortedDictionary(); - for (var index = 0; index < strArray1.Length; ++index) { - var strArray2 = strArray1[index].Split(' '); - if (strArray2[0].Equals("GOTO")) { - rawSchedule.TryGetValue(strArray2[1], out str); - strArray1 = str.Split('/'); - index = -1; - } - - var schedulePathInfo = new SchedulePathInfo(strArray1[index]); - if (schedulePathInfo.timeToGoTo != 0) - source.Add(schedulePathInfo.timeToGoTo, schedulePathInfo); - } + try + { + if (npc.Schedule == null) + return; + var rawSchedule = GetRawSchedule(npc.Name); + if (rawSchedule == null) + return; + var scheduleKey = GetScheduleKey(npc); + string str; + rawSchedule.TryGetValue(scheduleKey, out str); + if (string.IsNullOrEmpty(str)) + return; + var strArray1 = str.Split('/'); + var source = new SortedDictionary(); + for (var index = 0; index < strArray1.Length; ++index) + { + var strArray2 = strArray1[index].Split(' '); + if (strArray2[0].Equals("GOTO")) + { + rawSchedule.TryGetValue(strArray2[1], out str); + strArray1 = str.Split('/'); + continue; + } - var index1 = 0; - var list = source.ToList(); - list.OrderBy((Func, int>) (i => i.Key)); - KeyValuePair keyValuePair; - for (var key1 = 600; key1 <= 2600; key1 += 10) - if (index1 >= list.Count && !source.ContainsKey(key1)) { - var sortedDictionary = source; - var key2 = key1; - keyValuePair = list[list.Count - 1]; - var schedulePathInfo = keyValuePair.Value; - sortedDictionary.Add(key2, schedulePathInfo); + var schedulePathInfo = new SchedulePathInfo(strArray1[index]); + if (schedulePathInfo.timeToGoTo != 0) + source.Add(schedulePathInfo.timeToGoTo, schedulePathInfo); } - else if (index1 == list.Count - 1) { - if (!source.ContainsKey(key1)) { + + var index1 = 0; + var list = source.ToList(); + list.OrderBy((Func, int>)(i => i.Key)); + KeyValuePair keyValuePair; + for (var key1 = 600; key1 <= 2600; key1 += 10) + if (index1 >= list.Count && !source.ContainsKey(key1)) + { var sortedDictionary = source; - var key3 = key1; - keyValuePair = list[index1]; + var key2 = key1; + // fix ArgumentOutOfRangeException that happens below + if (list.Count != 0) keyValuePair = list[list.Count - 1]; + else keyValuePair = new KeyValuePair(); var schedulePathInfo = keyValuePair.Value; - sortedDictionary.Add(key3, schedulePathInfo); + sortedDictionary.Add(key2, schedulePathInfo); } - } - else { - var num = key1; - keyValuePair = list[index1 + 1]; - var key4 = keyValuePair.Key; - if (num == key4) { - ++index1; + else if (index1 == list.Count - 1) + { + if (!source.ContainsKey(key1)) + { + var sortedDictionary = source; + var key3 = key1; + keyValuePair = list[index1]; + var schedulePathInfo = keyValuePair.Value; + sortedDictionary.Add(key3, schedulePathInfo); + } } - else if (!source.ContainsKey(key1)) { - var sortedDictionary = source; - var key5 = key1; - keyValuePair = list[index1]; - var schedulePathInfo = keyValuePair.Value; - sortedDictionary.Add(key5, schedulePathInfo); + else + { + var num = key1; + keyValuePair = list[index1 + 1]; + var key4 = keyValuePair.Key; + if (num == key4) + { + ++index1; + } + else if (!source.ContainsKey(key1)) + { + var sortedDictionary = source; + var key5 = key1; + keyValuePair = list[index1]; + var schedulePathInfo = keyValuePair.Value; + sortedDictionary.Add(key5, schedulePathInfo); + } } - } - var schedulePathInfo1 = source[Game1.timeOfDay]; - var schedulePathDescription = SaveAnywhere.ModHelper.Reflection - .GetMethod(npc, "pathfindToNextScheduleLocation").Invoke( - npc.currentLocation.Name, npc.getTileX(), npc.getTileY(), schedulePathInfo1.endMap, - schedulePathInfo1.endX, schedulePathInfo1.endY, schedulePathInfo1.endDirection, - schedulePathInfo1.endBehavior, schedulePathInfo1.endMessage); - npc.DirectionsToNewLocation = schedulePathDescription; - npc.controller = new PathFindController(npc.DirectionsToNewLocation.route, npc, - Utility.getGameLocationOfCharacter(npc)) { - finalFacingDirection = npc.DirectionsToNewLocation.facingDirection, - endBehaviorFunction = null - }; + var schedulePathInfo1 = source[Game1.timeOfDay]; + var schedulePathDescription = SaveAnywhere.ModHelper.Reflection + .GetMethod(npc, "pathfindToNextScheduleLocation").Invoke( + npc.currentLocation.Name, npc.getTileX(), npc.getTileY(), schedulePathInfo1.endMap, + schedulePathInfo1.endX, schedulePathInfo1.endY, schedulePathInfo1.endDirection, + schedulePathInfo1.endBehavior, schedulePathInfo1.endMessage); + npc.DirectionsToNewLocation = schedulePathDescription; + npc.controller = new PathFindController(npc.DirectionsToNewLocation.route, npc, + Utility.getGameLocationOfCharacter(npc)) + { + finalFacingDirection = npc.DirectionsToNewLocation.facingDirection, + endBehaviorFunction = null + }; + } catch{} } private static IDictionary GetRawSchedule(string npcName) { diff --git a/Framework/NewShippingMenuV2.cs b/Framework/NewShippingMenuV2.cs index a3360cc..ad9443f 100644 --- a/Framework/NewShippingMenuV2.cs +++ b/Framework/NewShippingMenuV2.cs @@ -56,6 +56,8 @@ public class NewShippingMenuV2 : IClickableMenu { private int timesPokedMoon; private readonly int totalWidth; private float weatherX; + + public NewShippingMenuV2(IList items) : base(0, 0, Game1.viewport.Width, Game1.viewport.Height) { Game1.player.team.endOfNightStatus.UpdateState("shipment"); @@ -70,6 +72,7 @@ public NewShippingMenuV2(IList items) : base(0, 0, Game1.viewport.Width, G centerX = Game1.viewport.Width / 2; centerY = Game1.viewport.Height / 2; _hasFinished = false; + outro = true; var num = -1; for (var index = 0; index < 6; ++index) { var categories = this.categories; diff --git a/Framework/SaveManager.cs b/Framework/SaveManager.cs index 8795c83..dc56a89 100644 --- a/Framework/SaveManager.cs +++ b/Framework/SaveManager.cs @@ -76,8 +76,34 @@ public void BeginSaveData() { WaitingToSave = true; } + var drink = Game1.buffsDisplay.drink; + BuffData drinkdata = null; + + if (drink != null) + { + drinkdata = new BuffData( + drink.displaySource, + drink.source, + drink.millisecondsDuration, + drink.buffAttributes + ); + } + var food = Game1.buffsDisplay.food; + BuffData fooddata = null; + if (food != null) + { + fooddata = new BuffData( + food.displaySource, + food.source, + food.millisecondsDuration, + food.buffAttributes + ); + } Helper.Data.WriteJsonFile(RelativeDataPath, new PlayerData { Time = Game1.timeOfDay, + otherBuffs = GetotherBuffs().ToArray(), + drinkBuff = drinkdata, + foodBuff = fooddata, Characters = GetPositions().ToArray(), IsCharacterSwimming = Game1.player.swimming.Value }); @@ -89,6 +115,69 @@ public void LoadData() { if (data == null) return; Game1.timeOfDay = data.Time; + if (data.otherBuffs != null) + { + foreach (var buff in data.otherBuffs) + { + var atts = buff.Attributes; + Game1.buffsDisplay.addOtherBuff(new Buff(atts[0], + atts[1], + atts[2], + atts[3], + atts[4], + atts[5], + atts[6], + atts[7], + atts[8], + atts[9], + atts[10], + atts[11], + buff.MillisecondsDuration * 10 / 7000, + buff.Source, + buff.DisplaySource)); + } + } + var datadrink = data.drinkBuff; + var datafood = data.foodBuff; + + if (datadrink != null) + { + var atts = datadrink.Attributes; + Game1.buffsDisplay.tryToAddDrinkBuff(new Buff(atts[0], + atts[1], + atts[2], + atts[3], + atts[4], + atts[5], + atts[6], + atts[7], + atts[8], + atts[9], + atts[10], + atts[11], + datadrink.MillisecondsDuration * 10 / 7000, + datadrink.Source, + datadrink.DisplaySource)); + } + if (datafood != null) + { + var atts = datafood.Attributes; + Game1.buffsDisplay.tryToAddFoodBuff(new Buff(atts[0], + atts[1], + atts[2], + atts[3], + atts[4], + atts[5], + atts[6], + atts[7], + atts[8], + atts[9], + atts[10], + atts[11], + datafood.MillisecondsDuration * 10 / 7000, + datafood.Source, + datafood.DisplaySource),datafood.MillisecondsDuration); + } ResumeSwimming(data); SetPositions(data.Characters); var onLoaded = OnLoaded; @@ -109,7 +198,16 @@ public void ResumeSwimming(PlayerData data) { } catch { } } - + private IEnumerable GetotherBuffs() { + foreach (var buff in Game1.buffsDisplay.otherBuffs) { + yield return new BuffData( + buff.displaySource, + buff.source, + buff.millisecondsDuration, + buff.buffAttributes + ); + } + } private IEnumerable GetPositions() { var player = Game1.player; var name1 = player.Name; diff --git a/SaveAnywhere.csproj b/SaveAnywhere.csproj index 6704000..e35f0c4 100644 --- a/SaveAnywhere.csproj +++ b/SaveAnywhere.csproj @@ -5,7 +5,7 @@ - + diff --git a/manifest.json b/manifest.json index 07b178e..a4b5962 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "Name": "Save Anywhere", "Author": "Open Source", - "Version": "3.0.1", + "Version": "3.0.2", "Description": "This mod allows you to save your game at any time, anywhere.", "UniqueID": "OpenSource.SaveAnywhere", "EntryDll": "SaveAnywhere.dll",