diff --git a/Assets/Gothic-Core/Scripts/Adapters/UI/Menus/QuestLogMenu.cs b/Assets/Gothic-Core/Scripts/Adapters/UI/Menus/QuestLogMenu.cs index b9e48c42d..a85ffa1bf 100644 --- a/Assets/Gothic-Core/Scripts/Adapters/UI/Menus/QuestLogMenu.cs +++ b/Assets/Gothic-Core/Scripts/Adapters/UI/Menus/QuestLogMenu.cs @@ -203,6 +203,7 @@ private void CreateLists() rect.SetHeight(rend.sharedMaterial.mainTexture.height); rect.SetPositionX(halfMainWidth - _arrowMargin); rect.SetPositionY(halfMainHeight - _arrowMargin); + SetLocalZ(rect, -0.03f); } // DOWN @@ -221,6 +222,7 @@ private void CreateLists() rect.SetHeight(rend.sharedMaterial.mainTexture.height); rect.SetPositionX(halfMainWidth - _arrowMargin); rect.SetPositionY(-halfMainHeight + _arrowMargin); + SetLocalZ(rect, -0.03f); } } @@ -239,7 +241,7 @@ private void CreateContentViewer() textComp.overflowMode = TextOverflowModes.Page; textComp.pageToDisplay = 0; - // UP + // UP - right side, above content { var go = _resourceCacheService.TryGetPrefabObject(PrefabType.UiButtonTextured, name: "ARROW_UP", parent: contentViewer.go)!; var rect = go.GetComponentInChildren(); @@ -254,9 +256,10 @@ private void CreateContentViewer() rect.SetHeight(rend.sharedMaterial.mainTexture.height); rect.SetPositionX(halfTextWidth + rend.sharedMaterial.mainTexture.width); rect.SetPositionY(halfTextHeight + rend.sharedMaterial.mainTexture.height); + SetLocalZ(rect, -0.03f); } - // DOWN + // DOWN - right side, below content { var go = _resourceCacheService.TryGetPrefabObject(PrefabType.UiButtonTextured, name: "ARROW_DOWN", parent: contentViewer.go)!; var rect = go.GetComponentInChildren(); @@ -271,9 +274,10 @@ private void CreateContentViewer() rect.SetHeight(rend.sharedMaterial.mainTexture.height); rect.SetPositionX(halfTextWidth + rend.sharedMaterial.mainTexture.width); rect.SetPositionY(-halfTextHeight - rend.sharedMaterial.mainTexture.height); + SetLocalZ(rect, -0.03f); } - // BACK + // BACK - bottom-left corner, same Y as ARROW_DOWN { var go = _resourceCacheService.TryGetPrefabObject(PrefabType.UiButtonTextured, name: "ARROW_BACK", parent: contentViewer.go)!; var rect = go.GetComponentInChildren(); @@ -284,10 +288,12 @@ private void CreateContentViewer() rend.sharedMaterial = TextureService.ArrowLeftMaterial; button.onClick.AddListener(OnContentViewerBackClick); + var arrowW = rend.sharedMaterial.mainTexture.width * go.transform.localScale.x; rect.SetWidth(rend.sharedMaterial.mainTexture.width); rect.SetHeight(rend.sharedMaterial.mainTexture.height); - rect.SetPositionX(-halfTextWidth - rend.sharedMaterial.mainTexture.width); - rect.SetPositionY(halfTextHeight + rend.sharedMaterial.mainTexture.height); + rect.SetPositionX(-halfTextWidth + arrowW); + rect.SetPositionY(-halfTextHeight - rend.sharedMaterial.mainTexture.height); + SetLocalZ(rect, -0.03f); } } @@ -399,8 +405,12 @@ private void OnListItemClicked(int index) Background.SetActive(false); var contentViewer = MenuItemCache[_instanceContentViewer].go; - contentViewer.GetComponentInChildren().text = text; + var tmpText = contentViewer.GetComponentInChildren(); + tmpText.text = text; contentViewer.SetActive(true); + tmpText.ForceMeshUpdate(ignoreActiveState: true); + foreach (var subMesh in tmpText.GetComponentsInChildren()) + SetLocalZ(subMesh.rectTransform, -0.02f); } private void OnArrowUpClick() @@ -464,5 +474,12 @@ protected override void ExecuteCommand(string itemName, string commandName) // If the Command==ListMenu, then we set it as currently active. _listMenuCache.TryGetValue(menuItemName, out _activeListMenu); } + + private static void SetLocalZ(RectTransform rect, float z) + { + var pos = rect.localPosition; + pos.z = z; + rect.localPosition = pos; + } } } diff --git a/Assets/Gothic-Core/Scripts/Adapters/UI/Menus/StatusMenu.cs b/Assets/Gothic-Core/Scripts/Adapters/UI/Menus/StatusMenu.cs index 3a29ef488..5944f1719 100644 --- a/Assets/Gothic-Core/Scripts/Adapters/UI/Menus/StatusMenu.cs +++ b/Assets/Gothic-Core/Scripts/Adapters/UI/Menus/StatusMenu.cs @@ -1,8 +1,9 @@ -using System; +using System; using System.Linq; using Gothic.Core.Model.UI.Menu; +using Gothic.Core.Models.Vm; +using Gothic.Core.Services.Npc; using Gothic.Core.Services.Vm; -using Gothic.Core.Const; using MyBox; using Reflex.Attributes; using TMPro; @@ -18,121 +19,107 @@ public class StatusMenu : AbstractMenu private string _itemNameLearn = "MENU_ITEM_LEARN"; private string _itemNameAttributePattern = "MENU_ITEM_ATTRIBUTE_{0}"; - private string _itemNameArmorPattern = "MENU_ITEM_ARMOR_{0}"; private string _itemTalentTitlePattern = "MENU_ITEM_TALENT_{0}_TITLE"; private string _itemTalentSkillPattern = "MENU_ITEM_TALENT_{0}_SKILL"; private string _itemTalentDescriptionPattern = "MENU_ITEM_TALENT_{0}"; - + // Attribute slot → (currentIndex, maxIndex); maxIndex -1 means single value + // Gothic engine convention: 1=Strength(4), 2=Dexterity(5), 3=Mana(2/max3), 4=HP(0/max1) + private static readonly int[] _attrCurrentIndex = { 4, 5, 2, 0 }; + private static readonly int[] _attrMaxIndex = {-1,-1, 3, 1 }; + + // Armor slot → DamageType index: 1=Blunt, 2=Point(projectiles), 3=Fire, 4=Magic + // DamageType values: Blunt=1, Point=3, Fire=4, Magic=6 + private static readonly int[] _armorProtIndex = { 1, 3, 4, 6 }; + [Inject] private readonly VmService _vmService; + [Inject] private readonly NpcService _npcService; - private void Awake() { InitializeMenu(new MenuInstanceAdapter("MENU_STATUS", null)); } - public override void InitializeMenu(AbstractMenuInstance menuInstance) - { - base.InitializeMenu(menuInstance); - Setup(); - } - - private void Setup() + private void OnEnable() { + if (_npcService == null) + return; UpdateData(); } - /// - /// Fill data. Currently demo data. - /// private void UpdateData() { - MenuItemCache[_itemNameGuild].go.GetComponentInChildren().text = "TestGuild"; - MenuItemCache[_itemNameLevel].go.GetComponentInChildren().text = "100"; - MenuItemCache[_itemNameExp].go.GetComponentInChildren().text = "1337"; - MenuItemCache[_itemNameLevelNext].go.GetComponentInChildren().text = "13"; - MenuItemCache[_itemNameLearn].go.GetComponentInChildren().text = "42"; + var hero = _npcService.GetHeroContainer(); + var vob = hero.Vob; + + var guildId = hero.Props.TrueGuild != VmGothicEnums.Guild.GIL_NONE + ? (int)hero.Props.TrueGuild + : vob.Guild; + + MenuItemCache[_itemNameGuild].go.GetComponentInChildren().text = _vmService.GetGuildName(guildId); + MenuItemCache[_itemNameLevel].go.GetComponentInChildren().text = vob.Level.ToString(); + MenuItemCache[_itemNameExp].go.GetComponentInChildren().text = vob.Xp.ToString(); + MenuItemCache[_itemNameLevelNext].go.GetComponentInChildren().text = vob.XpNextLevel.ToString(); + MenuItemCache[_itemNameLearn].go.GetComponentInChildren().text = vob.Lp.ToString(); - Enumerable.Range(1, 4).ForEach(i => + Enumerable.Range(0, 4).ForEach(i => { - var key = string.Format(_itemNameAttributePattern, i); - MenuItemCache[key].go.GetComponentInChildren().text = $"{i}/100"; + var key = string.Format(_itemNameAttributePattern, i + 1); + var cur = vob.GetAttribute(_attrCurrentIndex[i]); + var text = _attrMaxIndex[i] >= 0 + ? $"{cur}/{vob.GetAttribute(_attrMaxIndex[i])}" + : cur.ToString(); + MenuItemCache[key].go.GetComponentInChildren().text = text; }); - Enumerable.Range(1, 4).ForEach(i => + Enumerable.Range(0, 4).ForEach(i => { - var key = string.Format(_itemNameArmorPattern, i); - MenuItemCache[key].go.GetComponentInChildren().text = $"{i}"; + var key = string.Format(_itemNameArmorPattern, i + 1); + MenuItemCache[key].go.GetComponentInChildren().text = vob.GetProtection(_armorProtIndex[i]).ToString(); }); var talentTitles = _vmService.TalentTitles; var talentSkills = _vmService.TalentSkills; - Enumerable.Range(0, 12).ForEach(i => + Enumerable.Range(0, talentTitles.Count).ForEach(i => { - var keyTitle = string.Format(_itemTalentTitlePattern, i+1); - var keySkill = string.Format(_itemTalentSkillPattern, i+1); - var keyDescription = string.Format(_itemTalentDescriptionPattern, i+1); + var keyTitle = string.Format(_itemTalentTitlePattern, i + 1); + var keySkill = string.Format(_itemTalentSkillPattern, i + 1); + var keyDescription = string.Format(_itemTalentDescriptionPattern, i + 1); - var randValue = new Random().Next(0, 2); - var skillDescriptionText = talentSkills[i]; + if (!MenuItemCache.ContainsKey(keyTitle)) + return; - string skillDescriptionFormatted; - if (skillDescriptionText.IsNullOrEmpty() || skillDescriptionText== "|") + var talent = vob.GetTalent(i); + var skillText = talentSkills[i]; + string skillFormatted; + if (skillText.IsNullOrEmpty() || skillText == "|") { - skillDescriptionFormatted = ""; + skillFormatted = string.Empty; } else { - skillDescriptionFormatted = skillDescriptionText.Split("|")[randValue]; + var parts = skillText.Split("|"); + var partIndex = Math.Min(talent.Skill, parts.Length - 1); + skillFormatted = parts[partIndex]; } MenuItemCache[keyTitle].go.GetComponentInChildren().text = talentTitles[i]; - MenuItemCache[keySkill].go.GetComponentInChildren().text = skillDescriptionFormatted; + MenuItemCache[keySkill].go.GetComponentInChildren().text = skillFormatted; - if (MenuItemCache.TryGetValue(keyDescription, out var item)) - { - item.go.GetComponentInChildren().text = $"{randValue}%"; - } + if (MenuItemCache.TryGetValue(keyDescription, out var descItem)) + descItem.go.GetComponentInChildren().text = $"{talent.Value}%"; }); } - protected override void Undefined(string itemName, string commandName) - { - throw new NotImplementedException(); - } - - protected override void StartMenu(string itemName, string commandName) - { - throw new NotImplementedException(); - } - - protected override void StartItem(string itemName, string commandName) - { - throw new NotImplementedException(); - } - - protected override void Close(string itemName, string commandName) - { - throw new NotImplementedException(); - } - - protected override void ConsoleCommand(string itemName, string commandName) - { - throw new NotImplementedException(); - } - - protected override void PlaySound(string itemName, string commandName) - { - throw new NotImplementedException(); - } - - protected override void ExecuteCommand(string itemName, string commandName) - { - throw new NotImplementedException(); - } + protected override void Undefined(string itemName, string commandName) { } + protected override void StartMenu(string itemName, string commandName) { } + protected override void StartItem(string itemName, string commandName) { } + protected override void Close(string itemName, string commandName) { } + protected override void ConsoleCommand(string itemName, string commandName) { } + protected override void PlaySound(string itemName, string commandName) { } + protected override void ExecuteCommand(string itemName, string commandName) { } } } diff --git a/Assets/Gothic-Core/Scripts/Services/Vm/VmService.cs b/Assets/Gothic-Core/Scripts/Services/Vm/VmService.cs index c23fc0cca..ce35ef9bd 100644 --- a/Assets/Gothic-Core/Scripts/Services/Vm/VmService.cs +++ b/Assets/Gothic-Core/Scripts/Services/Vm/VmService.cs @@ -59,6 +59,15 @@ public List TalentSkills } } + public string GetGuildName(int guildId) + { + var guilds = _gameStateService.GothicVm.GetSymbolByName("TXT_GUILDS"); + var max = _gameStateService.GothicVm.GetSymbolByName("GIL_MAX")?.GetInt(0); + if (guilds == null || guildId < 0 || guildId >= max) + return string.Empty; + return guilds.GetString((ushort)guildId); + } + public int InvCatMax => _gameStateService.GothicVm.GetSymbolByName("INV_CAT_MAX").GetInt(0); public List InventoryCategories {