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)
|
* Improve arena ships layering (sometimes information is displayed behind other sprites)
|
||||||
* In the ship tooltip, show power cost, toggled and overheat states
|
* In the ship tooltip, show power cost, toggled and overheat states
|
||||||
* Display shield (and its (dis)appearance)
|
* 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
|
* Add a voluntary retreat option
|
||||||
* Toggle bar/text display in power section of action bar
|
* 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
|
* 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);
|
let diff = battle.log.get(battle.log.count() - 1);
|
||||||
if (diff instanceof EndBattleDiff) {
|
if (diff instanceof EndBattleDiff) {
|
||||||
check.notequals(diff.outcome.winner, null);
|
check.notequals(diff.outcome.winner, null);
|
||||||
check.same(diff.outcome.winner, fleet2);
|
check.same(diff.outcome.winner, fleet2.id);
|
||||||
} else {
|
} else {
|
||||||
check.fail("Not an EndBattleDiff");
|
check.fail("Not an EndBattleDiff");
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,10 +349,12 @@ module TK.SpaceTac {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform all battle checks to ensure the state is consistent
|
* Perform all battle checks to ensure the state is consistent
|
||||||
|
*
|
||||||
|
* Returns all applied diffs
|
||||||
*/
|
*/
|
||||||
performChecks(): void {
|
performChecks(): BaseBattleDiff[] {
|
||||||
let checks = new BattleChecks(this);
|
let checks = new BattleChecks(this);
|
||||||
checks.apply();
|
return checks.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,7 +7,7 @@ module TK.SpaceTac.Specs {
|
||||||
cheats.win();
|
cheats.win();
|
||||||
|
|
||||||
check.equals(battle.ended, true, "ended");
|
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");
|
check.equals(any(battle.fleets[1].ships, ship => ship.alive), false, "all enemies dead");
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ module TK.SpaceTac.Specs {
|
||||||
cheats.lose();
|
cheats.lose();
|
||||||
|
|
||||||
check.equals(battle.ended, true, "ended");
|
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");
|
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 all the checks
|
||||||
*/
|
*/
|
||||||
apply(): void {
|
apply(): BaseBattleDiff[] {
|
||||||
|
let all: BaseBattleDiff[] = [];
|
||||||
let diffs: BaseBattleDiff[];
|
let diffs: BaseBattleDiff[];
|
||||||
let loops = 0;
|
let loops = 0;
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ module TK.SpaceTac {
|
||||||
if (diffs.length > 0) {
|
if (diffs.length > 0) {
|
||||||
//console.log("Battle checks diffs", diffs);
|
//console.log("Battle checks diffs", diffs);
|
||||||
this.battle.applyDiffs(diffs);
|
this.battle.applyDiffs(diffs);
|
||||||
|
all = all.concat(diffs);
|
||||||
}
|
}
|
||||||
|
|
||||||
loops += 1;
|
loops += 1;
|
||||||
|
@ -31,6 +33,8 @@ module TK.SpaceTac {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (diffs.length > 0);
|
} while (diffs.length > 0);
|
||||||
|
|
||||||
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -9,10 +9,10 @@ module TK.SpaceTac {
|
||||||
draw: boolean
|
draw: boolean
|
||||||
|
|
||||||
// Victorious fleet
|
// Victorious fleet
|
||||||
winner: Fleet | null
|
winner: RObjectId | null
|
||||||
|
|
||||||
constructor(winner: Fleet | null) {
|
constructor(winner: Fleet | null) {
|
||||||
this.winner = winner;
|
this.winner = winner ? winner.id : null;
|
||||||
this.draw = winner ? false : true;
|
this.draw = winner ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ module TK.SpaceTac {
|
||||||
*/
|
*/
|
||||||
grantExperience(fleets: Fleet[]) {
|
grantExperience(fleets: Fleet[]) {
|
||||||
fleets.forEach(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 enemies = flatten(fleets.filter(f => f !== fleet).map(f => f.ships));
|
||||||
let difficulty = sum(enemies.map(enemy => 100 + enemy.level.getExperience()));
|
let difficulty = sum(enemies.map(enemy => 100 + enemy.level.getExperience()));
|
||||||
fleet.ships.forEach(ship => {
|
fleet.ships.forEach(ship => {
|
||||||
|
|
|
@ -2,7 +2,7 @@ module TK.SpaceTac {
|
||||||
/**
|
/**
|
||||||
* A fleet of ships, all belonging to the same player
|
* A fleet of ships, all belonging to the same player
|
||||||
*/
|
*/
|
||||||
export class Fleet {
|
export class Fleet extends RObject {
|
||||||
// Fleet owner
|
// Fleet owner
|
||||||
player: Player
|
player: Player
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ module TK.SpaceTac {
|
||||||
|
|
||||||
// Create a fleet, bound to a player
|
// Create a fleet, bound to a player
|
||||||
constructor(player = new Player()) {
|
constructor(player = new Player()) {
|
||||||
|
super();
|
||||||
|
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.name = player ? player.name : "Fleet";
|
this.name = player ? player.name : "Fleet";
|
||||||
this.ships = [];
|
this.ships = [];
|
||||||
|
|
|
@ -172,5 +172,36 @@ module TK.SpaceTac.Specs {
|
||||||
check.equals(result.need_move, true);
|
check.equals(result.need_move, true);
|
||||||
check.equals(result.move_location, new Target(ship.arena_x + 6, ship.arena_y));
|
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;
|
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
|
* Resolves the encounter from a battle outcome
|
||||||
*/
|
*/
|
||||||
resolveEncounter(outcome: BattleOutcome) {
|
resolveEncounter(outcome: BattleOutcome) {
|
||||||
if (this.encounter && outcome.winner && outcome.winner != this.encounter) {
|
if (this.encounter && outcome.winner && !this.encounter.is(outcome.winner)) {
|
||||||
this.clearEncounter();
|
this.clearEncounter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ module TK.SpaceTac.Specs {
|
||||||
},
|
},
|
||||||
check => {
|
check => {
|
||||||
check.equals(battle.ended, true, "battle is ended");
|
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();
|
ship.setDead();
|
||||||
battle.performChecks();
|
battle.performChecks();
|
||||||
check.equals(battle.ended, true);
|
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 {
|
refreshContent(): void {
|
||||||
let parent = this.battleview;
|
let parent = this.battleview;
|
||||||
let outcome = this.outcome;
|
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();
|
this.content.clear();
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ module TK.SpaceTac.UI {
|
||||||
|
|
||||||
// Simulated result
|
// Simulated result
|
||||||
simulation = new MoveFireResult()
|
simulation = new MoveFireResult()
|
||||||
effects: BaseBattleDiff[] = []
|
simulated_diffs: BaseBattleDiff[] = []
|
||||||
|
|
||||||
// Move and fire lines
|
// Move and fire lines
|
||||||
drawn_info: UIGraphics
|
drawn_info: UIGraphics
|
||||||
|
@ -27,6 +27,9 @@ module TK.SpaceTac.UI {
|
||||||
impact_area: UIGraphics
|
impact_area: UIGraphics
|
||||||
impact_indicators: UIContainer
|
impact_indicators: UIContainer
|
||||||
|
|
||||||
|
// Diffs display
|
||||||
|
diffs_move: UIGraphics
|
||||||
|
|
||||||
// Collaborators to update
|
// Collaborators to update
|
||||||
actionbar: ActionBar
|
actionbar: ActionBar
|
||||||
range_hint: RangeHint
|
range_hint: RangeHint
|
||||||
|
@ -46,18 +49,16 @@ module TK.SpaceTac.UI {
|
||||||
builder = builder.in(this.container);
|
builder = builder.in(this.container);
|
||||||
|
|
||||||
// Visual effects
|
// Visual effects
|
||||||
this.impact_area = builder.graphics("impact-area");
|
this.impact_area = builder.graphics("impact-area", 0, 0, false);
|
||||||
this.impact_area.setVisible(false);
|
this.diffs_move = builder.graphics("effects-move");
|
||||||
this.drawn_info = builder.graphics("lines");
|
this.drawn_info = builder.graphics("lines", 0, 0, false);
|
||||||
this.drawn_info.setVisible(false);
|
|
||||||
this.move_ghost = builder.image("common-transparent", 0, 0, true);
|
this.move_ghost = builder.image("common-transparent", 0, 0, true);
|
||||||
this.move_ghost.setAlpha(0.8);
|
this.move_ghost.setAlpha(0.8);
|
||||||
this.move_ghost.setVisible(false);
|
this.move_ghost.setVisible(false);
|
||||||
this.fire_arrow = builder.image("battle-hud-simulator-ok");
|
this.fire_arrow = builder.image("battle-hud-simulator-ok");
|
||||||
this.fire_arrow.setOrigin(1, 0.5);
|
this.fire_arrow.setOrigin(1, 0.5);
|
||||||
this.fire_arrow.setVisible(false);
|
this.fire_arrow.setVisible(false);
|
||||||
this.impact_indicators = builder.container("impact-indicators");
|
this.impact_indicators = builder.container("impact-indicators", 0, 0, false);
|
||||||
this.impact_indicators.setVisible(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
|
* 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.fire_arrow.visible = true;
|
||||||
this.impact_area.visible = false;
|
this.impact_area.visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.updateDiffsDisplay();
|
||||||
|
|
||||||
this.container.visible = true;
|
this.container.visible = true;
|
||||||
} else {
|
} else {
|
||||||
this.container.visible = false;
|
this.container.visible = false;
|
||||||
|
@ -305,16 +328,13 @@ module TK.SpaceTac.UI {
|
||||||
*/
|
*/
|
||||||
simulate(): void {
|
simulate(): void {
|
||||||
if (this.ship && this.action && this.target) {
|
if (this.ship && this.action && this.target) {
|
||||||
let ship = this.ship;
|
let battle = nn(this.ship.getBattle());
|
||||||
let simulator = new MoveFireSimulator(ship);
|
let simulator = new MoveFireSimulator(this.ship);
|
||||||
this.simulation = simulator.simulateAction(this.action, this.target, 1);
|
this.simulation = simulator.simulateAction(this.action, this.target, 1);
|
||||||
|
this.simulated_diffs = simulator.getExpectedDiffs(battle, this.simulation);
|
||||||
this.effects = flatten(this.simulation.parts.map(part =>
|
|
||||||
part.action.getDiffs(ship, nn(ship.getBattle()), part.target)
|
|
||||||
));
|
|
||||||
} else {
|
} else {
|
||||||
this.simulation = new MoveFireResult();
|
this.simulation = new MoveFireResult();
|
||||||
this.effects = [];
|
this.simulated_diffs = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue