747 lines
25 KiB
C#
747 lines
25 KiB
C#
using BrewMonster.Scripts.Player;
|
|
using System.Collections.Generic;
|
|
|
|
namespace BrewMonster.Scripts
|
|
{
|
|
using WorkList = System.Collections.Generic.List<CECHPWork>;
|
|
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();
|
|
}
|
|
|
|
// 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<CECHPWork>(), new List<CECHPWork>(), new List<CECHPWork>() };
|
|
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));
|
|
//}
|
|
}
|
|
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;
|
|
}
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pWork.Cancel();
|
|
}
|
|
}
|
|
|
|
public void CancelWork(CECHPWork pWork)
|
|
{
|
|
|
|
}
|
|
public void CancelWorkAtPriority(int iPriority)
|
|
{
|
|
|
|
}
|
|
|
|
public bool DelayWork(int iPriority, CECHPWork pWork)
|
|
{
|
|
return false;
|
|
}
|
|
public void StartDelayedWork()
|
|
{
|
|
|
|
}
|
|
public void ClearDelayedWork()
|
|
{
|
|
|
|
}
|
|
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 (g_pGame->GetGameRun()->GetHostInputFilter()->IsMoveUsagePressed())
|
|
// {
|
|
// CECHPWorkTrace pWorkTrace = pWork as CECHPWorkTrace;
|
|
// if (!pWorkTrace.CanTouch())
|
|
// { // 2014-8-16 当还在通过键盘操纵移动时、有条件忽略 CECHPWorkTrace,
|
|
// //delete pWorkTrace; // 否则会因 CECHPWorkTrace 中临时转向目标位置、而后又被键盘操纵调整移动方向导致方向瞬间抖动
|
|
// return false; // 当 CECHPWorkTrace 中目标可立即接触时,不忽略 CECHPWorkTrace,以实现键盘控制移动中、对某怪应用技能时,立刻转向怪施放技能
|
|
// }
|
|
// }
|
|
//}
|
|
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; }
|
|
|
|
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 CECHPWorkPick(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;
|
|
}
|
|
|
|
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.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 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)
|
|
{
|
|
StartAwaitingWorks();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public abstract class CECHPWorkPostTickCommand
|
|
{
|
|
public abstract bool Run(CECHPWorkMan pWorkMan);
|
|
};
|
|
|
|
public abstract class CECHPWorkMatcher
|
|
{
|
|
public abstract bool Match(CECHPWork pWork, int priority, bool isDelayWork);
|
|
};
|
|
|
|
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;
|
|
uint m_dwTickTime;
|
|
|
|
// Constructor
|
|
public CECHPWorkPostTickRunWorkCommand(
|
|
CECHPWork pWork,
|
|
bool bNoDelay = false,
|
|
int iPriority = CECHPWorkMan.Work_priority.PRIORITY_1,
|
|
bool bShouldTick = false,
|
|
uint 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;
|
|
}
|
|
};
|
|
}
|