public override void ProcessExternalInputWhileHeld(Vector3 inputPosition) { base.ProcessExternalInputWhileHeld(inputPosition); int targetLine = -1; Vector3Int flatTileCoordinate = grid.GetFlatTileCoordinateAtPosition(inputPosition); if (Mathf.Sign(flatTileCoordinate.x) != Mathf.Sign(flatTileCoordinate.z) && flatTileCoordinate.x < Battle.main.defender.board.tiles.GetLength(0) - 1 && flatTileCoordinate.z < Battle.main.defender.board.tiles.GetLength(1) - 1) { if (flatTileCoordinate.x >= 0) { targetLine = flatTileCoordinate.x; } else { targetLine = flatTileCoordinate.z + (Battle.main.defender.board.tiles.GetLength(0) - 1); } } else { targetLine = -1; } if (effect == null) { if (targetLine >= 0) { effect = Effect.CreateEffect(typeof(AircraftRecon)); effect.visibleTo = Battle.main.attacker; effect.targetedPlayer = Battle.main.defender; } else { hookedPosition = Utilities.GetPositionOnElevationFromPerspective(inputPosition, Camera.main.transform.position, pickupPosition.y).projectedPosition; } } if (effect != null) { AircraftRecon recon = effect as AircraftRecon; if (targetLine >= 0) { if (targetLine != recon.target) { recon.target = targetLine; RefreshEffectRepresentation(); } } else { Destroy(recon.gameObject); effect = null; } } }
protected override void RefreshEffectRepresentation() { base.RefreshEffectRepresentation(); AircraftRecon recon = effect as AircraftRecon; int actualPosition = recon.target % (Battle.main.defender.board.tiles.GetLength(0) - 1); bool lineVertical = recon.target == actualPosition; if (indicator == null) { indicator = RequestLineMarker(50, true, new Vector3[] { Vector3.zero, Vector3.forward * 0.925f * Battle.main.defender.board.tiles.GetLength(0), Vector3.forward * 1.025f * Battle.main.defender.board.tiles.GetLength(0) + Vector3.right * (lineVertical ? recon.result : -recon.result) * 2, Vector3.forward * 1.125f * Battle.main.defender.board.tiles.GetLength(0), Vector3.forward * 2.05f * Battle.main.defender.board.tiles.GetLength(0) }, new int[][] { new int[] { 1 }, new int[] { 2 }, new int[] { 3 }, new int[] { 4 }, new int[0] }, 0, linesMaterial); indicator.Delinker += () => { indicator = null; }; indicator.transform.SetParent(transform, false); } indicator.transform.rotation = Quaternion.Euler(0, lineVertical ? 0 : 90, 0); Vector3 startingPosition = Battle.main.defender.board.tiles[0, 0].transform.position - new Vector3(1, 0, 1) * 1f + Vector3.up * (MiscellaneousVariables.it.boardUIRenderHeight + 0.005f); hookedPosition = startingPosition + new Vector3(lineVertical ? 1 : 0, 0, lineVertical ? 0 : 1) * (actualPosition + 1.5f); }
static void FightFor(Player player) { Player attacked_player = Battle.main.attacker == player ? Battle.main.defender : Battle.main.attacker; Map map = new Map(attacked_player.board); float[,] priority_map = map.ratings.Normalize(); float advantage = player.board.ships.Sum(x => x.health) / (float)attacked_player.board.ships.Sum(x => x.health > 0 ? x.maxHealth : 0); int prefered_torpedocount = Mathf.FloorToInt(Mathf.Clamp(player.arsenal.torpedoes, 0, player.arsenal.loadedTorpedoCap) * ((Mathf.Cos(advantage * Mathf.PI) + 1.0f) / 2.0f)); int gun_targetcount = player.arsenal.guns; int torpedo_targetcount = player.arsenal.loadedTorpedoes >= prefered_torpedocount || player.arsenal.loadedTorpedoes == player.arsenal.torpedoes ? prefered_torpedocount : 0; int aircraft_targetcount = Mathf.CeilToInt(Mathf.Clamp(player.arsenal.aircraft - Battle.main.effects.Count(x => x is AircraftRecon && x.visibleTo == player), 0, int.MaxValue) * priority_map.Average()); int cyclone_size = Battle.main.effects.Exists(x => x is Cyclone) ? (Battle.main.effects.Find(x => x is Cyclone) as Cyclone).maximumTileSpacingToTakeEffect * 2 : 0; for (int ti = 0; ti < gun_targetcount; ti++) { Vector2Int target = priority_map.Max(); ArtilleryAttack attack = Effect.CreateEffect(typeof(ArtilleryAttack)) as ArtilleryAttack; attack.target = attacked_player.board.tiles[target.x, target.y]; attack.visibleTo = player; attack.targetedPlayer = attacked_player; Effect.AddToStack(attack); if (cyclone_size > 0) { priority_map = priority_map.AddHeat(target, dist => dist <= cyclone_size ? 0.1f : 1.0f, (original, function) => original * function); } else { priority_map = priority_map.AddHeat(target, dist => 1 - Mathf.Pow(0.5f, dist), (original, function) => original * function); } } for (int ti = 0; ti < torpedo_targetcount; ti++) { float best_lane_rating = Mathf.NegativeInfinity; TorpedoAttack.Target best_target = new TorpedoAttack.Target(); for (int i = 0; i < 4; i++) { for (int a = 0; a < priority_map.GetLength(i % 2); a++) { float rating = 0; for (int b = 0; b < priority_map.GetLength((i + 1) % 2) / 2; b++) { int x = i % 2 == 0 ? a : (i == 1 ? b : priority_map.GetLength(0) - b - 1); int y = i % 2 == 1 ? a : (i == 0 ? b : priority_map.GetLength(1) - b - 1); rating += priority_map[x, y]; } if (rating > best_lane_rating) { best_lane_rating = rating; best_target.torpedoDropPoint = attacked_player.board.tiles[i % 2 == 0 ? a : (i == 1 ? 0 : (priority_map.GetLength(0) - 1)), i % 2 == 1 ? a : (i == 0 ? 0 : (priority_map.GetLength(1) - 1))]; best_target.torpedoHeading = new Vector2Int((2 - i) % 2, (1 - i) % 2); } } } TorpedoAttack attack = Effect.CreateEffect(typeof(TorpedoAttack)) as TorpedoAttack; attack.target = best_target; attack.visibleTo = player; attack.targetedPlayer = attacked_player; Effect.AddToStack(attack); float average = priority_map.Average(); priority_map = priority_map.AddHeat(best_target.torpedoDropPoint.coordinates, dist => 1 - Mathf.Pow(0.5f, dist), (original, function) => original * function); } for (int ti = 0; ti < aircraft_targetcount; ti++) { float best_line_rating = Mathf.NegativeInfinity; int best_line = 0; int line_count = attacked_player.board.tiles.GetLength(0) + attacked_player.board.tiles.GetLength(1) - 2; for (int line = 0; line < line_count; line++) { int line_position = line % (attacked_player.board.tiles.GetLength(0) - 1); bool lineVertical = line_position == line; float line_rating = 0; for (int a = 0; a < 2; a++) { for (int b = 0; b < attacked_player.board.tiles.GetLength(lineVertical ? 1 : 0); b++) { int x = lineVertical ? a + line_position : b; int y = lineVertical ? b : a + line_position; line_rating += priority_map[x, y]; } } if (line_rating > best_line_rating) { best_line = line; best_line_rating = line_rating; } } AircraftRecon recon = Effect.CreateEffect(typeof(AircraftRecon)) as AircraftRecon; recon.target = best_line; recon.visibleTo = player; recon.targetedPlayer = attacked_player; Effect.AddToStack(recon); bool line_vertical = best_line < attacked_player.board.tiles.GetLength(0); best_line %= attacked_player.board.tiles.GetLength(0) - 1; for (int a = 0; a < 2; a++) { for (int b = 0; b < attacked_player.board.tiles.GetLength(line_vertical ? 1 : 0); b++) { int x = line_vertical ? a + best_line : b; int y = line_vertical ? b : a + best_line; priority_map[x, y] = 0; } } } }