void HandleKillActor(S2CNwarUnitDead kDeathMsg) { if (!mIsRecvMsg) { return; } bool has_trigger = false; SkillAttackInstance inst = EffectManager.GetInstance().GetAttackInstance(kDeathMsg.em_id); if (inst != null) { // 需要从伤害信息中获取攻击者(此处要求服务端的伤害消息一定在死亡消息之前发送) Actor src = ActorManager.Instance.GetActor(inst.SrcActorID); if (src != null && src.Trans != null && mOwner.Trans != null) { has_trigger = true; Vector3 vec = mOwner.Trans.position - src.Trans.position; vec.y = 0; vec.Normalize(); // 设置击飞方向信息 SkillAttackInstance.DeathAppendInfo info = new SkillAttackInstance.DeathAppendInfo(); info.Id = kDeathMsg.id; info.FlyDir = vec; inst.AddDeathInfo(info); } } if (has_trigger == false) { mOwner.ActorMachine.DeathFlyInfo = new ActorMachine.DeathInfo(); mOwner.Kill(); } }
bool mHideEffect = false; // 是否隐藏子弹特效 /// <summary> /// 初始化 /// </summary> public bool Init() { m_SkillInfo = DBSkillSev.Instance.GetSkillInfo(SkillID); m_SubEmitId = (ulong)(((ulong)ActorID << 32 & 0xffffffff00000000) | ((ulong)SkillID << 16 & 0xffffffffffff0000)); // 暂时使用技能ID和角色ID来进行组合 if (m_SkillInfo != null && m_SkillInfo.BulletId != 0) { m_BulletInfo = DBBulletTrace.GetInstance().GetBulletInfo(m_SkillInfo.BulletId); if (m_BulletInfo != null) { if (HitPlayers.Count > 0) { uint hit_player_id = HitPlayers[0]; Actor src_player = ActorManager.Instance.GetPlayer(ActorID); Actor hitPlayer = ActorManager.Instance.GetPlayer(hit_player_id); if (src_player == null || hitPlayer == null || src_player.GetActorMono() == null || hitPlayer.GetActorMono() == null) { return(false); } ActorMono src_actormono = src_player.GetActorMono(); ActorMono hit_actormono = hitPlayer.GetActorMono(); BulletTrackInstance sub_bullet_trace = new xc.BulletTrackInstance(m_BulletInfo, m_SkillInfo, 0); m_TraceInsts.Add(sub_bullet_trace); // 开启新的BulletTrackInstance mHideEffect = ShieldManager.Instance.IsHideBulletEffect(src_player, hitPlayer); sub_bullet_trace.Do(m_SubEmitId, src_actormono, hit_actormono, mHideEffect, src_player.transform.position, src_player.transform.rotation, src_player.transform.forward, OnHit); // 将伤害信息添加到新创建的SkillAttackInstance列表中 SkillAttackInstance attack_inst = EffectManager.GetInstance().GetAttackInstance(m_SubEmitId); if (attack_inst != null) { Damage dmgInfo = null; if (m_DamageInfos.TryGetValue(hit_player_id, out dmgInfo)) { attack_inst.AddHurtInfo(dmgInfo); } } m_HitEmits[hit_player_id] = new HitCacheInfo(m_SubEmitId); m_SubEmitId++; mLastThunderPlayer = hit_player_id; HitPlayers.RemoveAt(0); return(true); } } } return(false); }
/// <summary> /// 添加命中的死亡数据 /// </summary> public void AddDeathInfo(SkillAttackInstance.DeathAppendInfo death_info) { m_DeathAppendInfos[death_info.Id] = death_info; HitCacheInfo info; if (m_HitEmits.TryGetValue(death_info.Id, out info)) { SkillAttackInstance attack_inst = EffectManager.GetInstance().GetAttackInstance(info.SubEmitID); if (attack_inst != null) { attack_inst.AddDeathInfo(death_info); } } }
/// <summary> /// 添加伤害数据 /// </summary> public void AddHurtInfo(Damage damageInfo) { m_DamageInfos[damageInfo.TargetID] = damageInfo; HitCacheInfo info; if (m_HitEmits.TryGetValue(damageInfo.TargetID, out info)) { SkillAttackInstance attack_inst = EffectManager.GetInstance().GetAttackInstance(info.SubEmitID); if (attack_inst != null) { attack_inst.AddHurtInfo(damageInfo); } } }
/// <summary> /// 当命中一个角色后的回调 /// </summary> /// <param name="sub_inst"></param> void OnHit(SkillAttackInstance sub_inst) { if (m_BulletInfo != null) { if (HitPlayers.Count > 0) { uint hit_player_id = HitPlayers[0]; Actor src_player = ActorManager.Instance.GetPlayer(mLastThunderPlayer); Actor hitPlayer = ActorManager.Instance.GetPlayer(hit_player_id); if (src_player == null || hitPlayer == null || src_player.GetActorMono() == null || hitPlayer.GetActorMono() == null) { GameDebug.Log("player is null"); } else { BulletTrackInstance sub_bullet_trace = new xc.BulletTrackInstance(m_BulletInfo, m_SkillInfo, 0); m_TraceInsts.Add(sub_bullet_trace); // 开启新的BulletTrackInstance sub_bullet_trace.Do(m_SubEmitId, src_player.GetActorMono(), hitPlayer.GetActorMono(), mHideEffect, src_player.transform.position, src_player.transform.rotation, src_player.transform.forward, OnHit); // 将伤害信息添加到新创建的SkillAttackInstance列表中 SkillAttackInstance attack_inst = EffectManager.GetInstance().GetAttackInstance(m_SubEmitId); if (attack_inst != null) { Damage dmgInfo = null; if (m_DamageInfos.TryGetValue(hit_player_id, out dmgInfo)) { attack_inst.AddHurtInfo(dmgInfo); } } m_HitEmits[hit_player_id] = new HitCacheInfo(m_SubEmitId); m_SubEmitId++; } mLastThunderPlayer = hit_player_id; HitPlayers.RemoveAt(0); } else// 此时表示闪电链的攻击结束了 { Destroy(); } } }
/// <summary> /// 销毁 /// </summary> void Destroy() { SkillAttackInst.DestroyAll(); SkillAttackInst = null; foreach (var bullet_trace in m_TraceInsts) { var skill_attack_id = bullet_trace.SkillAttackId; var attack_instance = EffectManager.Instance.GetAttackInstance(skill_attack_id); if (attack_instance != null) { attack_instance.DestroyAll(); } } m_TraceInsts.Clear(); // 有可能有没有表现的受击效果 foreach (var damg in m_DamageInfos.Values) { if (damg != null) { damg.HitEffect(); } } m_DamageInfos.Clear(); foreach (var item in m_DeathAppendInfos.Values) { if (item != null) { Actor actor = ActorManager.Instance.GetActor(item.Id); if (actor != null) { actor.Kill(); } } } m_DeathAppendInfos.Clear(); m_SkillInfo = null; m_BulletInfo = null; HitPlayers.Clear(); m_HitEmits.Clear(); }
/// <summary> /// 初始化子弹的信息 /// </summary> /// <param name="bulletObject"></param> /// <param name="src"></param> /// <param name="traceTarget"></param> /// <param name="effectId"></param> /// <param name="pos"></param> /// <param name="rotation"></param> /// <param name="dir"></param> /// <param name="hit_callback"></param> void InitBullet(GameObject bullet_object, ActorMono src, ActorMono trace_target, ulong effect_Id, Vector3 pos, Quaternion rotation, Vector3 dir, Action <SkillAttackInstance> hit_callback) { if (trace_target == null || trace_target.BindActor == null) { return; } pos.y += m_BulletInfo.OffsetY; pos += dir * m_BulletInfo.OffsetX; // 前向移动 //GameDebug.Log("EffectId : "+effect_Id); Transform bulletTrans = bullet_object.transform; // 设置子弹的位置和方向 bulletTrans.position = pos; bulletTrans.rotation = rotation; bulletTrans.localScale = Vector3.one; if (m_BulletInfo.BulletType == DBBulletTrace.BulletTypes.BT_BIND) { bulletTrans.parent = src.BindActor.Trans; } var skill_attack_inst = new SkillAttackInstance(); var skill_base = bullet_object.AddComponent <SkillBaseComponent>(); // 初始化 skill_base.Init(skill_attack_inst); skill_attack_inst.Init(effect_Id, src.BindActor.UID, m_SkillInfo, 0, m_BulletInfo.FlyMaxTime, 1.0f, skill_base, hit_callback); // 子弹加到管理器 EffectManager.GetInstance().AddSkillInstance(effect_Id, skill_attack_inst); if (m_BulletInfo.BulletType == DBBulletTrace.BulletTypes.BT_DIRECTION || m_BulletInfo.BulletType == DBBulletTrace.BulletTypes.BT_BIND) { // 绑定追踪组件 TraceTargetComponent trace_target_comp = bullet_object.AddComponent <TraceTargetComponent>(); Vector3 v_dir = Quaternion.Euler(0.0f, 0.0f, 0.0f) * dir; // flyDir要转化到当前运行方向的坐标轴中 bulletTrans.forward = v_dir; trace_target_comp.Init(src, trace_target, m_BulletInfo, skill_attack_inst); skill_base.AddMonoEnableOption(trace_target_comp, true, m_DelayTime); } else if (m_BulletInfo.BulletType == DBBulletTrace.BulletTypes.BT_LINK) { // 绑定追踪组件 StretchComponent traceComp = bullet_object.AddComponent <StretchComponent>(); traceComp.Init(src, trace_target, m_BulletInfo, skill_attack_inst); skill_base.AddMonoEnableOption(traceComp, true, m_DelayTime); } else if (m_BulletInfo.BulletType == DBBulletTrace.BulletTypes.BT_IMMEDIATE) { bulletTrans.parent = trace_target.BindActor.Trans; bulletTrans.localPosition = Vector3.zero; bulletTrans.rotation = Quaternion.identity; bulletTrans.localScale = Vector3.one; bulletTrans.parent = null; // 绑定追踪组件 ImmediateHitComponent traceComp = bullet_object.AddComponent <ImmediateHitComponent>(); traceComp.Init(src, trace_target, m_BulletInfo, skill_attack_inst); skill_base.AddMonoEnableOption(traceComp, true, m_DelayTime); } // 绑子弹音效 if (m_BulletInfo.AttackSound != string.Empty) { var bind_sound = bullet_object.AddComponent <BindSoundComponent>(); bind_sound.enabled = false; bind_sound.Init(m_BulletInfo.AttackSound, false); skill_base.AddMonoEnableOption(bind_sound, true, m_DelayTime); } }
/// <summary> /// 增加SkillAttackInstance /// </summary> public void AddSkillInstance(ulong uiID, SkillAttackInstance kSkillEffect) { mSkillAttackMaps[uiID] = kSkillEffect; }
public static void HandleServerData(ushort protocol, byte[] data) { switch (protocol) { case NetMsg.MSG_NWAR_HIT: // 受击 { var nwar_hit = S2CPackBase.DeserializePack <S2CNwarHit>(data); var actor = ActorManager.Instance.GetPlayer(nwar_hit.hit.dst_id); if (actor != null) { actor.BeattackedCtrl.HandleBeattacked(nwar_hit); } } break; case NetMsg.MSG_NWAR_THUNDER: // 闪电链的伤害 { var nwar_thunder = S2CPackBase.DeserializePack <S2CNwarThunder>(data); SkillAttackInstance attac_inst = EffectManager.GetInstance().GetAttackInstance(nwar_thunder.em_id); if (attac_inst != null) { ThunderHitInfo hit_info = new ThunderHitInfo(); hit_info.ActorID = nwar_thunder.act_id; hit_info.EmitID = nwar_thunder.em_id; //伤害id hit_info.SkillID = nwar_thunder.skill_id; // 技能id hit_info.HitPlayers = nwar_thunder.uuids; //依次打到的玩家列表 hit_info.SkillAttackInst = attac_inst; if (hit_info.Init()) { attac_inst.SetThunderHitInfo(hit_info); } } } break; case NetMsg.MSG_NWAR_UNIT_DEAD: //死亡 { var death_msg = S2CPackBase.DeserializePack <S2CNwarUnitDead>(data); var actor = ActorManager.Instance.GetPlayer(death_msg.id); if (actor != null) { actor.BeattackedCtrl.HandleKillActor(death_msg); } } break; case NetMsg.MSG_NWAR_BUFF_SUB_HP: // buff减血 { var rep = S2CPackBase.DeserializePack <S2CNwarBuffSubHp>(data); Actor act = ActorManager.Instance.GetPlayer(rep.uuid); if (act != null && !act.IsDead()) { act.DoDamage(rep.act_id, (int)rep.hp, 0f, false, 0); } } break; case NetMsg.MSG_NWAR_BUFF_SUB_EN: // buff减蓝 { } break; case NetMsg.MSG_NWAR_BUFF_ADD_HP: // buff加血 { var rep = S2CPackBase.DeserializePack <S2CNwarBuffAddHp>(data); Actor act = ActorManager.Instance.GetPlayer(rep.uuid); if (act != null && !act.IsDead() && act.IsLocalPlayer) { act.ShowDamageEffect(FightEffectHelp.FightEffectType.AddHp, rep.act_id, (int)rep.hp); } } break; case NetMsg.MSG_NWAR_SKILL_SING: //结束吟唱阶段 { var rep = S2CPackBase.DeserializePack <S2CNwarSkillSing>(data); Actor act = ActorManager.Instance.GetPlayer(rep.uuid); if (act != null && !act.IsDead() && act.IsLocalPlayer == false) { Skill skill = act.GetCurSkill(); if (skill != null && skill.SkillID == rep.skill_id) { if (skill.CurAction != null) { skill.CurAction.FinishCastingReadyStage(); } } } } break; case NetMsg.MSG_NWAR_BUFF_IMMUNE: //免疫飘字 { var rep = S2CPackBase.DeserializePack <S2CNwarBuffImmune>(data); Actor defender = ActorManager.Instance.GetActor(rep.uuid); if (defender != null) { defender.ShowDamageEffect(FightEffectHelp.FightEffectType.Immune, rep.act_id, 0); } } break; case NetMsg.MSG_NWAR_BUFF_WORD: //buff飘字效果 { var rep = S2CPackBase.DeserializePack <S2CNwarBuffWord>(data); var word_id = rep.word; string word = DBFlyWord.GetFlyWordById(word_id); if (word != "") { UINotice.Instance.ShowMessage(word); } } break; default: break; } }
/// <summary> /// 响应受击消息 /// </summary> /// <param name="beattackMsg"></param> void HandleBeattacked(S2CNwarHit beattackMsg) { if (!mIsRecvMsg) { return; } DBSkillSev.SkillInfoSev skillInfo = DBSkillSev.Instance.GetSkillInfo(beattackMsg.hit.skill_id); if (skillInfo == null) { GameDebug.LogError(string.Format("[HandleBeattacked]Skill ID:{0} info is null", beattackMsg.hit.skill_id)); return; } Damage dmg = new Damage(); uint src_id = beattackMsg.hit.act_id; Actor actor = ActorManager.Instance.GetPlayer(beattackMsg.hit.act_id); // 本地玩家受击,攻击者在角色列表中找不到的时候,需要给服务端发送look消息(目前AOI有bug) if (actor == null && mOwner != null && mOwner.IsLocalPlayer) { mMissUID.obj_idx = beattackMsg.hit.act_id; var cacheInfo = ActorManager.Instance.GetUnitCacheInfo(mMissUID); if (cacheInfo == null) { var sendLookFix = new C2SNwarLookFix(); sendLookFix.uuid = beattackMsg.hit.act_id; NetClient.GetCrossClient().SendData <C2SNwarLookFix>(NetMsg.MSG_NWAR_LOOK_FIX, sendLookFix); } } if (beattackMsg.hit.ori_type == GameConst.SKILL_ORI_PET) { if (actor != null) { Player player = actor as Player; if (player != null && player.CurrentPet != null) { src_id = player.CurrentPet.obj_idx; } } } dmg.SrcID = src_id; dmg.TargetID = beattackMsg.hit.dst_id; dmg.SkillID = beattackMsg.hit.skill_id; dmg.BeattackState = Damage.EBeattackState.BS_BendBack; dmg.DamageEffectType = beattackMsg.hit.hit_type; dmg.DamageValue = (int)beattackMsg.hit.dmg; dmg.DamageSpecs = new Dictionary <uint, int>(beattackMsg.hit.specs.Count); foreach (var spec in beattackMsg.hit.specs) { dmg.DamageSpecs.Add(spec.k, (int)spec.v); } SkillAttackInstance inst = EffectManager.GetInstance().GetAttackInstance(beattackMsg.hit.em_id); if (inst != null) { inst.AddHurtInfo(dmg); } else { dmg.HitEffect(); } LastAttackerId = beattackMsg.hit.act_id; }