Decompiled source of BetterHowToFish v1.4.0

BepInEx/plugins/FishSlap.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ClassLibrary3")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ClassLibrary3")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("326bffc6-6fe8-4664-bb45-5d208e992e70")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace FishSlap;

[BepInPlugin("com.you.fishslap", "Fish Slap", "1.4.0")]
public class Plugin : BaseUnityPlugin
{
	public static ConfigEntry<float> DoubleChance;

	public static ConfigEntry<float> DestroyChance;

	public static ConfigEntry<float> NoChangeChance;

	public static ConfigEntry<float> WorthMultiplier;

	public static ConfigEntry<bool> EnableText;

	public static ConfigEntry<float> TextSize;

	public static ConfigEntry<float> TextHeight;

	public static ConfigEntry<float> BeerSpeedMulti;

	public static ConfigEntry<float> BeerBuffDuration;

	public static ConfigEntry<float> BottleBuffDuration;

	public static ConfigEntry<float> BottleDoubleChanceMulti;

	public static ConfigEntry<float> BottlePoisonDuration;

	private void Awake()
	{
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Expected O, but got Unknown
		DoubleChance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DoubleChance", 0.3f, "Chance to double value / 翻倍概率");
		DestroyChance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DestroyChance", 0.2f, "Chance to destroy / 消失概率");
		NoChangeChance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "NoChangeChance", 0.5f, "Chance nothing / 不变概率");
		WorthMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "WorthMultiplier", 2f, "Multiplier / 翻倍倍数");
		EnableText = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableText", true, "Show floating text / 显示漂浮文字");
		TextSize = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TextSize", 0.15f, "Floating text size / 漂浮文字大小");
		TextHeight = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TextHeight", 0.5f, "Height above the fish / 文字离鱼的高度");
		BeerSpeedMulti = ((BaseUnityPlugin)this).Config.Bind<float>("Beer", "SpeedMultiplier", 1.5f, "Speed multiplier / 速度倍率");
		BeerBuffDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Beer", "BuffDuration", 30f, "Buff duration / buff 秒数");
		BottleBuffDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Bottle", "BuffDuration", 15f, "Bottle buff duration / 瓶中信 buff 秒数");
		BottleDoubleChanceMulti = ((BaseUnityPlugin)this).Config.Bind<float>("Bottle", "DoubleChanceMulti", 2f, "Double chance multiplier / 翻倍概率倍率");
		BottlePoisonDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Bottle", "PoisonDuration", 10f, "Poison duration / 中毒持续秒数");
		Harmony val = new Harmony("com.you.fishslap");
		val.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"FishSlap loaded! / FishSlap 已加载!");
	}
}
[HarmonyPatch(typeof(Melee), "HitTarget")]
internal class Patch_HitTarget
{
	private static void Postfix(Melee __instance, int side)
	{
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_022a: Unknown result type (might be due to invalid IL or missing references)
		FieldInfo field = typeof(Melee).GetField("_curTarget", BindingFlags.Instance | BindingFlags.NonPublic);
		if (field == null || !(field.GetValue(__instance) is Transform[] array) || side < 0 || side >= array.Length)
		{
			return;
		}
		Transform val = array[side];
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		Item val2 = ItemManager.Get(val);
		if ((Object)(object)val2 == (Object)null || (Object)(object)val2.Fish == (Object)null || (Object)(object)val2.Creature == (Object)null || !val2.Creature.IsDead)
		{
			return;
		}
		float num = Plugin.DoubleChance.Value;
		if (BottleBuffState.IsActive)
		{
			num *= Plugin.BottleDoubleChanceMulti.Value;
		}
		float value = Plugin.DestroyChance.Value;
		float value2 = Plugin.NoChangeChance.Value;
		float num2 = num + value + value2;
		if (num2 <= 0f)
		{
			num2 = 1f;
		}
		num /= num2;
		value /= num2;
		float value3 = Random.value;
		if (value3 < value)
		{
			val2.DestroyItem((byte)0, byte.MaxValue);
			Debug.Log((object)"[FishSlap] Fish destroyed!");
		}
		else
		{
			if (!(value3 < value + num))
			{
				return;
			}
			FieldInfo field2 = typeof(Item).GetField("_worth", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field2 != null)
			{
				int num3 = (int)field2.GetValue(val2);
				int num4 = Mathf.RoundToInt((float)num3 * Plugin.WorthMultiplier.Value);
				field2.SetValue(val2, num4);
				Debug.Log((object)$"[FishSlap] Value doubled: {num3} -> {num4}");
				if (Plugin.EnableText.Value)
				{
					ShowFloatingText(((Component)val2).transform.position + Vector3.up * Plugin.TextHeight.Value, "VALUE DOUBLED!");
				}
			}
		}
	}

	private static void ShowFloatingText(Vector3 pos, string text)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			WorldText worldTextPrefab = GameInfo.WorldTextPrefab;
			if (!((Object)(object)worldTextPrefab == (Object)null))
			{
				WorldText val = Object.Instantiate<WorldText>(worldTextPrefab, pos, Quaternion.identity);
				val.SetText(text, Plugin.TextSize.Value);
				val.FloatAndRemoveAnimation();
			}
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[FishSlap] Floating text failed: " + ex.Message));
		}
	}
}
public static class BeerState
{
	public static bool IsDrinkingBeer;
}
public static class BottleBuffState
{
	public static bool IsActive;
}
[HarmonyPatch(typeof(PlayerEating), "StartEatInput")]
internal class Patch_StartEatInput
{
	private static bool Prefix(PlayerEating __instance, CallbackContext context)
	{
		FieldInfo field = typeof(PlayerEating).GetField("_player", BindingFlags.Instance | BindingFlags.NonPublic);
		if (field == null)
		{
			return true;
		}
		object? value = field.GetValue(__instance);
		Player val = (Player)((value is Player) ? value : null);
		if ((Object)(object)val == (Object)null)
		{
			return true;
		}
		Item heldItem = val.Holding.HeldItem;
		if ((Object)(object)heldItem == (Object)null)
		{
			return true;
		}
		if ((Object)(object)heldItem.Creature != (Object)null)
		{
			BeerState.IsDrinkingBeer = ((Object)heldItem).name.Contains("Beer") || ((Object)heldItem).name.Contains("啤酒");
			return true;
		}
		if (heldItem is Bottle || ((Object)heldItem).name.Contains("Bottle"))
		{
			heldItem.DestroyItem((byte)0, byte.MaxValue);
			BottleBuffRunner bottleBuffRunner = ((Component)val).gameObject.GetComponent<BottleBuffRunner>();
			if ((Object)(object)bottleBuffRunner == (Object)null)
			{
				bottleBuffRunner = ((Component)val).gameObject.AddComponent<BottleBuffRunner>();
			}
			bottleBuffRunner.StartBuff(val);
			Debug.Log((object)"[FishSlap] Bottle used: poison + double-chance buff");
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(PlayerEating), "FinishEating")]
internal class Patch_FinishEating
{
	private static void Postfix(PlayerEating __instance)
	{
		if (!BeerState.IsDrinkingBeer)
		{
			return;
		}
		FieldInfo field = typeof(PlayerEating).GetField("_player", BindingFlags.Instance | BindingFlags.NonPublic);
		if (field == null)
		{
			return;
		}
		object? value = field.GetValue(__instance);
		Player val = (Player)((value is Player) ? value : null);
		if (!((Object)(object)val == (Object)null))
		{
			BeerBuffRunner beerBuffRunner = ((Component)val).gameObject.GetComponent<BeerBuffRunner>();
			if ((Object)(object)beerBuffRunner == (Object)null)
			{
				beerBuffRunner = ((Component)val).gameObject.AddComponent<BeerBuffRunner>();
			}
			beerBuffRunner.StartBuff(val);
			BeerState.IsDrinkingBeer = false;
			Debug.Log((object)"[FishSlap] Beer finished, buff started");
		}
	}
}
public class BeerBuffRunner : MonoBehaviour
{
	private Coroutine _curBuff;

	public void StartBuff(Player player)
	{
		if (_curBuff != null)
		{
			((MonoBehaviour)this).StopCoroutine(_curBuff);
		}
		_curBuff = ((MonoBehaviour)this).StartCoroutine(BuffRoutine(player));
	}

	private IEnumerator BuffRoutine(Player player)
	{
		PlayerMovement movement = player.Movement;
		FieldInfo walkField = typeof(PlayerMovement).GetField("_walkSpeed", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo sprintField = typeof(PlayerMovement).GetField("_sprintSpeed", BindingFlags.Instance | BindingFlags.NonPublic);
		if (walkField == null || sprintField == null)
		{
			Debug.LogWarning((object)"[FishSlap] Buff failed: speed fields not found");
			yield break;
		}
		float origWalk = (float)walkField.GetValue(movement);
		float origSprint = (float)sprintField.GetValue(movement);
		float multi = Plugin.BeerSpeedMulti.Value;
		float duration = Plugin.BeerBuffDuration.Value;
		walkField.SetValue(movement, origWalk * multi);
		sprintField.SetValue(movement, origSprint * multi);
		Debug.Log((object)$"[FishSlap] Beer buff applied: speed x{multi} for {duration}s");
		yield return (object)new WaitForSeconds(duration);
		walkField.SetValue(movement, origWalk);
		sprintField.SetValue(movement, origSprint);
		Debug.Log((object)"[FishSlap] Beer buff expired");
		_curBuff = null;
	}
}
public class BottleBuffRunner : MonoBehaviour
{
	private Coroutine _curBuff;

	public void StartBuff(Player player)
	{
		if (_curBuff != null)
		{
			((MonoBehaviour)this).StopCoroutine(_curBuff);
		}
		_curBuff = ((MonoBehaviour)this).StartCoroutine(BuffRoutine(player));
	}

	private IEnumerator BuffRoutine(Player player)
	{
		player.Vitals.ApplyNewPoison();
		Debug.Log((object)"[FishSlap] Poison applied");
		BottleBuffState.IsActive = true;
		float buffDuration = Plugin.BottleBuffDuration.Value;
		float poisonDuration = Plugin.BottlePoisonDuration.Value;
		Debug.Log((object)$"[FishSlap] Bottle buff applied for {buffDuration}s, poison {poisonDuration}s");
		for (float elapsed = 0f; elapsed < poisonDuration; elapsed += 0.5f)
		{
			player.Vitals.ApplyNewPoison();
			yield return (object)new WaitForSeconds(0.5f);
		}
		try
		{
			FieldInfo poisonField = typeof(PlayerVitals).GetField("_syncedPoison", BindingFlags.Instance | BindingFlags.Public);
			if (poisonField != null)
			{
				object syncVar = poisonField.GetValue(player.Vitals);
				PropertyInfo valueProp = syncVar.GetType().GetProperty("Value");
				if (valueProp != null && valueProp.CanWrite)
				{
					valueProp.SetValue(syncVar, 0);
				}
			}
			Debug.Log((object)"[FishSlap] Poison ended");
		}
		catch (Exception ex)
		{
			Exception e = ex;
			Debug.LogWarning((object)("[FishSlap] Clear poison failed: " + e.Message));
		}
		float remaining = buffDuration - poisonDuration;
		if (remaining > 0f)
		{
			yield return (object)new WaitForSeconds(remaining);
		}
		BottleBuffState.IsActive = false;
		Debug.Log((object)"[FishSlap] Bottle buff expired");
		_curBuff = null;
	}
}