Display simulated ship displacement effects while targetting
This commit is contained in:
parent
7d586d5a2b
commit
4e624dc9db
2
TODO.md
2
TODO.md
|
@ -43,7 +43,7 @@ Battle
|
|||
* Improve arena ships layering (sometimes information is displayed behind other sprites)
|
||||
* In the ship tooltip, show power cost, toggled and overheat states
|
||||
* Display shield (and its (dis)appearance)
|
||||
* Display estimated damage and displacement in targetting mode
|
||||
* Display estimated damage in targetting mode
|
||||
* Add a voluntary retreat option
|
||||
* Toggle bar/text display in power section of action bar
|
||||
* Show a cooldown indicator on move action icon, if the simulation would cause the engine to overheat
|
||||
|
|
|
@ -148,7 +148,7 @@ module TK.SpaceTac {
|
|||
let diff = battle.log.get(battle.log.count() - 1);
|
||||
if (diff instanceof EndBattleDiff) {
|
||||
check.notequals(diff.outcome.winner, null);
|
||||
check.same(diff.outcome.winner, fleet2);
|
||||
check.same(diff.outcome.winner, fleet2.id);
|
||||
} else {
|
||||
check.fail("Not an EndBattleDiff");
|
||||
}
|
||||
|
|
|
@ -349,10 +349,12 @@ module TK.SpaceTac {
|
|||
|
||||
/**
|
||||
* Perform all battle checks to ensure the state is consistent
|
||||
*
|
||||
* Returns all applied diffs
|
||||
*/
|
||||
performChecks(): void {
|
||||
performChecks(): BaseBattleDiff[] {
|
||||
let checks = new BattleChecks(this);
|
||||
checks.apply();
|
||||
return checks.apply();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,7 +7,7 @@ module TK.SpaceTac.Specs {
|
|||
cheats.win();
|
||||
|
||||
check.equals(battle.ended, true, "ended");
|
||||
check.same(nn(battle.outcome).winner, battle.fleets[0], "winner");
|
||||
check.same(nn(battle.outcome).winner, battle.fleets[0].id, "winner");
|
||||
check.equals(any(battle.fleets[1].ships, ship => ship.alive), false, "all enemies dead");
|
||||
})
|
||||
|
||||
|
@ -18,7 +18,7 @@ module TK.SpaceTac.Specs {
|
|||
cheats.lose();
|
||||
|
||||
check.equals(battle.ended, true, "ended");
|
||||
check.same(nn(battle.outcome).winner, battle.fleets[1], "winner");
|
||||
check.same(nn(battle.outcome).winner, battle.fleets[1].id, "winner");
|
||||
check.equals(any(battle.fleets[0].ships, ship => ship.alive), false, "all allies dead");
|
||||
})
|
||||
})
|
||||
|
|
|
@ -13,7 +13,8 @@ module TK.SpaceTac {
|
|||
/**
|
||||
* Apply all the checks
|
||||
*/
|
||||
apply(): void {
|
||||
apply(): BaseBattleDiff[] {
|
||||
let all: BaseBattleDiff[] = [];
|
||||
let diffs: BaseBattleDiff[];
|
||||
let loops = 0;
|
||||
|
||||
|
@ -23,6 +24,7 @@ module TK.SpaceTac {
|
|||
if (diffs.length > 0) {
|
||||
//console.log("Battle checks diffs", diffs);
|
||||
this.battle.applyDiffs(diffs);
|
||||
all = all.concat(diffs);
|
||||
}
|
||||
|
||||
loops += 1;
|
||||
|
@ -31,6 +33,8 @@ module TK.SpaceTac {
|
|||
break;
|
||||
}
|
||||
} while (diffs.length > 0);
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,10 +9,10 @@ module TK.SpaceTac {
|
|||
draw: boolean
|
||||
|
||||
// Victorious fleet
|
||||
winner: Fleet | null
|
||||
winner: RObjectId | null
|
||||
|
||||
constructor(winner: Fleet | null) {
|
||||
this.winner = winner;
|
||||
this.winner = winner ? winner.id : null;
|
||||
this.draw = winner ? false : true;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ module TK.SpaceTac {
|
|||
*/
|
||||
grantExperience(fleets: Fleet[]) {
|
||||
fleets.forEach(fleet => {
|
||||
let winfactor = (fleet == this.winner) ? 0.03 : (this.draw ? 0.01 : 0.005);
|
||||
let winfactor = (fleet.is(this.winner)) ? 0.03 : (this.draw ? 0.01 : 0.005);
|
||||
let enemies = flatten(fleets.filter(f => f !== fleet).map(f => f.ships));
|
||||
let difficulty = sum(enemies.map(enemy => 100 + enemy.level.getExperience()));
|
||||
fleet.ships.forEach(ship => {
|
||||
|
|
|
@ -2,7 +2,7 @@ module TK.SpaceTac {
|
|||
/**
|
||||
* A fleet of ships, all belonging to the same player
|
||||
*/
|
||||
export class Fleet {
|
||||
export class Fleet extends RObject {
|
||||
// Fleet owner
|
||||
player: Player
|
||||
|
||||
|
@ -26,6 +26,8 @@ module TK.SpaceTac {
|
|||
|
||||
// Create a fleet, bound to a player
|
||||
constructor(player = new Player()) {
|
||||
super();
|
||||
|
||||
this.player = player;
|
||||
this.name = player ? player.name : "Fleet";
|
||||
this.ships = [];
|
||||
|
|
|
@ -172,5 +172,36 @@ module TK.SpaceTac.Specs {
|
|||
check.equals(result.need_move, true);
|
||||
check.equals(result.move_location, new Target(ship.arena_x + 6, ship.arena_y));
|
||||
});
|
||||
|
||||
test.case("simulates the results on a fake battle, to provide a list of expected diffs", check => {
|
||||
let battle = TestTools.createBattle();
|
||||
let ship = battle.fleets[0].ships[0];
|
||||
let enemy = battle.fleets[1].ships[0];
|
||||
ship.setArenaPosition(100, 100);
|
||||
enemy.setArenaPosition(300, 100);
|
||||
TestTools.setShipModel(ship, 1, 1, 3);
|
||||
TestTools.setShipModel(enemy, 2, 1);
|
||||
let engine = TestTools.addEngine(ship, 80);
|
||||
let weapon = TestTools.addWeapon(ship, 5, 1, 150);
|
||||
let simulator = new MoveFireSimulator(ship);
|
||||
let result = simulator.simulateAction(weapon, Target.newFromShip(enemy), 5);
|
||||
let diffs = simulator.getExpectedDiffs(nn(ship.getBattle()), result);
|
||||
check.equals(diffs, [
|
||||
new ShipActionUsedDiff(ship, engine, Target.newFromLocation(155, 100)),
|
||||
new ShipValueDiff(ship, "power", -1),
|
||||
new ShipMoveDiff(ship, ship.location, new ArenaLocationAngle(155, 100), engine),
|
||||
new ShipActionUsedDiff(ship, weapon, Target.newFromShip(enemy)),
|
||||
new ShipValueDiff(ship, "power", -1),
|
||||
new ProjectileFiredDiff(ship, weapon, Target.newFromShip(enemy)),
|
||||
new ShipDamageDiff(enemy, 2, 1, 0, 5),
|
||||
new ShipValueDiff(enemy, "shield", -1),
|
||||
new ShipValueDiff(enemy, "hull", -2),
|
||||
new ShipDeathDiff(battle, enemy),
|
||||
new EndBattleDiff(battle.fleets[0], 0)
|
||||
]);
|
||||
|
||||
check.equals(enemy.getValue("hull"), 2);
|
||||
check.equals(enemy.getValue("hull"), 2);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -187,5 +187,25 @@ module TK.SpaceTac {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a move-fire simulation result, and predict the diffs it will apply on a battle
|
||||
*
|
||||
* The original battle passed as parameter will be duplicated, and not altered
|
||||
*/
|
||||
getExpectedDiffs(battle: Battle, simulation: MoveFireResult): BaseBattleDiff[] {
|
||||
let sim_battle = duplicate(battle, TK.SpaceTac);
|
||||
let sim_ship = nn(sim_battle.getShip(this.ship.id));
|
||||
let results: BaseBattleDiff[] = [];
|
||||
simulation.parts.forEach(part => {
|
||||
let diffs = part.action.getDiffs(sim_ship, battle, part.target);
|
||||
results = results.concat(diffs);
|
||||
sim_battle.applyDiffs(diffs);
|
||||
|
||||
diffs = sim_battle.performChecks();
|
||||
results = results.concat(diffs);
|
||||
});
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ module TK.SpaceTac {
|
|||
* Resolves the encounter from a battle outcome
|
||||
*/
|
||||
resolveEncounter(outcome: BattleOutcome) {
|
||||
if (this.encounter && outcome.winner && outcome.winner != this.encounter) {
|
||||
if (this.encounter && outcome.winner && !this.encounter.is(outcome.winner)) {
|
||||
this.clearEncounter();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ module TK.SpaceTac.Specs {
|
|||
},
|
||||
check => {
|
||||
check.equals(battle.ended, true, "battle is ended");
|
||||
check.same(nn(battle.outcome).winner, battle.fleets[1], "battle has an outcome");
|
||||
check.same(nn(battle.outcome).winner, battle.fleets[1].id, "battle has an outcome");
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
|
|
@ -62,7 +62,7 @@ module TK.SpaceTac.Specs {
|
|||
ship.setDead();
|
||||
battle.performChecks();
|
||||
check.equals(battle.ended, true);
|
||||
check.notsame(nn(battle.outcome).winner, fleet);
|
||||
check.notsame(nn(battle.outcome).winner, fleet.id);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ module TK.SpaceTac.UI {
|
|||
refreshContent(): void {
|
||||
let parent = this.battleview;
|
||||
let outcome = this.outcome;
|
||||
let victory = outcome.winner && this.player.is(outcome.winner.player);
|
||||
let victory = outcome.winner && this.player.fleet.is(outcome.winner);
|
||||
|
||||
this.content.clear();
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ module TK.SpaceTac.UI {
|
|||
|
||||
// Simulated result
|
||||
simulation = new MoveFireResult()
|
||||
effects: BaseBattleDiff[] = []
|
||||
simulated_diffs: BaseBattleDiff[] = []
|
||||
|
||||
// Move and fire lines
|
||||
drawn_info: UIGraphics
|
||||
|
@ -27,6 +27,9 @@ module TK.SpaceTac.UI {
|
|||
impact_area: UIGraphics
|
||||
impact_indicators: UIContainer
|
||||
|
||||
// Diffs display
|
||||
diffs_move: UIGraphics
|
||||
|
||||
// Collaborators to update
|
||||
actionbar: ActionBar
|
||||
range_hint: RangeHint
|
||||
|
@ -46,18 +49,16 @@ module TK.SpaceTac.UI {
|
|||
builder = builder.in(this.container);
|
||||
|
||||
// Visual effects
|
||||
this.impact_area = builder.graphics("impact-area");
|
||||
this.impact_area.setVisible(false);
|
||||
this.drawn_info = builder.graphics("lines");
|
||||
this.drawn_info.setVisible(false);
|
||||
this.impact_area = builder.graphics("impact-area", 0, 0, false);
|
||||
this.diffs_move = builder.graphics("effects-move");
|
||||
this.drawn_info = builder.graphics("lines", 0, 0, false);
|
||||
this.move_ghost = builder.image("common-transparent", 0, 0, true);
|
||||
this.move_ghost.setAlpha(0.8);
|
||||
this.move_ghost.setVisible(false);
|
||||
this.fire_arrow = builder.image("battle-hud-simulator-ok");
|
||||
this.fire_arrow.setOrigin(1, 0.5);
|
||||
this.fire_arrow.setVisible(false);
|
||||
this.impact_indicators = builder.container("impact-indicators");
|
||||
this.impact_indicators.setVisible(false);
|
||||
this.impact_indicators = builder.container("impact-indicators", 0, 0, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -200,6 +201,25 @@ module TK.SpaceTac.UI {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update information about simulated diffs
|
||||
*/
|
||||
updateDiffsDisplay(): void {
|
||||
this.diffs_move.clear();
|
||||
|
||||
this.simulated_diffs.forEach(diff => {
|
||||
if (diff instanceof ShipMoveDiff) {
|
||||
this.diffs_move.addLine({
|
||||
start: diff.start,
|
||||
end: diff.end,
|
||||
width: 4,
|
||||
color: 0xFFFFFF,
|
||||
alpha: 0.5
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update visual effects to show the simulation of current action/target
|
||||
*/
|
||||
|
@ -259,6 +279,9 @@ module TK.SpaceTac.UI {
|
|||
this.fire_arrow.visible = true;
|
||||
this.impact_area.visible = false;
|
||||
}
|
||||
|
||||
this.updateDiffsDisplay();
|
||||
|
||||
this.container.visible = true;
|
||||
} else {
|
||||
this.container.visible = false;
|
||||
|
@ -305,16 +328,13 @@ module TK.SpaceTac.UI {
|
|||
*/
|
||||
simulate(): void {
|
||||
if (this.ship && this.action && this.target) {
|
||||
let ship = this.ship;
|
||||
let simulator = new MoveFireSimulator(ship);
|
||||
let battle = nn(this.ship.getBattle());
|
||||
let simulator = new MoveFireSimulator(this.ship);
|
||||
this.simulation = simulator.simulateAction(this.action, this.target, 1);
|
||||
|
||||
this.effects = flatten(this.simulation.parts.map(part =>
|
||||
part.action.getDiffs(ship, nn(ship.getBattle()), part.target)
|
||||
));
|
||||
this.simulated_diffs = simulator.getExpectedDiffs(battle, this.simulation);
|
||||
} else {
|
||||
this.simulation = new MoveFireResult();
|
||||
this.effects = [];
|
||||
this.simulated_diffs = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue