using vnxbqy.UI;
using UnityEngine;
public abstract class GActorNpcFight : GActorFight, IOtherSelectable
{
protected GameObject m_Model { get; private set; }
protected Animator m_Animator { get; private set; }
private SFXController m_Shadow;
protected DialogueBubble m_DialogAppear;
protected DialogueBubble m_DialogTiming;
protected float m_LastTalkTime;
public NPCConfig NpcConfig { get; protected set; }
public NPCExConfig NpcConfigEx { get; protected set; }
private SFXController m_AppearEffect;
private bool m_LoadDefaultRes = false;
protected bool IsUnInit = false;
///
/// 上一次记录不能被攻击旋转的时间
///
protected float m_LastCantAtkedTime;
public override int NextAction
{
get
{
if (!m_Animator || !m_Animator.runtimeAnimatorController)
{
return -1;
}
return m_Animator.GetInteger(GAStaticDefine.Param_Action);
}
set
{
if (m_Animator && m_Animator.runtimeAnimatorController)
{
if (m_Animator.parameterCount > 0)
{
m_Animator.SetInteger(GAStaticDefine.Param_Action, value);
}
}
}
}
public virtual void InitNpcConfig(int npcID)
{
if (NpcConfig != null && NpcConfig.NPCID == npcID)
{
return;
}
if (npcID > 0)
{
NpcConfig = NPCConfig.Get(npcID);
NpcConfigEx = NPCExConfig.Get(npcID);
}
}
protected override void OnInit(GameNetPackBasic package)
{
base.OnInit(package);
IsUnInit = false;
m_LoadDefaultRes = false;
int _npcID = 0;
if (this is GA_NpcSummonFight)
{
_npcID = (int)(package as H0408_tagPlayerSummonNPCAppear).NPCID;
}
else if (this is GA_Pet)
{
_npcID = (int)(package as H0435_tagPetAppear).NPCID;
}
else if (this is GA_NpcFightNorm)
{
_npcID = (int)(package as H0406_tagNPCAppear).NPCID;
}
InitNpcConfig(_npcID);
if (NpcConfig == null)
{
// 报错
Debug.LogError("配置异常....: " + _npcID);
return;
}
ActorType = GameObjType.gotNPC;
Root.gameObject.layer = LayerUtility.Monster;
if (NpcConfig.ModeProportion != 1)
{
Root.localScale = Vector3.one * NpcConfig.ModeProportion;
}
if (CanBeSelected())
{
CapsuleCollider _collider = Root.AddMissingComponent();
_collider.center = new Vector3(0, NpcConfig.ModleHeight * .5f, 0);
_collider.radius = NpcConfig.ModelRadius;
_collider.height = NpcConfig.ModleHeight;
}
RequestShadow();
InstanceResourcesLoader.AsyncLoadNpc(NpcConfig.NPCID, OnPrefabLoadFinished);
}
private void OnPrefabLoadFinished(bool result, UnityEngine.Object prefab)
{
if (IsUnInit)
{
return;
}
if (!result || prefab == null)
{
if (!m_LoadDefaultRes)
{
m_LoadDefaultRes = true;
if (this is GA_Pet)
{
InstanceResourcesLoader.AsyncLoadDefaultPet(OnPrefabLoadFinished);
}
else
{
InstanceResourcesLoader.AsyncLoadDefaultFightNpc(OnPrefabLoadFinished);
}
}
else
{
m_LoadDefaultRes = false;
Debug.LogErrorFormat("加载Npc模型资源出错: {0}", NpcConfig.NPCID);
}
return;
}
if (!(this is GA_Pet))
{
GAMgr.Instance.AddNeedDestroyPrefab(prefab as GameObject);
}
if (m_LoadDefaultRes)
{
if (this is GA_Pet)
{
m_Model = GameObjectPoolManager.Instance.RequestDefaultPet();
}
else
{
m_Model = GameObjectPoolManager.Instance.RequestDefaultFightNpc();
}
}
else
{
m_Model = GameObjectPoolManager.Instance.RequestGameObject(prefab as GameObject);
}
if (!m_Model)
{
return;
}
OnMainModelLoaded();
bool _playEffect = true;
uint _parentSID = ActorInfo.ownerSID;
if (_parentSID != PlayerDatas.Instance.PlayerId)
{
GA_Player _player = GAMgr.Instance.GetBySID(_parentSID) as GA_Player;
if (_player != null)
{
_playEffect = _player.ShowOrHide;
}
}
if (_playEffect)
{
if (NpcConfig.NPCEffect != 0)
{
m_AppearEffect = SFXPlayUtility.Instance.PlayBattleEffect(NpcConfig.NPCEffect, this);
EffectConfig _effectConfig = EffectConfig.Get(NpcConfig.NPCEffect);
if (_effectConfig != null)
{
SoundPlayer.Instance.PlayAudio(m_AudioSource, _effectConfig.audio);
}
}
}
}
protected override void OnUnit()
{
HideEffect();
StatusMgr.Instance.ReleaseActor(ServerInstID);
if (!ShowOrHide)
{
m_Model.transform.localPosition = Vector3.zero;
m_Model.transform.localRotation = Quaternion.identity;
if (MP_Name != m_Model.transform)
{
MP_Name.SetParent(m_Model.transform);
}
if (MP_Hit != m_Model.transform)
{
MP_Hit.SetParent(m_Model.transform);
}
if (MP_Stun != m_Model.transform)
{
MP_Stun.SetParent(m_Model.transform);
}
}
if (m_LoadDefaultRes)
{
if (this is GA_Pet)
{
GameObjectPoolManager.Instance.ReleaseDefaultPet(m_Model);
}
else
{
GameObjectPoolManager.Instance.ReleaseDefaultFightNPC(m_Model);
}
}
else
{
GameObject _prefab = InstanceResourcesLoader.LoadNpc(NpcConfig.NPCID);
GameObjectPoolManager.Instance.ReleaseGameObject(_prefab, m_Model);
}
m_Model = null;
if (m_Animator)
{
m_Animator.runtimeAnimatorController = null;
NextAction = 0;
m_Animator.enabled = false;
m_Animator = null;
}
ReleaseShadow();
ReleaseName();
ReleaseLifeBar();
ReleaseDialogueBubble();
if (m_AppearEffect)
{
SFXPlayUtility.Instance.Release(m_AppearEffect);
m_AppearEffect = null;
}
IsUnInit = true;
base.OnUnit();
}
public override void Destroy()
{
}
public sealed override void SetAnimatorSpeed(float speed)
{
if (m_Animator)
{
m_Animator.speed = speed;
//if (this is GA_NpcSummonFight)
//{
// Debug.LogFormat("设置了动画速度: {0}", speed);
//}
}
}
public sealed override void Play(int stateNameHash, float normalizeTime = 0)
{
if (m_Animator)
{
if (m_Animator.HasState(0, stateNameHash))
{
m_Animator.Play(stateNameHash, 0, normalizeTime);
}
}
}
public override void Idle()
{
NextAction = GAStaticDefine.Act_Idle;
}
public override void Run()
{
NextAction = GAStaticDefine.Act_Run;
}
public override void IdleImmediate()
{
if (m_Animator)
{
Idle();
if (m_Animator.HasState(0, GAStaticDefine.State_IdleHash))
{
m_Animator.Play(GAStaticDefine.State_IdleHash);
}
//if (this is GA_Pet)
//{
// Debug.LogFormat("调用了 {0} 的立即站立", ServerInstID);
//}
}
}
public override void RunImmediate()
{
if (m_Animator)
{
Run();
m_Animator.Play(GAStaticDefine.State_RunHash);
if (this is GA_Pet)
{
Debug.LogFormat(" ---- 调用了 {0} 的立即跑动", ServerInstID);
}
}
}
public override bool IsIdle()
{
if (m_Animator)
{
AnimatorStateInfo _stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);
return _stateInfo.shortNameHash == GAStaticDefine.State_IdleHash;
}
return false;
}
public override bool IsRun()
{
if (m_Animator)
{
AnimatorStateInfo _stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);
return _stateInfo.shortNameHash == GAStaticDefine.State_RunHash;
}
return false;
}
public override bool IsHurt()
{
if (m_Animator)
{
AnimatorStateInfo _stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);
return _stateInfo.shortNameHash == GAStaticDefine.State_HurtHash;
}
return false;
}
public sealed override bool IsStun()
{
if (m_Animator)
{
AnimatorStateInfo _stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);
return _stateInfo.shortNameHash == GAStaticDefine.State_StunHash;
}
return false;
}
public sealed override void Hurt()
{
if (m_Animator == null)
{
return;
}
if (NextAction == GAStaticDefine.Act_Dead
|| NextAction == GAStaticDefine.Act_Warn)
{
return;
}
m_Animator.Play(GAStaticDefine.State_HurtHash);
}
public sealed override void HurtDown()
{
if (m_Animator == null)
{
return;
}
if (m_Animator.GetInteger(GAStaticDefine.Param_Action) == GAStaticDefine.Act_Dead
|| m_Animator.GetInteger(GAStaticDefine.Param_Action) == GAStaticDefine.Act_Warn)
{
return;
}
m_Animator.Play(GAStaticDefine.State_HurtDown1Hash);
}
public override void Die()
{
#if UNITY_EDITOR
if (this is GA_NpcClientFightBoss)
{
Debug.LogFormat("调用了死亡");
}
#endif
if (m_Animator == null)
{
ReleaseShadow();
StatusMgr.Instance.ReleaseActor(ServerInstID);
GAMgr.Instance.Release(this);
return;
}
if (m_AppearEffect)
{
var _animNodde = m_AppearEffect.GetComponent("Animation");
if (_animNodde)
{
if (_animNodde.HasState(0, GAStaticDefine.State_DeadHash))
{
_animNodde.Play(GAStaticDefine.State_DeadHash);
}
}
}
if (NextAction == GAStaticDefine.Act_Dead)
{
return;
}
if (OnDie != null)
{
OnDie();
}
ReleaseDialogueBubble();
if (PlayerDatas.Instance.hero != null)
{
if (PlayerDatas.Instance.hero.LockTarget == this)
{
PlayerDatas.Instance.hero.LockTarget = null;
}
if (PlayerDatas.Instance.hero.SelectTarget == this)
{
PlayerDatas.Instance.hero.SelectTarget = null;
}
}
ReleaseShadow();
StatusMgr.Instance.ReleaseActor(ServerInstID);
NextAction = GAStaticDefine.Act_Dead;
Play(GAStaticDefine.State_DeadHash);
Dead_4 _dead = m_Animator.GetBehaviour();
if (_dead)
{
_dead.killServerInstID = KillerServerInstID;
_dead.killerPos = KillerPos;
_dead.killHurtType = killHurtType;
}
if (this is GA_NpcClientFightBoss
|| this is GA_NpcFightBoss)
{
if (m_AudioSource)
{
if (NpcConfig.Sounds != null)
{
if (NpcConfig.Sounds.Length > 2)
{
SoundPlayer.Instance.PlayAudio(m_AudioSource, NpcConfig.Sounds[2]);
}
}
}
}
#if UNITY_EDITOR
string _content = string.Format("调用了 SID: {0}, CID: {1} 的Die方法 ", ServerInstID, ClientInstID);
RuntimeLogUtility.AddLog_Red(_content, ServerInstID);
#endif
}
public override void RequestShadow()
{
ReleaseShadow();
m_Shadow = SFXPlayUtility.Instance.PlayBattleEffect(999999, m_Root);
m_Shadow.duration = 0;
m_Shadow.transform.localScale = new Vector3((NpcConfig.ModelRadius * 2) / Root.transform.localScale.x,
1,
(NpcConfig.ModelRadius * 2) / Root.transform.localScale.z);
}
public sealed override void ReleaseShadow()
{
if (m_Shadow)
{
SFXPlayUtility.Instance.Release(m_Shadow);
m_Shadow = null;
}
}
public sealed override bool HasState(int stateHash)
{
if (m_Animator)
{
return m_Animator.HasState(0, stateHash);
}
return false;
}
public abstract void RequestDialogueBubble();
protected abstract void UpdateTimeDialogueBubble();
public void ReleaseDialogueBubble()
{
if (m_DialogAppear != null)
{
NPCDialogueBubble.Recyle(m_DialogAppear);
m_DialogAppear = null;
}
if (m_DialogTiming != null)
{
NPCDialogueBubble.Recyle(m_DialogTiming);
m_DialogTiming = null;
}
}
public override abstract void RequestName();
public override abstract void RequestLifeBar();
public abstract bool CanBeSelected();
public abstract void OnSelect();
public abstract void OnUnSelect();
public abstract void OnClick();
protected virtual void OnMainModelLoaded()
{
SkinnedMeshRenderer _renderer = m_Model.GetComponentInChildren();
if (_renderer)
{
_renderer.gameObject.layer = LayerUtility.Monster;
m_Material = _renderer.material;
}
m_Animator = m_Model.GetComponent();
if (!m_Animator)
{
if (m_Model.transform.childCount > 0)
{
m_Animator = m_Model.transform.GetChild(0).GetComponent();
}
}
if (m_Animator)
{
RuntimeAnimatorController _controller = null;
if (m_LoadDefaultRes)
{
if (this is GA_Pet)
{
_controller = AnimatorControllerLoader.LoadDefaultMobAnimatorController_Pet();
}
else
{
_controller = AnimatorControllerLoader.LoadDefaultMobAnimatorController_Fight();
}
}
else
{
_controller = AnimatorControllerLoader.LoadMobController(AnimatorControllerLoader.controllerSuffix, NpcConfig.MODE);
}
if (_controller)
{
m_Animator.runtimeAnimatorController = _controller;
}
m_Animator.enabled = true;
if (m_Animator.parameterCount > 0)
{
m_Animator.SetInteger(GAStaticDefine.Param_ActorInstID, (int)ClientInstID);
}
IdleImmediate();
}
SetupBindNode(m_Model.transform);
m_Model.transform.SetParent(m_Root.transform);
m_Model.transform.localPosition = Vector3.zero;
m_Model.transform.localRotation = Quaternion.identity;
m_Model.transform.localScale = Vector3.one;
GA_Hero _hero = PlayerDatas.Instance.hero;
if (_hero.SelectTarget == this)
{
RequestName();
RequestLifeBar();
}
}
///
/// 显示或者隐藏表现层
///
/// 显示: true, 隐藏: false
public override void ShowOrHideModel(bool showOrHide)
{
if (ShowOrHide == showOrHide)
{
return;
}
if (showOrHide)
{
if (m_Model)
{
m_Model.transform.localPosition = Vector3.zero;
m_Model.transform.localRotation = Quaternion.identity;
GA_Hero _hero = PlayerDatas.Instance.hero;
if (_hero != null && _hero.SelectTarget == this)
{
RequestLifeBar();
}
if (MP_Name != m_Model.transform)
{
MP_Name.SetParent(m_Model.transform);
}
if (MP_Hit != m_Model.transform)
{
MP_Hit.SetParent(m_Model.transform);
}
if (MP_Stun != m_Model.transform)
{
MP_Stun.SetParent(m_Model.transform);
}
}
RequestShadow();
}
else
{
if (MP_Name && MP_Name != m_Model.transform)
{
MP_Name.SetParent(Root);
}
if (MP_Hit && MP_Hit != m_Model.transform)
{
MP_Hit.SetParent(Root);
}
if (MP_Stun && MP_Stun != m_Model.transform)
{
MP_Stun.SetParent(Root);
}
if (m_Model)
{
m_Model.transform.localPosition = Constants.Special_Hide_Position;
}
ReleaseShadow();
}
ShowOrHide = showOrHide;
}
public void CastSkill(int skillID)
{
Vector3 _dir = (PlayerDatas.Instance.hero.Pos - Pos).normalized;
_dir.y = 0;
Forward = _dir;
Skill _skill = SkillMgr.Get(skillID);
if (_skill.IsValid() == false)
{
return;
}
SkillMgr.CastSkill(ServerInstID, skillID);
if (_skill.skillInfo.config.CastTime != 0)
{
Warn_300 _warn300 = m_Animator.GetBehaviour();
if (_warn300)
{
_warn300.nextSkillID = _skill.id;
}
m_Animator.speed = 2 / (_skill.skillInfo.config.CastTime * Constants.F_GAMMA);
NextAction = 300;
m_Animator.Play(GAStaticDefine.State_WarnHash);
int _type;
int _effectID = -1;
SFXController _sfxController = null;
WarnEffectController _warnEffectController = null;
if (_skill.skillInfo.config.WarnInfo > 99)
{
_type = _skill.skillInfo.config.WarnInfo / 1000000;
_effectID = _skill.skillInfo.config.WarnInfo % 1000000;
}
else
{
_type = _skill.skillInfo.config.WarnInfo;
}
if (_effectID != -1)
{
_sfxController = SFXPlayUtility.Instance.Play(_effectID, Pos, Vector3.forward);
_warnEffectController = _sfxController.GetComponent();
_warnEffectController.Init(10009, _skill.skillInfo.config.CastTime, _skill.skillInfo.config.CastTime);
if (_type == 100 || _type == 310)
{
_warnEffectController.CalculateScale(E_HitTestType.Sector, 1, _skill.skillInfo.config.AtkDist);
}
else if (_type > 200 && _type < 300)
{
_warnEffectController.transform.position = Pos;
float width = _type % 10;
float length = (_type % 100) / 10;
SkillHelper.EffectValue _effectValue;
if (_skill.skillInfo.effectValue.TryGetValue(2100, out _effectValue))
{
length = _effectValue.value1 * .5f;
}
_dir = MathUtility.ForwardXZ(PlayerDatas.Instance.hero.Pos, Pos);
if (_dir == Vector3.zero)
{
_dir = Forward;
}
_skill.mainTarget = PlayerDatas.Instance.hero;
Vector3 _sourcePos = Pos;
_sourcePos.y = 0;
Vector3 _targetPos = Pos + Forward * (length * .5f);
_targetPos.y = 0;
UnityEngine.AI.NavMeshHit _navMeshHit;
if (UnityEngine.AI.NavMesh.Raycast(_sourcePos, _targetPos, out _navMeshHit, -1))
{
_targetPos = _navMeshHit.position;
}
_skill.targetPosition = _targetPos;
//_skill.targetPosition.y = Pos.y;
_warnEffectController.transform.forward = _dir;
_warnEffectController.CalculateScale(E_HitTestType.Rect, width, length);
}
}
_skill.SkillPreparing = true;
SkillMgr.DoingPrepareSkill = true;
}
else
{
if (_skill.skillInfo.config.Skillactmark != 0)
{
NextAction = _skill.skillInfo.config.Skillactmark;
SkillMgr.CastSkill(ServerInstID, skillID);
ulong hurtValue = 0;
byte attackType = 0;
AttackHandler.CalculateDamage(this, PlayerDatas.Instance.hero, _skill, 0, ref hurtValue, ref attackType);
if (ClientDungeonStageUtility.isClientDungeon)
{
// hurtValue = int(dMaxHP*0.01*(1+atkSkillPer/10000.0))
hurtValue = (ulong)Mathf.Ceil(PlayerDatas.Instance.extersion.MaxHP * .01f * (1 + NpcConfig.PoisionAtk * Constants.F_DELTA));
}
if (PlayerDatas.Instance.hero.ActorInfo.Hp - hurtValue < 0)
{
hurtValue = PlayerDatas.Instance.hero.ActorInfo.Hp;
}
AttackHandler.HurtObjs _hurtObject = new AttackHandler.HurtObjs
{
AttackType = attackType,
clientInstID = PlayerDatas.Instance.hero.ClientInstID,
CurHP = PlayerDatas.Instance.hero.ActorInfo.Hp - hurtValue,
HurtHP = hurtValue,
RealHurtHP = hurtValue,
ObjID = PlayerDatas.Instance.hero.ServerInstID,
ObjType = (byte)GameObjType.gotPlayer
};
_skill.hurtClientList.Add(_hurtObject);
}
}
}
public void StartCantAtkedRotate()
{
m_LastCantAtkedTime = Time.time;
}
public sealed override void Polymorph(bool doOrNo, int npcID)
{
IsPolyMorph = doOrNo;
var _npcConfig = NPCConfig.Get(npcID);
if (IsPolyMorph)
{
ChangeBinderToRoot();
m_SheepIsDefaultNpc = false;
var _p = InstanceResourcesLoader.LoadNpc(npcID);
if (_p == null)
{
_p = InstanceResourcesLoader.LoadDefaultFightNPC();
m_SheepIsDefaultNpc = true;
}
m_Model.transform.localPosition = Constants.Special_Hide_Position;
m_SheepModel = GameObjectPoolManager.Instance.RequestGameObject(_p);
m_SheepModel.transform.SetParent(m_Root);
var _a = m_SheepModel.GetComponent();
if (_a)
{
RuntimeAnimatorController _controller = null;
if (m_SheepIsDefaultNpc)
{
_controller = AnimatorControllerLoader.LoadDefaultMobAnimatorController_Fight();
}
else
{
_controller = AnimatorControllerLoader.LoadMobController(AnimatorControllerLoader.controllerSuffix, _npcConfig.MODE);
}
if (_controller)
{
_a.runtimeAnimatorController = _controller;
}
_a.enabled = true;
_a.SetInteger(GAStaticDefine.Param_ActorInstID, (int)ClientInstID);
m_Animator.enabled = false;
m_Animator = _a;
}
if (ShowOrHide)
{
m_SheepModel.transform.localPosition = Vector3.zero;
}
else
{
m_SheepModel.transform.localPosition = Constants.Special_Hide_Position;
}
m_SheepModel.transform.localRotation = Quaternion.identity;
}
else
{
if (m_SheepModel)
{
var _a = m_SheepModel.GetComponent();
if (_a)
{
_a.enabled = false;
_a.runtimeAnimatorController = null;
}
if (m_SheepIsDefaultNpc)
{
GameObjectPoolManager.Instance.ReleaseDefaultFightNPC(m_SheepModel);
}
else
{
var _prefab = InstanceResourcesLoader.LoadNpc(npcID);
GameObjectPoolManager.Instance.ReleaseGameObject(_prefab, m_SheepModel);
}
}
m_SheepModel = null;
m_Model.transform.localPosition = Vector3.zero;
ChangeBinderToClothes();
m_Animator = m_Model.GetComponent();
m_Animator.enabled = true;
m_Animator.SetInteger(GAStaticDefine.Param_ActorInstID, (int)ClientInstID);
m_Animator.SetInteger(GAStaticDefine.Param_MoveState, (int)E_MovingState.Normal);
}
}
protected sealed override void ChangeBinderToRoot()
{
if (MP_Name != m_Model.transform)
{
MP_Name.SetParent(Root);
}
if (MP_Hit != m_Model.transform)
{
MP_Hit.SetParent(Root);
}
if (MP_Stun != m_Model.transform)
{
MP_Stun.SetParent(Root);
}
}
protected sealed override void ChangeBinderToClothes()
{
if (MP_Name != m_Model.transform)
{
MP_Name.SetParent(m_Model.transform);
}
if (MP_Hit != m_Model.transform)
{
MP_Hit.SetParent(m_Model.transform);
}
if (MP_Stun != m_Model.transform)
{
MP_Stun.SetParent(m_Model.transform);
}
}
}