Added looting from the battle outcome (WIP)
This commit is contained in:
parent
728119877b
commit
8354f03cfb
|
@ -6,6 +6,9 @@ module SpaceTac.Game {
|
|||
// Flag indicating if the battle is ended
|
||||
ended: boolean;
|
||||
|
||||
// Battle outcome, if *ended* is true
|
||||
outcome: BattleOutcome;
|
||||
|
||||
// Log of all battle events
|
||||
log: BattleLog;
|
||||
|
||||
|
@ -84,6 +87,18 @@ module SpaceTac.Game {
|
|||
return result;
|
||||
}
|
||||
|
||||
// Ends a battle and sets the outcome
|
||||
endBattle(winner: Fleet, log: boolean = true) {
|
||||
this.ended = true;
|
||||
this.outcome = new BattleOutcome(winner);
|
||||
if (winner) {
|
||||
this.outcome.createLoot(this);
|
||||
}
|
||||
if (log && this.log) {
|
||||
this.log.add(new EndBattleEvent(this.outcome));
|
||||
}
|
||||
}
|
||||
|
||||
// Checks end battle conditions, returns true if the battle ended
|
||||
checkEndBattle(log: boolean = true) {
|
||||
if (this.ended) {
|
||||
|
@ -94,18 +109,16 @@ module SpaceTac.Game {
|
|||
|
||||
if (alive_fleets === 0) {
|
||||
// It's a draw
|
||||
this.ended = true;
|
||||
this.log.add(new EndBattleEvent(null));
|
||||
this.endBattle(null, log);
|
||||
} else if (alive_fleets === 1) {
|
||||
// We have a winner
|
||||
var winner: Player = null;
|
||||
var winner: Fleet = null;
|
||||
this.fleets.forEach((fleet: Fleet) => {
|
||||
if (fleet.isAlive()) {
|
||||
winner = fleet.player;
|
||||
winner = fleet;
|
||||
}
|
||||
});
|
||||
this.ended = true;
|
||||
this.log.add(new EndBattleEvent(winner));
|
||||
this.endBattle(winner, log);
|
||||
}
|
||||
|
||||
return this.ended;
|
||||
|
|
50
src/scripts/game/BattleOutcome.ts
Normal file
50
src/scripts/game/BattleOutcome.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
module SpaceTac.Game {
|
||||
"use strict";
|
||||
|
||||
// Result of an ended battle
|
||||
export class BattleOutcome {
|
||||
// Indicates if the battle is a draw (no winner)
|
||||
draw: boolean;
|
||||
|
||||
// Victorious fleet
|
||||
winner: Fleet;
|
||||
|
||||
// Retrievable loot
|
||||
loot: Equipment[];
|
||||
|
||||
constructor(winner: Fleet) {
|
||||
this.winner = winner;
|
||||
this.draw = winner ? false : true;
|
||||
this.loot = [];
|
||||
}
|
||||
|
||||
// Create loot from dead ships
|
||||
createLoot(battle: Battle, random: RandomGenerator = new RandomGenerator()): void {
|
||||
this.loot = [];
|
||||
battle.fleets.forEach((fleet: Fleet) => {
|
||||
fleet.ships.forEach((ship: Ship) => {
|
||||
if (!ship.alive) {
|
||||
if (ship.fleet === this.winner) {
|
||||
// Member of the winner fleet, salvage a number of equipments
|
||||
var count = random.throwInt(0, ship.getEquipmentCount());
|
||||
while (count > 0) {
|
||||
var salvaged = ship.getRandomEquipment(random);
|
||||
salvaged.detach();
|
||||
this.loot.push(salvaged);
|
||||
count--;
|
||||
}
|
||||
|
||||
} else {
|
||||
var luck = random.throw();
|
||||
if (luck > 0.9) {
|
||||
// TODO Salvage a supposedly transported item
|
||||
} else if (luck > 0.5) {
|
||||
// TODO Salvage an equipped item
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,10 @@ module SpaceTac.Game {
|
|||
|
||||
// Piece of equipment to attach in slots
|
||||
export class Equipment {
|
||||
// Type of slot this equipment will fit in
|
||||
// Actual slot this equipment is attached to
|
||||
attached_to: Slot;
|
||||
|
||||
// Type of slot this equipment can fit in
|
||||
slot: SlotType;
|
||||
|
||||
// Equipment name
|
||||
|
@ -37,7 +40,9 @@ module SpaceTac.Game {
|
|||
target_effects: BaseEffect[];
|
||||
|
||||
// Basic constructor
|
||||
constructor() {
|
||||
constructor(slot: SlotType = null, name: string = null) {
|
||||
this.slot = slot;
|
||||
this.name = name;
|
||||
this.requirements = [];
|
||||
this.permanent_effects = [];
|
||||
this.target_effects = [];
|
||||
|
@ -46,13 +51,25 @@ module SpaceTac.Game {
|
|||
// Returns true if the equipment can be equipped on a ship
|
||||
// This checks *requirements* against the ship capabilities
|
||||
canBeEquipped(ship: Ship): boolean {
|
||||
var able = true;
|
||||
this.requirements.forEach((cap: Attribute) => {
|
||||
if (ship.attributes.getValue(cap.code) < cap.current) {
|
||||
able = false;
|
||||
}
|
||||
});
|
||||
return able;
|
||||
if (this.attached_to) {
|
||||
return false;
|
||||
} else {
|
||||
var able = true;
|
||||
this.requirements.forEach((cap: Attribute) => {
|
||||
if (ship.attributes.getValue(cap.code) < cap.current) {
|
||||
able = false;
|
||||
}
|
||||
});
|
||||
return able;
|
||||
}
|
||||
}
|
||||
|
||||
// Detach from the slot it is attached to
|
||||
detach(): void {
|
||||
if (this.attached_to) {
|
||||
this.attached_to.attached = null;
|
||||
this.attached_to = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,10 @@ module SpaceTac.Game {
|
|||
|
||||
// Add a ship in this fleet
|
||||
addShip(ship: Ship): void {
|
||||
if (this.ships.indexOf(ship) < 0) {
|
||||
this.ships.push(ship);
|
||||
}
|
||||
ship.fleet = this;
|
||||
this.ships.push(ship);
|
||||
}
|
||||
|
||||
// Set the current battle
|
||||
|
|
|
@ -8,7 +8,11 @@ module SpaceTac.Game {
|
|||
|
||||
// Basic constructor (can specify fake values as arguments)
|
||||
constructor(...values: number[]) {
|
||||
this.fake_values = values;
|
||||
this.fake_values = [];
|
||||
|
||||
values.forEach((value: number) => {
|
||||
this.forceNextValue(value);
|
||||
});
|
||||
}
|
||||
|
||||
// Generate a value, based on an attribute level
|
||||
|
@ -23,7 +27,7 @@ module SpaceTac.Game {
|
|||
// Generate a random integer value in a range
|
||||
throwInt(min: number, max: number): number {
|
||||
var value = this.throw(max - min + 1);
|
||||
return Math.floor(value) + max;
|
||||
return Math.floor(value) + min;
|
||||
}
|
||||
|
||||
// Choose a random item from an array
|
||||
|
@ -36,6 +40,11 @@ module SpaceTac.Game {
|
|||
// Call it several times to set future successive values
|
||||
// This value will replace the 0.0-1.0 random value, not the final one
|
||||
forceNextValue(value: number): void {
|
||||
if (value < 0.0) {
|
||||
value = 0.0;
|
||||
} else if (value >= 1.0) {
|
||||
value = 0.999999999;
|
||||
}
|
||||
this.fake_values.push(value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -258,6 +258,38 @@ module SpaceTac.Game {
|
|||
return result;
|
||||
}
|
||||
|
||||
// Get the number of attached equipments
|
||||
getEquipmentCount(): number {
|
||||
var result = 0;
|
||||
this.slots.forEach((slot: Slot) => {
|
||||
if (slot.attached) {
|
||||
result++;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get a random attached equipment, null if no equipment is attached
|
||||
getRandomEquipment(random: RandomGenerator = new RandomGenerator()): Equipment {
|
||||
var count = this.getEquipmentCount();
|
||||
if (count === 0) {
|
||||
return null;
|
||||
} else {
|
||||
var picked = random.throwInt(0, count - 1);
|
||||
var result: Equipment = null;
|
||||
var index = 0;
|
||||
this.slots.forEach((slot: Slot) => {
|
||||
if (slot.attached) {
|
||||
if (index === picked) {
|
||||
result = slot.attached;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Update attributes, taking into account attached equipment and active effects
|
||||
updateAttributes(): void {
|
||||
// TODO Something more generic
|
||||
|
|
|
@ -32,6 +32,7 @@ module SpaceTac.Game {
|
|||
attach(equipment: Equipment): void {
|
||||
if (this.type === equipment.slot && equipment.canBeEquipped(this.ship)) {
|
||||
this.attached = equipment;
|
||||
equipment.attached_to = this;
|
||||
|
||||
if (this.ship) {
|
||||
this.ship.updateAttributes();
|
||||
|
|
|
@ -6,13 +6,13 @@ module SpaceTac.Game {
|
|||
// Event logged when the battle ended
|
||||
// This is always the last event of a battle log
|
||||
export class EndBattleEvent extends BaseLogEvent {
|
||||
// Winner of the battle
|
||||
winner: Player;
|
||||
// Outcome of the battle
|
||||
outcome: BattleOutcome;
|
||||
|
||||
constructor(winner: Player) {
|
||||
constructor(outcome: BattleOutcome) {
|
||||
super("endbattle");
|
||||
|
||||
this.winner = winner;
|
||||
this.outcome = outcome;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,8 +169,8 @@ module SpaceTac.Game {
|
|||
expect(battle.ended).toBe(true);
|
||||
expect(battle.log.events.length).toBe(1);
|
||||
expect(battle.log.events[0].code).toBe("endbattle");
|
||||
expect((<EndBattleEvent>battle.log.events[0]).winner).not.toBeNull();
|
||||
expect((<EndBattleEvent>battle.log.events[0]).winner).toBe(fleet2.player);
|
||||
expect((<EndBattleEvent>battle.log.events[0]).outcome.winner).not.toBeNull();
|
||||
expect((<EndBattleEvent>battle.log.events[0]).outcome.winner).toBe(fleet2);
|
||||
});
|
||||
|
||||
it("handles a draw in end battle", function () {
|
||||
|
@ -196,7 +196,7 @@ module SpaceTac.Game {
|
|||
expect(battle.ended).toBe(true);
|
||||
expect(battle.log.events.length).toBe(1);
|
||||
expect(battle.log.events[0].code).toBe("endbattle");
|
||||
expect((<EndBattleEvent>battle.log.events[0]).winner).toBeNull();
|
||||
expect((<EndBattleEvent>battle.log.events[0]).outcome.winner).toBeNull();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
44
src/scripts/game/specs/BattleOutcome.spec.ts
Normal file
44
src/scripts/game/specs/BattleOutcome.spec.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
/// <reference path="../../definitions/jasmine.d.ts"/>
|
||||
|
||||
module SpaceTac.Game.Specs {
|
||||
"use strict";
|
||||
|
||||
describe("BattleOutcome", () => {
|
||||
it("generates loot from dead ships, for the winner to take", () => {
|
||||
var fleet1 = new Fleet();
|
||||
fleet1.addShip(new Ship(fleet1));
|
||||
fleet1.addShip(new Ship(fleet1));
|
||||
fleet1.addShip(new Ship(fleet1));
|
||||
var fleet2 = new Fleet();
|
||||
fleet2.addShip(new Ship(fleet2));
|
||||
fleet2.addShip(new Ship(fleet2));
|
||||
fleet2.addShip(new Ship(fleet2));
|
||||
|
||||
fleet1.ships[0].setDead();
|
||||
fleet1.ships[0].addSlot(SlotType.Armor).attach(new Equipment(SlotType.Armor));
|
||||
fleet1.ships[1].setDead();
|
||||
fleet1.ships[1].addSlot(SlotType.Engine).attach(new Equipment(SlotType.Engine, "1.1.1"));
|
||||
fleet1.ships[1].addSlot(SlotType.Engine).attach(new Equipment(SlotType.Engine, "1.1.2"));
|
||||
fleet1.ships[1].addSlot(SlotType.Engine).attach(new Equipment(SlotType.Engine, "1.1.3"));
|
||||
fleet1.ships[1].addSlot(SlotType.Engine).attach(new Equipment(SlotType.Engine, "1.1.4"));
|
||||
fleet2.ships[0].setDead();
|
||||
fleet2.ships[1].setDead();
|
||||
fleet2.ships[2].setDead();
|
||||
|
||||
var battle = new Battle(fleet1, fleet2);
|
||||
var outcome = new BattleOutcome(fleet1);
|
||||
|
||||
var random = new RandomGenerator(
|
||||
0, // leave first ship alone
|
||||
0.45, // take 2 equipments from the 4 of second ship
|
||||
1, // - take last equipment
|
||||
0 // - take first equipment
|
||||
);
|
||||
outcome.createLoot(battle, random);
|
||||
|
||||
expect(outcome.loot.length).toBe(2);
|
||||
expect(outcome.loot[0].name).toBe("1.1.4");
|
||||
expect(outcome.loot[1].name).toBe("1.1.1");
|
||||
});
|
||||
});
|
||||
}
|
|
@ -171,5 +171,37 @@ module SpaceTac.Game {
|
|||
expect(ship.isAbleToPlay()).toBe(false);
|
||||
expect(ship.isAbleToPlay(false)).toBe(false);
|
||||
});
|
||||
|
||||
it("counts attached equipment", function () {
|
||||
var ship = new Ship();
|
||||
|
||||
expect(ship.getEquipmentCount()).toBe(0);
|
||||
|
||||
ship.addSlot(SlotType.Armor).attach(new Equipment(SlotType.Armor));
|
||||
ship.addSlot(SlotType.Shield);
|
||||
ship.addSlot(SlotType.Weapon).attach(new Equipment(SlotType.Weapon));
|
||||
|
||||
expect(ship.getEquipmentCount()).toBe(2);
|
||||
});
|
||||
|
||||
it("can pick a random attached equipment", function () {
|
||||
var ship = new Ship();
|
||||
|
||||
expect(ship.getRandomEquipment()).toBe(null);
|
||||
|
||||
ship.addSlot(SlotType.Armor).attach(new Equipment(SlotType.Armor));
|
||||
ship.addSlot(SlotType.Shield);
|
||||
ship.addSlot(SlotType.Weapon).attach(new Equipment(SlotType.Weapon));
|
||||
|
||||
var random = new RandomGenerator(0.2);
|
||||
var picked = ship.getRandomEquipment(random);
|
||||
expect(picked).not.toBeNull();
|
||||
expect(picked).toBe(ship.slots[0].attached);
|
||||
|
||||
random.forceNextValue(1);
|
||||
picked = ship.getRandomEquipment(random);
|
||||
expect(picked).not.toBeNull();
|
||||
expect(picked).toBe(ship.slots[2].attached);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue