Add ext description text
This commit is contained in:
@@ -53,6 +53,12 @@ namespace BrewMonster.Scripts.Managers
|
||||
private static bool s_hasPendingCash;
|
||||
private static int s_pendingCashAmount;
|
||||
|
||||
// Flags to prevent log spam for extended description warnings
|
||||
// 防止扩展描述警告日志刷屏的标志
|
||||
private static bool m_HasLoggedExtDescNull = false;
|
||||
private static bool m_HasLoggedExtDescNotInit = false;
|
||||
private static bool m_HasLoggedExtDescError = false;
|
||||
|
||||
private InventoryModel model;
|
||||
private InventoryView view;
|
||||
|
||||
@@ -828,16 +834,81 @@ namespace BrewMonster.Scripts.Managers
|
||||
{
|
||||
// Fallback to legacy string-table description if centralised pipeline returns empty
|
||||
string itemDescription = GetItemDescription(item.m_tid);
|
||||
string itemExtendedDesc = GetItemExtendedDescription(item.m_tid);
|
||||
descriptionText?.Set(itemDescription ?? "No description available");
|
||||
extendedDescText?.Set(itemExtendedDesc ?? "");
|
||||
}
|
||||
|
||||
// Get extended description exactly like C++ code: g_pGame->GetItemExtDesc(m_tid)
|
||||
// C++ code doesn't check IsInitialized() - it just calls GetWideString() directly
|
||||
// 完全按照C++代码获取扩展描述:g_pGame->GetItemExtDesc(m_tid)
|
||||
// C++代码不检查IsInitialized() - 它直接调用GetWideString()
|
||||
string szExtDesc = null;
|
||||
try
|
||||
{
|
||||
var itemExtDescTab = EC_Game.GetItemExtDesc();
|
||||
if (itemExtDescTab != null)
|
||||
{
|
||||
// First try to get mapped message ID (like TryGetItemExtDesc does)
|
||||
// 首先尝试获取映射的消息ID(如TryGetItemExtDesc所做)
|
||||
if (EC_Game.TryGetItemMsg(item.m_tid, out int messageId, out int displayMode))
|
||||
{
|
||||
szExtDesc = itemExtDescTab.GetWideString(messageId);
|
||||
}
|
||||
|
||||
// Fallback: direct lookup using tid (exactly like C++: m_ItemExtDesc.GetWideString(tid))
|
||||
// 回退:直接使用tid查找(完全像C++:m_ItemExtDesc.GetWideString(tid))
|
||||
if (string.IsNullOrEmpty(szExtDesc))
|
||||
{
|
||||
szExtDesc = itemExtDescTab.GetWideString(item.m_tid);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
// Only log once to avoid spam
|
||||
// 仅记录一次以避免垃圾日志
|
||||
if (!m_HasLoggedExtDescError)
|
||||
{
|
||||
Debug.LogWarning($"[InventoryUI] Error getting extended description: {ex.Message}");
|
||||
m_HasLoggedExtDescError = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Display extended description if found (exactly like C++ checks: if (!szExtDesc || !szExtDesc[0]))
|
||||
// 如果找到扩展描述则显示(完全像C++检查:if (!szExtDesc || !szExtDesc[0]))
|
||||
string displayText = !string.IsNullOrEmpty(szExtDesc)
|
||||
? szExtDesc.Replace("\\r", "\n")
|
||||
: "";
|
||||
|
||||
// Debug logging to diagnose issues
|
||||
// 调试日志以诊断问题
|
||||
if (string.IsNullOrEmpty(displayText))
|
||||
{
|
||||
Debug.Log($"[InventoryUI] Extended description is empty for tid={item.m_tid}. szExtDesc was null/empty.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"[InventoryUI] Found extended description for tid={item.m_tid}, length={displayText.Length}");
|
||||
}
|
||||
|
||||
// Setup equip and drop buttons
|
||||
SetupEquipButton(package, item);
|
||||
SetupDropButton(package, item);
|
||||
|
||||
// Show panel first
|
||||
// 先显示面板
|
||||
ShowDetailPanel(true);
|
||||
|
||||
// Set text directly - if this causes rebuild issues, we'll use coroutine
|
||||
// 直接设置文本 - 如果这导致重建问题,我们将使用协程
|
||||
if (extendedDescText != null)
|
||||
{
|
||||
extendedDescText.Set(displayText);
|
||||
Debug.Log($"[InventoryUI] Set extended description text, extendedDescText is {(extendedDescText == null ? "null" : "not null")}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[InventoryUI] extendedDescText is null! Check Inspector assignment.");
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupEquipButton(byte package, EC_IvtrItem item)
|
||||
|
||||
@@ -1250,14 +1250,180 @@ namespace BrewMonster.Scripts.Managers
|
||||
m_strDesc += "\n";
|
||||
}
|
||||
|
||||
// Add extend description to description string / 添加扩展描述到描述字符串
|
||||
protected void AddExtDescText()
|
||||
{
|
||||
// Extend description from item_ext_desc.txt via EC_Game
|
||||
string ext = TryGetItemExtDesc();
|
||||
if (!string.IsNullOrEmpty(ext))
|
||||
// Get extended description from item_ext_desc.txt using tid / 使用tid从item_ext_desc.txt获取扩展描述
|
||||
string szExtDesc = TryGetItemExtDesc();
|
||||
// Note: Original C++ had early return commented out / 注意:原始C++代码的早期返回被注释掉了
|
||||
// if (!szExtDesc || !szExtDesc[0])
|
||||
// return;
|
||||
|
||||
m_strDesc += "\\r";
|
||||
|
||||
bool bAddLine = true;
|
||||
// Add special properties description / 添加特殊属性描述
|
||||
var pDescTab = EC_Game.GetItemDesc();
|
||||
// Note: ITEMDESC_COL2_BRIGHTBLUE constant - adjust based on actual string table / 注意:ITEMDESC_COL2_BRIGHTBLUE常量 - 根据实际字符串表调整
|
||||
int green = 1000; // ITEMDESC_COL2_BRIGHTBLUE placeholder - adjust this value
|
||||
|
||||
if (m_iCID != (int)InventoryClassId.ICID_GOBLIN) // goblin does not need to display these special properties / 地精不需要显示这些特殊属性
|
||||
{
|
||||
AddDescText(0, true, ext);
|
||||
// Exact C++ logic: (PROC_NO_USER_TRASH) || (!PROC_BINDING && (PROC_DROPWHENDIE || ...))
|
||||
// 精确的C++逻辑:(PROC_NO_USER_TRASH) || (!PROC_BINDING && (PROC_DROPWHENDIE || ...))
|
||||
if ((m_iProcType & (int)ProcType.PROC_NO_USER_TRASH) != 0
|
||||
|| (!((m_iProcType & (int)ProcType.PROC_BINDING) != 0)
|
||||
&& ((m_iProcType & (int)ProcType.PROC_DROPWHENDIE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_DROPPABLE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_SELLABLE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_TRADEABLE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_DISAPEAR) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_USE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_DEADDROP) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_OFFLINE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_UNREPAIRABLE) != 0)))
|
||||
{
|
||||
bAddLine = false;
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
string szCol = pDescTab.GetWideString(green);
|
||||
if (!string.IsNullOrEmpty(szCol))
|
||||
{
|
||||
m_strDesc += szCol;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: These message IDs are placeholders - adjust based on actual string table / 注意:这些消息ID是占位符 - 根据实际字符串表调整
|
||||
if ((m_iProcType & (int)ProcType.PROC_DROPWHENDIE) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_DEAD_PROTECT placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2000); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_DROPPABLE) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_DROP placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2001); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_SELLABLE) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_TRADE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2002); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_TRADEABLE) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_PLAYER_TRADE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2003); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_DISAPEAR) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_LEAVE_SCENE_DISAPEAR placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2004); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_USE) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_USE_AFTER_PICK_UP placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2005); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_DEADDROP) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_DROP_WHEN_DEAD placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2006); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_OFFLINE) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_DROP_WHEN_OFFLINE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2007); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_UNREPAIRABLE) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_UNREPAIRABLE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2008); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_NO_USER_TRASH) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_USER_TRASH placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2009); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TrimLastReturn();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TrimLastReturn();
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(szExtDesc))
|
||||
return;
|
||||
|
||||
// Extend description is below special properties / 扩展描述在特殊属性下方
|
||||
if (bAddLine)
|
||||
m_strDesc += "\\r\\r";
|
||||
else
|
||||
m_strDesc += "\\r";
|
||||
m_strDesc += szExtDesc;
|
||||
}
|
||||
|
||||
protected void AddExpireTimeDesc()
|
||||
@@ -1401,6 +1567,182 @@ namespace BrewMonster.Scripts.Managers
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get extended description text for UI display.
|
||||
/// This method mirrors AddExtDescText() logic but returns a string instead of modifying m_strDesc.
|
||||
/// 此方法镜像AddExtDescText()逻辑,但返回字符串而不是修改m_strDesc
|
||||
/// </summary>
|
||||
public string GetExtendedDescText()
|
||||
{
|
||||
string result = string.Empty;
|
||||
|
||||
// Get extended description from item_ext_desc.txt using tid / 使用tid从item_ext_desc.txt获取扩展描述
|
||||
string szExtDesc = TryGetItemExtDesc();
|
||||
// Note: Original C++ had early return commented out / 注意:原始C++代码的早期返回被注释掉了
|
||||
// if (!szExtDesc || !szExtDesc[0])
|
||||
// return;
|
||||
|
||||
result += "\\r";
|
||||
|
||||
bool bAddLine = true;
|
||||
// Add special properties description / 添加特殊属性描述
|
||||
var pDescTab = EC_Game.GetItemDesc();
|
||||
// Note: ITEMDESC_COL2_BRIGHTBLUE constant - adjust based on actual string table / 注意:ITEMDESC_COL2_BRIGHTBLUE常量 - 根据实际字符串表调整
|
||||
int green = 1000; // ITEMDESC_COL2_BRIGHTBLUE placeholder - adjust this value
|
||||
|
||||
if (m_iCID != (int)InventoryClassId.ICID_GOBLIN) // goblin does not need to display these special properties / 地精不需要显示这些特殊属性
|
||||
{
|
||||
// Exact C++ logic: (PROC_NO_USER_TRASH) || (!PROC_BINDING && (PROC_DROPWHENDIE || ...))
|
||||
// 精确的C++逻辑:(PROC_NO_USER_TRASH) || (!PROC_BINDING && (PROC_DROPWHENDIE || ...))
|
||||
if ((m_iProcType & (int)ProcType.PROC_NO_USER_TRASH) != 0
|
||||
|| (!((m_iProcType & (int)ProcType.PROC_BINDING) != 0)
|
||||
&& ((m_iProcType & (int)ProcType.PROC_DROPWHENDIE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_DROPPABLE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_SELLABLE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_TRADEABLE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_DISAPEAR) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_USE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_DEADDROP) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_OFFLINE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_UNREPAIRABLE) != 0)))
|
||||
{
|
||||
bAddLine = false;
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
string szCol = pDescTab.GetWideString(green);
|
||||
if (!string.IsNullOrEmpty(szCol))
|
||||
{
|
||||
result += szCol;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: These message IDs are placeholders - adjust based on actual string table / 注意:这些消息ID是占位符 - 根据实际字符串表调整
|
||||
if ((m_iProcType & (int)ProcType.PROC_DROPWHENDIE) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_DEAD_PROTECT placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2000); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_DROPPABLE) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_DROP placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2001); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_SELLABLE) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_TRADE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2002); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_TRADEABLE) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_PLAYER_TRADE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2003); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_DISAPEAR) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_LEAVE_SCENE_DISAPEAR placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2004); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_USE) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_USE_AFTER_PICK_UP placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2005); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_DEADDROP) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_DROP_WHEN_DEAD placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2006); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_OFFLINE) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_DROP_WHEN_OFFLINE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2007); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_UNREPAIRABLE) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_UNREPAIRABLE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2008); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_NO_USER_TRASH) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_USER_TRASH placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2009); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(szExtDesc))
|
||||
return result;
|
||||
|
||||
// Extend description is below special properties / 扩展描述在特殊属性下方
|
||||
if (bAddLine)
|
||||
result += "\\r\\r";
|
||||
else
|
||||
result += "\\r";
|
||||
result += szExtDesc;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
using PerfectWorld.Scripts.Shop;
|
||||
using PerfectWorld.Scripts.Managers;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using BrewMonster.Network;
|
||||
using CSNetwork.C2SCommand;
|
||||
@@ -13,10 +14,9 @@ using CSNetwork.C2SCommand;
|
||||
public class NPCShopDetailPanel : MonoBehaviour
|
||||
{
|
||||
[Header("UI Components")]
|
||||
public TextMeshProUGUI itemNameText;
|
||||
public TextMeshProUGUI itemDescriptionText;
|
||||
public TextOutlet itemDescriptionText;
|
||||
public Image itemIconImage;
|
||||
public TextMeshProUGUI itemPriceText;
|
||||
//public TextMeshProUGUI itemPriceText;
|
||||
|
||||
[Header("Action Buttons")]
|
||||
public Button closeButton;
|
||||
@@ -55,15 +55,11 @@ public class NPCShopDetailPanel : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
// Set item name
|
||||
if (itemNameText != null)
|
||||
itemNameText.text = currentItem.name;
|
||||
|
||||
// Set item description
|
||||
if (itemDescriptionText != null)
|
||||
{
|
||||
string description = GetItemDescription((int)currentItem.id);
|
||||
itemDescriptionText.text = description;
|
||||
itemDescriptionText.Set(description);
|
||||
}
|
||||
|
||||
// Set price (use first available price)
|
||||
@@ -80,8 +76,8 @@ public class NPCShopDetailPanel : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
if (itemPriceText != null)
|
||||
itemPriceText.text = price > 0 ? $"Price: {price}" : "Price: N/A";
|
||||
// if (itemPriceText != null)
|
||||
// itemPriceText.text = price > 0 ? $"Price: {price}" : "Price: N/A";
|
||||
|
||||
// Load icon
|
||||
if (itemIconImage != null)
|
||||
@@ -114,7 +110,7 @@ public class NPCShopDetailPanel : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
string GetItemDescription(int itemId)
|
||||
string GetItemDescription(int itemId)
|
||||
{
|
||||
// First check if description is already in the item data
|
||||
if (!string.IsNullOrEmpty(currentItem.desc))
|
||||
@@ -122,27 +118,48 @@ public class NPCShopDetailPanel : MonoBehaviour
|
||||
return currentItem.desc;
|
||||
}
|
||||
|
||||
// Otherwise, build description using the same central pipeline as inventory:
|
||||
try
|
||||
// Try to use EC_IvtrEquip description for equipment items (like EC_InventoryUI does)
|
||||
try
|
||||
{
|
||||
// Create EC_IvtrEquip for equipment items - this will work for weapons and armor
|
||||
EC_IvtrEquip equipment = new EC_IvtrEquip(itemId, 0);
|
||||
|
||||
// For NPC shop items, we typically have static data only
|
||||
// Try to get description using GetNormalDesc() which works with base stats
|
||||
string equipDesc = equipment.GetNormalDesc();
|
||||
if (!string.IsNullOrEmpty(equipDesc))
|
||||
{
|
||||
EC_IvtrItem item = EC_IvtrItem.CreateItem(itemId, 0, 1);
|
||||
if (item != null)
|
||||
// Replace C++ style "\r" line separators with real newlines for TMP
|
||||
return equipDesc.Replace("\\r", "\n");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
// If EC_IvtrEquip fails, fall through to EC_IvtrItem method
|
||||
Debug.LogWarning($"[NPCShopDetailPanel] Failed to get equipment description for item {itemId}: {ex.Message}");
|
||||
}
|
||||
|
||||
// Fallback: build description using EC_IvtrItem (for non-equipment items)
|
||||
try
|
||||
{
|
||||
EC_IvtrItem item = EC_IvtrItem.CreateItem(itemId, 0, 1);
|
||||
if (item != null)
|
||||
{
|
||||
// For NPC shop, we typically have static data only, so load from local DB
|
||||
item.GetDetailDataFromLocal();
|
||||
string description = item.GetDesc();
|
||||
if (!string.IsNullOrEmpty(description))
|
||||
{
|
||||
// For NPC shop, we typically have static data only, so load from local DB
|
||||
item.GetDetailDataFromLocal();
|
||||
string description = item.GetDesc();
|
||||
if (!string.IsNullOrEmpty(description))
|
||||
{
|
||||
return description.Replace("\\r", "\n");
|
||||
}
|
||||
return description.Replace("\\r", "\n");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[NPCShopDetailPanel] Failed to get description for item {itemId}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[NPCShopDetailPanel] Failed to get description for item {itemId}: {ex.Message}");
|
||||
}
|
||||
|
||||
return "No description available.";
|
||||
return "No description available.";
|
||||
}
|
||||
|
||||
void OnCloseClicked()
|
||||
@@ -197,5 +214,25 @@ public class NPCShopDetailPanel : MonoBehaviour
|
||||
if (buyButton != null)
|
||||
buyButton.onClick.RemoveListener(OnBuyButtonClicked);
|
||||
}
|
||||
|
||||
// === Text Outlet Helper ===
|
||||
[System.Serializable]
|
||||
public class TextOutlet
|
||||
{
|
||||
[SerializeField] public Text legacy;
|
||||
[SerializeField] public TMPro.TextMeshProUGUI tmp;
|
||||
|
||||
public void Set(string value)
|
||||
{
|
||||
if (legacy != null)
|
||||
{
|
||||
legacy.text = EC_Utility.FormatForLegacyText(value ?? string.Empty);
|
||||
}
|
||||
if (tmp != null)
|
||||
{
|
||||
tmp.text = EC_Utility.FormatForTextMeshPro(value ?? string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -896,7 +896,9 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
itemNameText: {fileID: 2676848775259769377}
|
||||
itemDescriptionText: {fileID: 1509498505529622136}
|
||||
itemDescriptionText:
|
||||
legacy: {fileID: 0}
|
||||
tmp: {fileID: 1509498505529622136}
|
||||
itemIconImage: {fileID: 5729739685989188916}
|
||||
itemPriceText: {fileID: 3533247489785110134}
|
||||
closeButton: {fileID: 0}
|
||||
|
||||
@@ -1899,7 +1899,7 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 21, y: -22.97}
|
||||
m_AnchoredPosition: {x: 21, y: -0}
|
||||
m_SizeDelta: {x: 472.5032, y: 0}
|
||||
m_Pivot: {x: 0, y: 0.5}
|
||||
--- !u!222 &2043307214318211948
|
||||
@@ -1930,7 +1930,7 @@ MonoBehaviour:
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text: aaa
|
||||
m_text:
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 369c2e14814cc9a4b8e3ad4e37769134, type: 2}
|
||||
m_sharedMaterial: {fileID: 9092487103257209053, guid: 369c2e14814cc9a4b8e3ad4e37769134, type: 2}
|
||||
@@ -4442,6 +4442,7 @@ RectTransform:
|
||||
m_Children:
|
||||
- {fileID: 9106031791145292554}
|
||||
- {fileID: 1001152567372181051}
|
||||
- {fileID: 1333165094145940333}
|
||||
m_Father: {fileID: 5834405183358786743}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
@@ -7163,6 +7164,157 @@ MonoBehaviour:
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!1 &5371522206622176611
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1333165094145940333}
|
||||
- component: {fileID: 7370426642012978972}
|
||||
- component: {fileID: 37862130938576806}
|
||||
- component: {fileID: 9183113038478938762}
|
||||
m_Layer: 5
|
||||
m_Name: Text (TMP) (2)
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1333165094145940333
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5371522206622176611}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7205431771786927886}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 21, y: -57.98}
|
||||
m_SizeDelta: {x: 465.7476, y: 0}
|
||||
m_Pivot: {x: 0, y: 0.5}
|
||||
--- !u!222 &7370426642012978972
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5371522206622176611}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &37862130938576806
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5371522206622176611}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text:
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 369c2e14814cc9a4b8e3ad4e37769134, type: 2}
|
||||
m_sharedMaterial: {fileID: 9092487103257209053, guid: 369c2e14814cc9a4b8e3ad4e37769134, type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_enableVertexGradient: 0
|
||||
m_colorMode: 3
|
||||
m_fontColorGradient:
|
||||
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_fontColorGradientPreset: {fileID: 0}
|
||||
m_spriteAsset: {fileID: 0}
|
||||
m_tintAllSprites: 0
|
||||
m_StyleSheet: {fileID: 0}
|
||||
m_TextStyleHashCode: -1183493901
|
||||
m_overrideHtmlColors: 0
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 36
|
||||
m_fontSizeBase: 36
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 0
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 72
|
||||
m_fontStyle: 0
|
||||
m_HorizontalAlignment: 1
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 0
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
m_horizontalMapping: 0
|
||||
m_verticalMapping: 0
|
||||
m_uvLineOffset: 0
|
||||
m_geometrySortingOrder: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_VertexBufferAutoSizeReduction: 0
|
||||
m_useMaxVisibleDescender: 1
|
||||
m_pageToDisplay: 1
|
||||
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_isUsingLegacyAnimationComponent: 0
|
||||
m_isVolumetricText: 0
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!114 &9183113038478938762
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5371522206622176611}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_HorizontalFit: 0
|
||||
m_VerticalFit: 2
|
||||
--- !u!1 &5460797107099608431
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -8046,13 +8198,13 @@ MonoBehaviour:
|
||||
hideDetailOnStart: 1
|
||||
nameText:
|
||||
legacy: {fileID: 0}
|
||||
tmp: {fileID: 7082730707602873357}
|
||||
tmp: {fileID: 0}
|
||||
descriptionText:
|
||||
legacy: {fileID: 0}
|
||||
tmp: {fileID: 6020258894941961325}
|
||||
extendedDescText:
|
||||
legacy: {fileID: 0}
|
||||
tmp: {fileID: 0}
|
||||
tmp: {fileID: 37862130938576806}
|
||||
equipButton: {fileID: 472698755110594484}
|
||||
dropButton: {fileID: 540159372834342487}
|
||||
autoRefresh: 1
|
||||
@@ -11506,7 +11658,7 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 21, y: -68.909996}
|
||||
m_AnchoredPosition: {x: 21, y: -28.989998}
|
||||
m_SizeDelta: {x: 465.7476, y: 0}
|
||||
m_Pivot: {x: 0, y: 0.5}
|
||||
--- !u!222 &5347950336050242333
|
||||
|
||||
@@ -1943,9 +1943,9 @@ RectTransform:
|
||||
- {fileID: 4504331075840543341}
|
||||
m_Father: {fileID: 1361524257611413148}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 108.9562, y: -31.05}
|
||||
m_SizeDelta: {x: 179.9124, y: 68.0217}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &8804506040386004496
|
||||
@@ -5768,9 +5768,9 @@ RectTransform:
|
||||
- {fileID: 2027606699309904338}
|
||||
m_Father: {fileID: 1361524257611413148}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 468.781, y: -31.05}
|
||||
m_SizeDelta: {x: 179.9124, y: 68.0217}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6741821173640675138
|
||||
@@ -18122,9 +18122,9 @@ RectTransform:
|
||||
- {fileID: 911293677621153352}
|
||||
m_Father: {fileID: 1361524257611413148}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 288.8686, y: -31.05}
|
||||
m_SizeDelta: {x: 179.9124, y: 68.0217}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5623009994815814977
|
||||
|
||||
@@ -54,35 +54,74 @@ namespace BrewMonster
|
||||
|
||||
protected bool LoadANSIStrings(string resourceName)
|
||||
{
|
||||
TextAsset textAsset = Resources.Load<TextAsset>(resourceName);
|
||||
if (textAsset == null)
|
||||
try
|
||||
{
|
||||
Debug.LogError($"[CECStringTab] Resource not found: {resourceName}");
|
||||
// If a real file path is provided (e.g. StreamingAssets), read directly from disk.
|
||||
// 如果提供的是实际文件路径(例如 StreamingAssets),则直接从磁盘读取。
|
||||
if (File.Exists(resourceName))
|
||||
{
|
||||
// ANSI tables are in CP936 in original PW; keep using CP936 decoder.
|
||||
// 原版完美世界的ANSI表是CP936编码,这里保持一致。
|
||||
byte[] bytes = File.ReadAllBytes(resourceName);
|
||||
string content = ByteToStringUtils.ByteArrayToCP936String(bytes);
|
||||
using var srFile = new StringReader(content);
|
||||
return ParseIntoDict(srFile, isWide: false);
|
||||
}
|
||||
|
||||
// Fallback to Resources (old behaviour).
|
||||
// 回退到 Resources 加载(旧行为)。
|
||||
TextAsset textAsset = Resources.Load<TextAsset>(resourceName);
|
||||
if (textAsset == null)
|
||||
{
|
||||
Debug.LogError($"[CECStringTab] Resource not found: {resourceName}");
|
||||
return false;
|
||||
}
|
||||
|
||||
string resContent = ByteToStringUtils.ByteArrayToCP936String(textAsset.bytes);
|
||||
using var srRes = new StringReader(resContent);
|
||||
return ParseIntoDict(srRes, isWide: false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[CECStringTab] LoadANSIStrings failed for '{resourceName}': {e}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Giải mã bytes -> string (ANSI: dùng Encoding.Default)
|
||||
string content = ByteToStringUtils.ByteArrayToCP936String(textAsset.bytes);
|
||||
using var sr = new StringReader(content);
|
||||
return ParseIntoDict(sr, isWide: false);
|
||||
}
|
||||
|
||||
protected bool LoadWideStrings(string resourceName)
|
||||
{
|
||||
TextAsset textAsset = Resources.Load<TextAsset>(resourceName);
|
||||
if (textAsset == null)
|
||||
try
|
||||
{
|
||||
Debug.LogError($"[CECStringTab] Resource not found: {resourceName}");
|
||||
// Support absolute / relative filesystem paths (e.g. StreamingAssets/configs/*.txt)
|
||||
// 支持文件系统路径(例如 StreamingAssets/configs/*.txt)
|
||||
if (File.Exists(resourceName))
|
||||
{
|
||||
// String tables we ship in StreamingAssets are saved as UTF-8.
|
||||
// 我们放在 StreamingAssets 里的字符串表保存为 UTF-8。
|
||||
string content = File.ReadAllText(resourceName, Encoding.UTF8);
|
||||
using var srFile = new StringReader(content);
|
||||
return ParseIntoDict(srFile, isWide: true);
|
||||
}
|
||||
|
||||
// Fallback to Resources-based loading (old behaviour)
|
||||
// 回退到基于 Resources 的加载(旧行为)
|
||||
TextAsset textAsset = Resources.Load<TextAsset>(resourceName);
|
||||
if (textAsset == null)
|
||||
{
|
||||
Debug.LogError($"[CECStringTab] Resource not found: {resourceName}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unity TextAsset.text is already UTF-8 decoded.
|
||||
string resContent = textAsset.text;
|
||||
using var srRes = new StringReader(resContent);
|
||||
return ParseIntoDict(srRes, isWide: true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[CECStringTab] LoadWideStrings failed for '{resourceName}': {e}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unity TextAsset mặc định đã decode text UTF8 -> textAsset.text
|
||||
// nhưng để chắc chắn BOM/Unicode thì đọc từ bytes
|
||||
string content;
|
||||
content = textAsset.text;
|
||||
|
||||
using var sr = new StringReader(content);
|
||||
return ParseIntoDict(sr, isWide: true);
|
||||
}
|
||||
|
||||
private static Encoding DetectEncoding(byte[] bom)
|
||||
@@ -183,6 +222,18 @@ namespace BrewMonster
|
||||
|
||||
private void PutString(int id, string value, bool isWide)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return;
|
||||
|
||||
// Many PW string tables wrap the payload in double quotes, e.g.:
|
||||
// 12345 "^ffcb4aSome text\rMore text"
|
||||
// Strip a single leading/trailing quote pair to avoid showing raw quotes in UI.
|
||||
// 许多字符串表会用双引号包裹内容,这里去掉首尾各一个引号以避免在UI中显示多余的引号。
|
||||
if (value.Length >= 2 && value[0] == '"' && value[value.Length - 1] == '"')
|
||||
{
|
||||
value = value.Substring(1, value.Length - 2);
|
||||
}
|
||||
|
||||
if (isWide) m_WStrTab[id] = value;
|
||||
else m_AStrTab[id] = value;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user