diff --git a/src/core/ArenaGrid.spec.ts b/src/core/ArenaGrid.spec.ts index 0834bfa..c27ccc8 100644 --- a/src/core/ArenaGrid.spec.ts +++ b/src/core/ArenaGrid.spec.ts @@ -4,6 +4,26 @@ module TK.SpaceTac.Specs { check.equals(got.y, expected_y, `y differs (${got.x},${got.y}) (${expected_x},${expected_y})`); } + testing("ArenaGrid", test =>  { + test.case("checks if a location is in range of another", check => { + let grid = new ArenaGrid(); + + check.in("first order", check => { + check.equals(grid.inRange({ x: 0, y: 0 }, { x: 4, y: 4 }, 5), false, "<5"); + check.equals(grid.inRange({ x: 0, y: 0 }, { x: 4, y: 4 }, 8), true, "<8"); + }); + + check.in("second order", check => { + check.equals(grid.inRange({ x: 4, y: 4 }, { x: 0, y: 0 }, 5), false, "<5"); + check.equals(grid.inRange({ x: 4, y: 4 }, { x: 0, y: 0 }, 8), true, "<8"); + }); + + check.equals(grid.inRange({ x: 0, y: 0 }, { x: 0.99999999999999, y: 0 }, 1), true, "0.99999999999999"); + check.equals(grid.inRange({ x: 0, y: 0 }, { x: 1.00000000000001, y: 0 }, 1), true, "1.00000000000001"); + check.equals(grid.inRange({ x: 0, y: 0 }, { x: 1.000001, y: 0 }, 1), false, "1.000001"); + }) + }); + testing("HexagonalArenaGrid", test => { test.case("checks coordinates", check => { let grid = new HexagonalArenaGrid(5, 1); diff --git a/src/core/ArenaGrid.ts b/src/core/ArenaGrid.ts index 793e7d0..31255c3 100644 --- a/src/core/ArenaGrid.ts +++ b/src/core/ArenaGrid.ts @@ -36,6 +36,13 @@ module TK.SpaceTac { measure(loc1: IArenaLocation, loc2: IArenaLocation): number { return arenaDistance(this.snap(loc1), this.snap(loc2)); } + + /** + * Check that a location is in range of another + */ + inRange(loc1: IArenaLocation, loc2: IArenaLocation, range: number): boolean { + return this.measure(loc1, loc2) - range < 1e-8; + } } /** @@ -48,12 +55,24 @@ module TK.SpaceTac { super(); } + getUnit(): number { + return this.unit; + } + snap(loc: IArenaLocation): IArenaLocation { return new ArenaLocation(Math.round(loc.x), Math.round(loc.y)); } measure(loc1: IArenaLocation, loc2: IArenaLocation): number { - return Math.round(super.measure(loc1, loc2) / this.unit); + let d = super.measure(loc1, loc2) / this.unit; + let r = Math.round(d); + if (r >= d) { + return Math.floor(d); + } else if (r - d < 1e-8) { + return r; + } else { + return Math.ceil(d); + } } } diff --git a/src/core/ArenaLocation.spec.ts b/src/core/ArenaLocation.spec.ts index 15a95ae..b821e91 100644 --- a/src/core/ArenaLocation.spec.ts +++ b/src/core/ArenaLocation.spec.ts @@ -5,22 +5,6 @@ module TK.SpaceTac.Specs { check.nears(arenaAngle({ x: 0, y: 0 }, { x: 1, y: 1 }), Math.PI / 4); }) - test.case("checks if a location is in range of another", check => { - check.in("first order", check => { - check.equals(arenaInRange({ x: 0, y: 0 }, { x: 4, y: 4 }, 5), false, "<5"); - check.equals(arenaInRange({ x: 0, y: 0 }, { x: 4, y: 4 }, 8), true, "<8"); - }); - - check.in("second order", check => { - check.equals(arenaInRange({ x: 4, y: 4 }, { x: 0, y: 0 }, 5), false, "<5"); - check.equals(arenaInRange({ x: 4, y: 4 }, { x: 0, y: 0 }, 8), true, "<8"); - }); - - check.equals(arenaInRange({ x: 0, y: 0 }, { x: 0.99999999999999, y: 0 }, 1), true, "0.99999999999999"); - check.equals(arenaInRange({ x: 0, y: 0 }, { x: 1.00000000000001, y: 0 }, 1), true, "1.00000000000001"); - check.equals(arenaInRange({ x: 0, y: 0 }, { x: 1.000001, y: 0 }, 1), false, "1.000001"); - }) - test.case("computes an angular difference", check => { check.equals(angularDifference(0.5, 1.5), 1.0); check.nears(angularDifference(0.5, 1.5 + Math.PI * 6), 1.0); diff --git a/src/core/ArenaLocation.ts b/src/core/ArenaLocation.ts index 9b3c05b..59eed53 100644 --- a/src/core/ArenaLocation.ts +++ b/src/core/ArenaLocation.ts @@ -75,13 +75,6 @@ module TK.SpaceTac { return Math.sqrt(dx * dx + dy * dy); } - /** - * Check if a location is in range of another (accounting for rounding errors) - */ - export function arenaInRange(loc1: IArenaLocation, loc2: IArenaLocation, range: number): boolean { - return arenaDistance(loc1, loc2) - range < 1e-8; - } - /** * Check if a location is inside an area */ diff --git a/src/core/Battle.spec.ts b/src/core/Battle.spec.ts index aa0e7f6..ee13c15 100644 --- a/src/core/Battle.spec.ts +++ b/src/core/Battle.spec.ts @@ -280,6 +280,7 @@ module TK.SpaceTac { test.case("lists area effects", check => { let battle = new Battle(); + battle.grid = new PixelGrid(); let ship = battle.fleets[0].addShip(); let peer = battle.fleets[1].addShip(); peer.setArenaPosition(100, 50); diff --git a/src/core/Battle.ts b/src/core/Battle.ts index 7b12117..e69c89d 100644 --- a/src/core/Battle.ts +++ b/src/core/Battle.ts @@ -332,8 +332,7 @@ module TK.SpaceTac { */ getAreaEffects(ship: Ship): [Ship | Drone, BaseEffect][] { let drone_effects = this.drones.list().map(drone => { - // TODO Should apply filterImpactedShips from drone action - if (drone.isInRange(ship.arena_x, ship.arena_y)) { + if (contains(drone.getAffectedShips(this), ship)) { return drone.effects.map((effect): [Ship | Drone, BaseEffect] => [drone, effect]); } else { return []; diff --git a/src/core/BattleChecks.spec.ts b/src/core/BattleChecks.spec.ts index 8777bb7..f6c640d 100644 --- a/src/core/BattleChecks.spec.ts +++ b/src/core/BattleChecks.spec.ts @@ -72,6 +72,7 @@ module TK.SpaceTac.Specs { test.case("applies vigilance actions", check => { let battle = new Battle(); + battle.grid = new PixelGrid(); let ship1 = battle.fleets[0].addShip(); ship1.setArenaPosition(100, 100); TestTools.setShipModel(ship1, 10, 0, 5); diff --git a/src/core/Drone.spec.ts b/src/core/Drone.spec.ts index acd183e..1b09bba 100644 --- a/src/core/Drone.spec.ts +++ b/src/core/Drone.spec.ts @@ -50,6 +50,15 @@ module TK.SpaceTac { ]); }); + test.case("applies targetting filter", check => { + let battle = TestTools.createBattle(); + battle.fleets[1].addShip().setDead(); + let drone = new Drone(nn(battle.playing_ship)); + check.equals(drone.getAffectedShips(battle), [battle.fleets[0].ships[0], battle.fleets[1].ships[0]]); + drone.filter = ActionTargettingFilter.ENEMIES; + check.equals(drone.getAffectedShips(battle), [battle.fleets[1].ships[0]]); + }); + test.case("builds a textual description", check => { let drone = new Drone(new Ship()); check.equals(drone.getDescription(), "While deployed:\n• do nothing"); diff --git a/src/core/Drone.ts b/src/core/Drone.ts index 6a8d067..cff33cc 100644 --- a/src/core/Drone.ts +++ b/src/core/Drone.ts @@ -12,13 +12,16 @@ module TK.SpaceTac { // Location in arena x = 0 y = 0 + + // Radius and ship filter radius = 0 + filter = ActionTargettingFilter.ALL // Effects to apply effects: BaseEffect[] = [] // Action that triggered that drone - parent: DeployDroneAction | null = null; + parent: DeployDroneAction | null = null constructor(owner: Ship, code = "drone") { super(); @@ -45,19 +48,20 @@ module TK.SpaceTac { return `While deployed:\n${effects}`; } - /** - * Check if a location is in range - */ - isInRange(x: number, y: number): boolean { - return Target.newFromLocation(x, y).getDistanceTo(this) <= this.radius; - } - /** * Get the list of affected ships. */ getAffectedShips(battle: Battle): Ship[] { - let ships = ifilter(battle.iships(), ship => ship.alive && ship.isInCircle(this.x, this.y, this.radius)); - return imaterialize(ships); + let ships = battle.ships.list(); + ships = ships.filter(ship => ship.alive); + ships = ships.filter(ship => battle.grid.inRange(this, ship.location, this.radius)); + let owner = battle.getShip(this.owner); + if (owner) { + ships = BaseAction.filterTargets(owner, ships, this.filter); + } else { + ships = []; + } + return ships; } } } \ No newline at end of file diff --git a/src/core/Target.spec.ts b/src/core/Target.spec.ts index 373c826..14226b4 100644 --- a/src/core/Target.spec.ts +++ b/src/core/Target.spec.ts @@ -28,12 +28,5 @@ module TK.SpaceTac.Specs { var t2 = Target.newFromLocation(4, 5); check.nears(t1.getAngleTo(t2), Math.PI / 4); }); - - test.case("checks if a target is in range of another", check => { - var t1 = Target.newFromLocation(5, 4); - check.equals(t1.isInRange(7, 3, 2), false); - check.equals(t1.isInRange(7, 3, 3), true); - check.equals(t1.isInRange(5, 5, 2), true); - }); }); } diff --git a/src/core/Target.ts b/src/core/Target.ts index 8c074b9..c71e4af 100644 --- a/src/core/Target.ts +++ b/src/core/Target.ts @@ -79,10 +79,5 @@ module TK.SpaceTac { return null; } } - - // Check if a target is in range from a specific point - isInRange(x: number, y: number, radius: number): boolean { - return arenaInRange(this, new ArenaLocation(x, y), radius); - } } } diff --git a/src/core/actions/BaseAction.ts b/src/core/actions/BaseAction.ts index 94424e9..9c763ea 100644 --- a/src/core/actions/BaseAction.ts +++ b/src/core/actions/BaseAction.ts @@ -164,7 +164,7 @@ module TK.SpaceTac { } /** - * Get the range of this action, for targetting purpose + * Get the range of this action, in raw arena coordinates, for targetting purpose */ getRangeRadius(ship: Ship): number { return 0; diff --git a/src/core/actions/DeployDroneAction.spec.ts b/src/core/actions/DeployDroneAction.spec.ts index 788b2ec..65969d0 100644 --- a/src/core/actions/DeployDroneAction.spec.ts +++ b/src/core/actions/DeployDroneAction.spec.ts @@ -51,7 +51,8 @@ module TK.SpaceTac.Specs { ship.setArenaPosition(0, 0); TestTools.setShipModel(ship, 100, 0, 3); - let action = new DeployDroneAction("testdrone", { power: 2 }, { deploy_distance: 8, drone_radius: 4, drone_effects: [new DamageEffect(50)] }); + let action = new DeployDroneAction("testdrone", { power: 2, filter: ActionTargettingFilter.ALLIES_BUT_SELF }, + { deploy_distance: 8, drone_radius: 4, drone_effects: [new DamageEffect(50)] }); ship.actions.addCustom(action); TestTools.actionChain(check, battle, [ @@ -71,6 +72,7 @@ module TK.SpaceTac.Specs { check.equals(drone.x, 5); check.equals(drone.y, 0); check.equals(drone.radius, 4); + check.equals(drone.filter, ActionTargettingFilter.ALLIES_BUT_SELF); compare_effects(check, drone.effects, [new DamageEffect(50)]); } ]) diff --git a/src/core/actions/DeployDroneAction.ts b/src/core/actions/DeployDroneAction.ts index fbaaa8e..0d48889 100644 --- a/src/core/actions/DeployDroneAction.ts +++ b/src/core/actions/DeployDroneAction.ts @@ -62,11 +62,15 @@ module TK.SpaceTac { } getRangeRadius(ship: Ship): number { - return ship.actions.isToggled(this) ? 0 : this.deploy_distance; + if (ship.actions.isToggled(this)) { + return 0; + } else { + return this.deploy_distance * ship.grid.getUnit(); + } } filterImpactedShips(ship: Ship, source: ArenaLocation, target: Target, ships: Ship[]): Ship[] { - let result = ships.filter(iship => arenaDistance(iship.location, target) <= this.radius); + let result = ships.filter(iship => ship.grid.inRange(target, iship.location, this.drone_radius)); result = BaseAction.filterTargets(ship, result, this.filter); return result; } @@ -83,7 +87,7 @@ module TK.SpaceTac { if (ship.actions.isToggled(this)) { return false; } else { - return arenaInRange(ship.location, target, this.deploy_distance); + return ship.grid.inRange(ship.location, target, this.deploy_distance); } } @@ -103,6 +107,7 @@ module TK.SpaceTac { drone.x = target.x; drone.y = target.y; drone.radius = this.drone_radius; + drone.filter = this.filter; drone.effects = this.drone_effects; result.push(new DroneDeployedDiff(drone)); diff --git a/src/core/actions/MoveAction.spec.ts b/src/core/actions/MoveAction.spec.ts index f85a7c6..1ab9caa 100644 --- a/src/core/actions/MoveAction.spec.ts +++ b/src/core/actions/MoveAction.spec.ts @@ -6,8 +6,7 @@ module TK.SpaceTac.Specs { battle.grid = new PixelGrid(); TestTools.setShipPlaying(battle, ship); ship.setValue("power", 6); - ship.arena_x = 0; - ship.arena_y = 0; + ship.setArenaPosition(0, 0); var action = new MoveAction("Engine", { distance_per_power: 10 }); ship.actions.addCustom(action); @@ -68,7 +67,7 @@ module TK.SpaceTac.Specs { ship.setArenaPosition(500, 500); enemy.setArenaPosition(1000, 500); - var action = new MoveAction("Engine", { distance_per_power: 1000, safety_distance: 200 }); + var action = new MoveAction("Engine", { distance_per_power: 1000 }); var result = action.checkLocationTarget(ship, Target.newFromLocation(700, 500)); check.equals(result, true); diff --git a/src/core/actions/MoveAction.ts b/src/core/actions/MoveAction.ts index 623d918..ff468ba 100644 --- a/src/core/actions/MoveAction.ts +++ b/src/core/actions/MoveAction.ts @@ -83,17 +83,21 @@ module TK.SpaceTac { } getRangeRadius(ship: Ship): number { - return ship.getValue("power") * this.distance_per_power * ship.grid.getUnit(); + return ship.getValue("power") * this.getDistancePerPower(ship); + } + + getDistancePerPower(ship: Ship): number { + return this.distance_per_power * ship.grid.getUnit(); } checkLocationTarget(ship: Ship, target: Target): boolean { - if (!ship.grid.check(target)) { + if (!ship.grid.check(target) || ship.grid.measure(ship.location, target) < 1e-8) { return false; } // TODO Check the space is not occupied - return true; + return ship.getValue("power") >= this.getPowerUsage(ship, target); } protected getSpecificDiffs(ship: Ship, battle: Battle, target: Target): BaseBattleDiff[] { diff --git a/src/core/actions/ToggleAction.spec.ts b/src/core/actions/ToggleAction.spec.ts index 7d65717..7714c96 100644 --- a/src/core/actions/ToggleAction.spec.ts +++ b/src/core/actions/ToggleAction.spec.ts @@ -21,6 +21,7 @@ module TK.SpaceTac.Specs { test.case("collects impacted ships", check => { let action = new ToggleAction("testtoggle", { radius: 50 }); let battle = new Battle(); + battle.grid = new PixelGrid(); let ship1 = battle.fleets[0].addShip(); ship1.setArenaPosition(0, 0); let ship2 = battle.fleets[0].addShip(); diff --git a/src/core/actions/ToggleAction.ts b/src/core/actions/ToggleAction.ts index 5fc2695..da6da53 100644 --- a/src/core/actions/ToggleAction.ts +++ b/src/core/actions/ToggleAction.ts @@ -62,7 +62,7 @@ module TK.SpaceTac { } filterImpactedShips(ship: Ship, source: ArenaLocation, target: Target, ships: Ship[]): Ship[] { - let result = ships.filter(iship => arenaDistance(iship.location, source) <= this.radius); + let result = ships.filter(iship => ship.grid.inRange(source, iship.location, this.radius)); result = BaseAction.filterTargets(ship, result, this.filter); return result; } diff --git a/src/core/actions/TriggerAction.spec.ts b/src/core/actions/TriggerAction.spec.ts index 4262814..96ba7d0 100644 --- a/src/core/actions/TriggerAction.spec.ts +++ b/src/core/actions/TriggerAction.spec.ts @@ -28,6 +28,7 @@ module TK.SpaceTac.Specs { ship3.alive = false; let battle = new Battle(fleet); + battle.grid = new PixelGrid(); battle.play_order = [ship, ship1, ship2, ship3]; TestTools.setShipPlaying(battle, ship); fleet.setBattle(battle); diff --git a/src/core/actions/TriggerAction.ts b/src/core/actions/TriggerAction.ts index 555a2b8..3391734 100644 --- a/src/core/actions/TriggerAction.ts +++ b/src/core/actions/TriggerAction.ts @@ -87,7 +87,11 @@ module TK.SpaceTac { } getRangeRadius(ship: Ship): number { - return this.range; + return this.range * ship.grid.getUnit(); + } + + getBlastRadius(ship: Ship): number { + return this.blast * ship.grid.getUnit(); } checkCannotBeApplied(ship: Ship, remaining_ap: number | null = null): ActionUnavailability | null { @@ -107,12 +111,12 @@ module TK.SpaceTac { filterImpactedShips(ship: Ship, source: ArenaLocation, target: Target, ships: Ship[]): Ship[] { if (this.blast) { - return ships.filter(ship => arenaDistance(ship.location, target) <= this.blast); + return ships.filter(iship => ship.grid.measure(iship.location, target) <= this.blast); } else if (this.angle) { let angle = arenaAngle(source, target); let maxangle = (this.angle * 0.5) * Math.PI / 180; return ships.filter(iship => { - let dist = arenaDistance(source, iship.location); + let dist = ship.grid.measure(source, iship.location); if (dist < 0.000001 || dist > this.range) { return false; } else { @@ -126,7 +130,7 @@ module TK.SpaceTac { checkLocationTarget(ship: Ship, target: Target): boolean { if (target && (this.blast > 0 || this.angle > 0)) { - return arenaInRange(ship.location, target, this.range); + return ship.grid.inRange(ship.location, target, this.range); } else { return false; } @@ -141,7 +145,7 @@ module TK.SpaceTac { if (this.blast > 0 || this.angle > 0) { return this.checkLocationTarget(ship, new Target(target.x, target.y)); } else { - return arenaInRange(ship.location, target, this.range); + return ship.grid.inRange(ship.location, target, this.range); } } } diff --git a/src/core/actions/VigilanceAction.spec.ts b/src/core/actions/VigilanceAction.spec.ts index d976523..3b2ab25 100644 --- a/src/core/actions/VigilanceAction.spec.ts +++ b/src/core/actions/VigilanceAction.spec.ts @@ -47,6 +47,7 @@ module TK.SpaceTac.Specs { test.case("handles the vigilance effect to know who to target", check => { let battle = new Battle(); + battle.grid = new PixelGrid(); let ship1a = battle.fleets[0].addShip(); ship1a.setArenaPosition(0, 0); TestTools.setShipModel(ship1a, 10, 0, 5); diff --git a/src/core/ai/TacticalAIHelpers.spec.ts b/src/core/ai/TacticalAIHelpers.spec.ts index 7121e0c..c201ab8 100644 --- a/src/core/ai/TacticalAIHelpers.spec.ts +++ b/src/core/ai/TacticalAIHelpers.spec.ts @@ -86,7 +86,7 @@ module TK.SpaceTac.Specs { let ship = battle.fleets[0].addShip(); let action1 = new DeployDroneAction("Drone"); let action2 = new ToggleAction("Toggle"); - let action3 = new VigilanceAction("Vigilance", { radius: 150 }); + let action3 = new VigilanceAction("Vigilance", { radius: 3 }); TestTools.setShipModel(ship, 100, 0, 10, 1, [action1, action2, action3]); TestTools.addEngine(ship, 1000); TestTools.setShipPlaying(battle, ship); @@ -173,6 +173,7 @@ module TK.SpaceTac.Specs { test.case("evaluates damage to enemies", check => { let battle = new Battle(); + battle.grid = new PixelGrid(); let ship = battle.fleets[0].addShip(); let action = TestTools.addWeapon(ship, 50, 5, 500, 100); @@ -198,13 +199,14 @@ module TK.SpaceTac.Specs { test.case("evaluates ship clustering", check => { let battle = new Battle(); + battle.grid = new PixelGrid(); let ship = battle.fleets[0].addShip(); TestTools.setShipModel(ship, 100, 0, 10); TestTools.addEngine(ship, 100); let weapon = TestTools.addWeapon(ship, 100, 1, 100, 10); let maneuver = new Maneuver(ship, weapon, Target.newFromLocation(200, 0)); - check.equals(maneuver.simulation.move_location.x, 100); + check.equals(maneuver.simulation.move_location.x, 101); check.equals(maneuver.simulation.move_location.y, 0); check.equals(TacticalAIHelpers.evaluateClustering(ship, battle, maneuver), 0); diff --git a/src/core/models/ModelAvenger.ts b/src/core/models/ModelAvenger.ts index 4d0a6f4..f06c372 100644 --- a/src/core/models/ModelAvenger.ts +++ b/src/core/models/ModelAvenger.ts @@ -21,14 +21,14 @@ module TK.SpaceTac { let charged_shot = new TriggerAction("Charged Shot", { effects: [new DamageEffect(3)], power: 4, - range: 900, + range: 18, }, "gatlinggun"); charged_shot.configureCooldown(2, 2); let long_range_missile = new TriggerAction("Long Range Missile", { effects: [new DamageEffect(2)], power: 4, - range: 700, blast: 120, + range: 14, blast: 2, }, "submunitionmissile"); long_range_missile.configureCooldown(1, 2); diff --git a/src/core/models/ModelBreeze.ts b/src/core/models/ModelBreeze.ts index 1788fe1..4eefb45 100644 --- a/src/core/models/ModelBreeze.ts +++ b/src/core/models/ModelBreeze.ts @@ -20,14 +20,14 @@ module TK.SpaceTac { let gatling = new TriggerAction("Gatling Gun", { effects: [new DamageEffect(2, DamageEffectMode.SHIELD_THEN_HULL)], power: 2, - range: 200, + range: 4, }, "gatlinggun"); gatling.configureCooldown(2, 1); let shield_steal = new TriggerAction("Shield Steal", { effects: [new ValueTransferEffect("shield", -1)], power: 1, - blast: 300 + blast: 6 }, "shieldtransfer"); shield_steal.configureCooldown(1, 2); diff --git a/src/core/models/ModelCommodore.ts b/src/core/models/ModelCommodore.ts index d529012..49342b1 100644 --- a/src/core/models/ModelCommodore.ts +++ b/src/core/models/ModelCommodore.ts @@ -19,11 +19,11 @@ module TK.SpaceTac { let laser = new TriggerAction("Wingspan Laser", { effects: [new DamageEffect(3, DamageEffectMode.SHIELD_THEN_HULL)], power: 4, - range: 250, angle: 140, + range: 5, angle: 140, }, "prokhorovlaser"); laser.configureCooldown(3, 1); - let interceptors = new VigilanceAction("Interceptors Field", { radius: 200, power: 3, filter: ActionTargettingFilter.ENEMIES }, { + let interceptors = new VigilanceAction("Interceptors Field", { radius: 4, power: 3, filter: ActionTargettingFilter.ENEMIES }, { intruder_count: 1, intruder_effects: [new DamageEffect(4, DamageEffectMode.SHIELD_THEN_HULL)] }, "interceptors"); @@ -31,7 +31,7 @@ module TK.SpaceTac { let power_steal = new TriggerAction("Power Thief", { effects: [new ValueTransferEffect("power", -1)], power: 1, - blast: 250 + blast: 5 }, "powerdepleter"); power_steal.configureCooldown(1, 1); diff --git a/src/core/models/ModelCreeper.ts b/src/core/models/ModelCreeper.ts index 2528692..cfc0f82 100644 --- a/src/core/models/ModelCreeper.ts +++ b/src/core/models/ModelCreeper.ts @@ -19,20 +19,20 @@ module TK.SpaceTac { let gatling = new TriggerAction("Gatling Gun", { effects: [new DamageEffect(1)], power: 2, - range: 200, + range: 4, }, "gatlinggun"); gatling.configureCooldown(1, 1); let repulse = new TriggerAction("Repulser", { effects: [new RepelEffect(150)], power: 2, - blast: 350, + blast: 7, }, "gravitshield"); repulse.configureCooldown(1, 1); let repairdrone = new DeployDroneAction("Repair Drone", { power: 3, filter: ActionTargettingFilter.ALLIES }, { - deploy_distance: 300, - drone_radius: 150, + deploy_distance: 6, + drone_radius: 3, drone_effects: [ new ValueEffect("hull", 0, 0, 0, 1) ] diff --git a/src/core/models/ModelFalcon.ts b/src/core/models/ModelFalcon.ts index 113cbe6..71c3e60 100644 --- a/src/core/models/ModelFalcon.ts +++ b/src/core/models/ModelFalcon.ts @@ -19,7 +19,7 @@ module TK.SpaceTac { let missile = new TriggerAction("SubMunition Missile", { effects: [new DamageEffect(3)], power: 3, - range: 250, blast: 150, + range: 5, blast: 3, }, "submunitionmissile"); missile.configureCooldown(2, 2); @@ -27,7 +27,7 @@ module TK.SpaceTac { let gatling = new TriggerAction("Multi-head Gatling", { effects: [new DamageEffect(2)], power: 2, - range: 350, blast: 150, + range: 7, blast: 3, }, "gatlinggun"); gatling.configureCooldown(3, 2); diff --git a/src/core/models/ModelFlea.ts b/src/core/models/ModelFlea.ts index 433762f..65f7a02 100644 --- a/src/core/models/ModelFlea.ts +++ b/src/core/models/ModelFlea.ts @@ -19,21 +19,21 @@ module TK.SpaceTac { let depleter = new TriggerAction("Power Depleter", { effects: [new StickyEffect(new AttributeLimitEffect("power_capacity", 3))], power: 2, - range: 450, + range: 9, }, "powerdepleter"); depleter.configureCooldown(1, 1); let shield_basher = new TriggerAction("Shield Basher", { effects: [new DamageEffect(2, DamageEffectMode.SHIELD_ONLY, false)], power: 3, - range: 300, + range: 6, }, "shieldbash"); shield_basher.configureCooldown(2, 1); let engine_hijack = new TriggerAction("Engine Hijacking", { effects: [new StickyEffect(new PinnedEffect(), 2)], power: 2, - range: 400, + range: 8, }, "pin"); engine_hijack.configureCooldown(1, 2); diff --git a/src/core/models/ModelJumper.ts b/src/core/models/ModelJumper.ts index cdbc2a2..89054e0 100644 --- a/src/core/models/ModelJumper.ts +++ b/src/core/models/ModelJumper.ts @@ -19,13 +19,13 @@ module TK.SpaceTac { let missile = new TriggerAction("SubMunition Missile", { effects: [new DamageEffect(2)], power: 3, - range: 400, blast: 120, + range: 8, blast: 2, }, "submunitionmissile"); let protector = new TriggerAction("Damage Reductor", { effects: [new StickyEffect(new AttributeEffect("evasion", 1), 2)], power: 3, - range: 300, blast: 150 + range: 6, blast: 3 }, "damageprotector"); protector.configureCooldown(1, 3); diff --git a/src/core/models/ModelRhino.ts b/src/core/models/ModelRhino.ts index 24fec00..6d60468 100644 --- a/src/core/models/ModelRhino.ts +++ b/src/core/models/ModelRhino.ts @@ -19,14 +19,14 @@ module TK.SpaceTac { let gatling = new TriggerAction("Gatling Gun", { effects: [new DamageEffect(2)], power: 3, - range: 400, + range: 8, }, "gatlinggun"); gatling.configureCooldown(2, 2); let laser = new TriggerAction("Prokhorov Laser", { effects: [new DamageEffect(3)], power: 4, - range: 250, angle: 60, + range: 5, angle: 60, }, "prokhorovlaser"); return [ diff --git a/src/core/models/ModelTomahawk.ts b/src/core/models/ModelTomahawk.ts index 2fa91d9..56a4b13 100644 --- a/src/core/models/ModelTomahawk.ts +++ b/src/core/models/ModelTomahawk.ts @@ -18,20 +18,20 @@ module TK.SpaceTac { let gatling1 = new TriggerAction("Primary Gatling", { effects: [new DamageEffect(3)], - power: 2, range: 400 + power: 2, range: 8 }, "gatlinggun"); gatling1.configureCooldown(1, 2); let gatling2 = new TriggerAction("Secondary Gatling", { effects: [new DamageEffect(2)], - power: 1, range: 200 + power: 1, range: 4 }, "gatlinggun"); gatling2.configureCooldown(1, 2); let missile = new TriggerAction("Diffuse Missiles", { effects: [new DamageEffect(2)], power: 2, - range: 200, blast: 100, + range: 4, blast: 2, }, "submunitionmissile"); missile.configureCooldown(1, 2); diff --git a/src/core/models/ModelTrapper.ts b/src/core/models/ModelTrapper.ts index 6a02b65..493f2c2 100644 --- a/src/core/models/ModelTrapper.ts +++ b/src/core/models/ModelTrapper.ts @@ -19,7 +19,7 @@ module TK.SpaceTac { let protector = new ToggleAction("Damage Protector", { power: 4, - radius: 300, + radius: 6, effects: [new AttributeEffect("evasion", 1)], filter: ActionTargettingFilter.ALLIES }); @@ -27,14 +27,14 @@ module TK.SpaceTac { let depleter = new TriggerAction("Power Depleter", { effects: [new StickyEffect(new AttributeLimitEffect("power_capacity", 3))], power: 2, - range: 200, + range: 4, }, "powerdepleter"); depleter.configureCooldown(1, 1); let missile = new TriggerAction("Defense Missiles", { effects: [new DamageEffect(3, DamageEffectMode.SHIELD_THEN_HULL)], power: 3, - range: 200, blast: 180, + range: 4, blast: 4, }, "submunitionmissile"); return [ diff --git a/src/core/models/ModelXander.ts b/src/core/models/ModelXander.ts index da56408..50c2692 100644 --- a/src/core/models/ModelXander.ts +++ b/src/core/models/ModelXander.ts @@ -19,7 +19,7 @@ module TK.SpaceTac { let laser = new TriggerAction("Prokhorov Laser", { effects: [new DamageEffect(2, DamageEffectMode.SHIELD_THEN_HULL)], power: 3, - range: 250, angle: 80, + range: 5, angle: 80, }); let hull = new TriggerAction("Hull Shedding", { diff --git a/src/ui/TestGame.ts b/src/ui/TestGame.ts index 8c72dc5..f6f5cab 100644 --- a/src/ui/TestGame.ts +++ b/src/ui/TestGame.ts @@ -82,7 +82,7 @@ module TK.SpaceTac.UI.Specs { view.splash = false; let battle = Battle.newQuickRandom(); - battle.grid = new PixelGrid(); + battle.grid = new ArenaGrid(); battle.placeShips(); let player = new Player(); nn(battle.playing_ship).fleet.setPlayer(player); diff --git a/src/ui/battle/ActionTooltip.spec.ts b/src/ui/battle/ActionTooltip.spec.ts index f781613..f308d2c 100644 --- a/src/ui/battle/ActionTooltip.spec.ts +++ b/src/ui/battle/ActionTooltip.spec.ts @@ -16,7 +16,7 @@ module TK.SpaceTac.UI.Specs { ActionTooltip.fill(tooltip.getBuilder(), ship, action1, 0); checkText(check, tooltip.container.content.list[1], "Use Thruster"); checkText(check, tooltip.container.content.list[2], "Cost: 1 power per 0km"); - checkText(check, tooltip.container.content.list[3], "Move: 0km per power point (safety: 120km)"); + checkText(check, tooltip.container.content.list[3], "Move: 0km per power point"); checkText(check, tooltip.container.content.list[4], "[ 1 ]"); tooltip.hide(); diff --git a/src/ui/battle/ArenaDrone.ts b/src/ui/battle/ArenaDrone.ts index 92c9bef..183826b 100644 --- a/src/ui/battle/ArenaDrone.ts +++ b/src/ui/battle/ArenaDrone.ts @@ -26,17 +26,19 @@ module TK.SpaceTac.UI { let builder = new UIBuilder(battleview, this); + let radius = drone.radius * battleview.battle.grid.getUnit(); + this.radius = builder.graphics("radius"); this.radius.fillStyle(0xe9f2f9, 0.1); - this.radius.fillCircle(0, 0, drone.radius); + this.radius.fillCircle(0, 0, radius); this.radius.lineStyle(2, 0xe9f2f9, 0.5); - this.radius.strokeCircle(0, 0, drone.radius); + this.radius.strokeCircle(0, 0, radius); this.activation = builder.graphics("activation", 0, 0, false); this.activation.fillStyle(0xe9f2f9, 0.0); - this.activation.fillCircle(0, 0, drone.radius); + this.activation.fillCircle(0, 0, radius); this.activation.lineStyle(2, 0xe9f2f9, 0.7); - this.activation.strokeCircle(0, 0, drone.radius); + this.activation.strokeCircle(0, 0, radius); this.sprite = builder.button(`action-${drone.code}`, 0, 0, undefined, () => this.drone.getDescription(), undefined, { center: true }); this.sprite.setScale(0.1, 0.1); diff --git a/src/ui/battle/Targetting.ts b/src/ui/battle/Targetting.ts index 50bce43..5d0699a 100644 --- a/src/ui/battle/Targetting.ts +++ b/src/ui/battle/Targetting.ts @@ -123,7 +123,7 @@ module TK.SpaceTac.UI { let move = part.action instanceof MoveAction; let color = (enabled && part.possible) ? (move ? 0xe09c47 : 0xdc6441) : 0x8e8e8e; let src = previous ? previous.target : this.ship.location; - let gradation = (part.action instanceof MoveAction) ? part.action.distance_per_power : 0; + let gradation = (part.action instanceof MoveAction) ? part.action.getDistancePerPower(this.ship) : 0; this.drawVector(color, src.x, src.y, part.target.x, part.target.y, gradation); } @@ -171,6 +171,9 @@ module TK.SpaceTac.UI { } if (radius) { + if (this.ship) { + radius *= this.ship.grid.getUnit(); + } if (angle) { area.addCircleArc({ radius: radius, diff --git a/src/ui/battle/WeaponEffect.ts b/src/ui/battle/WeaponEffect.ts index bb7b1d0..f54fe72 100644 --- a/src/ui/battle/WeaponEffect.ts +++ b/src/ui/battle/WeaponEffect.ts @@ -159,7 +159,7 @@ module TK.SpaceTac.UI { let missile = this.builder.image("battle-effects-default", this.source.x, this.source.y, true); missile.setRotation(arenaAngle(this.source, this.destination)); - let blast_radius = this.action.blast; + let blast_radius = this.action.getBlastRadius(this.ship); let projectile_duration = (arenaDistance(this.source, this.destination) * 1.5) || 1; await this.view.animations.addAnimation(missile, { x: this.destination.x, y: this.destination.y }, projectile_duration / speed); @@ -186,7 +186,8 @@ module TK.SpaceTac.UI { delay: ship => { let result = (arenaDistance(this.source, this.destination) * 1.5) || 1; if (this.action.blast) { - result += 300 * Phaser.Math.Easing.Quintic.Out(arenaDistance(this.destination, ship.location) / this.action.blast); + let d = arenaDistance(this.destination, ship.location) / this.action.getBlastRadius(this.ship); + result += 300 * Phaser.Math.Easing.Quintic.Out(d); } return result; } @@ -206,7 +207,7 @@ module TK.SpaceTac.UI { let laser = this.builder.image("battle-effects-laser", this.source.x, this.source.y); laser.setOrigin(0, 0.5); laser.setRotation(angle - dangle); - laser.setScale(this.action.range / laser.width); + laser.setScale(this.action.getRangeRadius(this.ship) / laser.width); let dest_angle = laser.rotation + angularDifference(laser.rotation, angle + dangle); return this.view.animations.addAnimation(laser, { rotation: dest_angle }, duration).then(() => laser.destroy()); }