Skip to content

Commit

Permalink
Fix incompatibility with GungeonCraft due to janky ILHook logic for s…
Browse files Browse the repository at this point in the history
…emiautomatic firing
  • Loading branch information
pcrain committed Dec 21, 2023
1 parent 0f1ff1b commit c391997
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 38 deletions.
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 1.0.1 (2023-12-20)
- Simplify logic for "Auto-fire Semi-Automatic Weapons" hook to fix compatibility issues with GungeonCraft and other mods

## 1.0.0 (2023-12-17)

- Initial Release! :D
18 changes: 9 additions & 9 deletions genproject
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,15 @@ if [ $rebuild -eq 1 ]; then
echo -e "[${GRN}>${BLN}] Importing ${dllname} to EtG plugins directory"
/bin/cp "$dllname" "$plugindir"
#Import the mod to GungeonCraft
echo -e "[${GRN}>${BLN}] Importing ${dllname} to Gungeoncraft project"
gcpath="/home/pretzel/workspace/gungy-cwaffing"
if [ -e "${gcpath}" ]; then
gcpackagepath="${gcpath}/packages/EtG.${namespace}.${projectversion}/lib/net35"
mkdir -p "$gcpackagepath"
/bin/cp "$dllname" "$gcpackagepath"
/bin/cp "$dllname" "${gcpath}/bin/Debug"
fi
#Import the mod to GungeonCraft (disabled for now)
# echo -e "[${GRN}>${BLN}] Importing ${dllname} to Gungeoncraft project"
# gcpath="/home/pretzel/workspace/gungy-cwaffing"
# if [ -e "${gcpath}" ]; then
# gcpackagepath="${gcpath}/packages/EtG.${namespace}.${projectversion}/lib/net35"
# mkdir -p "$gcpackagepath"
# /bin/cp "$dllname" "$gcpackagepath"
# /bin/cp "$dllname" "${gcpath}/bin/Debug"
# fi
fi
#Generate new Thunderstore Package
Expand Down
34 changes: 5 additions & 29 deletions src/DefaultConfigs/QoLConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ private static void InitQoLHooks()
);

// Remove cooldown for semiautomatic weapons
new ILHook(
typeof(PlayerController).GetMethod("HandleGunFiringInternal", BindingFlags.Instance | BindingFlags.NonPublic),
HandleGunFiringInternalIL
new Hook(
typeof(BraveInput).GetMethod("get_ControllerFakeSemiAutoCooldown", BindingFlags.Static | BindingFlags.Public),
typeof(QoLConfig).GetMethod("OverrideSemiAutoCooldown", BindingFlags.Static | BindingFlags.NonPublic)
);

// Change default coop character
Expand Down Expand Up @@ -154,35 +154,11 @@ private static void OnHandleFillbarValueChanged(Action<BraveOptionsMenuItem> ori
AkSoundEngine.PostEvent("Play_UI_menu_select_01", item.gameObject);
}

// ILHook references
// https://github.com/ThadHouse/quicnet/blob/522289d7f3206574d672c936b3129eedf415e735/src/Interop/ApiGenerator.cs#L78
// https://github.com/StrawberryJam2021/StrawberryJam2021/blob/21079f1c2521aa704fc5ddc91f67ff3ebc95c317/Entities/ToggleSwapBlock.cs#L32
private static void HandleGunFiringInternalIL(ILContext il)
{
ILCursor cursor = new ILCursor(il);
// cursor.DumpIL("HandlePlayerPhasingInputIL");

while (cursor.TryGotoNext(MoveType.After, instr => instr.MatchAdd(), instr => instr.MatchStfld<PlayerController>("m_controllerSemiAutoTimer")))
{
/* the next four instructions after this point are as follows
[keep ] IL_0272: ldarg.0
[keep ] IL_0273: ldfld System.Single PlayerController::m_controllerSemiAutoTimer
[replace] IL_0278: call System.Single BraveInput::get_ControllerFakeSemiAutoCooldown()
[keep ] 637 ... ble.un ... MonoMod.Cil.ILLabel
*/
cursor.Index += 2; // skip the next two instructions so we still have m_controllerSemiAutoTimer on the stack
cursor.Remove(); // remove the get_ControllerFakeSemiAutoCooldown() instruction
cursor.Emit(OpCodes.Ldarg_0); // load the player instance as arg0
cursor.Emit(OpCodes.Call, typeof(QoLConfig).GetMethod("OverrideSemiAutoCooldown", BindingFlags.Static | BindingFlags.NonPublic)); // replace with our own custom hook
break; // we only care about the first occurrence of this pattern in the function
}
}

private static float OverrideSemiAutoCooldown(PlayerController pc)
private static float OverrideSemiAutoCooldown(Func<float> orig)
{
if (_Gunfig.Enabled(FINGER_SAVER))
return 0f; // replace the value we're checking against with 0f to completely remove semi-automatic fake cooldown
return BraveInput.ControllerFakeSemiAutoCooldown; // return the original value
return orig(); // return the original value
}

private static PlayerController OnGenerateCoopPlayer(Func<HutongGames.PlayMaker.Actions.ChangeCoopMode, PlayerController> orig, HutongGames.PlayMaker.Actions.ChangeCoopMode coop)
Expand Down

0 comments on commit c391997

Please sign in to comment.