-
Notifications
You must be signed in to change notification settings - Fork 0
/
PortraiturePlusMod.cs
193 lines (173 loc) · 6.71 KB
/
PortraiturePlusMod.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
using HarmonyLib;
using Microsoft.Xna.Framework.Graphics;
using Portraiture;
using Portraiture.HDP;
using StardewModdingAPI;
using StardewValley;
namespace PortraiturePlus
{
/// <summary>The mod entry point.</summary>
// ReSharper disable once ClassNeverInstantiated.Global
internal sealed class PortraiturePlusMod : Mod
{
private static IModHelper _helper = null!;
private static readonly string Week = (Game1.dayOfMonth % 7) switch
{
0 => "Sunday",
1 => "Monday",
2 => "Tuesday",
3 => "Wednesday",
4 => "Thursday",
5 => "Friday",
6 => "Saturday",
_ => ""
};
private static readonly IDictionary<string, string> FestivalDates =
Game1.content.Load<Dictionary<string, string>>(@"Data\Festivals\FestivalDates", LocalizedContentManager.LanguageCode.en);
public override void Entry(IModHelper? help)
{
_helper = help!;
FestivalInit();
HarmonyFix();
}
public static void AddContentPackTextures(List<string> folders, Dictionary<string, Texture2D> pTextures)
{
var contentPacks = _helper.ContentPacks.GetOwned();
foreach (var pack in contentPacks)
{
var folderName = pack.Manifest.UniqueID;
var folderPath = pack.DirectoryPath;
folders.Add(folderName);
foreach (var file in Directory.EnumerateFiles(pack.DirectoryPath, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".png") || s.EndsWith(".xnb")))
{
var fileName = file.Replace(folderPath + "\\", "");
var name = Path.GetFileNameWithoutExtension(file);
var extension = Path.GetExtension(file).ToLower();
if (extension == "xnb")
fileName = name;
var texture = pack.ModContent.Load<Texture2D>(fileName);
var tileWith = Math.Max(texture.Width / 2, 64);
var scale = tileWith / 64f;
var scaled = new ScaledTexture2D(texture, scale);
if (!pTextures.ContainsKey(folderName + ">" + name))
pTextures.Add(folderName + ">" + name, scaled);
else
pTextures[folderName + ">" + name] = scaled;
}
}
}
private void HarmonyFix()
{
PortraiturePlusFix.Initialize(monitor: Monitor);
var harmony = new Harmony(ModManifest.UniqueID);
harmony.PatchAll();
harmony.Patch(original: PortraiturePlusFix.GetPortrait(), prefix: new HarmonyMethod(AccessTools.Method(typeof(PortraiturePlusFix), nameof(PortraiturePlusFix.getPortrait_Prefix))));
harmony.Patch(original: PortraiturePlusFix.LoadAllPortraits(), postfix: new HarmonyMethod(AccessTools.Method(typeof(PortraiturePlusFix), nameof(PortraiturePlusFix.loadAllPortraits_Postfix))));
}
public static Texture2D? GetPortrait(NPC npc, Texture2D tex, List<string> folders, PresetCollection presets, int activeFolder, Dictionary<string, Texture2D> pTextures)
{
var name = npc.Name;
if (!Context.IsWorldReady || folders.Count == 0)
return null;
activeFolder = Math.Max(activeFolder, 0);
if (presets.Presets.FirstOrDefault(pr => pr.Character == name) is { } pre)
activeFolder = Math.Max(folders.IndexOf(pre.Portraits), 0);
var folder = folders[activeFolder];
if (activeFolder == 0 || folders.Count <= activeFolder || folder == "none" || folder == "HDP" && PortraitureMod.helper.ModRegistry.IsLoaded("tlitookilakin.HDPortraits"))
return null;
if (folder == "HDP" && !PortraitureMod.helper.ModRegistry.IsLoaded("tlitookilakin.HDPortraits"))
{
try
{
var portraits = PortraitureMod.helper.GameContent.Load<MetadataModel>("Mods/HDPortraits/" + name);
switch (portraits)
{
case null:
return null;
case var _ when portraits.TryGetTexture(out var texture):
{
if (portraits.Animation == null || portraits.Animation.VFrames == 1 && portraits.Animation.HFrames == 1)
return ScaledTexture2D.FromTexture(tex, texture, portraits.Size / 64f);
portraits.Animation.Reset();
return new AnimatedTexture2D(texture, texture.Width / portraits.Animation.VFrames, texture.Height / portraits.Animation.HFrames, 6, true, portraits.Size / 64f);
}
default:
return null;
}
}
catch
{
return null;
}
}
var raining = Game1.isRaining ? "Rain" : "";
var year = Game1.year.ToString();
var season = Game1.currentSeason ?? "spring";
var npcDictionary = pTextures.Keys
.Where(key => key.Contains(name) && key.Contains(folder))
.ToDictionary(k => k.ToLowerInvariant(), l => pTextures[l]);
var dayOfMonth = Game1.dayOfMonth.ToString();
var festival = GetDayEvent();
var gl = Game1.currentLocation.Name ?? "";
var isOutdoors = Game1.currentLocation.IsOutdoors ? "Outdoor" : "Indoor";
// var isRaining = Game1.isRaining ? "_Rain" : "";
name = folder + ">" + name;
var queryScenarios = new List<string[]>
{
new[] {name, festival},
new[] {name, gl, season, year, dayOfMonth}, new[] {name, gl, season, year, Week},
new[] {name, gl, season, dayOfMonth}, new[] {name, gl, season, Week},
new[] {name, gl, season},
new[] {name, gl, dayOfMonth}, new[] {name, gl, Week},
new[] {name, gl},
new[] {name, season, raining},
new[] {name, season, isOutdoors},
new[] {name, season, year, dayOfMonth}, new[] {name, season, year, Week},
new[] {name, season, dayOfMonth}, new[] {name, season, Week},
new[] {name, season},
new[] {name, raining},
new[] {name}
};
foreach (var result in queryScenarios.Select(args => GetTexture2D(npcDictionary, args)).OfType<Texture2D>())
{
return result;
}
return pTextures.ContainsKey(folder + ">" + name) ? pTextures[folder + ">" + name] : null;
}
private static string GetDayEvent()
{
if (SaveGame.loaded?.weddingToday ?? Game1.weddingToday || Game1.CurrentEvent != null && Game1.CurrentEvent.isWedding)
return "Wedding";
var festival = FestivalDates.TryGetValue($"{Game1.currentSeason}{Game1.dayOfMonth}", out var festivalName) ? festivalName : "";
return festival;
}
private static Texture2D? GetTexture2D(Dictionary<string, Texture2D> npcDictionary, params string[] values)
{
var key = values.Aggregate((current, next) => current + "_" + next).ToLowerInvariant().TrimEnd('_');
return values.Any(text => text == "") ? null : npcDictionary!.GetValueOrDefault(key, null);
}
private static void FestivalInit()
{
foreach (var key in FestivalDates.Keys)
{
if (FestivalDates[key].Contains(' '))
{
FestivalDates[key] = FestivalDates[key].Replace(" ", "");
}
if (FestivalDates[key].Contains('\''))
{
FestivalDates[key] = FestivalDates[key].Replace("'", "");
}
FestivalDates[key] = FestivalDates[key] switch
{
"EggFestival" => "EggF",
"DanceoftheMoonlightJellies" => "Jellies",
"StardewValleyFair" => "Fair",
"FestivalofIce" => "Ice",
"FeastoftheWinterStar" => "WinterStar",
_ => FestivalDates[key]
};
}
}
}
}