示例#1
0
        public static void Reflect(int percentDamage, Character target)
        {
            if (target.trueOldHealth > target.currentHealth)
            {
                float     damage    = (target.trueOldHealth - target.currentHealth) * (percentDamage / 100f);
                Vector3   pos       = VectorUtility.PositionToInt(target.GetComponent <Transform>().position);
                Vector3[] direction = new Vector3[4] {
                    new Vector3(1f, 0f, 0f), new Vector3(-1f, 0f, 0f),
                    new Vector3(0f, 1f, 0f), new Vector3(0f, -1f, 0f)
                };
                foreach (Vector3 d in direction)
                {
                    GameObject g = Instantiate(GameManager.gm.player.GetComponent <PlayerMover>().distanceSprite,
                                               new Vector3(pos.x + d.x, pos.y + d.y, -0.25f), Quaternion.identity);
                    g.GetComponent <SpriteRenderer>().color = new Color(0.7f, 0.7f, 0.7f, 0.8f);
                    g.GetComponent <DistanceSprite>().Disappear(60);

                    Entity e = GameManager.gm.map.GetEntityOnTile(pos + d);
                    if (e != null && e.GetType().Equals(typeof(Character)) && ((Character)e).type != target.type)
                    {
                        // 진행 방향에 적이 있을 경우
                        Character opponent = (Character)e;
                        opponent.hasReflected     = true;
                        opponent.reflectDamage   += damage;
                        opponent.reflectDirection = d;
                    }
                }
            }
        }
示例#2
0
    /// <summary>
    /// 이동하지 않고 상하좌우로 붙어 있는 플레이어를 공격합니다.
    /// 공격에 성공하면 턴을 넘기고 true를 반환합니다.
    /// 플레이어가 주변에 없으면 턴을 넘기지 않고 false를 반환합니다.
    /// </summary>
    /// <returns></returns>
    private bool AttackWithoutMove()
    {
        bool           isAttacked = false;
        List <Vector3> melee      = new List <Vector3>();

        for (int i = 0; i <= c.EquippedWeapon.Range; i++)
        {
            melee.Add(new Vector3(-1f * i, 0f, 0f));
            melee.Add(new Vector3(1f * i, 0f, 0f));
            melee.Add(new Vector3(0f, -1f * i, 0f));
            melee.Add(new Vector3(0f, 1f * i, 0f));
        }
        foreach (Vector3 v in melee)
        {
            Vector3 destination = GetCurrentPosition() + v;
            if (gm.map.GetEntityOnTile(destination) != null &&
                gm.map.GetEntityOnTile(destination).GetType().Equals(typeof(Character)) &&
                ((Character)gm.map.GetEntityOnTile(destination)).type == Character.Type.Player)
            {
                if (destination.x < GetCurrentPosition().x)
                {
                    GetComponent <SpriteRenderer>().flipX = false;
                }
                else if (destination.x > GetCurrentPosition().x)
                {
                    GetComponent <SpriteRenderer>().flipX = true;
                }
                Attack(VectorUtility.PositionToInt((destination - GetCurrentPosition()).normalized), false);
                isAttacked = true;
                break;
            }
        }
        return(isAttacked);
    }
示例#3
0
        public static void Flurry(int splashDamage, Character target)
        {
            // Flurry 효과는 몬스터의 무기에 적용할 수 없음 (플레이어가 한 명이므로)

            Vector3 pos = VectorUtility.PositionToInt(target.GetComponent <Transform>().position);

            Vector3[] direction = new Vector3[4] {
                new Vector3(1f, 0f, 0f), new Vector3(-1f, 0f, 0f),
                new Vector3(0f, 1f, 0f), new Vector3(0f, -1f, 0f)
            };
            foreach (Vector3 d in direction)
            {
                GameObject g = Instantiate(GameManager.gm.player.GetComponent <PlayerMover>().distanceSprite,
                                           new Vector3(pos.x + d.x, pos.y + d.y, -0.25f), Quaternion.identity);
                g.GetComponent <SpriteRenderer>().color = new Color(0f, 0.8f, 0.8f, 0.8f);
                g.GetComponent <DistanceSprite>().Disappear(60);

                Entity e = GameManager.gm.map.GetEntityOnTile(pos + d);
                if (e != null && e.GetType().Equals(typeof(Character)) && ((Character)e).type == Character.Type.Enemy)
                {
                    // 진행 방향에 플레이어가 있을 경우
                    Character enemy = (Character)e;
                    enemy.gustDamage   += splashDamage;
                    enemy.gustDirection = d;
                }
            }
        }
示例#4
0
 private Vector3 Move(Vector3 destination)
 {
     if (VectorUtility.IsSamePosition(destination, GetCurrentPosition()))
     {
         // 제자리에 머물러 있는 경우 움직이는 애니메이션 없이 턴 넘김
         // 제자리에서 인접한 네 칸 안에 플레이어가 있으면 공격함
         if (!AttackWithoutMove())
         {
             isMoved = true;
         }
         return(destination);
     }
     else if (gm.map.CanMoveToTile(destination))
     {
         // TODO 한 턴에 2칸 이상을 이동하는 경우, 지나는 모든 타일에 대한 고려가 필요함
         if (destination.x < GetCurrentPosition().x)
         {
             GetComponent <SpriteRenderer>().flipX = false;
         }
         else if (destination.x > GetCurrentPosition().x)
         {
             GetComponent <SpriteRenderer>().flipX = true;
         }
         StartCoroutine(MoveAnimation(destination));
         return(destination);
     }
     else if (gm.map.GetTypeOfTile(destination) == 0 && gm.map.GetEntityOnTile(destination) != null &&
              gm.map.GetEntityOnTile(destination).GetType().Equals(typeof(Character)) &&
              ((Character)gm.map.GetEntityOnTile(destination)).type == Character.Type.Player)
     {
         // 진행 방향으로 한 칸 앞에 플레이어가 있는 경우
         if (destination.x < GetCurrentPosition().x)
         {
             GetComponent <SpriteRenderer>().flipX = false;
         }
         else if (destination.x > GetCurrentPosition().x)
         {
             GetComponent <SpriteRenderer>().flipX = true;
         }
         Attack(VectorUtility.PositionToInt((destination - GetCurrentPosition()).normalized), false);  // TODO 택시 거리 1칸이 보장되지 않음
         return(GetCurrentPosition());
     }
     else
     {
         // TODO 일단은 가려고 하는 곳이 갈 수 없는 지형이면 움직이지 않고 턴 넘김
         // 제자리에서 인접한 네 칸 안에 플레이어가 있으면 공격함
         if (!AttackWithoutMove())
         {
             isMoved = true;
         }
         return(GetCurrentPosition());
     }
 }
示例#5
0
    /// <summary>
    /// 순찰 경로를 초기화하는 함수입니다.
    /// </summary>
    /// <param name="checkpoints">들러야 하는 지점의 목록(순서대로)</param>
    private void InitializeCheckpoints(List <Vector3> checkpoints)
    {
        headCheckpoints   = new Stack <Vector3>();
        passedCheckpoints = new Stack <Vector3>();

        passedCheckpoints.Push(GetCurrentPosition());
        if (checkpoints != null)
        {
            for (int i = checkpoints.Count - 1; i >= 0; i--)
            {
                headCheckpoints.Push(VectorUtility.PositionToInt(checkpoints[i]));
            }
        }
    }
示例#6
0
    IEnumerator MoveAnimation(Vector3 destination)
    {
        isMoving = true;
        int     frame  = 18;
        Vector3 origin = t.position;

        // 애니메이션이 시작하기 전에 이동 판정 완료
        gm.map.SetEntityOnTile(null, origin);
        gm.map.SetEntityOnTile(c, destination);
        for (int i = 0; i < frame; i++)
        {
            t.position = Vector3.Lerp(origin, destination, (float)i / frame);
            yield return(null);
        }
        t.position = destination;
        isMoving   = false;
        Attack(VectorUtility.PositionToInt((destination - origin).normalized), true); // TODO 택시 거리 1칸이 보장되지 않음
    }
示例#7
0
 /// <summary>
 /// 현재 이 오브젝트의 위치를 정수 좌표로 반환합니다.
 /// </summary>
 /// <returns></returns>
 private Vector3 GetCurrentPosition()
 {
     return(VectorUtility.PositionToInt(t.position));
 }
示例#8
0
    // Update is called once per frame
    void Update()
    {
        if (gm == null)
        {
            gm = GameManager.gm;
            return;
        }

        if (isDistanceNone)
        {
            if (distanceType == DistanceType.None)
            {
                Debug.LogWarning("Enemy distanceType is None!");
                return;                     // Character의 Initialize에서 설정해 줄 때까지 대기
            }
            else if (distanceType == DistanceType.Manhattan)
            {
                distance      += VectorUtility.ManhattanDistance;
                isDistanceNone = false;
            }
            else if (distanceType == DistanceType.Chebyshev)
            {
                distance      += VectorUtility.ChebyshevDistance;
                isDistanceNone = false;
            }
        }

        if (!gm.IsSceneLoaded)
        {
            return;
        }

        if (gm.Turn == 0 && isMoved)
        {
            isMoved = false;
        }
        else if (gm.Turn == 1 && !isMoving && !isMoved)
        {
            if (c.hasStuned)
            {
                c.hasStuned = false;
                StartCoroutine(StunedAnimation());
                return;
            }
            Vector3 playerPos = VectorUtility.PositionToInt(gm.player.GetComponent <Transform>().position);
            Vector3 destination;

            Discover(playerPos, GetCurrentPosition());

            if (!AttackWithoutMove())
            {
                if (hasTaunted)
                {
                    // 한 번 도발당한 경우 처음 도발당한 위치에서 leaveDistance만큼 멀어지기 전까지 플레이어를 쫓아감
                    // 플레이어가 시야에서 벗어나도 쫓아감
                    destination = Move1Taxi(playerPos);
                    if (distance(tauntedPosition, destination) <= leaveDistance)
                    {
                        destination = Move(destination);
                    }
                    else
                    {
                        // 플레이어가 사라지면 도발 상태가 풀리고 처음 도발당한 위치로 돌아감
                        hasTaunted = false;
                        if (myTauntedSprite != null)
                        {
                            Destroy(myTauntedSprite);
                            myTauntedSprite = null;
                        }
                        if (myDistanceSprite != null)
                        {
                            myDistanceSprite.GetComponent <DistanceSprite>().Disappear();
                            myDistanceSprite = null;
                        }
                        destination = Move1Taxi(tauntedPosition);
                        destination = Move(destination);

                        // 처음 도발당한 위치로 돌아간 경우 정상 경로를 따라 순찰함
                        if (VectorUtility.IsSamePosition(destination, tauntedPosition))
                        {
                            isTauntedPositionValid = false;
                        }
                    }
                }
                else if (isTauntedPositionValid)
                {
                    // 도발 상태가 풀렸지만 아직 처음 도발당한 위치로 돌아가지 못한 경우
                    destination = Move1Taxi(tauntedPosition);
                    destination = Move(destination);

                    // 처음 도발당한 위치로 돌아간 경우 정상 경로를 따라 순찰함
                    if (VectorUtility.IsSamePosition(destination, tauntedPosition))
                    {
                        isTauntedPositionValid = false;
                    }
                }
                else
                {
                    // 시야에 플레이어가 없는 경우 정상 경로를 따라 순찰
                    destination = Move1Taxi(movePattern(), true);
                    destination = Move(destination);
                }

                Discover(playerPos, destination);
            }
        }
    }