예제 #1
0
    public void wander()
    {
        var offset = UnityEngine.Random.Range(0, 4);

        for (var @base = 0; @base < 4; @base += 1)
        {
            var ordinal = (offset + @base) % 4;
            var dir     = (OrthoDir)ordinal;
            if (dir.Px2DX() == 0)
            {
                continue;
            }
            var newPos = mapEvent.Position + dir.XY2D();
            if (mapEvent.Map.IsChipPassableAt(newPos))
            {
                if (Global.Instance().Maps.Avatar.Event.Position == newPos)
                {
                    mapEvent.GetComponent <CharaEvent>().Facing = dir;
                    var context = Global.Instance().Maps.Lua;
                    Run(MapEvent.PropertyLuaCollide);
                    break;
                }
                else if (mapEvent.CanPassAt(newPos) && mapEvent.Map.GetEventAt <MapEvent>(newPos) == null)
                {
                    var context = Global.Instance().Maps.Lua;
                    mapEvent.StartCoroutine(mapEvent.StepRoutine(dir));
                    break;
                }
            }
        }
    }
예제 #2
0
파일: Map.cs 프로젝트: yazici/erebus
    public List <Vector2Int> FindPath(MapEvent actor, Vector2Int to, int maxPathLength)
    {
        if (ManhattanDistance(actor.GetComponent <MapEvent>().position, to) > maxPathLength)
        {
            return(null);
        }
        if (!actor.CanPassAt(to))
        {
            return(null);
        }

        HashSet <Vector2Int>      visited   = new HashSet <Vector2Int>();
        List <List <Vector2Int> > heads     = new List <List <Vector2Int> >();
        List <Vector2Int>         firstHead = new List <Vector2Int>();

        firstHead.Add(actor.GetComponent <MapEvent>().position);
        heads.Add(firstHead);

        while (heads.Count > 0)
        {
            heads.Sort(delegate(List <Vector2Int> pathA, List <Vector2Int> pathB) {
                int pathACost = pathA.Count + ManhattanDistance(pathA[pathA.Count - 1], to);
                int pathBCost = pathB.Count + ManhattanDistance(pathB[pathB.Count - 1], to);
                return(pathACost.CompareTo(pathBCost));
            });
            List <Vector2Int> head = heads[0];
            heads.RemoveAt(0);
            Vector2Int at = head[head.Count - 1];

            if (at == to)
            {
                // trim to remove the current location from the beginning
                return(head.GetRange(1, head.Count - 1));
            }

            if (head.Count < maxPathLength)
            {
                foreach (OrthoDir dir in Enum.GetValues(typeof(OrthoDir)))
                {
                    Vector2Int next = head[head.Count - 1];
                    // minor perf here, this is critical code
                    switch (dir)
                    {
                    case OrthoDir.East:     next.x += 1;    break;

                    case OrthoDir.North:    next.y += 1;    break;

                    case OrthoDir.West:     next.x -= 1;    break;

                    case OrthoDir.South:    next.y -= 1;    break;
                    }
                    if (!visited.Contains(next) && actor.CanPassAt(next) &&
                        (actor.GetComponent <CharaEvent>() == null ||
                         actor.CanPassAt(next)) &&
                        (actor.GetComponent <CharaEvent>() == null ||
                         actor.GetComponent <CharaEvent>().CanCrossTileGradient(at, next)))
                    {
                        List <Vector2Int> newHead = new List <Vector2Int>(head)
                        {
                            next
                        };
                        heads.Add(newHead);
                        visited.Add(next);
                    }
                }
            }
        }

        return(null);
    }
예제 #3
0
    public void StepOrAttack(EightDir dir, Result <bool> executeResult)
    {
        MapEvent   parent  = me;
        Vector2Int vectors = me.location;
        Vector2Int target  = vectors + dir.XY();

        GetComponent <CharaEvent>().facing = dir;
        List <MapEvent> targetEvents = me.map.GetEventsAt(target);

        if (!GetComponent <BattleEvent>().CanCrossTileGradient(parent.location, target))
        {
            executeResult.value = false;
            return;
        }

        List <MapEvent> toCollide = new List <MapEvent>();
        bool            passable  = parent.CanPassAt(target);

        foreach (MapEvent targetEvent in targetEvents)
        {
            toCollide.Add(targetEvent);
            passable &= targetEvent.IsPassableBy(parent);
        }

        if (passable)
        {
            chara.PerformWhenDoneAnimating(me.StepRoutine(location, location + dir.XY(), false));
            me.location = target;
            if (unit.Get(StatTag.MOVE) > 1)
            {
                unit.canActAgain = !unit.canActAgain;
            }
            else if (unit.Get(StatTag.MOVE) < 1)
            {
                unit.isRecovering = true;
            }
            if (GetComponent <PCEvent>() != null)
            {
                foreach (MapEvent targetEvent in toCollide)
                {
                    if (targetEvent.switchEnabled)
                    {
                        StartCoroutine(CoUtils.RunWithCallback(targetEvent.CollideRoutine(GetComponent <PCEvent>()),
                                                               () => {
                            executeResult.value = true;
                        }));
                        return;
                    }
                }
            }
            executeResult.value = true;
            return;
        }
        else
        {
            foreach (MapEvent targetEvent in toCollide)
            {
                float h1 = unit.battle.map.terrain.HeightAt(location);
                float h2 = unit.battle.map.terrain.HeightAt(target);
                //if (GetComponent<PCEvent>() != null) {
                //    if (targetEvent.switchEnabled && !targetEvent.IsPassableBy(parent)
                //            && Mathf.Abs(h1 - h2) <= AttackHeightMax) {
                //        StartCoroutine(CollideRoutine(GetComponent<PCEvent>());
                //    }
                //}
                if (targetEvent.GetComponent <BattleEvent>() != null)
                {
                    BattleEvent other = targetEvent.GetComponent <BattleEvent>();
                    if (unit.align != other.unit.align)
                    {
                        if (Mathf.Abs(h1 - h2) > AttackHeightMax)
                        {
                            if (GetComponent <PCEvent>() != null)
                            {
                                unit.battle.Log("Too high up to attack!");
                            }
                            executeResult.value = false;
                            return;
                        }
                        else
                        {
                            unit.MeleeAttack(other.unit);
                            executeResult.value = true;
                            return;
                        }
                    }
                }
                // 7drl antipattern hack alert
                if (GetComponent <PCEvent>() != null && targetEvent.GetComponent <ChestEvent>() != null)
                {
                    ChestEvent chest = targetEvent.GetComponent <ChestEvent>();
                    if (!chest.opened)
                    {
                        StartCoroutine(CoUtils.RunWithCallback(chest.OpenRoutine(GetComponent <PCEvent>()), () => {
                            executeResult.value = true;
                        }));
                        return;
                    }
                }
            }
        }
        executeResult.value = false;
    }
예제 #4
0
    public List <Vector2Int> FindPath(MapEvent actor, Vector2Int to, int maxPathLength)
    {
        if (Vector2.Distance(actor.GetComponent <MapEvent>().location, to) * Mathf.Sqrt(2) > maxPathLength)
        {
            return(null);
        }
        if (!IsChipPassableAt(layers[0], to))
        {
            return(null);
        }

        HashSet <Vector2Int>      visited   = new HashSet <Vector2Int>();
        List <List <Vector2Int> > heads     = new List <List <Vector2Int> >();
        List <Vector2Int>         firstHead = new List <Vector2Int>();

        firstHead.Add(actor.GetComponent <MapEvent>().location);
        heads.Add(firstHead);

        while (heads.Count > 0)
        {
            heads.Sort(delegate(List <Vector2Int> pathA, List <Vector2Int> pathB) {
                int pathACost = pathA.Count + ManhattanDistance(pathA[pathA.Count - 1], to);
                int pathBCost = pathB.Count + ManhattanDistance(pathB[pathB.Count - 1], to);
                return(pathACost.CompareTo(pathBCost));
            });
            List <Vector2Int> head = heads[0];
            heads.RemoveAt(0);
            Vector2Int at = head[head.Count - 1];

            if (at == to)
            {
                // trim to remove the current location from the beginning
                return(head.GetRange(1, head.Count - 1));
            }

            if (head.Count < maxPathLength)
            {
                foreach (EightDir dir in Enum.GetValues(typeof(EightDir)))
                {
                    Vector2Int next = head[head.Count - 1];
                    // minor perf here, this is critical code
                    switch (dir)
                    {
                    case EightDir.N:    next.y += 1;                    break;

                    case EightDir.E:    next.x += 1;                    break;

                    case EightDir.S:    next.y -= 1;                    break;

                    case EightDir.W:    next.x -= 1;                    break;

                    case EightDir.NE:   next.y += 1;    next.x += 1;    break;

                    case EightDir.SE:   next.y -= 1;    next.x += 1;    break;

                    case EightDir.SW:   next.y -= 1;    next.x -= 1;    break;

                    case EightDir.NW:   next.y += 1;    next.x -= 1;    break;
                    }
                    if (visited.Contains(next))
                    {
                        continue;
                    }
                    if (next != to && !actor.CanPassAt(next))
                    {
                        continue;
                    }
                    if (actor.GetComponent <BattleEvent>() != null && !actor.GetComponent <BattleEvent>().CanCrossTileGradient(at, next))
                    {
                        continue;
                    }
                    if (next == to && Mathf.Abs(terrain.HeightAt(at) - terrain.HeightAt(to)) > BattleEvent.AttackHeightMax)
                    {
                        continue;
                    }
                    if (next != to && (GetEventAt <BattleEvent>(next) != null && GetEventAt <BattleEvent>(next).unit.IsDead()))
                    {
                        continue;
                    }
                    List <Vector2Int> newHead = new List <Vector2Int>(head)
                    {
                        next
                    };
                    heads.Add(newHead);
                    visited.Add(next);
                }
            }
        }

        return(null);
    }