Added "clean location" mission type
This commit is contained in:
parent
c8c08dc4cd
commit
c646b8722c
1
TODO.md
1
TODO.md
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -94,6 +94,7 @@ module TS.SpaceTac {
|
|||
*/
|
||||
addLocation(type: StarLocationType): StarLocation {
|
||||
let result = new StarLocation(this, type);
|
||||
this.locations.push(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
})
|
||||
})
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue