Skip to content

Commit

Permalink
Mod compatibility V3
Browse files Browse the repository at this point in the history
  • Loading branch information
SabreML committed Feb 22, 2023
1 parent 48484c6 commit d43cc0f
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 58 deletions.
91 changes: 34 additions & 57 deletions SingleplayerCoopEmotes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,27 @@

namespace SingleplayerCoopEmotes
{
[BepInPlugin("sabreml.singleplayercoopemotes", "SingleplayerCoopEmotes", "1.1.4")]
[BepInPlugin("sabreml.singleplayercoopemotes", "SingleplayerCoopEmotes", "1.1.5")]
public class SingleplayerCoopEmotes : BaseUnityPlugin
{
public void OnEnable()
{
On.RainWorld.OnModsInit += Init;
}

private static void Init(On.RainWorld.orig_OnModsInit orig, RainWorld self)
private void Init(On.RainWorld.orig_OnModsInit orig, RainWorld self)
{
orig(self);
if (self.dlcVersion < 1)
{
Debug.Log("(SPCoopEmotes) Error: DLC not detected!");
Logger.LogError("DLC not detected!");
return;
}
if (ModManager.JollyCoop)
{
Debug.Log("(SPCoopEmotes) Error: Jolly Co-op is enabled!");
Logger.LogError("Jolly Co-op is enabled!");
return;
}

Expand All @@ -39,21 +41,21 @@ private static void Init(On.RainWorld.orig_OnModsInit orig, RainWorld self)
// Regular hooks.
On.Player.JollyUpdate += JollyUpdateHK;
On.Player.JollyPointUpdate += JollyPointUpdateHK;
On.Player.GraphicsModuleUpdated += GraphicsModuleUpdatedHK;
On.PlayerGraphics.PlayerBlink += PlayerBlinkHK;

// IL hook to remove all `ModManager.CoopAvailable` checks.
IL.Player.checkInput += checkInputHK_IL;
// IL hooks to remove all `ModManager.CoopAvailable` checks.
IL.Player.checkInput += RemoveCoopAvailableChecks;
IL.Player.GraphicsModuleUpdated += RemoveCoopAvailableChecks;

// Manual hook to override the `Player.RevealMap` property getter.
new Hook(
// And a manual one for the `Player.RevealMap` property getter.
new ILHook(
typeof(Player).GetProperty("RevealMap", BindingFlags.Public | BindingFlags.Instance).GetGetMethod(),
typeof(SingleplayerCoopEmotes).GetMethod(nameof(get_RevealMapHK), BindingFlags.NonPublic | BindingFlags.Static)
new ILContext.Manipulator(RemoveCoopAvailableChecks)
);
}


private static void JollyUpdateHK(On.Player.orig_JollyUpdate orig, Player self, bool eu)
private void JollyUpdateHK(On.Player.orig_JollyUpdate orig, Player self, bool eu)
{
// If this is hooked then the checks above must have passed, so we don't need to worry about it trying to emote twice.
orig(self, eu);
Expand Down Expand Up @@ -91,7 +93,7 @@ private static void JollyUpdateHK(On.Player.orig_JollyUpdate orig, Player self,
// (Technically, making them face towards the hand rendered behind their body.)
//
// Added by request :)
private static void JollyPointUpdateHK(On.Player.orig_JollyPointUpdate orig, Player self)
private void JollyPointUpdateHK(On.Player.orig_JollyPointUpdate orig, Player self)
{
orig(self);
if (self.jollyButtonDown && self.PointDir() == Vector2.zero)
Expand All @@ -101,72 +103,47 @@ private static void JollyPointUpdateHK(On.Player.orig_JollyPointUpdate orig, Pla
}


// When Jolly Co-op is active and the jolly button is held, the `GraphicsModuleUpdated()` method makes held spears
// point in the direction indicated by the player.
private static void GraphicsModuleUpdatedHK(On.Player.orig_GraphicsModuleUpdated orig, Player self, bool actuallyViewed, bool eu)
// Called by `PlayerGraphics.Update()` when the player has fully curled up to sleep.
//
// This override is the same as the original except without the Spearmaster check, as it made them inconsistent with
// the other slugcats, and it didn't seem like it was actually used for anything.
private void PlayerBlinkHK(On.PlayerGraphics.orig_PlayerBlink orig, PlayerGraphics self)
{
orig(self, actuallyViewed, eu);

// Recreation of the checks that need to pass in the base method to point a spear, but with the `ModManager.CoopAvailable` check removed.
for (int i = 0; i < 2; i++)
if (UnityEngine.Random.value < 0.033333335f)
{
if (self.grasps[i] == null || !actuallyViewed || !self.jollyButtonDown || self.handPointing != i)
{
return;
}
if (!(self.grasps[i].grabbed is Spear) || self.bodyMode == Player.BodyModeIndex.Crawl || self.animation == Player.AnimationIndex.ClimbOnBeam)
{
return;
}
Spear playerSpear = self.grasps[i].grabbed as Spear;

playerSpear.setRotation = self.PointDir();
playerSpear.rotationSpeed = 0f;
self.blink = Math.Max(2, self.blink);
}
if (self.player.sleepCurlUp == 1f)
{
self.blink = Math.Max(2, self.blink);
}
}


// When Jolly Co-op is active and the jolly button is held, the `checkInput()` method skips opening the map
// and sets the player's movement input as the pointing direction.
private static void checkInputHK_IL(ILContext il)
// This is used to go to each `ModManager.CoopAvailable` check in the method and set its `brfalse` target to the next instruction.
// (This has the same result as just removing the check, but for some reason I can't get that to work.)
private void RemoveCoopAvailableChecks(ILContext il)
{
ILCursor cursor = new ILCursor(il);
bool editSuccessful = false;

// Go to each `ModManager.CoopAvailable` check, and set its label target to the next instruction.
//
// (This results in the same behaviour as just removing the check, but after multiple days of trying I couldn't get that to work.)
ILLabel label = null;
while (cursor.TryGotoNext(MoveType.After,
i => i.MatchLdsfld<ModManager>("CoopAvailable"),
i => i.MatchBrfalse(out label)
i => i.MatchBrfalse(out label) // Assign the `ILLabel` from this instruction to the `label` variable.
))
{
// Set `label`'s target to `cursor.Next`.
cursor.MarkLabel(label);
editSuccessful = true;
}
}


// Called by `PlayerGraphics.Update()` when the player has fully curled up to sleep.
//
// This override is the same as the original except without the Spearmaster check, as it made them inconsistent with
// the other slugcats, and it didn't seem like it was actually used for anything.
private static void PlayerBlinkHK(On.PlayerGraphics.orig_PlayerBlink orig, PlayerGraphics self)
{
if (UnityEngine.Random.value < 0.033333335f)
{
self.blink = Math.Max(2, self.blink);
}
if (self.player.sleepCurlUp == 1f)
// If it wasn't able to find and edit at least one `CoopAvailable` check, then somthing went wrong.
if (!editSuccessful)
{
self.blink = Math.Max(2, self.blink);
Debug.Log("(SPCoopEmotes) Error: IL edit failed!");
Logger.LogError("IL edit failed!");
}
}


// Same as the original, except without a `ModManager.CoopAvailable` check.
private static bool get_RevealMapHK(Func<Player, bool> orig, Player self)
{
return !self.jollyButtonDown && self.input[0].mp && !self.inVoidSea;
}
}
}
1 change: 1 addition & 0 deletions SingleplayerCoopEmotes.sln
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{ED14B559-DB0C-4B19-9A63-1F374E0DFD2A}"
ProjectSection(SolutionItems) = preProject
SingleplayerCoopEmotes\modinfo.json = SingleplayerCoopEmotes\modinfo.json
README.md = README.md
EndProjectSection
EndProject
Global
Expand Down
2 changes: 1 addition & 1 deletion SingleplayerCoopEmotes/modinfo.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "sabreml.singleplayercoopemotes",
"name": "Singleplayer Co-op Emotes",
"version": "1.1.4",
"version": "1.1.5",
"target_game_version": "v1.9.05",
"authors": "SabreML",
"description": "Makes the Jolly Co-op emotes work in singleplayer!"
Expand Down

0 comments on commit d43cc0f

Please sign in to comment.