예제 #1
0
    // selects a square to be targeted by the acting unit, might be canceled
    public IEnumerator SelectTargetDirRoutine(Result <EightDir> result,
                                              BattleUnit actingUnit,
                                              List <EightDir> allowedDirs,
                                              bool canCancel = true)
    {
        actor = actingUnit.battler;

        gameObject.SetActive(true);
        actingUnit.battle.cursor.DisableReticules();

        SelectionGrid      grid    = actingUnit.battle.SpawnSelectionGrid();
        TacticsTerrainMesh terrain = actingUnit.battle.map.terrain;

        grid.ConfigureNewGrid(actingUnit.location, 1, terrain, (Vector2Int loc) => {
            return((loc.x + loc.y + actingUnit.location.x + actingUnit.location.y) % 2 < 2);
        }, (Vector2Int loc) => {
            return(allowedDirs.Contains(actingUnit.battler.GetComponent <MapEvent>().DirectionTo(loc)));
        });
        if (allowedDirs.Count > 0)
        {
            AttemptSetDirection(allowedDirs[0]);
        }
        else
        {
            GetComponent <MapEvent>().SetLocation(actor.location);
        }

        while (!result.finished)
        {
            Result <EightDir> dirResult = new Result <EightDir>();
            yield return(AwaitSelectionRoutine(actor, dirResult));

            if (dirResult.canceled)
            {
                if (canCancel)
                {
                    result.Cancel();
                    break;
                }
            }
            else
            {
                result.value = dirResult.value;
            }
        }

        Destroy(grid.gameObject);
        actingUnit.battle.cursor.EnableReticules();
        gameObject.SetActive(false);
    }
예제 #2
0
    protected override IEnumerator InternalExecuteRoutine(Effector effect, Result <bool> result)
    {
        Func <Vector2Int, bool> rangeRule = (Vector2Int loc) => {
            return(Vector2Int.Distance(loc, actor.location) <= radius);
        };

        Vector2Int origin = new Vector2Int(
            (int)actorEvent.positionPx.x - Mathf.CeilToInt(radius),
            (int)actorEvent.positionPx.z - Mathf.CeilToInt(radius));

        SelectionGrid grid = battle.SpawnSelectionGrid();

        grid.ConfigureNewGrid(actor.location, Mathf.CeilToInt(radius), map.terrain, rangeRule, rangeRule);

        Result <Vector2Int> locResult = new Result <Vector2Int>();

        battle.SpawnCursor(actor.location);
        yield return(battle.cursor.AwaitSelectionRoutine(locResult, _ => true, null, loc => {
            return loc == actor.location;
        }));

        battle.DespawnCursor();
        Destroy(grid.gameObject);

        if (locResult.canceled)
        {
            result.Cancel();
        }
        else
        {
            List <Vector2Int> cells = new List <Vector2Int>();
            int r = Mathf.CeilToInt(radius);
            for (int y = locResult.value.y - r; y <= locResult.value.y + r; y += 1)
            {
                for (int x = locResult.value.x - r; x <= locResult.value.x + r; x += 1)
                {
                    Vector2Int cell = new Vector2Int(x, y);
                    if (DefaultSelectRule(effect)(cell))
                    {
                        cells.Add(cell);
                    }
                }
            }
            yield return(effect.ExecuteCellsRoutine(cells));

            result.value = true;
        }
    }
예제 #3
0
    protected override IEnumerator InternalExecuteRoutine(Effector effect, Result <bool> result)
    {
        Cursor        cursor = battle.SpawnCursor(actor.location);
        SelectionGrid grid   = battle.SpawnSelectionGrid();

        Func <Vector2Int, bool> selectRule = (Vector2Int v) => { return(IsSelected(effect, v)); };
        Func <Vector2Int, bool> rangeRule  = (Vector2Int v) => {
            Vector2Int otherLoc = battle.cursor.GetComponent <MapEvent>().location;
            return(map.PointsAlongPath(actor.location, otherLoc).Contains(v));
        };
        Func <Vector2Int, IEnumerator> scanner = (Vector2Int loc) => {
            grid.ConfigureNewGrid(actor.location, range, map.terrain, rangeRule, selectRule);
            return(null);
        };

        if (effect.TargetsHostiles())
        {
            float      minDist  = float.MaxValue;
            BattleUnit bestUnit = null;
            foreach (BattleUnit unit in battle.units)
            {
                float dist = Vector2Int.Distance(unit.location, actor.location);
                cursor.GetComponent <MapEvent>().SetLocation(unit.location);
                if (unit.align != actor.align && dist < minDist && selectRule(unit.location))
                {
                    bestUnit = unit;
                    minDist  = dist;
                }
            }
            if (bestUnit != null)
            {
                cursor.GetComponent <MapEvent>().SetLocation(bestUnit.location);
            }
        }

        Func <Vector2Int, bool> constrainer = loc => Vector2.Distance(loc, actor.location) <= range;

        grid.ConfigureNewGrid(actor.location, range, map.terrain, rangeRule, selectRule);

        Result <Vector2Int> locResult = new Result <Vector2Int>();

        yield return(battle.cursor.AwaitSelectionRoutine(locResult, selectRule, scanner, constrainer));

        battle.DespawnCursor();
        Destroy(grid.gameObject);

        if (locResult.canceled)
        {
            result.Cancel();
        }
        else
        {
            List <Vector2Int> cells = new List <Vector2Int>();
            if (penetrates)
            {
                foreach (Vector2Int v in map.PointsAlongPath(actor.location, locResult.value))
                {
                    if (map.terrain.HeightAt(v) == map.terrain.HeightAt(actor.location))
                    {
                        cells.Add(v);
                    }
                }
            }
            else
            {
                cells.Add(locResult.value);
            }

            yield return(effect.ExecuteCellsRoutine(cells));

            result.value = true;
        }
    }
예제 #4
0
    protected override IEnumerator InternalExecuteRoutine(Effector effect, Result <bool> result)
    {
        Cursor        cursor = battle.SpawnCursor(actor.location);
        SelectionGrid grid   = battle.SpawnSelectionGrid();

        Func <Vector2Int, bool>        selectRule;
        Func <Vector2Int, IEnumerator> scanner   = null;
        Func <Vector2Int, bool>        rangeRule = (Vector2Int loc) => {
            return(Vector2Int.Distance(loc, actor.location) <= range);
        };

        if (radius > 0)
        {
            selectRule = (Vector2Int loc) => {
                return(Vector2Int.Distance(cursor.GetComponent <MapEvent>().location, loc) <= radius);
            };
        }
        else
        {
            selectRule = DefaultSelectRule(effect);
        }
        scanner = (Vector2Int loc) => {
            grid.ConfigureNewGrid(actor.location, range + Mathf.CeilToInt(radius),
                                  map.terrain, rangeRule, selectRule);
            return(null);
        };

        if (effect.TargetsHostiles())
        {
            float      minDist  = float.MaxValue;
            BattleUnit bestUnit = null;
            foreach (BattleUnit unit in battle.units)
            {
                float dist = Vector2Int.Distance(unit.location, actor.location);
                if (unit.align != actor.align && dist < minDist && selectRule(unit.location))
                {
                    bestUnit = unit;
                    minDist  = dist;
                }
            }
            if (bestUnit != null)
            {
                cursor.GetComponent <MapEvent>().SetLocation(bestUnit.location);
            }
        }

        Vector2Int origin = new Vector2Int(
            (int)actorEvent.positionPx.x - (range + Mathf.CeilToInt(radius) - 1),
            (int)actorEvent.positionPx.z - (range + Mathf.CeilToInt(radius) - 1));

        Func <Vector2Int, bool> constrainer = loc => Vector2.Distance(loc, actor.location) <= range;

        grid.ConfigureNewGrid(actor.location, range, map.terrain, rangeRule, selectRule);

        Result <Vector2Int> locResult = new Result <Vector2Int>();

        yield return(battle.cursor.AwaitSelectionRoutine(locResult, _ => true, scanner, constrainer));

        battle.DespawnCursor();
        Destroy(grid.gameObject);

        if (locResult.canceled)
        {
            result.Cancel();
        }
        else
        {
            List <Vector2Int> cells = new List <Vector2Int>();
            int r = Mathf.CeilToInt(radius);
            for (int y = locResult.value.y - r; y <= locResult.value.y + r; y += 1)
            {
                for (int x = locResult.value.x - r; x <= locResult.value.x + r; x += 1)
                {
                    Vector2Int cell = new Vector2Int(x, y);
                    if (Vector2Int.Distance(cell, locResult.value) <= radius)
                    {
                        cells.Add(cell);
                    }
                }
            }
            yield return(effect.ExecuteCellsRoutine(cells));

            result.value = true;
        }
    }