1
0
Fork 0

Added "Repair Drone" template (WIP)

This commit is contained in:
Michaël Lemaire 2017-02-07 01:08:07 +01:00
parent 45a13e9458
commit 1167aedbdf
12 changed files with 298 additions and 6 deletions

5
TODO
View file

@ -1,4 +1,7 @@
* Add drones to apply temporary zone effects
* Refactor attribute effects (add/sub, value/max, temporary/permanent)
* Drones: add hooks on events
* Drones: add sprite, radius and tooltip
* Repair drone: add graphics
* Allow to cancel last moves
* Effect should be random in a range (eg. "damage target 50-75")
* Add an overload/cooling system

View file

@ -22,7 +22,7 @@ module TS.SpaceTac.Game {
populate(): void {
var templates: LootTemplate[] = [];
for (var template_name in TS.SpaceTac.Game.Equipments) {
if (template_name) {
if (template_name && template_name.indexOf("Abstract") != 0) {
var template_class = TS.SpaceTac.Game.Equipments[template_name];
var template: LootTemplate = new template_class();
templates.push(template);

View file

@ -141,6 +141,13 @@ module TS.SpaceTac.Game {
this.permanent_effects.push(template);
}
// Convenience function to add an offset effect on attribute value
addAttributeAddEffect(code: AttributeCode, min: number, max: number | null = null): void {
let template = new EffectTemplate(new AttributeAddEffect(code, 0));
template.addModifier("value", new IntegerRange(min, max));
this.target_effects.push(template);
}
// Convenience function to add a "damage on target" effect
addDamageOnTargetEffect(min: number, max: number = null): void {
var template = new EffectTemplate(new DamageEffect(0));
@ -157,6 +164,13 @@ module TS.SpaceTac.Game {
this.target_effects.push(template);
}
/**
* Set the power consumption
*/
setPowerConsumption(minimal: number, maximal: number | null = null) {
this.ap_usage = new IntegerRange(minimal, maximal);
}
// Method to reimplement to assign an action to a generated equipment
protected getActionForEquipment(equipment: Equipment): BaseAction {
return null;

View file

@ -174,10 +174,19 @@ module TS.SpaceTac.Game {
}
}
// Set an attribute value
// If offset is true, the value will be added to current value
// If log is true, an attribute event will be added to the battle log
setAttribute(attr: Attribute, value: number, offset: boolean = false, log: boolean = true) {
/**
* Set an attribute value
*
* If *offset* is true, the value will be added to current value.
* If *log* is true, an attribute event will be added to the battle log
*
* Returns true if the attribute changed.
*/
setAttribute(attr: Attribute | AttributeCode, value: number, offset = false, log = true): boolean {
if (!(attr instanceof Attribute)) {
attr = this.attributes.getRawAttr(attr);
}
var changed: boolean;
if (offset) {
@ -189,6 +198,8 @@ module TS.SpaceTac.Game {
if (changed && log) {
this.addBattleEvent(new AttributeChangeEvent(this, attr));
}
return changed;
}
// Initialize the action points counter

View file

@ -0,0 +1,64 @@
/// <reference path="../effects/BaseEffect.ts" />
module TS.SpaceTac.Game {
describe("DeployDroneAction", function () {
it("stores useful information", function () {
let equipment = new Equipment(SlotType.Weapon, "testdrone");
let action = new DeployDroneAction(equipment);
expect(action.code).toEqual("deploy-testdrone");
expect(action.name).toEqual("Deploy");
expect(action.equipment).toBe(equipment);
expect(action.needs_target).toBe(true);
});
it("allows to deploy in range", function () {
let ship = new Ship();
ship.setArenaPosition(0, 0);
let equipment = new Equipment();
equipment.distance = 8;
equipment.ap_usage = 0;
let action = new DeployDroneAction(equipment);
expect(action.checkTarget(null, ship, new Target(8, 0, null))).toEqual(new Target(8, 0, null));
expect(action.checkTarget(null, ship, new Target(12, 0, null))).toEqual(new Target(8, 0, null));
let other = new Ship();
other.setArenaPosition(8, 0);
expect(action.checkTarget(null, ship, new Target(8, 0, other))).toBeNull();
});
it("deploys a new drone", function () {
let ship = new Ship();
ship.setArenaPosition(0, 0);
let battle = new Battle();
battle.playing_ship = ship;
TestTools.setShipAP(ship, 3);
let equipment = new Equipment();
equipment.distance = 8;
equipment.ap_usage = 2;
equipment.duration = 2;
equipment.blast = 4;
equipment.target_effects.push(new DamageEffect(50));
let action = new DeployDroneAction(equipment);
let result = action.apply(battle, ship, new Target(5, 0, null));
expect(result).toBe(true);
expect(battle.drones.length).toBe(1);
let drone = battle.drones[0];
expect(drone.duration).toEqual(2);
expect(drone.owner).toBe(ship);
expect(drone.x).toEqual(5);
expect(drone.y).toEqual(0);
expect(drone.radius).toEqual(4);
expect(drone.effects).toEqual([new DamageEffect(50)]);
expect(battle.log.events).toEqual([
new DroneDeployedEvent(drone)
]);
expect(ship.ap_current.current).toEqual(1);
});
});
}

View file

@ -0,0 +1,29 @@
/// <reference path="BaseAction.ts"/>
module TS.SpaceTac.Game {
/**
* Action to deploy a drone in space
*/
export class DeployDroneAction extends BaseAction {
constructor(equipment: Equipment) {
super("deploy-" + equipment.code, "Deploy", true, equipment);
}
checkLocationTarget(battle: Battle, ship: Ship, target: Target): Target {
// TODO Not too close to other ships and drones
target = target.constraintInRange(ship.arena_x, ship.arena_y, this.equipment.distance);
return target;
}
protected customApply(battle: Battle, ship: Ship, target: Target): boolean {
let drone = new Drone(ship);
drone.x = target.x;
drone.y = target.y;
drone.radius = this.equipment.blast;
drone.effects = this.equipment.target_effects;
drone.duration = this.equipment.duration;
battle.addDrone(drone);
return true;
}
}
}

View file

@ -0,0 +1,18 @@
module TS.SpaceTac.Game {
describe("AttributeAddEffect", function () {
it("adds an amount to an attribute value", function () {
let effect = new AttributeAddEffect(AttributeCode.Shield, 20);
let ship = new Ship();
ship.shield.maximal = 80;
ship.setAttribute(AttributeCode.Shield, 55);
expect(ship.shield.current).toEqual(55);
effect.applyOnShip(ship);
expect(ship.shield.current).toEqual(75);
effect.applyOnShip(ship);
expect(ship.shield.current).toEqual(80);
});
});
}

View file

@ -0,0 +1,35 @@
/// <reference path="BaseEffect.ts"/>
module TS.SpaceTac.Game {
/**
* Effect to add (or subtract if negative) an amount to an attribute value.
*
* The effect is "permanent", and will not be removed when the effect ends.
*/
export class AttributeAddEffect extends BaseEffect {
// Affected attribute
attrcode: AttributeCode;
// Value to add (or subtract if negative)
value: number;
constructor(attrcode: AttributeCode, value: number) {
super("attradd");
this.attrcode = attrcode;
this.value = value;
}
applyOnShip(ship: Ship): boolean {
return ship.setAttribute(this.attrcode, this.value, true);
}
isBeneficial(): boolean {
return this.value >= 0;
}
getFullCode(): string {
return this.code + "-" + AttributeCode[this.attrcode].toLowerCase().replace("_", "");
}
}
}

View file

@ -0,0 +1,48 @@
module TS.SpaceTac.Game.Equipments {
describe("AbstractDrone", function () {
it("can be configured", function () {
let template = new AbstractDrone("test");
expect(template.name).toEqual("test");
template.setDeployDistance(5, 8);
expect(template.distance).toEqual(new Range(5, 8));
template.setEffectRadius(100, 300);
expect(template.blast).toEqual(new IntegerRange(100, 300));
template.setLifetime(2, 3);
expect(template.duration).toEqual(new IntegerRange(2, 3));
});
it("generates a drone-deploying equipment", function () {
let template = new AbstractDrone("Test");
template.setDeployDistance(100, 200);
template.setEffectRadius(50, 100);
template.setLifetime(2, 3);
template.addDamageOnTargetEffect(20, 30);
template.setPowerConsumption(3, 5);
let equipment = template.generateFixed(0);
expect(equipment.action).toEqual(new DeployDroneAction(equipment));
expect(equipment.ap_usage).toEqual(3);
expect(equipment.blast).toEqual(50);
expect(equipment.code).toEqual("test");
expect(equipment.distance).toEqual(100);
expect(equipment.duration).toEqual(2);
expect(equipment.name).toEqual("Test");
expect(equipment.permanent_effects).toEqual([]);
expect(equipment.slot).toEqual(SlotType.Weapon);
expect(equipment.target_effects).toEqual([new DamageEffect(20)]);
equipment = template.generateFixed(1);
expect(equipment.action).toEqual(new DeployDroneAction(equipment));
expect(equipment.ap_usage).toEqual(5);
expect(equipment.blast).toEqual(100);
expect(equipment.code).toEqual("test");
expect(equipment.distance).toEqual(200);
expect(equipment.duration).toEqual(3);
expect(equipment.name).toEqual("Test");
expect(equipment.permanent_effects).toEqual([]);
expect(equipment.slot).toEqual(SlotType.Weapon);
expect(equipment.target_effects).toEqual([new DamageEffect(30)]);
});
});
}

View file

@ -0,0 +1,40 @@
/// <reference path="../LootTemplate.ts"/>
module TS.SpaceTac.Game.Equipments {
/**
* Base class for all weapon equipment that deploys a drone.
*/
export class AbstractDrone extends LootTemplate {
constructor(name: string) {
super(SlotType.Weapon, name);
}
/**
* Set the maximal distance at which the drone may be deployed
*
* Be aware that *min_distance* means the MAXIMAL reachable distance, but on a low-power loot !
*/
setDeployDistance(min_distance: number, max_distance: number = null): void {
this.distance = new Range(min_distance, max_distance);
}
/**
* Set the effect radius of the deployed drone
*/
setEffectRadius(min_radius: number, max_radius: number = null): void {
this.blast = new IntegerRange(min_radius, max_radius);
}
/**
* Set the drone lifetime
*/
setLifetime(min_lifetime: number, max_lifetime: number = null): void {
this.duration = new IntegerRange(min_lifetime, max_lifetime);
}
protected getActionForEquipment(equipment: Equipment): BaseAction {
var result = new DeployDroneAction(equipment);
return result;
}
}
}

View file

@ -0,0 +1,10 @@
module TS.SpaceTac.Game.Equipments {
describe("RepairDrone", function () {
it("generates a drone that may repair ships hull", function () {
let template = new RepairDrone();
let equipment = template.generateFixed(0);
expect(equipment.target_effects).toEqual([new AttributeAddEffect(AttributeCode.Hull, 10)]);
});
});
}

View file

@ -0,0 +1,20 @@
/// <reference path="AbstractDrone.ts"/>
module TS.SpaceTac.Game.Equipments {
/**
* Drone that repairs damage done to the hull.
*/
export class RepairDrone extends AbstractDrone {
constructor() {
super("Repair Drone");
this.min_level = new IntegerRange(1, 4);
this.setDeployDistance(50, 100);
this.setEffectRadius(40, 80);
this.setPowerConsumption(4, 5);
this.addAttributeAddEffect(AttributeCode.Hull, 10, 20);
}
}
}