/******************************************************************************** * 文件名: Obj_NPC.cs * 全路径: \Script\Obj\Obj_NPC.cs * 创建人: 李嘉 * 创建时间:2013-10-25 * * 功能说明:游戏NPC的Obj逻辑类 * 修改记录: *********************************************************************************/ using Games.GlobeDefine; using Games.Mission; using GCGame.Table; using System.Collections; using System.Collections.Generic; using Module.Log; using UnityEngine; using Games.ChatHistory; namespace Games.LogicObj { public class Obj_NPC_Init_Data : Obj_Character_Init_Data { public bool ShowNPCHP = false; public Obj_NPC_Init_Data() { CleanUp(); } public override void CleanUp() { base.CleanUp(); m_nProfession = -1; } } public class Obj_NPC : Obj_Character { public override UIPathData HeadUiPath { get { return Obj_NPCHeadUI.pathData; } } protected Obj_NPCHeadUI m_headUIObj; protected long m_OwerGuid; //专属怪的主人guid protected string m_OwerName; //专属怪的主人名字 public Obj_NPC() { m_ObjType = GameDefine_Globe.OBJ_TYPE.OBJ_NPC; m_listMissionID = new List(); } public long OwerGUID { get { return m_OwerGuid; } } public ObjShieldData shieldData; public override bool Init(ObjParent_Init_Data initData1) { bool result = base.Init(initData1); if (result == false) { LogModule.ErrorLog("Base Init Failure!"); return false; } Obj_NPC_Init_Data initData = initData1 as Obj_NPC_Init_Data; if (initData == null) return false; m_OwerGuid = (long) initData.m_OwerGuid; m_OwerName = initData.m_OwerName; BaseAttr.HP = initData._InitCurHP; BaseAttr.MaxHP = initData._InitMaxHP; //服务器发过来的信息 BornPosX = initData.m_fX; BornPosY = gameObject.transform.position.y; BornPosZ = initData.m_fZ; //BaseAttr.RoleName = BaseAttr.RoleData.Name; // NPC挂任务 AddDialogMission(); //初始化寻路代理 InitNavAgent(); CreateNameBoard(); InitImpactInfo(initData); ObjManager.Instance.AddPoolObj(this); CreateModel(ForceUseModel == null ? ModelID : ForceUseModel.modelData.Id); if (GameManager.gameManager.AutoSearch != null) GameManager.gameManager.AutoSearch.AgentToNPC(this); _autoShowDialogue = IsAutoShowOptionDialog(); var roleTab = BaseAttr.RoleData; if (roleTab.NpcType == 4 && roleTab.Camp == 1) beTargetRange = 5; speedAdaption = roleTab.SpeedAdaption == 1; Hashtable tab = new Hashtable(); tab["roleBassId"] = initData.m_RoleBaseID; tab["type"] = Obj_Fellow.FellowDialogType.MonsterCheck; Events.EventDispatcher.Instance.SendMessage(Games.Events.EventId.FellowDialogEvent, tab); showHPFlag = initData.ShowNPCHP; return true; } /// /// 是否主角可以对话的NPC /// public bool CanTalkTo() { return Reputation.IsReputation(this, CharacterDefine.REPUTATION_TYPE.REPUTATION_DUMMY); } //NPC面向某一点 public override void FaceTo(Vector3 facePos) { var roleBaseAttr = TableManager.GetRoleBaseAttrByID(BaseAttr.RoleBaseID, 0); if (roleBaseAttr != null && roleBaseAttr.BindFace < 1) { if (CanTalkTo()) { var forward = facePos - transform.position; forward.y = 0f; if (forward == Vector3.zero) _targetRotation = null; else _targetRotation = Quaternion.LookRotation(forward, Vector3.up); } else base.FaceTo(facePos); } } private Quaternion? _targetRotation; private void SlowFaceTo() { if (_targetRotation != null) { m_ObjTransform.rotation = Quaternion.RotateTowards(m_ObjTransform.rotation, _targetRotation.Value, Time.deltaTime * 540f); if (m_ObjTransform.rotation == _targetRotation.Value) _targetRotation = null; } } protected override void CreateModelOver(Hashtable table) { base.CreateModelOver(table); RealoadPlayerWeaponVisual(); ReloadPlayerEffect(); RealoadWingModel(); } private float m_fBornPosX = 0.0f; public float BornPosX { get { return m_fBornPosX; } set { m_fBornPosX = value; } } private float m_fBornPosY = 0.0f; public float BornPosY { get { return m_fBornPosY; } set { m_fBornPosY = value; } } private float m_fBornPosZ = 0.0f; public float BornPosZ { get { return m_fBornPosZ; } set { m_fBornPosZ = value; } } /// /// 停止NPC当前播放的特效 /// public void StopNPCEffect() { if (ObjEffectLogic != null) { ObjEffectLogic.CleanImpacts(); ObjEffectLogic.CleanEffect(); } } public override bool OnDie() { var result = base.OnDie(); if (result) { if (m_headUIObj != null) m_headUIObj.SetNameColor(CharacterDefine.NPC_COLOR_DIE); #if UNITY_ANDROID if (NavAgent != null) { NavAgent.enabled = false; } #endif //死亡特效 var roleBaseAttr = TableManager.GetRoleBaseAttrByID(BaseAttr.RoleBaseID, 0); if (roleBaseAttr != null && ObjEffectLogic != null) { //死亡特效 if (roleBaseAttr.DieEffectID != -1) PlayEffect(roleBaseAttr.DieEffectID); } SceneMovieManager.Instance.OnKillMonster(BaseAttr.RoleBaseID); } return result; } protected override void Update() { base.Update(); AutoShowNPCDialogNear(); SlowFaceTo(); } private bool _autoShowDialogue; private const float _autoDialogueDistSqr = 2f * 2f; private const float _autoDialogueRefreshSqr = 2.5f * 2.5f; private void AutoShowNPCDialogNear() { // 注:Award_Npc需要动态确定IsServerFlagOpen if (_autoShowDialogue) { var mainPlayer = ObjManager.Instance.MainPlayer; if (mainPlayer != null) { if (_autoShowDialogue) { if ((mainPlayer.Position - Position).RemoveY().sqrMagnitude > _autoDialogueRefreshSqr) _autoShowDialogue = false; } else { if ((mainPlayer.Position - Position).RemoveY().sqrMagnitude < _autoDialogueDistSqr && mainPlayer.MovementState == MoveState.Static) { _autoShowDialogue = true; if (BaseAttr.RoleBaseID == GlobeVar.GUILDDATAID_SUZHOU) { if (MissionInfoController.Instance() == null) //没有弹出对话(无选项) Singleton.GetInstance().Show(this); } else { if (OptionDialogLogic.Instance() == null) //没有弹出对话(有选项) Singleton.GetInstance().Show(this); } } } } } } // 需要显示 OptionDialog的在这加吧 private bool IsAutoShowOptionDialog() { var bRet = false; //是黑市商人 switch (BaseAttr.RoleBaseID) { case GlobeVar.BLACKMAKETDATAID_ERHAI: case GlobeVar.BLACKMAKETDATAID_SHUZHOU: case GlobeVar.CANGKU1_SHUZHOU: case GlobeVar.CANGKU2_SHUZHOU: case GlobeVar.RECOVERNPC_DATAID: case GlobeVar.PAOSHANG_ACCEPTNPC_DATAID: case GlobeVar.AWARD_NPCID: case GlobeVar.GUILDDATAID_SUZHOU: bRet = true; break; } return bRet; } public static string GetColor(int sceneType) { switch (sceneType) { case 0: { return StrDictionary.GetClientDictionaryString("#{5562}", StrDictionary.GetClientDictionaryString("#{5012}")); } case 1: { return StrDictionary.GetClientDictionaryString("#{5562}", StrDictionary.GetClientDictionaryString("#{5013}")); } case 2: { return StrDictionary.GetClientDictionaryString("#{5562}", StrDictionary.GetClientDictionaryString("#{5014}")); } case 3: { return StrDictionary.GetClientDictionaryString("#{5562}", StrDictionary.GetClientDictionaryString("#{5015}")); } case 4: { return StrDictionary.GetClientDictionaryString("#{5562}", StrDictionary.GetClientDictionaryString("#{5016}")); } case 5: { return StrDictionary.GetClientDictionaryString("#{5562}", StrDictionary.GetClientDictionaryString("#{5017}")); } } return ""; } public override void ShowChatBubble(ChatHistoryItem history) { if (null != m_headUIObj) { m_headUIObj.ShowChatBubble(history); } } //有些特殊的NPC身上不挂任务,通过活动来判断 bool SpecialNpc() { if (RoleBaseID == 912 || RoleBaseID == 913 || RoleBaseID == 914) return true; return false; } public override void InitNameBoard(Obj_HeadUI headUiItem) { base.InitNameBoard(headUiItem); m_headUIObj = (Obj_NPCHeadUI) headUiItem; if (MissionList.Count > 0 || SpecialNpc()) { m_headUIObj.ChangeBoardState(true); //设置MissionBoard的NPC var missionBoard = m_headUIObj.boardObj.GetComponent(); if (missionBoard != null) { missionBoard.InitNpcInfo(this); } else { Module.Log.LogModule.ErrorLog("----------missionBoard is null"); } } else { m_headUIObj.ChangeBoardState(false); } if (Singleton.Instance.m_Belongs.Contains(ServerID)) { m_headUIObj.ChangeBelong(true); Singleton.Instance.m_Belongs.Remove(ServerID); } else m_headUIObj.ChangeBelong(false); m_headUIObj.SetOwnerName(m_OwerName); Tab_RoleBaseAttr roleBase = TableManager.GetRoleBaseAttrByID(RoleBaseID, 0); if (roleBase == null) return; if (roleBase.NpcType == 4) { m_headUIObj.HideHp(false); m_headUIObj.HideBackImage(true); } else { OptHPChange(); m_headUIObj.HideBackImage(false); } m_headUIObj.SetNameColor(GetNameBoardColor()); if (roleBase.IsShowHeadIcon == 1) { m_headUIObj.NameText.gameObject.SetActive(true); m_headUIObj.SetName(GetNPCNameColor(BaseAttr.RoleName)); } else { if (showHPFlag) { m_headUIObj.NameText.gameObject.SetActive(true); m_headUIObj.SetLevelName(BaseAttr.Level, GetNPCNameColor(BaseAttr.RoleName)); } else { m_headUIObj.NameText.gameObject.SetActive(false); } } m_headUIObj.HideChatBubble(false); if (shieldData != null) { m_headUIObj.CreateShield(); m_headUIObj.UpdateShield((float)shieldData.health / shieldData.maxHealth); } else { m_headUIObj.RemoveShield(); } } private string GetNPCNameColor(string name) { return GetNpcNameColor(name, this); } public static string GetNpcNameColor(string name, Obj_Character character) { Tab_RoleBaseAttr roleBase = TableManager.GetRoleBaseAttrByID(character.RoleBaseID, 0); if (roleBase != null && roleBase.NpcType == 4 && roleBase.SceneNpcType != -1) { name = StrDictionary.GetClientDictionaryString("#{5561}", name, GetColor(roleBase.SceneNpcType)); } Tab_CrossSerEscortConfig config = TableManager.GetCrossSerEscortConfigByID(character.RoleBaseID, 0); if (config != null) { var fuben = TableManager.GetFubenByID(GlobalData.GetCurSceenFubenId(), 0); if (fuben.IsShowCamp == 1) { if (character.BaseAttr.Force == 6) name = StrDictionary.GetClientDictionaryString("#{5820}") + name; if (character.BaseAttr.Force == 7) name = StrDictionary.GetClientDictionaryString("#{5821}") + name; if (character.BaseAttr.Force == 27) name = StrDictionary.GetClientDictionaryString("#{5822}") + name; } name = string.Format("{1}", config.NPCNameColor, name); } return name; } //怪物归属改变 public void ChangeBelong(bool state) { if (m_headUIObj != null) m_headUIObj.ChangeBelong(state); } ////////////////////////////////////////////////////////////////////////// //NPC对话相关处理 ////////////////////////////////////////////////////////////////////////// private int m_nDefaultDialogID = -1; //NPC对话索引列表 public int DefaultDialogID { get { return m_nDefaultDialogID; } set { m_nDefaultDialogID = value; } } private List m_listMissionID; //NPC任务脚本 public List MissionList { get { return m_listMissionID; } } void AddMissionToList(int nMissionID) { m_listMissionID.Add(nMissionID); } void ClearMissionList() { m_listMissionID.Clear(); } public bool IsHaveMission(int nMissionID) { if (m_listMissionID.Contains(nMissionID)) { Tab_MissionBase missionBase = TableManager.GetMissionBaseByID(nMissionID, 0); if (missionBase != null) //主线任务状态是未接取的全部是没有任务 { if (missionBase.MissionType == (int) MISSIONTYPE.MISSION_MAIN && GameManager.gameManager.MissionManager.GetMissionState(nMissionID) == (int) MissionState.Mission_NotAccept) { return false; } } return true; } return false; } public override bool OnEnterCombat(Obj_Character Attacker) { if (IsDie()) { return false; } base.OnEnterCombat(Attacker); if (Controller == null) { return false; } if (Controller.CurrentAIState.AIType != CharacterDefine.AI_TYPE.AI_TYPE_COMBAT) { Controller.EnterCombat(); } if (Attacker) { Controller.ThreadInfo.AddThreat(Attacker, 10); } return true; } public override void OnLevelCombat(Obj_Character Attacker) { base.OnLevelCombat(Attacker); if (Controller == null) { return; } if (Controller.CurrentAIState.AIType == CharacterDefine.AI_TYPE.AI_TYPE_COMBAT) { Controller.LeaveCombat(); } if (Attacker) { Controller.ThreadInfo.ResetThreat(Attacker); } } public void AddDialogMission() { Tab_RoleBaseAttr RoleBase = TableManager.GetRoleBaseAttrByID(BaseAttr.RoleBaseID, 0); if (RoleBase == null) return; Tab_NpcDialog DialogLine = TableManager.GetNpcDialogByID(RoleBase.DialogID, 0); if (DialogLine != null) { m_nDefaultDialogID = RoleBase.DialogID; for (int i = 0; i < DialogLine.getMissionIDCount(); ++i) { int nMissionID = DialogLine.GetMissionIDbyIndex(i); if (nMissionID >= 0) { m_listMissionID.Add(nMissionID); } } } } public override void OptNameChange() //名字变化后的操作 { if (m_headUIObj != null) m_headUIObj.SetName(GetNPCNameColor(BaseAttr.RoleName)); } public override void OptForceChange() //势力变化后的操作 { base.OptForceChange(); if (m_headUIObj != null) m_headUIObj.SetNameColor(GetNameBoardColor()); } public override void OptHPChange() { base.OptHPChange(); if (m_headUIObj != null) { Tab_RoleBaseAttr roleBase = TableManager.GetRoleBaseAttrByID(RoleBaseID, 0); if (roleBase.IsShowHeadIcon != 1) { if (!showHPFlag) { m_headUIObj.HideHp(false); //m_headUIObj.NameText.gameObject.SetActive(true); OptNameChange(); return; } else { m_headUIObj.HideHp(true); m_headUIObj.NameText.gameObject.SetActive(true); m_headUIObj.SetLevelName(BaseAttr.Level, BaseAttr.RoleName); } } float rate = 1; if (BaseAttr.MaxHP > 0) rate = BaseAttr.HP * 1.0f / (BaseAttr.MaxHP * 1.0f); m_headUIObj.SetNewHp(rate); } } public override bool UseSkill(Tab_SkillEx skillEx, Tab_SkillBase skillBase, int firstSkillId, int targetId, Vector3 facePoint, bool skipWindup = false) { var result = base.UseSkill(skillEx, skillBase, firstSkillId, targetId, facePoint, skipWindup); if (BossFramUI.Instance() != null && BossFramUI.Instance().TargetServerID == ServerID) { BossFramUI.Instance().ShowAttackObjName(result ? targetId : -1); } return result; } public override void CreateShield(ObjShieldData shield) { if (shieldData != null) LogModule.ErrorLog(string.Format("类型为{0}的Obj {1}试图获得两层盾牌!", ObjType, ServerID)); else { shieldData = shield; // 创建新的盾牌 if (m_headUIObj != null) { m_headUIObj.CreateShield(); m_headUIObj.UpdateShield((float)shieldData.health / shieldData.maxHealth); } LogModule.DebugLog(string.Format("创建类型为{0}的Obj {1}de盾牌!", ObjType, ServerID)); Events.EventDispatcher.Instance.Dispatch(Events.EventId.CreateTargetHealth,this); Events.EventDispatcher.Instance.Dispatch(Events.EventId.UpdateTargetHealth, this); } } public override void UpdateShieldHealth(long health, int handle) { if (shieldData != null && shieldData.handle == handle) { shieldData.health = health; // 更新盾牌数值 if (m_headUIObj != null) m_headUIObj.UpdateShield((float)shieldData.health / shieldData.maxHealth); Events.EventDispatcher.Instance.Dispatch(Events.EventId.UpdateTargetHealth, this); } } public override void RemoveShield(int handle) { if (shieldData != null && shieldData.handle == handle) { shieldData = null; // 移除盾牌 if (m_headUIObj != null) m_headUIObj.RemoveShield(); LogModule.DebugLog(string.Format("移除类型为{0}的Obj {1}de盾牌!", ObjType, ServerID)); Events.EventDispatcher.Instance.Dispatch(Events.EventId.RemoveTargetHealth, this); } } public Color GetOutLineColor() { string curColr; var reputation = Reputation.GetObjReputionType(this); switch (reputation) { case CharacterDefine.REPUTATION_TYPE.REPUTATION_NEUTRAL: curColr = "3e380f"; break; case CharacterDefine.REPUTATION_TYPE.REPUTATION_HOSTILE: curColr = "3f0f0f"; break; default: curColr = "0e4410"; break; } return GCGame.Utils.GetColorByString(curColr); } public virtual Color GetNameBoardColor() { return GetNameBoardColor(this); } public static Color GetNameBoardColor(Obj_Character character) { var curColr = string.Empty; if (character.RoleBaseID == 0 && Reputation.CanAttack(character)) { curColr = StrDictionary.GetClientDictionaryString("#{5564}"); } else { var roleBase = TableManager.GetRoleBaseAttrByID(character.RoleBaseID, 0); if (roleBase != null && roleBase.NpcType != 4 && Reputation.CanAttack(character)) curColr = roleBase.NpcType == 2 || roleBase.NpcType == 5 ? StrDictionary.GetClientDictionaryString("#{5563}") : StrDictionary.GetClientDictionaryString(roleBase.Camp == 2 ? "#{5559}" : "#{5564}"); } if (string.IsNullOrEmpty(curColr)) curColr = StrDictionary.GetClientDictionaryString("#{5560}"); return GCGame.Utils.GetColorByString(curColr); } public override void DestroyObj() { var optionDialog = OptionDialogLogic.Instance(); if (optionDialog != null && DialogCore.Instance.CareNPC != null && DialogCore.Instance.CareNPC.ServerID == ServerID) UIManager.CloseUI(UIInfo.OptionDialogRoot); if (BossFramUI.Instance() != null && BossFramUI.Instance().gameObject.activeInHierarchy) BossFramUI.Instance().CancelTarget(ServerID); if (m_headUIObj != null) m_headUIObj.RemoveShield(); if (RoleBaseID == 1123) { GCGame.Utils.ShowMainTopRightUI(); } base.DestroyObj(); } public bool IsNeedBecameVisible() { if (BaseAttr.RoleBaseID == GlobeVar.PARADE_BUSID) { return false; } return true; } public override void OnBindOpt(Obj_Character obj) { base.OnBindOpt(obj); //婚车特殊摆设 if (BaseAttr.RoleBaseID == GlobeVar.PARADE_BUSID && obj != null) { Transform playermodel = obj.transform.Find("Model"); Transform ridepoint = gameObject.transform.Find("Model/All/Bip01/Bip01 Pelvis/Bip01 Spine/Ride_Point01"); Transform seatpoint = gameObject.transform.Find("Model/All/Bone02/Ride_Point02"); if (playermodel == null || ridepoint == null || seatpoint == null) { return; } if (GetBindChildIndex(obj.ServerID) == 0 && ridepoint.childCount < 1) { obj.gameObject.transform.localPosition = new Vector3(0.0f, 0.78f, -0.47f); GameObject fakeobj = (GameObject) Instantiate(playermodel.gameObject); if (fakeobj != null) { fakeobj.SetActive(true); fakeobj.transform.parent = ridepoint; fakeobj.transform.localPosition = Vector3.zero; fakeobj.transform.localRotation = Quaternion.Euler(90.0f, 0.0f, 0.0f); fakeobj.transform.localScale = Vector3.one; // 注:以下代码实际没有意义 - al.InitState(fakeobj,null);会让AnimationLogic不响应Play函数 //AnimationLogic al = ridepoint.gameObject.AddComponent(); //if (al != null) //{ // al.InitState(fakeobj,null); // Tab_RoleBaseAttr role = TableManager.GetRoleBaseAttrByID(obj.BaseAttr.RoleBaseID, 0); // if (role != null) // { // Tab_CharModel mo = TableManager.GetCharModelByID(role.CharModelID, 0); // if (mo != null) // { // //al.AnimResFilePath = mo.AnimPath; // } // } // int animId = -1; // //sl/ts/dl/xy // if (obj.BaseAttr.RoleBaseID == 0) // animId = 153; // else if (obj.BaseAttr.RoleBaseID == 1) // animId = 155; // else if (obj.BaseAttr.RoleBaseID == 2) // animId = 159; // else if (obj.BaseAttr.RoleBaseID == 3) // animId = 157; // if (animId > 0) // { // al.Play(animId); // } //} } return; } if (GetBindChildIndex(obj.ServerID) == 1 && seatpoint.childCount < 1) { obj.gameObject.transform.localPosition = new Vector3(0.0f, 0.47f, -1.83f); GameObject fakeobj = (GameObject) Instantiate(playermodel.gameObject); if (fakeobj != null) { fakeobj.SetActive(true); fakeobj.transform.parent = seatpoint; fakeobj.transform.localPosition = Vector3.zero; fakeobj.transform.localRotation = Quaternion.Euler(90.0f, 0.0f, 0.0f); fakeobj.transform.localScale = Vector3.one; // 注:以下代码实际没有意义 - al.InitState(fakeobj,null);会让AnimationLogic不响应Play函数 //AnimationLogic al = seatpoint.gameObject.AddComponent(); //if (al != null) //{ // al.InitState(fakeobj,null); // Tab_RoleBaseAttr role = TableManager.GetRoleBaseAttrByID(obj.BaseAttr.RoleBaseID, 0); // if (role != null) // { // Tab_CharModel mo = TableManager.GetCharModelByID(role.CharModelID, 0); // if (mo != null) // { // //al.AnimResFilePath = mo.AnimPath; // } // } // int animId = -1; // //sl/ts/dl/xy // if (obj.BaseAttr.RoleBaseID == 0) // animId = 146; // else if (obj.BaseAttr.RoleBaseID == 1) // animId = 148; // else if (obj.BaseAttr.RoleBaseID == 2) // animId = 152; // else if (obj.BaseAttr.RoleBaseID == 3) // animId = 150; // if (animId > 0 && al) // al.Play(animId); //} } return; } } } private int m_BelongTeamID = GlobeVar.INVALID_ID; public int BelongTeamID { get { return m_BelongTeamID; } set { m_BelongTeamID = value; } } private int m_BelongObjID = GlobeVar.INVALID_ID; public int BelongObjID { get { return m_BelongObjID; } set { m_BelongObjID = value; } } private bool m_bIsGuildActivityBoss = false; // 帮会活动Boss; public bool IsGuildActivityBoss { get { return m_bIsGuildActivityBoss; } set { m_bIsGuildActivityBoss = value; } } } }