diff --git a/ReadMe.md b/ReadMe.md index dd2112f..430f540 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -1,5 +1,5 @@ ## SimplifiedMoveset -###### Version: 2.4.4 +###### Version: 2.4.5 This is a mod for Rain World v1.9. @@ -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.4.4). +1. Download the file `SimplifiedMoveset.zip` from [Releases](https://github.com/SchuhBaum/SimplifiedMoveset/releases/tag/v2.4.5). 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. @@ -26,7 +26,7 @@ There are two licenses available - MIT and Unlicense. You can choose which one y ### Changelog #### (Rain World v1.9) -v2.4.4: +v2.4.5: - (belly slide) Reduced the duration of the normal belly slide back to vanilla. The overall distance is unintentionally increased otherwise (like +20%). Not sure why since the speed is decreased and the same as the long belly slide. From what I tested the distance is as in vanilla now. I might need to double check later since this seems somewhat odd. - (belly slide) Reduced the speed and increased the duration of the belly slide for Gourmand. This way it matches better with his rocket jump. - (gourmand) Added this option. Enabled by default. Exhaust only when throwing spears. Stun creatures with rocket jumps. Slides, rocket jumps and rolls only stun and deal no damage. @@ -34,6 +34,7 @@ v2.4.4: - (gourmand) Allow rocket jumps to deal damage if you have enough speed (similar to Option_Roll_2). - (tube worm) Restored that wall jumps are priotized over using tube worms. - (wall jump) Restored that inputs are buffered for 6 frames when pressing jump early. +- (beam climb) Added some cases where you can drop down (by holding/pressing down and/or pressing jump). Prevent beam hopping when holding down. Otherwise it might trigger it accidentally. v2.4.0: - (crawl) Forgot to add an option check for the last change. diff --git a/SimplifiedMoveset/modinfo.json b/SimplifiedMoveset/modinfo.json index 666a4d0..0d93105 100644 --- a/SimplifiedMoveset/modinfo.json +++ b/SimplifiedMoveset/modinfo.json @@ -1,7 +1,7 @@ { "id": "SimplifiedMoveset", "name": "SimplifiedMoveset", - "version": "2.4.4", + "version": "2.4.5", "authors": "SchuhBaum", "description": "Various movement changes. The main idea is to remove or simplify timings, making it easier to perform advanced moves consistently.", "requirements": [], diff --git a/SimplifiedMoveset/workshopdata.json b/SimplifiedMoveset/workshopdata.json index 388a2f9..a7dca74 100644 --- a/SimplifiedMoveset/workshopdata.json +++ b/SimplifiedMoveset/workshopdata.json @@ -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.4.4", + "Version": "2.4.5", "TargetGameVersion": "", "Requirements": "", "RequirementNames": "", diff --git a/SourceCode/MainMod.cs b/SourceCode/MainMod.cs index 4f2c7b8..6e27dbf 100644 --- a/SourceCode/MainMod.cs +++ b/SourceCode/MainMod.cs @@ -11,7 +11,7 @@ namespace SimplifiedMoveset; -[BepInPlugin("SimplifiedMoveset", "SimplifiedMoveset", "2.4.4")] +[BepInPlugin("SimplifiedMoveset", "SimplifiedMoveset", "2.4.5")] public class MainMod : BaseUnityPlugin { // // meta data @@ -19,7 +19,7 @@ public class MainMod : BaseUnityPlugin { public static readonly string mod_id = "SimplifiedMoveset"; public static readonly string author = "SchuhBaum"; - public static readonly string version = "2.4.4"; + public static readonly string version = "2.4.5"; // // options diff --git a/SourceCode/PlayerMod.cs b/SourceCode/PlayerMod.cs index 1fa7484..2f6feae 100644 --- a/SourceCode/PlayerMod.cs +++ b/SourceCode/PlayerMod.cs @@ -92,6 +92,10 @@ internal static void On_Config_Changed() { On.Player.MovementUpdate += Player_MovementUpdate; } + if (Option_BeamClimb || Option_BellySlide || Option_Crawl || Option_Roll_1 || Option_TubeWorm) { + IL.Player.Jump += IL_Player_Jump; + } + if (Option_BeamClimb || Option_TubeWorm) { On.Player.Update += Player_Update; } @@ -110,10 +114,6 @@ internal static void On_Config_Changed() { IL.Player.TerrainImpact += IL_Player_TerrainImpact; } - if (Option_BellySlide || Option_Crawl || Option_Roll_1 || Option_TubeWorm) { - IL.Player.Jump += IL_Player_Jump; - } - if (Option_BellySlide || Option_Gourmand || Option_SpearThrow) { On.Player.ThrowObject += Player_ThrowObject; } @@ -667,6 +667,20 @@ public static void UpdateAnimation_GetUpOnBeam(Player player, Player_Attached_Fi // exits // // ----- // + if (player.IsJumpPressed() && player.input[0].y < 1) { + // + // same behavior as in UpdateAnimation_HangFromBeam(); copy&paste; + // + + if (IsTongueRetracting(player)) return; + attached_fields.dont_use_tubeworm_counter = 2; + attached_fields.grab_beam_cooldown_position = body_chunk_0.pos; + + player.animation = AnimationIndex.None; + player.animationFrame = 0; + return; + } + if (room.GetTile(player.bodyChunks[body_chunk_index].pos).horizontalBeam && Math.Abs(player.bodyChunks[body_chunk_index].pos.y - player.upOnHorizontalBeamPos.y) < 25.0) { // this might be helpful when horizontal beams are stacked vertically; // however, this can lead to a bug where you are not able to grab beams after jumping off; @@ -681,10 +695,13 @@ public static void UpdateAnimation_GetUpOnBeam(Player player, Player_Attached_Fi // revert when bumping into something or pressing the opposite direction if (player.input[0].y == -direction) { - player.upOnHorizontalBeamPos -= direction * new Vector2(0.0f, 20f); + // multiply by 2f since you switch the body chunk as well; + player.upOnHorizontalBeamPos -= 2f * direction * new Vector2(0.0f, 20f); attached_fields.get_up_on_beam_direction = -direction; return; - } else if (body_chunk_0.contactPoint.y == direction || body_chunk_1.contactPoint.y == direction) { + } + + if (body_chunk_0.contactPoint.y == direction || body_chunk_1.contactPoint.y == direction) { if (attached_fields.get_up_on_beam_abort_counter > 0) { // revert to the original position should always work // abort if stuck in a loop just in case attached_fields.grab_beam_counter = 15; player.animation = AnimationIndex.None; @@ -693,7 +710,8 @@ public static void UpdateAnimation_GetUpOnBeam(Player player, Player_Attached_Fi attached_fields.get_up_on_beam_abort_counter = 2; } - player.upOnHorizontalBeamPos -= direction * new Vector2(0.0f, 20f); + // multiply by 2f since you switch the body chunk as well; + player.upOnHorizontalBeamPos -= 2f * direction * new Vector2(0.0f, 20f); attached_fields.get_up_on_beam_direction = -direction; return; } @@ -757,20 +775,31 @@ public static void UpdateAnimation_HangFromBeam(Player player, Player_Attached_F return; } + // grab vertical beam if possible; if (SwitchHorizontalToVerticalBeam(player, attached_fields)) { player.animationFrame = 0; - return;// grab vertical beam if possible + return; + } + + if (player.input[0].y == 1 && player.input[1].y == 0) { + PrepareGetUpOnBeamAnimation(player, 1, attached_fields); + player.animationFrame = 0; + return; } if (player.IsJumpPressed()) { // retract tubeworm first // consistent behavior with when standing on beam and pressing jump if (IsTongueRetracting(player)) return; - if (player.input[0].y == 1) { // only drop when pressing jump without holding up + if (player.input[0].y == 1) { + // only drop when pressing jump without holding up; this helps when you transition + // directly to this animation from jumping for example; PrepareGetUpOnBeamAnimation(player, 1, attached_fields); player.animationFrame = 0; return; - } else if (player.input[0].y == -1 && player.IsTileSolid(1, 0, -1)) { + } + + if (player.input[0].y == -1 && player.IsTileSolid(1, 0, -1)) { // this case would lead to jumping + regrabbing beam otherwise // not clean.. player.input[1].jmp = true; @@ -782,10 +811,6 @@ public static void UpdateAnimation_HangFromBeam(Player player, Player_Attached_F player.animation = AnimationIndex.None; player.animationFrame = 0; return; - } else if (player.input[0].y == 1 && player.input[1].y == 0) { - PrepareGetUpOnBeamAnimation(player, 1, attached_fields); - player.animationFrame = 0; - return; } if (room.GetTile(body_chunk_0.pos).horizontalBeam) return; @@ -915,8 +940,24 @@ public static void UpdateAnimation_StandOnBeam(Player player, Player_Attached_Fi body_chunk_1.vel.x -= player.input[0].x * vel_x_gain; } - // move down to HangFromBeam - if (player.input[0].y == -1 && (player.input[1].y == 0 || player.IsJumpPressed())) { + if (player.input[0].y == -1) { + player.canJump = 0; + if (player.IsJumpPressed()) { + // + // same behavior as in UpdateAnimation_HangFromBeam(); copy&paste; + // + + if (IsTongueRetracting(player)) return; + attached_fields.dont_use_tubeworm_counter = 2; + attached_fields.grab_beam_cooldown_position = body_chunk_0.pos; + + player.animation = AnimationIndex.None; + player.animationFrame = 0; + return; + } + + // move down even when just holding down without pressing it; makes sense since + // you can't transition to this animation without beam climbing; PrepareGetUpOnBeamAnimation(player, -1, attached_fields); player.animationFrame = 0; return; @@ -1347,7 +1388,7 @@ private static void IL_Player_GrabVerticalPole(ILContext context) { // Option_Be // LogAllInstructions(context); } - private static void IL_Player_Jump(ILContext context) { // Option_BellySlide // Option_Crawl // Option_Roll_1 // Option_TubeWorm + private static void IL_Player_Jump(ILContext context) { // Option_BeamClimb // Option_BellySlide // Option_Crawl // Option_Roll_1 // Option_TubeWorm // LogAllInstructions(context); ILCursor cursor = new(context); @@ -1375,6 +1416,31 @@ private static void IL_Player_Jump(ILContext context) { // Option_BellySlide // cursor.MarkLabel(label); } + if (cursor.TryGotoNext(instruction => instruction.MatchLdsfld("ClimbOnBeam")) && + cursor.TryGotoNext(instruction => instruction.MatchCall("get_input"))) { + if (can_log_il_hooks) { + Debug.Log(mod_id + ": IL_Player_Jump: Index " + cursor.Index); + } + + if (Option_BeamClimb) { + // + // always fall down when holding down while climbing on vertical beams => ignore + // x-input; + // + + cursor.RemoveRange(4); + cursor.EmitDelegate>(player => { + if (player.input[0].y == -1) return false; + return player.input[0].x != 0; // vanilla case; + }); + } + } else { + if (can_log_il_hooks) { + Debug.Log(mod_id + ": IL_Player_Jump could not be applied."); + } + return; + } + if (cursor.TryGotoNext(instruction => instruction.MatchLdsfld("Roll"))) { if (can_log_il_hooks) { Debug.Log(mod_id + ": IL_Player_Jump: Index " + cursor.Index); // 517 @@ -1648,22 +1714,30 @@ private static void IL_Player_TongueUpdate(ILContext context) { // Option_TubeWo // LogAllInstructions(context); } - private static void IL_Player_Update(ILContext context) { + private static void IL_Player_Update(ILContext context) { // Option_BeamClimb // LogAllInstructions(context); ILCursor cursor = new(context); if (cursor.TryGotoNext(instruction => instruction.MatchLdsfld("Default")) && cursor.TryGotoNext(instruction => instruction.MatchLdfld("poleSkipPenalty"))) { + cursor.Goto(cursor.Index - 2); + if (cursor.Next.OpCode != OpCodes.Bgt) { + if (can_log_il_hooks) { + Debug.Log(mod_id + ": IL_Player_Update could not be applied."); + } + return; + } + + if (can_log_il_hooks) { + Debug.Log(mod_id + ": IL_Player_Update: Index " + cursor.Index); // 1936 + } + // // allow beam hopping even when the player is holding up => makes it no risk // and low reward instead of high risk and low reward; // - Debug.Log(mod_id + ": IL_Player_Update: Index " + cursor.Index); // 1936 - cursor.Goto(cursor.Index - 8); - - // removes the player.input[0].y <= 0 check; - cursor.RemoveRange(7); + cursor.Next.OpCode = OpCodes.Blt; } else { if (can_log_il_hooks) { Debug.Log(mod_id + ": IL_Player_Update could not be applied."); @@ -2257,7 +2331,9 @@ private static void Player_ThrowObject(On.Player.orig_ThrowObject orig, Player p } private static void Player_Update(On.Player.orig_Update orig, Player player, bool eu) { // Option_BeamClimb // Option_TubeWorm + // LogPlayerInformation(player); orig(player, eu); + if (Option_BeamClimb && player.Get_Attached_Fields() is Player_Attached_Fields attached_fields) { if (player.bodyMode == BodyModeIndex.ClimbingOnBeam) { attached_fields.time_since_climbing_on_beam = 0; diff --git a/SourceCode/SimplifiedMoveset.csproj b/SourceCode/SimplifiedMoveset.csproj index 871fea0..5889458 100644 --- a/SourceCode/SimplifiedMoveset.csproj +++ b/SourceCode/SimplifiedMoveset.csproj @@ -4,7 +4,7 @@ net48 enable 10.0 - 2.4.4 + 2.4.5