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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("BeastsOfBurdenEV")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BeastsOfBurdenEV")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("fcb9af9d-f8cd-406f-9405-e10a8d59b395")]
[assembly: AssemblyFileVersion("1.0.5")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.5.0")]
[module: UnverifiableCode]
namespace BeastsOfBurdenEV;
[BepInPlugin("clevel.beasts_of_burdenEV", "BeastsOfBurdenEV", "1.0.5")]
public class BeastsOfBurdenEV : BaseUnityPlugin
{
public enum Beasts
{
lox,
wolf,
boar,
hen,
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_0109: 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_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: 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:
case Beasts.hen:
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;
case Beasts.hen:
___m_commandable = commandHen.Value;
break;
}
}
}
private const string pluginGUID = "clevel.beasts_of_burdenEV";
private const string pluginName = "BeastsOfBurdenEV";
public const string pluginVersion = "1.0.5";
public static ManualLogSource logger;
private readonly Harmony harmony = new Harmony("clevel.beasts_of_burdenEV");
private static ConfigEntry<bool> commandWolf;
private static ConfigEntry<bool> commandBoar;
private static ConfigEntry<bool> commandLox;
private static ConfigEntry<bool> commandHen;
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_014b: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Expected O, but got Unknown
//IL_0188: Unknown result type (might be due to invalid IL or missing references)
//IL_0192: Expected O, but got Unknown
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_01cf: Expected O, but got Unknown
//IL_0202: Unknown result type (might be due to invalid IL or missing references)
//IL_020c: Expected O, but got Unknown
//IL_022d: Unknown result type (might be due to invalid IL or missing references)
//IL_0237: Expected O, but got Unknown
logger = ((BaseUnityPlugin)this).Logger;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading Beasts of Burden EpicValheim addition");
commandWolf = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurdenEV", "commandWolf", true, "Makes Wolf Commandable, normal & EV");
commandBoar = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurdenEV", "commandBoar", true, "Makes Boar Commandable, normal & EV");
commandLox = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurdenEV", "commandLox", true, "Makes Lox Commandable, normal & EV");
commandHen = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurdenEV", "commandHen", true, "Makes Hen Commandable, normal & EV");
attachToWolf = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurdenEV", "attachToWolf", true, "Allow cart to attach to Wolf");
attachToBoar = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurdenEV", "attachToBoar", true, "Allow cart to attach to Boar");
attachToLox = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurdenEV", "attachToLox", true, "Allow cart to attach to Lox");
attachToOtherTamed = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurdenEV", "attachToOtherTamed", true, "Experimental: Allow cart to attach to other types of tamed animals. ");
detachDistancePlayer = ((BaseUnityPlugin)this).Config.Bind<float>("BeastsOfBurdenEV", "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>("BeastsOfBurdenEV", "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>("BeastsOfBurdenEV", "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>("BeastsOfBurdenEV", "followDistanceMediumAnimal", 3f, new ConfigDescription("How close other animals will follow behind the player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
preventTamedFearOfFire = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurdenEV", "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,
"RRRM_LoxEV" => Beasts.lox,
"Wolf" => Beasts.wolf,
"RRRM_WolfEV" => Beasts.wolf,
"Boar" => Beasts.boar,
"RRRM_BoarEV" => Beasts.boar,
"Hen" => Beasts.hen,
"RRRM_HenEV" => Beasts.hen,
_ => Beasts.other,
};
}
logger.LogDebug((object)"Character has invalid m_nview.");
return Beasts.other;
}
public static Vector3 GetCartOffsetVectorForCharacter(Character c)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: 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);
Vector3 position = ((Component)allCharacter).transform.position;
float num2 = Vector3.Distance(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_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: 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>();
}
}