using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using EinjarheimProfessions; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Profesiones")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Profesiones")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("50CF68F9-AA2B-4F41-B995-4C2EB29C4A19")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [HarmonyPatch(typeof(WearNTear), "GetMaterialProperties")] internal static class Construction_Patch_GetMaterialProperties { private static void Postfix(WearNTear __instance, ref float maxSupport, ref float minSupport, ref float horizontalLoss, ref float verticalLoss) { try { if (!((Object)(object)__instance.m_nview != (Object)null) || !__instance.m_nview.IsValid()) { return; } ZDO zDO = __instance.m_nview.GetZDO(); if (zDO == null) { return; } float num = zDO.GetFloat("nazhi_construction_maxsupport", 0f); if (num > 0f) { float num2 = minSupport / maxSupport; maxSupport = num; minSupport = num * num2; float num3 = zDO.GetFloat("nazhi_construction_maxsupport_vloss", 0f); float num4 = zDO.GetFloat("nazhi_construction_maxsupport_hloss", 0f); if (num3 > 0f) { verticalLoss = num3; } if (num4 > 0f) { horizontalLoss = num4; } } } catch (Exception arg) { EinjarheimProfessionsPlugin.Log.LogError((object)$"[Construction] Error GetMaterialProperties: {arg}"); } } } namespace EinjarheimProfessions; [BepInPlugin("nazhi.einjarheim.professions", "Einjarheim Professions", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("valheim.exe")] public class EinjarheimProfessionsPlugin : BaseUnityPlugin { public const string PluginGuid = "nazhi.einjarheim.professions"; public const string PluginName = "Einjarheim Professions"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; internal static ConfigEntry ConstructionSupportPerLevel; internal const string ZdoKeyMaxSupport = "nazhi_construction_maxsupport"; internal static SE_Stats ChefRegenHP; internal static SE_Stats ChefRegenStamina; internal static SE_Stats ChefRegenEitr; private Harmony _harmony; internal static EinjarheimProfessionsPlugin Instance { get; private set; } private void Awake() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"[Einjarheim Professions] v1.0.0 – iniciando..."); BindConfigs(); InitChefSEs(); BlacksmithingSystem.RegisterSkill(); AlchemySystem.RegisterSkill(); SpecializationSystem.RegisterCommand(); _harmony = new Harmony("nazhi.einjarheim.professions"); _harmony.PatchAll(); Log.LogInfo((object)"[Einjarheim Professions] Profesiones cargadas:"); Log.LogInfo((object)"[Einjarheim Professions] · Cooking – bonus HP/Stamina/Eitr según nivel de cocina del chef"); Log.LogInfo((object)"[Einjarheim Professions] · Blacksmithing – durabilidad, daño y armadura según nivel de herrería"); Log.LogInfo((object)"[Einjarheim Professions] · Construction – HP de estructuras y descuento de recursos según Crafting"); Log.LogInfo((object)"[Einjarheim Professions] · Alchemy – potencia, duración y fermentación según nivel de alquimia"); Log.LogInfo((object)"[Einjarheim Professions] · Comando /masterizar disponible"); Log.LogInfo((object)string.Format("[{0}] · Construction SupportPerLevel={1}", "Einjarheim Professions", ConstructionSupportPerLevel.Value)); } private static void InitChefSEs() { ChefRegenHP = ScriptableObject.CreateInstance(); ((Object)ChefRegenHP).name = "nazhi_chef_regen_hp"; ((StatusEffect)ChefRegenHP).m_name = "Sazón del Chef (HP)"; ((StatusEffect)ChefRegenHP).m_tooltip = "Comida maestra: regeneración de HP aumentada"; ChefRegenHP.m_healthRegenMultiplier = 1.3f; ((StatusEffect)ChefRegenHP).m_startMessage = "Sazón del Chef activo (HP)"; ChefRegenStamina = ScriptableObject.CreateInstance(); ((Object)ChefRegenStamina).name = "nazhi_chef_regen_stamina"; ((StatusEffect)ChefRegenStamina).m_name = "Sazón del Chef (Stamina)"; ((StatusEffect)ChefRegenStamina).m_tooltip = "Comida maestra: regeneración de Stamina aumentada"; ChefRegenStamina.m_staminaRegenMultiplier = 1.2f; ((StatusEffect)ChefRegenStamina).m_startMessage = "Sazón del Chef activo (Stamina)"; ChefRegenEitr = ScriptableObject.CreateInstance(); ((Object)ChefRegenEitr).name = "nazhi_chef_regen_eitr"; ((StatusEffect)ChefRegenEitr).m_name = "Sazón del Chef (Eitr)"; ((StatusEffect)ChefRegenEitr).m_tooltip = "Comida maestra: regeneración de Eitr aumentada"; ChefRegenEitr.m_eitrRegenMultiplier = 1.2f; ((StatusEffect)ChefRegenEitr).m_startMessage = "Sazón del Chef activo (Eitr)"; Log.LogInfo((object)"[Cooking] SE de Chef maestro inicializados (x10 testing)"); } private void BindConfigs() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown ConstructionSupportPerLevel = ((BaseUnityPlugin)this).Config.Bind("Construction", "SupportPerLevel", 0.5f, new ConfigDescription("Buff de estabilidad cada 10 niveles de Crafting (escalonado). El techo de soporte se multiplica por (1 + tier * valor) donde tier = nivel/10. Las losses se dividen por (1 + tier * valor*0.5). Ej: 0.25 → lv10 +25% soporte (~2 bloques extra en Wood). Para producción usar ~0.25.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 2f), Array.Empty())); } private void OnDestroy() { ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"[Einjarheim Professions] OnDestroy – deshaciendo patches."); } Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } public enum ProfessionType { None, Cooking, Blacksmithing, Construction, Alchemy } internal static class SpecializationSystem { private const string ProfileKey = "nazhi_specialization"; internal const float LevelCap = 50f; internal const float SpecializedCap = 100f; private static readonly Dictionary _specializations = new Dictionary(); private static string RejectedKey(ProfessionType profession) { return $"nazhi_spec_rejected_{profession}"; } internal static void RegisterCommand() { CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new MasterizarCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new RenegarCommand()); } internal static void Save(Player player, ProfessionType spec) { if ((Object)(object)player == (Object)null) { return; } _specializations[player.GetPlayerID()] = spec; try { MethodInfo method = typeof(Player).GetMethod("SetCustomData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { object[] obj = new object[2] { "nazhi_specialization", null }; int num = (int)spec; obj[1] = num.ToString(); method.Invoke(player, obj); } else if (typeof(Player).GetField("m_customData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(player) is Dictionary dictionary) { int num = (int)spec; dictionary["nazhi_specialization"] = num.ToString(); } EinjarheimProfessionsPlugin.Log.LogInfo((object)$"[Specialization] Guardado: {player.GetPlayerName()} → {spec}"); } catch (Exception ex) { EinjarheimProfessionsPlugin.Log.LogWarning((object)("[Specialization] Save error: " + ex.Message)); } } internal static ProfessionType Load(Player player) { if ((Object)(object)player == (Object)null) { return ProfessionType.None; } try { MethodInfo method = typeof(Player).GetMethod("GetCustomData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); string value = null; if (method != null) { value = method.Invoke(player, new object[1] { "nazhi_specialization" }) as string; } else if (typeof(Player).GetField("m_customData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(player) is Dictionary dictionary) { dictionary.TryGetValue("nazhi_specialization", out value); } if (!string.IsNullOrEmpty(value) && int.TryParse(value, out var result)) { return (ProfessionType)result; } } catch (Exception ex) { EinjarheimProfessionsPlugin.Log.LogWarning((object)("[Specialization] Load error: " + ex.Message)); } return ProfessionType.None; } internal static void SaveRejection(Player player, ProfessionType profession) { if ((Object)(object)player == (Object)null) { return; } try { MethodInfo method = typeof(Player).GetMethod("SetCustomData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { method.Invoke(player, new object[2] { RejectedKey(profession), "1" }); } else if (typeof(Player).GetField("m_customData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(player) is Dictionary dictionary) { dictionary[RejectedKey(profession)] = "1"; } EinjarheimProfessionsPlugin.Log.LogInfo((object)$"[Specialization] Rechazo guardado: {profession}"); } catch (Exception ex) { EinjarheimProfessionsPlugin.Log.LogWarning((object)("[Specialization] SaveRejection error: " + ex.Message)); } } internal static bool HasRejected(Player player, ProfessionType profession) { if ((Object)(object)player == (Object)null) { return false; } try { MethodInfo method = typeof(Player).GetMethod("GetCustomData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); string value = null; if (method != null) { value = method.Invoke(player, new object[1] { RejectedKey(profession) }) as string; } else if (typeof(Player).GetField("m_customData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(player) is Dictionary dictionary) { dictionary.TryGetValue(RejectedKey(profession), out value); } return value == "1"; } catch { return false; } } internal static ProfessionType GetSpecialization(Player player) { if ((Object)(object)player == (Object)null) { return ProfessionType.None; } long playerID = player.GetPlayerID(); if (_specializations.TryGetValue(playerID, out var value)) { return value; } ProfessionType professionType = Load(player); _specializations[playerID] = professionType; return professionType; } internal static bool IsMaster(Player player) { return GetSpecialization(player) != ProfessionType.None; } internal static bool IsMasterOf(Player player, ProfessionType profession) { return GetSpecialization(player) == profession; } internal static float GetCap(Player player, ProfessionType profession) { return IsMasterOf(player, profession) ? 100f : 50f; } internal static void Specialize(Player player, ProfessionType newSpec) { if ((Object)(object)player == (Object)null || newSpec == ProfessionType.None) { return; } ProfessionType specialization = GetSpecialization(player); if (specialization != ProfessionType.None && specialization != newSpec) { float skillLevel = GetSkillLevel(player, specialization); if (skillLevel > 50f) { ClampSkill(player, specialization, 50f); EinjarheimProfessionsPlugin.Log.LogInfo((object)$"[Specialization] {specialization} bajado a {50f}"); } } Save(player, newSpec); ProfessionType[] array = new ProfessionType[4] { ProfessionType.Cooking, ProfessionType.Blacksmithing, ProfessionType.Construction, ProfessionType.Alchemy }; foreach (ProfessionType professionType in array) { if (professionType != newSpec) { float skillLevel2 = GetSkillLevel(player, professionType); if (skillLevel2 >= 50f) { ClampSkill(player, professionType, 50f); EinjarheimProfessionsPlugin.Log.LogInfo((object)$"[Specialization] {professionType} clampeado a {50f} al masterizar {newSpec}"); } } } Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "¡Te has especializado en " + GetProfessionDisplayName(newSpec) + "!", 0, (Sprite)null); } EinjarheimProfessionsPlugin.Log.LogInfo((object)$"[Specialization] {player.GetPlayerName()} → Maestro de {newSpec}"); } internal static void ExecuteMasterizar(Player player) { if ((Object)(object)player == (Object)null) { return; } if (IsMaster(player)) { ProfessionType specialization = GetSpecialization(player); ((Character)player).Message((MessageType)1, "Ya eres Maestro de " + GetProfessionDisplayName(specialization) + ".", 0, (Sprite)null); return; } List list = new List(); ProfessionType[] array = new ProfessionType[4] { ProfessionType.Cooking, ProfessionType.Blacksmithing, ProfessionType.Construction, ProfessionType.Alchemy }; foreach (ProfessionType professionType in array) { if (GetSkillLevel(player, professionType) >= 50f) { list.Add(professionType); } } if (list.Count == 0) { ((Character)player).Message((MessageType)1, "Necesitás al menos nivel 50 en una profesión para masterizarte.", 0, (Sprite)null); } else { ShowSpecializationPopup(player, list); } } internal static void ExecuteRenegar(Player player) { if (!((Object)(object)player == (Object)null)) { if (!IsMaster(player)) { ((Character)player).Message((MessageType)1, "No sos Maestro de ninguna profesión.", 0, (Sprite)null); return; } ProfessionType specialization = GetSpecialization(player); ShowRenegarPopup(player, specialization); } } internal static void ShowRenegarPopup(Player player, ProfessionType current) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (!StoreGui.IsVisible() && !InventoryGui.IsVisible()) { GameObject val = new GameObject("EinjarheimRenegarPopup"); RenegarPopupHandler renegarPopupHandler = val.AddComponent(); renegarPopupHandler.Init(player, current); } } internal static void RemoveMastery(Player player) { if ((Object)(object)player == (Object)null) { return; } _specializations[player.GetPlayerID()] = ProfessionType.None; try { MethodInfo method = typeof(Player).GetMethod("SetCustomData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { method.Invoke(player, new object[2] { "nazhi_specialization", 0.ToString() }); } else if (typeof(Player).GetField("m_customData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(player) is Dictionary dictionary) { dictionary["nazhi_specialization"] = 0.ToString(); } } catch (Exception ex) { EinjarheimProfessionsPlugin.Log.LogWarning((object)("[Specialization] RemoveMastery error: " + ex.Message)); } ProfessionType[] array = new ProfessionType[4] { ProfessionType.Cooking, ProfessionType.Blacksmithing, ProfessionType.Construction, ProfessionType.Alchemy }; foreach (ProfessionType profession in array) { float skillLevel = GetSkillLevel(player, profession); if (skillLevel > 50f) { ClampSkill(player, profession, 50f); } } ((Character)player).Message((MessageType)2, "Has abandonado tu Maestría. Todas las profesiones quedan limitadas a nivel 50.", 0, (Sprite)null); EinjarheimProfessionsPlugin.Log.LogInfo((object)("[Specialization] " + player.GetPlayerName() + " abandonó su Maestría.")); } internal static void ShowSpecializationPopup(Player player, List available) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (!StoreGui.IsVisible() && !InventoryGui.IsVisible()) { GameObject val = new GameObject("EinjarheimSpecPopup"); SpecializationPopupHandler specializationPopupHandler = val.AddComponent(); specializationPopupHandler.Init(player, available); } } internal static float GetSkillLevel(Player player, ProfessionType profession) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return 0f; } return profession switch { ProfessionType.Cooking => ((Character)player).GetSkillLevel((SkillType)105), ProfessionType.Construction => ((Character)player).GetSkillLevel((SkillType)107), ProfessionType.Blacksmithing => ((int)BlacksmithingSystem.BlacksmithingSkillType != 0) ? ((Character)player).GetSkillLevel(BlacksmithingSystem.BlacksmithingSkillType) : 0f, ProfessionType.Alchemy => ((int)AlchemySystem.SkillType != 0) ? ((Character)player).GetSkillLevel(AlchemySystem.SkillType) : 0f, _ => 0f, }; } internal static SkillType GetSkillType(ProfessionType profession) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) return (SkillType)(profession switch { ProfessionType.Cooking => 105, ProfessionType.Blacksmithing => BlacksmithingSystem.BlacksmithingSkillType, ProfessionType.Construction => 107, ProfessionType.Alchemy => AlchemySystem.SkillType, _ => 0, }); } internal static string GetProfessionDisplayName(ProfessionType profession) { return profession switch { ProfessionType.Cooking => "Cocina", ProfessionType.Blacksmithing => "Herrería", ProfessionType.Construction => "Construcción", ProfessionType.Alchemy => "Alquimia", _ => "Ninguna", }; } internal static void ClampSkill(Player player, ProfessionType profession, float cap) { //IL_0050: 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_0058: Invalid comparison between Unknown and I4 //IL_006b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } try { object? obj = typeof(Player).GetField("m_skills", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(player); Skills val = (Skills)((obj is Skills) ? obj : null); if (!((Object)(object)val == (Object)null)) { SkillType skillType = GetSkillType(profession); if ((int)skillType != 0 && val.m_skillData.TryGetValue(skillType, out var value) && value.m_level >= cap) { value.m_level = cap; value.m_accumulator = 0f; EinjarheimProfessionsPlugin.Log.LogInfo((object)$"[Specialization] ClampSkill: {profession} → {cap}"); } } } catch (Exception ex) { EinjarheimProfessionsPlugin.Log.LogWarning((object)$"[Specialization] ClampSkill error ({profession}): {ex.Message}"); } } internal static void OnPlayerSpawned(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return; } ProfessionType specialization = GetSpecialization(player); ProfessionType[] array = new ProfessionType[4] { ProfessionType.Cooking, ProfessionType.Blacksmithing, ProfessionType.Construction, ProfessionType.Alchemy }; foreach (ProfessionType profession in array) { float skillLevel = GetSkillLevel(player, profession); float cap = GetCap(player, profession); if (skillLevel > cap) { ClampSkill(player, profession, cap); } } EinjarheimProfessionsPlugin.Log.LogInfo((object)("[Specialization] " + player.GetPlayerName() + " → Maestro: " + GetProfessionDisplayName(specialization))); } } internal class MasterizarCommand : ConsoleCommand { public override string Name => "masterizar"; public override string Help => "Abre el menú de especialización de profesión si tenés nivel 50+."; public override bool IsCheat => false; public override void Run(string[] args) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { Console.instance.Print("No hay jugador local."); } else { SpecializationSystem.ExecuteMasterizar(localPlayer); } } } internal class SpecializationPopupHandler : MonoBehaviour { private Player _player; private List _available; private float _waitTimer; private bool _shown; private GameObject _panel; internal void Init(Player player, List available) { _player = player; _available = available; _shown = false; _waitTimer = 0f; } private void Update() { if (!_shown) { _waitTimer += Time.deltaTime; if (!(_waitTimer < 0.3f) && !InventoryGui.IsVisible() && !TextInput.IsVisible()) { BuildUI(); _shown = true; } } } private void BuildUI() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Expected O, but got Unknown //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: 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_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Expected O, but got Unknown if (GUIManager.Instance == null || (Object)(object)GUIManager.CustomGUIFront == (Object)null) { EinjarheimProfessionsPlugin.Log.LogWarning((object)"[Specialization] GUIManager no disponible."); Object.Destroy((Object)(object)((Component)this).gameObject); return; } float num = 380f + (float)_available.Count * 80f; _panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 700f, num, false); GameObject val = GUIManager.Instance.CreateText("Elige tu Especialización", _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -70f), GUIManager.Instance.AveriaSerifBold, 44, GUIManager.Instance.ValheimOrange, true, Color.black, 640f, 70f, false); val.GetComponent().alignment = (TextAnchor)4; GameObject val2 = GUIManager.Instance.CreateText("La profesión elegida podrá subir hasta nivel 100.\nLas otras 3 quedarán limitadas al nivel 50.", _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -155f), GUIManager.Instance.AveriaSerif, 28, Color.white, false, Color.black, 640f, 80f, false); val2.GetComponent().alignment = (TextAnchor)4; float num2 = -260f; for (int i = 0; i < _available.Count; i++) { ProfessionType prof = _available[i]; string professionDisplayName = SpecializationSystem.GetProfessionDisplayName(prof); float skillLevel = SpecializationSystem.GetSkillLevel(_player, prof); GameObject val3 = GUIManager.Instance.CreateButton($"{professionDisplayName} (Nivel {skillLevel:0})", _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, num2 - (float)i * 80f), 500f, 65f); ((UnityEvent)val3.GetComponent