using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BeastsOfBurden")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BeastsOfBurden")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("fcb9af9d-f8cd-406f-9405-e10a8d59b395")]
[assembly: AssemblyFileVersion("1.0.4")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.4.0")]
[module: UnverifiableCode]
namespace BeastsOfBurden;
[BepInPlugin("org.bepinex.plugins.beasts_of_burden", "BeastsOfBurden", "1.0.4")]
public class BeastsOfBurden : BaseUnityPlugin
{
public enum Beasts
{
lox,
wolf,
boar,
player,
other
}
[HarmonyPatch(typeof(Vagon), "LateUpdate")]
private class LateUpdate_Vagon_Patch
{
private static void Prefix(ref Vagon __instance, ref ConfigurableJoint ___m_attachJoin, ref Rigidbody ___m_body)
{
if ((Object)(object)___m_attachJoin != (Object)null && (Object)(object)((Joint)___m_attachJoin).connectedBody == (Object)null)
{
__instance.Detach();
}
}
}
[HarmonyPatch(typeof(Vagon), "InUse")]
private class InUse_Vagon_Patch
{
private static bool Prefix(ref bool __result, ref Vagon __instance)
{
if (Object.op_Implicit((Object)(object)__instance.m_container) && __instance.m_container.IsInUse())
{
__result = true;
}
else if (__instance.IsAttached())
{
__result = Object.op_Implicit((Object)(object)((Component)((Joint)__instance.m_attachJoin).connectedBody).gameObject.GetComponent<Player>());
}
else
{
__result = false;
}
return false;
}
}
[HarmonyPatch(typeof(Vagon), "FixedUpdate")]
private class Vagon_FixedUpdate_Patch
{
private static bool Prefix(Vagon __instance)
{
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
if (!__instance.m_nview.IsValid())
{
logger.LogDebug((object)"m_nview invalid");
return false;
}
__instance.UpdateAudio(Time.fixedDeltaTime);
if (__instance.m_nview.IsOwner())
{
if (Object.op_Implicit((Object)(object)__instance.m_useRequester))
{
if (__instance.IsAttached())
{
__instance.Detach();
}
else
{
Character val = FindClosestAttachableAnimal(__instance);
if ((Object)(object)val != (Object)null)
{
AttachCartTo(val, __instance);
}
else if (__instance.CanAttach(((Component)__instance.m_useRequester).gameObject))
{
AttachCartTo((Character)(object)__instance.m_useRequester, __instance);
}
else
{
((Character)__instance.m_useRequester).Message((MessageType)2, "Not in the right position", 0, (Sprite)null);
}
}
__instance.m_useRequester = null;
}
if (__instance.IsAttached())
{
__instance.m_detachDistance = GetCartDetachDistance(AttachedCharacter(__instance));
if (!__instance.CanAttach(((Component)((Joint)__instance.m_attachJoin).connectedBody).gameObject))
{
__instance.Detach();
logger.LogDebug((object)"Cart no longer attachable.");
}
}
}
else if (__instance.IsAttached())
{
__instance.Detach();
}
return false;
}
}
[HarmonyPatch(typeof(BaseAI), "UpdateAI")]
private class BaseAI_UpdateAI_patch
{
private static bool Prefix(float dt, ref BaseAI __instance)
{
if (__instance.m_character.IsTamed() && preventTamedFearOfFire.Value)
{
__instance.m_afraidOfFire = false;
}
return true;
}
}
[HarmonyPatch(typeof(BaseAI), "Follow")]
private class Tamed_Follow_patch
{
private static bool Prefix(GameObject go, float dt, ref BaseAI __instance)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
if (!__instance.m_character.IsTamed())
{
return true;
}
BaseAI obj = __instance;
if ((Object)(object)((MonsterAI)((obj is MonsterAI) ? obj : null)).GetFollowTarget().GetComponent<Player>() == (Object)null)
{
return true;
}
float num = Vector3.Distance(go.transform.position, ((Component)__instance).transform.position);
float value;
switch (ParseCharacterType(__instance.m_character))
{
case Beasts.lox:
value = followDistanceLox.Value;
break;
case Beasts.wolf:
case Beasts.boar:
value = followDistanceMediumAnimal.Value;
break;
default:
return true;
}
bool flag = num > value * 3f;
if (num < value)
{
__instance.StopMoving();
}
else
{
__instance.MoveTo(dt, go.transform.position, 0f, flag);
}
return false;
}
}
[HarmonyPatch(typeof(Tameable), "Interact")]
private class Command_Patch
{
private static void Prefix(ref bool ___m_commandable, ref Character ___m_character)
{
switch (ParseCharacterType(___m_character))
{
case Beasts.lox:
___m_commandable = commandLox.Value;
break;
case Beasts.wolf:
___m_commandable = commandWolf.Value;
break;
case Beasts.boar:
___m_commandable = commandBoar.Value;
break;
}
}
}
private const string pluginGUID = "org.bepinex.plugins.beasts_of_burden";
private const string pluginName = "BeastsOfBurden";
public const string pluginVersion = "1.0.4";
public static ManualLogSource logger;
private readonly Harmony harmony = new Harmony("org.bepinex.plugins.beasts_of_burden");
private static ConfigEntry<bool> commandWolf;
private static ConfigEntry<bool> commandBoar;
private static ConfigEntry<bool> commandLox;
private static ConfigEntry<bool> attachToWolf;
private static ConfigEntry<bool> attachToBoar;
private static ConfigEntry<bool> attachToLox;
private static ConfigEntry<bool> attachToOtherTamed;
private static ConfigEntry<float> detachDistanceFactor;
private static ConfigEntry<float> detachDistancePlayer;
private static ConfigEntry<float> followDistanceLox;
private static ConfigEntry<float> followDistanceMediumAnimal;
private static ConfigEntry<bool> preventTamedFearOfFire;
private void Awake()
{
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Expected O, but got Unknown
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Expected O, but got Unknown
//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
//IL_01ad: Expected O, but got Unknown
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_01ea: Expected O, but got Unknown
//IL_020b: Unknown result type (might be due to invalid IL or missing references)
//IL_0215: Expected O, but got Unknown
logger = ((BaseUnityPlugin)this).Logger;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading Beasts of Burden ");
commandWolf = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "commandWolf", true, "Makes Wolf Commandable (as it is in the normal game)");
commandBoar = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "commandBoar", true, "Makes Boar Commandable");
commandLox = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "commandLox", true, "Makes Lox Commandable");
attachToWolf = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "attachToWolf", true, "Allow cart to attach to Wolf");
attachToBoar = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "attachToBoar", true, "Allow cart to attach to Boar");
attachToLox = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "attachToLox", true, "Allow cart to attach to Lox");
attachToOtherTamed = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "attachToOtherTamed", true, "Experimental: Allow cart to attach to other types of tamed animals. ");
detachDistancePlayer = ((BaseUnityPlugin)this).Config.Bind<float>("BeastsOfBurden", "detachDistancePlayer", 2f, new ConfigDescription("How far the player has to be from the cart.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
detachDistanceFactor = ((BaseUnityPlugin)this).Config.Bind<float>("BeastsOfBurden", "detachDistanceFactor", 3.5f, new ConfigDescription("How far something has to be from the cart to use it a multiple of their radius", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
followDistanceLox = ((BaseUnityPlugin)this).Config.Bind<float>("BeastsOfBurden", "followDistanceLox", 8f, new ConfigDescription("How close the lox will follow behind the player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
followDistanceMediumAnimal = ((BaseUnityPlugin)this).Config.Bind<float>("BeastsOfBurden", "followDistanceMediumAnimal", 3f, new ConfigDescription("How close medium animals (wolf and boar) will follow behind the player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
preventTamedFearOfFire = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "preventTamedFearOfFire", false, new ConfigDescription("Prevent tamed animals from being afraid of fire.", (AcceptableValueBase)null, Array.Empty<object>()));
harmony.PatchAll();
}
private void OnDestroy()
{
harmony.UnpatchSelf();
}
public static Beasts ParseCharacterType(Character c)
{
if (c.IsPlayer())
{
return Beasts.player;
}
if (c.m_nview.IsValid())
{
return ((Object)ZNetScene.instance.GetPrefab(c.m_nview.GetZDO().GetPrefab())).name switch
{
"Lox" => Beasts.lox,
"Wolf" => Beasts.wolf,
"Boar" => Beasts.boar,
_ => Beasts.other,
};
}
logger.LogDebug((object)"Character has invalid m_nview.");
return Beasts.other;
}
public static Vector3 GetCartOffsetVectorForCharacter(Character c)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
if (Object.op_Implicit((Object)(object)c))
{
return new Vector3(0f, 0.8f, 0f - c.GetRadius());
}
return new Vector3(0f, 0.8f, 0f);
}
public static bool IsAttachableCharacter(Character c)
{
return ParseCharacterType(c) switch
{
Beasts.lox => attachToLox.Value,
Beasts.wolf => attachToWolf.Value,
Beasts.boar => attachToBoar.Value,
Beasts.player => true,
_ => attachToOtherTamed.Value,
};
}
public static float GetCartDetachDistance(Character c)
{
if (Object.op_Implicit((Object)(object)c))
{
if (c.IsPlayer())
{
return detachDistancePlayer.Value;
}
return c.GetRadius() * detachDistanceFactor.Value;
}
logger.LogError((object)"Character pass was null");
return 0f;
}
private static Character FindClosestAttachableAnimal(Vagon cart)
{
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)cart))
{
logger.LogError((object)"Cart pointer is null");
return null;
}
Transform attachPoint = cart.m_attachPoint;
Character val = null;
float num = float.MaxValue;
if (!Object.op_Implicit((Object)(object)cart.m_attachPoint))
{
logger.LogError((object)"cart.m_attachPoint is null.");
return null;
}
foreach (Character allCharacter in Character.GetAllCharacters())
{
if (Object.op_Implicit((Object)(object)allCharacter))
{
if (!allCharacter.IsPlayer() && allCharacter.IsTamed() && IsAttachableCharacter(allCharacter))
{
Vector3 cartOffsetVectorForCharacter = GetCartOffsetVectorForCharacter(allCharacter);
float num2 = Vector3.Distance(((Component)allCharacter).transform.position + cartOffsetVectorForCharacter, attachPoint.position);
float cartDetachDistance = GetCartDetachDistance(allCharacter);
if (num2 < cartDetachDistance && num2 < num)
{
val = allCharacter;
num = num2;
}
}
}
else
{
logger.LogWarning((object)"null character returned by Character.GetAllCharacter() in method FindClosestTamedAnimal");
}
}
if ((Object)(object)val != (Object)null)
{
logger.LogDebug((object)$"Closest animal is {val.m_name} at a distance of {num}");
}
return val;
}
private static Character AttachedCharacter(Vagon cart)
{
if (Object.op_Implicit((Object)(object)cart) && cart.IsAttached())
{
return ((Component)((Joint)cart.m_attachJoin).connectedBody).gameObject.GetComponent<Character>();
}
return null;
}
private static void LogCartContents(Vagon cart)
{
Container container = cart.m_container;
logger.LogDebug((object)"Cart contents:");
foreach (ItemData allItem in container.GetInventory().GetAllItems())
{
logger.LogDebug((object)("\t * " + allItem.m_shared.m_name));
}
}
private static void AttachCartTo(Character attachTarget, Vagon cart)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
cart.m_attachOffset = GetCartOffsetVectorForCharacter(attachTarget);
cart.m_attachJoin = ((Component)cart).gameObject.AddComponent<ConfigurableJoint>();
((Joint)cart.m_attachJoin).autoConfigureConnectedAnchor = false;
((Joint)cart.m_attachJoin).anchor = cart.m_attachPoint.localPosition;
((Joint)cart.m_attachJoin).connectedAnchor = cart.m_attachOffset;
((Joint)cart.m_attachJoin).breakForce = cart.m_breakForce;
cart.m_attachJoin.xMotion = (ConfigurableJointMotion)1;
cart.m_attachJoin.yMotion = (ConfigurableJointMotion)1;
cart.m_attachJoin.zMotion = (ConfigurableJointMotion)1;
SoftJointLimit linearLimit = default(SoftJointLimit);
((SoftJointLimit)(ref linearLimit)).limit = 0.001f;
cart.m_attachJoin.linearLimit = linearLimit;
SoftJointLimitSpring linearLimitSpring = default(SoftJointLimitSpring);
((SoftJointLimitSpring)(ref linearLimitSpring)).spring = cart.m_spring;
((SoftJointLimitSpring)(ref linearLimitSpring)).damper = cart.m_springDamping;
cart.m_attachJoin.linearLimitSpring = linearLimitSpring;
cart.m_attachJoin.zMotion = (ConfigurableJointMotion)0;
((Joint)cart.m_attachJoin).connectedBody = ((Component)attachTarget).gameObject.GetComponent<Rigidbody>();
}
}