1
0
Fork 0

Added "clean location" mission type

This commit is contained in:
Michaël Lemaire 2017-07-10 22:40:22 +02:00
parent c8c08dc4cd
commit c646b8722c
8 changed files with 109 additions and 22 deletions

View File

@ -36,6 +36,7 @@ Character sheet
Battle
------
* Fix numerous effects being displayed on ships at the end, behind outcome dialog
* Add a voluntary retreat option
* Display effects description instead of attribute changes
* Display radius for area effects (both on action hover, and while action is active)

View File

@ -107,7 +107,7 @@ module TS.SpaceTac {
*/
getMissions(around: StarLocation, max_count = 3): Mission[] {
while (this.missions.length < max_count) {
let generator = new MissionGenerator(around.star.universe, around.star.level, around, this.random);
let generator = new MissionGenerator(around.star.universe, around, this.random);
let mission = generator.generate();
this.missions.push(mission);
}

View File

@ -94,6 +94,7 @@ module TS.SpaceTac {
*/
addLocation(type: StarLocationType): StarLocation {
let result = new StarLocation(this, type);
this.locations.push(result);
return result;
}

View File

@ -72,13 +72,7 @@ module TS.SpaceTac {
this.encounter_gen = true;
if (this.encounter_random.random() < 0.8) {
var fleet_generator = new FleetGenerator(this.encounter_random);
let variations: [number, number][] = [[this.star.level, 4], [this.star.level + 1, 3], [this.star.level + 2, 2]];
if (this.star.level > 1) {
variations.push([this.star.level - 1, 5]);
}
let [level, enemies] = this.encounter_random.choice(variations);
this.encounter = fleet_generator.generate(level, new Player(this.star.universe, "Enemy"), enemies, true);
this.setupEncounter();
}
}
@ -123,5 +117,20 @@ module TS.SpaceTac {
this.encounter_gen = true;
this.encounter = null;
}
/**
* Forces the setup of an encounter
*/
setupEncounter() {
this.encounter_gen = true;
let fleet_generator = new FleetGenerator(this.encounter_random);
let variations: [number, number][] = [[this.star.level, 4], [this.star.level + 1, 3], [this.star.level + 2, 2]];
if (this.star.level > 1) {
variations.push([this.star.level - 1, 5]);
}
let [level, enemies] = this.encounter_random.choice(variations);
this.encounter = fleet_generator.generate(level, new Player(this.star.universe, "Enemy"), enemies, true);
}
}
}

View File

@ -6,19 +6,33 @@ module TS.SpaceTac.Specs {
let loc1 = star1.locations[0];
let star2 = universe.addStar(2);
let loc2 = star2.locations[0];
let star3 = universe.addStar(3);
let loc3 = star3.locations[0];
universe.addLink(star1, star2);
universe.addLink(star2, star3);
let generator = new MissionGenerator(universe, 3, loc2);
let generator = new MissionGenerator(universe, loc1);
let mission = generator.generateEscort();
expect(mission.title).toBe("Escort a ship to a level 3 system");
expect(mission.title).toBe("Escort a ship to a level 2 system");
expect(mission.parts.length).toBe(1);
expect(mission.parts[0] instanceof MissionPartEscort).toBe(true);
let escort = <MissionPartEscort>mission.parts[0];
expect(escort.destination).toBe(loc3);
expect(escort.destination).toBe(loc2);
expect(escort.ship.level.get()).toBe(2);
});
it("generates location cleaning missions", () => {
let universe = new Universe();
let star1 = universe.addStar(1);
let loc1 = star1.locations[0];
let loc2 = star1.addLocation(StarLocationType.PLANET);
let generator = new MissionGenerator(universe, loc1);
let mission = generator.generateCleanLocation();
expect(mission.title).toBe("Defeat a level 1 fleet in this system");
expect(mission.parts.length).toBe(1);
expect(mission.parts[0] instanceof MissionPartCleanLocation).toBe(true);
let part = <MissionPartCleanLocation>mission.parts[0];
expect(part.destination).toBe(loc2);
});
});
}

View File

@ -19,13 +19,11 @@ module TS.SpaceTac {
*/
export class MissionGenerator {
universe: Universe
level: number
around: StarLocation
random: RandomGenerator
constructor(universe: Universe, level: number, around: StarLocation, random = RandomGenerator.global) {
constructor(universe: Universe, around: StarLocation, random = RandomGenerator.global) {
this.universe = universe;
this.level = level;
this.around = around;
this.random = random;
}
@ -35,7 +33,8 @@ module TS.SpaceTac {
*/
generate(): Mission {
let generators = [
bound(this, "generateEscort")
bound(this, "generateEscort"),
bound(this, "generateCleanLocation"),
];
let generator = this.random.choice(generators);
@ -47,9 +46,9 @@ module TS.SpaceTac {
/**
* Generate a new ship
*/
private generateShip() {
private generateShip(level: number) {
let generator = new ShipGenerator(this.random);
let result = generator.generate(this.level, null, true);
let result = generator.generate(level, null, true);
result.name = `${this.random.choice(POOL_SHIP_NAMES)}-${this.random.randInt(10, 999)}`;
return result;
}
@ -59,12 +58,28 @@ module TS.SpaceTac {
*/
generateEscort(): Mission {
let mission = new Mission(this.universe);
let ship = this.generateShip();
let dest_star = minBy(this.around.star.getNeighbors(), star => Math.abs(star.level - this.level));
let dest_star = this.random.choice(this.around.star.getNeighbors());
let destination = this.random.choice(dest_star.locations);
let ship = this.generateShip(dest_star.level);
mission.addPart(new MissionPartEscort(mission, destination, ship));
mission.title = `Escort a ship to a level ${dest_star.level} system`;
return mission;
}
/**
* Generate a clean location mission
*/
generateCleanLocation(): Mission {
let mission = new Mission(this.universe);
let dest_star = this.random.choice(this.around.star.getNeighbors().concat([this.around.star]));
let choices = dest_star.locations;
if (dest_star == this.around.star) {
choices = choices.filter(loc => loc != this.around);
}
let destination = this.random.choice(choices);
mission.addPart(new MissionPartCleanLocation(mission, destination));
mission.title = `Defeat a level ${destination.star.level} fleet in ${(dest_star == this.around.star) ? "this" : "a nearby"} system`;
return mission;
}
}
}

View File

@ -0,0 +1,25 @@
module TS.SpaceTac.Specs {
describe("MissionPartEscort", () => {
it("completes when the fleet is at location, and the encounter is clean", function () {
let destination = new StarLocation(new Star(null, 0, 0, "Atanax"));
destination.clearEncounter();
let universe = new Universe();
let fleet = new Fleet();
let part = new MissionPartCleanLocation(new Mission(universe, fleet), destination);
expect(part.title).toEqual("Clean a planet in Atanax system");
expect(part.checkCompleted()).toBe(false, "Init location");
expect(destination.isClear()).toBe(true);
part.onStarted();
expect(destination.isClear()).toBe(false);
fleet.setLocation(destination, true);
expect(part.checkCompleted()).toBe(false, "Encounter not clear");
destination.clearEncounter();
expect(part.checkCompleted()).toBe(true, "Encouter cleared");
})
})
}

View File

@ -0,0 +1,22 @@
/// <reference path="MissionPartGoTo.ts" />
module TS.SpaceTac {
/**
* A mission part that requires the fleet to clean a specific location of enemies
*/
export class MissionPartCleanLocation extends MissionPartGoTo {
ship: Ship
constructor(mission: Mission, destination: StarLocation, directive?: string) {
super(mission, destination, directive || `Clean a ${StarLocationType[destination.type].toLowerCase()} in ${destination.star.name} system`);
}
checkCompleted(): boolean {
return super.checkCompleted() && this.destination.isClear();
}
onStarted(): void {
this.destination.setupEncounter();
}
}
}