using UnityEngine;
|
using Snxxz.UI;
|
using System.Collections.Generic;
|
using UnityEngine.EventSystems;
|
|
public class STM_BaseAttack : SMB_Base
|
{
|
protected float m_Duration;
|
protected float m_ProcessFrame;
|
protected int m_ProcessIndex;
|
|
protected float m_MoveDuration;
|
protected float m_MoveEscape;
|
protected AnimationCurve m_MoveCurve;
|
protected Vector3 m_ClickedEndPosition;
|
public int cacheSkillID;
|
protected Skill m_CacheSkill;
|
protected float m_AnimatorSpeed = 1;
|
protected float m_EffectAnimatorSpeed = 1;
|
|
private bool m_HasHandleDelayLogic = false;
|
protected bool hasHandleDelayLogic
|
{
|
get
|
{
|
return m_HasHandleDelayLogic;
|
}
|
set
|
{
|
m_HasHandleDelayLogic = value;
|
}
|
|
}
|
|
protected bool m_NeedMove;
|
protected Vector3 m_EndPosition;
|
|
#if UNITY_EDITOR
|
protected Vector3 m_EnterPos;
|
#endif
|
protected List<NPCPos> m_NpcPosList = new List<NPCPos>();
|
protected List<SFXController> m_CastedEffect = new List<SFXController>();
|
protected List<float> m_DelayHurtBlood = new List<float>();
|
|
private float m_AnimationPauseStartTime;
|
private float m_AnimationPauseLastTime;
|
private bool m_StartPauseAnimator;
|
private bool m_IsLastHitFrame = false;
|
|
protected SFXController m_StartHeadEffect;
|
private float m_GhostCreateDuration;
|
private float m_GhostLastTime;
|
private float m_GhostCreateInterval;
|
private Color m_GhostColor;
|
private float m_Intensity;
|
private float m_GhostCreateCalculateTime;
|
|
protected override void OnEnter(GActor owner, Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
{
|
base.OnEnter(owner, animator, stateInfo, layerIndex);
|
|
m_CastedEffect.Clear();
|
m_Duration = 0;
|
m_ProcessFrame = 0;
|
m_ProcessIndex = 0;
|
m_MoveDuration = 0;
|
m_GhostCreateDuration = 0;
|
m_GhostCreateInterval = 0;
|
m_GhostCreateCalculateTime = 0;
|
m_Intensity = 0;
|
m_DelayHurtBlood.Clear();
|
m_ClickedEndPosition = Vector3.zero;
|
hasHandleDelayLogic = false;
|
m_EndPosition = owner.Pos;
|
#if UNITY_EDITOR
|
m_EnterPos = m_EndPosition;
|
#endif
|
GActorFight _fight = owner as GActorFight;
|
|
if (_fight.SkillMgr.CurCastSkill != null)
|
{
|
cacheSkillID = _fight.SkillMgr.CurCastSkill.id;
|
m_CacheSkill = _fight.SkillMgr.Get(cacheSkillID);
|
}
|
|
if (m_CacheSkill == null)
|
{
|
return;
|
}
|
|
if (owner.ActorType == GameObjType.gotPlayer)
|
{
|
GActorPlayerBase _player = owner as GActorPlayerBase;
|
|
if (m_CacheSkill.skillInfo.soFile != null)
|
{
|
if (m_CacheSkill.skillInfo.soFile.ghostEffectID != 0)
|
{
|
InitGhostShadow(m_CacheSkill.skillInfo.soFile.ghostEffectID);
|
}
|
|
if (m_CacheSkill.skillInfo.soFile.effectOnTargetHead > 0)
|
{
|
if (m_CacheSkill.mainTarget != null)
|
{
|
m_StartHeadEffect = SFXPlayUtility.Instance.PlayEffectAsync(m_CacheSkill.skillInfo.soFile.effectOnTargetHead, m_CacheSkill.mainTarget);
|
}
|
}
|
|
if (m_CacheSkill.skillInfo.config.AtkType != (int)E_AtkType.FastMove)
|
{
|
m_EffectAnimatorSpeed = m_AnimatorSpeed = animator.speed = owner.ActorInfo.atkSpeed;
|
}
|
}
|
|
if (m_CacheSkill.skillInfo.soFile != null)
|
{
|
if (m_CacheSkill.skillInfo.soFile.hideWeapon)
|
{
|
_player.ShowOrHideWeapon(false);
|
}
|
}
|
|
_player.SwitchHeadNameBindNode(true);
|
|
if (owner.ServerInstID == PlayerDatas.Instance.PlayerId)
|
{
|
if (owner.State == E_ActorState.AutoRun)
|
{
|
owner.StopPathFind();
|
// 同步停止协议
|
C0502_tagCPlayerStopMove _0502 = new C0502_tagCPlayerStopMove();
|
_0502.Dir = 0;
|
_0502.PosX = (ushort)(owner.Pos.x * 2);
|
_0502.PosY = (ushort)(owner.Pos.z * 2);
|
_0502.WorldTick = 0;
|
|
if (!CrossServerUtility.IsCrossServer())
|
{
|
GameNetSystem.Instance.SendInfo(_0502);
|
}
|
else
|
{
|
GameNetSystem.Instance.SendToCrossServer(_0502);
|
}
|
}
|
|
if (owner.MP_Name1)
|
{
|
HeadUpSkillName.Popup(cacheSkillID, owner.MP_Name1.position, CameraController.Instance.CameraObject);
|
}
|
else
|
{
|
HeadUpSkillName.Popup(cacheSkillID, owner.Root.position, CameraController.Instance.CameraObject);
|
}
|
}
|
|
if (_player is GA_Player)
|
{
|
(_player as GA_Player).StopMoveToPosition();
|
}
|
|
#if UNITY_EDITOR
|
string _content = string.Format("STM_BaseAttack => {0} 的技能: {1} 进入技能状态逻辑", owner.ServerInstID, cacheSkillID);
|
RuntimeLogUtility.AddLog_Green(_content);
|
#endif
|
}
|
|
if (owner is GA_Player || owner is GA_Hero)
|
{
|
if (owner.State != E_ActorState.Roll)
|
{
|
owner.State = E_ActorState.CastSkill;
|
}
|
}
|
|
}
|
|
protected override void OnUpdate(GActor owner, Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
{
|
base.OnUpdate(owner, animator, stateInfo, layerIndex);
|
GActorFight _fight = owner as GActorFight;
|
|
if (GA_Hero.s_MapSwitching)
|
{
|
return;
|
}
|
|
if (m_CacheSkill == null)
|
{
|
return;
|
}
|
|
if (m_GhostCreateDuration > 0)
|
{
|
m_GhostCreateDuration -= Time.deltaTime;
|
m_GhostCreateCalculateTime += Time.deltaTime;
|
if (m_GhostCreateCalculateTime > m_GhostCreateInterval)
|
{
|
XRayShadow.Request(_fight.GetSMRenderer(), m_GhostColor, m_Intensity, m_GhostLastTime);
|
m_GhostCreateCalculateTime = 0;
|
}
|
}
|
|
m_Duration += Time.deltaTime;
|
|
m_ProcessFrame = (int)(m_Duration * 30 * animator.speed);
|
|
ProcessFrameEvent(owner, animator, stateInfo);
|
|
HandleInputMove();
|
|
if (m_StartPauseAnimator)
|
{
|
if (Time.time - m_AnimationPauseStartTime > m_AnimationPauseLastTime)
|
{
|
owner.SetAnimatorSpeed(1);
|
m_StartPauseAnimator = false;
|
ChangeCastedEffectAnimatorSpeed(1);
|
}
|
else
|
{
|
owner.SetAnimatorSpeed(0);
|
ChangeCastedEffectAnimatorSpeed(0);
|
return;
|
}
|
}
|
}
|
|
protected override void OnExit(GActor owner, Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
|
{
|
base.OnExit(owner, animator, stateInfo, layerIndex);
|
|
OnFininshedFightMove();
|
|
GActorFight _fight = owner as GActorFight;
|
|
if (_fight == null)
|
{
|
#if UNITY_EDITOR
|
Debug.LogErrorFormat("owner: {0} 类型问题: {1}", owner.ServerInstID, owner.GetType());
|
#endif
|
return;
|
}
|
|
_fight.SkillMgr.DoingPrepareSkill = false;
|
|
if (owner.ActorType == GameObjType.gotPlayer)
|
{
|
GActorPlayerBase _player = owner as GActorPlayerBase;
|
if (_player != null)
|
{
|
_player.SwitchHeadNameBindNode(false);
|
_player.ShowOrHideWeapon(true);
|
}
|
animator.speed = 1;
|
|
#if UNITY_EDITOR
|
string _content = string.Format("STM_BaseAttack => {0} 的技能: {1} 退出技能状态逻辑", owner.ServerInstID, cacheSkillID);
|
RuntimeLogUtility.AddLog_Green(_content);
|
#endif
|
}
|
|
if (_fight.OnSkillCompelete != null && m_CacheSkill != null)
|
{
|
_fight.OnSkillCompelete(m_CacheSkill.id);
|
}
|
|
ProcessDelayLogic();
|
|
if (owner is GA_Player || owner is GA_Hero)
|
{
|
if (owner.State == E_ActorState.CastSkill
|
|| (m_CacheSkill != null && m_CacheSkill.id == 190 && owner.State == E_ActorState.Roll))
|
{
|
owner.State = E_ActorState.Idle;
|
}
|
}
|
|
if (m_CacheSkill != null)
|
{
|
m_CacheSkill.cacheBuffList.Clear();
|
m_CacheSkill.SkillCompelete = true;
|
m_CacheSkill = null;
|
}
|
|
if (m_StartHeadEffect != null)
|
{
|
SFXPlayUtility.Instance.Release(m_StartHeadEffect);
|
m_StartHeadEffect = null;
|
}
|
|
for (int i = 0; i < m_CastedEffect.Count; ++i)
|
{
|
if (m_CastedEffect[i] == null)
|
{
|
continue;
|
}
|
m_CastedEffect[i].SetAnimatorSpeed(1);
|
if (m_CastedEffect[i].config != null
|
&& m_CastedEffect[i].config.stopImmediate == 1)
|
{
|
SFXPlayUtility.Instance.Release(m_CastedEffect[i]);
|
}
|
}
|
m_CastedEffect.Clear();
|
#if UNITY_EDITOR
|
if (RuntimeLogUtility.s_LogMoveDistance)
|
{
|
float _moveDistance = MathUtility.DistanceSqrtXZ(m_EnterPos, owner.Pos);
|
_moveDistance = Mathf.Sqrt(_moveDistance);
|
if (owner.ServerInstID == PlayerDatas.Instance.PlayerId)
|
{
|
Debug.LogFormat("此次技能位移了: {0} 米", _moveDistance);
|
}
|
}
|
#endif
|
}
|
|
private void ChangeCastedEffectAnimatorSpeed(float speed)
|
{
|
m_EffectAnimatorSpeed = speed;
|
for (int i = 0; i < m_CastedEffect.Count; ++i)
|
{
|
m_CastedEffect[i].SetAnimatorSpeed(speed);
|
}
|
}
|
|
protected void ProcessDelayLogic()
|
{
|
if (hasHandleDelayLogic)
|
{
|
return;
|
}
|
|
GActorFight _target = null;
|
|
int _hurtTotalValue = 0;
|
float _totalPercent = 0;
|
|
// 延迟飘血
|
if (m_DelayHurtBlood.Count > 0)
|
{
|
|
if (m_CacheSkill == null)
|
{
|
return;
|
}
|
|
for (int i = 0; i < m_DelayHurtBlood.Count; ++i)
|
{
|
_totalPercent += m_DelayHurtBlood[i];
|
}
|
|
m_DelayHurtBlood.Clear();
|
}
|
|
AttackHandler.HurtObjs _hurtObj;
|
|
if (m_CacheSkill != null)
|
{
|
for (int i = 0; i < m_CacheSkill.hurtServerList.Count; ++i)
|
{
|
_hurtObj = m_CacheSkill.hurtServerList[i];
|
_target = GAMgr.Instance.GetByCID(_hurtObj.clientInstID) as GActorFight;
|
|
if (_target == null)
|
{
|
continue;
|
}
|
|
_hurtTotalValue = (int)(_hurtObj.HurtHP * _totalPercent);
|
|
if (_hurtTotalValue != 0)
|
{
|
GAStaticDefine.PopHp(owner, _target, _hurtObj.AttackType, _hurtTotalValue);
|
}
|
|
if (_target.ActorInfo.serverDie)
|
{
|
_target.Die(owner.ServerInstID, 0, _hurtObj.AttackType);
|
}
|
else
|
{
|
_target.ActorInfo.ResetHp((int)_target.ActorInfo.SyncServerHp, (short)_target.ActorInfo.SyncServerHpEx);
|
}
|
|
// 主角血量扣除的补充
|
if (_target.ServerInstID == PlayerDatas.Instance.PlayerId)
|
{
|
PlayerDatas.Instance.FightRefreshPlayerHp((uint)_target.ActorInfo.SyncServerHp);
|
}
|
}
|
|
// 延迟死亡
|
for (int i = 0; i < m_CacheSkill.hurtClientList.Count; ++i)
|
{
|
_target = GAMgr.Instance.GetByCID(m_CacheSkill.hurtClientList[i].clientInstID) as GActorFight;
|
|
if (_target == null)
|
{
|
continue;
|
}
|
|
if (_target.ActorInfo.serverDie)
|
{
|
_target.Die(owner.ServerInstID, 0, m_CacheSkill.hurtClientList[i].AttackType);
|
}
|
}
|
|
for (int i = 0; i < m_CacheSkill.hurtClntFightNpcList.Count; ++i)
|
{
|
_target = GAMgr.Instance.GetByCID(m_CacheSkill.hurtClntFightNpcList[i].clientInstID) as GActorFight;
|
|
if (_target == null)
|
{
|
continue;
|
}
|
|
if (_target.ActorInfo.serverDie)
|
{
|
_target.Die(owner.ServerInstID, 0, m_CacheSkill.hurtClntFightNpcList[i].AttackType);
|
}
|
}
|
}
|
|
hasHandleDelayLogic = true;
|
}
|
|
private void ProcessFrameEvent(GActor owner, Animator animator, AnimatorStateInfo stateInfo)
|
{
|
if (m_CacheSkill.skillInfo.soFile == null)
|
{
|
return;
|
}
|
|
for (; m_ProcessIndex < m_CacheSkill.skillInfo.soFile.animationEventList.Count; ++m_ProcessIndex)
|
{
|
|
if (m_ProcessFrame < m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].index)
|
{
|
break;
|
}
|
|
switch (m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].frameEventType)
|
{
|
case E_FrameEventType.OnSkillEvent:
|
OnSkillEvent(m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].intParam);
|
break;
|
case E_FrameEventType.OnPlayEffect:
|
|
int _effectConfigID = m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].intParam;
|
|
OnPlayerEffect(_effectConfigID);
|
|
break;
|
case E_FrameEventType.OnSkillComplete:
|
OnSkillComplete();
|
break;
|
case E_FrameEventType.OnAnimationPause:
|
OnAnimationPause(m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].intParam);
|
break;
|
case E_FrameEventType.OnTimePause:
|
if (owner is GA_Hero)
|
{
|
SnxxzGame.Instance.StartTimePause(m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].intParam * Constants.F_GAMMA);
|
}
|
break;
|
case E_FrameEventType.OnSkillPrepare:
|
break;
|
case E_FrameEventType.OnCreateGhost:
|
int _id = m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].intParam;
|
InitGhostShadow(_id);
|
break;
|
case E_FrameEventType.OnPlayAudio:
|
|
bool _needPlay = true;
|
if (owner.ActorType == GameObjType.gotPlayer)
|
{
|
if (owner.ServerInstID != PlayerDatas.Instance.PlayerId)
|
{
|
if (m_CacheSkill.skillInfo.config.SkillOfSeries == 1)
|
{
|
_needPlay = false;
|
}
|
}
|
}
|
|
if (_needPlay)
|
{
|
int _audioID = m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].intParam;
|
GActorFight _fighter = owner as GActorFight;
|
if (_fighter != null)
|
{
|
_fighter.PlaySkillAudio(_audioID);
|
}
|
}
|
|
break;
|
}
|
}
|
|
}
|
|
private void OnAnimationPause(int param)
|
{
|
m_AnimationPauseLastTime = param * Constants.F_GAMMA;
|
m_AnimationPauseStartTime = Time.time;
|
m_StartPauseAnimator = true;
|
// Debug.Log("------------------------ 开始顿帧");
|
}
|
|
private void OnSkillEvent(int param)
|
{
|
//SnxxzGame.Instance.AddLog("log", string.Format("技能: {0} 已经开始处理帧: {1}的事件", m_CacheSkill.id, m_ProcessFrame));
|
//Debug.Log(string.Format("技能: {0} 已经开始处理帧: {1} 的事件", m_CacheSkill.id, m_ProcessFrame));
|
SoSkill.E_AttackType _type;
|
int _id;
|
int _param;
|
SoConfigBase _config = null;
|
m_IsLastHitFrame = true;
|
|
// 判断是否是最后一个伤害帧
|
for (int i = m_ProcessIndex + 1; i < m_CacheSkill.skillInfo.soFile.animationEventList.Count; ++i)
|
{
|
if (m_CacheSkill.skillInfo.soFile.animationEventList[i].frameEventType != E_FrameEventType.OnSkillEvent)
|
{
|
continue;
|
}
|
_config = null;
|
_param = m_CacheSkill.skillInfo.soFile.animationEventList[i].intParam;
|
_type = SoSkill.GetAttactType(_param);
|
_id = SoSkill.GetFrameEventId(_param);
|
if (_type == SoSkill.E_AttackType.Sweep)
|
{
|
_config = ScriptableObjectLoader.LoadSoSweepHit(_id);
|
}
|
else if (_type == SoSkill.E_AttackType.FlyObject)
|
{
|
_config = ScriptableObjectLoader.LoadSoFlyObject(_id);
|
}
|
if (_config != null && _config.floodPercent != 0)
|
{
|
m_IsLastHitFrame = false;
|
break;
|
}
|
}
|
|
_type = SoSkill.GetAttactType(param);
|
_id = SoSkill.GetFrameEventId(param);
|
|
// Debug.LogFormat("类型: {0}, 数值: {1}", _type, _id);
|
switch (_type)
|
{
|
case SoSkill.E_AttackType.Sweep:
|
|
SweepProcess(_id);
|
|
break;
|
case SoSkill.E_AttackType.FlyObject:
|
|
FlyObjectProcess(_id);
|
|
break;
|
}
|
}
|
|
protected virtual void SweepProcess(int id)
|
{
|
SoSweepHit _sweepHit = ScriptableObjectLoader.LoadSoSweepHit(id);
|
|
if (_sweepHit == null)
|
{
|
Debug.LogErrorFormat("技能{0}的Sweep配置出错, 找不到给定的Id: {1}", cacheSkillID, id);
|
return;
|
}
|
|
if (!PreFightMission.Instance.IsFinished())
|
{
|
if (m_CacheSkill.id == 10026)
|
{
|
PreFightMission.Instance.Create8SmallBoss(owner.Pos);
|
}
|
}
|
|
if (PlayerDatas.Instance.PlayerId == owner.ServerInstID)
|
{
|
if (_sweepHit.cameraSfxId != 0)
|
{
|
SoCameraSFX _cameraSFX = ScriptableObjectLoader.LoadSoCameraSFX(_sweepHit.cameraSfxId);
|
if (_cameraSFX != null)
|
{
|
CameraController.Instance.DoShake(_cameraSFX.direction, _cameraSFX.power, _cameraSFX.interval, _cameraSFX.duration);
|
|
CameraController.Instance.StartZoom(_cameraSFX.zoomScale, _cameraSFX.zoomTime);
|
}
|
}
|
}
|
|
if ((owner is GA_NpcFightBoss
|
|| owner is GA_NpcClientFightBoss)
|
&& m_CacheSkill.id == 10016)
|
{
|
GActorNpcFight _boss = owner as GActorNpcFight;
|
if (_boss.NpcConfig.Sounds != null && _boss.NpcConfig.Sounds.Length > 0)
|
{
|
(owner as GActorNpcFight).PlaySkillAudio(_boss.NpcConfig.Sounds[0]);
|
}
|
}
|
|
GActorFight _fight = owner as GActorFight;
|
DesiceFightMove(_fight, _sweepHit);
|
|
GActorFight _target = null;
|
int _hurtTotalValue = 0;
|
|
m_NpcPosList.Clear();
|
|
float _floodPercent = _sweepHit.floodPercent * Constants.F_DELTA;
|
|
if (m_CacheSkill.hurtServerList.Count > 0)
|
{
|
for (int i = 0; i < m_CacheSkill.hurtServerList.Count; ++i)
|
{
|
_target = GAMgr.Instance.GetByCID(m_CacheSkill.hurtServerList[i].clientInstID) as GActorFight;
|
|
if (_target == null)
|
{
|
continue;
|
}
|
|
if (_target is GA_Pet)
|
{
|
Debug.LogFormat("收到服务端封包, 释放者: {0}, 使用技能: {1} 的伤害宠物类型....SID: {2}, CID: {3}",
|
owner.ServerInstID,
|
m_CacheSkill.id,
|
m_CacheSkill.hurtServerList[i].ObjID,
|
m_CacheSkill.hurtServerList[i].clientInstID);
|
}
|
|
_hurtTotalValue = (int)(m_CacheSkill.hurtServerList[i].HurtHP * _floodPercent);
|
|
AttackHandler.HandlerAttackTarget(_fight,
|
_target,
|
_hurtTotalValue,
|
m_CacheSkill.hurtServerList[i].AttackType,
|
m_CacheSkill.id,
|
id,
|
_sweepHit,
|
_target.ActorInfo.serverDie && m_IsLastHitFrame);
|
|
if (!_target.ActorInfo.serverDie
|
&& m_CacheSkill.hurtServerList[i].AttackType != (byte)HurtAttackType.Miss)
|
{
|
AddToNpcPosList(_fight, _target, _sweepHit.bodyControlId, (_target.Pos - owner.Pos).normalized, m_NpcPosList);
|
}
|
}
|
}
|
//#if UNITY_EDITOR
|
// else
|
// {
|
// string _content = string.Format("技能: {0} 第 {1} 帧, 第 {2} 个插帧没有任何服务端攻击对象. ---- {3}", m_CacheSkill.id, m_ProcessFrame, m_ProcessIndex, m_CacheSkill.GetHashCode());
|
// RuntimeLogUtility.AddLog_Red(_content);
|
// }
|
//#endif
|
|
if (m_CacheSkill.hurtClientList.Count > 0)
|
{
|
for (int i = 0; i < m_CacheSkill.hurtClientList.Count; ++i)
|
{
|
_target = GAMgr.Instance.GetByCID(m_CacheSkill.hurtClientList[i].clientInstID) as GActorFight;
|
|
if (_target == null)
|
{
|
continue;
|
}
|
|
_hurtTotalValue = Mathf.CeilToInt(m_CacheSkill.hurtClientList[i].HurtHP * _floodPercent);
|
|
AttackHandler.HandlerAttackTarget(_fight,
|
_target,
|
_hurtTotalValue,
|
m_CacheSkill.hurtClientList[i].AttackType,
|
m_CacheSkill.id,
|
id,
|
_sweepHit,
|
m_IsLastHitFrame && _target.ActorInfo.serverDie);
|
|
|
|
if (!_target.ActorInfo.serverDie
|
&& m_CacheSkill.hurtClientList[i].AttackType != (byte)HurtAttackType.Miss)
|
{
|
AddToNpcPosList(_fight, _target, _sweepHit.bodyControlId, (_target.Pos - owner.Pos).normalized, m_NpcPosList);
|
}
|
}
|
}
|
|
if (m_CacheSkill.hurtClntFightNpcList.Count > 0)
|
{
|
for (int i = 0; i < m_CacheSkill.hurtClntFightNpcList.Count; ++i)
|
{
|
_target = GAMgr.Instance.GetByCID(m_CacheSkill.hurtClntFightNpcList[i].clientInstID) as GActorFight;
|
|
if (_target == null)
|
{
|
continue;
|
}
|
|
_hurtTotalValue = (int)(m_CacheSkill.hurtClntFightNpcList[i].HurtHP * _floodPercent);
|
|
AttackHandler.HandlerAttackTarget(_fight, _target, _hurtTotalValue,
|
m_CacheSkill.hurtClntFightNpcList[i].AttackType,
|
m_CacheSkill.id, id, _sweepHit,
|
_target.ActorInfo.serverDie && m_IsLastHitFrame);
|
}
|
}
|
|
if (m_CacheSkill.hurtServerList.Count == 0)
|
{
|
m_DelayHurtBlood.Add(_floodPercent);
|
}
|
|
if (m_NpcPosList.Count > 0)
|
{
|
if (!ClientDungeonStageUtility.isClientDungeon
|
&& !ClientSceneManager.Instance.IsClientFightMode
|
#if UNITY_EDITOR
|
&& !RuntimeLogUtility.TEST_CLIENT_PVP
|
#endif
|
)
|
{
|
CB402_tagCMNPCBeatBack _beatBack = new CB402_tagCMNPCBeatBack();
|
_beatBack.ObjType = (byte)GameObjType.gotNPC;
|
_beatBack.Count = (byte)m_NpcPosList.Count;
|
_beatBack.NPCPosList = new CB402_tagCMNPCBeatBack.tagCMNPCPos[_beatBack.Count];
|
|
for (int i = 0; i < _beatBack.Count; ++i)
|
{
|
_beatBack.NPCPosList[i] = new CB402_tagCMNPCBeatBack.tagCMNPCPos
|
{
|
ObjID = (uint)m_NpcPosList[i].objId,
|
PosX = (ushort)(m_NpcPosList[i].posX + GA_Hero.MapOffset.x),
|
PosY = (ushort)(m_NpcPosList[i].posY + GA_Hero.MapOffset.z)
|
};
|
}
|
|
if (!CrossServerUtility.IsCrossServer())
|
{
|
GameNetSystem.Instance.SendInfo(_beatBack);
|
}
|
else
|
{
|
GameNetSystem.Instance.SendToCrossServer(_beatBack);
|
}
|
}
|
|
}
|
|
}
|
|
protected virtual void FlyObjectProcess(int id)
|
{
|
SoFlyObject _config = ScriptableObjectLoader.LoadSoFlyObject(id);
|
|
if (owner.ServerInstID == PlayerDatas.Instance.PlayerId)
|
{
|
if (_config.cameraSfxId != 0)
|
{
|
SoCameraSFX _cameraSFX = ScriptableObjectLoader.LoadSoCameraSFX(_config.cameraSfxId);
|
if (_cameraSFX != null)
|
{
|
CameraController.Instance.DoShake(_cameraSFX.direction, _cameraSFX.power, _cameraSFX.interval, _cameraSFX.duration);
|
|
CameraController.Instance.StartZoom(_cameraSFX.zoomScale, _cameraSFX.zoomTime);
|
}
|
}
|
}
|
|
GActorFight _fight = owner as GActorFight;
|
|
DesiceFightMove(_fight, _config);
|
|
FlyObject.InitInfo _initInfo = new FlyObject.InitInfo();
|
_initInfo.casterServerObjID = owner.ServerInstID;
|
_initInfo.isLastShoot = m_IsLastHitFrame;
|
_initInfo.configId = id;
|
_initInfo.skillId = cacheSkillID;
|
|
if (_fight.SelectTarget != null)
|
{
|
_initInfo.mainTargetClientInstID = _fight.SelectTarget.ClientInstID;
|
}
|
if (string.IsNullOrEmpty(_config.shootNode) == false)
|
{
|
_initInfo.position = owner.Root.GetChildTransformDeeply(_config.shootNode).position;
|
}
|
else
|
{
|
_initInfo.position = owner.Pos;
|
}
|
_initInfo.forward = owner.Forward;
|
|
FlyObjectManager.Instance.Create(_initInfo);
|
|
}
|
|
protected void DesiceFightMove(GActorFight fightActor, SoConfigBase config)
|
{
|
m_NeedMove = config != null
|
&& config.curve != null
|
&& config.moveDuration > 0
|
&& fightActor != null
|
&& StatusMgr.Instance.CanMove(fightActor.ServerInstID);
|
|
if (m_NeedMove)
|
{
|
bool _moveThrougthEnable = config.moveThrougthEnable;
|
bool _forceMoveThrougth = config.forceMoveThrougthEnable;
|
|
if (m_CacheSkill != null
|
&& m_CacheSkill.skillInfo != null
|
&& m_CacheSkill.skillInfo.config != null
|
&& m_CacheSkill.skillInfo.config.Skillactmark != GAStaticDefine.Act_Roll)
|
{
|
if (fightActor.SelectTarget != null
|
&& !fightActor.SelectTarget.ActorInfo.serverDie)
|
{
|
if (fightActor.SelectTarget.ActorType == GameObjType.gotNPC)
|
{
|
GActorNpcFight _npc = fightActor.SelectTarget as GActorNpcFight;
|
if (_npc != null)
|
{
|
if (_npc.NpcConfig != null)
|
{
|
m_NeedMove = _npc.NpcConfig.weight != 0 && _moveThrougthEnable;
|
|
if (!m_NeedMove)
|
{
|
m_NeedMove = _forceMoveThrougth;
|
}
|
}
|
}
|
}
|
else
|
{
|
m_NeedMove = _moveThrougthEnable;
|
}
|
}
|
}
|
}
|
if (m_NeedMove)
|
{
|
m_MoveDuration = config.moveDuration;
|
m_MoveEscape = 0;
|
m_MoveCurve = config.curve;
|
|
E_SkillCastType _type = (E_SkillCastType)(m_CacheSkill.skillInfo.config.Tag % 10);
|
|
m_EndPosition = m_CacheSkill.targetPosition;
|
}
|
else
|
{
|
if (m_MoveEscape < m_Duration)
|
{
|
m_NeedMove = true;
|
}
|
else
|
{
|
m_MoveCurve = null;
|
}
|
}
|
|
}
|
|
private void HandleInputMove()
|
{
|
GActorFight _fight = owner as GActorFight;
|
|
if (m_CacheSkill.skillInfo.soFile != null && m_CacheSkill.skillInfo.soFile.acceptInput)
|
{
|
if (owner.ServerInstID == PlayerDatas.Instance.PlayerId)
|
{
|
GA_Hero _hero = PlayerDatas.Instance.hero;
|
|
if (UserInputHandler.isTouched)
|
{
|
Vector3 _position = owner.Pos;
|
Vector3 _nextPosition = _position + owner.destForward * owner.ActorInfo.moveSpeed * Time.deltaTime;
|
|
if (GActor.TryGetValidPos(_nextPosition, ref _position))
|
{
|
owner.Pos = new Vector3(_position.x, owner.Pos.y, _position.z);
|
}
|
}
|
else
|
{
|
if (Input.GetMouseButtonDown(0))
|
{
|
Camera _mainCamera = CameraController.Instance.CameraObject;
|
|
bool _valid = true;
|
#if UNITY_EDITOR
|
if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject())
|
{
|
_valid = false;
|
}
|
#else
|
int id = Input.GetTouch(0).fingerId;
|
if (EventSystem.current != null &&EventSystem.current.IsPointerOverGameObject(id))
|
{
|
_valid = false;
|
}
|
#endif
|
RaycastHit _hitInfo;
|
Ray _ray = _mainCamera.ScreenPointToRay(Input.mousePosition);
|
|
Vector3 _destPosition = owner.Pos;
|
|
if (!Physics.Raycast(_ray, out _hitInfo, 100, LayerUtility.WalkbleMask))
|
{
|
_valid = false;
|
}
|
|
if (!GActor.TryGetValidPos(_hitInfo.point, ref _destPosition))
|
{
|
_valid = false;
|
}
|
|
if (_valid)
|
{
|
m_ClickedEndPosition = _destPosition;
|
}
|
}
|
|
if (m_ClickedEndPosition != Vector3.zero)
|
{
|
Vector3 _direction = (m_ClickedEndPosition - owner.Pos).normalized;
|
owner.Pos += _direction * owner.ActorInfo.moveSpeed * Time.deltaTime;
|
}
|
}
|
|
float _distance = MathUtility.DistanceSqrtXZ(_hero.PrevPos, _hero.Pos);
|
if (_distance > 0.25f)
|
{
|
_hero.PrevPos = _hero.Pos;
|
UserInputHandler.Send_CB409_tagCMPyMove(0);
|
}
|
}
|
}
|
else
|
{
|
if (m_NeedMove && m_MoveCurve != null)
|
{
|
m_MoveEscape += Time.deltaTime;
|
|
float _moveSpeed = m_MoveCurve.Evaluate(m_MoveEscape);
|
|
Vector3 _nextPosition = Vector3.MoveTowards(owner.Pos, m_EndPosition, _moveSpeed * Time.deltaTime);
|
if (GActor.TryGetValidPos(_nextPosition, ref _nextPosition))
|
{
|
owner.Pos = new Vector3(_nextPosition.x, owner.Pos.y, _nextPosition.z);
|
}
|
|
if (m_MoveEscape > m_MoveDuration)
|
{
|
OnFininshedFightMove();
|
}
|
}
|
}
|
}
|
|
protected virtual void OnPlayerEffect(int id)
|
{
|
if (owner.ServerInstID != PlayerDatas.Instance.PlayerId)
|
{
|
// 隐藏其他玩家的时候也不显示他们的特效
|
if (!owner.ShowOrHide)
|
{
|
return;
|
}
|
|
if (SystemSetting.Instance.GetCurrentQualityLevel() == GameQuality.Low)
|
{
|
return;
|
}
|
}
|
|
if (owner is GA_Player && !BattleEffectPlayRule.Instance.CanPlay(owner.ServerInstID))
|
{
|
return;
|
}
|
|
// SFXController _controller = SFXPlayUtility.Instance.PlayEffectAsync(id, owner);
|
|
SFXController _controller = null;
|
if (owner.ActorType == GameObjType.gotPlayer)
|
{
|
_controller = SFXPlayUtility.Instance.PlayEffectAsync(id, owner);
|
}
|
else
|
{
|
_controller = SFXPlayUtility.Instance.PlayBattleEffect(id, owner);
|
}
|
|
if (_controller)
|
{
|
_controller.SetAnimatorSpeed(m_EffectAnimatorSpeed);
|
m_CastedEffect.Add(_controller);
|
}
|
}
|
|
protected virtual void OnSkillComplete()
|
{
|
#if UNITY_EDITOR
|
string _content = string.Format("STM_BaseAttack => {0} 的技能: {1} 执行至 OnSkillComplete 帧", owner.ServerInstID, cacheSkillID);
|
RuntimeLogUtility.AddLog_Green(_content);
|
#endif
|
|
ProcessDelayLogic();
|
|
if (m_CacheSkill != null)
|
{
|
m_CacheSkill.ClearServerHurtList();
|
m_CacheSkill.SkillCompelete = true;
|
m_CacheSkill = null;
|
}
|
}
|
|
private void InitGhostShadow(int id)
|
{
|
SoGhostShadow _ghostShadow = ScriptableObjectLoader.LoadSoGhostShadow(id);
|
m_GhostCreateDuration = _ghostShadow.duration * Constants.F_GAMMA;
|
m_GhostLastTime = _ghostShadow.eachLastTime * Constants.F_GAMMA;
|
m_GhostCreateInterval = _ghostShadow.interval * Constants.F_GAMMA;
|
m_GhostColor = _ghostShadow.color;
|
m_Intensity = _ghostShadow.intensity;
|
}
|
|
private void OnFininshedFightMove()
|
{
|
if (!m_NeedMove)
|
{
|
return;
|
}
|
|
m_NeedMove = false;
|
|
GActorFight _fight = owner as GActorFight;
|
|
if (_fight == null)
|
{
|
return;
|
}
|
|
if (ClientDungeonStageUtility.isClientDungeon
|
#if UNITY_EDITOR
|
|| RuntimeLogUtility.TEST_CLIENT_PVP
|
#endif
|
)
|
{
|
return;
|
}
|
|
if (_fight.ServerInstID == PlayerDatas.Instance.PlayerId)
|
{
|
if (PreFightMission.Instance.IsFinished())
|
{
|
if (MathUtility.DistanceSqrtXZ(_fight.Pos, _fight.PrevPos) > .25f)
|
{
|
//Debug.LogFormat("同步了一次当前的位置, {0} => {1}", new Vector2((int)_fight.prevPos.x * 2,
|
// (int)_fight.prevPos.z * 2),
|
// new Vector2((int)_fight.Pos.x * 2,
|
// (int)_fight.Pos.z * 2));
|
if (m_CacheSkill != null
|
&& m_CacheSkill.skillInfo.config.AtkType != 9
|
&& m_CacheSkill.skillInfo.config.AtkType != 10
|
&& m_CacheSkill.skillInfo.config.AtkType != 34)
|
{
|
CB406_tagCMFightMove _proto = new CB406_tagCMFightMove
|
{
|
StartX = (ushort)(_fight.PrevPos.x * 2 + GA_Hero.MapOffset.x),
|
StartY = (ushort)(_fight.PrevPos.z * 2 + GA_Hero.MapOffset.z),
|
DestX = (ushort)(_fight.Pos.x * 2 + GA_Hero.MapOffset.x),
|
DestY = (ushort)(_fight.Pos.z * 2 + GA_Hero.MapOffset.z),
|
WorldTick = PlayerDatas.Instance.GetWorldTick()
|
};
|
|
if (!CrossServerUtility.IsCrossServer())
|
{
|
GameNetSystem.Instance.SendInfo(_proto);
|
}
|
else
|
{
|
GameNetSystem.Instance.SendToCrossServer(_proto);
|
}
|
}
|
}
|
}
|
}
|
|
_fight.PrevPos = _fight.Pos;
|
}
|
}
|