Add log data
This commit is contained in:
@@ -763,27 +763,245 @@ namespace BrewMonster.UI
|
||||
else if (DataType == DATA_TYPE.DT_NPC_MAKE_SERVICE)
|
||||
{
|
||||
NPC_MAKE_SERVICE pService = (NPC_MAKE_SERVICE)pData;
|
||||
m_pLst_Main.AddString(strText + Encoding.Unicode.GetString(MemoryMarshal.AsBytes<ushort>(pService.name)));
|
||||
string serviceName = Encoding.Unicode.GetString(MemoryMarshal.AsBytes<ushort>(pService.name));
|
||||
m_pLst_Main.AddString(strText + serviceName);
|
||||
|
||||
// Log NPC_MAKE_SERVICE data
|
||||
BMLogger.Log($"NPC_MAKE_SERVICE detected - ServiceID: {a_uiService[i]}, MakeServiceID: {pService.id}, Name: {serviceName}, MakeSkillID: {pService.id_make_skill}, ProduceType: {pService.produce_type}");
|
||||
|
||||
// Log pages data
|
||||
if (pService.pages != null)
|
||||
{
|
||||
for (int pageIdx = 0; pageIdx < pService.pages.Length; pageIdx++)
|
||||
{
|
||||
var page = pService.pages[pageIdx];
|
||||
string pageTitle = Encoding.Unicode.GetString(MemoryMarshal.AsBytes<ushort>(page.page_title));
|
||||
// Trim null characters and whitespace from page title
|
||||
pageTitle = pageTitle?.TrimEnd('\0', ' ', '\t', '\r', '\n') ?? "";
|
||||
|
||||
// Collect all non-zero goods IDs with their names
|
||||
// Note: id_goods contains RECIPE IDs, not item IDs
|
||||
List<string> goodsInfo = new List<string>();
|
||||
if (page.id_goods != null)
|
||||
{
|
||||
for (int goodsIdx = 0; goodsIdx < page.id_goods.Length; goodsIdx++)
|
||||
{
|
||||
uint recipeId = page.id_goods[goodsIdx];
|
||||
if (recipeId != 0)
|
||||
{
|
||||
// Get recipe data, output item, and materials
|
||||
string outputItemInfo = "";
|
||||
List<string> materialInfo = new List<string>();
|
||||
try
|
||||
{
|
||||
var edm = ElementDataManProvider.GetElementDataMan();
|
||||
if (edm == null)
|
||||
{
|
||||
// ElementDataMan is null, skip
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try recipe space first
|
||||
DATA_TYPE dt = DATA_TYPE.DT_INVALID;
|
||||
object recipeData = edm.get_data_ptr(recipeId, ID_SPACE.ID_SPACE_RECIPE, ref dt);
|
||||
|
||||
// Check if we got recipe data - sometimes dt is DT_INVALID but data is still RECIPE_ESSENCE
|
||||
RECIPE_ESSENCE? recipe = null;
|
||||
if (recipeData != null && recipeData is RECIPE_ESSENCE)
|
||||
{
|
||||
recipe = (RECIPE_ESSENCE)recipeData;
|
||||
}
|
||||
else if (recipeData != null && dt == DATA_TYPE.DT_RECIPE_ESSENCE)
|
||||
{
|
||||
recipe = (RECIPE_ESSENCE)recipeData;
|
||||
}
|
||||
|
||||
if (recipe.HasValue)
|
||||
{
|
||||
RECIPE_ESSENCE recipeValue = recipe.Value;
|
||||
|
||||
// Get output item from first target (main output)
|
||||
if (recipeValue.targets != null && recipeValue.targets.Length > 0)
|
||||
{
|
||||
if (recipeValue.targets[0].id_to_make != 0)
|
||||
{
|
||||
uint outputItemId = recipeValue.targets[0].id_to_make;
|
||||
try
|
||||
{
|
||||
EC_IvtrItem pItem = EC_IvtrItem.CreateItem((int)outputItemId, 0, 1);
|
||||
if (pItem != null)
|
||||
{
|
||||
string outputName = pItem.GetName();
|
||||
outputItemInfo = $"{outputItemId} ({outputName})";
|
||||
}
|
||||
else
|
||||
{
|
||||
outputItemInfo = $"{outputItemId} (unknown)";
|
||||
}
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
outputItemInfo = $"{outputItemId} (error: {ex2.Message})";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BMLogger.LogWarning($" Recipe {recipeId}: First target id_to_make is 0");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BMLogger.LogWarning($" Recipe {recipeId}: targets is null or empty");
|
||||
}
|
||||
|
||||
// Get all materials
|
||||
if (recipeValue.materials != null)
|
||||
{
|
||||
for (int matIdx = 0; matIdx < recipeValue.materials.Length; matIdx++)
|
||||
{
|
||||
var material = recipeValue.materials[matIdx];
|
||||
if (material.id != 0 && material.num > 0)
|
||||
{
|
||||
string materialName = "";
|
||||
try
|
||||
{
|
||||
EC_IvtrItem matItem = EC_IvtrItem.CreateItem((int)material.id, 0, 1);
|
||||
if (matItem != null)
|
||||
{
|
||||
materialName = matItem.GetName();
|
||||
}
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
materialName = $"error: {ex2.Message}";
|
||||
}
|
||||
|
||||
string matEntry = !string.IsNullOrEmpty(materialName)
|
||||
? $"{material.id} ({materialName}) x{material.num}"
|
||||
: $"{material.id} (unknown) x{material.num}";
|
||||
materialInfo.Add(matEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BMLogger.LogWarning($" Recipe {recipeId}: materials is null");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
BMLogger.LogWarning($" Failed to get data for recipe ID {recipeId}: {ex.Message}\n{ex.StackTrace}");
|
||||
}
|
||||
|
||||
// Format: "RecipeID -> Output: ID (Name) | Materials: ID (Name) xCount, ..."
|
||||
string goodsEntry = $"Recipe {recipeId}";
|
||||
if (!string.IsNullOrEmpty(outputItemInfo))
|
||||
{
|
||||
goodsEntry += $" -> Output: {outputItemInfo}";
|
||||
}
|
||||
else
|
||||
{
|
||||
goodsEntry += " -> Output: (none)";
|
||||
}
|
||||
if (materialInfo.Count > 0)
|
||||
{
|
||||
goodsEntry += $" | Materials: {string.Join(", ", materialInfo)}";
|
||||
}
|
||||
else
|
||||
{
|
||||
goodsEntry += " | Materials: (none)";
|
||||
}
|
||||
goodsInfo.Add(goodsEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Log page if it has a title or has goods
|
||||
if (!string.IsNullOrEmpty(pageTitle) || goodsInfo.Count > 0)
|
||||
{
|
||||
string goodsList = goodsInfo.Count > 0 ? string.Join(", ", goodsInfo) : "";
|
||||
BMLogger.Log($" Page[{pageIdx}]: Title=\"{pageTitle}\", Goods=[{goodsList}], GoodsCount={goodsInfo.Count}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (DataType == DATA_TYPE.DT_NPC_DECOMPOSE_SERVICE)
|
||||
{
|
||||
//NPC_DECOMPOSE_SERVICE pService = (NPC_DECOMPOSE_SERVICE)pData;
|
||||
//CECHostPlayer pHost = GetHostPlayer();
|
||||
//CECSkill pSkill;
|
||||
//int j = 0;
|
||||
//for (j = 0; j < pHost.GetPassiveSkillNum(); j++)
|
||||
//{
|
||||
// pSkill = pHost.GetPassiveSkillByIndex(j);
|
||||
// if ((pSkill.GetType() == CECSkill::TYPE_LIVE ||
|
||||
// pSkill.GetType() == CECSkill::TYPE_PRODUCE) &&
|
||||
// (int)pService.id_decompose_skill == pSkill.GetSkillID())
|
||||
// {
|
||||
// m_pLst_Main.AddString(strText + pService.name);
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
//if (j == pHost.GetPassiveSkillNum())
|
||||
// continue;
|
||||
NPC_DECOMPOSE_SERVICE pService = (NPC_DECOMPOSE_SERVICE)pData;
|
||||
string serviceName = Encoding.Unicode.GetString(MemoryMarshal.AsBytes<ushort>(pService.name));
|
||||
|
||||
// Log NPC_DECOMPOSE_SERVICE data
|
||||
BMLogger.Log($"NPC_DECOMPOSE_SERVICE detected - ServiceID: {a_uiService[i]}, DecomposeServiceID: {pService.id}, Name: {serviceName}, DecomposeSkillID: {pService.id_decompose_skill}");
|
||||
|
||||
CECHostPlayer hostPlayer = GetHostPlayer();
|
||||
bool hasRequiredSkill = false;
|
||||
|
||||
// TODO: Implement proper skill check when GetPassiveSkillNum() and GetPassiveSkillByIndex() are available
|
||||
// For now, we'll use reflection to access private GetPassiveSkillByID method or implement a workaround
|
||||
// The C++ code checks if player has the required decompose skill (TYPE_LIVE or TYPE_PRODUCE)
|
||||
try
|
||||
{
|
||||
// Try using reflection to access private GetPassiveSkillByID method
|
||||
var method = typeof(CECHostPlayer).GetMethod("GetPassiveSkillByID",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
|
||||
if (method != null)
|
||||
{
|
||||
var pSkill = method.Invoke(hostPlayer, new object[] { (int)pService.id_decompose_skill, false }) as CECSkill;
|
||||
if (pSkill != null)
|
||||
{
|
||||
int skillType = pSkill.GetType();
|
||||
int skillID = pSkill.GetSkillID();
|
||||
|
||||
BMLogger.Log($" Found skill by ID (via reflection): ID={skillID}, Type={skillType}");
|
||||
|
||||
// Check if this is the required decompose skill with correct type
|
||||
if ((skillType == (int)CECSkill.SkillType.TYPE_LIVE ||
|
||||
skillType == (int)CECSkill.SkillType.TYPE_PRODUCE) &&
|
||||
(int)pService.id_decompose_skill == skillID)
|
||||
{
|
||||
hasRequiredSkill = true;
|
||||
BMLogger.Log($" Skill check PASSED - Player has required decompose skill (ID: {pService.id_decompose_skill}, Type: {skillType})");
|
||||
m_pLst_Main.AddString(strText + serviceName);
|
||||
m_pLst_Main.SetItemData(m_pLst_Main.GetCount() - 1, a_uiService[i]);
|
||||
m_pLst_Main.SetItemDataPtr(m_pLst_Main.GetCount() - 1, pData);
|
||||
}
|
||||
else
|
||||
{
|
||||
BMLogger.Log($" Skill found but type mismatch - Expected TYPE_LIVE or TYPE_PRODUCE, got {skillType}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BMLogger.Log($" Skill check FAILED - Player does not have required decompose skill (ID: {pService.id_decompose_skill})");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BMLogger.LogWarning($" GetPassiveSkillByID method not found via reflection - skill check cannot be performed");
|
||||
// For now, show the service anyway for logging/debugging purposes
|
||||
// TODO: Remove this when proper skill check is implemented
|
||||
hasRequiredSkill = true;
|
||||
m_pLst_Main.AddString(strText + serviceName);
|
||||
m_pLst_Main.SetItemData(m_pLst_Main.GetCount() - 1, a_uiService[i]);
|
||||
m_pLst_Main.SetItemDataPtr(m_pLst_Main.GetCount() - 1, pData);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
BMLogger.LogError($"Error checking decompose skill: {ex.Message}");
|
||||
BMLogger.LogError($"Stack trace: {ex.StackTrace}");
|
||||
// For debugging: show service anyway
|
||||
hasRequiredSkill = true;
|
||||
m_pLst_Main.AddString(strText + serviceName);
|
||||
m_pLst_Main.SetItemData(m_pLst_Main.GetCount() - 1, a_uiService[i]);
|
||||
m_pLst_Main.SetItemDataPtr(m_pLst_Main.GetCount() - 1, pData);
|
||||
}
|
||||
|
||||
if (!hasRequiredSkill)
|
||||
continue;
|
||||
}
|
||||
else if (DataType == DATA_TYPE.DT_NPC_IDENTIFY_SERVICE)
|
||||
{
|
||||
@@ -3024,11 +3242,22 @@ namespace BrewMonster.UI
|
||||
else if (DataType == DATA_TYPE.DT_NPC_MAKE_SERVICE)
|
||||
{
|
||||
NPC_MAKE_SERVICE pService = (NPC_MAKE_SERVICE)pData;
|
||||
string serviceName = Encoding.Unicode.GetString(MemoryMarshal.AsBytes<ushort>(pService.name));
|
||||
|
||||
// Log NPC_MAKE_SERVICE data when selected
|
||||
BMLogger.Log($"SelectListItem - NPC_MAKE_SERVICE selected - ServiceID: {iService}, MakeServiceID: {pService.id}, Name: {serviceName}, MakeSkillID: {pService.id_make_skill}, ProduceType: {pService.produce_type}");
|
||||
|
||||
idFunction = (int)SERVICE_TYPE.NPC_MAKE;
|
||||
}
|
||||
else if (DataType == DATA_TYPE.DT_NPC_DECOMPOSE_SERVICE)
|
||||
{
|
||||
NPC_DECOMPOSE_SERVICE pService = (NPC_DECOMPOSE_SERVICE)pData;
|
||||
string serviceName = Encoding.Unicode.GetString(MemoryMarshal.AsBytes<ushort>(pService.name));
|
||||
|
||||
// Log NPC_DECOMPOSE_SERVICE data when selected
|
||||
BMLogger.Log($"SelectListItem - NPC_DECOMPOSE_SERVICE selected - ServiceID: {iService}, DecomposeServiceID: {pService.id}, Name: {serviceName}, DecomposeSkillID: {pService.id_decompose_skill}");
|
||||
BMLogger.Log($" Note: This decompose service is being treated as idFunction={SERVICE_TYPE.NPC_DECOMPOSE}");
|
||||
|
||||
idFunction = (int)SERVICE_TYPE.NPC_DECOMPOSE;
|
||||
}
|
||||
else if (DataType == DATA_TYPE.DT_NPC_IDENTIFY_SERVICE)
|
||||
@@ -3216,38 +3445,79 @@ namespace BrewMonster.UI
|
||||
}
|
||||
else if (idFunction == (int)SERVICE_TYPE.NPC_MAKE)
|
||||
{
|
||||
// C++
|
||||
//NPC_MAKE_SERVICE pMake = (NPC_MAKE_SERVICE)pData;
|
||||
//if (pMake.produce_type == 2)
|
||||
// pShow1 = m_pAUIManager.GetDialog("Win_Produce1");
|
||||
//else
|
||||
// pShow1 = m_pAUIManager.GetDialog("Win_Produce");
|
||||
//GetGameUIMan().m_pDlgProduce = (CDlgProduce*)pShow1;
|
||||
//GetHostPlayer().PrepareNPCService(iService);
|
||||
//pShow1.SetDataPtr(pMake, "ptr_NPC_MAKE_SERVICE");
|
||||
//if (pMake.produce_type == 1 ||
|
||||
// pMake.produce_type == 3 ||
|
||||
// pMake.produce_type == 4 ||
|
||||
// pMake.produce_type == 5)
|
||||
// GetGameUIMan().m_pDlgProduce.ClearMaterial();
|
||||
//pShow2 = m_pAUIManager.GetDialog("Win_Inventory");
|
||||
//GetGameUIMan().m_pDlgProduce.UpdateProduce(1, 0);
|
||||
NPC_MAKE_SERVICE pMake = (NPC_MAKE_SERVICE)pData;
|
||||
|
||||
// NPC_MAKE_SERVICE pMake = (NPC_MAKE_SERVICE)pData;
|
||||
// if (pMake.produce_type == 2)
|
||||
// pShow1 = m_pAUIManager.GetDialog("Win_Produce1");
|
||||
// else
|
||||
// pShow1 = m_pAUIManager.GetDialog("Win_Produce");
|
||||
// GetGameUIMan().m_pDlgProduce = (CDlgProduce*)pShow1;
|
||||
// GetHostPlayer().PrepareNPCService(iService);
|
||||
// pShow1.SetDataPtr(pMake, "ptr_NPC_MAKE_SERVICE");
|
||||
// if (pMake.produce_type == 1 ||
|
||||
// pMake.produce_type == 3 ||
|
||||
// pMake.produce_type == 4 ||
|
||||
// pMake.produce_type == 5)
|
||||
// GetGameUIMan().m_pDlgProduce.ClearMaterial();
|
||||
// pShow2 = m_pAUIManager.GetDialog("Win_Inventory");
|
||||
// GetGameUIMan().m_pDlgProduce.UpdateProduce(1, 0);
|
||||
BMLogger.Log($"PopupCorrespondingServiceDialog - NPC_MAKE: produce_type={pMake.produce_type}, MakeSkillID={pMake.id_make_skill}");
|
||||
|
||||
// Dialog loading commented out - Win_Produce dialog not yet implemented
|
||||
// Determine which dialog to use based on produce_type
|
||||
//string dialogName = (pMake.produce_type == 2) ? "Win_Produce1" : "Win_Produce";
|
||||
//pShow1 = m_pAUIManager.GetDialog(dialogName);
|
||||
|
||||
//if (pShow1 == null)
|
||||
//{
|
||||
// BMLogger.LogError($"NPC_MAKE: Dialog '{dialogName}' not found! Service may not work correctly.");
|
||||
// // Try alternative dialog name or create placeholder
|
||||
// // For now, just log the error and continue
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// // Get or set DlgProduce reference (if it exists)
|
||||
// // GetGameUIMan().m_pDlgProduce = (CDlgProduce*)pShow1;
|
||||
//
|
||||
// // Prepare NPC service
|
||||
// try
|
||||
// {
|
||||
// GetHostPlayer().PrepareNPCService(iService);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// BMLogger.LogError($"NPC_MAKE: Error calling PrepareNPCService: {ex.Message}");
|
||||
// }
|
||||
//
|
||||
// // Set data pointer
|
||||
// try
|
||||
// {
|
||||
// pShow1.SetDataPtr(pMake, "ptr_NPC_MAKE_SERVICE");
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// BMLogger.LogError($"NPC_MAKE: Error setting data pointer: {ex.Message}");
|
||||
// }
|
||||
//
|
||||
// // Clear material for certain produce types
|
||||
// if (pMake.produce_type == 1 ||
|
||||
// pMake.produce_type == 3 ||
|
||||
// pMake.produce_type == 4 ||
|
||||
// pMake.produce_type == 5)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// // GetGameUIMan().m_pDlgProduce.ClearMaterial();
|
||||
// // Note: ClearMaterial() will be called when DlgProduce is implemented
|
||||
// BMLogger.Log($"NPC_MAKE: Should clear material for produce_type={pMake.produce_type}");
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// BMLogger.LogError($"NPC_MAKE: Error clearing material: {ex.Message}");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Get inventory dialog
|
||||
// pShow2 = m_pAUIManager.GetDialog("Win_Inventory");
|
||||
//
|
||||
// // Update produce dialog
|
||||
// try
|
||||
// {
|
||||
// // GetGameUIMan().m_pDlgProduce.UpdateProduce(1, 0);
|
||||
// // Note: UpdateProduce() will be called when DlgProduce is implemented
|
||||
// BMLogger.Log($"NPC_MAKE: Should call UpdateProduce(1, 0)");
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// BMLogger.LogError($"NPC_MAKE: Error updating produce: {ex.Message}");
|
||||
// }
|
||||
//}
|
||||
}
|
||||
else if (idFunction == (int)SERVICE_TYPE.NPC_DECOMPOSE)
|
||||
{
|
||||
@@ -3535,10 +3805,10 @@ namespace BrewMonster.UI
|
||||
else
|
||||
{
|
||||
EC_IvtrItem pItem = EC_IvtrItem.CreateItem((int)pService.storage_open_item, 0, 1);
|
||||
string szMsg;
|
||||
// cannot open storage task
|
||||
m_pLst_Main.ResetContent();
|
||||
//m_pTxt_Content.SetText(bTaskNPC ? pCurNPCEssence.Value.hello_msg : szMsg.Format(GetStringFromTable(984), pItem.GetName()));
|
||||
//string szMsg = string.Format(GetStringFromTable(984), pItem.GetName());
|
||||
//m_pTxt_Content.SetText(bTaskNPC ? Encoding.Unicode.GetString(MemoryMarshal.AsBytes<ushort>(pCurNPCEssence.Value.hello_msg)) : szMsg);
|
||||
//SetData(NPC_DIALOG.NPC_DIALOG_TASK_LIST, "");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user