322 lines
12 KiB
C#
322 lines
12 KiB
C#
using BrewMonster;
|
|
using BrewMonster.Network;
|
|
using BrewMonster.Scripts;
|
|
using BrewMonster.Scripts.Task;
|
|
using CSNetwork.GPDataType;
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using UnityEngine;
|
|
using static CECNPC;
|
|
|
|
public class CECNPCServer : CECNPC
|
|
{
|
|
NPC_ESSENCE? m_pDBEssence;
|
|
MONSTER_ESSENCE? m_pMonEssence;
|
|
float m_fTaxRate = 0.05f; // Tax rate
|
|
|
|
private IconTaskType m_TaskIcon = IconTaskType.QI_NONE;
|
|
private CECCounter m_TaskCounter = new CECCounter();
|
|
|
|
public override void SetUpCECNPC(CECNPCMan pNPCMan)
|
|
{
|
|
base.SetUpCECNPC(pNPCMan);
|
|
m_iCID = (int)Class_ID.OCID_SERVER;
|
|
m_pDBEssence = null;
|
|
m_TaskCounter.SetPeriod(1000);
|
|
}
|
|
public override bool Init(int tid, in info_npc info, ReadOnlySpan<byte> packet, int infoOffset)
|
|
{
|
|
base.Init(tid, info, packet, infoOffset);
|
|
//BrewMonster.BMLogger.Log("HoangDev: MonsterInit");
|
|
var pDB = ElementDataManProvider.GetElementDataMan();
|
|
DATA_TYPE DataType = default;
|
|
var data = pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
|
|
m_pDBEssence = data != null ? (NPC_ESSENCE?)data : null;
|
|
|
|
var data1 = pDB.get_data_ptr(m_pDBEssence.Value.id_src_monster, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
|
|
|
|
if (data1 == null)
|
|
{
|
|
if ((data1 = (MONSTER_ESSENCE?)pDB.get_data_ptr(4249, ID_SPACE.ID_SPACE_ESSENCE, ref DataType)) == null)
|
|
{
|
|
BMLogger.LogError("HoangDEv : CECNPCServer::Init, server NPC reference to null monster data");
|
|
return false;
|
|
}
|
|
}
|
|
m_pMonEssence = (MONSTER_ESSENCE?)data1;
|
|
|
|
m_fTouchRad = m_pMonEssence.Value.size;
|
|
m_BasicProps.iLevel = m_pMonEssence.Value.level;
|
|
QueueLoadNPCModel();
|
|
|
|
/* float fExt = m_fTouchRad * 1.5f;
|
|
m_cdr.vExts.Set(fExt, fExt, fExt);
|
|
m_pNPCModelPolicy.SetDefaultPickAABBExt(m_cdr.vExts);*/
|
|
|
|
// If NPC doesn't have specific name, use the name in database
|
|
if ((info.state & (int)PlayerNPCState.GP_STATE_NPC_NAME) == 0)
|
|
{
|
|
m_strName = Encoding.Unicode.GetString(MemoryMarshal.AsBytes<ushort>(m_pDBEssence.Value.name));
|
|
m_npcUI.SetName(m_strName);
|
|
}
|
|
|
|
transform.forward = EC_Utility.ToVector3(EC_Utility.glb_DecompressDirH(info.dir));
|
|
transform.position = EC_Utility.ToVector3(info.pos);
|
|
|
|
StartWork((int)WorkType.WT_NOTHING, (int)WorkID.WORK_STAND);
|
|
return true;
|
|
}
|
|
|
|
protected override void Update()
|
|
{
|
|
base.Update();
|
|
|
|
if (m_TaskCounter.IncCounter(Time.deltaTime * 1000))
|
|
{
|
|
m_TaskCounter.Reset();
|
|
UpdateCurTaskIcon();
|
|
}
|
|
}
|
|
|
|
// Get way point ID bound with this NPC
|
|
public uint? GetWayPointID()
|
|
{
|
|
uint? dwID = 0;
|
|
if ((m_pDBEssence?.combined_services & 0x08) != 0)
|
|
dwID = m_pDBEssence?.id_to_discover;
|
|
|
|
return dwID;
|
|
}
|
|
|
|
// Get essence data in database
|
|
public NPC_ESSENCE? GetDBEssence() { return m_pDBEssence; }
|
|
|
|
// Get tax rate
|
|
public float GetTaxRate() { return m_fTaxRate; }
|
|
|
|
// Get item price scale factor
|
|
public float GetPriceScale()
|
|
{
|
|
return 1.0f + m_pDBEssence.Value.tax_rate;
|
|
}
|
|
|
|
private void UpdateCurTaskIcon()
|
|
{
|
|
var pHost = CECGameRun.Instance.GetHostPlayer();
|
|
if (pHost == null || pHost.GetTaskInterface() == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (m_pDBEssence == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var pTaskMan = EC_Game.GetTaskTemplateMan();
|
|
var pDataMan = ElementDataManProvider.GetElementDataMan();
|
|
var pTask = pHost.GetTaskInterface();
|
|
|
|
const uint TASK_HAVE_COMPLETE = 0x10000000;
|
|
const uint TASK_COMPLETE = 0x01;
|
|
const uint TASK_INCOMPLETE = 0x02;
|
|
const uint TASK_CANGET = 0x04;
|
|
const uint TASK_CANNOTGET = 0x08;
|
|
const uint TASK_COMPLETE_TYPE1 = 0x10;
|
|
const uint TASK_CANGET_TYPE1 = 0x20;
|
|
const uint TASK_COMPLETE_TYPE2 = 0x40;
|
|
const uint TASK_CANGET_TYPE2 = 0x80;
|
|
const uint TASK_COMPLETE_TYPE3 = 0x100;
|
|
const uint TASK_CANGET_TYPE3 = 0x200;
|
|
const uint TASK_COMPLETE_TYPE4 = 0x400;
|
|
const uint TASK_CANGET_TYPE4 = 0x800;
|
|
|
|
m_TaskIcon = IconTaskType.QI_NONE;
|
|
uint taskFlag = 0;
|
|
|
|
//BMLogger.Log($"[UpdateCurTaskIcon] NPC {m_NPCInfo.nid}, id_task_in_service={m_pDBEssence.Value.id_task_in_service}, id_task_out_service={m_pDBEssence.Value.id_task_out_service}");
|
|
if (m_pDBEssence.Value.id_task_in_service != 0)
|
|
{
|
|
DATA_TYPE dt = DATA_TYPE.DT_INVALID;
|
|
var serviceData = pDataMan.get_data_ptr(m_pDBEssence.Value.id_task_in_service, ID_SPACE.ID_SPACE_ESSENCE, ref dt);
|
|
|
|
if (serviceData != null && dt == DATA_TYPE.DT_NPC_TASK_IN_SERVICE)
|
|
{
|
|
var inService = (NPC_TASK_IN_SERVICE)serviceData;
|
|
|
|
for (int i = 0; i < inService.id_tasks.Length; i++)
|
|
{
|
|
uint idTask = inService.id_tasks[i];
|
|
if (idTask <= 0 || !pTask.HasTask(idTask))
|
|
continue;
|
|
|
|
BMLogger.Log($"[UpdateCurTaskIcon] Check IN task {idTask}, HasTask={pTask.HasTask(idTask)}, CanFinish={pTask.CanFinishTask((idTask))}");
|
|
|
|
var pTaskTemp = pTaskMan.GetTaskTemplByID(idTask);
|
|
if (pTaskTemp == null)
|
|
continue;
|
|
|
|
if (pTask.CanFinishTask(idTask))
|
|
{
|
|
taskFlag |= TASK_HAVE_COMPLETE;
|
|
|
|
if (pTaskTemp.IsKeyTask())
|
|
{
|
|
m_TaskIcon = IconTaskType.QI_IN_K;
|
|
BMLogger.Log($"[UpdateCurTaskIcon] Set icon QI_IN_K for task {idTask}");
|
|
UpdateTaskIconUI();
|
|
return;
|
|
}
|
|
else if (pTaskTemp.GetType() == (uint)ENUM_TASK_TYPE.enumTTEvent || pTaskTemp.GetType() == (uint)ENUM_TASK_TYPE.enumTTDaily)
|
|
{
|
|
taskFlag |= TASK_COMPLETE_TYPE3;
|
|
}
|
|
else if (pTaskTemp.GetType() == (uint)ENUM_TASK_TYPE.enumTTQiShaList)
|
|
{
|
|
taskFlag |= TASK_COMPLETE_TYPE2;
|
|
}
|
|
else if (pTaskTemp.GetType() == (uint)ENUM_TASK_TYPE.enumTTFaction || pTaskTemp.GetType() == (uint)ENUM_TASK_TYPE.enumTTFunction)
|
|
{
|
|
taskFlag |= TASK_COMPLETE_TYPE1;
|
|
}
|
|
else if (pTaskTemp.GetType() == (uint)ENUM_TASK_TYPE.enumTTMajor)
|
|
{
|
|
taskFlag |= TASK_COMPLETE_TYPE4;
|
|
}
|
|
else
|
|
{
|
|
taskFlag |= TASK_COMPLETE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
taskFlag |= TASK_INCOMPLETE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((taskFlag & TASK_HAVE_COMPLETE) != 0)
|
|
{
|
|
if ((taskFlag & TASK_COMPLETE_TYPE4) != 0)
|
|
m_TaskIcon = IconTaskType.QI_IN_TYPE4;
|
|
else if ((taskFlag & TASK_COMPLETE_TYPE3) != 0)
|
|
m_TaskIcon = IconTaskType.QI_IN_TYPE3;
|
|
else if ((taskFlag & TASK_COMPLETE_TYPE2) != 0)
|
|
m_TaskIcon = IconTaskType.QI_IN_TYPE2;
|
|
else if ((taskFlag & TASK_COMPLETE) != 0)
|
|
m_TaskIcon = IconTaskType.QI_IN;
|
|
else if ((taskFlag & TASK_COMPLETE_TYPE1) != 0)
|
|
m_TaskIcon = IconTaskType.QI_IN_TYPE1;
|
|
|
|
BMLogger.Log($"[UpdateCurTaskIcon] Set complete icon {m_TaskIcon}");
|
|
UpdateTaskIconUI();
|
|
return;
|
|
}
|
|
|
|
if (m_pDBEssence.Value.id_task_out_service != 0)
|
|
{
|
|
DATA_TYPE dt = DATA_TYPE.DT_INVALID;
|
|
var serviceData = pDataMan.get_data_ptr(
|
|
m_pDBEssence.Value.id_task_out_service,
|
|
ID_SPACE.ID_SPACE_ESSENCE,
|
|
ref dt
|
|
);
|
|
|
|
if (serviceData != null && dt == DATA_TYPE.DT_NPC_TASK_OUT_SERVICE)
|
|
{
|
|
var outService = (NPC_TASK_OUT_SERVICE)serviceData;
|
|
|
|
if (outService.storage_id != 0 && outService.storage_open_item != 0)
|
|
{
|
|
var pack = pHost.GetInventory(InventoryConst.IVTRTYPE_PACK);
|
|
if (pack != null && pack.GetItemTotalNum((int)outService.storage_open_item) > 0)
|
|
{
|
|
taskFlag |= TASK_CANGET_TYPE2;
|
|
}
|
|
}
|
|
|
|
// Check normal tasks
|
|
for (int i = 0; i < outService.id_tasks.Length; i++)
|
|
{
|
|
uint idTask = outService.id_tasks[i];
|
|
if (idTask <= 0)
|
|
continue;
|
|
|
|
//BMLogger.Log($"[UpdateCurTaskIcon] Check OUT task {idTask}, CanShow={pTask.CanShowTask(idTask)}, CanDeliver={pTask.CanDeliverTask(idTask)}");
|
|
|
|
if (!pTask.CanShowTask(idTask))
|
|
continue;
|
|
|
|
var pTaskTemp = pTaskMan.GetTaskTemplByID(idTask);
|
|
if (pTaskTemp == null)
|
|
continue;
|
|
|
|
if (pTask.CanDeliverTask(idTask) == 0)
|
|
{
|
|
if (pTaskTemp.IsKeyTask())
|
|
{
|
|
m_TaskIcon = IconTaskType.QI_OUT_K;
|
|
//BMLogger.Log($"[UpdateCurTaskIcon] Set icon QI_OUT_K for task {idTask}");
|
|
UpdateTaskIconUI();
|
|
return;
|
|
}
|
|
else if (pTaskTemp.GetType() == (uint)ENUM_TASK_TYPE.enumTTEvent || pTaskTemp.GetType() == (uint)ENUM_TASK_TYPE.enumTTDaily)
|
|
{
|
|
taskFlag |= TASK_CANGET_TYPE3;
|
|
}
|
|
else if (pTaskTemp.GetType() == (uint)ENUM_TASK_TYPE.enumTTQiShaList)
|
|
{
|
|
taskFlag |= TASK_CANGET_TYPE2;
|
|
}
|
|
else if (pTaskTemp.GetType() == (uint)ENUM_TASK_TYPE.enumTTFaction || pTaskTemp.GetType() == (uint)ENUM_TASK_TYPE.enumTTFunction)
|
|
{
|
|
taskFlag |= TASK_CANGET_TYPE1;
|
|
}
|
|
else if (pTaskTemp.GetType() == (uint)ENUM_TASK_TYPE.enumTTMajor)
|
|
{
|
|
taskFlag |= TASK_CANGET_TYPE4;
|
|
}
|
|
else
|
|
{
|
|
taskFlag |= TASK_CANGET;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
taskFlag |= TASK_CANNOTGET;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set icon by available task priority
|
|
if ((taskFlag & TASK_CANGET_TYPE4) != 0)
|
|
m_TaskIcon = IconTaskType.QI_OUT_TYPE4;
|
|
else if ((taskFlag & TASK_CANGET_TYPE3) != 0)
|
|
m_TaskIcon = IconTaskType.QI_OUT_TYPE3;
|
|
else if ((taskFlag & TASK_CANGET_TYPE2) != 0)
|
|
m_TaskIcon = IconTaskType.QI_OUT_TYPE2;
|
|
else if ((taskFlag & TASK_CANGET) != 0)
|
|
m_TaskIcon = IconTaskType.QI_OUT;
|
|
else if ((taskFlag & TASK_CANGET_TYPE1) != 0)
|
|
m_TaskIcon = IconTaskType.QI_OUT_TYPE1;
|
|
else if ((taskFlag & TASK_INCOMPLETE) != 0)
|
|
m_TaskIcon = IconTaskType.QI_IN_N;
|
|
else if ((taskFlag & TASK_CANNOTGET) != 0)
|
|
m_TaskIcon = IconTaskType.QI_OUT_N;
|
|
|
|
//BMLogger.Log($"[UpdateCurTaskIcon] Final icon {m_TaskIcon}, taskFlag={taskFlag}");
|
|
UpdateTaskIconUI();
|
|
}
|
|
|
|
private void UpdateTaskIconUI()
|
|
{
|
|
if(m_npcUI != null)
|
|
{
|
|
m_npcUI.SetTaskIcon(m_TaskIcon);
|
|
}
|
|
}
|
|
}
|