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 VehicleRemoval v1.5.1
VehicleRemoval_v1.5.1.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [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("VehicleRemoval")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.5.1.0")] [assembly: AssemblyInformationalVersion("1.5.1")] [assembly: AssemblyProduct("VehicleRemoval")] [assembly: AssemblyTitle("VehicleRemoval")] [assembly: AssemblyVersion("1.5.1.0")] namespace VehicleRemoval; [BepInPlugin("frost.vehicleremoval", "VehicleRemoval", "1.5.1")] public class VehicleRemovalPlugin : BaseUnityPlugin { public const string PluginGuid = "frost.vehicleremoval"; public const string PluginName = "VehicleRemoval"; public const string PluginVersion = "1.5.1"; internal static ManualLogSource Log; internal static ConfigEntry<string> VehicleMaterials; private void Awake() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; VehicleMaterials = ((BaseUnityPlugin)this).Config.Bind<string>("VehicleRemoval", "VehicleMaterials", "Cart=Wood:20,BronzeNails:10;Raft=Wood:20,GreyDwarfEye:5,Resin:10;Karve=FineWood:30,BronzeNails:80,DeerHide:10,Resin:20;VikingShip=FineWood:40,IronNails:100,AncientBark:40,DeerHide:10", "Материалы возврата, если у транспорта нет рецепта в игре (у телеги и кораблей их нет: крафт special-cased). Формат: Префаб=Предмет:кол-во,Предмет:кол-во;... Имена предметов — префабы ObjectDB. Рецепт из игры имеет приоритет, это запасной путь"); VehicleRemovalState.Parse(VehicleMaterials.Value); VehicleMaterials.SettingChanged += delegate { VehicleRemovalState.Parse(VehicleMaterials.Value); }; new Harmony("frost.vehicleremoval").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"VehicleRemoval 1.5.1 загружен"); } } internal static class VehicleRemovalState { private static readonly Dictionary<string, List<KeyValuePair<string, int>>> _map = new Dictionary<string, List<KeyValuePair<string, int>>>(StringComparer.OrdinalIgnoreCase); public static void Parse(string config) { _map.Clear(); string[] array = config.Split(';'); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split('='); if (array2.Length != 2 || array2[0].Trim().Length == 0) { continue; } List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>(); string[] array3 = array2[1].Split(','); for (int j = 0; j < array3.Length; j++) { string[] array4 = array3[j].Split(':'); if (array4.Length == 2 && int.TryParse(array4[1].Trim(), out var result) && array4[0].Trim().Length > 0) { list.Add(new KeyValuePair<string, int>(array4[0].Trim(), result)); } } if (list.Count > 0) { _map[array2[0].Trim()] = list; } } VehicleRemovalPlugin.Log.LogInfo((object)("Таблица материалов транспорта: " + string.Join(", ", _map.Keys))); } public static List<KeyValuePair<string, int>> Get(string prefabName) { if (!_map.TryGetValue(prefabName, out var value)) { return null; } return value; } } [HarmonyPatch(typeof(Player), "RemovePiece")] internal static class Player_RemovePiece_Patch { private static readonly FieldInfo RemoveEffectsField = AccessTools.Field(typeof(Player), "m_removeEffects"); private static readonly MethodInfo GetBuildStaminaMethod = AccessTools.Method(typeof(Player), "GetBuildStamina", (Type[])null, (Type[])null); private static void Postfix(Player __instance, bool __result) { if (__result) { return; } try { TryRemoveVehicle(__instance); } catch (Exception ex) { Debug.LogError((object)("[VehicleRemoval] Ошибка сноса транспорта: " + ex)); } } private static bool TryRemoveVehicle(Player player) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return false; } RaycastHit val = default(RaycastHit); if (!Physics.Raycast(((Component)instance).transform.position, ((Component)instance).transform.forward, ref val, 50f, LayerMask.GetMask(new string[1] { "vehicle" }))) { return false; } Ship componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Ship>(); GameObject val2 = ((componentInParent != null) ? ((Component)componentInParent).gameObject : null); if ((Object)(object)val2 == (Object)null) { Vagon componentInParent2 = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Vagon>(); val2 = ((componentInParent2 != null) ? ((Component)componentInParent2).gameObject : null); } if ((Object)(object)val2 == (Object)null) { return false; } if (!PrivateArea.CheckAccess(val2.transform.position, 0f, true, false)) { ((Character)player).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null, false); return false; } ZNetView component = val2.GetComponent<ZNetView>(); bool flag = (Object)(object)component == (Object)null || !component.IsValid(); if (!flag) { component.ClaimOwnership(); flag = component.IsOwner(); } if (flag) { DropRecipeResources(val2); } object? obj = RemoveEffectsField?.GetValue(player); EffectList val3 = (EffectList)((obj is EffectList) ? obj : null); if (val3 != null) { val3.Create(val2.transform.position, val2.transform.rotation, val2.transform, 1f, -1, ((Character)player).GetZDOID()); } float num = ((GetBuildStaminaMethod != null) ? ((float)GetBuildStaminaMethod.Invoke(player, null)) : 0f); ((Character)player).UseStamina(num); ((Character)player).AddNoise(50f); player.FaceLookDirection(); if (flag) { ZNetScene.instance.Destroy(val2); ((Character)player).Message((MessageType)1, "Транспорт разобран — материалы возвращены", 0, (Sprite)null, false); } else { WearNTear component2 = val2.GetComponent<WearNTear>(); if ((Object)(object)component2 == (Object)null) { return false; } component2.Remove(false); ((Character)player).Message((MessageType)1, "Транспорт уничтожен — материалы в обломках", 0, (Sprite)null, false); } VehicleRemovalPlugin.Log.LogInfo((object)("Разобран транспорт: " + ((Object)val2).name)); return true; } private static void DropRecipeResources(GameObject target) { ObjectDB instance = ObjectDB.instance; string prefabName = Utils.GetPrefabName(target); if (!((Object)(object)instance == (Object)null) && !string.IsNullOrEmpty(prefabName)) { Recipe val = FindRecipe(instance, prefabName); if ((Object)(object)val != (Object)null) { DropFromRecipe(instance, target, val, prefabName); } else if (!DropFromConfig(instance, target, prefabName)) { LogRecipeDiagnostics(instance, prefabName); VehicleRemovalPlugin.Log.LogWarning((object)("Материалы для " + prefabName + " не возвращены: рецепта нет и в VehicleMaterials пусто")); } } } private static void DropFromRecipe(ObjectDB db, GameObject target, Recipe found, string prefabName) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) int num = 0; Requirement[] resources = found.m_resources; foreach (Requirement val in resources) { if (val != null && !((Object)(object)val.m_resItem == (Object)null) && val.m_amount > 0) { string prefabName2 = Utils.GetPrefabName(((Object)val.m_resItem).name); SpawnDrop(db, prefabName2, val.m_amount, target.transform.position + Vector3.up); num++; } } VehicleRemovalPlugin.Log.LogInfo((object)("Рецепт " + prefabName + ": материалов возвращено позиций " + num)); } private static bool DropFromConfig(ObjectDB db, GameObject target, string prefabName) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) List<KeyValuePair<string, int>> list = VehicleRemovalState.Get(prefabName); if (list == null || list.Count == 0) { return false; } foreach (KeyValuePair<string, int> item in list) { SpawnDrop(db, item.Key, item.Value, target.transform.position + Vector3.up); } VehicleRemovalPlugin.Log.LogInfo((object)("Материалы из конфига для " + prefabName + ": " + list.Count + " позиций")); return true; } private static void SpawnDrop(ObjectDB db, string itemName, int amount, Vector3 position) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) GameObject itemPrefab = db.GetItemPrefab(itemName); if ((Object)(object)itemPrefab == (Object)null) { VehicleRemovalPlugin.Log.LogWarning((object)("Предмет для возврата не найден в ObjectDB: " + itemName)); return; } int num = amount; while (num > 0) { ItemDrop component = Object.Instantiate<GameObject>(itemPrefab, position, Quaternion.identity).GetComponent<ItemDrop>(); component.SetStack(Mathf.Min(num, component.m_itemData.m_shared.m_maxStackSize)); ItemDrop.OnCreateNew(component, false); num -= component.m_itemData.m_stack; } VehicleRemovalPlugin.Log.LogInfo((object)$"Возврат: {itemName} x{amount}"); } private static Recipe FindRecipe(ObjectDB db, string prefabName) { Recipe val = null; foreach (Recipe recipe in db.m_recipes) { if (!((Object)(object)recipe == (Object)null) && !((Object)(object)recipe.m_item == (Object)null) && ((Object)((Component)recipe.m_item).gameObject).name == prefabName) { return recipe; } } string b = "Recipe_" + prefabName; foreach (Recipe recipe2 in db.m_recipes) { if (!((Object)(object)recipe2 == (Object)null)) { if (string.Equals(((Object)recipe2).name, b, StringComparison.OrdinalIgnoreCase)) { return recipe2; } if ((Object)(object)val == (Object)null && ((Object)recipe2).name != null && ((Object)recipe2).name.ToLowerInvariant().Contains(prefabName.ToLowerInvariant())) { val = recipe2; } } } GameObject itemPrefab = db.GetItemPrefab(prefabName); ItemDrop val2 = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 != (Object)null && val2.m_itemData != null && val2.m_itemData.m_shared != null) { SharedData shared = val2.m_itemData.m_shared; foreach (Recipe recipe3 in db.m_recipes) { if (!((Object)(object)recipe3 == (Object)null) && !((Object)(object)recipe3.m_item == (Object)null) && recipe3.m_item.m_itemData != null && recipe3.m_item.m_itemData.m_shared != null && recipe3.m_item.m_itemData.m_shared == shared) { return recipe3; } } } foreach (Recipe recipe4 in db.m_recipes) { if (!((Object)(object)recipe4 == (Object)null) && !((Object)(object)recipe4.m_item == (Object)null) && string.Equals(((Object)((Component)recipe4.m_item).gameObject).name, prefabName, StringComparison.OrdinalIgnoreCase)) { return recipe4; } } return val; } private static void LogRecipeDiagnostics(ObjectDB db, string prefabName) { int num = 0; List<string> list = new List<string>(); string value = prefabName.ToLowerInvariant(); foreach (Recipe recipe in db.m_recipes) { if (!((Object)(object)recipe == (Object)null) && !((Object)(object)recipe.m_item == (Object)null)) { num++; string name = ((Object)((Component)recipe.m_item).gameObject).name; if (list.Count < 10 && name.ToLowerInvariant().Contains(value)) { list.Add(name); } } } GameObject itemPrefab = db.GetItemPrefab(prefabName); VehicleRemovalPlugin.Log.LogWarning((object)string.Format("Рецепт для {0} не найден. Рецептов всего: {1}; кандидаты по подстроке: [{2}]; предмет {0} в ObjectDB: {3}", prefabName, num, string.Join(", ", list), ((Object)(object)itemPrefab != (Object)null) ? "ЕСТЬ" : "НЕТ")); foreach (Recipe recipe2 in db.m_recipes) { if (!((Object)(object)recipe2 == (Object)null) && !((Object)(object)recipe2.m_item == (Object)null) && !((Object)(object)recipe2.m_craftingStation == (Object)null) && !(recipe2.m_craftingStation.m_name != "$piece_workbench")) { VehicleRemovalPlugin.Log.LogInfo((object)$"Верстак: {((Object)recipe2).name} -> предмет {((Object)((Component)recipe2.m_item).gameObject).name}"); } } } }