Skip to content

Commit 0321d6c

Browse files
authored
Loader patch loading refactor + Custom weapons and sprites for them (#94)
1 parent f981661 commit 0321d6c

2 files changed

Lines changed: 148 additions & 86 deletions

File tree

src/Loader.cs

Lines changed: 120 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,109 @@ public static class Loader
3232
{ "tribeAbility", typeof(TribeAbility.Type) },
3333
{ "unitAbility", typeof(UnitAbility.Type) },
3434
{ "improvementAbility", typeof(ImprovementAbility.Type) },
35-
{ "playerAbility", typeof(PlayerAbility.Type) }
35+
{ "playerAbility", typeof(PlayerAbility.Type) },
36+
{ "weaponData", typeof(UnitData.WeaponEnum) }
3637
};
3738
internal static List<GameModeButtonsInformation> gamemodes = new();
39+
private static readonly Dictionary<Type, Action<JObject, bool>> typeHandlers = new()
40+
{
41+
[typeof(TribeData.Type)] = new((token, duringEnumCacheCreation) =>
42+
{
43+
if (duringEnumCacheCreation)
44+
{
45+
Registry.customTribes.Add((TribeData.Type)Registry.autoidx);
46+
token["style"] = Registry.climateAutoidx;
47+
token["climate"] = Registry.climateAutoidx;
48+
Registry.climateAutoidx++;
49+
}
50+
else
51+
{
52+
if (token["preview"] != null)
53+
{
54+
Visual.PreviewTile[] preview = JsonSerializer.Deserialize<Visual.PreviewTile[]>(token["preview"].ToString())!;
55+
Registry.tribePreviews[Util.GetJTokenName(token)] = preview;
56+
}
57+
}
58+
}),
59+
60+
[typeof(UnitData.Type)] = new((token, duringEnumCacheCreation) =>
61+
{
62+
if (duringEnumCacheCreation)
63+
{
64+
UnitData.Type unitPrefabType = UnitData.Type.Scout;
65+
if (token["prefab"] != null)
66+
{
67+
string prefabId = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(token["prefab"]!.ToString());
68+
if (Enum.TryParse(prefabId, out UnitData.Type parsedType))
69+
unitPrefabType = parsedType;
70+
}
71+
PrefabManager.units.TryAdd((int)(UnitData.Type)Registry.autoidx, PrefabManager.units[(int)unitPrefabType]);
72+
}
73+
else
74+
{
75+
if (token["embarksTo"] != null)
76+
{
77+
string unitId = Util.GetJTokenName(token);
78+
string embarkUnitId = token["embarksTo"].ToString();
79+
Main.embarkNames[unitId] = embarkUnitId;
80+
}
81+
if (token["weapon"] != null)
82+
{
83+
string weaponString = token["weapon"].ToString();
84+
if (EnumCache<UnitData.WeaponEnum>.TryGetType(weaponString, out UnitData.WeaponEnum type))
85+
{
86+
token["weapon"] = (int)type;
87+
}
88+
}
89+
}
90+
}),
91+
92+
[typeof(ImprovementData.Type)] = new((token, duringEnumCacheCreation) =>
93+
{
94+
if (duringEnumCacheCreation)
95+
{
96+
ImprovementData.Type improvementPrefabType = ImprovementData.Type.CustomsHouse;
97+
if (token["prefab"] != null)
98+
{
99+
string prefabId = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(token["prefab"]!.ToString());
100+
if (Enum.TryParse(prefabId, out ImprovementData.Type parsedType))
101+
improvementPrefabType = parsedType;
102+
}
103+
PrefabManager.improvements.TryAdd((ImprovementData.Type)Registry.autoidx, PrefabManager.improvements[improvementPrefabType]);
104+
}
105+
else
106+
{
107+
if (token["attractsResource"] != null)
108+
{
109+
string improvementId = Util.GetJTokenName(token);
110+
string attractsId = token["attractsResource"].ToString();
111+
Main.attractsResourceNames[improvementId] = attractsId;
112+
}
113+
if (token["attractsToTerrain"] != null)
114+
{
115+
string improvementId = Util.GetJTokenName(token);
116+
string attractsId = token["attractsToTerrain"].ToString();
117+
Main.attractsTerrainNames[improvementId] = attractsId;
118+
}
119+
}
120+
}),
121+
122+
[typeof(ResourceData.Type)] = new((token, duringEnumCacheCreation) =>
123+
{
124+
if (duringEnumCacheCreation)
125+
{
126+
ResourceData.Type resourcePrefabType = ResourceData.Type.Game;
127+
if (token["prefab"] != null)
128+
{
129+
string prefabId = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(token["prefab"]!.ToString());
130+
if (Enum.TryParse(prefabId, out ResourceData.Type parsedType))
131+
resourcePrefabType = parsedType;
132+
}
133+
PrefabManager.resources.TryAdd((ResourceData.Type)Registry.autoidx, PrefabManager.resources[resourcePrefabType]);
134+
}
135+
})
136+
};
137+
38138
public record GameModeButtonsInformation(int gameModeIndex, UIButtonBase.ButtonAction action, int? buttonIndex, Sprite? sprite);
39139

40140
public static void AddGameModeButton(string id, UIButtonBase.ButtonAction action, Sprite? sprite)
@@ -368,66 +468,22 @@ public static void LoadGameLogicDataPatch(Mod mod, JObject gld, JObject patch)
368468
JObject? token = jtoken.TryCast<JObject>();
369469
if (token != null)
370470
{
371-
if (token["idx"] != null && (int)token["idx"] == -1)
471+
string dataType = Util.GetJTokenName(token, 2);
472+
if (typeMappings.TryGetValue(dataType, out Type? targetType))
372473
{
373-
string id = Util.GetJTokenName(token);
374-
string dataType = Util.GetJTokenName(token, 2);
375-
token["idx"] = Registry.autoidx;
376-
if (typeMappings.TryGetValue(dataType, out Type? targetType))
474+
if (token["idx"] != null && (int)token["idx"] == -1)
377475
{
476+
string id = Util.GetJTokenName(token);
477+
token["idx"] = Registry.autoidx;
378478
MethodInfo? methodInfo = typeof(EnumCache<>).MakeGenericType(targetType).GetMethod("AddMapping");
379479
if (methodInfo != null)
380480
{
381481
methodInfo.Invoke(null, new object[] { id, Registry.autoidx });
382482
methodInfo.Invoke(null, new object[] { id, Registry.autoidx });
383-
if (targetType == typeof(TribeData.Type))
384-
{
385-
Registry.customTribes.Add((TribeData.Type)Registry.autoidx);
386-
token["style"] = Registry.climateAutoidx;
387-
token["climate"] = Registry.climateAutoidx;
388-
Registry.climateAutoidx++;
389-
}
390-
else if (targetType == typeof(UnitData.Type))
391-
{
392-
UnitData.Type unitPrefabType = UnitData.Type.Scout;
393-
if (token["prefab"] != null)
394-
{
395-
TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo;
396-
string prefabId = textInfo.ToTitleCase(token["prefab"].ToString());
397-
if (Enum.TryParse(prefabId, out UnitData.Type parsedType))
398-
{
399-
unitPrefabType = parsedType;
400-
}
401-
}
402-
PrefabManager.units.TryAdd((int)(UnitData.Type)Registry.autoidx, PrefabManager.units[(int)unitPrefabType]);
403-
}
404-
else if (targetType == typeof(ImprovementData.Type))
405-
{
406-
ImprovementData.Type improvementPrefabType = ImprovementData.Type.CustomsHouse;
407-
if (token["prefab"] != null)
408-
{
409-
TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo;
410-
string prefabId = textInfo.ToTitleCase(token["prefab"].ToString());
411-
if (Enum.TryParse(prefabId, out ImprovementData.Type parsedType))
412-
{
413-
improvementPrefabType = parsedType;
414-
}
415-
}
416-
PrefabManager.improvements.TryAdd((ImprovementData.Type)Registry.autoidx, PrefabManager.improvements[improvementPrefabType]);
417-
}
418-
else if (targetType == typeof(ResourceData.Type))
483+
484+
if (typeHandlers.TryGetValue(targetType, out var handler))
419485
{
420-
ResourceData.Type resourcePrefabType = ResourceData.Type.Game;
421-
if (token["prefab"] != null)
422-
{
423-
TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo;
424-
string prefabId = textInfo.ToTitleCase(token["prefab"].ToString());
425-
if (Enum.TryParse(prefabId, out ResourceData.Type parsedType))
426-
{
427-
resourcePrefabType = parsedType;
428-
}
429-
}
430-
PrefabManager.resources.TryAdd((ResourceData.Type)Registry.autoidx, PrefabManager.resources[resourcePrefabType]);
486+
handler(token, true);
431487
}
432488
Plugin.logger.LogInfo("Created mapping for " + targetType.ToString() + " with id " + id + " and index " + Registry.autoidx);
433489
Registry.autoidx++;
@@ -436,40 +492,19 @@ public static void LoadGameLogicDataPatch(Mod mod, JObject gld, JObject patch)
436492
}
437493
}
438494
}
439-
foreach (JToken jtoken in patch.SelectTokens("$.tribeData.*").ToArray())
440-
{
441-
JObject token = jtoken.Cast<JObject>();
442-
443-
if (token["preview"] != null)
444-
{
445-
Visual.PreviewTile[] preview = JsonSerializer.Deserialize<Visual.PreviewTile[]>(token["preview"].ToString())!;
446-
Registry.tribePreviews[Util.GetJTokenName(token)] = preview;
447-
}
448-
}
449-
foreach (JToken jtoken in patch.SelectTokens("$.unitData.*").ToArray())
450-
{
451-
JObject token = jtoken.Cast<JObject>();
452-
if (token["embarksTo"] != null)
453-
{
454-
string unitId = Util.GetJTokenName(token);
455-
string embarkUnitId = token["embarksTo"].ToString();
456-
Main.embarkNames[unitId] = embarkUnitId;
457-
}
458-
}
459-
foreach (JToken jtoken in patch.SelectTokens("$.improvementData.*").ToArray())
495+
foreach (JToken jtoken in patch.SelectTokens("$.*.*").ToArray())
460496
{
461-
JObject token = jtoken.Cast<JObject>();
462-
if (token["attractsResource"] != null)
463-
{
464-
string improvementId = Util.GetJTokenName(token);
465-
string attractsId = token["attractsResource"].ToString();
466-
Main.attractsResourceNames[improvementId] = attractsId;
467-
}
468-
if (token["attractsToTerrain"] != null)
497+
JObject? token = jtoken.TryCast<JObject>();
498+
if (token != null)
469499
{
470-
string improvementId = Util.GetJTokenName(token);
471-
string attractsId = token["attractsToTerrain"].ToString();
472-
Main.attractsTerrainNames[improvementId] = attractsId;
500+
string dataType = Util.GetJTokenName(token, 2);
501+
if (typeMappings.TryGetValue(dataType, out Type? targetType))
502+
{
503+
if (typeHandlers.TryGetValue(targetType, out var handler))
504+
{
505+
handler(token, false);
506+
}
507+
}
473508
}
474509
}
475510
gld.Merge(patch, new() { MergeArrayHandling = MergeArrayHandling.Replace, MergeNullValueHandling = MergeNullValueHandling.Merge });

src/Managers/Visual.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public record SkinInfo(int idx, string id, SkinData? skinData);
3636
public static Dictionary<int, int> basicPopupWidths = new();
3737
private static bool firstTimeOpeningPreview = true;
3838
private static UnitData.Type currentUnitTypeUI = UnitData.Type.None;
39+
private static TribeData.Type attackerTribe = TribeData.Type.None;
3940

4041
#region General
4142

@@ -487,10 +488,36 @@ private static void PlayerInfoIcon_SetData(PlayerInfoIcon __instance, TribeData.
487488
private static void BasicPopup_Update(BasicPopup __instance)
488489
{
489490
int id = __instance.GetInstanceID();
490-
if (Visual.basicPopupWidths.ContainsKey(id))
491+
if (basicPopupWidths.ContainsKey(id))
491492
__instance.rectTransform.SetWidth(basicPopupWidths[id]);
492493
}
493494

495+
[HarmonyPrefix]
496+
[HarmonyPatch(typeof(Unit), nameof(Unit.Attack))]
497+
private static bool Unit_Attack(Unit __instance, WorldCoordinates target, bool moveToTarget, Il2CppSystem.Action onComplete)
498+
{
499+
if (__instance.Owner != null)
500+
{
501+
attackerTribe = __instance.Owner.tribe;
502+
}
503+
return true;
504+
}
505+
506+
[HarmonyPostfix]
507+
[HarmonyPatch(typeof(WeaponGFX), nameof(WeaponGFX.SetSkin))]
508+
private static void WeaponGFX_SetSkin(WeaponGFX __instance, SkinType skinType)
509+
{
510+
if (attackerTribe != TribeData.Type.None)
511+
{
512+
Sprite? sprite = Registry.GetSprite(__instance.defaultSprite.name, Util.GetStyle(attackerTribe, skinType));
513+
if (sprite != null)
514+
{
515+
__instance.spriteRenderer.sprite = sprite;
516+
}
517+
attackerTribe = TribeData.Type.None;
518+
}
519+
}
520+
494521
[HarmonyPostfix]
495522
[HarmonyPatch(typeof(PopupBase), nameof(PopupBase.Hide))]
496523
private static void PopupBase_Hide(PopupBase __instance)

0 commit comments

Comments
 (0)