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;
}
}