Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Rideable Boars v1.0.4
BepInEx/plugins/RideableBoars/RideableBoars.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Splatform; using UnityEngine; using UnityEngine.UI; using Valheim.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.4.0")] namespace BoarRiding; [BepInPlugin("xneliox.rideableboars", "Rideable Boars", "1.0.4")] public sealed class BoarRidingPlugin : BaseUnityPlugin { public const string PluginGuid = "xneliox.rideableboars"; public const string PluginName = "Rideable Boars"; public const string PluginVersion = "1.0.4"; internal static bool HeadlessServer; internal const string ItemPrefabName = "BoarSaddle"; internal static BoarRidingPlugin Instance; internal static GameObject SaddleItemPrefab; internal static Recipe SaddleRecipe; internal static AssetBundle SaddleAssetBundle; internal static readonly GameObject[] CustomSaddleVisuals = (GameObject[])(object)new GameObject[3]; private static readonly HashSet<int> WildBarebackRides = new HashSet<int>(); internal ConfigEntry<float> OneStarSpeed; internal ConfigEntry<float> TwoStarSpeed; internal ConfigEntry<float> SaddleX; internal ConfigEntry<float> SaddleY; internal ConfigEntry<float> SaddleZ; internal ConfigEntry<float> SaddleScale; internal ConfigEntry<float> RiderX; internal ConfigEntry<float> RiderY; internal ConfigEntry<float> RiderZ; internal ConfigEntry<float> RiderForwardCorrection; internal ConfigEntry<float> RiderExtraForwardOffset; internal ConfigEntry<float> NormalBoarSaddleYOffset; internal ConfigEntry<float> NormalBoarSaddleScale; internal ConfigEntry<float> CustomSaddleSizeMultiplier; internal ConfigEntry<float> CustomSaddleZ; internal ConfigEntry<float> CustomSaddleZTwoStars; internal ConfigEntry<float> CustomSaddleYNoStars; internal ConfigEntry<float> CustomSaddleYOneStar; internal ConfigEntry<float> CustomSaddleYTwoStars; internal ConfigEntry<float> CustomSaddlePitchOneStar; internal ConfigEntry<bool> AllowMountedPortalTravel; internal ConfigEntry<bool> MovementKeySteering; internal ConfigEntry<float> MountedCameraShakeMultiplier; internal ConfigEntry<KeyboardShortcut> CommandWheelShortcut; internal ConfigEntry<KeyboardShortcut> MountShortcut; internal ConfigEntry<KeyboardShortcut> DismountShortcut; internal ConfigEntry<KeyboardShortcut> BarebackShortcut; internal ConfigEntry<KeyboardShortcut> RemoveSaddleShortcut; internal ConfigEntry<float> RecallRange; internal ConfigEntry<float> FollowRange; internal ConfigEntry<float> RidingSkillStaminaRegenPerLevel; internal ConfigEntry<bool> BoarLevelSystemEnabled; internal ConfigEntry<int> BoarMaximumLevel; internal ConfigEntry<float> BoarHealthPerLevel; internal ConfigEntry<float> OneStarBoarHealthPerLevel; internal ConfigEntry<float> TwoStarBoarHealthPerLevel; internal ConfigEntry<float> BoarHealthIncreaseEveryFiveLevels; internal ConfigEntry<float> WildBoarNextLevelChance; internal ConfigEntry<float> BoarBaseExperience; internal ConfigEntry<float> BoarExperienceGrowth; internal ConfigEntry<float> BoarRidingDistanceExperience; internal ConfigEntry<float> BoarRidingTimeExperience; internal ConfigEntry<float> BoarCommandExperience; internal ConfigEntry<float> BoarCombatExperienceMultiplier; internal ConfigEntry<float> BoarKillExperience; internal ConfigEntry<float> BoarSurvivalExperienceMultiplier; internal ConfigEntry<float> BoarExperienceRate; internal ConfigEntry<float> BoarCatchUpMultiplier; internal ConfigEntry<float> FavouriteHealthRegeneration; internal ConfigEntry<bool> FavouriteRegenerationInCombat; internal ConfigEntry<bool> ShowBoarLevel; internal ConfigEntry<bool> ShowLevelUpEffect; private ZDOID _lastRiddenBoar = ZDOID.None; private ZDOID _lastRiddenAnimal = ZDOID.None; private ZDOID _favouritePinAnimal = ZDOID.None; private string _favouriteAnimalName = string.Empty; private bool _favouriteAnimalIsBoar; private bool _favouriteAnimalDead; private Vector3 _favouriteLastKnownPosition; private bool _hasFavouriteLastKnownPosition; private PinData _favouriteAnimalPin; private Minimap _favouritePinMap; private Sprite _favouriteBoarIcon; private float _nextFavouritePinUpdate; private float _nextFavouriteHeal; private float _nextFavouritePositionSave; private string _favouritePreferenceKey; private string _favouriteFallbackPreferenceKey; private bool _favouriteServerStateSynchronized; private long _favouriteSavedAtUtcTicks; private long _favouriteWorldUid; private bool _favouritePinMismatchReported; private ZRoutedRpc _registeredKickRpc; internal BoarCommandRadialConfig _commandRadial; private bool _commandWheelOpenRequested; private bool _commandAllTamedBoars; private ZDOID _progressionRiddenBoar = ZDOID.None; private Vector3 _progressionLastPosition; private float _progressionDistance; private float _progressionRideTime; private readonly Dictionary<ZDOID, float> _nextCommandExperience = new Dictionary<ZDOID, float>(); private static readonly FieldRef<Hud, RadialBase> RadialMenu = AccessTools.FieldRefAccess<Hud, RadialBase>("m_radialMenu"); private Harmony _harmony; private const string KickRiderRpc = "RideableBoars_KickRider"; private static readonly int FavouriteOwnerKey = StringExtensionMethods.GetStableHashCode("RideableBoars_FavouriteOwner"); private static readonly int FavouriteMountStateKey = StringExtensionMethods.GetStableHashCode("RideableBoars_FavouriteMountState"); internal static readonly int BoarLevelKey = StringExtensionMethods.GetStableHashCode("RideableBoars_Level"); internal static readonly int BoarExperienceKey = StringExtensionMethods.GetStableHashCode("RideableBoars_Experience"); internal static readonly int BoarBaseHealthKey = StringExtensionMethods.GetStableHashCode("RideableBoars_BaseHealth"); internal static void RegisterLocalization() { Localization instance = Localization.instance; if (instance != null) { RegisterLocalization(instance, instance.GetSelectedLanguage()); } } internal static void RegisterLocalization(Localization localization, string language) { if (localization != null) { bool flag = string.Equals(language, "Russian", StringComparison.OrdinalIgnoreCase) || string.Equals(language, "Русский", StringComparison.OrdinalIgnoreCase); bool flag2 = string.Equals(language, "German", StringComparison.OrdinalIgnoreCase) || string.Equals(language, "Deutsch", StringComparison.OrdinalIgnoreCase); AddLocalizedWord(localization, "boarriding_saddle_name", flag ? "Седло для кабана" : (flag2 ? "Wildschweinsattel" : "Boar Saddle")); AddLocalizedWord(localization, "boarriding_saddle_description", flag ? "Прочное седло для верховой езды на приручённых кабанах." : (flag2 ? "Ein robuster Sattel zum Reiten gezähmter Wildschweine." : "A sturdy saddle for riding tamed boars.")); AddLocalizedWord(localization, "boarriding_ride_bareback", flag ? "Ехать без седла" : (flag2 ? "Ohne Sattel reiten" : "Ride bareback")); AddLocalizedWord(localization, "boarriding_command_wheel", flag ? "Команды кабану" : (flag2 ? "Wildschweinbefehle" : "Boar Commands")); AddLocalizedWord(localization, "boarriding_follow", flag ? "Следовать" : (flag2 ? "Folgen" : "Follow")); AddLocalizedWord(localization, "boarriding_wait", flag ? "Ждать" : (flag2 ? "Warten" : "Wait")); AddLocalizedWord(localization, "boarriding_recall", flag ? "Позвать" : (flag2 ? "Rückruf" : "Recall")); AddLocalizedWord(localization, "boarriding_recalled", flag ? "Кабан был отозван." : (flag2 ? "Das Wildschwein wurde zurückgerufen." : "The boar was recalled.")); AddLocalizedWord(localization, "boarriding_roam", flag ? "Свободно двигаться" : (flag2 ? "Freies Bewegen" : "Roam freely")); AddLocalizedWord(localization, "boarriding_roaming", flag ? "Кабан снова свободно двигается" : (flag2 ? "Das Wildschwein bewegt sich wieder frei" : "The boar is roaming freely again")); AddLocalizedWord(localization, "boarriding_follow_too_far", flag ? "Кабан слишком далеко, чтобы следовать" : (flag2 ? "Das Wildschwein ist zu weit entfernt, um dir zu folgen" : "The boar is too far away to follow")); AddLocalizedWord(localization, "boarriding_target_favourite", flag ? "Только избранный кабан" : (flag2 ? "Nur Lieblingswildschwein" : "Favourite boar only")); AddLocalizedWord(localization, "boarriding_target_all", flag ? "Все приручённые кабаны" : (flag2 ? "Alle gezähmten Wildschweine" : "All tamed boars")); AddLocalizedWord(localization, "boarriding_scope_favourite", flag ? "Команды: избранный кабан" : (flag2 ? "Befehle gelten jetzt nur für das Lieblingswildschwein" : "Commands now target the favourite boar only")); AddLocalizedWord(localization, "boarriding_scope_all", flag ? "Команды: все приручённые кабаны" : (flag2 ? "Befehle gelten jetzt für alle geladenen gezähmten Wildschweine" : "Commands now target all loaded tamed boars")); AddLocalizedWord(localization, "boarriding_no_loaded_boars", flag ? "Нет загруженных приручённых кабанов" : (flag2 ? "Keine geladenen gezähmten Wildschweine gefunden" : "No loaded tamed boars found")); AddLocalizedWord(localization, "boarriding_no_boar", flag ? "Нет доступного приручённого кабана." : (flag2 ? "Kein verfügbares gezähmtes Wildschwein." : "No available tamed boar.")); AddLocalizedWord(localization, "boarriding_out_of_range", flag ? "Кабан слишком далеко." : (flag2 ? "Das Wildschwein ist zu weit entfernt." : "The boar is too far away.")); AddLocalizedWord(localization, "boarriding_waiting", flag ? "Кабан ждёт." : (flag2 ? "Das Wildschwein wartet." : "The boar is waiting.")); AddLocalizedWord(localization, "boarriding_following", flag ? "Кабан следует за вами." : (flag2 ? "Das Wildschwein folgt dir." : "The boar is following you.")); AddLocalizedWord(localization, "boarriding_favourite_boar", flag ? "Любимый кабан" : (flag2 ? "Lieblingswildschwein" : "Favourite Boar")); AddLocalizedWord(localization, "boarriding_favourite_mount", flag ? "Любимое ездовое животное" : (flag2 ? "Lieblingsreittier" : "Favourite Mount")); AddLocalizedWord(localization, "boarriding_favourite_boar_dead", flag ? "Любимый кабан погиб" : (flag2 ? "Lieblingswildschwein gestorben" : "Favourite Boar died")); AddLocalizedWord(localization, "boarriding_favourite_dead_command", flag ? "Ваш любимый кабан погиб." : (flag2 ? "Dein Lieblingswildschwein ist gestorben." : "Your favourite boar has died.")); AddLocalizedWord(localization, "boarriding_eject_rider", flag ? "Сбросить чужого всадника" : (flag2 ? "Fremden Reiter abwerfen" : "Eject other rider")); AddLocalizedWord(localization, "boarriding_not_owner", flag ? "Этот кабан вам не принадлежит." : (flag2 ? "Dieses Wildschwein gehört dir nicht." : "This boar does not belong to you.")); AddLocalizedWord(localization, "boarriding_no_other_rider", flag ? "На вашем кабане нет чужого всадника." : (flag2 ? "Auf deinem Wildschwein sitzt kein fremder Reiter." : "No other rider is using your boar.")); AddLocalizedWord(localization, "boarriding_eject_sent", flag ? "Чужой всадник сброшен." : (flag2 ? "Der fremde Reiter wird abgeworfen." : "The other rider is being ejected.")); AddLocalizedWord(localization, "boarriding_you_were_ejected", flag ? "Владелец сбросил вас с кабана." : (flag2 ? "Der Besitzer hat dich vom Wildschwein abgeworfen." : "The owner ejected you from the boar.")); AddLocalizedWord(localization, "boarriding_level", flag ? "Уровень" : (flag2 ? "Level" : "Level")); AddLocalizedWord(localization, "boarriding_level_up", flag ? "достиг уровня" : (flag2 ? "hat Level erreicht" : "reached Level")); AddLocalizedWord(localization, "boarriding_level_up_message", flag ? "{0} - достиг уровня {1}" : (flag2 ? "{0} - hat Level {1} erreicht" : "{0} - reached Level {1}")); } } private static void AddLocalizedWord(Localization localization, string key, string text) { AccessTools.Method(typeof(Localization), "AddWord", (Type[])null, (Type[])null).Invoke(localization, new object[2] { key, text }); } private unsafe void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Expected O, but got Unknown //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_0454: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Expected O, but got Unknown //IL_04d5: Unknown result type (might be due to invalid IL or missing references) //IL_04df: Expected O, but got Unknown //IL_0513: Unknown result type (might be due to invalid IL or missing references) //IL_051d: Expected O, but got Unknown //IL_056b: Unknown result type (might be due to invalid IL or missing references) //IL_0575: Expected O, but got Unknown //IL_05a9: Unknown result type (might be due to invalid IL or missing references) //IL_05b3: Expected O, but got Unknown //IL_05e7: Unknown result type (might be due to invalid IL or missing references) //IL_05f1: Expected O, but got Unknown //IL_0625: Unknown result type (might be due to invalid IL or missing references) //IL_062f: Expected O, but got Unknown //IL_0663: Unknown result type (might be due to invalid IL or missing references) //IL_066d: Expected O, but got Unknown //IL_06a1: Unknown result type (might be due to invalid IL or missing references) //IL_06ab: Expected O, but got Unknown //IL_06df: Unknown result type (might be due to invalid IL or missing references) //IL_06e9: Expected O, but got Unknown //IL_071d: Unknown result type (might be due to invalid IL or missing references) //IL_0727: Expected O, but got Unknown //IL_075b: Unknown result type (might be due to invalid IL or missing references) //IL_0765: Expected O, but got Unknown //IL_0799: Unknown result type (might be due to invalid IL or missing references) //IL_07a3: Expected O, but got Unknown //IL_07d7: Unknown result type (might be due to invalid IL or missing references) //IL_07e1: Expected O, but got Unknown //IL_0815: Unknown result type (might be due to invalid IL or missing references) //IL_081f: Expected O, but got Unknown //IL_0853: Unknown result type (might be due to invalid IL or missing references) //IL_085d: Expected O, but got Unknown //IL_0891: Unknown result type (might be due to invalid IL or missing references) //IL_089b: Expected O, but got Unknown //IL_08cf: Unknown result type (might be due to invalid IL or missing references) //IL_08d9: Expected O, but got Unknown //IL_090d: Unknown result type (might be due to invalid IL or missing references) //IL_0917: Expected O, but got Unknown //IL_094b: Unknown result type (might be due to invalid IL or missing references) //IL_0955: Expected O, but got Unknown //IL_0ab3: Unknown result type (might be due to invalid IL or missing references) //IL_0ab8: Unknown result type (might be due to invalid IL or missing references) //IL_0abb: Unknown result type (might be due to invalid IL or missing references) //IL_0ac2: Invalid comparison between Unknown and I4 //IL_0b3a: Unknown result type (might be due to invalid IL or missing references) //IL_0b3f: Unknown result type (might be due to invalid IL or missing references) //IL_0b42: Unknown result type (might be due to invalid IL or missing references) //IL_0b49: Invalid comparison between Unknown and I4 //IL_0b54: Unknown result type (might be due to invalid IL or missing references) //IL_0b59: Unknown result type (might be due to invalid IL or missing references) //IL_0aca: Unknown result type (might be due to invalid IL or missing references) //IL_0acf: Unknown result type (might be due to invalid IL or missing references) //IL_0b1f: Unknown result type (might be due to invalid IL or missing references) //IL_0af1: Unknown result type (might be due to invalid IL or missing references) //IL_0af6: Unknown result type (might be due to invalid IL or missing references) //IL_0b6a: Unknown result type (might be due to invalid IL or missing references) //IL_0b6f: Unknown result type (might be due to invalid IL or missing references) //IL_0b76: Unknown result type (might be due to invalid IL or missing references) //IL_0b7d: Invalid comparison between Unknown and I4 //IL_0ba9: Unknown result type (might be due to invalid IL or missing references) //IL_0e96: Unknown result type (might be due to invalid IL or missing references) //IL_0ea0: Expected O, but got Unknown Instance = this; HeadlessServer = (int)SystemInfo.graphicsDeviceType == 4; MigrateLegacyConfig(); LoadCustomSaddleAssets(); OneStarSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Speed", "One Star", 1.2f, "Speed multiplier for a one-star boar."); TwoStarSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Speed", "Two Stars", 1.4f, "Speed multiplier for a two-star boar."); SaddleX = ((BaseUnityPlugin)this).Config.Bind<float>("Saddle Position", "X", 0f, "Horizontal saddle position."); SaddleY = ((BaseUnityPlugin)this).Config.Bind<float>("Saddle Position", "Y", 1.02f, "Saddle height."); SaddleZ = ((BaseUnityPlugin)this).Config.Bind<float>("Saddle Position", "Z", 0.35f, "Forward/backward saddle position."); SaddleScale = ((BaseUnityPlugin)this).Config.Bind<float>("Saddle Position", "Scale", 0.36f, "Scale of the visible saddle."); RiderX = ((BaseUnityPlugin)this).Config.Bind<float>("Rider Position", "X", 0f, "Horizontal rider position."); RiderY = ((BaseUnityPlugin)this).Config.Bind<float>("Rider Position", "Y", 0.25f, "Rider height relative to the saddle."); RiderZ = ((BaseUnityPlugin)this).Config.Bind<float>("Rider Position", "Z", 0.25f, "Forward/backward rider position."); RiderForwardCorrection = ((BaseUnityPlugin)this).Config.Bind<float>("Rider Position", "Custom Saddle Forward Correction", 0.32f, "Moves the rider toward the boar's head so the character sits in the custom saddle centre."); RiderExtraForwardOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Rider Position", "Extra Forward Offset", 0.12f, "Additional forward rider offset for all star levels, with or without a saddle. Does not move the saddle or interaction area."); NormalBoarSaddleYOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Saddle Position", "No-Star Boar Height Offset", -0.16f, "Additional height correction for no-star boars only."); NormalBoarSaddleScale = ((BaseUnityPlugin)this).Config.Bind<float>("Saddle Position", "No-Star Boar Scale", 0.84f, "Additional scale multiplier for no-star boars only."); CustomSaddleSizeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Saddle Position", "Custom Model Scale", 0.68f, "Shared size multiplier for the custom saddle models."); CustomSaddleZ = ((BaseUnityPlugin)this).Config.Bind<float>("Custom Saddle Fit", "Back Position", -0.05f, "Forward/backward position of the custom saddle models."); CustomSaddleZTwoStars = ((BaseUnityPlugin)this).Config.Bind<float>("Custom Saddle Fit", "Two-Star Back Position", -0.05f, "Forward/backward position of the custom saddle on two-star boars, centred farther back on the large upper back."); CustomSaddleYNoStars = ((BaseUnityPlugin)this).Config.Bind<float>("Custom Saddle Fit", "No-Star Height", 0.95f, "Back height of the custom saddle on a no-star boar."); CustomSaddleYOneStar = ((BaseUnityPlugin)this).Config.Bind<float>("Custom Saddle Fit", "One-Star Height", 1.015f, "Back height of the custom saddle on a one-star boar."); CustomSaddleYTwoStars = ((BaseUnityPlugin)this).Config.Bind<float>("Custom Saddle Fit", "Two-Star Height", 1.11f, "Back height of the custom saddle on a two-star boar."); CustomSaddlePitchOneStar = ((BaseUnityPlugin)this).Config.Bind<float>("Custom Saddle Fit", "One-Star Back Pitch", 0.75f, "Tilts the one-star saddle to follow the rising shoulder line without clipping through the back."); AllowMountedPortalTravel = ((BaseUnityPlugin)this).Config.Bind<bool>("Portal Travel", "Allow Mounted Boars", true, "Allows a player who is riding a boar to take the boar through a portal."); MovementKeySteering = ((BaseUnityPlugin)this).Config.Bind<bool>("Riding Camera", "Movement-Key Steering", true, "Steers a ridden boar with the movement keys instead of the camera direction. This allows free camera movement while riding."); MountedCameraShakeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Riding Camera", "Camera Shake Multiplier", 0f, new ConfigDescription("Camera-shake strength while riding a boar. 0 disables it, 0.5 halves it and 1 keeps Valheim's normal strength.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); CommandWheelShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "Open Command Wheel", new KeyboardShortcut((KeyCode)98, Array.Empty<KeyCode>()), "Opens the command wheel for the last ridden tamed boar."); MountShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "Mount Saddled Boar", new KeyboardShortcut((KeyCode)101, Array.Empty<KeyCode>()), "Mounts the targeted saddled boar. E keeps Valheim's normal interaction behavior."); DismountShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "Dismount", new KeyboardShortcut((KeyCode)101, Array.Empty<KeyCode>()), "Dismounts with E when no usable object is targeted. When an object is targeted, E interacts without dismounting."); BarebackShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "Ride Bareback", new KeyboardShortcut((KeyCode)101, Array.Empty<KeyCode>()), "Rides an unsaddled boar only while aiming at its back."); RemoveSaddleShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "Remove Saddle", new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Removes and recovers the targeted boar saddle."); RecallRange = ((BaseUnityPlugin)this).Config.Bind<float>("Commands", "Recall Range", 200f, new ConfigDescription("Maximum distance at which the last ridden boar can hear the recall command.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 1000f), Array.Empty<object>())); FollowRange = ((BaseUnityPlugin)this).Config.Bind<float>("Commands", "Follow Range", 15f, new ConfigDescription("Maximum distance for the normal follow command. Use Recall for greater distances.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 100f), Array.Empty<object>())); RidingSkillStaminaRegenPerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Riding", "Stamina Regeneration Per Skill Level", 0.05f, new ConfigDescription("Additional mount stamina regenerated per second for every Riding skill level while actively riding. At level 100 the default adds 5 stamina per second.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), Array.Empty<object>())); BoarLevelSystemEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Boar Levels", "Enabled", true, "Enables persistent levels and experience for tamed boars."); BoarMaximumLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Boar Levels", "Maximum Level", 50, new ConfigDescription("Highest level a tamed boar can reach.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 200), Array.Empty<object>())); BoarHealthPerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "Health Per Level", 1f, new ConfigDescription("Base maximum-health gain per progression level for a normal boar.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); OneStarBoarHealthPerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "1-Star Health Per Level", 2f, new ConfigDescription("Base maximum-health gain per progression level for a one-star boar.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); TwoStarBoarHealthPerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "2-Star Health Per Level", 3f, new ConfigDescription("Base maximum-health gain per progression level for a two-star boar.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); BoarHealthIncreaseEveryFiveLevels = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "Health Gain Increase Every 5 Levels", 0.5f, new ConfigDescription("Additional health added to every later level-up after each five-level band, independently for every star tier.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); WildBoarNextLevelChance = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "Wild Boar Next Level Chance", 0.45f, new ConfigDescription("Chance for a newly spawned wild boar to advance one more progression level. Every level is possible, but higher levels become increasingly rare.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.95f), Array.Empty<object>())); BoarBaseExperience = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "Base Experience Required", 25f, new ConfigDescription("Experience required for level 2.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10000f), Array.Empty<object>())); BoarExperienceGrowth = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "Experience Growth", 1.1f, new ConfigDescription("Experience requirement multiplier for each later level.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f), Array.Empty<object>())); BoarRidingDistanceExperience = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "Experience Per 25 Metres Ridden", 4f, new ConfigDescription("Experience awarded for every 25 metres actually travelled while riding.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); BoarRidingTimeExperience = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "Experience Per Minute Ridden", 5f, new ConfigDescription("Experience awarded for every active minute of riding.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); BoarCommandExperience = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "Experience Per Command", 1f, new ConfigDescription("Experience for an executed movement command. Each boar has a cooldown to prevent farming.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); BoarCombatExperienceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "Combat Experience Multiplier", 0.1f, new ConfigDescription("Experience per point of damage dealt by the boar.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); BoarKillExperience = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "Kill Experience", 20f, new ConfigDescription("Base experience for an enemy killed by the boar, multiplied by the enemy's star level.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1000f), Array.Empty<object>())); BoarSurvivalExperienceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "Survival Experience Multiplier", 0.02f, new ConfigDescription("Experience per point of damage survived by a tamed boar.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); BoarExperienceRate = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "Experience Rate", 1.25f, new ConfigDescription("Global boar experience multiplier. The default makes boars level slightly faster than the passive Riding skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>())); BoarCatchUpMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Boar Levels", "New Mount Catch-Up Bonus", 2f, new ConfigDescription("Maximum additional experience multiplier for a boar below the rider's comparable progression. This speeds up new mounts without copying the Riding skill level.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); FavouriteHealthRegeneration = ((BaseUnityPlugin)this).Config.Bind<float>("Favourite Boar", "Health Regeneration Per Second", 1f, new ConfigDescription("Passive health regenerated each second by the current favourite boar.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); FavouriteRegenerationInCombat = ((BaseUnityPlugin)this).Config.Bind<bool>("Favourite Boar", "Regenerate During Combat", false, "Allows favourite-boar regeneration while it has an active target or is attacking."); ShowBoarLevel = ((BaseUnityPlugin)this).Config.Bind<bool>("Boar Levels", "Show Level", true, "Shows the persistent level next to a tamed boar's name."); ShowLevelUpEffect = ((BaseUnityPlugin)this).Config.Bind<bool>("Boar Levels", "Show Level Up Effect", true, "Shows a message and a subtle effect when a boar levels up."); if (Mathf.Approximately(BoarBaseExperience.Value, 100f)) { BoarBaseExperience.Value = 25f; } if (Mathf.Approximately(BoarExperienceGrowth.Value, 1.2f)) { BoarExperienceGrowth.Value = 1.1f; } if (Mathf.Approximately(BoarRidingDistanceExperience.Value, 2f)) { BoarRidingDistanceExperience.Value = 4f; } if (Mathf.Approximately(BoarRidingTimeExperience.Value, 2f)) { BoarRidingTimeExperience.Value = 5f; } if (BoarHealthPerLevel.Value <= 0.25f) { BoarHealthPerLevel.Value = 1f; } if (Mathf.Approximately(RecallRange.Value, 60f)) { RecallRange.Value = 200f; ((BaseUnityPlugin)this).Config.Save(); } KeyboardShortcut value = BarebackShortcut.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey == 101) { value = BarebackShortcut.Value; if (((object)(*(KeyboardShortcut*)(&value))/*cast due to .constrained prefix*/).ToString().IndexOf("Shift", StringComparison.OrdinalIgnoreCase) < 0) { value = BarebackShortcut.Value; if (((object)(*(KeyboardShortcut*)(&value))/*cast due to .constrained prefix*/).ToString().IndexOf("Control", StringComparison.OrdinalIgnoreCase) < 0) { goto IL_0b34; } } BarebackShortcut.Value = new KeyboardShortcut((KeyCode)101, Array.Empty<KeyCode>()); ((BaseUnityPlugin)this).Config.Save(); } goto IL_0b34; IL_0b34: value = DismountShortcut.Value; bool flag = (int)((KeyboardShortcut)(ref value)).MainKey == 101; int num = 0; value = DismountShortcut.Value; foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { num++; flag = flag && (int)modifier == 306; } if (flag && num == 1) { DismountShortcut.Value = new KeyboardShortcut((KeyCode)101, Array.Empty<KeyCode>()); ((BaseUnityPlugin)this).Config.Save(); } if (Mathf.Approximately(CustomSaddleZTwoStars.Value, 0.2f)) { CustomSaddleZTwoStars.Value = -0.05f; ((BaseUnityPlugin)this).Config.Save(); } if (Mathf.Approximately(SaddleY.Value, 0.68f) && Mathf.Approximately(SaddleZ.Value, -0.08f) && Mathf.Approximately(SaddleScale.Value, 0.55f)) { SaddleY.Value = 0.9f; SaddleZ.Value = 0.1f; SaddleScale.Value = 0.42f; ((BaseUnityPlugin)this).Config.Save(); } if (Mathf.Approximately(SaddleY.Value, 0.9f) && Mathf.Approximately(SaddleZ.Value, 0.1f) && Mathf.Approximately(SaddleScale.Value, 0.42f)) { SaddleY.Value = 0.84f; SaddleZ.Value = -0.35f; SaddleScale.Value = 0.32f; ((BaseUnityPlugin)this).Config.Save(); } if (Mathf.Approximately(SaddleY.Value, 0.84f) && Mathf.Approximately(SaddleZ.Value, -0.35f) && Mathf.Approximately(SaddleScale.Value, 0.32f)) { SaddleY.Value = 1.02f; SaddleZ.Value = 0.35f; SaddleScale.Value = 0.36f; if (Mathf.Approximately(RiderZ.Value, 0f)) { RiderZ.Value = 0.25f; } ((BaseUnityPlugin)this).Config.Save(); } if (Mathf.Approximately(CustomSaddleYNoStars.Value, 0.9f)) { CustomSaddleYNoStars.Value = 0.95f; ((BaseUnityPlugin)this).Config.Save(); } if (Mathf.Approximately(CustomSaddleYOneStar.Value, 1f) || Mathf.Approximately(CustomSaddleYOneStar.Value, 1.03f)) { CustomSaddleYOneStar.Value = 1.015f; ((BaseUnityPlugin)this).Config.Save(); } if (Mathf.Approximately(CustomSaddlePitchOneStar.Value, -3f) || Mathf.Approximately(CustomSaddlePitchOneStar.Value, -0.5f)) { CustomSaddlePitchOneStar.Value = 0.75f; ((BaseUnityPlugin)this).Config.Save(); } if (Mathf.Approximately(RiderForwardCorrection.Value, 0.22f)) { RiderForwardCorrection.Value = 0.32f; ((BaseUnityPlugin)this).Config.Save(); } _harmony = new Harmony("xneliox.rideableboars"); _harmony.PatchAll(typeof(BoarRidingPlugin).Assembly); if (!HeadlessServer) { _commandRadial = ScriptableObject.CreateInstance<BoarCommandRadialConfig>(); _commandRadial.PreloadIcons(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Rideable Boars 1.0.4 loaded."); } private void MigrateLegacyConfig() { try { string text = Path.Combine(Paths.ConfigPath, "valheim.boarriding.cfg"); string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath; if (File.Exists(text) && !File.Exists(configFilePath)) { File.Copy(text, configFilePath, overwrite: false); ((BaseUnityPlugin)this).Config.Reload(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Migrated the legacy configuration to " + Path.GetFileName(configFilePath) + ".")); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not migrate the legacy configuration: " + ex.Message)); } } private void Update() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) if (HeadlessServer || (Object)(object)Player.m_localPlayer == (Object)null) { return; } Player localPlayer = Player.m_localPlayer; EnsureKickRpcRegistered(); EnsureFavouriteLoaded(localPlayer); IDoodadController doodadController = localPlayer.GetDoodadController(); Sadle val = (Sadle)(object)((doodadController is Sadle) ? doodadController : null); Character val2 = (Object.op_Implicit((Object)(object)val) ? val.GetCharacter() : null); if (Object.op_Implicit((Object)(object)val2)) { RememberFavourite(val2, localPlayer); } UpdateRidingProgression(val2); UpdateFavouriteAnimalPin(); UpdateFavouriteHealthRegeneration(localPlayer); KeyboardShortcut value = DismountShortcut.Value; if (((KeyboardShortcut)(ref value)).IsDown() && Object.op_Implicit((Object)(object)val) && IsBoar(val.GetCharacter()) && !IsPlainUseShortcut(DismountShortcut.Value)) { val.OnUseStop(localPlayer); return; } RadialBase val3 = (Object.op_Implicit((Object)(object)Hud.instance) ? RadialMenu.Invoke(Hud.instance) : null); if (_commandWheelOpenRequested && Object.op_Implicit((Object)(object)val3) && !val3.Active) { OpenCommandWheel(val3); if (val3.Active && (object)val3.CurrentConfig == _commandRadial) { _commandWheelOpenRequested = false; } } int num; if (Object.op_Implicit((Object)(object)val3) && val3.Active) { num = (((object)val3.CurrentConfig == _commandRadial) ? 1 : 0); if (num != 0) { ZCursor.LockState = (CursorLockMode)0; ZCursor.Show(); _commandRadial.RefreshCenterText(val3); } } else { num = 0; } if (num != 0 && Input.GetKeyDown((KeyCode)27)) { CloseCommandWheel(val3); return; } if (!IsTextEntryActive() && IsShortcutDownAllowExtraModifiers(CommandWheelShortcut.Value)) { if (Object.op_Implicit((Object)(object)val3) && val3.Active && (object)val3.CurrentConfig == _commandRadial) { CloseCommandWheel(val3); _commandWheelOpenRequested = false; } else { _commandWheelOpenRequested = true; if (Object.op_Implicit((Object)(object)val3)) { OpenCommandWheel(val3); if (val3.Active && (object)val3.CurrentConfig == _commandRadial) { _commandWheelOpenRequested = false; } } } } HandleCustomInteractionShortcuts(localPlayer, val); } private static bool IsShortcutDownAllowExtraModifiers(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } return true; } private static bool IsPlainUseShortcut(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 101) { return false; } using (IEnumerator<KeyCode> enumerator = ((KeyboardShortcut)(ref shortcut)).Modifiers.GetEnumerator()) { if (enumerator.MoveNext()) { _ = enumerator.Current; return false; } } return true; } private static bool IsTextEntryActive() { if (!TextInput.IsVisible() && !Console.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Minimap.InTextInput()) { if ((Object)(object)Hud.instance != (Object)null && (Object)(object)Hud.instance.m_buildUi != (Object)null) { return Hud.instance.m_buildUi.SearchFieldFocused; } return false; } return true; } private void HandleCustomInteractionShortcuts(Player player, Sadle ridden) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Invalid comparison between Unknown and I4 //IL_0091: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)ridden)) { return; } GameObject hoverObject = ((Humanoid)player).GetHoverObject(); if (!Object.op_Implicit((Object)(object)hoverObject)) { return; } Tameable componentInParent = hoverObject.GetComponentInParent<Tameable>(); if (!Object.op_Implicit((Object)(object)componentInParent) || !IsBoar(((Component)componentInParent).GetComponent<Character>())) { return; } Sadle componentInParent2 = hoverObject.GetComponentInParent<Sadle>(); bool flag = Object.op_Implicit((Object)(object)componentInParent2) && Object.op_Implicit((Object)(object)componentInParent.m_saddle) && (Object)(object)componentInParent2 == (Object)(object)componentInParent.m_saddle; KeyboardShortcut value = RemoveSaddleShortcut.Value; if (((KeyboardShortcut)(ref value)).IsDown() && flag && componentInParent.IsTamed() && HasSaddle(componentInParent)) { componentInParent.DropSaddle(((Component)player).transform.position); return; } KeyboardShortcut value2 = MountShortcut.Value; if ((int)((KeyboardShortcut)(ref value2)).MainKey != 101 && ((KeyboardShortcut)(ref value2)).IsDown() && HasSaddle(componentInParent) && Object.op_Implicit((Object)(object)componentInParent.m_saddle)) { componentInParent.m_saddle.Interact((Humanoid)(object)player, false, false); } } private void OpenCommandWheel(RadialBase radial) { if (!Object.op_Implicit((Object)(object)radial) || (Object)(object)_commandRadial == (Object)null) { return; } radial.CanOpen = true; ZCursor.LockState = (CursorLockMode)0; ZCursor.Show(); object value = AccessTools.Field(typeof(RadialBase), "m_animationManager").GetValue(radial); if (value != null) { MethodInfo methodInfo = AccessTools.Method(value.GetType(), "EndAll", (Type[])null, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(value, null); } } AccessTools.Field(typeof(RadialBase), "m_selected").SetValue(radial, null); radial.Open((IRadialConfig)(object)_commandRadial, (IRadialConfig)null); } internal bool IsOwnCommandWheel(RadialBase radial) { if (Object.op_Implicit((Object)(object)radial) && radial.Active && (Object)(object)_commandRadial != (Object)null) { return (object)radial.CurrentConfig == _commandRadial; } return false; } internal void RestoreCommandWheelCenter(RadialBase radial) { if (IsOwnCommandWheel(radial)) { _commandRadial.RefreshCenterText(radial); } } internal void AddCommandWheelToMainRadial(RadialBase radial, List<RadialMenuElement> elements) { if (Object.op_Implicit((Object)(object)radial) && !((Object)(object)_commandRadial == (Object)null) && elements != null) { _commandRadial.RemoveCommandElements(elements); GroupElement val = Object.Instantiate<GroupElement>(RadialData.SO.GroupElement); val.Init((IRadialConfig)(object)_commandRadial, radial.CurrentConfig, radial); elements.Add((RadialMenuElement)(object)val); } } private void EnsureFavouriteLoaded(Player player) { //IL_00a3: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player) || (Object)(object)ZNet.instance == (Object)null) { return; } long worldUID = ZNet.instance.GetWorldUID(); string text = "RideableBoars.Favourite." + worldUID + "." + player.GetPlayerID(); string text2 = Convert.ToBase64String(Encoding.UTF8.GetBytes(player.GetPlayerName() ?? string.Empty)); string text3 = "RideableBoars.Favourite.ByName." + worldUID + "." + text2; if (!string.Equals(_favouritePreferenceKey, text, StringComparison.Ordinal)) { _favouritePreferenceKey = text; _favouriteFallbackPreferenceKey = text3; _favouriteServerStateSynchronized = false; _lastRiddenAnimal = ZDOID.None; _lastRiddenBoar = ZDOID.None; _favouriteAnimalName = string.Empty; _favouriteAnimalIsBoar = false; _favouriteAnimalDead = false; _favouriteLastKnownPosition = Vector3.zero; _hasFavouriteLastKnownPosition = false; _favouriteSavedAtUtcTicks = 0L; _favouriteWorldUid = worldUID; _favouritePinMismatchReported = false; } if (_favouriteServerStateSynchronized) { return; } ZNetView component = ((Component)player).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsValid()) { return; } string text4 = component.GetZDO().GetString(FavouriteMountStateKey, string.Empty); string text5 = PlayerPrefs.GetString(text, string.Empty); string text6 = PlayerPrefs.GetString(text3, string.Empty); if (!IsFavouriteValueForWorld(text4, worldUID, allowLegacy: false)) { if (!string.IsNullOrEmpty(text4)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Ignored favourite mount from player ZDO because it belongs to another world or is an unscoped legacy value."); } text4 = string.Empty; } if (!IsFavouriteValueForWorld(text5, worldUID, allowLegacy: true)) { text5 = string.Empty; } if (!IsFavouriteValueForWorld(text6, worldUID, allowLegacy: true)) { text6 = string.Empty; } string source; string text7 = ChooseNewestFavouriteValue(text5, text6, text4, out source); if (!string.IsNullOrEmpty(text7)) { LoadFavourite(text7); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Favourite mount restored from " + source + ": " + DescribeFavouriteState())); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)("No saved favourite mount was found for world " + ZNet.instance.GetWorldUID() + " and character " + player.GetPlayerName() + ".")); } _favouriteServerStateSynchronized = true; if (!((ZDOID)(ref _lastRiddenAnimal)).IsNone() && !string.Equals(text4, text7, StringComparison.Ordinal)) { SaveFavourite(); } } private static string ChooseNewestFavouriteValue(string localValue, string fallbackValue, string serverValue, out string source) { string[] array = new string[3] { localValue, fallbackValue, serverValue }; string[] array2 = new string[3] { "local player ID storage", "character-name fallback storage", "player ZDO" }; string text = string.Empty; source = "none"; long num = long.MinValue; for (int i = 0; i < array.Length; i++) { if (!string.IsNullOrEmpty(array[i])) { long favouriteTimestamp = GetFavouriteTimestamp(array[i]); if (string.IsNullOrEmpty(text) || favouriteTimestamp > num) { text = array[i]; source = array2[i]; num = favouriteTimestamp; } } } return text; } private static long GetFavouriteTimestamp(string value) { if (string.IsNullOrEmpty(value)) { return 0L; } string[] array = value.Split(new char[1] { '|' }); if (array.Length < 9 || !long.TryParse(array[8], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return 0L; } return result; } private static bool IsFavouriteValueForWorld(string value, long worldUid, bool allowLegacy) { if (string.IsNullOrEmpty(value)) { return true; } string[] array = value.Split(new char[1] { '|' }); if (array.Length < 10) { return allowLegacy; } if (long.TryParse(array[9], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return result == worldUid; } return false; } private void LoadFavourite(string value) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) try { string[] array = value.Split(new char[1] { '|' }); if (array.Length >= 5 && long.TryParse(array[0], out var result) && uint.TryParse(array[1], out var result2) && long.TryParse(array[2], out var result3) && uint.TryParse(array[3], out var result4)) { _lastRiddenAnimal = new ZDOID(result, result2); _lastRiddenBoar = new ZDOID(result3, result4); _favouriteAnimalName = Encoding.UTF8.GetString(Convert.FromBase64String(array[4])); _favouriteAnimalIsBoar = ((ZDOID)(ref _lastRiddenAnimal)).Equals(_lastRiddenBoar); if (array.Length >= 8 && float.TryParse(array[5], NumberStyles.Float, CultureInfo.InvariantCulture, out var result5) && float.TryParse(array[6], NumberStyles.Float, CultureInfo.InvariantCulture, out var result6) && float.TryParse(array[7], NumberStyles.Float, CultureInfo.InvariantCulture, out var result7)) { _favouriteLastKnownPosition = new Vector3(result5, result6, result7); _hasFavouriteLastKnownPosition = true; } _favouriteSavedAtUtcTicks = GetFavouriteTimestamp(value); if (array.Length >= 10 && long.TryParse(array[9], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result8)) { _favouriteWorldUid = result8; } _favouriteAnimalDead = array.Length >= 11 && array[10] == "1"; } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not restore the favourite mount: " + ex.Message)); } } private void RememberFavourite(Character character, Player player) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) ZDOID zDOID = character.GetZDOID(); if (((ZDOID)(ref zDOID)).IsNone()) { return; } bool flag = IsBoar(character); string hoverName = character.GetHoverName(); bool flag2 = !((ZDOID)(ref _lastRiddenAnimal)).Equals(zDOID) || _favouriteAnimalName != hoverName || _favouriteAnimalIsBoar != flag; _lastRiddenAnimal = zDOID; _favouriteAnimalName = hoverName; _favouriteAnimalIsBoar = flag; _favouriteAnimalDead = false; bool flag3 = !_hasFavouriteLastKnownPosition || (Time.unscaledTime >= _nextFavouritePositionSave && Vector3.Distance(_favouriteLastKnownPosition, ((Component)character).transform.position) >= 10f); if (flag3) { _favouriteLastKnownPosition = ((Component)character).transform.position; _hasFavouriteLastKnownPosition = true; _nextFavouritePositionSave = Time.unscaledTime + 5f; } if (flag) { _lastRiddenBoar = zDOID; ZNetView component = ((Component)character).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid() && component.IsOwner() && component.GetZDO().GetLong(FavouriteOwnerKey, 0L) == 0L) { component.GetZDO().Set(FavouriteOwnerKey, player.GetPlayerID()); } } if (flag2) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Favourite mount changed to " + FormatZdoId(zDOID) + " (name: " + hoverName + ", boar: " + flag + ").")); } if (flag2 || flag3) { SaveFavourite(flag2); } } private void SaveFavourite(bool logDetails = false) { if (!string.IsNullOrEmpty(_favouritePreferenceKey) && !((ZDOID)(ref _lastRiddenAnimal)).IsNone()) { if ((Object)(object)ZNet.instance != (Object)null) { _favouriteWorldUid = ZNet.instance.GetWorldUID(); } _favouriteSavedAtUtcTicks = DateTime.UtcNow.Ticks; string text = Convert.ToBase64String(Encoding.UTF8.GetBytes(_favouriteAnimalName ?? string.Empty)); string text2 = ((ZDOID)(ref _lastRiddenAnimal)).UserID + "|" + ((ZDOID)(ref _lastRiddenAnimal)).ID + "|" + ((ZDOID)(ref _lastRiddenBoar)).UserID + "|" + ((ZDOID)(ref _lastRiddenBoar)).ID + "|" + text; text2 = ((!_hasFavouriteLastKnownPosition) ? (text2 + "|0|0|0") : (text2 + "|" + _favouriteLastKnownPosition.x.ToString("R", CultureInfo.InvariantCulture) + "|" + _favouriteLastKnownPosition.y.ToString("R", CultureInfo.InvariantCulture) + "|" + _favouriteLastKnownPosition.z.ToString("R", CultureInfo.InvariantCulture))); text2 = text2 + "|" + _favouriteSavedAtUtcTicks.ToString(CultureInfo.InvariantCulture); text2 = text2 + "|" + _favouriteWorldUid.ToString(CultureInfo.InvariantCulture); text2 = text2 + "|" + (_favouriteAnimalDead ? "1" : "0"); PlayerPrefs.SetString(_favouritePreferenceKey, text2); if (!string.IsNullOrEmpty(_favouriteFallbackPreferenceKey)) { PlayerPrefs.SetString(_favouriteFallbackPreferenceKey, text2); } PlayerPrefs.Save(); Player localPlayer = Player.m_localPlayer; ZNetView val = (Object.op_Implicit((Object)(object)localPlayer) ? ((Component)localPlayer).GetComponent<ZNetView>() : null); if (Object.op_Implicit((Object)(object)val) && val.IsValid() && val.IsOwner()) { val.GetZDO().Set(FavouriteMountStateKey, text2); } if (logDetails) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Favourite mount saved to PlayerPrefs and player ZDO: " + DescribeFavouriteState())); } } } private string DescribeFavouriteState() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) string text = (_hasFavouriteLastKnownPosition ? ((Vector3)(ref _favouriteLastKnownPosition)).ToString("F1") : "unknown"); return "animal=" + FormatZdoId(_lastRiddenAnimal) + ", boar=" + FormatZdoId(_lastRiddenBoar) + ", name=" + _favouriteAnimalName + ", position=" + text + ", savedUtcTicks=" + _favouriteSavedAtUtcTicks + ", world=" + _favouriteWorldUid + ", dead=" + _favouriteAnimalDead; } internal void PreserveFavouriteForPortal(Character boar, Player player) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)boar) && Object.op_Implicit((Object)(object)player)) { RememberFavourite(boar, player); _favouriteLastKnownPosition = ((Component)boar).transform.position; _hasFavouriteLastKnownPosition = true; SaveFavourite(logDetails: true); } } internal void MarkFavouriteDead(Character boar) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)boar) && !((ZDOID)(ref _lastRiddenAnimal)).IsNone()) { ZDOID zDOID = boar.GetZDOID(); if (!((ZDOID)(ref zDOID)).IsNone() && ((ZDOID)(ref zDOID)).Equals(_lastRiddenAnimal) && !_favouriteAnimalDead) { _favouriteLastKnownPosition = ((Component)boar).transform.position; _hasFavouriteLastKnownPosition = true; _favouriteAnimalName = boar.GetHoverName(); _favouriteAnimalDead = true; RemoveFavouriteAnimalPin(); SaveFavourite(logDetails: true); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Favourite boar died; keeping its final map position: " + DescribeFavouriteState())); } } } internal void RestoreMountedBoarAfterPortal(MountedBoarPortalState state) { if (state != null) { ((MonoBehaviour)this).StartCoroutine(RestoreMountedBoarAfterPortalRoutine(state)); } } private IEnumerator RestoreMountedBoarAfterPortalRoutine(MountedBoarPortalState state) { yield return null; float deadline = Time.unscaledTime + 5f; while (Time.unscaledTime < deadline && Object.op_Implicit((Object)(object)state.Player) && Object.op_Implicit((Object)(object)state.Boar)) { Sadle saddle = (Object.op_Implicit((Object)(object)state.Saddle) ? state.Saddle : ((Component)state.Boar).GetComponentInChildren<Sadle>(true)); ZNetView val = ((!Object.op_Implicit((Object)(object)saddle)) ? ((ZNetView)null) : ((ZNetView)AccessTools.Field(typeof(Sadle), "m_nview").GetValue(saddle))); if (Object.op_Implicit((Object)(object)saddle) && Object.op_Implicit((Object)(object)val) && val.IsValid()) { if (val.IsOwner()) { val.GetZDO().Set(ZDOVars.s_user, 0L); } object[] array = new object[1]; ZDOID zDOID = ((Character)state.Player).GetZDOID(); array[0] = ((ZDOID)(ref zDOID)).UserID; val.InvokeRPC("RequestControl", array); yield return (object)new WaitForSecondsRealtime(0.15f); IDoodadController doodadController = state.Player.GetDoodadController(); if ((Object)(object)((doodadController is Sadle) ? doodadController : null) == (Object)(object)saddle && ((Character)state.Player).IsAttached()) { PreserveFavouriteForPortal(state.Boar, state.Player); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Mounted boar control restored after portal travel."); yield break; } } yield return (object)new WaitForSecondsRealtime(0.2f); } ((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not restore mounted boar control after portal travel."); } private static string FormatZdoId(ZDOID id) { if (!((ZDOID)(ref id)).IsNone()) { return ((ZDOID)(ref id)).UserID + ":" + ((ZDOID)(ref id)).ID; } return "None"; } private void ForgetFavourite() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) RemoveFavouriteAnimalPin(); _lastRiddenAnimal = ZDOID.None; _lastRiddenBoar = ZDOID.None; _favouriteAnimalName = string.Empty; _favouriteAnimalIsBoar = false; _favouriteAnimalDead = false; _favouriteLastKnownPosition = Vector3.zero; _hasFavouriteLastKnownPosition = false; if (!string.IsNullOrEmpty(_favouritePreferenceKey)) { PlayerPrefs.DeleteKey(_favouritePreferenceKey); if (!string.IsNullOrEmpty(_favouriteFallbackPreferenceKey)) { PlayerPrefs.DeleteKey(_favouriteFallbackPreferenceKey); } PlayerPrefs.Save(); } Player localPlayer = Player.m_localPlayer; ZNetView val = (Object.op_Implicit((Object)(object)localPlayer) ? ((Component)localPlayer).GetComponent<ZNetView>() : null); if (Object.op_Implicit((Object)(object)val) && val.IsValid() && val.IsOwner()) { val.GetZDO().Set(FavouriteMountStateKey, string.Empty); } } private void EnsureKickRpcRegistered() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && _registeredKickRpc != instance) { instance.Register<ZDOID, long>("RideableBoars_KickRider", (Action<long, ZDOID, long>)OnKickRider); _registeredKickRpc = instance; } } private void OnKickRider(long sender, ZDOID boarId, long ownerPlayerId) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return; } IDoodadController doodadController = localPlayer.GetDoodadController(); Sadle val = (Sadle)(object)((doodadController is Sadle) ? doodadController : null); Character val2 = (Object.op_Implicit((Object)(object)val) ? val.GetCharacter() : null); if (!Object.op_Implicit((Object)(object)val2) || !IsBoar(val2)) { return; } ZDOID zDOID = val2.GetZDOID(); if (!((ZDOID)(ref zDOID)).Equals(boarId)) { return; } ZNetView component = ((Component)val2).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid() && component.GetZDO().GetLong(FavouriteOwnerKey, 0L) == ownerPlayerId) { localPlayer.StopDoodadControl(); if (((Character)localPlayer).IsAttached()) { ((Character)localPlayer).AttachStop(); } ((Character)localPlayer).Message((MessageType)2, "$boarriding_you_were_ejected", 0, (Sprite)null, false); } } private void UpdateFavouriteAnimalPin() { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime < _nextFavouritePinUpdate) { return; } _nextFavouritePinUpdate = Time.unscaledTime + 1f; Minimap instance = Minimap.instance; if (!Object.op_Implicit((Object)(object)instance) || ((ZDOID)(ref _lastRiddenAnimal)).IsNone()) { RemoveFavouriteAnimalPin(); return; } if (_favouritePinMap != instance) { if (_favouriteAnimalPin != null && Object.op_Implicit((Object)(object)_favouritePinMap)) { _favouritePinMap.RemovePin(_favouriteAnimalPin); } _favouriteAnimalPin = null; _favouritePinAnimal = ZDOID.None; _favouritePinMap = instance; } GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.FindInstance(_lastRiddenAnimal) : null); Vector3 val2; if (Object.op_Implicit((Object)(object)val)) { Tameable component = val.GetComponent<Tameable>(); Character component2 = val.GetComponent<Character>(); bool flag = Object.op_Implicit((Object)(object)component2) && IsBoar(component2) && Object.op_Implicit((Object)(object)component) && component.IsTamed(); if (flag && component2.IsDead()) { MarkFavouriteDead(component2); val2 = _favouriteLastKnownPosition; } else if (!flag) { if (!_hasFavouriteLastKnownPosition) { RemoveFavouriteAnimalPin(); return; } val2 = _favouriteLastKnownPosition; if (!_favouritePinMismatchReported) { _favouritePinMismatchReported = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)("Favourite ZDO " + FormatZdoId(_lastRiddenAnimal) + " resolved to an incomplete or different object. Keeping the saved map position until the boar loads.")); } } else { _favouritePinMismatchReported = false; val2 = (_favouriteLastKnownPosition = val.transform.position); _hasFavouriteLastKnownPosition = true; _favouriteAnimalName = component2.GetHoverName(); _favouriteAnimalIsBoar = true; } } else { ZDO val3 = ((ZDOMan.instance != null) ? ZDOMan.instance.GetZDO(_lastRiddenAnimal) : null); if (val3 == null) { if (!_hasFavouriteLastKnownPosition) { RemoveFavouriteAnimalPin(); return; } val2 = _favouriteLastKnownPosition; } else { val2 = (_favouriteLastKnownPosition = val3.GetPosition()); _hasFavouriteLastKnownPosition = true; } } if (_favouriteAnimalPin == null || !((ZDOID)(ref _favouritePinAnimal)).Equals(_lastRiddenAnimal)) { RemoveFavouriteAnimalPin(); string text = (_favouriteAnimalDead ? "$boarriding_favourite_boar_dead" : (_favouriteAnimalIsBoar ? "$boarriding_favourite_boar" : "$boarriding_favourite_mount")); string text2 = ((Localization.instance != null) ? Localization.instance.Localize(text) : (_favouriteAnimalDead ? "Favourite Boar died" : (_favouriteAnimalIsBoar ? "Favourite Boar" : "Favourite Mount"))); string text3 = ((Localization.instance != null) ? Localization.instance.Localize(_favouriteAnimalName) : _favouriteAnimalName); string text4 = (string.IsNullOrEmpty(text3) ? text2 : (text2 + ": " + text3)); _favouriteAnimalPin = instance.AddPin(val2, (PinType)10, text4, false, false, 0L, default(PlatformUserID)); _favouritePinMap = instance; _favouritePinAnimal = _lastRiddenAnimal; if (_favouriteAnimalIsBoar) { if ((Object)(object)_favouriteBoarIcon == (Object)null) { _favouriteBoarIcon = LoadModSprite("boar_favourite_map.png"); } if ((Object)(object)_favouriteBoarIcon != (Object)null) { _favouriteAnimalPin.m_icon = _favouriteBoarIcon; } } _favouriteAnimalPin.m_doubleSize = false; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Favourite map pin created: " + DescribeFavouriteState())); } _favouriteAnimalPin.m_pos = val2; } private void UpdateFavouriteHealthRegeneration(Player player) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (Time.time < _nextFavouriteHeal) { return; } _nextFavouriteHeal = Time.time + 1f; if (!Object.op_Implicit((Object)(object)player) || _favouriteAnimalDead || ((ZDOID)(ref _lastRiddenAnimal)).IsNone() || (Object)(object)ZNetScene.instance == (Object)null) { return; } GameObject val = ZNetScene.instance.FindInstance(_lastRiddenAnimal); Character val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<Character>() : null); Tameable val3 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<Tameable>() : null); ZNetView val4 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ZNetView>() : null); if (Object.op_Implicit((Object)(object)val2) && !val2.IsDead() && Object.op_Implicit((Object)(object)val3) && val3.IsTamed() && Object.op_Implicit((Object)(object)val4) && val4.IsValid() && val4.GetZDO().GetLong(FavouriteOwnerKey, 0L) == player.GetPlayerID()) { MonsterAI component = val.GetComponent<MonsterAI>(); if (FavouriteRegenerationInCombat.Value || (!val2.InAttack() && (!Object.op_Implicit((Object)(object)component) || !((Object)(object)((BaseAI)component).GetTargetCreature() != (Object)null)))) { val2.Heal(FavouriteHealthRegeneration.Value, false); } } } private void UpdateRidingProgression(Character riddenBoar) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (!BoarLevelSystemEnabled.Value || !IsBoar(riddenBoar)) { _progressionRiddenBoar = ZDOID.None; _progressionDistance = 0f; _progressionRideTime = 0f; return; } ZDOID zDOID = riddenBoar.GetZDOID(); if (!((ZDOID)(ref _progressionRiddenBoar)).Equals(zDOID)) { _progressionRiddenBoar = zDOID; _progressionLastPosition = ((Component)riddenBoar).transform.position; _progressionDistance = 0f; _progressionRideTime = 0f; } float num = Vector3.Distance(_progressionLastPosition, ((Component)riddenBoar).transform.position); _progressionLastPosition = ((Component)riddenBoar).transform.position; if (num > 0.02f && num < 10f) { _progressionDistance += num; _progressionRideTime += Time.deltaTime; } if (_progressionDistance >= 25f) { int num2 = Mathf.FloorToInt(_progressionDistance / 25f); _progressionDistance -= (float)num2 * 25f; AwardBoarExperience(riddenBoar, (float)num2 * BoarRidingDistanceExperience.Value); } if (_progressionRideTime >= 60f) { int num3 = Mathf.FloorToInt(_progressionRideTime / 60f); _progressionRideTime -= (float)num3 * 60f; AwardBoarExperience(riddenBoar, (float)num3 * BoarRidingTimeExperience.Value); } } internal static int GetBoarProgressionLevel(Character boar) { ZNetView val = (Object.op_Implicit((Object)(object)boar) ? ((Component)boar).GetComponent<ZNetView>() : null); if (!Object.op_Implicit((Object)(object)val) || !val.IsValid()) { return 1; } return Mathf.Max(1, val.GetZDO().GetInt(BoarLevelKey, 1)); } internal static float GetExperienceRequiredForLevel(int level) { if (!((Object)(object)Instance == (Object)null)) { return Instance.BoarBaseExperience.Value * Mathf.Pow(Instance.BoarExperienceGrowth.Value, (float)Mathf.Max(0, level - 1)); } return 100f; } private static int RollWildBoarLevel() { if ((Object)(object)Instance == (Object)null) { return 1; } int i = 1; int num = Mathf.Max(1, Instance.BoarMaximumLevel.Value); float num2 = Mathf.Clamp(Instance.WildBoarNextLevelChance.Value, 0.01f, 0.95f); for (; i < num; i++) { if (!(Random.value < num2)) { break; } } return i; } private static float GetBoarHealthBonus(Character boar, int level) { if ((Object)(object)Instance == (Object)null || level <= 1) { return 0f; } int num = ((!Object.op_Implicit((Object)(object)boar)) ? 1 : Mathf.Max(1, boar.GetLevel())); float num2 = ((num >= 3) ? Instance.TwoStarBoarHealthPerLevel.Value : ((num == 2) ? Instance.OneStarBoarHealthPerLevel.Value : Instance.BoarHealthPerLevel.Value)); float num3 = 0f; for (int i = 2; i <= level; i++) { int num4 = (i - 1) / 5; num3 += num2 + (float)num4 * Instance.BoarHealthIncreaseEveryFiveLevels.Value; } return num3; } private static string GetBoarNameWithoutLevel(Character boar) { string text = (Object.op_Implicit((Object)(object)boar) ? boar.GetHoverName() : "Boar"); int num = text.LastIndexOf(" – Level ", StringComparison.Ordinal); if (num < 0) { num = text.LastIndexOf(" - Level ", StringComparison.Ordinal); } if (num <= 0) { return text; } return text.Substring(0, num); } internal void SetFavouriteForTesting(Character boar) { Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && IsBoar(boar)) { RememberFavourite(boar, localPlayer); } } internal static void EnsureBoarProgression(Character boar) { if (!Object.op_Implicit((Object)(object)boar) || (Object)(object)Instance == (Object)null || !Instance.BoarLevelSystemEnabled.Value || !IsBoar(boar)) { return; } Tameable component = ((Component)boar).GetComponent<Tameable>(); ZNetView component2 = ((Component)boar).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2) || !component2.IsValid()) { return; } ZDO zDO = component2.GetZDO(); int num = zDO.GetInt(BoarLevelKey, 0); if (num <= 0 && component2.IsOwner()) { num = (component.IsTamed() ? 1 : RollWildBoarLevel()); zDO.Set(BoarLevelKey, num, false); zDO.Set(BoarExperienceKey, 0f); } int level = Mathf.Clamp((num <= 0) ? 1 : num, 1, Instance.BoarMaximumLevel.Value); float num2 = zDO.GetFloat(BoarBaseHealthKey, 0f); if (num2 <= 0f) { num2 = boar.GetMaxHealth(); if (component2.IsOwner()) { zDO.Set(BoarBaseHealthKey, num2); } } float num3 = num2 + GetBoarHealthBonus(boar, level); MethodInfo methodInfo = AccessTools.Method(typeof(Character), "SetMaxHealth", new Type[1] { typeof(float) }, (Type[])null); if (methodInfo != null && Mathf.Abs(boar.GetMaxHealth() - num3) > 0.01f) { methodInfo.Invoke(boar, new object[1] { num3 }); } } internal static void AwardBoarExperience(Character boar, float amount) { //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) if (amount <= 0f || !Object.op_Implicit((Object)(object)boar) || (Object)(object)Instance == (Object)null || !Instance.BoarLevelSystemEnabled.Value || !IsBoar(boar)) { return; } Tameable component = ((Component)boar).GetComponent<Tameable>(); ZNetView component2 = ((Component)boar).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsTamed() || !Object.op_Implicit((Object)(object)component2) || !component2.IsValid()) { return; } if (!component2.IsOwner()) { component2.ClaimOwnership(); } if (!component2.IsOwner()) { return; } EnsureBoarProgression(boar); ZDO zDO = component2.GetZDO(); int num = Mathf.Clamp(zDO.GetInt(BoarLevelKey, 1), 1, Instance.BoarMaximumLevel.Value); if (num >= Instance.BoarMaximumLevel.Value) { return; } float num2 = Instance.BoarExperienceRate.Value; Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer)) { float num3 = ((Character)localPlayer).GetSkillFactor((SkillType)110) * 100f; float num4 = 1f + num3 * 0.5f; float num5 = Mathf.Clamp01(Mathf.Max(0f, num4 - (float)num) / 15f) * Instance.BoarCatchUpMultiplier.Value; num2 += num5; } float num6 = zDO.GetFloat(BoarExperienceKey, 0f) + amount * num2; bool flag = false; float maxHealth = boar.GetMaxHealth(); while (num < Instance.BoarMaximumLevel.Value) { float num7 = Instance.BoarBaseExperience.Value * Mathf.Pow(Instance.BoarExperienceGrowth.Value, (float)(num - 1)); if (num6 < num7) { break; } num6 -= num7; num++; flag = true; } zDO.Set(BoarLevelKey, num, false); zDO.Set(BoarExperienceKey, num6); EnsureBoarProgression(boar); if (flag) { boar.Heal(Mathf.Max(0f, boar.GetMaxHealth() - maxHealth), false); } if (flag && Instance.ShowLevelUpEffect.Value && Object.op_Implicit((Object)(object)Player.m_localPlayer)) { string format = ((Localization.instance != null) ? Localization.instance.Localize("$boarriding_level_up_message") : "{0} - reached Level {1}"); ((Character)Player.m_localPlayer).Message((MessageType)2, string.Format(format, GetBoarNameWithoutLevel(boar), num), 0, (Sprite)null, false); FieldInfo fieldInfo = AccessTools.Field(typeof(Tameable), "m_sootheEffect"); object obj = ((fieldInfo != null) ? fieldInfo.GetValue(component) : null); MethodInfo methodInfo = ((obj != null) ? AccessTools.Method(obj.GetType(), "Create", new Type[5] { typeof(Vector3), typeof(Quaternion), typeof(Transform), typeof(float), typeof(int) }, (Type[])null) : null); if (methodInfo != null) { methodInfo.Invoke(obj, new object[5] { ((Component)boar).transform.position, Quaternion.identity, ((Component)boar).transform, 1f, -1 }); } } } private void AwardCommandExperience(Character boar) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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)boar) && !(BoarCommandExperience.Value <= 0f)) { ZDOID zDOID = boar.GetZDOID(); if (!_nextCommandExperience.TryGetValue(zDOID, out var value) || !(Time.time < value)) { _nextCommandExperience[zDOID] = Time.time + 30f; AwardBoarExperience(boar, BoarCommandExperience.Value); } } } private void RemoveFavouriteAnimalPin() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (_favouriteAnimalPin != null && Object.op_Implicit((Object)(object)_favouritePinMap)) { _favouritePinMap.RemovePin(_favouriteAnimalPin); } _favouriteAnimalPin = null; _favouritePinAnimal = ZDOID.None; _favouritePinMap = null; } internal static Sprite LoadModSprite(string filename) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Instance == (Object)null) { return null; } string path = ResolveModAssetPath(Path.Combine("icons", filename)); if (!File.Exists(path)) { return null; } try { Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); MethodInfo methodInfo = AccessTools.Method(typeof(ImageConversion), "LoadImage", new Type[3] { typeof(Texture2D), typeof(byte[]), typeof(bool) }, (Type[])null); if (methodInfo == null || !(bool)methodInfo.Invoke(null, new object[3] { val, File.ReadAllBytes(path), false })) { return null; } ((Object)val).name = Path.GetFileNameWithoutExtension(filename); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); } catch (Exception ex) { LogError("Icon could not be loaded: " + ex.Message); return null; } } private static string ResolveModAssetPath(string relativePath) { string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Instance).Info.Location); string text = Path.Combine(directoryName, relativePath); if (File.Exists(text)) { return text; } return Path.Combine(directoryName, "RideableBoars", relativePath); } private static void CloseCommandWheel(RadialBase radial) { if (Object.op_Implicit((Object)(object)radial)) { AccessTools.Method(typeof(RadialBase), "Close", (Type[])null, (Type[])null).Invoke(radial, new object[1] { true }); } } internal unsafe static string GetLocalizedShortcut(KeyboardShortcut shortcut) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Invalid comparison between Unknown and I4 //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Invalid comparison between Unknown and I4 //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: 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) //IL_00a3: Invalid comparison between Unknown and I4 //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Invalid comparison between Unknown and I4 //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Invalid comparison between Unknown and I4 //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Invalid comparison between Unknown and I4 bool flag = Localization.instance != null && (string.Equals(Localization.instance.GetSelectedLanguage(), "German", StringComparison.OrdinalIgnoreCase) || string.Equals(Localization.instance.GetSelectedLanguage(), "Deutsch", StringComparison.OrdinalIgnoreCase)); List<string> list = new List<string>(); foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if ((int)modifier == 304) { list.Add(flag ? "Umschalt" : "Left Shift"); } else if ((int)modifier == 303) { list.Add(flag ? "Umschalt rechts" : "Right Shift"); } else if ((int)modifier == 306) { list.Add(flag ? "Strg" : "Left Control"); } else if ((int)modifier == 305) { list.Add(flag ? "Strg rechts" : "Right Control"); } else if ((int)modifier == 308) { list.Add(flag ? "Alt" : "Left Alt"); } else if ((int)modifier == 307) { list.Add(flag ? "Alt Gr" : "Right Alt"); } else { list.Add(((object)(*(KeyCode*)(&modifier))/*cast due to .constrained prefix*/).ToString()); } } list.Add(((object)((KeyboardShortcut)(ref shortcut)).MainKey/*cast due to .constrained prefix*/).ToString()); return string.Join(" + ", list.ToArray()); } internal static bool IsBoar(Character character) { if (Object.op_Implicit((Object)(object)character)) { return ((Object)((Component)character).gameObject).name.StartsWith("Boar", StringComparison.OrdinalIgnoreCase); } return false; } internal static bool HasSaddle(Tameable tameable) { if (!Object.op_Implicit((Object)(object)tameable) || !Object.op_Implicit((Object)(object)tameable.m_saddle)) { return false; } MethodInfo methodInfo = AccessTools.Method(typeof(Tameable), "HaveSaddle", (Type[])null, (Type[])null); if (methodInfo != null) { return (bool)methodInfo.Invoke(tameable, null); } return false; } internal bool CommandLastBoar(BoarCommand command) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; switch (command) { case BoarCommand.EjectRider: return EjectFavouriteRider(localPlayer); case BoarCommand.TargetFavourite: ResetLoadedBoarCommands(localPlayer); _commandAllTamedBoars = false; return ShowCommandMessage("$boarriding_scope_favourite"); case BoarCommand.TargetAll: ResetLoadedBoarCommands(localPlayer); _commandAllTamedBoars = true; return ShowCommandMessage("$boarriding_scope_all"); default: { if (_favouriteAnimalDead) { return ShowCommandMessage("$boarriding_favourite_dead_command"); } if (_commandAllTamedBoars) { return CommandAllLoadedBoars(command, localPlayer); } if (!Object.op_Implicit((Object)(object)localPlayer) || ((ZDOID)(ref _lastRiddenBoar)).IsNone()) { return ShowCommandMessage("$boarriding_no_boar"); } GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.FindInstance(_lastRiddenBoar) : null); Tameable val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<Tameable>() : null); Character val3 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<Character>() : null); if ((!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val3) || !IsBoar(val3) || !Object.op_Implicit((Object)(object)val2) || !val2.IsTamed()) && TryResolveFavouriteBoarZdo(localPlayer) != null && Object.op_Implicit((Object)(object)ZNetScene.instance)) { val = ZNetScene.instance.FindInstance(_lastRiddenBoar); } if (!Object.op_Implicit((Object)(object)val) && command == BoarCommand.Recall) { return RecallUnloadedFavouriteBoar(localPlayer); } Tameable val4 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<Tameable>() : null); MonsterAI val5 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<MonsterAI>() : null); if (!Object.op_Implicit((Object)(object)val4) || !val4.IsTamed() || !Object.op_Implicit((Object)(object)val5)) { return ShowCommandMessage("$boarriding_no_boar"); } float num = Vector3.Distance(((Component)localPlayer).transform.position, val.transform.position); if (command == BoarCommand.Follow && num > FollowRange.Value) { return ShowCommandMessage("$boarriding_follow_too_far"); } if (command == BoarCommand.Recall && num > RecallRange.Value) { return ShowCommandMessage("$boarriding_out_of_range"); } if (command != BoarCommand.Wait) { StopOtherBoarsFollowingPlayer(localPlayer, val); } ApplyCommandState(val4, val5, localPlayer, command); AwardCommandExperience(val.GetComponent<Character>()); return ShowCommandMessage(command switch { BoarCommand.Roam => "$boarriding_roaming", BoarCommand.Recall => "$boarriding_recalled", BoarCommand.Wait => "$boarriding_waiting", _ => "$boarriding_following", }); } } } private bool RecallUnloadedFavouriteBoar(Player player) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_003c: 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) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player) || ZDOMan.instance == null) { return ShowCommandMessage("$boarriding_no_boar"); } Vector3 val = (_hasFavouriteLastKnownPosition ? _favouriteLastKnownPosition : ((Component)player).transform.position); float num = Vector3.Distance(((Component)player).transform.position, val); if (num > RecallRange.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Unloaded favourite recall rejected: animal=" + FormatZdoId(_lastRiddenBoar) + ", distance=" + num.ToString("F1", CultureInfo.InvariantCulture) + ", range=" + RecallRange.Value.ToString("F1", CultureInfo.InvariantCulture) + ".")); return ShowCommandMessage("$boarriding_out_of_range"); } ZDO val2 = ZDOMan.instance.GetZDO(_lastRiddenBoar); if (val2 == null || val2.GetPrefab() != StringExtensionMethods.GetStableHashCode("Boar")) { val2 = TryResolveFavouriteBoarZdo(player); } if (val2 == null) { ZDOMan.instance.RequestZDO(_lastRiddenBoar); ((BaseUnityPlugin)this).Logger.LogWarning((object)("Favourite recall could not resolve boar " + FormatZdoId(_lastRiddenBoar) + " in world " + _favouriteWorldUid + ". A ZDO request was sent.")); return ShowCommandMessage("$boarriding_no_boar"); } val = val2.GetPosition(); Vector3 val3 = ((Component)player).transform.position - ((Component)player).transform.forward * 3f + ((Component)player).transform.right * 1.5f; float num2 = default(float); if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(val3, ref num2)) { val3.y = num2 + 0.2f; } else { val3.y = ((Component)player).transform.position.y + 0.2f; } val2.SetPosition(val3); _favouriteLastKnownPosition = val3; _hasFavouriteLastKnownPosition = true; SaveFavourite(); if (_favouriteAnimalPin != null) { _favouriteAnimalPin.m_pos = val3; } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Recalled unloaded favourite boar " + FormatZdoId(_lastRiddenBoar) + " from " + ((Vector3)(ref val)).ToString("F1") + " to " + ((Vector3)(ref val3)).ToString("F1") + ".")); return ShowCommandMessage("$boarriding_recalled"); } private ZDO TryResolveFavouriteBoarZdo(Player player) { //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: 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_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) if (ZDOMan.instance == null || !_hasFavouriteLastKnownPosition) { return null; } List<ZDO> list = new List<ZDO>(); int num = 0; while (!ZDOMan.instance.GetAllZDOsWithPrefabIterative("Boar", list, ref num)) { } string text = StripBoarLevelSuffix(_favouriteAnimalName); ZDO val = null; float num2 = float.MaxValue; foreach (ZDO item in list) { if (item == null || !item.IsValid() || !item.GetBool(ZDOVars.s_tamed, false)) { continue; } if (((ZDOID)(ref item.m_uid)).Equals(_lastRiddenBoar) && (Object)(object)ZNetScene.instance != (Object)null) { GameObject val2 = ZNetScene.instance.FindInstance(item.m_uid); Character character = (Object.op_Implicit((Object)(object)val2) ? val2.GetComponent<Character>() : null); Tameable val3 = (Object.op_Implicit((Object)(object)val2) ? val2.GetComponent<Tameable>() : null); if (Object.op_Implicit((Object)(object)val2) && (!IsBoar(character) || !Object.op_Implicit((Object)(object)val3) || !val3.IsTamed())) { continue; } } string a = item.GetString(ZDOVars.s_tamedName, string.Empty); bool flag = !string.IsNullOrEmpty(text) && string.Equals(a, text, StringComparison.OrdinalIgnoreCase); bool flag2 = Object.op_Implicit((Object)(object)player) && item.GetLong(FavouriteOwnerKey, 0L) == player.GetPlayerID(); float num3 = Vector3.Distance(_favouriteLastKnownPosition, item.GetPosition()); if (flag || flag2 || (string.IsNullOrEmpty(text) && !(num3 > 8f))) { float num4 = num3 + (flag ? 0f : 1000f) + (flag2 ? 0f : 100f); if (!(num4 >= num2)) { val = item; num2 = num4; } } } if (val == null) { return null; } ZDOID lastRiddenBoar = _lastRiddenBoar; _lastRiddenBoar = val.m_uid; _lastRiddenAnimal = val.m_uid; _favouriteLastKnownPosition = val.GetPosition(); _hasFavouriteLastKnownPosition = true; SaveFavourite(logDetails: true); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Resolved favourite boar ZDO from " + FormatZdoId(lastRiddenBoar) + " to " + FormatZdoId(val.m_uid) + " by persistent world data.")); return val; } private static string StripBoarLevelSuffix(string name) { if (string.IsNullOrEmpty(name)) { return string.Empty; } int num = name.LastIndexOf(" – Level ", StringComparison.Ordinal); if (num < 0) { num = name.LastIndexOf(" - Level ", StringComparison.Ordinal); } if (num <= 0) { return name; } return name.Substring(0, num); } private bool EjectFavouriteRider(Player player) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player) || ((ZDOID)(ref _lastRiddenBoar)).IsNone() || (Object)(object)ZNetScene.instance == (Object)null) { return ShowCommandMessage("$boarriding_no_boar"); } GameObject val = ZNetScene.instance.FindInstance(_lastRiddenBoar); Character val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<Character>() : null); ZNetView val3 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ZNetView>() : null); if (!Object.op_Implicit((Object)(object)val2) || !IsBoar(val2) || !Object.op_Implicit((Object)(object)val3) || !val3.IsValid()) { return ShowCommandMessage("$boarriding_no_boar"); } if (val3.GetZDO().GetLong(FavouriteOwnerKey, 0L) != player.GetPlayerID()) { return ShowCommandMessage("$boarriding_not_owner"); } long num = val3.GetZDO().GetLong(ZDOVars.s_user, 0L); if (num != 0L) { ZDOID zDOID = ((Character)player).GetZDOID(); if (num != ((ZDOID)(ref zDOID)).UserID) { EnsureKickRpcRegistered(); if (_registeredKickRpc == null) { return ShowCommandMessage("$boarriding_no_other_rider"); } _registeredKickRpc.InvokeRoutedRPC(num, "RideableBoars_KickRider", new object[2] { _lastRiddenBoar, player.GetPlayerID() }); return ShowCommandMessage("$boarriding_eject_sent"); } } return ShowCommandMessage("$boarriding_no_other_rider"); } private static void StopOtherBoarsFollowingPlayer(Player player, GameObject favourite) { foreach (Character allCharacter in Character.GetAllCharacters()) { if (!IsBoar(allCharacter) || (Object)(object)((Component)allCharacter).gameObject == (Object)(object)favourite) { continue; } Tameable component = ((Component)allCharacter).GetComponent<Tameable>(); MonsterAI component2 = ((Component)allCharacter).GetComponent<MonsterAI>(); if (Object.op_Implicit((Object)(object)component) && component.IsTamed() && Object.op_Implicit((Object)(object)component2) && (Object)(object)component2.GetFollowTarget() == (Object)(object)((Component)player).gameObject) { BoarWaitState boarWaitState = ((Component)allCharacter).GetComponent<BoarWaitState>(); if (!Object.op_Implicit((Object)(object)boarWaitState)) { boarWaitState = ((Component)allCharacter).gameObject.AddComponent<BoarWaitState>(); } boarWaitState.Waiting = true; boarWaitState.FreeRoam = false; component.Command((Humanoid)(object)player, false); } } } private static void ResetLoadedBoarCommands(Player player) { if (!Object.op_Implicit((Object)(object)player)) { return; } foreach (Character allCharacter in Character.GetAllCharacters()) { if (!IsBoar(allCharacter)) { continue; } Tameable component = ((Component)allCharacter).GetComponent<Tameable>(); MonsterAI component2 = ((Component)allCharacter).GetComponent<MonsterAI>(); if (Object.op_Implicit((Object)(object)component) && component.IsTamed() && Object.op_Implicit((Object)(object)component2) && (Object)(object)component2.GetFollowTarget() == (Object)(object)((Component)player).gameObject) { BoarWaitState boarWaitState = ((Component)allCharacter).GetComponent<BoarWaitState>(); if (!Object.op_Implicit((Object)(object)boarWaitState)) { boarWaitState = ((Component)allCharacter).gameObject.AddComponent<BoarWaitState>(); } boarWaitState.Waiting = true; component.Command((Humanoid)(object)player, false); } } } private bool CommandAllLoadedBoars(BoarCommand command, Player player) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player)) { return false; } int num = 0; foreach (Character allCharacter in Character.GetAllCharacters()) { if (!IsBoar(allCharacter)) { continue; } Tameable component = ((Component)allCharacter).GetComponent<Tameable>(); MonsterAI component2 = ((Component)allCharacter).GetComponent<MonsterAI>(); if (Object.op_Implicit((Object)(object)component) && component.IsTamed() && Object.op_Implicit((Object)(object)component2)) { float num2 = Vector3.Distance(((Component)player).transform.position, ((Component)allCharacter).transform.position); if ((command != BoarCommand.Follow || !(num2 > FollowRange.Value)) && (command != BoarCommand.Recall || !(num2 > RecallRange.Value))) { ApplyCommandState(component, component2, player, command); AwardCommandExperience(allCharacter); num++; } } } if (num == 0) { return ShowCommandMessage("$boarriding_no_loaded_boars"); } return ShowCommandMessage(command switch { BoarCommand.Roam => "$boarriding_roaming", BoarCommand.Wait => "$boarriding_waiting", _ => "$boarriding_following", }); } private static void ApplyCommandState(Tameable tameable, MonsterAI ai, Player player, BoarCommand command) { BoarWaitState boarWaitState = ((Component)tameable).GetComponent<BoarWaitState>(); if (!Object.op_Implicit((Object)(object)boarWaitState)) { boarWaitState = ((Component)tameable).gameObject.AddComponent<BoarWaitState>(); } if (command == BoarCommand.Roam) { boarWaitState.Waiting = false; boarWaitState.FreeRoam = true; if ((Object)(object)ai.GetFollowTarget() == (Object)(object)((Component)player).gameObject) { tameable.Command((Humanoid)(object)player, false); } ((BaseAI)ai).ResetPatrolPoint(); return; } boarWaitState.Waiting = command == BoarCommand.Wait; boarWaitState.FreeRoam = false; GameObject followTarget = ai.GetFollowTarget(); bool flag = command != BoarCommand.Wait; bool flag2 = (Object)(object)followTarget == (Object)(object)((Component)player).gameObject; if ((flag && !flag2) || (!flag && (Object)(object)followTarget != (Object)null)) { tameable.Command((Humanoid)(object)player, false); } } private static bool ShowCommandMessage(string text) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { ((Character)Player.m_localPlayer).Message((MessageType)2, text, 0, (Sprite)null, false); } return true; } private void OnD