예제 #1
0
        protected virtual void UpdateSkill()
        {
            if (_coolTick == 0)
            {
                // 유효한 타겟인지
                if (_target == null || _target.Room != Room)
                {
                    _target = null;
                    State   = CreatureState.Moving;
                    BroadcastMove();
                    return;
                }

                // 스킬이 아직 사용 가능한지
                Vector2Int dir         = (_target.CellPos - CellPos);
                int        dist        = dir.cellDistFromZero;
                bool       canUseSkill = (dist <= _skillRange && (dir.x == 0 || dir.y == 0));
                if (canUseSkill == false)
                {
                    State = CreatureState.Moving;
                    BroadcastMove();
                    return;
                }

                // 타게팅 방향 주시
                MoveDir lookDir = GetDirFromVector(dir);
                if (Dir != lookDir)
                {
                    Dir = lookDir;
                    BroadcastMove();
                }

                Skill skillData = null;
                DataManager.SkillDict.TryGetValue(1, out skillData);

                // 데미지 판정
                _target.OnDamaged(this, skillData.damage + TotalAttack);

                // 스킬 사용 Broadcast
                S_Skill skill = new S_Skill()
                {
                    Info = new SkillInfo()
                };
                skill.ObjectId     = Id;
                skill.Info.SkillId = skillData.id;
                Room.Broadcast(CellPos, skill);

                // 스킬 쿨타임 적용
                int coolTick = (int)(1000 * skillData.cooldown);
                _coolTick = Environment.TickCount64 + coolTick;
            }

            if (_coolTick > Environment.TickCount64)
            {
                return;
            }

            _coolTick = 0;
        }
예제 #2
0
        // C_Skill
        public void HandleSkill(Player player, C_Skill skillPacket)
        {
            if (player == null)
            {
                return;
            }

            ObjectInfo info = player.Info;

            if (info.PosInfo.State != CreatureState.Idle)
            {
                return;
            }

            // TODO : 스킬 사용가능한지 검증


            // 통과
            info.PosInfo.State = CreatureState.Skill;

            S_Skill skill = new S_Skill()
            {
                Info = new SkillInfo()
            };

            skill.ObjectId     = info.ObjectId;
            skill.Info.SkillId = skillPacket.Info.SkillId; // 유저가 보내준 스킬
            Broadcast(player.CellPos, skill);

            Data.Skill skillData = null;
            if (DataManager.SkillDict.TryGetValue(skill.Info.SkillId, out skillData) == false)
            {
                return;
            }

            // 스킬 종류에 따른 로직
            switch (skillData.skillType)
            {
            case SkillType.SkillAuto:     // 평타
                                          // 데미지 판정
                Vector2Int skillPos = player.GetFrontCellPos(info.PosInfo.MoveDir);
                GameObject target   = Map.Find(skillPos);
                if (target != null)
                {
                    this.Push(target.OnDamaged, player, player.Info.StatInfo.Attack);
                }
                break;

            case SkillType.SkillProjectile:     // 투사체
                SpawnProjectile(player, skillData);
                break;

            case SkillType.SkillNone:
                break;

            default:
                return;
            }
        }
예제 #3
0
    public static void S_SkillHandler(PacketSession session, IMessage packet)
    {
        S_Skill skillPacket = packet as S_Skill;

        GameObject go = Managers.Object.FindById(skillPacket.ObjectId);

        if (go == null)
        {
            return;
        }

        CreatureController cc = go.GetComponent <CreatureController>();

        if (cc != null)
        {
            cc.UseSkill(skillPacket.Info.SkillId);
        }
    }
예제 #4
0
    public static void S_SkillHandler(PacketSession session, IMessage packet)
    {
        S_Skill skillPacket = packet as S_Skill;

        // 여기서 찾은 PlayerId가 꼭 나라는 보장은 없다. 스킬은 아무나 쓰니깐
        GameObject go = Managers.Object.FindById(skillPacket.ObjectId);

        if (go == null)
        {
            return;
        }

        // 정보를 고치기 위해 CreatureController에 접근
        CreatureController pc = go.GetComponent <CreatureController>();

        if (pc != null)
        {
            pc.UseSkill(skillPacket.Info.SkillId);
        }
    }
        public void HandleSkill(Player player, C_Skill skillPacket)
        {
            if (player == null)
            {
                return;
            }

            ObjectInfo info = player.Info;

            if (info.PosInfo.State != CreatureState.Idle)
            {
                return;
            }

            // TODO : 스킬 사용 가능 여부 체크
            info.PosInfo.State = CreatureState.Skill;
            S_Skill skill = new S_Skill()
            {
                Info = new SkillInfo()
            };

            skill.ObjectId     = info.ObjectId;
            skill.Info.SkillId = skillPacket.Info.SkillId;
            Broadcast(skill);

            Data.Skill skillData = null;
            if (DataManager.SkillDict.TryGetValue(skillPacket.Info.SkillId, out skillData) == false)
            {
                return;
            }

            switch (skillData.skillType)
            {
            case SkillType.SkillAuto:
            {
                Vector2Int skillPos = player.GetFrontCellPos(info.PosInfo.MoveDir);
                GameObject target   = Map.Find(skillPos);
                if (target != null)
                {
                    Console.WriteLine("Hit GameObject !");
                }
            }
            break;

            case SkillType.SkillProjectile:
            {
                Arrow arrow = ObjectManager.Instance.Add <Arrow>();
                if (arrow == null)
                {
                    return;
                }

                arrow.Owner           = player;
                arrow.Data            = skillData;
                arrow.PosInfo.State   = CreatureState.Moving;
                arrow.PosInfo.MoveDir = player.PosInfo.MoveDir;
                arrow.PosInfo.PosX    = player.PosInfo.PosX;
                arrow.PosInfo.PosY    = player.PosInfo.PosY;
                arrow.Speed           = skillData.projectile.speed;
                Push(EnterGame, arrow);
            }
            break;
            }
        }
예제 #6
0
 public static void S_SkillHandler(PacketSession session, IMessage packet) // 무언가 스킬 사용
 {
     S_Skill skillPacket = packet as S_Skill;
 }
예제 #7
0
        protected virtual void UpdateSkill()
        {
            // _coolTick이 0이라는것은 스킬 사용할 준비가 완료됐음을 뜻함
            if (_coolTick == 0)
            {
                // 유효한 타겟인지 체크
                if (_target == null || _target.Room != Room || _target.Hp == 0)
                {
                    _target = null;
                    State   = CreatureState.Moving;
                    BroadcastMove(); // 좀 비효율적이지만..
                    return;
                }

                // 스킬이 아직 사용 가능한지
                Vector2Int dir         = (_target.CellPos - CellPos);
                int        dist        = dir.cellDistFromZero;
                bool       canUseSkill = (dist <= _skillRange && (dir.x == 0 || dir.y == 0));
                if (canUseSkill == false)
                {
                    // 스킬을 사용할 수 없는 상태가 됨
                    // 플레이어가 도망가거나 게임 자체를 나가거나 할 때 그걸 다시 쫓을지는 Moving 상태에서 판단
                    State = CreatureState.Moving;
                    BroadcastMove();
                    return;
                }

                // 타게팅 방향 주시
                MoveDir lookDir = GetDirFromVec(dir); // 상대방 - 내위치 = 내가 상대방을 바라보는 방향
                if (Dir != lookDir)
                {
                    Dir = lookDir;   // 모가지를 돌리고
                    BroadcastMove(); // 알림
                }

                Skill skillData = null;
                // 몬스터 시트를 따로 빼서 몬스터에 연결된 스킬과 아이디를 맵핑
                DataManager.SkillDict.TryGetValue(1, out skillData);

                // 데미지 판정
                _target.OnDamaged(this, skillData.damage + Stat.Attack);

                // 스킬 사용 Broadcast
                S_Skill skill = new S_Skill()
                {
                    Info = new SkillInfo()
                };
                skill.ObjectId     = Id;
                skill.Info.SkillId = skillData.id;
                Room.Broadcast(skill); // 몹이 스킬을 쓴다고 알림

                // 스킬 쿨타임 시작
                int coolTick = (int)(1000 * skillData.cooldown); // 단위 ms임
                _coolTick = Environment.TickCount64 + coolTick;  // 다음 tick 시간 구함
            }

            // 다시 스킬을 사용할 준비가 됐는지 여부
            if (_coolTick > Environment.TickCount64)
            {
                return;
            }

            // 햇갈릴수도 있겠네
            _coolTick = 0; //_coolTick이 0이면 스킬사용 준비가 됐다는 뜻이다.
        }
예제 #8
0
        // GameRoom의 JobSerilizer에 의해 실행되기 때문에 EnterGame같은거 직접 불러도 됨
        public void HandleSkill(Player player, C_Skill skillPacket)
        {
            if (player == null) // player가 지금 GameRoom에 소속되었는지도 체크
            {
                return;
            }

            // 스킬분기처리.. 몇 개 없다는 가정하에
            // 스킬이 많아지면 Skill 클래스를 따로 파서 플레이어에 주입하는게 낫다

            ObjectInfo info = player.Info;

            if (info.PosInfo.State != CreatureState.Idle)
            {
                return;
            }

            // 스킬 사용 가능 여부 체크

            // 스킬 애니메이션 맞춰주는 부분
            info.PosInfo.State = CreatureState.Skill;
            S_Skill skill = new S_Skill()
            {
                Info = new SkillInfo()
            };                                                        // info도 클래스임

            skill.ObjectId     = info.ObjectId;
            skill.Info.SkillId = skillPacket.Info.SkillId; // 나중에 시트로 뺄거야
            Broadcast(skill);                              // 에코서버마냥 전파한다

            // 이제 DB에서 Id에 해당하는 스킬데이터를 뽑아온다
            Data.Skill skillData = null;
            if (DataManager.SkillDict.TryGetValue(skillPacket.Info.SkillId, out skillData) == false)
            {
                return;
            }

            // id에 해당하는 스킬이 있다
            switch (skillData.skillType)
            {
            case SkillType.SkillAuto:
            {
                // 주먹질
                // 데미지 판정 -> 항상 치팅 대비
                // 내 공격방향에 적이 있나 없나 체크
                // GetFrontCellPos에 MoveDir.None 처리가 없으니
                // 항상 공격자의 위치를 반환해서 아무대나 떄려도 타격이 되는 문제가 있었음
                // MoveDir.None이 그냥 키입력 여부를 받는거라 서버에는 필요없으므로 전체적으로 없애기로함
                Vector2Int skillPos = player.GetFrontCellPos(info.PosInfo.MoveDir);
                GameObject target   = Map.Find(skillPos);
                if (target != null)
                {
                    Console.WriteLine("Hit GameObject!");
                }
            }
            break;

            case SkillType.SkillProjectile:
            {
                // 화살 생성
                // 클라에서도 화살이 날아가는것을 계산하고 있어야 치팅을 방지할수 있다.
                // 어떤 투사체인지 구분할수 있는게 필요 (지금은 화살만..)
                Arrow arrow = ObjectManager.Instance.Add <Arrow>();
                if (arrow == null)
                {
                    return;
                }

                // 데이터 대입
                arrow.Owner           = player;
                arrow.Data            = skillData; // 투사체를 생성한 주체(스킬)의 정보를 저장
                arrow.PosInfo.State   = CreatureState.Moving;
                arrow.PosInfo.MoveDir = player.PosInfo.MoveDir;
                arrow.PosInfo.PosX    = player.PosInfo.PosX;
                arrow.PosInfo.PosY    = player.PosInfo.PosY;
                arrow.Speed           = skillData.projectile.speed;
                // 직접 불러서 해도 전혀 문제없긴함 EnterGame(arrow)
                Push(EnterGame, arrow);         // 치팅방지 + 코드재사용(화살이 생성됐음을 모두에게 알림)
            }
            break;
            }
        }