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 HardheimMultiPlant v1.2.0
plugins/MultiPlant.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Extensions; using Jotunn.Managers; using Jotunn.Utils; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("MultiPlant")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("MultiPlant")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("f4ffda28-275e-405d-906b-28e0d2f550e2")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace HardheimMultiPlant; [BepInPlugin("h4nz0.hardheimmultiplant", "Hardheim Multi Plant", "1.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [SynchronizationMode(/*Could not decode attribute arguments.*/)] public class HardheimMultiPlantPlugin : BaseUnityPlugin { public const string ModGuid = "h4nz0.hardheimmultiplant"; public const string ModName = "Hardheim Multi Plant"; public const string ModVersion = "1.2.0"; internal static HardheimMultiPlantPlugin Instance; internal static ManualLogSource Log; private Harmony _harmony; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<int> RequiredFarmingSkill; internal static ConfigEntry<int> ExtraPlantsAtThreshold; internal static ConfigEntry<int> MaxExtraPlants; internal static ConfigEntry<float> PlantSpacing; internal static ConfigEntry<bool> UseSelectedPlantRequiredSpace; internal static ConfigEntry<float> PlantRequiredSpaceMultiplier; internal static ConfigEntry<float> MinimumSmallPlantSpacing; internal static ConfigEntry<float> MinimumTreePlantSpacing; internal static ConfigEntry<bool> RequireCultivatorEquipped; internal static ConfigEntry<string> AllowedPrefabKeywords; internal static ConfigEntry<bool> EnableSnapping; internal static ConfigEntry<float> SnapStep; internal static ConfigEntry<bool> SnapUseGhostRight; internal static ConfigEntry<bool> PreviewExtraPlants; internal static ConfigEntry<bool> OnlyLocalPreview; internal static ConfigEntry<bool> ExtraPlacementRequiresFreeSpace; internal static ConfigEntry<bool> GroundSnapToTerrain; internal static ConfigEntry<float> GroundSnapRayHeight; internal static ConfigEntry<bool> DebugEnabled; internal static ConfigEntry<bool> DebugGhostUpdate; internal static ConfigEntry<bool> DebugPlacement; internal static ConfigEntry<bool> DebugConfigSync; internal static ConfigEntry<bool> DebugShowPositionDetails; internal static ConfigEntry<bool> DebugDumpConfigOnLoad; internal static ConfigEntry<bool> DebugDumpConfigOnSync; internal static ConfigEntry<bool> DebugDumpAdminState; internal static ConfigEntry<bool> DebugCollisionCheck; internal static ConfigEntry<bool> UseSquarePattern; internal static ConfigEntry<bool> UseGroundRaySnap; internal static ConfigEntry<float> GroundRayStartHeight; internal static ConfigEntry<float> GroundRayDistance; internal static ConfigEntry<bool> RequireRealGroundHit; internal static ConfigEntry<float> GroundNormalMinY; internal static ConfigEntry<bool> CheckExistingPlants; internal static ConfigEntry<float> ExistingPlantCheckMultiplier; internal static ConfigEntry<bool> CheckNearbyObjectsForGrowthSpace; internal static ConfigEntry<float> NearbyObjectCheckMultiplier; private static readonly List<GameObject> PreviewGhosts = new List<GameObject>(); private static readonly List<Vector3> CachedExtraPositions = new List<Vector3>(); private static readonly List<Vector2Int> CachedExtraCells = new List<Vector2Int>(); private static readonly FieldInfo PlacementGhostField = AccessTools.Field(typeof(Player), "m_placementGhost"); private static readonly BindingFlags AllInstance = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static string _lastGhostName = string.Empty; private static int _lastExtraCount = -1; private static bool _lastPreviewVisible = false; private static Quaternion _stickyRotation = Quaternion.identity; private static bool _hasStickyRotation = false; private static Quaternion _lastGoodPreviewRotation = Quaternion.identity; private static bool _hasLastGoodPreviewRotation = false; private static GameObject _lastPlacedPrefabVisualSource; private static string _lastPlacedPrefabName = string.Empty; private static string _lastSelectedPlantKey = string.Empty; private void Awake() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; CreateConfigValues(); HookJotunnEvents(); _harmony = new Harmony("h4nz0.hardheimmultiplant"); _harmony.PatchAll(); Log.LogInfo((object)"=================================================="); Log.LogInfo((object)"Hardheim Multi Plant 1.2.0 betöltve."); Log.LogInfo((object)"Jotunn dependency aktív: igen"); Log.LogInfo((object)"Config sync mód: AdminOnlyStrictness.IfOnServer"); Log.LogInfo((object)"=================================================="); if (DebugDumpConfigOnLoad.Value) { DumpAllConfig("Awake"); } } private void OnDestroy() { try { _harmony.UnpatchSelf(); } catch { } DestroyPreviewGhosts(); } private void CreateConfigValues() { Enabled = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Általános", "Enabled", true, "A mod fő kapcsolója. Ha kikapcsolod, sem preview, sem extra ültetés nem fut.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config = ((BaseUnityPlugin)this).Config; AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100); RequiredFarmingSkill = ConfigFileExtensions.BindConfig<int>(config, "Egyensúly", "RequiredFarmingSkill", 60, "Minimum Farming skill szint, ami felett aktiválódik a többes ültetés.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config2 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 16); ExtraPlantsAtThreshold = ConfigFileExtensions.BindConfig<int>(config2, "Egyensúly", "ExtraPlantsAtThreshold", 8, "Ennyi extra növény jelenik meg és ültethető le, amikor a játékos eléri a minimum skill szintet.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config3 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 32); MaxExtraPlants = ConfigFileExtensions.BindConfig<int>(config3, "Egyensúly", "MaxExtraPlants", 8, "Maximum ennyi extra növényt enged a mod összesen.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config4 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 10f); PlantSpacing = ConfigFileExtensions.BindConfig<float>(config4, "Elhelyezés", "PlantSpacing", 1.15f, "Régi/fallback távolság. Csak akkor használja, ha az aktuálisan ültetett növényből nem tud minimum helyet kiolvasni.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); UseSelectedPlantRequiredSpace = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Elhelyezés", "UseSelectedPlantRequiredSpace", true, "Ha igaz, a rács távolságát az aktuálisan kiválasztott növény Plant komponenséből / collider méretéből számolja, nem egy fix közös értékből.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config5 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f); PlantRequiredSpaceMultiplier = ConfigFileExtensions.BindConfig<float>(config5, "Elhelyezés", "PlantRequiredSpaceMultiplier", 1.05f, "Szorzó az aktuális növény minimum helyigényére. 1.05 = kis biztonsági ráhagyás.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config6 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 5f); MinimumSmallPlantSpacing = ConfigFileExtensions.BindConfig<float>(config6, "Elhelyezés", "MinimumSmallPlantSpacing", 1.15f, "Minimum rácstávolság kis növényeknél, ha a játékból kiolvasott érték ennél kisebb lenne.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config7 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f); MinimumTreePlantSpacing = ConfigFileExtensions.BindConfig<float>(config7, "Elhelyezés", "MinimumTreePlantSpacing", 4f, "Minimum rácstávolság fáknál/csemetéknél, ha a játékból kiolvasott érték ennél kisebb lenne.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); RequireCultivatorEquipped = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Szabályok", "RequireCultivatorEquipped", true, "Ha igaz, a mod csak akkor működik, ha a játékosnál Cultivator van használatban.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); AllowedPrefabKeywords = ConfigFileExtensions.BindConfig<string>(((BaseUnityPlugin)this).Config, "Szűrő", "AllowedPrefabKeywords", "carrot,turnip,onion,seed,seedling,sapling,beech,birch,fir,pine,jotunpuffs,magecap,barley,flax", "Vesszővel elválasztott kulcsszavak. Csak az ezekre illeszkedő ültethető ghostokra aktiválódik a mod.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); EnableSnapping = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Snapping", "EnableSnapping", false, "Régi X/Z rács-snapping kapcsoló. Alapból kikapcsolva, mert a 3x3 previewt szétcsúsztathatja vagy eltolhatja a vanilla középső ghosthoz képest.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config8 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 5f); SnapStep = ConfigFileExtensions.BindConfig<float>(config8, "Snapping", "SnapStep", 0.5f, "A snapping rácslépése méterben. Például 0.5 = félméteres igazítás.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); SnapUseGhostRight = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Snapping", "SnapUseGhostRight", true, "Ha igaz, az extra növények az aktuális placement ghost jobb oldali tengelye mentén sorakoznak fel. Ha hamis, a játékos jobb oldali tengelyét használja.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); PreviewExtraPlants = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Preview", "PreviewExtraPlants", true, "Ha igaz, ültetés előtt megjelennek az extra ghostok.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); OnlyLocalPreview = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Preview", "OnlyLocalPreview", true, "Ha igaz, a preview csak a helyi játékosnak jelenik meg.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ExtraPlacementRequiresFreeSpace = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Szabályok", "ExtraPlacementRequiresFreeSpace", true, "Ha igaz, az extra növény csak akkor kerül lerakásra, ha a célpozíció szabadnak látszik.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); GroundSnapToTerrain = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Snapping", "GroundSnapToTerrain", true, "Ha igaz, az extra preview és lerakás a talaj felszínére igazodik, nem csak X/Z rácsra.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config9 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f); GroundSnapRayHeight = ConfigFileExtensions.BindConfig<float>(config9, "Snapping", "GroundSnapRayHeight", 10f, "Milyen magasról induljon a talajra igazító raycast az extra pozícióknál.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); UseSquarePattern = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Elhelyezés", "UseSquarePattern", true, "Ha igaz, az extra ültetési pontok négyzetes mintában helyezkednek el az eredeti pont körül.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); UseGroundRaySnap = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Snapping", "UseGroundRaySnap", true, "Ha igaz, a számolt extra pontokat lefelé sugárvetéssel a talajhoz igazítja.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config10 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f); GroundRayStartHeight = ConfigFileExtensions.BindConfig<float>(config10, "Snapping", "GroundRayStartHeight", 3f, "Ennyivel a célpont fölül indul a lefelé sugárvetés a talaj megkereséséhez.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config11 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f); GroundRayDistance = ConfigFileExtensions.BindConfig<float>(config11, "Snapping", "GroundRayDistance", 10f, "A lefelé sugárvetés maximális hossza a talaj megkereséséhez.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); RequireRealGroundHit = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Snapping", "RequireRealGroundHit", true, "Ha igaz, az extra ghost/növény csak akkor jelenik meg és csak akkor kerül lerakásra, ha a lefelé raycast valódi terepet/Heightmap-et talál. Kerítésre, játékosra, itemre nem snapel.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config12 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f); GroundNormalMinY = ConfigFileExtensions.BindConfig<float>(config12, "Snapping", "GroundNormalMinY", 0.55f, "Minimum talaj-normál Y érték. 1 = vízszintes, 0.55 körül még lejtős talajt enged, de falat/kerítést nem.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); CheckExistingPlants = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Szabályok", "CheckExistingPlants", true, "Ha igaz, az extra ghost és extra ültetés figyeli a már elültetett növényeket is, és pirosra vált / kihagyja a túl közeli pontokat.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config13 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 2f); ExistingPlantCheckMultiplier = ConfigFileExtensions.BindConfig<float>(config13, "Szabályok", "ExistingPlantCheckMultiplier", 0.95f, "A kiválasztott növény spacing értékének ekkora részén belül már túl közelinek számít egy meglévő növény. 0.95 = majdnem teljes spacing.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); CheckNearbyObjectsForGrowthSpace = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Szabályok", "CheckNearbyObjectsForGrowthSpace", true, "Ha igaz, a preview és az extra ültetés nem csak meglévő növényeket figyel, hanem építményeket és tereptárgyakat is a növekedési hely körül. Így nem enged túl közel kerítéshez, falhoz, ládához stb.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config14 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f); NearbyObjectCheckMultiplier = ConfigFileExtensions.BindConfig<float>(config14, "Szabályok", "NearbyObjectCheckMultiplier", 0.55f, "A kiválasztott növény spacing értékének ekkora részén belül számít túl közelinek egy építmény vagy tereptárgy. Kis növénynél 0.55 kb. 0.63m, fáknál arányosan nagyobb.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); DebugEnabled = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Debug", "DebugEnabled", false, "Fő debug kapcsoló. Erősen részletes naplózást engedélyez.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); DebugGhostUpdate = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Debug", "DebugGhostUpdate", true, "Részletes log az előnézeti ghost frissítésről.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); DebugPlacement = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Debug", "DebugPlacement", true, "Részletes log a tényleges extra lerakásról.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); DebugConfigSync = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Debug", "DebugConfigSync", true, "Részletes log a Jotunn config sync eseményekről.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); DebugShowPositionDetails = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Debug", "DebugShowPositionDetails", true, "Kiírja a számolt pozíciókat, snap előtti és snap utáni adatokat.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); DebugDumpConfigOnLoad = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Debug", "DebugDumpConfigOnLoad", true, "A mod indulásakor kiírja az összes fontos konfig értéket.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); DebugDumpConfigOnSync = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Debug", "DebugDumpConfigOnSync", true, "Config sync után kiírja az összes fontos konfig értéket.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); DebugDumpAdminState = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Debug", "DebugDumpAdminState", true, "Kiírja a Jotunn által ismert admin állapotot és annak változásait.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); DebugCollisionCheck = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Debug", "DebugCollisionCheck", true, "Kiírja a helyfoglalás-ellenőrzés találatait az extra lerakásoknál.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); } private void HookJotunnEvents() { SynchronizationManager.OnConfigurationSynchronized += OnConfigurationSynchronized; SynchronizationManager.OnAdminStatusChanged += OnAdminStatusChanged; } private void OnConfigurationSynchronized(object sender, ConfigurationSynchronizationEventArgs args) { if (DebugEnabled.Value && DebugConfigSync.Value) { Log.LogInfo((object)"[CFGSYNC] =================================================="); Log.LogInfo((object)"[CFGSYNC] Konfig szinkron esemény érkezett."); Log.LogInfo((object)("[CFGSYNC] InitialSynchronization = " + args.InitialSynchronization)); Log.LogInfo((object)("[CFGSYNC] PlayerIsAdmin = " + SafeGetAdminState())); Log.LogInfo((object)"[CFGSYNC] =================================================="); if (DebugDumpConfigOnSync.Value) { DumpAllConfig("OnConfigurationSynchronized"); } } } private void OnAdminStatusChanged() { if (DebugEnabled.Value && DebugDumpAdminState.Value) { Log.LogInfo((object)"[ADMIN] ================================================"); Log.LogInfo((object)"[ADMIN] Admin státusz változás érkezett."); Log.LogInfo((object)("[ADMIN] PlayerIsAdmin = " + SafeGetAdminState())); Log.LogInfo((object)"[ADMIN] ================================================"); } } internal static bool SafeGetAdminState() { try { return SynchronizationManager.Instance != null && SynchronizationManager.Instance.PlayerIsAdmin; } catch { return false; } } internal static void DumpAllConfig(string source) { Log.LogInfo((object)("[DUMP][" + source + "] ------------------------------")); Log.LogInfo((object)("[DUMP][" + source + "] Enabled = " + Enabled.Value)); Log.LogInfo((object)("[DUMP][" + source + "] RequiredFarmingSkill = " + RequiredFarmingSkill.Value)); Log.LogInfo((object)("[DUMP][" + source + "] ExtraPlantsAtThreshold = " + ExtraPlantsAtThreshold.Value)); Log.LogInfo((object)("[DUMP][" + source + "] MaxExtraPlants = " + MaxExtraPlants.Value)); Log.LogInfo((object)("[DUMP][" + source + "] PlantSpacing = " + PlantSpacing.Value)); Log.LogInfo((object)("[DUMP][" + source + "] UseSelectedPlantRequiredSpace = " + UseSelectedPlantRequiredSpace.Value)); Log.LogInfo((object)("[DUMP][" + source + "] PlantRequiredSpaceMultiplier = " + PlantRequiredSpaceMultiplier.Value)); Log.LogInfo((object)("[DUMP][" + source + "] MinimumSmallPlantSpacing = " + MinimumSmallPlantSpacing.Value)); Log.LogInfo((object)("[DUMP][" + source + "] MinimumTreePlantSpacing = " + MinimumTreePlantSpacing.Value)); Log.LogInfo((object)("[DUMP][" + source + "] RequireCultivatorEquipped = " + RequireCultivatorEquipped.Value)); Log.LogInfo((object)("[DUMP][" + source + "] AllowedPrefabKeywords = " + AllowedPrefabKeywords.Value)); Log.LogInfo((object)("[DUMP][" + source + "] EnableSnapping = " + EnableSnapping.Value)); Log.LogInfo((object)("[DUMP][" + source + "] SnapStep = " + SnapStep.Value)); Log.LogInfo((object)("[DUMP][" + source + "] SnapUseGhostRight = " + SnapUseGhostRight.Value)); Log.LogInfo((object)("[DUMP][" + source + "] PreviewExtraPlants = " + PreviewExtraPlants.Value)); Log.LogInfo((object)("[DUMP][" + source + "] OnlyLocalPreview = " + OnlyLocalPreview.Value)); Log.LogInfo((object)("[DUMP][" + source + "] ExtraPlacementRequiresFreeSpace = " + ExtraPlacementRequiresFreeSpace.Value)); Log.LogInfo((object)("[DUMP][" + source + "] GroundSnapToTerrain = " + GroundSnapToTerrain.Value)); Log.LogInfo((object)("[DUMP][" + source + "] GroundSnapRayHeight = " + GroundSnapRayHeight.Value)); Log.LogInfo((object)("[DUMP][" + source + "] CheckExistingPlants = " + CheckExistingPlants.Value)); Log.LogInfo((object)("[DUMP][" + source + "] ExistingPlantCheckMultiplier = " + ExistingPlantCheckMultiplier.Value)); Log.LogInfo((object)("[DUMP][" + source + "] CheckNearbyObjectsForGrowthSpace = " + CheckNearbyObjectsForGrowthSpace.Value)); Log.LogInfo((object)("[DUMP][" + source + "] NearbyObjectCheckMultiplier = " + NearbyObjectCheckMultiplier.Value)); Log.LogInfo((object)("[DUMP][" + source + "] PlayerIsAdmin = " + SafeGetAdminState())); Log.LogInfo((object)("[DUMP][" + source + "] ------------------------------")); } internal static void LogDebug(string msg) { if (DebugEnabled.Value) { Log.LogInfo((object)("[DEBUG] " + msg)); } } internal static void LogGhost(string msg) { if (DebugEnabled.Value && DebugGhostUpdate.Value) { Log.LogInfo((object)("[GHOST] " + msg)); } } internal static void LogPlacement(string msg) { if (DebugEnabled.Value && DebugPlacement.Value) { Log.LogInfo((object)("[PLACE] " + msg)); } } internal static string CleanName(string name) { return string.IsNullOrEmpty(name) ? string.Empty : name.Replace("(Clone)", "").Trim(); } internal static string[] SplitKeywords(string raw) { if (string.IsNullOrWhiteSpace(raw)) { return new string[0]; } string[] array = raw.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); List<string> list = new List<string>(); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (!string.IsNullOrWhiteSpace(text)) { list.Add(text); } } return list.ToArray(); } internal static string Vec(Vector3 v) { return "(" + v.x.ToString("0.000") + ", " + v.y.ToString("0.000") + ", " + v.z.ToString("0.000") + ")"; } internal static GameObject GetPlacementGhost(Player player) { if ((Object)(object)player == (Object)null || PlacementGhostField == null) { return null; } try { object? value = PlacementGhostField.GetValue(player); return (GameObject)((value is GameObject) ? value : null); } catch (Exception ex) { Log.LogWarning((object)("[GHOST] Nem sikerült kiolvasni az m_placementGhost mezőt: " + ex)); return null; } } internal static ItemData GetRightItemSafe(Player player) { if ((Object)(object)player == (Object)null) { return null; } try { FieldInfo fieldInfo = typeof(Humanoid).GetField("m_rightItem", AllInstance) ?? typeof(Player).GetField("m_rightItem", AllInstance); if (fieldInfo != null) { object? value = fieldInfo.GetValue(player); ItemData val = (ItemData)((value is ItemData) ? value : null); if (val != null) { return val; } } } catch { } try { MethodInfo methodInfo = typeof(Humanoid).GetMethod("GetCurrentWeapon", AllInstance) ?? typeof(Player).GetMethod("GetCurrentWeapon", AllInstance); if (methodInfo != null) { object? obj2 = methodInfo.Invoke(player, null); ItemData val2 = (ItemData)((obj2 is ItemData) ? obj2 : null); if (val2 != null) { return val2; } } } catch { } return null; } internal static bool HasCultivatorEquipped(Player player, GameObject placementGhost) { if ((Object)(object)player == (Object)null) { return false; } if (!RequireCultivatorEquipped.Value) { return true; } ItemData rightItemSafe = GetRightItemSafe(player); string text = ((rightItemSafe != null && rightItemSafe.m_shared != null) ? (rightItemSafe.m_shared.m_name ?? string.Empty) : string.Empty); string text2 = ((rightItemSafe != null && (Object)(object)rightItemSafe.m_dropPrefab != (Object)null) ? (((Object)rightItemSafe.m_dropPrefab).name ?? string.Empty) : string.Empty); string text3 = (((Object)(object)placementGhost != (Object)null) ? CleanName(((Object)placementGhost).name) : string.Empty); if (text3.StartsWith("HH_", StringComparison.OrdinalIgnoreCase)) { return false; } bool flag = text.IndexOf("cultivator", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("kultiv", StringComparison.OrdinalIgnoreCase) >= 0 || text.Equals("$item_cultivator", StringComparison.OrdinalIgnoreCase) || text2.IndexOf("cultivator", StringComparison.OrdinalIgnoreCase) >= 0; bool flag2 = text3.IndexOf("cultivate", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("sapling", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("seed", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("carrot", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("turnip", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("onion", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("barley", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("flax", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("beech", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("birch", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("fir", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("pine", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("jotunpuffs", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("magecap", StringComparison.OrdinalIgnoreCase) >= 0; bool result = flag || flag2; if (DebugEnabled.Value && DebugGhostUpdate.Value) { Log.LogInfo((object)("[GHOST] HasCultivatorEquipped -> " + result + " | sharedName=" + text + " | dropName=" + text2 + " | ghostName=" + text3)); } return result; } internal static bool IsPlantPlacement(GameObject placementGhost) { if ((Object)(object)placementGhost == (Object)null) { return false; } string text = CleanName(((Object)placementGhost).name); if (text.StartsWith("HH_", StringComparison.OrdinalIgnoreCase)) { return false; } string text2 = text.ToLowerInvariant(); return text2.Contains("sapling") || text2.Contains("seed") || text2.Contains("carrot") || text2.Contains("turnip") || text2.Contains("onion") || text2.Contains("barley") || text2.Contains("flax") || text2.Contains("beech") || text2.Contains("birch") || text2.Contains("fir") || text2.Contains("pine") || text2.Contains("jotunpuffs") || text2.Contains("magecap"); } internal static bool IsPlantableGhost(GameObject ghost) { if ((Object)(object)ghost == (Object)null) { return false; } string text = CleanName(((Object)ghost).name); if (text.StartsWith("HH_")) { return false; } string text2 = text; if (string.IsNullOrWhiteSpace(text2)) { return false; } string[] array = SplitKeywords(AllowedPrefabKeywords.Value); for (int i = 0; i < array.Length; i++) { if (text2.IndexOf(array[i], StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } internal static bool TryGetFarmingSkillType(out SkillType skillType) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected I4, but got Unknown skillType = (SkillType)0; try { skillType = (SkillType)(int)(SkillType)Enum.Parse(typeof(SkillType), "Farming"); return true; } catch (Exception ex) { Log.LogWarning((object)("[SKILL] Nem sikerült feloldani a Skills.SkillType.Farming enumot: " + ex)); return false; } } internal static float GetFarmingLevel(Player player) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return 0f; } if (!TryGetFarmingSkillType(out var skillType)) { return 0f; } try { return ((Character)player).GetSkillLevel(skillType); } catch (Exception ex) { Log.LogWarning((object)("[SKILL] Nem sikerült lekérni a Farming skill szintet: " + ex)); return 0f; } } internal static int GetExtraPlantCount(Player player) { float farmingLevel = GetFarmingLevel(player); int num = Mathf.Max(0, RequiredFarmingSkill.Value); if (farmingLevel < (float)num) { if (DebugEnabled.Value && DebugGhostUpdate.Value) { Log.LogInfo((object)("[COUNT] Farming skill túl alacsony. current=" + farmingLevel + " required=" + num)); } return 0; } int num2 = Mathf.Max(0, ExtraPlantsAtThreshold.Value); if (farmingLevel > (float)num) { int num3 = Mathf.FloorToInt((farmingLevel - (float)num) / 20f); num2 += num3; } num2 = Mathf.Clamp(num2, 0, Mathf.Max(0, MaxExtraPlants.Value)); if (DebugEnabled.Value && (DebugGhostUpdate.Value || DebugPlacement.Value)) { Log.LogInfo((object)("[COUNT] Farming=" + farmingLevel + " required=" + num + " -> extra=" + num2)); } return num2; } internal static Piece GetSelectedPieceSafe(Player player) { if ((Object)(object)player == (Object)null) { return null; } try { FieldInfo field = typeof(Player).GetField("m_buildPieces", AllInstance); PieceTable val = (PieceTable)((field != null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val == (Object)null) { return null; } MethodInfo method = typeof(PieceTable).GetMethod("GetSelectedPiece", AllInstance, null, Type.EmptyTypes, null); if (method != null) { object? obj = method.Invoke(val, null); Piece val2 = (Piece)((obj is Piece) ? obj : null); if ((Object)(object)val2 != (Object)null) { return val2; } } FieldInfo field2 = typeof(PieceTable).GetField("m_selectedPiece", AllInstance); if (field2 != null) { object? value = field2.GetValue(val); Piece val3 = (Piece)((value is Piece) ? value : null); if ((Object)(object)val3 != (Object)null) { return val3; } } } catch (Exception ex) { if (DebugEnabled.Value && DebugGhostUpdate.Value) { Log.LogInfo((object)("[SELECTED] Nem sikerült kiolvasni az aktuális Piece-t: " + ex.Message)); } } return null; } internal static string GetPlantKey(GameObject placementGhost, Piece selectedPiece) { string text = (((Object)(object)selectedPiece != (Object)null && (Object)(object)((Component)selectedPiece).gameObject != (Object)null) ? CleanName(((Object)((Component)selectedPiece).gameObject).name) : string.Empty); string text2 = (((Object)(object)placementGhost != (Object)null) ? CleanName(((Object)placementGhost).name) : string.Empty); return text + "|" + text2; } internal static bool IsSmallPlantName(string name) { if (string.IsNullOrWhiteSpace(name)) { return false; } string text = name.ToLowerInvariant(); return text.Contains("carrot") || text.Contains("turnip") || text.Contains("onion") || text.Contains("barley") || text.Contains("flax") || text.Contains("jotunpuffs") || text.Contains("magecap"); } internal static bool IsTreePlantName(string name) { if (string.IsNullOrWhiteSpace(name)) { return false; } string text = name.ToLowerInvariant(); return text.Contains("beech") || text.Contains("birch") || text.Contains("fir") || text.Contains("pine") || text.Contains("oak") || text.Contains("yggdrasil"); } internal static float GetExplicitPlantSpacingByName(string name) { if (string.IsNullOrWhiteSpace(name)) { return 0f; } string name2 = name.ToLowerInvariant(); if (IsSmallPlantName(name2)) { return Mathf.Max(0.2f, MinimumSmallPlantSpacing.Value); } if (IsTreePlantName(name2)) { return Mathf.Max(1f, MinimumTreePlantSpacing.Value); } return 0f; } internal static float ReadPlantRequiredSpace(GameObject plantObject) { //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)plantObject == (Object)null) { return 0f; } float num = 0f; Plant componentInChildren = plantObject.GetComponentInChildren<Plant>(true); if ((Object)(object)componentInChildren != (Object)null) { FieldInfo[] fields = typeof(Plant).GetFields(AllInstance); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType != typeof(float)) { continue; } string text = fieldInfo.Name.ToLowerInvariant(); if (!text.Contains("radius") && !text.Contains("space") && !text.Contains("distance")) { continue; } try { float num2 = (float)fieldInfo.GetValue(componentInChildren); if (num2 > num && num2 >= 0.05f && num2 <= 20f) { num = num2; } } catch { } } } if (num <= 0f) { Collider[] componentsInChildren = plantObject.GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !val.isTrigger) { Bounds bounds = val.bounds; Vector3 size = ((Bounds)(ref bounds)).size; float num3 = Mathf.Max(size.x, size.z); if (num3 > num && num3 >= 0.05f && num3 <= 20f) { num = num3; } } } } return num; } internal static float GetSpacingForSelectedPlant(Player player, GameObject sourceGhost, Piece selectedPiece) { float num = Mathf.Max(0.2f, PlantSpacing.Value); if (!UseSelectedPlantRequiredSpace.Value) { return num; } GameObject val = (((Object)(object)selectedPiece != (Object)null) ? ((Component)selectedPiece).gameObject : null); string text = (((Object)(object)val != (Object)null) ? CleanName(((Object)val).name) : string.Empty); string text2 = (((Object)(object)sourceGhost != (Object)null) ? CleanName(((Object)sourceGhost).name) : string.Empty); string name = text + "|" + text2; float explicitPlantSpacingByName = GetExplicitPlantSpacingByName(name); if (explicitPlantSpacingByName > 0f) { if (DebugEnabled.Value && (DebugGhostUpdate.Value || DebugPlacement.Value)) { Log.LogInfo((object)("[SPACING] explicit selected=" + text + " | ghost=" + text2 + " | finalSpacing=" + explicitPlantSpacingByName.ToString("0.###"))); } return Mathf.Clamp(explicitPlantSpacingByName, 0.2f, 10f); } float num2 = ReadPlantRequiredSpace(val); float num3 = Mathf.Max(0.5f, PlantRequiredSpaceMultiplier.Value); float num4 = ((num2 > 0f) ? (num2 * num3) : num); num4 = Mathf.Max(num4, num); num4 = Mathf.Clamp(num4, 0.2f, 10f); if (DebugEnabled.Value && (DebugGhostUpdate.Value || DebugPlacement.Value)) { Log.LogInfo((object)("[SPACING] fallback selected=" + text + " | ghost=" + text2 + " | plantRequired=" + num2.ToString("0.###") + " | multiplier=" + num3.ToString("0.###") + " | finalSpacing=" + num4.ToString("0.###"))); } return num4; } internal static float SnapValue(float value, float step) { return Mathf.Round(value / step) * step; } internal static Vector3 ApplySnapping(Vector3 position) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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) if (!EnableSnapping.Value) { return position; } float step = Mathf.Max(0.05f, SnapStep.Value); return new Vector3(SnapValue(position.x, step), position.y, SnapValue(position.z, step)); } internal static bool IsValidPlantingGroundHit(RaycastHit hit) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((RaycastHit)(ref hit)).collider == (Object)null) { return false; } if (((RaycastHit)(ref hit)).normal.y < Mathf.Clamp(GroundNormalMinY.Value, 0.1f, 1f)) { if (DebugEnabled.Value && DebugShowPositionDetails.Value) { Log.LogInfo((object)("[GROUND] Elutasítva: túl meredek felület. collider=" + ((Object)((RaycastHit)(ref hit)).collider).name + " normalY=" + ((RaycastHit)(ref hit)).normal.y.ToString("0.###"))); } return false; } GameObject gameObject = ((Component)((RaycastHit)(ref hit)).collider).gameObject; string text = (((Object)(object)gameObject != (Object)null) ? (((Object)gameObject).name ?? string.Empty) : string.Empty); string text2 = text.ToLowerInvariant(); if ((Object)(object)((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<Heightmap>() != (Object)null) { return true; } if (text2.Contains("terrain") || text2.Contains("heightmap") || text2.Contains("ground")) { return true; } if (DebugEnabled.Value && DebugShowPositionDetails.Value) { Log.LogInfo((object)("[GROUND] Elutasítva: nem valódi talaj. collider=" + text + " layer=" + LayerMask.LayerToName(gameObject.layer))); } return false; } internal static bool TrySnapToGround(Vector3 position, out Vector3 snapped) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) snapped = position; if (!GroundSnapToTerrain.Value) { return true; } float num = Mathf.Max(1f, GroundSnapRayHeight.Value); Vector3 val = position + Vector3.up * num; float num2 = num * 2f + 20f; RaycastHit[] array = Physics.RaycastAll(new Ray(val, Vector3.down), num2, -1, (QueryTriggerInteraction)1); if (array == null || array.Length == 0) { if (DebugEnabled.Value && DebugShowPositionDetails.Value) { Log.LogInfo((object)("[GROUND] Nincs raycast találat: " + Vec(position))); } return !RequireRealGroundHit.Value; } Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); for (int i = 0; i < array.Length; i++) { RaycastHit hit = array[i]; if (IsValidPlantingGroundHit(hit)) { snapped = new Vector3(position.x, ((RaycastHit)(ref hit)).point.y, position.z); if (DebugEnabled.Value && DebugShowPositionDetails.Value) { Log.LogInfo((object)("[GROUND] valid hit=" + (((Object)(object)((RaycastHit)(ref hit)).collider != (Object)null) ? ((Object)((Component)((RaycastHit)(ref hit)).collider).gameObject).name : "null") + " | from=" + Vec(position) + " -> " + Vec(snapped))); } return true; } } if (DebugEnabled.Value && DebugShowPositionDetails.Value) { Log.LogInfo((object)("[GROUND] Nem talált valódi talajt ezen a ponton: " + Vec(position))); } return !RequireRealGroundHit.Value; } internal static Vector3 SnapToGround(Vector3 position) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!UseGroundRaySnap.Value) { return position; } if (TrySnapToGround(position, out var snapped)) { return snapped; } return position; } internal static List<int> BuildOffsetPattern(int count) { List<int> list = new List<int>(); int num = 1; while (list.Count < count) { list.Add(num); if (list.Count >= count) { break; } list.Add(-num); num++; } return list; } internal static bool IsIgnoredPlacementCollider(Collider hit) { if ((Object)(object)hit == (Object)null || (Object)(object)((Component)hit).gameObject == (Object)null) { return true; } string text = ((Object)((Component)hit).gameObject).name ?? string.Empty; if (text.Length == 0) { return true; } return text.IndexOf("cultivated", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("ghost", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("vfx", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("terrain", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("PlantingPreview", StringComparison.OrdinalIgnoreCase) >= 0; } internal static bool IsExistingPlantCollider(Collider hit) { if ((Object)(object)hit == (Object)null || (Object)(object)((Component)hit).gameObject == (Object)null) { return false; } GameObject gameObject = ((Component)hit).gameObject; string text = ((Object)gameObject).name ?? string.Empty; if (text.IndexOf("PlantingPreview", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } if (text.IndexOf("ghost", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } if (text.IndexOf("vfx", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } if (text.IndexOf("terrain", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } if ((Object)(object)((Component)hit).GetComponentInParent<Player>() != (Object)null) { return false; } if ((Object)(object)((Component)hit).GetComponentInParent<Plant>() != (Object)null) { return true; } if ((Object)(object)((Component)hit).GetComponentInParent<Pickable>() != (Object)null && (IsSmallPlantName(text) || IsTreePlantName(text) || IsPlantPlacement(gameObject))) { return true; } if (IsSmallPlantName(text) || IsTreePlantName(text) || IsPlantPlacement(gameObject)) { return true; } Transform root = gameObject.transform.root; if ((Object)(object)root != (Object)null) { string name = ((Object)((Component)root).gameObject).name ?? string.Empty; if (IsSmallPlantName(name) || IsTreePlantName(name) || IsPlantPlacement(((Component)root).gameObject)) { return true; } } return false; } internal static bool IsInsidePreviewRoot(Collider hit) { if ((Object)(object)hit == (Object)null) { return false; } Transform val = ((Component)hit).transform; while ((Object)(object)val != (Object)null) { string text = (((Object)(object)((Component)val).gameObject != (Object)null) ? (((Object)((Component)val).gameObject).name ?? string.Empty) : string.Empty); if (text.IndexOf("PlantingPreview", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } val = val.parent; } return false; } internal static bool ExistingPlantIsOutsideOnThisGridEdge(Vector3 candidatePosition, Vector3 plantPosition, Vector2Int cell, Vector3 right, Vector3 forward) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) Vector3 val = plantPosition - candidatePosition; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { return true; } bool flag = false; bool flag2 = false; if (((Vector2Int)(ref cell)).x > 0) { flag = true; flag2 |= Vector3.Dot(val, right) > 0.05f; } else if (((Vector2Int)(ref cell)).x < 0) { flag = true; flag2 |= Vector3.Dot(val, right) < -0.05f; } if (((Vector2Int)(ref cell)).y > 0) { flag = true; flag2 |= Vector3.Dot(val, forward) > 0.05f; } else if (((Vector2Int)(ref cell)).y < 0) { flag = true; flag2 |= Vector3.Dot(val, forward) < -0.05f; } return !flag || flag2; } internal static bool IsNearbyObjectBlockingPlantGrowth(Collider hit) { if ((Object)(object)hit == (Object)null || (Object)(object)((Component)hit).gameObject == (Object)null) { return false; } if (IsInsidePreviewRoot(hit)) { return false; } if (IsIgnoredPlacementCollider(hit)) { return false; } if (IsExistingPlantCollider(hit)) { return false; } if ((Object)(object)((Component)hit).GetComponentInParent<Player>() != (Object)null) { return false; } if ((Object)(object)((Component)hit).GetComponentInParent<Character>() != (Object)null) { return false; } if ((Object)(object)((Component)hit).GetComponentInParent<ItemDrop>() != (Object)null) { return false; } GameObject gameObject = ((Component)hit).gameObject; string text = ((Object)gameObject).name ?? string.Empty; string text2 = text.ToLowerInvariant(); if (text2.Contains("heightmap") || text2.Contains("terrain") || text2.Contains("ground")) { return false; } if (text2.Contains("water")) { return false; } if (text2.Contains("leviathan")) { return false; } if ((Object)(object)((Component)hit).GetComponentInParent<Piece>() != (Object)null) { return true; } if ((Object)(object)((Component)hit).GetComponentInParent<WearNTear>() != (Object)null) { return true; } if ((Object)(object)((Component)hit).GetComponentInParent<StaticPhysics>() != (Object)null) { return true; } if ((Object)(object)((Component)hit).GetComponentInParent<Container>() != (Object)null) { return true; } if ((Object)(object)((Component)hit).GetComponentInParent<Door>() != (Object)null) { return true; } if ((Object)(object)((Component)hit).GetComponentInParent<ZNetView>() != (Object)null) { return true; } return true; } internal static bool HasNearbyObjectTooCloseForGrowth(Vector3 position, float spacing) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) if (!CheckNearbyObjectsForGrowthSpace.Value) { return false; } float num = Mathf.Clamp(spacing * Mathf.Clamp(NearbyObjectCheckMultiplier.Value, 0.1f, 2f), 0.1f, 10f); Collider[] array = Physics.OverlapSphere(position, num, -1, (QueryTriggerInteraction)1); foreach (Collider val in array) { if (IsNearbyObjectBlockingPlantGrowth(val)) { if (DebugEnabled.Value && DebugCollisionCheck.Value) { string text = (((Object)(object)((Component)val).gameObject != (Object)null) ? ((Object)((Component)val).gameObject).name : "null"); Log.LogInfo((object)("[OBJECT BLOCK] Tereptárgy/építmény túl közel a növekedési helyhez. pos=" + Vec(position) + " radius=" + num.ToString("0.###") + " hit=" + text)); } return true; } } return false; } internal static bool HasExistingPlantTooClose(Vector3 position, float spacing) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) return HasExistingPlantTooCloseOnGridEdge(position, spacing, Vector2Int.zero, Vector3.right, Vector3.forward, useEdgeDirection: false); } internal static bool HasExistingPlantTooCloseOnGridEdge(Vector3 position, float spacing, Vector2Int cell, Vector3 right, Vector3 forward, bool useEdgeDirection) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) if (!CheckExistingPlants.Value) { return false; } float num = Mathf.Clamp(spacing * Mathf.Clamp(ExistingPlantCheckMultiplier.Value, 0.2f, 2f), 0.2f, 10f); Collider[] array = Physics.OverlapSphere(position, num, -1, (QueryTriggerInteraction)1); foreach (Collider val in array) { if (IsInsidePreviewRoot(val) || !IsExistingPlantCollider(val)) { continue; } Vector3 plantPosition = (((Object)(object)((Component)val).transform != (Object)null) ? ((Component)val).transform.position : position); Vector2Int val2; if (useEdgeDirection && !ExistingPlantIsOutsideOnThisGridEdge(position, plantPosition, cell, right, forward)) { if (DebugEnabled.Value && DebugCollisionCheck.Value) { string text = (((Object)(object)((Component)val).gameObject != (Object)null) ? ((Object)((Component)val).gameObject).name : "null"); ManualLogSource log = Log; string[] obj = new string[6] { "[PLANT EDGE IGNORE] Meglévő növény közel van, de nem ezen a rács-szélen. cell=", null, null, null, null, null }; val2 = cell; obj[1] = ((object)(Vector2Int)(ref val2)).ToString(); obj[2] = " pos="; obj[3] = Vec(position); obj[4] = " hit="; obj[5] = text; log.LogInfo((object)string.Concat(obj)); } continue; } if (DebugEnabled.Value && DebugCollisionCheck.Value) { string text2 = (((Object)(object)((Component)val).gameObject != (Object)null) ? ((Object)((Component)val).gameObject).name : "null"); ManualLogSource log2 = Log; string[] obj2 = new string[8] { "[PLANT BLOCK] Meglévő növény túl közel a rács szélén. cell=", null, null, null, null, null, null, null }; val2 = cell; obj2[1] = ((object)(Vector2Int)(ref val2)).ToString(); obj2[2] = " pos="; obj2[3] = Vec(position); obj2[4] = " radius="; obj2[5] = num.ToString("0.###"); obj2[6] = " hit="; obj2[7] = text2; log2.LogInfo((object)string.Concat(obj2)); } return true; } return false; } internal static bool CanPlaceAt(Vector3 position, float spacing) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) return CanPlaceAt(position, spacing, Vector2Int.zero, Vector3.right, Vector3.forward, useEdgeDirection: false); } internal static bool CanPlaceAt(Vector3 position, float spacing, Vector2Int cell, Vector3 right, Vector3 forward, bool useEdgeDirection) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) if (!ExtraPlacementRequiresFreeSpace.Value) { if (DebugEnabled.Value && DebugCollisionCheck.Value) { Log.LogInfo((object)("[COLLISION] Ellenőrzés kikapcsolva. Pozíció automatikusan elfogadva: " + Vec(position))); } return true; } if (HasExistingPlantTooCloseOnGridEdge(position, spacing, cell, right, forward, useEdgeDirection)) { if (DebugEnabled.Value && DebugCollisionCheck.Value) { Log.LogInfo((object)("[COLLISION] Eredmény pozíción " + Vec(position) + " -> blocked=true, reason=existing plant edge")); } return false; } if (HasNearbyObjectTooCloseForGrowth(position, spacing)) { if (DebugEnabled.Value && DebugCollisionCheck.Value) { Log.LogInfo((object)("[COLLISION] Eredmény pozíción " + Vec(position) + " -> blocked=true, reason=nearby object growth space")); } return false; } Collider[] array = Physics.OverlapSphere(position, 0.18f, -1, (QueryTriggerInteraction)1); bool flag = false; foreach (Collider val in array) { if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null) { continue; } string text = ((Object)((Component)val).gameObject).name ?? string.Empty; if (text.Length != 0) { bool flag2 = IsIgnoredPlacementCollider(val); if (DebugEnabled.Value && DebugCollisionCheck.Value) { Log.LogInfo((object)("[COLLISION] Hit: " + text + " | ignore=" + flag2 + " | pos=" + Vec(position))); } if (!flag2) { flag = true; } } } if (DebugEnabled.Value && DebugCollisionCheck.Value) { Log.LogInfo((object)("[COLLISION] Eredmény pozíción " + Vec(position) + " -> blocked=" + flag)); } return !flag; } internal static bool CanPreviewPlaceAt(Vector3 position, float spacing) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) return CanPreviewPlaceAt(position, spacing, Vector2Int.zero, Vector3.right, Vector3.forward, useEdgeDirection: false); } internal static bool CanPreviewPlaceAt(Vector3 position, float spacing, Vector2Int cell, Vector3 right, Vector3 forward, bool useEdgeDirection) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (!ExtraPlacementRequiresFreeSpace.Value) { return true; } if (HasExistingPlantTooCloseOnGridEdge(position, spacing, cell, right, forward, useEdgeDirection)) { return false; } if (HasNearbyObjectTooCloseForGrowth(position, spacing)) { return false; } Collider[] array = Physics.OverlapSphere(position, 0.18f, -1, (QueryTriggerInteraction)1); foreach (Collider val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null) && !IsIgnoredPlacementCollider(val)) { return false; } } return true; } internal static Quaternion GetPreviewRotation(GameObject sourceGhost) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0045: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (_hasStickyRotation) { _lastGoodPreviewRotation = _stickyRotation; _hasLastGoodPreviewRotation = true; return _stickyRotation; } if ((Object)(object)sourceGhost != (Object)null) { Quaternion rotation = sourceGhost.transform.rotation; Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles; if (rotation != Quaternion.identity || eulerAngles.y > 0.01f) { _lastGoodPreviewRotation = rotation; _hasLastGoodPreviewRotation = true; return rotation; } } if (_hasLastGoodPreviewRotation) { return _lastGoodPreviewRotation; } return Quaternion.identity; } internal static int LimitExtraCountByResources(Player player, Piece piece, int requestedExtra, bool reserveVanillaCenterCost) { if (requestedExtra <= 0) { return 0; } if ((Object)(object)player == (Object)null || (Object)(object)piece == (Object)null || piece.m_resources == null || piece.m_resources.Length == 0) { return requestedExtra; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return 0; } int num = requestedExtra; for (int i = 0; i < piece.m_resources.Length; i++) { Requirement val = piece.m_resources[i]; if (val != null && !((Object)(object)val.m_resItem == (Object)null) && val.m_amount > 0) { string name = val.m_resItem.m_itemData.m_shared.m_name; int num2 = inventory.CountItems(name, -1, true); if (reserveVanillaCenterCost) { num2 -= val.m_amount; } int num3 = Mathf.Max(0, num2) / val.m_amount; num = Mathf.Min(num, num3); } } return Mathf.Clamp(num, 0, requestedExtra); } internal static List<Vector3> CalculateExtraPositions(Player player, GameObject sourceGhost, Piece selectedPiece) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Unknown result type (might be due to invalid IL or missing references) //IL_044e: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Unknown result type (might be due to invalid IL or missing references) CachedExtraPositions.Clear(); CachedExtraCells.Clear(); if ((Object)(object)player == (Object)null || (Object)(object)sourceGhost == (Object)null) { LogGhost("CalculateExtraPositions megszakítva: player vagy sourceGhost null."); return CachedExtraPositions; } int extraPlantCount = GetExtraPlantCount(player); extraPlantCount = LimitExtraCountByResources(player, selectedPiece, extraPlantCount, reserveVanillaCenterCost: true); if (extraPlantCount <= 0) { LogGhost("CalculateExtraPositions: extraCount <= 0, nincs extra pozíció."); return CachedExtraPositions; } float spacingForSelectedPlant = GetSpacingForSelectedPlant(player, sourceGhost, selectedPiece); Vector3 position = sourceGhost.transform.position; Quaternion previewRotation = GetPreviewRotation(sourceGhost); Vector3 val = previewRotation * Vector3.right; Vector3 val2 = previewRotation * Vector3.forward; val.y = 0f; val2.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.right; } if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = Vector3.forward; } ((Vector3)(ref val)).Normalize(); ((Vector3)(ref val2)).Normalize(); List<Vector3> list = new List<Vector3>(); List<Vector2Int> list2 = new List<Vector2Int>(); if (UseSquarePattern.Value) { List<Vector2Int> list3 = new List<Vector2Int> { new Vector2Int(1, 1), new Vector2Int(-1, 1), new Vector2Int(1, -1), new Vector2Int(-1, -1), new Vector2Int(1, 0), new Vector2Int(-1, 0), new Vector2Int(0, 1), new Vector2Int(0, -1), new Vector2Int(2, 2), new Vector2Int(-2, 2), new Vector2Int(2, -2), new Vector2Int(-2, -2), new Vector2Int(2, 0), new Vector2Int(-2, 0), new Vector2Int(0, 2), new Vector2Int(0, -2) }; for (int i = 0; i < extraPlantCount && i < list3.Count; i++) { Vector2Int item = list3[i]; list.Add((val * (float)((Vector2Int)(ref item)).x + val2 * (float)((Vector2Int)(ref item)).y) * spacingForSelectedPlant); list2.Add(item); } } else { Vector3 val3; if (!SnapUseGhostRight.Value) { Vector3 right = ((Component)player).transform.right; val3 = ((Vector3)(ref right)).normalized; } else { val3 = val; } Vector3 val4 = val3; List<int> list4 = BuildOffsetPattern(extraPlantCount); for (int j = 0; j < list4.Count; j++) { list.Add(val4 * ((float)list4[j] * spacingForSelectedPlant)); list2.Add(new Vector2Int(list4[j], 0)); } } if (DebugEnabled.Value && DebugShowPositionDetails.Value) { Log.LogInfo((object)("[POS] origin=" + Vec(position) + " spacing=" + spacingForSelectedPlant + " extraCount=" + extraPlantCount + " square=" + UseSquarePattern.Value)); } for (int k = 0; k < list.Count; k++) { Vector3 val5 = position + list[k]; Vector3 val6 = val5; bool flag = false; if (TrySnapToGround(val5, out var snapped)) { val6 = snapped; flag = true; Vector3 val7 = val6; CachedExtraPositions.Add(val7); if (k < list2.Count) { CachedExtraCells.Add(list2[k]); } else { CachedExtraCells.Add(Vector2Int.zero); } if (DebugEnabled.Value && DebugShowPositionDetails.Value) { Log.LogInfo((object)("[POS] idx=" + k + " raw=" + Vec(val5) + " terrainHit=" + flag + " final=" + Vec(val7))); } } else if (DebugEnabled.Value && DebugShowPositionDetails.Value) { Log.LogInfo((object)("[POS] idx=" + k + " kihagyva, mert nincs valódi talaj. raw=" + Vec(val5))); } } return CachedExtraPositions; } internal static GameObject GetBestPreviewVisualSource(Player player, GameObject sourceGhost) { if ((Object)(object)player == (Object)null) { return null; } GameObject placementGhost = GetPlacementGhost(player); if ((Object)(object)placementGhost == (Object)null) { LogGhost("Preview visual source: placementGhost null."); return null; } string text = CleanName(((Object)placementGhost).name); if (text.Equals("cultivate_v2", StringComparison.OrdinalIgnoreCase)) { if ((Object)(object)_lastPlacedPrefabVisualSource != (Object)null) { LogGhost("Preview visual source fallback: utolsó lerakott prefab: " + _lastPlacedPrefabName); return _lastPlacedPrefabVisualSource; } LogGhost("Preview visual source: cultivate_v2 -> nincs még lerakott prefab, skip."); return null; } LogGhost("Preview visual source: placementGhost használva: " + text); return placementGhost; } internal static bool CopyVisualChildrenOnly(GameObject source, GameObject targetRoot) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null || (Object)(object)targetRoot == (Object)null) { return false; } bool result = false; Renderer[] componentsInChildren = source.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null)) { GameObject gameObject = ((Component)val).gameObject; GameObject val2; try { val2 = Object.Instantiate<GameObject>(gameObject); } catch (Exception ex) { Log.LogWarning((object)("[GHOST] Renderer child klónozás hiba: " + ex)); continue; } ((Object)val2).name = "PreviewVisual_" + ((Object)gameObject).name; val2.transform.SetParent(targetRoot.transform, false); Transform transform = gameObject.transform; val2.transform.localPosition = source.transform.InverseTransformPoint(transform.position); val2.transform.localRotation = Quaternion.Inverse(source.transform.rotation) * transform.rotation; val2.transform.localScale = transform.lossyScale; StripNonVisualComponents(val2); Renderer[] componentsInChildren2 = val2.GetComponentsInChildren<Renderer>(true); if (componentsInChildren2.Length != 0) { result = true; } else { Object.Destroy((Object)(object)val2); } } } return result; } internal static void StripNonVisualComponents(GameObject go) { if ((Object)(object)go == (Object)null) { return; } MonoBehaviour[] componentsInChildren = go.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } Collider[] componentsInChildren2 = go.GetComponentsInChildren<Collider>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { Object.Destroy((Object)(object)componentsInChildren2[j]); } Rigidbody[] componentsInChildren3 = go.GetComponentsInChildren<Rigidbody>(true); for (int k = 0; k < componentsInChildren3.Length; k++) { Object.Destroy((Object)(object)componentsInChildren3[k]); } Joint[] componentsInChildren4 = go.GetComponentsInChildren<Joint>(true); for (int l = 0; l < componentsInChildren4.Length; l++) { Object.Destroy((Object)(object)componentsInChildren4[l]); } ZNetView[] componentsInChildren5 = go.GetComponentsInChildren<ZNetView>(true); for (int m = 0; m < componentsInChildren5.Length; m++) { Object.Destroy((Object)(object)componentsInChildren5[m]); } ZSyncTransform[] componentsInChildren6 = go.GetComponentsInChildren<ZSyncTransform>(true); for (int n = 0; n < componentsInChildren6.Length; n++) { Object.Destroy((Object)(object)componentsInChildren6[n]); } Piece[] componentsInChildren7 = go.GetComponentsInChildren<Piece>(true); for (int num = 0; num < componentsInChildren7.Length; num++) { Object.Destroy((Object)(object)componentsInChildren7[num]); } WearNTear[] componentsInChildren8 = go.GetComponentsInChildren<WearNTear>(true); for (int num2 = 0; num2 < componentsInChildren8.Length; num2++) { Object.Destroy((Object)(object)componentsInChildren8[num2]); } TerrainModifier[] componentsInChildren9 = go.GetComponentsInChildren<TerrainModifier>(true); for (int num3 = 0; num3 < componentsInChildren9.Length; num3++) { Object.Destroy((Object)(object)componentsInChildren9[num3]); } Plant[] componentsInChildren10 = go.GetComponentsInChildren<Plant>(true); for (int num4 = 0; num4 < componentsInChildren10.Length; num4++) { Object.Destroy((Object)(object)componentsInChildren10[num4]); } Pickable[] componentsInChildren11 = go.GetComponentsInChildren<Pickable>(true); for (int num5 = 0; num5 < componentsInChildren11.Length; num5++) { Object.Destroy((Object)(object)componentsInChildren11[num5]); } } internal static void PreparePreviewVisuals(GameObject go) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0133: 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_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)go == (Object)null) { return; } Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true); Color val4 = default(Color); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } val.enabled = true; val.shadowCastingMode = (ShadowCastingMode)0; val.receiveShadows = false; Material[] sharedMaterials = val.sharedMaterials; Material[] array = (Material[])(object)new Material[sharedMaterials.Length]; for (int j = 0; j < sharedMaterials.Length; j++) { Material val2 = sharedMaterials[j]; if ((Object)(object)val2 == (Object)null) { array[j] = null; continue; } Material val3; try { val3 = new Material(val2); } catch { array[j] = val2; continue; } try { ((Color)(ref val4))..ctor(0.35f, 1f, 0.35f, 0.65f); if (val3.HasProperty("_Color")) { Color color = val3.color; color.r *= val4.r; color.g *= val4.g; color.b *= val4.b; color.a = Mathf.Min(color.a, val4.a); val3.color = color; } if (val3.HasProperty("_BaseColor")) { Color color2 = val3.GetColor("_BaseColor"); color2.r *= val4.r; color2.g *= val4.g; color2.b *= val4.b; color2.a = Mathf.Min(color2.a, val4.a); val3.SetColor("_BaseColor", color2); } if (val3.HasProperty("_EmissionColor")) { val3.EnableKeyword("_EMISSION"); val3.SetColor("_EmissionColor", new Color(0.08f, 0.35f, 0.08f, 1f)); } if (val3.HasProperty("_ZWrite")) { val3.SetInt("_ZWrite", 0); } val3.renderQueue = 3000; } catch (Exception ex) { Log.LogWarning((object)("[GHOST] Preview material finomítás hiba: " + ex)); } array[j] = val3; } val.materials = array; } } internal static void SetPreviewValidState(GameObject go, bool valid) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)go == (Object)null) { return; } Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Material[] materials = val.materials; foreach (Material val2 in materials) { if ((Object)(object)val2 == (Object)null) { continue; } Color val3 = (valid ? new Color(0.35f, 1f, 0.35f, 0.65f) : new Color(1f, 0.25f, 0.25f, 0.65f)); try { if (val2.HasProperty("_Color")) { Color color = val2.color; color.r = val3.r; color.g = val3.g; color.b = val3.b; color.a = val3.a; val2.color = color; } if (val2.HasProperty("_BaseColor")) { val2.SetColor("_BaseColor", val3); } if (val2.HasProperty("_EmissionColor")) { val2.EnableKeyword("_EMISSION"); val2.SetColor("_EmissionColor", valid ? new Color(0.08f, 0.35f, 0.08f, 1f) : new Color(0.35f, 0.05f, 0.05f, 1f)); } } catch (Exception ex) { Log.LogWarning((object)("[GHOST] SetPreviewValidState hiba: " + ex)); } } } } internal static GameObject CreatePreviewGhost(Player player, GameObject sourceGhost) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown GameObject bestPreviewVisualSource = GetBestPreviewVisualSource(player, sourceGhost); if ((Object)(object)bestPreviewVisualSource == (Object)null) { return null; } GameObject val = new GameObject("PlantingPreview_" + CleanName(((Object)bestPreviewVisualSource).name)); val.SetActive(false); if (!CopyVisualChildrenOnly(bestPreviewVisualSource, val)) { Object.Destroy((Object)(object)val); Log.LogWarning((object)"[GHOST] Nem sikerült vizuális elemet másolni a preview ghosthoz."); return null; } PreparePreviewVisuals(val); int num = val.GetComponentsInChildren<Renderer>(true).Length; LogGhost("Vizuális preview ghost létrehozva: " + ((Object)val).name + " | source=" + CleanName(((Object)bestPreviewVisualSource).name) + " | renderers=" + num); return val; } internal static void EnsurePreviewGhostCount(int count, Player player, GameObject sourceGhost) { while (PreviewGhosts.Count < count) { GameObject val = CreatePreviewGhost(player, sourceGhost); if ((Object)(object)val == (Object)null) { break; } PreviewGhosts.Add(val); } while (PreviewGhosts.Count > count) { int index = PreviewGhosts.Count - 1; if ((Object)(object)PreviewGhosts[index] != (Object)null) { Object.Destroy((Object)(object)PreviewGhosts[index]); } PreviewGhosts.RemoveAt(index); } } internal static void DestroyPreviewGhosts() { //IL_005c: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < PreviewGhosts.Count; i++) { if ((Object)(object)PreviewGhosts[i] != (Object)null) { Object.Destroy((Object)(object)PreviewGhosts[i]); } } PreviewGhosts.Clear(); CachedExtraPositions.Clear(); _hasStickyRotation = false; _stickyRotation = Quaternion.identity; _lastGoodPreviewRotation = Quaternion.identity; _hasLastGoodPreviewRotation = false; LogGhost("Minden preview ghost törölve."); } internal static void HidePreviewGhosts() { for (int i = 0; i < PreviewGhosts.Count; i++) { if ((Object)(object)PreviewGhosts[i] != (Object)null) { PreviewGhosts[i].SetActive(false); } } if (_lastPreviewVisible) { LogGhost("Preview ghostok elrejtve."); } _lastPreviewVisible = false; _hasStickyRotation = false; } internal static void UpdatePreviewGhosts(Player player) { //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_04d2: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) if (!Enabled.Value || !PreviewExtraPlants.Value) { HidePreviewGhosts(); return; } if ((Object)(object)player == (Object)null) { HidePreviewGhosts(); return; } if (OnlyLocalPreview.Value && (Object)(object)player != (Object)(object)Player.m_localPlayer) { HidePreviewGhosts(); return; } GameObject placementGhost = GetPlacementGhost(player); if ((Object)(object)placementGhost == (Object)null) { HidePreviewGhosts(); return; } string text = CleanName(((Object)placementGhost).name); if (text.StartsWith("HH_", StringComparison.OrdinalIgnoreCase)) { HidePreviewGhosts(); return; } int extraPlantCount = GetExtraPlantCount(player); bool flag = HasCultivatorEquipped(player, placementGhost); Piece selectedPieceSafe = GetSelectedPieceSafe(player); GameObject val = (((Object)(object)selectedPieceSafe != (Object)null) ? ((Component)selectedPieceSafe).gameObject : null); bool flag2 = IsPlantPlacement(placementGhost) || IsPlantPlacement(val); bool flag3 = (IsPlantableGhost(placementGhost) || IsPlantableGhost(val)) && flag2; bool flag4 = flag3 && flag && extraPlantCount > 0; if (DebugEnabled.Value && DebugGhostUpdate.Value && (text != _lastGhostName || extraPlantCount != _lastExtraCount || flag4 != _lastPreviewVisible)) { Log.LogInfo((object)("[GHOST] Állapotváltás | ghost=" + text + " | cultivator=" + flag + " | plantPlacement=" + flag2 + " | plantable=" + flag3 + " | extraCount=" + extraPlantCount + " | shouldShow=" + flag4)); _lastGhostName = text; _lastExtraCount = extraPlantCount; } if (!flag4) { HidePreviewGhosts(); return; } Piece selectedPiece = selectedPieceSafe; string plantKey = GetPlantKey(placementGhost, selectedPiece); if (plantKey != _lastSelectedPlantKey) { LogGhost("Kiválasztott növény változott: " + _lastSelectedPlantKey + " -> " + plantKey + ". Preview újraépítés."); DestroyPreviewGhosts(); _lastSelectedPlantKey = plantKey; } List<Vector3> list = CalculateExtraPositions(player, placementGhost, selectedPiece); EnsurePreviewGhostCount(list.Count, player, placementGhost); Quaternion previewRotation = GetPreviewRotation(placementGhost); float spacingForSelectedPlant = GetSpacingForSelectedPlant(player, placementGhost, selectedPiece); if (_hasStickyRotation) { try { placementGhost.transform.rotation = previewRotation; } catch { } } Vector3 right = previewRotation * Vector3.right; Vector3 forward = previewRotation * Vector3.forward; right.y = 0f; forward.y = 0f; if (((Vector3)(ref right)).sqrMagnitude < 0.0001f) { right = Vector3.right; } if (((Vector3)(ref forward)).sqrMagnitude < 0.0001f) { forward = Vector3.forward; } ((Vector3)(ref right)).Normalize(); ((Vector3)(ref forward)).Normalize(); for (int i = 0; i < PreviewGhosts.Count; i++) { GameObject val2 = PreviewGhosts[i]; if ((Object)(object)val2 == (Object)null) { continue; } if (i >= list.Count) { val2.SetActive(false); continue; } Vector2Int cell = ((i < CachedExtraCells.Count) ? CachedExtraCells[i] : Vector2Int.zero); bool valid = CanPreviewPlaceAt(list[i], spacingForSelectedPlant, cell, right, forward, useEdgeDirection: true); Vector3 val3 = list[i] + Vector3.up * 0.08f; val2.transform.SetPositionAndRotation(val3, previewRotation); SetPreviewValidState(val2, valid); if (!val2.activeSelf) { val2.SetActive(true); } if (!DebugEnabled.Value || !DebugGhostUpdate.Value || !DebugShowPositionDetails.Value) { continue; } Renderer[] componentsInChildren = val2.GetComponentsInChildren<Renderer>(true); int num = 0; for (int j = 0; j < componentsInChildren.Length; j++) { if ((Object)(object)componentsInChildren[j] != (Object)null && componentsInChildren[j].enabled) { num++; } } Log.LogInfo((object)("[GHOST] Preview[" + i + "] -> " + Vec(list[i]) + " | valid=" + valid + " | renderers=" + componentsInChildren.Length + " | enabled=" + num + " | activeSelf=" + val2.activeSelf)); } _lastPreviewVisible = true; } internal static void PlaceExtraPlants(Player player, Piece piece, Quaternion rot) { //IL_04c7: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)piece == (Object)null) { LogPlacement("PlaceExtraPlants megszakítva: player vagy piece null."); return; } if (!Enabled.Value) { LogPlacement("PlaceExtraPlants megszakítva: mod kikapcsolva."); return; } GameObject placementGhost = GetPlacementGhost(player); if ((Object)(object)placementGhost == (Object)null) { LogPlacement("PlaceExtraPlants megszakítva: nincs aktív placement ghost."); return; } if (!HasCultivatorEquipped(player, placementGhost)) { LogPlacement("PlaceExtraPlants megszakítva: nincs Cultivator."); return; } GameObject gameObject = ((Component)piece).gameObject; bool flag = IsPlantableGhost(placementGhost) && IsPlantPlacement(placementGhost); bool flag2 = (Object)(object)gameObject != (Object)null && IsPlantableGhost(gameObject) && IsPlantPlacement(gameObject); if (!flag && !flag2) { LogPlacement("PlaceExtraPlants megszakítva: sem a placement ghost, sem a selected piece nem támogatott növény. ghost=" + CleanName(((Object)placementGhost).name) + " piece=" + (((Object)(object)gameObject != (Object)null) ? CleanName(((Object)gameObject).name) : "null")); return; } if ((Object)(object)gameObject == (Object)null) { LogPlacement("PlaceExtraPlants megszakítva: piece.gameObject null."); return; } CalculateExtraPositions(player, placementGhost, piece); float spacingForSelectedPlant = GetSpacingForSelectedPlant(player, placementGhost, piece); if (CachedExtraPositions.Count <= 0) { LogPlacement("PlaceExtraPlants megszakítva: nincs extra pozíció újraszámolás után."); return; } _lastPlacedPrefabVisualSource = gameObject; _lastPlacedPrefabName = CleanName(((Object)gameObject).name); _stickyRotation = rot; _hasStickyRotation = true; _lastGoodPreviewRotation = rot; _hasLastGoodPreviewRotation = true; LogPlacement("Extra lerakás indul. piece=" + CleanName(((Object)gameObject).name) + " cachedPositions=" + CachedExtraPositions.Count + " | rotY=" + ((Quaternion)(ref rot)).eulerAngles.y.ToString("0.0")); Vector3 right = rot * Vector3.right; Vector3 forward = rot * Vector3.forward; right.y = 0f; forward.y = 0f; if (((Vector3)(ref right)).sqrMagnitude < 0.0001f) { right = Vector3.right; } if (((Vector3)(ref forward)).sqrMagnitude < 0.0001f) { forward = Vector3.forward; } ((Vector3)(ref right)).Normalize(); ((Vector3)(ref forward)).Normalize(); int num = 0; int num2 = 0; int num3 = LimitExtraCountByResources(player, piece, CachedExtraPositions.Count, reserveVanillaCenterCost: false); for (int i = 0; i < CachedExtraPositions.Count; i++) { if (num >= num3) { LogPlacement("Extra lerakás megállítva mag limit miatt. placed=" + num + " max=" + num3); break; } Vector3 val = CachedExtraPositions[i]; Vector2Int cell = ((i < CachedExtraCells.Count) ? CachedExtraCells[i] : Vector2Int.zero); if (!CanPlaceAt(val, spacingForSelectedPlant, cell, right, forward, useEdgeDirection: true)) { num2++; LogPla