// 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); }
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; } }
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; } }
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; } }