/********************************************************************************
* 文件名: 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
}
}