using BrewMonster.Network; using System.Collections.Generic; using UnityEngine; namespace BrewMonster.Scripts { using static BrewMonster.Scripts.CECHPWork; using WorkList = System.Collections.Generic.List; public class CECHPWork : CECObjectWork { // Host work ID public static class Host_work_ID { public const int WORK_INVALID = -1, WORK_STAND = 0, // Stand and do nothing WORK_MOVETOPOS = 1, // Move to a destination terrain position WORK_TRACEOBJECT = 2, // Trace specified object (NPC, player etc.) WORK_HACKOBJECT = 3, // Hack specified object (NPC, player etc.) WORK_SPELLOBJECT = 4, // Spell magic on specified object (NPC, player etc.) WORK_USEITEM = 5, // Host use item WORK_DEAD = 6, // Host is dead WORK_FOLLOW = 7, // Follow some one else WORK_FLYOFF = 8, // Fly off WORK_FREEFALL = 9, // Free fall WORK_SIT = 10, // Sit WORK_PICKUP = 11, // Pickup item WORK_CONCENTRATE = 12, // All concentrate work WORK_REVIVE = 13, // Revive WORK_FLASHMOVE = 14, // Flash move WORK_BEBOUND = 15, // Be bound by buddy WORK_PASSIVEMOVE = 16, // Passive movement (knock back / pull) WORK_CONGREGATE = 17, // Congregate reply WORK_SKILLSTATEACT = 18, // skill buff action WORK_FORCENAVIGATEMOVE = 19, // force navigate move NUM_WORK = 20; } protected static class Work_mask { public const uint MASK_STAND = 0x0001, MASK_MOVETOPOS = 0x0002, MASK_TRACEOBJECT = 0x0004, MASK_HACKOBJECT = 0x0008, MASK_SPELLOBJECT = 0x0010, MASK_USEITEM = 0x0020, MASK_DEAD = 0x0040, MASK_FOLLOW = 0x0080, MASK_FLYOFF = 0x0100, MASK_FREEFALL = 0x0200, MASK_SIT = 0x0400, MASK_PICKUP = 0x0800, MASK_CONCENTRATE = 0x1000, MASK_REVIVE = 0x2000, MASK_FLASHMOVE = 0x4000, MASK_BEBOUND = 0x8000, MASK_CONGREGATE = 0x10000, MASK_SKILLSTATEACT = 0x20000, MASK_FORCENAVIGATE = 0x40000; public const uint MASK_ALLWORK = 0xffffffff; } protected CECHPWorkMan m_pWorkMan; // Work manager protected CECHostPlayer m_pHost; // Host player object public CECHPWork(int iWorkID, CECHPWorkMan pWorkMan) : base(iWorkID) { m_pWorkMan = pWorkMan; m_pHost = pWorkMan.GetHostPlayer(); } public virtual bool Tick(float dwDeltaTime) { if (m_bFirstTick) { m_bFirstTick = false; OnFirstTick(); } return true; } protected virtual void OnFirstTick() { base.OnFirstTick(); } // Operations // Override from CECObjectWork public override void Cancel() { } // This work is do player moving ? public virtual bool IsMoving() { return false; } // Copy work data public virtual bool CopyData(CECHPWork pWork) { m_bFinished = pWork.m_bFinished; m_bFirstTick = pWork.m_bFirstTick; return true; } public string GetWorkName() { return GetWorkName(GetWorkID()); } public static uint GetWorkMask(int iWorkID) { if (!Validate(iWorkID)) { return 0; } uint[] l_workMask = new uint[]{ Work_mask.MASK_STAND, Work_mask.MASK_MOVETOPOS, Work_mask.MASK_TRACEOBJECT, Work_mask.MASK_HACKOBJECT, Work_mask.MASK_SPELLOBJECT, Work_mask.MASK_USEITEM, Work_mask.MASK_DEAD, Work_mask.MASK_FOLLOW, Work_mask.MASK_FLYOFF, Work_mask.MASK_FREEFALL, Work_mask.MASK_SIT, Work_mask.MASK_PICKUP, Work_mask.MASK_CONCENTRATE, Work_mask.MASK_REVIVE, Work_mask.MASK_FLASHMOVE, Work_mask.MASK_BEBOUND, Work_mask.MASK_CONGREGATE, Work_mask.MASK_SKILLSTATEACT, Work_mask.MASK_FORCENAVIGATE, }; return l_workMask[iWorkID]; } public static bool Validate(int iWorkID) { return iWorkID >= 0 && iWorkID < Host_work_ID.NUM_WORK; } public static string GetWorkName(int iWorkID) { string[] l_WorkName = new string[Host_work_ID.NUM_WORK] { "WORK_STAND", "WORK_MOVETOPOS", "WORK_TRACEOBJECT", "WORK_HACKOBJECT", "WORK_SPELLOBJECT", "WORK_USEITEM", "WORK_DEAD", "WORK_FOLLOW", "WORK_FLYOFF", "WORK_FREEFALL", "WORK_SIT", "WORK_PICKUP", "WORK_CONCENTRATE", "WORK_REVIVE", "WORK_FLASHMOVE", "WORK_BEBOUND", "WORK_PASSIVEMOVE", "WORK_CONGREGATE", "WORK_SKILLSTATEACT", "WORK_FORCENAVIGATEMOVE" }; if (Validate(iWorkID)) { return l_WorkName[iWorkID]; } else if (iWorkID == Host_work_ID.WORK_INVALID) { return "WORK_INVALID"; } else { return "Unknown"; } } } /////////////////////////////////////////////////////////////////////////// // // Class CECHPWorkMan // /////////////////////////////////////////////////////////////////////////// public class CECHPWorkMan { // Work priority public static class Work_priority { public const int PRIORITY_0 = 0, PRIORITY_1 = 1, PRIORITY_2 = 2, NUM_PRIORITY = 3; }; // Delayed work info. public struct DELAYWORK { public int iPriority; public CECHPWork pWork; } private CECHostPlayer m_pHost; private WorkList[] m_WorkStack = new WorkList[Work_priority.NUM_PRIORITY] { new List(), new List(), new List() }; private int m_iCurPriority; private DELAYWORK m_Delayed; private CECHPWorkPostTickCommand m_pPostTickCommand; public CECHPWorkMan(CECHostPlayer pHost) { m_pHost = pHost; m_iCurPriority = -1; m_Delayed = new DELAYWORK { iPriority = 0, pWork = null }; m_pPostTickCommand = null; } public CECHPWork GetRunningWork(int iWorkID) { CECHPWork result = null; if (ValidatePriority(m_iCurPriority)) { WorkList workList = m_WorkStack[m_iCurPriority]; for (int i = 0; i < workList.Count; ++i) { if (iWorkID == workList[i].GetWorkID()) { result = workList[i]; break; } } } return result; } public CECHPWork GetWork(int iWorkID, int iPriority = Work_priority.PRIORITY_1, bool bIncludeDelayedWork = false) { CECHPWorkGeneralMatcher cECHPWork = new CECHPWorkGeneralMatcher(iWorkID, iPriority, bIncludeDelayedWork); return GetWork(cECHPWork); } public CECHPWork GetWork(CECHPWorkMatcher matcher) { CECHPWork result = null; for (int i = (Work_priority.NUM_PRIORITY - 1); i >= 0; --i) { WorkList workList = m_WorkStack[i]; if (workList != null) { for (int j = 0; j < workList.Count; ++j) { CECHPWork pWork = workList[j]; if (matcher.Match(pWork, i, false)) { result = pWork; break; } } } } if (result == null && GetDelayedWork() != null && matcher.Match(m_Delayed.pWork, m_Delayed.iPriority, true)) { result = GetDelayedWork(); } return result; } bool InternallyStartWork(int iPriority, CECHPWork pWork) { bool bStarted = false; if (CanRunSimultaneouslyWithCurrentWork(iPriority, pWork)) { WorkList workList = m_WorkStack[iPriority]; workList.Add(pWork); bStarted = true; //LOG_DEBUG_INFO(AString().Format("CECHPWork::%s started simultaneously, priority=%d", pWork->GetWorkName(), iPriority)); } else { if (pWork.GetWorkID() == CECHPWork.Host_work_ID.WORK_DEAD) { for (int i = iPriority; i < Work_priority.NUM_PRIORITY; i++) { FinishWorkAtPriority(i); } ClearDelayedWork(); WorkList workList = m_WorkStack[iPriority]; workList.Add(pWork); m_iCurPriority = iPriority; bStarted = true; } else { bool shouldStart = (iPriority >= m_iCurPriority); FinishWorkAtPriority(iPriority); WorkList workList = m_WorkStack[iPriority]; workList.Add(pWork); if (shouldStart) { if (iPriority > m_iCurPriority) { CancelWorkAtPriority(m_iCurPriority); } m_iCurPriority = iPriority; bStarted = true; } } //if (bStarted) //{ // LOG_DEBUG_INFO(AString().Format("CECHPWork::%s started, priority=%d", pWork->GetWorkName(), iPriority)); //} //else //{ // LOG_DEBUG_INFO(AString().Format("CECHPWork::%s add to priority queue %d", pWork->GetWorkName(), iPriority)); //} } if (bStarted && pWork.GetWorkID() == CECHPWork.Host_work_ID.WORK_FORCENAVIGATEMOVE && ValidatePriority(iPriority)) { // (debug log removed) } return bStarted; } bool CanRunSimultaneouslyWithCurrentWork(int iPriority, CECHPWork pWork) { if (!ValidatePriority(iPriority) || iPriority != m_iCurPriority) { return false; } WorkList workList = m_WorkStack[iPriority]; if (workList == null || workList.Count == 0) { return false; } foreach (var work in workList) { if (!CanRunSimultaneously(work, pWork)) { return false; } } return true; } public bool CanCastSkillImmediately(int idSkill) { return !IsSpellingMagic() && !HasWorkRunningOnPriority(Work_priority.PRIORITY_2); } bool CanRunSimultaneously(CECHPWork pWork1, CECHPWork pWork2) { if (pWork1.GetWorkID() == CECHPWork.Host_work_ID.WORK_MOVETOPOS && pWork2.GetWorkID() == CECHPWork.Host_work_ID.WORK_SPELLOBJECT) { return CanSpellWhileMoving(pWork2 as CECHPWorkSpell); } if (pWork2.GetWorkID() == CECHPWork.Host_work_ID.WORK_MOVETOPOS && pWork1.GetWorkID() == CECHPWork.Host_work_ID.WORK_SPELLOBJECT) { return CanSpellWhileMoving(pWork1 as CECHPWorkSpell); } return false; } bool CanSpellWhileMoving(CECHPWorkSpell pWorkSpell) { //return pWorkSpell.GetSkill() // && CECCastSkillWhenMove::Instance().IsSkillSupported(pWorkSpell->GetSkill()->GetSkillID(), m_pHost); return false; } void StartAwaitingWorks() { if (ValidatePriority(m_iCurPriority)) { for (--m_iCurPriority; m_iCurPriority >= 0; --m_iCurPriority) { WorkList workList = m_WorkStack[m_iCurPriority]; if (workList == null || workList.Count == 0) { continue; } foreach (var work in workList) { work.OnWorkShift(); //LOG_DEBUG_INFO(AString().Format("CECHPWork::%s started by decrease priority, priority=%d", workList[j]->GetWorkName(), m_iCurPriority)); } break; } } StartDelayedWork(); } void FinishWorkAtPriority(int iPriority) { if (!ValidatePriority(iPriority)) { return; } WorkList workList = m_WorkStack[iPriority]; while ((workList != null && workList.Count > 0)) { KillWork(iPriority, 0); } if (m_iCurPriority == iPriority) { m_iCurPriority = -1; } } void KillWork(int iPriority, int index) { if (!ValidatePriority(iPriority)) { return; } WorkList workList = m_WorkStack[iPriority]; if (index < 0 || index >= workList.Count) { return; } CECHPWork pWork = workList[index]; KillWork(pWork); //LOG_DEBUG_INFO(AString().Format("CECHPWork::%s priority=%d killed", pWork->GetWorkName(), iPriority)); //delete pWork; workList.RemoveAt(index); } void KillWork(CECHPWork pWork) { if (pWork == null) { return; } if (pWork.GetWorkID() == CECHPWork.Host_work_ID.WORK_MOVETOPOS) { CECHPWorkMove pWorkMove = pWork as CECHPWorkMove; if (pWorkMove != null) { if (pWorkMove.GetAutoMove()) { pWorkMove.Finish(); } else { pWorkMove.Cancel(); } } } if(pWork.GetWorkID() == Host_work_ID.WORK_FORCENAVIGATEMOVE) { CECHPWorkNavigate pWorkNavigate = pWork as CECHPWorkNavigate; if(pWorkNavigate != null) { pWorkNavigate.Finish(); } else { pWorkNavigate.Cancel(); } } else { pWork.Cancel(); } } public void CancelWork(CECHPWork pWork) { if (pWork == null) { //ASSERT(false); return; } pWork.Cancel(); } public void CancelWorkAtPriority(int iPriority) { if (!ValidatePriority(iPriority)) { return; } WorkList workList = m_WorkStack[iPriority]; for (int i = 0; i < workList.Count; ++i) { CancelWork(workList[i]); //LOG_DEBUG_INFO(AString().Format("CECHPWork::%s priority=%d cancelled", workList[i]->GetWorkName(), iPriority)); } } public bool DelayWork(int iPriority, CECHPWork pWork) { if (pWork == null) { // ASSERT(false); return false; } if (!ValidatePriority(iPriority)) { // ASSERT(false); return false; } if (!IsAnyWorkRunning()) { return false; } if (CanRunSimultaneouslyWithCurrentWork(iPriority, pWork)) { return false; } bool bDelay = false; if (m_pHost.IsMeleeing()) { UnityGameSession.c2s_CmdCancelAction(); bDelay = true; } else if (IsPickingUp() || IsSpellingMagic()) { bDelay = true; } if (bDelay) { ClearDelayedWork(); m_Delayed.iPriority = iPriority; m_Delayed.pWork = pWork; // LOG_DEBUG_INFO(AString().Format("CECHPWork::%s delayed, priority=%d", pWork->GetWorkName(), iPriority)); } return bDelay; } public void StartDelayedWork() { if (!HasDelayedWork()) { return; } CECHPWork pWork = m_Delayed.pWork; m_Delayed.pWork = null; // LOG_DEBUG_INFO(AString().Format("CECHPWork:: start delayed work %s, priority=%d", pWork->GetWorkName(), m_Delayed.iPriority)); InternallyStartWork(m_Delayed.iPriority, pWork); } public bool IsFlashMoving() { return IsWorkRunning(CECHPWork.Host_work_ID.WORK_FLASHMOVE); } public bool IsFlyingOff() { return IsWorkRunning(CECHPWork.Host_work_ID.WORK_FLYOFF); } public bool HasDelayedWork() { return GetDelayedWork() != null; } public void ClearDelayedWork() { if (!HasDelayedWork()) { return; } // LOG_DEBUG_INFO(AString().Format("delayed CECHPWork::%s priority=%d cleared", m_Delayed.pWork->GetWorkName(), m_Delayed.iPriority)); // delete m_Delayed.pWork; m_Delayed.pWork = null; } public CECHPWork GetDelayedWork() { return m_Delayed.pWork; } public bool ValidatePriority(int iPriority) { return iPriority >= 0 && iPriority < Work_priority.NUM_PRIORITY; } public bool StartWork(int iPriority, CECHPWork pWork, bool bNoDelay = false) { if (pWork == null) { return false; } if (!ValidatePriority(iPriority)) { return false; } if (pWork.GetWorkID() == CECHPWork.Host_work_ID.WORK_TRACEOBJECT) { /* if (EC_Game.GetGameRun().GetHostInputFilter()->IsMoveUsagePressed()) { CECHPWorkTrace pWorkTrace = pWork as CECHPWorkTrace; if (!pWorkTrace.CanTouch()) { // 2014-8-16 ������ͨ�����̲����ƶ�ʱ������������ CECHPWorkTrace, //delete pWorkTrace; // ������� CECHPWorkTrace ����ʱת��Ŀ��λ�á������ֱ����̲��ݵ����ƶ������·���˲�䶶�� return false; // �� CECHPWorkTrace ��Ŀ��������Ӵ�ʱ�������� CECHPWorkTrace����ʵ�ּ��̿����ƶ��С���ij��Ӧ�ü���ʱ������ת���ʩ�ż��� } }*/ } if (!bNoDelay && DelayWork(iPriority, pWork)) { return true; } return InternallyStartWork(iPriority, pWork); } public bool StartWork_p0(CECHPWork pWork, bool bNoDelay = false) { return StartWork(Work_priority.PRIORITY_0, pWork, bNoDelay); } public bool StartWork_p1(CECHPWork pWork, bool bNoDelay = false) { return StartWork(Work_priority.PRIORITY_1, pWork, bNoDelay); } public bool StartWork_p2(CECHPWork pWork, bool bNoDelay = false) { return StartWork(Work_priority.PRIORITY_2, pWork, bNoDelay); } public CECHostPlayer GetHostPlayer() { return m_pHost; } // Create a trace work for an NPC (used by Move->Trace handoff for coord-click auto-run). // 为 NPC 创建追踪工作(用于点击坐标自动跑到 NPC 后切换到追踪/交互)。 public CECHPWorkTrace CreateNPCTraceWork(CECNPC pNPC, int taskId) { if (pNPC == null) { return null; } CECHPWorkTrace pWork = CreateWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT) as CECHPWorkTrace; if (pWork == null) { return null; } // Default to talk when arriving at an NPC via UI link (matches original behavior). // 通过 UI 链接到 NPC,默认以“对话”作为到达后的行为(贴近原版)。 var traceObj = pWork.CreatTraceTarget(pNPC.GetNPCID(), CECHPWorkTrace.Trace_reason.TRACE_TALK); if (traceObj == null) { return null; } // Use AutoPF while tracing as well. // 追踪时也使用 AutoPF。 pWork.SetTraceTarget(traceObj, true); return pWork; } public CECHPWork CreateWork(int idWork) { CECHPWork pWork = null; switch (idWork) { case CECHPWork.Host_work_ID.WORK_STAND: pWork = new CECHPWorkStand(this); break; case CECHPWork.Host_work_ID.WORK_MOVETOPOS: pWork = new CECHPWorkMove(this); break; case CECHPWork.Host_work_ID.WORK_TRACEOBJECT: pWork = new CECHPWorkTrace(this); break; case CECHPWork.Host_work_ID.WORK_HACKOBJECT: pWork = new CECHPWorkMelee(this); break; case CECHPWork.Host_work_ID.WORK_SPELLOBJECT: pWork = new CECHPWorkSpell(this); break; case CECHPWork.Host_work_ID.WORK_USEITEM: pWork = new CECHPWorkUse(this); break; //case CECHPWork.Host_work_ID.WORK_DEAD: pWork = new CECHPWorkDead(this); break; //case CECHPWork.Host_work_ID.WORK_FOLLOW: pWork = new CECHPWorkFollow(this); break; case CECHPWork.Host_work_ID.WORK_FLYOFF: pWork = new CECHPWorkFly(this); break; case CECHPWork.Host_work_ID.WORK_FREEFALL: pWork = new CECHPWorkFall(this); break; //case CECHPWork.Host_work_ID.WORK_SIT: pWork = new CECHPWorkSit(this); break; case CECHPWork.Host_work_ID.WORK_PICKUP: pWork = new EC_HPWorkPick(this); break; case CECHPWork.Host_work_ID.WORK_CONCENTRATE: pWork = new CECHPWorkConcentrate(this); break; //case CECHPWork.Host_work_ID.WORK_REVIVE: pWork = new CECHPWorkRevive(this); break; case CECHPWork.Host_work_ID.WORK_FLASHMOVE: pWork = new CECHPWorkFMove(this); break; //case CECHPWork.Host_work_ID.WORK_BEBOUND: pWork = new CECHPWorkBeBound(this); break; case CECHPWork.Host_work_ID.WORK_PASSIVEMOVE: pWork = new CECHPWorkPassiveMove(this); break; //case CECHPWork.Host_work_ID.WORK_CONGREGATE: pWork = new CECHPWorkCongregate(this); break; //case CECHPWork.Host_work_ID.WORK_SKILLSTATEACT: pWork = new CECHPWorkSkillStateAction(this); break; case CECHPWork.Host_work_ID.WORK_FORCENAVIGATEMOVE: pWork = new CECHPWorkNavigate(this); break; default: return null; } return pWork; } public bool CanStartWork(int iWorkID, int iPriority = CECHPWorkMan.Work_priority.PRIORITY_1) { if (!ValidatePriority(iPriority)) { return false; } if (GetWork(iWorkID) != null) { return false; } if (!HasWorkOnPriority(iPriority)) { return true; } WorkList workList = m_WorkStack[iPriority]; if (workList != null) { for (int i = 0; i < workList.Count; ++i) { if (!workList[i].CanTransferTo(CECHPWork.GetWorkMask(iWorkID))) { return false; } } } return true; } public bool IsSpellingMagic() { return IsWorkRunning(Host_work_ID.WORK_SPELLOBJECT); } bool HasWorkOnPriority(int iPriority) { return ValidatePriority(iPriority) && m_WorkStack[iPriority] != null && m_WorkStack[iPriority].Count != 0; } public void SetPostTickCommand(CECHPWorkPostTickCommand command) { m_pPostTickCommand = command; } public bool HasWorkRunningOnPriority(int iPriority) { return HasWorkOnPriority(iPriority); } bool IsAnyWorkRunning() { return HasWorkRunningOnPriority(m_iCurPriority); } public void Tick(float dwDeltaTime) { if (!IsAnyWorkRunning()) { return; } WorkList workList = m_WorkStack[m_iCurPriority]; for (int i = 0; i < workList.Count;) { CECHPWork pWork = workList[i]; SetPostTickCommand(null); pWork.Tick(dwDeltaTime); if (m_pPostTickCommand == null) { if (!pWork.IsFinished()) { ++i; continue; } KillWork(m_iCurPriority, i); } else { m_pPostTickCommand.Run(this); SetPostTickCommand(null); break; // ��ȷ�� m_pPostTickCommand ִ��ʲô���ݣ��˴����� } } if (workList == null || workList.Count == 0) { StartAwaitingWorks(); } } public bool IsFollowing() { return IsWorkRunning(CECHPWork.Host_work_ID.WORK_FOLLOW); } public bool IsMovingToPosition() { return IsWorkRunning(CECHPWork.Host_work_ID.WORK_MOVETOPOS); } public bool IsTracing() { return IsWorkRunning(CECHPWork.Host_work_ID.WORK_TRACEOBJECT); } bool IsWorkRunning(int iWorkID) { bool result = false; if (ValidatePriority(m_iCurPriority)) { WorkList workList = m_WorkStack[m_iCurPriority]; if (workList != null) { for (int i = 0; i < workList.Count; ++i) { if (iWorkID == workList[i].GetWorkID()) { result = true; break; } } } } return result; } public void FinishWork(CECHPWorkMatcher matcher) { bool bCurrentWorkFinished = false; for (int i = Work_priority.NUM_PRIORITY - 1; i >= 0; --i) { WorkList workList = m_WorkStack[i]; if (workList == null || workList.Count == 0) { continue; } for (int j = 0; j < workList.Count;) { if (!matcher.Match(workList[j], i, false)) { ++j; continue; } KillWork(i, j); if (i == m_iCurPriority && (workList == null || workList.Count == 0)) { bCurrentWorkFinished = true; } } } if (GetDelayedWork() != null && matcher.Match(m_Delayed.pWork, m_Delayed.iPriority, true)) { ClearDelayedWork(); } if (bCurrentWorkFinished) { StartAwaitingWorks(); } } public void FinishRunningWork(int idWork) { if (!IsWorkRunning(idWork)) { return; } WorkList workList = m_WorkStack[m_iCurPriority]; if (workList != null) { for (int i = 0; i < workList.Count;) { if (workList[i].GetWorkID() != idWork) { ++i; continue; } KillWork(m_iCurPriority, i); } if (workList == null || workList.Count == 0) { StartAwaitingWorks(); } } } public bool IsReviving() { return IsWorkRunning(Host_work_ID.WORK_REVIVE); } public bool IsUsingItem() { return IsWorkRunning(Host_work_ID.WORK_USEITEM); } public bool IsPassiveMoving() { return IsWorkRunning(Host_work_ID.WORK_PASSIVEMOVE); } public bool IsSitting() { return IsWorkRunning(Host_work_ID.WORK_SIT); } public bool IsStanding() { return IsWorkRunning(Host_work_ID.WORK_STAND); } public bool IsBeingBound() { return IsWorkRunning(Host_work_ID.WORK_BEBOUND); } //todo: use this method public void FinishAllWork(bool bGotoStand) { for (int i = 0; i < Work_priority.NUM_PRIORITY; ++i) { FinishWorkAtPriority(i); } ClearDelayedWork(); if (bGotoStand) { StartWork_p0(CreateWork(CECHPWork.Host_work_ID.WORK_STAND)); } } bool IsPickingUp() { return IsWorkRunning(CECHPWork.Host_work_ID.WORK_PICKUP); } public bool IsMoving() { bool result = false; if (ValidatePriority(m_iCurPriority)) { WorkList workList = m_WorkStack[m_iCurPriority]; if (workList != null) { for (int i = 0; i < workList.Count; ++i) { if (workList[i].IsMoving()) { result = true; break; } } } } return result; } public bool IsFreeFalling() { return IsWorkRunning(Host_work_ID.WORK_FREEFALL); } public bool IsOperatingPet() { return IsWorkRunning(Host_work_ID.WORK_CONCENTRATE); } } public abstract class CECHPWorkPostTickCommand { public abstract bool Run(CECHPWorkMan pWorkMan); }; public abstract class CECHPWorkMatcher { public virtual bool Match(CECHPWork pWork, int priority, bool isDelayWork) { return false; } }; public class CECHPWorkGeneralMatcher : CECHPWorkMatcher { int m_workID; int m_priority; bool m_matchDelayedWork; public override bool Match(CECHPWork pWork, int priority, bool isDelayWork) { return pWork != null && pWork.GetWorkID() == m_workID && priority == m_priority && isDelayWork == m_matchDelayedWork; } public CECHPWorkGeneralMatcher(int workID, int priority, bool bIncludeDelayedWork) { m_workID = workID; m_priority = priority; m_matchDelayedWork = bIncludeDelayedWork; } } public class CECHPWorkPostTickRunWorkCommand : CECHPWorkPostTickCommand { CECHPWork m_pWork; int m_iPriority; bool m_bNoDelay; bool m_bShouldTick; float m_dwTickTime; // Constructor public CECHPWorkPostTickRunWorkCommand( CECHPWork pWork, bool bNoDelay = false, int iPriority = CECHPWorkMan.Work_priority.PRIORITY_1, bool bShouldTick = false, float dwTickTime = 0) { m_pWork = pWork; m_bNoDelay = bNoDelay; m_iPriority = iPriority; m_bShouldTick = bShouldTick; m_dwTickTime = dwTickTime; } public override bool Run(CECHPWorkMan pWorkMan) { if (m_pWork == null || pWorkMan == null) { return false; } if (!pWorkMan.StartWork(m_iPriority, m_pWork, m_bNoDelay)) { m_pWork = null; return false; } if (m_bShouldTick) { m_pWork.Tick(m_dwTickTime); } m_pWork = null; return true; } }; }