Skip to content
This repository was archived by the owner on Nov 29, 2023. It is now read-only.

Commit e5a8f4e

Browse files
committed
[Tangerine] Add a loader for character controller classes
1 parent 450e468 commit e5a8f4e

2 files changed

Lines changed: 60 additions & 0 deletions

File tree

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using HarmonyLib;
2+
using Il2CppInterop.Runtime;
3+
using Il2CppInterop.Runtime.Injection;
4+
using System;
5+
using System.Collections.Generic;
6+
7+
namespace Tangerine.Game
8+
{
9+
public static class TangerineCharacter
10+
{
11+
private static readonly Dictionary<int, Type> _characterDict = new();
12+
13+
internal static void InitializeHarmony(Harmony harmony)
14+
{
15+
harmony.PatchAll(typeof(TangerineCharacter));
16+
}
17+
18+
/// <summary>
19+
/// Adds a controller class by injecting it into the game's runtime
20+
/// </summary>
21+
/// <param name="characterId"><c>n_ID</c> of the character that will use this controller</param>
22+
/// <param name="controllerType"><see langword="typeof"/> the controller class</param>
23+
/// <param name="interfaces">Interfaces the class should implement (e.g. <see cref="ILogicUpdate"/>)</param>
24+
public static void AddController(int characterId, Type controllerType, Type[] interfaces)
25+
{
26+
// Throw an exception if a controller with the same ID is already registered
27+
_characterDict[characterId] = controllerType;
28+
29+
if (!ClassInjector.IsTypeRegisteredInIl2Cpp(controllerType))
30+
{
31+
Plugin.Log.LogWarning($"Registering character controller: {controllerType}");
32+
33+
var options = new RegisterTypeOptions()
34+
{
35+
Interfaces = new Il2CppInterfaceCollection(interfaces),
36+
};
37+
38+
ClassInjector.RegisterTypeInIl2Cpp(controllerType, options);
39+
}
40+
41+
// Example of injecting an enum value. This is not needed as the game can cast the values itself
42+
// EnumInjector.InjectEnumValues<EControlCharacter>(new Dictionary<string, object>() { { "X_DMC", 139 } });
43+
}
44+
45+
[HarmonyPatch(typeof(CharacterControlFactory), nameof(CharacterControlFactory.GetCharacterControlType))]
46+
[HarmonyPrefix]
47+
private static bool CharacterControlTypePrefix(EControlCharacter character, int subID, ref Il2CppSystem.Type __result)
48+
{
49+
if (_characterDict.TryGetValue((int)character, out var type))
50+
{
51+
__result = Il2CppType.From(type);
52+
Plugin.Log.LogWarning($"Loading character controller {__result}");
53+
return false;
54+
}
55+
56+
return true;
57+
}
58+
}
59+
}

Tangerine/Plugin.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public override void Load()
2020
_harmony = new Harmony(MyPluginInfo.PLUGIN_GUID);
2121
TangerineDataManager.InitializeHarmony(_harmony);
2222
TangerineTextDataManager.InitializeHarmony(_harmony);
23+
Game.TangerineCharacter.InitializeHarmony(_harmony);
2324
TangerineLoader.InitializeHarmony(_harmony);
2425
}
2526
}

0 commit comments

Comments
 (0)