using vnxbqy.UI;
|
using UnityEngine;
|
using System.Collections.Generic;
|
|
public class GA_NpcClientFightNorm : GActorNpcFight
|
{
|
public ProcessManager ProcessManager { get; private set; }
|
|
public bool dieNoFall = false;
|
public UnityEngine.Events.UnityAction<uint, int> OnAttackObj;
|
public UnityEngine.Events.UnityAction<uint, int> OnBeAttack;
|
|
public void AttackObj(uint sid, int skillId)
|
{
|
if (OnAttackObj != null)
|
{
|
OnAttackObj(sid, skillId);
|
}
|
}
|
|
public void BeAttack(uint sid, int skillId)
|
{
|
if (OnBeAttack != null)
|
{
|
OnBeAttack(sid, skillId);
|
}
|
}
|
|
public float lockHp { get; private set; }
|
|
public void LockHp(float per)
|
{
|
lockHp = per;
|
}
|
|
public bool lockCommonAtk = false;
|
public int lockSkillID = -1;
|
public int hitSoundId = 0;
|
|
public Dictionary<int, SFXController> ProcessEffectDict = new Dictionary<int, SFXController>();
|
|
public void AutoAI()
|
{
|
lockCommonAtk = false;
|
lockSkillID = -1;
|
}
|
|
public bool isTalking = false;
|
public bool isStopAI = false;
|
|
private HeadUpName m_HeadUpName;
|
private LifeBar m_LifeBar;
|
|
private uint m_LockTargetSID;
|
public uint LockTargetSID
|
{
|
get
|
{
|
return m_LockTargetSID;
|
}
|
set
|
{
|
m_LockTargetSID = value;
|
}
|
}
|
|
// 用于触发点击的组件
|
private NPCInteractProcessor m_NPCInteractProcessor;
|
|
public override Vector3 BornPos
|
{
|
get
|
{
|
return base.BornPos;
|
}
|
|
set
|
{
|
base.BornPos = value;
|
if (m_AIHandler != null)
|
{
|
m_AIHandler.BornPos = value;
|
}
|
|
if (m_Obstacle)
|
{
|
m_Obstacle.transform.position = new Vector3(value.x, 0, value.z);
|
m_Obstacle.transform.eulerAngles = Root.eulerAngles;
|
}
|
}
|
}
|
|
private UnityEngine.AI.NavMeshObstacle m_Obstacle;
|
|
protected SampleAI m_AIHandler;
|
|
/// <summary>
|
/// 是否被英雄攻击了
|
/// </summary>
|
public bool heroAttacked;
|
public int posIndex = -1;
|
|
public UnityEngine.Events.UnityAction OnAttacked;
|
|
public void BeAttacked()
|
{
|
if (OnAttacked != null)
|
{
|
OnAttacked();
|
}
|
|
heroAttacked = true;
|
}
|
|
protected override void OnInit(GameNetPackBasic package)
|
{
|
base.OnInit(package);
|
|
// 可选择对象创建碰撞区
|
if (CanBeSelected())
|
{
|
m_NPCInteractProcessor = Root.AddMissingComponent<NPCInteractProcessor>();
|
m_NPCInteractProcessor.npcIntergactEvent += OnClick;
|
}
|
|
dieNoFall = false;
|
|
// 初始化基本属性
|
ActorInfo.Hp = (ulong)NpcConfig.DHP + (ulong)NpcConfig.MaxHPEx * Constants.ExpPointValue;
|
ActorInfo.MaxHp = ActorInfo.Hp;
|
ActorInfo.SyncServerHp = ActorInfo.Hp;
|
if (NpcConfig.OrgSpeed != 0)
|
{
|
ActorInfo.moveSpeed = 1000 / NpcConfig.OrgSpeed * .5f;
|
}
|
ActorInfo.PlayerName = NpcConfig.charName;
|
ActorInfo.LV = (ushort)NpcConfig.NPCLV;
|
|
// 战斗类型的怪物随机朝向
|
Rotation = Quaternion.Euler(0, UnityEngine.Random.Range(0, 360), 0);
|
|
lockHp = 0;
|
isTalking = false;
|
isStopAI = false;
|
heroAttacked = false;
|
|
AutoAI();
|
|
if (ProcessManager == null)
|
{
|
ProcessManager = new ProcessManager();
|
}
|
ProcessManager.Load(this);
|
|
InitAI();
|
}
|
|
protected virtual void InitAI()
|
{
|
if (NpcConfig.AIType == 1
|
|| NpcConfig.AIType == 202)
|
{
|
m_AIHandler = new AI_Npc_200(this, BornPos);
|
}
|
else if (NpcConfig.AIType == 196)
|
{
|
m_AIHandler = new AI_Npc_198(this, BornPos);
|
}
|
}
|
|
public override void OnClick()
|
{
|
if (ActorInfo.serverDie
|
|| BossShowModel.Instance.BossShowing)
|
{
|
return;
|
}
|
|
GA_Hero _hero = PlayerDatas.Instance.hero;
|
|
if (!PathFinder.WalkAble(_hero.Pos, Pos))
|
{
|
return;
|
}
|
|
// 当前锁定的目标已经是此对象
|
if (_hero.LockTarget == this)
|
{
|
// 开启攻击至死AI
|
}
|
else
|
{
|
// 设置锁定目标为此对象
|
_hero.LockTarget = this;
|
_hero.SelectTarget = this;
|
}
|
}
|
|
protected override void OnMainModelLoaded()
|
{
|
base.OnMainModelLoaded();
|
|
if (NpcConfig.NPCID == 1002)
|
{
|
m_Obstacle = SoMap.CreateImpasse.General(Pos, Root.eulerAngles, new Vector3(3, 10, 1));
|
#if UNITY_EDITOR
|
m_Obstacle.name = string.Format("Obstacle_{0}_{1}", ServerInstID, NpcConfig.NPCID);
|
#endif
|
}
|
}
|
|
protected override void OnUnit()
|
{
|
if (m_NPCInteractProcessor)
|
{
|
m_NPCInteractProcessor.npcIntergactEvent -= OnClick;
|
m_NPCInteractProcessor = null;
|
}
|
|
if (ProcessManager != null)
|
{
|
ProcessManager.UnLoad();
|
}
|
|
if (m_AIHandler != null)
|
{
|
m_AIHandler.UnInit();
|
m_AIHandler = null;
|
}
|
|
if (m_Obstacle)
|
{
|
Object.Destroy(m_Obstacle.gameObject);
|
m_Obstacle = null;
|
}
|
|
belongEventID = -1;
|
if (posIndex != -1)
|
{
|
HeroRoundGird.Instance.Release(posIndex);
|
posIndex = -1;
|
}
|
|
foreach (var _sfx in ProcessEffectDict.Values)
|
{
|
SFXPlayUtility.Instance.Release(_sfx);
|
}
|
ProcessEffectDict.Clear();
|
|
base.OnUnit();
|
}
|
|
protected override void OnFixedUpdate()
|
{
|
base.OnFixedUpdate();
|
|
if (!ActorInfo.serverDie)
|
{
|
UpdateTimeDialogueBubble();
|
}
|
}
|
|
protected override void OnLateUpdate()
|
{
|
}
|
|
protected override void OnUpdate()
|
{
|
base.OnUpdate();
|
|
if (ActorInfo.serverDie || ActorInfo.RealHp == 0)
|
{
|
return;
|
}
|
|
if (ProcessManager != null)
|
{
|
ProcessManager.Update();
|
}
|
|
if (m_AIHandler != null)
|
{
|
m_AIHandler.Update();
|
}
|
}
|
|
public virtual void SyncHp()
|
{
|
if (m_LifeBar != null)
|
{
|
m_LifeBar.Show(ActorInfo.RealHp, ActorInfo.RealMaxHp);
|
}
|
}
|
|
public override void Die()
|
{
|
if (m_Obstacle)
|
{
|
Object.Destroy(m_Obstacle.gameObject);
|
m_Obstacle = null;
|
}
|
|
base.Die();
|
}
|
|
public bool IsState(int stateHash)
|
{
|
if (m_Animator)
|
{
|
AnimatorStateInfo _stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);
|
return _stateInfo.shortNameHash == stateHash;
|
}
|
return false;
|
}
|
|
public override void RequestLifeBar()
|
{
|
ReleaseLifeBar();
|
m_LifeBar = LifeBar.RequireLifeBar(MP_Name, 0, CameraController.Instance.CameraObject);
|
}
|
|
public override void RefreshLifeBar(ulong value)
|
{
|
if (m_LifeBar)
|
{
|
m_LifeBar.Show(ActorInfo.RealHp, ActorInfo.RealMaxHp);
|
}
|
}
|
|
public override void ReleaseLifeBar()
|
{
|
if (m_LifeBar != null)
|
{
|
m_LifeBar.target = null;
|
m_LifeBar.neverHide = false;
|
LifeBar.Recycle(m_LifeBar);
|
m_LifeBar = null;
|
}
|
}
|
|
public override void ReleaseName()
|
{
|
if (m_HeadUpName != null)
|
{
|
m_HeadUpName.target = null;
|
HeadUpName.Recycle(m_HeadUpName);
|
m_HeadUpName = null;
|
}
|
}
|
|
public override void RequestName()
|
{
|
ReleaseName();
|
|
HeadUpName.Pattern _pattern = HeadUpName.Pattern.Monster;
|
m_HeadUpName = HeadUpName.RequireHeadUpName(_pattern, MP_Name, 0, CameraController.Instance.CameraObject);
|
m_HeadUpName.SetMonsterInfo(NpcConfig.NPCID, NpcConfig.NPCLV);
|
}
|
|
public override void RequestDialogueBubble()
|
{
|
if (m_DialogAppear)
|
{
|
NPCDialogueBubble.Recyle(m_DialogAppear);
|
}
|
}
|
|
protected override void UpdateTimeDialogueBubble()
|
{
|
if (!MP_Name)
|
{
|
return;
|
}
|
// 瞎BB逻辑
|
if (Time.realtimeSinceStartup - m_LastTalkTime > 5)
|
{
|
if (m_DialogTiming != null)
|
{
|
NPCDialogueBubble.Recyle(m_DialogTiming);
|
}
|
m_DialogTiming = NPCDialogueBubble.TimingShow(NpcConfig.NPCID, MP_Name, CameraController.Instance.CameraObject);
|
m_LastTalkTime = Time.realtimeSinceStartup;
|
}
|
}
|
|
public override bool CanBeSelected()
|
{
|
return NpcConfig.NPCType != (int)E_NpcType.BreakableObj
|
&& NpcConfig.Country != 1
|
&& NpcConfig.NPCType != (int)E_NpcType.Ghost;
|
}
|
|
public override void OnSelect()
|
{
|
SelectionManager.Request(SelectionManager.E_Type.Red, this, (NpcConfig.ModelRadius * 2) / Root.transform.localScale.x);
|
|
RequestName();
|
RequestLifeBar();
|
}
|
|
public override void OnUnSelect()
|
{
|
SelectionManager.Release(SelectionManager.E_Type.Red);
|
|
if (!ActorInfo.serverDie)
|
{
|
ReleaseName();
|
ReleaseLifeBar();
|
}
|
}
|
|
public override bool CanPushedBack()
|
{
|
return NpcConfig.weight != 0
|
&& (IsHurt() || IsIdle());
|
}
|
|
public override bool CanHurted()
|
{
|
return NpcConfig.hurtFeedback == 1
|
&& (IsIdle() || IsHurt() || IsRun())
|
&& !SkillMgr.DoingPrepareSkill
|
&& (SkillMgr.CurCastSkill == null
|
|| SkillMgr.CurCastSkill.SkillCompelete);
|
}
|
|
public override bool CanDieFly()
|
{
|
return NpcConfig.NPCType != (int)E_NpcType.BreakableObj;
|
}
|
|
public override bool CanAtked()
|
{
|
// 判断是否相同阵营
|
bool _sameFaction = NpcConfig.Country != 0
|
&& NpcConfig.Country == PlayerDatas.Instance.baseData.faction;
|
|
return !_sameFaction
|
&& NpcConfig.NPCType != (int)E_NpcType.Func
|
&& NpcConfig.NPCType != (int)E_NpcType.Collect
|
&& NpcConfig.NPCType != (int)E_NpcType.Pet
|
&& !ActorInfo.serverDie
|
&& lockHp != 1
|
&& !IsState(GAStaticDefine.State_Open);
|
}
|
|
public override bool CanAtkedRotate()
|
{
|
return NpcConfig.NPCType != (int)E_NpcType.BreakableObj
|
&& NpcConfig.AIType != 201
|
&& !IsRun()
|
&& !SkillMgr.DoingPrepareSkill
|
&& (SkillMgr.CurCastSkill == null
|
|| SkillMgr.CurCastSkill.SkillCompelete)
|
&& (Time.time - m_LastCantAtkedTime > NpcConfig.AtkInterval * Constants.F_GAMMA + 1f);
|
}
|
}
|