Merge branch 'develop' of https://git.brew.monster/Unity/perfect-world-unity into update-in-game
This commit is contained in:
@@ -27,3 +27,5 @@ MonoBehaviour:
|
||||
prefab: {fileID: 977375840943150650, guid: 51bad2e6d1ec69a4683135ce85288faa, type: 3}
|
||||
- id: Win_Hpmpxp
|
||||
prefab: {fileID: 6032603119232429246, guid: 8350aa55906d08448bb47e10a473ca61, type: 3}
|
||||
- id: Win_Produce
|
||||
prefab: {fileID: 5750242998044155948, guid: ecf0d8daf08db6f4a8d94a4bb07847ec, type: 3}
|
||||
|
||||
@@ -1447,6 +1447,13 @@ namespace CSNetwork.S2CCommand
|
||||
public int idTask;
|
||||
}
|
||||
|
||||
public struct NPCSevMakeItemCONTENT
|
||||
{
|
||||
public int idSkill;
|
||||
public int idItem;
|
||||
public uint dwCount;
|
||||
}
|
||||
|
||||
public struct cmd_sevnpc_serve2
|
||||
{
|
||||
public int service_type;
|
||||
|
||||
@@ -686,6 +686,25 @@ namespace CSNetwork.C2SCommand
|
||||
|
||||
return octets;
|
||||
}
|
||||
|
||||
public static Octets CreateNPCSevMakeItemCmd(int idSkill, int idItem, uint dwCount)
|
||||
{
|
||||
var cmd = new cmd_sevnpc_serve
|
||||
{
|
||||
service_type = NPC_service_type.GP_NPCSEV_MAKEITEM,
|
||||
len = (uint)Marshal.SizeOf<NPCSevMakeItemCONTENT>()
|
||||
};
|
||||
|
||||
NPCSevMakeItemCONTENT content = new NPCSevMakeItemCONTENT()
|
||||
{
|
||||
idSkill = idSkill,
|
||||
idItem = idItem,
|
||||
dwCount = dwCount
|
||||
};
|
||||
|
||||
return SerializeCommand(CommandID.SEVNPC_SERVE, cmd, content);
|
||||
}
|
||||
|
||||
public static Octets CreateEmoteActionCmd(int wPose)
|
||||
{
|
||||
cmd_emote_action pCmd = new cmd_emote_action()
|
||||
|
||||
@@ -1369,6 +1369,30 @@ namespace CSNetwork.GPDataType
|
||||
public byte byPackage;
|
||||
public byte bySlot;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_produce_start
|
||||
{
|
||||
public ushort use_time;
|
||||
public ushort count;
|
||||
public int type;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_produce_once
|
||||
{
|
||||
public int type;
|
||||
public uint amount;
|
||||
public uint slot_amount;
|
||||
public byte where; // Which package: 0 standard, 2 trash, 1 equip
|
||||
public byte index; // Which slot in that package
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_produce_null
|
||||
{
|
||||
public int type;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct info_matter
|
||||
{
|
||||
|
||||
@@ -512,7 +512,7 @@ namespace CSNetwork
|
||||
break;
|
||||
case CommandID.PICKUP_ITEM:
|
||||
case CommandID.HOST_OBTAIN_ITEM:
|
||||
// case CommandID.PRODUCE_ONCE:
|
||||
case CommandID.PRODUCE_ONCE:
|
||||
case CommandID.TASK_DELIVER_ITEM:
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_PICKUPITEM, (int)MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf,
|
||||
pCmdHeader);
|
||||
@@ -807,6 +807,13 @@ namespace CSNetwork
|
||||
case CommandID.FLYSWORD_TIME:
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_FLYSWORDTIME, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
|
||||
break;
|
||||
case CommandID.PRODUCE_START:
|
||||
case CommandID.PRODUCE_END:
|
||||
case CommandID.PRODUCE_NULL:
|
||||
// Post MSG_HST_PRODUCEITEM message with command ID as parameter (matches C++ behavior)
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_PRODUCEITEM, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1254,6 +1261,12 @@ namespace CSNetwork
|
||||
gamedatasend.Data = C2SCommandFactory.CreateNPCSevWaypointCmd(NPC_service_type.GP_NPCSEV_WAYPOINT, 0);
|
||||
SendProtocol(gamedatasend);
|
||||
}
|
||||
public void c2s_SendCmdNPCSevMakeItem(int idSkill, int idItem, uint dwCount)
|
||||
{
|
||||
gamedatasend gamedatasend = new gamedatasend();
|
||||
gamedatasend.Data = C2SCommandFactory.CreateNPCSevMakeItemCmd(idSkill, idItem, dwCount);
|
||||
SendProtocol(gamedatasend);
|
||||
}
|
||||
public void GetRoleBaseInfo(int iNumRole, List<int> aRoleIDs)
|
||||
{
|
||||
int iNumLimit = 128;
|
||||
|
||||
@@ -292,6 +292,11 @@ namespace BrewMonster.Network
|
||||
Instance._gameSession.c2s_SendCmdNPCSevWaypoint();
|
||||
}
|
||||
|
||||
public static void c2s_CmdNPCSevMakeItem(int idSkill, int idItem, uint dwCount)
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdNPCSevMakeItem(idSkill, idItem, dwCount);
|
||||
}
|
||||
|
||||
public void GetFactionInfo(int iNumFaction, int[] aFactinoIDs)
|
||||
{
|
||||
m_stubbornFactionInfoSender.Add(iNumFaction, aFactinoIDs);
|
||||
|
||||
@@ -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)
|
||||
@@ -3215,38 +3444,106 @@ 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}");
|
||||
// }
|
||||
//}
|
||||
|
||||
uint npcID = pCurNPCEssence.HasValue ? pCurNPCEssence.Value.id : 0;
|
||||
|
||||
AUIDialog dlg = m_pAUIManager.GetDialog("Win_Produce");
|
||||
DlgProduce dlgProduce = dlg as DlgProduce;
|
||||
if (dlgProduce == null)
|
||||
{
|
||||
CECGameUIMan gameUIMan = GetGameUIMan();
|
||||
DialogScriptTableObject dialogResource = gameUIMan.GetDialogResource();
|
||||
Canvas canvas = gameUIMan.GetCanvas();
|
||||
|
||||
if(dlgProduce != null && canvas != null)
|
||||
{
|
||||
GameObject ob = dialogResource.GetPrefabDialog("Win_Produce");
|
||||
if (ob != null)
|
||||
{
|
||||
dlgProduce = GameObject.Instantiate(ob, canvas.transform).GetComponent<DlgProduce>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(dlgProduce != null)
|
||||
{
|
||||
dlgProduce.Show(true);
|
||||
dlgProduce.OpenProduce(npcID);
|
||||
}
|
||||
|
||||
}
|
||||
else if (idFunction == (int)SERVICE_TYPE.NPC_DECOMPOSE)
|
||||
{
|
||||
@@ -3534,10 +3831,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, "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,609 @@
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using BrewMonster.Scripts.Task;
|
||||
using BrewMonster.UI;
|
||||
using ModelRenderer.Scripts.Common;
|
||||
using PerfectWorld.Scripts.Managers;
|
||||
using PerfectWorld.Scripts.Task;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using CSNetwork;
|
||||
using System.Text;
|
||||
using TMPro;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public class DlgProduce : AUIDialog
|
||||
{
|
||||
[Header("Produce Tabs")]
|
||||
[SerializeField] private Transform tabBtnContainer;
|
||||
[SerializeField] private GameObject tabBtnPb;
|
||||
[SerializeField] private string tabButtonTextComponentName = "Text";
|
||||
|
||||
[Header("Produce Detail")]
|
||||
[SerializeField] private Transform itemContainer;
|
||||
[SerializeField] private GameObject itemPb;
|
||||
|
||||
[Header("Material Slots")]
|
||||
[SerializeField] private List<Transform> materialSlots = new List<Transform>();
|
||||
|
||||
[Header("Result Slot")]
|
||||
[SerializeField] private Transform itemResult;
|
||||
|
||||
[Header("Item Info Panel")]
|
||||
public Transform itemInfoRoot;
|
||||
public TMPro.TextMeshProUGUI infoNameText;
|
||||
public TMPro.TextMeshProUGUI infoDescText;
|
||||
public TMPro.TextMeshProUGUI infoExtraText;
|
||||
|
||||
private NPC_MAKE_SERVICE? cachedMakeService = null;
|
||||
private int currentTabIndex = 0;
|
||||
private uint selectedRecipeId = 0; // Track the currently selected recipe
|
||||
|
||||
static readonly Color COLOR_NOT_ENOUGH = new Color32(145, 145, 145, 255);
|
||||
static readonly Color COLOR_ENOUGH = Color.white;
|
||||
|
||||
[SerializeField] private Button startProduceBtn;
|
||||
[SerializeField] private Button cancelProduceBtn;
|
||||
|
||||
public void OpenProduce(uint npcId)
|
||||
{
|
||||
if (!LoadMakeService(npcId))
|
||||
{
|
||||
Debug.LogError("[DlgProduce] LoadMakeService failed");
|
||||
return;
|
||||
}
|
||||
|
||||
selectedRecipeId = 0; // Reset selected recipe
|
||||
SetupButtonHandlers();
|
||||
CreateTabs();
|
||||
OnTabSelected(0);
|
||||
}
|
||||
|
||||
void SetupButtonHandlers()
|
||||
{
|
||||
if (startProduceBtn != null)
|
||||
{
|
||||
startProduceBtn.onClick.RemoveAllListeners();
|
||||
startProduceBtn.onClick.AddListener(OnStartProduceClicked);
|
||||
}
|
||||
|
||||
if (cancelProduceBtn != null)
|
||||
{
|
||||
cancelProduceBtn.onClick.RemoveAllListeners();
|
||||
cancelProduceBtn.onClick.AddListener(OnCancelProduceClicked);
|
||||
}
|
||||
}
|
||||
|
||||
bool LoadMakeService(uint npcId)
|
||||
{
|
||||
var edm = ElementDataManProvider.GetElementDataMan();
|
||||
if (edm == null)
|
||||
return false;
|
||||
|
||||
DATA_TYPE dt = DATA_TYPE.DT_INVALID;
|
||||
object npcData = edm.get_data_ptr(npcId, ID_SPACE.ID_SPACE_ESSENCE, ref dt);
|
||||
|
||||
if (dt != DATA_TYPE.DT_NPC_ESSENCE || npcData == null)
|
||||
return false;
|
||||
|
||||
NPC_ESSENCE npc = (NPC_ESSENCE)npcData;
|
||||
if (npc.id_make_service == 0)
|
||||
return false;
|
||||
|
||||
DATA_TYPE serviceDt = DATA_TYPE.DT_INVALID;
|
||||
object serviceData = edm.get_data_ptr(
|
||||
npc.id_make_service,
|
||||
ID_SPACE.ID_SPACE_ESSENCE,
|
||||
ref serviceDt
|
||||
);
|
||||
|
||||
if (serviceDt != DATA_TYPE.DT_NPC_MAKE_SERVICE || serviceData == null)
|
||||
return false;
|
||||
|
||||
cachedMakeService = (NPC_MAKE_SERVICE)serviceData;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CreateTabs()
|
||||
{
|
||||
ClearContainer(tabBtnContainer);
|
||||
|
||||
if (!cachedMakeService.HasValue || cachedMakeService.Value.pages == null)
|
||||
return;
|
||||
|
||||
var makeService = cachedMakeService.Value;
|
||||
|
||||
for (int pageIndex = 0; pageIndex < makeService.pages.Length; pageIndex++)
|
||||
{
|
||||
var page = makeService.pages[pageIndex];
|
||||
bool hasRecipes = false;
|
||||
if (page.id_goods != null)
|
||||
{
|
||||
foreach (uint recipeId in page.id_goods)
|
||||
{
|
||||
if (recipeId != 0)
|
||||
{
|
||||
hasRecipes = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasRecipes)
|
||||
continue;
|
||||
|
||||
GameObject tabObj = Instantiate(tabBtnPb, tabBtnContainer);
|
||||
tabObj.name = $"ProduceTab_Page_{pageIndex}";
|
||||
tabObj.SetActive(true);
|
||||
|
||||
string pageTitle = ByteToStringUtils.UshortArrayToUnicodeString(page.page_title);
|
||||
if (string.IsNullOrWhiteSpace(pageTitle))
|
||||
pageTitle = $"Page {pageIndex + 1}";
|
||||
|
||||
TMPro.TextMeshProUGUI tabTMP = null;
|
||||
TextMeshProUGUI tabText = null;
|
||||
|
||||
Transform textTf = tabObj.transform.Find(tabButtonTextComponentName);
|
||||
if (textTf != null)
|
||||
{
|
||||
tabTMP = textTf.GetComponent<TMPro.TextMeshProUGUI>();
|
||||
if (tabTMP == null)
|
||||
{
|
||||
tabText = textTf.GetComponent<TextMeshProUGUI>();
|
||||
}
|
||||
}
|
||||
|
||||
if (tabTMP == null && tabText == null)
|
||||
{
|
||||
tabTMP = tabObj.GetComponentInChildren<TMPro.TextMeshProUGUI>();
|
||||
if(tabTMP == null)
|
||||
{
|
||||
tabText = tabObj.GetComponentInChildren<TextMeshProUGUI>();
|
||||
}
|
||||
}
|
||||
|
||||
if(tabTMP != null)
|
||||
tabTMP.text = pageTitle;
|
||||
else if(tabText != null)
|
||||
tabText.text = pageTitle;
|
||||
|
||||
Button btn = tabObj.GetComponent<Button>();
|
||||
if(btn == null)
|
||||
btn = tabObj.GetComponentInChildren<Button>();
|
||||
|
||||
if(btn != null)
|
||||
{
|
||||
int capturedIndex = pageIndex;
|
||||
btn.onClick.AddListener(() => OnTabSelected(capturedIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnTabSelected(int index)
|
||||
{
|
||||
currentTabIndex = index;
|
||||
RefreshSubItemList();
|
||||
}
|
||||
|
||||
void RefreshSubItemList()
|
||||
{
|
||||
ClearContainer(itemContainer);
|
||||
|
||||
if (!cachedMakeService.HasValue)
|
||||
return;
|
||||
|
||||
var service = cachedMakeService.Value;
|
||||
if (service.pages == null || currentTabIndex >= service.pages.Length)
|
||||
return;
|
||||
|
||||
var page = service.pages[currentTabIndex];
|
||||
if (page.id_goods == null)
|
||||
return;
|
||||
|
||||
foreach (uint recipeId in page.id_goods)
|
||||
{
|
||||
if (recipeId == 0)
|
||||
continue;
|
||||
|
||||
CreateSubItem(recipeId);
|
||||
}
|
||||
}
|
||||
|
||||
void CreateSubItem(uint recipeId)
|
||||
{
|
||||
if (itemPb == null || itemContainer == null)
|
||||
return;
|
||||
|
||||
GameObject item = Instantiate(itemPb, itemContainer);
|
||||
item.name = $"Recipe_{recipeId}";
|
||||
item.SetActive(true);
|
||||
Debug.Log("[DlgProduce] Creating produce item for recipe ID: " + item.name);
|
||||
|
||||
ProduceItemPanel panel = item.GetComponent<ProduceItemPanel>();
|
||||
if(panel != null)
|
||||
{
|
||||
panel.Setup(recipeId,this);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[DlgProduce] ProduceItemPanel component not found on item prefab");
|
||||
}
|
||||
|
||||
var trigger = item.AddComponent<UnityEngine.EventSystems.EventTrigger>();
|
||||
|
||||
var entryEnter = new UnityEngine.EventSystems.EventTrigger.Entry
|
||||
{
|
||||
eventID = UnityEngine.EventSystems.EventTriggerType.PointerEnter
|
||||
};
|
||||
entryEnter.callback.AddListener((_) =>
|
||||
{
|
||||
ShowItemInfoByRecipe(recipeId);
|
||||
});
|
||||
trigger.triggers.Add(entryEnter);
|
||||
|
||||
var entryExit = new UnityEngine.EventSystems.EventTrigger.Entry
|
||||
{
|
||||
eventID = UnityEngine.EventSystems.EventTriggerType.PointerExit
|
||||
};
|
||||
entryExit.callback.AddListener((_) =>
|
||||
{
|
||||
HideItemInfo();
|
||||
});
|
||||
trigger.triggers.Add(entryExit);
|
||||
|
||||
}
|
||||
|
||||
void ClearContainer(Transform container)
|
||||
{
|
||||
if (container == null)
|
||||
return;
|
||||
|
||||
for (int i = container.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
Destroy(container.GetChild(i).gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
void ClearMaterialSlots()
|
||||
{
|
||||
foreach (var slot in materialSlots)
|
||||
{
|
||||
if (slot == null) continue;
|
||||
|
||||
slot.gameObject.SetActive(false);
|
||||
|
||||
Transform iconTf = slot.Find("item");
|
||||
if (iconTf != null)
|
||||
{
|
||||
Image img = iconTf.GetComponent<Image>();
|
||||
if (img != null)
|
||||
img.sprite = null;
|
||||
}
|
||||
|
||||
Transform qtyTf = slot.Find("text_quantity");
|
||||
if (qtyTf != null)
|
||||
{
|
||||
TextMeshProUGUI txt = qtyTf.GetComponent<TextMeshProUGUI>();
|
||||
if (txt != null)
|
||||
txt.text = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (itemResult != null)
|
||||
{
|
||||
itemResult.gameObject.SetActive(false);
|
||||
|
||||
Transform iconTf = itemResult.Find("item");
|
||||
if (iconTf != null)
|
||||
{
|
||||
Image img = iconTf.GetComponent<Image>();
|
||||
if (img != null)
|
||||
img.sprite = null;
|
||||
}
|
||||
|
||||
Transform qtyTf = itemResult.Find("text_quantity");
|
||||
if (qtyTf != null)
|
||||
{
|
||||
TextMeshProUGUI txt = qtyTf.GetComponent<TextMeshProUGUI>();
|
||||
if (txt != null)
|
||||
txt.text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void ShowRecipeMaterials(uint recipeId)
|
||||
{
|
||||
selectedRecipeId = recipeId; // Track the selected recipe
|
||||
ClearMaterialSlots();
|
||||
|
||||
var edm = ElementDataManProvider.GetElementDataMan();
|
||||
if (edm == null)
|
||||
return;
|
||||
|
||||
DATA_TYPE dt = DATA_TYPE.DT_INVALID;
|
||||
object data = edm.get_data_ptr(recipeId, ID_SPACE.ID_SPACE_RECIPE, ref dt);
|
||||
|
||||
if (data is not RECIPE_ESSENCE recipe)
|
||||
return;
|
||||
|
||||
if (itemResult != null &&
|
||||
recipe.targets != null &&
|
||||
recipe.targets.Length > 0 &&
|
||||
recipe.targets[0].id_to_make != 0)
|
||||
{
|
||||
uint outputItemId = recipe.targets[0].id_to_make;
|
||||
|
||||
itemResult.gameObject.SetActive(true);
|
||||
|
||||
Transform iconTf = itemResult.Find("item");
|
||||
if (iconTf != null)
|
||||
{
|
||||
Image img = iconTf.GetComponent<Image>();
|
||||
if (img != null)
|
||||
{
|
||||
Sprite sp = EC_IvtrItemUtils.Instance.ResolveItemIconSprite((int)outputItemId);
|
||||
if (sp != null)
|
||||
{
|
||||
img.sprite = sp;
|
||||
img.enabled = true;
|
||||
img.preserveAspect = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Transform qtyTf = itemResult.Find("text_quantity");
|
||||
if (qtyTf != null)
|
||||
{
|
||||
TextMeshProUGUI txt = qtyTf.GetComponent<TextMeshProUGUI>();
|
||||
if (txt != null)
|
||||
txt.text = "1";
|
||||
}
|
||||
}
|
||||
|
||||
if (recipe.materials == null)
|
||||
return;
|
||||
|
||||
bool allEnough = true;
|
||||
int slotIndex = 0;
|
||||
foreach (var mat in recipe.materials)
|
||||
{
|
||||
if (slotIndex >= materialSlots.Count)
|
||||
break;
|
||||
|
||||
if (mat.id == 0 || mat.num <= 0)
|
||||
continue;
|
||||
|
||||
int owned = GetInventoryItemCount(mat.id);
|
||||
bool enough = owned >= mat.num;
|
||||
|
||||
if (!enough)
|
||||
allEnough = false;
|
||||
|
||||
Transform slot = materialSlots[slotIndex];
|
||||
slot.gameObject.SetActive(true);
|
||||
|
||||
Transform iconTf = slot.Find("item");
|
||||
if (iconTf != null)
|
||||
{
|
||||
Image img = iconTf.GetComponent<Image>();
|
||||
if (img != null)
|
||||
{
|
||||
Sprite sp = EC_IvtrItemUtils.Instance.ResolveItemIconSprite((int)mat.id);
|
||||
img.sprite = sp;
|
||||
img.enabled = true;
|
||||
img.preserveAspect = true;
|
||||
img.color = enough ? COLOR_ENOUGH : COLOR_NOT_ENOUGH;
|
||||
}
|
||||
}
|
||||
|
||||
Transform qtyTf = slot.Find("text_quantity");
|
||||
if (qtyTf != null)
|
||||
{
|
||||
var tmp = qtyTf.GetComponent<TMPro.TextMeshProUGUI>();
|
||||
if (tmp != null)
|
||||
tmp.text = $"{mat.num}";
|
||||
else
|
||||
{
|
||||
TextMeshProUGUI txt = qtyTf.GetComponent<TextMeshProUGUI>();
|
||||
if (txt != null)
|
||||
txt.text = $"{mat.num}";
|
||||
}
|
||||
}
|
||||
|
||||
slotIndex++;
|
||||
}
|
||||
|
||||
if (itemResult != null)
|
||||
{
|
||||
Transform iconTf = itemResult.Find("item");
|
||||
if (iconTf != null)
|
||||
{
|
||||
Image img = iconTf.GetComponent<Image>();
|
||||
if (img != null)
|
||||
{
|
||||
img.color = allEnough ? COLOR_ENOUGH : COLOR_NOT_ENOUGH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(startProduceBtn != null)
|
||||
{
|
||||
startProduceBtn.interactable = allEnough;
|
||||
}
|
||||
}
|
||||
|
||||
void OnStartProduceClicked()
|
||||
{
|
||||
if (selectedRecipeId == 0)
|
||||
{
|
||||
Debug.LogWarning("[DlgProduce] No recipe selected");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cachedMakeService.HasValue)
|
||||
{
|
||||
Debug.LogError("[DlgProduce] No make service cached");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get skill ID from the service (not from recipe)
|
||||
// The second parameter is the recipe ID (not the item ID)
|
||||
int idSkill = (int)cachedMakeService.Value.id_make_skill;
|
||||
int idRecipe = (int)selectedRecipeId;
|
||||
uint dwCount = 1; // Default count is 1 (matching C++ code for Win_Produce1)
|
||||
|
||||
// Send the command to the server
|
||||
// Parameters: idSkill (from service), idRecipe (recipe ID), dwCount
|
||||
UnityGameSession.c2s_CmdNPCSevMakeItem(idSkill, idRecipe, dwCount);
|
||||
Debug.Log($"[DlgProduce] Sent make item command: skill={idSkill}, recipe={idRecipe}, count={dwCount}");
|
||||
}
|
||||
|
||||
void OnCancelProduceClicked()
|
||||
{
|
||||
CloseProduce();
|
||||
}
|
||||
|
||||
public void CloseProduce()
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
ClearContainer(tabBtnContainer);
|
||||
ClearContainer(itemContainer);
|
||||
ClearMaterialSlots();
|
||||
cachedMakeService = null;
|
||||
currentTabIndex = 0;
|
||||
selectedRecipeId = 0;
|
||||
Debug.Log("[DlgProduce] Produce dialog closed");
|
||||
}
|
||||
|
||||
// Called when production starts (NOTIFY_PRODUCE_START)
|
||||
public void OnProduceStart(CSNetwork.GPDataType.cmd_produce_start cmd)
|
||||
{
|
||||
Debug.Log($"[DlgProduce] OnProduceStart: type={cmd.type}, use_time={cmd.use_time}, count={cmd.count}");
|
||||
// TODO: Update progress bar, disable start button, etc.
|
||||
// This would typically start a progress bar showing production time
|
||||
if (startProduceBtn != null)
|
||||
{
|
||||
startProduceBtn.interactable = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Called when one item is produced (NOTIFY_PRODUCE_END_ONE)
|
||||
public void OnProduceOnce(CSNetwork.GPDataType.cmd_produce_once cmd)
|
||||
{
|
||||
Debug.Log($"[DlgProduce] OnProduceOnce: type={cmd.type}, amount={cmd.amount}, where={cmd.where}, index={cmd.index}");
|
||||
// TODO: Update UI counters, progress, skill ability, etc.
|
||||
// This would typically update the remaining count and progress
|
||||
}
|
||||
|
||||
// Called when production ends (NOTIFY_PRODUCE_END)
|
||||
public void OnProduceEnd()
|
||||
{
|
||||
Debug.Log("[DlgProduce] OnProduceEnd: Production completed");
|
||||
// TODO: Re-enable start button, reset progress, etc.
|
||||
if (startProduceBtn != null)
|
||||
{
|
||||
startProduceBtn.interactable = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Called when production fails (NOTIFY_PRODUCE_NULL)
|
||||
public void OnProduceNull(CSNetwork.GPDataType.cmd_produce_null cmd)
|
||||
{
|
||||
Debug.Log($"[DlgProduce] OnProduceNull: type={cmd.type} - Production failed");
|
||||
// TODO: Show error message, re-enable start button, etc.
|
||||
if (startProduceBtn != null)
|
||||
{
|
||||
startProduceBtn.interactable = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowItemInfoByRecipe(uint recipeId)
|
||||
{
|
||||
if (itemInfoRoot == null)
|
||||
return;
|
||||
|
||||
var edm = ElementDataManProvider.GetElementDataMan();
|
||||
if (edm == null)
|
||||
return;
|
||||
|
||||
DATA_TYPE dt = DATA_TYPE.DT_INVALID;
|
||||
object data = edm.get_data_ptr(recipeId, ID_SPACE.ID_SPACE_RECIPE, ref dt);
|
||||
|
||||
if (data is not RECIPE_ESSENCE recipe ||
|
||||
recipe.targets == null ||
|
||||
recipe.targets.Length == 0)
|
||||
return;
|
||||
|
||||
uint itemId = recipe.targets[0].id_to_make;
|
||||
if (itemId == 0)
|
||||
return;
|
||||
|
||||
EC_IvtrItem item = null;
|
||||
try
|
||||
{
|
||||
item = EC_IvtrItem.CreateItem((int)itemId, 0, 1);
|
||||
item?.GetDetailDataFromLocal();
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (item == null)
|
||||
return;
|
||||
|
||||
itemInfoRoot.gameObject.SetActive(true);
|
||||
|
||||
if (infoNameText != null)
|
||||
infoNameText.text = EC_Utility.ProcessColorCodes(new StringBuilder (item.GetName()));
|
||||
|
||||
if (infoDescText != null)
|
||||
infoDescText.text = EC_Utility.ProcessColorCodes(new StringBuilder (item.GetDesc()?.Replace("\\r", "\n") ?? ""));
|
||||
|
||||
if (infoExtraText != null)
|
||||
{
|
||||
infoExtraText.text = $"Item ID: {itemId}";
|
||||
}
|
||||
}
|
||||
|
||||
public void HideItemInfo()
|
||||
{
|
||||
if (itemInfoRoot != null)
|
||||
itemInfoRoot.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
// Helper to get total count of an item in player's inventory
|
||||
int GetInventoryItemCount(uint itemId)
|
||||
{
|
||||
var host = CECGameRun.Instance?.GetHostPlayer();
|
||||
if (host == null)
|
||||
return 0;
|
||||
|
||||
var inv = host.GetInventory(0); // 0 = inventory bag
|
||||
if (inv == null)
|
||||
return 0;
|
||||
|
||||
int total = 0;
|
||||
int size = inv.GetSize();
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
var item = inv.GetItem(i, false);
|
||||
if (item != null && item.m_tid == itemId)
|
||||
{
|
||||
total += item.m_iCount;
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
public void OnDestroy()
|
||||
{
|
||||
ClearContainer(tabBtnContainer);
|
||||
ClearContainer(itemContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5653f9f523864f47a37bcfad6111bce
|
||||
@@ -0,0 +1,104 @@
|
||||
using BrewMonster;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using static CSNetwork.Common.ExpTypes;
|
||||
|
||||
public class ProduceItemPanel : MonoBehaviour
|
||||
{
|
||||
[Header("UI")]
|
||||
public Image icon;
|
||||
|
||||
private uint recipeId;
|
||||
private Coroutine loadIconCoroutine;
|
||||
private DlgProduce ownerDlg;
|
||||
private Button cachedButton;
|
||||
|
||||
public void Setup(uint recipeId, DlgProduce dlg)
|
||||
{
|
||||
this.recipeId = recipeId;
|
||||
this.ownerDlg = dlg;
|
||||
|
||||
SetupClickHandler();
|
||||
LoadOutputIcon();
|
||||
}
|
||||
|
||||
void SetupClickHandler()
|
||||
{
|
||||
if (cachedButton == null)
|
||||
{
|
||||
cachedButton = GetComponent<Button>();
|
||||
if (cachedButton == null)
|
||||
cachedButton = GetComponentInChildren<Button>();
|
||||
|
||||
if (cachedButton == null && icon != null)
|
||||
cachedButton = icon.gameObject.AddComponent<Button>();
|
||||
}
|
||||
|
||||
if (cachedButton != null)
|
||||
{
|
||||
cachedButton.onClick.RemoveAllListeners();
|
||||
cachedButton.onClick.AddListener(OnClicked);
|
||||
}
|
||||
}
|
||||
|
||||
void OnClicked()
|
||||
{
|
||||
Debug.Log($"[ProduceItemPanel] Click recipe {recipeId}");
|
||||
|
||||
if (ownerDlg != null)
|
||||
ownerDlg.ShowRecipeMaterials(recipeId);
|
||||
}
|
||||
|
||||
void LoadOutputIcon()
|
||||
{
|
||||
if (icon == null || recipeId == 0)
|
||||
return;
|
||||
|
||||
if (loadIconCoroutine != null)
|
||||
StopCoroutine(loadIconCoroutine);
|
||||
|
||||
loadIconCoroutine = StartCoroutine(LoadIconCoroutine());
|
||||
}
|
||||
|
||||
IEnumerator LoadIconCoroutine()
|
||||
{
|
||||
yield return null;
|
||||
|
||||
var edm = ElementDataManProvider.GetElementDataMan();
|
||||
if (edm == null)
|
||||
yield break;
|
||||
|
||||
DATA_TYPE dt = DATA_TYPE.DT_INVALID;
|
||||
object recipeData = edm.get_data_ptr(recipeId, ID_SPACE.ID_SPACE_RECIPE, ref dt);
|
||||
|
||||
if (recipeData is not RECIPE_ESSENCE recipe)
|
||||
yield break;
|
||||
|
||||
if (recipe.targets == null || recipe.targets.Length == 0)
|
||||
yield break;
|
||||
|
||||
uint outputItemId = recipe.targets[0].id_to_make;
|
||||
if (outputItemId == 0)
|
||||
yield break;
|
||||
|
||||
Sprite sp = EC_IvtrItemUtils.Instance.ResolveItemIconSprite((int)outputItemId);
|
||||
if (sp != null)
|
||||
{
|
||||
icon.sprite = sp;
|
||||
icon.enabled = true;
|
||||
icon.color = Color.white;
|
||||
icon.preserveAspect = true;
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if (loadIconCoroutine != null)
|
||||
StopCoroutine(loadIconCoroutine);
|
||||
|
||||
if (cachedButton != null)
|
||||
cachedButton.onClick.RemoveListener(OnClicked);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b12f7c9b50bc084881f32c1ebde5957
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ecf0d8daf08db6f4a8d94a4bb07847ec
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,153 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c1e41545fff9af745986f5611faf421a
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 2
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites:
|
||||
- serializedVersion: 2
|
||||
name: arrow1_0
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 3
|
||||
y: 6
|
||||
width: 107
|
||||
height: 67
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
customData:
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 582dac677001bf944a81d8d7411aebb5
|
||||
internalID: 2076531766
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 38b49d8dc0d44f2438253ad3616201e7
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable:
|
||||
arrow1_0: 2076531766
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,153 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 456a4fcc95d933c4792f57ade804238e
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 2
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites:
|
||||
- serializedVersion: 2
|
||||
name: arrow2_0
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 15
|
||||
y: 8
|
||||
width: 107
|
||||
height: 67
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
customData:
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: 0
|
||||
bones: []
|
||||
spriteID: 7342b1324a3cec945b723102aff9d934
|
||||
internalID: 397534948
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 43b7b36b881efbc4785aac3234b14dfb
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable:
|
||||
arrow2_0: 397534948
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,172 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &3478571236783653060
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7551350917878394023}
|
||||
- component: {fileID: 2586856635111866746}
|
||||
- component: {fileID: 3227995981941927}
|
||||
m_Layer: 0
|
||||
m_Name: itemProduce
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &7551350917878394023
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3478571236783653060}
|
||||
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:
|
||||
- {fileID: 5438773728966160586}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 42, y: -42}
|
||||
m_SizeDelta: {x: 84, y: 84}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &2586856635111866746
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3478571236783653060}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_WrapAround: 0
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_SelectedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 7716303670266317094}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!114 &3227995981941927
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3478571236783653060}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 0b12f7c9b50bc084881f32c1ebde5957, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
icon: {fileID: 7716303670266317094}
|
||||
--- !u!1 &5714852699199745934
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5438773728966160586}
|
||||
- component: {fileID: 7941037763135429874}
|
||||
- component: {fileID: 7716303670266317094}
|
||||
m_Layer: 5
|
||||
m_Name: icon
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5438773728966160586
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5714852699199745934}
|
||||
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: 7551350917878394023}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: -42}
|
||||
m_SizeDelta: {x: 84, y: 84}
|
||||
m_Pivot: {x: 0, y: 0.5}
|
||||
--- !u!222 &7941037763135429874
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5714852699199745934}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &7716303670266317094
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5714852699199745934}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, 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_Sprite: {fileID: 21300000, guid: 8b997e886fff00540b9c069a9dff12af, type: 3}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b89cfffd83c228f4886273562ff4e111
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -548,6 +548,9 @@ namespace BrewMonster
|
||||
case int value when value == EC_MsgDef.MSG_HST_PICKUPITEM:
|
||||
OnMsgHstPickupItem(Msg);
|
||||
break;
|
||||
case int value when value == EC_MsgDef.MSG_HST_PRODUCEITEM:
|
||||
OnMsgHstProduceItem(Msg);
|
||||
break;
|
||||
case int value when value == EC_MsgDef.MSG_HST_SELTARGET:
|
||||
OnMsgHstSelTarget(Msg); break;
|
||||
case int value when value == EC_MsgDef.MSG_HST_ATKRESULT: OnMsgHstAttackResult(Msg); break;
|
||||
@@ -2026,9 +2029,100 @@ namespace BrewMonster
|
||||
}
|
||||
|
||||
break;
|
||||
case CommandID.PRODUCE_ONCE:
|
||||
{
|
||||
// Parse cmd_produce_once struct data
|
||||
cmd_produce_once produceCmd = GPDataTypeHelper.FromBytes<cmd_produce_once>(data);
|
||||
|
||||
int produceItemId = produceCmd.type;
|
||||
int produceExpireDate = 0;
|
||||
uint produceAmount = produceCmd.amount;
|
||||
byte producePack = produceCmd.where;
|
||||
byte produceSlot = produceCmd.index;
|
||||
|
||||
// Create new inventory item data
|
||||
var produceNewItem = new EC_IvtrItem
|
||||
{
|
||||
Package = producePack,
|
||||
Slot = produceSlot,
|
||||
m_tid = produceItemId,
|
||||
m_expire_date = produceExpireDate,
|
||||
State = 0,
|
||||
m_iCount = (int)produceAmount,
|
||||
Crc = 0,
|
||||
Content = null
|
||||
};
|
||||
|
||||
// TODO: Handle other pickup item commands if necessary
|
||||
// Add item to inventory
|
||||
var produce_ivt = GetInventory(producePack);
|
||||
if (!produce_ivt.MergeItem(produceItemId, produceExpireDate, (int)produceAmount, out var produceLastSlot, out var produceSlotNum) ||
|
||||
produceLastSlot != produceSlot || produceSlotNum != (int)produceCmd.slot_amount)
|
||||
{
|
||||
Debug.LogWarning($"[PRODUCE_ONCE] Failed to merge item {produceItemId} to package {producePack}, slot {produceSlot}");
|
||||
return;
|
||||
}
|
||||
produce_ivt.SetItem(produceSlot, produceNewItem);
|
||||
|
||||
Debug.Log($"[PRODUCE_ONCE] Successfully added produced item {produceItemId} to package {producePack}, slot {produceSlot} with count {produceAmount}");
|
||||
|
||||
// Trigger UI refresh if an EC_InventoryUI is present in scene
|
||||
var produce_ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
|
||||
if (produce_ui != null)
|
||||
{
|
||||
produce_ui.RefreshAll();
|
||||
}
|
||||
|
||||
UpdateEquipSkins();
|
||||
|
||||
// Notify DlgProduce about successful produce (NOTIFY_PRODUCE_END_ONE)
|
||||
var dlgProduce = GameObject.FindFirstObjectByType<DlgProduce>();
|
||||
if (dlgProduce != null)
|
||||
{
|
||||
dlgProduce.OnProduceOnce(produceCmd);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnMsgHstProduceItem(in ECMSG Msg)
|
||||
{
|
||||
var data = Msg.dwParam1 as byte[];
|
||||
int cmd = Convert.ToInt32(Msg.dwParam2);
|
||||
|
||||
// Get DlgProduce to notify
|
||||
var dlgProduce = GameObject.FindFirstObjectByType<DlgProduce>();
|
||||
if (dlgProduce == null)
|
||||
{
|
||||
Debug.LogWarning("[OnMsgHstProduceItem] DlgProduce not found");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case CommandID.PRODUCE_START:
|
||||
{
|
||||
cmd_produce_start pCmd = GPDataTypeHelper.FromBytes<cmd_produce_start>(data);
|
||||
Debug.Log($"[PRODUCE_START] type={pCmd.type}, use_time={pCmd.use_time}, count={pCmd.count}");
|
||||
dlgProduce.OnProduceStart(pCmd);
|
||||
}
|
||||
break;
|
||||
case CommandID.PRODUCE_END:
|
||||
{
|
||||
Debug.Log("[PRODUCE_END] Production ended");
|
||||
dlgProduce.OnProduceEnd();
|
||||
}
|
||||
break;
|
||||
case CommandID.PRODUCE_NULL:
|
||||
{
|
||||
cmd_produce_null pCmd = GPDataTypeHelper.FromBytes<cmd_produce_null>(data);
|
||||
Debug.Log($"[PRODUCE_NULL] type={pCmd.type}");
|
||||
dlgProduce.OnProduceNull(pCmd);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Debug.LogWarning($"[OnMsgHstProduceItem] Unknown command: {cmd}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user