Skip to content

Commit bac9492

Browse files
committed
Game save fixes, biome system
1 parent 884e46c commit bac9492

File tree

15 files changed

+175
-44
lines changed

15 files changed

+175
-44
lines changed

OrnithologistsGuild.CP/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"Name": "[CP] Ornithologist's Guild",
33
"Author": "Ivy",
4-
"Version": "1.3.0",
4+
"Version": "1.4.0",
55
"Description": "Bird houses, binoculars, and a new building to explore! Ornithologist's Guild brings a totally new birding experience to Stardew Valley, complete with updated bird mechanics, seasonal birds, a progression system, a new shop, an NPC with a tragic past, and much more!",
66
"UniqueID": "Ivy.OrnithologistsGuild.CP",
77
"MinimumApiVersion": "3.0.0",

OrnithologistsGuild.STF/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"Name": "[STF] Ornithologist's Guild",
33
"Author": "Ivy",
4-
"Version": "1.3.0",
4+
"Version": "1.4.0",
55
"Description": "Bird houses, binoculars, and a new building to explore! Ornithologist's Guild brings a totally new birding experience to Stardew Valley, complete with updated bird mechanics, seasonal birds, a progression system, a new shop, an NPC with a tragic past, and much more!",
66
"UniqueID": "Ivy.OrnithologistsGuild.STF",
77
"MinimumApiVersion": "3.0.0",

OrnithologistsGuild/Content/ContentManager.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34

45
namespace OrnithologistsGuild.Content
@@ -13,6 +14,8 @@ public class ContentManager
1314
public static string[] BathIds;
1415
public static string[] FeederIds;
1516

17+
public static Dictionary<string, string[]> DefaultBiomes;
18+
1619
public static void Initialize()
1720
{
1821
Baths = ModEntry.Instance.Helper.Data.ReadJsonFile<Models.BathDef[]>("baths.json");
@@ -22,6 +25,8 @@ public static void Initialize()
2225

2326
BathIds = Baths.Select(b => b.ID).ToArray();
2427
FeederIds = Feeders.Select(f => f.ID).ToArray();
28+
29+
DefaultBiomes = ModEntry.Instance.Helper.Data.ReadJsonFile<Dictionary<string, string[]>>("default-biomes.json");
2530
}
2631
}
2732
}

OrnithologistsGuild/Content/ContentPackManager.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,12 @@ public class ContentPackManager
99
{
1010
private const string FILENAME = "content.json";
1111

12-
internal static ContentPatcher.IContentPatcherAPI CP;
13-
1412
public static List<ContentPackDef> ContentPackDefs = new List<ContentPackDef>();
1513

1614
public static Dictionary<string, BirdieDef> BirdieDefs = new Dictionary<string, BirdieDef>();
1715

1816
public static void Initialize()
1917
{
20-
CP = ModEntry.Instance.Helper.ModRegistry.GetApi<ContentPatcher.IContentPatcherAPI>("Pathoschild.ContentPatcher");
21-
2218
ModEntry.Instance.Helper.Events.GameLoop.UpdateTicked += GameLoop_UpdateTicked;
2319
}
2420

@@ -109,7 +105,7 @@ public static void LoadVanilla()
109105
private static void GameLoop_UpdateTicked(object sender, StardewModdingAPI.Events.UpdateTickedEventArgs _)
110106
{
111107
// Parse conditions on second tick
112-
if (CP.IsConditionsApiReady)
108+
if (ModEntry.CP.IsConditionsApiReady)
113109
{
114110
ModEntry.Instance.Helper.Events.GameLoop.UpdateTicked -= GameLoop_UpdateTicked;
115111

@@ -120,7 +116,7 @@ private static void GameLoop_UpdateTicked(object sender, StardewModdingAPI.Event
120116
{
121117
try
122118
{
123-
birdieDef.ParseConditions(CP);
119+
birdieDef.ParseConditions();
124120
} catch (Exception e)
125121
{
126122
ModEntry.Instance.Monitor.Log(@$"Error in content pack: {contentPackDef.ContentPack.Manifest.Name} {contentPackDef.ContentPack.Manifest.Version} (in {birdieDef.ID}): {e.ToString()}", LogLevel.Error);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using OrnithologistsGuild.Content;
3+
using StardewValley;
4+
5+
namespace OrnithologistsGuild
6+
{
7+
public static class GameLocationExtensions
8+
{
9+
public static string[] GetBiomes(this GameLocation gameLocation)
10+
{
11+
if (!gameLocation.IsOutdoors) return null;
12+
13+
if (!string.IsNullOrWhiteSpace(gameLocation.getMapProperty("Biomes")))
14+
{
15+
return gameLocation.getMapProperty("Biomes").Split("/");
16+
}
17+
18+
if (ContentManager.DefaultBiomes.ContainsKey(gameLocation.Name))
19+
{
20+
return ContentManager.DefaultBiomes[gameLocation.Name];
21+
}
22+
23+
return new string[] { "default" };
24+
}
25+
}
26+
}
27+

OrnithologistsGuild/LocationPatches.cs renamed to OrnithologistsGuild/GameLocationPatches.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace OrnithologistsGuild
55
{
6-
public class LocationPatches
6+
public class GameLocationPatches
77
{
88
private static IMonitor Monitor;
99

OrnithologistsGuild/ModEntry.cs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ namespace OrnithologistsGuild
1313
/// <summary>The mod entry point.</summary>
1414
public partial class ModEntry : Mod
1515
{
16+
internal static ContentPatcher.IContentPatcherAPI CP;
17+
1618
internal static DynamicGameAssets.IDynamicGameAssetsApi DGA;
1719
internal static ContentPack DGAContentPack;
1820

@@ -48,10 +50,33 @@ private void GameLoop_SaveLoaded(object sender, SaveLoadedEventArgs e)
4850
{
4951
SaveDataManager.Load();
5052
Mail.Initialize();
53+
54+
// Verify that all outdoor maps have biomes specified
55+
foreach (var location in StardewValley.Game1.locations)
56+
{
57+
var biomes = location.GetBiomes();
58+
if (location.IsOutdoors && (
59+
biomes == null ||
60+
biomes.Length == 0 ||
61+
(biomes.Length == 1 && biomes[0].Equals("default")
62+
)))
63+
{
64+
Monitor.Log($"No biomes specified for outdoor location \"{location.Name}\"", LogLevel.Warn);
65+
}
66+
}
5167
}
5268

5369
private void GameLoop_GameLaunched(object sender, GameLaunchedEventArgs e)
5470
{
71+
// Custom tokens
72+
CP = Helper.ModRegistry.GetApi<ContentPatcher.IContentPatcherAPI>("Pathoschild.ContentPatcher");
73+
CP.RegisterToken(this.ModManifest, "LocationBiome", () =>
74+
{
75+
if (!Context.IsWorldReady) return null;
76+
77+
return StardewValley.Game1.player.currentLocation.GetBiomes();
78+
});
79+
5580
// Config
5681
ConfigManager.Initialize();
5782

@@ -82,10 +107,10 @@ private void GameLoop_GameLaunched(object sender, GameLaunchedEventArgs e)
82107
// Harmony patches
83108
var harmony = new Harmony(this.ModManifest.UniqueID);
84109

85-
LocationPatches.Initialize(this.Monitor);
110+
GameLocationPatches.Initialize(this.Monitor);
86111
harmony.Patch(
87112
original: AccessTools.Method(typeof(StardewValley.GameLocation), nameof(StardewValley.GameLocation.addBirdies)),
88-
prefix: new HarmonyMethod(typeof(LocationPatches), nameof(LocationPatches.addBirdies_Prefix))
113+
prefix: new HarmonyMethod(typeof(GameLocationPatches), nameof(GameLocationPatches.addBirdies_Prefix))
89114
);
90115

91116
TreePatches.Initialize(this.Monitor);

OrnithologistsGuild/Models/BirdieDef.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ public void LoadSoundAssets()
3333
}
3434
}
3535

36-
public void ParseConditions(IContentPatcherAPI contentPatcher)
36+
public void ParseConditions()
3737
{
3838
foreach (var condition in this.Conditions)
3939
{
40-
condition.ManagedConditions = contentPatcher.ParseConditions(
40+
condition.ManagedConditions = ModEntry.CP.ParseConditions(
4141
manifest: ModEntry.Instance.ModManifest,
4242
rawConditions: condition.When,
4343
formatVersion: new SemanticVersion("1.20.0")

OrnithologistsGuild/OrnithologistsGuild.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,8 @@
110110
<None Update="content-pack\i18n\default.json">
111111
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
112112
</None>
113+
<None Update="default-biomes.json">
114+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
115+
</None>
113116
</ItemGroup>
114117
</Project>

OrnithologistsGuild/Utilities/SaveDataManager.cs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,23 @@
1-
using StardewModdingAPI;
1+
using Microsoft.Xna.Framework.Graphics;
2+
using StardewModdingAPI;
23

34
namespace OrnithologistsGuild
45
{
56
public class SaveDataManager
67
{
7-
public static Models.SaveData SaveData;
8+
private const string KEY = "OrnithologistsGuild";
89

9-
private static string GetSaveDataFilename()
10-
{
11-
return $"data/{Constants.SaveFolderName}.json";
12-
}
10+
public static Models.SaveData SaveData;
1311

1412
public static void Load()
1513
{
16-
SaveData = ModEntry.Instance.Helper.Data.ReadJsonFile<Models.SaveData>(GetSaveDataFilename()) ?? new Models.SaveData();
17-
14+
SaveData = ModEntry.Instance.Helper.Data.ReadSaveData<Models.SaveData>(KEY) ?? new Models.SaveData();
1815
ModEntry.Instance.Monitor.Log($"Loaded {SaveData.LifeList.Count} life list entries");
1916
}
2017

2118
public static void Save()
2219
{
23-
ModEntry.Instance.Helper.Data.WriteJsonFile<Models.SaveData>(GetSaveDataFilename(), SaveData);
24-
20+
ModEntry.Instance.Helper.Data.WriteSaveData(KEY, SaveData);
2521
ModEntry.Instance.Monitor.Log($"Saved {SaveData.LifeList.Count} life list entries");
2622
}
2723
}

OrnithologistsGuild/assets/content-pack-vanilla/content.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"FormatVersion": 1,
3+
"$Comment": "Exactly replicates vanilla Stardew Valley bird spawning logic",
34
"Birdies": [
45
{
56
"ID": "BrownBird",

OrnithologistsGuild/assets/content-pack/content.json

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
},
3030
{
3131
"When": {
32-
"LocationName": "Desert, Railroad"
32+
"Ivy.OrnithologistsGuild/LocationBiome": "void, desert"
3333
},
3434
"NilWt": true
3535
},
@@ -74,7 +74,7 @@
7474
},
7575
{
7676
"When": {
77-
"LocationName": "Desert, Railroad"
77+
"Ivy.OrnithologistsGuild/LocationBiome": "void, desert, island"
7878
},
7979
"NilWt": true
8080
},
@@ -115,10 +115,16 @@
115115
},
116116
{
117117
"When": {
118-
"LocationName": "Desert, Railroad"
118+
"Ivy.OrnithologistsGuild/LocationBiome": "void, desert, island"
119119
},
120120
"NilWt": true
121121
},
122+
{
123+
"When": {
124+
"Ivy.OrnithologistsGuild/LocationBiome": "forest"
125+
},
126+
"AddWt": 0.1
127+
},
122128
{
123129
"When": {
124130
"Season": "Winter"
@@ -155,7 +161,7 @@
155161
},
156162
{
157163
"When": {
158-
"LocationName": "Desert, Railroad"
164+
"Ivy.OrnithologistsGuild/LocationBiome": "void, desert, island"
159165
},
160166
"NilWt": true
161167
},
@@ -202,7 +208,7 @@
202208
},
203209
{
204210
"When": {
205-
"LocationName": "Desert, Railroad"
211+
"Ivy.OrnithologistsGuild/LocationBiome": "void"
206212
},
207213
"NilWt": true
208214
}
@@ -238,13 +244,13 @@
238244
},
239245
{
240246
"When": {
241-
"LocationName": "Railroad"
247+
"Ivy.OrnithologistsGuild/LocationBiome": "void"
242248
},
243249
"NilWt": true
244250
},
245251
{
246252
"When": {
247-
"LocationName": "Town, Custom_EastScarpe"
253+
"Ivy.OrnithologistsGuild/LocationBiome": "city"
248254
},
249255
"AddWt": 0.4
250256
}
@@ -277,13 +283,13 @@
277283
},
278284
{
279285
"When": {
280-
"LocationName": "Desert, Railroad"
286+
"Ivy.OrnithologistsGuild/LocationBiome": "void, desert, island"
281287
},
282288
"NilWt": true
283289
},
284290
{
285291
"When": {
286-
"LocationName": "Mountain, Woods, Forest",
292+
"Ivy.OrnithologistsGuild/LocationBiome": "forest, wetland",
287293
"Season": "Spring, Summer"
288294
},
289295
"AddWt": 0.3
@@ -318,13 +324,13 @@
318324
},
319325
{
320326
"When": {
321-
"LocationName": "Desert, Railroad"
327+
"Ivy.OrnithologistsGuild/LocationBiome": "void, desert, island"
322328
},
323329
"NilWt": true
324330
},
325331
{
326332
"When": {
327-
"LocationName": "Forest"
333+
"Ivy.OrnithologistsGuild/LocationBiome": "forest"
328334
},
329335
"AddWt": 0.25
330336
}
@@ -340,7 +346,7 @@
340346
"Cautiousness": 5,
341347
"FlapDuration": 400,
342348
"FlySpeed": 4,
343-
"BaseWt": 0,
349+
"BaseWt": 0.5,
344350
"FeederBaseWts": {},
345351
"FoodBaseWts": {},
346352
"Conditions": [
@@ -352,9 +358,9 @@
352358
},
353359
{
354360
"When": {
355-
"LocationName": "Desert"
361+
"Ivy.OrnithologistsGuild/LocationBiome |contains=desert": "false"
356362
},
357-
"AddWt": 0.5
363+
"NilWt": true
358364
}
359365
]
360366
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
// Vanilla Stardew Valley
3+
"Farm": ["farm"],
4+
"Town": ["city"],
5+
"Beach": ["ocean"],
6+
"BusStop": ["farm", "city"],
7+
"Mountain": ["wetland"],
8+
"Forest": ["forest"],
9+
"Mine": ["city"],
10+
"Desert": ["desert"],
11+
"Woods": ["forest", "wetland"],
12+
"Railroad": ["void"],
13+
"Summit": ["forest"],
14+
"Backwoods": ["forest"],
15+
"BeachNightMarket": ["ocean"],
16+
"IslandSouth": ["island", "ocean"],
17+
"IslandSouthEast": ["island", "ocean"],
18+
"IslandEast": ["island"],
19+
"IslandWest": ["island", "ocean"],
20+
"IslandNorth": ["island"],
21+
"IslandShrine": ["island"],
22+
23+
// East Scarp compat (may be overriden by mod author in the future)
24+
"Custom_EastScarpe": ["city", "ocean"],
25+
"Custom_ESMeadowFarm": ["farm"],
26+
"Custom_ESOrchard": ["void"],
27+
"Custom_ESMineEntrance": ["city"],
28+
"Custom_ESDeepMountains": ["forest"]
29+
30+
// Ridgeside Village compat (may be overriden by mod author in the future)
31+
// TODO
32+
33+
// Stardew Valley Expanded compat (may be overriden by mod author in the future)
34+
// TODO
35+
}

0 commit comments

Comments
 (0)