GameEntity(四)—— Ientity

目录为:Assets/Scripts/GameEntity/目录下
Ientity.cs

这是Entity的接口

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//最主要的游戏实体
//整个Entity的接口
public class Ientity
{
    //构造函数
    public Ientity (UInt64 sGUID, EntityCampType campType)
    {
        GameObjGUID = sGUID;
        EntityCamp = campType;
        mpcGOSSI = new CGameObjectSyncInfo ();
    }

    public AudioSource absorbSound;

    //同步相关
    protected CGameObjectSyncInfo m_pcGOSSI = null;
    public CGameObjectSyncInfo GOSSI
    {
        get
        {
            return m_pcGOSSI;
        }
    }

    //祭坛持有的Npc type
    public int EntityHoldNpcType;

    //资源路径
    public string resPath;

    //Transform组件
    public Transform objTransform = null;

    //血条GameObject
    public GameObject xueTiaoObj = null;

    //死亡现场(用于是否播放死亡特效)
    public bool deadSpot = false;

    //GUID
    //标识场景里的对象
    public UInt64 GameObjGUID
    {
        get;
        set;
    }

    //能否被锁定
    public bool mCanBeLocked = true;

    public UInt32 ObjTypeID
    {
        get;
        set;
    }

    public float EntityOverplusRemainTime
    {
        get;
        set;
    }

    public float EntityOverplusTotalTime
    {
        set;
        get;
    }

    public int MapObgId
    {
        set;
        get;
    }

    public float StrategyTick
    {
        set;
        get;
    }

    public EntityCampType EntityCamp
    {
        get;
        set;
    }

    public float PhyAtk
    {
        set;
        get;
    }

    public float MagAtk
    {
        set;
        get;
    }

    public float PhyDef
    {
        set;
        get;
    }

    public float MagDef
    {
        set;
        get;
    }

    public float AtkSpeed
    {
        set;
        get;
    }

    public float AtkDis
    {
        get;
        set;
    }

    public float HpRecover
    {
        set;
        get;
    }

    public float MpRecover
    {
        set;
        get;
    }

    public float RebornTime
    {
        set;
        get;
    }

    public float Hp
    {
        set;
        get;
    }

    public float HpMax
    {
        private set;
        get;
    }

    public float Mp
    {
        private set;
        get;
    }

    public float MpMax
    {
        private set;
        get;
    }

    public int Level
    {
        private set;
        get;
    }

    public float Cp
    {
        private set;
        get;
    }

    public float TeamCp
    {
        private set;
        get;
    }

    public float Exp
    {
        private set;
        get;
    }

    public int CooldownReduce
    {
        set;
        get;
    }

    //在Guis里面
    public XueTiaoUI XueTiao
    {
        private set;
        get;
    }

    public EntityType entityType
    {
        get;
        set;
    }

    //是否是NPC类型
    public bool IfNPC()
    {
        return entityType < EntityType.Player;
    }

    //Npc类型
    public int NpcGUIDType
    {
        get;
        set;
    }

    public string ModelName
    {
        get;
        set;
    }

    public float ColliderRadius
    {
        get;
        set;
    }

    public ENPCCateChild NPCCateChild
    {
        get;
        set;
    }

    //real object
    public GameObject realObject
    {
        set;
        get;
    }

    //real entity
    public EntityFSM RealEntity
    {
        set;
        get;
    }

    //FSM
    public EntityFSM FSM
    {
        private set;
        get;
    }

    enum EAsyncState
    {
        eAS_Asynced,
        eAS_Error,
    }

    enum EActionState
    {
        eAS_Free,
        eAS_Run,
    }

    public virtual void OnUpdate()
    {
        if (FSM != null)
        {
            FSM.Execute (this);
        }
    }

    #region State change
    //FSM pos
    public Vector3 EntityFSMPosition
    {
        set;
        get;
    }

    //FSM dir
    public Vector3 EntityFSMDirection
    {
        private set;
        get;
    }

    public float EntityFSMMoveSpeed
    {
        private set;
        get;
    }

    public int EntitySkillID
    {
        get;
        set;
    }

    public int EntitySKillModeId
    {
        private set;
        get;
    }

    protected Ientity entitySkillTarget
    {
        get;
        set;
    }

    //变化原因(0:普通伤害 1:BUFF掉血 2:暴击 3:回复)
    public const byte HpUpdateOfCommon = 0;
    public const byte HpUPdateOfBuf = 1;
    public const byte HpUpdateofCrit = 2;
    public const byte HpUpdateOfRecover = 3;

    //状态改变
    public void OnFSMStateChange(EntityFSM fsm, float last)
    {
        if (this.FSM != null && this.FSM.StateChange(this, fsm))
        {
            return;
        }

        if (this.FSM == fsm && this.FSM != null && this.FSM.State == FsmState.FSM_STATE_DEAD)
        {
            return;
        }

        if (this.FSM != null)
        {
            this.FSM.Exit(this);
        }

        if (this.FSM != null)
        {
            this.RealEntity.FSMStateName = fsm.ToString ();
        }

        this.FSM = fsm;
        StrategyTick = Time.time;
        this.FSM.Enter (this, last);
    }

    public void OnFSMStateChange(EntityFSM fsm)
    {
        if (this.FSM != null && this.FSM.StateChange(this, fsm))
        {
            return;
        }

        if (this.FSM == fsm && this.FSM != null && (this.FSM.State == FsmState.FSM_STATE_DEAD))
        {
            return;
        }

        if (this.FSM != null)
        {
            this.FSM.Exit (this);
        }

        this.FSM = fsm;
        if (this.FSM != null)
        {
            this.RealEntity.FSMStateName = fsm.ToString ();
        }

        StrategyTick = Time.time;
        this.FSM.Enter (this, 0.0f);
    }

    //角色中了束缚
    public void OnEntityGetAstrictBuff()
    {

    }

    //移除buff状态
    public void OnEntityRemoveAstrictBuff()
    {

    }

    //复活
    public virtual void OnReborn()
    {
        this.DoReborn ();
    }

    protected virtual void DoReborn ()
    {

    }

    //Entity移动属性变化
    public virtual void OnEntityMoveSpeedChange(int value)
    {
        this.GOSSI.sServerBeginPos = this.GOSSI.sServerSyncPos;
        this.GOSSI.fBeginTime = Time.realtimeSinceStartup;
        this.EntityFSMMoveSpeed = (float)value / 100;
        this.GOSSI.fServerSpeed = this.EntityFSMMoveSpeed;

        if (1 > this.GOSSI.fServerSpeed)
        {
            //本地调试,不要上传!
            //Debug.LogWarning("OnEntityMoveSpeedChange() GO " + GameObjGUID + " Speed " + this.GOSSI.fServerSpeed);
        }

        NpcConfigInfo npcConfig;
        if (ConfigReader.NpcXmlInfoDict.TryGetValue(NpcGUIDType, out npcConfig))
        {
            float speed = value / npcConfig.NpcMoveSpeed * npcConfig.n32BaseMoveSpeedScaling / 1000;
            if (speed == 0)
            {
                return;
            }

            //改变动画播放速度
            this.RealEntity.SetMoveAnimationSpd (speed);
        }
    }

    protected int skillState;   //技能状态(1:开始吟唱 2:开始施法(前摇)3:释放技能)
    protected int isAbsorb; //1是吸附,0不是

    public void EntityFSMChangeDataOnPrepareSkill(Vector3 mvPos, Vector3 mvDir, int skillID, Ientity targetID, int isAbsorbSkill = 0)
    {
        EntityFSMPosition = mvPos;
        EntityFSMDirection = mvDir;
        EntitySkillID = skillID;
        entitySkillTarget = targetID;
        isAbsorb = isAbsorbSkill;
    }

    //强制位移
    public void EntityFSMChangeDataOnForceMove(int skId)
    {
        EntitySKillModeId = skId;
    }

    //EntityFSMChangeDataOnSing
    public void EntityFSMChangeDataOnSing(Vector3 mvPos, Vector3 mvDir, int skillID, Ientity targetID)
    {
        EntityFSMPosition = mvPos;
        EntityFSMDirection = mvDir;
        EntitySkillID = skillID;
        entitySkillTarget = targetID;
    }

    //OnEntityPrepareAttack
    public virtual void OnEntityPrepareAttack()
    {

    }

    //引导技能
    public virtual void OnEntityLeadSkill()
    {
        RealEntity.PlayerFreeAnimation ();
    }

    //Entites the FSM changeData
    public void EntityFSMChangeDataOnDead(Vector3 mvPos, Vector3 mvDir)
    {
        EntityFSMPosition = mvPos;
        EntityFSMDirection = mvDir;
    }

    public void EntityFSMChangeData(Vector3 mvPos, Vector3 mvDir, float mvSpeed)
    {
        EntityFSMPosition = mvPos;
        EntityFSMDirection = mvDir;
        EntityFSMMoveSpeed = mvSpeed;
    }

    //Entites the FSM changedata
    public void EntityFSMChangedata(Vector3 mvPos, Vector3 mvDir)
    {
        EntityFSMPosition = mvPos;
        EntityFSMDirection = mvDir;
    }

    //子类实现
    public virtual void OnEntitySkill()
    {

    }

    //进入Idle状态
    public virtual void OnEnterIdle()
    {
        //this.RealEntity.PlayerAnimation("idle");
    }

    //Run状态进入时调用
    public virtual void OnEnterMove()
    {

    }

    //Raises the entity move event
    public virtual void OnExecuteMove()
    {
        if (RealEntity == null || this.entityType == EntityType.Buiding)
        {
            return;
        }

        //播放run动画
        RealEntity.PlayerRunAnimation ();

        float fThisRealTimeSinceStartup = Time.realtimeSinceStartup;
        float fTimeSpan = fThisRealTimeSinceStartup - m_pcGOSSI.fBeginTime;

        float fThisFrameTimeSpan = fThisRealTimeSinceStartup - m_pcGOSSI.fLastSyncSecond;
        m_pcGOSSI.fLastSyncSecond = fThisRealTimeSinceStartup;
        float fMoveDist = fTimeSpan * m_pcGOSSI.fServerSpeed;
        m_pcGOSSI.sServerSyncPos = m_pcGOSSI.sServerBeginPos + m_pcGOSSI.sServerDir * fMoveDist;

        //2D计算
        Vector3 serverPos2D = new Vector3 (m_pcGOSSI.sServerSyncPos.x, 60, m_pcGOSSI.sServerSyncPos.z);
        Vector3 realPos2D = new Vector3 (objTransform.position.x, 60, objTransform.position.z);

        //需要同步的情况
        float fDistToSyncPos = Vector3.Distance (serverPos2D, realPos2D);
        //距离大于10就同步
        if (fDistToSyncPos > 10)
        {
            objTransform.position = m_pcGOSSI.sServerSyncPos;
            //旋转
            objTransform.rotation = Quaternion.LookRotation (EntityFSMDirection);
            m_pcGOSSI.sLocalSyncDir = EntityFSMDirection;

            return;
        }

        Vector3 sCrossPoint = 5 * m_pcGOSSI.sServerDir + m_pcGOSSI.sServerSyncPos;
        Vector3 sThisSyncDir = sCrossPoint - realPos2D;
        sThisSyncDir.y = 0;
        sThisSyncDir.Normalize ();

        float fAngle = Vector3.Angle (sThisSyncDir, m_pcGOSSI.sLocalSyncDir);
        if (5 < fAngle)
        {
            float fLerpValue = fAngle / 100;
            Vector3 sTempThisSyncDir = Vector3.Lerp(m_pcGOSSI.sLocalSyncDir, sThisSyncDir, fLerpValue);
            sThisSyncDir = sTempThisSyncDir;
        }

        float fThisMoveSpeed = m_pcGOSSI.fServerSpeed;
        Vector3 sTempSyncDir = m_pcGOSSI.sServerSyncPos - realPos2D;
        sTempSyncDir.y = 0;
        sTempSyncDir.Normalize ();

        fAngle = Vector3.Angle (sTempSyncDir, m_pcGOSSI.sLocalSyncDir);
        if (90 < fAngle)
        {
            if (1 > fDistToSyncPos)
            {
                fThisMoveSpeed = m_pcGOSSI.fServerSpeed;
            }
            else if (2 > fDistToSyncPos)
            {
                fThisMoveSpeed -= m_pcGOSSI.fServerSpeed * 0.01f;
            }
            else if (5 > fDistToSyncPos)
            {
                fThisMoveSpeed -= fThisMoveSpeed * 0.05f;
            }
            else if (6 > fDistToSyncPos)
            {
                fThisMoveSpeed -= fThisMoveSpeed * 0.10f;
            }
            //这里有点看不懂
            fThisMoveSpeed = m_pcGOSSI.fServerSpeed;
        }
        else
        {
            if (1 > fDistToSyncPos)
            {
                fThisMoveSpeed = m_pcGOSSI.fServerSpeed;
            }
            else if (2 > fDistToSyncPos)
            {
                fThisMoveSpeed += fThisMoveSpeed * 0.05f;
            }
            else if (4 > fDistToSyncPos)
            {
                fThisMoveSpeed += fThisMoveSpeed * 0.10f;
            }
            else if (6 > fDistToSyncPos)
            {
                fThisMoveSpeed += fThisMoveSpeed * 0.20f;
            }

            fThisMoveSpeed = m_pcGOSSI.fServerSpeed;
        }

        float fDistDiff = Mathf.Abs (fThisMoveSpeed - m_pcGOSSI.fServerSpeed);
        if (0.1 <= fDistDiff)
        {
            Debug.Log("GO " + GameObjGUID + " fThisMoveSpeed:" + fThisMoveSpeed);
        }

        //位置计算
        float fThisSyncDist = fThisMoveSpeed * fThisFrameTimeSpan;
        Vector3 sNewPos = sThisSyncDir * fThisSyncDist + realPos2D;

        if (sNewPos.magnitude > 0)
        {
            objTransform.position = sNewPos;
        }

        m_pcGOSSI.sLocalSyncDir = sThisSyncDir;
        Quaternion DestQuaternion = Quaternion.LookRotation (sThisSyncDir);
        Quaternion sMidQuater = Quaternion.Lerp (objTransform.rotation, DestQuaternion, 3 * Time.deltaTime);
        objTransform.rotation = sMidQuater;
    }

    //进入强制移动
    public void OnEnterForceMove()
    {
        if (RealEntity == null || this.entityType == EntityType.Buiding)
        {
            return;
        }
    }

    //执行强制移动
    public virtual void OnExecuteForceMove()
    {
        if (RealEntity == null || this.entityType == EntityType.Buiding)
        {
            return;
        }

        SkillMoveConfig skillInfo = ConfigReader.GetSkillMoveConfig (EntitySKillModeId);
        if (skillInfo != null)
        {
            //播放动画
            this.RealEntity.PlayerAnimation (skillInfo.action);
        }

        float timeSinceStartup = Time.realtimeSinceStartup;
        float fTimeSpan = timeSinceStartup - m_pcGOSSI.fBeginTime;
        float fMoveDist = fTimeSpan * m_pcGOSSI.fForceMoveSpeed;
        m_pcGOSSI.sServerSyncPos = m_pcGOSSI.sServerBeginPos + m_pcGOSSI.sServerDir * fMoveDist;
        float fDistToSyncPos = Vector3.Distance (m_pcGOSSI.sServerSyncPos, objTransform.position);

        if (fDistToSyncPos > 10)
        {
            objTransform.position = m_pcGOSSI.sServerSyncPos;
            objTransform.rotation = Quaternion.LookRotation (EntityFSMDirection);
            m_pcGOSSI.sLocalSyncDir = EntityFSMDirection;

            return;
        }

        //小于1就不改
        if (fDistToSyncPos < 1)
        {
            return;
        }

        Vector3 sThisSyncDir = m_pcGOSSI.sServerSyncPos - objTransform.position;
        sThisSyncDir.Normalize ();

        float fThisMoveSpeed = m_pcGOSSI.fForceMoveSpeed;
        float fThisSyncDist = fThisMoveSpeed * Time.deltaTime;
        Vector3 sNewPos = sThisSyncDir * fThisSyncDist + objTransform.position;
        this.objTransform.position = sNewPos;

        Quaternion DestQuaternion = Quaternion.LookRotation (sThisSyncDir);
        Quaternion sMidQuater = Quaternion.Lerp (objTransform.rotation, DestQuaternion, 3 * Time.deltaTime);
        objTransform.rotation = sMidQuater;
    }

    //进入玩家先行状态
    public virtual void OnEnterEntityAdMove()
    {

    }

    //执行玩家先行状态
    public virtual void OnExecuteEntityAdMove()
    {

    }

    public virtual void OnEnterRelive()
    {
        if (this.RealEntity == null)
        {
            return;
        }

        this.RealEntity.PlayerDeadAnimation ();

        if (this.XueTiao != null)
        {
            this.XueTiao.SetVisible (false);
        }
    }

    public virtual void OnExitRelive()
    {
        if (this.XueTiao != null)
        {
            this.XueTiao.SetVisible (true);
        }
    }

    public virtual void OnEnterFree()
    {
        if (RealEntity == null)
        {
            return;
        }

        Vector2 serverPos2D = new Vector2 (m_pcGOSSI.sServerBeginPos.x, m_pcGOSSI.sServerBeginPos.z);
        Vector2 objPos2D = new Vector2 (objTransform.position.x, objTransform.position.z);

        //服务器的pos和本地pos的距离
        float fDistToServerPos = Vector2.Distance (serverPos2D, objPos2D);

        if (fDistToServerPos > 10)
        {
            objTransform.position = m_pcGOSSI.sServerBeginPos;
            RealEntity.PlayerFreeAnimation ();
            objTransform.rotation = Quaternion.LookRotation (EntityFSMDirection);
        }

        //ShowXueTiao();
    }

    //Raises the entity free event
    public virtual void OnExecuteFree()
    {
        if (RealEntity == null || this.entityType == EntityType.Buiding)
        {
            return;
        }

        Vector2 serverPos2D = new Vector2 (m_pcGOSSI.sServerBeginPos.x, m_pcGOSSI.sServerBeginPos.z);
        Vector2 objPos2D = new Vector2 (objTransform.position.x, objTransform.position.z);

        //dis
        float fDistToServerPos = Vector2.Distance (serverPos2D, objPos2D);

        //dir
        Vector3 sSyncDir = m_pcGOSSI.sServerBeginPos - objTransform.position;
        sSyncDir.y = 0;
        sSyncDir.Normalize ();

        //服务端和客户端方向的夹角
        float fAngle = Vector3.Angle (objTransform.forward, sSyncDir);

        //修正pos
        if (10 < fDistToServerPos)
        {
            objTransform.position = m_pcGOSSI.sServerBeginPos;
            objTransform.rotation = Quaternion.LookRotation (m_pcGOSSI.sServerDir);
            RealEntity.PlayerFreeAnimation ();

            return;
        }
        else if (0.5f >= fDistToServerPos)
        {
            RealEntity.PlayerFreeAnimation ();

            return;
        }

        //此时距离为大于0.5小于10的状态,这说明玩家操作了,所以run
        RealEntity.PlayerRunAnimation ();
        float fSpeed = m_pcGOSSI.fServerSpeed;
        float fThissSyncDist = fSpeed * Time.deltaTime;

        if (fThissSyncDist > fDistToServerPos)
        {
            fThissSyncDist = fDistToServerPos;
        }

        Vector3 sNewPos = sSyncDir * fThissSyncDist + objTransform.position;
        objTransform.position = sNewPos;

        Quaternion DestQuaternion = Quaternion.LookRotation (EntityFSMDirection);
        Quaternion sMidQuater = Quaternion.Lerp (objTransform.rotation, DestQuaternion, 2 * Time.deltaTime);
        objTransform.rotation = sMidQuater;
    }

    public virtual void OnEntityExitPrepareSkill()
    {

    }

    //Raises the entity prepare skill event
    protected static float skillDistanceErrorThresold = 1.0f;

    //public GameObject AbsorbAct
    private void PlayAbsorbSkill()
    {

    }

    //释放技能
    public virtual void OnEntityReleaseSkill()
    {
        //获取SkillManager
        SkillManagerConfig skillManagerConfig = ConfigReader.GetSkillManagerCfg (EntitySkillID);
        if (skillManagerConfig == null)
        {
            return;
        }

        //吸附技能
        if (skillManagerConfig.isAbsorb == 1)
        {
            //删除已有的相同特效
            foreach (Transform child in RealEntity.objAttackPoint)
            {
                if (child.name.Contains (skillManagerConfig.absorbRes))
                {
                    int offset = child.name.IndexOf ('_');
                    if (offset != 0)
                    {
                        string name = child.name.Substring (offset + 1);
                        int id = Convert.ToInt32 (name);
                        //删除特效,放回objpool
                        EffectManager.Instance.DestroyEffect (id);
                    }
                }
            }

            //创建吸附技能效果
            string absorbActPath = "effect/soul_act/" + skillManagerConfig.absorbRes;
            NormalEffect absorbSkillEffect = EffectManager.Instance.CreateNormalEffect (absorbActPath, RealEntity.objAttackPoint.gameOjbect);

            objTransform.rotation = Quaternion.LookRotation (EntityFSMDirection);
        }
        //不是吸附技能
        else
        {
            //普通攻击
            if (skillManagerConfig.isNormalAttack == 1)
            {
                RealEntity.PlayerAttackAnimation ();
            }
            //放技能
            else
            {
                RealEntity.PlayerAnimation (skillManagerConfig.rAnimation);
                if (RealEntity.animation[skillManagerConfig.rAnimation] != null && RealEntity.animation[skillManagerConfig.rAnimation].wrapMode != WrapMode.Loop)
                {
                    RealEntity.CrossFadeSqu ("free");
                }

                EffectManager.playSkillReleaseSound (this, EntitySkillID);
            }

            //只算x, z方向的距离,不算y的
            float distance = GetDistanceToPos (EntityFSMPosition);
            if (entityType != EntityType.Buiding)
            {
                objTransform.rotation = Quaternion.LookRotation (EntityFSMDirection);
            }
        }
    }

    public virtual void OnEntityLeadingSkill()
    {
        SkillManagerConfig skillManagerConfig = ConfigReader.GetSkillManagerCfg (EntitySkillID);
        if (skillManagerConfig == null)
        {
            return;
        }

        RealEntity.PlayerAnimation (skillManagerConfig.rAnimation);

        float distance = GetDistanceToPos (EntityFSMPosition);

        if (entityType != EntityType.Buiding)
        {
            objTransform.rotation = Quaternion.LookRotation (EntityFSMDirection);
        }
    }

    public virtual void OnEntityLastingSkill()
    {
        SkillManagerConfig skillManagerConfig = ConfigReader.GetSkillManagerCfg (EntitySkillID);
        if (skillManagerConfig == null)
        {
            return;
        }

        RealEntity.PlayerAnimation (skillManagerConfig.rAnimation);

        float distance = GetDistanceToPos (EntityFSMPosition);
        if (entityType != EntityType.Buiding)
        {
            objTransform.rotation = Quaternion.LookRotation (EntityFSMDirection);
        }
    }

    protected GameObject CircleAreaCollision = null;

    //初始化攻击动画速度
    public virtual void InitWhenCreateModel()
    {
        int id = (int)ObjTypeID;

        if (this.entityType != EntityType.Player)
        {
            RealEntity.SetAttackAnimationLoop (true);
        }

        NpcConfigInfo npcInfo = ConfigReader.GetNpcInfo (id);
        AtkSpeed = npcInfo.NpcAttackSpeed;
        if (AtkSpeed != 0)
        {
            float spd = 1 / (AtkSpeed / 1000.0f);
            RealEntity.SetAttackAnimationSpd (spd);
        }
        else
        {
            RealEntity.SetAttackAnimationSpd (1.0f);
        }
    }

    //创建阴影
    public virtual void OnCreateShadow()
    {
        if (this.realObject.transform.FindChild("shadow(Clone)"))
        {
            return;
        }

        int id = (int)ObjTypeID;
        float radius = ConfigReader.GetNpcInfo (id).NpcCollideRadius;
        float range = radius / 100.0f;

        //                                                                      "effect/shadow/shadow"
        ResourceUnit objUnit = ResourcesManager.Instance.loadImmediate (GameDefine.GameConstDefine.LoadGameShadow, ResourceType.PREFAB);
        GameObject obj = GameObject.Instantiate (objUnit.Asset) as GameObject;

        obj.transform.parent = this.realObject.transform;
        obj.transform.localScale = new Vector3 (range, 1, range);
        obj.transform.localPosition = Vector3.zero;
    }

    //不计算y方向
    public float GetDistanceToPos(Vector3 pos)
    {
        if (RealEntity == null)
        {
            return 0.0f;
        }

        Vector3 selfPos = objTransform.position;
        Vector3 tarPos = pos;
        Vector3 diff = tarPos - selfPos;

        return Mathf.Sqrt (diff.x * diff.x + diff.z * diff.z);
    }

    //不计算y方向
    //算距离
    public float GetDistanceToEntity(Ientity tar)
    {
        if (tar == null || tar.RealEntity == null || RealEntity == null)
        {
            return 0.0f;
        }

        Vector3 selfPos = objTransform.position;
        Vector3 tarPos = tar.objTransform.position;
        Vector3 diff = tarPos - selfPos;

        return Mathf.Sqrt (diff.x * diff.x + diff.z * diff.z);
    }

    //Entity死亡
    public virtual void OnEnterDead()
    {
        //目标死亡主角相关处理
        Iselfplayer player = PlayerManager.Instance.LocalPlayer;
        if (player != null && player.SyncLockTarget != null && GameObjGUID == player.SyncLockTarget.GameObjGUID)
        {
            player.SetSyncLockTarget (null);
        }

        //播放死亡声音
        Vector3 pos = PlayerManager.TreeInstance.LocalPlayer.RealEntity.transform.position;

        //距离近的话就放死亡音效
        if (GetDistanceToPos(pos) <= 30)
        {
            this.PlayDeadSound ();
        }

        //建筑物更换模型和播表现特效
        if (this.entityType == EntityType.Buiding && this.NPCCateChild != ENPCCateChild.eNPCChild_BUILD_Base)
        {
            if (!EntityManager.GetHomeBaseList().contains(this))
            {
                //爆炸特效
                GameMethos.SetLoadJianTaBaoZha (this);

                //删除entity
                int ret = EntityManager.HandleDeleteEntity (this.GameObjGUID);
                if (ret != 0)
                {
                    Debug.LogError("OnEnterDead HandleDelectEntity:" + GameObjGUID + "failed");
                }
            }

            //建筑死亡,执行回调
            EventCenter.Broadcast<Ientity> (EGameEvent.eGameEvent_NotifyBuildingDes, this);

            return;
        }

        //非建筑物播死亡动画和清理血条等状态
        this.DoEntityDead ();
        RealEntity.PlayerDeadAnimation ();
    }

    //On Execute Dead
    public virtual void OnExecuteDead()
    {

    }

    //播放死亡音效
    private void PlayDeadSound()
    {
        string deadSound = "";
        if (this.entityType == EntityType.Player)
        {
            deadSound = ConfigReader.GetHeroInfo (this.NpcGUIDType).HeroDeathsould;
        }
        else
        {
            deadSound = ConfigReader.GetNpcInfo (this.NpcGUIDType).NpcDeathSould;
        }

        if (deadSound != "" && deadSound != "0" && deadSound != null)
        {
            //                                                                      "Audio/sounddead/"
            ResourceUnit clipUnit = ResourcesManager.Instance.loadImmediate (AudioDefine.PATH_HERO_DEADSOUND + deadSound, ResourceType.ASSET);
            AudioClip clip = clipUnit.Asset as AudioClip;
            AudioManager.Instance.PlayEffectAudio (clip);
        }
    }

    //Entity死亡要处理的事
    protected virtual void DoEntityDead()
    {
        this.HideXueTiao ();
        RealEntity.OnDestroyCollider ();
    }

    #endregion

    public virtual void OnAttackEnd()
    {

    }

    public virtual void OnSKillAnimationEnd()
    {

    }

    public virtual void OnAttackAnimationEnd()
    {

    }

    //Raises the update hp event
    public virtual void OnUpdateHp()
    {
        if (this.XueTiao != null)
        {
            this.XueTiao.UpdateHP ();
        }
    }

    public void CreateXueTiao()
    {
        if (XueTiao == null && XueTiaoManager.Instance != null)
        {
            XueTiao = XueTiaoManager.Instance.CreateXueTiao (this);
            xueTiaoObj = XueTiao.gameObject;
        }

        if (FSM != null && FSM.State == FsmState.FSM_STATE_DEAD)
        {
            HideXueTiao ();
        }
        else
        {
            ShowXueTiao ();
        }
    }

    public void DestroyXueTiao()
    {
        if (XueTiao != null)
        {
            if (XueTiao.gameObject == null)
            {
                Debug.Log("xue tiao obj is null");
            }

            GameObjectPool.Instance.ReleaseGO (XueTiao.mResName, xueTiaoObj, PoolObjectType.POT_XueTiao);
            XueTiao = null;
        }
    }

    public void ShowXueTiao()
    {
        if (XueTiao != null)
        {
            XueTiao.SetVisible (true);
            this.OnUpdateHp ();

            //Player需要更新Mp
            if (entityType == EntityType.Player)
            {
                XueTiaoPlayer XueTiaoPlayer = XueTiao as XueTiaoPlayer;
                XueTiaoPlayer.UpdateMp ();
            }
        }
    }

    public void HideXueTiao()
    {
        if (XueTiao != null)
        {
            XueTiao.SetVisible (false);
        }
    }

    public virtual void SetMp(float curMp)
    {
        Mp = curMp;
    }

    public virtual void SetHp(float curHp)
    {
        Hp = curHp;
    }

    public virtual void SetHpMax(float curHpMax)
    {
        HpMax = curHpMax;
    }

    public virtual void SetMpMax(float curMpMax)
    {
        MpMax = curMpMax;
    }

    public virtual void SetLevel(int curLv)
    {
        Level = curLv;
    }

    public virtual void SetExp(float curExp)
    {
        Exp = curExp;
    }

    public void SetCp(float curCp)
    {
        Cp = curCp;
    }

    public void SetTempCp(float curCp)
    {
        TeamCp = curCp;
    }

    public virtual float GetCollisionRadius()
    {
        int id = (int)ObjTypeID;

        return ConfigReader.GetNpcInfo (id).NpcCollideRadius / 100.0f;
    }

    public void UpdateHpChange(byte reason, float curHp)
    {
        float changeValue = Hp - curHp;
        SetHp ((float)curHp);

        if (XueTiao != null)
        {
            XueTiao.UpdateHP ();
        }

        if (reason != HpUpdateOfRecover && XueTiao != null)
        {
            XueTiao.XueTiaoDmgShow (Hp, changeValue, HpMax);
        }
    }

    public virtual void OnSkillInfoChange(int skillID, float time,  float maxTime, int slot)
    {

    }

    //SkillType:GameDefine处定义
    public virtual int GetSkillIdBySkillType(SkillType type)
    {
        switch (type)
        {
        case SkillType.SKILL_TYPE1:
            return ConfigReader.GetNpcInfo (NpcGUIDType).NpcSkillType1;
        case SkillType.SKILL_TYPE2:
            return ConfigReader.GetNpcInfo (NpcGUIDType).NpcSkillType2;
        case SkillType.SKILL_TYPE3:
            return ConfigReader.GetNpcInfo (NpcGUIDType).NpcSkillType3;
        case SkillType.SKILL_TYPE4:
            return ConfigReader.GetNpcInfo (NpcGUIDType).NpcSkillType4;
        case SkillType.SKILL_TYPE5:
            return ConfigReader.GetNpcInfo (NpcGUIDType).NpcSkillType5;
        }

        return -1;
    }

    //从Entity回调过来
    //点击中Entity的事件
    public void OnEntityFingerClick()
    {
        Iplayer pl = PlayerManager.Instance.LocalPlayer;
        if (pl != null)
        {
            if (pl.FSM != null && pl.FSM.State == FsmState.FSM_STATE_DEAD)
            {
                return;
            }

            if (this.FSM != null && this.FSM.State == FsmState.FSM_STATE_DEAD)
            {
                return;
            }

            float dis = Vector3.Distance (pl.objTransform.position, this.objTransform.position);
            if (dis > GameDefine.GameConstDefine.PlayerLockTargetDis)
            {
                return;
            }

            if (this.GameObjGUID == pl.GameObjGUID)
            {
                return;
            }

            if (ConfigReader.NpcXmlInfoDict.ContainsKey (NpcGUIDType) && ConfigReader.NpcXmlInfoDict [NpcGUIDType].un32ShopID != 0)
            {
                Debug.LogError (NpcGUIDType);
                OpenShop ();

                return;
            }
        }
        //pl存在
        else
        {
            pl = PlayerManager.Instance.LocalAccount;
        }

        if (ConfigReader.NpcXmlInfoDict.ContainsKey(NpcGUIDType) && ConfigReader.NpcXmlInfoDict[NpcGUIDType].un32ShopID != 0)
        {
            return;
        }

        pl.SetSyncLockTarget (this);
    }

    public void OpenShop(int id = 0)
    {
        if (UIShop.Instance == null)
        {
            //                                                              "Audio/HeroSelect/vo_merchant"
            ResourceUnit clipUnit = ResourcesManager.Instance.loadImmediate (AudioDefine.PATH_CLICKSHOP_SOUND, ResourceType.ASSET);
            AudioClip clip = clipUnit.Asset as AudioClip;

            NGUITools.PlaySound (clip);

            BlGameUI.Instance.OnOpenUI (GameConstDefine.GameShop);
            if (id == 0)
            {
                id = ConfigReader.NpcXmlInfoDict [NpcGUIDType].un32ShopID;
            }

            UIShop.Instance.InitShop (id);
            //都是UIShop处的东西
            UIShop.Instance.OnPageSelect (PackageSelect.ShopPage1);
        }
    }

    //是否是统一的camp
    public bool IsSameCamp(EntityCampType camp)
    {
        int campIndex = (int)camp % 2;
        int campIndex2 = (int)EntityCamp % 2;
        if (campIndex == campIndex2)
        {
            return true;
        }

        return false;
    }

    private const float hpLimit = 200.0f;

    //播放概率与不播放概率
    private float[] ifPlayMonsterSound = { 0.5f, 0.5f };

    public void SetJungleMonsterBeAtkVoice()
    {
        int id = (int)ObjTypeID;
        NpcConfigInfo info = ConfigReader.GetNpcInfo (id);

        if (entityType != EntityType.Monster || Hp < hpLimit || AudioManager.Instance.HeroLinesAudioDict.ContainsKey(GameObjGUID))
        {
            return;
        }

        List<float> ifPlaySoundList = new List<float> ();
        for (int i = 0; i < ifPlayMonsterSound.Length; i++)
        {
            ifPlaySoundList.Add (ifPlayMonsterSound [i]);
        }

        int indexPlay = GameMethod.RandProbablilyIndex (ifPlaySoundList);   //获得是否播放下标
        if (indexPlay == 1)
        {
            return;
        }

        //如果有同样类型声音正在播放
        if (HasSameTypeNpcPlaySoundIsPlaying())
        {
            return;
        }

        if (info.n32Script1Rate == null)
        {
            return;
        }

        List<float> probabilityList = GameMethod.ResolveToFloatList (info.n32Script1Rate);
        for (int i = 0; i < probabilityList.Count; i++)
        {
            probabilityList [i] = (float)(probabilityList [i] - 90000) / 100.0f;
        }

        int index = GameMethod.RandProbablityIndex (probabilityList);   //获得概率下标

        List<string> voiceList = GameMethod.ResolveToStrList (info.un32Script1);
        string name = voiceList [index];    //获得概率下标对应的声音
        //                              "Audio/HeroSelect/"
        string path = AudioDefine.PATH_JUNGLE_MONSTER_BE_ATK_SOUND + name;

        ResourceUnit clipUnit = ResourcesManager.Instance.loadImmediate (path, ResourceType.ASSET);
        AudioClip clip = clipUnit.Asset as AudioClip;

        AudioManager.Instance.PlayHeroLinesAudio (GameObjGUID, clip);
    }

    private bool HasSameTypeNpcPlaySoundIsPlaying()
    {
        int id = (int)ObjTypeID;
        foreach (var item in AudioManager.Instance.HeroLinesAudioDict.Keys)
        {
            if (id != (int)ObjTypeID)
            {
                continue;
            }

            AudioSource adSource = AudioManager.Instance.HeroLinesAudioDict [item];
            if (adSource.isPlaying)
            {
                return true;
            }
        }

        return false;
    }

    private GameObject singEffect;
    private AudioSource singSound;

    //吟唱
    public virtual void OnEnterSing()
    {
        SkillManagerConfig skillConfig = ConfigReader.GetSkillManagerCfg (EntitySkillID);
        RealEntity.PlayerAnimation (skillConfig.yAnimation);

        if (singEffect != null)
        {
            singEffect.transform.parent = null;
            GameObject.DestroyImmediate (singEffect);
        }

        //                              "effect/skill/"
        string path = GameConstDefine.LoadGameSkillEffectPath + "release/" + skillConfig.yEffect;

        ResourceUnit objUnit = ResourcesManager.Instance.loadImmediate (path, ResourceType.PREFAB);
        GameObject obj = objUnit.Asset as GameObject;

        if (obj == null)
        {
            return;
        }

        singEffect = GameObject.Instantiate (obj) as GameObject;
        if (singEffect == null)
        {
            return;
        }

        singEffect.transform.parent = RealEntity.objAttackPoint;
        singEffect.transform.localPosition = new Vector3 (0.0f, 0.0f, 0.0f);

        //                                      "sound/"
        string soundPath = GameConstDefine.LoadGameSoundPath + skillConfig.ySound;

        ResourceUnit soundObjUnit = ResourcesManager.Instance.loadImmediate (soundPath, ResourceType.ASSET);

        if (soundObjUnit.Asset != null)
        {
            AudioClip clip = soundObjUnit.Asset as AudioClip;
            if (clip != null)
            {
                AudioSource Audio = AudioManager.Instance.PlayLongVoiceAudio (clip);
                SceneSoundManager.Instance.addSound (Audio, RealEntity.gameObject);
                singSound = Audio;
                AudioManager.Instance.ChangeAudioVolume (Audio, 1.0f);
            }
        }
    }

    //结束吟唱
    public virtual void OnExitSing()
    {
        if (singEffect != null)
        {
            singEffect.transform.parent = null;
            GameObject.DestroyImmediate (singEffect);
        }

        if (singSound != null)
        {
            singSound.Stop ();
            singSound = null;
        }
    }

    //被击飞效果
    public virtual void OnBeatFly(uint buffId, string action, float raiseSpeed, float raiseAccSpeed, float fallSpeed, float fallAccSpeed, float stayTime, int canRecover)
    {
        if (realObject != null)
        {
            BeatFlyMotion beatFlyMotion = realObject.GetComponent<BeatFlyMotion> ();
            //判断是否有被击飞组件,没有就添加
            if (beatFlyMotion == null)
            {
                beatFlyMotion = realObject.AddComponent<BeatFlyMotion> ();
            }

            beatFlyMotion.BeatFly (buffId, action, raiseSpeed, raiseAccSpeed, fallSpeed, fallAccSpeed, stayTime, canRecover);
        }
    }

    //被击飞效果立即下落
    public virtual void BeatFlyFalDown(uint buffID)
    {
        if (realObject != null)
        {
            BeatFlyMotion beatFlyMotion = realObject.GetComponent<BeatFlyMotion> ();
            //当前buff对应击飞buffer移除击飞效果
            if (beatFlyMotion != null && buffID == beatFlyMotion.mBuffId)
            {
                beatFlyMotion.FallNow ();
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值