Added BattlePlanning structure to hold player/ai choices
This commit is contained in:
parent
059bed29be
commit
92ed2d9e45
|
@ -26,8 +26,8 @@ module TK {
|
||||||
/**
|
/**
|
||||||
* Check that two objects are the same (only by comparing their ID)
|
* Check that two objects are the same (only by comparing their ID)
|
||||||
*/
|
*/
|
||||||
is(other: RObject | RObjectId | null): boolean {
|
is(other: RObject | RObjectId | null | undefined): boolean {
|
||||||
if (other === null) {
|
if (other === null || typeof other === "undefined") {
|
||||||
return false;
|
return false;
|
||||||
} else if (other instanceof RObject) {
|
} else if (other instanceof RObject) {
|
||||||
return this.id === other.id;
|
return this.id === other.id;
|
||||||
|
|
58
src/core/BattlePlanning.spec.ts
Normal file
58
src/core/BattlePlanning.spec.ts
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
module TK.SpaceTac.Specs {
|
||||||
|
testing("BattlePlanning", test => {
|
||||||
|
test.case("initializes from a battle state", check => {
|
||||||
|
let battle = new Battle();
|
||||||
|
let planning = new BattlePlanning(battle);
|
||||||
|
check.equals(planning.getBattlePlan(), {
|
||||||
|
fleets: [
|
||||||
|
{ fleet: battle.fleets[0].id, ships: [] },
|
||||||
|
{ fleet: battle.fleets[1].id, ships: [] },
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
battle.fleets[0].addShip();
|
||||||
|
planning = new BattlePlanning(battle);
|
||||||
|
check.equals(planning.getBattlePlan(), {
|
||||||
|
fleets: [
|
||||||
|
{
|
||||||
|
fleet: battle.fleets[0].id, ships: [
|
||||||
|
{ ship: battle.fleets[0].ships[0].id, actions: [] },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ fleet: battle.fleets[1].id, ships: [] },
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.case("gets child fleet and ship plans", check => {
|
||||||
|
const battle = new Battle();
|
||||||
|
battle.fleets[0].addShip();
|
||||||
|
battle.fleets[1].addShip();
|
||||||
|
battle.fleets[1].addShip();
|
||||||
|
const planning = new BattlePlanning(battle);
|
||||||
|
|
||||||
|
check.equals(planning.getFleetPlan(battle.fleets[0]).fleet, battle.fleets[0].id);
|
||||||
|
check.equals(planning.getFleetPlan(battle.fleets[1]).fleet, battle.fleets[1].id);
|
||||||
|
check.equals(planning.getFleetPlan(new Fleet()).fleet, -1);
|
||||||
|
|
||||||
|
check.equals(planning.getShipPlan(battle.fleets[0].ships[0]).ship, battle.fleets[0].ships[0].id);
|
||||||
|
check.equals(planning.getShipPlan(battle.fleets[1].ships[0]).ship, battle.fleets[1].ships[0].id);
|
||||||
|
check.equals(planning.getShipPlan(battle.fleets[1].ships[1]).ship, battle.fleets[1].ships[1].id);
|
||||||
|
check.equals(planning.getShipPlan(new Ship()).ship, -1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test.case("adds an action and target to a ship plan", check => {
|
||||||
|
const battle = new Battle();
|
||||||
|
const ship = battle.fleets[0].addShip();
|
||||||
|
const action1 = ship.actions.addCustom(new BaseAction());
|
||||||
|
const planning = new BattlePlanning(battle);
|
||||||
|
|
||||||
|
check.equals(planning.getShipPlan(ship).actions, []);
|
||||||
|
|
||||||
|
planning.addAction(ship, action1, Target.newFromShip(ship));
|
||||||
|
check.equals(planning.getShipPlan(ship).actions, [
|
||||||
|
{ action: action1.id, target: Target.newFromShip(ship) }
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
66
src/core/BattlePlanning.ts
Normal file
66
src/core/BattlePlanning.ts
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
namespace TK.SpaceTac {
|
||||||
|
/**
|
||||||
|
* A tool to manipulate battle plans (action plans for all involved ships, for one turn)
|
||||||
|
*/
|
||||||
|
export class BattlePlanning {
|
||||||
|
private plan: BattlePlan
|
||||||
|
|
||||||
|
constructor(private battle: Battle, readonly player?: Player) {
|
||||||
|
this.plan = {
|
||||||
|
fleets: battle.fleets.map(fleet => ({
|
||||||
|
fleet: fleet.id,
|
||||||
|
ships: fleet.ships.map(ship => ({
|
||||||
|
ship: ship.id,
|
||||||
|
actions: []
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getBattlePlan(): BattlePlan {
|
||||||
|
return this.plan;
|
||||||
|
}
|
||||||
|
|
||||||
|
getFleetPlan(fleet: Fleet): FleetPlan {
|
||||||
|
const fplan = first(this.plan.fleets, ifleet => fleet.is(ifleet.fleet));
|
||||||
|
return fplan || { fleet: -1, ships: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
getShipPlan(ship: Ship): ShipPlan {
|
||||||
|
const fplan = this.getFleetPlan(ship.fleet);
|
||||||
|
const splan = first(fplan.ships, iship => ship.is(iship.ship));
|
||||||
|
return splan || { ship: -1, actions: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an action to a ship plan
|
||||||
|
*/
|
||||||
|
addAction(ship: Ship, action: BaseAction, target?: Target) {
|
||||||
|
const plan = this.getShipPlan(ship);
|
||||||
|
if (any(plan.actions, iaction => action.is(iaction.action))) {
|
||||||
|
// TODO replace (or remove if toggle action ?)
|
||||||
|
} else {
|
||||||
|
plan.actions.push({ action: action.id, target });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BattlePlan = {
|
||||||
|
fleets: FleetPlan[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FleetPlan = {
|
||||||
|
fleet: RObjectId,
|
||||||
|
ships: ShipPlan[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ShipPlan = {
|
||||||
|
ship: RObjectId
|
||||||
|
actions: ActionPlan[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ActionPlan = {
|
||||||
|
action: RObjectId
|
||||||
|
target?: Target
|
||||||
|
}
|
||||||
|
}
|
|
@ -148,7 +148,7 @@ module TK.SpaceTac.UI {
|
||||||
* This will effectively apply the action
|
* This will effectively apply the action
|
||||||
*/
|
*/
|
||||||
processSelection(target: Target): void {
|
processSelection(target: Target): void {
|
||||||
if (this.view.applyAction(this.action, target)) {
|
if (this.view.applyPlayerAction(this.action, target)) {
|
||||||
this.bar.actionEnded();
|
this.bar.actionEnded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,6 @@ module TK.SpaceTac.UI {
|
||||||
|
|
||||||
// Capture clicks
|
// Capture clicks
|
||||||
zone.on("pointerdown", (pointer: Phaser.Input.Pointer) => {
|
zone.on("pointerdown", (pointer: Phaser.Input.Pointer) => {
|
||||||
console.error(pointer);
|
|
||||||
button_down = (pointer.buttons == 1);
|
button_down = (pointer.buttons == 1);
|
||||||
});
|
});
|
||||||
zone.on("pointerup", () => {
|
zone.on("pointerup", () => {
|
||||||
|
|
|
@ -26,6 +26,9 @@ module TK.SpaceTac.UI {
|
||||||
// Multiplayer sharing
|
// Multiplayer sharing
|
||||||
multi!: MultiBattle
|
multi!: MultiBattle
|
||||||
|
|
||||||
|
// Battle planning for each fleets
|
||||||
|
plannings: BattlePlanning[] = []
|
||||||
|
|
||||||
// Layers
|
// Layers
|
||||||
layer_background!: UIContainer
|
layer_background!: UIContainer
|
||||||
layer_arena!: UIContainer
|
layer_arena!: UIContainer
|
||||||
|
@ -76,6 +79,7 @@ module TK.SpaceTac.UI {
|
||||||
this.player = data.player;
|
this.player = data.player;
|
||||||
this.actual_battle = data.battle;
|
this.actual_battle = data.battle;
|
||||||
this.battle = duplicate(data.battle, <any>TK.SpaceTac);
|
this.battle = duplicate(data.battle, <any>TK.SpaceTac);
|
||||||
|
this.plannings = this.battle.fleets.map(fleet => new BattlePlanning(this.battle, fleet.player));
|
||||||
this.ship_hovered = null;
|
this.ship_hovered = null;
|
||||||
this.background = null;
|
this.background = null;
|
||||||
this.multi = new MultiBattle();
|
this.multi = new MultiBattle();
|
||||||
|
@ -90,7 +94,6 @@ module TK.SpaceTac.UI {
|
||||||
create() {
|
create() {
|
||||||
super.create();
|
super.create();
|
||||||
|
|
||||||
var game = this.game;
|
|
||||||
this.interacting = false;
|
this.interacting = false;
|
||||||
this.log_processor = new LogProcessor(this);
|
this.log_processor = new LogProcessor(this);
|
||||||
|
|
||||||
|
@ -188,30 +191,20 @@ module TK.SpaceTac.UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply an action to the actual battle
|
* Apply a player action to the actual battle (this will add it to the current battle plan)
|
||||||
*/
|
*/
|
||||||
applyAction(action: BaseAction, target?: Target): boolean {
|
applyPlayerAction(action: BaseAction, target?: Target): boolean {
|
||||||
if (this.session.spectator) {
|
if (this.session.spectator) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ship = this.actual_battle.playing_ship;
|
this.plannings.forEach(planning => {
|
||||||
if (ship) {
|
if (this.action_bar.ship && this.player.is(planning.player)) {
|
||||||
let ship_action = ship.actions.getById(action.id);
|
planning.addAction(this.action_bar.ship, action, target);
|
||||||
if (ship_action) {
|
|
||||||
let result = this.actual_battle.applyOneAction(action.id, target);
|
|
||||||
if (result) {
|
|
||||||
this.setInteractionEnabled(false);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
console.error("Action not found in available list", action, ship.actions);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
console.error("Action not applied - ship not playing");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -245,7 +238,7 @@ module TK.SpaceTac.UI {
|
||||||
*/
|
*/
|
||||||
validationPressed(): void {
|
validationPressed(): void {
|
||||||
if (this.targetting.active) {
|
if (this.targetting.active) {
|
||||||
this.targetting.validate((action, target) => this.applyAction(action, target));
|
this.targetting.validate((action, target) => this.applyPlayerAction(action, target));
|
||||||
} else {
|
} else {
|
||||||
this.action_bar.keyActionPressed(-1);
|
this.action_bar.keyActionPressed(-1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,7 +224,7 @@ module TK.SpaceTac.UI {
|
||||||
} else if (!this.ai_disabled) {
|
} else if (!this.ai_disabled) {
|
||||||
this.view.playAI();
|
this.view.playAI();
|
||||||
} else {
|
} else {
|
||||||
this.view.applyAction(EndTurnAction.SINGLETON);
|
this.view.applyPlayerAction(EndTurnAction.SINGLETON);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.view.setInteractionEnabled(false);
|
this.view.setInteractionEnabled(false);
|
||||||
|
|
Loading…
Reference in a new issue