/******************************************************************************** * 文件名: Obj_Fellow.cs * 全路径: \Script\Obj\Obj_Fellow.cs * 创建人: 李嘉 * 创建时间:2013-10-25 * * 功能说明:游戏伙伴Obj逻辑类 * 修改记录: *********************************************************************************/ using System; using System.Collections; using System.Collections.Generic; using Games.GlobeDefine; using GCGame; using GCGame.Table; using UnityEngine; using Games.ChatHistory; using Games.Events; namespace Games.LogicObj { public class Fellow_InitData : Obj_Character_Init_Data { public int m_FellowQuality; //伙伴品质(创建伙伴用) public long m_OwenGuid; public int handBookModelID; public Fellow_InitData() { CleanUp(); } public override void CleanUp() { base.CleanUp(); m_FellowQuality = -1; m_OwenGuid = -1; } } public partial class Obj_Fellow : Obj_Character { //宠物攻击AI,先写在一个文件中 //宠物普通攻击ID 10005 private readonly int AttackID = 10005; private float CDTime; private float lastUseTime; private Obj_FellowHeadUI m_HeadUIScrip; /// /// 伙伴品质 /// private int m_Quality; private Obj_Character m_Target; public override bool useXRay { get { return IsOwnedByMainPlayer(); } } public Obj_Fellow() { m_ObjType = GameDefine_Globe.OBJ_TYPE.OBJ_FELLOW; OwnerObjId = -1; } public override UIPathData HeadUiPath { get { return Obj_FellowHeadUI.pathData; } } public int Quality { get { return m_Quality; } set { m_Quality = value; SetFellowQuilityIcon(); } } public int OwnerObjId { get; set; } private bool _init; public override bool Init(ObjParent_Init_Data initData1) { speedAdaption = true; var result = base.Init(initData1); if (result) { _startShowEffects.Clear(); var initData = (Fellow_InitData) initData1; OwnerObjId = initData.m_OwnerObjId; m_Quality = initData.m_FellowQuality; //防止伙伴追上人物导致动作不流畅 把客户端主角伙伴速度修改为和人物一样 if (IsOwnedByMainPlayer()) { Singleton.GetInstance().MainPlayer.CurFellowObjId = ServerID; BaseAttr.MoveSpeed = GameManager.gameManager.PlayerDataPool.MainPlayerBaseAttr.MoveSpeed; } else { var otherPlayer = Singleton.Instance.FindObjInScene(OwnerObjId) as Obj_OtherPlayer; if (null != otherPlayer) { otherPlayer.FellowID = ServerID; m_bVisible = otherPlayer.IsVisibleChar(); } else { EventDispatcher.Instance.Add(Games.Events.EventId.FellowOwerEvent, FindOwer); } BaseAttr.MoveSpeed = initData.m_MoveSpeed; } var fellowAttrTab = TableManager.GetFellowBaseByID(BaseAttr.RoleBaseID, 0); if (fellowAttrTab != null) { //初始化CharModelID,并读取部分客户端信息 ModelID = initData.handBookModelID > 0 ? initData.handBookModelID : fellowAttrTab.ModelId; var charModel = TableManager.GetCharModelByID(ModelID, 0); if (null != charModel) { BaseAttr.HeadPic = charModel.HeadPic; // 设置名字版高度 m_DeltaHeight = charModel.HeadInfoHeight * ModelScale; m_ObjTransform.localRotation = Utils.DirServerToClient(initData.m_fDir); // 设置展示特效 Obj_FakeShow.AppendEffectIds(_startShowEffects, charModel.EffectID); } } //召出播放特效 if (Singleton.GetInstance().MainPlayer != null) if (OwnerObjId == Singleton.GetInstance().MainPlayer.ServerID) if (GameManager.gameManager.PlayerDataPool.FellowPlayerEffect) { PlayEffect(54); GameManager.gameManager.PlayerDataPool.FellowPlayerEffect = false; } //初始化HP BaseAttr.MaxHP = initData._InitMaxHP; BaseAttr.HP = initData._InitCurHP; var SkillExInfo = TableManager.GetSkillExByID(AttackID, 0); if (SkillExInfo != null) { var coolDown = TableManager.GetCoolDownTimeByID(SkillExInfo.CDTimeId, 0); if (coolDown != null) CDTime = coolDown.CDTime / 1000; } //初始化寻路代理 InitNavAgent(); CreateNameBoard(); InitImpactInfo(initData); CanLogic = true; if (!_init) { _init = true; PlayerPreferenceData.SystemHideFellow.onValueUpdate += OnHideFellowUpdate; } OnHideFellowUpdate(PlayerPreferenceData.SystemHideFellow); ObjManager.Instance.AddPoolObj(this); } return result; } protected override void OnDestroy() { if (!GameManager.applicationQuit) { PlayerPreferenceData.SystemHideFellow.onValueUpdate -= OnHideFellowUpdate; EventDispatcher.Instance.Remove(Events.EventId.FellowOwerEvent, FindOwer); } base.OnDestroy(); } private void OnHideFellowUpdate(bool isHide) { var hide = !IsOwnedByMainPlayer() && isHide; if (hide) ModelNode.RemoveModel(); else CreateModel(ModelID); SetShadow(!hide); } private void FindOwer(object id) { var otherPlayer = Singleton.Instance.FindObjInScene(OwnerObjId) as Obj_OtherPlayer; if (null != otherPlayer) { otherPlayer.FellowID = ServerID; ChangeNameColor(Reputation.IsEnemy(otherPlayer)); EventDispatcher.Instance.Remove(Games.Events.EventId.FellowOwerEvent, FindOwer); } } public void ChangeNameColor(bool IsEnemy) { if (m_HeadUIScrip == null) return; if(IsEnemy) { m_HeadUIScrip.SetNameColor(Utils.GetColorByString(StrDictionary.GetClientDictionaryString("#{5556}"))); m_HeadUIScrip.HpSliderShowLogic(2); } else { m_HeadUIScrip.SetNameColor(Utils.GetColorByString(StrDictionary.GetClientDictionaryString("#{5558}"))); m_HeadUIScrip.HpSliderShowLogic(IsOwnedByMainPlayer() ? 1 : 0); } } public override void OptHPChange() { base.OptHPChange(); if (m_HeadUIScrip != null) { float rate = 1; if (BaseAttr.MaxHP > 0) rate = BaseAttr.HP * 1.0f / (BaseAttr.MaxHP * 1.0f); m_HeadUIScrip.SetNewHp(rate); } } public void SetFellowQuilityIcon() { if (m_HeadUIScrip != null) m_HeadUIScrip.SetFellowQuilityIcon(m_Quality); } public void GetAssetReference(List> list) { var models = new[] { ModelNode, weaponLeft, weaponRight, weaponEffectLeft, weaponEffectRight, effectAura, wingObj }; for (var i = 0; i < models.Length; i++) { var model = models[i]; if (!string.IsNullOrEmpty(model.targetBundle) && !string.IsNullOrEmpty(model.targetModel)) { var add = true; for (var j = 0; j < list.Count; j++) if (list[j].first == model.targetBundle && list[j].second == model.targetModel) { add = false; break; } if (add) list.Add(new MyTuple(model.targetBundle, model.targetModel)); } } } public override void ShowChatBubble(ChatHistoryItem history) { if (null != m_HeadUIScrip) { m_HeadUIScrip.ShowChatBubble(history); } } public override void InitNameBoard(Obj_HeadUI headUiItem) { base.InitNameBoard(headUiItem); m_HeadUIScrip = (Obj_FellowHeadUI) headUiItem; SetFellowQuilityIcon(); m_HeadUIScrip.SetName(BaseAttr.RoleName); if (IsOwnedByMainPlayer()) { float rate = 1; if (BaseAttr.MaxHP > 0) rate = BaseAttr.HP * 1.0f / (BaseAttr.MaxHP * 1.0f); m_HeadUIScrip.SetNewHp(rate); ChangeNameColor(false); } else { var otherPlayer = Singleton.Instance.FindObjInScene(OwnerObjId) as Obj_OtherPlayer; ChangeNameColor(Reputation.IsEnemy(otherPlayer)); if (GameManager.gameManager.m_RunningScene == 658) { //Debug.LogError("在紫荆之巅中隐藏其他玩家宠物的名字"); headUiItem.NameText.gameObject.SetActive(false); } } m_HeadUIScrip.HideChatBubble(false); if (IsOwnedByMainPlayer()) InitFellowDialog(); } public void ChangeName(string name) { if (BaseAttr != null) BaseAttr.RoleName = name; if (m_HeadUIScrip != null) m_HeadUIScrip.SetName(name); } /// /// 是否主角的伙伴 /// public bool IsOwnedByMainPlayer() { var mainPlayer = ObjManager.Instance.MainPlayer; return mainPlayer != null && mainPlayer.ServerID == OwnerObjId; } /// /// 把主角伙伴客户端速度设置为与主角一致 /// public void SetMoveSpeedAsMainPlayer() { if (Singleton.GetInstance().MainPlayer != null) if (IsOwnedByMainPlayer()) { BaseAttr.MoveSpeed = GameManager.gameManager.PlayerDataPool.MainPlayerBaseAttr.MoveSpeed; if (NavAgent != null) NavAgent.speed = BaseAttr.MoveSpeed; } } private Vector3 GetFellowPos(Obj_MainPlayer mainPlayer) { var fAngle = (float) (Math.PI * (5.0f / 4.0f)); var nDist = 1; var retPos = Position; //主角位置 var mainPos = mainPlayer.Position; //主角朝向 var mainDir = Utils.DirClientToServer(mainPlayer.Rotation); mainDir = Utils.NormaliseDirection(mainDir); retPos.x = (float) (nDist * Math.Cos(fAngle)); retPos.z = (float) (nDist * Math.Sin(fAngle)); //旋转 var x = (float) (retPos.x * Math.Cos(mainDir) - retPos.z * Math.Sin(mainDir)); var z = (float) (retPos.z * Math.Cos(mainDir) + retPos.x * Math.Sin(mainDir)); retPos.x = x; retPos.z = z; //平移 retPos.x += mainPos.x; retPos.z += mainPos.z; return retPos; } #region 宠物动画系统 // idle在动画机中的哈希值 private static int? _idleAnimHash; private float _startShowTime = -1f; private readonly List _startShowEffects = new List(); protected override void OnBodyCreate(ObjPartRoot model, object dataTable) { // 注:默认条件下,宠物动画为idle; _startShowTime = Time.time + Obj_FakeShow.startShowInterval; base.OnBodyCreate(model, dataTable); AnimLogic.onAnimEnter += OnAnimationEnter; } protected override void OnBodyDestroy(ObjPartRoot model) { base.OnBodyDestroy(model); _startShowTime = -1f; } private void OnAnimationEnter(int animHash) { if (_idleAnimHash == null) { var idleData = TableManager.GetAnimationByID(idleAnimId); _idleAnimHash = Animator.StringToHash(idleData.AnimName.ToLower()); } if (_idleAnimHash.Value == animHash) { // 重复进入Idle不刷新状态 if (_startShowTime < 0f) _startShowTime = Time.time + Obj_FakeShow.startShowInterval; } else _startShowTime = -1f; } public override bool UseSkill(Tab_SkillEx skillEx, Tab_SkillBase skillBase, int firstSkillId, int targetId, Vector3 facePoint, bool skipWindup = false) { UpdateSkillCooldown(firstSkillId); var result = base.UseSkill(skillEx, skillBase, firstSkillId, targetId, facePoint, skipWindup); return result; } /// /// 更新技能CD数值 /// public void UpdateSkillCooldown(int skillId) { if(IsOwnedByMainPlayer()) { GameManager.gameManager.PlayerDataPool.FellowContainer.UpdateSkillCD(skillId,-1); } } protected override void Update() { base.Update(); if (_startShowTime >= 0f && _startShowTime < Time.time) { // 注:不存在startShow的宠物也将使用这个Loop。 _startShowTime = Time.time + Obj_FakeShow.startShowInterval; if (AnimLogic != null) AnimLogic.Play(Obj_FakeShow.startShowId); if (ObjEffectLogic != null) for (var i = 0; i < _startShowEffects.Count; i++) ObjEffectLogic.PlayEffect(_startShowEffects[i]); } } #endregion } }