Merge pull request 'fixbug/npc-dialog' (#333) from fixbug/npc-dialog into develop
Reviewed-on: https://git.pthub.vn/Unity/perfect-world-unity/pulls/333
This commit is contained in:
@@ -17,6 +17,12 @@ public class GShopLoader : MonoBehaviour
|
||||
[Header("Loaded Data")]
|
||||
public GShopData primaryShop = new GShopData();
|
||||
public GShopData secondaryShop = new GShopData();
|
||||
|
||||
/// <summary>True after gshop.txt has been loaded and parsed successfully.</summary>
|
||||
public bool IsPrimaryShopLoaded { get; private set; }
|
||||
|
||||
/// <summary>Invoked once when <see cref="primaryShop"/> data is ready.</summary>
|
||||
public event Action OnPrimaryShopLoaded;
|
||||
|
||||
async void Start()
|
||||
{
|
||||
@@ -37,6 +43,8 @@ public class GShopLoader : MonoBehaviour
|
||||
if (await LoadShopData(GSHOP_ADDRESS, primaryShop))
|
||||
{
|
||||
Debug.Log($"Primary shop loaded: {primaryShop.items.Count} items, {primaryShop.mainTypes.Count} categories");
|
||||
IsPrimaryShopLoaded = true;
|
||||
OnPrimaryShopLoaded?.Invoke();
|
||||
//LogShopData("Primary Shop", primaryShop);
|
||||
}
|
||||
|
||||
|
||||
@@ -1036,9 +1036,9 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
// Only update description and name if task changed
|
||||
if( idTask != m_idLastTask )
|
||||
{
|
||||
_nameTaskText.SetText(EC_Utility.FormatForTextMeshPro(GetTaskNameWithColor(pTemp)));
|
||||
_nameTaskText.SetText(EC_Utility.FormatForTextMeshPro(CECUIHelper.FormatCoordText(GetTaskNameWithColor(pTemp))));
|
||||
//pTextDesc->SetText(FormatTaskText(pTemp->GetDescription(), pTextDesc->GetColor()));
|
||||
pTextDesc.SetText(EC_Utility.FormatForTextMeshPro(pTemp.GetDescription()));
|
||||
pTextDesc.SetText(EC_Utility.FormatForTextMeshPro(CECUIHelper.FormatCoordText(pTemp.GetDescription())));
|
||||
m_idLastTask = idTask;
|
||||
bLastTaskChanged = true;
|
||||
}
|
||||
@@ -1154,9 +1154,9 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
// Update description when the selected task changes
|
||||
if (idTask != m_idLastTask)
|
||||
{
|
||||
_nameTaskText.SetText(EC_Utility.FormatForTextMeshPro(GetTaskNameWithColor(pTemp)));
|
||||
_nameTaskText.SetText(EC_Utility.FormatForTextMeshPro(CECUIHelper.FormatCoordText(GetTaskNameWithColor(pTemp))));
|
||||
Debug.Log("[DlgTask] SearchForTask name task: " + _nameTaskText.text);
|
||||
if (pTextDesc != null) pTextDesc.SetText(EC_Utility.FormatForTextMeshPro(pTemp.GetDescription()));
|
||||
if (pTextDesc != null) pTextDesc.SetText(EC_Utility.FormatForTextMeshPro(CECUIHelper.FormatCoordText(pTemp.GetDescription())));
|
||||
m_idLastTask = idTask;
|
||||
bLastTaskChanged = true;
|
||||
}
|
||||
@@ -1619,7 +1619,7 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
// UnityEngine.UI.ScrollRect scrollRect = pTextItem.GetComponentInParent<UnityEngine.UI.ScrollRect>();
|
||||
// float oldNormPos = scrollRect != null ? scrollRect.verticalNormalizedPosition : 0f;
|
||||
|
||||
string formatted = EC_Utility.FormatForTextMeshPro(strNewTextItem ?? string.Empty);
|
||||
string formatted = EC_Utility.FormatForTextMeshPro(CECUIHelper.FormatCoordText(strNewTextItem ?? string.Empty));
|
||||
if (!string.Equals(formatted, pTextItem.text))
|
||||
{
|
||||
pTextItem.text = formatted;
|
||||
|
||||
@@ -602,7 +602,7 @@ namespace BrewMonster.Scripts.Task.UI
|
||||
|
||||
bool bCanContributionFinish = !hasContributionAward;
|
||||
// ACString strTask = pTempl->GetName();
|
||||
string strTask = pTempl.GetDescription();
|
||||
string strTask = CECUIHelper.FormatCoordText(pTempl.GetDescription());
|
||||
// ������ʾһ����������
|
||||
if (topLevel)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Managers;
|
||||
using ModelRenderer.Scripts.Common;
|
||||
using ModelRenderer.Scripts.GameData;
|
||||
using BrewMonster.Scripts.Task;
|
||||
using BrewMonster.Scripts;
|
||||
using BrewMonster.Scripts.Chat;
|
||||
@@ -102,7 +105,7 @@ namespace BrewMonster.Scripts.UI
|
||||
|
||||
// Fallback to coord_data.txt (C++: Configs/Coord_data.txt via CECGame::GetObjectCoord)
|
||||
// 回退到 coord_data.txt(C++:Configs/Coord_data.txt,通过 CECGame::GetObjectCoord)
|
||||
if (BrewMonster.Network.EC_Game.TryGetFirstObjectCoord(id.ToString(), out var coordPos, out var mapName))
|
||||
if (global::BrewMonster.Network.EC_Game.TryGetFirstObjectCoord(id.ToString(), out var coordPos, out var mapName))
|
||||
{
|
||||
in_table = true;
|
||||
BMLogger.Log(
|
||||
@@ -372,6 +375,96 @@ namespace BrewMonster.Scripts.UI
|
||||
EC_ManMessage.PostMessage(0, 0, 0, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PW client: <c>CECUIHelper::FormatCoordText</c> — replaces <c>@essenceId@</c> (monster template) and
|
||||
/// <c>$essenceId$</c> (NPC or mine template) with display names; when coordinates exist, wraps the name in a TMP
|
||||
/// coord link like the main quest UI.
|
||||
/// </summary>
|
||||
public static string FormatCoordText(string szText)
|
||||
{
|
||||
if (string.IsNullOrEmpty(szText))
|
||||
return string.Empty;
|
||||
|
||||
var sb = new StringBuilder(szText.Length + 48);
|
||||
int len = szText.Length;
|
||||
int i = 0;
|
||||
elementdataman edm = global::BrewMonster.ElementDataManProvider.GetElementDataMan();
|
||||
|
||||
while (i < len)
|
||||
{
|
||||
int segStart = i;
|
||||
while (i < len && szText[i] != '@' && szText[i] != '$')
|
||||
i++;
|
||||
sb.Append(szText, segStart, i - segStart);
|
||||
if (i >= len)
|
||||
break;
|
||||
|
||||
char open = szText[i];
|
||||
i++;
|
||||
int idStart = i;
|
||||
while (i < len && szText[i] != '@' && szText[i] != '$')
|
||||
i++;
|
||||
if (i >= len)
|
||||
{
|
||||
sb.Append(open);
|
||||
sb.Append(szText, idStart, i - idStart);
|
||||
break;
|
||||
}
|
||||
|
||||
char flag = szText[i];
|
||||
string keyword = szText.Substring(idStart, i - idStart);
|
||||
i++;
|
||||
|
||||
if (!uint.TryParse(keyword, out uint essenceId))
|
||||
{
|
||||
sb.Append(open);
|
||||
sb.Append(keyword);
|
||||
sb.Append(flag);
|
||||
continue;
|
||||
}
|
||||
|
||||
AppendEssencePlaceholder(sb, edm, essenceId, flag);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
static void AppendEssencePlaceholder(StringBuilder sb, elementdataman edm, uint essenceId, char flag)
|
||||
{
|
||||
string strName = null;
|
||||
if (edm != null)
|
||||
{
|
||||
DATA_TYPE dt = default;
|
||||
object p = edm.get_data_ptr(essenceId, ID_SPACE.ID_SPACE_ESSENCE, ref dt);
|
||||
if (flag == '$')
|
||||
{
|
||||
if (dt == DATA_TYPE.DT_NPC_ESSENCE && p is NPC_ESSENCE npc)
|
||||
strName = npc.Name;
|
||||
else if (dt == DATA_TYPE.DT_MINE_ESSENCE && p is MINE_ESSENCE mine)
|
||||
strName = ByteToStringUtils.UshortArrayToUnicodeString(mine.name);
|
||||
}
|
||||
else if (flag == '@')
|
||||
{
|
||||
if (dt == DATA_TYPE.DT_MONSTER_ESSENCE && p is MONSTER_ESSENCE mon)
|
||||
strName = mon.Name;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(strName))
|
||||
{
|
||||
sb.Append("^00FF00?????^FFFFFF");
|
||||
return;
|
||||
}
|
||||
|
||||
bool inTable = false;
|
||||
GetTaskObjectCoordinates((int)essenceId, ref inTable);
|
||||
if (inTable)
|
||||
sb.Append("<link=\"coord_").Append(essenceId).Append("\"><color=#00FF00>").Append(strName)
|
||||
.Append("</color></link>");
|
||||
else
|
||||
sb.Append(strName);
|
||||
}
|
||||
|
||||
public static string PolicySpecialCharReplace(
|
||||
string szText,
|
||||
CHAT_S2C.PolicyChatParameter pPolicyChatPara)
|
||||
|
||||
@@ -52,11 +52,37 @@ public class ShopUIManager : MonoBehaviour
|
||||
//-1 means all sub types
|
||||
public SubTypeShop subTypeShop;
|
||||
private int currentSubType = -1;
|
||||
private bool _shopLoaderEventsSubscribed;
|
||||
|
||||
void Start()
|
||||
{
|
||||
InitializeUI();
|
||||
SetupEventListeners();
|
||||
InitializePool();
|
||||
SubscribeShopLoaderEvents();
|
||||
}
|
||||
|
||||
void SubscribeShopLoaderEvents()
|
||||
{
|
||||
if (_shopLoaderEventsSubscribed)
|
||||
return;
|
||||
if (shopLoader == null)
|
||||
shopLoader = FindFirstObjectByType<GShopLoader>();
|
||||
if (shopLoader == null)
|
||||
return;
|
||||
|
||||
shopLoader.OnPrimaryShopLoaded += OnPrimaryShopDataReady;
|
||||
_shopLoaderEventsSubscribed = true;
|
||||
|
||||
// Load may have finished before we subscribed (e.g. script order).
|
||||
if (shopLoader.IsPrimaryShopLoaded)
|
||||
OnPrimaryShopDataReady();
|
||||
}
|
||||
|
||||
void OnPrimaryShopDataReady()
|
||||
{
|
||||
if (shopMainPanel != null && shopMainPanel.activeSelf)
|
||||
RefreshShopDisplay();
|
||||
}
|
||||
|
||||
void InitializePool()
|
||||
@@ -106,8 +132,10 @@ public class ShopUIManager : MonoBehaviour
|
||||
{
|
||||
if (shopMainPanel != null)
|
||||
{
|
||||
OnCategorySelected(0);
|
||||
RefreshShopDisplay();
|
||||
SubscribeShopLoaderEvents();
|
||||
shopMainPanel.SetActive(true);
|
||||
// Always apply category 0 when opening; OnCategorySelected(0) no-ops if currentCategory is already 0.
|
||||
OnCategorySelected(0, forceRefresh: true);
|
||||
ApplyPendingCash();
|
||||
UnityGameSession.RequesrQueryPlayerCash();
|
||||
}
|
||||
@@ -175,9 +203,9 @@ public class ShopUIManager : MonoBehaviour
|
||||
shopDetailPanel.SetActive(false);
|
||||
}
|
||||
|
||||
void OnCategorySelected(int categoryIndex)
|
||||
void OnCategorySelected(int categoryIndex, bool forceRefresh = false)
|
||||
{
|
||||
if (categoryIndex == currentCategory)
|
||||
if (!forceRefresh && categoryIndex == currentCategory)
|
||||
return;
|
||||
|
||||
float startTime = Time.realtimeSinceStartup;
|
||||
@@ -572,6 +600,9 @@ public class ShopUIManager : MonoBehaviour
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if (shopLoader != null && _shopLoaderEventsSubscribed)
|
||||
shopLoader.OnPrimaryShopLoaded -= OnPrimaryShopDataReady;
|
||||
|
||||
// Clean up pooled objects
|
||||
if (useObjectPooling && itemPanelPool != null)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user