Skip to content

Commit

Permalink
v2.5.3
Browse files Browse the repository at this point in the history
  • Loading branch information
SchuhBaum committed Aug 30, 2024
1 parent 1d96370 commit 57a85e7
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 67 deletions.
7 changes: 5 additions & 2 deletions ReadMe.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## SimplifiedMoveset
###### Version: 2.5.2
###### Version: 2.5.3

This is a mod for Rain World v1.9.

Expand All @@ -11,7 +11,7 @@ https://www.youtube.com/watch?v=Jp6UyUgoWB0

### Installation
0. Update Rain World to version 1.9 if needed.
1. Download the file `SimplifiedMoveset.zip` from [Releases](https://github.com/SchuhBaum/SimplifiedMoveset/releases/tag/v2.5.2).
1. Download the file `SimplifiedMoveset.zip` from [Releases](https://github.com/SchuhBaum/SimplifiedMoveset/releases/tag/v2.5.3).
2. Extract its content in the folder `[Steam]\SteamApps\common\Rain World\RainWorld_Data\StreamingAssets\mods`.
3. Start the game as normal. In the main menu select `Remix` and enable the mod.

Expand All @@ -26,6 +26,9 @@ See the file LICENSE-MIT.

### Changelog
#### (Rain World v1.9)
v2.5.3:
- (beam climb) Beam hopping is more lenient. Every slugcat can beam hop like Rivulet.

v2.5.2:
- Blacklisted slugcat npcs. Otherwise, hunter slugpups might not grab and eat dead creatures.

Expand Down
2 changes: 1 addition & 1 deletion SimplifiedMoveset/modinfo.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "SimplifiedMoveset",
"name": "SimplifiedMoveset",
"version": "2.5.2",
"version": "2.5.3",
"authors": "SchuhBaum",
"description": "Various movement changes. The main idea is to remove or simplify timings, making it easier to perform advanced moves consistently.",
"requirements": [],
Expand Down
2 changes: 1 addition & 1 deletion SimplifiedMoveset/workshopdata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"Title": "SimplifiedMoveset",
"Description": "Various movement changes. The main idea is to remove or simplify timings, making it easier to perform advanced moves consistently.",
"ID": "SimplifiedMoveset",
"Version": "2.5.2",
"Version": "2.5.3",
"TargetGameVersion": "v1.9.15",
"Requirements": "",
"RequirementNames": "",
Expand Down
4 changes: 2 additions & 2 deletions SourceCode/MainMod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@

namespace SimplifiedMoveset;

[BepInPlugin("SimplifiedMoveset", "SimplifiedMoveset", "2.5.2")]
[BepInPlugin("SimplifiedMoveset", "SimplifiedMoveset", "2.5.3")]
public class MainMod : BaseUnityPlugin {
//
// meta data
//

public static readonly string mod_id = "SimplifiedMoveset";
public static readonly string author = "SchuhBaum";
public static readonly string version = "2.5.2";
public static readonly string version = "2.5.3";

//
// options
Expand Down
138 changes: 78 additions & 60 deletions SourceCode/PlayerMod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1859,66 +1859,84 @@ private static void IL_Player_Update(ILContext context) { // Option_BeamClimb //
ILCursor cursor = new(context);

if (cursor.TryGotoNext(instruction => instruction.MatchLdsfld<BodyModeIndex>("Default")) &&
cursor.TryGotoNext(instruction => instruction.MatchLdfld<Player>("poleSkipPenalty"))
) {
// TODO:
// The problem is the timing. Rivulet is more lenient. You can hop
// on beams with one empty tile in between. This looks weird. It
// makes more sense to accept jump inputs for more than one frame.

// ILCursor cursor_temp = new(cursor);

// if (cursor_temp.TryGotoPrev(instr => instr.MatchLdcR4(7.5f)) &&
// cursor_temp.TryGotoNext(MoveType.After, instr => instr.MatchLdcI4(0))) {
// cursor_temp.Emit(OpCodes.Pop);
// cursor_temp.Emit(OpCodes.Ldarg_0);

// cursor_temp.EmitDelegate<Func<Player,bool>>(player => {
// // return player.input[0].x != 0 && (player.room.GetTile(player.bodyChunks[1].pos).horizontalBeam || player.room.GetTile(player.bodyChunks[1].lastPos).horizontalBeam);
// Room.Tile tile = player.room.GetTile(player.bodyChunks[1].pos);
// // if (tile.horizontalBeam) return player.input[0].x != 0;
// if (tile.horizontalBeam) return true;

// // Chunk 0 is bad. The player grabs the beam in that case.
// tile = player.room.GetTile(player.bodyChunks[0].pos);
// // if (tile.horizontalBeam) return player.input[0].x != 0;
// if (tile.horizontalBeam) return true;

// tile = player.room.GetTile(player.bodyChunks[1].lastPos);
// // if (tile.horizontalBeam) return player.input[0].x != 0;
// if (tile.horizontalBeam) return true;
// tile = player.room.GetTile(player.bodyChunks[0].lastPos);
// // if (tile.horizontalBeam) return player.input[0].x != 0;
// if (tile.horizontalBeam) return true;

// // if (tile.horizontalBeam) {
// // return player.input[0].x != 0 && Mathf.Abs(player.room.MiddleOfTile(tile.X, tile.Y).y - player.bodyChunks[1].pos.y+10f) < 20f;
// // }
// return false;
// // return player.input[0].x != 0 && (player.room.GetTile(player.bodyChunks[1].pos).horizontalBeam || player.room.GetTile(player.bodyChunks[1].lastPos).horizontalBeam);
// });
// }

// if (cursor_temp.TryGotoPrev(instr => instr.MatchLdcR4(7.5f))) {
// // This part compares the height of the middle of the body chunk
// // tile and the chunk itself. Anything larger than 10f should
// // result in true.
// // Rivulet gets its own checks later. They are more lenient. In
// // contrast to Rivulet, the chunk tile is the beam tile. We want
// // to know how far the chunk height is exactly from the beam height.
// // In Rivulet's case, the beam tile can be below. There, the check
// // does nothing and is always true.
// cursor_temp.Next.Operand = 15f;
// }

// if (cursor_temp.TryGotoPrev(
// instr => instr.MatchLdarg(0),
// instr => instr.MatchCall<Player>("get_isRivulet")
// )) {
// // Everyone can beam hop like Rivulet. You can hop even when you
// // are one tile above. Maybe that is a bit much.
// cursor_temp.RemoveRange(3);
// }
cursor.TryGotoNext(instruction => instruction.MatchLdfld<Player>("poleSkipPenalty")))
{
if (Option_BeamClimb) {
// The problem is the timing. Rivulet is more lenient. You can hop
// on beams with one empty tile in between. This looks weird. It
// makes more sense to accept jump inputs for more than one frame.
// But that has its problems too. Do the Rivulet hop for now.

ILCursor cursor_temp = new(cursor);

// if (cursor_temp.TryGotoPrev(instr => instr.MatchLdfld<Player.InputPackage>("jmp"))) {
// // The problem is that the timing affects other things. Recovering
// // from jumping up vertical beams for example. You recover and instantly
// // jump up again.
// cursor_temp.Goto(cursor_temp.Index + 3);
// cursor_temp.Emit(OpCodes.Ldarg_0);
// cursor_temp.EmitDelegate<Func<bool,Player,bool>>((pressed_jump,player) => {
// if (pressed_jump) return true;
// for (int index = 1; index <= 5; ++index) {
// if (player.input[index].jmp && !player.input[index+1].jmp) return true;
// }
// return false;
// });
// }

// if (cursor_temp.TryGotoPrev(instr => instr.MatchLdcR4(7.5f)) &&
// cursor_temp.TryGotoNext(MoveType.After, instr => instr.MatchLdcI4(0))) {
// cursor_temp.Emit(OpCodes.Pop);
// cursor_temp.Emit(OpCodes.Ldarg_0);

// cursor_temp.EmitDelegate<Func<Player,bool>>(player => {
// // return player.input[0].x != 0 && (player.room.GetTile(player.bodyChunks[1].pos).horizontalBeam || player.room.GetTile(player.bodyChunks[1].lastPos).horizontalBeam);
// Room.Tile tile = player.room.GetTile(player.bodyChunks[1].pos);
// // if (tile.horizontalBeam) return player.input[0].x != 0;
// if (tile.horizontalBeam) return true;

// // Chunk 0 is bad. The player grabs the beam in that case.
// tile = player.room.GetTile(player.bodyChunks[0].pos);
// // if (tile.horizontalBeam) return player.input[0].x != 0;
// if (tile.horizontalBeam) return true;

// tile = player.room.GetTile(player.bodyChunks[1].lastPos);
// // if (tile.horizontalBeam) return player.input[0].x != 0;
// if (tile.horizontalBeam) return true;
// tile = player.room.GetTile(player.bodyChunks[0].lastPos);
// // if (tile.horizontalBeam) return player.input[0].x != 0;
// if (tile.horizontalBeam) return true;

// // if (tile.horizontalBeam) {
// // return player.input[0].x != 0 && Mathf.Abs(player.room.MiddleOfTile(tile.X, tile.Y).y - player.bodyChunks[1].pos.y+10f) < 20f;
// // }
// return false;
// // return player.input[0].x != 0 && (player.room.GetTile(player.bodyChunks[1].pos).horizontalBeam || player.room.GetTile(player.bodyChunks[1].lastPos).horizontalBeam);
// });
// }

// if (cursor_temp.TryGotoPrev(instr => instr.MatchLdcR4(7.5f))) {
// // This part compares the height of the middle of the body chunk
// // tile and the chunk itself. Anything larger than 10f should
// // result in true.
// // Rivulet gets its own checks later. They are more lenient. In
// // contrast to Rivulet, the chunk tile is the beam tile. We want
// // to know how far the chunk height is exactly from the beam height.
// // In Rivulet's case, the beam tile can be below. There, the check
// // does nothing and is always true.
// cursor_temp.Next.Operand = 15f;
// }

if (cursor_temp.TryGotoPrev(
instr => instr.MatchLdarg(0),
instr => instr.MatchCall<Player>("get_isRivulet")
)) {
// Everyone can beam hop like Rivulet. You can hop even when you
// are one tile above. Maybe that is a bit much. But this is the
// simplest solution.
cursor_temp.RemoveRange(3);
}
}

cursor.Goto(cursor.Index - 2);
if (can_log_il_hooks) {
Expand Down
2 changes: 1 addition & 1 deletion SourceCode/SimplifiedMoveset.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>net48</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>10.0</LangVersion>
<Version>2.5.2</Version>
<Version>2.5.3</Version>
</PropertyGroup>

<ItemGroup>
Expand Down

0 comments on commit 57a85e7

Please sign in to comment.