Files
test/Assets/Scripts/Task/ATaskTemplMan.cs
T
2025-10-10 16:04:14 +07:00

261 lines
9.8 KiB
C#

using BrewMonster;
using ModelRenderer.Scripts.GameData;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace PerfectWorld.Scripts.Task
{
public class ATaskTemplMan
{
public const ulong TASK_PACK_MAGIC = 0x93858361;
public const ulong _task_templ_cur_version = 121;
private ulong g_ulNewCount = 0;// do we need this?
private Dictionary<ulong, ATaskTempl> m_TaskTemplMap = new Dictionary<ulong, ATaskTempl>();
private Dictionary<ulong, ATaskTempl> m_AllTemplMap = new Dictionary<ulong, ATaskTempl>();
private Dictionary<ulong, ATaskTempl> m_DynTaskMap = new Dictionary<ulong, ATaskTempl>();
private Dictionary<ulong, ATaskTempl> m_TitleTaskMap = new Dictionary<ulong, ATaskTempl>();
private Dictionary<ulong, ATaskTempl> m_ExlusiveAwardTaskMap = new Dictionary<ulong, ATaskTempl>();
private Dictionary<ulong, ATaskTempl> m_ProtectNPCMap = new Dictionary<ulong, ATaskTempl>();
private Dictionary<ulong, ATaskTempl> m_AutoDelvMap = new Dictionary<ulong, ATaskTempl>();
private Dictionary<ulong, ATaskTempl> m_DeathTrigMap = new Dictionary<ulong, ATaskTempl>();
private Dictionary<ulong, ATaskTempl> m_PQTemplMap = new Dictionary<ulong, ATaskTempl>();
private Dictionary<uint, uint> m_StorageEssenseMap = new Dictionary<uint, uint>();
private Dictionary<uint, uint> m_WeightEssenseMap = new Dictionary<uint, uint>();
private Dictionary<int, int> m_StorageTaskMap = new Dictionary<int, int>();
private List<ATaskTempl> m_SkillTaskLst = new List<ATaskTempl>();
private List<ATaskTempl> m_TmLmtChkLst = new List<ATaskTempl>();
private elementdataman m_pEleDataMan;
public void Release()
{
}
public void Init(elementdataman pMan)
{
m_pEleDataMan = pMan;
}
public bool LoadTasksFromPack(string szPackPath, bool bLoadDescript)
{
//TaskInterface::WriteLog(0, 0, 2, "LoadPack begin");
BMLogger.Log("[Dat]- szPackPath: " + szPackPath);
if (!File.Exists(szPackPath))
{
BMLogger.LogError("[Dat]- File not found: " + szPackPath);
return false;
}
long readBytes = 0;
FileStream fs = new FileStream(szPackPath, FileMode.Open, FileAccess.Read);
TASK_PACK_HEADER tph = AAssit.ReadFromBinaryOf<TASK_PACK_HEADER>(fs, ref readBytes);
if (tph.magic != TASK_PACK_MAGIC
|| tph.version != _task_templ_cur_version)
return false;
if (tph.item_count == 0) return true;
uint[] pOffs = new uint[tph.item_count];
g_ulNewCount++;
// fread(pOffs, sizeof(long), tph.item_count, fp);
pOffs = AAssit.ReadArrayFromBinary<uint>(fs, (int)tph.item_count, ref readBytes);
for (int i = 0; i < 3; i++) //TODO: tph.item_count
{
fs.Seek(pOffs[i], SeekOrigin.Begin);
ATaskTempl pTempl = new ATaskTempl();
g_ulNewCount++;
if (!pTempl.LoadFromBinFile(fs))
{
CECTaskInterface.WriteLog(0, (int)pTempl.m_FixedData.m_ID, 0, "Cant Load Task");
// LOG_DELETE(pTempl);
continue;
}
AddOneTaskTempl(pTempl);
// TaskInterface::WriteLog(0, pTempl->m_ID, 2, "LoadTask");
}
// // char log[1024];
// // sprintf(log, "LoadTask, Count = %d", m_TaskTemplMap.size());
// // TaskInterface::WriteLog(0, 0, 2, log);
// //todo: check
// // LOG_DELETE_ARR(pOffs);
fs.Close();
// UpdateTimeLimitCheckList();
#if _ELEMENTCLIENT
_task_err.Release();
_task_err.Init("Configs\\task_err.txt", true);
#endif
return true;
}
// General method to read a struct from a FileStream
private T ReadStruct<T>(FileStream stream) where T : struct
{
int size = System.Runtime.InteropServices.Marshal.SizeOf(typeof(T));
byte[] buffer = new byte[size];
int bytesRead = stream.Read(buffer, 0, size);
if (bytesRead != size)
throw new EndOfStreamException("Could not read enough bytes for struct");
var handle = System.Runtime.InteropServices.GCHandle.Alloc(buffer, System.Runtime.InteropServices.GCHandleType.Pinned);
try
{
return (T)System.Runtime.InteropServices.Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
}
finally
{
handle.Free();
}
}
public bool LoadNPCInfoFromPack(string szPath)
{
return true;
}
public void VerifyDynTasksPack(string szPath)
{
}
private void AddOneTaskTempl(ATaskTempl pTask)
{
//todo: recheck - wrong logic
if (m_AllTemplMap.ContainsKey(pTask.m_FixedData.m_ID))
{
CECTaskInterface.WriteLog(0, (int)pTask.m_FixedData.m_ID, 0, "Dup Task Found");
// Optionally log duplicate task found, e.g.:
// Debug.LogWarning($"Duplicate Task Found: {pTempl.m_ID}");
return;
}
m_TaskTemplMap[pTask.m_FixedData.m_ID] = pTask;
if (pTask.m_FixedData.m_bDeathTrig) m_DeathTrigMap[pTask.m_FixedData.m_ID] = pTask;
else if (pTask.m_FixedData.m_bAutoDeliver) m_AutoDelvMap[pTask.m_FixedData.m_ID] = pTask;
if (pTask.m_FixedData.m_bPQTask) m_PQTemplMap[pTask.m_FixedData.m_ID] = pTask;
if (pTask.m_FixedData.m_bSkillTask) m_SkillTaskLst.Add(pTask);
//todo: recheck m_DynTaskType type
if (pTask.m_FixedData.m_DynTaskType != '\0')
{
if (m_DynTaskMap.TryGetValue(pTask.m_FixedData.m_ID, out ATaskTempl task))
{
CECTaskInterface.WriteLog(0, (int)pTask.m_FixedData.m_ID, 0, "Dup Dyn Task Found");
}
m_DynTaskMap[pTask.m_FixedData.m_ID] = pTask;
}
if (pTask.m_FixedData.m_bDisplayInTitleTaskUI)
m_TitleTaskMap[pTask.m_FixedData.m_ID] = pTask;
if (pTask.m_FixedData.m_bAutoDeliver && pTask.m_FixedData.m_bDisplayInExclusiveUI)
m_ExlusiveAwardTaskMap[pTask.m_FixedData.m_ID] = pTask;
//#if _TASK_CLIENT
// if (pTask.m_ulDelvNPC != 0 && pTask.m_bCanSeekOut)
// m_TasksCanSeekOut.Add(pTask);
//#endif
AddTaskToMap(pTask);
}
private void AddTaskToMap(ATaskTempl pTempl)
{
if (pTempl.m_FixedData.m_enumMethod == (ulong)TaskMethod.enumTMProtectNPC && pTempl.m_FixedData.m_ulNPCToProtect > 0)
m_ProtectNPCMap[pTempl.m_FixedData.m_ulNPCToProtect] = pTempl;
m_AllTemplMap[pTempl.m_FixedData.m_ID] = pTempl;
ATaskTempl pChild = pTempl.m_pFirstChild;
while (pChild != null)
{
AddTaskToMap(pChild);
pChild = pChild.m_pNextSibling;
}
}
void UpdateTimeLimitCheckList()
{
m_TmLmtChkLst.Clear();
foreach (var entry in m_TaskTemplMap)
{
if (entry.Value.m_FixedData.m_ulMaxReceiver != 0)
{
m_TmLmtChkLst.Add(entry.Value);
}
}
}
public bool InitStorageTask()
{
m_StorageEssenseMap.Clear();
m_WeightEssenseMap.Clear();
DATA_TYPE dt;
//ID_SPACE.ID_SPACE_ESSENCE
foreach (var pair in m_pEleDataMan.essence_id_data_type_map)
{
if (pair.Value == DATA_TYPE.DT_NPC_TASK_OUT_SERVICE)
{
dt = pair.Value;
NPC_TASK_OUT_SERVICE pData = (NPC_TASK_OUT_SERVICE)m_pEleDataMan.get_data_ptr(pair.Key, ID_SPACE.ID_SPACE_ESSENCE, ref dt);
if (pData.storage_id == 0) continue;
if (pData.storage_id > CECTaskInterface.TASK_STORAGE_COUNT) return false;
if (m_StorageEssenseMap.ContainsKey(pData.storage_id)) return false;
m_StorageEssenseMap[pData.storage_id] = pData.id;
for (var i = 0; i < pData.id_tasks.Length; i++)
{
if (pData.id_tasks[i] > 0)
{
m_StorageTaskMap[(int)pData.id_tasks[i]] = (int)pData.storage_id;
}
}
}
}
// ID_SPACE_CONFIG
foreach (var pair in m_pEleDataMan.config_id_data_type_map)
{
if (pair.Value == DATA_TYPE.DT_NPC_TASK_OUT_SERVICE)
{
dt = pair.Value;
NPC_TASK_OUT_SERVICE pData = (NPC_TASK_OUT_SERVICE)m_pEleDataMan.get_data_ptr(pair.Key, ID_SPACE.ID_SPACE_ESSENCE, ref dt);
if (pData.storage_id == 0) continue;
if (pData.storage_id > CECTaskInterface.TASK_STORAGE_COUNT) return false;
if (m_StorageEssenseMap.ContainsKey(pData.storage_id)) return false;
m_StorageEssenseMap[pData.storage_id] = pData.id;
for (var i = 0; i < pData.id_tasks.Length; i++)
{
if (pData.id_tasks[i] > 0)
{
m_StorageTaskMap[(int)pData.id_tasks[i]] = (int)pData.storage_id;
}
}
}
}
return true;
}
}
}