Files
test/Assets/PerfectWorld/Scripts/Managers/EC_EPWork.cs
T

715 lines
22 KiB
C#

using CSNetwork.GPDataType;
using PerfectWorld.Scripts.Player;
using System;
namespace BrewMonster.Scripts
{
using WorkList = System.Collections.Generic.List<CECEPWork>;
public abstract class CECEPWorkMatcher
{
public abstract bool Match(CECEPWork work, int workType);
}
// class CECEPWorkMelee
public class CECEPWorkMelee : CECEPWork
{
int m_iAttackTarget;
public CECEPWorkMelee(CECEPWorkMan pWorkMan, int attackTarget) : base(EP_work_ID.WORK_HACKOBJECT, pWorkMan)
{
m_iAttackTarget = attackTarget;
}
public override void Start()
{
GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND;
GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_ATTACK_1 + UnityEngine.Random.Range(0, 3));
GetPlayer().EnterFightState();
}
public override void Tick(float dwDeltaTime)
{
GetPlayer().TurnFaceTo(m_iAttackTarget);
// Slide to server position
A3DVECTOR3 vDir = GetPlayer().m_vServerPos - GetPlayer().GetPos();
float fDist = vDir.Normalize();
if (fDist > 0.0001f)
{
float fMoveDist = 10.0f * dwDeltaTime * 0.001f;
if (fMoveDist > fDist)
fMoveDist = fDist;
GetPlayer().SetPos(GetPlayer().GetPos() + vDir * fMoveDist);
}
if (GetPlayer().m_FightCnt.IncCounter(dwDeltaTime))
{
Finish();
}
}
public override void Cancel()
{
GetPlayer().TurnFaceTo(0);
}
};
public class CECEPWorkIDMatcher : CECEPWorkMatcher
{
int m_workID;
public CECEPWorkIDMatcher(int workID)
{
m_workID = workID;
}
public override bool Match(CECEPWork work, int workType)
{
return work != null && work.GetWorkID() == m_workID;
}
}
// class CECEPWorkCongregate
public class CECEPWorkCongregate : CECEPWork
{
int m_iType;
public CECEPWorkCongregate(CECEPWorkMan pWorkMan, int iType) : base(EP_work_ID.WORK_CONGREGATE, pWorkMan)
{
m_iType = iType;
}
public override void Start()
{
}
public int GetType()
{
return m_iType;
}
}
public class CECEPCongregateWorkMatcher : CECEPWorkMatcher
{
int m_iType;
public CECEPCongregateWorkMatcher(int iType)
{
m_iType = iType;
}
public override bool Match(CECEPWork work, int workType)
{
if (work != null && work.GetWorkID() == CECEPWork.EP_work_ID.WORK_CONGREGATE)
{
CECEPWorkCongregate pCongregateWork = work as CECEPWorkCongregate;
return pCongregateWork.GetType() == m_iType;
}
return false;
}
}
// class CECEPWorkIdle
public class CECEPWorkIdle : CECEPWork
{
int m_iType;
bool m_bOTCheck;
CECCounter m_OTCnt;
uint m_dwParam;
public CECEPWorkIdle(CECEPWorkMan pWorkMan, int iType, int iOTTime, uint dwParam) : base(EP_work_ID.WORK_IDLE, pWorkMan)
{
m_dwParam = dwParam;
m_iType = iType;
m_bOTCheck = iOTTime > 0 ? true : false;
if (m_bOTCheck)
{
m_OTCnt.SetPeriod(iOTTime);
m_OTCnt.Reset();
}
switch (iType)
{
case Idle_work_type.IDLE_SITDOWN:
GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND;
if (m_dwParam != 0)
GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_SITDOWN_LOOP);
else
{
GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_SITDOWN);
GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_SITDOWN_LOOP, true, 200, true);
}
break;
case Idle_work_type.IDLE_REVIVE:
GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_REVIVE);
break;
case Idle_work_type.IDLE_BOOTH:
GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND;
break;
}
}
public override void Tick(float dwDeltaTime)
{
base.Tick(dwDeltaTime);
}
public int GetType()
{
return m_iType;
}
}
public class CECEPIdleWorkMatcher : CECEPWorkMatcher
{
int m_iType;
public CECEPIdleWorkMatcher(int iType)
{
m_iType = iType;
}
public override bool Match(CECEPWork work, int workType)
{
if (work != null && work.GetWorkID() == CECEPWork.EP_work_ID.WORK_IDLE)
{
CECEPWorkIdle pIdleWork = work as CECEPWorkIdle;
return pIdleWork.GetType() == m_iType;
}
return false;
}
}
public class CECEPWork
{
public static class EP_work_ID
{
public const int WORK_INVALID = -1,
WORK_STAND = 0, // Stand and do nothing
WORK_MOVE = 1, // Move
WORK_HACKOBJECT = 2, // Hack specified object (NPC, player etc.)
WORK_SPELL = 3, // Spell magic
WORK_PICKUP = 4, // Pickup matter
WORK_DEAD = 5, // Dead
WORK_USEITEM = 6, // Use item
WORK_IDLE = 7, // Idle works
WORK_FLASHMOVE = 8, // Flash move
WORK_PASSIVEMOVE = 9, // Move controlled by server
WORK_CONGREGATE = 10, // Congregate reply
WORK_SKILLSTATEACT = 11, // skill buff action
NUM_WORK = 12;
}
// Idle work type
public static class Idle_work_type
{
public const int IDLE_SITDOWN = 0,
IDLE_REVIVE = 1,
IDLE_BOOTH = 2;
}
static string[] l_WorkName = new string[EP_work_ID.NUM_WORK]
{
"WORK_STAND",
"WORK_MOVE",
"WORK_HACKOBJECT",
"WORK_SPELL",
"WORK_PICKUP",
"WORK_DEAD",
"WORK_USEITEM",
"WORK_IDLE",
"WORK_FLASHMOVE",
"WORK_PASSIVEMOVE",
"WORK_CONGREGATE",
"WORK_SKILLSTATEACT",
};
protected int m_iWorkID;
protected CECEPWorkMan m_pWorkMan;
protected bool m_bFinished;
protected EC_ElsePlayer GetPlayer()
{
return m_pWorkMan.GetPlayer();
}
public CECEPWork(int iWorkID, CECEPWorkMan pWorkMan)
{
m_iWorkID = iWorkID;
m_pWorkMan = pWorkMan;
m_bFinished = false;
}
public static string GetWorkName(int iWork)
{
if (iWork >= EP_work_ID.WORK_STAND && iWork < l_WorkName.Length)
{
return l_WorkName[iWork];
}
else
{
return "Invalid Work";
}
}
public string GetWorkName()
{
return GetWorkName(GetWorkID());
}
public int GetWorkID()
{
return m_iWorkID;
}
public bool IsFinished()
{
return m_bFinished;
}
public virtual void Start() { }
public virtual void Tick(float dwDeltaTime) { }
public virtual void Cancel() { }
public virtual void Finish()
{
m_bFinished = true;
}
static bool Validate(int iWork)
{
return iWork >= EP_work_ID.WORK_STAND && iWork < EP_work_ID.NUM_WORK;
}
}
// class CECEPWorkSpell
public class CECEPWorkSpell : CECEPWork
{
CECCounter m_SkillCnt;
CECSkill m_pCurSkill;
int m_idCurSkillTarget;
public CECEPWorkSpell(CECEPWorkMan pWorkMan, uint dwPeriod, CECSkill pSkill, int target) : base(CECEPWork.EP_work_ID.WORK_SPELL, pWorkMan)
{
m_pCurSkill = pSkill;
m_idCurSkillTarget = target;
m_SkillCnt.SetPeriod(dwPeriod);
m_SkillCnt.Reset();
}
public override void Start()
{
GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND;
}
public override void Tick(float dwDeltaTime)
{
//TO DO: fix later
//GetPlayer().m_FightCnt.IncCounter(dwDeltaTime);
//int iRealTime = g_pGame.GetRealTickTime();
//if (m_SkillCnt.IncCounter(iRealTime))
//{
// Finish();
//}
//else
//{
// if (m_idCurSkillTarget != 0)
// {
// GetPlayer().TurnFaceTo(m_idCurSkillTarget);
// }
// if (GetPlayer().IsPlayingMoveAction() && !GetPlayer().IsWorkMoveRunning())
// { // 从移动施法到停止移动、会一直在持续播放移动动作,此处暂停
// GetPlayer().PlayAction(CECPlayer::ACT_FIGHTSTAND);
// }
// if (!GetPlayer().IsPlayingAction())
// {
// GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_FIGHTSTAND); // 技能动作播放完成后、播放战斗站立动作
// }
//}
}
public override void Cancel()
{
//TO DO: fix later
//if (m_pCurSkill != null)
//{
// m_pCurSkill = null;
//}
//m_idCurSkillTarget = 0;
//GetPlayer().StopSkillAttackAction();
//GetPlayer().TurnFaceTo(0);
}
public CECSkill GetSkill()
{
return m_pCurSkill;
}
}
public class CECEPWorkMan
{
public static class Work_type
{
public const int WT_NOTHING = 0, // Do thing
WT_NORMAL = 1, // Normal type work
WT_INTERRUPT = 2, // Interrupt type work
NUM_WORKTYPE = 3;
}
private EC_ElsePlayer m_pElsePlayer;
private WorkList[] m_WorkStack = new WorkList[Work_type.NUM_WORKTYPE];
private int m_iCurWorkType;
public CECEPWorkMan(EC_ElsePlayer pElsePlayer)
{
m_pElsePlayer = pElsePlayer;
m_iCurWorkType = -1;
}
public EC_ElsePlayer GetPlayer()
{
return m_pElsePlayer;
}
public bool ValidateWorkType(int iWorkType)
{
return iWorkType >= 0 && iWorkType < Work_type.NUM_WORKTYPE;
}
public bool FindWork(int iWorkType, int iWorkID)
{
if (!ValidateWorkType(iWorkType))
{
return false;
}
WorkList workList = m_WorkStack[iWorkType];
if (workList != null)
{
for (int i = 0; i < workList.Count; ++i)
{
if (iWorkID == workList[i].GetWorkID())
{
return true;
}
}
}
return false;
}
public void StartNormalWork(CECEPWork pWork)
{
StartWork(Work_type.WT_NORMAL, ref pWork);
}
private bool CanRunSimultaneously(CECEPWork pWork1, CECEPWork pWork2)
{
if (pWork1.GetWorkID() == CECEPWork.EP_work_ID.WORK_MOVE &&
pWork2.GetWorkID() == CECEPWork.EP_work_ID.WORK_SPELL)
{
return CanSpellWhileMoving(pWork2 as CECEPWorkSpell);
}
if (pWork2.GetWorkID() == CECEPWork.EP_work_ID.WORK_MOVE &&
pWork1.GetWorkID() == CECEPWork.EP_work_ID.WORK_SPELL)
{
return CanSpellWhileMoving(pWork1 as CECEPWorkSpell);
}
return false;
}
private bool CanReplace(CECEPWork pNewWork, CECEPWork pExistWork)
{
if (pNewWork.GetWorkID() == CECEPWork.EP_work_ID.WORK_SPELL &&
pExistWork.GetWorkID() == CECEPWork.EP_work_ID.WORK_SPELL)
{
return CanSpellWhileMoving(pNewWork as CECEPWorkSpell)
&& CanSpellWhileMoving(pExistWork as CECEPWorkSpell);
}
return false;
}
private bool CanSpellWhileMoving(CECEPWorkSpell pWorkSpell)
{
return false;
// TO DO: fix later
// return pWorkSpell.GetSkill()
// && CECCastSkillWhenMove.Instance().IsSkillSupported(pWorkSpell.GetSkill().GetSkillID(), GetPlayer());
}
private bool CanMergeWithCurrentWork(int iWorkType, CECEPWork pWork)
{
if (!ValidateWorkType(iWorkType) || iWorkType != m_iCurWorkType)
{
return false;
}
WorkList workList = m_WorkStack[iWorkType];
if (workList == null || workList.Count == 0)
{
return false;
}
for (int i = 0; i < workList.Count; ++i)
{
if (!CanRunSimultaneously(pWork, workList[i]) && // 要么同时共存
!CanReplace(pWork, workList[i]))
{ // 要么可以替换
return false;
}
}
return true;
}
private void KillWork(int iWorkType, int index)
{
if (!ValidateWorkType(iWorkType))
{
//ASSERT(false);
return;
}
WorkList workList = m_WorkStack[iWorkType];
if (index < 0 || index >= (int)workList.Count)
{
//ASSERT(false);
return;
}
CECEPWork pWork = workList[index];
pWork.Cancel();
//LOG_DEBUG_INFO(AString().Format("CECEPWorkMan::%s(%s) killed", pWork.GetWorkName(), GetWorkTypeName(iWorkType)));
//delete pWork;
pWork = null;
workList.RemoveAt(index);
}
private void MergeWork(int iWorkType, CECEPWork pWork)
{
if (!CanMergeWithCurrentWork(iWorkType, pWork))
{
//ASSERT(false);
return;
}
WorkList workList = m_WorkStack[iWorkType];
for (int i = 0; i < workList.Count; ++i)
{
if (CanReplace(pWork, workList[i]))
{
//LOG_DEBUG_INFO(AString().Format("CECEPWorkMan::MergeWork %s replacing %s at %s", pWork.GetWorkName(), workList[i].GetWorkName(), GetWorkTypeName(iWorkType)));
KillWork(iWorkType, i);
workList.Insert(i, pWork);
return;
}
}
workList.Add(pWork);
//LOG_DEBUG_INFO(AString().Format("CECEPWorkMan::MergeWork %s appended to %s", pWork.GetWorkName(), GetWorkTypeName(iWorkType)));
}
private void FinishWorkAtWorkType(int iWorkType)
{
if (!ValidateWorkType(iWorkType))
{
//ASSERT(false);
return;
}
WorkList workList = m_WorkStack[iWorkType];
while (workList != null && workList.Count != 0)
{
KillWork(iWorkType, 0);
}
if (m_iCurWorkType == iWorkType)
{
m_iCurWorkType = -1;
}
}
private void AppendWork(int iWorkType, CECEPWork pWork)
{
if (!ValidateWorkType(iWorkType) || pWork == null)
{
//ASSERT(false);
return;
}
m_WorkStack[iWorkType].Add(pWork);
}
private void CancelWorkAtWorkType(int iWorkType)
{
if (!ValidateWorkType(iWorkType))
{
return;
}
WorkList workList = m_WorkStack[iWorkType];
for (int i = 0; i < workList.Count; ++i)
{
CancelWork(workList[i]);
//LOG_DEBUG_INFO(AString().Format("CECEPWorkMan::%s(%s) cancelled", workList[i].GetWorkName(), GetWorkTypeName(iWorkType)));
}
}
private void CancelWork(CECEPWork pWork)
{
if (pWork == null)
{
//ASSERT(false);
return;
}
pWork.Cancel();
}
public void StartWork(int iWorkType, ref CECEPWork pWork)
{
if (!ValidateWorkType(iWorkType))
{
pWork = null;
return;
}
if (CanMergeWithCurrentWork(iWorkType, pWork))
{
MergeWork(iWorkType, pWork);
}
else
{
if (pWork.GetWorkID() == CECEPWork.EP_work_ID.WORK_DEAD)
{
for (int i = iWorkType; i < Work_type.NUM_WORKTYPE; i++)
{
FinishWorkAtWorkType(i);
}
AppendWork(iWorkType, pWork);
m_iCurWorkType = iWorkType;
}
else
{
bool shouldStart = (iWorkType >= m_iCurWorkType);
FinishWorkAtWorkType(iWorkType);
AppendWork(iWorkType, pWork);
if (!shouldStart)
{
//LOG_DEBUG_INFO(AString().Format("CECEPWork::StartWork %s flushed %s", pWork.GetWorkName(), GetWorkTypeName(iWorkType)));
return;
}
if (iWorkType > m_iCurWorkType)
{
CancelWorkAtWorkType(m_iCurWorkType);
}
m_iCurWorkType = iWorkType;
}
}
pWork.Start();
}
private bool IsAnyWorkRunning()
{
return ValidateWorkType(m_iCurWorkType) && m_WorkStack != null && m_WorkStack[m_iCurWorkType] != null;
}
private void StartAwaitingWorks()
{
if (ValidateWorkType(m_iCurWorkType))
{
for (--m_iCurWorkType; m_iCurWorkType >= 0; --m_iCurWorkType)
{
WorkList workList = m_WorkStack[m_iCurWorkType];
if (workList == null || workList.Count == 0)
{
continue;
}
for (int j = 0; j < workList.Count; ++j)
{
workList[j].Start();
//LOG_DEBUG_INFO(AString().Format("CECElsePlayer::StartAwaitingWorks %s(%s) started by decrease priority", workList[j].GetWorkName(), GetWorkTypeName(m_iCurWorkType)));
}
break;
}
}
}
public void Tick(float dwDeltaTime)
{
if (!IsAnyWorkRunning())
{
return;
}
WorkList workList = m_WorkStack[m_iCurWorkType];
if (workList != null)
{
for (int i = 0; i < workList.Count;)
{
CECEPWork pWork = workList[i];
pWork.Tick(dwDeltaTime);
if (!pWork.IsFinished())
{
++i;
continue;
}
KillWork(m_iCurWorkType, i);
}
if (workList == null || workList.Count == 0)
{
StartAwaitingWorks();
}
}
}
public void FinishWork(CECEPWorkMatcher matcher)
{
bool bCurrentWorkFinished = false;
for (int i = Work_type.NUM_WORKTYPE - 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))
{
++j;
continue;
}
KillWork(i, j);
if (i == m_iCurWorkType && (workList == null || workList.Count == 0))
{
bCurrentWorkFinished = true;
}
}
}
if (bCurrentWorkFinished)
{
StartAwaitingWorks();
}
}
public void FinishWork(int idWork)
{
FinishWork(new CECEPWorkIDMatcher(idWork));
}
public bool IsWorkRunning(int iWork)
{
return FindWork(m_iCurWorkType, iWork);
}
public void FinishRunningWork(int idWork)
{
if (!IsWorkRunning(idWork))
{
return;
}
WorkList workList = m_WorkStack[m_iCurWorkType];
if (workList != null)
{
for (int i = 0; i < workList.Count;)
{
if (workList[i].GetWorkID() != idWork)
{
++i;
continue;
}
//LOG_DEBUG_INFO(AString().Format("CECEPWorkMan::FinishRunningWork %s(%s)", workList[i].GetWorkName(), GetWorkTypeName(m_iCurWorkType)));
KillWork(m_iCurWorkType, i);
}
if (workList == null)
{
StartAwaitingWorks();
}
}
}
public bool FinishIdleWork(int iType)
{
FinishWork(new CECEPIdleWorkMatcher(iType));
return true;
}
public bool FinishCongregateWork(int iType)
{
FinishWork(new CECEPCongregateWorkMatcher(iType));
return true;
}
}
}