using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.NET.Common;
using Candide;
using Candide.CandideUI;
using Candide.CandideUI.Components;
using Candide.CandideUI.Components.Buttons;
using Candide.CandideUI.Containers;
using Candide.CandideUI.UiInput;
using Candide.CandideUI.Windows;
using Candide.CandideUI.WorldOverview;
using Candide.GameModels;
using Candide.GameModels.Managers;
using Candide.GameModels.Models;
using Candide.GameModels.Models.Constructions;
using Candide.Input.InputProviders.Native;
using Candide.Multiplayer.Chat;
using Candide.Multiplayer.Network;
using Candide.Sound;
using Candide.Terminal;
using CandideCreator.Shared.Graphics;
using CandideCreator.Shared.Helpers;
using CandideServer;
using CandideServer.Entities;
using CandideServer.EventBus;
using CandideServer.MessageModels;
using CandideServer.Models;
using CandideServer.Models.Player;
using CandideServer.Models.Spells;
using CandideServer.Models.Town;
using CandideServer.Server;
using CandideServer.ServerManagers;
using CandideServer.ServerServices;
using CandideServer.SimulationModels;
using CandideServer.SyncStrategies;
using CandideServer.Toolkit;
using FontStashSharp.RichText;
using HarmonyLib;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using ModSettingsMenu.Api;
using RomesteadContentFramework.Api;
using RomesteadLocalizationAPI.Api;
using Shared;
using Shared.Combat.Projectiles;
using Shared.Combat.Spells;
using Shared.Combat.Spells.Casting;
using Shared.Combat.Spells.Parameters;
using Shared.Data;
using Shared.Entity;
using Shared.Entity.Components;
using Shared.Helpers;
using Shared.Models.Construction;
using Shared.Models.Items;
using Shared.Models.Shops;
using Shared.Text;
using WayhomeCoins.Configuration;
using WayhomeCoins.Features;
using WayhomeCoins.Networking;
using WayhomeCoins.Patches;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("WayhomeCoins")]
[assembly: AssemblyDescription("Wayhome Coins For Romestead by Ice Box Studio")]
[assembly: AssemblyCompany("Ice Box Studio")]
[assembly: AssemblyProduct("WayhomeCoins")]
[assembly: AssemblyCopyright("Copyright (C) 2026 Ice Box Studio All rights reserved.")]
[assembly: ComVisible(false)]
[assembly: Guid("ca545aa6-4c2b-4eb7-88da-9f09f0b9c884")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
[assembly: AssemblyVersion("1.0.1.0")]
[module: RefSafetyRules(11)]
namespace WayhomeCoins
{
internal static class I18n
{
internal const string MarketCoinNameKey = "wayhomecoins:market_wayhome_coin*item:name";
internal const string MarketCoinDescriptionKey = "wayhomecoins:market_wayhome_coin*item:description";
public static readonly RomesteadLocalizer L = RomesteadLocalization.For("IceBoxStudio.Romestead.WayhomeCoins");
public static void RegisterJson(string path)
{
L.RegisterJson(path);
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "IceBoxStudio.Romestead.WayhomeCoins";
public const string PLUGIN_NAME = "WayhomeCoins";
public const string PLUGIN_VERSION = "1.0.1";
public const string PLUGIN_AUTHOR = "Ice Box Studio";
public const string PLUGIN_AUTHOR_URL = "https://steamcommunity.com/id/ibox666/";
public const int NEXUS_MODS_ID = 108;
public const string THUNDERSTORE_TEAM = "Ice_Box_Studio_Romestead";
public const string THUNDERSTORE_MOD_NAME = "WayhomeCoins";
public const string UPDATE_MANIFEST_URL = "https://cdn.jsdelivr.net/gh/ibox233/MyMod_Version@main/WayhomeCoins.json";
}
[BepInPlugin("IceBoxStudio.Romestead.WayhomeCoins", "WayhomeCoins", "1.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class WayhomeCoins : BasePlugin
{
private Harmony _harmony;
public static WayhomeCoins Instance { get; private set; }
internal static ManualLogSource Logger { get; private set; }
public override void Load()
{
//IL_017d: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Expected O, but got Unknown
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Expected O, but got Unknown
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: Expected O, but got Unknown
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Expected O, but got Unknown
Instance = this;
Logger = ((BasePlugin)this).Log;
bool flag = default(bool);
try
{
Logger.LogInfo((object)"=============================================");
ManualLogSource logger = Logger;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(16, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("WayhomeCoins");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" initializing...");
}
logger.LogInfo(val);
ManualLogSource logger2 = Logger;
val = new BepInExInfoLogInterpolatedStringHandler(10, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Author: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Ice Box Studio");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("(");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("https://steamcommunity.com/id/ibox666/");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
}
logger2.LogInfo(val);
I18n.RegisterJson(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Localization.json"));
ConfigManager.Init(((BasePlugin)this).Config);
ModSettingsMenuRegistration.Register(((BasePlugin)this).Config);
BaseServer.Instance.NetworkEventBusManager.Subscribe(Assembly.GetExecutingAssembly(), (string)null);
ConfigManager.MarketSettingsChanged += OnMarketSettingsChanged;
_harmony = new Harmony("IceBoxStudio.Romestead.WayhomeCoins");
_harmony.PatchAll(Assembly.GetExecutingAssembly());
ItemDataBasePatch.RegisterMarketCoin();
ShopDataBasePatch.EnsureMarketShopRegistered();
ManualLogSource logger3 = Logger;
val = new BepInExInfoLogInterpolatedStringHandler(13, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("WayhomeCoins");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" initialized.");
}
logger3.LogInfo(val);
Logger.LogInfo((object)"=============================================");
}
catch (Exception ex)
{
ManualLogSource logger4 = Logger;
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(24, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("WayhomeCoins");
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" initialization error: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("\n");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.StackTrace);
}
logger4.LogError(val2);
}
}
private static void OnMarketSettingsChanged()
{
ItemDataBasePatch.RegisterMarketCoin();
ShopDataBasePatch.RefreshMarketShop();
}
}
}
namespace WayhomeCoins.Patches
{
[HarmonyPatch(typeof(CandideEngine), "Update")]
internal static class CandideEngineUpdatePatch
{
private static void Postfix()
{
WayhomeClient.UpdateHotkeys();
}
}
[HarmonyPatch(typeof(ItemDataBase), "AddItems")]
internal static class ItemDataBasePatch
{
private static void Postfix(List<ItemData> itemDataList)
{
ApplyCooldown((IEnumerable<ItemData>)itemDataList);
if (ItemDataBase.DataMap.TryGetValue("consumable:travelers_coin", out var value))
{
ApplyCooldown(value);
}
}
public static void RegisterMarketCoin()
{
RomesteadContent.Items.Register("wayhomecoins:market_wayhome_coin", I18n.L.Text("wayhomecoins:market_wayhome_coin*item:name", Array.Empty<object>()), I18n.L.Text("wayhomecoins:market_wayhome_coin*item:description", Array.Empty<object>()), (Action<ItemData>)delegate(ItemData item)
{
//IL_0023: 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_0038: Expected O, but got Unknown
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Expected O, but got Unknown
item.Icon = "sell";
item.MaxStackSize = ConfigManager.MarketStackSize;
item.Tier = 1;
item.Tradable = new TradableItem
{
Price = ConfigManager.MarketPrice
};
item.Worship = new ItemWorshipData
{
AssociatedGodId = string.Empty
};
item.Usable = new UsableItem
{
SpellId = "item:teleport_home:start",
Type = (UsableType)0,
UsesMax = 1,
Cooldown = ConfigManager.CooldownSeconds
};
});
}
private static void ApplyCooldown(IEnumerable<ItemData> items)
{
if (items == null)
{
return;
}
foreach (ItemData item in items)
{
if (item?.Id == "consumable:travelers_coin")
{
ApplyCooldown(item);
}
}
}
private static void ApplyCooldown(ItemData item)
{
if (item?.Usable != null)
{
item.Usable.Cooldown = ConfigManager.CooldownSeconds;
}
}
}
[HarmonyPatch(typeof(ItemInstanceManager), "TryUseItem")]
internal static class ItemInstanceManagerPatch
{
private static bool Prefix(ItemInstanceModel item, ref bool __result)
{
if (!ConfigManager.Active || item == null || !WayhomeServer.IsWayhomeCoinId(item.BaseDataId) || !NetworkManager.ClientActive)
{
return true;
}
WayhomeClient.ShowMenu();
__result = true;
return false;
}
}
[HarmonyPatch(typeof(LocalizationManager), "SetLocalization")]
[HarmonyAfter(new string[] { "IceBoxStudio.Romestead.RomesteadContentFramework" })]
internal static class LocalizationManagerPatch
{
private static void Postfix()
{
ItemDataBasePatch.RegisterMarketCoin();
}
}
[HarmonyPatch(typeof(OfferingsServerManager), "TryHandInOffering", new Type[]
{
typeof(Guid),
typeof(Guid?)
})]
internal static class OfferingsServerManagerPatch
{
private static bool Prefix(Guid altarBuildingId, Guid? characterEntityId)
{
BuildingSimulationModel val = default(BuildingSimulationModel);
if (!ServerGameState.TryGetBuilding(altarBuildingId, ref val) || !val.InstanceModel.StorageInventoryId.HasValue)
{
return true;
}
SharedInventoryModel val2 = default(SharedInventoryModel);
if (!ServerGameState.TryGetInventory(val.InstanceModel.StorageInventoryId.Value, ref val2))
{
return true;
}
if (val2.GetItemCount("wayhomecoins:market_wayhome_coin") <= 0)
{
return true;
}
SendBlockedMessage(characterEntityId);
return false;
}
private static void SendBlockedMessage(Guid? characterEntityId)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
if (characterEntityId.HasValue && TryGetPlayer(characterEntityId.Value, out var player))
{
BaseServer.Instance.SendHostMessage("wayhome-coins-teleport-failed", (object)new WayhomeResultMessage
{
MessageKey = "status.market_coin_not_offering"
}, player.Peer);
}
}
private static bool TryGetPlayer(Guid characterEntityId, out ServerJoinedPlayerModel player)
{
foreach (ServerJoinedPlayerModel value in PlayerServerService.JoinedPlayers.Values)
{
if (value != null && value.CharacterModel?.Character?.EntityId == characterEntityId)
{
player = value;
return true;
}
}
player = null;
return false;
}
}
[HarmonyPatch(typeof(ServerScriptedSpell))]
internal static class ServerScriptedSpellPatch
{
[HarmonyPatch("CanCast")]
[HarmonyPrefix]
private static bool CanCastPrefix(ServerSpellCastingContext context, ref CanCastSpellResult __result)
{
//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)
if (!IsTeleportHome(context.Context, out var player))
{
return true;
}
if (!ConfigManager.Active || !WayhomeServer.IsTeleportHomeOnCooldown(player))
{
return true;
}
__result = (CanCastSpellResult)1;
return false;
}
[HarmonyPatch("DoCast")]
[HarmonyPostfix]
private static void DoCastPostfix(ProjectileSystem projectileSystem, ServerSpellCastingContext context, CastSpellArgs castSpellArgs)
{
//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)
if (IsTeleportHome(context.Context, out var player))
{
WayhomeServer.SetCooldown(player);
}
}
private static bool IsTeleportHome(SpellCastingContext context, out ServerPlayerCharacter player)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
player = null;
object spellTypeArgs = context.SpellTypeArgs;
ScriptedSpellArgs val = (ScriptedSpellArgs)((spellTypeArgs is ScriptedSpellArgs) ? spellTypeArgs : null);
if (val == null || val.Script != "player-teleport-home")
{
return false;
}
if (context.Target.HasValue)
{
return ServerGameState.TryGetPlayerCharacter(context.Target.Value, ref player);
}
return false;
}
}
[HarmonyPatch(typeof(ShopDataBase), "AddData")]
internal static class ShopDataBasePatch
{
private static void Postfix(List<Shop> shops)
{
EnsureMarketShopRegistered();
}
public static void EnsureMarketShopRegistered()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
if (ConfigManager.Active)
{
ConfigEntry<bool> marketSalesEnabled = ConfigManager.MarketSalesEnabled;
if (marketSalesEnabled != null && marketSalesEnabled.Value)
{
Dictionary<string, Shop> shopDataMap = ShopDataBase.ShopDataMap;
Shop val = new Shop();
val.Id = "wayhomecoins:market_wayhome_shop";
val.ItemIds = new string[1] { "wayhomecoins:market_wayhome_coin" };
val.MerchantLevel = ConfigManager.MerchantLevel;
shopDataMap["wayhomecoins:market_wayhome_shop"] = val;
return;
}
}
ShopDataBase.ShopDataMap.Remove("wayhomecoins:market_wayhome_shop");
}
public static void RefreshMarketShop()
{
EnsureMarketShopRegistered();
}
}
[HarmonyPatch(typeof(WorldOverviewWindow), "CursorClickOnMap", new Type[] { typeof(Vector2) })]
internal static class WorldOverviewWindowPatch
{
private static bool Prefix(WorldOverviewWindow __instance, Vector2 tilePosition, ref bool __result)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
if (!WayhomeClient.TryOpenMapShortcut(tilePosition, (CandideWindow)(object)__instance))
{
return true;
}
__result = false;
return false;
}
}
}
namespace WayhomeCoins.Networking
{
internal static class WayhomeEventKeys
{
public const string GetTargets = "wayhome-coins-get-targets";
public const string Teleport = "wayhome-coins-teleport";
public const string TeleportSucceeded = "wayhome-coins-teleport-succeeded";
public const string TeleportFailed = "wayhome-coins-teleport-failed";
}
public sealed class WayhomeTargetsRequest
{
}
public sealed class WayhomeTargetsResponse
{
public WayhomeTargetInfo[] Targets = Array.Empty<WayhomeTargetInfo>();
public int CoinCount;
public float CooldownRemainingSeconds;
}
public sealed class WayhomeTargetInfo
{
public WayhomeTargetKind Kind;
public Guid TargetId;
public string Name;
public string Icon;
public int CoinCost = 1;
}
public sealed class WayhomeTeleportRequest
{
public WayhomeTargetKind Kind;
public Guid TargetId;
}
public sealed class WayhomeResultMessage
{
public string MessageKey;
}
}
namespace WayhomeCoins.Features
{
internal static class WayhomeClient
{
private static CandideEngine _subscribedGame;
private static CandideModalWindow _menuModal;
private static bool _menuRequestPending;
private static bool _mapShortcutRequestPending;
private const int TargetListWidth = 260;
private const int TargetButtonLabelWidth = 220;
public static void UpdateHotkeys()
{
//IL_0012: 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)
EnsureNetworkEventsSubscribed();
if (CanUseHotkeys() && (int)ConfigManager.OpenMenuHotkey.Value != 0 && NativeInput.Pressed(ConfigManager.OpenMenuHotkey.Value))
{
ShowMenu();
}
}
public static void ShowMenu()
{
EnsureNetworkEventsSubscribed();
CandideDesktop desktop = CandideUiSystem.Desktop;
if (desktop != null && ConfigManager.Active && NetworkManager.ClientActive && _menuModal == null && !_menuRequestPending)
{
_menuRequestPending = true;
NetworkManager.Get<WayhomeTargetsResponse>("wayhome-coins-get-targets", (object)new WayhomeTargetsRequest(), (Action<WayhomeTargetsResponse>)delegate(WayhomeTargetsResponse response)
{
_menuRequestPending = false;
ShowTargetsModal(desktop, response);
}, 3f, (Action<byte>)delegate
{
_menuRequestPending = false;
ShowError(Text("status.targets_failed"));
}, true);
}
}
public static bool TryOpenMapShortcut(Vector2 tilePosition, CandideWindow mapWindow)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
EnsureNetworkEventsSubscribed();
if (((mapWindow != null) ? ((CandideUiElement)mapWindow).Desktop : null) != null && ConfigManager.Active)
{
ConfigEntry<bool> mapShortcutEnabled = ConfigManager.MapShortcutEnabled;
if (mapShortcutEnabled != null && mapShortcutEnabled.Value && NetworkManager.ClientActive)
{
if (!TryFindMapShortcutTarget(tilePosition, out var kind, out var targetId))
{
return false;
}
if (_mapShortcutRequestPending)
{
return true;
}
RequestMapShortcut(mapWindow, kind, targetId);
return true;
}
}
return false;
}
[EventBus("wayhome-coins-teleport-succeeded", true, null)]
public static void OnTeleportSucceeded(WayhomeResultMessage message)
{
ShowStatus(message?.MessageKey ?? "status.teleport.success");
}
[EventBus("wayhome-coins-teleport-failed", true, null)]
public static void OnTeleportFailed(WayhomeResultMessage message)
{
ShowStatus(message?.MessageKey ?? "status.teleport.failed");
}
private static void ShowTargetsModal(CandideDesktop desktop, WayhomeTargetsResponse response)
{
if (_menuModal != null)
{
return;
}
if (response == null)
{
ShowError(Text("status.targets_failed"));
return;
}
_menuModal = CandideModalWindow.ShowCustomModal(desktop, true, (Action<CandideModalWindow, CandideVerticalStackPanel>)delegate(CandideModalWindow modal, CandideVerticalStackPanel panel)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Expected O, but got Unknown
//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_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Expected O, but got Unknown
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Expected O, but got Unknown
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: 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_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Expected O, but got Unknown
//IL_0162: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_018a: Expected O, but got Unknown
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Expected O, but got Unknown
//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
//IL_01dc: Expected O, but got Unknown
((CandideUiContainerMultipleItems)panel).AddChild((CandideUiElement)new CandideTextLabel
{
Text = Text("ui.title"),
TextAlign = (TextHorizontalAlignment)1,
HorizontalAlignment = (HorizontalAlignment)3
}, false);
((CandideUiContainerMultipleItems)panel).AddChild((CandideUiElement)new CandideHorizontalSeparator
{
HorizontalAlignment = (HorizontalAlignment)3,
Padding = new CandideThickness(0, 6)
}, false);
((CandideUiContainerMultipleItems)panel).AddChild((CandideUiElement)new CandideTextLabel
{
Text = string.Format(Text("ui.coin_count"), response.CoinCount),
HorizontalAlignment = (HorizontalAlignment)3
}, false);
if (response.CooldownRemainingSeconds > 0f)
{
((CandideUiContainerMultipleItems)panel).AddChild((CandideUiElement)new CandideTextLabel
{
Text = string.Format(Text("ui.cooldown_remaining"), Math.Ceiling(response.CooldownRemainingSeconds)),
HorizontalAlignment = (HorizontalAlignment)3
}, false);
}
if (response.CoinCount <= 0 || response.CooldownRemainingSeconds > 0f)
{
((CandideUiContainerMultipleItems)panel).AddChild((CandideUiElement)new CandideTextLabel
{
Text = ((response.CoinCount <= 0) ? Text("status.no_coin") : Text("status.cooldown")),
Wrap = true,
HorizontalAlignment = (HorizontalAlignment)3
}, false);
}
CandideVerticalScrollViewer val = new CandideVerticalScrollViewer
{
MaxHeight = 300,
HorizontalAlignment = (HorizontalAlignment)1,
Margin = new CandideThickness(0, 8, 0, 0)
};
CandideVerticalStackPanel val2 = new CandideVerticalStackPanel
{
Width = 260,
DefaultColumnProportion = Proportion.Fill,
HorizontalAlignment = (HorizontalAlignment)3
};
((CandideUiContainerSingleItem)val).SetChild((CandideUiElement)(object)val2);
((CandideUiContainerMultipleItems)panel).AddChild((CandideUiElement)(object)val, false);
WayhomeTargetInfo[] array = response.Targets ?? Array.Empty<WayhomeTargetInfo>();
if (array.Length == 0)
{
((CandideUiContainerMultipleItems)val2).AddChild((CandideUiElement)new CandideTextLabel
{
Text = Text("ui.no_targets"),
Wrap = true,
HorizontalAlignment = (HorizontalAlignment)3
}, false);
}
else
{
WayhomeTargetInfo[] array2 = array;
foreach (WayhomeTargetInfo wayhomeTargetInfo in array2)
{
AddTargetButton(modal, val2, wayhomeTargetInfo, response.CooldownRemainingSeconds <= 0f && response.CoinCount >= Math.Max(1, wayhomeTargetInfo.CoinCost));
}
}
});
((CandideWindow)_menuModal).Closed += delegate
{
_menuModal = null;
};
}
private static void AddTargetButton(CandideModalWindow modal, CandideVerticalStackPanel list, WayhomeTargetInfo target, bool enabled)
{
//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_0059: 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_0067: 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_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Expected O, but got Unknown
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
CandideGridIconLabelButton val = new CandideGridIconLabelButton(string.IsNullOrWhiteSpace(target.Icon) ? "sell" : target.Icon, (IconFlag)1, (int?)220)
{
Text = FormatTargetName(target),
Enabled = enabled,
HorizontalAlignment = (HorizontalAlignment)3,
Padding = new CandideThickness(2, 2, 6, 4),
Margin = new CandideThickness(0, 2, 0, 2)
};
((CandideTextLabel)val.TextLabel).TextAlign = (TextHorizontalAlignment)0;
((CandideUiElement)val.TextLabel).Margin = new CandideThickness(4, 0, 0, -2);
((CandideButtonBase)val).OnClickAction = delegate
{
CandideModalWindow.ShowConfirmationModal(((CandideUiElement)modal).Desktop, string.Format(Text("ui.confirm"), Math.Max(1, target.CoinCost), target.Name), (Action)delegate
{
((CandideWindow)modal).Close();
PlayTeleportSound();
SendTeleport(target.Kind, target.TargetId);
}, (Action)null);
};
((CandideUiContainerMultipleItems)list).AddChild((CandideUiElement)(object)val, false);
}
private static void RequestMapShortcut(CandideWindow mapWindow, WayhomeTargetKind kind, Guid targetId)
{
_mapShortcutRequestPending = true;
NetworkManager.Get<WayhomeTargetsResponse>("wayhome-coins-get-targets", (object)new WayhomeTargetsRequest(), (Action<WayhomeTargetsResponse>)delegate(WayhomeTargetsResponse response)
{
_mapShortcutRequestPending = false;
ShowMapShortcutConfirmation(mapWindow, response, kind, targetId);
}, 3f, (Action<byte>)delegate
{
_mapShortcutRequestPending = false;
ShowError(Text("status.targets_failed"));
}, true);
}
private static void ShowMapShortcutConfirmation(CandideWindow mapWindow, WayhomeTargetsResponse response, WayhomeTargetKind kind, Guid targetId)
{
CandideWindow obj = mapWindow;
if (((obj != null) ? ((CandideUiElement)obj).Desktop : null) == null || response?.Targets == null)
{
ShowError(Text("status.targets_failed"));
return;
}
WayhomeTargetInfo target = Array.Find(response.Targets, (WayhomeTargetInfo candidate) => candidate.Kind == kind && candidate.TargetId == targetId);
if (target == null)
{
ShowStatus("status.target_unavailable");
return;
}
int num = Math.Max(1, target.CoinCost);
if (response.CooldownRemainingSeconds > 0f)
{
ShowStatus("status.cooldown");
return;
}
if (response.CoinCount < num)
{
ShowStatus("status.no_coin");
return;
}
CandideModalWindow.ShowConfirmationModal(((CandideUiElement)mapWindow).Desktop, string.Format(Text("ui.confirm"), num, target.Name), (Action)delegate
{
mapWindow.Close();
PlayTeleportSound();
SendTeleport(target.Kind, target.TargetId);
}, (Action)null);
}
private static bool TryFindMapShortcutTarget(Vector2 tilePosition, out WayhomeTargetKind kind, out Guid targetId)
{
//IL_0013: 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)
ConfigEntry<bool> homeTargetEnabled = ConfigManager.HomeTargetEnabled;
if (homeTargetEnabled != null && homeTargetEnabled.Value && TryFindMapTownTarget(tilePosition, out targetId))
{
kind = WayhomeTargetKind.Home;
return true;
}
ConfigEntry<bool> altarTargetEnabled = ConfigManager.AltarTargetEnabled;
if (altarTargetEnabled != null && altarTargetEnabled.Value && TryFindMapAltarTarget(tilePosition, out targetId))
{
kind = WayhomeTargetKind.Altar;
return true;
}
kind = WayhomeTargetKind.Home;
targetId = Guid.Empty;
return false;
}
private static bool TryFindMapTownTarget(Vector2 tilePosition, out Guid townId)
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
townId = Guid.Empty;
Building building = default(Building);
foreach (ClientTownModel value in GameState.Towns.Values)
{
if (GameState.TryGetBuilding((Guid?)value.Model.TownCoreId, ref building) && ContainsTile(building, tilePosition))
{
townId = value.Model.Id;
return true;
}
}
return false;
}
private static bool TryFindMapAltarTarget(Vector2 tilePosition, out Guid buildingId)
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
buildingId = Guid.Empty;
if (!WorldFlagsHelper.HasFlag(GameState.WorldFlags, "worship_flag:altar_teleport"))
{
return false;
}
foreach (Building value in GameState.Buildings.Values)
{
if (!(value.Model.BuildingTypeId != "altar") && ContainsTile(value, tilePosition))
{
ConstructionModel constructionOrNull = ConstructionDataBase.GetConstructionOrNull(value.Model.ConstructionId);
if (constructionOrNull != null && constructionOrNull.UpgradeLevel >= 1)
{
buildingId = value.Model.Id;
return true;
}
}
}
return false;
}
private static bool ContainsTile(Building building, Vector2 tilePosition)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
return ((Rectangle)(ref building.Model.TileBounds)).Contains((int)Math.Floor(tilePosition.X), (int)Math.Floor(tilePosition.Y));
}
private static string FormatTargetName(WayhomeTargetInfo target)
{
int num = Math.Max(1, target.CoinCost);
if (num > 1)
{
return string.Format(Text("ui.target_cost"), target.Name, num);
}
return target.Name;
}
private static void SendTeleport(WayhomeTargetKind kind, Guid targetId)
{
NetworkManager.SendMessage("wayhome-coins-teleport", (object)new WayhomeTeleportRequest
{
Kind = kind,
TargetId = targetId
}, (byte)2, true, false);
}
private static void PlayTeleportSound()
{
SoundPlayer.PlayEventOneShot("event:/interface/altar/ui_altar_teleport", 1f, 1f);
}
private static bool CanUseHotkeys()
{
if (!ConfigManager.Active || !NetworkManager.ClientActive)
{
return false;
}
if (UiInputSystem.InputFocusableElement != null)
{
return false;
}
CandideEngine game = Globals.Game;
if (game != null)
{
GameTerminal terminal = game.Terminal;
if (terminal == null)
{
return true;
}
return !terminal.Active;
}
return false;
}
private static void EnsureNetworkEventsSubscribed()
{
CandideEngine game = Globals.Game;
if (game != null && _subscribedGame != game)
{
game.NetworkEventBusManager.Subscribe(Assembly.GetExecutingAssembly(), (string)null);
_subscribedGame = game;
}
}
private static void ShowError(string text)
{
CandideDesktop desktop = CandideUiSystem.Desktop;
if (desktop != null)
{
CandideModalWindow.ShowErrorModal(desktop, text);
}
else
{
ShowStatusDirect(text);
}
}
private static void ShowStatus(string messageKey)
{
ShowStatusDirect(Text(messageKey));
}
private static void ShowStatusDirect(string text)
{
ChatLogMessage obj = ChatLogMessage.DirectText(text, (ChatMessageType)4, (string)null);
obj.Silent = true;
ChatLogManager.SendLocalChatMessage(obj);
}
private static string Text(string key)
{
return I18n.L.Text(key, Array.Empty<object>());
}
}
internal static class WayhomeServer
{
public const string TravelersCoinId = "consumable:travelers_coin";
public const string MarketCoinId = "wayhomecoins:market_wayhome_coin";
public const string MarketShopId = "wayhomecoins:market_wayhome_shop";
private static readonly string[] SpendableCoinIds = new string[2] { "wayhomecoins:market_wayhome_coin", "consumable:travelers_coin" };
private static readonly Guid TentBaseId = Guid.Parse("5a34399a-9a36-4447-ad3c-908ffbad824a");
private static readonly Dictionary<Guid, double> NextReadyTimeByCharacter = new Dictionary<Guid, double>();
[EventBus("wayhome-coins-get-targets", true, null)]
public static void OnGetTargets(WayhomeTargetsRequest request, EventBusArgs args)
{
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Expected O, but got Unknown
try
{
if (!ConfigManager.Active || !TryGetPlayer(args, out var _, out var joinedPlayer, out var inventory))
{
BaseServer.Instance.SendGetResponseError(args, (byte)1);
return;
}
BaseServer.Instance.SendGetResponseMessage(args, (object)new WayhomeTargetsResponse
{
Targets = GetTargets(joinedPlayer).ToArray(),
CoinCount = GetCoinCount(inventory),
CooldownRemainingSeconds = GetCooldownRemaining(joinedPlayer)
}, true);
}
catch (Exception ex)
{
ManualLogSource logger = WayhomeCoins.Logger;
if (logger != null)
{
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(28, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Get wayhome targets failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
logger.LogError(val);
}
BaseServer.Instance.SendGetResponseError(args, (byte)1);
}
}
[EventBus("wayhome-coins-teleport", true, null)]
public static void OnTeleport(WayhomeTeleportRequest request, EventBusArgs args)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Expected O, but got Unknown
try
{
if (TryTeleportFromMessage(request, args, out var failKey))
{
SendResult(args, "wayhome-coins-teleport-succeeded", "status.teleport.success");
}
else
{
SendResult(args, "wayhome-coins-teleport-failed", failKey);
}
}
catch (Exception ex)
{
ManualLogSource logger = WayhomeCoins.Logger;
if (logger != null)
{
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(25, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Wayhome teleport failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
logger.LogError(val);
}
SendResult(args, "wayhome-coins-teleport-failed", "status.teleport.failed");
}
}
public static bool TryTeleportFromMessage(WayhomeTeleportRequest request, EventBusArgs args, out string failKey)
{
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
failKey = "status.teleport.failed";
if (request == null || !ConfigManager.Active)
{
return false;
}
if (!TryGetPlayer(args, out var _, out var joinedPlayer, out var inventory))
{
return false;
}
if (!IsTargetKindEnabled(request.Kind))
{
failKey = "status.target_disabled";
return false;
}
if (!TryResolveTarget(joinedPlayer, request.Kind, request.TargetId, out var worldId, out var position))
{
failKey = "status.target_unavailable";
return false;
}
if (!CanTeleportNow(joinedPlayer, out failKey))
{
return false;
}
int coinCost = GetCoinCost(joinedPlayer, worldId, position);
return TrySpendAndMove(joinedPlayer, inventory, worldId, position, coinCost, out failKey);
}
public static float GetCooldownRemaining(ServerJoinedPlayerModel player)
{
if (player?.CharacterModel?.Character == null || !NextReadyTimeByCharacter.TryGetValue(player.CharacterModel.Character.EntityId, out var value))
{
return 0f;
}
double num = value - ServerGameState.GetWorldPlayTimeSeconds();
if (!(num <= 0.0))
{
return (float)num;
}
return 0f;
}
private static List<WayhomeTargetInfo> GetTargets(ServerJoinedPlayerModel player)
{
List<WayhomeTargetInfo> list = new List<WayhomeTargetInfo>();
ConfigEntry<bool> homeTargetEnabled = ConfigManager.HomeTargetEnabled;
if (homeTargetEnabled != null && homeTargetEnabled.Value)
{
AddTownTargets(player, list);
}
ConfigEntry<bool> altarTargetEnabled = ConfigManager.AltarTargetEnabled;
if (altarTargetEnabled != null && altarTargetEnabled.Value)
{
AddAltarTargets(list);
}
ConfigEntry<bool> tentTargetEnabled = ConfigManager.TentTargetEnabled;
if (tentTargetEnabled != null && tentTargetEnabled.Value)
{
AddTentTargets(player, list);
}
ConfigEntry<bool> graveTargetEnabled = ConfigManager.GraveTargetEnabled;
if (graveTargetEnabled != null && graveTargetEnabled.Value && TryResolveGrave(player, player.LastGraveId ?? Guid.Empty, out var _, out var _, out var grave))
{
list.Add(new WayhomeTargetInfo
{
Kind = WayhomeTargetKind.Grave,
TargetId = grave.Id,
Name = Text("target.grave"),
Icon = "map_marker:gravestone"
});
}
ConfigEntry<bool> playerTargetEnabled = ConfigManager.PlayerTargetEnabled;
if (playerTargetEnabled != null && playerTargetEnabled.Value)
{
AddPlayerTargets(player, list);
}
ApplyTargetCosts(player, list);
return list;
}
private static bool TryResolveTarget(ServerJoinedPlayerModel player, WayhomeTargetKind kind, Guid targetId, out Guid worldId, out Vector3 position)
{
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
BuildingSimulationModel building;
ServerEntityModel grave;
switch (kind)
{
case WayhomeTargetKind.Home:
{
ServerTownModel town;
return TryResolveTownCore(player, targetId, out town, out worldId, out position, out building);
}
case WayhomeTargetKind.Altar:
return TryResolveAltar(targetId, out worldId, out position, out building);
case WayhomeTargetKind.Grave:
return TryResolveGrave(player, targetId, out worldId, out position, out grave);
case WayhomeTargetKind.Tent:
return TryResolveTent(player, targetId, out worldId, out position, out grave);
case WayhomeTargetKind.Player:
{
ServerJoinedPlayerModel target;
return TryResolvePlayer(player, targetId, out worldId, out position, out target);
}
default:
worldId = Guid.Empty;
position = default(Vector3);
return false;
}
}
private static void AddAltarTargets(List<WayhomeTargetInfo> result)
{
if (!WorldFlagsHelper.HasFlag(ServerGameState.WorldFlags, "worship_flag:altar_teleport"))
{
return;
}
foreach (ServerTownModel value in ServerGameState.Towns.Values)
{
foreach (Guid buildingId in value.Model.BuildingIds)
{
if (TryResolveAltar(buildingId, out var _, out var _, out var building))
{
result.Add(new WayhomeTargetInfo
{
Kind = WayhomeTargetKind.Altar,
TargetId = building.InstanceModel.Id,
Name = string.Format(Text("target.altar"), GetTownTargetName(value)),
Icon = "altar"
});
}
}
}
}
private static bool TryResolveAltar(Guid targetId, out Guid worldId, out Vector3 position, out BuildingSimulationModel building)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
worldId = Guid.Empty;
position = default(Vector3);
building = null;
if (targetId == Guid.Empty || !WorldFlagsHelper.HasFlag(ServerGameState.WorldFlags, "worship_flag:altar_teleport") || !ServerGameState.TryGetBuilding(targetId, ref building) || building.InstanceModel.BuildingTypeId != "altar")
{
return false;
}
ConstructionModel constructionOrNull = ConstructionDataBase.GetConstructionOrNull(building.InstanceModel.ConstructionId);
if (constructionOrNull == null || constructionOrNull.UpgradeLevel < 1)
{
return false;
}
return TryResolveBuildingOutside(building, out worldId, out position, bottomCenter: true);
}
private static void AddTownTargets(ServerJoinedPlayerModel player, List<WayhomeTargetInfo> result)
{
Guid worldId;
Vector3 position;
BuildingSimulationModel building;
if (CanUseAnyTownAndTentTargets())
{
foreach (ServerTownModel value in ServerGameState.Towns.Values)
{
if (TryResolveTownCore(value, out worldId, out position, out building))
{
result.Add(new WayhomeTargetInfo
{
Kind = WayhomeTargetKind.Home,
TargetId = value.Model.Id,
Name = GetTownTargetName(value),
Icon = "town_core"
});
}
}
return;
}
if (TryResolvePlayerTownCore(player, out var town, out worldId, out position, out building))
{
result.Add(new WayhomeTargetInfo
{
Kind = WayhomeTargetKind.Home,
TargetId = town.Model.Id,
Name = GetTownTargetName(town),
Icon = "town_core"
});
}
}
private static bool TryResolveTownCore(ServerJoinedPlayerModel player, Guid targetId, out ServerTownModel town, out Guid worldId, out Vector3 position, out BuildingSimulationModel building)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
if (CanUseAnyTownAndTentTargets() && targetId != Guid.Empty)
{
town = null;
worldId = Guid.Empty;
position = default(Vector3);
building = null;
if (ServerGameState.Towns.TryGetValue(targetId, out town))
{
return TryResolveTownCore(town, out worldId, out position, out building);
}
return false;
}
if (TryResolvePlayerTownCore(player, out town, out worldId, out position, out building))
{
if (!(targetId == Guid.Empty))
{
return town.Model.Id == targetId;
}
return true;
}
return false;
}
private static bool TryResolvePlayerTownCore(ServerJoinedPlayerModel player, out ServerTownModel town, out Guid worldId, out Vector3 position, out BuildingSimulationModel building)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
town = null;
worldId = Guid.Empty;
position = default(Vector3);
building = null;
if (player?.CharacterModel?.Character == null)
{
return false;
}
if (!TryGetPlayerTown(player, out town))
{
return false;
}
return TryResolveTownCore(town, out worldId, out position, out building);
}
private static bool TryResolveTownCore(ServerTownModel town, out Guid worldId, out Vector3 position, out BuildingSimulationModel building)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
worldId = Guid.Empty;
position = default(Vector3);
building = null;
if (town?.Model == null)
{
return false;
}
if (!ServerGameState.Buildings.TryGetValue(town.Model.TownCoreId, out building))
{
return false;
}
return TryResolveBuildingOutside(building, out worldId, out position, bottomCenter: false);
}
private static bool TryResolveBuildingOutside(BuildingSimulationModel building, out Guid worldId, out Vector3 position, bool bottomCenter)
{
//IL_000c: 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_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
worldId = Guid.Empty;
position = default(Vector3);
if (building == null || !ServerGameState.Worlds.TryGetValue(building.InstanceModel.ExteriorWorldId, out var value) || !value.ParentWorldId.HasValue)
{
return false;
}
worldId = value.ParentWorldId.Value;
Vector2 centeredPositionFromTileBounds = TileBoundsHelper.GetCenteredPositionFromTileBounds(building.InstanceModel.TileBounds);
if (bottomCenter)
{
centeredPositionFromTileBounds.Y += ((float)building.InstanceModel.TileBounds.Height / 2f - 1f) * 16f;
}
position = VectorExtension.ToVector3Xy(centeredPositionFromTileBounds);
return true;
}
private static bool TryGetPlayerTown(ServerJoinedPlayerModel player, out ServerTownModel town)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Invalid comparison between Unknown and I4
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
town = null;
(Guid, Vector3) characterSpawn = PlayerCharacterServerManager.GetCharacterSpawn(player.CharacterModel);
BuildingSimulationModel val = default(BuildingSimulationModel);
if (ServerGameState.Worlds.TryGetValue(characterSpawn.Item1, out var value) && (int)value.Type == 2 && (int)value.Interior == 0 && value.BuildingId.HasValue && ServerGameState.TryGetBuilding(value.BuildingId.Value, ref val) && val.InstanceModel.TownId.HasValue && ServerGameState.TryGetTown(val.InstanceModel.TownId.Value, ref town))
{
return true;
}
Guid entityId = player.CharacterModel.Character.EntityId;
BuildingSimulationModel val2 = default(BuildingSimulationModel);
foreach (ServerTownModel value3 in ServerGameState.Towns.Values)
{
if (ServerGameState.TryGetBuilding(value3.Model.TownCoreId, ref val2) && val2.InstanceModel.Parameters != null && val2.InstanceModel.Parameters.TryGetValue("owner_character_id", out var value2) && Guid.TryParse(value2, out var result) && result == entityId)
{
town = value3;
return true;
}
}
return false;
}
private static void AddPlayerTargets(ServerJoinedPlayerModel player, List<WayhomeTargetInfo> result)
{
foreach (ServerJoinedPlayerModel value in PlayerServerService.JoinedPlayers.Values)
{
if (CanTeleportToPlayer(player, value))
{
result.Add(new WayhomeTargetInfo
{
Kind = WayhomeTargetKind.Player,
TargetId = value.CharacterModel.Character.EntityId,
Name = string.Format(Text("target.player"), GetPlayerName(value)),
Icon = "ui:citizen"
});
}
}
}
private static bool TryResolvePlayer(ServerJoinedPlayerModel player, Guid targetId, out Guid worldId, out Vector3 position, out ServerJoinedPlayerModel target)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
worldId = Guid.Empty;
position = default(Vector3);
target = null;
if (targetId == Guid.Empty)
{
return false;
}
foreach (ServerJoinedPlayerModel value in PlayerServerService.JoinedPlayers.Values)
{
ServerPlayerCharacter characterModel = value.CharacterModel;
if (characterModel != null)
{
Guid? guid = characterModel.Character?.EntityId;
if (guid.HasValue && !(guid.GetValueOrDefault() != targetId) && CanTeleportToPlayer(player, value))
{
target = value;
worldId = value.CharacterModel.Character.WorldId;
position = value.CharacterModel.Character.Position + new Vector3(16f, 0f, 0f);
return true;
}
}
}
return false;
}
private static bool TryResolveGrave(ServerJoinedPlayerModel player, Guid targetId, out Guid worldId, out Vector3 position, out ServerEntityModel grave)
{
//IL_000c: 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)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
worldId = Guid.Empty;
position = default(Vector3);
grave = null;
if (targetId == Guid.Empty || player.LastGraveId != targetId)
{
return false;
}
if (!ServerGameState.TryGetServerEntity(targetId, ref grave, "TryResolveGrave") || grave.BaseId != EntityIds.PlayerGrave)
{
return false;
}
if (!GraveBelongsToPlayer(grave, player.CharacterModel.Character.EntityId))
{
return false;
}
worldId = grave.WorldId;
position = grave.Position + new Vector3(0f, 16f, 0f);
return true;
}
private static void AddTentTargets(ServerJoinedPlayerModel player, List<WayhomeTargetInfo> result)
{
if (CanUseAnyTownAndTentTargets())
{
HashSet<Guid> hashSet = new HashSet<Guid>();
{
foreach (ServerEntityModel value in ServerGameState.Entities.Values)
{
if (IsTentEntity(value) && hashSet.Add(value.Id))
{
result.Add(new WayhomeTargetInfo
{
Kind = WayhomeTargetKind.Tent,
TargetId = value.Id,
Name = GetTentTargetName(value),
Icon = "tent_red"
});
}
}
return;
}
}
if (TryResolvePlayerTent(player, out var _, out var _, out var tentEntity))
{
result.Add(new WayhomeTargetInfo
{
Kind = WayhomeTargetKind.Tent,
TargetId = tentEntity.Id,
Name = GetTentTargetName(tentEntity),
Icon = "tent_red"
});
}
}
private static bool TryResolveTent(ServerJoinedPlayerModel player, Guid targetId, out Guid worldId, out Vector3 position, out ServerEntityModel tentEntity)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
if (CanUseAnyTownAndTentTargets() && targetId != Guid.Empty)
{
worldId = Guid.Empty;
position = default(Vector3);
tentEntity = null;
if (!ServerGameState.Entities.TryGetValue(targetId, out tentEntity) || !IsTentEntity(tentEntity))
{
return false;
}
worldId = tentEntity.WorldId;
position = tentEntity.Position + new Vector3(0f, 16f, 0f);
return true;
}
if (TryResolvePlayerTent(player, out worldId, out position, out tentEntity))
{
if (!(targetId == Guid.Empty))
{
return tentEntity.Id == targetId;
}
return true;
}
return false;
}
private static bool TryResolvePlayerTent(ServerJoinedPlayerModel player, out Guid worldId, out Vector3 position, out ServerEntityModel tentEntity)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
worldId = Guid.Empty;
position = default(Vector3);
tentEntity = null;
ServerPlayerCharacter val = player?.CharacterModel;
if (!val.SpawnPointEntityId.HasValue || !val.SpawnPosition.HasValue)
{
return false;
}
if (!ServerGameState.Entities.TryGetValue(val.SpawnPointEntityId.Value, out tentEntity) || !IsTentEntity(tentEntity))
{
return false;
}
worldId = val.SpawnWorldId;
position = VectorExtension.ToVector3Xy(val.SpawnPosition.Value);
return true;
}
private static bool TrySpendAndMove(ServerJoinedPlayerModel player, SharedInventoryModel inventory, Guid worldId, Vector3 position, int coinCost, out string failKey)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
failKey = "status.teleport.failed";
if (GetCooldownRemaining(player) > 0f)
{
failKey = "status.cooldown";
return false;
}
if (GetCoinCount(inventory) < coinCost)
{
failKey = "status.no_coin";
return false;
}
if (!TrySpendCoins(inventory, coinCost))
{
failKey = "status.no_coin";
return false;
}
DetachCarriedEntity(player);
PlayerServerManager.MovePlayerCharacter(player, position, (Guid?)worldId, true);
SetCooldown(player);
return true;
}
private static bool TryGetPlayer(EventBusArgs args, out ServerPlayerCharacter character, out ServerJoinedPlayerModel joinedPlayer, out SharedInventoryModel inventory)
{
character = null;
joinedPlayer = null;
inventory = null;
(ServerPlayerCharacter, ServerJoinedPlayerModel)? playerInfoFromPeerId = PlayerServerService.GetPlayerInfoFromPeerId((int)args.Peer.Id);
if (!playerInfoFromPeerId.HasValue)
{
return false;
}
character = playerInfoFromPeerId.Value.Item1;
joinedPlayer = playerInfoFromPeerId.Value.Item2;
return ServerGameState.TryGetInventory(character.Character.CharacterInventoryModel.InventoryId, ref inventory);
}
public static bool IsWayhomeCoinId(string itemId)
{
if (!(itemId == "consumable:travelers_coin"))
{
return itemId == "wayhomecoins:market_wayhome_coin";
}
return true;
}
private static int GetCoinCount(SharedInventoryModel inventory)
{
if (inventory == null)
{
return 0;
}
int num = 0;
for (int i = 0; i < SpendableCoinIds.Length; i++)
{
num += inventory.GetItemCount(SpendableCoinIds[i]);
}
return num;
}
private static bool TrySpendCoins(SharedInventoryModel inventory, int count)
{
if (count <= 0)
{
return true;
}
if (GetCoinCount(inventory) < count)
{
return false;
}
int num = count;
for (int i = 0; i < SpendableCoinIds.Length; i++)
{
if (num <= 0)
{
break;
}
while (num > 0)
{
(int, ItemInstanceModel) tuple = inventory.FindFirstSlotIndexWithBaseId(SpendableCoinIds[i], false);
if (tuple.Item1 < 0)
{
break;
}
int num2 = Math.Min(num, tuple.Item2.StackCount);
if (!SimpleInventoryServerManager.TryExpendItem(inventory.Id, tuple.Item1, num2, false))
{
return false;
}
num -= num2;
}
}
return num <= 0;
}
private static bool IsTargetKindEnabled(WayhomeTargetKind kind)
{
return kind switch
{
WayhomeTargetKind.Home => ConfigManager.HomeTargetEnabled?.Value ?? false,
WayhomeTargetKind.Altar => ConfigManager.AltarTargetEnabled?.Value ?? false,
WayhomeTargetKind.Grave => ConfigManager.GraveTargetEnabled?.Value ?? false,
WayhomeTargetKind.Tent => ConfigManager.TentTargetEnabled?.Value ?? false,
WayhomeTargetKind.Player => ConfigManager.PlayerTargetEnabled?.Value ?? false,
_ => false,
};
}
private static bool CanUseAnyTownAndTentTargets()
{
return ConfigManager.AnyTownAndTentTargetEnabled?.Value ?? false;
}
private static bool IsTentEntity(ServerEntityModel entity)
{
return entity?.BaseId == TentBaseId;
}
private static bool CanTeleportToPlayer(ServerJoinedPlayerModel player, ServerJoinedPlayerModel target)
{
if (player != null && target?.CharacterModel?.Character != null && !target.Dead)
{
return target.CharacterModel.Character.EntityId != player.CharacterModel.Character.EntityId;
}
return false;
}
private static bool CanTeleportNow(ServerJoinedPlayerModel player, out string failKey)
{
failKey = null;
if (player == null)
{
failKey = "status.teleport.failed";
return false;
}
if (player.Dead)
{
ConfigEntry<bool> allowTeleportWhileDead = ConfigManager.AllowTeleportWhileDead;
if (allowTeleportWhileDead == null || !allowTeleportWhileDead.Value)
{
failKey = "status.restricted_dead";
return false;
}
}
EntityWrapper entity = player.Entity;
if (entity != null && entity.CarriedId.HasValue)
{
ConfigEntry<bool> allowTeleportWhileCarrying = ConfigManager.AllowTeleportWhileCarrying;
if (allowTeleportWhileCarrying == null || !allowTeleportWhileCarrying.Value)
{
failKey = "status.restricted_carrying";
return false;
}
}
if (IsInDungeon(player))
{
ConfigEntry<bool> allowTeleportInDungeon = ConfigManager.AllowTeleportInDungeon;
if (allowTeleportInDungeon == null || !allowTeleportInDungeon.Value)
{
failKey = "status.restricted_dungeon";
return false;
}
}
if (IsInCombat(player))
{
ConfigEntry<bool> allowTeleportInCombat = ConfigManager.AllowTeleportInCombat;
if (allowTeleportInCombat == null || !allowTeleportInCombat.Value)
{
failKey = "status.restricted_combat";
return false;
}
}
return true;
}
private static bool IsInDungeon(ServerJoinedPlayerModel player)
{
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Invalid comparison between Unknown and I4
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Invalid comparison between Unknown and I4
Guid? guid = player?.CharacterModel?.Character?.WorldId;
if (guid.HasValue && ServerGameState.Worlds.TryGetValue(guid.Value, out var value) && (int)value.Type == 2)
{
return (int)value.Interior == 1;
}
return false;
}
private static bool IsInCombat(ServerJoinedPlayerModel player)
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
EntityWrapper val = player?.Entity;
if (val == null)
{
return false;
}
foreach (ServerEntityModel value in ServerGameState.Entities.Values)
{
EntityWrapper val2 = value?.EntityWrapper;
if (val2 != null && !val2.Removed && ComponentExtension.HasFlags(val2.Mask, (Component)8) && val2.TargetOfAggro != null && val2.TargetOfAggro.Id == val.Id)
{
return true;
}
}
return false;
}
private static void DetachCarriedEntity(ServerJoinedPlayerModel player)
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
if (player != null && (player.EntityModel?.CarriedEntityId).HasValue)
{
EntityServerManager.Detach(player.EntityModel, (Vector3?)null, SyncStrategy.SendToAll, true);
}
}
private static void ApplyTargetCosts(ServerJoinedPlayerModel player, List<WayhomeTargetInfo> targets)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
foreach (WayhomeTargetInfo target in targets)
{
target.CoinCost = ((!TryResolveTarget(player, target.Kind, target.TargetId, out var worldId, out var position)) ? 1 : GetCoinCost(player, worldId, position));
}
}
private static int GetCoinCost(ServerJoinedPlayerModel player, Guid worldId, Vector3 position)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
ConfigEntry<bool> distanceCostEnabled = ConfigManager.DistanceCostEnabled;
if (distanceCostEnabled == null || !distanceCostEnabled.Value)
{
return 1;
}
float distanceTiles = GetDistanceTiles(player, worldId, position);
if (distanceTiles <= 0f)
{
return 1;
}
int num = (int)Math.Floor(distanceTiles / (float)ConfigManager.TilesPerExtraCoin);
return Math.Clamp(1 + num, 1, ConfigManager.MaxDistanceCostCoins);
}
private static float GetDistanceTiles(ServerJoinedPlayerModel player, Guid worldId, Vector3 position)
{
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: 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)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
if (!TryGetOutsidePosition(player?.CharacterModel?.Character?.WorldId ?? Guid.Empty, (player?.CharacterModel?.Character?.Position).GetValueOrDefault(), out var outsideWorldId, out var outsidePosition) || !TryGetOutsidePosition(worldId, position, out var outsideWorldId2, out var outsidePosition2) || outsideWorldId != outsideWorldId2)
{
return 0f;
}
return Vector2.Distance(VectorExtension.ToVector2(outsidePosition), VectorExtension.ToVector2(outsidePosition2)) / 16f;
}
private static bool TryGetOutsidePosition(Guid worldId, Vector3 position, out Guid outsideWorldId, out Vector3 outsidePosition)
{
//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_0026: Invalid comparison between Unknown and I4
outsideWorldId = worldId;
outsidePosition = position;
if (!ServerGameState.Worlds.TryGetValue(worldId, out var value))
{
return false;
}
if ((int)value.Type != 2)
{
return true;
}
BuildingSimulationModel building = default(BuildingSimulationModel);
if (value.BuildingId.HasValue && ServerGameState.TryGetBuilding(value.BuildingId.Value, ref building) && TryResolveBuildingOutside(building, out outsideWorldId, out outsidePosition, bottomCenter: false))
{
return true;
}
return false;
}
private static string GetPlayerName(ServerJoinedPlayerModel player)
{
string text = player?.CharacterModel?.Character?.Name;
if (!string.IsNullOrWhiteSpace(text))
{
return text;
}
return Text("target.player_unknown");
}
private static string GetTentTargetName(ServerEntityModel tent)
{
if (tent?.Parameters != null && tent.Parameters.TryGetValue("owner_character_id", out var value) && Guid.TryParse(value, out var result) && TryGetCharacterName(result, out var name))
{
return string.Format(Text("target.tent_owner"), name);
}
return Text("target.tent");
}
private static bool TryGetCharacterName(Guid characterId, out string name)
{
if (ServerGameState.PlayerCharacters.TryGetValue(characterId, out var value) && !string.IsNullOrWhiteSpace(value.Character?.Name))
{
name = value.Character.Name;
return true;
}
foreach (ServerJoinedPlayerModel value2 in PlayerServerService.JoinedPlayers.Values)
{
ServerPlayerCharacter characterModel = value2.CharacterModel;
if (characterModel != null)
{
Guid? guid = characterModel.Character?.EntityId;
if (guid.HasValue && guid.GetValueOrDefault() == characterId && !string.IsNullOrWhiteSpace(value2.CharacterModel.Character.Name))
{
name = value2.CharacterModel.Character.Name;
return true;
}
}
}
name = null;
return false;
}
private static bool GraveBelongsToPlayer(ServerEntityModel grave, Guid characterId)
{
if (grave.Parameters == null || !grave.Parameters.TryGetValue("character_id", out var value))
{
return true;
}
if (Guid.TryParse(value, out var result))
{
return result == characterId;
}
return false;
}
public static bool IsTeleportHomeOnCooldown(ServerPlayerCharacter character)
{
if (!ConfigManager.Active || character == null || !PlayerServerService.JoinedPlayers.TryGetValue(character.PlayerId, out var value))
{
return false;
}
return GetCooldownRemaining(value) > 0f;
}
public static void SetCooldown(ServerPlayerCharacter character)
{
if (ConfigManager.Active && character != null && PlayerServerService.JoinedPlayers.TryGetValue(character.PlayerId, out var value))
{
SetCooldown(value);
}
}
private static void SetCooldown(ServerJoinedPlayerModel player)
{
float cooldownSeconds = ConfigManager.CooldownSeconds;
if (cooldownSeconds <= 0f)
{
NextReadyTimeByCharacter.Remove(player.CharacterModel.Character.EntityId);
}
else
{
NextReadyTimeByCharacter[player.CharacterModel.Character.EntityId] = ServerGameState.GetWorldPlayTimeSeconds() + (double)cooldownSeconds;
}
}
private static void SendResult(EventBusArgs args, string key, string messageKey)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
BaseServer.Instance.SendHostMessage(key, (object)new WayhomeResultMessage
{
MessageKey = messageKey
}, args.Peer);
}
private static string Text(string key)
{
return I18n.L.Text(key, Array.Empty<object>());
}
private static string GetTownTargetName(ServerTownModel town)
{
object obj;
if (town == null)
{
obj = null;
}
else
{
TownModel model = town.Model;
obj = ((model != null) ? model.GetLocalizedName() : null);
}
string text = (string)obj;
if (!string.IsNullOrWhiteSpace(text) && !text.StartsWith("<", StringComparison.Ordinal))
{
return text;
}
return Text("target.town_core");
}
}
public enum WayhomeTargetKind : byte
{
Home,
Altar,
Grave,
Tent,
Player
}
}
namespace WayhomeCoins.Configuration
{
internal static class ConfigManager
{
private sealed class LocalizedSectionTag
{
private readonly string _displayNameKey;
public string Section { get; }
public string DisplayName => Text(_displayNameKey);
public int? Order { get; }
public LocalizedSectionTag(string section, string displayNameKey, int? order)
{
Section = section;
_displayNameKey = displayNameKey;
Order = order;
}
}
private sealed class LocalizedEntryTag
{
private readonly string _displayNameKey;
private readonly string _descriptionKey;
public string DisplayName => Text(_displayNameKey);
public string Description => Text(_descriptionKey);
public int? Order { get; }
public double? SliderStep { get; }
public bool? Keybind { get; }
public LocalizedEntryTag(string displayNameKey, string descriptionKey, int? order, double? sliderStep, bool keybind)
{
_displayNameKey = displayNameKey;
_descriptionKey = descriptionKey;
Order = order;
SliderStep = sliderStep;
Keybind = keybind;
}
}
public const string GeneralSection = "General";
public const string TargetsSection = "Targets";
public const string MarketSection = "Market";
public const string RestrictionsSection = "Restrictions";
public const string CostSection = "Cost";
public const string ControlsSection = "Controls";
public static ConfigEntry<bool> Enabled { get; private set; }
public static ConfigEntry<float> TeleportCooldownSeconds { get; private set; }
public static ConfigEntry<bool> HomeTargetEnabled { get; private set; }
public static ConfigEntry<bool> AltarTargetEnabled { get; private set; }
public static ConfigEntry<bool> GraveTargetEnabled { get; private set; }
public static ConfigEntry<bool> TentTargetEnabled { get; private set; }
public static ConfigEntry<bool> AnyTownAndTentTargetEnabled { get; private set; }
public static ConfigEntry<bool> PlayerTargetEnabled { get; private set; }
public static ConfigEntry<bool> AllowTeleportWhileCarrying { get; private set; }
public static ConfigEntry<bool> AllowTeleportWhileDead { get; private set; }
public static ConfigEntry<bool> AllowTeleportInCombat { get; private set; }
public static ConfigEntry<bool> AllowTeleportInDungeon { get; private set; }
public static ConfigEntry<bool> DistanceCostEnabled { get; private set; }
public static ConfigEntry<int> DistanceTilesPerExtraCoin { get; private set; }
public static ConfigEntry<int> DistanceCostMaxCoins { get; private set; }
public static ConfigEntry<bool> MapShortcutEnabled { get; private set; }
public static ConfigEntry<bool> MarketSalesEnabled { get; private set; }
public static ConfigEntry<int> MarketCoinPrice { get; private set; }
public static ConfigEntry<int> MarketCoinStackSize { get; private set; }
public static ConfigEntry<int> MarketMerchantLevel { get; private set; }
public static ConfigEntry<Keys> OpenMenuHotkey { get; private set; }
public static bool Active => Enabled?.Value ?? false;
public static float CooldownSeconds => Math.Clamp(TeleportCooldownSeconds?.Value ?? 30f, 0f, 120f);
public static ulong MarketPrice => (ulong)Math.Clamp(MarketCoinPrice?.Value ?? 200, 1, 1000);
public static int MarketStackSize => Math.Clamp(MarketCoinStackSize?.Value ?? 100, 1, 100);
public static int MerchantLevel => Math.Clamp(MarketMerchantLevel?.Value ?? 1, 1, 7);
public static int TilesPerExtraCoin => Math.Clamp(DistanceTilesPerExtraCoin?.Value ?? 500, 50, 5000);
public static int MaxDistanceCostCoins => Math.Clamp(DistanceCostMaxCoins?.Value ?? 5, 1, 100);
public static event Action MarketSettingsChanged;
public static void Init(ConfigFile config)
{
Enabled = config.Bind<bool>("General", "Enabled", true, Description("config.enabled.description", "entry.enabled", 1, "General", "section.general", 10));
AcceptableValueBase acceptableValues = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f);
double? sliderStep = 1.0;
TeleportCooldownSeconds = config.Bind<float>("General", "TeleportCooldownSeconds", 30f, Description("config.cooldown.description", "entry.cooldown", 2, null, null, null, acceptableValues, sliderStep));
HomeTargetEnabled = config.Bind<bool>("Targets", "HomeTargetEnabled", true, Description("config.home_target.description", "entry.home_target", 1, "Targets", "section.targets", 20));
AltarTargetEnabled = config.Bind<bool>("Targets", "AltarTargetEnabled", true, Description("config.altar_target.description", "entry.altar_target", 2));
GraveTargetEnabled = config.Bind<bool>("Targets", "GraveTargetEnabled", true, Description("config.grave_target.description", "entry.grave_target", 3));
TentTargetEnabled = config.Bind<bool>("Targets", "TentTargetEnabled", true, Description("config.tent_target.description", "entry.tent_target", 4));
PlayerTargetEnabled = config.Bind<bool>("Targets", "PlayerTargetEnabled", true, Description("config.player_target.description", "entry.player_target", 5));
AnyTownAndTentTargetEnabled = config.Bind<bool>("Targets", "AnyTownAndTentTargetEnabled", true, Description("config.any_town_tent_target.description", "entry.any_town_tent_target", 6));
AllowTeleportWhileCarrying = config.Bind<bool>("Restrictions", "AllowTeleportWhileCarrying", false, Description("config.allow_carrying.description", "entry.allow_carrying", 1, "Restrictions", "section.restrictions", 30));
AllowTeleportWhileDead = config.Bind<bool>("Restrictions", "AllowTeleportWhileDead", false, Description("config.allow_dead.description", "entry.allow_dead", 2));
AllowTeleportInCombat = config.Bind<bool>("Restrictions", "AllowTeleportInCombat", false, Description("config.allow_combat.description", "entry.allow_combat", 3));
AllowTeleportInDungeon = config.Bind<bool>("Restrictions", "AllowTeleportInDungeon", false, Description("config.allow_dungeon.description", "entry.allow_dungeon", 4));
DistanceCostEnabled = config.Bind<bool>("Cost", "DistanceCostEnabled", false, Description("config.distance_cost.description", "entry.distance_cost", 1, "Cost", "section.cost", 40));
acceptableValues = (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 5000);
sliderStep = 50.0;
DistanceTilesPerExtraCoin = config.Bind<int>("Cost", "DistanceTilesPerExtraCoin", 500, Description("config.distance_tiles_per_coin.description", "entry.distance_tiles_per_coin", 2, null, null, null, acceptableValues, sliderStep));
acceptableValues = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100);
sliderStep = 1.0;
DistanceCostMaxCoins = config.Bind<int>("Cost", "DistanceCostMaxCoins", 5, Description("config.distance_max_cost.description", "entry.distance_max_cost", 3, null, null, null, acceptableValues, sliderStep));
MapShortcutEnabled = config.Bind<bool>("Controls", "MapShortcutEnabled", true, Description("config.map_shortcut.description", "entry.map_shortcut", 1, "Controls", "section.controls", 60));
MarketSalesEnabled = config.Bind<bool>("Market", "MarketSalesEnabled", true, Description("config.market_sales.description", "entry.market_sales", 1, "Market", "section.market", 50));
acceptableValues = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000);
sliderStep = 1.0;
MarketCoinPrice = config.Bind<int>("Market", "MarketCoinPrice", 200, Description("config.market_price.description", "entry.market_price", 2, null, null, null, acceptableValues, sliderStep));
acceptableValues = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100);
sliderStep = 1.0;
MarketCoinStackSize = config.Bind<int>("Market", "MarketCoinStackSize", 100, Description("config.market_stack.description", "entry.market_stack", 3, null, null, null, acceptableValues, sliderStep));
acceptableValues = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 7);
sliderStep = 1.0;
MarketMerchantLevel = config.Bind<int>("Market", "MarketMerchantLevel", 1, Description("config.market_level.description", "entry.market_level", 4, null, null, null, acceptableValues, sliderStep));
OpenMenuHotkey = config.Bind<Keys>("Controls", "OpenMenuHotkey", (Keys)79, Description("config.open_menu_hotkey.description", "entry.open_menu_hotkey", 2, null, null, null, null, null, keybind: true));
MarketSalesEnabled.SettingChanged += delegate
{
RaiseMarketSettingsChanged();
};
MarketCoinPrice.SettingChanged += delegate
{
RaiseMarketSettingsChanged();
};
MarketCoinStackSize.SettingChanged += delegate
{
RaiseMarketSettingsChanged();
};
MarketMerchantLevel.SettingChanged += delegate
{
RaiseMarketSettingsChanged();
};
}
private static ConfigDescription Description(string descriptionKey, string entryNameKey, int entryOrder, string section = null, string sectionNameKey = null, int? sectionOrder = null, AcceptableValueBase acceptableValues = null, double? sliderStep = null, bool keybind = false)
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
List<object> list = new List<object>();
if (!string.IsNullOrWhiteSpace(section))
{
list.Add(new LocalizedSectionTag(section, sectionNameKey, sectionOrder));
}
list.Add(new LocalizedEntryTag(entryNameKey, descriptionKey, entryOrder, sliderStep, keybind));
return new ConfigDescription(Text(descriptionKey), acceptableValues, list.ToArray());
}
private static string Text(string key)
{
return I18n.L.Text(key, Array.Empty<object>());
}
private static void RaiseMarketSettingsChanged()
{
ConfigManager.MarketSettingsChanged?.Invoke();
}
}
internal static class ModSettingsMenuRegistration
{
private static ConfigFile _config;
private static string _locale;
private static bool _subscribed;
public static void Register(ConfigFile config)
{
_config = config;
if (!_subscribed)
{
ModSettingsRegistry.RefreshRequested += Refresh;
_subscribed = true;
}
RegisterCurrent(config);
}
private static void Refresh()
{
if (_config != null)
{
string currentLocale = I18n.L.CurrentLocale;
ModSettingsRegistration val = default(ModSettingsRegistration);
if (!(_locale == currentLocale) || !ModSettingsRegistry.TryGet("IceBoxStudio.Romestead.WayhomeCoins", ref val))
{
RegisterCurrent(_config);
}
}
}
private static void RegisterCurrent(ConfigFile config)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: 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_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: 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_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Expected O, but got Unknown
ModSettingsRegistry.Register("IceBoxStudio.Romestead.WayhomeCoins", Text("mod.name"), config, new ModSettingsModOptions
{
Icon = "cog",
Version = "1.0.1",
Author = "Ice Box Studio",
Description = Text("mod.description"),
NexusModsId = 108,
ThunderstoreTeam = "Ice_Box_Studio_Romestead",
ThunderstoreModName = "WayhomeCoins",
UpdateManifestUrl = "https://cdn.jsdelivr.net/gh/ibox233/MyMod_Version@main/WayhomeCoins.json",
Order = -70
});
_locale = I18n.L.CurrentLocale;
}
private static string Text(string key)
{
return I18n.L.Text(key, Array.Empty<object>());
}
}
}