diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs b/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs index f128d154b4..863fb742f4 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs @@ -48,14 +48,17 @@ namespace PerfectWorld.Scripts.Managers private Dictionary matterDataStorage = new Dictionary(); public bool ProcessMessage(ECMSG Msg) { - /*if (Msg.iSubID == 0) - { - return true; - } - else */if (Msg.iSubID == 0) + if (Msg.iSubID == 0) { switch ((int)Msg.dwMsg) { + case int value when value == EC_MsgDef.MSG_MM_MATTERINFO: + { + Debug.Log("MATTERINFO"); + //ENABLE LATER: It fetch all matters in the game world, causing performance issues + //OnMsgMatterInfo(Msg); + break; + } case int value when value == EC_MsgDef.MSG_MM_MATTERENTWORLD: { Debug.Log("MATTERENTWORLD"); @@ -71,6 +74,43 @@ namespace PerfectWorld.Scripts.Managers return true; } + public void OnMsgMatterInfo(ECMSG Msg) + { + byte[] data = (byte[])Msg.dwParam1; + + try + { + // Parse the data structure: count + info_matter array + int offset = 0; + + // Read count (int) + int count = BitConverter.ToInt32(data, offset); + offset += sizeof(int); + + Debug.Log($"MATTERINFO: Received {count} matter entries"); + + // Parse each info_matter entry + for (int i = 0; i < count; i++) + { + // Parse info_matter structure + info_matter matterInfo = CSNetwork.GPDataType.GPDataTypeHelper.FromBytes(data, offset); + offset += Marshal.SizeOf(typeof(info_matter)); + + // Store the matter data for later player access + matterDataStorage[matterInfo.mid] = matterInfo; + + Debug.Log($"Matter info - ID: {matterInfo.mid}, TID: {matterInfo.tid}, Position: {matterInfo.pos}, State: {matterInfo.state}"); + + // Spawn cube for this matter since it has entered the world + SpawnMatterCube(matterInfo.mid); + } + } + catch (Exception ex) + { + Debug.LogError($"Failed to parse matter info data: {ex.Message}"); + } + } + public void OnMsgMatterEnterWorld(ECMSG Msg) { byte[] data = (byte[])Msg.dwParam1; @@ -94,6 +134,20 @@ namespace PerfectWorld.Scripts.Managers } } + private void SpawnMatterCube(int matterId) + { + // Find the pickupItem component in the scene and create cube for this specific matter + pickupItem pickupScript = UnityEngine.Object.FindFirstObjectByType(); + if (pickupScript != null) + { + pickupScript.CreateMatterCube(matterId); + } + else + { + Debug.LogWarning("pickupItem component not found in scene - cannot spawn matter cube"); + } + } + private void NotifyPickupItem(int matterId) { // Find the pickupItem component in the scene and update cubes diff --git a/Assets/PerfectWorld/Scripts/UI/pickupItem.cs b/Assets/PerfectWorld/Scripts/UI/pickupItem.cs index e5a3bb4e24..6127acf62c 100644 --- a/Assets/PerfectWorld/Scripts/UI/pickupItem.cs +++ b/Assets/PerfectWorld/Scripts/UI/pickupItem.cs @@ -2,9 +2,11 @@ using UnityEngine; using UnityEngine.UI; using BrewMonster.Network; using PerfectWorld.Scripts.Managers.BrewMonster.Managers; +using PerfectWorld.Scripts.Managers; using CSNetwork.GPDataType; using System.Collections.Generic; using BrewMonster; +using TMPro; public class pickupItem : MonoBehaviour { @@ -18,6 +20,9 @@ public class pickupItem : MonoBehaviour // Dictionary to track pending pickups by TID private Dictionary pendingPickups = new Dictionary(); // TID -> MatterID + // Set to track items that have been picked up by the player (to prevent respawn) + private HashSet pickedUpItems = new HashSet(); // MID of picked up items + // Reference to the matter manager private EC_ManMatter matterManager; @@ -126,6 +131,13 @@ public class pickupItem : MonoBehaviour var matterData = matterManager.GetMatterData(matterId); if (!matterData.HasValue) return; + // Check if this item was previously picked up by the player + if (pickedUpItems.Contains(matterId)) + { + Debug.Log($"Skipping cube creation for matter {matterId} - item was previously picked up by player"); + return; + } + // Check if cube already exists if (matterCubes.ContainsKey(matterId)) { @@ -136,7 +148,7 @@ public class pickupItem : MonoBehaviour // Create cube GameObject GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.name = $"Matter_{matterData.Value.mid}_TID_{matterData.Value.tid}"; - + cube.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f); // Position the cube based on matter position Vector3 position = new Vector3( matterData.Value.pos.x, @@ -151,6 +163,9 @@ public class pickupItem : MonoBehaviour cube.AddComponent(); } + // Create text object to display item name above the cube + CreateItemNameText(cube, matterData.Value.tid); + // Add a script to handle click events MatterCubeClickHandler clickHandler = cube.AddComponent(); clickHandler.Initialize(matterId, this); @@ -161,6 +176,73 @@ public class pickupItem : MonoBehaviour Debug.Log($"Created cube for matter {matterId} at position {position}"); } + private void CreateItemNameText(GameObject cube, int tid) + { + // Create a child GameObject for the text + GameObject textObject = new GameObject("ItemNameText"); + textObject.transform.SetParent(cube.transform); + + // Position the text above the cube + textObject.transform.localPosition = new Vector3(0, 1.2f, 0); // Above the cube + + // Add TextMeshPro component + TextMeshPro textMesh = textObject.AddComponent(); + + // Get the item name + string itemName = EC_IvtrItem.ResolveItemName(tid); + if (string.IsNullOrEmpty(itemName)) + { + itemName = $"Item {tid}"; + } + + // Configure the text + textMesh.text = itemName; + textMesh.fontSize = 10f; + textMesh.color = Color.white; + textMesh.alignment = TextAlignmentOptions.Center; + + // Make the text face the camera + textObject.AddComponent(); + + // Add a background for better visibility + GameObject background = new GameObject("TextBackground"); + background.transform.SetParent(textObject.transform); + background.transform.localPosition = Vector3.zero; + background.transform.localScale = new Vector3(2f, 0.8f, 0.1f); + + // Add a simple quad renderer for background + MeshRenderer bgRenderer = background.AddComponent(); + MeshFilter bgFilter = background.AddComponent(); + + // Create a simple quad mesh for the background + Mesh quadMesh = new Mesh(); + quadMesh.vertices = new Vector3[] + { + new Vector3(-0.5f, -0.5f, 0), + new Vector3(0.5f, -0.5f, 0), + new Vector3(0.5f, 0.5f, 0), + new Vector3(-0.5f, 0.5f, 0) + }; + quadMesh.triangles = new int[] { 0, 1, 2, 0, 2, 3 }; + quadMesh.uv = new Vector2[] + { + new Vector2(0, 0), + new Vector2(1, 0), + new Vector2(1, 1), + new Vector2(0, 1) + }; + quadMesh.RecalculateNormals(); + + bgFilter.mesh = quadMesh; + + // Create a simple material for the background + Material bgMaterial = new Material(Shader.Find("Standard")); + bgMaterial.color = new Color(0, 0, 0, 0.7f); // Semi-transparent black + bgRenderer.material = bgMaterial; + + Debug.Log($"Created item name text for TID {tid}: {itemName}"); + } + public void RemoveMatterCube(int matterId) { if (matterCubes.ContainsKey(matterId)) @@ -182,10 +264,10 @@ public class pickupItem : MonoBehaviour // Get all current matter IDs int[] allMatterIds = matterManager.GetAllMatterIds(); - // Create cubes for new matters + // Create cubes for new matters (but skip items previously picked up by player) foreach (int matterId in allMatterIds) { - if (!matterCubes.ContainsKey(matterId)) + if (!matterCubes.ContainsKey(matterId) && !pickedUpItems.Contains(matterId)) { CreateMatterCube(matterId); } @@ -217,6 +299,9 @@ public class pickupItem : MonoBehaviour { int matterId = pendingPickups[tid]; + // Track this item as picked up by the player + pickedUpItems.Add(matterId); + // Remove the cube RemoveMatterCube(matterId); @@ -243,6 +328,24 @@ public class pickupItem : MonoBehaviour Debug.Log($"Pickup failed for TID: {tid}, removed from pending pickups"); } } + + /// + /// Clears the tracking of picked up items. Call this when player changes areas or logs out. + /// + public void ClearPickedUpItemsTracking() + { + pickedUpItems.Clear(); + Debug.Log("Cleared picked up items tracking"); + } + + /// + /// Gets the count of items that have been picked up by the player. + /// + /// Number of items picked up + public int GetPickedUpItemsCount() + { + return pickedUpItems.Count; + } private void OnPickupButtonClicked() { @@ -286,6 +389,9 @@ public class pickupItem : MonoBehaviour // Clean up pending pickups pendingPickups.Clear(); + + // Clean up picked up items tracking + pickedUpItems.Clear(); } } @@ -309,3 +415,28 @@ public class MatterCubeClickHandler : MonoBehaviour } } } + +// Simple Billboard component to make text always face the camera +public class Billboard : MonoBehaviour +{ + private Camera mainCamera; + + void Start() + { + mainCamera = Camera.main; + if (mainCamera == null) + { + mainCamera = FindFirstObjectByType(); + } + } + + void Update() + { + if (mainCamera != null) + { + // Make the text face the camera + transform.LookAt(mainCamera.transform); + transform.Rotate(0, 180, 0); // Flip to face the camera properly + } + } +}