Decompiled source of Y4NGZUpgradesJP v1.1.0

plugins/Y4NGZUpgradesJP/Y4NGZUpgradesJP.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Y4NGZUpgradesJP")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Y4NGZUpgradesJP")]
[assembly: AssemblyTitle("Y4NGZUpgradesJP")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Y4NGZUpgradesJP;

[BepInPlugin("kanta.y4ngzupgradesjp", "Y4NGZUpgrades JP", "2.4.0")]
public class Plugin : BaseUnityPlugin
{
	private sealed class UpgradeText
	{
		public readonly string Name;

		public readonly string Summary;

		public readonly string[] Levels;

		public UpgradeText(string name, string summary, params string[] levels)
		{
			Name = name;
			Summary = summary;
			Levels = levels ?? new string[0];
		}
	}

	private Harmony harmony;

	private static readonly Dictionary<string, UpgradeText> Upgrades = new Dictionary<string, UpgradeText>(StringComparer.OrdinalIgnoreCase)
	{
		["Transporter"] = new UpgradeText("運搬強化", "運搬するスクラップによる移動速度とスタミナへのペナルティを軽減する。スクラップの価値は変わらない。", "所持重量による負担を20%軽減。", "所持重量による負担を40%軽減。", "所持重量による負担を60%軽減。"),
		["Pumping Iron"] = new UpgradeText("筋力強化", "有効な近接武器の攻撃力を強化する。素手攻撃は対象外。Better Armoryの武器も対象外。", "近接武器の威力+1。バニラのシャベル1発分が基準。", "近接攻撃時、25%の確率で命中した敵を1秒間スタンさせる。"),
		["Resilience"] = new UpgradeText("耐久力", "最大HPを増加させ、負傷中は毎秒1HP回復する。最終ランクでは敵の近接攻撃を反撃する。", "最大HP120。HPを最大20まで回復。", "最大HP140。回復上限が30HPに増加。", "最大HP160。回復上限は30HPのまま。", "最大HP180。敵の近接攻撃を50%の確率で反射し、シャベル1発分のダメージと1秒スタンを与える。"),
		["Lethal Hands"] = new UpgradeText("格闘訓練", "素手攻撃を解禁する。1発ごとの間隔は0.75秒で、威力はバニラのシャベル1発分を基準とする。", "パンチの威力はシャベル0.5発分。", "パンチの威力はシャベル1発分。", "パンチの威力はシャベル1.5発分。さらに対象を1秒間スタンさせる。"),
		["Deeper Pockets"] = new UpgradeText("ポケット拡張", "通常4枠のホットバーに追加スロットを増やす。", "ホットバー5枠。", "ホットバー6枠。", "ホットバー7枠。さらに両手持ちアイテムを2個同時に持てる。"),
		["Adrenaline Rush"] = new UpgradeText("アドレナリンラッシュ", "低HP時に移動速度が上昇する。Lv2では1ラウンドに1回だけ致命傷を耐えられる。", "HP20以下になると、HPが20を超えるまで移動速度が30%上昇する。", "1ラウンドに1回、致命傷を受けてもHP1で生存し、重傷状態になったうえで2秒間無敵になる。落下・溺死・置き去りは対象外。"),
		["Field Optics"] = new UpgradeText("光学強化", "スキャナーとライトの光学性能を強化し、スクラップをより早く発見し、広い範囲を照らせるようにする。", "スキャン範囲+15%、ライトの明るさ+10%、照射幅+10%。", "スキャン範囲+30%、ライトの明るさ+15%、照射幅+20%。", "スキャン範囲+45%、ライトの明るさ+40%、照射幅+30%。"),
		["Quick Hands"] = new UpgradeText("クイックハンド", "長押し操作を高速化し、アイテムを拾える距離を延長する。", "長押し操作10%高速化、拾える距離+1m。", "長押し操作20%高速化、拾える距離+2m。", "長押し操作30%高速化、拾える距離+3m。"),
		["Field Mechanic"] = new UpgradeText("現場技師", "施設設備を現場で妨害・操作できるようにする。すべての長押し操作は1.2秒。", "燃料ポンプの停止確率を半減し、会社の監視カメラをラウンド終了まで無効化できる。", "通常の施錠ドアを鍵なしでハッキングして開けられる。", "現場作戦タブレット、または近距離の長押し操作からタレットを90秒間停止できる。クールダウン20秒。"),
		["Scavenger"] = new UpgradeText("スカベンジャー", "現地で回収するものから、より多くの資源と価値を引き出す。", "弾薬の取得量が10%増加し、燃料シュートへの投入価値が10%増加。", "弾薬の取得量が20%増加し、燃料シュートへの投入価値が20%増加。", "弾薬の取得量が30%増加し、燃料シュートへの投入価値が30%増加。"),
		["Field Operations"] = new UpgradeText("現場作戦", "現場作戦タブレットを使用可能にする。", "タブレットを解禁。スキャン、内部マップ、ドローン接続、10秒で接続するメインフレーム接続を使用可能。さらにスクラップ探索と罠停止が可能。LethalCCTV導入時は隠し場所コード、カメラ表示・停止、警報制御、ロックダウンも使用可能。"),
		["Deathbound"] = new UpgradeText("死の絆", "ホットバー左端のスロットを死亡後も保持する。", "ホットバー左端のアイテムは死亡時に落とさず、リスポーン時に戻ってくる。保護されたスロットは赤く表示される。"),
		["Courier Drone"] = new UpgradeText("輸送ドローン", "現場作戦タブレットから操作するスチームパンク式輸送ドローン。ドローンのHPは30。", "最大150lbのスクラップを運搬し、3.5m以内の敵を火炎放射器で攻撃する。", "8~18mの敵を対象にグレネードランチャーで攻撃。クールダウン8秒。自動射撃前には近くの味方を確認するが、発射後に味方が近づくと爆発する。手動操縦時はこの確認を行わない。", "タブレットからドローンを自分で操縦できるパイロットモードを解禁。"),
		["Light Feet"] = new UpgradeText("軽い足取り", "自動防衛系の危険装置があなたに反応しなくなる。", "足音で地雷が作動しなくなる。", "タレットがあなたを発見してから最大2.5秒間、発砲を遅らせる。", "落雷によるダメージと死亡を無効化。"),
		["Sixth Sense"] = new UpgradeText("第六感", "直接見えていない対象だけを輪郭表示する。遮蔽物の向こう側にある対象を発見しやすくする。", "メイン入口、非常口、メインフレーム、隠し場所、目的地を15m以内で表示。タレットと地雷は5m以内のみ。", "10m以内の拾えるスクラップとアイテムも表示。", "15m以内の生存中の敵も表示。"),
		["Chameleon"] = new UpgradeText("カメレオン", "会社の監視カメラだけを欺く迷彩。敵には効果がない。", "監視カメラがあなたを検知するまでの時間+15%。", "監視カメラがあなたを検知するまでの時間+30%。", "監視カメラがあなたを検知するまでの時間+50%。"),
		["Sprinter"] = new UpgradeText("スプリンター", "速度、スタミナ、登攀、地形、静音移動、着地性能を強化する運動訓練。", "移動速度+1.4、沈み込みによる減速-20%、はしご速度+20%。", "スプリント時間+6秒、スタミナ回復+5%、摩擦力+25%、はしご速度+40%。", "ジャンプ力+3、上り坂による減速-25%、はしご速度+60%。", "ジャンプ力さらに+0.75、足音の届く距離-10m、しゃがみ時の減速-10%。", "落下ダメージ-25%。"),
		["Escape Artist"] = new UpgradeText("脱出の達人", "移動性能とパルクールを段階的に強化する。重量物を持っているとスライディング性能が低下する。", "ダッシュ中にしゃがんでパワースライド。スタミナ14%消費、クールダウン2.25秒。", "0.95~3mの段差を乗り越え可能。スタミナ8%消費。", "空中で追加ジャンプ1回。スタミナ8%消費し、着地で回復。"),
		["Lone Wolf"] = new UpgradeText("孤狼", "船室の外で生存している従業員が自分だけになったとき、最後の生存者を強化する。", "発動中、移動速度+30%。", "発動中、スタミナが毎秒ゲージ1.5%ずつ回復。", "発動中、30m以内の敵が5秒間赤く表示される。20秒ごとに繰り返す。"),
		["Shadow Step"] = new UpgradeText("シャドウステップ", "敵に発見される距離を短くし、最終段階で短時間の透明化を解禁する。", "しゃがみ中の敵の検知距離-25%。", "歩行中も検知距離-25%。ダッシュ中は通常通り発見される。", "Shadow Stepキーで6秒間透明化。クールダウン120秒は透明化終了後から開始するため、使用間隔は126秒。"),
		["Buddy System"] = new UpgradeText("バディシステム", "味方を支援するオーラ。バフは他の従業員にのみ適用され、自分には適用されない。", "10m以内の味方は移動速度+3%、被ダメージ-3%。壁や霧の向こうでも輪郭表示される。", "範囲が15mになり、両方の効果が6%に上昇。"),
		["Ping"] = new UpgradeText("マーキング", "専用キーで使うチーム用マーキング。射程80m、持続5秒、クールダウン3秒。", "場所をマーク、または敵・アイテム・操作対象・罠を輪郭表示する。", "マークされた敵の接触ダメージ-20%。", "マークされた味方の被ダメージ-20%。"),
		["Worklight Beacon"] = new UpgradeText("作業灯ビーコン", "貼り付け式の作業灯を投げて設置する。1個180秒点灯し、毎ラウンド開始時にチャージが回復する。拾い直すとチャージが返却される。", "3チャージ、照明半径10m。", "5チャージ、照明半径13m。", "9チャージ、照明半径17m。"),
		["Command Net"] = new UpgradeText("コマンドネット", "インベントリ枠を消費しない通信・戦術表示機能。", "内蔵無線を追加。Command Netキー長押しで無線機を持たずに通信できる。", "味方がダメージを受けると5秒間、その輪郭を表示する。", "船室の外に出ると画面隅にミニマップを表示。味方、入口、敵、監視カメラ、目的地を追跡する。"),
		["Overachiever"] = new UpgradeText("努力家", "昇進するたびに追加のアップグレードトークンを獲得する。すでに取得した昇進分にも遡ってボーナスが適用される。", "昇進1回につき追加トークン+1。", "昇進1回につき追加トークン+2。", "昇進1回につき追加トークン+4。"),
		["Inspire"] = new UpgradeText("鼓舞", "Pingを使って近くの死体に蘇生を試みられるようにする。", "7m以内の死体にPingすると50%の確率で蘇生。1ラウンド1回までで、成功時のみ使用回数を消費。成功後クールダウン75秒。"),
		["Veteran"] = new UpgradeText("熟練兵", "何度も出勤するクルーに会社が少しだけ寛容になる。チーム全員に、誰かが取得した最高レベルが適用される。", "ラウンド終了時、死亡した味方によるクレジットペナルティを半減。", "次のQuotaの期限が3日ではなく4日になる。")
	};

	private static readonly Dictionary<string, string> UiTranslations = new Dictionary<string, string>(StringComparer.Ordinal)
	{
		["EMPLOYEE FILE"] = "従業員ファイル",
		["APPLICANT"] = "応募者",
		["UPGRADES"] = "アップグレード",
		["SUITS"] = "スーツ",
		["COSMETICS"] = "コスメ",
		["EMOTES"] = "エモート",
		["TOKENS"] = "トークン",
		["TOKEN"] = "トークン",
		["PLAYER:"] = "プレイヤー:",
		["LEVELS"] = "レベル",
		["LEVEL"] = "レベル",
		["COST:"] = "コスト:",
		["LOCKED"] = "ロック中",
		["UNLOCKED"] = "解放済み",
		["MAXED"] = "最大レベル",
		["FILE SUMMARY"] = "概要",
		["COMPLETE"] = "完了",
		["Enforcer"] = "戦闘員",
		["ENFORCER"] = "戦闘員",
		["Technician"] = "技術兵",
		["TECHNICIAN"] = "技術兵",
		["Ghost"] = "偵察兵",
		["GHOST"] = "偵察兵",
		["Foreman"] = "指揮官",
		["FOREMAN"] = "指揮官",
		["NOT ENOUGH TOKENS"] = "トークンが足りません",
		["ALREADY AT MAX TIER"] = "すでに最大レベルです",
		["TREE REQUIREMENT NOT MET"] = "ツリー条件を満たしていません",
		["PREREQUISITE NOT MET"] = "前提条件を満たしていません",
		["PURCHASE REFUSED - NOTHING CHARGED"] = "購入できませんでした。トークンは消費されません。",
		["PRICE CHANGED - NOTHING CHARGED"] = "価格が変更されました。トークンは消費されません。",
		["SAVE NOT READY - NOTHING CHARGED"] = "セーブが準備中です。トークンは消費されません。",
		["Unlocks the next level."] = "次のレベルを解放します。",
		["Final level for this upgrade file."] = "このアップグレードの最終レベルです。"
	};

	private void Awake()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		harmony = new Harmony("kanta.y4ngzupgradesjp");
		Assembly assembly = FindAssembly("Y4NGZUpgrades");
		if (assembly == null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"Y4NGZUpgrades.dll が見つかりません。");
			return;
		}
		Type type = assembly.GetType("Y4NGZUpgrades.Gui.PurchaseMenu");
		if (type == null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"PurchaseMenu が見つかりません。");
			return;
		}
		PatchByName(type, "GetUpgradeTierEffect", "GetUpgradeTierEffectPostfix");
		PatchByName(type, "GetUpgradeSummary", "GetUpgradeSummaryPostfix");
		PatchPurchaseMenuUiHooks(type);
		((BaseUnityPlugin)this).Logger.LogInfo((object)"========================================");
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Y4NGZUpgrades JP 2.3.0 起動");
		((BaseUnityPlugin)this).Logger.LogInfo((object)"パーク別説明文・レベル効果を強制日本語化");
		((BaseUnityPlugin)this).Logger.LogInfo((object)"========================================");
	}

	private void PatchByName(Type type, string methodName, string postfixName)
	{
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Expected O, but got Unknown
		MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		MethodInfo[] array = methods.Where((MethodInfo m) => m.Name == methodName).ToArray();
		if (array.Length == 0)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("メソッドが見つかりません: " + methodName));
			return;
		}
		MethodInfo method = typeof(Plugin).GetMethod(postfixName, BindingFlags.Static | BindingFlags.NonPublic);
		MethodInfo[] array2 = array;
		foreach (MethodInfo methodInfo in array2)
		{
			try
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((BaseUnityPlugin)this).Logger.LogInfo((object)("パーク説明パッチ成功: " + type.FullName + "." + methodInfo.Name));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("パーク説明パッチ失敗: " + methodInfo.Name + "\n" + ex));
			}
		}
	}

	private static void GetUpgradeTierEffectPostfix(object __0, int __1, ref string __result)
	{
		string upgradeKey = GetUpgradeKey(__0);
		if (upgradeKey != null && Upgrades.TryGetValue(upgradeKey, out var value))
		{
			if (__1 >= 1 && __1 <= value.Levels.Length)
			{
				__result = value.Levels[__1 - 1];
			}
		}
	}

	private static void GetUpgradeSummaryPostfix(object __0, ref string __result)
	{
		string upgradeKey = GetUpgradeKey(__0);
		if (upgradeKey != null && Upgrades.TryGetValue(upgradeKey, out var value))
		{
			__result = value.Summary;
		}
	}

	private static string GetUpgradeKey(object node)
	{
		if (node == null)
		{
			return null;
		}
		string stringMember = GetStringMember(node, "Name");
		if (!string.IsNullOrEmpty(stringMember) && Upgrades.ContainsKey(stringMember))
		{
			return stringMember;
		}
		string stringMember2 = GetStringMember(node, "Id");
		if (!string.IsNullOrEmpty(stringMember2) && Upgrades.ContainsKey(stringMember2))
		{
			return stringMember2;
		}
		return null;
	}

	private static string GetStringMember(object instance, string memberName)
	{
		Type type = instance.GetType();
		try
		{
			PropertyInfo property = type.GetProperty(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null && property.PropertyType == typeof(string))
			{
				return property.GetValue(instance, null) as string;
			}
		}
		catch
		{
		}
		try
		{
			FieldInfo field = type.GetField(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null && field.FieldType == typeof(string))
			{
				return field.GetValue(instance) as string;
			}
		}
		catch
		{
		}
		return null;
	}

	private void PatchPurchaseMenuUiHooks(Type purchaseMenu)
	{
		PatchMethodsWithPostfix(purchaseMenu, "showUpgrades", "ShowUpgradesPostfix");
		PatchMethodsWithPostfix(purchaseMenu, "showUpgradeGui", "ShowUpgradeGuiPostfix");
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Y4NGZ UI専用パッチを有効化しました。グローバルTMPパッチは使用しません。");
	}

	private void PatchMethodsWithPostfix(Type type, string methodName, string postfixName)
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Expected O, but got Unknown
		MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		MethodInfo method = typeof(Plugin).GetMethod(postfixName, BindingFlags.Static | BindingFlags.NonPublic);
		int num = 0;
		MethodInfo[] array = methods;
		foreach (MethodInfo methodInfo in array)
		{
			if (!(methodInfo.Name != methodName))
			{
				try
				{
					harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("UIパッチ失敗: " + methodName + "\n" + ex));
				}
			}
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Y4NGZ UIフック " + methodName + ": " + num + " 個"));
	}

	private static void ShowUpgradesPostfix(object __instance)
	{
		TranslatePurchaseMenu(__instance);
	}

	private static void ShowUpgradeGuiPostfix(object __instance)
	{
		TranslatePurchaseMenu(__instance);
	}

	private static void TranslatePurchaseMenu(object instance)
	{
		Component val = (Component)((instance is Component) ? instance : null);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		Transform transform = val.transform;
		if ((Object)(object)transform == (Object)null)
		{
			return;
		}
		TMP_Text[] componentsInChildren = ((Component)transform).GetComponentsInChildren<TMP_Text>(true);
		foreach (TMP_Text val2 in componentsInChildren)
		{
			if (!((Object)(object)val2 == (Object)null))
			{
				string text = val2.text;
				if (TryTranslateGeneral(text, out var translated) && translated != text)
				{
					val2.text = translated;
				}
			}
		}
		Text[] componentsInChildren2 = ((Component)transform).GetComponentsInChildren<Text>(true);
		foreach (Text val3 in componentsInChildren2)
		{
			if (!((Object)(object)val3 == (Object)null))
			{
				string text2 = val3.text;
				if (TryTranslateGeneral(text2, out var translated2) && translated2 != text2)
				{
					val3.text = translated2;
				}
			}
		}
	}

	private static bool TryTranslateGeneral(string current, out string translated)
	{
		translated = current;
		if (string.IsNullOrEmpty(current))
		{
			return false;
		}
		if (UiTranslations.TryGetValue(current, out var value))
		{
			translated = value;
			return true;
		}
		string key = current.Replace("\r\n", "\n").Trim();
		if (UiTranslations.TryGetValue(key, out value))
		{
			translated = value;
			return true;
		}
		return false;
	}

	private static Assembly FindAssembly(string name)
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			try
			{
				if (string.Equals(assembly.GetName().Name, name, StringComparison.OrdinalIgnoreCase))
				{
					return assembly;
				}
			}
			catch
			{
			}
		}
		return null;
	}

	private static Type FindType(string fullName)
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			try
			{
				Type type = assembly.GetType(fullName, throwOnError: false);
				if (type != null)
				{
					return type;
				}
			}
			catch
			{
			}
		}
		return null;
	}
}