226 lines
7.2 KiB
C#
226 lines
7.2 KiB
C#
using BrewMonster;
|
|
using BrewMonster.Network;
|
|
using BrewMonster.Scripts.World;
|
|
using CSNetwork;
|
|
using CSNetwork.GPDataType;
|
|
using CSNetwork.Protocols;
|
|
using CSNetwork.Protocols.RPCData;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading.Tasks;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
namespace PerfectWorld.Scripts.Managers
|
|
{
|
|
/// <summary>
|
|
/// Matter Manager - Handles matter data storage and provides access to other classes
|
|
///
|
|
/// Usage Examples:
|
|
/// // Get matter manager instance
|
|
/// var matterManager = EC_ManMessageMono.Instance.GetECManMatter;
|
|
///
|
|
/// // Get specific matter data
|
|
/// var matterData = matterManager.GetMatterData(12345);
|
|
///
|
|
/// // Get individual fields
|
|
/// int? mid = matterManager.GetMatterId(12345);
|
|
/// int? tid = matterManager.GetMatterTid(12345);
|
|
/// A3DVECTOR3? pos = matterManager.GetMatterPosition(12345);
|
|
/// byte? state = matterManager.GetMatterState(12345);
|
|
///
|
|
/// // Find matters by criteria
|
|
/// int[] mattersByTid = matterManager.FindMattersByTid(100);
|
|
/// int[] mattersByState = matterManager.FindMattersByState(1);
|
|
/// int[] nearbyMatters = matterManager.FindMattersNearPosition(new A3DVECTOR3(0,0,0), 10.0f);
|
|
/// </summary>
|
|
[Serializable]
|
|
public class EC_ManMatter : IMsgHandler
|
|
{
|
|
public int HandlerId => (int)MANAGER_INDEX.MAN_MATTER;
|
|
|
|
// Storage for matter data that players can access later
|
|
private Dictionary<int, info_matter> matterDataStorage = new Dictionary<int, info_matter>();
|
|
private Dictionary<int, CECMatter> m_MatterTab = new Dictionary<int, CECMatter>();
|
|
public bool ProcessMessage(ECMSG Msg)
|
|
{
|
|
if (Msg.iSubID == 0)
|
|
{
|
|
switch ((int)Msg.dwMsg)
|
|
{
|
|
case int value when value == EC_MsgDef.MSG_MM_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:
|
|
{
|
|
OnMsgMatterEnterWorld(Msg);
|
|
break;
|
|
}
|
|
case int value when value == EC_MsgDef.MSG_MM_MATTERDISAPPEAR:
|
|
{
|
|
OnMsgMatterDisappear(Msg);
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public async void OnMsgMatterInfo(ECMSG Msg)
|
|
{
|
|
byte[] data = (byte[])Msg.dwParam1;
|
|
|
|
try
|
|
{
|
|
// Parse the data structure: count + info_matter array
|
|
int offset = 0;
|
|
|
|
// Read count (ushort)
|
|
ushort count = BitConverter.ToUInt16(data, offset);
|
|
offset += sizeof(ushort);
|
|
|
|
// Parse each info_matter entry
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
// Parse info_matter structure
|
|
info_matter info = CSNetwork.GPDataType.GPDataTypeHelper.FromBytes<info_matter>(data, offset);
|
|
|
|
offset += Marshal.SizeOf(typeof(info_matter));
|
|
|
|
// Store the matter data for later player access
|
|
matterDataStorage[info.mid] = info;
|
|
|
|
await MatterEnter(info);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogError($"Failed to parse matter info data: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public async void OnMsgMatterEnterWorld(ECMSG Msg)
|
|
{
|
|
byte[] data = (byte[])Msg.dwParam1;
|
|
|
|
try
|
|
{
|
|
// Parse the byte array into info_matter structure
|
|
info_matter matterInfo = CSNetwork.GPDataType.GPDataTypeHelper.FromBytes<info_matter>(data);
|
|
await MatterEnter(matterInfo);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogError($"Failed to parse matter data: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public void OnMsgMatterDisappear(ECMSG Msg)
|
|
{
|
|
byte[] data = (byte[])Msg.dwParam1;
|
|
int matterId = BitConverter.ToInt32(data);
|
|
|
|
MatterLeave(matterId);
|
|
}
|
|
|
|
private async Task<bool> MatterEnter(info_matter info)
|
|
{
|
|
CECMatter pMatter = GetMatter(info.mid);
|
|
if (pMatter != null)
|
|
return true;
|
|
|
|
// Create a new matter
|
|
pMatter = await CECMatter.Init(info);
|
|
if (pMatter == null)
|
|
{
|
|
Debug.LogError($"Failed to create matter: {info.mid}");
|
|
return false;
|
|
}
|
|
pMatter.SetBornStamp(CECWorld.Instance.GetBornStamp());
|
|
m_MatterTab[info.mid] = pMatter;
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
// Remove a matter
|
|
public void RemoveMatter(int idMatter) { MatterLeave(idMatter); }
|
|
|
|
public void MatterLeave(int mid)
|
|
{
|
|
CECMatter pMatter = GetMatter(mid);
|
|
if (pMatter != null)
|
|
{
|
|
UnityEngine.Object.Destroy(pMatter.gameObject);
|
|
m_MatterTab.Remove(mid);
|
|
}
|
|
//TODO: Might need to implement later
|
|
/*/
|
|
else
|
|
{
|
|
MatterTable::pair_type Pair = m_DynModelTab.get(mid);
|
|
|
|
if (Pair.second)
|
|
{
|
|
pMatter = *Pair.first;
|
|
|
|
ReleaseMatter(pMatter);
|
|
|
|
// Remove it from active matter table
|
|
m_DynModelTab.erase(mid);
|
|
|
|
QueueMatterUndoLoad(mid);
|
|
}
|
|
}
|
|
|
|
CECPlayerWrapper* pWrapper = CECAutoPolicy::GetInstance().GetPlayerWrapper();
|
|
if( pWrapper ) pWrapper->OnObjectDisappear(mid);
|
|
//*/
|
|
}
|
|
|
|
// Public methods for players to access matter data
|
|
public info_matter? GetMatterData(int matterId)
|
|
{
|
|
return matterDataStorage.TryGetValue(matterId, out info_matter data) ? data : null;
|
|
}
|
|
|
|
public bool HasMatterData(int matterId)
|
|
{
|
|
return matterDataStorage.ContainsKey(matterId);
|
|
}
|
|
|
|
public CECMatter GetMatter(int mid, uint dwBornStamp = 0)
|
|
{
|
|
if (m_MatterTab.TryGetValue(mid, out CECMatter matter))
|
|
{
|
|
if (dwBornStamp != 0)
|
|
{
|
|
if (matter.GetBornStamp() != dwBornStamp)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
return matter;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public CECMatter CreateMatter(info_matter info)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
} |