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 Bretaheim v0.3.3
plugins/Bretaheim/Bretaheim.dll
Decompiled 8 hours 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.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Bretaheim.Data; using Bretaheim.DevTools; using Bretaheim.WorldGen; using Bretaheim.WorldGen.Core; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using SoftReferenceableAssets; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Bretaheim")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+f3a4c989d38b33dd892947fe2cbae2cc85bfc7be")] [assembly: AssemblyProduct("Bretaheim")] [assembly: AssemblyTitle("Bretaheim")] [assembly: AssemblyVersion("1.0.0.0")] namespace Bretaheim { [BepInPlugin("tarbaby.bretaheim", "Bretaheim", "0.3.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "tarbaby.bretaheim"; public const string PluginName = "Bretaheim"; public const string PluginVersion = "0.3.3"; private Harmony harmony; public static Plugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } public static U5Data U5 { get; private set; } public static ConfigEntry<string> U5Directory { get; private set; } public static ConfigEntry<float> TileMetres { get; private set; } public static ConfigEntry<bool> NewWorldsAreBritannia { get; private set; } public static ConfigEntry<string> DumpPieceGeometry { get; private set; } public static ConfigEntry<bool> SelfTest { get; private set; } public static ConfigEntry<bool> LogHitches { get; private set; } public static ConfigEntry<string> BuildSettlements { get; private set; } public static ConfigEntry<string> CombinedShells { get; private set; } public static ConfigEntry<int> SpawnLocation { get; private set; } public static string PluginDirectory { get; private set; } = ""; private void Awake() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? ""; U5Directory = ((BaseUnityPlugin)this).Config.Bind<string>("General", "UltimaVDirectory", "", "Folder of your own copy of Ultima V (e.g. the GOG install) containing DATA.OVL, BRIT.DAT, TOWNE.DAT, ... The mod reads the world, towns, people and conversations from it at start-up; no Ultima V data ships with the mod."); TileMetres = ((BaseUnityPlugin)this).Config.Bind<float>("World", "TileMetres", 32f, new ConfigDescription("Size of one Ultima V tile in metres (32 = Britannia is an 8.2 km square). Must be the same on the server and every client.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(8f, 36f), Array.Empty<object>())); NewWorldsAreBritannia = ((BaseUnityPlugin)this).Config.Bind<bool>("World", "NewWorldsAreBritannia", true, "New worlds get a seed starting with \"Britannia\", which makes them Britannia. A world is Britannia exactly when its seed starts with \"Britannia\"; worlds with other seeds stay vanilla."); BuildSettlements = ((BaseUnityPlugin)this).Config.Bind<string>("World", "BuildSettlements", "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32", "Location numbers of the settlements built from their maps in new Britannia worlds (2 Britain, 4 Yew, 13 Iolo's hut, 17 Lord British's castle, 19-21 West, North and East Britanny, 25 Ararat in the Underworld; see 'u5 dump locations'). Must be the same on the server and every client."); CombinedShells = ((BaseUnityPlugin)this).Config.Bind<string>("World", "CombinedShells", "*", "Settlements whose building shells (walls, floors, roofs) are built as one combined object per zone instead of thousands of separate pieces (* = all of them). Must match on every peer."); SpawnLocation = ((BaseUnityPlugin)this).Config.Bind<int>("World", "SpawnLocation", 13, "Where players first appear in a new Britannia world: 13 = inside Iolo's hut (the game's start), or the location number of a built settlement to start just outside it (2 = Britain). Read by whoever creates the world (the server, or the host); existing worlds keep their spawn."); DumpPieceGeometry = ((BaseUnityPlugin)this).Config.Bind<string>("Development", "DumpPieceGeometry", "", "Comma-separated prefab names (or *) whose snap points and bounds are written to BepInEx/u5_piece_geometry.json at start-up. Leave empty."); SelfTest = ((BaseUnityPlugin)this).Config.Bind<bool>("Development", "SelfTest", false, "Log development self-checks at start-up. Leave off."); LogHitches = ((BaseUnityPlugin)this).Config.Bind<bool>("Development", "LogHitches", true, "Log every frame over 150 ms (\"hitch\") with what ran in it: zone spawning, terrain, object creation, settlement pieces, townsfolk, structures."); harmony = new Harmony("tarbaby.bretaheim"); PieceGeometryDump.Install(harmony); U5Command.Install(harmony); if (!LoadU5Data()) { Log.LogError((object)("Bretaheim is disabled until UltimaVDirectory points at an Ultima V install (edit " + ((BaseUnityPlugin)this).Config.ConfigFilePath + " and restart).")); return; } harmony.PatchAll(); WorldGenPatches.Install(harmony); if (WorldGenPatches.Installed) { WorldSize.Install(harmony); Underworld.Install(harmony); Whirlpool.Register(); TownFurniture.Install(harmony); Whirlpool.Install(harmony); ((Component)this).gameObject.AddComponent<UnderworldWatch>(); PlaceMarkers.Install(harmony); Settlements.Install(harmony); Structures.Register(); TownsfolkSpawner.Register(); Ballistas.Register(); Ettin.Register(); Camp.Register(); Ladders.Register(); Furnishings.Register(); Stairs.Register(); Dungeons.Register(); UltimaItems.Register(); SpellStatus.Register(); Treasure.Register(); TalkPanel.Install(harmony); ShopTrading.Install(harmony); BigInventory.Install(harmony); PouchPanel.Install(harmony); StartingGold.Install(harmony); TownWatch.Install(harmony); TownsfolkPatches.Install(harmony); UltimaCreatures.Install(harmony); AvatarStats.Install(harmony); Ballistas.Install(harmony); Crime.Install(harmony); TownDoors.Install(harmony); CreatureTalker.Install(harmony); ResidentMonster.Install(harmony); Sleep.Install(harmony); Respawn.Install(harmony); Stage.Install(harmony); TerrainQueue.Install(harmony); Dungeons.Install(harmony); Treasure.Install(harmony); UseItems.Install(harmony); WornEffects.Install(harmony); MagicCarpet.Register(); Horses.Register(); Horses.Install(harmony); Vessels.Install(harmony); ((Component)this).gameObject.AddComponent<TransportWatch>(); ((Component)this).gameObject.AddComponent<WornEffects.Tick>(); ((Component)this).gameObject.AddComponent<BlackthornGuards>(); BlackthornCapture.Install(harmony); ((Component)this).gameObject.AddComponent<Endgame.Watch>(); Moongates.Install(harmony); Shadowlords.Install(harmony); ((Component)this).gameObject.AddComponent<MoongateKeeper>(); ((Component)this).gameObject.AddComponent<ShadowlordWatch>(); KarmaDeeds.Install(harmony); RationsWatch.Install(harmony); Restrictions.Install(harmony); Intro.Install(harmony); IolosHut.Install(harmony); Spells.Install(harmony); Shrines.Install(harmony); Furnishings.Install(harmony); Stairs.Install(harmony); if (LogHitches.Value) { LoadProfiler.Install(harmony); } ((Component)this).gameObject.AddComponent<Crime.Watch>(); ((Component)this).gameObject.AddComponent<Camp.Keys>(); ((Component)this).gameObject.AddComponent<Spells.Keys>(); ((Component)this).gameObject.AddComponent<RationsWatch>(); ((Component)this).gameObject.AddComponent<Restrictions.ToolWatch>(); ((Component)this).gameObject.AddComponent<IolosHut.Keeper>(); ((Component)this).gameObject.AddComponent<UltimaSpawner>(); FixedPieces.Install(harmony); BiomeBlend.Install(harmony); RiverBanks.Install(harmony); Bridges.Install(harmony); ((Component)this).gameObject.AddComponent<WorldWrap>(); ((Component)this).gameObject.AddComponent<DungeonRunner>(); if (SelfTest.Value) { ((Component)this).gameObject.AddComponent<TownsfolkSelfTest>(); } if (LogHitches.Value) { ((Component)this).gameObject.AddComponent<LoadProfiler>(); } } Log.LogInfo((object)"Bretaheim v0.3.3 loaded."); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } private static bool LoadU5Data() { string value = U5Directory.Value; if (string.IsNullOrWhiteSpace(value)) { Log.LogError((object)"UltimaVDirectory is not set."); return false; } value = Environment.ExpandEnvironmentVariables(value.Trim()); if (value.StartsWith("~")) { value = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + value.Substring(1); } List<string> list = U5Data.Validate(value); if (list.Count > 0) { Log.LogError((object)("UltimaVDirectory '" + value + "' is not a usable Ultima V install; missing: " + string.Join(", ", list))); return false; } try { Stopwatch stopwatch = Stopwatch.StartNew(); U5 = U5Data.Load(value); Log.LogInfo((object)($"Read Ultima V from '{value}' in {stopwatch.ElapsedMilliseconds} ms: " + $"{U5.Locations.Length} locations, {U5.DungeonRooms.Count} dungeon rooms.")); return true; } catch (Exception ex) when (ex is IOException || ex is U5FormatException || ex is IndexOutOfRangeException) { Log.LogError((object)("Could not read Ultima V from '" + value + "': " + ex.Message)); return false; } } } public static class U5Command { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__1_0; public static Func<string, int, bool> <>9__2_2; internal void <InitTerminal_Postfix>b__1_0(ConsoleEventArgs args) { Run(args.Context, args.Args.Skip(1).ToArray()); } internal bool <Run>b__2_2(string _, int i) { return i != 1; } } public static void Install(Harmony harmony) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(Terminal), "InitTerminal", (Type[])null, (Type[])null); if (methodInfo == null) { Plugin.Log.LogError((object)"Terminal.InitTerminal not found: the u5 console command is unavailable"); } else { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(U5Command), "InitTerminal_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void InitTerminal_Postfix() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown object obj = <>c.<>9__1_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { Run(args.Context, args.Args.Skip(1).ToArray()); }; <>c.<>9__1_0 = val; obj = (object)val; } new ConsoleCommand("u5", "Ultima V data: u5 dump <locations|map|npcs|talk|items|monsters|spells|...> [args]; u5 encounter [type [body]] (devcommands) brings a random encounter, or one creature of that type before you (in that Valheim body); u5 play <notes> plays the harpsichord you stand at; u5 press next|skip|<letter>|<button> presses on the Ultima screens and the talk panel; u5 key cast|mix|close and u5 mix <spell> [n] do the magic keys, u5 pouch [give reagent|spell <i> <n> | ready <spell>] the reagents and spells held, u5 type <text> answers the open text box (tests); u5 intro [fast] [2d | scene] replays the introduction (in the world, from scene 0..3, or the original's screens; fast: four times as fast); u5 karma [n]; u5 exp [n] (setting needs devcommands); u5 unmake (devcommands) to meet Hildir again; u5 time | moons | dusk | dawn | midnight: Britannia's clock, moons and moongates; u5 dungeon <name> (devcommands) takes you to a dungeon entrance; u5 quest: the state of the quest; u5 resurrect [2d], u5 blackthorn and u5 endgame [box] (devcommands) play Blackthorn's interrogation and Lord British's rescue; u5 under [<x> <y> | surface <x> <y> | falls | whirlpool | doom | ararat | <dungeon>] where you are, or (devcommands) to the Underworld; u5 vessel frigate|skiff|pirates|horse (devcommands) brings one", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } private static void Run(Terminal terminal, string[] args) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0241: 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) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_0770: Unknown result type (might be due to invalid IL or missing references) //IL_0781: Unknown result type (might be due to invalid IL or missing references) //IL_0645: Unknown result type (might be due to invalid IL or missing references) //IL_0651: Unknown result type (might be due to invalid IL or missing references) //IL_0664: Unknown result type (might be due to invalid IL or missing references) //IL_0672: Unknown result type (might be due to invalid IL or missing references) //IL_06a1: Unknown result type (might be due to invalid IL or missing references) //IL_06ad: Unknown result type (might be due to invalid IL or missing references) if (args.Length > 1 && args[0] == "vessel") { Player localPlayer = Player.m_localPlayer; if (!Terminal.m_cheat) { Print("u5 vessel needs devcommands"); return; } if ((Object)(object)localPlayer == (Object)null || Britannia.Active == null) { Print("u5 vessel: only in Britannia"); return; } Vector3 val = ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward * 25f; switch (args[1]) { case "frigate": case "skiff": { bool flag = args[1] == "frigate"; GameObject val2 = Vessels.Spawn(flag, val, ((Component)localPlayer).transform.eulerAngles.y, localPlayer.GetPlayerID(), localPlayer.GetPlayerName(), flag ? Shops.SkiffsAboard(130) : 0); Print(((Object)(object)val2 != (Object)null) ? $"a {args[1]} at {val}" : "no such vessel"); break; } case "pirates": Print(Pirates.Spawn(((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward * 70f, new Random()) ?? "no deep water 70 m ahead"); break; case "horse": { Print(Horses.Buy(localPlayer, out var where) ? ("a horse " + where) : "no room for a horse here"); break; } default: Print("u5 vessel frigate|skiff|pirates|horse"); break; } return; } if (args.Length != 0 && args[0] == "encounter") { Player localPlayer2 = Player.m_localPlayer; int result; if (!Terminal.m_cheat) { Print("u5 encounter needs devcommands"); } else if ((Object)(object)localPlayer2 == (Object)null || Britannia.Active == null) { Print("u5 encounter: only in Britannia"); } else if (args.Length > 1 && int.TryParse(args[1], out result)) { Character val3 = UltimaCreatures.Spawn(result, ((Component)localPlayer2).transform.position + ((Component)localPlayer2).transform.forward * 6f + Vector3.up, wild: false, (args.Length > 2) ? args[2] : null); Print(((Object)(object)val3 != (Object)null) ? (val3.m_name + " (" + Utils.GetPrefabName(((Component)val3).gameObject) + ")") : $"no body for creature type {result}"); } else { Print(UltimaSpawner.Encounter(((Component)localPlayer2).transform.position, localPlayer2.GetPlayerName(), new Random()) ?? "nothing comes here (no monster for this land, a town, or 8 already near)"); } return; } if (args.Length > 1 && args[0] == "press") { foreach (string item in args.Skip(1)) { if (!UltimaScreenPanel.Press(item.ToLowerInvariant()) && !TalkPanel.Press(item.Replace('_', ' '))) { Print("u5 press: " + item + " is not offered"); break; } } return; } int result4; if (args.Length > 1 && (args[0] == "key" || args[0] == "mix")) { Player localPlayer3 = Player.m_localPlayer; if ((Object)(object)localPlayer3 == (Object)null) { return; } int result2; int result3; if (args[0] == "key" && args[1] == "cast") { Spells.CastReadied(localPlayer3); } else if (args[0] == "key" && args[1] == "close") { MixPanel.Close(); SkyPanel.Close(); UltimaScreenPanel.Close(); } else if (args[0] == "key" && args[1] == "mix") { if (Spells.NearFire(((Component)localPlayer3).transform.position)) { MixPanel.Open(localPlayer3); } else { Print("u5 key mix: no fire near"); } } else if (!(args[0] == "mix") || !int.TryParse(args[1], out result2) || !MixPanel.Choose(result2, (args.Length <= 2 || !int.TryParse(args[2], out result3)) ? 1 : result3)) { Print("u5 key cast|mix|close; u5 mix <spell 0-47> [count] with the mixing panel open"); } } else if (args.Length != 0 && args[0] == "pouch") { if (Plugin.U5 == null) { Print("Ultima V data is not loaded"); } else { Print(PouchPanel.Command(args)); } } else if (args.Length > 1 && args[0] == "scroll" && int.TryParse(args[1], out result4)) { BigInventory.ScrollTo(result4); } else if (args.Length > 1 && args[0] == "type") { if (!UltimaScreenPanel.Type(string.Join(" ", args.Skip(1)))) { if (!TextInput.IsVisible() || (Object)(object)TextInput.instance == (Object)null) { Print("u5 type: no text box open"); return; } TextInput instance = TextInput.instance; AccessTools.Method(typeof(TextInput), "setText", (Type[])null, (Type[])null)?.Invoke(instance, new object[1] { string.Join(" ", args.Skip(1)) }); instance.Hide(); } } else if (args.Length != 0 && args[0] == "under") { Underworld.Command(args, Print); } else if (args.Length != 0 && args[0] == "dungeon") { Player localPlayer4 = Player.m_localPlayer; int result5; int num = ((args.Length <= 1) ? (-1) : (int.TryParse(args[1], out result5) ? result5 : ((Plugin.U5?.FindLocation(args[1])?.Number).GetValueOrDefault() - 33))); Vector2? val4 = Dungeons.Centre(num); if (!Terminal.m_cheat) { Print("u5 dungeon needs devcommands"); return; } if ((Object)(object)localPlayer4 == (Object)null || !val4.HasValue) { Print("u5 dungeon <Deceit|Despise|Destard|Wrong|Covetous|Shame|Hythloth>: only in Britannia"); return; } BritanniaShape britanniaShape = Britannia.ShapeAt(val4.Value.x, val4.Value.y); float x = val4.Value.x; float num2 = val4.Value.y - 9f; ((Character)localPlayer4).TeleportTo(new Vector3(x, 30f + britanniaShape.Height(x, num2) + 1f, num2), ((Component)localPlayer4).transform.rotation, true); Print("to " + Dungeons.Name(num) + ": say " + Plugin.U5.Ovl.WordsOfPower[num] + " near its door to open it"); } else if (args.Length != 0 && args[0] == "play") { Player me = Player.m_localPlayer; Harpsichord harpsichord = (((Object)(object)me == (Object)null) ? null : (from h in Object.FindObjectsByType<Harpsichord>((FindObjectsSortMode)0) orderby Vector3.Distance(((Component)h).transform.position, ((Component)me).transform.position) select h).FirstOrDefault()); if ((Object)(object)harpsichord == (Object)null || Vector3.Distance(((Component)harpsichord).transform.position, ((Component)me).transform.position) > 5f) { Print("u5 play: no harpsichord here"); } else { harpsichord.SetText(string.Join("", args.Skip(1))); } } else { if ((Plugin.U5 != null && ClockCommands.Run(args, Print)) || (Plugin.U5 != null && StoryCommands.Run(args, Print))) { return; } if (args.Length != 0 && (args[0] == "intro" || args[0] == "karma" || args[0] == "exp" || args[0] == "unmake")) { Player localPlayer5 = Player.m_localPlayer; int result7; if ((Object)(object)localPlayer5 == (Object)null || Britannia.Active == null) { Print("u5 " + args[0] + ": only in Britannia"); } else if (args[0] == "intro" && args.Length > 2 && args[1] == "hide") { Print(IntroStage.Toggle(args[2])); } else if (args[0] == "intro") { if (args.Length > 1 && args[1] == "fast") { IntroStage.Speed = 4f; args = args.Where((string _, int i) => i != 1).ToArray(); } ((MonoBehaviour)Plugin.Instance).StartCoroutine(Intro.Play(args.Length > 1 && args[1] == "2d", (args.Length > 1 && int.TryParse(args[1], out var result6)) ? result6 : 0)); } else if (args[0] == "karma" && args.Length > 1 && Terminal.m_cheat && int.TryParse(args[1], out result7)) { Karma.Set(localPlayer5.m_customData, result7); Print($"karma {Karma.Get(localPlayer5.m_customData)}"); } else if (args[0] == "karma") { Print(string.Format("karma {0}{1}", KarmaDeeds.Of(localPlayer5), KarmaDeeds.WearsAnkh(localPlayer5) ? $" ({Karma.Get(localPlayer5.m_customData)} and the Ankh's {10})" : "")); } else if (args[0] == "exp") { Avatar mine = AvatarStats.Mine; if (args.Length > 1 && Terminal.m_cheat && int.TryParse(args[1], out var result8)) { mine.Experience = Math.Max(0, Math.Min(9999, result8)); mine.Save(localPlayer5.m_customData); } Print($"experience {mine.Experience}, level {mine.Level}, {mine.MaxHitPoints} hit points, mana {mine.Mana}"); } else if (!Terminal.m_cheat) { Print("u5 unmake needs devcommands"); } else { Avatar mine2 = AvatarStats.Mine; mine2.Made = false; mine2.Strength = (mine2.Dexterity = (mine2.Intelligence = (mine2.Mana = 0))); mine2.Save(localPlayer5.m_customData); Print("the Avatar is unmade: speak with Hildir in Iolo's hut"); } return; } if (args.Length == 0 || args[0] != "dump") { Print("u5 dump <what> [args]\n locations the 40 places with map file, floors and overworld position\n map <location> [z] a settlement floor as tile ids (hex)\n npcs <location> NPCs: type, dialogue, schedule\n talk <location> <slot> an NPC's conversation decoded\n items equipment names, attack/defence/range/price\n monsters creature names and raw stats\n spells | reagents | virtues | words\n dungeon <0-7|name> <level> [plan] DUNGEON.DAT cells; plan: the level as built (88x88 tiles), its rooms\n room <index> | room <dungeon> <n> a DUNGEON.CBT room (11x11 + metadata), by file index or by dungeon\n world <x> <y> [w] [h] [under] overworld tile ids\n tiles [from] [count] LOOK2.DAT tile names\n signs [location] SIGNS.DAT\n init INIT.GAM: party, inventory, karma, date, position"); return; } if (Plugin.U5 != null) { try { Print(Dump.Run(Plugin.U5, args.Skip(1).ToArray())); return; } catch (Exception ex) { Print("error: " + ex.Message); return; } } Print("Ultima V data is not loaded: set UltimaVDirectory in BepInEx/config/tarbaby.bretaheim.cfg and restart."); } void Print(string text) { string[] array = text.TrimEnd('\n').Split('\n'); foreach (string text2 in array) { terminal.AddString(text2); } } } } } namespace Bretaheim.WorldGen { public static class AvatarStats { private const string ExperienceRpc = "U5_Experience"; private static readonly Random random = new Random(); private static readonly int[] comfort = new int[9] { SEMan.s_statusEffectRested, SEMan.s_statusEffectResting, SEMan.s_statusEffectWet, SEMan.s_statusEffectCold, SEMan.s_statusEffectFreezing, SEMan.s_statusEffectShelter, SEMan.s_statusEffectCampFire, SEMan.s_statusEffectSoftDeath, StringExtensionMethods.GetStableHashCode("CorpseRun") }; private static Player Me => Player.m_localPlayer; private static bool Active => Britannia.Active != null; public static Avatar Mine { get { if (!((Object)(object)Me != (Object)null)) { return new Avatar(); } return Avatar.Load(Me.m_customData); } } public static void Install(Harmony harmony) { //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Expected O, but got Unknown //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Expected O, but got Unknown //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Expected O, but got Unknown Patch(harmony, typeof(Player), "SetMaxHealth", "SetMaxHealth_Prefix"); Patch(harmony, typeof(Player), "SetSleeping", null, "SetSleeping_Postfix"); Patch(harmony, typeof(Character), "OnDeath", "OnDeath_Prefix"); Patch(harmony, typeof(SkillsDialog), "Setup", null, "SkillsSetup_Postfix"); Patch(harmony, typeof(Skills), "RaiseSkill", "RaiseSkill_Prefix"); Patch(harmony, typeof(Skills), "GetSkillLevel", "GetSkillLevel_Prefix"); Patch(harmony, typeof(Skills), "OnDeath", "RaiseSkill_Prefix"); MethodInfo methodInfo = AccessTools.Method(typeof(SEMan), "AddStatusEffect", new Type[5] { typeof(int), typeof(bool), typeof(int), typeof(float), typeof(short) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(SEMan), "AddStatusEffect", new Type[5] { typeof(StatusEffect), typeof(bool), typeof(int), typeof(float), typeof(short) }, (Type[])null); if (methodInfo != null) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(AvatarStats), "AddStatusEffectHash_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodInfo2 != null) { harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(AvatarStats), "AddStatusEffect_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodInfo == null || methodInfo2 == null) { Plugin.Log.LogWarning((object)"Avatar stats: SEMan.AddStatusEffect not found (Valheim's Rested stays)"); } Patch(harmony, typeof(Game), "Start", null, "GameStart_Postfix"); Patch(harmony, typeof(Player), "OnSpawned", null, "OnSpawned_Postfix"); Patch(harmony, typeof(Player), "RPC_UseStamina", "UseStamina_Prefix"); Patch(harmony, typeof(Bed), "Interact", "BedInteract_Prefix"); Patch(harmony, typeof(Bed), "GetHoverText", "BedHover_Prefix"); Patch(harmony, typeof(Hud), "UpdateHealth", null, "UpdateHealth_Postfix"); MethodInfo methodInfo3 = AccessTools.Method(typeof(DamageText), "ShowText", new Type[4] { typeof(TextType), typeof(Vector3), typeof(float), typeof(bool) }, (Type[])null); if (methodInfo3 != null) { harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(AvatarStats), "ShowText_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { Plugin.Log.LogWarning((object)"Avatar stats: DamageText.ShowText not found"); } } private static void Patch(Harmony h, Type t, string m, string prefix = null, string postfix = null) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) MethodInfo methodInfo = AccessTools.Method(t, m, (!(t == typeof(Player)) || !(m == "SetMaxHealth")) ? null : new Type[2] { typeof(float), typeof(bool) }, (Type[])null); if (methodInfo == null) { Plugin.Log.LogWarning((object)("Avatar stats: " + t.Name + "." + m + " not found")); } else { h.Patch((MethodBase)methodInfo, (prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(AvatarStats), prefix, (Type[])null), (postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(AvatarStats), postfix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void SetMaxHealth_Prefix(Player __instance, ref float health) { if (Active && !((Object)(object)__instance != (Object)(object)Me)) { health = (float)Mine.MaxHitPoints * 10f; } } private static void UpdateHealth_Postfix(Hud __instance, Player player) { if (Active && (Object)(object)player != (Object)null) { __instance.m_healthText.text = Mathf.CeilToInt(((Character)player).GetHealth() / 10f).ToString(); } } private static void ShowText_Prefix(ref float dmg) { if (Active) { dmg /= 10f; } } private static bool UseStamina_Prefix() { return !Active; } private static bool TownBed(Bed bed) { if (Active) { return (Object)(object)((Component)bed).GetComponentInParent<U5Fixed>() != (Object)null; } return false; } private static bool BedInteract_Prefix(Bed __instance, Humanoid human, bool repeat, ref bool __result) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) if (!TownBed(__instance)) { return true; } __result = false; if (repeat) { return false; } Player val = (Player)(object)((human is Player) ? human : null); if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer) { if (Inns.MayRest(val, __instance, out var why)) { Sleep.LieDown(val, ((Object)(object)__instance.m_spawnPoint != (Object)null) ? __instance.m_spawnPoint : ((Component)__instance).transform, ((Component)__instance).gameObject); return false; } if (why != null) { Plugin.Log.LogInfo((object)("Inn bed refused: " + why)); } } Player val2 = (Player)(object)((human is Player) ? human : null); if (val2 != null && (Object)(object)val2 == (Object)(object)Player.m_localPlayer) { Searching.Search(((Component)__instance).transform.position, 2.3f, 35274, val2); } __result = true; return false; } private static bool BedHover_Prefix(Bed __instance, ref string __result) { if (!TownBed(__instance)) { return true; } Player localPlayer = Player.m_localPlayer; __result = Localization.instance.Localize(__instance.GetHoverName() + (((Object)(object)localPlayer != (Object)null && Inns.MayRest(localPlayer, __instance)) ? "\n[<color=yellow><b>$KEY_Use</b></color>] Sleep" : "\n[<color=yellow><b>$KEY_Use</b></color>] Search")); return false; } public static int WeaponAttack(Player player) { ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); object obj; if (currentWeapon == null) { obj = null; } else { GameObject dropPrefab = currentWeapon.m_dropPrefab; obj = ((dropPrefab != null) ? ((Object)dropPrefab).name : null); } string text = (string)obj; int num = ((text != null && currentWeapon != ((Humanoid)player).m_unarmedWeapon?.m_itemData) ? ShopTrading.Items.EquipmentOf(text) : (-1)); int val = ((num < 0) ? 1 : Plugin.U5.Ovl.ItemAttack(num)); return Ultima.WeaponRoll(Math.Max(1, val), random); } public static int Defence(Player player) { IEnumerable<int> worn = from i in ((Humanoid)player).GetInventory().GetEquippedItems() where (Object)(object)i.m_dropPrefab != (Object)null select ShopTrading.Items.EquipmentOf(((Object)i.m_dropPrefab).name); return Avatar.Defence(Plugin.U5.Ovl, worn) + WornEffects.ExtraDefence(player) + (SpellStatus.Has(player, "U5_Protection") ? 3 : 0); } private static void OnDeath_Prefix(Character __instance) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) CreatureStats creatureStats = UltimaCreatures.Of(__instance); if (creatureStats == null || (Object)(object)((Component)__instance).GetComponent<TownNpc>() != (Object)null) { return; } HitData value = Traverse.Create((object)__instance).Field("m_lastHit").GetValue<HitData>(); Character obj = ((value != null) ? value.GetAttacker() : null); Player val = (Player)(object)((obj is Player) ? obj : null); if (val == null) { return; } int num = Avatar.ExperienceFor(creatureStats); if ((Object)(object)val == (Object)(object)Me) { Earn(num); return; } ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { ZDOID zDOID = ((Character)val).GetZDOID(); instance.InvokeRoutedRPC(((ZDOID)(ref zDOID)).UserID, "U5_Experience", new object[1] { num }); } } private static void GameStart_Postfix() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.Register<int>("U5_Experience", (Action<long, int>)delegate(long sender, int exp) { Earn(exp); }); } } private static void Earn(int exp) { if (!((Object)(object)Me == (Object)null) && Active) { Avatar mine = Mine; mine.Experience = Math.Min(9999, mine.Experience + exp); mine.Save(Me.m_customData); ((Character)Me).Message((MessageType)1, $"+{exp} experience", 0, (Sprite)null, false); } } private static void SetSleeping_Postfix(Player __instance, bool sleep) { if (!sleep && Active && !((Object)(object)__instance != (Object)(object)Me)) { Avatar mine = Mine; int num = mine.LevelUp(random); if (num >= 0) { mine.Save(Me.m_customData); Me.SetMaxHealth((float)mine.MaxHitPoints * 10f, true); ((Character)Me).SetHealth((float)mine.MaxHitPoints * 10f); ((Character)Me).Message((MessageType)2, Plugin.U5.Ovl.CStr(30544).Trim() + "\n" + Avatar.LevelUpWords(Plugin.U5.Ovl, Me.GetPlayerName(), mine.Level, num), 0, (Sprite)null, false); Plugin.Log.LogInfo((object)$"{Me.GetPlayerName()} is now level {mine.Level}"); } } } private static bool RaiseSkill_Prefix() { return !Active; } private static bool GetSkillLevel_Prefix(ref float __result) { if (!Active) { return true; } __result = 0f; return false; } private static bool Restful(int hash) { return Array.IndexOf(comfort, hash) >= 0; } private static void OnSpawned_Postfix(Player __instance) { if (Active && !((Object)(object)__instance != (Object)(object)Me)) { int[] array = comfort; foreach (int num in array) { ((Character)__instance).GetSEMan().RemoveStatusEffect(num, false); } } } private static bool AddStatusEffectHash_Prefix(int nameHash, ref StatusEffect __result) { if (!Active || !Restful(nameHash)) { return true; } __result = null; return false; } private static bool AddStatusEffect_Prefix(StatusEffect statusEffect, ref StatusEffect __result) { if (!Active || (Object)(object)statusEffect == (Object)null || !Restful(statusEffect.NameHash())) { return true; } __result = null; return false; } private static void SkillsSetup_Postfix(SkillsDialog __instance, Player player) { //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: 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_0412: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) if (!Active || (Object)(object)player != (Object)(object)Me) { return; } List<GameObject> value = Traverse.Create((object)__instance).Field("m_elements").GetValue<List<GameObject>>(); if (value == null) { return; } Avatar mine = Mine; int num = KarmaDeeds.Of(player); int num2 = ((mine.Level >= 8) ? mine.Experience : (100 << mine.Level - 1)); (string, string, float, string)[] array = new(string, string, float, string)[8] { ("Strength", mine.Strength.ToString(), (float)mine.Strength / 30f, "Ultima strength (up to 30)"), ("Dexterity", mine.Dexterity.ToString(), (float)mine.Dexterity / 30f, "Ultima dexterity (up to 30)"), ("Intelligence", mine.Intelligence.ToString(), (float)mine.Intelligence / 30f, "Ultima intelligence (up to 30)"), ("Magic", mine.Mana.ToString(), (mine.Intelligence > 0) ? ((float)mine.Mana / (float)mine.Intelligence) : 0f, "Mana for spells"), ("Hit points", $"{Mathf.CeilToInt(((Character)player).GetHealth() / 10f)}/{mine.MaxHitPoints}", ((Character)player).GetHealth() / Mathf.Max(1f, (float)mine.MaxHitPoints * 10f), "30 a level"), ("Level", mine.Level.ToString(), (float)mine.Level / 8f, "Lord British's apparition raises it when thou sleepest, once thy deeds have earned it"), ("Experience", mine.Experience.ToString(), (num2 > 0) ? Mathf.Clamp01((float)mine.Experience / (float)num2) : 1f, (mine.Level >= 8) ? "" : $"Level {mine.Level + 1} at {num2}"), ("Karma", num.ToString(), (float)num / 99f, KarmaDeeds.WearsAnkh(player) ? $"Thy virtue (the Ankh: +{10})" : "Thy virtue") }; while (value.Count < array.Length) { GameObject val = Object.Instantiate<GameObject>(__instance.m_elementPrefab, Vector3.zero, Quaternion.identity, (Transform)(object)__instance.m_listRoot); ((RectTransform)val.transform).anchoredPosition = new Vector2(0f, (float)(-value.Count) * __instance.m_spacing); value.Add(val); } RectTransform listRoot = __instance.m_listRoot; Rect rect = __instance.m_listRoot.rect; listRoot.SetSizeWithCurrentAnchors((Axis)1, Mathf.Max(((Rect)(ref rect)).height, (float)array.Length * __instance.m_spacing)); for (int i = 0; i < value.Count; i++) { GameObject val2 = value[i]; if (i >= array.Length) { val2.SetActive(false); continue; } val2.SetActive(true); var (text, text2, value2, text3) = array[i]; ((Component)Utils.FindChild(val2.transform, "name", (IterativeSearchType)0)).GetComponent<TMP_Text>().text = text; ((Component)Utils.FindChild(val2.transform, "leveltext", (IterativeSearchType)0)).GetComponent<TMP_Text>().text = text2; ((Component)Utils.FindChild(val2.transform, "bonustext", (IterativeSearchType)0)).gameObject.SetActive(false); ((Component)Utils.FindChild(val2.transform, "levelbar_total", (IterativeSearchType)0)).GetComponent<GuiBar>().SetValue(value2); ((Component)Utils.FindChild(val2.transform, "levelbar", (IterativeSearchType)0)).GetComponent<GuiBar>().SetValue(value2); ((Component)Utils.FindChild(val2.transform, "currentlevel", (IterativeSearchType)0)).GetComponent<GuiBar>().SetValue(0f); UITooltip componentInChildren = val2.GetComponentInChildren<UITooltip>(); if (componentInChildren != null) { componentInChildren.Set(text, text3, __instance.m_tooltipAnchor, default(Vector2)); } } __instance.m_totalSkillText.text = $"<color=orange>Level {mine.Level}</color>"; } } public static class Ballistas { public const string BoltName = "u5_explosive_bolt"; public const string ProjectileName = "u5_explosive_bolt_projectile"; public const float BoltDamage = 400f; private const float BlastRadius = 4f; internal static Character firing; public static void Register() { PrefabManager.OnVanillaPrefabsAvailable += Create; } private static void Create() { //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= Create; GameObject val = PrefabManager.Instance.CreateClonedPrefab("u5_explosive_bolt_projectile", "Turret_projectile"); GameObject val2 = PrefabManager.Instance.CreateClonedPrefab("u5_explosive_bolt", "TurretBolt"); GameObject prefab = PrefabManager.Instance.GetPrefab("fx_siegebomb_explosion"); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { Plugin.Log.LogError((object)"Ballistas: no Turret_projectile/TurretBolt to make explosive bolts from"); return; } Projectile component = val.GetComponent<Projectile>(); component.m_aoe = 4f; component.m_respawnItemOnHit = false; if ((Object)(object)prefab != (Object)null) { component.m_hitEffects.m_effectPrefabs = ((IEnumerable<EffectData>)(((object)component.m_hitEffects.m_effectPrefabs) ?? ((object)new EffectData[0]))).Concat((IEnumerable<EffectData>)(object)new EffectData[1] { new EffectData { m_prefab = prefab, m_enabled = true } }).ToArray(); } SharedData shared = val2.GetComponent<ItemDrop>().m_itemData.m_shared; shared.m_name = "Explosive bolt"; shared.m_attack.m_attackProjectile = val; shared.m_damages = new DamageTypes { m_damage = 400f }; ItemManager.Instance.AddItem(new CustomItem(val2, false)); } public static void Install(Harmony harmony) { Patch(harmony, "UpdateTarget", "UpdateTarget_Prefix"); Patch(harmony, "Interact", "Interact_Prefix"); Patch(harmony, "UseItem", "UseItem_Prefix"); Patch(harmony, "GetHoverText", "GetHoverText_Prefix"); Patch(harmony, "ShootProjectile", null, "ShootProjectile_Postfix"); } private static void Patch(Harmony h, string m, string prefix = null, string postfix = null) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) MethodInfo methodInfo = AccessTools.Method(typeof(Turret), m, (Type[])null, (Type[])null); if (methodInfo == null) { Plugin.Log.LogWarning((object)("Ballistas: Turret." + m + " not found")); } else { h.Patch((MethodBase)methodInfo, (prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(Ballistas), prefix, (Type[])null), (postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(Ballistas), postfix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static bool UpdateTarget_Prefix(Turret __instance) { TownBallista component = ((Component)__instance).GetComponent<TownBallista>(); if ((Object)(object)component == (Object)null) { return true; } component.Aim(); return false; } private static bool Interact_Prefix(Turret __instance, Humanoid character, bool hold, ref bool __result) { TownBallista component = ((Component)__instance).GetComponent<TownBallista>(); if ((Object)(object)component == (Object)null) { return true; } int num; if (!hold) { Player val = (Player)(object)((character is Player) ? character : null); if (val != null) { num = (component.PlayerFires(val) ? 1 : 0); goto IL_002a; } } num = 0; goto IL_002a; IL_002a: __result = (byte)num != 0; return false; } private static bool UseItem_Prefix(Turret __instance, ref bool __result) { if ((Object)(object)((Component)__instance).GetComponent<TownBallista>() == (Object)null) { return true; } __result = false; return false; } private static bool GetHoverText_Prefix(Turret __instance, ref string __result) { if ((Object)(object)((Component)__instance).GetComponent<TownBallista>() == (Object)null) { return true; } __result = Localization.instance.Localize("Ballista\n[<color=yellow><b>$KEY_Use</b></color>] Fire"); return false; } private static void ShootProjectile_Postfix(Turret __instance) { TownBallista component = ((Component)__instance).GetComponent<TownBallista>(); if (!((Object)(object)component == (Object)null)) { GameObject value = Traverse.Create((object)__instance).Field("m_lastProjectile").GetValue<GameObject>(); Projectile val = (((Object)(object)value != (Object)null) ? value.GetComponent<Projectile>() : null); Character val2 = firing ?? component.CrewBody; if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null) { Traverse.Create((object)val).Field("m_owner").SetValue((object)val2); } } } } public class TownBallista : MonoBehaviour { private const float Range = 50f; private const float Arc = 60f; private const float ManFor = 15f; private const float CheckEvery = 0.5f; private const float CrewBehind = 1.6f; private static readonly int SightMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" }); private Turret turret; private ZNetView nview; private Settlements.Built town; private TownNpc crew; private Character target; private float checkAt; private float seenAt = -100f; public Character CrewBody { get { if (!((Object)(object)crew != (Object)null)) { return null; } return ((Component)crew).GetComponent<Character>(); } } private bool Manned { get { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)crew != (Object)null && !crew.IsDead) { return Vector3.Distance(((Component)crew).transform.position, CrewSpot) < 2.5f; } return false; } } private Vector3 CrewSpot => ((Component)this).transform.position - ((Component)this).transform.forward * 1.6f + Vector3.up * 0.1f; private Settlements.Built Town { get { //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) if (town != null) { return town; } Vector3 p = ((Component)this).transform.position; return town = Settlements.All.FirstOrDefault((Settlements.Built b) => Mathf.Max(Mathf.Abs(p.x - b.Origin.x), Mathf.Abs(p.z - b.Origin.z)) < b.Site.Half + 1f); } } private void Awake() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) turret = ((Component)this).GetComponent<Turret>(); nview = ((Component)this).GetComponent<ZNetView>(); ZNetScene instance = ZNetScene.instance; object obj; if (instance == null) { obj = null; } else { GameObject prefab = instance.GetPrefab("u5_explosive_bolt"); obj = ((prefab != null) ? prefab.GetComponent<ItemDrop>() : null); } ItemDrop val = (ItemDrop)obj; if ((Object)(object)val != (Object)null) { turret.m_defaultAmmo = val; AmmoType val2 = ((IEnumerable<AmmoType>)turret.m_allowedAmmo).FirstOrDefault((Func<AmmoType, bool>)((AmmoType a) => (Object)(object)a.m_ammo != (Object)null && ((Object)a.m_ammo).name == "TurretBolt")); if ((Object)(object)val2.m_visual != (Object)null) { turret.m_allowedAmmo.Add(new AmmoType { m_ammo = val, m_visual = val2.m_visual }); } } turret.m_maxAmmo = 0; turret.m_viewDistance = 50f; turret.m_horizontalAngle = 60f; turret.m_targetPlayers = false; turret.m_targetTamed = false; } private void Update() { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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) if ((Object)(object)nview == (Object)null || nview.GetZDO() == null || !nview.IsOwner() || Time.time < checkAt) { return; } checkAt = Time.time + 0.5f; target = Spot(); if ((Object)(object)target != (Object)null) { seenAt = Time.time; if (((Object)(object)crew == (Object)null || crew.IsDead) && Town != null) { Settlements.Built b = Town; Vector3 crewSpot = CrewSpot; Quaternion rotation = ((Component)this).transform.rotation; crew = TownsfolkSpawner.SpawnCrew(b, crewSpot, ((Quaternion)(ref rotation)).eulerAngles.y, this); if ((Object)(object)crew != (Object)null) { Plugin.Log.LogInfo((object)(Town.Location.Name + ": a guard mans the ballista against " + target.m_name)); } } } else if ((Object)(object)crew != (Object)null && Time.time - seenAt > 15f) { Dismiss(); } } private void OnDestroy() { Dismiss(); } private void Dismiss() { if ((Object)(object)crew != (Object)null) { ZNetView component = ((Component)crew).GetComponent<ZNetView>(); if (((component != null) ? component.GetZDO() : null) != null && crew.IsOwned) { ZNetScene.instance.Destroy(((Component)crew).gameObject); } } crew = null; } private Character Spot() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0116: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Invalid comparison between Unknown and I4 //IL_0148: 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_00f0: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (((Object)(object)turret.m_eye != (Object)null) ? turret.m_eye.transform.position : (((Component)this).transform.position + Vector3.up * 1.5f)); Character result = null; float num = 50f; Vector3 val3 = default(Vector3); foreach (Character allCharacter in Character.GetAllCharacters()) { if ((Object)(object)allCharacter == (Object)null || allCharacter.IsPlayer() || allCharacter.IsDead() || allCharacter.IsTamed() || (Object)(object)((Component)allCharacter).GetComponent<TownNpc>() != (Object)null || (Object)(object)((Component)allCharacter).GetComponent<CreatureTalker>() != (Object)null || ResidentMonster.Is(allCharacter) || (UltimaCreatures.Of(allCharacter) == null && ((Object)(object)allCharacter.GetBaseAI() == (Object)null || (int)allCharacter.GetFaction() == 1 || (int)allCharacter.GetFaction() == 0))) { continue; } Vector3 val2 = allCharacter.GetCenterPoint() - val; float magnitude = ((Vector3)(ref val2)).magnitude; if (!(magnitude >= num)) { ((Vector3)(ref val3))..ctor(val2.x, 0f, val2.z); if (!(Vector3.Angle(((Component)this).transform.forward, val3) > 60f) && !Blocked(val, allCharacter.GetCenterPoint())) { result = allCharacter; num = magnitude; } } } return result; } private bool Blocked(Vector3 from, Vector3 to) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) //IL_0025: Unknown result type (might be due to invalid IL or missing references) RaycastHit[] array = Physics.RaycastAll(from, to - from, Vector3.Distance(from, to), SightMask); for (int i = 0; i < array.Length; i++) { RaycastHit val = array[i]; if (!((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(((Component)this).transform)) { return true; } } return false; } public void Aim() { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)nview == (Object)null) && nview.IsValid() && nview.IsOwner()) { Character val = ((Manned && (Object)(object)target != (Object)null && !target.IsDead()) ? target : null); Character value = Traverse.Create((object)turret).Field("m_target").GetValue<Character>(); if (!((Object)(object)val == (Object)(object)value)) { nview.InvokeRPC(ZNetView.Everybody, "RPC_SetTarget", new object[1] { ((Object)(object)val != (Object)null) ? val.GetZDOID() : ZDOID.None }); } } } public bool PlayerFires(Player player) { if (turret.IsCoolingDown()) { return false; } nview.ClaimOwnership(); Ballistas.firing = (Character)(object)player; try { turret.ShootProjectile(); } finally { Ballistas.firing = null; } ((Character)player).Message((MessageType)2, Plugin.U5.Ovl.CStr(17138).Trim(), 0, (Sprite)null, false); if (Town != null) { Crime.Commit(player, Town); } return true; } } public static class BigInventory { private static int visible = 4; private static int first; private static Text rowsText; private static readonly FieldRef<InventoryGrid, List<InventoryElement>> Elements = AccessTools.FieldRefAccess<InventoryGrid, List<InventoryElement>>("m_elements"); private static readonly FieldRef<InventoryGrid, Vector2i> Selected = AccessTools.FieldRefAccess<InventoryGrid, Vector2i>("m_selected"); private static readonly Dictionary<InventoryElement, Vector2> placed = new Dictionary<InventoryElement, Vector2>(); public static void Install(Harmony harmony) { //IL_0033: 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_004b: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Expected O, but got Unknown //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(Player), "OnSpawned", (Type[])null, (Type[])null); if (methodInfo != null) { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(BigInventory), "OnSpawned_Postfix", (Type[])null) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo2 = AccessTools.Method(typeof(Player), "SetInventorySize", (Type[])null, (Type[])null); if (methodInfo2 != null) { harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(BigInventory), "SetInventorySize_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo3 = AccessTools.Method(typeof(Humanoid), "DropInvalidItems", (Type[])null, (Type[])null); if (methodInfo3 != null) { harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(BigInventory), "DropInvalidItems_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo4 = AccessTools.Method(typeof(Humanoid), "DrainEquipedItemDurability", (Type[])null, (Type[])null); if (methodInfo4 != null) { harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(typeof(BigInventory), "Drain_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo5 = AccessTools.Method(typeof(Inventory), "FindEmptySlot", (Type[])null, (Type[])null); if (methodInfo5 != null) { harmony.Patch((MethodBase)methodInfo5, new HarmonyMethod(typeof(BigInventory), "FindEmptySlot_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo6 = AccessTools.Method(typeof(InventoryGui), "Show", (Type[])null, (Type[])null); if (methodInfo6 != null) { harmony.Patch((MethodBase)methodInfo6, (HarmonyMethod)null, new HarmonyMethod(typeof(BigInventory), "Show_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo7 = AccessTools.Method(typeof(InventoryGrid), "UpdateInventory", (Type[])null, (Type[])null); if (methodInfo7 != null) { harmony.Patch((MethodBase)methodInfo7, (HarmonyMethod)null, new HarmonyMethod(typeof(BigInventory), "UpdateInventory_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodInfo == null || methodInfo2 == null || methodInfo3 == null || methodInfo4 == null || methodInfo6 == null || methodInfo7 == null) { Plugin.Log.LogWarning((object)"Inventory: Player.OnSpawned / SetInventorySize, Humanoid.DropInvalidItems / DrainEquipedItemDurability, InventoryGui.Show or InventoryGrid.UpdateInventory not found"); } } private static void OnSpawned_Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { Apply(__instance); PouchPanel.Migrate(__instance); } } private static void SetInventorySize_Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { Apply(__instance); } } private static int VanillaRows(Player p) { string s = default(string); if (!p.TryGetUniqueKeyValue("invrows", ref s) || !int.TryParse(s, out var result)) { return 4; } return Mathf.Clamp(result, 1, 9); } public static void Apply(Player p) { Inventory inventory = ((Humanoid)p).GetInventory(); int vanillaRows = VanillaRows(p); int num = InventorySize.RowsFor(Britannia.Active != null, vanillaRows, from i in inventory.GetAllItems() select i.m_gridPos.y); if (num != inventory.GetHeight()) { inventory.SetHeight(num); Plugin.Log.LogInfo((object)string.Format("Inventory: {0} × {1} slots{2}", inventory.GetWidth(), num, (Britannia.Active != null) ? " (Britannia)" : "")); } InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance == (Object)null)) { visible = InventorySize.VisibleFor(num, vanillaRows); instance.SetInventorySize(visible); } } private static void DropInvalidItems_Prefix(Humanoid __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { Inventory inventory = ((Humanoid)val).GetInventory(); int num = (from i in inventory.GetAllItems() select i.m_gridPos.y + 1).DefaultIfEmpty(0).Max(); if (num > inventory.GetHeight()) { inventory.SetHeight(num); } } } private static bool Drain_Prefix(Humanoid __instance, ItemData item, float dt) { if (item == null || item.m_stack <= 1 || (Object)(object)item.m_dropPrefab == (Object)null || UltimaItems.Map.Get(((Object)item.m_dropPrefab).name) == null) { return true; } if (item.m_durability - item.m_shared.m_durabilityDrain * dt * Game.m_durabilityRate > 0f) { return true; } item.m_stack--; item.m_durability = item.GetMaxDurability(); ((Character)__instance).Message((MessageType)1, Localization.instance.Localize("$msg_broke", new string[1] { item.m_shared.m_name }), 0, item.GetIcon(), false); __instance.GetInventory().m_onChanged?.Invoke(); return false; } private static bool FindEmptySlot_Prefix(Inventory __instance, bool topFirst, ref Vector2i __result) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //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) Player localPlayer = Player.m_localPlayer; if (topFirst || (Object)(object)localPlayer == (Object)null || __instance != ((Humanoid)localPlayer).GetInventory() || __instance.GetHeight() <= 6) { return true; } int width = __instance.GetWidth(); int height = __instance.GetHeight(); for (int i = 1; i <= height; i++) { int num = i % height; for (int j = 0; j < width; j++) { if (__instance.GetItemAt(j, num) == null) { __result = new Vector2i(j, num); return false; } } } __result = new Vector2i(-1, -1); return false; } private static void Show_Postfix(InventoryGui __instance) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { Apply(localPlayer); } } public static void ScrollTo(int row) { first = row; } private static void UpdateInventory_Postfix(InventoryGrid __instance, Inventory inventory, Player player) { //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_017e: 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_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)__instance != (Object)(object)instance.m_playerGrid || (Object)(object)player == (Object)null || inventory == null) { return; } int height = inventory.GetHeight(); int num = Mathf.Min(visible, height); Transform transform = ((Component)__instance).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); float elementSpace = __instance.m_elementSpace; if (height > num) { Vector3 pointerPosition = ZInput.pointerPosition; Rect rect = val.rect; if (((Rect)(ref rect)).Contains(((Transform)val).InverseTransformPoint(pointerPosition))) { float mouseScrollWheel = ZInput.GetMouseScrollWheel(); if (mouseScrollWheel < 0f) { first++; } else if (mouseScrollWheel > 0f) { first--; } } if (ZInput.IsGamepadActive()) { int y = Selected.Invoke(__instance).y; if (y < first) { first = y; } else if (y >= first + num) { first = y - num + 1; } } } first = Mathf.Clamp(first, 0, height - num); RectTransform gridRoot = __instance.m_gridRoot; gridRoot.anchoredPosition = new Vector2(gridRoot.anchoredPosition.x, (float)first * elementSpace); foreach (InventoryElement item in Elements.Invoke(__instance)) { if (!((Object)(object)item == (Object)null)) { Transform transform2 = ((Component)item).transform; RectTransform val2 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null); if (!placed.TryGetValue(item, out var value)) { value = (placed[item] = val2.anchoredPosition); } bool flag = item.Position.y >= first && item.Position.y < first + num; if (((Component)item).gameObject.activeSelf != flag) { ((Component)item).gameObject.SetActive(flag); } val2.anchoredPosition = (flag ? value : (value + new Vector2(100000f, 0f))); } } if (height > num && (Object)(object)rowsText == (Object)null) { GUIManager instance2 = GUIManager.Instance; rowsText = instance2.CreateText("", (Transform)(object)instance.m_player, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-120f, -14f), instance2.AveriaSerifBold, 15, instance2.ValheimOrange, true, Color.black, 240f, 24f, false).GetComponent<Text>(); rowsText.alignment = (TextAnchor)5; } if (!((Object)(object)rowsText == (Object)null)) { ((Component)rowsText).gameObject.SetActive(height > num); rowsText.text = $"rows {first + 1}–{first + num} of {height} (mouse wheel)"; } } } public static class BiomeBlend { private const float Step = 4f; private const int Radius = 2; private static readonly List<Color32> colours = new List<Color32>(); public static void Install(Harmony harmony) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown try { MethodInfo methodInfo = AccessTools.Method(typeof(Heightmap), "RebuildRenderMesh", (Type[])null, (Type[])null) ?? throw new MissingMethodException("Heightmap", "RebuildRenderMesh"); MethodInfo methodInfo2 = AccessTools.Method(typeof(Heightmap), "GetBiome", new Type[3] { typeof(Vector3), typeof(float), typeof(bool) }, (Type[])null) ?? throw new MissingMethodException("Heightmap", "GetBiome"); harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(BiomeBlend), "RebuildRenderMesh_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(BiomeBlend), "GetBiome_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Soft biome borders not installed: " + ex.Message)); } } private static bool GetBiome_Prefix(Vector3 point, ref Biome __result) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0021: Unknown result type (might be due to invalid IL or missing references) if (Britannia.Active == null) { return true; } __result = (Biome)Britannia.ShapeAt(point.x, point.z).Biome(point.x, point.z); return false; } private static void RebuildRenderMesh_Postfix(Heightmap __instance, Mesh ___m_renderMesh, int ___m_width, float ___m_scale, bool ___m_isDistantLod) { //IL_001d: 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) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: 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_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) if (Britannia.Active == null || ___m_isDistantLod || (Object)(object)___m_renderMesh == (Object)null) { return; } BritanniaShape britanniaShape = Britannia.ShapeAt(((Component)__instance).transform.position); float num = (float)___m_width * ___m_scale; Vector3 val = ((Component)__instance).transform.position - new Vector3(num / 2f, 0f, num / 2f); int num2 = Mathf.CeilToInt(num / 4f) + 1 + 4; Color[] array = (Color[])(object)new Color[num2 * num2]; for (int i = 0; i < num2; i++) { for (int j = 0; j < num2; j++) { Biome val2 = (Biome)britanniaShape.Biome(val.x + (float)(j - 2) * 4f, val.z + (float)(i - 2) * 4f); array[i * num2 + j] = Color32.op_Implicit(Heightmap.GetBiomeColor(val2)); } } array = Box(Box(array, num2, 1, 0), num2, 0, 1); int num3 = ___m_width + 1; colours.Clear(); for (int k = 0; k < num3; k++) { for (int l = 0; l < num3; l++) { float num4 = (float)l * ___m_scale / 4f + 2f; float num5 = (float)k * ___m_scale / 4f + 2f; int num6 = Mathf.Min((int)num4, num2 - 2); int num7 = Mathf.Min((int)num5, num2 - 2); float num8 = num4 - (float)num6; float num9 = num5 - (float)num7; Color val3 = Color.Lerp(array[num7 * num2 + num6], array[num7 * num2 + num6 + 1], num8); Color val4 = Color.Lerp(array[(num7 + 1) * num2 + num6], array[(num7 + 1) * num2 + num6 + 1], num8); colours.Add(Color32.op_Implicit(Color.Lerp(val3, val4, num9))); } } if (colours.Count == ___m_renderMesh.vertexCount) { ___m_renderMesh.SetColors(colours); } } private static Color[] Box(Color[] src, int g, int dx, int dy) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) Color[] array = (Color[])(object)new Color[src.Length]; for (int i = 0; i < g; i++) { for (int j = 0; j < g; j++) { Color val = Color.clear; for (int k = -2; k <= 2; k++) { int num = Mathf.Clamp(j + k * dx, 0, g - 1); int num2 = Mathf.Clamp(i + k * dy, 0, g - 1); val += src[num2 * g + num]; } array[i * g + j] = val / 5f; } } return array; } } public class BlackthornGuards : MonoBehaviour { private const float Reach = 3f; private const float Again = 30f; private float checkAt; private float askedAt = -999f; private bool passed; private void Update() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) if (Time.time < checkAt) { return; } checkAt = Time.time + 0.5f; Player localPlayer = Player.m_localPlayer; Settlements.Built built = Settlements.Get(18); if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || built == null || Britannia.Active == null) { return; } Vector3 position = ((Component)localPlayer).transform.position; if (!(Mathf.Max(Mathf.Abs(position.x - built.Origin.x), Mathf.Abs(position.z - built.Origin.z)) < built.Site.Half + built.Site.Blend)) { passed = false; } else { if (passed || TalkPanel.IsOpen || Crime.WantedBy(localPlayer) != 0 || Crime.HostileTo(localPlayer) != 0 || Time.time - askedAt < 30f) { return; } foreach (Character allCharacter in Character.GetAllCharacters()) { TownNpc townNpc = TownsfolkPatches.NpcOf(allCharacter); if (!((Object)(object)townNpc == (Object)null) && townNpc.IsGuard && !townNpc.IsDead && townNpc.Location == 18 && !(Vector3.Distance(((Component)allCharacter).transform.position, position) > 3f)) { askedAt = Time.time; Challenge(localPlayer, townNpc, built); break; } } } } private void Challenge(Player me, TownNpc guard, Settlements.Built palace) { DataOvl ovl = Plugin.U5.Ovl; bool flag = (WornEffects.Bits(me) & 8) != 0; Plugin.Log.LogInfo((object)$"Blackthorn's guard challenges {me.GetPlayerName()} (badge {flag})"); if (!flag) { Crime.Commit(me, palace); return; } string question = "\"" + ovl.CStr(37116).Replace("\n", " ").Trim() + "\""; TalkPanel.AskTyped(guard, guard.GetHoverName(), question, "Your response", delegate(string answer) { if (ItemUse.PasswordMatches(ovl, answer)) { passed = true; TalkPanel.Tell("\"" + ovl.CStr(37178).Trim() + "\""); Plugin.Log.LogInfo((object)(me.GetPlayerName() + " gave Blackthorn's password")); } else { TalkPanel.Close(); Crime.Commit(me, palace); } }); } } public static class Bridges { private static Type clearAreaType; private static BritanniaShape planned; private static List<(Vector3 centre, List<Placement> pieces)> bridges = new List<(Vector3, List<Placement>)>(); public static void Install(Harmony harmony) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown try { clearAreaType = AccessTools.Inner(typeof(ZoneSystem), "ClearArea") ?? throw new MissingMemberException("ZoneSystem", "ClearArea"); harmony.Patch((MethodBase)(AccessTools.Method(typeof(ZoneSystem), "PlaceLocations", (Type[])null, (Type[])null) ?? throw new MissingMethodException("ZoneSystem", "PlaceLocations")), (HarmonyMethod)null, new HarmonyMethod(typeof(Bridges), "PlaceLocations_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Bridges not installed: " + ex.Message)); } } public static List<(Vector3 centre, List<Placement> pieces)> All() { BritanniaShape shape = Britannia.Active; if (shape == null) { return new List<(Vector3, List<Placement>)>(); } if (planned == shape) { return bridges; } planned = shape; bridges = BridgePlanner.Bridges(shape).Select(delegate((int x, int y, bool eastWest) b) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) shape.TileCentre(b.x, b.y, out var wx, out var wz); return ((Vector3, List<Placement>))(new Vector3(wx, 30f, wz), BridgePlanner.Plan(shape, b.x, b.y, b.eastWest)); }).ToList(); Plugin.Log.LogInfo((object)$"Bridges: {bridges.Count} ({bridges.Sum(((Vector3 centre, List<Placement> pieces) b) => b.pieces.Count)} pieces)"); return bridges; } private static void PlaceLocations_Postfix(Vector2s zoneID, IList clearAreas, SpawnMode mode, List<GameObject> spawnedObjects) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Invalid comparison between Unknown and I4 //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_013e: 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) //IL_0102: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Invalid comparison between Unknown and I4 //IL_01c5: Unknown result type (might be due to invalid IL or missing references) if (Britannia.Active == null || ((int)mode != 0 && (int)mode != 2)) { return; } foreach (var item in All()) { var (centre, list) = item; if (ZoneSystem.GetZone(centre) != zoneID) { continue; } float num = list.Max((Placement p) => Mathf.Max(Mathf.Abs(p.X - centre.x), Mathf.Abs(p.Z - centre.z))) + 4f; clearAreas.Add(Activator.CreateInstance(clearAreaType, centre, num)); int num2 = 0; foreach (Placement item2 in list) { GameObject prefab = ZNetScene.instance.GetPrefab(item2.Prefab); if ((Object)(object)prefab == (Object)null) { continue; } if ((int)mode == 2) { ZNetView.StartGhostInit(); } Quaternion val = Quaternion.Euler(0f, item2.Yaw, 0f); if (item2.Turned) { val *= Quaternion.Euler(item2.Tilt, 0f, 0f); } GameObject val2 = Object.Instantiate<GameObject>(prefab, new Vector3(item2.X, 30f + item2.Y, item2.Z), val); Vector3 val3 = (Vector3)(item2.Scaled ? new Vector3(item2.SX, item2.SY, item2.SZ) : Vector3.zero); if (item2.Scaled) { val2.transform.localScale = val3; } ZNetView component = val2.GetComponent<ZNetView>(); ZDO val4 = ((component != null) ? component.GetZDO() : null); if (val4 != null) { val4.Set("u5_fixed", true); if (item2.Scaled) { val4.Set("u5_scale", val3); } WearNTear component2 = val2.GetComponent<WearNTear>(); if ((Object)(object)component2 != (Object)null) { FixedPieces.Apply(component2, val4); } } if ((int)mode == 2) { spawnedObjects.Add(val2); ZNetView.FinishGhostInit(); } num2++; } Plugin.Log.LogInfo((object)$"Zone {zoneID}: a bridge of {num2} pieces at {centre}"); } } } public static class Britannia { public const string SeedPrefix = "Britannia"; public const float SeaLevel = 30f; private static BritanniaShape cached; private static BritanniaShape cachedUnder; private static int cachedSeed; private static float cachedTile; private static TerrainTable terrain; private static TerrainTable underTerrain; public static BritanniaShape Active { get; private set; } public static string Failure { get; private set; } public static List<Poi> Pois { get; private set; } = new List<Poi>(); public static int Seed { get; private set; } public static BritanniaShape Under { get; private set; } public static BritanniaShape ShapeAt(float wx, float wz) { if (Under == null || !Continents.InUnderworld(wx, Under.TileMetres)) { return Active; } return Under; } public static BritanniaShape ShapeAt(Vector3 p) { //IL_0000: 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) return ShapeAt(p.x, p.z); } public static bool InUnderworld(Vector3 p) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (Active != null && ShapeAt(p.x, p.z) == Under) { return Under != null; } return false; } public static BritanniaShape Level(int z) { if (z != 0) { return Under; } return Active; } public static Vector3 TileCentre(int tx, int ty, bool underworld) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) BritanniaShape britanniaShape = (underworld ? Under : Active); britanniaShape.TileCentre(tx, ty, out var wx, out var wz); return new Vector3(wx, 30f + britanniaShape.Height(wx, wz), wz); } public static (int x, int y, int z) Tile(Vector3 p) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) BritanniaShape britanniaShape = ShapeAt(p); britanniaShape.ToTile(p.x, p.z, out var u, out var v); return (x: (int)Math.Floor(u) & 0xFF, y: (int)Math.Floor(v) & 0xFF, z: (britanniaShape == Under) ? (-1) : 0); } public static bool IsBritanniaSeed(string seedName) { return seedName?.StartsWith("Britannia", StringComparison.OrdinalIgnoreCase) ?? false; } public static void Activate(World world) { ActivateWorld(world); RiverBanks.WorldChanged(); } private static void ActivateWorld(World world) { Active = null; Under = null; Failure = null; if (world == null || world.m_menu || !IsBritanniaSeed(world.m_seedName)) { return; } if (Plugin.U5 == null) { Fail("World '" + world.m_name + "' is a Britannia world but the Ultima V data is not loaded (set UltimaVDirectory and restart)."); return; } try { float value = Plugin.TileMetres.Value; if (cached == null || cachedSeed != world.m_seed || cachedTile != value) { Stopwatch stopwatch = Stopwatch.StartNew(); string json = File.ReadAllText(Path.Combine(Plugin.PluginDirectory, "mappings", "terrain.json")); terrain = terrain ?? TerrainTable.Parse(json); underTerrain = underTerrain ?? TerrainTable.Parse(json, underworld: true); cached = new BritanniaShape(Plugin.U5.Britannia, terrain, world.m_seed, value); cachedUnder = Continents.UnderworldShape(Plugin.U5.Underworld, underTerrain, world.m_seed, value); cachedSeed = world.m_seed; cachedTile = value; Plugin.Log.LogInfo((object)$"Britannia and Underworld terrain for seed '{world.m_seedName}' built in {stopwatch.ElapsedMilliseconds} ms"); } Pois = Bretaheim.WorldGen.Core.Pois.Build(Plugin.U5); Settlements.Prepare(cached, cachedUnder, Pois); PlaceMarkers.Reset(); Shrines.Reset(); Seed = world.m_seed; Under = cachedUnder; Active = cached; Plugin.Log.LogInfo((object)$"World '{world.m_name}' is Britannia ({Pois.Count} places)."); } catch (Exception ex) { Plugin.Log.LogError((object)ex.ToString()); Fail("Could not build Britannia for '" + world.m_name + "': " + ex.Message); } } private static void Fail(string why) { Active = null; Under = null; Failure = why + " World generation is stopped so nothing vanilla is saved into it: quit Valheim completely and restart."; Plugin.Log.LogError((object)Failure); } public static Vector3 TileCentre(int tx, int ty) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) Active.TileCentre(tx, ty, out var wx, out var wz); return new Vector3(wx, 30f + Active.Height(wx, wz), wz); } public static Vector3 SpawnPoint() { //IL_0009: 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 (Settlements.TrySpawnPoint(out var pos)) { return pos; } SaveGame initialGame = Plugin.U5.InitialGame; Location location = Plugin.U5.Location((initialGame.Location >= 1 && initialGame.Location <= 40) ? initialGame.Location : 13); return TileCentre(location.X, location.Y); } } public static class Calendar { private static UltimaDate? start; private static Moons moons; public static UltimaDate Start { get { if (!start.HasValue) { SaveGame saveGame = Plugin.U5?.InitialGame; start = ((saveGame != null) ? new UltimaDate(saveGame.Year, saveGame.Month, saveGame.Day, saveGame.Hour, saveGame.Minute) : new UltimaDate(139, 4, 5, 8, 35)); } return start.Value; } } public static bool Running { get { if ((Object)(object)ZNet.instance != (Object)null) { return (Object)(object)EnvMan.instance != (Object)null; } return false; } } public static double Seconds { get { if (!((Object)(object)ZNet.instance != (Object)null)) { return 0.0; } return ZNet.instance.GetTimeSeconds(); } } public static double DayLength => ((Object)(object)EnvMan.instance != (Object)null && EnvMan.instance.m_dayLengthSec > 0) ? EnvMan.instance.m_dayLengthSec : 1800; public static UltimaDate Now { get { if (!Running) { return Start.WithTime(12, 0); } return UltimaCalendar.At(Start, Seconds, DayLength); } } public static int Hour => Now.Hour; public static int Minute => Now.Minute; public static long WorldDay { get { if (!Running) { return 0L; } return UltimaCalendar.WorldDay(Seconds, DayLength); } } public static Moons Moons => moons ?? (moons = Moons.Of(Plugin.U5.Ovl)); public static double SecondsUntil(int hour) { return UltimaCalendar.NextHour(Seconds, DayLength, hour) - Seconds; } public static string Describe() { UltimaDate now = Now; return $"It is {now.TimeText} on {now.DateText} (day {WorldDay + 1} of this world). {Moons.Describe(now)}."; } } public static class WorldKeys { public static string Get(string name) { string result = default(string); if (!((Object)(object)ZoneSystem.instance != (Object)null) || !ZoneSystem.instance.GetGlobalKey(name, ref result)) { return null; } return result; } public static void Set(string name, string value) { if (!((Object)(object)ZoneSystem.instance == (Object)null)) { ZoneSystem.instance.SetGlobalKey(string.IsNullOrEmpty(value) ? name : (name + " " + value)); } } } public static class ClockCommands { public static bool Run(string[] args, Action<string> print) { //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) if (args.Length == 0) { return false; } switch (args[0]) { case "time": case "date": print(Calendar.Describe()); if (Britannia.Active != null) { print(Shadowlords.Describe()); } return true; case "gates": case "moons": { print(Calendar.Describe()); if (Britannia.Active == null) { return true; } Player localPlayer = Player.m_localPlayer; for (int i = 0; i < 8; i++) { MoonstoneSite moonstoneSite = Moongates.Site(i); Vector3? val = Moongates.Position(moonstoneSite); string text = ((val.HasValue && (Object)(object)localPlayer != (Object)null) ? $", {Vector3.Distance(val.Value, ((Component)localPlayer).transform.position):0} m away" : ""); print(string.Format("moonstone {0}: {1}{2}{3}", i, moonstoneSite, val.HasValue ? $" at ({val.Value.x:0}, {val.Value.z:0})" : "", text)); } return true; } case "dusk": return Skip(20, print); case "dawn": return Skip(5, print); case "midnight": return Skip(0, print); default: return false; } } private static bool Skip(int hour, Action<string> print) { if (!Calendar.Running) { print("no world is loaded"); return true; } double num = Math.Ceiling(Calendar.SecondsUntil(hour)) + 1.0; if (!Terminal.m_cheat || !ZNet.instance.IsServer()) { print($"{hour}:00 is {num:0} s away: type \"skiptime {num:0}\" (devcommands; an admin on a dedicated server)"); return true; } ZNet.instance.SetNetTime(ZNet.instance.GetTimeSeconds() + num); print($"skipped {num:0} s: {Calendar.Describe()}"); return true; } } public static class Camp { public class Keys : MonoBehaviour { private void Update() { if (ZInput.GetKeyDown((KeyCode)104, true) && Britannia.Active != null) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !Busy()) { Pitch(localPlayer); } } } private static bool Busy() { if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsVisible() && !InventoryGui.IsVisible() && !Minimap.IsOpen() && !TalkPanel.IsOpen && !StoreGui.IsVisible()) { return GameCamera.InFreeFly(); } return true; } } public const string LeanToName = "u5_leanto"; public const string FirePrefab = "fire_pit"; public const string CampKey = "u5_camp"; private const float LeanToAhead = 1.5f; private const float FireAhead = 4.2f; private const float Off = 0.3f; private const int SHoleUp = 41666; private const int SCamp = 41734; public static void Register() { PrefabManager.OnVanillaPrefabsAvailable += Create; } private static void Create() { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= Create; GameObject val = PrefabManager.Instance.CreateClonedPrefab("u5_leanto", "wood_roof_45"); GameObject prefab = PrefabManager.Instance.GetPrefab("wood_pole2"); if ((Object)(object)val == (Object)null || (Object)(object)prefab == (Object)null) { Plugin.Log.LogError((object)"Camp: no wood_roof_45/wood_pole2 to make a lean-to of"); return; } Piece component = val.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { component.m_name = "Lean-to"; } float[] array = new float[2] { -0.9f, 0.9f }; foreach (float num in array) { GameObject obj = Visual(prefab); obj.transform.SetParent(val.transform, false); obj.transform.localPosition = new Vector3(num, 0f, -0.85f); } GameObject val2 = new GameObject("attach"); val2.transform.SetParent(val.transform, false); val2.transform.localPosition = new Vector3(0f, -0.8f, 0.1f); val2.transform.localRotation = Quaternion.Euler(0f, 180f, 0f); val.AddComponent<LeanTo>(); PrefabManager.Instance.AddPrefab(new CustomPrefab(val, false)); } private static GameObject Visual(GameObject prefab) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown GameObject val = new GameObject("u5_camp_holder"); val.SetActive(false); GameObject val2 = Object.Instantiate<GameObject>(prefab, val.transform); for (int i = 0; i < 4; i++) { Component[] componentsInChildren = val2.GetComponentsInChildren<Component>(true); foreach (Component val3 in componentsInChildren) { if (val3 is MonoBehaviour || val3 is Rigidbody) { Object.DestroyImmediate((Object)(object)val3); } } } val2.transform.SetParent((Transform)null, false); Object.Destroy((Object)(object)val); val2.SetActive(true); return val2; } public static bool Near(Vector3 at, float within) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return LeanTo.All.Any((LeanTo l) => (Object)(object)l != (Object)null && Vector3.Distance(((Component)l).transform.position, at) < within + 1.5f); } public static void Pitch(Player me) { //IL_0033: 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_0043: 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) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL