Exemplo n.º 1
0
    public static void ActiveSkill(AbilityData _ability, Unit _Caster, bool normal = false)
    {
        //if (SkillDebugMode && _Caster.UnitType == UnitType.Unit && SimulationGameInfo.SimulationGameCheck)
        //    Debug.Log("ActiveSkill  applyTarget " + _ability.applyTarget + " , skillIdx " + _ability.skillIdx + " , notiIdx " + _ability.notiIdx);

        if (_ability.applyTarget == 0)// 나만
        {
            if (_Caster.Usable)
            {
                ApplySkill((SkillType)_ability.skillType, _ability, _Caster, _Caster, normal);
            }
        }
        else if (_ability.applyTarget == 2)  //< 논타겟(발사체에서 주로사용)
        {
            ApplySkill((SkillType)_ability.skillType, _ability, _Caster, null, normal);
        }
        else //< 그외 모두
        {
            ushort radius = 0;

            radius = (ushort)(_ability.radius);/* + _LowDataMgr.GetSkillAction(_ability.Idx).range)*/

            //< 뭐든간에 프로젝트타일이라면 조금더 늘려줌
            if ((SkillType)_ability.skillType == SkillType.Projecttile)
            {
                radius += (ushort)((float)radius * 2);
            }

            //< 조건이 되는 모든 리스트를 구한다.
            List <SelectUnitData> _SelectUnitDatas = new List <SelectUnitData>();
            List <Unit>           targetList       = GetTargetList(_ability.applyTarget, _Caster);
            for (int i = 0; i < targetList.Count; i++)
            {
                //< 각도 체크
                if (_ability.angle > 0 && _ability.angle <= 360)
                {
                    if (SceneManager.instance.IsRTNetwork && (SkillType)_ability.skillType == SkillType.Projecttile)
                    {
                        //네트워크 임시 프로젝타일
                        if (!MathHelper.InAngle(_Caster.transform.forward.normalized, _Caster.transform.position, targetList[i].transform.position, 60))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (!MathHelper.InAngle(_Caster.transform.forward.normalized, _Caster.transform.position, targetList[i].transform.position, _ability.angle))
                        {
                            continue;
                        }
                    }
                }

                //< 범위 체크
                //if (_ability.radius > 0)
                if (radius > 0)
                {
                    if (!MathHelper.IsInRange((targetList[i].transform.position - _Caster.transform.position), radius, _Caster.Radius, targetList[i].Radius))
                    {
                        continue;
                    }
                }

                SelectUnitData newData = new SelectUnitData();
                newData.magnitude = (targetList[i].transform.position - _Caster.transform.position).magnitude;
                newData.Owner     = targetList[i];
                _SelectUnitDatas.Add(newData);
            }

            //< 제일 가까운 대상에게 사용한다.
            int limitTarget = _ability.targetCount == 0 ? 100 : (int)_ability.targetCount;

            //< 이펙트스킬이라면 이펙트카운트로 대입
            if ((SkillType)_ability.skillType == SkillType.EffectSkill)
            {
                limitTarget = _ability.eCount;
            }

            //멀티플레이가 아닐때만 여기서 처리 - 멀티플레이일경우 미스처리는 서버에서 한다
            if (!SceneManager.instance.IsRTNetwork)
            {
                //일단 버프는 빗나가지않게만 처리 나중에 어케할지결정
                if (_ability.callBuffIdx == 0)
                {
                    //선택된애들중에 명중률 계산해서 미스나면 삭제
                    for (int i = _SelectUnitDatas.Count - 1; i >= 0; i--)
                    {
                        //float HitRate = _Caster.CharInfo.HitRate - _SelectUnitDatas[i].Owner.CharInfo.DodgeRate;
                        //bool isHit = (HitRate * 0.01f) >= Random.value;

                        // ( (피격자의 회피 수치 – 공격자의 명중 수치) * Evade_f.Value1_f / (공격자의 명중 수치) ) + Evade_f.Value2_f
                        // 만약 (피격자의 회피 수치 – 공격자의 명중 수치) < 0일때 0을 취함.
                        // 만약 회피 확률 < 0 일때,회피 확율 = 0
                        // 만약 회피 확률 > EvadeC_f.Value1_f 일떄 회피확률 = EvadeC_f.Value1_f
                        // 2017.8.24. kyh

                        //새 명중률 계산
                        float DodgeRate = 0;
                        if (_SelectUnitDatas[i].Owner.CharInfo.DodgeRate - _Caster.CharInfo.HitRate < 0)
                        {
                            DodgeRate = 0;
                        }
                        else
                        {
                            // old
                            //DodgeRate = ((_SelectUnitDatas[i].Owner.CharInfo.DodgeRate - _Caster.CharInfo.HitRate) / (500 + _Caster.CharInfo.HitRate));
                            // new
                            // ( (피격자의 회피 수치 – 공격자의 명중 수치) * Evade_f.Value1_f / (공격자의 명중 수치) ) + Evade_f.Value2_f
                            // 2017.8.24. kyh
                            float evade1 = _LowDataMgr.instance.GetFormula(FormulaType.EVADE, 1);
                            float evade2 = _LowDataMgr.instance.GetFormula(FormulaType.EVADE, 2);
                            DodgeRate = ((_SelectUnitDatas[i].Owner.CharInfo.DodgeRate - _Caster.CharInfo.HitRate) * evade1 / _Caster.CharInfo.HitRate) + evade2;
                        }

                        if (DodgeRate > _LowDataMgr.instance.GetFormula(FormulaType.EVADE_CAP, 1))
                        {
                            DodgeRate = _LowDataMgr.instance.GetFormula(FormulaType.EVADE_CAP, 1);
                        }

                        bool isEvade = DodgeRate >= Random.value;

                        //회피했다
                        if (isEvade)
                        {
                            //현재 값을 지우고 머리위에 회피를 띄우자
                            G_GameInfo.GameInfo.BoardPanel.ShowBuff(_SelectUnitDatas[i].Owner.gameObject, _Caster.gameObject, _LowDataMgr.instance.GetStringCommon(21));
                            _SelectUnitDatas.Remove(_SelectUnitDatas[i]);
                        }
                    }
                }
            }

            _SelectUnitDatas.Sort(delegate(SelectUnitData tmp1, SelectUnitData tmp2) { return(tmp1.magnitude.CompareTo(tmp2.magnitude)); });

            List <Unit> targetResult = new List <Unit>();

            //타겟제한에 따라 공격을 하니 네트워크 모드 일경우 여기부터 리스트를 뽑아서 따로 보내주자
            for (int i = 0; i < _SelectUnitDatas.Count; i++)
            {
                //if (SceneManager.isRTNetworkMode == GAME_MODE.FREEFIGHT)
                if (SceneManager.instance.IsRTNetwork)
                {
                    targetResult.Add(_SelectUnitDatas[i].Owner); //<---단순 리스트만 받아간다.
                }
                else
                {
                    //< 스킬 사용
                    ApplySkill((SkillType)_ability.skillType, _ability, _Caster, _SelectUnitDatas[i].Owner, normal);
                }

                limitTarget--;
                if (limitTarget <= 0)
                {
                    break;
                }
            }

            if (SceneManager.instance.IsRTNetwork)
            {
                //멀티플레이이고 이게 내 유닛이라면 서버로 데미지 계산 요청
                if (_Caster.m_rUUID == G_GameInfo.PlayerController.Leader.m_rUUID || _Caster.IsPartner == true && _Caster.TeamID == G_GameInfo.PlayerController.Leader.TeamID)
                {
                    if (targetResult.Count == 0)
                    {
                        return;
                    }

                    List <Sw.TargetInfo> targets = new List <Sw.TargetInfo>();
                    targets.Clear();

                    for (int i = 0; i < targetResult.Count; i++)
                    {
                        var Target = new Sw.TargetInfo();

                        if (targetResult[i].UnitType == UnitType.Npc || targetResult[i].UnitType == UnitType.Boss)
                        {
                            Target.UnTargetType = (int)Sw.ROLE_TYPE.ROLE_TYPE_NPC;
                        }
                        else if (targetResult[i].UnitType == UnitType.Unit && !targetResult[i].IsPartner)
                        {
                            Target.UnTargetType = (int)Sw.ROLE_TYPE.ROLE_TYPE_USER;
                        }
                        else if (targetResult[i].UnitType == UnitType.Unit && targetResult[i].IsPartner)
                        {
                            Target.UnTargetType = (int)Sw.ROLE_TYPE.ROLE_TYPE_HERO;
                        }

                        Target.UllTargetId = (long)targetResult[i].m_rUUID;

                        Vector3 my     = _Caster.cachedTransform.position;
                        Vector3 target = targetResult[i].transform.position;
                        my.y = target.y = 0;

                        Vector3 pushingDir = (target - my).normalized * 3f; //(transform.position - attackerGO.transform.position).normalized;
                        target = target + pushingDir;

                        Vector3 MinPos = NaviTileInfo.instance.GetMinPos();
                        Target.UnPosX = (int)(Mathf.Abs(MinPos.x - target.x) / NaviTileInfo.instance.GetTileSize());
                        Target.UnPosY = (int)(Mathf.Abs(MinPos.z - target.z) / NaviTileInfo.instance.GetTileSize());
                        Target.UnPush = 1;

                        targets.Add(Target);
                    }

                    //어택일경우는 데미지 체크를 보냄
                    if ((SkillType)_ability.skillType == SkillType.Attack || (SkillType)_ability.skillType == SkillType.AttackBuff)
                    {
                        //데미지일 경우
                        //iFunClient.instance.ReqDamage(_Caster.m_rUUID, _LowDataMgr.GetSkillAction(_ability.Idx).idx, _ability.notiIdx, _Caster.transform.position, _Caster.transform.eulerAngles.y, a_list);
                        NetworkClient.instance.SendPMsgRoleAttackC((int)_LowDataMgr.GetSkillAction(_ability.Idx).idx, 0, (int)_ability.notiIdx, 1, ref targets);
                    }
                    else if ((SkillType)_ability.skillType == SkillType.Projecttile)
                    {
                        //프로젝타일 일경우
                        //iFunClient.instance.ReqDamage(_Caster.m_rUUID, _LowDataMgr.GetSkillAction(_ability.Idx).idx, _ability.notiIdx, _Caster.transform.position, _Caster.transform.eulerAngles.y, a_list);
                    }
                    else if ((SkillType)_ability.skillType == SkillType.Buff)
                    {
                        //버프일 경우
                        //iFunClient.instance.ReqBuff(_Caster.m_rUUID, _LowDataMgr.GetSkillAction(_ability.Idx).idx, _ability.notiIdx);
                    }
                    else if ((SkillType)_ability.skillType == SkillType.EffectSkill)
                    {
                        //장판스킬일경우 - 없다는데 봐야알지
                    }
                    else if ((SkillType)_ability.skillType == SkillType.Heal)
                    {
                        //힐스킬일경우 - 없다는데 봐야알지
                    }
                }
            }
        }
    }
Exemplo n.º 2
0
    //< 범위안에 모든적을 공격한다.
    void AllTakeDamage(bool targetCountCheck = true)
    {
        Vector3 a_TargetPos;
        Vector3 a_ArrowPos = ModelObj.transform.position;

        byte        targetCount = (byte)(projectileInfo.penetrateCount == 0 ? (byte)50 : projectileInfo.penetrateCount);
        float       radius      = projectileInfo.radius;
        List <Unit> targets     = G_GameInfo.CharacterMgr.liveList_All((byte)(Owner.TeamID == 0 ? 1 : 0));

        for (int j = 0; j < targets.Count; j++)
        {
            if (targets[j] == null || targets[j].IsDie)
            {
                continue;
            }

            //< 범위안에 있을경우 대미지!
            a_TargetPos  = targets[j].transform.position;
            a_ArrowPos.y = a_TargetPos.y = 0;

            if ((a_TargetPos - a_ArrowPos).magnitude < radius)
            {
                Explode(targets[j]);

                if (targetCountCheck)
                {
                    targetCount--;
                    if (targetCount == 0)
                    {
                        break;
                    }
                }
            }
        }
        if (SceneManager.instance.IsRTNetwork && (Owner.m_rUUID == NetData.instance._userInfo._charUUID))
        {
            //묶어서 여기에서 보냄
            List <Sw.TargetInfo> targetdata = new List <Sw.TargetInfo>();
            targetdata.Clear();

            for (int i = 0; i < netDamageList.Count; i++)
            {
                var Target = new Sw.TargetInfo();

                if (netDamageList[i].UnitType == UnitType.Npc || netDamageList[i].UnitType == UnitType.Boss)
                {
                    Target.UnTargetType = (int)Sw.ROLE_TYPE.ROLE_TYPE_NPC;
                }
                else if (netDamageList[i].UnitType == UnitType.Unit && !netDamageList[i].IsPartner)
                {
                    Target.UnTargetType = (int)Sw.ROLE_TYPE.ROLE_TYPE_USER;
                }
                else if (netDamageList[i].UnitType == UnitType.Unit && netDamageList[i].IsPartner)
                {
                    Target.UnTargetType = (int)Sw.ROLE_TYPE.ROLE_TYPE_HERO;
                }

                Target.UllTargetId = (long)netDamageList[i].m_rUUID;

                targetdata.Add(Target);
            }

            //어택일경우는 데미지 체크를 보냄
            //if ((SkillType)abilityData.skillType == SkillType.Attack)
            {
                //데미지일 경우
                NetworkClient.instance.SendPMsgRoleAttackC((int)_LowDataMgr.GetSkillAction(abilityData.Idx).idx, 0, (int)abilityData.notiIdx, 1, ref targetdata, (long)ProjectTileId);
            }

            targetdata.Clear();

            //일단 데미지를 줬으니 리셋
            netDamageList.Clear();
        }
    }