WIP
This commit is contained in:
parent
74debe585d
commit
355ee74026
2
TODO.md
2
TODO.md
|
@ -55,7 +55,7 @@ Battle
|
|||
* Fix repel effect to snap to grid and use grid units (beware of two ships being moved to the same location!)
|
||||
* Display the grid in targetting mode, with colors (replaces range hint)
|
||||
* Fix move-fire simulator's scanCircle
|
||||
* Fix tactical AI scanArea
|
||||
* Fix occupied space in move action targetting being displayed as "not enough power"
|
||||
* Apply to action's default targets
|
||||
* Add engine trail effect, and sound
|
||||
* Find incentives to move from starting position (permanent drones or anomalies?)
|
||||
|
|
|
@ -234,9 +234,30 @@ module TK.SpaceTac {
|
|||
/**
|
||||
* Check if a target is suitable for this action
|
||||
*
|
||||
* Will call checkLocationTarget or checkShipTarget by default
|
||||
* Will call checkLocationTarget or checkShipTarget by default, after checking that the target is compatible
|
||||
* with targetting mode.
|
||||
*/
|
||||
checkTarget(ship: Ship, target: Target, from: IArenaLocation = ship.location): boolean {
|
||||
let mode = this.getTargettingMode(ship);
|
||||
|
||||
if (mode == ActionTargettingMode.SELF || mode == ActionTargettingMode.SELF_CONFIRM) {
|
||||
if (!target.isShip(ship)) {
|
||||
return false;
|
||||
}
|
||||
} else if (mode == ActionTargettingMode.SHIP) {
|
||||
if (!target.isShip()) {
|
||||
return false;
|
||||
}
|
||||
} else if (mode == ActionTargettingMode.SPACE) {
|
||||
if (target.isShip() || !ship.grid.check(target)) {
|
||||
return false;
|
||||
}
|
||||
} else if (mode == ActionTargettingMode.SURROUNDINGS) {
|
||||
if (!target.isShip(ship) || !ship.grid.check(target)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (target.isShip()) {
|
||||
return this.checkShipTarget(ship, target, from);
|
||||
} else {
|
||||
|
@ -250,7 +271,7 @@ module TK.SpaceTac {
|
|||
* Should not check for power or action availability, only whether the target is valid
|
||||
*/
|
||||
protected checkLocationTarget(ship: Ship, target: Target, from: IArenaLocation): boolean {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -259,7 +280,7 @@ module TK.SpaceTac {
|
|||
* Should not check for power or action availability, only whether the target is valid
|
||||
*/
|
||||
protected checkShipTarget(ship: Ship, target: Target, from: IArenaLocation): boolean {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -75,20 +75,8 @@ module TK.SpaceTac {
|
|||
return result;
|
||||
}
|
||||
|
||||
checkShipTarget(ship: Ship, target: Target, from: IArenaLocation): boolean {
|
||||
if (ship.actions.isToggled(this)) {
|
||||
return target.isShip(ship);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
checkLocationTarget(ship: Ship, target: Target, from: IArenaLocation): boolean {
|
||||
if (ship.actions.isToggled(this)) {
|
||||
return false;
|
||||
} else {
|
||||
return ship.grid.inRange(from, target, this.deploy_distance);
|
||||
}
|
||||
return ship.grid.inRange(from, target, this.deploy_distance);
|
||||
}
|
||||
|
||||
getSpecificDiffs(ship: Ship, battle: Battle, target: Target): BaseBattleDiff[] {
|
||||
|
|
|
@ -59,10 +59,6 @@ module TK.SpaceTac {
|
|||
}
|
||||
}
|
||||
|
||||
protected checkShipTarget(ship: Ship, target: Target): boolean {
|
||||
return ship.is(target.ship_id);
|
||||
}
|
||||
|
||||
getTargettingMode(ship: Ship): ActionTargettingMode {
|
||||
return ship.getValue("power") ? ActionTargettingMode.SELF_CONFIRM : ActionTargettingMode.SELF;
|
||||
}
|
||||
|
|
|
@ -91,11 +91,6 @@ module TK.SpaceTac {
|
|||
}
|
||||
|
||||
protected checkLocationTarget(ship: Ship, target: Target, from: IArenaLocation): boolean {
|
||||
// Check the location is on the grid
|
||||
if (!ship.grid.check(target)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that we move at least a unit
|
||||
if (ship.grid.measure(from, target) < 1) {
|
||||
return false;
|
||||
|
|
|
@ -67,10 +67,6 @@ module TK.SpaceTac {
|
|||
return result;
|
||||
}
|
||||
|
||||
checkShipTarget(ship: Ship, target: Target, from: IArenaLocation): boolean {
|
||||
return ship.is(target.ship_id);
|
||||
}
|
||||
|
||||
getSpecificDiffs(ship: Ship, battle: Battle, target: Target, apply_effects = true): BaseBattleDiff[] {
|
||||
let activated = ship.actions.isToggled(this);
|
||||
|
||||
|
|
|
@ -124,5 +124,24 @@ module TK.SpaceTac.Specs {
|
|||
ship.actions.toggle(vigilance, true);
|
||||
check.equals(action.checkCannotBeApplied(ship), ActionUnavailability.VIGILANCE);
|
||||
})
|
||||
|
||||
test.case("can only be used on the grid, and in range", check => {
|
||||
let battle = new Battle();
|
||||
battle.grid = new SquareGrid({ xmin: 0, xmax: 10, ymin: 0, ymax: 5 }, 1);
|
||||
let ship = battle.fleets[0].addShip();
|
||||
let action = ship.actions.addCustom(new TriggerAction("Weapon", { range: 8, blast: 1 }));
|
||||
|
||||
check.equals(action.checkTarget(ship, Target.newFromLocation(3, 3), ship.location), true);
|
||||
check.equals(action.checkTarget(ship, Target.newFromLocation(7, 0), ship.location), true);
|
||||
check.equals(action.checkTarget(ship, Target.newFromLocation(0, 7), ship.location), false);
|
||||
check.equals(action.checkTarget(ship, Target.newFromLocation(9, 4), ship.location), false);
|
||||
check.equals(action.checkTarget(ship, Target.newFromLocation(1.5, 1.5), ship.location), false);
|
||||
|
||||
action = ship.actions.addCustom(new TriggerAction("Weapon", { range: 8 }));
|
||||
check.equals(action.checkTarget(ship, Target.newFromLocation(3, 3), ship.location), false);
|
||||
|
||||
action = ship.actions.addCustom(new TriggerAction("Weapon", { range: 8, angle: 15 }));
|
||||
check.equals(action.checkTarget(ship, Target.newFromLocation(3, 3), ship.location), true);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
|
|
@ -129,11 +129,8 @@ module TK.SpaceTac {
|
|||
}
|
||||
|
||||
checkLocationTarget(ship: Ship, target: Target, from: IArenaLocation): boolean {
|
||||
if (target && (this.blast > 0 || this.angle > 0)) {
|
||||
return ship.grid.inRange(from, target, this.range);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
let grid = ship.grid;
|
||||
return grid.check(target) && grid.inRange(from, target, this.range);
|
||||
}
|
||||
|
||||
checkShipTarget(ship: Ship, target: Target, from: IArenaLocation): boolean {
|
||||
|
@ -142,11 +139,7 @@ module TK.SpaceTac {
|
|||
return false;
|
||||
} else {
|
||||
// Check if target is in range
|
||||
if (this.blast > 0 || this.angle > 0) {
|
||||
return this.checkLocationTarget(ship, new Target(target.x, target.y), from);
|
||||
} else {
|
||||
return ship.grid.inRange(from, target, this.range);
|
||||
}
|
||||
return ship.grid.inRange(from, target, this.range);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ module TK.SpaceTac.UI {
|
|||
grid_ok: UIBatch
|
||||
grid_power: UIBatch
|
||||
grid_invalid: UIBatch
|
||||
grid_work: Iterator<[IArenaLocation, MoveFireResult]> = IATEND
|
||||
|
||||
// Diffs display
|
||||
diffs_move: UIGraphics
|
||||
|
@ -65,6 +66,10 @@ module TK.SpaceTac.UI {
|
|||
this.grid_ok = builder.batch({ image: "battle-hud-grid-ok", x: -24, y: -20 });
|
||||
this.grid_power = builder.batch({ image: "battle-hud-grid-power", x: -24, y: -20 });
|
||||
this.grid_invalid = builder.batch({ image: "battle-hud-grid-invalid", x: -24, y: -20 });
|
||||
|
||||
// TODO Find a prettier solution
|
||||
(<any>this.container).preUpdate = () => this.updateGridIndicators(true);
|
||||
this.view.sys.updateList.add(this.container);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,27 +237,40 @@ module TK.SpaceTac.UI {
|
|||
/**
|
||||
* Update the grid indicators
|
||||
*/
|
||||
updateGridIndicators(): void {
|
||||
this.grid_ok.clear();
|
||||
this.grid_power.clear();
|
||||
this.grid_invalid.clear();
|
||||
|
||||
if (this.ship && this.action) {
|
||||
let grid = this.ship.grid;
|
||||
let action = this.action;
|
||||
let simulator = new MoveFireSimulator(this.ship, grid);
|
||||
|
||||
iforeach(grid.iterate(this.ship.location), loc => {
|
||||
let target = Target.newFromLocation(loc.x, loc.y);
|
||||
let result = simulator.simulateAction(action, target);
|
||||
if (result.status == MoveFireStatus.OK) {
|
||||
this.grid_ok.add(target.x, target.y);
|
||||
} else if (result.status == MoveFireStatus.NOT_ENOUGH_POWER) {
|
||||
this.grid_power.add(target.x, target.y);
|
||||
updateGridIndicators(periodic = false): void {
|
||||
if (periodic) {
|
||||
let started = Timer.nowMs();
|
||||
do {
|
||||
let state = this.grid_work.next();
|
||||
if (state.done) {
|
||||
break;
|
||||
} else {
|
||||
this.grid_invalid.add(target.x, target.y);
|
||||
let [location, result] = state.value;
|
||||
if (result.status == MoveFireStatus.OK) {
|
||||
this.grid_ok.add(location.x, location.y);
|
||||
} else if (result.status == MoveFireStatus.NOT_ENOUGH_POWER) {
|
||||
this.grid_power.add(location.x, location.y);
|
||||
} else {
|
||||
this.grid_invalid.add(location.x, location.y);
|
||||
}
|
||||
}
|
||||
});
|
||||
} while (Timer.fromMs(started) < 100);
|
||||
} else {
|
||||
this.grid_ok.clear();
|
||||
this.grid_power.clear();
|
||||
this.grid_invalid.clear();
|
||||
|
||||
if (this.ship && this.action) {
|
||||
let grid = this.ship.grid;
|
||||
let action = this.action;
|
||||
let simulator = new MoveFireSimulator(this.ship, grid);
|
||||
this.grid_work = imap(grid.iterate(this.ship.location), (loc): [IArenaLocation, MoveFireResult] => {
|
||||
let target = Target.newFromLocation(loc.x, loc.y);
|
||||
return [loc, simulator.simulateAction(action, target)];
|
||||
})[Symbol.iterator]();
|
||||
} else {
|
||||
this.grid_work = IATEND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue