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 REPO Werewolf v1.0.0
BepInEx/plugins/Minorunara_Werewolf/Minorunara_Werewolf.dll
Decompiled a day 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.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using Photon.Voice.Unity; using TMPro; using UnityEngine; using UnityEngine.Audio; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; using UnityEngine.UI; using Werewolf.Core; using Werewolf.Debugging; using Werewolf.Game; using Werewolf.Game.Patches; using Werewolf.Net; using Werewolf.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("Minorunara_Werewolf")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+d25146b9bff09860509a3818fa26fb257548c4a3")] [assembly: AssemblyProduct("Minorunara_Werewolf")] [assembly: AssemblyTitle("Minorunara_Werewolf")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } internal static class IsExternalInit { } } namespace Werewolf { internal sealed class ConfigBindings { private const string SecGeneral = "01. General"; private const string SecMeeting = "02. Meeting"; private const string SecRoleAssignment = "03. Role Assignment"; private const string SecShaman = "04. Shaman"; private const string SecWerewolf = "05. Werewolf"; private const string SecBlackCat = "06. Black Cat"; private const string SecBomber = "07. Bomber"; internal const string SecStage = "08. Stage"; private const string SecPlayerUpgrades = "09. Player Upgrades"; internal const string SecLoadoutItems = "10. Loadout Items"; private const string SecClientKeybinds = "Client Keybinds"; private const string SecClientUi = "Client UI"; private const string SecTutorial = "Tutorial"; private const string SecVoice = "Voice"; private const string SecDebug = "Debug"; internal readonly ConfigEntry<int> WerewolfCount; internal readonly ConfigEntry<int> BlackCatChancePercent; internal readonly ConfigEntry<int> BomberChancePercent; internal readonly ConfigEntry<int> RoundSeconds; internal readonly ConfigEntry<int> BlackCatRevealDelaySec; internal readonly ConfigEntry<bool> BlackCatCurseEnabled; internal readonly ConfigEntry<bool> DebugMode; internal readonly ConfigEntry<int> ShamanChancePercent; internal readonly ConfigEntry<int> ShamanGazeFullSec; internal readonly ConfigEntry<int> ShamanGhostCooldownSec; internal readonly ConfigEntry<int> ShamanStormWeakMeters; internal readonly ConfigEntry<int> ShamanStormMediumMeters; internal readonly ConfigEntry<int> ShamanStormStrongMeters; internal readonly ConfigEntry<int> BomberProximityMeters; internal readonly ConfigEntry<int> BomberGaugeFullSec; internal readonly ConfigEntry<int> BomberInitialCooldownSec; internal readonly ConfigEntry<int> BomberCooldownSec; internal readonly ConfigEntry<int> BomberBlastRadiusMeters; internal readonly ConfigEntry<int> BomberBlastPlayerDamage; internal readonly ConfigEntry<int> BomberBlastEnemyDamage; internal readonly ConfigEntry<int> BomberAmmoRefillPct; internal readonly ConfigEntry<KeyCode> BomberPlantKey; internal readonly ConfigEntry<KeyCode> BomberDetonateKey; internal readonly ConfigEntry<string> Language; internal readonly ConfigEntry<int> MeetingRightsPerPlayer; internal readonly ConfigEntry<int> ConveneSuppressStartSec; internal readonly ConfigEntry<int> ConveneSuppressAfterSec; internal readonly ConfigEntry<int> MeetingCountdownSec; internal readonly ConfigEntry<int> MeetingDurationSec; internal readonly ConfigEntry<bool> VoteTimeCutEnabled; internal readonly ConfigEntry<int> ResultDisplaySec; internal readonly ConfigEntry<float> ButtonOffsetX; internal readonly ConfigEntry<float> ButtonOffsetY; internal readonly ConfigEntry<float> ButtonOffsetZ; internal readonly ConfigEntry<float> ButtonYaw; internal readonly ConfigEntry<float> ButtonPitch; internal readonly ConfigEntry<int> StaminaUnlockPct; internal readonly ConfigEntry<int> JumpUnlockPct; internal readonly ConfigEntry<int> EnemyIgnoreUnlockPct; internal readonly ConfigEntry<int> HealUnlockPct; internal readonly ConfigEntry<int> HealIntervalSec; internal readonly ConfigEntry<int> BeaconChargePct; internal readonly ConfigEntry<int> InformantThresholdPct; internal readonly ConfigEntry<int> ExtraJumpCount; internal readonly ConfigEntry<int> BeaconCooldownSec; internal readonly ConfigEntry<int> BeaconSuppressStartSec; internal readonly ConfigEntry<int> BeaconSuppressAfterMeetingSec; internal readonly ConfigEntry<int> CatGaugeSyncIntervalSec; internal readonly ConfigEntry<bool> OrbGaugeEnabled; internal readonly ConfigEntry<KeyCode> WolfModeKey; internal readonly ConfigEntry<KeyCode> BeaconKey; internal readonly ConfigEntry<bool> WerewolfModeEnabled; internal readonly ConfigEntry<bool> MinimapHideEnabled; internal readonly ConfigEntry<int> ValuableMapMode; internal readonly ConfigEntry<int> GameOverAutoReturnSec; internal readonly ConfigEntry<int> ToastDurationSec; internal readonly ConfigEntry<KeyCode> LobbySettingsPanelKey; internal readonly ConfigEntry<KeyCode> ManualKey; internal readonly ConfigEntry<KeyCode> CorpseReportKey; internal readonly ConfigEntry<KeyCode> ResultReturnKey; internal readonly ConfigEntry<KeyCode> MeetingMapKey; internal readonly ConfigEntry<KeyCode> MeetingChatLogKey; internal readonly ConfigEntry<float> MeetingMapOrthoSize; internal readonly ConfigEntry<int> MeetingMapResolution; internal readonly ConfigEntry<bool> MeetingMapGrid; internal readonly ConfigEntry<bool> MeetingChatLog; internal readonly ConfigEntry<int> NecroVoiceMode; internal readonly ConfigEntry<float> NecroVoiceVolume; internal readonly ConfigEntry<float> NecroVoiceLowPassCutoffHz; internal readonly ConfigEntry<float> NecroVoiceEchoDelayMs; internal readonly ConfigEntry<float> NecroVoiceEchoDecay; internal readonly ConfigEntry<float> NecroVoiceReverbRoom; internal readonly ConfigEntry<float> NecroVoiceReverbRoomHF; internal readonly ConfigEntry<float> NecroVoiceReverbDecayTime; internal readonly ConfigEntry<float> NecroVoiceReverbDecayHFRatio; internal readonly ConfigEntry<float> NecroVoiceReverbReflections; internal readonly ConfigEntry<float> NecroVoiceReverbReflectionsDelay; internal readonly ConfigEntry<float> NecroVoiceReverbLevel; internal readonly ConfigEntry<float> NecroVoiceReverbDelay; internal readonly ConfigEntry<float> NecroVoiceReverbDiffusion; internal readonly ConfigEntry<float> NecroVoiceReverbDensity; internal readonly ConfigEntry<float> NecroVoiceReverbHFReference; private readonly Dictionary<TutorialId, ConfigEntry<bool>> _tutorialSeen; internal readonly ConfigEntry<bool> ResetTutorials; internal readonly ConfigEntry<float> TutorialFontScale; internal readonly ConfigEntry<float> CursorMirrorScale; internal readonly ConfigEntry<int> HudOffsetX; internal readonly ConfigEntry<int> HudOffsetY; internal readonly ConfigEntry<int> StartLevelNumber; internal ConfigEntry<string> StartMapName; internal readonly ConfigEntry<int> StartEnergyPct; internal readonly ConfigEntry<int> OrbDropMax; private readonly Dictionary<string, ConfigEntry<int>> _startUpgrades; private readonly ValuableMapMode _valuableMapModeDefault; private readonly NecroVoiceMode _necroVoiceModeDefault; internal Func<string> ItemsSpecProvider { get; set; } internal ConfigBindings(ConfigFile config) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Expected O, but got Unknown //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Expected O, but got Unknown //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Expected O, but got Unknown //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Expected O, but got Unknown //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Expected O, but got Unknown //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Expected O, but got Unknown //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Expected O, but got Unknown //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Expected O, but got Unknown //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Expected O, but got Unknown //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Expected O, but got Unknown //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Expected O, but got Unknown //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Expected O, but got Unknown //IL_044d: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Expected O, but got Unknown //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Expected O, but got Unknown //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: Expected O, but got Unknown //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_04f0: Expected O, but got Unknown //IL_0519: Unknown result type (might be due to invalid IL or missing references) //IL_0523: Expected O, but got Unknown //IL_054c: Unknown result type (might be due to invalid IL or missing references) //IL_0556: Expected O, but got Unknown //IL_057f: Unknown result type (might be due to invalid IL or missing references) //IL_0589: Expected O, but got Unknown //IL_05b2: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Expected O, but got Unknown //IL_05e5: Unknown result type (might be due to invalid IL or missing references) //IL_05ef: Expected O, but got Unknown //IL_0618: Unknown result type (might be due to invalid IL or missing references) //IL_0622: Expected O, but got Unknown //IL_064e: Unknown result type (might be due to invalid IL or missing references) //IL_0658: Expected O, but got Unknown //IL_0684: Unknown result type (might be due to invalid IL or missing references) //IL_068e: Expected O, but got Unknown //IL_06ba: Unknown result type (might be due to invalid IL or missing references) //IL_06c4: Expected O, but got Unknown //IL_06f0: Unknown result type (might be due to invalid IL or missing references) //IL_06fa: Expected O, but got Unknown //IL_0744: Unknown result type (might be due to invalid IL or missing references) //IL_074e: Expected O, but got Unknown //IL_077a: Unknown result type (might be due to invalid IL or missing references) //IL_0784: Expected O, but got Unknown //IL_07ad: Unknown result type (might be due to invalid IL or missing references) //IL_07b7: Expected O, but got Unknown //IL_07e0: Unknown result type (might be due to invalid IL or missing references) //IL_07ea: Expected O, but got Unknown //IL_0816: Unknown result type (might be due to invalid IL or missing references) //IL_0820: Expected O, but got Unknown //IL_0849: Unknown result type (might be due to invalid IL or missing references) //IL_0853: Expected O, but got Unknown //IL_087c: Unknown result type (might be due to invalid IL or missing references) //IL_0886: Expected O, but got Unknown //IL_08b4: Unknown result type (might be due to invalid IL or missing references) //IL_08be: Expected O, but got Unknown //IL_08ea: Unknown result type (might be due to invalid IL or missing references) //IL_08f4: Expected O, but got Unknown //IL_0920: Unknown result type (might be due to invalid IL or missing references) //IL_092a: Expected O, but got Unknown //IL_0953: Unknown result type (might be due to invalid IL or missing references) //IL_095d: Expected O, but got Unknown //IL_09a6: Unknown result type (might be due to invalid IL or missing references) //IL_09b0: Expected O, but got Unknown //IL_09d9: Unknown result type (might be due to invalid IL or missing references) //IL_09e3: Expected O, but got Unknown //IL_0adb: Unknown result type (might be due to invalid IL or missing references) //IL_0ae5: Expected O, but got Unknown //IL_0b0c: Unknown result type (might be due to invalid IL or missing references) //IL_0b16: Expected O, but got Unknown //IL_0b3d: Unknown result type (might be due to invalid IL or missing references) //IL_0b47: Expected O, but got Unknown //IL_0b6e: Unknown result type (might be due to invalid IL or missing references) //IL_0b78: Expected O, but got Unknown //IL_0b9f: Unknown result type (might be due to invalid IL or missing references) //IL_0ba9: Expected O, but got Unknown //IL_0bd0: Unknown result type (might be due to invalid IL or missing references) //IL_0bda: Expected O, but got Unknown //IL_0c01: Unknown result type (might be due to invalid IL or missing references) //IL_0c0b: Expected O, but got Unknown //IL_0c35: Unknown result type (might be due to invalid IL or missing references) //IL_0c3f: Expected O, but got Unknown //IL_0c69: Unknown result type (might be due to invalid IL or missing references) //IL_0c73: Expected O, but got Unknown //IL_0c9d: Unknown result type (might be due to invalid IL or missing references) //IL_0ca7: Expected O, but got Unknown //IL_0ce0: Unknown result type (might be due to invalid IL or missing references) //IL_0cea: Expected O, but got Unknown //IL_0d23: Unknown result type (might be due to invalid IL or missing references) //IL_0d2d: Expected O, but got Unknown //IL_0d66: Unknown result type (might be due to invalid IL or missing references) //IL_0d70: Expected O, but got Unknown //IL_0da9: Unknown result type (might be due to invalid IL or missing references) //IL_0db3: Expected O, but got Unknown //IL_0dec: Unknown result type (might be due to invalid IL or missing references) //IL_0df6: Expected O, but got Unknown //IL_0e28: Unknown result type (might be due to invalid IL or missing references) //IL_0e32: Expected O, but got Unknown //IL_0e6a: Unknown result type (might be due to invalid IL or missing references) //IL_0e74: Expected O, but got Unknown //IL_0ea0: Unknown result type (might be due to invalid IL or missing references) //IL_0eaa: Expected O, but got Unknown //IL_0ec7: Unknown result type (might be due to invalid IL or missing references) //IL_0ed1: Expected O, but got Unknown //IL_0eee: Unknown result type (might be due to invalid IL or missing references) //IL_0ef8: Expected O, but got Unknown //IL_0f27: Unknown result type (might be due to invalid IL or missing references) //IL_0f31: Expected O, but got Unknown //IL_0f5c: Unknown result type (might be due to invalid IL or missing references) //IL_0f66: Expected O, but got Unknown //IL_0f91: Unknown result type (might be due to invalid IL or missing references) //IL_0f9b: Expected O, but got Unknown //IL_0fe6: Unknown result type (might be due to invalid IL or missing references) //IL_0ff0: Expected O, but got Unknown //IL_0a93: Unknown result type (might be due to invalid IL or missing references) //IL_0a9d: Expected O, but got Unknown //IL_1073: Unknown result type (might be due to invalid IL or missing references) //IL_107d: Expected O, but got Unknown //IL_10d6: Unknown result type (might be due to invalid IL or missing references) //IL_10e0: Expected O, but got Unknown //IL_1119: Unknown result type (might be due to invalid IL or missing references) //IL_1123: Expected O, but got Unknown //IL_115c: Unknown result type (might be due to invalid IL or missing references) //IL_1166: Expected O, but got Unknown //IL_119f: Unknown result type (might be due to invalid IL or missing references) //IL_11a9: Expected O, but got Unknown //IL_11e2: Unknown result type (might be due to invalid IL or missing references) //IL_11ec: Expected O, but got Unknown //IL_1225: Unknown result type (might be due to invalid IL or missing references) //IL_122f: Expected O, but got Unknown //IL_1268: Unknown result type (might be due to invalid IL or missing references) //IL_1272: Expected O, but got Unknown //IL_12ab: Unknown result type (might be due to invalid IL or missing references) //IL_12b5: Expected O, but got Unknown //IL_12ee: Unknown result type (might be due to invalid IL or missing references) //IL_12f8: Expected O, but got Unknown //IL_1331: Unknown result type (might be due to invalid IL or missing references) //IL_133b: Expected O, but got Unknown //IL_1374: Unknown result type (might be due to invalid IL or missing references) //IL_137e: Expected O, but got Unknown //IL_13b7: Unknown result type (might be due to invalid IL or missing references) //IL_13c1: Expected O, but got Unknown //IL_13fa: Unknown result type (might be due to invalid IL or missing references) //IL_1404: Expected O, but got Unknown //IL_143d: Unknown result type (might be due to invalid IL or missing references) //IL_1447: Expected O, but got Unknown //IL_1480: Unknown result type (might be due to invalid IL or missing references) //IL_148a: Expected O, but got Unknown //IL_14b5: Unknown result type (might be due to invalid IL or missing references) //IL_14bf: Expected O, but got Unknown GameConfig gameConfig = new GameConfig(); _valuableMapModeDefault = gameConfig.ValuableMapMode; _necroVoiceModeDefault = gameConfig.NecroVoiceMode; WerewolfModeEnabled = config.Bind<bool>("01. General", "WerewolfModeEnabled", true, "Werewolf mode ON/OFF. While true, rounds are played as werewolf sessions. Host authoritative: only the host's value applies to the room / 人狼モードのON/OFF。true の間はラウンドが人狼セッションとして進行する。ホスト権威(部屋に効くのはホストの値のみ。参加者側の値は自分がホストのときにだけ効く)"); Language = config.Bind<string>("01. General", "Language (restart required)", "English", new ConfigDescription("Display language (restart required). 日本語 = built-in Japanese, English = built-in English, custom = load Lang/custom.txt next to the DLL. A matching Lang file (Lang/en.txt for English, Lang/custom.txt for custom), if present, overrides the built-in text per key (missing keys fall back to the built-in table) / 表示言語(反映には再起動が必要)。日本語=埋め込み日本語, English=埋め込み英語, custom=DLL同階層の Lang/custom.txt。対応する Lang ファイル(English は Lang/en.txt)があればキー単位で埋め込み文言を上書きする(欠落キーは埋め込みへフォールバック)", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "日本語", "English", "custom" }), Array.Empty<object>())); RoundSeconds = config.Bind<int>("01. General", "RoundSeconds", gameConfig.RoundSeconds, new ConfigDescription("Round time limit (seconds) / ラウンド制限時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(180, 3600), Array.Empty<object>())); MinimapHideEnabled = config.Bind<bool>("01. General", "MinimapHideEnabled", gameConfig.MinimapHideEnabled, "Hide valuables and corpses from the minimap / 貴重品・死体のミニマップ非表示設定"); ValuableMapMode = config.Bind<int>("01. General", "ValuableMapMode", (int)gameConfig.ValuableMapMode, new ConfigDescription("Valuable map mode (0 = realtime, 1 = meeting sync (recommended; positions freeze at discovery and snapshot at meeting start / extraction complete), 2 = hidden) / 貴重品マップ表示モード(0=リアルタイム, 1=会議同期(推奨・発見時の位置で静止表示し会議開始/抽出完了時にスナップショット更新), 2=非表示)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>())); OrbGaugeEnabled = config.Bind<bool>("01. General", "OrbGaugeEnabled", gameConfig.OrbGaugeEnabled, "Whether value lost as enemy-dropped orbs counts toward the perk gauge / 敵ドロップ品(オーブ)の減額を特典ゲージへ算入するか"); NecroVoiceMode = config.Bind<int>("01. General", "NecroVoiceMode", (int)_necroVoiceModeDefault, new ConfigDescription("Netherworld voice eavesdrop mode (0 = OFF, 1 = non-werewolf dead, 2 = all dead). Host setting, synced to all clients / 冥界の声の傍聴モード(0=OFF, 1=人狼以外の死者, 2=全死者)。ホスト設定で全クライアントに同期される", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>())); GameOverAutoReturnSec = config.Bind<int>("01. General", "GameOverAutoReturnSec", gameConfig.GameOverAutoReturnSec, new ConfigDescription("Fallback: seconds until the result screen auto-returns to the lobby when the host does not press the return key (0 = never) / ホストが帰還キーを押さない場合に結果画面から自動でロビーへ戻るまでの保険秒数(0=自動で戻らない)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>())); MeetingRightsPerPlayer = config.Bind<int>("02. Meeting", "MeetingRightsPerPlayer", gameConfig.MeetingRightsPerPlayer, new ConfigDescription("Emergency meeting calls per player. Consumed only when a call is accepted / 1人あたりの会議開催権の回数。召集が受理された時点でのみ消費する", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>())); MeetingCountdownSec = config.Bind<int>("02. Meeting", "MeetingCountdownSec", gameConfig.MeetingCountdownSec, new ConfigDescription("Lead time from the meeting announcement until everyone warps (seconds) / 会議開始通知から全員ワープまでの予告時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 30), Array.Empty<object>())); MeetingDurationSec = config.Bind<int>("02. Meeting", "MeetingDurationSec", gameConfig.MeetingDurationSec, new ConfigDescription("Meeting time limit (seconds). End time = warp time + this value / 会議の制限時間(秒)。終了時刻 = ワープ時刻 + この秒数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 600), Array.Empty<object>())); VoteTimeCutEnabled = config.Bind<bool>("02. Meeting", "VoteTimeCutEnabled", gameConfig.VoteTimeCutEnabled, "Whether each accepted vote shortens the remaining meeting time by a share based on the number of living players / 投票が受理されるたびに会議残り時間を生存人数に応じた割合で短縮するか"); ResultDisplaySec = config.Bind<int>("02. Meeting", "ResultDisplaySec", gameConfig.ResultDisplaySec, new ConfigDescription("How long the vote results stay on screen before play resumes (seconds) / 開票結果の表示保持時間(秒)。この経過後に通常プレイへ復帰する", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>())); ConveneSuppressStartSec = config.Bind<int>("02. Meeting", "ConveneSuppressStartSec", gameConfig.ConveneSuppressStartSec, new ConfigDescription("Time right after the game starts during which meetings cannot be called (seconds) / ゲーム開始直後に会議召集を抑止する時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>())); ConveneSuppressAfterSec = config.Bind<int>("02. Meeting", "ConveneSuppressAfterSec", gameConfig.ConveneSuppressAfterSec, new ConfigDescription("Time right after a meeting ends during which the next meeting cannot be called (seconds) / 会議終了直後に次の会議召集を抑止する時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>())); ShamanChancePercent = config.Bind<int>("03. Role Assignment", "ShamanChancePercent", gameConfig.ShamanChancePercent, new ConfigDescription("Shaman appearance chance P_shaman (0..100%). Villager-side variant: one villager is converted, werewolf count N is unaffected / 祈祷師の出現確率 P_shaman(0..100%)。村人側変種=当選時に村人1名が変換され、人狼の人数 N には影響しない", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); WerewolfCount = config.Bind<int>("03. Role Assignment", "WerewolfCount", gameConfig.WerewolfCount, new ConfigDescription("Number of werewolves N (Werewolf slots; a winning Bomber roll converts one slot, always leaving at least one pure Werewolf). The Black Cat mutates from the villager side and is not counted here / 人狼の人数 N(人狼枠。爆弾魔当選時はこの枠の1人が爆弾魔へ変異する。純人狼は最低1人残る)。黒猫は村人陣営から変異するためこの人数には含まれない", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>())); BlackCatChancePercent = config.Bind<int>("03. Role Assignment", "BlackCatChancePercent", gameConfig.BlackCatChancePercent, new ConfigDescription("Black Cat appearance chance P_cat (0..100%). The Black Cat mutates from one villager and joins the werewolf team; rolls happen only while at least one villager would remain / 黒猫の出現確率 P_cat(0..100%)。黒猫は村人陣営から変異して人狼陣営に加わる(変異後も村人が最低1人残る構成でのみ抽選)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); BomberChancePercent = config.Bind<int>("03. Role Assignment", "BomberChancePercent", gameConfig.BomberChancePercent, new ConfigDescription("Bomber appearance chance P_bomber (0..100%). The Bomber mutates from one werewolf slot (needs werewolves >= 2) / 爆弾魔の出現確率 P_bomber(0..100%)。爆弾魔は人狼枠から変異する(人狼の人数2以上で抽選)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); ShamanGazeFullSec = config.Bind<int>("04. Shaman", "ShamanGazeFullSec", gameConfig.ShamanGazeFullSec, new ConfigDescription("Seconds of keeping the nearest unannounced corpse in view to trigger the spirit vision (decays at double speed while out of view) / 霊表示に必要な注視秒数(最寄りの未周知死体が視界内で蓄積・視界外は倍速減衰)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>())); ShamanGhostCooldownSec = config.Bind<int>("04. Shaman", "ShamanGhostCooldownSec", gameConfig.ShamanGhostCooldownSec, new ConfigDescription("Cooldown after the spirit vision ends before it can charge again (seconds) / 霊表示終了から再蓄積可能になるまでのクールダウン(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 120), Array.Empty<object>())); ShamanStormWeakMeters = config.Bind<int>("04. Shaman", "ShamanStormWeakMeters", gameConfig.ShamanStormWeakMeters, new ConfigDescription("Radius of the weak haunting ring around an unannounced corpse (m) / 霊障(弱)の発動半径(m)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); ShamanStormMediumMeters = config.Bind<int>("04. Shaman", "ShamanStormMediumMeters", gameConfig.ShamanStormMediumMeters, new ConfigDescription("Radius of the medium haunting ring (m) / 霊障(中)の発動半径(m)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); ShamanStormStrongMeters = config.Bind<int>("04. Shaman", "ShamanStormStrongMeters", gameConfig.ShamanStormStrongMeters, new ConfigDescription("Radius of the strong haunting ring (m) / 霊障(強)の発動半径(m)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); StaminaUnlockPct = config.Bind<int>("05. Werewolf", "StaminaUnlockPct", gameConfig.StaminaUnlockPct, new ConfigDescription("Unlock threshold for infinite stamina (% of the map's total valuable value destroyed) / 無限スタミナの解禁閾値(マップ総貴重品額に対する減額%)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); JumpUnlockPct = config.Bind<int>("05. Werewolf", "JumpUnlockPct", gameConfig.JumpUnlockPct, new ConfigDescription("Unlock threshold for extra jumps (%) / 追加ジャンプの解禁閾値(%)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); ExtraJumpCount = config.Bind<int>("05. Werewolf", "ExtraJumpCount", gameConfig.ExtraJumpCount, new ConfigDescription("Extra mid-air jumps (-1 = effectively unlimited) / 滞空中の追加ジャンプ回数(-1=実質無限)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 20), Array.Empty<object>())); EnemyIgnoreUnlockPct = config.Bind<int>("05. Werewolf", "EnemyIgnoreUnlockPct", gameConfig.EnemyIgnoreUnlockPct, new ConfigDescription("Unlock threshold for enemy ignore (%) / 敵認識無効の解禁閾値(%)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); HealUnlockPct = config.Bind<int>("05. Werewolf", "HealUnlockPct", gameConfig.HealUnlockPct, new ConfigDescription("Unlock threshold for regeneration (%) / 自然治癒の解禁閾値(%)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); HealIntervalSec = config.Bind<int>("05. Werewolf", "HealIntervalSec", gameConfig.HealIntervalSec, new ConfigDescription("Regeneration interval while Wolf Mode is on (seconds per 1 HP) / 狼化中の自然治癒の回復間隔(1HPあたりの秒数)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), Array.Empty<object>())); BeaconChargePct = config.Bind<int>("05. Werewolf", "BeaconChargePct", gameConfig.BeaconChargePct, new ConfigDescription("Threshold per beacon charge (%; each multiple reached grants every werewolf one use) / ビーコン1チャージあたりの閾値(%。この倍数の到達ごとに各人狼へ1回分付与)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); BeaconCooldownSec = config.Bind<int>("05. Werewolf", "BeaconCooldownSec", gameConfig.BeaconCooldownSec, new ConfigDescription("Beacon cooldown (seconds) / ビーコンのクールダウン時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 600), Array.Empty<object>())); BeaconSuppressStartSec = config.Bind<int>("05. Werewolf", "BeaconSuppressStartSec", gameConfig.BeaconSuppressStartSec, new ConfigDescription("Time right after the game starts during which the beacon cannot be used (seconds) / ゲーム開始直後のビーコン使用抑止時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 180), Array.Empty<object>())); BeaconSuppressAfterMeetingSec = config.Bind<int>("05. Werewolf", "BeaconSuppressAfterMeetingSec", gameConfig.BeaconSuppressAfterMeetingSec, new ConfigDescription("Time right after a meeting ends during which the beacon cannot be used (seconds) / 会議終了直後のビーコン使用抑止時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 180), Array.Empty<object>())); BlackCatRevealDelaySec = config.Bind<int>("06. Black Cat", "BlackCatRevealDelaySec", gameConfig.BlackCatRevealDelaySec, new ConfigDescription("Delay from game start until the Black Cat is privately notified of its role (seconds) / ゲーム開始から黒猫本人へ自覚通知するまでの遅延(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), Array.Empty<object>())); BlackCatCurseEnabled = config.Bind<bool>("06. Black Cat", "BlackCatCurseEnabled", gameConfig.BlackCatCurseEnabled, "Enable the Black Cat's drag-down ability when executed / 黒猫が処刑されたときの道連れ能力を有効にする"); InformantThresholdPct = config.Bind<int>("06. Black Cat", "InformantThresholdPct", gameConfig.InformantThresholdPct, new ConfigDescription("Informant threshold: reveals the werewolf list to the Black Cat (%; a high value not reached early is recommended) / 内通(黒猫への人狼一覧開示)の閾値(%。序盤に到達しない高めを推奨)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); CatGaugeSyncIntervalSec = config.Bind<int>("06. Black Cat", "CatGaugeSyncIntervalSec", gameConfig.CatGaugeSyncIntervalSec, new ConfigDescription("Gauge sync interval to the Black Cat (seconds; 0 = realtime. Werewolves always get realtime. Meeting start/end always refreshes regardless of the interval) / 黒猫へのゲージ配信間隔(秒。0=リアルタイム配信。人狼へは常にリアルタイム。会議開始・終了時は間隔に関係なく更新される)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 600), Array.Empty<object>())); BomberProximityMeters = config.Bind<int>("07. Bomber", "BomberProximityMeters", gameConfig.BomberProximityMeters, new ConfigDescription("Distance within which the Bomber counts a plant target as close contact (m) / 爆弾魔がプラント対象を至近と見なす距離(m)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); BomberGaugeFullSec = config.Bind<int>("07. Bomber", "BomberGaugeFullSec", gameConfig.BomberGaugeFullSec, new ConfigDescription("Total seconds of close contact needed to fill the proximity gauge / 近接ゲージが満タンになるまでの累計滞在秒", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), Array.Empty<object>())); BomberInitialCooldownSec = config.Bind<int>("07. Bomber", "BomberInitialCooldownSec", gameConfig.BomberInitialCooldownSec, new ConfigDescription("Initial cooldown after the match starts; proximity gauges are paused during it (seconds) / 試合開始直後の専用クールダウン。この間は近接ゲージも停止(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 180), Array.Empty<object>())); BomberCooldownSec = config.Bind<int>("07. Bomber", "BomberCooldownSec", gameConfig.BomberCooldownSec, new ConfigDescription("Cooldown after meetings, planting, re-planting, and detonation (seconds) / 会議後・プラント・付替・爆破後クールダウン(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>())); BomberAmmoRefillPct = config.Bind<int>("07. Bomber", "BomberAmmoRefillPct", gameConfig.BomberAmmoRefillPct, new ConfigDescription("Perk-gauge share required to refill one bomb (%) / 弾1発の補充に要する特典ゲージ割合%", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); BomberBlastRadiusMeters = config.Bind<int>("07. Bomber", "BomberBlastRadiusMeters", Mathf.RoundToInt(gameConfig.BomberBlastRadiusMeters), new ConfigDescription("Blast radius / warning-sound audible radius (m, integer) / 爆風半径・警告音可聴半径(m・整数)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); BomberBlastPlayerDamage = config.Bind<int>("07. Bomber", "BomberBlastPlayerDamage", gameConfig.BomberBlastPlayerDamage, new ConfigDescription("Damage to nearby players / 周囲プレイヤーへのダメージ", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 999), Array.Empty<object>())); BomberBlastEnemyDamage = config.Bind<int>("07. Bomber", "BomberBlastEnemyDamage", gameConfig.BomberBlastEnemyDamage, new ConfigDescription("Damage to enemies / 敵ダメージ", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 999), Array.Empty<object>())); StartLevelNumber = config.Bind<int>("08. Stage", "StartLevelNumber", gameConfig.StartLevelNumber, new ConfigDescription("Level of the werewolf session (the N in the on-screen \"Level N\") / 人狼セッションのレベル(画面表示「Level N」の N)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>())); StartMapName = config.Bind<string>("08. Stage", "StartMapName", "", "Map type name for the werewolf session. Empty = random (vanilla default selection). Unknown names also mean random / 人狼セッションの開始マップ種別名。空 = ランダム(バニラ既定の選択)。実在しない名前もランダム扱い"); StartEnergyPct = config.Bind<int>("08. Stage", "StartEnergyPct", gameConfig.StartEnergyPct, new ConfigDescription("Truck charger level at session start (%; 0 = empty, 100 = full) / トラック充電器の開始時充電量(%。0 = 空, 100 = 満充電)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); OrbDropMax = config.Bind<int>("08. Stage", "OrbDropMax", gameConfig.OrbDropMax, new ConfigDescription("Number of valuable orbs dropped when an enemy dies (vanilla = 3) / 敵撃破時にドロップする貴重品オーブの数(バニラ = 3)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), Array.Empty<object>())); Dictionary<string, int> dictionary = new Dictionary<string, int> { ["Health"] = 1, ["Strength"] = 2 }; _startUpgrades = new Dictionary<string, ConfigEntry<int>>(WorldgenUpgrades.Names.Count); foreach (string name in WorldgenUpgrades.Names) { int value; int num = (dictionary.TryGetValue(name, out value) ? value : 0); _startUpgrades[name] = config.Bind<int>("09. Player Upgrades", "StartUpgrade" + name, num, new ConfigDescription("Starting upgrade level shared by all players (" + name + "). 0 = no upgrade / 全プレイヤー共通の開始時強化段階(" + name + ")。0 = 強化なし", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), Array.Empty<object>())); } WolfModeKey = config.Bind<KeyCode>("Client Keybinds", "WolfModeKey", (KeyCode)102, new ConfigDescription("Key binding for the Wolf Mode toggle (bulk ON/OFF of unlocked perks) / 狼化トグル(解禁済み特典の一括ON/OFF)のキーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); BeaconKey = config.Bind<KeyCode>("Client Keybinds", "BeaconKey", (KeyCode)103, new ConfigDescription("Key binding for using the beacon / ビーコン使用のキーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); BomberPlantKey = config.Bind<KeyCode>("Client Keybinds", "BomberPlantKey", (KeyCode)102, new ConfigDescription("Key binding for the Bomber's plant (turn a player into a bomb) / 爆弾魔のプラント(爆弾化)キーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); BomberDetonateKey = config.Bind<KeyCode>("Client Keybinds", "BomberDetonateKey", (KeyCode)103, new ConfigDescription("Key binding for the Bomber's detonation / 爆弾魔の起爆キーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); CorpseReportKey = config.Bind<KeyCode>("Client Keybinds", "CorpseReportKey", (KeyCode)114, new ConfigDescription("Key binding to report an emergency meeting near an undiscovered body (dead player's head) / 未発見の死体(死者頭部)の近くで押すと緊急会議を通報するキーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); MeetingMapKey = config.Bind<KeyCode>("Client Keybinds", "MeetingMapKey", (KeyCode)109, new ConfigDescription("Key binding to toggle the full-map overlay during meetings / 会議中の全体マップオーバーレイのトグルキー", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); MeetingChatLogKey = config.Bind<KeyCode>("Client Keybinds", "MeetingChatLogKey", (KeyCode)108, new ConfigDescription("Key binding to toggle the chat log panel during meetings / 会議チャットログのトグルキー", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); LobbySettingsPanelKey = config.Bind<KeyCode>("Client Keybinds", "LobbySettingsPanelKey", (KeyCode)288, new ConfigDescription("Key binding to toggle the lobby settings panel / ロビー設定確認パネルの表示/非表示トグルのキーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); ManualKey = config.Bind<KeyCode>("Client Keybinds", "ManualKey", (KeyCode)282, new ConfigDescription("Key binding to toggle the in-game manual / ゲーム内説明書の表示/非表示トグルのキーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); ResultReturnKey = config.Bind<KeyCode>("Client Keybinds", "ResultReturnKey", (KeyCode)286, new ConfigDescription("Host only: key binding to return to the lobby from the match result screen / ホスト専用: 試合結果画面からロビーへ戻るキーバインド", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); ButtonOffsetX = config.Bind<float>("Client UI", "ButtonOffsetX", gameConfig.ButtonOffsetX, new ConfigDescription("Meeting button offset X relative to the truck (fine-tuned on Stage 1) / 会議召集ボタンのトラック基準相対オフセットX", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10f, 10f), new object[1] { "HideFromREPOConfig" })); ButtonOffsetY = config.Bind<float>("Client UI", "ButtonOffsetY", gameConfig.ButtonOffsetY, new ConfigDescription("Meeting button offset Y relative to the truck (fine-tuned on Stage 1) / 会議召集ボタンのトラック基準相対オフセットY", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10f, 10f), new object[1] { "HideFromREPOConfig" })); ButtonOffsetZ = config.Bind<float>("Client UI", "ButtonOffsetZ", gameConfig.ButtonOffsetZ, new ConfigDescription("Meeting button offset Z relative to the truck (fine-tuned on Stage 1) / 会議召集ボタンのトラック基準相対オフセットZ", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10f, 10f), new object[1] { "HideFromREPOConfig" })); ButtonYaw = config.Bind<float>("Client UI", "ButtonYaw", gameConfig.ButtonYaw, new ConfigDescription("Meeting button yaw fine-tune (degrees; tuned on Stage 1) / 会議召集ボタンの向き(Yaw, 度)の微調整", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), new object[1] { "HideFromREPOConfig" })); ButtonPitch = config.Bind<float>("Client UI", "ButtonPitch", gameConfig.ButtonPitch, new ConfigDescription("Meeting button pitch (degrees). 0 = flat facing up, 90 = wall mount (vertical, facing forward) / 会議召集ボタンのピッチ(度)。0=水平面上向き、90=壁面マウント(垂直面前向き)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), new object[1] { "HideFromREPOConfig" })); ToastDurationSec = config.Bind<int>("Client UI", "ToastDurationSec", gameConfig.ToastDurationSec, new ConfigDescription("Toast notification duration (seconds) / トースト通知の表示秒数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), new object[1] { "HideFromREPOConfig" })); MeetingMapOrthoSize = config.Bind<float>("Client UI", "MeetingMapOrthoSize", 60f, new ConfigDescription("Camera orthographicSize while the full-map overlay is open (larger = wider view). MiniMap MOD defaults to 2.25 / max 10; a larger default is used here to show the whole level. Needs vary per level, so tune in-game (recommended range 5-50) / 全体マップオーバーレイ表示時のカメラ orthographicSize(大きいほど広範囲)。レベル毎に必要な広さが異なるため実機で調整可(推奨レンジ 5〜50)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1.5f, 200f), new object[1] { "HideFromREPOConfig" })); MeetingMapResolution = config.Bind<int>("Client UI", "MeetingMapResolution", 1, new ConfigDescription("Full-map overlay render resolution preset. 0=1280x768 / 1=1600x960 / 2=1920x1152 (all 5:3, same aspect as the 1200x720 panel). The vanilla handheld-map RT is low-res and blurry when magnified, so a dedicated RT replaces it while the overlay is open / 全体マップオーバーレイのレンダリング解像度プリセット(0=1280x768 / 1=1600x960 / 2=1920x1152)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), new object[1] { "HideFromREPOConfig" })); MeetingMapGrid = config.Bind<bool>("Client UI", "MeetingMapGrid", true, new ConfigDescription("Show an Excel-style coordinate grid on the meeting full-map overlay (columns A,B,C... left to right / rows 1,2,3... top to bottom; one cell = one room module), so locations can be called out like \"the room at C5\" / 会議全体マップにエクセル風の座標グリッド(列=左からA,B,C…・行=上から1,2,3…・1マス=1部屋モジュール)を重ねて表示する(「C5の部屋」のような位置伝達用)", (AcceptableValueBase)null, Array.Empty<object>())); MeetingChatLog = config.Bind<bool>("Client UI", "MeetingChatLog", true, new ConfigDescription("Show the chat log panel on the right side of the screen during meetings (speaker avatar and message bubbles, plus a recap of deaths, destroyed valuables, delivery progress and beacon uses). Messages from the dead are shown only to the dead / 会議中に画面右端へ会議チャットログを表示する(発言者アバターと吹き出し+死亡者・破壊された貴重品・納品状況・ビーコン使用の要約)。死者の発言は死者にだけ表示される", (AcceptableValueBase)null, Array.Empty<object>())); CursorMirrorScale = config.Bind<float>("Client UI", "CursorMirrorScale", 1f, new ConfigDescription("Scale of the mirror cursor drawn over meeting panels (1.0 = vanilla cursor's measured size) / 会議パネル等の上に重ねるミラーカーソルのサイズ倍率(1.0=バニラカーソルの実測換算そのまま)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), Array.Empty<object>())); HudOffsetX = config.Bind<int>("Client UI", "HudOffsetX (+right)", 0, new ConfigDescription("Horizontal offset of the top-left role badge in 1920x1080-reference px (+ = right). Adjust if it overlaps the vanilla health/stamina display on your resolution / 左上役職バッジの横オフセット(1920x1080基準px・+で右)。バニラの体力/スタミナ表示と重なる環境で調整する", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1000, 1000), Array.Empty<object>())); HudOffsetY = config.Bind<int>("Client UI", "HudOffsetY (+down)", 0, new ConfigDescription("Vertical offset of the top-left role badge in 1920x1080-reference px (+ = down). Adjust if it overlaps the vanilla health/stamina display on your resolution / 左上役職バッジの縦オフセット(1920x1080基準px・+で下)。バニラの体力/スタミナ表示と重なる環境で調整する", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1000, 1000), Array.Empty<object>())); ResetTutorials = config.Bind<bool>("Tutorial", "ResetTutorials", false, "Set to true to reset all tutorial seen-flags (flips back to false automatically on the next poll; acts as a reset button to show the tutorials again) / true にするとチュートリアルの既読状態を全てリセットする(次のポーリングで自動的にfalseへ戻る。チュートリアルをもう一度表示させたい時のリセットボタン代わり)"); TutorialFontScale = config.Bind<float>("Tutorial", "FontScale", 0.7f, new ConfigDescription("Tutorial text font scale (ratio against the vanilla tutorial notification's maximum size) / チュートリアル文言のフォントサイズ倍率(バニラのチュートリアル通知の上限サイズに対する比率)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.4f, 1.5f), Array.Empty<object>())); _tutorialSeen = new Dictionary<TutorialId, ConfigEntry<bool>>(); foreach (TutorialId value2 in Enum.GetValues(typeof(TutorialId))) { _tutorialSeen[value2] = config.Bind<bool>("Tutorial", "Seen" + value2, false, new ConfigDescription($"Whether tutorial \"{value2}\" has been shown (internal bookkeeping) / チュートリアル「{value2}」を表示済みか(内部管理用)", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); } NecroVoiceVolume = config.Bind<float>("Voice", "NecroVoiceVolume", gameConfig.NecroVoiceVolume, new ConfigDescription("Eavesdrop voice volume (0..1; vanilla normal voice is roughly 0.5) / 傍聴音声の再生音量(0..1。バニラ通常声≒0.5相当)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { "HideFromREPOConfig" })); NecroVoiceLowPassCutoffHz = config.Bind<float>("Voice", "NecroVoiceLowPassCutoffHz", gameConfig.NecroVoiceLowPassCutoffHz, new ConfigDescription("Eavesdrop voice muffling (LowPass cutoff frequency, Hz) / 傍聴音声のくすみ(LowPass カットオフ周波数 Hz)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(100f, 20000f), new object[1] { "HideFromREPOConfig" })); NecroVoiceEchoDelayMs = config.Bind<float>("Voice", "NecroVoiceEchoDelayMs", gameConfig.NecroVoiceEchoDelayMs, new ConfigDescription("Eavesdrop voice echo interval (ms) / 傍聴音声の反響1回の間隔(ms)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 2000f), new object[1] { "HideFromREPOConfig" })); NecroVoiceEchoDecay = config.Bind<float>("Voice", "NecroVoiceEchoDecay", gameConfig.NecroVoiceEchoDecay, new ConfigDescription("Eavesdrop voice echo decay (0..1) / 傍聴音声の反響の減衰率(0..1)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { "HideFromREPOConfig" })); NecroVoiceReverbRoom = config.Bind<float>("Voice", "NecroVoiceReverbRoom", gameConfig.NecroVoiceReverbRoom, new ConfigDescription("Eavesdrop voice reverb room level (1/100 dB) / 傍聴音声の Reverb ルーム全体レベル(100分の1dB)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10000f, 0f), new object[1] { "HideFromREPOConfig" })); NecroVoiceReverbRoomHF = config.Bind<float>("Voice", "NecroVoiceReverbRoomHF", gameConfig.NecroVoiceReverbRoomHF, new ConfigDescription("Eavesdrop voice reverb room HF level (1/100 dB) / 傍聴音声の Reverb ルーム高域レベル(100分の1dB)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10000f, 0f), new object[1] { "HideFromREPOConfig" })); NecroVoiceReverbDecayTime = config.Bind<float>("Voice", "NecroVoiceReverbDecayTime", gameConfig.NecroVoiceReverbDecayTime, new ConfigDescription("Eavesdrop voice reverb decay time (seconds) / 傍聴音声の Reverb 残響減衰時間(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 20f), new object[1] { "HideFromREPOConfig" })); NecroVoiceReverbDecayHFRatio = config.Bind<float>("Voice", "NecroVoiceReverbDecayHFRatio", gameConfig.NecroVoiceReverbDecayHFRatio, new ConfigDescription("Eavesdrop voice reverb HF decay ratio / 傍聴音声の Reverb 高域減衰比", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), new object[1] { "HideFromREPOConfig" })); NecroVoiceReverbReflections = config.Bind<float>("Voice", "NecroVoiceReverbReflections", gameConfig.NecroVoiceReverbReflections, new ConfigDescription("Eavesdrop voice reverb early reflection level (1/100 dB) / 傍聴音声の Reverb 初期反射レベル(100分の1dB)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10000f, 1000f), new object[1] { "HideFromREPOConfig" })); NecroVoiceReverbReflectionsDelay = config.Bind<float>("Voice", "NecroVoiceReverbReflectionsDelay", gameConfig.NecroVoiceReverbReflectionsDelay, new ConfigDescription("Eavesdrop voice reverb early reflection delay (seconds) / 傍聴音声の Reverb 初期反射遅延(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.3f), new object[1] { "HideFromREPOConfig" })); NecroVoiceReverbLevel = config.Bind<float>("Voice", "NecroVoiceReverbLevel", gameConfig.NecroVoiceReverbLevel, new ConfigDescription("Eavesdrop voice reverb late reflection level (1/100 dB) / 傍聴音声の Reverb 後期反射レベル(100分の1dB)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10000f, 2000f), new object[1] { "HideFromREPOConfig" })); NecroVoiceReverbDelay = config.Bind<float>("Voice", "NecroVoiceReverbDelay", gameConfig.NecroVoiceReverbDelay, new ConfigDescription("Eavesdrop voice reverb late reflection delay (seconds) / 傍聴音声の Reverb 後期反射遅延(秒)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.1f), new object[1] { "HideFromREPOConfig" })); NecroVoiceReverbDiffusion = config.Bind<float>("Voice", "NecroVoiceReverbDiffusion", gameConfig.NecroVoiceReverbDiffusion, new ConfigDescription("Eavesdrop voice reverb diffusion (0..100) / 傍聴音声の Reverb 拡散度(0..100)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1] { "HideFromREPOConfig" })); NecroVoiceReverbDensity = config.Bind<float>("Voice", "NecroVoiceReverbDensity", gameConfig.NecroVoiceReverbDensity, new ConfigDescription("Eavesdrop voice reverb density (0..100) / 傍聴音声の Reverb 密度(0..100)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1] { "HideFromREPOConfig" })); NecroVoiceReverbHFReference = config.Bind<float>("Voice", "NecroVoiceReverbHFReference", gameConfig.NecroVoiceReverbHFReference, new ConfigDescription("Eavesdrop voice reverb HF reference frequency (Hz) / 傍聴音声の Reverb 高域基準周波数(Hz)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 20000f), new object[1] { "HideFromREPOConfig" })); DebugMode = config.Bind<bool>("Debug", "DebugMode", gameConfig.DebugMode, new ConfigDescription("Debug mode. true allows cheat commands (/ww ...), writes secret log lines immediately (false batches them until the match ends; ADR-0030), and shows a persistent TEST PLAY banner to every participant when the host enables it (ADR-0058) / デバッグモード。true でチートコマンド(/ww ...)を許可し、secret ログ行を即時出力する(false は試合終了時に一括出力。ADR-0030)。ホストが有効にすると全参加者にテストプレイ常設バナーが表示される(ADR-0058)", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); } internal GameConfig Snapshot() { int value = ValuableMapMode.Value; ValuableMapMode valuableMapMode = ((value >= 0 && value <= 2) ? ((ValuableMapMode)value) : _valuableMapModeDefault); int value2 = NecroVoiceMode.Value; NecroVoiceMode necroVoiceMode = ((value2 >= 0 && value2 <= 2) ? ((NecroVoiceMode)value2) : _necroVoiceModeDefault); Dictionary<string, int> dictionary = new Dictionary<string, int>(_startUpgrades.Count); foreach (KeyValuePair<string, ConfigEntry<int>> startUpgrade in _startUpgrades) { dictionary[startUpgrade.Key] = startUpgrade.Value.Value; } return new GameConfig { WerewolfCount = WerewolfCount.Value, BlackCatChancePercent = BlackCatChancePercent.Value, BomberChancePercent = BomberChancePercent.Value, RoundSeconds = RoundSeconds.Value, BlackCatRevealDelaySec = BlackCatRevealDelaySec.Value, BlackCatCurseEnabled = BlackCatCurseEnabled.Value, DebugMode = DebugMode.Value, MeetingRightsPerPlayer = MeetingRightsPerPlayer.Value, ConveneSuppressStartSec = ConveneSuppressStartSec.Value, ConveneSuppressAfterSec = ConveneSuppressAfterSec.Value, MeetingCountdownSec = MeetingCountdownSec.Value, MeetingDurationSec = MeetingDurationSec.Value, VoteTimeCutEnabled = VoteTimeCutEnabled.Value, ResultDisplaySec = ResultDisplaySec.Value, ButtonOffsetX = ButtonOffsetX.Value, ButtonOffsetY = ButtonOffsetY.Value, ButtonOffsetZ = ButtonOffsetZ.Value, ButtonYaw = ButtonYaw.Value, ButtonPitch = ButtonPitch.Value, StaminaUnlockPct = StaminaUnlockPct.Value, JumpUnlockPct = JumpUnlockPct.Value, EnemyIgnoreUnlockPct = EnemyIgnoreUnlockPct.Value, HealUnlockPct = HealUnlockPct.Value, HealIntervalSec = HealIntervalSec.Value, BeaconChargePct = BeaconChargePct.Value, InformantThresholdPct = InformantThresholdPct.Value, ExtraJumpCount = ExtraJumpCount.Value, BeaconCooldownSec = BeaconCooldownSec.Value, BeaconSuppressStartSec = BeaconSuppressStartSec.Value, BeaconSuppressAfterMeetingSec = BeaconSuppressAfterMeetingSec.Value, CatGaugeSyncIntervalSec = CatGaugeSyncIntervalSec.Value, OrbGaugeEnabled = OrbGaugeEnabled.Value, WerewolfModeEnabled = WerewolfModeEnabled.Value, MinimapHideEnabled = MinimapHideEnabled.Value, ValuableMapMode = valuableMapMode, GameOverAutoReturnSec = GameOverAutoReturnSec.Value, ToastDurationSec = ToastDurationSec.Value, StartLevelNumber = StartLevelNumber.Value, StartMapName = (StartMapName.Value ?? ""), StartItemsSpec = (ItemsSpecProvider?.Invoke() ?? ""), StartEnergyPct = StartEnergyPct.Value, StartUpgradesSpec = WorldgenSpec.Encode(dictionary), OrbDropMax = OrbDropMax.Value, NecroVoiceMode = necroVoiceMode, NecroVoiceVolume = NecroVoiceVolume.Value, NecroVoiceLowPassCutoffHz = NecroVoiceLowPassCutoffHz.Value, NecroVoiceEchoDelayMs = NecroVoiceEchoDelayMs.Value, NecroVoiceEchoDecay = NecroVoiceEchoDecay.Value, NecroVoiceReverbRoom = NecroVoiceReverbRoom.Value, NecroVoiceReverbRoomHF = NecroVoiceReverbRoomHF.Value, NecroVoiceReverbDecayTime = NecroVoiceReverbDecayTime.Value, NecroVoiceReverbDecayHFRatio = NecroVoiceReverbDecayHFRatio.Value, NecroVoiceReverbReflections = NecroVoiceReverbReflections.Value, NecroVoiceReverbReflectionsDelay = NecroVoiceReverbReflectionsDelay.Value, NecroVoiceReverbLevel = NecroVoiceReverbLevel.Value, NecroVoiceReverbDelay = NecroVoiceReverbDelay.Value, NecroVoiceReverbDiffusion = NecroVoiceReverbDiffusion.Value, NecroVoiceReverbDensity = NecroVoiceReverbDensity.Value, NecroVoiceReverbHFReference = NecroVoiceReverbHFReference.Value, ShamanChancePercent = ShamanChancePercent.Value, ShamanGazeFullSec = ShamanGazeFullSec.Value, ShamanGhostCooldownSec = ShamanGhostCooldownSec.Value, ShamanStormWeakMeters = ShamanStormWeakMeters.Value, ShamanStormMediumMeters = ShamanStormMediumMeters.Value, ShamanStormStrongMeters = ShamanStormStrongMeters.Value, BomberProximityMeters = BomberProximityMeters.Value, BomberGaugeFullSec = BomberGaugeFullSec.Value, BomberInitialCooldownSec = BomberInitialCooldownSec.Value, BomberCooldownSec = BomberCooldownSec.Value, BomberBlastRadiusMeters = BomberBlastRadiusMeters.Value, BomberBlastPlayerDamage = BomberBlastPlayerDamage.Value, BomberBlastEnemyDamage = BomberBlastEnemyDamage.Value, BomberAmmoRefillPct = BomberAmmoRefillPct.Value }; } internal bool IsTutorialSeen(TutorialId id) { if (_tutorialSeen.TryGetValue(id, out var value)) { return value.Value; } return true; } internal void MarkTutorialSeen(TutorialId id) { if (_tutorialSeen.TryGetValue(id, out var value)) { value.Value = true; } } internal void TickTutorialReset() { if (!ResetTutorials.Value) { return; } foreach (ConfigEntry<bool> value in _tutorialSeen.Values) { value.Value = false; } ResetTutorials.Value = false; } } internal static class GameRefs { public static FieldRef<PlayerAvatar, bool> PlayerAvatar_deadSet; public static FieldRef<PlayerAvatar, bool> PlayerAvatar_isDisabled; public static FieldRef<PlayerAvatar, bool> PlayerAvatar_isTumbling; public static FieldRef<PlayerAvatar, bool> PlayerAvatar_levelAnimationCompleted; public static FieldRef<PlayerAvatar, PlayerDeathHead> PlayerAvatar_playerDeathHead; public static FieldRef<PlayerAvatar, PlayerVoiceChat> PlayerAvatar_voiceChat; public static FieldRef<PlayerAvatar, bool> PlayerAvatar_voiceChatFetched; public static FieldRef<PlayerAvatar, PlayerTumble> PlayerAvatar_tumble; public static FieldRef<PlayerHealth, int> PlayerHealth_health; public static FieldRef<PlayerTumble, PhysGrabObject> PlayerTumble_physGrabObject; public static FieldRef<PlayerDeathHead, PhysGrabObject> PlayerDeathHead_physGrabObject; public static FieldRef<PlayerVoiceChat, bool> PlayerVoiceChat_isTalking; public static FieldRef<PlayerVoiceChat, AudioSource> PlayerVoiceChat_audioSource; public static FieldRef<PlayerVoiceChat, Recorder> PlayerVoiceChat_recorder; public static FieldRef<PlayerVoiceChat, bool> PlayerVoiceChat_TTSinstantiated; public static FieldRef<PlayerVoiceChat, float> PlayerVoiceChat_overrideMuteTimer; public static FieldRef<PlayerVoiceChat, float> PlayerVoiceChat_clipLoudness; public static FieldRef<PlayerVoiceChat, PlayerAvatar> PlayerVoiceChat_playerAvatar; public static FieldRef<RunManager, Level> RunManager_debugLevel; public static FieldRef<RunManager, bool> RunManager_restarting; public static FieldRef<RunManager, List<PlayerVoiceChat>> RunManager_voiceChats; public static FieldRef<RunManager, float> RunManager_cosmeticWorldObjectCooldown; public static FieldRef<RunManager, bool> RunManager_moonLevelChanged; public static FieldRef<RoundDirector, int> RoundDirector_extractionPoints; public static FieldRef<RoundDirector, int> RoundDirector_extractionPointsCompleted; public static FieldRef<RoundDirector, bool> RoundDirector_allExtractionPointsCompleted; public static FieldRef<RoundDirector, int> RoundDirector_haulGoal; public static FieldRef<RoundDirector, int> RoundDirector_extractionPointSurplus; public static FieldRef<StatsManager, string> StatsManager_saveFileCurrent; public static FieldRef<StatsManager, SortedDictionary<string, Dictionary<string, int>>> StatsManager_dictionaryOfDictionaries; public static FieldRef<PunManager, PhotonView> PunManager_photonView; public static FieldRef<MetaManager, List<int>> MetaManager_cosmeticTokens; public static FieldRef<InputManager, Dictionary<InputKey, InputAction>> InputManager_inputActions; public static FieldRef<DataDirector, bool> DataDirector_toggleMute; public static FieldRef<ChatManager, string> ChatManager_chatMessage; public static FieldRef<MenuPlayerListed, PlayerAvatar> MenuPlayerListed_playerAvatar; public static FieldRef<MenuPlayerListed, int> MenuPlayerListed_listSpot; public static FieldRef<MenuPlayerHead, bool> MenuPlayerHead_isTalking; public static FieldRef<MenuPlayerHead, RectTransform> MenuPlayerHead_headTransform; public static FieldRef<PlayerCrown, PlayerAvatar> PlayerCrown_playerAvatar; public static FieldRef<PlayerCrown, bool> PlayerCrown_active; public static FieldRef<WorldSpaceUIPlayerName, PlayerAvatar> WorldSpaceUIPlayerName_playerAvatar; public static FieldRef<MapToolController, bool> MapToolController_Active; public static FieldRef<TruckScreenText, PlayerChatBoxState> TruckScreenText_playerChatBoxState; public static FieldRef<PlayerController, bool> PlayerController_JumpFirst; public static FieldRef<PlayerController, int> PlayerController_JumpExtraCurrent; public static FieldRef<ItemMelee, HurtCollider> ItemMelee_hurtCollider; public static FieldRef<PhysGrabber, PhysGrabObject> PhysGrabber_grabbedPhysGrabObject; public static FieldRef<PhysGrabObject, bool> PhysGrabObject_isMelee; public static FieldRef<ValuableObject, float> ValuableObject_dollarValueCurrent; public static FieldRef<ValuableObject, float> ValuableObject_dollarValueOriginal; public static FieldRef<ValuableObject, int> ValuableObject_dollarValueOverride; public static FieldRef<ValuableObject, bool> ValuableObject_discovered; public static FieldRef<PhysGrabObjectImpactDetector, ValuableObject> PhysGrabObjectImpactDetector_valuableObject; public static FieldRef<PhysGrabObjectImpactDetector, PhysGrabObject> PhysGrabObjectImpactDetector_physGrabObject; public static FieldRef<EnemyParent, Enemy> EnemyParent_Enemy; public static FieldRef<EnemyParent, bool> EnemyParent_Spawned; public static FieldRef<Enemy, EnemyRigidbody> Enemy_Rigidbody; public static FieldRef<Enemy, bool> Enemy_HasRigidbody; public static FieldRef<MapCustom, MapCustomEntity> MapCustom_mapCustomEntity; public static FieldRef<EnemyDirector, List<string>> EnemyDirector_debugNoVision; public static FieldRef<EnemyShadow, PlayerAvatar> EnemyShadow_playerTarget; public static MethodInfo EnemyShadow_UpdatePlayerTarget; public static FieldRef<AudioManager, SoundSnapshot> AudioManager_currentSnapshot; public static FieldInfo ParticleScriptExplosion_explosionPrefab; public static FieldInfo ParticlePrefabExplosion_HurtColliderSecondSetup; private static List<string> s_failures; private static int s_resolvedCount; public static bool ResolveAll() { s_failures = new List<string>(); s_resolvedCount = 0; PlayerAvatar_deadSet = Field<PlayerAvatar, bool>("deadSet"); PlayerAvatar_isDisabled = Field<PlayerAvatar, bool>("isDisabled"); PlayerAvatar_isTumbling = Field<PlayerAvatar, bool>("isTumbling"); PlayerAvatar_levelAnimationCompleted = Field<PlayerAvatar, bool>("levelAnimationCompleted"); PlayerAvatar_playerDeathHead = Field<PlayerAvatar, PlayerDeathHead>("playerDeathHead"); PlayerAvatar_voiceChat = Field<PlayerAvatar, PlayerVoiceChat>("voiceChat"); PlayerAvatar_voiceChatFetched = Field<PlayerAvatar, bool>("voiceChatFetched"); PlayerAvatar_tumble = Field<PlayerAvatar, PlayerTumble>("tumble"); PlayerHealth_health = Field<PlayerHealth, int>("health"); PlayerTumble_physGrabObject = Field<PlayerTumble, PhysGrabObject>("physGrabObject"); PlayerDeathHead_physGrabObject = Field<PlayerDeathHead, PhysGrabObject>("physGrabObject"); PlayerVoiceChat_isTalking = Field<PlayerVoiceChat, bool>("isTalking"); PlayerVoiceChat_audioSource = Field<PlayerVoiceChat, AudioSource>("audioSource"); PlayerVoiceChat_recorder = Field<PlayerVoiceChat, Recorder>("recorder"); PlayerVoiceChat_TTSinstantiated = Field<PlayerVoiceChat, bool>("TTSinstantiated"); PlayerVoiceChat_overrideMuteTimer = Field<PlayerVoiceChat, float>("overrideMuteTimer"); PlayerVoiceChat_clipLoudness = Field<PlayerVoiceChat, float>("clipLoudness"); PlayerVoiceChat_playerAvatar = Field<PlayerVoiceChat, PlayerAvatar>("playerAvatar"); RunManager_debugLevel = Field<RunManager, Level>("debugLevel"); RunManager_restarting = Field<RunManager, bool>("restarting"); RunManager_voiceChats = Field<RunManager, List<PlayerVoiceChat>>("voiceChats"); RunManager_cosmeticWorldObjectCooldown = Field<RunManager, float>("cosmeticWorldObjectCooldown"); RunManager_moonLevelChanged = Field<RunManager, bool>("moonLevelChanged"); RoundDirector_extractionPoints = Field<RoundDirector, int>("extractionPoints"); RoundDirector_extractionPointsCompleted = Field<RoundDirector, int>("extractionPointsCompleted"); RoundDirector_allExtractionPointsCompleted = Field<RoundDirector, bool>("allExtractionPointsCompleted"); RoundDirector_haulGoal = Field<RoundDirector, int>("haulGoal"); RoundDirector_extractionPointSurplus = Field<RoundDirector, int>("extractionPointSurplus"); StatsManager_saveFileCurrent = Field<StatsManager, string>("saveFileCurrent"); StatsManager_dictionaryOfDictionaries = Field<StatsManager, SortedDictionary<string, Dictionary<string, int>>>("dictionaryOfDictionaries"); PunManager_photonView = Field<PunManager, PhotonView>("photonView"); MetaManager_cosmeticTokens = Field<MetaManager, List<int>>("cosmeticTokens"); InputManager_inputActions = Field<InputManager, Dictionary<InputKey, InputAction>>("inputActions"); DataDirector_toggleMute = Field<DataDirector, bool>("toggleMute"); ChatManager_chatMessage = Field<ChatManager, string>("chatMessage"); MenuPlayerListed_playerAvatar = Field<MenuPlayerListed, PlayerAvatar>("playerAvatar"); MenuPlayerListed_listSpot = Field<MenuPlayerListed, int>("listSpot"); MenuPlayerHead_isTalking = Field<MenuPlayerHead, bool>("isTalking"); MenuPlayerHead_headTransform = Field<MenuPlayerHead, RectTransform>("headTransform"); PlayerCrown_playerAvatar = Field<PlayerCrown, PlayerAvatar>("playerAvatar"); PlayerCrown_active = Field<PlayerCrown, bool>("active"); WorldSpaceUIPlayerName_playerAvatar = Field<WorldSpaceUIPlayerName, PlayerAvatar>("playerAvatar"); MapToolController_Active = Field<MapToolController, bool>("Active"); TruckScreenText_playerChatBoxState = Field<TruckScreenText, PlayerChatBoxState>("playerChatBoxState"); PlayerController_JumpFirst = Field<PlayerController, bool>("JumpFirst"); PlayerController_JumpExtraCurrent = Field<PlayerController, int>("JumpExtraCurrent"); ItemMelee_hurtCollider = Field<ItemMelee, HurtCollider>("hurtCollider"); PhysGrabber_grabbedPhysGrabObject = Field<PhysGrabber, PhysGrabObject>("grabbedPhysGrabObject"); PhysGrabObject_isMelee = Field<PhysGrabObject, bool>("isMelee"); ValuableObject_dollarValueCurrent = Field<ValuableObject, float>("dollarValueCurrent"); ValuableObject_dollarValueOriginal = Field<ValuableObject, float>("dollarValueOriginal"); ValuableObject_dollarValueOverride = Field<ValuableObject, int>("dollarValueOverride"); ValuableObject_discovered = Field<ValuableObject, bool>("discovered"); PhysGrabObjectImpactDetector_valuableObject = Field<PhysGrabObjectImpactDetector, ValuableObject>("valuableObject"); PhysGrabObjectImpactDetector_physGrabObject = Field<PhysGrabObjectImpactDetector, PhysGrabObject>("physGrabObject"); EnemyParent_Enemy = Field<EnemyParent, Enemy>("Enemy"); EnemyParent_Spawned = Field<EnemyParent, bool>("Spawned"); Enemy_Rigidbody = Field<Enemy, EnemyRigidbody>("Rigidbody"); Enemy_HasRigidbody = Field<Enemy, bool>("HasRigidbody"); MapCustom_mapCustomEntity = Field<MapCustom, MapCustomEntity>("mapCustomEntity"); EnemyDirector_debugNoVision = Field<EnemyDirector, List<string>>("debugNoVision"); EnemyShadow_playerTarget = Field<EnemyShadow, PlayerAvatar>("playerTarget"); EnemyShadow_UpdatePlayerTarget = RawMethod(typeof(EnemyShadow), "UpdatePlayerTarget"); AudioManager_currentSnapshot = Field<AudioManager, SoundSnapshot>("currentSnapshot"); ParticleScriptExplosion_explosionPrefab = RawField(typeof(ParticleScriptExplosion), "explosionPrefab"); ParticlePrefabExplosion_HurtColliderSecondSetup = RawField(typeof(ParticlePrefabExplosion), "HurtColliderSecondSetup"); if (s_failures.Count == 0) { WLog.Line("game_refs_resolved", false, ("count", s_resolvedCount)); return true; } WLog.Line("game_refs_disabled", false, ("failedFields", s_failures.Count)); return false; } private static FieldRef<TObj, TField> Field<TObj, TField>(string fieldName) where TObj : class { try { FieldRef<TObj, TField> result = AccessTools.FieldRefAccess<TObj, TField>(fieldName); s_resolvedCount++; return result; } catch (Exception ex) { Fail(typeof(TObj).Name, fieldName, ex.Message); return null; } } private static MethodInfo RawMethod(Type type, string methodName) { MethodInfo methodInfo = AccessTools.Method(type, methodName, (Type[])null, (Type[])null); if (methodInfo == null) { Fail(type.Name, methodName, "method not found"); return null; } s_resolvedCount++; return methodInfo; } private static FieldInfo RawField(Type type, string fieldName) { FieldInfo fieldInfo = AccessTools.Field(type, fieldName); if (fieldInfo == null) { Fail(type.Name, fieldName, "field not found"); return null; } s_resolvedCount++; return fieldInfo; } private static void Fail(string typeName, string fieldName, string error) { s_failures.Add(typeName + "." + fieldName); WLog.Line("game_ref_failed", false, ("type", typeName), ("field", fieldName), ("err", error)); } } [BepInPlugin("minorunara.werewolf", "Werewolf", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "minorunara.werewolf"; public const string PluginName = "Werewolf"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Logger; internal static GameConfig GameConfig; internal static ConfigBindings Bindings; internal static ConfigEntry<KeyCode> WolfModeKey; internal static ConfigEntry<KeyCode> BeaconKey; internal static ConfigEntry<KeyCode> LobbySettingsPanelKey; internal static ConfigEntry<KeyCode> MeetingMapKey; internal static ConfigEntry<KeyCode> MeetingChatLogKey; internal static ConfigEntry<KeyCode> CorpseReportKey; internal static ConfigEntry<KeyCode> ResultReturnKey; internal static ConfigEntry<KeyCode> ManualKey; internal static void RefreshGameConfig() { if (Bindings != null) { GameConfig = Bindings.Snapshot(); } } private void Awake() { //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; if (!CosmeticLottery.ValidateWeights()) { Logger.LogWarning((object)"CosmeticLottery.ValidateWeights failed: weight constants (Common/Uncommon/Rare/UltraRare) do not sum to TotalWeight. Cosmetic coin drop rates will be inconsistent."); } StructuredLog.Install(); Bindings = new ConfigBindings(((BaseUnityPlugin)this).Config); GameConfig = Bindings.Snapshot(); WolfModeKey = Bindings.WolfModeKey; BeaconKey = Bindings.BeaconKey; LobbySettingsPanelKey = Bindings.LobbySettingsPanelKey; MeetingMapKey = Bindings.MeetingMapKey; MeetingChatLogKey = Bindings.MeetingChatLogKey; CorpseReportKey = Bindings.CorpseReportKey; ManualKey = Bindings.ManualKey; ResultReturnKey = Bindings.ResultReturnKey; WorldgenItemBindings.Install(((BaseUnityPlugin)this).Config, Bindings); WorldgenMapBinding.Install(((BaseUnityPlugin)this).Config, Bindings); LoadLanguageOverride(); WLog.Line("init", false, ("plugin", "Werewolf"), ("version", "1.0.0")); if (!GameRefs.ResolveAll()) { Logger.LogError((object)"Werewolf 1.0.0: 本体フィールド参照の解決に失敗したためMODを無効化しました(本体アップデートでフィールドが変わった可能性。修復手順: docs/steering/tech.md「本体アップデート対応プレイブック」)"); return; } if (!ApplyPatchesIsolated(new Harmony("minorunara.werewolf"))) { Logger.LogError((object)"Werewolf 1.0.0: Harmonyパッチ適用に失敗したためMODを無効化しました(本体アップデートでパッチ対象が変わった可能性。修復手順: docs/steering/tech.md「本体アップデート対応プレイブック」)"); return; } ((Component)this).gameObject.AddComponent<WerewolfDirector>(); Logger.LogInfo((object)("Werewolf 1.0.0 loaded! " + $"(werewolfCount={GameConfig.WerewolfCount}, " + $"blackCatChancePercent={GameConfig.BlackCatChancePercent}, " + $"bomberChancePercent={GameConfig.BomberChancePercent}, " + $"roundSeconds={GameConfig.RoundSeconds}, " + $"blackCatRevealDelaySec={GameConfig.BlackCatRevealDelaySec}, " + $"debugMode={GameConfig.DebugMode})")); } private void OnDestroy() { StructuredLog.FlushDeferredSecrets("plugin_destroy"); } private static bool ApplyPatchesIsolated(Harmony harmony) { List<(string, Exception)> list = new List<(string, Exception)>(); Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(Plugin).Assembly); foreach (Type type in typesFromAssembly) { try { harmony.CreateClassProcessor(type).Patch(); } catch (Exception item) { list.Add((type.FullName, item)); } } if (list.Count == 0) { int num = 0; foreach (MethodBase patchedMethod in harmony.GetPatchedMethods()) { _ = patchedMethod; num++; } WLog.Line("harmony_patched", false, ("methods", num)); return true; } foreach (var item4 in list) { string item2 = item4.Item1; Exception item3 = item4.Item2; Exception ex = item3.InnerException ?? item3; WLog.Line("harmony_patch_failed", false, ("patchClass", item2), ("err", ex.Message)); Logger.LogError((object)$"Harmony patch failed: {item2}\n{item3}"); } harmony.UnpatchSelf(); WLog.Line("harmony_disabled", false, ("failedClasses", list.Count)); return false; } private void LoadLanguageOverride() { try { string text = Bindings?.Language?.Value; if (string.IsNullOrEmpty(text)) { return; } int num; switch (text) { case "ja": return; default: num = ((text == "en") ? 1 : 0); break; case "English": num = 1; break; } bool flag = (byte)num != 0; if (flag) { Texts.Current = Language.English; WLog.Line("lang_loaded", false, ("code", "en"), ("source", "builtin")); } string text2 = (flag ? "en" : text); string location = typeof(Plugin).Assembly.Location; string text3 = (string.IsNullOrEmpty(location) ? null : Path.GetDirectoryName(location)); if (string.IsNullOrEmpty(text3)) { if (!flag) { WLog.Line("lang_load_failed", false, ("code", text2), ("reason", "no_dll_dir")); } return; } string text4 = Path.Combine(text3, "Lang", text2 + ".txt"); if (!File.Exists(text4)) { if (!flag) { WLog.Line("lang_load_failed", false, ("code", text2), ("reason", "file_missing"), ("path", text4)); } } else { Dictionary<TextId, string> dictionary = LangFile.Parse(File.ReadAllText(text4, Encoding.UTF8)); Texts.SetOverride(dictionary); WLog.Line("lang_loaded", false, ("code", text2), ("entries", dictionary.Count)); } } catch (Exception ex) { WLog.Line("lang_load_failed", false, ("reason", "exception"), ("detail", ex.GetType().Name)); } } } internal static class WorldgenItemBindings { private static ConfigFile _config; private static ConfigBindings _bindings; private static Dictionary<string, ConfigEntry<int>> _entries; private static bool _initialized; private static bool _failed; private static bool _skipLogged; private static readonly Dictionary<string, int> DefaultAmounts = new Dictionary<string, int> { ["Item Cart Cannon"] = 1, ["Item Cart Medium"] = 2, ["Item Cart Small"] = 1, ["Item Drone Indestructible"] = 1, ["Item Drone Zero Gravity"] = 1, ["Item Grenade Explosive"] = 2, ["Item Grenade Shockwave"] = 2, ["Item Grenade Stun"] = 2, ["Item Gun Laser"] = 1, ["Item Gun Shockwave"] = 1, ["Item Gun Shotgun"] = 1, ["Item Gun Stun"] = 1, ["Item Gun Tranq"] = 1, ["Item Health Pack Large"] = 1, ["Item Health Pack Medium"] = 2, ["Item Health Pack Small"] = 3, ["Item Leaf Blower"] = 1, ["Item Melee Baseball Bat"] = 1, ["Item Melee Frying Pan"] = 1, ["Item Melee Inflatable Hammer"] = 0, ["Item Melee Stun Baton"] = 1, ["Item Melee Sword"] = 1, ["Item Mine Explosive"] = 2, ["Item Mine Shockwave"] = 2, ["Item Mine Stun"] = 2, ["Item Orb Zero Gravity"] = 1, ["Item Phase Bridge"] = 1, ["Item Staff Torque"] = 1, ["Item Staff Void"] = 1, ["Item Staff Zero Gravity"] = 1, ["Item Upgrade Map Player Count"] = 1, ["Item Vehicle Semiscooter"] = 1, ["Item Vehicle Semiscooter Small"] = 1, ["Item WalkieTalkieBox"] = 1 }; internal static void Install(ConfigFile config, ConfigBindings bindings) { _config = config; _bindings = bindings; } internal static void TryInitialize() { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown if (_initialized || _failed || _config == null) { return; } try { IReadOnlyDictionary<string, int> itemMaxAmounts = GameItemDatabase.Instance.ItemMaxAmounts; if (itemMaxAmounts == null || itemMaxAmounts.Count == 0) { return; } Dictionary<string, ConfigEntry<int>> dictionary = new Dictionary<string, ConfigEntry<int>>(itemMaxAmounts.Count); foreach (KeyValuePair<string, int> item in itemMaxAmounts) { try { int value; int num = (DefaultAmounts.TryGetValue(item.Key, out value) ? Math.Min(value, item.Value) : 0); dictionary[item.Key] = _config.Bind<int>("10. Loadout Items", item.Key, num, new ConfigDescription($"Amount brought to the truck at werewolf session start (0 = none, max = {item.Value}) / " + $"人狼セッション開始時にトラックへ持ち込む個数(0 = 持ち込まない, 上限 = {item.Value})", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, item.Value), Array.Empty<object>())); } catch (Exception ex) { WLog.Line("worldgen_itembind_skip", false, ("item", item.Key), ("err", ex.Message)); } } _entries = dictionary; _initialized = true; if (_bindings != null) { _bindings.ItemsSpecProvider = ComposeSpec; } WLog.Line("worldgen_itembind_init", false, ("count", dictionary.Count)); } catch (Exception ex2) { _failed = true; WLog.Line("worldgen_itembind_error", false, ("err", ex2.Message)); } } internal static string ComposeSpec() { Dictionary<string, ConfigEntry<int>> entries = _entries; if (entries == null) { return ""; } Dictionary<string, int> dictionary = new Dictionary<string, int>(entries.Count); foreach (KeyValuePair<string, ConfigEntry<int>> item in entries) { dictionary[item.Key] = item.Value.Value; } List<string> list = new List<string>(); string result = WorldgenSpec.Encode(dictionary, list); if (list.Count > 0 && !_skipLogged) { _skipLogged = true; WLog.Line("worldgen_itemspec_skip", false, ("names", string.Join(" / ", list))); } return result; } } internal static class WorldgenMapBinding { private static ConfigFile _config; private static ConfigBindings _bindings; private static bool _initialized; private static bool _failed; internal static void Install(ConfigFile config, ConfigBindings bindings) { _config = config; _bindings = bindings; } internal static void TryInitialize() { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown if (_initialized || _failed || _config == null || _bindings == null) { return; } try { IReadOnlyList<string> playableLevelNames = GameItemDatabase.Instance.PlayableLevelNames; if (playableLevelNames == null || playableLevelNames.Count == 0) { return; } List<string> list = new List<string>(playableLevelNames.Count + 1) { "" }; foreach (string item in playableLevelNames) { if (!list.Contains(item)) { list.Add(item); } } ConfigEntry<string> startMapName = _bindings.StartMapName; string text = startMapName.Value ?? ""; _config.Remove(((ConfigEntryBase)startMapName).Definition); ConfigEntry<string> val = _config.Bind<string>("08. Stage", "StartMapName", "", new ConfigDescription("Map type name for the werewolf session. Empty = random (vanilla default selection) / 人狼セッションの開始マップ種別名。空 = ランダム(バニラ既定の選択)", (AcceptableValueBase)(object)new AcceptableValueList<string>(list.ToArray()), Array.Empty<object>())); val.Value = text; _bindings.StartMapName = val; _initialized = true; WLog.Line("worldgen_mapbind_init", false, ("levels", list.Count - 1), ("value", val.Value)); if (!string.Equals(val.Value, text, StringComparison.Ordinal)) { WLog.Line("worldgen_mapbind_fallback", false, ("from", text)); } } catch (Exception ex) { _failed = true; WLog.Line("worldgen_mapbind_error", false, ("err", ex.Message)); } } } } namespace Werewolf.UI { public static class AssetCatalog { private const string EmbeddedNamespace = "Werewolf.Assets"; private const string BundleFileName = "werewolf_assets"; private static readonly Dictionary<string, Sprite> _sprites = new Dictionary<string, Sprite>(); private static readonly Dictionary<string, Sprite> _graySprites = new Dictionary<string, Sprite>(); private static readonly Dictionary<string, Texture2D> _textures = new Dictionary<string, Texture2D>(); private static readonly Dictionary<string, GameObject> _prefabs = new Dictionary<string, GameObject>(); private static readonly Dictionary<string, AudioClip> _clips = new Dictionary<string, AudioClip>(); private static AssetBundle _bundle; private static bool _bundleAttempted; private static Sprite _bombIconPlaceholder; private static AudioClip _heartbeatPlaceholder; public static Sprite GetSprite(string key) { //IL_0046: 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) if (string.IsNullOrEmpty(key)) { return null; } if (_sprites.TryGetValue(key, out var value)) { return value; } Texture2D texture = GetTexture(key); Sprite val = null; if ((Object)(object)texture != (Object)null) { try { val = Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f)); } catch (Exception ex) { LogFallback(key, "sprite_create_failed", ex.GetType().Name); val = null; } } _sprites[key] = val; return val; } public static Sprite GetGraySprite(string key) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_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_0061: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(key)) { return null; } if (_graySprites.TryGetValue(key, out var value)) { return value; } Sprite val = null; Texture2D texture = GetTexture(key); if ((Object)(object)texture != (Object)null) { try { Color[] pixels = texture.GetPixels(); for (int i = 0; i < pixels.Length; i++) { Color val2 = pixels[i]; float num = val2.r * 0.299f + val2.g * 0.587f + val2.b * 0.114f; pixels[i] = new Color(num, num, num, val2.a); } Texture2D val3 = new Texture2D(((Texture)texture).width, ((Texture)texture).height, (TextureFormat)4, false); val3.SetPixels(pixels); val3.Apply(false, false); val = Sprite.Create(val3, new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), new Vector2(0.5f, 0.5f)); } catch (Exception ex) { LogFallback(key, "gray_build_failed", ex.GetType().Name); val = null; } } _graySprites[key] = val; return val; } public static Texture2D GetTexture(string key) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown if (string.IsNullOrEmpty(key)) { return null; } if (_textures.TryGetValue(key, out var value)) { return value; } Texture2D val = null; try { byte[] array = LoadEmbeddedBytes(key + ".png"); if (array != null && array.Length != 0) { val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, array)) { LogFallback(key, "png_decode_failed"); Object.Destroy((Object)(object)val); val = null; } } else { LogFallback(key, "png_missing"); } } catch (Exception ex) { LogFallback(key, "png_exception", ex.GetType().Name); val = null; } _textures[key] = val; return val; } public static GameObject GetPrefab(string key) { if (string.IsNullOrEmpty(key)) { return null; } if (_prefabs.TryGetValue(key, out var value)) { return value; } GameObject val = null; AssetBundle val2 = TryLoadBundle(); if ((Object)(object)val2 != (Object)null) { try { val = val2.LoadAsset<GameObject>(key); if ((Object)(object)val == (Object)null) { LogFallback(key, "bundle_key_missing"); } } catch (Exception ex) { LogFallback(key, "bundle_load_exception", ex.GetType().Name); val = null; } } else { LogFallback(key, "bundle_missing"); } _prefabs[key] = val; return val; } public static AudioClip GetClip(string key) { if (string.IsNullOrEmpty(key)) { return null; } if (_clips.TryGetValue(key, out var value)) { return value; } AudioClip val = null; try { byte[] array = LoadEmbeddedBytes(key + ".wav"); if (array != null && array.Length != 0) { val = DecodePcm16Wav(key, array); } else { LogFallback(key, "wav_missing"); } } catch (Exception ex) { LogFallback(key, "wav_exception", ex.GetType().Name); val = null; } _clips[key] = val; return val; } public static Sprite GetBombIcon() { Sprite sprite = GetSprite("img_bomb"); if ((Object)(object)sprite != (Object)null) { return sprite; } return BombIconPlaceholder(); } public static AudioClip GetHeartbeatClip() { AudioClip clip = GetClip("sfx_heartbeat"); if ((Object)(object)clip != (Object)null) { return clip; } return HeartbeatPlaceholder(); } private static Sprite BombIconPlaceholder() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0206: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: 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) if ((Object)(object)_bombIconPlaceholder != (Object)null) { return _bombIconPlaceholder; } Texture2D val = new Texture2D(128, 128, (TextureFormat)5, false); ((Texture)val).wrapMode = (TextureWrapMode)1; Color[] array = (Color[])(object)new Color[16384]; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(64f, 57.6f); float num = 40.96f; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(92.16f, 108.8f); float num2 = 12.8f; Color val4 = default(Color); for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { ((Color)(ref val4))..ctor(0f, 0f, 0f, 0f); float num3 = Vector2.Distance(new Vector2((float)j, (float)i), val2); if (num3 <= num) { ((Color)(ref val4))..ctor(0.08f, 0.08f, 0.08f, 1f); if (num3 > num - 3f) { ((Color)(ref val4))..ctor(0.02f, 0.02f, 0.02f, 1f); } } float num4 = (float)j - 80.64f; float num5 = (float)i - 92.16f; if (Mathf.Abs(num4 - num5) < 2f && (float)j >= 76.8f && (float)j <= 92.16f && (float)i >= 84.48f && (float)i <= 102.4f) { ((Color)(ref val4))..ctor(0.55f, 0.35f, 0.1f, 1f); } float num6 = Vector2.Distance(new Vector2((float)j, (float)i), val3); if (num6 <= num2) { float num7 = 1f - num6 / num2; ((Color)(ref val4))..ctor(1f, Mathf.Lerp(0.35f, 0.85f, num7), 0.1f, 1f); } array[i * 128 + j] = val4; } } val.SetPixels(array); val.Apply(); _bombIconPlaceholder = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f)); ((Object)_bombIconPlaceholder).name = "WW_BombIconPlaceholder"; return _bombIconPlaceholder; } private static AudioClip HeartbeatPlaceholder() { if ((Object)(object)_heartbeatPlaceholder != (Object)null) { return _heartbeatPlaceholder; } int total = 22050; float[] samples = new float[total]; AddPulse(0.02f, 0.75f); AddPulse(0.35f, 0.55f); AudioClip val = AudioClip.Create("WW_HeartbeatPlaceholder", total, 1, 22050, false); if ((Object)(object)val == (Object)null) { return null; } if (!val.SetData(samples, 0)) { return null; } _heartbeatPlaceholder = val; return val; void AddPulse(float startSec, float amp) { int num = (int)(startSec * 22050f); int num2 = 4410; for (int i = 0; i < num2 && num + i < total; i++) { float num3 = (float)i / 22050f; float num4 = Mathf.Exp(-8f * num3); float num5 = Mathf.Sin(MathF.PI * 120f * num3); samples[num + i] += amp * num4 * num5; } } } internal static void ResetForTests() { _sprites.Clear(); _graySprites.Clear(); _textures.Clear(); _prefabs.Clear(); _clips.Clear(); _bundle = null; _bundleAttempted = false; _bombIconPlaceholder = null; _heartbeatPlaceholder = null; } private static byte[] LoadEmbeddedBytes(string fileName) { Assembly assembly = typeof(AssetCatalog).Assembly; string name = "Werewolf.Assets." + fileName; using Stream stream = assembly.GetManifestResourceStream(name); if (stream == null) { return null; } byte[] array = new byte[stream.Length]; int i; int num; for (i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } if (i != array.Length) { byte[] array2 = new byte[i]; Buffer.BlockCopy(array, 0, array2, 0, i); return array2; } return array; } private static AssetBundle TryLoadBundle() { if ((Object)(object)_bundle != (Object)null) { return _bundle; } if (_bundleAttempted) { return null; } _bundleAttempted = true; try { string location = typeof(AssetCatalog).Assembly.Location; if (string.IsNullOrEmpty(location)) { return null; } string directoryName = Path.GetDirectoryName(location); if (string.IsNullOrEmpty(directoryName)) { return null; } string text = Path.Combine(directoryName, "werewolf_assets"); if (!File.Exists(text)) { return null; } _bundle = AssetBundle.LoadFromFile(text); return _bundle; } catch (Exception ex) { LogFallback("werewolf_assets", "bundle_exception", ex.GetType().Name); return null; } } private static AudioClip DecodePcm16Wav(string key, byte[] bytes) { if (bytes.Length < 44) { LogFallback(key, "wav_too_short"); return null; } if (bytes[0] != 82 || bytes[1] != 73 || bytes[2] != 70 || bytes[3] != 70 || bytes[8] != 87 || bytes[9] != 65 || bytes[10] != 86 || bytes[11] != 69) { LogFallback(key, "wav_not_riff"); return null; } int num = 12; short num2 = 0; int num3 = 0; short num4 = 0; short num5 = 0; byte[] array = null; while (num + 8 <= bytes.Length) { string text = new string(new char[4] { (char)bytes[num], (char)bytes[num + 1], (char)bytes[num + 2], (char)bytes[num + 3] }); int num6 = BitConverter.ToInt32(bytes, num + 4); int num7 = num + 8; if (num7 + num6 > bytes.Length) { LogFallback(key, "wav_chunk_overflow"); return null; } if (text == "fmt ") { if (num6 < 16) { LogFallback(key, "wav_fmt_short"); return null; } num5 = BitConverter.ToInt16(bytes, num7); num2 = BitConverter.ToInt16(bytes, num7 + 2); num3 = BitConverter.ToInt32(bytes, num7 + 4); num4 = BitConverter.ToInt16(bytes, num7 + 14); } else if (text == "data") { array = new byte[num6]; Buffer.BlockCopy(bytes, num7, array, 0, num6); } int num8 = 8 + num6 + (num6 & 1); num += num8; if (array != null && num2 > 0 && num3 > 0) { break; } } if (array == null || num2 <= 0 || num3 <= 0 || num4 != 16 || num5 != 1) { LogFallback(key, "wav_unsupported", "fmt=" + num5 + ",ch=" + num2 + ",sr=" + num3 + ",bps=" + num4); return null; } int num9 = array.Length / (2 * num2); if (num9 <= 0) { LogFallback(key, "wav_no_frames"); return null; } float[] array2 = new float[num9 * num2]; for (int i = 0; i < array2.Length; i++) { short num10 = (short)(array[i * 2] | (array[i * 2 + 1] << 8)); array2[i] = (float)num10 * 3.0517578E-05f; } AudioClip val = AudioClip.Create(key, num9, (int)num2, num3, false); if ((Object)(object)val == (Object)null) { LogFallback(key, "wav_clip_create_failed"); return null; } if (!val.SetData(array2, 0)) { LogFallback(key, "wav_clip_setdata_failed"); return null; } return val; } private static void LogFallback(string key, string reason, string detail = null) { try { if (detail == null) { WLog.Line("asset_fallback", false, ("key", key), ("reason", reason)); } else { WLog.Line("asset_fallback", false, ("key", key), ("reason", reason), ("detail", detail)); } } catch { } } } public sealed class BlackCatAwakeningToast : IClientPanel { private const float CardWidth = 760f; private const float CardHeight = 170f; private const float TopMargin = 150f; private const float TitleFontSize = 40f; private const float BodyFontSize = 22f; private static readonly Vector2 IconSize = new Vector2(120f, 120f); private const float IconLeftMargin = 24f; private const float TextColumnGap = 24f; private const float TextRightMargin = 16f; private const float SlideInSec = 0.4f; private const float HoldSec = 5f; private const float SlideOutSec = 0.4f; private GameObject _root; private CanvasGroup _group;